From af1b0a8bb96a65472362db4258e5704580f9d1e4 Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Thu, 27 Jun 2013 18:40:35 -0700 Subject: [PATCH] fbstring::shrink_to_fit Summary: Adds the eponymous C++11 capability to fbstring. Test Plan: fbstring runtests Reviewed By: tudorb@fb.com FB internal diff: D867995 --- folly/FBString.h | 108 +++++++--- folly/test/FBStringTest.cpp | 409 +++++++++++++++++++++++------------- 2 files changed, 337 insertions(+), 180 deletions(-) diff --git a/folly/FBString.h b/folly/FBString.h index a410a186..04b90a7c 100644 --- a/folly/FBString.h +++ b/folly/FBString.h @@ -985,7 +985,7 @@ private: } public: - // 21.3.1 construct/copy/destroy + // C++11 21.4.2 construct/copy/destroy explicit basic_fbstring(const A& a = A()) { } @@ -1047,6 +1047,11 @@ public: : store_(s, n, c, a) { } + // Construction from initialization list + basic_fbstring(std::initializer_list il) { + assign(il.begin(), il.end()); + } + ~basic_fbstring() { } @@ -1076,7 +1081,7 @@ public: basic_fbstring& operator=(basic_fbstring&& goner) { if (FBSTRING_UNLIKELY(&goner == this)) { // Compatibility with std::basic_string<>, - // 21.4.2 [string.cons] / 23 requires self-move-assignment support. + // C++11 21.4.2 [string.cons] / 23 requires self-move-assignment support. return *this; } // No need of this anymore @@ -1121,11 +1126,17 @@ public: return *this; } - // 21.3.2 iterators: + basic_fbstring& operator=(std::initializer_list il) { + return assign(il.begin(), il.end()); + } + + // C++11 21.4.3 iterators: iterator begin() { return store_.mutable_data(); } const_iterator begin() const { return store_.data(); } + const_iterator cbegin() const { return begin(); } + iterator end() { return store_.mutable_data() + store_.size(); } @@ -1134,6 +1145,8 @@ public: return store_.data() + store_.size(); } + const_iterator cend() const { return end(); } + reverse_iterator rbegin() { return reverse_iterator(end()); } @@ -1142,6 +1155,8 @@ public: return const_reverse_iterator(end()); } + const_reverse_iterator crbegin() const { return rbegin(); } + reverse_iterator rend() { return reverse_iterator(begin()); } @@ -1150,6 +1165,8 @@ public: return const_reverse_iterator(begin()); } + const_reverse_iterator crend() const { return rend(); } + // Added by C++11 // C++11 21.4.5, element access: const value_type& front() const { return *begin(); } @@ -1169,7 +1186,7 @@ public: store_.shrink(1); } - // 21.3.3 capacity: + // C++11 21.4.4 capacity: size_type size() const { return store_.size(); } size_type length() const { return size(); } @@ -1213,11 +1230,19 @@ public: store_.reserve(res_arg); } + void shrink_to_fit() { + // Shrink only if slack memory is sufficiently large + if (capacity() < size() * 3 / 2) { + return; + } + basic_fbstring(cbegin(), cend()).swap(*this); + } + void clear() { resize(0); } bool empty() const { return size() == 0; } - // 21.3.4 element access: + // C++11 21.4.5 element access: const_reference operator[](size_type pos) const { return *(c_str() + pos); } @@ -1240,7 +1265,7 @@ public: return (*this)[n]; } - // 21.3.5 modifiers: + // C++11 21.4.6 modifiers: basic_fbstring& operator+=(const basic_fbstring& str) { return append(str); } @@ -1254,6 +1279,11 @@ public: return *this; } + basic_fbstring& operator+=(std::initializer_list il) { + append(il); + return *this; + } + basic_fbstring& append(const basic_fbstring& str) { #ifndef NDEBUG auto desiredSize = size() + str.size(); @@ -1323,6 +1353,10 @@ public: return *this; } + basic_fbstring& append(std::initializer_list il) { + return append(il.begin(), il.end()); + } + void push_back(const value_type c) { // primitive store_.push_back(c); } @@ -1332,6 +1366,10 @@ public: return assign(str.data(), str.size()); } + basic_fbstring& assign(basic_fbstring&& str) { + return *this = std::move(str); + } + basic_fbstring& assign(const basic_fbstring& str, const size_type pos, size_type n) { const size_type sz = str.size(); @@ -1362,6 +1400,10 @@ public: return assign(s, traits_type::length(s)); } + basic_fbstring& assign(std::initializer_list il) { + return assign(il.begin(), il.end()); + } + template basic_fbstring& assign(ItOrLength first_or_n, ItOrChar last_or_c) { return replace(begin(), end(), first_or_n, last_or_c); @@ -1394,7 +1436,7 @@ public: return *this; } - iterator insert(const iterator p, const value_type c) { + iterator insert(const_iterator p, const value_type c) { const size_type pos = p - begin(); insert(p, 1, c); return begin() + pos; @@ -1403,10 +1445,11 @@ public: private: template class Selector {}; - basic_fbstring& insertImplDiscr(iterator p, - size_type n, value_type c, Selector<1>) { + iterator insertImplDiscr(const_iterator p, + size_type n, value_type c, Selector<1>) { Invariant checker(*this); (void) checker; + auto const pos = p - begin(); assert(p >= begin() && p <= end()); if (capacity() - size() < n) { const size_type sz = p - begin(); @@ -1414,33 +1457,33 @@ private: p = begin() + sz; } const iterator oldEnd = end(); - if( n < size_type(oldEnd - p)) { + if (n < size_type(oldEnd - p)) { append(oldEnd - n, oldEnd); //std::copy( // reverse_iterator(oldEnd - n), // reverse_iterator(p), // reverse_iterator(oldEnd)); - fbstring_detail::pod_move(&*p, &*oldEnd - n, &*p + n); - std::fill(p, p + n, c); + fbstring_detail::pod_move(&*p, &*oldEnd - n, + begin() + pos + n); + std::fill(begin() + pos, begin() + pos + n, c); } else { append(n - (end() - p), c); - append(p, oldEnd); - std::fill(p, oldEnd, c); + append(iterator(p), oldEnd); + std::fill(iterator(p), oldEnd, c); } store_.writeTerminator(); - return *this; + return begin() + pos; } template - basic_fbstring& insertImplDiscr(iterator i, - InputIter b, InputIter e, Selector<0>) { - insertImpl(i, b, e, + iterator insertImplDiscr(const_iterator i, + InputIter b, InputIter e, Selector<0>) { + return insertImpl(i, b, e, typename std::iterator_traits::iterator_category()); - return *this; } template - void insertImpl(iterator i, + iterator insertImpl(const_iterator i, FwdIterator s1, FwdIterator s2, std::forward_iterator_tag) { Invariant checker(*this); (void) checker; @@ -1462,9 +1505,9 @@ private: const iterator tailBegin = end() - n2; store_.expand_noinit(n2); fbstring_detail::pod_copy(tailBegin, tailBegin + n2, end() - n2); - std::copy(reverse_iterator(tailBegin), reverse_iterator(i), + std::copy(const_reverse_iterator(tailBegin), const_reverse_iterator(i), reverse_iterator(tailBegin + n2)); - std::copy(s1, s2, i); + std::copy(s1, s2, begin() + pos); } else { FwdIterator t = s1; const size_type old_size = size(); @@ -1474,27 +1517,35 @@ private: std::copy(t, s2, begin() + old_size); fbstring_detail::pod_copy(data() + pos, data() + old_size, begin() + old_size + newElems); - std::copy(s1, t, i); + std::copy(s1, t, begin() + pos); } store_.writeTerminator(); + return begin() + pos; } template - void insertImpl(iterator i, - InputIterator b, InputIterator e, std::input_iterator_tag) { + iterator insertImpl(const_iterator i, + InputIterator b, InputIterator e, + std::input_iterator_tag) { + const auto pos = i - begin(); basic_fbstring temp(begin(), i); for (; b != e; ++b) { temp.push_back(*b); } temp.append(i, end()); swap(temp); + return begin() + pos; } public: template - void insert(iterator p, ItOrLength first_or_n, ItOrChar last_or_c) { + iterator insert(const_iterator p, ItOrLength first_or_n, ItOrChar last_or_c) { Selector::is_specialized> sel; - insertImplDiscr(p, first_or_n, last_or_c, sel); + return insertImplDiscr(p, first_or_n, last_or_c, sel); + } + + iterator insert(const_iterator p, std::initializer_list il) { + return insert(p, il.begin(), il.end()); } basic_fbstring& erase(size_type pos = 0, size_type n = npos) { @@ -1690,7 +1741,6 @@ public: store_.swap(rhs.store_); } - // 21.3.6 string operations: const value_type* c_str() const { return store_.c_str(); } @@ -2165,7 +2215,7 @@ bool operator>=(const typename basic_fbstring::value_type* lhs, return !(lhs < rhs); } -// subclause 21.3.7.8: +// C++11 21.4.8.8 template void swap(basic_fbstring& lhs, basic_fbstring& rhs) { lhs.swap(rhs); diff --git a/folly/test/FBStringTest.cpp b/folly/test/FBStringTest.cpp index bd6def42..65fb7ad1 100644 --- a/folly/test/FBStringTest.cpp +++ b/folly/test/FBStringTest.cpp @@ -77,17 +77,34 @@ std::list RandomList(unsigned int maxSize) { // Tests begin here //////////////////////////////////////////////////////////////////////////////// -template void clause_21_3_1_a(String & test) { +template void clause11_21_4_2_a(String & test) { test.String::~String(); new(&test) String(); } -template void clause_21_3_1_b(String & test) { - // Copy constructor +template void clause11_21_4_2_b(String & test) { + String test2(test); + assert(test2 == test); +} +template void clause11_21_4_2_c(String & test) { + // Test move constructor. There is a more specialized test, see + // TEST(FBString, testMoveCtor) + String donor(test); + String test2(std::move(donor)); + EXPECT_EQ(test2, test); + // Technically not required, but all implementations that actually + // support move will move large strings. Make a guess for 128 as the + // maximum small string optimization that's reasonable. + EXPECT_LE(donor.size(), 128); +} +template void clause11_21_4_2_d(String & test) { + // Copy constructor with position and length const size_t pos = random(0, test.size()); - String s(test, pos, random(0, (size_t)(test.size() - pos))); + String s(test, pos, random(0, 9) + ? random(0, (size_t)(test.size() - pos)) + : String::npos); // test for npos, too, in 10% of the cases test = s; } -template void clause_21_3_1_c(String & test) { +template void clause11_21_4_2_e(String & test) { // Constructor from char*, size_t const size_t pos = random(0, test.size()), @@ -96,36 +113,58 @@ template void clause_21_3_1_c(String & test) { String s(test.c_str() + pos, n); String after(test.data(), test.size()); EXPECT_EQ(before, after); - + test.swap(s); +} +template void clause11_21_4_2_f(String & test) { + // Constructor from char* + const size_t + pos = random(0, test.size()), + n = random(0, test.size() - pos); + String before(test.data(), test.size()); + String s(test.c_str() + pos); + String after(test.data(), test.size()); + EXPECT_EQ(before, after); + test.swap(s); +} +template void clause11_21_4_2_g(String & test) { + // Constructor from size_t, char + const size_t n = random(0, test.size()); + const auto c = test.front(); + test = String(n, c); +} +template void clause11_21_4_2_h(String & test) { + // Constructors from various iterator pairs // Constructor from char*, char* String s1(test.begin(), test.end()); EXPECT_EQ(test, s1); String s2(test.data(), test.data() + test.size()); EXPECT_EQ(test, s2); - - // Constructor from iterators + // Constructor from other iterators std::list lst; for (auto c : test) lst.push_back(c); String s3(lst.begin(), lst.end()); EXPECT_EQ(test, s3); - // Constructor from wchar_t iterators std::list lst1; for (auto c : test) lst1.push_back(c); String s4(lst1.begin(), lst1.end()); EXPECT_EQ(test, s4); - // Constructor from wchar_t pointers wchar_t t[20]; t[0] = 'a'; t[1] = 'b'; fbstring s5(t, t + 2);; EXPECT_EQ("ab", s5); - - test = s; } -template void clause_21_3_1_d(String & test) { - // Assignment +template void clause11_21_4_2_i(String & test) { + // From initializer_list + std::initializer_list + il = { 'h', 'e', 'l', 'l', 'o' }; + String s(il); + test.swap(s); +} +template void clause11_21_4_2_j(String & test) { + // Assignment from const String& auto size = random(0, 2000); String s(size, '\0'); EXPECT_EQ(s.size(), size); @@ -134,7 +173,20 @@ template void clause_21_3_1_d(String & test) { } test = s; } -template void clause_21_3_1_e(String & test) { +template void clause11_21_4_2_k(String & test) { + // Assignment from String&& + auto size = random(0, 2000); + String s(size, '\0'); + EXPECT_EQ(s.size(), size); + FOR_EACH_RANGE (i, 0, s.size()) { + s[i] = random('a', 'z'); + } + test = std::move(s); + if (typeid(String) == typeid(fbstring)) { + EXPECT_LE(s.size(), 128); + } +} +template void clause11_21_4_2_l(String & test) { // Assignment from char* String s(random(0, 1000), '\0'); size_t i = 0; @@ -143,7 +195,7 @@ template void clause_21_3_1_e(String & test) { } test = s.c_str(); } -template void clause_21_3_1_f(String & test) { +template void clause11_21_4_2_lprime(String & test) { // Aliased assign const size_t pos = random(0, test.size()); if (avoidAliasing) { @@ -152,15 +204,23 @@ template void clause_21_3_1_f(String & test) { test = test.c_str() + pos; } } -template void clause_21_3_1_g(String & test) { +template void clause11_21_4_2_m(String & test) { // Assignment from char test = random('a', 'z'); } +template void clause11_21_4_2_n(String & test) { + // Assignment from initializer_list + initializer_list + il = { 'h', 'e', 'l', 'l', 'o' }; + test = il; +} -template void clause_21_3_2(String & test) { +template void clause11_21_4_3(String & test) { // Iterators. The code below should leave test unchanged EXPECT_EQ(test.size(), test.end() - test.begin()); EXPECT_EQ(test.size(), test.rend() - test.rbegin()); + EXPECT_EQ(test.size(), test.cend() - test.cbegin()); + EXPECT_EQ(test.size(), test.crend() - test.crbegin()); auto s = test.size(); test.resize(test.end() - test.begin()); @@ -169,12 +229,20 @@ template void clause_21_3_2(String & test) { EXPECT_EQ(s, test.size()); } -template void clause_21_3_3(String & test) { +template void clause11_21_4_4(String & test) { // exercise capacity, size, max_size EXPECT_EQ(test.size(), test.length()); EXPECT_LE(test.size(), test.max_size()); EXPECT_LE(test.capacity(), test.max_size()); EXPECT_LE(test.size(), test.capacity()); + + // exercise shrink_to_fit. Nonbinding request so we can't really do + // much beyond calling it. + auto copy = test; + copy.reserve(copy.capacity() * 3); + copy.shrink_to_fit(); + EXPECT_EQ(copy, test); + // exercise empty string empty("empty"); string notempty("not empty"); @@ -182,16 +250,18 @@ template void clause_21_3_3(String & test) { else test = String(notempty.begin(), notempty.end()); } -template void clause_21_3_4(String & test) { - // exercise element access 21.3.4 +template void clause11_21_4_5(String & test) { + // exercise element access if (!test.empty()) { + EXPECT_EQ(test[0], test.front()); + EXPECT_EQ(test[test.size() - 1], test.back()); auto const i = random(0, test.size() - 1); EXPECT_EQ(test[i], test.at(i)); test = test[i]; } } -template void clause_21_3_5_a(String & test) { +template void clause11_21_4_6_1(String & test) { // 21.3.5 modifiers (+=) String test1; randomString(&test1); @@ -240,9 +310,12 @@ template void clause_21_3_5_a(String & test) { len = test.size(); test += random('a', 'z'); EXPECT_EQ(test.size(), len + 1); + // initializer_list + initializer_list il { 'a', 'b', 'c' }; + test += il; } -template void clause_21_3_5_b(String & test) { +template void clause11_21_4_6_2(String & test) { // 21.3.5 modifiers (append, push_back) String s; @@ -267,70 +340,85 @@ template void clause_21_3_5_b(String & test) { c = random('a', 'z'); test.push_back(c); EXPECT_EQ(test[test.size() - 1], c); + // initializer_list + initializer_list il { 'a', 'b', 'c' }; + test.append(il); } -template void clause_21_3_5_c(String & test) { +template void clause11_21_4_6_3_a(String & test) { // assign String s; randomString(&s); test.assign(s); + EXPECT_EQ(test, s); + // move assign + test.assign(std::move(s)); + if (typeid(String) == typeid(fbstring)) { + EXPECT_LE(s.size(), 128); + } } -template void clause_21_3_5_d(String & test) { +template void clause11_21_4_6_3_b(String & test) { // assign String s; randomString(&s, maxString); test.assign(s, random(0, s.size()), random(0, maxString)); } -template void clause_21_3_5_e(String & test) { +template void clause11_21_4_6_3_c(String & test) { // assign String s; randomString(&s, maxString); test.assign(s.c_str(), random(0, s.size())); } -template void clause_21_3_5_f(String & test) { +template void clause11_21_4_6_3_d(String & test) { // assign String s; randomString(&s, maxString); test.assign(s.c_str()); } -template void clause_21_3_5_g(String & test) { +template void clause11_21_4_6_3_e(String & test) { // assign String s; randomString(&s, maxString); test.assign(random(0, maxString), random('a', 'z')); } -template void clause_21_3_5_h(String & test) { +template void clause11_21_4_6_3_f(String & test) { // assign from bidirectional iterator std::list lst(RandomList(maxString)); test.assign(lst.begin(), lst.end()); } -template void clause_21_3_5_i(String & test) { +template void clause11_21_4_6_3_g(String & test) { // assign from aliased source test.assign(test); } -template void clause_21_3_5_j(String & test) { +template void clause11_21_4_6_3_h(String & test) { // assign from aliased source test.assign(test, random(0, test.size()), random(0, maxString)); } -template void clause_21_3_5_k(String & test) { +template void clause11_21_4_6_3_i(String & test) { // assign from aliased source test.assign(test.c_str(), random(0, test.size())); } -template void clause_21_3_5_l(String & test) { +template void clause11_21_4_6_3_j(String & test) { // assign from aliased source test.assign(test.c_str()); } -template void clause_21_3_5_m(String & test) { +template void clause11_21_4_6_3_k(String & test) { + // assign from initializer_list + initializer_list il { 'a', 'b', 'c' }; + test.assign(il); +} + +template void clause11_21_4_6_4(String & test) { // insert String s; randomString(&s, maxString); @@ -346,15 +434,23 @@ template void clause_21_3_5_m(String & test) { test.insert(random(0, test.size()), s.c_str()); test.insert(random(0, test.size()), random(0, maxString), random('a', 'z')); - test.insert(test.begin() + random(0, test.size()), - random('a', 'z')); + typename String::size_type pos = random(0, test.size()); + typename String::iterator res = + test.insert(test.begin() + pos, random('a', 'z')); + EXPECT_EQ(res - test.begin(), pos); std::list lst(RandomList(maxString)); - test.insert(test.begin() + random(0, test.size()), - lst.begin(), lst.end()); + pos = random(0, test.size()); + // Uncomment below to see a bug in gcc + /*res = */test.insert(test.begin() + pos, lst.begin(), lst.end()); + // insert from initializer_list + initializer_list il { 'a', 'b', 'c' }; + pos = random(0, test.size()); + // Uncomment below to see a bug in gcc + /*res = */test.insert(test.begin() + pos, il); } -template void clause_21_3_5_n(String & test) { - // erase +template void clause11_21_4_6_5(String & test) { + // erase and pop_back if (!test.empty()) { test.erase(random(0, test.size()), random(0, maxString)); } @@ -368,9 +464,13 @@ template void clause_21_3_5_n(String & test) { test.erase(i, i + random(0, size_t(test.end() - i))); } } + if (!test.empty()) { + // Can't test pop_back with std::string, doesn't support it yet. + //test.pop_back(); + } } -template void clause_21_3_5_o(String & test) { +template void clause11_21_4_6_6(String & test) { auto pos = random(0, test.size()); if (avoidAliasing) { test.replace(pos, random(0, test.size() - pos), @@ -461,7 +561,7 @@ template void clause_21_3_5_o(String & test) { random(0, maxString), random('a', 'z')); } -template void clause_21_3_5_p(String & test) { +template void clause11_21_4_6_7(String & test) { std::vector vec(random(0, maxString)); test.copy( @@ -470,13 +570,13 @@ template void clause_21_3_5_p(String & test) { random(0, test.size())); } -template void clause_21_3_5_q(String & test) { +template void clause11_21_4_6_8(String & test) { String s; randomString(&s, maxString); s.swap(test); } -template void clause_21_3_6_a(String & test) { +template void clause11_21_4_7_1(String & test) { // 21.3.6 string operations // exercise c_str() and data() assert(test.c_str() == test.data()); @@ -486,14 +586,14 @@ template void clause_21_3_6_a(String & test) { assert(test.get_allocator() == s.get_allocator()); } -template void clause_21_3_6_b(String & test) { +template void clause11_21_4_7_2_a(String & test) { String str = test.substr( random(0, test.size()), random(0, test.size())); Num2String(test, test.find(str, random(0, test.size()))); } -template void clause_21_3_6_c(String & test) { +template void clause11_21_4_7_2_b(String & test) { auto from = random(0, test.size()); auto length = random(0, test.size() - from); String str = test.substr(from, length); @@ -502,7 +602,7 @@ template void clause_21_3_6_c(String & test) { random(0, str.size()))); } -template void clause_21_3_6_d(String & test) { +template void clause11_21_4_7_2_c(String & test) { String str = test.substr( random(0, test.size()), random(0, test.size())); @@ -510,20 +610,20 @@ template void clause_21_3_6_d(String & test) { random(0, test.size()))); } -template void clause_21_3_6_e(String & test) { +template void clause11_21_4_7_2_d(String & test) { Num2String(test, test.find( random('a', 'z'), random(0, test.size()))); } -template void clause_21_3_6_f(String & test) { +template void clause11_21_4_7_3_a(String & test) { String str = test.substr( random(0, test.size()), random(0, test.size())); Num2String(test, test.rfind(str, random(0, test.size()))); } -template void clause_21_3_6_g(String & test) { +template void clause11_21_4_7_3_b(String & test) { String str = test.substr( random(0, test.size()), random(0, test.size())); @@ -532,7 +632,7 @@ template void clause_21_3_6_g(String & test) { random(0, str.size()))); } -template void clause_21_3_6_h(String & test) { +template void clause11_21_4_7_3_c(String & test) { String str = test.substr( random(0, test.size()), random(0, test.size())); @@ -540,20 +640,20 @@ template void clause_21_3_6_h(String & test) { random(0, test.size()))); } -template void clause_21_3_6_i(String & test) { +template void clause11_21_4_7_3_d(String & test) { Num2String(test, test.rfind( random('a', 'z'), random(0, test.size()))); } -template void clause_21_3_6_j(String & test) { +template void clause11_21_4_7_4_a(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_first_of(str, random(0, test.size()))); } -template void clause_21_3_6_k(String & test) { +template void clause11_21_4_7_4_b(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_first_of(str.c_str(), @@ -561,27 +661,27 @@ template void clause_21_3_6_k(String & test) { random(0, str.size()))); } -template void clause_21_3_6_l(String & test) { +template void clause11_21_4_7_4_c(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_first_of(str.c_str(), random(0, test.size()))); } -template void clause_21_3_6_m(String & test) { +template void clause11_21_4_7_4_d(String & test) { Num2String(test, test.find_first_of( random('a', 'z'), random(0, test.size()))); } -template void clause_21_3_6_n(String & test) { +template void clause11_21_4_7_5_a(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_last_of(str, random(0, test.size()))); } -template void clause_21_3_6_o(String & test) { +template void clause11_21_4_7_5_b(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_last_of(str.c_str(), @@ -589,27 +689,27 @@ template void clause_21_3_6_o(String & test) { random(0, str.size()))); } -template void clause_21_3_6_p(String & test) { +template void clause11_21_4_7_5_c(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_last_of(str.c_str(), random(0, test.size()))); } -template void clause_21_3_6_q(String & test) { +template void clause11_21_4_7_5_d(String & test) { Num2String(test, test.find_last_of( random('a', 'z'), random(0, test.size()))); } -template void clause_21_3_6_r(String & test) { +template void clause11_21_4_7_6_a(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_first_not_of(str, random(0, test.size()))); } -template void clause_21_3_6_s(String & test) { +template void clause11_21_4_7_6_b(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_first_not_of(str.c_str(), @@ -617,27 +717,27 @@ template void clause_21_3_6_s(String & test) { random(0, str.size()))); } -template void clause_21_3_6_t(String & test) { +template void clause11_21_4_7_6_c(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_first_not_of(str.c_str(), random(0, test.size()))); } -template void clause_21_3_6_u(String & test) { +template void clause11_21_4_7_6_d(String & test) { Num2String(test, test.find_first_not_of( random('a', 'z'), random(0, test.size()))); } -template void clause_21_3_6_v(String & test) { +template void clause11_21_4_7_7_a(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_last_not_of(str, random(0, test.size()))); } -template void clause_21_3_6_w(String & test) { +template void clause11_21_4_7_7_b(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_last_not_of(str.c_str(), @@ -645,24 +745,24 @@ template void clause_21_3_6_w(String & test) { random(0, str.size()))); } -template void clause_21_3_6_x(String & test) { +template void clause11_21_4_7_7_c(String & test) { String str; randomString(&str, maxString); Num2String(test, test.find_last_not_of(str.c_str(), random(0, test.size()))); } -template void clause_21_3_6_y(String & test) { +template void clause11_21_4_7_7_d(String & test) { Num2String(test, test.find_last_not_of( random('a', 'z'), random(0, test.size()))); } -template void clause_21_3_6_z(String & test) { +template void clause11_21_4_7_8(String & test) { test = test.substr(random(0, test.size()), random(0, test.size())); } -template void clause_21_3_7_a(String & test) { +template void clause11_21_4_7_9_a(String & test) { String s; randomString(&s, maxString); int tristate = test.compare(s); @@ -671,7 +771,7 @@ template void clause_21_3_7_a(String & test) { Num2String(test, tristate); } -template void clause_21_3_7_b(String & test) { +template void clause11_21_4_7_9_b(String & test) { String s; randomString(&s, maxString); int tristate = test.compare( @@ -683,7 +783,7 @@ template void clause_21_3_7_b(String & test) { Num2String(test, tristate); } -template void clause_21_3_7_c(String & test) { +template void clause11_21_4_7_9_c(String & test) { String str; randomString(&str, maxString); int tristate = test.compare( @@ -697,7 +797,7 @@ template void clause_21_3_7_c(String & test) { Num2String(test, tristate); } -template void clause_21_3_7_d(String & test) { +template void clause11_21_4_7_9_d(String & test) { String s; randomString(&s, maxString); int tristate = test.compare(s.c_str()); @@ -706,7 +806,7 @@ template void clause_21_3_7_d(String & test) { Num2String(test, tristate); } -template void clause_21_3_7_e(String & test) { +template void clause11_21_4_7_9_e(String & test) { String str; randomString(&str, maxString); int tristate = test.compare( @@ -719,7 +819,7 @@ template void clause_21_3_7_e(String & test) { Num2String(test, tristate); } -template void clause_21_3_7_f(String & test) { +template void clause11_21_4_8_1_a(String & test) { String s1; randomString(&s1, maxString); String s2; @@ -727,7 +827,7 @@ template void clause_21_3_7_f(String & test) { test = s1 + s2; } -template void clause_21_3_7_g(String & test) { +template void clause11_21_4_8_1_b(String & test) { String s; randomString(&s, maxString); String s1; @@ -735,13 +835,13 @@ template void clause_21_3_7_g(String & test) { test = s.c_str() + s1; } -template void clause_21_3_7_h(String & test) { +template void clause11_21_4_8_1_c(String & test) { String s; randomString(&s, maxString); test = typename String::value_type(random('a', 'z')) + s; } -template void clause_21_3_7_i(String & test) { +template void clause11_21_4_8_1_d(String & test) { String s; randomString(&s, maxString); String s1; @@ -749,7 +849,7 @@ template void clause_21_3_7_i(String & test) { test = s + s1.c_str(); } -template void clause_21_3_7_j(String & test) { +template void clause11_21_4_8_1_e(String & test) { String s; randomString(&s, maxString); String s1; @@ -757,14 +857,14 @@ template void clause_21_3_7_j(String & test) { test = s + s1.c_str(); } -template void clause_21_3_7_k(String & test) { +template void clause11_21_4_8_1_f(String & test) { String s; randomString(&s, maxString); test = s + typename String::value_type(random('a', 'z')); } // Numbering here is from C++11 -template void clause_21_4_8_9_a(String & test) { +template void clause11_21_4_8_9_a(String & test) { basic_stringstream stst(test.c_str()); String str; while (stst) { @@ -789,15 +889,15 @@ TEST(FBString, testAllClauses) { wc = folly::basic_fbstring(wr.c_str()); \ auto localSeed = seed + count; \ rng = RandomT(localSeed); \ - clause_##x(r); \ + clause11_##x(r); \ rng = RandomT(localSeed); \ - clause_##x(c); \ + clause11_##x(c); \ EXPECT_EQ(r, c) \ << "Lengths: " << r.size() << " vs. " << c.size() \ << "\nReference: '" << r << "'" \ << "\nActual: '" << c.data()[0] << "'"; \ rng = RandomT(localSeed); \ - clause_##x(wc); \ + clause11_##x(wc); \ int wret = wcslen(wc.c_str()); \ char mb[wret+1]; \ int ret = wcstombs(mb, wc.c_str(), sizeof(mb)); \ @@ -809,73 +909,80 @@ TEST(FBString, testAllClauses) { } while (++count % 100 != 0) int count = 0; - TEST_CLAUSE(21_3_1_a); - TEST_CLAUSE(21_3_1_b); - TEST_CLAUSE(21_3_1_c); - TEST_CLAUSE(21_3_1_d); - TEST_CLAUSE(21_3_1_e); - TEST_CLAUSE(21_3_1_f); - TEST_CLAUSE(21_3_1_g); - - TEST_CLAUSE(21_3_2); - TEST_CLAUSE(21_3_3); - TEST_CLAUSE(21_3_4); - TEST_CLAUSE(21_3_5_a); - TEST_CLAUSE(21_3_5_b); - TEST_CLAUSE(21_3_5_c); - TEST_CLAUSE(21_3_5_d); - TEST_CLAUSE(21_3_5_e); - TEST_CLAUSE(21_3_5_f); - TEST_CLAUSE(21_3_5_g); - TEST_CLAUSE(21_3_5_h); - TEST_CLAUSE(21_3_5_i); - TEST_CLAUSE(21_3_5_j); - TEST_CLAUSE(21_3_5_k); - TEST_CLAUSE(21_3_5_l); - TEST_CLAUSE(21_3_5_m); - TEST_CLAUSE(21_3_5_n); - TEST_CLAUSE(21_3_5_o); - TEST_CLAUSE(21_3_5_p); - - TEST_CLAUSE(21_3_6_a); - TEST_CLAUSE(21_3_6_b); - TEST_CLAUSE(21_3_6_c); - TEST_CLAUSE(21_3_6_d); - TEST_CLAUSE(21_3_6_e); - TEST_CLAUSE(21_3_6_f); - TEST_CLAUSE(21_3_6_g); - TEST_CLAUSE(21_3_6_h); - TEST_CLAUSE(21_3_6_i); - TEST_CLAUSE(21_3_6_j); - TEST_CLAUSE(21_3_6_k); - TEST_CLAUSE(21_3_6_l); - TEST_CLAUSE(21_3_6_m); - TEST_CLAUSE(21_3_6_n); - TEST_CLAUSE(21_3_6_o); - TEST_CLAUSE(21_3_6_p); - TEST_CLAUSE(21_3_6_q); - TEST_CLAUSE(21_3_6_r); - TEST_CLAUSE(21_3_6_s); - TEST_CLAUSE(21_3_6_t); - TEST_CLAUSE(21_3_6_u); - TEST_CLAUSE(21_3_6_v); - TEST_CLAUSE(21_3_6_w); - TEST_CLAUSE(21_3_6_x); - TEST_CLAUSE(21_3_6_y); - TEST_CLAUSE(21_3_6_z); - - TEST_CLAUSE(21_3_7_a); - TEST_CLAUSE(21_3_7_b); - TEST_CLAUSE(21_3_7_c); - TEST_CLAUSE(21_3_7_d); - TEST_CLAUSE(21_3_7_e); - TEST_CLAUSE(21_3_7_f); - TEST_CLAUSE(21_3_7_g); - TEST_CLAUSE(21_3_7_h); - TEST_CLAUSE(21_3_7_i); - TEST_CLAUSE(21_3_7_j); - TEST_CLAUSE(21_3_7_k); - + TEST_CLAUSE(21_4_2_a); + TEST_CLAUSE(21_4_2_b); + TEST_CLAUSE(21_4_2_c); + TEST_CLAUSE(21_4_2_d); + TEST_CLAUSE(21_4_2_e); + TEST_CLAUSE(21_4_2_f); + TEST_CLAUSE(21_4_2_g); + TEST_CLAUSE(21_4_2_h); + TEST_CLAUSE(21_4_2_i); + TEST_CLAUSE(21_4_2_j); + TEST_CLAUSE(21_4_2_k); + TEST_CLAUSE(21_4_2_l); + TEST_CLAUSE(21_4_2_lprime); + TEST_CLAUSE(21_4_2_m); + TEST_CLAUSE(21_4_2_n); + TEST_CLAUSE(21_4_3); + TEST_CLAUSE(21_4_4); + TEST_CLAUSE(21_4_5); + TEST_CLAUSE(21_4_6_1); + TEST_CLAUSE(21_4_6_2); + TEST_CLAUSE(21_4_6_3_a); + TEST_CLAUSE(21_4_6_3_b); + TEST_CLAUSE(21_4_6_3_c); + TEST_CLAUSE(21_4_6_3_d); + TEST_CLAUSE(21_4_6_3_e); + TEST_CLAUSE(21_4_6_3_f); + TEST_CLAUSE(21_4_6_3_g); + TEST_CLAUSE(21_4_6_3_h); + TEST_CLAUSE(21_4_6_3_i); + TEST_CLAUSE(21_4_6_3_j); + TEST_CLAUSE(21_4_6_3_k); + TEST_CLAUSE(21_4_6_4); + TEST_CLAUSE(21_4_6_5); + TEST_CLAUSE(21_4_6_6); + TEST_CLAUSE(21_4_6_7); + TEST_CLAUSE(21_4_6_8); + TEST_CLAUSE(21_4_7_1); + + TEST_CLAUSE(21_4_7_2_a); + TEST_CLAUSE(21_4_7_2_b); + TEST_CLAUSE(21_4_7_2_c); + TEST_CLAUSE(21_4_7_2_d); + TEST_CLAUSE(21_4_7_3_a); + TEST_CLAUSE(21_4_7_3_b); + TEST_CLAUSE(21_4_7_3_c); + TEST_CLAUSE(21_4_7_3_d); + TEST_CLAUSE(21_4_7_4_a); + TEST_CLAUSE(21_4_7_4_b); + TEST_CLAUSE(21_4_7_4_c); + TEST_CLAUSE(21_4_7_4_d); + TEST_CLAUSE(21_4_7_5_a); + TEST_CLAUSE(21_4_7_5_b); + TEST_CLAUSE(21_4_7_5_c); + TEST_CLAUSE(21_4_7_5_d); + TEST_CLAUSE(21_4_7_6_a); + TEST_CLAUSE(21_4_7_6_b); + TEST_CLAUSE(21_4_7_6_c); + TEST_CLAUSE(21_4_7_6_d); + TEST_CLAUSE(21_4_7_7_a); + TEST_CLAUSE(21_4_7_7_b); + TEST_CLAUSE(21_4_7_7_c); + TEST_CLAUSE(21_4_7_7_d); + TEST_CLAUSE(21_4_7_8); + TEST_CLAUSE(21_4_7_9_a); + TEST_CLAUSE(21_4_7_9_b); + TEST_CLAUSE(21_4_7_9_c); + TEST_CLAUSE(21_4_7_9_d); + TEST_CLAUSE(21_4_7_9_e); + TEST_CLAUSE(21_4_8_1_a); + TEST_CLAUSE(21_4_8_1_b); + TEST_CLAUSE(21_4_8_1_c); + TEST_CLAUSE(21_4_8_1_d); + TEST_CLAUSE(21_4_8_1_e); + TEST_CLAUSE(21_4_8_1_f); TEST_CLAUSE(21_4_8_9_a); } -- 2.34.1