/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <atomic>
#include <cstdlib>
-
#include <iomanip>
#include <list>
#include <sstream>
+
#include <boost/algorithm/string.hpp>
#include <boost/random.hpp>
+#include <folly/Conv.h>
#include <folly/Foreach.h>
#include <folly/Portability.h>
#include <folly/Random.h>
-#include <folly/Conv.h>
#include <folly/portability/GTest.h>
using namespace std;
EXPECT_EQ(test, s2);
// Constructor from other iterators
std::list<char> lst;
- for (auto c : test) lst.push_back(c);
+ 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);
+ for (auto c : test) {
+ lst1.push_back(c);
+ }
String s4(lst1.begin(), lst1.end());
EXPECT_EQ(test, s4);
// Constructor from wchar_t pointers
}
template <class String> void clause11_21_4_2_m(String & test) {
// Assignment from char
- test = random('a', 'z');
+ using value_type = typename String::value_type;
+ test = random(static_cast<value_type>('a'), static_cast<value_type>('z'));
}
template <class String> void clause11_21_4_2_n(String & test) {
// Assignment from initializer_list<char>
// exercise empty
string empty("empty");
string notempty("not empty");
- if (test.empty()) test = String(empty.begin(), empty.end());
- else test = String(notempty.begin(), notempty.end());
+ if (test.empty()) {
+ test = String(empty.begin(), empty.end());
+ } else {
+ test = String(notempty.begin(), notempty.end());
+ }
}
template <class String> void clause11_21_4_5(String & test) {
String s;
randomString(&s, maxString);
int tristate = test.compare(s);
- if (tristate > 0) tristate = 1;
- else if (tristate < 0) tristate = 2;
+ if (tristate > 0) {
+ tristate = 1;
+ } else if (tristate < 0) {
+ tristate = 2;
+ }
Num2String(test, tristate);
}
random(0, test.size()),
random(0, test.size()),
s);
- if (tristate > 0) tristate = 1;
- else if (tristate < 0) tristate = 2;
+ if (tristate > 0) {
+ tristate = 1;
+ } else if (tristate < 0) {
+ tristate = 2;
+ }
Num2String(test, tristate);
}
str,
random(0, str.size()),
random(0, str.size()));
- if (tristate > 0) tristate = 1;
- else if (tristate < 0) tristate = 2;
+ if (tristate > 0) {
+ tristate = 1;
+ } else if (tristate < 0) {
+ tristate = 2;
+ }
Num2String(test, tristate);
}
String s;
randomString(&s, maxString);
int tristate = test.compare(s.c_str());
- if (tristate > 0) tristate = 1;
- else if (tristate < 0) tristate = 2;
- Num2String(test, tristate);
+ if (tristate > 0) {
+ tristate = 1;
+ } else if (tristate < 0) {
+ tristate = 2;
+ }
+ Num2String(test, tristate);
}
template <class String> void clause11_21_4_7_9_e(String & test) {
random(0, test.size()),
str.c_str(),
random(0, str.size()));
- if (tristate > 0) tristate = 1;
- else if (tristate < 0) tristate = 2;
+ if (tristate > 0) {
+ tristate = 1;
+ } else if (tristate < 0) {
+ tristate = 2;
+ }
Num2String(test, tristate);
}
void(*f_fbstring)(folly::fbstring&),
void(*f_wfbstring)(folly::basic_fbstring<wchar_t>&)) {
do {
- if (1) {} else EXPECT_TRUE(1) << "Testing clause " << clause;
+ if (1) {
+ } else {
+ EXPECT_TRUE(1) << "Testing clause " << clause;
+ }
randomString(&r);
c = r;
EXPECT_EQ(c, r);
auto mbv = std::vector<char>(wret + 1);
auto mb = mbv.data();
int ret = wcstombs(mb, wc.c_str(), wret + 1);
- if (ret == wret) mb[wret] = '\0';
+ if (ret == wret) {
+ mb[wret] = '\0';
+ }
const char *mc = c.c_str();
std::string one(mb);
std::string two(mc);
{ // D3698862
EXPECT_EQ(fbstring().find(fbstring(), 4), fbstring::npos);
}
+ if (usingJEMalloc()) { // D4355440
+ fbstring str(1337, 'f');
+ str.reserve(3840);
+ EXPECT_NE(str.capacity(), 3840);
+
+ struct {
+ std::atomic<size_t> refCount_;
+ } dummyRefCounted;
+ EXPECT_EQ(
+ str.capacity(),
+ goodMallocSize(3840) - sizeof(dummyRefCounted) - sizeof(char));
+ }
}
TEST(FBString, findWithNpos) {
}
};
-} // anon namespace
+} // namespace
TEST(FBStringCtorTest, DefaultInitStructDefaultAlloc) {
TestStructDefaultAllocator t1 { };
folly::fbstring f(p, n);
EXPECT_EQ(f.size(), 0);
}
+
+// Tests for the comparison operators. I use EXPECT_TRUE rather than EXPECT_LE
+// because what's under test is the operator rather than the relation between
+// the objects.
+
+TEST(FBString, compareToStdString) {
+ using folly::fbstring;
+ using namespace std::string_literals;
+ auto stdA = "a"s;
+ auto stdB = "b"s;
+ fbstring fbA("a");
+ fbstring fbB("b");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+
+TEST(U16FBString, compareToStdU16String) {
+ using folly::basic_fbstring;
+ using namespace std::string_literals;
+ auto stdA = u"a"s;
+ auto stdB = u"b"s;
+ basic_fbstring<char16_t> fbA(u"a");
+ basic_fbstring<char16_t> fbB(u"b");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+
+TEST(U32FBString, compareToStdU32String) {
+ using folly::basic_fbstring;
+ using namespace std::string_literals;
+ auto stdA = U"a"s;
+ auto stdB = U"b"s;
+ basic_fbstring<char32_t> fbA(U"a");
+ basic_fbstring<char32_t> fbB(U"b");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+
+TEST(WFBString, compareToStdWString) {
+ using folly::basic_fbstring;
+ using namespace std::string_literals;
+ auto stdA = L"a"s;
+ auto stdB = L"b"s;
+ basic_fbstring<wchar_t> fbA(L"a");
+ basic_fbstring<wchar_t> fbB(L"b");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+
+// Same again, but with a more challenging input - a common prefix and different
+// lengths.
+
+TEST(FBString, compareToStdStringLong) {
+ using folly::fbstring;
+ using namespace std::string_literals;
+ auto stdA = "1234567890a"s;
+ auto stdB = "1234567890ab"s;
+ fbstring fbA("1234567890a");
+ fbstring fbB("1234567890ab");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+
+TEST(U16FBString, compareToStdU16StringLong) {
+ using folly::basic_fbstring;
+ using namespace std::string_literals;
+ auto stdA = u"1234567890a"s;
+ auto stdB = u"1234567890ab"s;
+ basic_fbstring<char16_t> fbA(u"1234567890a");
+ basic_fbstring<char16_t> fbB(u"1234567890ab");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+
+#if FOLLY_HAVE_WCHAR_SUPPORT
+TEST(U32FBString, compareToStdU32StringLong) {
+ using folly::basic_fbstring;
+ using namespace std::string_literals;
+ auto stdA = U"1234567890a"s;
+ auto stdB = U"1234567890ab"s;
+ basic_fbstring<char32_t> fbA(U"1234567890a");
+ basic_fbstring<char32_t> fbB(U"1234567890ab");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+
+TEST(WFBString, compareToStdWStringLong) {
+ using folly::basic_fbstring;
+ using namespace std::string_literals;
+ auto stdA = L"1234567890a"s;
+ auto stdB = L"1234567890ab"s;
+ basic_fbstring<wchar_t> fbA(L"1234567890a");
+ basic_fbstring<wchar_t> fbB(L"1234567890ab");
+ EXPECT_TRUE(stdA == fbA);
+ EXPECT_TRUE(fbB == stdB);
+ EXPECT_TRUE(stdA != fbB);
+ EXPECT_TRUE(fbA != stdB);
+ EXPECT_TRUE(stdA < fbB);
+ EXPECT_TRUE(fbA < stdB);
+ EXPECT_TRUE(stdB > fbA);
+ EXPECT_TRUE(fbB > stdA);
+ EXPECT_TRUE(stdA <= fbB);
+ EXPECT_TRUE(fbA <= stdB);
+ EXPECT_TRUE(stdA <= fbA);
+ EXPECT_TRUE(fbA <= stdA);
+ EXPECT_TRUE(stdB >= fbA);
+ EXPECT_TRUE(fbB >= stdA);
+ EXPECT_TRUE(stdB >= fbB);
+ EXPECT_TRUE(fbB >= stdB);
+}
+#endif