Skip to content

Commit

Permalink
fbstring::append, fbstring::operator+= overloads for string_view
Browse files Browse the repository at this point in the history
Summary: Since C++17, `std::basic_string::append` and `std::basic_string::operator+=` have overloads supporting `std::basic_string_view`. Technically, these overloads accept types which are convertible to matching `std::basic_string_view` but not convertible to matching `const_pointer`. Give `folly::basic_fbstring` similar overloads.

Reviewed By: thedavekwon

Differential Revision: D62008263

fbshipit-source-id: 84cc357ec2acbba1e30eac84b2fdc42a76bc0f07
  • Loading branch information
yfeldblum authored and facebook-github-bot committed Aug 30, 2024
1 parent 06b6275 commit abeb583
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 8 deletions.
35 changes: 27 additions & 8 deletions folly/FBString.h
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,15 @@ class basic_fbstring {
private:
using string_view_type = std::basic_string_view<value_type, traits_type>;

template <typename StringViewLike>
static inline constexpr bool is_string_view_like_v =
std::is_convertible_v<StringViewLike const&, string_view_type> &&
!std::is_convertible_v<StringViewLike const&, const_pointer>;

template <typename StringViewLike, typename Dummy>
using if_is_string_view_like_t =
std::enable_if_t<is_string_view_like_v<StringViewLike>, Dummy>;

static void procrustes(size_type& n, size_type nmax) {
if (n > nmax) {
n = nmax;
Expand Down Expand Up @@ -1109,19 +1118,13 @@ class basic_fbstring {

template <
typename StringViewLike,
std::enable_if_t<
std::is_convertible_v<const StringViewLike&, string_view_type> &&
!std::is_convertible_v<const StringViewLike&, const value_type*>,
int> = 0>
if_is_string_view_like_t<StringViewLike, int> = 0>
explicit basic_fbstring(const StringViewLike& view, const A& a = A())
: basic_fbstring(string_view_type(view), a, string_view_ctor{}) {}

template <
typename StringViewLike,
std::enable_if_t<
std::is_convertible_v<const StringViewLike&, string_view_type> &&
!std::is_convertible_v<const StringViewLike&, const value_type*>,
int> = 0>
if_is_string_view_like_t<StringViewLike, int> = 0>
basic_fbstring(
const StringViewLike& view, size_type pos, size_type n, const A& a = A())
: basic_fbstring(
Expand Down Expand Up @@ -1282,6 +1285,14 @@ class basic_fbstring {
return *this;
}

template <
typename StringViewLike,
if_is_string_view_like_t<StringViewLike, int> = 0>
basic_fbstring& operator+=(const StringViewLike& like) {
append(like);
return *this;
}

basic_fbstring& append(const basic_fbstring& str);

basic_fbstring& append(
Expand All @@ -1305,6 +1316,14 @@ class basic_fbstring {
return append(il.begin(), il.end());
}

template <
typename StringViewLike,
if_is_string_view_like_t<StringViewLike, int> = 0>
basic_fbstring& append(const StringViewLike& like) {
string_view_type view = like;
return append(view.begin(), view.end());
}

void push_back(const value_type c) { // primitive
store_.push_back(c);
}
Expand Down
26 changes: 26 additions & 0 deletions folly/test/FBStringTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,11 @@ void clause11_21_4_5(String& test) {

template <class String>
void clause11_21_4_6_1(String& test) {
using string_view_type = std::basic_string_view<
typename String::value_type,
typename String::traits_type>;
auto orig = test;

// 21.3.5 modifiers (+=)
String test1;
randomString(&test1);
Expand Down Expand Up @@ -384,10 +389,23 @@ void clause11_21_4_6_1(String& test) {
// initializer_list
initializer_list<typename String::value_type> il{'a', 'b', 'c'};
test += il;
// string_view
auto testsv = orig;
testsv += string_view_type{orig};
EXPECT_EQ(orig + orig, testsv);
// like string_view
auto testlsv = orig;
testlsv += invocable_to([&] { return string_view_type{orig}; });
EXPECT_EQ(orig + orig, testlsv);
}

template <class String>
void clause11_21_4_6_2(String& test) {
using string_view_type = std::basic_string_view<
typename String::value_type,
typename String::traits_type>;
auto orig = test;

// 21.3.5 modifiers (append, push_back)
String s;

Expand Down Expand Up @@ -415,6 +433,14 @@ void clause11_21_4_6_2(String& test) {
// initializer_list
initializer_list<typename String::value_type> il{'a', 'b', 'c'};
test.append(il);
// string_view
auto testsv = orig;
testsv.append(string_view_type{orig});
EXPECT_EQ(orig + orig, testsv);
// like string_view
auto testlsv = orig;
testlsv.append(folly::invocable_to([&] { return string_view_type{orig}; }));
EXPECT_EQ(orig + orig, testlsv);
}

template <class String>
Expand Down

0 comments on commit abeb583

Please sign in to comment.