Avoid memory copy at XString initialisation.

This commit is contained in:
Jief L 2020-04-29 23:34:28 +03:00
parent 0c0c2d53d4
commit 82b679bcbd
9 changed files with 854 additions and 542 deletions

View File

@ -122,6 +122,7 @@
9A637AE82430D927000B9474 /* XTheme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5E3262F2428F4EE002240E8 /* XTheme.cpp */; };
9A637AE92430D928000B9474 /* XTheme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5E3262F2428F4EE002240E8 /* XTheme.cpp */; };
9A637AEA2430D928000B9474 /* XTheme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5E3262F2428F4EE002240E8 /* XTheme.cpp */; };
9A7AEDE7245963BF003AAD04 /* XToolsCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A7AEDE6245963BF003AAD04 /* XToolsCommon.h */; };
9A9AEB94243F7B5600FBD7D8 /* unicode_conversions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A9AEB90243F7B5600FBD7D8 /* unicode_conversions.cpp */; };
9A9AEB97243F7B5600FBD7D8 /* unicode_conversions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A9AEB93243F7B5600FBD7D8 /* unicode_conversions.h */; };
9A9AEB99243F7B7A00FBD7D8 /* printf_lite-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A9AEB98243F7B7900FBD7D8 /* printf_lite-test.h */; };
@ -884,6 +885,7 @@
9A35A6172451FE1500CAFF76 /* XStringAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XStringAbstract.h; sourceTree = "<group>"; };
9A4185B42439F29D00BEAFB8 /* LoadOptions_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadOptions_test.h; sourceTree = "<group>"; };
9A4185B52439F29D00BEAFB8 /* LoadOptions_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadOptions_test.cpp; sourceTree = "<group>"; };
9A7AEDE6245963BF003AAD04 /* XToolsCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XToolsCommon.h; sourceTree = "<group>"; };
9A9AEB90243F7B5600FBD7D8 /* unicode_conversions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unicode_conversions.cpp; sourceTree = "<group>"; };
9A9AEB93243F7B5600FBD7D8 /* unicode_conversions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unicode_conversions.h; sourceTree = "<group>"; };
9A9AEB98243F7B7900FBD7D8 /* printf_lite-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "printf_lite-test.h"; sourceTree = "<group>"; };
@ -1442,6 +1444,7 @@
9AC77FAB24176C04005CDD5C /* cpp_foundation */ = {
isa = PBXGroup;
children = (
9A7AEDE6245963BF003AAD04 /* XToolsCommon.h */,
9A9AEB90243F7B5600FBD7D8 /* unicode_conversions.cpp */,
9A9AEB93243F7B5600FBD7D8 /* unicode_conversions.h */,
9AC77FB624176C04005CDD5C /* XArray.h */,
@ -1490,6 +1493,7 @@
9A105B7824483AE40006DE06 /* usbfix.h in Headers */,
9A28CD33241BC0DF00F3D247 /* strcmp_test.h in Headers */,
9AC7802124176C04005CDD5C /* boot.h in Headers */,
9A7AEDE7245963BF003AAD04 /* XToolsCommon.h in Headers */,
9AC7802F24176C04005CDD5C /* ati.h in Headers */,
9A105B6D24483AE40006DE06 /* stddef.h in Headers */,
9AC780B52417EE53005CDD5C /* global_test.h in Headers */,

View File

@ -41,6 +41,27 @@
9A28CD4B241F4CCE00F3D247 /* xcode_utf_fixed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD4A241F4CCE00F3D247 /* xcode_utf_fixed.cpp */; };
9A28CD4C241F4CCE00F3D247 /* xcode_utf_fixed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD4A241F4CCE00F3D247 /* xcode_utf_fixed.cpp */; };
9A28CD4D241F4CCE00F3D247 /* xcode_utf_fixed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD4A241F4CCE00F3D247 /* xcode_utf_fixed.cpp */; };
9A2A7C6C24576CCE00422263 /* LoadOptions_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4185AF2439E4D500BEAFB8 /* LoadOptions_test.cpp */; };
9A2A7C6D24576CCE00422263 /* XObjArray_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B08522402FE9B00E2B470 /* XObjArray_tests.cpp */; };
9A2A7C6E24576CCE00422263 /* abort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD1D241BB61B00F3D247 /* abort.cpp */; };
9A2A7C6F24576CCE00422263 /* XString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4FFA7C2451C8330050B38B /* XString.cpp */; };
9A2A7C7024576CCE00422263 /* XString_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4FFA802451C88D0050B38B /* XString_test.cpp */; };
9A2A7C7124576CCE00422263 /* strlen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD1E241BB61B00F3D247 /* strlen.cpp */; };
9A2A7C7224576CCE00422263 /* xcode_utf_fixed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD4A241F4CCE00F3D247 /* xcode_utf_fixed.cpp */; };
9A2A7C7324576CCE00422263 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A9223302402FD1000483CBA /* main.cpp */; };
9A2A7C7424576CCE00422263 /* strlen_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD15241BACBB00F3D247 /* strlen_test.cpp */; };
9A2A7C7524576CCE00422263 /* strcmp_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD06241B8DD400F3D247 /* strcmp_test.cpp */; };
9A2A7C7624576CCE00422263 /* strncmp_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD05241B8DD400F3D247 /* strncmp_test.cpp */; };
9A2A7C7724576CCE00422263 /* all_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B08512402FE9B00E2B470 /* all_tests.cpp */; };
9A2A7C7824576CCE00422263 /* unicode_conversions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A9AEB8C243F73CE00FBD7D8 /* unicode_conversions.cpp */; };
9A2A7C7924576CCE00422263 /* global_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B08642403144C00E2B470 /* global_test.cpp */; };
9A2A7C7A24576CCE00422263 /* printf_lite.c in Sources */ = {isa = PBXBuildFile; fileRef = 9ACAB116242623EE00BDB3CF /* printf_lite.c */; };
9A2A7C7B24576CCE00422263 /* XStringArray_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B084F2402FE9B00E2B470 /* XStringArray_test.cpp */; };
9A2A7C7C24576CCE00422263 /* strcmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A28CD0F241B9EF800F3D247 /* strcmp.cpp */; };
9A2A7C7D24576CCE00422263 /* XStringArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4185BE2439F73A00BEAFB8 /* XStringArray.cpp */; };
9A2A7C7E24576CCE00422263 /* XArray_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B08532402FE9B00E2B470 /* XArray_tests.cpp */; };
9A2A7C7F24576CCE00422263 /* printf_lite-test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AA045892425F94D000D6970 /* printf_lite-test.cpp */; };
9A2A7C8024576CCE00422263 /* Platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A0B085D240300E000E2B470 /* Platform.cpp */; };
9A4185B12439E4D600BEAFB8 /* LoadOptions_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4185AF2439E4D500BEAFB8 /* LoadOptions_test.cpp */; };
9A4185B22439E4D600BEAFB8 /* LoadOptions_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4185AF2439E4D500BEAFB8 /* LoadOptions_test.cpp */; };
9A4185B32439E4D600BEAFB8 /* LoadOptions_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4185AF2439E4D500BEAFB8 /* LoadOptions_test.cpp */; };
@ -82,6 +103,15 @@
);
runOnlyForDeploymentPostprocessing = 1;
};
9A2A7C8224576CCE00422263 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
9A57C22B2418B9A00029A39F /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -129,6 +159,7 @@
9A28CD1E241BB61B00F3D247 /* strlen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = strlen.cpp; sourceTree = "<group>"; };
9A28CD49241F437C00F3D247 /* xcode_utf_fixed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xcode_utf_fixed.h; sourceTree = "<group>"; };
9A28CD4A241F4CCE00F3D247 /* xcode_utf_fixed.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xcode_utf_fixed.cpp; sourceTree = "<group>"; };
9A2A7C8624576CCE00422263 /* cpp_tests UTF32 c++17 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "cpp_tests UTF32 c++17"; sourceTree = BUILT_PRODUCTS_DIR; };
9A4185AF2439E4D500BEAFB8 /* LoadOptions_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadOptions_test.cpp; sourceTree = "<group>"; };
9A4185B02439E4D600BEAFB8 /* LoadOptions_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadOptions_test.h; sourceTree = "<group>"; };
9A4185BE2439F73A00BEAFB8 /* XStringArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = XStringArray.cpp; sourceTree = "<group>"; };
@ -140,6 +171,7 @@
9A57C22F2418B9A00029A39F /* cpp_tests UTF16 unsigned char */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "cpp_tests UTF16 unsigned char"; sourceTree = BUILT_PRODUCTS_DIR; };
9A57C266241A799B0029A39F /* XString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XString.h; sourceTree = "<group>"; };
9A6BA73C2449977300BDA52C /* XStringAbstract.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XStringAbstract.h; sourceTree = "<group>"; };
9A7AEDE82459696C003AAD04 /* XToolsCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XToolsCommon.h; sourceTree = "<group>"; };
9A92232D2402FD1000483CBA /* cpp_tests UTF16 signed char */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "cpp_tests UTF16 signed char"; sourceTree = BUILT_PRODUCTS_DIR; };
9A9223302402FD1000483CBA /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
9A92234D2402FD9500483CBA /* Platform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
@ -178,6 +210,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
9A2A7C8124576CCE00422263 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
9A57C22A2418B9A00029A39F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -198,6 +237,7 @@
9A0B08432402FE9300E2B470 /* cpp_foundation */ = {
isa = PBXGroup;
children = (
9A7AEDE82459696C003AAD04 /* XToolsCommon.h */,
9A4FFA7C2451C8330050B38B /* XString.cpp */,
9A57C266241A799B0029A39F /* XString.h */,
9A6BA73C2449977300BDA52C /* XStringAbstract.h */,
@ -300,6 +340,7 @@
9A92232D2402FD1000483CBA /* cpp_tests UTF16 signed char */,
9A0B08862403B08400E2B470 /* cpp_tests UTF32 */,
9A57C22F2418B9A00029A39F /* cpp_tests UTF16 unsigned char */,
9A2A7C8624576CCE00422263 /* cpp_tests UTF32 c++17 */,
);
name = Products;
sourceTree = "<group>";
@ -364,6 +405,23 @@
productReference = 9A0B08862403B08400E2B470 /* cpp_tests UTF32 */;
productType = "com.apple.product-type.tool";
};
9A2A7C6A24576CCE00422263 /* cpp_tests UTF32 c++17 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9A2A7C8324576CCE00422263 /* Build configuration list for PBXNativeTarget "cpp_tests UTF32 c++17" */;
buildPhases = (
9A2A7C6B24576CCE00422263 /* Sources */,
9A2A7C8124576CCE00422263 /* Frameworks */,
9A2A7C8224576CCE00422263 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = "cpp_tests UTF32 c++17";
productName = cpp_tests;
productReference = 9A2A7C8624576CCE00422263 /* cpp_tests UTF32 c++17 */;
productType = "com.apple.product-type.tool";
};
9A57C2172418B9A00029A39F /* cpp_tests UTF16 unsigned char */ = {
isa = PBXNativeTarget;
buildConfigurationList = 9A57C22C2418B9A00029A39F /* Build configuration list for PBXNativeTarget "cpp_tests UTF16 unsigned char" */;
@ -427,6 +485,7 @@
9A92232C2402FD1000483CBA /* cpp_tests UTF16 signed char */,
9A0B08712403B08400E2B470 /* cpp_tests UTF32 */,
9A57C2172418B9A00029A39F /* cpp_tests UTF16 unsigned char */,
9A2A7C6A24576CCE00422263 /* cpp_tests UTF32 c++17 */,
);
};
/* End PBXProject section */
@ -460,6 +519,34 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
9A2A7C6B24576CCE00422263 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9A2A7C6C24576CCE00422263 /* LoadOptions_test.cpp in Sources */,
9A2A7C6D24576CCE00422263 /* XObjArray_tests.cpp in Sources */,
9A2A7C6E24576CCE00422263 /* abort.cpp in Sources */,
9A2A7C6F24576CCE00422263 /* XString.cpp in Sources */,
9A2A7C7024576CCE00422263 /* XString_test.cpp in Sources */,
9A2A7C7124576CCE00422263 /* strlen.cpp in Sources */,
9A2A7C7224576CCE00422263 /* xcode_utf_fixed.cpp in Sources */,
9A2A7C7324576CCE00422263 /* main.cpp in Sources */,
9A2A7C7424576CCE00422263 /* strlen_test.cpp in Sources */,
9A2A7C7524576CCE00422263 /* strcmp_test.cpp in Sources */,
9A2A7C7624576CCE00422263 /* strncmp_test.cpp in Sources */,
9A2A7C7724576CCE00422263 /* all_tests.cpp in Sources */,
9A2A7C7824576CCE00422263 /* unicode_conversions.cpp in Sources */,
9A2A7C7924576CCE00422263 /* global_test.cpp in Sources */,
9A2A7C7A24576CCE00422263 /* printf_lite.c in Sources */,
9A2A7C7B24576CCE00422263 /* XStringArray_test.cpp in Sources */,
9A2A7C7C24576CCE00422263 /* strcmp.cpp in Sources */,
9A2A7C7D24576CCE00422263 /* XStringArray.cpp in Sources */,
9A2A7C7E24576CCE00422263 /* XArray_tests.cpp in Sources */,
9A2A7C7F24576CCE00422263 /* printf_lite-test.cpp in Sources */,
9A2A7C8024576CCE00422263 /* Platform.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
9A57C2182418B9A00029A39F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -536,6 +623,25 @@
};
name = Release;
};
9A2A7C8424576CCE00422263 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
9A2A7C8524576CCE00422263 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
9A57C22D2418B9A00029A39F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -773,6 +879,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9A2A7C8324576CCE00422263 /* Build configuration list for PBXNativeTarget "cpp_tests UTF32 c++17" */ = {
isa = XCConfigurationList;
buildConfigurations = (
9A2A7C8424576CCE00422263 /* Debug */,
9A2A7C8524576CCE00422263 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
9A57C22C2418B9A00029A39F /* Build configuration list for PBXNativeTarget "cpp_tests UTF16 unsigned char" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -44,24 +44,28 @@ int printf(const char* format, ...)
const char* strerror(EFI_STATUS Status)
{
size_t size = stdio_static_buf.allocatedSize();
UINTN n = 0;
do {
stdio_static_buf.CheckSize(stdio_static_buf.length()+10);
n = AsciiSPrint(stdio_static_buf.dataSized(stdio_static_buf.allocatedSize()), stdio_static_buf.allocatedSize(), "%r", Status);
} while ( n > stdio_static_buf.allocatedSize() - 2 );
n = AsciiSPrint(stdio_static_buf.dataSized(stdio_static_buf.allocatedSize()), stdio_static_buf.allocatedSize(), "%r", Status);
while ( n > size - 2 )
{
size += 10;
n = AsciiSPrint(stdio_static_buf.dataSized(size), size, "%r", Status);
}
return stdio_static_buf.s();
}
//this function print guid in LittleEndian format while we need BigEndian as Apple do
const char* strguid(EFI_GUID* guid)
{
size_t size = stdio_static_buf.allocatedSize();
UINTN n = 0;
do {
stdio_static_buf.CheckSize(stdio_static_buf.length()+10);
n = AsciiSPrint(stdio_static_buf.dataSized(stdio_static_buf.allocatedSize()), stdio_static_buf.allocatedSize(), "%g", guid);
} while ( n > stdio_static_buf.allocatedSize() - 2 );
n = AsciiSPrint(stdio_static_buf.dataSized(size), size, "%g", guid);
while ( n > size - 2 )
{
size += 10;
n = AsciiSPrint(stdio_static_buf.dataSized(size), size, "%g", guid);
}
return stdio_static_buf.s();
}

View File

@ -20,50 +20,56 @@
#include "../../Include/Library/printf_lite.h"
//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
XString operator"" _XS ( const char* s, size_t len)
{
XString returnValue;
returnValue.takeValueFrom(s, len);
return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
}
XString16 operator"" _XS16 ( const char16_t* s, size_t len)
{
XString16 returnValue;
returnValue.takeValueFrom(s, len);
return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
}
XString32 operator"" _XS32 ( const char32_t* s, size_t len)
{
XString32 returnValue;
returnValue.takeValueFrom(s, len);
return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
}
XStringW operator"" _XSW ( const char* s, size_t len)
{
XStringW returnValue;
returnValue.takeValueFrom(s, len);
return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
}
XStringW operator"" _XSW ( const wchar_t* s, size_t len)
{
XStringW returnValue;
returnValue.takeValueFrom(s, len);
return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
}
//
//constexpr LString8 operator"" _XS ( const char* s, size_t len)
//{
//// LString8 returnValue;
//// returnValue.takeValueFromLiteral(s);
//// (void)len;
//// return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
// return LString8(s); // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
//}
//
//XString16 operator"" _XS16 ( const char16_t* s, size_t len)
//{
// XString16 returnValue;
// returnValue.takeValueFromLiteral(s);
// (void)len;
// return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
//}
//
//XString32 operator"" _XS32 ( const char32_t* s, size_t len)
//{
// XString32 returnValue;
// returnValue.takeValueFromLiteral(s);
// (void)len;
// return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
//}
//
//XStringW operator"" _XSW ( const wchar_t* s, size_t len)
//{
// XStringW returnValue;
// returnValue.takeValueFromLiteral(s);
// (void)len;
// return returnValue; // don't do "return returnValue.takeValueFrom(s, len)" because it break the return value optimization.
//}
const XString NullXString;
const XString16 NullXString16;
const XString32 NullXString32;
const XStringW NullXStringW;
//template<class O/*, enable_if(is_char(O))*/>
//XStringW LStringW::operator + (const O* p2) { XStringW s; s.strcat(this->s()); s.strcat(p2); return s; }
//
//template<>
//XStringW LStringW::operator + (const wchar_t* p2) { XStringW s; s.strcat(this->s()); s.strcat(p2); return s; }
XString SPrintf(const char* format, ...)
{
va_list va;
@ -71,7 +77,7 @@ XString SPrintf(const char* format, ...)
va_start (va, format);
str.vSPrintf(format, va);
va_end(va);
va_end(va);
return str;
}
@ -83,7 +89,7 @@ XStringW SWPrintf(const char* format, ...)
va_start (va, format);
str.vSWPrintf(format, va);
va_end(va);
va_end(va);
return str;
}
@ -97,21 +103,3 @@ XStringW SWPrintf(const char* format, ...)
// return ret;
//}
//
//
//XStringW CleanCtrl(const XStringW &S)
//{
// XStringW ReturnValue;
// UINTN i;
//
// for ( i=0 ; i<S.size() ; i+=1 ) {
//#if __WCHAR_MIN__ < 0
// if ( S.wc_str()[i] >=0 && S.wc_str()[i] < ' ' ) ReturnValue += 'x'; /* wchar_t are signed */
//#else
// if ( S.wc_str()[i] < ' ' ) ReturnValue += 'x'; /* wchar_t are unsigned */
//#endif
// else ReturnValue += S.wc_str()[i];
// }
// return ReturnValue;
//}

View File

@ -21,23 +21,33 @@
#define XString16GrowByDefault 16
#endif
//typedef XStringAbstract<char> XString;
//------------------------------------------------------------------------------------------------------------------
class XString;
class LString8 : public LString<char, XString>
{
public:
constexpr LString8() = delete;
constexpr LString8(const char* s) : LString<char, XString>(s) {};
// no assignement, no destructor
friend constexpr LString8 operator "" _XS ( const char* s, size_t) { return LString8(s); }
};
class XString : public XStringAbstract<char, XString>
{
public:
XString() : XStringAbstract<char, XString>() {};
XString(const XString& S) : XStringAbstract<char, XString>(S) {}
XString(const LString8& S) : XStringAbstract<char, XString>(S) { }
template<typename O, class OtherXStringClass>
XString(const XStringAbstract<O, OtherXStringClass> &S) : XStringAbstract<char, XString>(S) {}
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString(const OtherXStringClass& S) : XStringAbstract<char, XString>(S) {}
XString& operator=(const XString &S) { this->XStringAbstract<char, XString>::operator=(S); return *this; }
using XStringAbstract<char, XString>::operator =;
protected:
static void transmitSPrintf(const char* buf, unsigned int nbchar, void* context)
{
@ -57,7 +67,16 @@ public:
vSPrintf(format, va);
va_end(va);
}
};
//------------------------------------------------------------------------------------------------------------------
class XString16;
class LString16 : public LString<char16_t, XString16>
{
constexpr LString16(const char16_t* s) : LString<char16_t, XString16>(s) {};
friend constexpr LString16 operator "" _XS16 ( const char16_t* s, size_t) { return LString16(s); }
};
class XString16 : public XStringAbstract<char16_t, XString16>
@ -66,12 +85,24 @@ class XString16 : public XStringAbstract<char16_t, XString16>
XString16() : XStringAbstract<char16_t, XString16>() {};
XString16(const XString16& S) : XStringAbstract<char16_t, XString16>(S) {}
template<typename O, class OtherXStringClass>
XString16(const XStringAbstract<O, OtherXStringClass> &S) : XStringAbstract<char16_t, XString16>(S) {}
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString16(const OtherXStringClass& S) : XStringAbstract<char16_t, XString16>(S) {}
XString16& operator=(const XString16 &S) { this->XStringAbstract<char16_t, XString16>::operator=(S); return *this; }
using XStringAbstract<char16_t, XString16>::operator =;
// friend LString16 operator "" _XS16 ( const char16_t* s, size_t len);
};
//------------------------------------------------------------------------------------------------------------------
class XString32;
class LString32 : public LString<char32_t, XString32>
{
constexpr LString32(const char32_t* s) : LString<char32_t, XString32>(s) {};
friend constexpr LString32 operator "" _XS32 ( const char32_t* s, size_t) { return LString32(s); }
};
class XString32 : public XStringAbstract<char32_t, XString32>
@ -80,12 +111,25 @@ class XString32 : public XStringAbstract<char32_t, XString32>
XString32() : XStringAbstract<char32_t, XString32>() {};
XString32(const XString32& S) : XStringAbstract<char32_t, XString32>(S) {}
template<typename O, class OtherXStringClass>
XString32(const XStringAbstract<O, OtherXStringClass> &S) : XStringAbstract<char32_t, XString32>(S) {}
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString32(const OtherXStringClass& S) : XStringAbstract<char32_t, XString32>(S) {}
XString32& operator=(const XString32 &S) { this->XStringAbstract<char32_t, XString32>::operator=(S); return *this; }
using XStringAbstract<char32_t, XString32>::operator =;
// friend LString32 operator "" _XS32 ( const char32_t* s, size_t len);
};
//------------------------------------------------------------------------------------------------------------------
class XStringW;
class LStringW : public LString<wchar_t, XStringW>
{
public:
constexpr LStringW() = delete;
constexpr LStringW(const wchar_t* s) : LString<wchar_t, XStringW>(s) {};
friend constexpr LStringW operator "" _XSW ( const wchar_t* s, size_t) { return LStringW(s); }
};
class XStringW : public XStringAbstract<wchar_t, XStringW>
@ -94,8 +138,10 @@ class XStringW : public XStringAbstract<wchar_t, XStringW>
XStringW() : XStringAbstract<wchar_t, XStringW>() {};
XStringW(const XStringW& S) : XStringAbstract<wchar_t, XStringW>(S) {}
template<class OtherXStringClass>
template<class OtherXStringClass, enable_if( is___String(OtherXStringClass) && !is___LString(OtherXStringClass))> // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XStringW(const OtherXStringClass& S) : XStringAbstract<wchar_t, XStringW>(S) {}
XStringW(const LStringW& S) : XStringAbstract<wchar_t, XStringW>(S) { }
XStringW& operator=(const XStringW &S) { this->XStringAbstract<wchar_t, XStringW>::operator=(S); return *this; }
@ -122,14 +168,13 @@ public:
vSWPrintf(format, va);
va_end(va);
}
};
XString operator"" _XS ( const char* s, size_t len);
XString16 operator"" _XS16 ( const char16_t* s, size_t len);
XString32 operator"" _XS32 ( const char32_t* s, size_t len);
XStringW operator"" _XSW ( const char* s, size_t len);
XStringW operator"" _XSW ( const wchar_t* s, size_t len);
constexpr LString8 operator"" _XS ( const char* s, size_t len);
constexpr LString16 operator"" _XS16 ( const char16_t* s, size_t len);
constexpr LString32 operator"" _XS32 ( const char32_t* s, size_t len);
constexpr LStringW operator"" _XSW ( const wchar_t* s, size_t len);
extern const XString NullXString;
extern const XStringW NullXStringW;
@ -144,6 +189,5 @@ XStringW SWPrintf(const char* format, ...) __attribute__((__format__ (__printf__
//
//XStringAbstract SubString(const T *S, size_t pos, size_t count);
//XStringAbstract CleanCtrl(const XStringAbstract &S);
#endif

View File

@ -1,10 +1,27 @@
//*************************************************************************************************
//*************************************************************************************************
//
// XSTRING
//
//*************************************************************************************************
//*************************************************************************************************
/*
* Copyright (c) 2019 Jief Luce.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#if !defined(__XSTRINGABSTRACT_H__)
#define __XSTRINGABSTRACT_H__
@ -179,15 +196,13 @@ size_t XStringAbstract__rindexOf(const O* s, size_t Pos, const P* other, bool to
template<class T, class ThisXStringClass>
class XStringAbstractNoDtor
class __String
{
public:
// const SubType NullXString;
static T nullChar;
typedef T char_t;
typedef ThisXStringClass xs_t;
protected:
T *m_data;
size_t m_allocatedSize;
// convenience method. Did it this way to avoid #define in header. They can have an impact on other headers
size_t Xmin(size_t x1, size_t x2) const { if ( x1 < x2 ) return x1; return x2; }
@ -203,101 +218,29 @@ protected:
size_t offset = size_of_utf_string_len(m_data, (unsigned_type(IntegralType))pos); // If pos is too big, size_of_utf_string_len returns the end of the string
return m_data + offset;
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Init , Alloc
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
void Init(size_t aSize=0)
{
//DBG_XSTRING("Init aSize=%d\n", aSize);
// We don't allocate any memory at first. To not have to test all the time if m_data is null, we init it to an empty string
m_data = &nullChar;
m_allocatedSize = 0;
// if aSize == 0, nothing is done, because m_allocatedSize == aSize
CheckSize(aSize, 0);
}
public:
T *CheckSize(size_t nNewSize, size_t nGrowBy = XStringGrowByDefault) // nNewSize is in number of chars, NOT bytes
{
//DBG_XSTRING("CheckSize: m_size=%d, nNewSize=%d\n", m_size, nNewSize);
if ( m_allocatedSize < nNewSize )
{
nNewSize += nGrowBy;
if ( m_allocatedSize == 0 ) m_data = (T*)malloc( (nNewSize+1)*sizeof(T) );
else m_data = (T*)Xrealloc(m_data, (nNewSize+1)*sizeof(T), (m_allocatedSize+1)*sizeof(T));
if ( !m_data ) {
panic("XStringAbstractNoDtor<T>::CheckSize(%zu, %zu) : Xrealloc(%" PRIuPTR ", %lu, %zd) returned NULL. System halted\n", nNewSize, nGrowBy, uintptr_t(m_data), nNewSize*sizeof(T), m_allocatedSize*sizeof(T));
}
m_allocatedSize = nNewSize;
m_data[m_allocatedSize] = 0; // we allocated one more char (nNewSize+1). This \0 is an extra precaution. It's not for the normal null terminator. All string operation must considered that only m_allocatedSize bytes were allocated.
}
return m_data;
}
// void setSize(size_t newSize) // nNewSize is in number of chars, NOT bytes
// {
// //DBG_XSTRING("setLength(%d)\n", len);
// CheckSize(newSize);
// // if ( len >= size() ) {
// // DBG_XSTRING("XStringAbstractNoDtor<T>::setLength(size_t len) : len >= size() (%d != %d). System halted\n", len, size());
// // panic();
// // }
// m_data[newSize] = 0; // we may rewrite a 0 in nullChar, if no memory were allocated. That's ok.
// }
// T* memoryOffset(size_t i) {
//
// }
public:
constexpr XStringAbstractNoDtor() : m_data(&nullChar), m_allocatedSize(0) {}
constexpr __String(const T* s) : m_data((T*)s) {}
public:
// constexpr __String() : m_data(&nullChar) { }
constexpr __String(const __String&) = delete;
constexpr __String() = delete;
// ~XStringAbstractNoDtor()
// {
// //DBG_XSTRING("Destructor :%ls\n", data());
//// if ( m_allocatedSize > 0 ) free((void*)m_data);
// }
// no assignement, no destructor
template<typename IntegralType, enable_if(is_integral(IntegralType))>
T* data(IntegralType pos) const { return _data(pos); }
// template<typename IntegralType, typename XStringAbstract__enable_if<XStringAbstract__is_integral<IntegralType>::value, IntegralType>::type* = nullptr>
template<typename IntegralType, enable_if(is_integral(IntegralType))>
T* dataSized(IntegralType size)
{
if ( size<0 ) panic("T* dataSized() -> i < 0");
if ( (unsigned_type(IntegralType))size > MAX_XSIZE ) panic("T* dataSized() -> i > MAX_XSIZE");
CheckSize((size_t)size);
return _data(0);
}
//
// // Pos is counted in logical char but size is counted in physical char (char, char16_t, char32_t or wchar_t)
// template<typename IntegralType1, typename IntegralType2, enable_if(is_integral(IntegralType1) && is_integral(IntegralType2))>
// T* dataSized(IntegralType1 pos, IntegralType2 size)
// {
// if ( pos<0 ) panic("T* dataSized(xisize i, size_t sizeMin, size_t nGrowBy) -> i < 0");
// if ( size<0 ) panic("T* dataSized(xisize i, size_t sizeMin, size_t nGrowBy) -> i < 0");
// size_t offset = size_of_utf_string_len(m_data, (typename XStringAbstract__make_unsigned<IntegralType1>::type)pos); // If pos is too big, size_of_utf_string_len returns the end of the string
// CheckSize(offset + (typename XStringAbstract__make_unsigned<IntegralType2>::type)size);
// return _data(pos);
// }
T* forgetDataWithoutFreeing()
{
T* ret = m_data;
Init(0);
return ret;
}
size_t length() const { return length_of_utf_string(m_data); }
// size_t sizeZZ() const { return size_of_utf_string(m_data); }
size_t sizeInNativeChars() const { return size_of_utf_string(m_data); }
size_t sizeInBytes() const { return size_of_utf_string(m_data)*sizeof(T); }
size_t sizeInBytesIncludingTerminator() const { return (size_of_utf_string(m_data)+1)*sizeof(T); } // usefull for unit tests
size_t allocatedSize() const { return m_allocatedSize; }
const T* wc_str() const { return m_data; }
@ -306,7 +249,6 @@ public:
const T* data() const { return m_data; } // todo delete
/* Empty ? */
void setEmpty() { m_data[0] = 0; } // we may rewrite a 0 in nullChar if no memory were allocated (m_data == &nullChar). That's ok.
bool isEmpty() const { return m_data == nullptr || *m_data == 0; }
bool notEmpty() const { return !isEmpty(); }
@ -323,7 +265,7 @@ public:
char32_t char32At(IntegralType i) const
{
if (i < 0) {
panic("XStringAbstractNoDtor<T>::char32At(size_t i) : i < 0. System halted\n");
panic("__String<T>::char32At(size_t i) : i < 0. System halted\n");
}
size_t nb = 0;
const T *p = m_data;
@ -332,7 +274,7 @@ public:
p = get_char32_from_string(p, &char32);
if (!char32) {
if ( (unsigned_type(IntegralType))i == nb ) return 0; // no panic if we want to access the null terminator
panic("XStringAbstractNoDtor::char32At(size_t i) : i >= length(). System halted\n");
panic("__String::char32At(size_t i) : i >= length(). System halted\n");
}
nb += 1;
} while (nb <= (unsigned_type(IntegralType))i);
@ -353,137 +295,21 @@ public:
char32_t lastChar() const { if ( length() > 0 ) return char32At(length()-1); else return 0; }
//--------------------------------------------------------------------- strcat, strcpy, operator =
/* strcpy char */
template<typename O, enable_if(is_char(O))>
void strcpy(O otherChar)
{
if ( otherChar != 0) {
size_t newSize = utf_size_of_utf_string_len(m_data, &otherChar, 1);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data, m_allocatedSize, &otherChar, 1);
m_data[newSize] = 0;
}else{
setEmpty();
}
}
/* strcpy */
template<typename O>
void strcpy(const O* other)
{
if ( other && *other ) {
size_t newSize = utf_size_of_utf_string(m_data, other);
CheckSize(newSize+1, 0);
utf_string_from_utf_string(m_data, m_allocatedSize, other);
m_data[newSize] = 0;
}else{
setEmpty();
}
}
/* strncpy */
template<typename O>
void strncpy(const O* other, size_t other_len)
{
if ( other && *other && other_len > 0 ) {
size_t newSize = utf_size_of_utf_string_len(m_data, other, other_len);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data, m_allocatedSize, other, other_len);
m_data[newSize] = 0;
}else{
setEmpty();
}
}
/* strcat char */
template<typename O, enable_if(is_char(O))>
void strcat(O otherChar)
{
if ( otherChar ) {
size_t currentSize = size_of_utf_string(m_data);
size_t newSize = currentSize + utf_size_of_utf_string_len(m_data, &otherChar, 1);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data+currentSize, m_allocatedSize, &otherChar, 1);
m_data[newSize] = 0;
}else{
// nothing to do
}
}
/* strcat */
template<typename O>
void strcat(const O* other)
{
if ( other && *other ) {
size_t currentSize = size_of_utf_string(m_data); // size is number of T, not in bytes
size_t newSize = currentSize + utf_size_of_utf_string(m_data, other); // size is number of T, not in bytes
CheckSize(newSize+1, 0);
utf_string_from_utf_string(m_data+currentSize, m_allocatedSize-currentSize, other);
m_data[newSize] = 0;
}else{
// nothing to do
}
}
/* strncat */
template<typename O>
void strncat(const O* other, size_t other_len)
{
if ( other && *other && other_len > 0 ) {
size_t currentSize = size_of_utf_string(m_data);
size_t newSize = currentSize + utf_size_of_utf_string_len(m_data, other, other_len);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data+currentSize, m_allocatedSize, other, other_len);
m_data[newSize] = 0;
}else{
// nothing to do
}
}
/* takeValueFrom */
template<typename O, class OtherXStringClass>
ThisXStringClass& takeValueFrom(const XStringAbstractNoDtor<O, OtherXStringClass>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& takeValueFrom(const O* S) { strcpy(S); return *((ThisXStringClass*)this); }
template<typename O, class OtherXStringClass>
ThisXStringClass& takeValueFrom(const XStringAbstractNoDtor<O, OtherXStringClass>& S, size_t len) { strncpy(S.data(0), len); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& takeValueFrom(const O* S, size_t len) { strncpy(S, len); return *((ThisXStringClass*)this); }
/* copy ctor */
XStringAbstractNoDtor<T, ThisXStringClass>(const XStringAbstractNoDtor<T, ThisXStringClass> &S) { Init(0); takeValueFrom(S); }
/* ctor */
template<typename O, class OtherXStringClass>
explicit XStringAbstractNoDtor<T, ThisXStringClass>(const XStringAbstractNoDtor<O, OtherXStringClass>& S) { Init(0); takeValueFrom(S); }
// template<typename O>
// explicit XStringAbstractNoDtor<T, ThisXStringClass>(const O* S) { Init(0); takeValueFrom(S); }
// /* copy ctor */
// __String<T, ThisXStringClass>(const __String<T, ThisXStringClass> &S) { Init(0); takeValueFrom(S); }
// /* ctor */
// template<typename O, class OtherXStringClass>
// explicit __String<T, ThisXStringClass>(const __String<O, OtherXStringClass>& S) { Init(0); takeValueFrom(S); }
//// template<typename O>
//// explicit __String<T, ThisXStringClass>(const O* S) { Init(0); takeValueFrom(S); }
/* Copy Assign */ // Only other XString, no litteral at the moment.
XStringAbstractNoDtor<T, ThisXStringClass>& operator =(const XStringAbstractNoDtor<T, ThisXStringClass>& S) { strcpy(S.s()); return *this; }
/* Assign */
template<typename O, class OtherXStringClass>
ThisXStringClass& operator =(const XStringAbstractNoDtor<O, OtherXStringClass>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); }
// template<class O>
// ThisXStringClass& operator =(const O* S) { strcpy(S); return *this; }
/* += */
template<typename O, class OtherXStringClass>
ThisXStringClass& operator += (const XStringAbstractNoDtor<O, OtherXStringClass>& S) { strcat(S.s()); return *((ThisXStringClass*)this); }
template<typename O, enable_if(is_char(O))>
ThisXStringClass& operator += (O S) { strcat(S); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& operator += (const O* S) { strcat(S); return *((ThisXStringClass*)this); }
template<typename O, class OtherXStringClass>
ThisXStringClass operator + (const XStringAbstractNoDtor<O, OtherXStringClass>& p2) const { ThisXStringClass s; s=*this; s+=p2; return s; }
template<typename O, enable_if(is_char(O))>
ThisXStringClass operator + (O p1) const { ThisXStringClass s; s=*this; s.strcat(p1); return s; }
template<typename O>
ThisXStringClass operator + (const O* p2) const { ThisXStringClass s; s=*this; s+=p2; return s; }
template<typename O, enable_if(is_char(O))>
friend ThisXStringClass operator + (O p1, const ThisXStringClass& p2) { ThisXStringClass s; s.strcat(p1); s.strcat(p2.s()); return s; }
template<typename O>
friend ThisXStringClass operator + (const O *p1, const ThisXStringClass& p2) { ThisXStringClass s; s.strcat(p1); s.strcat(p2.s()); return s; }
// __String<T, ThisXStringClass>& operator =(const __String<T, ThisXStringClass>& S) { strcpy(S.s()); return *this; }
// /* Assign */
// template<typename O, class OtherXStringClass>
// ThisXStringClass& operator =(const __String<O, OtherXStringClass>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); }
//// template<class O>
//// ThisXStringClass& operator =(const O* S) { strcpy(S); return *this; }
//--------------------------------------------------------------------- indexOf, rindexOf, contains, subString
@ -496,7 +322,7 @@ public:
template<typename O>
size_t indexOf(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(m_data, Pos, S, false); }
template<typename O, class OtherXStringClass>
size_t indexOf(const XStringAbstractNoDtor<O, OtherXStringClass>& S, size_t Pos = 0) const { return indexOf(S.s(), Pos); }
size_t indexOf(const __String<O, OtherXStringClass>& S, size_t Pos = 0) const { return indexOf(S.s(), Pos); }
/* IC */
size_t indexOfIC(char32_t char32Searched, size_t Pos = 0) const
{
@ -506,7 +332,7 @@ public:
template<typename O>
size_t indexOfIC(const O* S, size_t Pos = 0) const { return XStringAbstract__indexOf(m_data, Pos, S, true); }
template<typename O, class OtherXStringClass>
size_t indexOfIC(const XStringAbstractNoDtor<O, OtherXStringClass>& S, size_t Pos = 0) const { return indexOfIC(S.s(), Pos); }
size_t indexOfIC(const __String<O, OtherXStringClass>& S, size_t Pos = 0) const { return indexOfIC(S.s(), Pos); }
/* rindexOf */
@ -518,7 +344,7 @@ public:
template<typename O>
size_t rindexOf(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(m_data, Pos, S, false); }
template<typename O, class OtherXStringClass>
size_t rindexOf(const XStringAbstractNoDtor<O, OtherXStringClass>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); }
size_t rindexOf(const __String<O, OtherXStringClass>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); }
/* IC */
size_t rindexOfIC(const char32_t char32Searched, size_t Pos = MAX_XSIZE-1) const
{
@ -528,14 +354,14 @@ public:
template<typename O>
size_t rindexOfIC(const O* S, size_t Pos = MAX_XSIZE-1) const { return XStringAbstract__rindexOf(m_data, Pos, S, true); }
template<typename O, class OtherXStringClass>
size_t rindexOfIC(const XStringAbstractNoDtor<O, OtherXStringClass>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); }
size_t rindexOfIC(const __String<O, OtherXStringClass>& S, size_t Pos = MAX_XSIZE-1) const { return rindexOf(S.s(), Pos); }
template<typename O, class OtherXStringClass>
bool contains(const XStringAbstractNoDtor<O, OtherXStringClass>& S) const { return indexOf(S) != MAX_XSIZE; }
bool contains(const __String<O, OtherXStringClass>& S) const { return indexOf(S) != MAX_XSIZE; }
template<typename O>
bool contains(const O* S) const { return indexOf(S) != MAX_XSIZE; }
template<typename O, class OtherXStringClass>
size_t containsIC(const XStringAbstractNoDtor<O, OtherXStringClass>& S) const { return indexOfIC(S) != MAX_XSIZE; }
size_t containsIC(const __String<O, OtherXStringClass>& S) const { return indexOfIC(S) != MAX_XSIZE; }
template<typename O>
size_t containsIC(const O* S) const { return indexOfIC(S) != MAX_XSIZE; }
@ -558,11 +384,11 @@ public:
}
template<typename O, class OtherXStringClass>
bool startWith(const XStringAbstractNoDtor<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWith(m_data, otherS.m_data, false); }
bool startWith(const __String<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWith(m_data, otherS.m_data, false); }
template<typename O>
bool startWith(const O* other) const { return XStringAbstract__startWith(m_data, other, false); }
template<typename O, class OtherXStringClass>
bool startWithIC(const XStringAbstractNoDtor<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWith(m_data, otherS.m_data, true); }
bool startWithIC(const __String<O, OtherXStringClass>& otherS) const { return XStringAbstract__startWith(m_data, otherS.m_data, true); }
template<typename O>
bool startWithIC(const O* other) const { return XStringAbstract__startWith(m_data, other, true); }
@ -636,7 +462,7 @@ public:
// }
// }
//}
// void insert(const XStringAbstractNoDtor<T, ThisXStringClass>& Str, size_t pos);
// void insert(const __String<T, ThisXStringClass>& Str, size_t pos);
//{
// if ( pos < size() ) {
// CheckSize(size()+Str.size());
@ -693,10 +519,10 @@ public:
// p += 1;
// }
// }
// XStringAbstractNoDtor SubStringReplace(T c1, T c2);
// __String SubStringReplace(T c1, T c2);
//{
// T* p;
// XStringAbstractNoDtor Result;
// __String Result;
//
// p = s();
// while ( *p ) {
@ -717,12 +543,12 @@ public:
// int Compare(const wchar_t* S) const { return ::Compare<T, wchar_t>(m_data, S); };
//
template<typename O, class OtherXStringClass>
bool equal(const XStringAbstractNoDtor<O, OtherXStringClass>& S) const { return XStringAbstract__compare(m_data, S.s(), false) == 0; }
bool equal(const __String<O, OtherXStringClass>& S) const { return XStringAbstract__compare(m_data, S.s(), false) == 0; }
template<typename O>
bool equal(const O* S) const { return XStringAbstract__compare(m_data, S, false) == 0; }
template<typename O, class OtherXStringClass>
bool equalIC(const XStringAbstractNoDtor<O, OtherXStringClass>& S) const { return XStringAbstract__compare(m_data, S.s(), true) == 0; }
bool equalIC(const __String<O, OtherXStringClass>& S) const { return XStringAbstract__compare(m_data, S.s(), true) == 0; }
template<typename O>
bool equalIC(const O* S) const { return XStringAbstract__compare(m_data, S, true) == 0; }
@ -731,42 +557,42 @@ public:
public:
// == operator
template<typename O, class OtherXStringClass>
bool operator == (const XStringAbstractNoDtor<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) == 0; }
bool operator == (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) == 0; }
// template<typename O>
// bool operator == (const O* s2) const { return (*this).strcmp(s2) == 0; }
// template<typename O>
// friend bool operator == (const O* s1, ThisXStringClass& s2) { return s2.strcmp(s1) == 0; }
template<typename O, class OtherXStringClass>
bool operator != (const XStringAbstractNoDtor<O, OtherXStringClass>& s2) const { return !(*this == s2); }
bool operator != (const __String<O, OtherXStringClass>& s2) const { return !(*this == s2); }
// template<typename O>
// bool operator != (const O* s2) const { return !(*this == s2); }
// template<typename O>
// friend bool operator != (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) != 0; }
template<typename O, class OtherXStringClass>
bool operator < (const XStringAbstractNoDtor<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) < 0; }
bool operator < (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) < 0; }
// template<typename O>
// bool operator < (const O* s2) const { return (*this).strcmp(s2) < 0; }
// template<typename O>
// friend bool operator < (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) > 0; }
template<typename O, class OtherXStringClass>
bool operator > (const XStringAbstractNoDtor<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) > 0; }
bool operator > (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) > 0; }
// template<typename O>
// bool operator > (const O* s2) const { return (*this).strcmp(s2) > 0; }
// template<typename O>
// friend bool operator > (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) < 0; }
template<typename O, class OtherXStringClass>
bool operator <= (const XStringAbstractNoDtor<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) <= 0; }
bool operator <= (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) <= 0; }
// template<typename O>
// bool operator <= (const O* s2) const { return (*this).strcmp(s2) <= 0; }
// template<typename O>
// friend bool operator <= (const O* s1, const ThisXStringClass& s2) { return s2.strcmp(s1) >= 0; }
template<typename O, class OtherXStringClass>
bool operator >= (const XStringAbstractNoDtor<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) >= 0; }
bool operator >= (const __String<O, OtherXStringClass>& s2) const { return (*this).strcmp(s2.s()) >= 0; }
// template<typename O>
// bool operator >= (const O* s2) const { return (*this).strcmp(s2) >= 0; }
// template<typename O>
@ -775,44 +601,368 @@ public:
};
template<class T, class ThisXStringClass>
T XStringAbstractNoDtor<T, ThisXStringClass>::nullChar = 0;
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
template<class T, class ThisXStringClass>
class XStringAbstract : public XStringAbstractNoDtor<T, ThisXStringClass>
class LString : public __String<T, ThisXStringClass>
{
public:
XStringAbstract() : XStringAbstractNoDtor<T, ThisXStringClass>() {}
XStringAbstract(const XStringAbstract& S) : XStringAbstractNoDtor<T, ThisXStringClass>(S) {}
public:
protected:
constexpr LString(const T* s) : __String<T, ThisXStringClass>(s) {};
constexpr LString() = delete;
constexpr LString(const LString& L) : __String<T, ThisXStringClass>(L.m_data) {};
template<typename O, class OtherXStringClass>
XStringAbstract(const XStringAbstract<O, OtherXStringClass> &S) : XStringAbstractNoDtor<T, ThisXStringClass>(S) {}
//
XStringAbstract& operator=(const XStringAbstract &S) { this->XStringAbstractNoDtor<T, ThisXStringClass>::operator=(S); return *this; }
using XStringAbstractNoDtor<T, ThisXStringClass>::operator =;
// no assignement, no destructor
~XStringAbstract()
{
//DBG_XSTRING("Destructor :%ls\n", data());
if ( XStringAbstractNoDtor<T, ThisXStringClass>::m_allocatedSize > 0 ) free((void*)XStringAbstractNoDtor<T, ThisXStringClass>::m_data);
}
};
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#define m_data __String<T, ThisXStringClass>::m_data
template<class T, class ThisXStringClass>
class XStringAbstract : public __String<T, ThisXStringClass>
{
static T nullChar;
protected:
size_t m_allocatedSize;
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Init , Alloc
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//
// void Init(size_t aSize=0)
// {
// //DBG_XSTRING("Init aSize=%d\n", aSize);
// // We don't allocate any memory at first. To not have to test all the time if m_data is null, we init it to an empty string
// m_data = &nullChar;
// m_allocatedSize = 0;
// // if aSize == 0, nothing is done, because m_allocatedSize == aSize
// CheckSize(aSize, 0);
// }
/*
* nNewSize doesn't include null terminator. Alloc(0) will allocate 1 char.
* NOTE : m_allocatedSize WILL include the the null terminator. Alloc(0) makes m_allocatedSize == 1
*/
void Alloc(size_t nNewSize)
{
if ( m_allocatedSize == 0 ) m_data = (T*)malloc( (nNewSize+1)*sizeof(T) );
else m_data = (T*)Xrealloc(m_data, (nNewSize+1)*sizeof(T), (m_allocatedSize+1)*sizeof(T));
if ( !m_data ) {
panic("XStringAbstract::Alloc(%zu) : Xrealloc(%" PRIuPTR ", %lu, %zd) returned NULL. System halted\n", nNewSize, uintptr_t(m_data), (nNewSize+1)*sizeof(T), (m_allocatedSize+1)*sizeof(T));
}
m_allocatedSize = nNewSize;
}
// public:
T *CheckSize(size_t nNewSize, size_t nGrowBy = XStringGrowByDefault) // nNewSize is in number of chars, NOT bytes
{
//DBG_XSTRING("CheckSize: m_size=%d, nNewSize=%d\n", m_size, nNewSize);
if ( m_allocatedSize < nNewSize )
{
nNewSize += nGrowBy;
if ( m_allocatedSize == 0 ) { //if ( *m_data ) {
size_t len = __String<T, ThisXStringClass>::length();
if ( nNewSize < len ) nNewSize = len;
T* m_dataSav = m_data;
m_data = NULL;
Alloc(nNewSize);
utf_string_from_utf_string(m_data, m_allocatedSize, m_dataSav);
}else{
Alloc(nNewSize);
}
// m_data[m_allocatedSize] = 0; // we allocated one more char (nNewSize+1). This \0 is an extra precaution. It's not for the normal null terminator. All string operation must considered that only m_allocatedSize bytes were allocated.
}
return m_data;
}
// void setSize(size_t newSize) // nNewSize is in number of chars, NOT bytes
// {
// //DBG_XSTRING("setLength(%d)\n", len);
// CheckSize(newSize);
// // if ( len >= size() ) {
// // DBG_XSTRING("__String<T>::setLength(size_t len) : len >= size() (%d != %d). System halted\n", len, size());
// // panic();
// // }
// m_data[newSize] = 0; // we may rewrite a 0 in nullChar, if no memory were allocated. That's ok.
// }
public:
/* default ctor */
XStringAbstract() : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0) {}
/* copy ctor */
XStringAbstract(const XStringAbstract& S) : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0)
{
if ( S.m_data && !S.m_allocatedSize ) {
m_data = S.m_data;
}else{
takeValueFrom(S);
}
}
~XStringAbstract()
{
//DBG_XSTRING("Destructor :%ls\n", data());
if ( m_allocatedSize > 0 ) free((void*)m_data);
}
/* ctor */
template<class OtherLStringClass>
explicit XStringAbstract(const LString<T, OtherLStringClass>& S) : __String<T, ThisXStringClass>(S.s()), m_allocatedSize(0) {}
template<typename O, class OtherXStringClass>
explicit XStringAbstract<T, ThisXStringClass>(const XStringAbstract<O, OtherXStringClass>& S) : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0) { takeValueFrom(S); }
template<typename O, class OtherXStringClass>
explicit XStringAbstract<T, ThisXStringClass>(const LString<O, OtherXStringClass>& S) : __String<T, ThisXStringClass>(&nullChar), m_allocatedSize(0) { takeValueFrom(S); }
// TEMPORARILY DISABLED
// template<typename O>
// explicit __String<T, ThisXStringClass>(const O* S) { Init(0); takeValueFrom(S); }
//
/* Copy Assign */ // Only other XString, no litteral at the moment.
XStringAbstract& operator=(const XStringAbstract &S) { takeValueFrom(S); return *this; }
/* Assign */
template<typename O, class OtherXStringClass>
ThisXStringClass& operator =(const __String<O, OtherXStringClass>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); }
// TEMPORARILY DISABLED
// template<class O>
// ThisXStringClass& operator =(const O* S) { strcpy(S); return *this; }
protected:
ThisXStringClass& takeValueFromLiteral (const T* s)
{
if ( m_allocatedSize > 0 ) panic("XStringAbstract::takeValueFromLiteral -> m_allocatedSize > 0");
m_data = (T*)s;
return *((ThisXStringClass*)this);
}
public:
size_t allocatedSize() const { return m_allocatedSize; }
void setEmpty()
{
if ( m_allocatedSize <= 0 ) m_data = &nullChar;
else m_data[0] = 0;
}
template<typename IntegralType, enable_if(is_integral(IntegralType))>
T* dataSized(IntegralType size)
{
if ( size<0 ) panic("T* dataSized() -> i < 0");
if ( (unsigned_type(IntegralType))size > MAX_XSIZE ) panic("T* dataSized() -> i > MAX_XSIZE");
CheckSize((size_t)size);
return __String<T, ThisXStringClass>::_data(0);
}
//
// // Pos is counted in logical char but size is counted in physical char (char, char16_t, char32_t or wchar_t)
// template<typename IntegralType1, typename IntegralType2, enable_if(is_integral(IntegralType1) && is_integral(IntegralType2))>
// T* dataSized(IntegralType1 pos, IntegralType2 size)
// {
// if ( pos<0 ) panic("T* dataSized(xisize i, size_t sizeMin, size_t nGrowBy) -> i < 0");
// if ( size<0 ) panic("T* dataSized(xisize i, size_t sizeMin, size_t nGrowBy) -> i < 0");
// size_t offset = size_of_utf_string_len(m_data, (typename _xtools__make_unsigned<IntegralType1>::type)pos); // If pos is too big, size_of_utf_string_len returns the end of the string
// CheckSize(offset + (typename _xtools__make_unsigned<IntegralType2>::type)size);
// return _data(pos);
// }
T* forgetDataWithoutFreeing()
{
T* ret = m_data;
m_data = &nullChar;
m_allocatedSize = 0;
return ret;
}
//--------------------------------------------------------------------- strcat, strcpy, operator =
/* strcpy char */
template<typename O, enable_if(is_char(O))>
void strcpy(O otherChar)
{
if ( otherChar != 0) {
size_t newSize = utf_size_of_utf_string_len(m_data, &otherChar, 1);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data, m_allocatedSize, &otherChar, 1);
m_data[newSize] = 0;
}else{
setEmpty();
}
}
/* strcpy */
template<typename O>
void strcpy(const O* other)
{
if ( other && *other ) {
size_t newSize = utf_size_of_utf_string(m_data, other);
CheckSize(newSize+1, 0);
utf_string_from_utf_string(m_data, m_allocatedSize, other);
m_data[newSize] = 0;
}else{
setEmpty();
}
}
/* strncpy */
template<typename O>
void strncpy(const O* other, size_t other_len)
{
if ( other && *other && other_len > 0 ) {
size_t newSize = utf_size_of_utf_string_len(m_data, other, other_len);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data, m_allocatedSize, other, other_len);
m_data[newSize] = 0;
}else{
setEmpty();
}
}
/* strcat char */
template<typename O, enable_if(is_char(O))>
void strcat(O otherChar)
{
if ( otherChar ) {
size_t currentSize = size_of_utf_string(m_data);
size_t newSize = currentSize + utf_size_of_utf_string_len(m_data, &otherChar, 1);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data+currentSize, m_allocatedSize, &otherChar, 1);
m_data[newSize] = 0;
}else{
// nothing to do
}
}
/* strcat char* */
template<typename O>
void strcat(const O* other)
{
if ( other && *other ) {
size_t currentSize = size_of_utf_string(m_data); // size is number of T, not in bytes
size_t newSize = currentSize + utf_size_of_utf_string(m_data, other); // size is number of T, not in bytes
CheckSize(newSize+1, 0);
utf_string_from_utf_string(m_data+currentSize, m_allocatedSize-currentSize, other);
m_data[newSize] = 0;
}else{
// nothing to do
}
}
/* strcat __String */
template<typename OtherCharType, class OtherXStringClass>
void strcat(const __String<OtherCharType, OtherXStringClass>& other)
{
size_t currentSize = size_of_utf_string(m_data); // size is number of T, not in bytes
size_t newSize = currentSize + utf_size_of_utf_string(m_data, other.s()); // size is number of T, not in bytes
CheckSize(newSize+1, 0);
utf_string_from_utf_string(m_data+currentSize, m_allocatedSize-currentSize, other.s());
m_data[newSize] = 0;
}
/* strncat */
template<typename O>
void strncat(const O* other, size_t other_len)
{
if ( other && *other && other_len > 0 ) {
size_t currentSize = size_of_utf_string(m_data);
size_t newSize = currentSize + utf_size_of_utf_string_len(m_data, other, other_len);
CheckSize(newSize+1, 0);
utf_string_from_utf_string_len(m_data+currentSize, m_allocatedSize, other, other_len);
m_data[newSize] = 0;
}else{
// nothing to do
}
}
/* takeValueFrom */
template<typename O, class OtherXStringClass>
ThisXStringClass& takeValueFrom(const __String<O, OtherXStringClass>& S) { strcpy(S.s()); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& takeValueFrom(const O* S) { strcpy(S); return *((ThisXStringClass*)this); }
template<typename O, class OtherXStringClass>
ThisXStringClass& takeValueFrom(const __String<O, OtherXStringClass>& S, size_t len) { strncpy(S.data(0), len); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& takeValueFrom(const O* S, size_t len) { strncpy(S, len); return *((ThisXStringClass*)this); }
/* += */
template<typename O, class OtherXStringClass>
ThisXStringClass& operator += (const __String<O, OtherXStringClass>& S) { strcat(S.s()); return *((ThisXStringClass*)this); }
template<typename O, enable_if(is_char(O))>
ThisXStringClass& operator += (O S) { strcat(S); return *((ThisXStringClass*)this); }
template<typename O>
ThisXStringClass& operator += (const O* S) { strcat(S); return *((ThisXStringClass*)this); }
};
template<class T, class ThisXStringClass>
T XStringAbstract<T, ThisXStringClass>::nullChar = 0;
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
///* __String + char32_t */
//template<typename CharType1, class XStringClass1>
//XStringClass1 operator + (const __String<CharType1, XStringClass1>& p1, char32_t p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* __String + __String */
//template<typename CharType1, class XStringClass1, typename CharType2, class XStringClass2>
//XStringClass1 operator + (const __String<CharType1, XStringClass1>& p1, const __String<CharType2, XStringClass2>& p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* char* + __String */
//template<typename CharType1, typename CharType2, class XStringClass2>
//XStringClass2 operator + (const CharType1* p1, const __String<CharType2, XStringClass2>& p2) { XStringClass2 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//
///* __String + char* */
//template<typename T1, class XStringClass1, typename CharType2>
//XStringClass1 operator + (const __String<T1, XStringClass1>& p1, const CharType2* p2) { XStringClass1 s; s.takeValueFrom(p1); s.strcat(p2); return s; }
template <typename Base> _xtools__true_type is_base_of_test_func( Base* );
template <typename Base> _xtools__false_type is_base_of_test_func( void* );
template <typename B, typename D>
auto test_pre_is_base_of(int) -> decltype(is_base_of_test_func<B>(static_cast<D*>(nullptr)));
template< class, class = _xtools__void_t<>, class = _xtools__void_t<> >
struct __string_type { typedef void type; };
template< typename T >
struct __string_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef __String<typename T::char_t, typename T::xs_t> type; };
#define is___String_t(x) decltype(test_pre_is_base_of< typename __string_type<x>::type , x>(0))
#define is___String(x) is___String_t(x)::value
template< class, class = _xtools__void_t<>, class = _xtools__void_t<> >
struct __lstring_type { typedef void type; };
template< typename T >
struct __lstring_type<T, _xtools__void_t<typename T::xs_t>, _xtools__void_t<typename T::char_t>> { typedef LString<typename T::char_t, typename T::xs_t> type; };
#define is___LString_t(x) decltype(test_pre_is_base_of< typename __lstring_type<x>::type , x>(0))
#define is___LString(x) is___LString_t(x)::value
/* __string_class_or<T1, T2>::type is T1 is T1 is a subclass of __String. If T1 is not a subclass of __String, returns T2 if it's a subclass of __String */
template <typename T1, typename T2, typename Tdummy=void> struct __string_class_or;
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && !is___String(T2))> { /*typedef double type;*/ };
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(is___String(T1))> { typedef typename T1::xs_t type; };
template <typename T1, typename T2>
struct __string_class_or<T1, T2, enable_if_t(!is___String(T1) && is___String(T2))> { typedef typename T2::xs_t type; };
//------------------------------------------------------- + operator
template<typename T1, typename T2, enable_if( is___String(T1) || is___String(T2) )>
typename __string_class_or<T1, T2>::type operator + (T1 p1, T2 p2) { typename __string_class_or<T1, T2>::type s; s.takeValueFrom(p1); s.strcat(p2); return s; }
//-------------------------------------------------------
#undef DBG_XSTRING
#undef asciiToLower
#undef m_data
#endif // __XSTRINGABSTRACT_H__

View File

@ -33,7 +33,7 @@ class XStringArray_/* : public XStringArraySuper*/
bool isEmpty() const { return this->size() == 0 ; }
bool notEmpty() const { return this->size() > 0 ; }
// #define enable_if XStringAbstract__enable_if_t
// #define enable_if _xtools_enable_if_t
/* [] */
template<typename IntegralType, enable_if(is_integral(IntegralType))>
const XStringClass& operator [](IntegralType i) const { return array[i]; }
@ -46,8 +46,8 @@ class XStringArray_/* : public XStringArraySuper*/
// const XStringClass& dbg(size_t i) const { return array[i]; }
XStringClass ConcatAll(const XStringClass& Separator = ", "_XS, const XStringClass& Prefix = NullXString, const XStringClass& Suffix = NullXString) const
template<class XStringClass1, class XStringClass2, class XStringClass3, enable_if(is___String(XStringClass1) && is___String(XStringClass2) && is___String(XStringClass3))>
XStringClass ConcatAll(const XStringClass1& Separator, const XStringClass2& Prefix, const XStringClass3& Suffix) const
{
xsize i;
XStringClass s;
@ -64,6 +64,17 @@ class XStringArray_/* : public XStringArraySuper*/
return s;
}
XStringClass ConcatAll() const
{
return ConcatAll(", "_XS, NullXString, NullXString);
}
template<class XStringClass1, enable_if(is___String(XStringClass1))>
XStringClass ConcatAll(const XStringClass1& Separator) const
{
return ConcatAll(Separator, NullXString, NullXString);
}
template<class OtherXStringArrayClass>
bool Equal(const OtherXStringArrayClass &aStrings) const
@ -310,7 +321,7 @@ XStringArrayClass Split(const CharType1* S, const CharType2* Separator)
// return Split<XStringArrayClass>(SS, XSeparator);
};
template<class XStringArrayClass, class XStringClass1, class XStringClass2, enable_if(!is_char(XStringClass1) && !is_char_ptr(XStringClass1) && !is_char(XStringClass2))>
template<class XStringArrayClass, class XStringClass1, class XStringClass2, enable_if(is___String(XStringClass1) && is___String(XStringClass2))>
XStringArrayClass Split(const XStringClass1& S, const XStringClass2& Separator)
{
return Split<XStringArrayClass>(S.s(), Separator.s());

View File

@ -10,80 +10,61 @@
#define XToolsCommon_h
struct XStringAbstract__false_type {
struct _xtools__false_type {
static constexpr bool value = false;
bool v() const { return false; }
};
struct XStringAbstract__true_type {
struct _xtools__true_type {
static constexpr bool value = true;
bool v() const { return true; }
};
/* make unsigned */
template <class _Tp>
struct XStringAbstract__make_unsigned {};
struct _xtools__make_unsigned {};
template <> struct XStringAbstract__make_unsigned< char> {typedef unsigned char type;};
template <> struct XStringAbstract__make_unsigned< signed char> {typedef unsigned char type;};
template <> struct XStringAbstract__make_unsigned<unsigned char> {typedef unsigned char type;};
template <> struct XStringAbstract__make_unsigned< char16_t> {typedef char16_t type;};
template <> struct XStringAbstract__make_unsigned< char32_t> {typedef char32_t type;};
template <> struct XStringAbstract__make_unsigned< wchar_t> {typedef wchar_t type;};
template <> struct XStringAbstract__make_unsigned< signed short> {typedef unsigned short type;};
template <> struct XStringAbstract__make_unsigned<unsigned short> {typedef unsigned short type;};
template <> struct XStringAbstract__make_unsigned< signed int> {typedef unsigned int type;};
template <> struct XStringAbstract__make_unsigned<unsigned int> {typedef unsigned int type;};
template <> struct XStringAbstract__make_unsigned< signed long> {typedef unsigned long type;};
template <> struct XStringAbstract__make_unsigned<unsigned long> {typedef unsigned long type;};
template <> struct XStringAbstract__make_unsigned< signed long long> {typedef unsigned long long type;};
template <> struct XStringAbstract__make_unsigned<unsigned long long> {typedef unsigned long long type;};
#define unsigned_type(x) typename XStringAbstract__make_unsigned<x>::type
/* enable_if */
template <bool, typename T = void>
struct XStringAbstract__enable_if_t
{};
template <typename T>
struct XStringAbstract__enable_if_t<true, T> {
typedef T type;
};
//#define enable_if(x) XStringAbstract__enable_if_t(x, void)::type
#define enable_if(x) typename enable_if_type = typename XStringAbstract__enable_if_t<x>::type
//
//template< bool B, class T = void >
//using XStringAbstract__enable_if_t = typename XStringAbstract__enable_if<B,T>::type;
template <> struct _xtools__make_unsigned< char> {typedef unsigned char type;};
template <> struct _xtools__make_unsigned< signed char> {typedef unsigned char type;};
template <> struct _xtools__make_unsigned<unsigned char> {typedef unsigned char type;};
template <> struct _xtools__make_unsigned< char16_t> {typedef char16_t type;};
template <> struct _xtools__make_unsigned< char32_t> {typedef char32_t type;};
template <> struct _xtools__make_unsigned< wchar_t> {typedef wchar_t type;};
template <> struct _xtools__make_unsigned< signed short> {typedef unsigned short type;};
template <> struct _xtools__make_unsigned<unsigned short> {typedef unsigned short type;};
template <> struct _xtools__make_unsigned< signed int> {typedef unsigned int type;};
template <> struct _xtools__make_unsigned<unsigned int> {typedef unsigned int type;};
template <> struct _xtools__make_unsigned< signed long> {typedef unsigned long type;};
template <> struct _xtools__make_unsigned<unsigned long> {typedef unsigned long type;};
template <> struct _xtools__make_unsigned< signed long long> {typedef unsigned long long type;};
template <> struct _xtools__make_unsigned<unsigned long long> {typedef unsigned long long type;};
// is_integral
template <class _Tp> struct XStringAbstract__is_integral_st : public XStringAbstract__false_type {};
template <> struct XStringAbstract__is_integral_st<bool> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<char> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<signed char> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<unsigned char> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<wchar_t> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<short> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<unsigned short> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<int> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<unsigned int> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<long> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<unsigned long> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<long long> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_integral_st<unsigned long long> : public XStringAbstract__true_type {};
#define is_integral(x) XStringAbstract__is_integral_st<x>::value
template <class _Tp> struct _xtools__is_integral_st : public _xtools__false_type {};
//template <> struct _xtools__is_integral_st<bool> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<char> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<signed char> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<unsigned char> : public _xtools__true_type {};
//template <> struct _xtools__is_integral_st<wchar_t> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<short> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<unsigned short> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<int> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<unsigned int> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<long> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<unsigned long> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<long long> : public _xtools__true_type {};
template <> struct _xtools__is_integral_st<unsigned long long> : public _xtools__true_type {};
// is_char
template <class _Tp> struct XStringAbstract__is_char_st : public XStringAbstract__false_type {};
template <> struct XStringAbstract__is_char_st<char> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_st<signed char> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_st<unsigned char> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_st<char16_t> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_st<char32_t> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_st<wchar_t> : public XStringAbstract__true_type {};
#define is_char(x) XStringAbstract__is_char_st<x>::value
template <class _Tp> struct _xtools__is_char_st : public _xtools__false_type {};
template <> struct _xtools__is_char_st<char> : public _xtools__true_type {};
template <> struct _xtools__is_char_st<signed char> : public _xtools__true_type {};
template <> struct _xtools__is_char_st<unsigned char> : public _xtools__true_type {};
template <> struct _xtools__is_char_st<char16_t> : public _xtools__true_type {};
template <> struct _xtools__is_char_st<char32_t> : public _xtools__true_type {};
template <> struct _xtools__is_char_st<wchar_t> : public _xtools__true_type {};
//
//// STRUCT TEMPLATE remove_reference
@ -100,38 +81,81 @@ template <> struct XStringAbstract__is_char_st<wchar_t>
// };
// STRUCT TEMPLATE remove_const
template<class _Ty>
struct remove_const
{ // remove const
using type = _Ty;
};
template<class _Ty>
struct remove_const<const _Ty>
{ // remove const
using type = _Ty;
};
//template<class _Ty>
// struct remove_const
// { // remove const
// typedef _Ty type;
// };
//
//template<class _Ty>
// struct remove_const<const _Ty>
// { // remove const
// typedef _Ty type;
// };
template< class T > struct _xtools__remove_const_ptr { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<const T> { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<T*> { typedef T type; };
template< class T > struct _xtools__remove_const_ptr<const T*> { typedef T type; };
template< class T, int n > struct _xtools__remove_const_ptr<T[n]> { typedef T type; };
template< class T, int n > struct _xtools__remove_const_ptr<const T[n]> { typedef T type; };
// is_char_ptr
template <class _Tp> struct XStringAbstract__is_char_ptr_st : public XStringAbstract__false_type {};
template <> struct XStringAbstract__is_char_ptr_st<char*> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_ptr_st<char[]> : public XStringAbstract__true_type {};
template <size_t _Np> struct XStringAbstract__is_char_ptr_st<char[_Np]> : public XStringAbstract__true_type {};
//template <> struct XStringAbstract__is_char_ptr_st<signed char> : public XStringAbstract__true_type {};
//template <> struct XStringAbstract__is_char_ptr_st<unsigned char> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_ptr_st<char16_t*> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_ptr_st<char16_t[]> : public XStringAbstract__true_type {};
template <size_t _Np> struct XStringAbstract__is_char_ptr_st<char16_t[_Np]> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_ptr_st<char32_t*> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_ptr_st<char32_t[]> : public XStringAbstract__true_type {};
template <size_t _Np> struct XStringAbstract__is_char_ptr_st<char32_t[_Np]> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_ptr_st<wchar_t*> : public XStringAbstract__true_type {};
template <> struct XStringAbstract__is_char_ptr_st<wchar_t[]> : public XStringAbstract__true_type {};
template <size_t _Np> struct XStringAbstract__is_char_ptr_st<wchar_t[_Np]> : public XStringAbstract__true_type {};
#define is_char_ptr(x) XStringAbstract__is_char_ptr_st<typename remove_const<x>::type>::value
template <class _Tp> struct _xtools__is_char_ptr_st : public _xtools__false_type {};
template <> struct _xtools__is_char_ptr_st<char*> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<char[]> : public _xtools__true_type {};
template <size_t _Np> struct _xtools__is_char_ptr_st<char[_Np]> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<signed char*> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<signed char[]> : public _xtools__true_type {};
template <size_t _Np> struct _xtools__is_char_ptr_st<signed char[_Np]> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<unsigned char*> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<unsigned char[]> : public _xtools__true_type {};
template <size_t _Np> struct _xtools__is_char_ptr_st<unsigned char[_Np]> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<char16_t*> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<char16_t[]> : public _xtools__true_type {};
template <size_t _Np> struct _xtools__is_char_ptr_st<char16_t[_Np]> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<char32_t*> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<char32_t[]> : public _xtools__true_type {};
template <size_t _Np> struct _xtools__is_char_ptr_st<char32_t[_Np]> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<wchar_t*> : public _xtools__true_type {};
template <> struct _xtools__is_char_ptr_st<wchar_t[]> : public _xtools__true_type {};
template <size_t _Np> struct _xtools__is_char_ptr_st<wchar_t[_Np]> : public _xtools__true_type {};
/* enable_if */
template <bool, typename T = void>
struct _xtools_enable_if_t
{};
template <typename T>
struct _xtools_enable_if_t<true, T> {
typedef T type;
};
template< class... >
using _xtools__void_t = void;
/* has type member */
// primary template handles types that have no nested ::type member:
template< class, class = _xtools__void_t<> >
struct _xtools__has_type_member : _xtools__false_type { };
// specialization recognizes types that do have a nested ::type member:
template< class T >
struct _xtools__has_type_member<T, _xtools__void_t<typename T::char_t>> : _xtools__true_type { };
#define unsigned_type(x) typename _xtools__make_unsigned<x>::type
#define is_integral(x) _xtools__is_integral_st<x>::value
#define is_char(x) _xtools__is_char_st<x>::value
#define is_char_ptr(x) _xtools__is_char_ptr_st<typename _xtools__remove_const_ptr<x>::type>::value
#define enable_if_t(x) typename _xtools_enable_if_t<x>::type
#define enable_if(x) typename enable_if_type = typename _xtools_enable_if_t<x>::type
#endif /* XToolsCommon_h */

View File

@ -859,7 +859,7 @@ SimpleString teststrncat_(const InitialValue& initialValue, const ValueToCat& va
xstr.takeValueFrom(initialValue.cha);
xstr.strncat(valueToCat.cha, i);
size_t expectedLength = length_of_utf_string(initialValue.cha) + min(i, valueToCat.utf32_length);
size_t expectedLength = length_of_utf_string(initialValue.cha) + Xmin(i, valueToCat.utf32_length);
CHECK_RESULT(xstr.length() == expectedLength,
ssprintf("xstr.length() == expectedLength (%zu)", expectedLength),
ssprintf("xstr.length() != expectedLength (%zu!=%zu)", xstr.length(), expectedLength)
@ -1411,34 +1411,34 @@ SimpleString teststartWith_(const InitialValue& initialValue)
// typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
// ch_t c; // dummy for call utf function
XStringClass initialString;
initialString.takeValueFrom(initialValue.cha);
XStringClass initia__String;
initia__String.takeValueFrom(initialValue.cha);
char32_t expectedChar = 0;
if ( initialValue.utf32_length > 0) expectedChar = initialValue.utf32[initialValue.utf32_length-1];
for ( size_t count = 0 ; count < initialValue.utf32_length+3 ; count+=1 )
{
XStringClass subStr = initialString.subString(0, count);
XStringClass subStr = initia__String.subString(0, count);
bool expectedResult = true;
if ( subStr.length() > 0 && count >= initialValue.utf32_length ) expectedResult = false;
CHECK_RESULT(initialString.startWith(subStr) == expectedResult,
ssprintf("\"%s\".startWith(\"%s\") == %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult),
ssprintf("\"%s\".startWith(\"%s\") != %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult)
CHECK_RESULT(initia__String.startWith(subStr) == expectedResult,
ssprintf("\"%s\".startWith(\"%s\") == %d", SimpleString(initia__String.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult),
ssprintf("\"%s\".startWith(\"%s\") != %d", SimpleString(initia__String.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult)
);
//initialString.startWith(subStr);
//initia__String.startWith(subStr);
subStr = initialString.subString(0, count-1) + ((char32_t)(initialValue.utf32[count-1]+1));
subStr = initia__String.subString(0, count-1) + ((char32_t)(initialValue.utf32[count-1]+1));
expectedResult = false;
CHECK_RESULT(initialString.startWith(subStr) == expectedResult,
ssprintf("\"%s\".startWith(\"%s\") == %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult),
ssprintf("\"%s\".startWith(\"%s\") != %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult)
CHECK_RESULT(initia__String.startWith(subStr) == expectedResult,
ssprintf("\"%s\".startWith(\"%s\") == %d", SimpleString(initia__String.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult),
ssprintf("\"%s\".startWith(\"%s\") != %d", SimpleString(initia__String.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult)
);
//subStr = initialString.subString(0, count-1);
//subStr = initia__String.subString(0, count-1);
//subStr = subStr + ((char32_t)(initialValue.utf32[count-1]+1));
//initialString.startWith(subStr);
//initia__String.startWith(subStr);
}
//str.takeValueFrom(initialValue.cha);
@ -1463,16 +1463,16 @@ SimpleString testbasename_(const InitialValue& initialValue, const TestString<Ex
// typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
// ch_t c; // dummy for call utf function
XStringClass initialString;
initialString.takeValueFrom(initialValue.cha);
XStringClass initia__String;
initia__String.takeValueFrom(initialValue.cha);
XStringClass xstr = initialString.basename();
XStringClass xstr = initia__String.basename();
CHECK_RESULT(xstr.strcmp(expectedResult.cha) == 0,
ssprintf("\"%s\".basename() == \"%s\"", SimpleString(initialString.s()).c_str(), SimpleString(expectedResult.cha).c_str()),
ssprintf("\"%s\".basename() != (\"%s\"!=\"%s\")", SimpleString(initialString.s()).c_str(), SimpleString(xstr.s()).c_str(), SimpleString(expectedResult.cha).c_str())
ssprintf("\"%s\".basename() == \"%s\"", SimpleString(initia__String.s()).c_str(), SimpleString(expectedResult.cha).c_str()),
ssprintf("\"%s\".basename() != (\"%s\"!=\"%s\")", SimpleString(initia__String.s()).c_str(), SimpleString(xstr.s()).c_str(), SimpleString(expectedResult.cha).c_str())
);
XStringClass xstr2 = initialString.basename();
XStringClass xstr2 = initia__String.basename();
return SimpleString();
}
@ -1494,23 +1494,23 @@ XStringClass xstr2 = initialString.basename();
//#include <libgen.h>
//std::is_class
//
//void func_test(XStringW& xsw)
//{
// (void)xsw;
//}
void func_test(XStringW& xsw)
{
(void)xsw;
}
template<typename T>
class CE
class C
{
public:
const T* data;
constexpr CE() : data(0) { }
typedef char char_t;
const char* data;
constexpr C() : data(0) { }
};
class CE2 : public XStringAbstractNoDtor<char, CE2>
{
};
//constexpr LString8 g_xs1 = "foobar";
//constexpr LStringW g_xsw1 = L"foobar";
//XString g_xs2 = "foobar"_XS;
int XString_tests()
{
@ -1518,52 +1518,27 @@ int XString_tests()
// printf("XString16_tests -> Enter\n");
#endif
//constexpr CE<char> ce;
//constexpr CE2 xsw;
//LString8 a = "dfsf"_XS;
//XStringW b = "ssdfsdf"_XS;
//XString c = a + b;
//const char c = ' ';
//const char* cc = " ";
//char buf[64];
//char16_t* buf16 = (char16_t*)u"foo16";
XString x1("a"_XS);
XString x2("b"_XS);
XStringW xw1("c"_XS);
//char c = 1;
//int ii = sizeof(size_t);
//unsigned long long ull = 1;
//unsigned long long ll = 3;
//xw1.dataSized(c);
//xw1.dataSized(ii);
//xw1.dataSized(ull);
//xw1.dataSized(ll);
char c = 1;
int ii = sizeof(size_t);
unsigned long long ull = 1;
unsigned long long ll = 3;
xw1.dataSized(c);
xw1.dataSized(ii);
xw1.dataSized(ull);
xw1.dataSized(ll);
//auto x3 = xw1 = x1;
//func_test(x3);
//
//XStringAbstract__is_char_st<decltype(buf16)> a;
//printf("a.v()=%d\n", a.v());
//XStringW sw1 = buf16;
//std::is_array<decltype(buf)> b;
//XStringAbstract__enable_if_t<is_char(decltype(c))>::type a;
//printf("%ls", XStringW().takeValueFrom(" ").s());
//func_test(XStringW().takeValueFrom(" "));
// testDefaultCtor<XString>("XString");
// XString16 a = u"toto"_XS16;
const char* utf8 = "ギ"; (void)utf8;
size_t utf8_size = sizeof("ギ") - 1; (void)utf8_size; // this char is 6 bytes long !
const wchar_t* utfw = L"ギ"; (void)utfw;
size_t utfw_size = sizeof(L"ギ") - 1; (void)utfw_size; // this char is 6 bytes long !
const char16_t* utf16 = u"ギ"; (void)utf16;
size_t utf16_size = sizeof(u"ギ") - 1; (void)utf16_size; // this char is 6 bytes long !
const char32_t* utf32 = U"ギ"; (void)utf32;
size_t utf32_size = sizeof(U"ギ") - 1; (void)utf32_size; // this char is 6 bytes long !
//const char* utf8 = "ギ"; (void)utf8;
//size_t utf8_size = sizeof("ギ") - 1; (void)utf8_size; // this char is 6 bytes long !
//const wchar_t* utfw = L"ギ"; (void)utfw;
//size_t utfw_size = sizeof(L"ギ") - 1; (void)utfw_size; // this char is 6 bytes long !
//const char16_t* utf16 = u"ギ"; (void)utf16;
//size_t utf16_size = sizeof(u"ギ") - 1; (void)utf16_size; // this char is 6 bytes long !
//const char32_t* utf32 = U"ギ"; (void)utf32;
//size_t utf32_size = sizeof(U"ギ") - 1; (void)utf32_size; // this char is 6 bytes long !
//size_t size = sizeof("ꇉ")-1; // this char is 3 bytes long
//size_t size = sizeof("伽")-1; // this char is 3 bytes long
//size_t size = sizeof("楘")-1; // this char is 3 bytes long
@ -1578,46 +1553,28 @@ size_t utf32_size = sizeof(U"ギ") - 1; (void)utf32_size; // this char is 6 b
#ifdef _MSC_VER
//SetConsoleOutputCP(65001);
#endif
//
//printf("%s", "Выход \n");
//XString ddd = "Выход "_XS;
//printf(" xstring %s, asize=%zu, sizeinbyte=%zu sizeof=%zu lastcharat=%zu\n", ddd.c_str(), ddd.allocatedSize(), ddd.sizeInBytes(), sizeof(ddd), ddd.indexOf(ddd.lastChar()));
//
//TestString<char> ts1 = TestString<char>(nbchar("Выход "), "Выход ", nbchar(PREFIX_U("Выход ")), PREFIX_U("Выход "));
//testlastChar_<XString>(ts1);
//teststrncpy_<XString>("utf8", testStringMultiCodedArray[1].utf8, testStringMultiCodedArray[1].wchar);
//testindexOf(XString, utf8, utf16);
//testCompare(XString, utf8, utf16);
//testindexOf_<XString>(testStringMultiCoded4CaseArray[0].utf8);
//testTakeValueFrom_<XString16>(testStringMultiCodedArray[0].utf16, testStringMultiCodedArray[0].utf16);
//const char* p1 = "foo/bar"; // basename returns bar
//const char* p1 = "foo/"; // basename returns foo
//const char* p1 = "foo//"; // basename returns foo
//const char* p1 = "foo///"; // basename returns foo
//const char* p1 = ""; // basename returns "."
//const char* p1 = " foo/bar "; // basename returns "bar "
//const char* p1 = " foo "; // basename returns " foo "
//const char* p1 = " "; // basename returns " "
//const char* p2 = basename((char*)p1);
TEST_ALL_CLASSES(testDefaultCtor, __TEST0);
TEST_ALL_CLASSES(testEmpty, __TEST0);
TEST_ALL_CLASSES(testTakeValueFrom, TEST_ALL_UTF);
TEST_ALL_CLASSES(testchar32At, TEST_ALL_INTEGRAL);
TEST_ALL_CLASSES(testdataSized, TEST_ALL_INTEGRAL);
TEST_ALL_CLASSES(teststrncpy, TEST_ALL_UTF); // 26944 tests
TEST_ALL_CLASSES(teststrcat, TEST_ALL_UTF_ALL_UTF);
TEST_ALL_CLASSES(teststrncat, TEST_ALL_UTF_ALL_UTF); // 2101632 tests
// TEST_ALL_CLASSES(testDefaultCtor, __TEST0);
// TEST_ALL_CLASSES(testEmpty, __TEST0);
// TEST_ALL_CLASSES(testTakeValueFrom, TEST_ALL_UTF);
// TEST_ALL_CLASSES(testchar32At, TEST_ALL_INTEGRAL);
// TEST_ALL_CLASSES(testdataSized, TEST_ALL_INTEGRAL);
//
// TEST_ALL_CLASSES(teststrncpy, TEST_ALL_UTF); // 26944 tests
// TEST_ALL_CLASSES(teststrcat, TEST_ALL_UTF_ALL_UTF);
// TEST_ALL_CLASSES(teststrncat, TEST_ALL_UTF_ALL_UTF); // 2101632 tests
//
TEST_ALL_CLASSES(testSubString, __TEST0);
// TEST_ALL_CLASSES(testCompare, TEST_ALL_UTF);
// TEST_ALL_CLASSES(testindexOf, TEST_ALL_UTF);
//
// TEST_ALL_CLASSES(testlastChar, __TEST0);
TEST_ALL_CLASSES(testCompare, TEST_ALL_UTF);
TEST_ALL_CLASSES(testindexOf, TEST_ALL_UTF);
TEST_ALL_CLASSES(testlastChar, __TEST0);
TEST_ALL_CLASSES(testtrim, __TEST0);
TEST_ALL_CLASSES(teststartWith, __TEST0);
TEST_ALL_CLASSES(testbasename, __TEST0);
@ -1643,3 +1600,18 @@ size_t utf32_size = sizeof(U"ギ") - 1; (void)utf32_size; // this char is 6 b
#endif
return nbTestFailed > 0;
}
//const char* p1 = "foo/bar"; // basename returns bar
//const char* p1 = "foo/"; // basename returns foo
//const char* p1 = "foo//"; // basename returns foo
//const char* p1 = "foo///"; // basename returns foo
//const char* p1 = ""; // basename returns "."
//const char* p1 = " foo/bar "; // basename returns "bar "
//const char* p1 = " foo "; // basename returns " foo "
//const char* p1 = " "; // basename returns " "
//const char* p2 = basename((char*)p1);