Commit dff24ff9 authored by Andrei Alexandrescu's avatar Andrei Alexandrescu Committed by Dave Watson

Bring fbstring::operator+ to date with C++11

Summary: Some overloads, particularly with rvalue references, were missing. Also this fixes https://our.intern.facebook.com/intern/tasks/?t=5849579

Test Plan: unittests

Reviewed By: simpkins@fb.com

Subscribers: trunkagent, las, net-systems@, njormrod, folly-diffs@

FB internal diff: D1746319

Tasks: 5849579

Signature: t1:1746319:1418875228:febb965cf52710a5e76b7c1cce5aec601086ad90
parent 5219f070
...@@ -1969,11 +1969,18 @@ public: ...@@ -1969,11 +1969,18 @@ public:
return find_last_not_of(&c, pos, 1); return find_last_not_of(&c, pos, 1);
} }
basic_fbstring substr(size_type pos = 0, size_type n = npos) const { basic_fbstring substr(size_type pos = 0, size_type n = npos) const& {
enforce(pos <= size(), std::__throw_out_of_range, ""); enforce(pos <= size(), std::__throw_out_of_range, "");
return basic_fbstring(data() + pos, std::min(n, size() - pos)); return basic_fbstring(data() + pos, std::min(n, size() - pos));
} }
basic_fbstring substr(size_type pos = 0, size_type n = npos) && {
enforce(pos <= size(), std::__throw_out_of_range, "");
erase(0, pos);
if (n < size()) resize(n);
return std::move(*this);
}
int compare(const basic_fbstring& str) const { int compare(const basic_fbstring& str) const {
// FIX due to Goncalo N M de Carvalho July 18, 2005 // FIX due to Goncalo N M de Carvalho July 18, 2005
return compare(0, size(), str); return compare(0, size(), str);
...@@ -2021,7 +2028,7 @@ private: ...@@ -2021,7 +2028,7 @@ private:
}; };
// non-member functions // non-member functions
// C++11 21.4.8.1/2 // C++11 21.4.8.1/1
template <typename E, class T, class A, class S> template <typename E, class T, class A, class S>
inline inline
basic_fbstring<E, T, A, S> operator+(const basic_fbstring<E, T, A, S>& lhs, basic_fbstring<E, T, A, S> operator+(const basic_fbstring<E, T, A, S>& lhs,
...@@ -2063,24 +2070,44 @@ basic_fbstring<E, T, A, S> operator+(basic_fbstring<E, T, A, S>&& lhs, ...@@ -2063,24 +2070,44 @@ basic_fbstring<E, T, A, S> operator+(basic_fbstring<E, T, A, S>&& lhs,
return std::move(lhs.append(rhs)); return std::move(lhs.append(rhs));
} }
// C++11 21.4.8.1/5
template <typename E, class T, class A, class S> template <typename E, class T, class A, class S>
inline inline
basic_fbstring<E, T, A, S> operator+( basic_fbstring<E, T, A, S> operator+(
const typename basic_fbstring<E, T, A, S>::value_type* lhs, const E* lhs,
const basic_fbstring<E, T, A, S>& rhs) { const basic_fbstring<E, T, A, S>& rhs) {
// //
basic_fbstring<E, T, A, S> result; basic_fbstring<E, T, A, S> result;
const typename basic_fbstring<E, T, A, S>::size_type len = const auto len = basic_fbstring<E, T, A, S>::traits_type::length(lhs);
basic_fbstring<E, T, A, S>::traits_type::length(lhs);
result.reserve(len + rhs.size()); result.reserve(len + rhs.size());
result.append(lhs, len).append(rhs); result.append(lhs, len).append(rhs);
return result; return result;
} }
// C++11 21.4.8.1/6
template <typename E, class T, class A, class S> template <typename E, class T, class A, class S>
inline inline
basic_fbstring<E, T, A, S> operator+( basic_fbstring<E, T, A, S> operator+(
typename basic_fbstring<E, T, A, S>::value_type lhs, const E* lhs,
basic_fbstring<E, T, A, S>&& rhs) {
//
const auto len = basic_fbstring<E, T, A, S>::traits_type::length(lhs);
if (rhs.capacity() >= len + rhs.size()) {
// Good, at least we don't need to reallocate
return std::move(rhs.insert(rhs.begin(), lhs, lhs + len));
}
// Meh, no go. Do it by hand since we have len already.
basic_fbstring<E, T, A, S> result;
result.reserve(len + rhs.size());
result.append(lhs, len).append(rhs);
return result;
}
// C++11 21.4.8.1/7
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
E lhs,
const basic_fbstring<E, T, A, S>& rhs) { const basic_fbstring<E, T, A, S>& rhs) {
basic_fbstring<E, T, A, S> result; basic_fbstring<E, T, A, S> result;
...@@ -2090,11 +2117,28 @@ basic_fbstring<E, T, A, S> operator+( ...@@ -2090,11 +2117,28 @@ basic_fbstring<E, T, A, S> operator+(
return result; return result;
} }
// C++11 21.4.8.1/8
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
E lhs,
basic_fbstring<E, T, A, S>&& rhs) {
//
if (rhs.capacity() > rhs.size()) {
// Good, at least we don't need to reallocate
return std::move(rhs.insert(rhs.begin(), lhs));
}
// Meh, no go. Forward to operator+(E, const&).
auto const& rhsC = rhs;
return lhs + rhsC;
}
// C++11 21.4.8.1/9
template <typename E, class T, class A, class S> template <typename E, class T, class A, class S>
inline inline
basic_fbstring<E, T, A, S> operator+( basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs, const basic_fbstring<E, T, A, S>& lhs,
const typename basic_fbstring<E, T, A, S>::value_type* rhs) { const E* rhs) {
typedef typename basic_fbstring<E, T, A, S>::size_type size_type; typedef typename basic_fbstring<E, T, A, S>::size_type size_type;
typedef typename basic_fbstring<E, T, A, S>::traits_type traits_type; typedef typename basic_fbstring<E, T, A, S>::traits_type traits_type;
...@@ -2106,11 +2150,22 @@ basic_fbstring<E, T, A, S> operator+( ...@@ -2106,11 +2150,22 @@ basic_fbstring<E, T, A, S> operator+(
return result; return result;
} }
// C++11 21.4.8.1/10
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
basic_fbstring<E, T, A, S>&& lhs,
const E* rhs) {
//
return std::move(lhs += rhs);
}
// C++11 21.4.8.1/11
template <typename E, class T, class A, class S> template <typename E, class T, class A, class S>
inline inline
basic_fbstring<E, T, A, S> operator+( basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs, const basic_fbstring<E, T, A, S>& lhs,
typename basic_fbstring<E, T, A, S>::value_type rhs) { E rhs) {
basic_fbstring<E, T, A, S> result; basic_fbstring<E, T, A, S> result;
result.reserve(lhs.size() + 1); result.reserve(lhs.size() + 1);
...@@ -2119,6 +2174,16 @@ basic_fbstring<E, T, A, S> operator+( ...@@ -2119,6 +2174,16 @@ basic_fbstring<E, T, A, S> operator+(
return result; return result;
} }
// C++11 21.4.8.1/12
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
basic_fbstring<E, T, A, S>&& lhs,
E rhs) {
//
return std::move(lhs += rhs);
}
template <typename E, class T, class A, class S> template <typename E, class T, class A, class S>
inline inline
bool operator==(const basic_fbstring<E, T, A, S>& lhs, bool operator==(const basic_fbstring<E, T, A, S>& lhs,
......
...@@ -603,6 +603,21 @@ template <class String> void clause11_21_4_7_2_a(String & test) { ...@@ -603,6 +603,21 @@ template <class String> void clause11_21_4_7_2_a(String & test) {
Num2String(test, test.find(str, random(0, test.size()))); Num2String(test, test.find(str, random(0, test.size())));
} }
template <class String> void clause11_21_4_7_2_a1(String & test) {
String str = String(test).substr(
random(0, test.size()),
random(0, test.size()));
Num2String(test, test.find(str, random(0, test.size())));
}
template <class String> void clause11_21_4_7_2_a2(String & test) {
auto const& cTest = test;
String str = cTest.substr(
random(0, test.size()),
random(0, test.size()));
Num2String(test, test.find(str, random(0, test.size())));
}
template <class String> void clause11_21_4_7_2_b(String & test) { template <class String> void clause11_21_4_7_2_b(String & test) {
auto from = random(0, test.size()); auto from = random(0, test.size());
auto length = random(0, test.size() - from); auto length = random(0, test.size() - from);
...@@ -612,6 +627,25 @@ template <class String> void clause11_21_4_7_2_b(String & test) { ...@@ -612,6 +627,25 @@ template <class String> void clause11_21_4_7_2_b(String & test) {
random(0, str.size()))); random(0, str.size())));
} }
template <class String> void clause11_21_4_7_2_b1(String & test) {
auto from = random(0, test.size());
auto length = random(0, test.size() - from);
String str = String(test).substr(from, length);
Num2String(test, test.find(str.c_str(),
random(0, test.size()),
random(0, str.size())));
}
template <class String> void clause11_21_4_7_2_b2(String & test) {
auto from = random(0, test.size());
auto length = random(0, test.size() - from);
const auto& cTest = test;
String str = cTest.substr(from, length);
Num2String(test, test.find(str.c_str(),
random(0, test.size()),
random(0, str.size())));
}
template <class String> void clause11_21_4_7_2_c(String & test) { template <class String> void clause11_21_4_7_2_c(String & test) {
String str = test.substr( String str = test.substr(
random(0, test.size()), random(0, test.size()),
...@@ -620,6 +654,23 @@ template <class String> void clause11_21_4_7_2_c(String & test) { ...@@ -620,6 +654,23 @@ template <class String> void clause11_21_4_7_2_c(String & test) {
random(0, test.size()))); random(0, test.size())));
} }
template <class String> void clause11_21_4_7_2_c1(String & test) {
String str = String(test).substr(
random(0, test.size()),
random(0, test.size()));
Num2String(test, test.find(str.c_str(),
random(0, test.size())));
}
template <class String> void clause11_21_4_7_2_c2(String & test) {
const auto& cTest = test;
String str = cTest.substr(
random(0, test.size()),
random(0, test.size()));
Num2String(test, test.find(str.c_str(),
random(0, test.size())));
}
template <class String> void clause11_21_4_7_2_d(String & test) { template <class String> void clause11_21_4_7_2_d(String & test) {
Num2String(test, test.find( Num2String(test, test.find(
random('a', 'z'), random('a', 'z'),
...@@ -838,6 +889,30 @@ template <class String> void clause11_21_4_8_1_a(String & test) { ...@@ -838,6 +889,30 @@ template <class String> void clause11_21_4_8_1_a(String & test) {
} }
template <class String> void clause11_21_4_8_1_b(String & test) { template <class String> void clause11_21_4_8_1_b(String & test) {
String s1;
randomString(&s1, maxString);
String s2;
randomString(&s2, maxString);
test = move(s1) + s2;
}
template <class String> void clause11_21_4_8_1_c(String & test) {
String s1;
randomString(&s1, maxString);
String s2;
randomString(&s2, maxString);
test = s1 + move(s2);
}
template <class String> void clause11_21_4_8_1_d(String & test) {
String s1;
randomString(&s1, maxString);
String s2;
randomString(&s2, maxString);
test = move(s1) + move(s2);
}
template <class String> void clause11_21_4_8_1_e(String & test) {
String s; String s;
randomString(&s, maxString); randomString(&s, maxString);
String s1; String s1;
...@@ -845,13 +920,27 @@ template <class String> void clause11_21_4_8_1_b(String & test) { ...@@ -845,13 +920,27 @@ template <class String> void clause11_21_4_8_1_b(String & test) {
test = s.c_str() + s1; test = s.c_str() + s1;
} }
template <class String> void clause11_21_4_8_1_c(String & test) { template <class String> void clause11_21_4_8_1_f(String & test) {
String s;
randomString(&s, maxString);
String s1;
randomString(&s1, maxString);
test = s.c_str() + move(s1);
}
template <class String> void clause11_21_4_8_1_g(String & test) {
String s; String s;
randomString(&s, maxString); randomString(&s, maxString);
test = typename String::value_type(random('a', 'z')) + s; test = typename String::value_type(random('a', 'z')) + s;
} }
template <class String> void clause11_21_4_8_1_d(String & test) { template <class String> void clause11_21_4_8_1_h(String & test) {
String s;
randomString(&s, maxString);
test = typename String::value_type(random('a', 'z')) + move(s);
}
template <class String> void clause11_21_4_8_1_i(String & test) {
String s; String s;
randomString(&s, maxString); randomString(&s, maxString);
String s1; String s1;
...@@ -859,20 +948,28 @@ template <class String> void clause11_21_4_8_1_d(String & test) { ...@@ -859,20 +948,28 @@ template <class String> void clause11_21_4_8_1_d(String & test) {
test = s + s1.c_str(); test = s + s1.c_str();
} }
template <class String> void clause11_21_4_8_1_e(String & test) { template <class String> void clause11_21_4_8_1_j(String & test) {
String s; String s;
randomString(&s, maxString); randomString(&s, maxString);
String s1; String s1;
randomString(&s1, maxString); randomString(&s1, maxString);
test = s + s1.c_str(); test = move(s) + s1.c_str();
} }
template <class String> void clause11_21_4_8_1_f(String & test) { template <class String> void clause11_21_4_8_1_k(String & test) {
String s; String s;
randomString(&s, maxString); randomString(&s, maxString);
test = s + typename String::value_type(random('a', 'z')); test = s + typename String::value_type(random('a', 'z'));
} }
template <class String> void clause11_21_4_8_1_l(String & test) {
String s;
randomString(&s, maxString);
String s1;
randomString(&s1, maxString);
test = move(s) + s1.c_str();
}
// Numbering here is from C++11 // Numbering here is from C++11
template <class String> void clause11_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()); basic_stringstream<typename String::value_type> stst(test.c_str());
...@@ -969,8 +1066,14 @@ TEST(FBString, testAllClauses) { ...@@ -969,8 +1066,14 @@ TEST(FBString, testAllClauses) {
TEST_CLAUSE(21_4_7_1); TEST_CLAUSE(21_4_7_1);
TEST_CLAUSE(21_4_7_2_a); TEST_CLAUSE(21_4_7_2_a);
TEST_CLAUSE(21_4_7_2_a1);
TEST_CLAUSE(21_4_7_2_a2);
TEST_CLAUSE(21_4_7_2_b); TEST_CLAUSE(21_4_7_2_b);
TEST_CLAUSE(21_4_7_2_b1);
TEST_CLAUSE(21_4_7_2_b2);
TEST_CLAUSE(21_4_7_2_c); TEST_CLAUSE(21_4_7_2_c);
TEST_CLAUSE(21_4_7_2_c1);
TEST_CLAUSE(21_4_7_2_c2);
TEST_CLAUSE(21_4_7_2_d); TEST_CLAUSE(21_4_7_2_d);
TEST_CLAUSE(21_4_7_3_a); TEST_CLAUSE(21_4_7_3_a);
TEST_CLAUSE(21_4_7_3_b); TEST_CLAUSE(21_4_7_3_b);
...@@ -1004,6 +1107,12 @@ TEST(FBString, testAllClauses) { ...@@ -1004,6 +1107,12 @@ TEST(FBString, testAllClauses) {
TEST_CLAUSE(21_4_8_1_d); TEST_CLAUSE(21_4_8_1_d);
TEST_CLAUSE(21_4_8_1_e); TEST_CLAUSE(21_4_8_1_e);
TEST_CLAUSE(21_4_8_1_f); TEST_CLAUSE(21_4_8_1_f);
TEST_CLAUSE(21_4_8_1_g);
TEST_CLAUSE(21_4_8_1_h);
TEST_CLAUSE(21_4_8_1_i);
TEST_CLAUSE(21_4_8_1_j);
TEST_CLAUSE(21_4_8_1_k);
TEST_CLAUSE(21_4_8_1_l);
TEST_CLAUSE(21_4_8_9_a); 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