From: Pasukhin Dmitry Date: Wed, 22 Oct 2025 11:39:48 +0000 (+0100) Subject: Foundation Classes - Optimize AsciiString with pre-defined string (#752) X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=3b67b4b5da9d215b73ecbaa4d77e14a70224585d;p=occt.git Foundation Classes - Optimize AsciiString with pre-defined string (#752) - Rename internal members mystring/mylength -> myString/myLength across AsciiString implementation and related files to improve naming consistency. - Add std::string_view support and efficient overloads: - constructor from string_view, AssignCat/Copy/Insert/SetValue from string_view - Cat, operators (+, +=) and comparison helpers accepting string_view - Token/StartsWith/EndsWith/Search helpers and literal-template overloads - operator std::string_view() to obtain a non-owning view - IsEqual/IsSameString/IsDifferent variants for string_view/C-string combinations - optimized literal templates to avoid runtime strlen for compile-time literals - Improve memory handling and allocation helpers (allocate/reallocate/deallocate) and keep padding strategy consistent. - Add Insert/AssignCat implementations that accept string_view and use memmove/memcpy. - Fix calls in HAsciiString to use direct method instead of members - Adjust misc. parameter names and small code-style/clarity improvements. These changes enable zero-copy interop with std::string_view, reduce redundant C-string operations for literals, and unify internal naming for maintainability. --- diff --git a/src/FoundationClasses/TKernel/GTests/TCollection_AsciiString_Test.cxx b/src/FoundationClasses/TKernel/GTests/TCollection_AsciiString_Test.cxx index 75b02fb8f9..fe3c72c692 100644 --- a/src/FoundationClasses/TKernel/GTests/TCollection_AsciiString_Test.cxx +++ b/src/FoundationClasses/TKernel/GTests/TCollection_AsciiString_Test.cxx @@ -359,3 +359,1060 @@ TEST(TCollection_AsciiStringTest, PaddingSafety) } } } + +// ======================================== +// Tests for AssignCat method +// ======================================== + +TEST(TCollection_AsciiStringTest, AssignCat_BasicCases) +{ + TCollection_AsciiString aString("Hello"); + + // AssignCat with C string + aString.AssignCat(" World"); + EXPECT_STREQ("Hello World", aString.ToCString()); + EXPECT_EQ(11, aString.Length()); + + // AssignCat with another AsciiString + TCollection_AsciiString aSuffix("!"); + aString.AssignCat(aSuffix); + EXPECT_STREQ("Hello World!", aString.ToCString()); + EXPECT_EQ(12, aString.Length()); + + // AssignCat with character + aString.AssignCat('?'); + EXPECT_STREQ("Hello World!?", aString.ToCString()); + EXPECT_EQ(13, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, AssignCat_EmptyStrings) +{ + TCollection_AsciiString aString; + + // AssignCat to empty string + aString.AssignCat("First"); + EXPECT_STREQ("First", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // AssignCat empty string + aString.AssignCat(""); + EXPECT_STREQ("First", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // AssignCat null terminator character + TCollection_AsciiString aString2("Test"); + aString2.AssignCat('\0'); + EXPECT_STREQ("Test", aString2.ToCString()); + EXPECT_EQ(4, aString2.Length()); +} + +TEST(TCollection_AsciiStringTest, AssignCat_SelfReference) +{ + TCollection_AsciiString aString("ABC"); + + // Self-reference: concatenate the entire string to itself + aString.AssignCat(aString.ToCString()); + EXPECT_STREQ("ABCABC", aString.ToCString()); + EXPECT_EQ(6, aString.Length()); + + // Self-reference: concatenate part of itself + TCollection_AsciiString aString2("Hello"); + const char* aSubStr = aString2.ToCString() + 1; // "ello" + aString2.AssignCat(aSubStr); + EXPECT_STREQ("Helloello", aString2.ToCString()); + EXPECT_EQ(9, aString2.Length()); +} + +TEST(TCollection_AsciiStringTest, AssignCat_IntegerAndReal) +{ + TCollection_AsciiString aString("Value: "); + + // AssignCat with integer + aString.AssignCat(42); + EXPECT_STREQ("Value: 42", aString.ToCString()); + + // AssignCat with real + TCollection_AsciiString aString2("Pi is approximately "); + aString2.AssignCat(3.14159); + EXPECT_TRUE(strstr(aString2.ToCString(), "3.14159") != NULL); +} + +TEST(TCollection_AsciiStringTest, AssignCat_LargeStrings) +{ + TCollection_AsciiString aString(100, 'A'); + TCollection_AsciiString aSuffix(100, 'B'); + + aString.AssignCat(aSuffix); + EXPECT_EQ(200, aString.Length()); + + // Verify first 100 are 'A' and last 100 are 'B' + const char* aPtr = aString.ToCString(); + for (int i = 0; i < 100; ++i) + { + EXPECT_EQ('A', aPtr[i]); + } + for (int i = 100; i < 200; ++i) + { + EXPECT_EQ('B', aPtr[i]); + } +} + +// ======================================== +// Tests for Insert method +// ======================================== + +TEST(TCollection_AsciiStringTest, Insert_BasicCases) +{ + TCollection_AsciiString aString("HelloWorld"); + + // Insert at beginning + aString.Insert(1, "Start"); + EXPECT_STREQ("StartHelloWorld", aString.ToCString()); + + // Insert in middle + TCollection_AsciiString aString2("AC"); + aString2.Insert(2, "B"); + EXPECT_STREQ("ABC", aString2.ToCString()); + + // Insert at end + TCollection_AsciiString aString3("Hello"); + aString3.Insert(6, " World"); + EXPECT_STREQ("Hello World", aString3.ToCString()); +} + +TEST(TCollection_AsciiStringTest, Insert_EmptyStrings) +{ + TCollection_AsciiString aString; + + // Insert into empty string + aString.Insert(1, "First"); + EXPECT_STREQ("First", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // Insert empty string + TCollection_AsciiString aString2("Test"); + aString2.Insert(3, ""); + EXPECT_STREQ("Test", aString2.ToCString()); + EXPECT_EQ(4, aString2.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_SelfReference) +{ + TCollection_AsciiString aString("XYZ"); + + // Insert entire string into itself at beginning + aString.Insert(1, aString.ToCString()); + EXPECT_STREQ("XYZXYZ", aString.ToCString()); + EXPECT_EQ(6, aString.Length()); + + // Insert part of string into itself + TCollection_AsciiString aString2("ABCD"); + const char* aSubStr = aString2.ToCString() + 1; // "BCD" + aString2.Insert(2, aSubStr); + EXPECT_STREQ("ABCDBCD", aString2.ToCString()); + EXPECT_EQ(7, aString2.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_WithCharacter) +{ + TCollection_AsciiString aString("Hllo"); + + // Insert character in middle + aString.Insert(2, 'e'); + EXPECT_STREQ("Hello", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // Insert character at beginning + TCollection_AsciiString aString2("ello"); + aString2.Insert(1, 'H'); + EXPECT_STREQ("Hello", aString2.ToCString()); +} + +TEST(TCollection_AsciiStringTest, Insert_BoundaryConditions) +{ + TCollection_AsciiString aString("Test"); + + // Insert at position 1 (beginning) + TCollection_AsciiString aString1 = aString; + aString1.Insert(1, ">"); + EXPECT_STREQ(">Test", aString1.ToCString()); + + // Insert at position length+1 (end) + TCollection_AsciiString aString2 = aString; + aString2.Insert(5, "<"); + EXPECT_STREQ("Test<", aString2.ToCString()); +} + +// ======================================== +// Tests for Insert method with overlapping source +// ======================================== + +TEST(TCollection_AsciiStringTest, Insert_OverlapLeftSide) +{ + // Test case: source overlaps the left side of the shift window + // String: "ABCDEFGH", insert "ABC" at position 4 + // Result: "ABC[ABC]DEFGH" - source is before insertion point + TCollection_AsciiString aString("ABCDEFGH"); + const char* aSource = aString.ToCString(); // "ABCDEFGH" + aString.Insert(4, aSource, 3); // Insert first 3 chars at pos 4 + EXPECT_STREQ("ABCABCDEFGH", aString.ToCString()); + EXPECT_EQ(11, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapRightSide) +{ + // Test case: source overlaps the right side of the shift window + // String: "ABCDEFGH", insert "DEFGH" at position 2 + // When shifting, "BCDEFGH" moves to positions 6-12 + // Source "DEFGH" (originally at 3-7) also shifts to 8-12 + // Result: "A" + "DEFGH" (from shifted position 8-12) + "BCDEFGH" = "ADEFGHBCDEFGH" + TCollection_AsciiString aString("ABCDEFGH"); + const char* aSource = aString.ToCString() + 3; // "DEFGH" + aString.Insert(2, aSource); + EXPECT_STREQ("ADEFGHBCDEFGH", aString.ToCString()); + EXPECT_EQ(13, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapInsideShiftWindow) +{ + // Test case: source is completely inside the shift window + // String: "ABCDEFGH", insert "CDE" at position 2 + // Result: "A[CDE]BCDEFGH" - source will be shifted + TCollection_AsciiString aString("ABCDEFGH"); + const char* aSource = aString.ToCString() + 2; // "CDEFGH" + aString.Insert(2, aSource, 3); // Insert "CDE" at pos 2 + EXPECT_STREQ("ACDEBCDEFGH", aString.ToCString()); + EXPECT_EQ(11, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapStartsBeforeShiftWindow) +{ + // Test case: source starts before and extends into shift window + // String: "ABCDEFGH", insert "BCDE" at position 4 + // Result: "ABC[BCDE]DEFGH" + TCollection_AsciiString aString("ABCDEFGH"); + const char* aSource = aString.ToCString() + 1; // "BCDEFGH" + aString.Insert(4, aSource, 4); // Insert "BCDE" at pos 4 + EXPECT_STREQ("ABCBCDEDEFGH", aString.ToCString()); + EXPECT_EQ(12, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapAtInsertionPoint) +{ + // Test case: source starts exactly at insertion point + // String: "ABCDEFGH", insert "DEF" at position 4 + // Result: "ABC[DEF]DEFGH" - source starts where we insert + TCollection_AsciiString aString("ABCDEFGH"); + const char* aSource = aString.ToCString() + 3; // "DEFGH" + aString.Insert(4, aSource, 3); // Insert "DEF" at pos 4 + EXPECT_STREQ("ABCDEFDEFGH", aString.ToCString()); + EXPECT_EQ(11, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapComplex1) +{ + // Test case: Insert middle portion into beginning + // String: "123456789", insert "456" at position 1 + // Result: "[456]123456789" + TCollection_AsciiString aString("123456789"); + const char* aSource = aString.ToCString() + 3; // "456789" + aString.Insert(1, aSource, 3); // Insert "456" at pos 1 + EXPECT_STREQ("456123456789", aString.ToCString()); + EXPECT_EQ(12, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapComplex2) +{ + // Test case: Insert beginning portion into middle + // String: "XYZABC", insert "XY" at position 4 + // Result: "XYZ[XY]ABC" + TCollection_AsciiString aString("XYZABC"); + const char* aSource = aString.ToCString(); // "XYZABC" + aString.Insert(4, aSource, 2); // Insert "XY" at pos 4 + EXPECT_STREQ("XYZXYABC", aString.ToCString()); + EXPECT_EQ(8, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapSpansEntireShiftWindow) +{ + // Test case: source spans from before to after shift window + // String: "ABCDEFGHIJK", insert "BCDEFGH" at position 5 + // Result: "ABCD[BCDEFGH]EFGHIJK" - very wide overlap + TCollection_AsciiString aString("ABCDEFGHIJK"); + const char* aSource = aString.ToCString() + 1; // "BCDEFGHIJK" + aString.Insert(5, aSource, 7); // Insert "BCDEFGH" at pos 5 + EXPECT_STREQ("ABCDBCDEFGHEFGHIJK", aString.ToCString()); + EXPECT_EQ(18, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapSingleChar) +{ + // Test case: Insert single character from itself + // String: "ABC", insert 'B' at position 1 + TCollection_AsciiString aString("ABC"); + const char* aSource = aString.ToCString() + 1; // "BC" + aString.Insert(1, aSource, 1); // Insert 'B' at pos 1 + EXPECT_STREQ("BABC", aString.ToCString()); + EXPECT_EQ(4, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapEndToBeginning) +{ + // Test case: Insert end of string at beginning + // String: "HELLO", insert "LO" at position 1 + TCollection_AsciiString aString("HELLO"); + const char* aSource = aString.ToCString() + 3; // "LO" + aString.Insert(1, aSource); + EXPECT_STREQ("LOHELLO", aString.ToCString()); + EXPECT_EQ(7, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Insert_OverlapLargeString) +{ + // Test case: Large string with overlap + // This tests that memmove is used correctly for large overlapping regions + TCollection_AsciiString aString(50, 'A'); + aString.SetValue(25, "MARKER"); // "AAA...MARKER...AAA" + const char* aSource = aString.ToCString() + 20; // Take substring from position 20 + aString.Insert(10, aSource, 10); // Insert 10 chars at position 10 + EXPECT_EQ(60, aString.Length()); + // Verify MARKER appears twice (once from original, once from inserted overlap) + const char* aResult = aString.ToCString(); + EXPECT_TRUE(strstr(aResult, "MARKER") != nullptr); +} + +// ======================================== +// Tests for Cat method +// ======================================== + +TEST(TCollection_AsciiStringTest, Cat_BasicCases) +{ + TCollection_AsciiString aString("Hello"); + + // Cat with C string + TCollection_AsciiString aResult1 = aString.Cat(" World"); + EXPECT_STREQ("Hello World", aResult1.ToCString()); + EXPECT_STREQ("Hello", aString.ToCString()); // Original unchanged + + // Cat with AsciiString + TCollection_AsciiString aSuffix("!"); + TCollection_AsciiString aResult2 = aString.Cat(aSuffix); + EXPECT_STREQ("Hello!", aResult2.ToCString()); + + // Cat with character + TCollection_AsciiString aResult3 = aString.Cat('?'); + EXPECT_STREQ("Hello?", aResult3.ToCString()); +} + +TEST(TCollection_AsciiStringTest, Cat_IntegerAndReal) +{ + TCollection_AsciiString aString("Count: "); + + // Cat with integer + TCollection_AsciiString aResult1 = aString.Cat(42); + EXPECT_STREQ("Count: 42", aResult1.ToCString()); + + // Cat with negative integer + TCollection_AsciiString aResult2 = aString.Cat(-100); + EXPECT_STREQ("Count: -100", aResult2.ToCString()); + + // Cat with real + TCollection_AsciiString aString2("Value: "); + TCollection_AsciiString aResult3 = aString2.Cat(3.14); + EXPECT_TRUE(strstr(aResult3.ToCString(), "3.14") != NULL); + + // Cat with zero + TCollection_AsciiString aResult4 = aString.Cat(0); + EXPECT_STREQ("Count: 0", aResult4.ToCString()); +} + +TEST(TCollection_AsciiStringTest, Cat_EmptyStrings) +{ + TCollection_AsciiString aEmpty; + + // Cat to empty string + TCollection_AsciiString aResult1 = aEmpty.Cat("First"); + EXPECT_STREQ("First", aResult1.ToCString()); + + // Cat empty string + TCollection_AsciiString aString("Test"); + TCollection_AsciiString aResult2 = aString.Cat(""); + EXPECT_STREQ("Test", aResult2.ToCString()); +} + +TEST(TCollection_AsciiStringTest, Cat_ChainedOperations) +{ + TCollection_AsciiString aString("A"); + + // Chain multiple Cat operations + TCollection_AsciiString aResult = aString.Cat("B").Cat("C").Cat("D"); + EXPECT_STREQ("ABCD", aResult.ToCString()); +} + +// ======================================== +// Tests for Copy method +// ======================================== + +TEST(TCollection_AsciiStringTest, Copy_BasicCases) +{ + TCollection_AsciiString aString("Original"); + + // Copy with C string + aString.Copy("NewValue"); + EXPECT_STREQ("NewValue", aString.ToCString()); + EXPECT_EQ(8, aString.Length()); + + // Copy with AsciiString + TCollection_AsciiString aSource("Another"); + aString.Copy(aSource); + EXPECT_STREQ("Another", aString.ToCString()); + EXPECT_EQ(7, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Copy_ShorterAndLonger) +{ + TCollection_AsciiString aString("LongString"); + + // Copy shorter string (should reuse memory) + aString.Copy("Short"); + EXPECT_STREQ("Short", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // Copy longer string + aString.Copy("VeryLongStringHere"); + EXPECT_STREQ("VeryLongStringHere", aString.ToCString()); + EXPECT_EQ(18, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Copy_EmptyString) +{ + TCollection_AsciiString aString("Original"); + + // Copy empty string + aString.Copy(""); + EXPECT_STREQ("", aString.ToCString()); + EXPECT_EQ(0, aString.Length()); + EXPECT_TRUE(aString.IsEmpty()); +} + +TEST(TCollection_AsciiStringTest, Copy_SelfAssignment) +{ + TCollection_AsciiString aString("Test"); + + // Copy to itself (should be no-op) + aString.Copy(aString.ToCString()); + EXPECT_STREQ("Test", aString.ToCString()); + EXPECT_EQ(4, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, Copy_MemoryReuse) +{ + TCollection_AsciiString aString(100, 'A'); + + // Copy shorter string - should reuse buffer + aString.Copy("Short"); + EXPECT_STREQ("Short", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // Copy another short string - should still reuse + aString.Copy("Tiny"); + EXPECT_STREQ("Tiny", aString.ToCString()); + EXPECT_EQ(4, aString.Length()); +} + +// ======================================== +// Tests for Search and SearchFromEnd methods +// ======================================== + +TEST(TCollection_AsciiStringTest, Search_BasicCases) +{ + TCollection_AsciiString aString("This is a test string"); + + // Search for existing substring + EXPECT_EQ(1, aString.Search("This")); + EXPECT_EQ(11, aString.Search("test")); + EXPECT_EQ(16, aString.Search("string")); + + // Search for non-existing substring + EXPECT_EQ(-1, aString.Search("xyz")); + EXPECT_EQ(-1, aString.Search("notfound")); +} + +TEST(TCollection_AsciiStringTest, Search_EdgeCases) +{ + TCollection_AsciiString aString("abcabc"); + + // Search for substring - finds first occurrence + EXPECT_EQ(1, aString.Search("abc")); + + // Search for single character - finds first occurrence + EXPECT_EQ(1, aString.Search("a")); + EXPECT_EQ(2, aString.Search("b")); + EXPECT_EQ(3, aString.Search("c")); + + // Search for empty string + EXPECT_EQ(-1, aString.Search("")); + + // Search in empty string + TCollection_AsciiString anEmpty; + EXPECT_EQ(-1, anEmpty.Search("test")); +} + +TEST(TCollection_AsciiStringTest, Search_RepeatedPattern) +{ + TCollection_AsciiString aString("aaaaaaa"); + + // Search should find first occurrence + EXPECT_EQ(1, aString.Search("aaa")); + + // Test with different patterns + TCollection_AsciiString aString2("abcabcabc"); + EXPECT_EQ(1, aString2.Search("abc")); // First occurrence + EXPECT_EQ(1, aString2.Search("abcabc")); // Longer pattern +} + +TEST(TCollection_AsciiStringTest, SearchFromEnd_BasicCases) +{ + TCollection_AsciiString aString("This is a test string with test"); + + // SearchFromEnd should find last occurrence + EXPECT_EQ(28, aString.SearchFromEnd("test")); + EXPECT_EQ(16, aString.SearchFromEnd("string")); + + // Search for non-existing substring + EXPECT_EQ(-1, aString.SearchFromEnd("xyz")); +} + +TEST(TCollection_AsciiStringTest, SearchFromEnd_EdgeCases) +{ + TCollection_AsciiString aString("abcabc"); + + // SearchFromEnd for repeated pattern + EXPECT_EQ(4, aString.SearchFromEnd("abc")); + + // SearchFromEnd for single character + EXPECT_EQ(4, aString.SearchFromEnd("a")); + EXPECT_EQ(6, aString.SearchFromEnd("c")); + + // SearchFromEnd for empty string + EXPECT_EQ(-1, aString.SearchFromEnd("")); + + // SearchFromEnd in empty string + TCollection_AsciiString anEmpty; + EXPECT_EQ(-1, anEmpty.SearchFromEnd("test")); +} + +TEST(TCollection_AsciiStringTest, Search_LongerThanString) +{ + TCollection_AsciiString aString("Short"); + + // Search for substring longer than string + EXPECT_EQ(-1, aString.Search("VeryLongSubstring")); +} + +// ======================================== +// Tests for IsSameString method +// ======================================== + +TEST(TCollection_AsciiStringTest, IsSameString_CaseSensitive) +{ + TCollection_AsciiString aString1("Test"); + TCollection_AsciiString aString2("Test"); + TCollection_AsciiString aString3("test"); + TCollection_AsciiString aString4("Different"); + + // Case sensitive comparison + EXPECT_TRUE(TCollection_AsciiString::IsSameString(aString1, aString2, Standard_True)); + EXPECT_FALSE(TCollection_AsciiString::IsSameString(aString1, aString3, Standard_True)); + EXPECT_FALSE(TCollection_AsciiString::IsSameString(aString1, aString4, Standard_True)); +} + +TEST(TCollection_AsciiStringTest, IsSameString_CaseInsensitive) +{ + TCollection_AsciiString aString1("Test"); + TCollection_AsciiString aString2("TEST"); + TCollection_AsciiString aString3("test"); + TCollection_AsciiString aString4("TeSt"); + + // Case insensitive comparison + EXPECT_TRUE(TCollection_AsciiString::IsSameString(aString1, aString2, Standard_False)); + EXPECT_TRUE(TCollection_AsciiString::IsSameString(aString1, aString3, Standard_False)); + EXPECT_TRUE(TCollection_AsciiString::IsSameString(aString1, aString4, Standard_False)); +} + +TEST(TCollection_AsciiStringTest, IsSameString_EmptyStrings) +{ + TCollection_AsciiString aEmpty1; + TCollection_AsciiString aEmpty2(""); + TCollection_AsciiString aNonEmpty("Test"); + + // Empty string comparisons + EXPECT_TRUE(TCollection_AsciiString::IsSameString(aEmpty1, aEmpty2, Standard_True)); + EXPECT_TRUE(TCollection_AsciiString::IsSameString(aEmpty1, aEmpty2, Standard_False)); + EXPECT_FALSE(TCollection_AsciiString::IsSameString(aEmpty1, aNonEmpty, Standard_True)); +} + +TEST(TCollection_AsciiStringTest, IsSameString_DifferentLengths) +{ + TCollection_AsciiString aString1("Short"); + TCollection_AsciiString aString2("VeryLong"); + + // Different length strings are never same + EXPECT_FALSE(TCollection_AsciiString::IsSameString(aString1, aString2, Standard_True)); + EXPECT_FALSE(TCollection_AsciiString::IsSameString(aString1, aString2, Standard_False)); +} + +TEST(TCollection_AsciiStringTest, IsSameString_WithCStrings) +{ + // Test overload with C strings + EXPECT_TRUE(TCollection_AsciiString::IsSameString("Test", 4, "Test", 4, Standard_True)); + EXPECT_FALSE(TCollection_AsciiString::IsSameString("Test", 4, "test", 4, Standard_True)); + EXPECT_TRUE(TCollection_AsciiString::IsSameString("Test", 4, "test", 4, Standard_False)); +} + +// ======================================== +// Tests for IsEqual, IsDifferent, IsLess, IsGreater methods +// ======================================== + +TEST(TCollection_AsciiStringTest, IsEqual_AllOverloads) +{ + TCollection_AsciiString aString("Test"); + + // IsEqual with AsciiString + TCollection_AsciiString aString2("Test"); + EXPECT_TRUE(aString.IsEqual(aString2)); + + // IsEqual with C string + EXPECT_TRUE(aString.IsEqual("Test")); + EXPECT_FALSE(aString.IsEqual("Different")); + + // IsEqual with case sensitivity + TCollection_AsciiString aString3("test"); + EXPECT_FALSE(aString.IsEqual(aString3)); +} + +TEST(TCollection_AsciiStringTest, IsDifferent_AllOverloads) +{ + TCollection_AsciiString aString("Test"); + + // IsDifferent with AsciiString + TCollection_AsciiString aString2("Different"); + EXPECT_TRUE(aString.IsDifferent(aString2)); + + // IsDifferent with C string + EXPECT_TRUE(aString.IsDifferent("Different")); + EXPECT_FALSE(aString.IsDifferent("Test")); +} + +TEST(TCollection_AsciiStringTest, IsLess_AllOverloads) +{ + TCollection_AsciiString aStringA("Apple"); + TCollection_AsciiString aStringB("Banana"); + + // IsLess with AsciiString + EXPECT_TRUE(aStringA.IsLess(aStringB)); + EXPECT_FALSE(aStringB.IsLess(aStringA)); + + // IsLess with C string + EXPECT_TRUE(aStringA.IsLess("Banana")); + EXPECT_FALSE(aStringB.IsLess("Apple")); + + // IsLess with same string + EXPECT_FALSE(aStringA.IsLess(aStringA)); +} + +TEST(TCollection_AsciiStringTest, IsGreater_AllOverloads) +{ + TCollection_AsciiString aStringA("Apple"); + TCollection_AsciiString aStringB("Banana"); + + // IsGreater with AsciiString + EXPECT_TRUE(aStringB.IsGreater(aStringA)); + EXPECT_FALSE(aStringA.IsGreater(aStringB)); + + // IsGreater with C string + EXPECT_TRUE(aStringB.IsGreater("Apple")); + EXPECT_FALSE(aStringA.IsGreater("Banana")); + + // IsGreater with same string + EXPECT_FALSE(aStringA.IsGreater(aStringA)); +} + +TEST(TCollection_AsciiStringTest, Comparison_EmptyStrings) +{ + TCollection_AsciiString aEmpty; + TCollection_AsciiString aNonEmpty("Test"); + + // Empty string comparisons + EXPECT_TRUE(aEmpty.IsEqual("")); + EXPECT_FALSE(aEmpty.IsEqual(aNonEmpty)); + EXPECT_TRUE(aEmpty.IsDifferent(aNonEmpty)); + EXPECT_TRUE(aEmpty.IsLess(aNonEmpty)); + EXPECT_FALSE(aEmpty.IsGreater(aNonEmpty)); +} + +// ======================================== +// Tests for SetValue method +// ======================================== + +TEST(TCollection_AsciiStringTest, SetValue_BasicCases) +{ + TCollection_AsciiString aString("Hello"); + + // SetValue with character + aString.SetValue(1, 'h'); + EXPECT_STREQ("hello", aString.ToCString()); + + aString.SetValue(5, '!'); + EXPECT_STREQ("hell!", aString.ToCString()); +} + +TEST(TCollection_AsciiStringTest, SetValue_WithString) +{ + TCollection_AsciiString aString("AAAAA"); + + // SetValue with C string + aString.SetValue(2, "XYZ"); + EXPECT_STREQ("AXYZA", aString.ToCString()); + + // SetValue with AsciiString + TCollection_AsciiString aReplacement("12"); + aString.SetValue(1, aReplacement); + EXPECT_STREQ("12YZA", aString.ToCString()); +} + +TEST(TCollection_AsciiStringTest, SetValue_BoundaryConditions) +{ + TCollection_AsciiString aString("Test"); + + // SetValue at first position + aString.SetValue(1, 'X'); + EXPECT_STREQ("Xest", aString.ToCString()); + + // SetValue at last position + aString.SetValue(4, 'Y'); + EXPECT_STREQ("XesY", aString.ToCString()); +} + +TEST(TCollection_AsciiStringTest, SetValue_StringOverflow) +{ + TCollection_AsciiString aString("AAAA"); + + // SetValue with string that extends beyond current length + aString.SetValue(3, "XYZ"); + EXPECT_STREQ("AAXYZ", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); +} + +// ======================================== +// Tests for Remove and RemoveAll methods +// ======================================== + +TEST(TCollection_AsciiStringTest, Remove_BasicCases) +{ + TCollection_AsciiString aString("Hello World"); + + // Remove from middle + aString.Remove(6, 6); + EXPECT_STREQ("Hello", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // Remove from beginning + TCollection_AsciiString aString2("XYZTest"); + aString2.Remove(1, 3); + EXPECT_STREQ("Test", aString2.ToCString()); + + // Remove from end + TCollection_AsciiString aString3("TestXYZ"); + aString3.Remove(5, 3); + EXPECT_STREQ("Test", aString3.ToCString()); +} + +TEST(TCollection_AsciiStringTest, Remove_EntireString) +{ + TCollection_AsciiString aString("Test"); + + // Remove all characters + aString.Remove(1, 4); + EXPECT_STREQ("", aString.ToCString()); + EXPECT_EQ(0, aString.Length()); + EXPECT_TRUE(aString.IsEmpty()); +} + +TEST(TCollection_AsciiStringTest, RemoveAll_SingleCharacter) +{ + TCollection_AsciiString aString("Mississippi"); + + // RemoveAll 's' -> "Miiippi" (4 's' removed) + aString.RemoveAll('s'); + EXPECT_STREQ("Miiippi", aString.ToCString()); + + // RemoveAll 'i' -> "Mpp" (4 'i' removed: M-i-i-i-pp-i) + aString.RemoveAll('i'); + EXPECT_STREQ("Mpp", aString.ToCString()); +} + +TEST(TCollection_AsciiStringTest, RemoveAll_NoOccurrence) +{ + TCollection_AsciiString aString("Test"); + + // RemoveAll character that doesn't exist + aString.RemoveAll('X'); + EXPECT_STREQ("Test", aString.ToCString()); + EXPECT_EQ(4, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, RemoveAll_AllCharacters) +{ + TCollection_AsciiString aString("AAAA"); + + // RemoveAll the only character + aString.RemoveAll('A'); + EXPECT_STREQ("", aString.ToCString()); + EXPECT_EQ(0, aString.Length()); + EXPECT_TRUE(aString.IsEmpty()); +} + +// ======================================== +// Tests for Trunc method +// ======================================== + +TEST(TCollection_AsciiStringTest, Trunc_BasicCases) +{ + TCollection_AsciiString aString("Hello World"); + + // Truncate to shorter length + aString.Trunc(5); + EXPECT_STREQ("Hello", aString.ToCString()); + EXPECT_EQ(5, aString.Length()); + + // Truncate to zero + aString.Trunc(0); + EXPECT_STREQ("", aString.ToCString()); + EXPECT_EQ(0, aString.Length()); + EXPECT_TRUE(aString.IsEmpty()); +} + +TEST(TCollection_AsciiStringTest, Trunc_NoChange) +{ + TCollection_AsciiString aString("Test"); + + // Truncate to same length + aString.Trunc(4); + EXPECT_STREQ("Test", aString.ToCString()); + EXPECT_EQ(4, aString.Length()); +} + +// ======================================== +// Tests for std::string_view API +// ======================================== + +#if defined(__cplusplus) && __cplusplus >= 201703L +TEST(TCollection_AsciiStringTest, StringView_Constructor) +{ + std::string_view aView("Hello World"); + TCollection_AsciiString aString(aView); + + EXPECT_STREQ("Hello World", aString.ToCString()); + EXPECT_EQ(11, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, StringView_AssignmentAndComparison) +{ + TCollection_AsciiString aString; + std::string_view aView("Test"); + + // Assignment from string_view + aString = aView; + EXPECT_STREQ("Test", aString.ToCString()); + + // Comparison with string_view + EXPECT_TRUE(aString.IsEqual(aView)); + EXPECT_FALSE(aString.IsDifferent(aView)); +} + +TEST(TCollection_AsciiStringTest, StringView_CatAndAssignCat) +{ + TCollection_AsciiString aString("Hello"); + std::string_view aView(" World"); + + // Cat with string_view + TCollection_AsciiString aResult = aString.Cat(aView); + EXPECT_STREQ("Hello World", aResult.ToCString()); + + // AssignCat with string_view + aString.AssignCat(aView); + EXPECT_STREQ("Hello World", aString.ToCString()); +} + +TEST(TCollection_AsciiStringTest, StringView_Insert) +{ + TCollection_AsciiString aString("HloWorld"); + std::string_view aView("el"); + + // Insert string_view + aString.Insert(2, aView); + EXPECT_STREQ("HelloWorld", aString.ToCString()); +} +#endif + +// ======================================== +// Tests for Move semantics +// ======================================== + +TEST(TCollection_AsciiStringTest, MoveConstructor) +{ + TCollection_AsciiString aString1("Original String"); + TCollection_AsciiString aString2(std::move(aString1)); + + EXPECT_STREQ("Original String", aString2.ToCString()); + EXPECT_EQ(15, aString2.Length()); + + // Original should be in valid but unspecified state + // (typically empty after move) + EXPECT_TRUE(aString1.IsEmpty() || aString1.Length() >= 0); +} + +TEST(TCollection_AsciiStringTest, MoveAssignment) +{ + TCollection_AsciiString aString1("First"); + TCollection_AsciiString aString2("Second"); + + aString2 = std::move(aString1); + + EXPECT_STREQ("First", aString2.ToCString()); + EXPECT_EQ(5, aString2.Length()); +} + +// ======================================== +// Tests for template literal constructors +// ======================================== + +TEST(TCollection_AsciiStringTest, TemplateLiteral_Constructor) +{ + // Test compile-time size deduction for string literals + TCollection_AsciiString aString("Literal"); + EXPECT_STREQ("Literal", aString.ToCString()); + EXPECT_EQ(7, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, TemplateLiteral_Assignment) +{ + TCollection_AsciiString aString; + aString = "Assigned"; + EXPECT_STREQ("Assigned", aString.ToCString()); + EXPECT_EQ(8, aString.Length()); +} + +// ======================================== +// Tests for edge cases and stress tests +// ======================================== + +TEST(TCollection_AsciiStringTest, StressTest_MultipleOperations) +{ + TCollection_AsciiString aString; + + // Build string through multiple operations + for (int i = 0; i < 10; ++i) + { + aString.AssignCat("A"); + } + EXPECT_EQ(10, aString.Length()); + + // Insert in middle multiple times + for (int i = 0; i < 5; ++i) + { + aString.Insert(6, "B"); + } + EXPECT_EQ(15, aString.Length()); + + // Remove characters + aString.RemoveAll('B'); + EXPECT_EQ(10, aString.Length()); + EXPECT_STREQ("AAAAAAAAAA", aString.ToCString()); +} + +TEST(TCollection_AsciiStringTest, StressTest_LargeOperations) +{ + // Create large string + TCollection_AsciiString aLarge(1000, 'X'); + EXPECT_EQ(1000, aLarge.Length()); + + // Copy to another large string + TCollection_AsciiString aCopy; + aCopy.Copy(aLarge); + EXPECT_EQ(1000, aCopy.Length()); + + // Concatenate large strings + aLarge.AssignCat(aCopy); + EXPECT_EQ(2000, aLarge.Length()); +} + +TEST(TCollection_AsciiStringTest, EdgeCase_NullCharacterHandling) +{ + // Ensure null characters are handled correctly + TCollection_AsciiString aString('\0'); + EXPECT_TRUE(aString.IsEmpty()); + EXPECT_EQ(0, aString.Length()); +} + +TEST(TCollection_AsciiStringTest, EdgeCase_ConsecutiveOperations) +{ + TCollection_AsciiString aString("Test"); + + // Multiple consecutive copies + aString.Copy("A"); + aString.Copy("BB"); + aString.Copy("CCC"); + EXPECT_STREQ("CCC", aString.ToCString()); + + // Multiple consecutive assigncats + aString.AssignCat("D"); + aString.AssignCat("E"); + aString.AssignCat("F"); + EXPECT_STREQ("CCCDEF", aString.ToCString()); +} + +// Test case for bug with enum definition building (multiple AssignCat in loop) +TEST(TCollection_AsciiStringTest, AssignCat_MultipleInLoop) +{ + // This reproduces the scenario in MoniTool_TypedValue::Definition() + TCollection_AsciiString aDef; + char aMess[50]; + + // Build enum definition like MoniTool_TypedValue does + aDef.AssignCat("Enum"); + sprintf(aMess, " [in %d-%d]", 0, 1); + aDef.AssignCat(aMess); + + // Should be "Enum [in 0-1]" at this point + EXPECT_STREQ("Enum [in 0-1]", aDef.ToCString()); + + // Now add enum values in a loop + for (Standard_Integer i = 0; i <= 1; i++) + { + const char* anEnva = (i == 0) ? "Off" : "On"; + sprintf(aMess, " %d:%s", i, anEnva); + aDef.AssignCat(aMess); + } + + // Should be "Enum [in 0-1] 0:Off 1:On" + EXPECT_STREQ("Enum [in 0-1] 0:Off 1:On", aDef.ToCString()); + + // Add alpha section + aDef.AssignCat(" , alpha: "); + sprintf(aMess, "On:%d ", 1); + aDef.AssignCat("On"); + aDef.AssignCat(aMess); + sprintf(aMess, "Off:%d ", 0); + aDef.AssignCat("Off"); + aDef.AssignCat(aMess); + + // Final result should contain all parts + const char* aResult = aDef.ToCString(); + EXPECT_TRUE(strstr(aResult, "Enum") != nullptr); + EXPECT_TRUE(strstr(aResult, "[in 0-1]") != nullptr); + EXPECT_TRUE(strstr(aResult, "0:Off") != nullptr); + EXPECT_TRUE(strstr(aResult, "1:On") != nullptr); + EXPECT_TRUE(strstr(aResult, "alpha:") != nullptr); +} diff --git a/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.cxx b/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.cxx index f9670b9a7f..87d22802de 100644 --- a/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.cxx +++ b/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.cxx @@ -26,6 +26,7 @@ #include #include #include +#include namespace { @@ -38,6 +39,24 @@ inline Standard_Size calculatePaddedSize(const int theLength) { return (theLength + 4) & ~0x3; // Always guarantees at least +1 byte, up to +4 bytes } + +//! Helper structure to hold formatted integer string with its length +struct FormattedInteger +{ + char Buffer[16]; // Enough for 32-bit int + sign + null terminator + Standard_Integer Length; + + FormattedInteger(const Standard_Integer theValue) { Length = Sprintf(Buffer, "%d", theValue); } +}; + +//! Helper structure to hold formatted real number string with its length +struct FormattedReal +{ + char Buffer[64]; // Enough for double in %g format + null terminator + Standard_Integer Length; + + FormattedReal(const Standard_Real theValue) { Length = Sprintf(Buffer, "%g", theValue); } +}; } // namespace //================================================================================================= @@ -49,16 +68,6 @@ TCollection_AsciiString::TCollection_AsciiString() //================================================================================================= -TCollection_AsciiString::TCollection_AsciiString(const Standard_CString theString) -{ - if (theString == NULL) - { - throw Standard_NullObject("TCollection_AsciiString(): NULL pointer passed to constructor"); - } - allocate(static_cast(strlen(theString))); - memcpy(mystring, theString, mylength); -} - //================================================================================================= TCollection_AsciiString::TCollection_AsciiString(const Standard_CString theString, @@ -73,17 +82,17 @@ TCollection_AsciiString::TCollection_AsciiString(const Standard_CString theStrin { } allocate(aLength); - memcpy(mystring, theString, mylength); + memcpy(myString, theString, myLength); } //================================================================================================= -TCollection_AsciiString::TCollection_AsciiString(const Standard_Character aChar) +TCollection_AsciiString::TCollection_AsciiString(const Standard_Character theChar) { - if (aChar != '\0') + if (theChar != '\0') { allocate(1); - mystring[0] = aChar; + myString[0] = theChar; } else { @@ -93,39 +102,39 @@ TCollection_AsciiString::TCollection_AsciiString(const Standard_Character aChar) //================================================================================================= -TCollection_AsciiString::TCollection_AsciiString(const Standard_Integer length, - const Standard_Character filler) +TCollection_AsciiString::TCollection_AsciiString(const Standard_Integer theLength, + const Standard_Character theFiller) { - allocate(length); - memset(mystring, filler, length); + allocate(theLength); + memset(myString, theFiller, theLength); } //================================================================================================= -TCollection_AsciiString::TCollection_AsciiString(const Standard_Integer aValue) +TCollection_AsciiString::TCollection_AsciiString(const Standard_Integer theValue) { - char t[13]; - allocate(Sprintf(t, "%d", aValue)); - memcpy(mystring, t, mylength); + const FormattedInteger aFormatted(theValue); + allocate(aFormatted.Length); + memcpy(myString, aFormatted.Buffer, myLength); } //================================================================================================= -TCollection_AsciiString::TCollection_AsciiString(const Standard_Real aValue) +TCollection_AsciiString::TCollection_AsciiString(const Standard_Real theValue) { - char t[50]; - allocate(Sprintf(t, "%g", aValue)); - memcpy(mystring, t, mylength); + const FormattedReal aFormatted(theValue); + allocate(aFormatted.Length); + memcpy(myString, aFormatted.Buffer, myLength); } //================================================================================================= TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& theString) { - allocate(theString.mylength); - if (mylength != 0) + allocate(theString.myLength); + if (myLength != 0) { - memcpy(mystring, theString.mystring, mylength); + memcpy(myString, theString.myString, myLength); } } @@ -134,17 +143,17 @@ TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& TCollection_AsciiString::TCollection_AsciiString(TCollection_AsciiString&& theOther) Standard_Noexcept { - if (theOther.mystring == THE_DEFAULT_CHAR_STRING) + if (theOther.myString == THE_DEFAULT_CHAR_STRING) { allocate(0); } else { - mystring = theOther.mystring; - mylength = theOther.mylength; + myString = theOther.myString; + myLength = theOther.myLength; } - theOther.mylength = 0; - theOther.mystring = THE_DEFAULT_CHAR_STRING; + theOther.myLength = 0; + theOther.myString = THE_DEFAULT_CHAR_STRING; } //================================================================================================= @@ -152,12 +161,12 @@ TCollection_AsciiString::TCollection_AsciiString(TCollection_AsciiString&& theOt TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& theString, const Standard_Character theChar) { - allocate(theString.mylength + 1); - if (theString.mylength != 0) + allocate(theString.myLength + 1); + if (theString.myLength != 0) { - memcpy(mystring, theString.mystring, theString.mylength); + memcpy(myString, theString.myString, theString.myLength); } - mystring[mylength - 1] = theChar; + myString[myLength - 1] = theChar; } //================================================================================================= @@ -166,14 +175,14 @@ TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& const Standard_CString theString2) { const Standard_Integer aStr2Len = Standard_Integer(theString2 ? strlen(theString2) : 0); - allocate(theString1.mylength + aStr2Len); - if (theString1.mylength != 0) + allocate(theString1.myLength + aStr2Len); + if (theString1.myLength != 0) { - memcpy(mystring, theString1.mystring, theString1.mylength); + memcpy(myString, theString1.myString, theString1.myLength); } if (aStr2Len != 0) { - memcpy(mystring + theString1.mylength, theString2, aStr2Len); + memcpy(myString + theString1.myLength, theString2, aStr2Len); } } @@ -182,37 +191,38 @@ TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& theString1, const TCollection_AsciiString& theString2) { - allocate(theString1.mylength + theString2.mylength); - if (theString1.mylength) + allocate(theString1.myLength + theString2.myLength); + if (theString1.myLength) { - memcpy(mystring, theString1.mystring, theString1.mylength); + memcpy(myString, theString1.myString, theString1.myLength); } - if (theString2.mylength != 0) + if (theString2.myLength != 0) { - memcpy(mystring + theString1.mylength, theString2.mystring, theString2.mylength); + memcpy(myString + theString1.myLength, theString2.myString, theString2.myLength); } } //================================================================================================= -TCollection_AsciiString::TCollection_AsciiString(const TCollection_ExtendedString& astring, - const Standard_Character replaceNonAscii) +TCollection_AsciiString::TCollection_AsciiString( + const TCollection_ExtendedString& theExtendedString, + const Standard_Character theReplaceNonAscii) { - if (replaceNonAscii) + if (theReplaceNonAscii) { - allocate(astring.Length()); - for (int i = 0; i < mylength; i++) + allocate(theExtendedString.Length()); + for (int i = 0; i < myLength; i++) { - Standard_ExtCharacter c = astring.Value(i + 1); - mystring[i] = (IsAnAscii(c) ? ToCharacter(c) : replaceNonAscii); + Standard_ExtCharacter c = theExtendedString.Value(i + 1); + myString[i] = (IsAnAscii(c) ? ToCharacter(c) : theReplaceNonAscii); } } else { // create UTF-8 string // Note: allocate() adds padding (theLength + 4) & ~0x3, so no need for +1 for null terminator - allocate(astring.LengthOfCString()); - astring.ToUTF8CString(mystring); + allocate(theExtendedString.LengthOfCString()); + theExtendedString.ToUTF8CString(myString); } } @@ -227,7 +237,7 @@ TCollection_AsciiString::TCollection_AsciiString(const Standard_WideChar* theStr } allocate(aLength); NCollection_UtfWideIter anIterRead(theStringUtf); - for (Standard_Utf8Char* anIterWrite = mystring; *anIterRead != 0; ++anIterRead) + for (Standard_Utf8Char* anIterWrite = myString; *anIterRead != 0; ++anIterRead) { anIterWrite = anIterRead.GetUtf(anIterWrite); } @@ -235,82 +245,115 @@ TCollection_AsciiString::TCollection_AsciiString(const Standard_WideChar* theStr //================================================================================================= -void TCollection_AsciiString::AssignCat(const Standard_Integer other) +void TCollection_AsciiString::AssignCat(const Standard_Integer theOther) { - - AssignCat(TCollection_AsciiString(other)); + const FormattedInteger aFormatted(theOther); + AssignCat(aFormatted.Buffer, aFormatted.Length); } //================================================================================================= -void TCollection_AsciiString::AssignCat(const Standard_Real other) +void TCollection_AsciiString::AssignCat(const Standard_Real theOther) { - - AssignCat(TCollection_AsciiString(other)); + const FormattedReal aFormatted(theOther); + AssignCat(aFormatted.Buffer, aFormatted.Length); } //================================================================================================= -void TCollection_AsciiString::AssignCat(const Standard_Character other) +void TCollection_AsciiString::AssignCat(const Standard_Character theOther) { - if (other != '\0') + if (theOther != '\0') { - reallocate(mylength + 1); - mystring[mylength - 1] = other; + reallocate(myLength + 1); + myString[myLength - 1] = theOther; } } //================================================================================================= -void TCollection_AsciiString::AssignCat(const Standard_CString theOther) +void TCollection_AsciiString::AssignCat(const Standard_CString theString, + const Standard_Integer theLength) { - if (theOther == NULL) + if (theLength == 0 || theString == nullptr) + return; + + // Check if theString points into our own buffer (self-assignment protection) + // Use std::less for well-defined pointer comparison (avoids undefined behavior) + const bool isSelfReference = + !std::less()(theString, myString) + && std::less()(theString, myString + myLength); + + if (isSelfReference) { - throw Standard_NullObject("TCollection_AsciiString::Operator += parameter other"); - } + // Self-reference: need to copy the data before reallocation + const Standard_Integer anOffset = static_cast(theString - myString); + const Standard_Integer anOldLength = myLength; + + reallocate(myLength + theLength); - Standard_Integer anOtherLen = Standard_Integer(strlen(theOther)); - if (anOtherLen != 0) + // After reallocation, copy from the updated position in the same buffer + memmove(myString + anOldLength, myString + anOffset, theLength); + } + else { - const Standard_Integer anOldLength = mylength; - reallocate(mylength + anOtherLen); - memcpy(mystring + anOldLength, theOther, anOtherLen + 1); + // Normal case: no overlap with our buffer + const Standard_Integer anOldLength = myLength; + reallocate(myLength + theLength); + memcpy(myString + anOldLength, theString, theLength); } + + myString[myLength] = '\0'; // Ensure null termination +} + +//================================================================================================= + +void TCollection_AsciiString::Capitalize() +{ + if (myLength) + myString[0] = ::UpperCase(myString[0]); + for (int i = 1; i < myLength; i++) + myString[i] = ::LowerCase(myString[i]); } //================================================================================================= -void TCollection_AsciiString::AssignCat(const TCollection_AsciiString& theOther) +TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_CString theString, + const Standard_Integer theLength) const { - if (theOther.mylength != 0) - { - const Standard_Integer anOldLength = mylength; - reallocate(mylength + theOther.mylength); - memcpy(mystring + anOldLength, theOther.mystring, theOther.mylength + 1); - } + TCollection_AsciiString aResult(*this); + aResult.AssignCat(theString, theLength); + return aResult; } //================================================================================================= -void TCollection_AsciiString::Capitalize() +TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_Integer theOther) const +{ + const FormattedInteger aFormatted(theOther); + return Cat(aFormatted.Buffer, aFormatted.Length); +} + +//================================================================================================= + +TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_Real theOther) const { - if (mylength) - mystring[0] = ::UpperCase(mystring[0]); - for (int i = 1; i < mylength; i++) - mystring[i] = ::LowerCase(mystring[i]); + const FormattedReal aFormatted(theOther); + return Cat(aFormatted.Buffer, aFormatted.Length); } //================================================================================================= -void TCollection_AsciiString::Center(const Standard_Integer Width, const Standard_Character Filler) +void TCollection_AsciiString::Center(const Standard_Integer theWidth, + const Standard_Character theFiller) { - if (Width > mylength) + if (theWidth > myLength) { - Standard_Integer newlength = mylength + ((Width - mylength) / 2); - LeftJustify(newlength, Filler); - RightJustify(Width, Filler); + Standard_Integer aNewLength = myLength + ((theWidth - myLength) / 2); + LeftJustify(aNewLength, theFiller); + RightJustify(theWidth, theFiller); } - else if (Width < 0) + else if (theWidth < 0) { throw Standard_NegativeValue(); } @@ -318,22 +361,22 @@ void TCollection_AsciiString::Center(const Standard_Integer Width, const Standar //================================================================================================= -void TCollection_AsciiString::ChangeAll(const Standard_Character aChar, - const Standard_Character NewChar, - const Standard_Boolean CaseSensitive) +void TCollection_AsciiString::ChangeAll(const Standard_Character theChar, + const Standard_Character theNewChar, + const Standard_Boolean theCaseSensitive) { - if (CaseSensitive) + if (theCaseSensitive) { - for (int i = 0; i < mylength; i++) - if (mystring[i] == aChar) - mystring[i] = NewChar; + for (int i = 0; i < myLength; i++) + if (myString[i] == theChar) + myString[i] = theNewChar; } else { - Standard_Character anUpperChar = ::UpperCase(aChar); - for (int i = 0; i < mylength; i++) - if (::UpperCase(mystring[i]) == anUpperChar) - mystring[i] = NewChar; + Standard_Character anUpperChar = ::UpperCase(theChar); + for (int i = 0; i < myLength; i++) + if (::UpperCase(myString[i]) == anUpperChar) + myString[i] = theNewChar; } } @@ -346,42 +389,33 @@ void TCollection_AsciiString::Clear() //================================================================================================= -void TCollection_AsciiString::Copy(const Standard_CString fromwhere) +void TCollection_AsciiString::Copy(const Standard_CString theString, + const Standard_Integer theLength) { - if (fromwhere == mystring) + if (myString == theString) { return; } - if (fromwhere && fromwhere[0] != '\0') - { - reallocate(static_cast(strlen(fromwhere))); - memcpy(mystring, fromwhere, mylength); - } - else - { - mylength = 0; - mystring = THE_DEFAULT_CHAR_STRING; - } -} - -//================================================================================================= - -void TCollection_AsciiString::Copy(const TCollection_AsciiString& fromwhere) -{ - if (&fromwhere == this) + if (theLength == 0 || theString == nullptr) { + deallocate(); + allocate(0); return; } - if (fromwhere.mystring && fromwhere.mylength > 0) + + if (theLength <= myLength) { - reallocate(fromwhere.mylength); - memcpy(mystring, fromwhere.mystring, mylength); + // Reuse existing buffer - just update length and null terminator + myLength = theLength; } - else if (mystring != THE_DEFAULT_CHAR_STRING) + else { - mylength = 0; - mystring[mylength] = '\0'; + // Need bigger buffer - deallocate and allocate fresh + deallocate(); + allocate(theLength); } + memcpy(myString, theString, myLength); + myString[myLength] = '\0'; } //================================================================================================= @@ -392,14 +426,14 @@ void TCollection_AsciiString::Move(TCollection_AsciiString&& theOther) { return; } - if (mystring != THE_DEFAULT_CHAR_STRING) + if (myString != THE_DEFAULT_CHAR_STRING) { - Standard::Free(mystring); + Standard::Free(myString); } - mystring = theOther.mystring; - mylength = theOther.mylength; - theOther.mystring = THE_DEFAULT_CHAR_STRING; - theOther.mylength = 0; + myString = theOther.myString; + myLength = theOther.myLength; + theOther.myString = THE_DEFAULT_CHAR_STRING; + theOther.myLength = 0; } //================================================================================================= @@ -410,8 +444,8 @@ void TCollection_AsciiString::Swap(TCollection_AsciiString& theOther) { return; } - std::swap(mystring, theOther.mystring); - std::swap(mylength, theOther.mylength); + std::swap(myString, theOther.myString); + std::swap(myLength, theOther.myLength); } //================================================================================================= @@ -423,17 +457,19 @@ TCollection_AsciiString::~TCollection_AsciiString() //================================================================================================= -Standard_Integer TCollection_AsciiString::FirstLocationInSet(const TCollection_AsciiString& Set, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const +Standard_Integer TCollection_AsciiString::FirstLocationInSet( + const Standard_CString theSet, + const Standard_Integer theSetLength, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const { - if (mylength == 0 || Set.mylength == 0) + if (myLength == 0 || theSetLength == 0) return 0; - if (FromIndex > 0 && ToIndex <= mylength && FromIndex <= ToIndex) + if (theFromIndex > 0 && theToIndex <= myLength && theFromIndex <= theToIndex) { - for (int i = FromIndex - 1; i < ToIndex; i++) - for (int j = 0; j < Set.mylength; j++) - if (mystring[i] == Set.mystring[j]) + for (int i = theFromIndex - 1; i < theToIndex; i++) + for (int j = 0; j < theSetLength; j++) + if (myString[i] == theSet[j]) return i + 1; return 0; } @@ -443,22 +479,23 @@ Standard_Integer TCollection_AsciiString::FirstLocationInSet(const TCollection_A //================================================================================================= Standard_Integer TCollection_AsciiString::FirstLocationNotInSet( - const TCollection_AsciiString& Set, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const + const Standard_CString theSet, + const Standard_Integer theSetLength, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const { - if (mylength == 0 || Set.mylength == 0) + if (myLength == 0 || theSetLength == 0) return 0; - if (FromIndex > 0 && ToIndex <= mylength && FromIndex <= ToIndex) + if (theFromIndex > 0 && theToIndex <= myLength && theFromIndex <= theToIndex) { - Standard_Boolean find; - for (int i = FromIndex - 1; i < ToIndex; i++) + Standard_Boolean aFind; + for (int i = theFromIndex - 1; i < theToIndex; i++) { - find = Standard_False; - for (int j = 0; j < Set.mylength; j++) - if (mystring[i] == Set.mystring[j]) - find = Standard_True; - if (!find) + aFind = Standard_False; + for (int j = 0; j < theSetLength; j++) + if (myString[i] == theSet[j]) + aFind = Standard_True; + if (!aFind) return i + 1; } return 0; @@ -468,237 +505,182 @@ Standard_Integer TCollection_AsciiString::FirstLocationNotInSet( //================================================================================================= -void TCollection_AsciiString::Insert(const Standard_Integer where, const Standard_Character what) +void TCollection_AsciiString::Insert(const Standard_Integer theWhere, + const Standard_Character theWhat) { - if (where > mylength + 1) - throw Standard_OutOfRange("TCollection_AsciiString::Insert : Parameter where is too big"); - if (where < 1) - throw Standard_OutOfRange("TCollection_AsciiString::Insert : Parameter where is too small"); + if (theWhere > myLength + 1) + throw Standard_OutOfRange("TCollection_AsciiString::Insert : Parameter theWhere is too big"); + if (theWhere < 1) + throw Standard_OutOfRange("TCollection_AsciiString::Insert : Parameter theWhere is too small"); - const int anOldLength = mylength; - reallocate(mylength + 1); - if (where != anOldLength + 1) + const int anOldLength = myLength; + reallocate(myLength + 1); + if (theWhere != anOldLength + 1) { - for (int i = anOldLength - 1; i >= where - 1; i--) - mystring[i + 1] = mystring[i]; + for (int i = anOldLength - 1; i >= theWhere - 1; i--) + myString[i + 1] = myString[i]; } - mystring[where - 1] = what; + myString[theWhere - 1] = theWhat; } //================================================================================================= -void TCollection_AsciiString::Insert(const Standard_Integer where, const Standard_CString what) +void TCollection_AsciiString::Insert(const Standard_Integer theWhere, + const Standard_CString theString, + const Standard_Integer theLength) { - if (where <= mylength + 1 && where > 0) + if (theWhere < 1 || theWhere > myLength + 1) + throw Standard_OutOfRange("TCollection_AsciiString::Insert : parameter theWhere"); + + if (theLength == 0 || theString == nullptr) + return; + + const int anInsertSize = theLength; + const int anOldLength = myLength; + const int aNewLength = anOldLength + anInsertSize; + const int anInsertIndex = theWhere - 1; + + // Check if theString points into our own buffer (self-reference protection) + // Use std::less for well-defined pointer comparison (avoids undefined behavior) + const bool isSelfReference = + !std::less()(theString, myString) + && std::less()(theString, myString + myLength); + + if (isSelfReference) { - if (what) + // Self-reference: save offset, reallocate, then handle the shifted source + const Standard_Integer anOffset = static_cast(theString - myString); + + reallocate(aNewLength); + + // Shift existing characters to the right + if (anInsertIndex < anOldLength) { - const Standard_Integer whatlength = Standard_Integer(strlen(what)); - const int anOldLength = mylength; - reallocate(mylength + whatlength); - if (where != anOldLength + 1) - { - for (int i = anOldLength - 1; i >= where - 1; i--) - mystring[i + whatlength] = mystring[i]; - } - for (int i = 0; i < whatlength; i++) - mystring[where - 1 + i] = what[i]; + memmove(myString + anInsertIndex + anInsertSize, + myString + anInsertIndex, + anOldLength - anInsertIndex); } + + // After the shift, if the source was at or after the insertion point, + // it has been shifted by anInsertSize positions to the right + const Standard_Integer aSourceOffset = + (anOffset >= anInsertIndex) ? (anOffset + anInsertSize) : anOffset; + + // Insert from the recalculated position in the same buffer using memmove + memmove(myString + anInsertIndex, myString + aSourceOffset, anInsertSize); } else { - throw Standard_OutOfRange("TCollection_AsciiString::Insert : " - "Parameter where is invalid"); - } -} + // Normal case: no overlap with our buffer + reallocate(aNewLength); -//================================================================================================= - -void TCollection_AsciiString::Insert(const Standard_Integer where, - const TCollection_AsciiString& what) -{ - Standard_CString swhat = what.mystring; - if (where <= mylength + 1) - { - const Standard_Integer whatlength = what.mylength; - if (whatlength) + // Shift existing characters to the right + if (anInsertIndex < anOldLength) { - const int anOldLength = mylength; - reallocate(mylength + whatlength); - - if (where != anOldLength + 1) - { - for (int i = anOldLength - 1; i >= where - 1; i--) - mystring[i + whatlength] = mystring[i]; - } - for (int i = 0; i < whatlength; i++) - mystring[where - 1 + i] = swhat[i]; + memmove(myString + anInsertIndex + anInsertSize, + myString + anInsertIndex, + anOldLength - anInsertIndex); } - } - else - { - throw Standard_OutOfRange("TCollection_AsciiString::Insert : " - "Parameter where is too big"); + + // Insert the new content + memcpy(myString + anInsertIndex, theString, anInsertSize); } } //================================================================================================= -void TCollection_AsciiString::InsertAfter(const Standard_Integer Index, - const TCollection_AsciiString& what) +void TCollection_AsciiString::InsertAfter(const Standard_Integer theIndex, + const Standard_CString theString, + const Standard_Integer theLength) { - if (Index < 0 || Index > mylength) + if (theIndex < 0 || theIndex > myLength) throw Standard_OutOfRange(); - Insert(Index + 1, what); + Insert(theIndex + 1, theString, theLength); } //================================================================================================= -void TCollection_AsciiString::InsertBefore(const Standard_Integer Index, - const TCollection_AsciiString& what) +void TCollection_AsciiString::InsertBefore(const Standard_Integer theIndex, + const Standard_CString theString, + const Standard_Integer theLength) { - if (Index < 1 || Index > mylength) + if (theIndex < 1 || theIndex > myLength) throw Standard_OutOfRange(); - Insert(Index, what); -} - -//================================================================================================= - -Standard_Boolean TCollection_AsciiString::IsEqual(const Standard_CString other) const -{ - if (other) - { - return (strncmp(other, mystring, mylength + 1) == 0); - } - throw Standard_NullObject("TCollection_AsciiString::Operator == " - "Parameter 'other'"); + Insert(theIndex, theString, theLength); } //================================================================================================= -Standard_Boolean TCollection_AsciiString::IsEqual(const TCollection_AsciiString& other) const +Standard_Boolean TCollection_AsciiString::IsEqual(const Standard_CString theString, + const Standard_Integer theLength) const { - if (mylength != other.mylength) + if (myLength != theLength) return Standard_False; - return (strncmp(other.mystring, mystring, mylength) == 0); -} - -//================================================================================================= - -Standard_Boolean TCollection_AsciiString::IsSameString(const TCollection_AsciiString& theString1, - const TCollection_AsciiString& theString2, - const Standard_Boolean theIsCaseSensitive) -{ - const Standard_Integer aSize1 = theString1.Length(); - if (aSize1 != theString2.Length()) - { - return Standard_False; - } - - if (theIsCaseSensitive) - { - return (strncmp(theString1.ToCString(), theString2.ToCString(), aSize1) == 0); - } - - for (Standard_Integer aCharIter = 1; aCharIter <= aSize1; ++aCharIter) - { - if (toupper(theString1.Value(aCharIter)) != toupper(theString2.Value(aCharIter))) - { - return Standard_False; - } - } - return Standard_True; -} -//================================================================================================= + if (myLength == 0) + return Standard_True; -Standard_Boolean TCollection_AsciiString::IsDifferent(const Standard_CString other) const -{ - if (other) - { - return (strncmp(other, mystring, mylength + 1) != 0); - } - throw Standard_NullObject("TCollection_AsciiString::Operator != " - "Parameter 'other'"); + return memcmp(myString, theString, myLength) == 0; } //================================================================================================= -Standard_Boolean TCollection_AsciiString::IsDifferent(const TCollection_AsciiString& other) const +Standard_Boolean TCollection_AsciiString::IsLess(const Standard_CString theString, + const Standard_Integer theLength) const { + const int aMinLength = std::min(myLength, theLength); + const int aResult = memcmp(myString, theString, aMinLength); - if (mylength != other.mylength) + if (aResult < 0) return Standard_True; - return (strncmp(other.mystring, mystring, mylength) != 0); -} - -//================================================================================================= + if (aResult > 0) + return Standard_False; -Standard_Boolean TCollection_AsciiString::IsLess(const Standard_CString other) const -{ - if (other) - { - return (strncmp(mystring, other, mylength + 1) < 0); - } - throw Standard_NullObject("TCollection_AsciiString::Operator < " - "Parameter 'other'"); + return myLength < theLength; } //================================================================================================= -Standard_Boolean TCollection_AsciiString::IsLess(const TCollection_AsciiString& other) const +Standard_Boolean TCollection_AsciiString::IsGreater(const Standard_CString theString, + const Standard_Integer theLength) const { - return (strncmp(mystring, other.mystring, mylength + 1) < 0); -} + const int aMinLength = std::min(myLength, theLength); + const int aResult = memcmp(myString, theString, aMinLength); -//================================================================================================= + if (aResult > 0) + return Standard_True; + if (aResult < 0) + return Standard_False; -Standard_Boolean TCollection_AsciiString::IsGreater(const Standard_CString other) const -{ - if (other) - { - return (strncmp(mystring, other, mylength + 1) > 0); - } - throw Standard_NullObject("TCollection_AsciiString::Operator > " - "Parameter 'other'"); + return myLength > theLength; } //================================================================================================= -Standard_Boolean TCollection_AsciiString::IsGreater(const TCollection_AsciiString& other) const +Standard_Boolean TCollection_AsciiString::StartsWith(const Standard_CString theStartString, + const Standard_Integer theStartLength) const { - return (strncmp(mystring, other.mystring, mylength + 1) > 0); -} - -//================================================================================================= + if (theStartLength > myLength) + return Standard_False; -Standard_Boolean TCollection_AsciiString::StartsWith( - const TCollection_AsciiString& theStartString) const -{ - if (this == &theStartString) - { - return true; - } + if (theStartLength == 0) + return Standard_True; - return mylength >= theStartString.mylength - && strncmp(theStartString.mystring, mystring, theStartString.mylength) == 0; + return memcmp(myString, theStartString, theStartLength) == 0; } //================================================================================================= -Standard_Boolean TCollection_AsciiString::EndsWith( - const TCollection_AsciiString& theEndString) const +Standard_Boolean TCollection_AsciiString::EndsWith(const Standard_CString theEndString, + const Standard_Integer theEndLength) const { - if (this == &theEndString) - { - return true; - } + if (theEndLength > myLength) + return Standard_False; + + if (theEndLength == 0) + return Standard_True; - return mylength >= theEndString.mylength - && strncmp(theEndString.mystring, - mystring + mylength - theEndString.mylength, - theEndString.mylength) - == 0; + return memcmp(myString + myLength - theEndLength, theEndString, theEndLength) == 0; } //================================================================================================= @@ -706,8 +688,8 @@ Standard_Boolean TCollection_AsciiString::EndsWith( Standard_Integer TCollection_AsciiString::IntegerValue() const { char* ptr; - Standard_Integer value = (Standard_Integer)strtol(mystring, &ptr, 10); - if (ptr != mystring) + Standard_Integer value = (Standard_Integer)strtol(myString, &ptr, 10); + if (ptr != myString) return value; throw Standard_NumericError("TCollection_AsciiString::IntegerValue"); @@ -718,13 +700,13 @@ Standard_Integer TCollection_AsciiString::IntegerValue() const Standard_Boolean TCollection_AsciiString::IsIntegerValue() const { char* ptr; - strtol(mystring, &ptr, 10); + strtol(myString, &ptr, 10); - if (ptr != mystring) + if (ptr != myString) { - for (int i = int(ptr - mystring); i < mylength; i++) + for (int i = int(ptr - myString); i < myLength; i++) { - if (mystring[i] == '.') + if (myString[i] == '.') return Standard_False; // what about 'e','x',etc ??? } return Standard_True; @@ -737,14 +719,14 @@ Standard_Boolean TCollection_AsciiString::IsIntegerValue() const Standard_Boolean TCollection_AsciiString::IsRealValue(Standard_Boolean theToCheckFull) const { char* ptr; - Strtod(mystring, &ptr); + Strtod(myString, &ptr); if (theToCheckFull) { return (ptr[0] == '\0'); } else { - return (ptr != mystring); + return (ptr != myString); } } @@ -754,8 +736,8 @@ Standard_Boolean TCollection_AsciiString::IsAscii() const { // LD : Debuggee le 26/11/98 // Cette fonction retournait TOUJOURS Standard_True ! - for (int i = 0; i < mylength; i++) - if (mystring[i] >= 127 || mystring[i] < ' ') + for (int i = 0; i < myLength; i++) + if (myString[i] >= 127 || myString[i] < ' ') return Standard_False; return Standard_True; } @@ -765,8 +747,8 @@ Standard_Boolean TCollection_AsciiString::IsAscii() const void TCollection_AsciiString::LeftAdjust() { Standard_Integer i; - for (i = 0; i < mylength; i++) - if (!IsSpace(mystring[i])) + for (i = 0; i < myLength; i++) + if (!IsSpace(myString[i])) break; if (i > 0) Remove(1, i); @@ -774,17 +756,17 @@ void TCollection_AsciiString::LeftAdjust() //================================================================================================= -void TCollection_AsciiString::LeftJustify(const Standard_Integer Width, - const Standard_Character Filler) +void TCollection_AsciiString::LeftJustify(const Standard_Integer theWidth, + const Standard_Character theFiller) { - if (Width > mylength) + if (theWidth > myLength) { - const int anOldLength = mylength; - reallocate(Width); - for (int i = anOldLength; i < Width; i++) - mystring[i] = Filler; + const int anOldLength = myLength; + reallocate(theWidth); + for (int i = anOldLength; i < theWidth; i++) + myString[i] = theFiller; } - else if (Width < 0) + else if (theWidth < 0) { throw Standard_NegativeValue(); } @@ -792,19 +774,19 @@ void TCollection_AsciiString::LeftJustify(const Standard_Integer Width, //================================================================================================= -Standard_Integer TCollection_AsciiString::Location(const Standard_Integer N, - const Standard_Character C, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const +Standard_Integer TCollection_AsciiString::Location(const Standard_Integer theN, + const Standard_Character theC, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const { - if (FromIndex > 0 && ToIndex <= mylength && FromIndex <= ToIndex) + if (theFromIndex > 0 && theToIndex <= myLength && theFromIndex <= theToIndex) { - for (int i = FromIndex - 1, count = 0; i <= ToIndex - 1; i++) + for (int i = theFromIndex - 1, aCount = 0; i <= theToIndex - 1; i++) { - if (mystring[i] == C) + if (myString[i] == theC) { - count++; - if (count == N) + aCount++; + if (aCount == theN) return i + 1; } } @@ -815,25 +797,25 @@ Standard_Integer TCollection_AsciiString::Location(const Standard_Integer N, //================================================================================================= -Standard_Integer TCollection_AsciiString::Location(const TCollection_AsciiString& what, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const +Standard_Integer TCollection_AsciiString::Location(const TCollection_AsciiString& theWhat, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const { - if (mylength == 0 || what.mylength == 0) + if (myLength == 0 || theWhat.myLength == 0) return 0; - if (ToIndex <= mylength && FromIndex > 0 && FromIndex <= ToIndex) + if (theToIndex <= myLength && theFromIndex > 0 && theFromIndex <= theToIndex) { - Standard_Integer i = FromIndex - 1; - Standard_Integer k = 1; - Standard_Integer l = FromIndex - 2; - Standard_Boolean Find = Standard_False; - while (!Find && i < ToIndex) + Standard_Integer i = theFromIndex - 1; + Standard_Integer k = 1; + Standard_Integer l = theFromIndex - 2; + Standard_Boolean aFind = Standard_False; + while (!aFind && i < theToIndex) { - if (mystring[i] == what.Value(k)) + if (myString[i] == theWhat.Value(k)) { k++; - if (k > what.mylength) - Find = Standard_True; + if (k > theWhat.myLength) + aFind = Standard_True; } else { @@ -844,7 +826,7 @@ Standard_Integer TCollection_AsciiString::Location(const TCollection_AsciiString } i++; } - if (Find) + if (aFind) return l + 2; else return 0; @@ -856,15 +838,15 @@ Standard_Integer TCollection_AsciiString::Location(const TCollection_AsciiString void TCollection_AsciiString::LowerCase() { - for (int i = 0; i < mylength; i++) - mystring[i] = ::LowerCase(mystring[i]); + for (int i = 0; i < myLength; i++) + myString[i] = ::LowerCase(myString[i]); } //================================================================================================= -void TCollection_AsciiString::Prepend(const TCollection_AsciiString& what) +void TCollection_AsciiString::Prepend(const TCollection_AsciiString& theWhat) { - Insert(1, what); + Insert(1, theWhat); } //================================================================================================= @@ -872,8 +854,8 @@ void TCollection_AsciiString::Prepend(const TCollection_AsciiString& what) Standard_Real TCollection_AsciiString::RealValue() const { char* ptr; - Standard_Real value = Strtod(mystring, &ptr); - if (ptr != mystring) + Standard_Real value = Strtod(myString, &ptr); + if (ptr != myString) return value; throw Standard_NumericError("TCollection_AsciiString::RealValue"); @@ -881,18 +863,18 @@ Standard_Real TCollection_AsciiString::RealValue() const //================================================================================================= -void TCollection_AsciiString::Read(Standard_IStream& astream) +void TCollection_AsciiString::Read(Standard_IStream& theStream) { - // get characters from astream + // get characters from theStream const Standard_Integer bufSize = 8190; Standard_Character buffer[bufSize]; - std::streamsize oldWidth = astream.width(bufSize); - astream >> buffer; - astream.width(oldWidth); + std::streamsize oldWidth = theStream.width(bufSize); + theStream >> buffer; + theStream.width(oldWidth); // put to string reallocate(Standard_Integer(strlen(buffer))); - memcpy(mystring, buffer, mylength); + memcpy(myString, buffer, myLength); } //--------------------------------------------------------------------------- @@ -904,10 +886,10 @@ Standard_IStream& operator>>(Standard_IStream& astream, TCollection_AsciiString& //================================================================================================= -void TCollection_AsciiString::Print(Standard_OStream& astream) const +void TCollection_AsciiString::Print(Standard_OStream& theStream) const { - if (mystring) - astream << mystring; + if (myString) + theStream << myString; } // ---------------------------------------------------------------------------- @@ -919,45 +901,47 @@ Standard_OStream& operator<<(Standard_OStream& astream, const TCollection_AsciiS //================================================================================================= -void TCollection_AsciiString::RemoveAll(const Standard_Character what, - const Standard_Boolean CaseSensitive) +void TCollection_AsciiString::RemoveAll(const Standard_Character theWhat, + const Standard_Boolean theCaseSensitive) { - if (mylength == 0) + if (myLength == 0) { return; } - const Standard_Character aTargetChar = CaseSensitive ? what : ::UpperCase(what); + const Standard_Character aTargetChar = theCaseSensitive ? theWhat : ::UpperCase(theWhat); int aNewLength = 0; - for (int i = 0; i < mylength; ++i) + for (int i = 0; i < myLength; ++i) { - const Standard_Character aCurrentChar = CaseSensitive ? mystring[i] : ::UpperCase(mystring[i]); + const Standard_Character aCurrentChar = + theCaseSensitive ? myString[i] : ::UpperCase(myString[i]); if (aCurrentChar != aTargetChar) { - mystring[aNewLength++] = mystring[i]; + myString[aNewLength++] = myString[i]; } } - mylength = aNewLength; - mystring[mylength] = '\0'; + myLength = aNewLength; + myString[myLength] = '\0'; } //================================================================================================= -void TCollection_AsciiString::RemoveAll(const Standard_Character what) +void TCollection_AsciiString::RemoveAll(const Standard_Character theWhat) { - RemoveAll(what, Standard_True); + RemoveAll(theWhat, Standard_True); } //================================================================================================= -void TCollection_AsciiString::Remove(const Standard_Integer where, const Standard_Integer ahowmany) +void TCollection_AsciiString::Remove(const Standard_Integer theWhere, + const Standard_Integer theHowMany) { - if (where + ahowmany <= mylength + 1) + if (theWhere + theHowMany <= myLength + 1) { int i, j; - for (i = where + ahowmany - 1, j = where - 1; i < mylength; i++, j++) - mystring[j] = mystring[i]; - mylength -= ahowmany; - mystring[mylength] = '\0'; + for (i = theWhere + theHowMany - 1, j = theWhere - 1; i < myLength; i++, j++) + myString[j] = myString[i]; + myLength -= theHowMany; + myString[myLength] = '\0'; } else { @@ -972,29 +956,29 @@ void TCollection_AsciiString::Remove(const Standard_Integer where, const Standar void TCollection_AsciiString::RightAdjust() { Standard_Integer i; - for (i = mylength - 1; i >= 0; i--) - if (!IsSpace(mystring[i])) + for (i = myLength - 1; i >= 0; i--) + if (!IsSpace(myString[i])) break; - if (i < mylength - 1) - Remove(i + 2, mylength - (i + 2) + 1); + if (i < myLength - 1) + Remove(i + 2, myLength - (i + 2) + 1); } //================================================================================================= -void TCollection_AsciiString::RightJustify(const Standard_Integer Width, - const Standard_Character Filler) +void TCollection_AsciiString::RightJustify(const Standard_Integer theWidth, + const Standard_Character theFiller) { - if (Width > mylength) + if (theWidth > myLength) { - const int anOldLength = mylength; - reallocate(Width); + const int anOldLength = myLength; + reallocate(theWidth); int i, k; - for (i = anOldLength - 1, k = Width - 1; i >= 0; i--, k--) - mystring[k] = mystring[i]; + for (i = anOldLength - 1, k = theWidth - 1; i >= 0; i--, k--) + myString[k] = myString[i]; for (; k >= 0; k--) - mystring[k] = Filler; + myString[k] = theFiller; } - else if (Width < 0) + else if (theWidth < 0) { throw Standard_NegativeValue(); } @@ -1002,42 +986,17 @@ void TCollection_AsciiString::RightJustify(const Standard_Integer Width, //================================================================================================= -Standard_Integer TCollection_AsciiString::Search(const Standard_CString what) const +Standard_Integer TCollection_AsciiString::Search(const Standard_CString theWhat, + const Standard_Integer theWhatLength) const { - Standard_Integer size = Standard_Integer(what ? strlen(what) : 0); - if (size) - { - int k, j; - int i = 0; - while (i < mylength - size + 1) - { - k = i++; - j = 0; - while (j < size && mystring[k++] == what[j++]) - if (j == size) - return i; - } - } - return -1; -} + if (theWhatLength == 0) + return -1; -//================================================================================================= - -Standard_Integer TCollection_AsciiString::Search(const TCollection_AsciiString& what) const -{ - Standard_Integer size = what.mylength; - Standard_CString swhat = what.mystring; - if (size) + for (int i = 0; i <= myLength - theWhatLength; ++i) { - int k, j; - int i = 0; - while (i < mylength - size + 1) + if (memcmp(myString + i, theWhat, theWhatLength) == 0) { - k = i++; - j = 0; - while (j < size && mystring[k++] == swhat[j++]) - if (j == size) - return i; + return i + 1; // Return 1-based position } } return -1; @@ -1045,42 +1004,17 @@ Standard_Integer TCollection_AsciiString::Search(const TCollection_AsciiString& //================================================================================================= -Standard_Integer TCollection_AsciiString::SearchFromEnd(const Standard_CString what) const +Standard_Integer TCollection_AsciiString::SearchFromEnd(const Standard_CString theWhat, + const Standard_Integer theWhatLength) const { - Standard_Integer size = Standard_Integer(what ? strlen(what) : 0); - if (size) - { - int k, j; - int i = mylength - 1; - while (i >= size - 1) - { - k = i--; - j = size - 1; - while (j >= 0 && mystring[k--] == what[j--]) - if (j == -1) - return i - size + 3; - } - } - return -1; -} + if (theWhatLength == 0) + return -1; -//================================================================================================= - -Standard_Integer TCollection_AsciiString::SearchFromEnd(const TCollection_AsciiString& what) const -{ - int size = what.mylength; - if (size) + for (int i = myLength - theWhatLength; i >= 0; --i) { - Standard_CString swhat = what.mystring; - int k, j; - int i = mylength - 1; - while (i >= size - 1) + if (memcmp(myString + i, theWhat, theWhatLength) == 0) { - k = i--; - j = size - 1; - while (j >= 0 && mystring[k--] == swhat[j--]) - if (j == -1) - return i - size + 3; + return i + 1; // Return 1-based position } } return -1; @@ -1091,7 +1025,7 @@ Standard_Integer TCollection_AsciiString::SearchFromEnd(const TCollection_AsciiS void TCollection_AsciiString::SetValue(const Standard_Integer theWhere, const Standard_Character theWhat) { - if (theWhere <= 0 || theWhere > mylength) + if (theWhere <= 0 || theWhere > myLength) { throw Standard_OutOfRange("TCollection_AsciiString::SetValue(): out of range location"); } @@ -1099,146 +1033,134 @@ void TCollection_AsciiString::SetValue(const Standard_Integer theWhere, { throw Standard_OutOfRange("TCollection_AsciiString::SetValue(): NULL terminator is passed"); } - mystring[theWhere - 1] = theWhat; + myString[theWhere - 1] = theWhat; } //================================================================================================= -void TCollection_AsciiString::SetValue(const Standard_Integer where, const Standard_CString what) +void TCollection_AsciiString::SetValue(const Standard_Integer theWhere, + const Standard_CString theString, + const Standard_Integer theLength) { - if (where > 0 && where <= mylength + 1) - { - Standard_Integer size = Standard_Integer(what ? strlen(what) : 0); - size += (where - 1); - if (size >= mylength) - { - reallocate(size); - } - for (int i = where - 1; i < size; i++) - mystring[i] = what[i - (where - 1)]; - } - else + if (theWhere <= 0) + throw Standard_OutOfRange("TCollection_AsciiString::SetValue"); + + const int anInsertSize = theLength; + const int aNewLength = theWhere - 1 + anInsertSize; + + if (aNewLength > myLength) { - throw Standard_OutOfRange("TCollection_AsciiString::SetValue : " - "parameter where"); + reallocate(aNewLength); } + + memcpy(myString + theWhere - 1, theString, anInsertSize); } //================================================================================================= -void TCollection_AsciiString::SetValue(const Standard_Integer where, - const TCollection_AsciiString& what) +TCollection_AsciiString TCollection_AsciiString::Split(const Standard_Integer theWhere) { - if (where > 0 && where <= mylength + 1) - { - Standard_Integer size = what.mylength; - Standard_CString swhat = what.mystring; - size += (where - 1); - if (size >= mylength) - { - reallocate(size); - } - for (int i = where - 1; i < size; i++) - mystring[i] = swhat[i - (where - 1)]; - } - else + if (theWhere >= 0 && theWhere <= myLength) { - throw Standard_OutOfRange("TCollection_AsciiString::SetValue : " - "parameter where"); + TCollection_AsciiString res(&myString[theWhere], myLength - theWhere); + Trunc(theWhere); + return res; } + throw Standard_OutOfRange("TCollection_AsciiString::Split index"); } //================================================================================================= -TCollection_AsciiString TCollection_AsciiString::Split(const Standard_Integer where) +TCollection_AsciiString TCollection_AsciiString::SubString(const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const { - if (where >= 0 && where <= mylength) - { - TCollection_AsciiString res(&mystring[where], mylength - where); - Trunc(where); - return res; - } - throw Standard_OutOfRange("TCollection_AsciiString::Split index"); + // note the we are doing here weird casts just to suppress annoying and meaningless warning + // -Wstrict-overflow + Standard_OutOfRange_Always_Raise_if(theFromIndex <= 0 || theToIndex <= 0 + || (unsigned int)theToIndex > (unsigned int)myLength + || (unsigned int)theFromIndex > (unsigned int)theToIndex, + "TCollection_AsciiString::SubString() out of range"); + return TCollection_AsciiString(&myString[theFromIndex - 1], theToIndex - theFromIndex + 1); } //================================================================================================= -TCollection_AsciiString TCollection_AsciiString::Token(const Standard_CString separators, - const Standard_Integer whichone) const +TCollection_AsciiString TCollection_AsciiString::Token(const Standard_CString theSeparators, + const Standard_Integer theWhichOne) const { - if (!separators) + if (!theSeparators) throw Standard_NullObject("TCollection_AsciiString::Token : " - "parameter 'separators'"); + "parameter 'theSeparators'"); - Standard_Integer theOne; - Standard_Integer StringIndex = 0; - Standard_Integer SeparatorIndex; - Standard_Integer BeginIndex = 0; - Standard_Integer EndIndex = 0; + Standard_Integer anIndex; + Standard_Integer aStringIndex = 0; + Standard_Integer aSeparatorIndex; + Standard_Integer aBeginIndex = 0; + Standard_Integer anEndIndex = 0; - // std::cout << "'" << mystring << "'" << std::endl ; - for (theOne = 0; theOne < whichone; theOne++) + // std::cout << "'" << myString << "'" << std::endl ; + for (anIndex = 0; anIndex < theWhichOne; anIndex++) { - BeginIndex = 0; - EndIndex = 0; - // std::cout << "theOne " << theOne << std::endl ; - if (StringIndex == mylength) + aBeginIndex = 0; + anEndIndex = 0; + // std::cout << "anIndex " << anIndex << std::endl ; + if (aStringIndex == myLength) break; - for (; StringIndex < mylength && EndIndex == 0; StringIndex++) + for (; aStringIndex < myLength && anEndIndex == 0; aStringIndex++) { - SeparatorIndex = 0; - // std::cout << "StringIndex " << StringIndex << std::endl ; - while (separators[SeparatorIndex]) + aSeparatorIndex = 0; + // std::cout << "aStringIndex " << aStringIndex << std::endl ; + while (theSeparators[aSeparatorIndex]) { - if (mystring[StringIndex] == separators[SeparatorIndex]) + if (myString[aStringIndex] == theSeparators[aSeparatorIndex]) { break; } - SeparatorIndex += 1; + aSeparatorIndex += 1; } - if (separators[SeparatorIndex] != '\0') + if (theSeparators[aSeparatorIndex] != '\0') { // We have a Separator - if (BeginIndex && EndIndex == 0) + if (aBeginIndex && anEndIndex == 0) { - EndIndex = StringIndex; - // std::cout << "EndIndex " << EndIndex << " '" << SubString( BeginIndex , - // EndIndex ).ToCString() << "'" << std::endl ; + anEndIndex = aStringIndex; + // std::cout << "anEndIndex " << anEndIndex << " '" << SubString( aBeginIndex , + // anEndIndex ).ToCString() << "'" << std::endl ; break; } } - else if (BeginIndex == 0) + else if (aBeginIndex == 0) { // We have not a Separator - BeginIndex = StringIndex + 1; - // std::cout << "BeginIndex " << BeginIndex << std::endl ; + aBeginIndex = aStringIndex + 1; + // std::cout << "aBeginIndex " << aBeginIndex << std::endl ; } } - // std::cout << "BeginIndex " << BeginIndex << " EndIndex " << EndIndex << std::endl ; + // std::cout << "aBeginIndex " << aBeginIndex << " anEndIndex " << anEndIndex << std::endl ; } - if (BeginIndex == 0) + if (aBeginIndex == 0) return TCollection_AsciiString("", 0); - if (EndIndex == 0) - EndIndex = mylength; - // std::cout << "'" << SubString( BeginIndex , EndIndex ).ToCString() << "'" << std::endl ; - return TCollection_AsciiString(&mystring[BeginIndex - 1], EndIndex - BeginIndex + 1); + if (anEndIndex == 0) + anEndIndex = myLength; + // std::cout << "'" << SubString( aBeginIndex , anEndIndex ).ToCString() << "'" << std::endl ; + return TCollection_AsciiString(&myString[aBeginIndex - 1], anEndIndex - aBeginIndex + 1); } //================================================================================================= -void TCollection_AsciiString::Trunc(const Standard_Integer ahowmany) +void TCollection_AsciiString::Trunc(const Standard_Integer theHowMany) { - if (ahowmany < 0 || ahowmany > mylength) + if (theHowMany < 0 || theHowMany > myLength) throw Standard_OutOfRange("TCollection_AsciiString::Trunc : " - "parameter 'ahowmany'"); - mylength = ahowmany; - mystring[mylength] = '\0'; + "parameter 'theHowMany'"); + myLength = theHowMany; + myString[myLength] = '\0'; } //================================================================================================= void TCollection_AsciiString::UpperCase() { - for (int i = 0; i < mylength; i++) - mystring[i] = ::UpperCase(mystring[i]); + for (int i = 0; i < myLength; i++) + myString[i] = ::UpperCase(myString[i]); } //================================================================================================= @@ -1246,37 +1168,37 @@ void TCollection_AsciiString::UpperCase() Standard_Integer TCollection_AsciiString::UsefullLength() const { Standard_Integer i; - for (i = mylength - 1; i >= 0; i--) - if (IsGraphic(mystring[i])) + for (i = myLength - 1; i >= 0; i--) + if (IsGraphic(myString[i])) break; return i + 1; } //================================================================================================= -Standard_Character TCollection_AsciiString::Value(const Standard_Integer where) const +Standard_Character TCollection_AsciiString::Value(const Standard_Integer theWhere) const { - if (where > 0 && where <= mylength) + if (theWhere > 0 && theWhere <= myLength) { - return mystring[where - 1]; + return myString[theWhere - 1]; } - throw Standard_OutOfRange("TCollection_AsciiString::Value : parameter where"); + throw Standard_OutOfRange("TCollection_AsciiString::Value : parameter theWhere"); } //================================================================================================= void TCollection_AsciiString::allocate(const int theLength) { - mylength = theLength; + myLength = theLength; if (theLength == 0) { - mystring = THE_DEFAULT_CHAR_STRING; + myString = THE_DEFAULT_CHAR_STRING; } else { const Standard_Size aRoundSize = calculatePaddedSize(theLength); - mystring = static_cast(Standard::AllocateOptimal(aRoundSize)); - mystring[mylength] = '\0'; + myString = static_cast(Standard::AllocateOptimal(aRoundSize)); + myString[myLength] = '\0'; } } @@ -1286,35 +1208,64 @@ void TCollection_AsciiString::reallocate(const int theLength) { if (theLength != 0) { - if (mystring == THE_DEFAULT_CHAR_STRING) + if (myString == THE_DEFAULT_CHAR_STRING) { // Use same padding strategy as allocate() for consistency const Standard_Size aRoundSize = calculatePaddedSize(theLength); - mystring = static_cast(Standard::AllocateOptimal(aRoundSize)); + myString = static_cast(Standard::AllocateOptimal(aRoundSize)); } else { // For existing allocations, use padding size with Standard::Reallocate const Standard_Size aRoundSize = calculatePaddedSize(theLength); - mystring = static_cast(Standard::Reallocate(mystring, aRoundSize)); + myString = static_cast(Standard::Reallocate(myString, aRoundSize)); } - mystring[theLength] = '\0'; } - if (mystring != THE_DEFAULT_CHAR_STRING) + // Ensure null termination at new length + if (myString != THE_DEFAULT_CHAR_STRING) { - mystring[theLength] = '\0'; + myString[theLength] = '\0'; } - mylength = theLength; + myLength = theLength; } //================================================================================================= void TCollection_AsciiString::deallocate() { - if (mystring != THE_DEFAULT_CHAR_STRING) + if (myString != THE_DEFAULT_CHAR_STRING) { - Standard::Free(mystring); + Standard::Free(myString); + } + myLength = 0; + myString = THE_DEFAULT_CHAR_STRING; +} + +//================================================================================================= + +Standard_Boolean TCollection_AsciiString::IsSameString(const Standard_CString theString1, + const Standard_Integer theLength1, + const Standard_CString theString2, + const Standard_Integer theLength2, + const Standard_Boolean theIsCaseSensitive) +{ + if (theLength1 != theLength2) + return Standard_False; + + if (theLength1 == 0) + return Standard_True; + + if (theIsCaseSensitive) + { + return memcmp(theString1, theString2, theLength1) == 0; + } + else + { + for (Standard_Integer anIndex = 0; anIndex < theLength1; ++anIndex) + { + if (::UpperCase(theString1[anIndex]) != ::UpperCase(theString2[anIndex])) + return Standard_False; + } + return Standard_True; } - mylength = 0; - mystring = THE_DEFAULT_CHAR_STRING; } diff --git a/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.hxx b/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.hxx index ee2dc0056c..b2df46f5cc 100644 --- a/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.hxx +++ b/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.hxx @@ -27,6 +27,11 @@ #include #include #include + +#if __cplusplus >= 201703L + #include +#endif + class TCollection_ExtendedString; //! Class defines a variable-length sequence of 8-bit characters. @@ -52,54 +57,78 @@ public: //! Initializes a AsciiString to an empty AsciiString. Standard_EXPORT TCollection_AsciiString(); - //! Initializes a AsciiString with a CString. - Standard_EXPORT TCollection_AsciiString(const Standard_CString message); +#if __cplusplus >= 201703L + //! Initializes a AsciiString with a string_view. + //! @param[in] theStringView the string view to initialize from + explicit inline TCollection_AsciiString(const std::string_view& theStringView); +#endif + + //! Initializes a AsciiString with a CString (null-terminated). + //! @param[in] theMessage the C string to initialize from + inline TCollection_AsciiString(const Standard_CString theMessage); - //! Initializes a AsciiString with a CString. - Standard_EXPORT TCollection_AsciiString(const Standard_CString message, - const Standard_Integer aLen); + //! Initializes a AsciiString with a CString and explicit length. + //! @param[in] theMessage the C string to initialize from + //! @param[in] theLength the length of the string + Standard_EXPORT TCollection_AsciiString(const Standard_CString theMessage, + const Standard_Integer theLength); //! Initializes a AsciiString with a single character. - Standard_EXPORT TCollection_AsciiString(const Standard_Character aChar); + //! @param[in] theChar the character to initialize from + Standard_EXPORT TCollection_AsciiString(const Standard_Character theChar); - //! Initializes an AsciiString with space allocated. - //! and filled with . This is useful for buffers. - Standard_EXPORT TCollection_AsciiString(const Standard_Integer length, - const Standard_Character filler); + //! Initializes an AsciiString with specified length space allocated + //! and filled with filler character. This is useful for buffers. + //! @param[in] theLength the length to allocate + //! @param[in] theFiller the character to fill with + Standard_EXPORT TCollection_AsciiString(const Standard_Integer theLength, + const Standard_Character theFiller); //! Initializes an AsciiString with an integer value - Standard_EXPORT TCollection_AsciiString(const Standard_Integer value); + //! @param[in] theValue the integer value to convert to string + Standard_EXPORT TCollection_AsciiString(const Standard_Integer theValue); //! Initializes an AsciiString with a real value - Standard_EXPORT TCollection_AsciiString(const Standard_Real value); + //! @param[in] theValue the real value to convert to string + Standard_EXPORT TCollection_AsciiString(const Standard_Real theValue); //! Initializes a AsciiString with another AsciiString. - Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& astring); + //! @param[in] theString the string to copy from + Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& theString); //! Move constructor + //! @param[in] theOther the string to move from Standard_EXPORT TCollection_AsciiString(TCollection_AsciiString&& theOther) Standard_Noexcept; //! Initializes a AsciiString with copy of another AsciiString //! concatenated with the message character. - Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& astring, - const Standard_Character message); + //! @param[in] theString the string to copy + //! @param[in] theChar the character to append + Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& theString, + const Standard_Character theChar); //! Initializes a AsciiString with copy of another AsciiString //! concatenated with the message string. - Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& astring, - const Standard_CString message); + //! @param[in] theString the string to copy + //! @param[in] theMessage the C string to append + Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& theString, + const Standard_CString theMessage); //! Initializes a AsciiString with copy of another AsciiString //! concatenated with the message string. - Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& astring, - const TCollection_AsciiString& message); + //! @param[in] theString the string to copy + //! @param[in] theOtherString the string to append + Standard_EXPORT TCollection_AsciiString(const TCollection_AsciiString& theString, + const TCollection_AsciiString& theOtherString); //! Creation by converting an extended string to an ascii string. //! If replaceNonAscii is non-null character, it will be used //! in place of any non-ascii character found in the source string. //! Otherwise, creates UTF-8 unicode string. - Standard_EXPORT TCollection_AsciiString(const TCollection_ExtendedString& astring, - const Standard_Character replaceNonAscii = 0); + //! @param[in] theExtendedString the extended string to convert + //! @param[in] theReplaceNonAscii replacement character for non-ASCII characters + Standard_EXPORT TCollection_AsciiString(const TCollection_ExtendedString& theExtendedString, + const Standard_Character theReplaceNonAscii = 0); #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) //! Initialize UTF-8 Unicode string from wide-char string considering it as Unicode string @@ -107,319 +136,807 @@ public: //! //! This constructor is unavailable if application is built with deprecated msvc option //! "-Zc:wchar_t-", since OCCT itself is never built with this option. + //! @param[in] theStringUtf the wide character string to convert Standard_EXPORT TCollection_AsciiString(const Standard_WideChar* theStringUtf); #endif - //! Appends to me. This is an unary operator. - Standard_EXPORT void AssignCat(const Standard_Character other); + //! Template constructor for string literals or char arrays. + //! @param[in] theLiteral the string literal or char array + template + inline TCollection_AsciiString(const char (&theLiteral)[N]); + + //! Appends other character to this string. This is an unary operator. + //! @param[in] theOther the character to append + Standard_EXPORT void AssignCat(const Standard_Character theOther); + + void operator+=(const Standard_Character theOther) { AssignCat(theOther); } + + //! Appends other integer to this string. This is an unary operator. + //! @param[in] theOther the integer to append + Standard_EXPORT void AssignCat(const Standard_Integer theOther); + + void operator+=(const Standard_Integer theOther) { AssignCat(theOther); } + + //! Appends other real number to this string. This is an unary operator. + //! @param[in] theOther the real number to append + Standard_EXPORT void AssignCat(const Standard_Real theOther); - void operator+=(const Standard_Character other) { AssignCat(other); } + void operator+=(const Standard_Real theOther) { AssignCat(theOther); } - //! Appends to me. This is an unary operator. - Standard_EXPORT void AssignCat(const Standard_Integer other); + //! Core implementation: Appends string (pointer and length) to this ASCII string. + //! This is the primary implementation that all other AssignCat overloads redirect to. + //! @param[in] theString pointer to the string to append + //! @param[in] theLength length of the string to append + Standard_EXPORT void AssignCat(const Standard_CString theString, + const Standard_Integer theLength); - void operator+=(const Standard_Integer other) { AssignCat(other); } + //! Appends other string to this string. This is an unary operator. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Hello"); + //! TCollection_AsciiString anotherString(" World"); + //! aString += anotherString; + //! // Result: aString == "Hello World" + //! ``` + //! @param[in] theOther the string to append + inline void AssignCat(const TCollection_AsciiString& theOther); - //! Appends to me. This is an unary operator. - Standard_EXPORT void AssignCat(const Standard_Real other); + void operator+=(const TCollection_AsciiString& theOther) { AssignCat(theOther); } - void operator+=(const Standard_Real other) { AssignCat(other); } + //! Appends C string to this ASCII string. + //! @param[in] theCString the C string to append + inline void AssignCat(const Standard_CString theCString); - //! Appends to me. This is an unary operator. - //! ex: aString += "Dummy" - //! To catenate more than one CString, you must put a - //! AsciiString before. - //! Example: aString += "Hello " + "Dolly" IS NOT VALID ! - //! But astring += anotherString + "Hello " + "Dolly" is valid. - Standard_EXPORT void AssignCat(const Standard_CString other); + void operator+=(const Standard_CString theCString) { AssignCat(theCString); } - void operator+=(const Standard_CString other) { AssignCat(other); } +#if __cplusplus >= 201703L + //! Appends string view to this ASCII string. This is an unary operator. + //! @param[in] theStringView the string view to append + inline void AssignCat(const std::string_view& theStringView); - //! Appends to me. This is an unary operator. - //! Example: aString += anotherString - Standard_EXPORT void AssignCat(const TCollection_AsciiString& other); + void operator+=(const std::string_view& theStringView) { AssignCat(theStringView); } +#endif - void operator+=(const TCollection_AsciiString& other) { AssignCat(other); } + //! Template method for appending string literals or char arrays. + //! For true string literals (const char[N] in code), the size is known at compile time. + //! For char arrays (like sprintf buffers), we need to call strlen to get actual length. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Hello"); + //! aString += " World"; // Size known at compile time for string literal + //! char buffer[50]; sprintf(buffer, "test"); + //! aString += buffer; // Uses strlen for actual length + //! ``` + //! @param[in] theLiteral the string literal or char array to append + template + inline void AssignCat(const char (&theLiteral)[N]); + + template + inline void operator+=(const char (&theLiteral)[N]); //! Converts the first character into its corresponding //! upper-case character and the other characters into lowercase - //! Example: before - //! me = "hellO " - //! after - //! me = "Hello " + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("hellO "); + //! aString.Capitalize(); + //! // Result: aString == "Hello " + //! ``` Standard_EXPORT void Capitalize(); - //! Appends to me. - //! Syntax: - //! aString = aString + "Dummy" - //! Example: aString contains "I say " - //! aString = aString + "Hello " + "Dolly" - //! gives "I say Hello Dolly" - //! To catenate more than one CString, you must put a String before. - //! So the following example is WRONG ! - //! aString = "Hello " + "Dolly" THIS IS NOT ALLOWED - //! This rule is applicable to AssignCat (operator +=) too. - TCollection_AsciiString Cat(const Standard_Character other) const; - - TCollection_AsciiString operator+(const Standard_Character other) const { return Cat(other); } - - //! Appends to me. - //! Syntax: - //! aString = aString + 15; - //! Example: aString contains "I say " - //! gives "I say 15" - //! To catenate more than one CString, you must put a String before. - //! So the following example is WRONG ! - //! aString = "Hello " + "Dolly" THIS IS NOT ALLOWED - //! This rule is applicable to AssignCat (operator +=) too. - TCollection_AsciiString Cat(const Standard_Integer other) const; - - TCollection_AsciiString operator+(const Standard_Integer other) const { return Cat(other); } - - //! Appends to me. - //! Syntax: - //! aString = aString + 15.15; - //! Example: aString contains "I say " - //! gives "I say 15.15" - //! To catenate more than one CString, you must put a String before. - //! So the following example is WRONG ! - //! aString = "Hello " + "Dolly" THIS IS NOT ALLOWED - //! This rule is applicable to AssignCat (operator +=) too. - TCollection_AsciiString Cat(const Standard_Real other) const; - - TCollection_AsciiString operator+(const Standard_Real other) const { return Cat(other); } - - //! Appends to me. - //! Syntax: - //! aString = aString + "Dummy" - //! Example: aString contains "I say " - //! aString = aString + "Hello " + "Dolly" - //! gives "I say Hello Dolly" - //! To catenate more than one CString, you must put a String before. - //! So the following example is WRONG ! - //! aString = "Hello " + "Dolly" THIS IS NOT ALLOWED - //! This rule is applicable to AssignCat (operator +=) too. - TCollection_AsciiString Cat(const Standard_CString other) const; - - TCollection_AsciiString operator+(const Standard_CString other) const { return Cat(other); } - - //! Appends to me. - //! Example: aString = aString + anotherString - TCollection_AsciiString Cat(const TCollection_AsciiString& other) const; - - TCollection_AsciiString operator+(const TCollection_AsciiString& other) const - { - return Cat(other); - } + //! Core implementation: Appends string (pointer and length) to this ASCII string and returns + //! a new string. This is the primary implementation that all other Cat overloads redirect to. + //! @param[in] theString pointer to the string to append + //! @param[in] theLength length of the string to append + //! @return new string with the string appended + Standard_EXPORT TCollection_AsciiString Cat(const Standard_CString theString, + const Standard_Integer theLength) const; + + //! Appends other character to this string. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("I say "); + //! TCollection_AsciiString aResult = aString + '!'; + //! // Result: aResult == "I say !" + //! + //! // To catenate more, you must put a String before. + //! // "Hello " + "Dolly" // THIS IS NOT ALLOWED + //! // This rule is applicable to AssignCat (operator +=) too. + //! ``` + //! @param[in] theOther the character to append + //! @return new string with character appended + TCollection_AsciiString Cat(const Standard_Character theOther) const { return Cat(&theOther, 1); } + + inline TCollection_AsciiString operator+(const Standard_Character theOther) const; + + //! Appends other integer to this string. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("I say "); + //! TCollection_AsciiString aResult = aString + 15; + //! // Result: aResult == "I say 15" + //! ``` + //! @param[in] theOther the integer to append + //! @return new string with integer appended + Standard_EXPORT TCollection_AsciiString Cat(const Standard_Integer theOther) const; + + TCollection_AsciiString operator+(const Standard_Integer theOther) const { return Cat(theOther); } + + //! Appends other real number to this string. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("I say "); + //! TCollection_AsciiString aResult = aString + 15.15; + //! // Result: aResult == "I say 15.15" + //! ``` + //! @param[in] theOther the real number to append + //! @return new string with real number appended + Standard_EXPORT TCollection_AsciiString Cat(const Standard_Real theOther) const; + + TCollection_AsciiString operator+(const Standard_Real theOther) const { return Cat(theOther); } + + //! Appends other string to this string. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Hello"); + //! TCollection_AsciiString anotherString(" World"); + //! TCollection_AsciiString aResult = aString + anotherString; + //! // Result: aResult == "Hello World" + //! ``` + //! @param[in] theOther the string to append + //! @return new string with other string appended + inline TCollection_AsciiString Cat(const TCollection_AsciiString& theOther) const; + + inline TCollection_AsciiString operator+(const TCollection_AsciiString& theOther) const; + + //! Appends C string to this ASCII string. + //! @param[in] theCString the C string to append + //! @return new string with C string appended + inline TCollection_AsciiString Cat(const Standard_CString theCString) const; + + inline TCollection_AsciiString operator+(const Standard_CString theCString) const; + +#if __cplusplus >= 201703L + //! Appends string view to this ASCII string. + //! @param[in] theStringView the string view to append + //! @return new string with string view appended + inline TCollection_AsciiString Cat(const std::string_view& theStringView) const; + + inline TCollection_AsciiString operator+(const std::string_view& theStringView) const; +#endif + + //! Template method for concatenating string literals or char arrays. + //! For safety, uses strlen to get actual string length. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Hello"); + //! TCollection_AsciiString aResult = aString + " World"; // String literal + //! char buffer[50]; sprintf(buffer, "test"); + //! aResult = aString + buffer; // Char array - uses strlen + //! // Result: aResult == "Hello test" + //! ``` + //! @param[in] theLiteral the string literal or char array to concatenate + //! @return new string with literal appended + template + inline TCollection_AsciiString Cat(const char (&theLiteral)[N]) const; + + template + inline TCollection_AsciiString operator+(const char (&theLiteral)[N]) const; //! Modifies this ASCII string so that its length //! becomes equal to Width and the new characters //! are equal to Filler. New characters are added //! both at the beginning and at the end of this string. //! If Width is less than the length of this ASCII string, nothing happens. - //! Example - //! TCollection_AsciiString - //! myAlphabet("abcdef"); - //! myAlphabet.Center(9,' '); - //! assert ( myAlphabet == " - //! abcdef " ); - Standard_EXPORT void Center(const Standard_Integer Width, const Standard_Character Filler); + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString anAlphabet("abcdef"); + //! anAlphabet.Center(9, ' '); + //! // Result: anAlphabet == " abcdef " + //! ``` + //! @param[in] theWidth the desired width + //! @param[in] theFiller the character to fill with + Standard_EXPORT void Center(const Standard_Integer theWidth, const Standard_Character theFiller); //! Substitutes all the characters equal to aChar by NewChar - //! in the AsciiString . + //! in this AsciiString. //! The substitution can be case sensitive. //! If you don't use default case sensitive, no matter whether aChar //! is uppercase or not. - //! Example: me = "Histake" -> ChangeAll('H','M',Standard_True) - //! gives me = "Mistake" - Standard_EXPORT void ChangeAll(const Standard_Character aChar, - const Standard_Character NewChar, - const Standard_Boolean CaseSensitive = Standard_True); - - //! Removes all characters contained in . + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Histake"); + //! aString.ChangeAll('H', 'M', Standard_True); + //! // Result: aString == "Mistake" + //! ``` + //! @param[in] theChar the character to replace + //! @param[in] theNewChar the replacement character + //! @param[in] theCaseSensitive flag indicating case sensitivity + Standard_EXPORT void ChangeAll(const Standard_Character theChar, + const Standard_Character theNewChar, + const Standard_Boolean theCaseSensitive = Standard_True); + + //! Removes all characters contained in this string. //! This produces an empty AsciiString. Standard_EXPORT void Clear(); - //! Copy to . + //! Core implementation: Copy string (pointer and length) to this ASCII string. + //! This is the primary implementation that all other Copy overloads redirect to. //! Used as operator = - //! Example: aString = anotherCString; - Standard_EXPORT void Copy(const Standard_CString fromwhere); + //! @param[in] theString pointer to the string to copy from + //! @param[in] theLength length of the string to copy + Standard_EXPORT void Copy(const Standard_CString theString, const Standard_Integer theLength); - void operator=(const Standard_CString fromwhere) { Copy(fromwhere); } + //! Copy C string to this ASCII string. + //! Used as operator = + //! @param[in] theCString the C string to copy from + inline void Copy(const Standard_CString theCString); - //! Copy to . + void operator=(const Standard_CString theCString) { Copy(theCString); } + +#if __cplusplus >= 201703L + //! Copy string view to this ASCII string. + //! Used as operator = + //! @param[in] theStringView the string view to copy from + inline void Copy(const std::string_view& theStringView); + + void operator=(const std::string_view& theStringView) { Copy(theStringView); } +#endif + + //! Template method for copying string literals or char arrays. + //! For safety, uses strlen to get actual string length. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString; + //! aString = "Hello World"; // String literal + //! char buffer[50]; sprintf(buffer, "test"); + //! aString = buffer; // Char array - uses strlen + //! // Result: aString == "test" + //! ``` + //! @param[in] theLiteral the string literal or char array to copy from + template + inline void Copy(const char (&theLiteral)[N]); + + template + inline void operator=(const char (&theLiteral)[N]); + + //! Copy fromwhere to this string. //! Used as operator = - //! Example: aString = anotherString; - Standard_EXPORT void Copy(const TCollection_AsciiString& fromwhere); + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString; + //! TCollection_AsciiString anotherString("Hello World"); + //! aString = anotherString; // operator= + //! // Result: aString == "Hello World" + //! ``` + inline void Copy(const TCollection_AsciiString& theFromWhere); //! Copy assignment operator - TCollection_AsciiString& operator=(const TCollection_AsciiString& theOther) - { - Copy(theOther); - return *this; - } + inline TCollection_AsciiString& operator=(const TCollection_AsciiString& theOther); //! Moves string without reallocations + //! @param[in] theOther the string to move from Standard_EXPORT void Move(TCollection_AsciiString&& theOther); //! Move assignment operator - TCollection_AsciiString& operator=(TCollection_AsciiString&& theOther) noexcept - { - Move(std::forward(theOther)); - return *this; - } + inline TCollection_AsciiString& operator=(TCollection_AsciiString&& theOther) noexcept; //! Exchange the data of two strings (without reallocating memory). + //! @param[in,out] theOther the string to exchange data with Standard_EXPORT void Swap(TCollection_AsciiString& theOther); //! Frees memory allocated by AsciiString. Standard_EXPORT ~TCollection_AsciiString(); - //! Returns the index of the first character of that is - //! present in . + //! Core implementation: Returns the index of the first character of this string that is + //! present in the given character set (pointer and length). + //! The search begins at index FromIndex and ends at index ToIndex. + //! Returns zero if failure. + //! Raises an exception if FromIndex or ToIndex is out of range. + //! @param[in] theSet pointer to the set of characters to search for + //! @param[in] theSetLength length of the set + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character found in set, or 0 if not found + Standard_EXPORT Standard_Integer FirstLocationInSet(const Standard_CString theSet, + const Standard_Integer theSetLength, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; + + //! Returns the index of the first character of this string that is + //! present in Set. //! The search begins to the index FromIndex and ends to the //! the index ToIndex. //! Returns zero if failure. //! Raises an exception if FromIndex or ToIndex is out of range. - //! Example: before - //! me = "aabAcAa", S = "Aa", FromIndex = 1, Toindex = 7 - //! after - //! me = "aabAcAa" - //! returns - //! 1 - Standard_EXPORT Standard_Integer FirstLocationInSet(const TCollection_AsciiString& Set, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const; - - //! Returns the index of the first character of - //! that is not present in the set . + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("aabAcAa"); + //! TCollection_AsciiString aSet("Aa"); + //! Standard_Integer anIndex = aString.FirstLocationInSet(aSet, 1, 7); + //! // Result: anIndex == 1 + //! ``` + //! @param[in] theSet the set of characters to search for + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character found in set, or 0 if not found + inline Standard_Integer FirstLocationInSet(const TCollection_AsciiString& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; + +#if __cplusplus >= 201703L + //! Returns the index of the first character of this string that is present in string_view. + //! @param[in] theSet the string view of characters to search for + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character found in set, or 0 if not found + inline Standard_Integer FirstLocationInSet(const std::string_view& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; +#endif + + //! Template method for FirstLocationInSet with string literals. + //! @param[in] theLiteral the string literal of characters to search for + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character found in set, or 0 if not found + template + inline Standard_Integer FirstLocationInSet(const char (&theLiteral)[N], + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; + + //! Core implementation: Returns the index of the first character of this string + //! that is not present in the given character set (pointer and length). + //! The search begins at index FromIndex and ends at index ToIndex. + //! Returns zero if failure. + //! Raises an exception if FromIndex or ToIndex is out of range. + //! @param[in] theSet pointer to the set of characters to check against + //! @param[in] theSetLength length of the set + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character not in set, or 0 if not found + Standard_EXPORT Standard_Integer FirstLocationNotInSet(const Standard_CString theSet, + const Standard_Integer theSetLength, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; + + //! Returns the index of the first character of this string + //! that is not present in the set Set. //! The search begins to the index FromIndex and ends to the - //! the index ToIndex in . + //! the index ToIndex in this string. //! Returns zero if failure. //! Raises an exception if FromIndex or ToIndex is out of range. - //! Example: before - //! me = "aabAcAa", S = "Aa", FromIndex = 1, Toindex = 7 - //! after - //! me = "aabAcAa" - //! returns - //! 3 - Standard_EXPORT Standard_Integer FirstLocationNotInSet(const TCollection_AsciiString& Set, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const; - - //! Inserts a Character at position . - //! Example: - //! aString contains "hy not ?" - //! aString.Insert(1,'W'); gives "Why not ?" - //! aString contains "Wh" - //! aString.Insert(3,'y'); gives "Why" - //! aString contains "Way" - //! aString.Insert(2,'h'); gives "Why" - Standard_EXPORT void Insert(const Standard_Integer where, const Standard_Character what); - - //! Inserts a CString at position . - //! Example: - //! aString contains "O more" - //! aString.Insert(2,"nce"); gives "Once more" - Standard_EXPORT void Insert(const Standard_Integer where, const Standard_CString what); - - //! Inserts a AsciiString at position . - Standard_EXPORT void Insert(const Standard_Integer where, const TCollection_AsciiString& what); - - //! Pushing a string after a specific index in the string . - //! Raises an exception if Index is out of bounds. - //! - less than 0 (InsertAfter), or less than 1 (InsertBefore), or - //! - greater than the number of characters in this ASCII string. - //! Example: - //! before - //! me = "cde" , Index = 0 , other = "ab" - //! after - //! me = "abcde" , other = "ab" - Standard_EXPORT void InsertAfter(const Standard_Integer Index, - const TCollection_AsciiString& other); - - //! Pushing a string before a specific index in the string . - //! Raises an exception if Index is out of bounds. - //! - less than 0 (InsertAfter), or less than 1 (InsertBefore), or - //! - greater than the number of characters in this ASCII string. - //! Example: - //! before - //! me = "cde" , Index = 1 , other = "ab" - //! after - //! me = "abcde" , other = "ab" - Standard_EXPORT void InsertBefore(const Standard_Integer Index, - const TCollection_AsciiString& other); - - //! Returns True if the string contains zero character. - Standard_Boolean IsEmpty() const { return mylength == 0; } + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("aabAcAa"); + //! TCollection_AsciiString aSet("Aa"); + //! Standard_Integer anIndex = aString.FirstLocationNotInSet(aSet, 1, 7); + //! // Result: anIndex == 3 + //! ``` + //! @param[in] theSet the set of characters to check against + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character not in set, or 0 if not found + inline Standard_Integer FirstLocationNotInSet(const TCollection_AsciiString& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; + +#if __cplusplus >= 201703L + //! Returns the index of the first character of this string that is not present in string_view. + //! @param[in] theSet the string view of characters to check against + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character not in set, or 0 if not found + inline Standard_Integer FirstLocationNotInSet(const std::string_view& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; +#endif + + //! Template method for FirstLocationNotInSet with string literals. + //! @param[in] theLiteral the string literal of characters to check against + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first character not in set, or 0 if not found + template + inline Standard_Integer FirstLocationNotInSet(const char (&theLiteral)[N], + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; + + //! Inserts a Character at position where. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("hy not ?"); + //! aString.Insert(1, 'W'); + //! // Result: aString == "Why not ?" + //! + //! TCollection_AsciiString bString("Wh"); + //! bString.Insert(3, 'y'); + //! // Result: bString == "Why" + //! ``` + //! @param[in] theWhere the position to insert at + //! @param[in] theWhat the character to insert + Standard_EXPORT void Insert(const Standard_Integer theWhere, const Standard_Character theWhat); + + //! Core implementation: Inserts a string (pointer and length) at position theWhere. + //! This is the primary implementation that all other Insert overloads redirect to. + //! @param[in] theWhere position to insert at + //! @param[in] theString pointer to the string to insert + //! @param[in] theLength length of the string to insert + Standard_EXPORT void Insert(const Standard_Integer theWhere, + const Standard_CString theString, + const Standard_Integer theLength); + + //! Inserts a AsciiString at position where. + //! @param[in] theWhere the position to insert at + //! @param[in] theWhat the ASCII string to insert + inline void Insert(const Standard_Integer theWhere, const TCollection_AsciiString& theWhat); + + //! Inserts a C string at position theWhere. + //! @param[in] theWhere position to insert at + //! @param[in] theCString the C string to insert + inline void Insert(const Standard_Integer theWhere, const Standard_CString theCString); + +#if __cplusplus >= 201703L + //! Inserts a string_view at position theWhere. + //! @param[in] theWhere position to insert at + //! @param[in] theStringView the string view to insert + inline void Insert(const Standard_Integer theWhere, const std::string_view& theStringView); +#endif + + //! Template method for inserting string literals with compile-time size deduction. + //! This optimization avoids runtime strlen() calls and unnecessary conversions. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("O more"); + //! aString.Insert(2, "nce"); // Size known at compile time + //! // Result: aString == "Once more" + //! ``` + //! @param[in] theWhere the position to insert at + //! @param[in] theLiteral the string literal or char array to insert + template + inline void Insert(const Standard_Integer theWhere, const char (&theLiteral)[N]); + + //! Core implementation: Inserts string (pointer and length) after a specific index in this + //! string. This is the primary implementation that all other InsertAfter overloads redirect to. + //! Raises an exception if index is out of bounds (less than 0 or greater than the length). + //! @param[in] theIndex the index to insert after + //! @param[in] theString pointer to the string to insert + //! @param[in] theLength length of the string to insert + Standard_EXPORT void InsertAfter(const Standard_Integer theIndex, + const Standard_CString theString, + const Standard_Integer theLength); + + //! Inserts an ASCII string after a specific index in this string. + //! Raises an exception if index is out of bounds. + //! @param[in] theIndex the index to insert after + //! @param[in] theOther the string to insert + inline void InsertAfter(const Standard_Integer theIndex, const TCollection_AsciiString& theOther); + + //! Inserts a C string after a specific index in this string. + //! Raises an exception if index is out of bounds. + //! @param[in] theIndex the index to insert after + //! @param[in] theCString the C string to insert + inline void InsertAfter(const Standard_Integer theIndex, const Standard_CString theCString); + +#if __cplusplus >= 201703L + //! Inserts a string_view after a specific index in this string. + //! Raises an exception if index is out of bounds. + //! @param[in] theIndex the index to insert after + //! @param[in] theStringView the string view to insert + inline void InsertAfter(const Standard_Integer theIndex, const std::string_view& theStringView); +#endif + + //! Template method for inserting string literals or char arrays after a specific index. + //! @param[in] theIndex the index to insert after + //! @param[in] theLiteral the string literal or char array to insert + template + inline void InsertAfter(const Standard_Integer theIndex, const char (&theLiteral)[N]); + + //! Core implementation: Inserts string (pointer and length) before a specific index in this + //! string. This is the primary implementation that all other InsertBefore overloads redirect to. + //! Raises an exception if index is out of bounds (less than 1 or greater than the length). + //! @param[in] theIndex the index to insert before + //! @param[in] theString pointer to the string to insert + //! @param[in] theLength length of the string to insert + Standard_EXPORT void InsertBefore(const Standard_Integer theIndex, + const Standard_CString theString, + const Standard_Integer theLength); + + //! Inserts an ASCII string before a specific index in this string. + //! Raises an exception if index is out of bounds. + //! @param[in] theIndex the index to insert before + //! @param[in] theOther the string to insert + inline void InsertBefore(const Standard_Integer theIndex, + const TCollection_AsciiString& theOther); + + //! Inserts a C string before a specific index in this string. + //! Raises an exception if index is out of bounds. + //! @param[in] theIndex the index to insert before + //! @param[in] theCString the C string to insert + inline void InsertBefore(const Standard_Integer theIndex, const Standard_CString theCString); + +#if __cplusplus >= 201703L + //! Inserts a string_view before a specific index in this string. + //! Raises an exception if index is out of bounds. + //! @param[in] theIndex the index to insert before + //! @param[in] theStringView the string view to insert + inline void InsertBefore(const Standard_Integer theIndex, const std::string_view& theStringView); +#endif + + //! Template method for inserting string literals or char arrays before a specific index. + //! @param[in] theIndex the index to insert before + //! @param[in] theLiteral the string literal or char array to insert + template + inline void InsertBefore(const Standard_Integer theIndex, const char (&theLiteral)[N]); + + //! Returns True if this string contains zero character. + Standard_Boolean IsEmpty() const { return myLength == 0; } //! Returns true if the characters in this ASCII string //! are identical to the characters in ASCII string other. //! Note that this method is an alias of operator ==. - Standard_EXPORT Standard_Boolean IsEqual(const Standard_CString other) const; + //! @param[in] theOther the ASCII string to compare with + //! @return true if strings are equal, false otherwise + inline Standard_Boolean IsEqual(const TCollection_AsciiString& theOther) const; + + inline Standard_Boolean operator==(const TCollection_AsciiString& theOther) const; - Standard_Boolean operator==(const Standard_CString other) const { return IsEqual(other); } + //! Core implementation: Returns true if the characters in this ASCII string + //! are identical to the string (pointer and length). + //! This is the primary implementation that string_view and CString overloads redirect to. + //! @param[in] theString pointer to the string to compare with + //! @param[in] theLength length of the string to compare with + //! @return true if strings are equal, false otherwise + Standard_EXPORT Standard_Boolean IsEqual(const Standard_CString theString, + const Standard_Integer theLength) const; + //! Returns true if the characters in this ASCII string are identical to the C string. + //! @param[in] theCString the C string to compare with + //! @return true if strings are equal, false otherwise + inline Standard_Boolean IsEqual(const Standard_CString theCString) const; + + inline Standard_Boolean operator==(const Standard_CString theCString) const; + +#if __cplusplus >= 201703L //! Returns true if the characters in this ASCII string - //! are identical to the characters in ASCII string other. - //! Note that this method is an alias of operator ==. - Standard_EXPORT Standard_Boolean IsEqual(const TCollection_AsciiString& other) const; + //! are identical to the characters in string_view. + //! @param[in] theStringView the string view to compare with + //! @return true if strings are equal, false otherwise + inline Standard_Boolean IsEqual(const std::string_view& theStringView) const; - Standard_Boolean operator==(const TCollection_AsciiString& other) const { return IsEqual(other); } + inline Standard_Boolean operator==(const std::string_view& theStringView) const; +#endif + + //! Template method for comparing with string literals with compile-time optimization. + //! This optimization avoids runtime strlen() calls and unnecessary conversions. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Hello"); + //! bool isEqual = aString.IsEqual("Hello"); // Size known at compile time + //! bool isEqual2 = (aString == "Hello"); // Same optimization + //! ``` + //! @param[in] theLiteral the string literal or char array to compare with + //! @return true if strings are equal, false otherwise + template + inline Standard_Boolean IsEqual(const char (&theLiteral)[N]) const; + + template + inline Standard_Boolean operator==(const char (&theLiteral)[N]) const; //! Returns true if there are differences between the //! characters in this ASCII string and ASCII string other. //! Note that this method is an alias of operator != - Standard_EXPORT Standard_Boolean IsDifferent(const Standard_CString other) const; + //! @param[in] theOther the ASCII string to compare with + //! @return true if strings are different, false otherwise + inline Standard_Boolean IsDifferent(const TCollection_AsciiString& theOther) const; - Standard_Boolean operator!=(const Standard_CString other) const { return IsDifferent(other); } + inline Standard_Boolean operator!=(const TCollection_AsciiString& theOther) const; - //! Returns true if there are differences between the - //! characters in this ASCII string and ASCII string other. - //! Note that this method is an alias of operator != - Standard_EXPORT Standard_Boolean IsDifferent(const TCollection_AsciiString& other) const; + //! Core implementation: Returns true if there are differences between this ASCII string + //! and the string (pointer and length). + //! This is the primary implementation that string_view and CString overloads redirect to. + //! @param[in] theString pointer to the string to compare with + //! @param[in] theLength length of the string to compare with + //! @return true if strings are different, false otherwise + inline Standard_Boolean IsDifferent(const Standard_CString theString, + const Standard_Integer theLength) const; - Standard_Boolean operator!=(const TCollection_AsciiString& other) const - { - return IsDifferent(other); - } + //! Returns true if there are differences between this ASCII string and C string. + //! @param[in] theCString the C string to compare with + //! @return true if strings are different, false otherwise + inline Standard_Boolean IsDifferent(const Standard_CString theCString) const; - //! Returns TRUE if is 'ASCII' less than . - Standard_EXPORT Standard_Boolean IsLess(const Standard_CString other) const; + inline Standard_Boolean operator!=(const Standard_CString theCString) const; - Standard_Boolean operator<(const Standard_CString other) const { return IsLess(other); } +#if __cplusplus >= 201703L + //! Returns true if there are differences between the + //! characters in this ASCII string and string_view. + //! @param[in] theStringView the string view to compare with + //! @return true if strings are different, false otherwise + inline Standard_Boolean IsDifferent(const std::string_view& theStringView) const; - //! Returns TRUE if is 'ASCII' less than . - Standard_EXPORT Standard_Boolean IsLess(const TCollection_AsciiString& other) const; + inline Standard_Boolean operator!=(const std::string_view& theStringView) const; +#endif - Standard_Boolean operator<(const TCollection_AsciiString& other) const { return IsLess(other); } + //! Template method for comparing difference with string literals or char arrays. + //! @param[in] theLiteral the string literal or char array to compare with + //! @return true if strings are different, false otherwise + template + inline Standard_Boolean IsDifferent(const char (&theLiteral)[N]) const; + + template + inline Standard_Boolean operator!=(const char (&theLiteral)[N]) const; + + //! Core implementation: Returns TRUE if this string is lexicographically less than + //! the string (pointer and length). + //! This is the primary implementation that all other IsLess overloads redirect to. + //! @param[in] theString pointer to the string to compare with + //! @param[in] theLength length of the string to compare with + //! @return true if this string is lexicographically less than the given string + Standard_EXPORT Standard_Boolean IsLess(const Standard_CString theString, + const Standard_Integer theLength) const; + + //! Returns TRUE if this string is 'ASCII' less than other. + //! @param[in] theOther the ASCII string to compare with + //! @return true if this string is lexicographically less than other + inline Standard_Boolean IsLess(const TCollection_AsciiString& theOther) const; + + inline Standard_Boolean operator<(const TCollection_AsciiString& theOther) const; + + //! Returns TRUE if this string is lexicographically less than C string. + //! @param[in] theCString the C string to compare with + //! @return true if this string is lexicographically less than C string + inline Standard_Boolean IsLess(const Standard_CString theCString) const; + + Standard_Boolean operator<(const Standard_CString theCString) const { return IsLess(theCString); } + +#if __cplusplus >= 201703L + //! Returns TRUE if this ASCII string is lexicographically less than theStringView. + //! @param[in] theStringView the string view to compare with + //! @return true if this string is lexicographically less than theStringView + inline Standard_Boolean IsLess(const std::string_view& theStringView) const; + + inline Standard_Boolean operator<(const std::string_view& theStringView) const; +#endif - //! Returns TRUE if is 'ASCII' greater than . - Standard_EXPORT Standard_Boolean IsGreater(const Standard_CString other) const; + //! Template method for lexicographic comparison with string literals or char arrays. + //! @param[in] theLiteral the string literal or char array to compare with + //! @return true if this string is lexicographically less than literal + template + inline Standard_Boolean IsLess(const char (&theLiteral)[N]) const; + + template + inline Standard_Boolean operator<(const char (&theLiteral)[N]) const; + + //! Core implementation: Returns TRUE if this string is lexicographically greater than + //! the string (pointer and length). + //! This is the primary implementation that all other IsGreater overloads redirect to. + //! @param[in] theString pointer to the string to compare with + //! @param[in] theLength length of the string to compare with + //! @return true if this string is lexicographically greater than the given string + Standard_EXPORT Standard_Boolean IsGreater(const Standard_CString theString, + const Standard_Integer theLength) const; + + //! Returns TRUE if this string is 'ASCII' greater than other. + //! @param[in] theOther the ASCII string to compare with + //! @return true if this string is lexicographically greater than other + inline Standard_Boolean IsGreater(const TCollection_AsciiString& theOther) const; + + inline Standard_Boolean operator>(const TCollection_AsciiString& theOther) const; + + //! Returns TRUE if this string is lexicographically greater than C string. + //! @param[in] theCString the C string to compare with + //! @return true if this string is lexicographically greater than C string + inline Standard_Boolean IsGreater(const Standard_CString theCString) const; + + inline Standard_Boolean operator>(const Standard_CString theCString) const; + +#if __cplusplus >= 201703L + //! Returns TRUE if this ASCII string is lexicographically greater than theStringView. + //! @param[in] theStringView the string view to compare with + //! @return true if this string is lexicographically greater than theStringView + inline Standard_Boolean IsGreater(const std::string_view& theStringView) const; + + inline Standard_Boolean operator>(const std::string_view& theStringView) const; +#endif - Standard_Boolean operator>(const Standard_CString other) const { return IsGreater(other); } + //! Template method for lexicographic greater comparison with string literals or char arrays. + //! @param[in] theLiteral the string literal or char array to compare with + //! @return true if this string is lexicographically greater than literal + template + inline Standard_Boolean IsGreater(const char (&theLiteral)[N]) const; - //! Returns TRUE if is 'ASCII' greater than . - Standard_EXPORT Standard_Boolean IsGreater(const TCollection_AsciiString& other) const; + template + inline Standard_Boolean operator>(const char (&theLiteral)[N]) const; - Standard_Boolean operator>(const TCollection_AsciiString& other) const - { - return IsGreater(other); - } + //! Core implementation: Determines whether the beginning of this string instance matches + //! the specified string (pointer and length). + //! @param[in] theStartString pointer to the string to check for at the beginning + //! @param[in] theStartLength length of the string to check for + //! @return true if this string starts with theStartString + Standard_EXPORT Standard_Boolean StartsWith(const Standard_CString theStartString, + const Standard_Integer theStartLength) const; //! Determines whether the beginning of this string instance matches the specified string. - Standard_EXPORT Standard_Boolean StartsWith(const TCollection_AsciiString& theStartString) const; + //! @param[in] theStartString the string to check for at the beginning + //! @return true if this string starts with theStartString + inline Standard_Boolean StartsWith(const TCollection_AsciiString& theStartString) const; + + //! Determines whether the beginning of this string matches the specified C string. + //! @param[in] theCString the C string to check for at the beginning + //! @return true if this string starts with theCString + inline Standard_Boolean StartsWith(const Standard_CString theCString) const; + +#if __cplusplus >= 201703L + //! Determines whether the beginning of this string instance matches the specified string_view. + //! @param[in] theStartString the string view to check for at the beginning + //! @return true if this string starts with theStartString + inline Standard_Boolean StartsWith(const std::string_view& theStartString) const; +#endif + + //! Core implementation: Determines whether the end of this string instance matches + //! the specified string (pointer and length). + //! @param[in] theEndString pointer to the string to check for at the end + //! @param[in] theEndLength length of the string to check for + //! @return true if this string ends with theEndString + Standard_EXPORT Standard_Boolean EndsWith(const Standard_CString theEndString, + const Standard_Integer theEndLength) const; //! Determines whether the end of this string instance matches the specified string. - Standard_EXPORT Standard_Boolean EndsWith(const TCollection_AsciiString& theEndString) const; + //! @param[in] theEndString the string to check for at the end + //! @return true if this string ends with theEndString + inline Standard_Boolean EndsWith(const TCollection_AsciiString& theEndString) const; + +#if __cplusplus >= 201703L + //! Determines whether the end of this string instance matches the specified string_view. + //! @param[in] theEndString the string view to check for at the end + //! @return true if this string ends with theEndString + inline Standard_Boolean EndsWith(const std::string_view& theEndString) const; +#endif + + //! Template method for checking if string starts with a literal or char array. + //! @param[in] theLiteral the string literal or char array to check for at the beginning + //! @return true if this string starts with literal + template + inline Standard_Boolean StartsWith(const char (&theLiteral)[N]) const; - //! Converts a AsciiString containing a numeric expression to - //! an Integer. - //! Example: "215" returns 215. + //! Template method for checking if string ends with a literal or char array. + //! @param[in] theLiteral the string literal or char array to check for at the end + //! @return true if this string ends with literal + template + inline Standard_Boolean EndsWith(const char (&theLiteral)[N]) const; + + //! Converts a AsciiString containing a numeric expression to an Integer. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("215"); + //! Standard_Integer anInt = aString.IntegerValue(); + //! // Result: anInt == 215 + //! ``` + //! @return the integer value of the string Standard_EXPORT Standard_Integer IntegerValue() const; //! Returns True if the AsciiString contains an integer value. //! Note: an integer value is considered to be a real value as well. + //! @return true if string represents an integer value Standard_EXPORT Standard_Boolean IsIntegerValue() const; //! Returns True if the AsciiString starts with some characters that can be interpreted as integer @@ -427,12 +944,14 @@ public: //! @param[in] theToCheckFull when TRUE, checks if entire string defines a real value; //! otherwise checks if string starts with a real value //! Note: an integer value is considered to be a real value as well. + //! @return true if string represents a real value Standard_EXPORT Standard_Boolean IsRealValue(Standard_Boolean theToCheckFull = Standard_False) const; //! Returns True if the AsciiString contains only ASCII characters //! between ' ' and '~'. //! This means no control character and no extended ASCII code. + //! @return true if string contains only ASCII characters Standard_EXPORT Standard_Boolean IsAscii() const; //! Removes all space characters in the beginning of the string. @@ -443,110 +962,160 @@ public: //! equal to Filler. //! If Width < Length nothing happens. //! Raises an exception if Width is less than zero. + //! //! Example: - //! before - //! me = "abcdef" , Width = 9 , Filler = ' ' - //! after - //! me = "abcdef " - Standard_EXPORT void LeftJustify(const Standard_Integer Width, const Standard_Character Filler); - - //! Returns number of characters in . + //! ```cpp + //! TCollection_AsciiString aString("abcdef"); + //! aString.LeftJustify(9, ' '); + //! // Result: aString == "abcdef " + //! ``` + //! @param[in] theWidth the desired width + //! @param[in] theFiller the character to fill with + Standard_EXPORT void LeftJustify(const Standard_Integer theWidth, + const Standard_Character theFiller); + + //! Returns number of characters in this string. //! This is the same functionality as 'strlen' in C. - //! Example - //! TCollection_AsciiString myAlphabet("abcdef"); - //! assert ( myAlphabet.Length() == 6 ); + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString anAlphabet("abcdef"); + //! Standard_Integer aLength = anAlphabet.Length(); + //! // Result: aLength == 6 + //! ``` //! - 1 is the position of the first character in this string. //! - The length of this string gives the position of its last character. //! - Positions less than or equal to zero, or //! greater than the length of this string are //! invalid in functions which identify a character //! of this string by its position. - Standard_Integer Length() const; + //! @return the number of characters in the string + Standard_Integer Length() const { return myLength; } - //! Returns an index in the string of the first occurrence - //! of the string S in the string from the starting index + //! Returns an index in this string of the first occurrence + //! of the string S in this string from the starting index //! FromIndex to the ending index ToIndex //! returns zero if failure //! Raises an exception if FromIndex or ToIndex is out of range. + //! //! Example: - //! before - //! me = "aabAaAa", S = "Aa", FromIndex = 1, ToIndex = 7 - //! after - //! me = "aabAaAa" - //! returns - //! 4 - Standard_EXPORT Standard_Integer Location(const TCollection_AsciiString& other, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const; + //! ```cpp + //! TCollection_AsciiString aString("aabAaAa"); + //! TCollection_AsciiString aSearchString("Aa"); + //! Standard_Integer anIndex = aString.Location(aSearchString, 1, 7); + //! // Result: anIndex == 4 + //! ``` + //! @param[in] theOther the string to search for + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of first occurrence, or 0 if not found + Standard_EXPORT Standard_Integer Location(const TCollection_AsciiString& theOther, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; //! Returns the index of the nth occurrence of the character C - //! in the string from the starting index FromIndex to the + //! in this string from the starting index FromIndex to the //! ending index ToIndex. //! Returns zero if failure. //! Raises an exception if FromIndex or ToIndex is out of range. + //! //! Example: - //! before - //! me = "aabAa", N = 3, C = 'a', FromIndex = 1, ToIndex = 5 - //! after - //! me = "aabAa" - //! returns - //! 5 - Standard_EXPORT Standard_Integer Location(const Standard_Integer N, - const Standard_Character C, - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const; - - //! Converts to its lower-case equivalent. - //! Example - //! TCollection_AsciiString myString("Hello Dolly"); - //! myString.UpperCase(); - //! assert ( myString == "HELLO DOLLY" ); - //! myString.LowerCase(); - //! assert ( myString == "hello dolly" ); + //! ```cpp + //! TCollection_AsciiString aString("aabAa"); + //! Standard_Integer anIndex = aString.Location(3, 'a', 1, 5); + //! // Result: anIndex == 5 + //! ``` + //! @param[in] theN the occurrence number to find + //! @param[in] theC the character to search for + //! @param[in] theFromIndex the starting index for search + //! @param[in] theToIndex the ending index for search + //! @return the index of the nth occurrence, or 0 if not found + Standard_EXPORT Standard_Integer Location(const Standard_Integer theN, + const Standard_Character theC, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; + + //! Converts this string to its lower-case equivalent. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Hello Dolly"); + //! aString.UpperCase(); + //! // Result: aString == "HELLO DOLLY" + //! aString.LowerCase(); + //! // Result: aString == "hello dolly" + //! ``` Standard_EXPORT void LowerCase(); //! Inserts the string other at the beginning of this ASCII string. - //! Example - //! TCollection_AsciiString myAlphabet("cde"); - //! TCollection_AsciiString myBegin("ab"); - //! myAlphabet.Prepend(myBegin); - //! assert ( myAlphabet == "abcde" ); - Standard_EXPORT void Prepend(const TCollection_AsciiString& other); - - //! Displays on a stream. - Standard_EXPORT void Print(Standard_OStream& astream) const; - friend Standard_EXPORT Standard_OStream& operator<<(Standard_OStream& astream, - const TCollection_AsciiString& astring); - - //! Read from a stream. - Standard_EXPORT void Read(Standard_IStream& astream); - friend Standard_EXPORT Standard_IStream& operator>>(Standard_IStream& astream, - TCollection_AsciiString& astring); - - //! Converts an AsciiString containing a numeric expression. - //! to a Real. - //! Example: ex: "215" returns 215.0. - //! ex: "3.14159267" returns 3.14159267. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString anAlphabet("cde"); + //! TCollection_AsciiString aBegin("ab"); + //! anAlphabet.Prepend(aBegin); + //! // Result: anAlphabet == "abcde" + //! ``` + //! @param[in] theOther the string to prepend + Standard_EXPORT void Prepend(const TCollection_AsciiString& theOther); + + //! Displays this string on a stream. + //! @param[in] theStream the output stream + Standard_EXPORT void Print(Standard_OStream& theStream) const; + friend Standard_EXPORT Standard_OStream& operator<<(Standard_OStream& theStream, + const TCollection_AsciiString& theString); + + //! Read this string from a stream. + //! @param[in] theStream the input stream + Standard_EXPORT void Read(Standard_IStream& theStream); + friend Standard_EXPORT Standard_IStream& operator>>(Standard_IStream& theStream, + TCollection_AsciiString& theString); + + //! Converts an AsciiString containing a numeric expression to a Real. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString1("215"); + //! Standard_Real aReal1 = aString1.RealValue(); + //! // Result: aReal1 == 215.0 + //! + //! TCollection_AsciiString aString2("3.14159267"); + //! Standard_Real aReal2 = aString2.RealValue(); + //! // Result: aReal2 == 3.14159267 + //! ``` + //! @return the real value of the string Standard_EXPORT Standard_Real RealValue() const; //! Remove all the occurrences of the character C in the string. + //! //! Example: - //! before - //! me = "HellLLo", C = 'L' , CaseSensitive = True - //! after - //! me = "Hello" - Standard_EXPORT void RemoveAll(const Standard_Character C, const Standard_Boolean CaseSensitive); - - //! Removes every characters from . - Standard_EXPORT void RemoveAll(const Standard_Character what); - - //! Erases characters from position , - //! included. + //! ```cpp + //! TCollection_AsciiString aString("HellLLo"); + //! aString.RemoveAll('L', Standard_True); + //! // Result: aString == "Hello" + //! ``` + //! @param[in] theC the character to remove + //! @param[in] theCaseSensitive flag indicating case sensitivity + Standard_EXPORT void RemoveAll(const Standard_Character theC, + const Standard_Boolean theCaseSensitive); + + //! Removes every what characters from this string. + //! @param[in] theWhat the character to remove + Standard_EXPORT void RemoveAll(const Standard_Character theWhat); + + //! Erases ahowmany characters from position where, + //! where included. + //! //! Example: - //! aString contains "Hello" - //! aString.Remove(2,2) erases 2 characters from position 2 - //! This gives "Hlo". - Standard_EXPORT void Remove(const Standard_Integer where, const Standard_Integer ahowmany = 1); + //! ```cpp + //! TCollection_AsciiString aString("Hello"); + //! aString.Remove(2, 2); // erases 2 characters from position 2 + //! // Result: aString == "Hlo" + //! ``` + //! @param[in] theWhere the position to start erasing from + //! @param[in] theHowMany the number of characters to erase + Standard_EXPORT void Remove(const Standard_Integer theWhere, + const Standard_Integer theHowMany = 1); //! Removes all space characters at the end of the string. Standard_EXPORT void RightAdjust(); @@ -556,141 +1125,358 @@ public: //! equal to Filler. //! if Width < Length nothing happens. //! Raises an exception if Width is less than zero. + //! //! Example: - //! before - //! me = "abcdef" , Width = 9 , Filler = ' ' - //! after - //! me = " abcdef" - Standard_EXPORT void RightJustify(const Standard_Integer Width, const Standard_Character Filler); - - //! Searches a CString in from the beginning - //! and returns position of first item matching. - //! it returns -1 if not found. - //! Example: - //! aString contains "Sample single test" - //! aString.Search("le") returns 5 - Standard_EXPORT Standard_Integer Search(const Standard_CString what) const; - - //! Searches an AsciiString in from the beginning - //! and returns position of first item matching. + //! ```cpp + //! TCollection_AsciiString aString("abcdef"); + //! aString.RightJustify(9, ' '); + //! // Result: aString == " abcdef" + //! ``` + //! @param[in] theWidth the desired width + //! @param[in] theFiller the character to fill with + Standard_EXPORT void RightJustify(const Standard_Integer theWidth, + const Standard_Character theFiller); + + //! Core implementation: Searches a string (pointer and length) in this string from the beginning + //! and returns position of first item matching. + //! It returns -1 if not found. + //! @param[in] theWhat pointer to the string to search for + //! @param[in] theWhatLength length of the string to search for + //! @return the position of first match, or -1 if not found + Standard_EXPORT Standard_Integer Search(const Standard_CString theWhat, + const Standard_Integer theWhatLength) const; + + //! Searches an AsciiString in this string from the beginning + //! and returns position of first item what matching. + //! It returns -1 if not found. + //! @param[in] theWhat the ASCII string to search for + //! @return the position of first match, or -1 if not found + inline Standard_Integer Search(const TCollection_AsciiString& theWhat) const; + + //! Searches a C string in this string from the beginning. + //! @param[in] theCString the C string to search for + //! @return the position of first match, or -1 if not found + inline Standard_Integer Search(const Standard_CString theCString) const; + +#if __cplusplus >= 201703L + //! Searches a string_view in this string from the beginning + //! and returns position of first item matching. //! It returns -1 if not found. - Standard_EXPORT Standard_Integer Search(const TCollection_AsciiString& what) const; + //! @param[in] theWhat the string view to search for + //! @return the position of first match, or -1 if not found + inline Standard_Integer Search(const std::string_view& theWhat) const; +#endif + + //! Template method for searching string literals or char arrays. + //! @param[in] theLiteral the string literal or char array to search for + //! @return the position of first match, or -1 if not found + template + inline Standard_Integer Search(const char (&theLiteral)[N]) const; - //! Searches a CString in a AsciiString from the end - //! and returns position of first item matching. + //! Core implementation: Searches a string (pointer and length) in this string from the end + //! and returns position of first item matching. //! It returns -1 if not found. - //! Example: - //! aString contains "Sample single test" - //! aString.SearchFromEnd("le") returns 12 - Standard_EXPORT Standard_Integer SearchFromEnd(const Standard_CString what) const; + //! @param[in] theWhat pointer to the string to search for + //! @param[in] theWhatLength length of the string to search for + //! @return the position of first match from end, or -1 if not found + Standard_EXPORT Standard_Integer SearchFromEnd(const Standard_CString theWhat, + const Standard_Integer theWhatLength) const; //! Searches a AsciiString in another AsciiString from the end - //! and returns position of first item matching. + //! and returns position of first item what matching. + //! It returns -1 if not found. + //! @param[in] theWhat the ASCII string to search for + //! @return the position of first match from end, or -1 if not found + inline Standard_Integer SearchFromEnd(const TCollection_AsciiString& theWhat) const; + + //! Searches a C string in this string from the end. + //! @param[in] theCString the C string to search for + //! @return the position of first match from end, or -1 if not found + inline Standard_Integer SearchFromEnd(const Standard_CString theCString) const; + +#if __cplusplus >= 201703L + //! Searches a string_view in this string from the end + //! and returns position of first item matching. //! It returns -1 if not found. - Standard_EXPORT Standard_Integer SearchFromEnd(const TCollection_AsciiString& what) const; + //! @param[in] theWhat the string view to search for + //! @return the position of first match from end, or -1 if not found + inline Standard_Integer SearchFromEnd(const std::string_view& theWhat) const; +#endif - //! Replaces one character in the AsciiString at position . - //! If is less than zero or greater than the length of - //! an exception is raised. - //! Example: - //! aString contains "Garbake" - //! astring.Replace(6,'g') gives = "Garbage" - Standard_EXPORT void SetValue(const Standard_Integer where, const Standard_Character what); + //! Template method for searching string literals or char arrays from end. + //! @param[in] theLiteral the string literal or char array to search for + //! @return the position of first match from end, or -1 if not found + template + inline Standard_Integer SearchFromEnd(const char (&theLiteral)[N]) const; - //! Replaces a part of by a CString. - //! If is less than zero or greater than the length of + //! Replaces one character in the AsciiString at position where. + //! If where is less than zero or greater than the length of this string //! an exception is raised. + //! //! Example: - //! aString contains "abcde" - //! aString.SetValue(4,"1234567") gives = "abc1234567" - Standard_EXPORT void SetValue(const Standard_Integer where, const Standard_CString what); - - //! Replaces a part of by another AsciiString. - Standard_EXPORT void SetValue(const Standard_Integer where, const TCollection_AsciiString& what); + //! ```cpp + //! TCollection_AsciiString aString("Garbake"); + //! aString.SetValue(6, 'g'); + //! // Result: aString == "Garbage" + //! ``` + //! @param[in] theWhere the position to replace at + //! @param[in] theWhat the character to replace with + Standard_EXPORT void SetValue(const Standard_Integer theWhere, const Standard_Character theWhat); + + //! Core implementation: Replaces a part of this string with a string (pointer and length). + //! This is the primary implementation that all other SetValue string overloads redirect to. + //! @param[in] theWhere position to start replacement + //! @param[in] theString pointer to the string to replace with + //! @param[in] theLength length of the string to replace with + Standard_EXPORT void SetValue(const Standard_Integer theWhere, + const Standard_CString theString, + const Standard_Integer theLength); + + //! Replaces a part of this string by another AsciiString. + //! @param[in] theWhere the position to start replacement + //! @param[in] theWhat the ASCII string to replace with + inline void SetValue(const Standard_Integer theWhere, const TCollection_AsciiString& theWhat); + + //! Replaces a part of this ASCII string with a C string. + //! @param[in] theWhere position to start replacement + //! @param[in] theCString the C string to replace with + inline void SetValue(const Standard_Integer theWhere, const Standard_CString theCString); + +#if __cplusplus >= 201703L + //! Replaces a part of this ASCII string with a string_view. + //! @param[in] theWhere position to start replacement + //! @param[in] theStringView the string view to replace with + inline void SetValue(const Standard_Integer theWhere, const std::string_view& theStringView); +#endif //! Splits a AsciiString into two sub-strings. + //! //! Example: - //! aString contains "abcdefg" - //! aString.Split(3) gives = "abc" and returns "defg" - Standard_EXPORT TCollection_AsciiString Split(const Standard_Integer where); - - //! Creation of a sub-string of the string . + //! ```cpp + //! TCollection_AsciiString aString("abcdefg"); + //! TCollection_AsciiString aSecondPart = aString.Split(3); + //! // Result: aString == "abc" and aSecondPart == "defg" + //! ``` + //! @param[in] theWhere the position to split at + //! @return the second part of the split string + Standard_EXPORT TCollection_AsciiString Split(const Standard_Integer theWhere); + + //! Creation of a sub-string of this string. //! The sub-string starts to the index Fromindex and ends //! to the index ToIndex. //! Raises an exception if ToIndex or FromIndex is out of bounds + //! //! Example: - //! before - //! me = "abcdefg", ToIndex=3, FromIndex=6 - //! after - //! me = "abcdefg" - //! returns - //! "cdef" - TCollection_AsciiString SubString(const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const; + //! ```cpp + //! TCollection_AsciiString aString("abcdefg"); + //! TCollection_AsciiString aSubString = aString.SubString(3, 6); + //! // Result: aSubString == "cdef" + //! ``` + //! @param[in] theFromIndex the starting index + //! @param[in] theToIndex the ending index + //! @return the substring from FromIndex to ToIndex + Standard_EXPORT TCollection_AsciiString SubString(const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const; //! Returns pointer to AsciiString (char *). //! This is useful for some casual manipulations. //! Warning: Because this "char *" is 'const', you can't modify its contents. - Standard_CString ToCString() const; + //! @return the C string representation + Standard_CString ToCString() const { return myString; } + +#if __cplusplus >= 201703L + //! Returns string_view for this AsciiString. + //! This provides a lightweight, non-owning view of the string data. + //! @return the string_view representation + explicit operator std::string_view() const { return std::string_view(myString, myLength); } +#endif - //! Extracts token from . - //! By default, the is set to space and tabulation. + //! Extracts whichone token from this string. + //! By default, the separators is set to space and tabulation. //! By default, the token extracted is the first one (whichone = 1). - //! contains all separators you need. - //! If no token indexed by is found, it returns empty AsciiString. - //! Example: - //! aString contains "This is a message" - //! aString.Token() returns "This" - //! aString.Token(" ",4) returns "message" - //! aString.Token(" ",2) returns "is" - //! aString.Token(" ",9) returns "" - //! Other separators than space character and tabulation are allowed : - //! aString contains "1234; test:message , value" - //! aString.Token("; :,",4) returns "value" - //! aString.Token("; :,",2) returns "test" - Standard_EXPORT TCollection_AsciiString Token(const Standard_CString separators = " \t", - const Standard_Integer whichone = 1) const; - - //! Truncates to characters. - //! Example: me = "Hello Dolly" -> Trunc(3) -> me = "Hel" - Standard_EXPORT void Trunc(const Standard_Integer ahowmany); - - //! Converts to its upper-case equivalent. + //! separators contains all separators you need. + //! If no token indexed by whichone is found, it returns empty AsciiString. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("This is a message"); + //! TCollection_AsciiString aToken1 = aString.Token(); + //! // Result: aToken1 == "This" + //! + //! TCollection_AsciiString aToken2 = aString.Token(" ", 4); + //! // Result: aToken2 == "message" + //! + //! TCollection_AsciiString aToken3 = aString.Token(" ", 2); + //! // Result: aToken3 == "is" + //! + //! TCollection_AsciiString aToken4 = aString.Token(" ", 9); + //! // Result: aToken4 == "" + //! + //! TCollection_AsciiString bString("1234; test:message , value"); + //! TCollection_AsciiString bToken1 = bString.Token("; :,", 4); + //! // Result: bToken1 == "value" + //! + //! TCollection_AsciiString bToken2 = bString.Token("; :,", 2); + //! // Result: bToken2 == "test" + //! ``` + //! @param[in] theSeparators the separator characters + //! @param[in] theWhichOne the token number to extract + Standard_EXPORT TCollection_AsciiString Token(const Standard_CString theSeparators = " \t", + const Standard_Integer theWhichOne = 1) const; + + //! Truncates this string to ahowmany characters. + //! + //! Example: + //! ```cpp + //! TCollection_AsciiString aString("Hello Dolly"); + //! aString.Trunc(3); + //! // Result: aString == "Hel" + //! ``` + //! @param[in] theHowMany the number of characters to keep + Standard_EXPORT void Trunc(const Standard_Integer theHowMany); + + //! Converts this string to its upper-case equivalent. Standard_EXPORT void UpperCase(); //! Length of the string ignoring all spaces (' ') and the //! control character at the end. + //! @return the useful length of the string Standard_EXPORT Standard_Integer UsefullLength() const; - //! Returns character at position in . - //! If is less than zero or greater than the length of , + //! Returns character at position where in this string. + //! If where is less than zero or greater than the length of this string, //! an exception is raised. + //! //! Example: - //! aString contains "Hello" - //! aString.Value(2) returns 'e' - Standard_EXPORT Standard_Character Value(const Standard_Integer where) const; + //! ```cpp + //! TCollection_AsciiString aString("Hello"); + //! Standard_Character aChar = aString.Value(2); + //! // Result: aChar == 'e' + //! ``` + //! @param[in] theWhere the position to get character from + //! @return the character at the specified position + Standard_EXPORT Standard_Character Value(const Standard_Integer theWhere) const; //! Computes a hash code for the given ASCII string //! Returns the same integer value as the hash function for TCollection_ExtendedString //! @return a computed hash code - size_t HashCode() const; + inline size_t HashCode() const; //! Returns True when the two strings are the same. //! (Just for HashCode for AsciiString) - static Standard_Boolean IsEqual(const TCollection_AsciiString& string1, - const TCollection_AsciiString& string2); + //! @param[in] string1 first string to compare + //! @param[in] string2 second string to compare + //! @return true if strings are equal + inline static Standard_Boolean IsEqual(const TCollection_AsciiString& string1, + const TCollection_AsciiString& string2); //! Returns True when the two strings are the same. //! (Just for HashCode for AsciiString) + //! @param[in] string1 first string to compare + //! @param[in] string2 second C string to compare + //! @return true if strings are equal static Standard_Boolean IsEqual(const TCollection_AsciiString& string1, const Standard_CString string2); - //! Returns True if the strings contain same characters. - Standard_EXPORT static Standard_Boolean IsSameString(const TCollection_AsciiString& theString1, - const TCollection_AsciiString& theString2, +#if __cplusplus >= 201703L + //! Returns True when the ASCII string and string_view are the same. + //! (Just for HashCode for AsciiString) + //! @param[in] theString1 first string to compare + //! @param[in] theStringView second string view to compare + //! @return true if strings are equal + inline static Standard_Boolean IsEqual(const TCollection_AsciiString& theString1, + const std::string_view& theStringView); + + //! Returns True when the string_view and ASCII string are the same. + //! (Just for HashCode for AsciiString) + //! @param[in] theStringView first string view to compare + //! @param[in] theString2 second string to compare + //! @return true if strings are equal + inline static Standard_Boolean IsEqual(const std::string_view& theStringView, + const TCollection_AsciiString& theString2); +#endif + + //! Core implementation: Returns True if the two strings (pointer and length) contain same + //! characters. This is the primary implementation that all other IsSameString overloads redirect + //! to. + //! @param[in] theString1 pointer to first string to compare + //! @param[in] theLength1 length of first string + //! @param[in] theString2 pointer to second string to compare + //! @param[in] theLength2 length of second string + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + Standard_EXPORT static Standard_Boolean IsSameString(const Standard_CString theString1, + const Standard_Integer theLength1, + const Standard_CString theString2, + const Standard_Integer theLength2, const Standard_Boolean theIsCaseSensitive); - friend class TCollection_HAsciiString; + //! Returns True if the strings contain same characters. + //! @param[in] theString1 first string to compare + //! @param[in] theString2 second string to compare + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + inline static Standard_Boolean IsSameString(const TCollection_AsciiString& theString1, + const TCollection_AsciiString& theString2, + const Standard_Boolean theIsCaseSensitive); + + //! Returns True if the string and C string contain same characters. + //! @param[in] theString1 first string to compare + //! @param[in] theCString second C string to compare + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + inline static Standard_Boolean IsSameString(const TCollection_AsciiString& theString1, + const Standard_CString theCString, + const Standard_Boolean theIsCaseSensitive); + + //! Returns True if the C string and string contain same characters. + //! @param[in] theCString first C string to compare + //! @param[in] theString2 second string to compare + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + inline static Standard_Boolean IsSameString(const Standard_CString theCString, + const TCollection_AsciiString& theString2, + const Standard_Boolean theIsCaseSensitive); + +#if __cplusplus >= 201703L + //! Returns True if the string and string_view contain same characters. + //! @param[in] theString1 first string to compare + //! @param[in] theStringView second string view to compare + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + inline static Standard_Boolean IsSameString(const TCollection_AsciiString& theString1, + const std::string_view& theStringView, + const Standard_Boolean theIsCaseSensitive); + + //! Returns True if the string_view and string contain same characters. + //! @param[in] theStringView first string view to compare + //! @param[in] theString2 second string to compare + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + inline static Standard_Boolean IsSameString(const std::string_view& theStringView, + const TCollection_AsciiString& theString2, + const Standard_Boolean theIsCaseSensitive); +#endif + + //! Returns True if the two C strings contain same characters. + //! @param[in] theCString1 first C string to compare + //! @param[in] theCString2 second C string to compare + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + inline static Standard_Boolean IsSameString(const Standard_CString theCString1, + const Standard_CString theCString2, + const Standard_Boolean theIsCaseSensitive); + +#if __cplusplus >= 201703L + //! Returns True if the two string_views contain same characters. + //! @param[in] theStringView1 first string view to compare + //! @param[in] theStringView2 second string view to compare + //! @param[in] theIsCaseSensitive flag indicating case sensitivity + //! @return true if strings contain same characters + inline static Standard_Boolean IsSameString(const std::string_view& theStringView1, + const std::string_view& theStringView2, + const Standard_Boolean theIsCaseSensitive); +#endif private: //! Internal wrapper to allocate on stack or heap @@ -703,8 +1489,8 @@ private: void deallocate(); private: - Standard_PCharacter mystring{}; //!< NULL-terminated string - Standard_Integer mylength{}; //!< length in bytes (excluding terminating NULL symbol) + Standard_PCharacter myString{}; //!< NULL-terminated string + Standard_Integer myLength{}; //!< length in bytes (excluding terminating NULL symbol) }; #include diff --git a/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.lxx b/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.lxx index 0eacfca289..20d0f1709c 100644 --- a/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.lxx +++ b/src/FoundationClasses/TKernel/TCollection/TCollection_AsciiString.lxx @@ -12,12 +12,17 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include -#include #include -// definition global methods for using in NCollection +//! Returns True when the two strings are the same. +//! @param[in] theString1 first string to compare +//! @param[in] theString2 second string to compare +//! @return true if strings are equal +inline Standard_Boolean IsEqual(const TCollection_AsciiString& theString1, + const TCollection_AsciiString& theString2) +{ + return TCollection_AsciiString::IsEqual(theString1, theString2); +} namespace std { @@ -30,62 +35,523 @@ struct hash //================================================================================================= -inline Standard_Boolean IsEqual(const TCollection_AsciiString& string1, - const TCollection_AsciiString& string2) +inline void TCollection_AsciiString::AssignCat(const TCollection_AsciiString& theOther) +{ + AssignCat(theOther.ToCString(), theOther.Length()); +} + +//================================================================================================= + +inline void TCollection_AsciiString::AssignCat(const Standard_CString theCString) { - return TCollection_AsciiString::IsEqual(string1, string2); + if (theCString) + { + AssignCat(theCString, static_cast(strlen(theCString))); + } } //================================================================================================= -inline Standard_CString TCollection_AsciiString::ToCString() const +#if __cplusplus >= 201703L +inline void TCollection_AsciiString::AssignCat(const std::string_view& theStringView) { - return mystring; + if (!theStringView.empty()) + { + AssignCat(theStringView.data(), static_cast(theStringView.size())); + } } +#endif + +//================================================================================================= -// ---------------------------------------------------------------------------- -inline Standard_Integer TCollection_AsciiString::Length() const +template +inline void TCollection_AsciiString::AssignCat(const char (&theLiteral)[N]) { - return mylength; + AssignCat(theLiteral, static_cast(strlen(theLiteral))); } +//================================================================================================= + inline TCollection_AsciiString TCollection_AsciiString::Cat( - const TCollection_AsciiString& other) const + const TCollection_AsciiString& theOther) const +{ + return Cat(theOther.ToCString(), theOther.Length()); +} + +//================================================================================================= + +inline TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_CString theCString) const +{ + return theCString ? Cat(theCString, static_cast(strlen(theCString))) + : TCollection_AsciiString(*this); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline TCollection_AsciiString TCollection_AsciiString::Cat( + const std::string_view& theStringView) const +{ + return Cat(theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline TCollection_AsciiString TCollection_AsciiString::Cat(const char (&theLiteral)[N]) const +{ + return Cat(theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline void TCollection_AsciiString::Copy(const Standard_CString theCString) +{ + Copy(theCString, theCString ? static_cast(strlen(theCString)) : 0); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline void TCollection_AsciiString::Copy(const std::string_view& theStringView) +{ + Copy(theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline void TCollection_AsciiString::Copy(const char (&theLiteral)[N]) +{ + Copy(theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline void TCollection_AsciiString::Copy(const TCollection_AsciiString& theFromWhere) +{ + if (&theFromWhere != this) + { + Copy(theFromWhere.ToCString(), theFromWhere.Length()); + } +} + +//================================================================================================= + +inline void TCollection_AsciiString::Insert(const Standard_Integer theWhere, + const TCollection_AsciiString& theWhat) +{ + Insert(theWhere, theWhat.ToCString(), theWhat.Length()); +} + +//================================================================================================= + +inline void TCollection_AsciiString::Insert(const Standard_Integer theWhere, + const Standard_CString theCString) +{ + if (theCString) + { + Insert(theWhere, theCString, static_cast(strlen(theCString))); + } +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline void TCollection_AsciiString::Insert(const Standard_Integer theWhere, + const std::string_view& theStringView) +{ + Insert(theWhere, theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline void TCollection_AsciiString::Insert(const Standard_Integer theWhere, + const char (&theLiteral)[N]) +{ + Insert(theWhere, theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline void TCollection_AsciiString::InsertAfter(const Standard_Integer theIndex, + const TCollection_AsciiString& theOther) +{ + InsertAfter(theIndex, theOther.ToCString(), theOther.Length()); +} + +//================================================================================================= + +inline void TCollection_AsciiString::InsertAfter(const Standard_Integer theIndex, + const Standard_CString theCString) +{ + if (theCString) + InsertAfter(theIndex, theCString, static_cast(strlen(theCString))); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline void TCollection_AsciiString::InsertAfter(const Standard_Integer theIndex, + const std::string_view& theStringView) +{ + InsertAfter(theIndex, theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline void TCollection_AsciiString::InsertAfter(const Standard_Integer theIndex, + const char (&theLiteral)[N]) +{ + InsertAfter(theIndex, theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline void TCollection_AsciiString::InsertBefore(const Standard_Integer theIndex, + const TCollection_AsciiString& theOther) +{ + InsertBefore(theIndex, theOther.ToCString(), theOther.Length()); +} + +//================================================================================================= + +inline void TCollection_AsciiString::InsertBefore(const Standard_Integer theIndex, + const Standard_CString theCString) +{ + if (theCString) + InsertBefore(theIndex, theCString, static_cast(strlen(theCString))); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline void TCollection_AsciiString::InsertBefore(const Standard_Integer theIndex, + const std::string_view& theStringView) +{ + InsertBefore(theIndex, theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline void TCollection_AsciiString::InsertBefore(const Standard_Integer theIndex, + const char (&theLiteral)[N]) +{ + InsertBefore(theIndex, theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsEqual( + const TCollection_AsciiString& theOther) const +{ + return IsEqual(theOther.myString, theOther.myLength); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsEqual(const Standard_CString theCString) const +{ + return theCString ? IsEqual(theCString, static_cast(strlen(theCString))) + : (myLength == 0); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsEqual( + const std::string_view& theStringView) const +{ + return IsEqual(theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::IsEqual(const char (&theLiteral)[N]) const +{ + return IsEqual(theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsDifferent( + const TCollection_AsciiString& theOther) const +{ + return IsDifferent(theOther.myString, theOther.myLength); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsDifferent( + const Standard_CString theCString) const +{ + return !IsEqual(theCString); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsDifferent( + const std::string_view& theStringView) const +{ + return !IsEqual(theStringView); +} +#endif + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::IsDifferent(const char (&theLiteral)[N]) const +{ + return !IsEqual(theLiteral); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsLess( + const TCollection_AsciiString& theOther) const +{ + return IsLess(theOther.ToCString(), theOther.Length()); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsLess(const Standard_CString theCString) const +{ + return theCString ? IsLess(theCString, static_cast(strlen(theCString))) + : Standard_False; +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsLess(const std::string_view& theStringView) const +{ + return IsLess(theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::IsLess(const char (&theLiteral)[N]) const +{ + return IsLess(theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsGreater( + const TCollection_AsciiString& theOther) const +{ + return IsGreater(theOther.ToCString(), theOther.Length()); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsGreater(const Standard_CString theCString) const +{ + return theCString ? IsGreater(theCString, static_cast(strlen(theCString))) + : (myLength > 0); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsGreater( + const std::string_view& theStringView) const +{ + return IsGreater(theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::IsGreater(const char (&theLiteral)[N]) const +{ + return IsGreater(theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::StartsWith( + const TCollection_AsciiString& theStartString) const +{ + return StartsWith(theStartString.ToCString(), theStartString.Length()); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::StartsWith(const Standard_CString theCString) const +{ + return theCString ? StartsWith(theCString, static_cast(strlen(theCString))) + : (myLength == 0); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::StartsWith( + const std::string_view& theStartString) const +{ + return StartsWith(theStartString.data(), static_cast(theStartString.size())); +} +#endif + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::EndsWith( + const TCollection_AsciiString& theEndString) const +{ + return EndsWith(theEndString.ToCString(), theEndString.Length()); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::EndsWith( + const std::string_view& theEndString) const +{ + return EndsWith(theEndString.data(), static_cast(theEndString.size())); +} +#endif + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::StartsWith(const char (&theLiteral)[N]) const +{ + return StartsWith(theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::EndsWith(const char (&theLiteral)[N]) const +{ + return EndsWith(theLiteral, static_cast(strlen(theLiteral))); +} + +//================================================================================================= + +inline Standard_Integer TCollection_AsciiString::Search( + const TCollection_AsciiString& theWhat) const +{ + return Search(theWhat.ToCString(), theWhat.Length()); +} + +//================================================================================================= + +inline Standard_Integer TCollection_AsciiString::Search(const Standard_CString theCString) const +{ + return theCString ? Search(theCString, static_cast(strlen(theCString))) : -1; +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Integer TCollection_AsciiString::Search(const std::string_view& theWhat) const { - return TCollection_AsciiString(*this, other); + return Search(theWhat.data(), static_cast(theWhat.size())); } +#endif + +//================================================================================================= -inline TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_CString other) const +template +inline Standard_Integer TCollection_AsciiString::Search(const char (&theLiteral)[N]) const { - return TCollection_AsciiString(*this, other); + return Search(theLiteral, static_cast(strlen(theLiteral))); } -inline TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_Character other) const +//================================================================================================= + +inline Standard_Integer TCollection_AsciiString::SearchFromEnd( + const TCollection_AsciiString& theWhat) const { - return TCollection_AsciiString(*this, other); + return SearchFromEnd(theWhat.ToCString(), theWhat.Length()); } -inline TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_Integer other) const +//================================================================================================= + +inline Standard_Integer TCollection_AsciiString::SearchFromEnd( + const Standard_CString theCString) const { + return theCString ? SearchFromEnd(theCString, static_cast(strlen(theCString))) + : -1; +} + +//================================================================================================= - return TCollection_AsciiString(*this, TCollection_AsciiString(other)); +#if __cplusplus >= 201703L +inline Standard_Integer TCollection_AsciiString::SearchFromEnd( + const std::string_view& theWhat) const +{ + return SearchFromEnd(theWhat.data(), static_cast(theWhat.size())); } +#endif + +//================================================================================================= -inline TCollection_AsciiString TCollection_AsciiString::Cat(const Standard_Real other) const +template +inline Standard_Integer TCollection_AsciiString::SearchFromEnd(const char (&theLiteral)[N]) const { + return SearchFromEnd(theLiteral, static_cast(strlen(theLiteral))); +} - return TCollection_AsciiString(*this, TCollection_AsciiString(other)); +//================================================================================================= + +inline void TCollection_AsciiString::SetValue(const Standard_Integer theWhere, + const TCollection_AsciiString& theWhat) +{ + SetValue(theWhere, theWhat.ToCString(), theWhat.Length()); } //================================================================================================= +inline void TCollection_AsciiString::SetValue(const Standard_Integer theWhere, + const Standard_CString theCString) +{ + if (theCString) + { + SetValue(theWhere, theCString, static_cast(strlen(theCString))); + } + else + { + SetValue(theWhere, "", 0); + } +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline void TCollection_AsciiString::SetValue(const Standard_Integer theWhere, + const std::string_view& theStringView) +{ + SetValue(theWhere, theStringView.data(), static_cast(theStringView.size())); +} +#endif + +//================================================================================================= + inline size_t TCollection_AsciiString::HashCode() const { - if (mylength < 4) + if (myLength < 4) { - return opencascade::FNVHash::hash_combine(*mystring, mylength); + return opencascade::FNVHash::hash_combine(*myString, myLength); } - return opencascade::hashBytes(mystring, mylength); + return opencascade::hashBytes(myString, myLength); } //================================================================================================= @@ -98,23 +564,438 @@ inline Standard_Boolean TCollection_AsciiString::IsEqual(const TCollection_Ascii //================================================================================================= -inline Standard_Boolean TCollection_AsciiString::IsEqual(const TCollection_AsciiString& string1, - const Standard_CString string2) +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsEqual(const TCollection_AsciiString& theString1, + const std::string_view& theStringView) +{ + return theString1.IsEqual(theStringView); +} +#endif + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsEqual(const std::string_view& theStringView, + const TCollection_AsciiString& theString2) +{ + return theString2.IsEqual(theStringView); +} +#endif + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsSameString( + const TCollection_AsciiString& theString1, + const TCollection_AsciiString& theString2, + const Standard_Boolean theIsCaseSensitive) +{ + return IsSameString(theString1.ToCString(), + theString1.Length(), + theString2.ToCString(), + theString2.Length(), + theIsCaseSensitive); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsSameString( + const TCollection_AsciiString& theString1, + const Standard_CString theCString, + const Standard_Boolean theIsCaseSensitive) +{ + if (!theCString) + return theString1.Length() == 0; + + return IsSameString(theString1.ToCString(), + theString1.Length(), + theCString, + static_cast(strlen(theCString)), + theIsCaseSensitive); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsSameString( + const Standard_CString theCString, + const TCollection_AsciiString& theString2, + const Standard_Boolean theIsCaseSensitive) +{ + return IsSameString(theString2, theCString, theIsCaseSensitive); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsSameString( + const TCollection_AsciiString& theString1, + const std::string_view& theStringView, + const Standard_Boolean theIsCaseSensitive) +{ + return IsSameString(theString1.ToCString(), + theString1.Length(), + theStringView.data(), + static_cast(theStringView.size()), + theIsCaseSensitive); +} +#endif + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsSameString( + const std::string_view& theStringView, + const TCollection_AsciiString& theString2, + const Standard_Boolean theIsCaseSensitive) +{ + // Redirect to the primary static method with swapped arguments + return IsSameString(theString2, theStringView, theIsCaseSensitive); +} +#endif + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsSameString( + const Standard_CString theCString1, + const Standard_CString theCString2, + const Standard_Boolean theIsCaseSensitive) +{ + if (!theCString1 && !theCString2) + return Standard_True; + if (!theCString1 || !theCString2) + return Standard_False; + + return IsSameString(theCString1, + static_cast(strlen(theCString1)), + theCString2, + static_cast(strlen(theCString2)), + theIsCaseSensitive); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::IsSameString( + const std::string_view& theStringView1, + const std::string_view& theStringView2, + const Standard_Boolean theIsCaseSensitive) +{ + return IsSameString(theStringView1.data(), + static_cast(theStringView1.size()), + theStringView2.data(), + static_cast(theStringView2.size()), + theIsCaseSensitive); +} +#endif + +//================================================================================================= + +template +inline void TCollection_AsciiString::operator+=(const char (&theLiteral)[N]) +{ + AssignCat(theLiteral); +} + +//================================================================================================= + +template +inline TCollection_AsciiString TCollection_AsciiString::operator+(const char (&theLiteral)[N]) const +{ + return Cat(theLiteral); +} + +//================================================================================================= + +template +inline void TCollection_AsciiString::operator=(const char (&theLiteral)[N]) +{ + Copy(theLiteral); +} + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::operator==(const char (&theLiteral)[N]) const +{ + return IsEqual(theLiteral); +} + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::operator!=(const char (&theLiteral)[N]) const +{ + return IsDifferent(theLiteral); +} + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::operator<(const char (&theLiteral)[N]) const +{ + return IsLess(theLiteral); +} + +//================================================================================================= + +template +inline Standard_Boolean TCollection_AsciiString::operator>(const char (&theLiteral)[N]) const +{ + return IsGreater(theLiteral); +} + +//================================================================================================= + +inline TCollection_AsciiString TCollection_AsciiString::operator+( + const Standard_Character theOther) const +{ + return Cat(theOther); +} + +//================================================================================================= + +inline Standard_Integer TCollection_AsciiString::FirstLocationInSet( + const TCollection_AsciiString& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const +{ + return FirstLocationInSet(theSet.ToCString(), theSet.Length(), theFromIndex, theToIndex); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Integer TCollection_AsciiString::FirstLocationInSet( + const std::string_view& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const +{ + return FirstLocationInSet(theSet.data(), + static_cast(theSet.size()), + theFromIndex, + theToIndex); +} +#endif + +//================================================================================================= + +template +inline Standard_Integer TCollection_AsciiString::FirstLocationInSet( + const char (&theLiteral)[N], + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const +{ + return FirstLocationInSet(theLiteral, + static_cast(N - 1), + theFromIndex, + theToIndex); +} + +//================================================================================================= + +inline Standard_Integer TCollection_AsciiString::FirstLocationNotInSet( + const TCollection_AsciiString& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const +{ + return FirstLocationNotInSet(theSet.ToCString(), theSet.Length(), theFromIndex, theToIndex); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Integer TCollection_AsciiString::FirstLocationNotInSet( + const std::string_view& theSet, + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const +{ + return FirstLocationNotInSet(theSet.data(), + static_cast(theSet.size()), + theFromIndex, + theToIndex); +} +#endif + +//================================================================================================= + +template +inline Standard_Integer TCollection_AsciiString::FirstLocationNotInSet( + const char (&theLiteral)[N], + const Standard_Integer theFromIndex, + const Standard_Integer theToIndex) const +{ + return FirstLocationNotInSet(theLiteral, + static_cast(N - 1), + theFromIndex, + theToIndex); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::IsDifferent(const Standard_CString theString, + const Standard_Integer theLength) const +{ + return !IsEqual(theString, theLength); +} + +//================================================================================================= + +inline TCollection_AsciiString TCollection_AsciiString::operator+( + const TCollection_AsciiString& theOther) const +{ + return Cat(theOther); +} + +//================================================================================================= + +inline TCollection_AsciiString TCollection_AsciiString::operator+( + const Standard_CString theCString) const +{ + return Cat(theCString); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline TCollection_AsciiString TCollection_AsciiString::operator+( + const std::string_view& theStringView) const +{ + return Cat(theStringView); +} +#endif + +//================================================================================================= + +inline TCollection_AsciiString& TCollection_AsciiString::operator=( + const TCollection_AsciiString& theOther) +{ + Copy(theOther); + return *this; +} + +//================================================================================================= + +inline TCollection_AsciiString& TCollection_AsciiString::operator=( + TCollection_AsciiString&& theOther) noexcept +{ + Move(std::forward(theOther)); + return *this; +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::operator==( + const TCollection_AsciiString& theOther) const +{ + return IsEqual(theOther); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::operator==(const Standard_CString theCString) const +{ + return IsEqual(theCString); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::operator==( + const std::string_view& theStringView) const +{ + return IsEqual(theStringView); +} +#endif + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::operator!=( + const TCollection_AsciiString& theOther) const +{ + return IsDifferent(theOther); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::operator!=(const Standard_CString theCString) const +{ + return IsDifferent(theCString); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::operator!=( + const std::string_view& theStringView) const +{ + return IsDifferent(theStringView); +} +#endif + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::operator<( + const TCollection_AsciiString& theOther) const +{ + return IsLess(theOther); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::operator<( + const std::string_view& theStringView) const +{ + return IsLess(theStringView); +} +#endif + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::operator>( + const TCollection_AsciiString& theOther) const +{ + return IsGreater(theOther); +} + +//================================================================================================= + +inline Standard_Boolean TCollection_AsciiString::operator>(const Standard_CString theCString) const +{ + return IsGreater(theCString); +} + +//================================================================================================= + +#if __cplusplus >= 201703L +inline Standard_Boolean TCollection_AsciiString::operator>( + const std::string_view& theStringView) const +{ + return IsGreater(theStringView); +} +#endif + +//================================================================================================= + +#if __cplusplus >= 201703L +inline TCollection_AsciiString::TCollection_AsciiString(const std::string_view& theStringView) + : TCollection_AsciiString(theStringView.data(), + static_cast(theStringView.size())) +{ +} +#endif + +//================================================================================================= + +inline TCollection_AsciiString::TCollection_AsciiString(const Standard_CString theMessage) + : TCollection_AsciiString(theMessage, + theMessage ? static_cast(strlen(theMessage)) : 0) { - return string1.IsEqual(string2); } //================================================================================================= -inline TCollection_AsciiString TCollection_AsciiString::SubString( - const Standard_Integer FromIndex, - const Standard_Integer ToIndex) const +template +inline TCollection_AsciiString::TCollection_AsciiString(const char (&theLiteral)[N]) + : TCollection_AsciiString(theLiteral, static_cast(strlen(theLiteral))) { - // note the we are doing here weird casts just to suppress annoying and meaningless warning - // -Wstrict-overflow - Standard_OutOfRange_Always_Raise_if(FromIndex <= 0 || ToIndex <= 0 - || (unsigned int)ToIndex > (unsigned int)mylength - || (unsigned int)FromIndex > (unsigned int)ToIndex, - "TCollection_AsciiString::SubString() out of range"); - return TCollection_AsciiString(&mystring[FromIndex - 1], ToIndex - FromIndex + 1); } diff --git a/src/FoundationClasses/TKernel/TCollection/TCollection_ExtendedString.cxx b/src/FoundationClasses/TKernel/TCollection/TCollection_ExtendedString.cxx index c2b8fbc1aa..47ac3b2592 100644 --- a/src/FoundationClasses/TKernel/TCollection/TCollection_ExtendedString.cxx +++ b/src/FoundationClasses/TKernel/TCollection/TCollection_ExtendedString.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.cxx b/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.cxx index 2911c9d1eb..5558c518b3 100644 --- a/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.cxx +++ b/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.cxx @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -516,7 +517,7 @@ Standard_Boolean TCollection_HAsciiString::IsSameState( const Handle(TCollection_HAsciiString)& other) const { if (myString.Length() == other->Length()) - return (strncmp(myString.mystring, other->ToCString(), myString.Length()) == 0); + return (strncmp(myString.ToCString(), other->ToCString(), myString.Length()) == 0); else return Standard_False; } diff --git a/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.lxx b/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.lxx index 6c46643409..362b5f55c2 100644 --- a/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.lxx +++ b/src/FoundationClasses/TKernel/TCollection/TCollection_HAsciiString.lxx @@ -30,7 +30,7 @@ inline void TCollection_HAsciiString::AssignCat(const Handle(TCollection_HAsciiS inline Standard_Integer TCollection_HAsciiString::Length() const { - return myString.mylength; + return myString.Length(); } //=================================================================================================