Commit af1b0a8b authored by Andrei Alexandrescu's avatar Andrei Alexandrescu Committed by Sara Golemon

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
parent ea72b037
......@@ -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<value_type> 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<value_type> 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<value_type> 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<value_type> 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<value_type> il) {
return assign(il.begin(), il.end());
}
template <class ItOrLength, class ItOrChar>
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 <int i> class Selector {};
basic_fbstring& insertImplDiscr(iterator p,
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<class InputIter>
basic_fbstring& insertImplDiscr(iterator i,
iterator insertImplDiscr(const_iterator i,
InputIter b, InputIter e, Selector<0>) {
insertImpl(i, b, e,
return insertImpl(i, b, e,
typename std::iterator_traits<InputIter>::iterator_category());
return *this;
}
template <class FwdIterator>
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 <class InputIterator>
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 <class ItOrLength, class ItOrChar>
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<std::numeric_limits<ItOrLength>::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<value_type> 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<E, T, A, S>::value_type* lhs,
return !(lhs < rhs);
}
// subclause 21.3.7.8:
// C++11 21.4.8.8
template <typename E, class T, class A, class S>
void swap(basic_fbstring<E, T, A, S>& lhs, basic_fbstring<E, T, A, S>& rhs) {
lhs.swap(rhs);
......
......@@ -77,17 +77,34 @@ std::list<char> RandomList(unsigned int maxSize) {
// Tests begin here
////////////////////////////////////////////////////////////////////////////////
template <class String> void clause_21_3_1_a(String & test) {
template <class String> void clause11_21_4_2_a(String & test) {
test.String::~String();
new(&test) String();
}
template <class String> void clause_21_3_1_b(String & test) {
// Copy constructor
template <class String> void clause11_21_4_2_b(String & test) {
String test2(test);
assert(test2 == test);
}
template <class String> 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 <class String> 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 <class String> void clause_21_3_1_c(String & test) {
template <class String> 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 <class String> 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 <class String> 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 <class String> 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 <class String> 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<char> 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<wchar_t> 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 <class String> void clause_21_3_1_d(String & test) {
// Assignment
template <class String> void clause11_21_4_2_i(String & test) {
// From initializer_list<char>
std::initializer_list<typename String::value_type>
il = { 'h', 'e', 'l', 'l', 'o' };
String s(il);
test.swap(s);
}
template <class String> 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 <class String> void clause_21_3_1_d(String & test) {
}
test = s;
}
template <class String> void clause_21_3_1_e(String & test) {
template <class String> 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 <class String> 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 <class String> void clause_21_3_1_e(String & test) {
}
test = s.c_str();
}
template <class String> void clause_21_3_1_f(String & test) {
template <class String> 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 <class String> void clause_21_3_1_f(String & test) {
test = test.c_str() + pos;
}
}
template <class String> void clause_21_3_1_g(String & test) {
template <class String> void clause11_21_4_2_m(String & test) {
// Assignment from char
test = random('a', 'z');
}
template <class String> void clause11_21_4_2_n(String & test) {
// Assignment from initializer_list<char>
initializer_list<typename String::value_type>
il = { 'h', 'e', 'l', 'l', 'o' };
test = il;
}
template <class String> void clause_21_3_2(String & test) {
template <class String> 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 <class String> void clause_21_3_2(String & test) {
EXPECT_EQ(s, test.size());
}
template <class String> void clause_21_3_3(String & test) {
template <class String> 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 <class String> void clause_21_3_3(String & test) {
else test = String(notempty.begin(), notempty.end());
}
template <class String> void clause_21_3_4(String & test) {
// exercise element access 21.3.4
template <class String> 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 <class String> void clause_21_3_5_a(String & test) {
template <class String> void clause11_21_4_6_1(String & test) {
// 21.3.5 modifiers (+=)
String test1;
randomString(&test1);
......@@ -240,9 +310,12 @@ template <class String> 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<typename String::value_type> il { 'a', 'b', 'c' };
test += il;
}
template <class String> void clause_21_3_5_b(String & test) {
template <class String> void clause11_21_4_6_2(String & test) {
// 21.3.5 modifiers (append, push_back)
String s;
......@@ -267,70 +340,85 @@ template <class String> 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<typename String::value_type> il { 'a', 'b', 'c' };
test.append(il);
}
template <class String> void clause_21_3_5_c(String & test) {
template <class String> 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 <class String> void clause_21_3_5_d(String & test) {
template <class String> 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 <class String> void clause_21_3_5_e(String & test) {
template <class String> 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 <class String> void clause_21_3_5_f(String & test) {
template <class String> void clause11_21_4_6_3_d(String & test) {
// assign
String s;
randomString(&s, maxString);
test.assign(s.c_str());
}
template <class String> void clause_21_3_5_g(String & test) {
template <class String> void clause11_21_4_6_3_e(String & test) {
// assign
String s;
randomString(&s, maxString);
test.assign(random(0, maxString), random('a', 'z'));
}
template <class String> void clause_21_3_5_h(String & test) {
template <class String> void clause11_21_4_6_3_f(String & test) {
// assign from bidirectional iterator
std::list<char> lst(RandomList(maxString));
test.assign(lst.begin(), lst.end());
}
template <class String> void clause_21_3_5_i(String & test) {
template <class String> void clause11_21_4_6_3_g(String & test) {
// assign from aliased source
test.assign(test);
}
template <class String> void clause_21_3_5_j(String & test) {
template <class String> void clause11_21_4_6_3_h(String & test) {
// assign from aliased source
test.assign(test, random(0, test.size()), random(0, maxString));
}
template <class String> void clause_21_3_5_k(String & test) {
template <class String> void clause11_21_4_6_3_i(String & test) {
// assign from aliased source
test.assign(test.c_str(), random(0, test.size()));
}
template <class String> void clause_21_3_5_l(String & test) {
template <class String> void clause11_21_4_6_3_j(String & test) {
// assign from aliased source
test.assign(test.c_str());
}
template <class String> void clause_21_3_5_m(String & test) {
template <class String> void clause11_21_4_6_3_k(String & test) {
// assign from initializer_list
initializer_list<typename String::value_type> il { 'a', 'b', 'c' };
test.assign(il);
}
template <class String> void clause11_21_4_6_4(String & test) {
// insert
String s;
randomString(&s, maxString);
......@@ -346,15 +434,23 @@ template <class String> 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<char> 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<typename String::value_type> 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 <class String> void clause_21_3_5_n(String & test) {
// erase
template <class String> 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 <class String> 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 <class String> void clause_21_3_5_o(String & test) {
template <class String> 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 <class String> void clause_21_3_5_o(String & test) {
random(0, maxString), random('a', 'z'));
}
template <class String> void clause_21_3_5_p(String & test) {
template <class String> void clause11_21_4_6_7(String & test) {
std::vector<typename String::value_type>
vec(random(0, maxString));
test.copy(
......@@ -470,13 +570,13 @@ template <class String> void clause_21_3_5_p(String & test) {
random(0, test.size()));
}
template <class String> void clause_21_3_5_q(String & test) {
template <class String> void clause11_21_4_6_8(String & test) {
String s;
randomString(&s, maxString);
s.swap(test);
}
template <class String> void clause_21_3_6_a(String & test) {
template <class String> 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 <class String> void clause_21_3_6_a(String & test) {
assert(test.get_allocator() == s.get_allocator());
}
template <class String> void clause_21_3_6_b(String & test) {
template <class String> 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 <class String> void clause_21_3_6_c(String & test) {
template <class String> 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 <class String> void clause_21_3_6_c(String & test) {
random(0, str.size())));
}
template <class String> void clause_21_3_6_d(String & test) {
template <class String> 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 <class String> void clause_21_3_6_d(String & test) {
random(0, test.size())));
}
template <class String> void clause_21_3_6_e(String & test) {
template <class String> void clause11_21_4_7_2_d(String & test) {
Num2String(test, test.find(
random('a', 'z'),
random(0, test.size())));
}
template <class String> void clause_21_3_6_f(String & test) {
template <class String> 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 <class String> void clause_21_3_6_g(String & test) {
template <class String> 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 <class String> void clause_21_3_6_g(String & test) {
random(0, str.size())));
}
template <class String> void clause_21_3_6_h(String & test) {
template <class String> 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 <class String> void clause_21_3_6_h(String & test) {
random(0, test.size())));
}
template <class String> void clause_21_3_6_i(String & test) {
template <class String> void clause11_21_4_7_3_d(String & test) {
Num2String(test, test.rfind(
random('a', 'z'),
random(0, test.size())));
}
template <class String> void clause_21_3_6_j(String & test) {
template <class String> 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 <class String> void clause_21_3_6_k(String & test) {
template <class String> 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 <class String> void clause_21_3_6_k(String & test) {
random(0, str.size())));
}
template <class String> void clause_21_3_6_l(String & test) {
template <class String> 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 <class String> void clause_21_3_6_m(String & test) {
template <class String> void clause11_21_4_7_4_d(String & test) {
Num2String(test, test.find_first_of(
random('a', 'z'),
random(0, test.size())));
}
template <class String> void clause_21_3_6_n(String & test) {
template <class String> 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 <class String> void clause_21_3_6_o(String & test) {
template <class String> 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 <class String> void clause_21_3_6_o(String & test) {
random(0, str.size())));
}
template <class String> void clause_21_3_6_p(String & test) {
template <class String> 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 <class String> void clause_21_3_6_q(String & test) {
template <class String> void clause11_21_4_7_5_d(String & test) {
Num2String(test, test.find_last_of(
random('a', 'z'),
random(0, test.size())));
}
template <class String> void clause_21_3_6_r(String & test) {
template <class String> 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 <class String> void clause_21_3_6_s(String & test) {
template <class String> 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 <class String> void clause_21_3_6_s(String & test) {
random(0, str.size())));
}
template <class String> void clause_21_3_6_t(String & test) {
template <class String> 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 <class String> void clause_21_3_6_u(String & test) {
template <class String> void clause11_21_4_7_6_d(String & test) {
Num2String(test, test.find_first_not_of(
random('a', 'z'),
random(0, test.size())));
}
template <class String> void clause_21_3_6_v(String & test) {
template <class String> 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 <class String> void clause_21_3_6_w(String & test) {
template <class String> 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 <class String> void clause_21_3_6_w(String & test) {
random(0, str.size())));
}
template <class String> void clause_21_3_6_x(String & test) {
template <class String> 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 <class String> void clause_21_3_6_y(String & test) {
template <class String> void clause11_21_4_7_7_d(String & test) {
Num2String(test, test.find_last_not_of(
random('a', 'z'),
random(0, test.size())));
}
template <class String> void clause_21_3_6_z(String & test) {
template <class String> void clause11_21_4_7_8(String & test) {
test = test.substr(random(0, test.size()), random(0, test.size()));
}
template <class String> void clause_21_3_7_a(String & test) {
template <class String> void clause11_21_4_7_9_a(String & test) {
String s;
randomString(&s, maxString);
int tristate = test.compare(s);
......@@ -671,7 +771,7 @@ template <class String> void clause_21_3_7_a(String & test) {
Num2String(test, tristate);
}
template <class String> void clause_21_3_7_b(String & test) {
template <class String> void clause11_21_4_7_9_b(String & test) {
String s;
randomString(&s, maxString);
int tristate = test.compare(
......@@ -683,7 +783,7 @@ template <class String> void clause_21_3_7_b(String & test) {
Num2String(test, tristate);
}
template <class String> void clause_21_3_7_c(String & test) {
template <class String> void clause11_21_4_7_9_c(String & test) {
String str;
randomString(&str, maxString);
int tristate = test.compare(
......@@ -697,7 +797,7 @@ template <class String> void clause_21_3_7_c(String & test) {
Num2String(test, tristate);
}
template <class String> void clause_21_3_7_d(String & test) {
template <class String> 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 <class String> void clause_21_3_7_d(String & test) {
Num2String(test, tristate);
}
template <class String> void clause_21_3_7_e(String & test) {
template <class String> void clause11_21_4_7_9_e(String & test) {
String str;
randomString(&str, maxString);
int tristate = test.compare(
......@@ -719,7 +819,7 @@ template <class String> void clause_21_3_7_e(String & test) {
Num2String(test, tristate);
}
template <class String> void clause_21_3_7_f(String & test) {
template <class String> void clause11_21_4_8_1_a(String & test) {
String s1;
randomString(&s1, maxString);
String s2;
......@@ -727,7 +827,7 @@ template <class String> void clause_21_3_7_f(String & test) {
test = s1 + s2;
}
template <class String> void clause_21_3_7_g(String & test) {
template <class String> void clause11_21_4_8_1_b(String & test) {
String s;
randomString(&s, maxString);
String s1;
......@@ -735,13 +835,13 @@ template <class String> void clause_21_3_7_g(String & test) {
test = s.c_str() + s1;
}
template <class String> void clause_21_3_7_h(String & test) {
template <class String> void clause11_21_4_8_1_c(String & test) {
String s;
randomString(&s, maxString);
test = typename String::value_type(random('a', 'z')) + s;
}
template <class String> void clause_21_3_7_i(String & test) {
template <class String> void clause11_21_4_8_1_d(String & test) {
String s;
randomString(&s, maxString);
String s1;
......@@ -749,7 +849,7 @@ template <class String> void clause_21_3_7_i(String & test) {
test = s + s1.c_str();
}
template <class String> void clause_21_3_7_j(String & test) {
template <class String> void clause11_21_4_8_1_e(String & test) {
String s;
randomString(&s, maxString);
String s1;
......@@ -757,14 +857,14 @@ template <class String> void clause_21_3_7_j(String & test) {
test = s + s1.c_str();
}
template <class String> void clause_21_3_7_k(String & test) {
template <class String> 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 <class String> void clause_21_4_8_9_a(String & test) {
template <class String> void clause11_21_4_8_9_a(String & test) {
basic_stringstream<typename String::value_type> stst(test.c_str());
String str;
while (stst) {
......@@ -789,15 +889,15 @@ TEST(FBString, testAllClauses) {
wc = folly::basic_fbstring<wchar_t>(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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment