#pragma once
#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iosfwd>
#include <limits>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <fmt/format.h>
#include <folly/CPortability.h>
#include <folly/CppAttributes.h>
#include <folly/Likely.h>
#include <folly/Portability.h>
#include <folly/Traits.h>
#include <folly/hash/Hash.h>
#include <folly/lang/Assume.h>
#include <folly/lang/CheckedMath.h>
#include <folly/lang/Exception.h>
#include <folly/memory/Malloc.h>
#if FOLLY_CPLUSPLUS >= 202002L
#include <compare>
#endif
FOLLY_PUSH_WARNING
FOLLY_GNU_DISABLE_WARNING(…)
namespace folly {
#ifdef FOLLY_SANITIZE_ADDRESS
#define FBSTRING_DISABLE_SSO …
#else
#define FBSTRING_DISABLE_SSO …
#endif
namespace fbstring_detail {
template <class InIt, class OutIt>
inline std::pair<InIt, OutIt> copy_n(
InIt b, typename std::iterator_traits<InIt>::difference_type n, OutIt d) { … }
template <class Pod, class T>
inline void podFill(Pod* b, Pod* e, T c) { … }
template <class Pod>
inline void podCopy(const Pod* b, const Pod* e, Pod* d) { … }
template <class Pod>
inline void podMove(const Pod* b, const Pod* e, Pod* d) { … }
}
enum class AcquireMallocatedString { … };
template <class Char>
class fbstring_core { … };
template <class Char>
inline void fbstring_core<Char>::copySmall(const fbstring_core& rhs) { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::copyMedium(const fbstring_core& rhs) { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::copyLarge(const fbstring_core& rhs) { … }
template <class Char>
inline void fbstring_core<Char>::initSmall(
const Char* const data, const size_t size) { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::initMedium(
const Char* const data, const size_t size) { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::initLarge(
const Char* const data, const size_t size) { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::unshare(size_t minCapacity) { … }
template <class Char>
inline Char* fbstring_core<Char>::mutableDataLarge() { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::reserveLarge(size_t minCapacity) { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::reserveMedium(
const size_t minCapacity) { … }
template <class Char>
FOLLY_NOINLINE void fbstring_core<Char>::reserveSmall(
size_t minCapacity, const bool disableSSO) { … }
template <class Char>
inline Char* fbstring_core<Char>::expandNoinit(
const size_t delta,
bool expGrowth,
bool disableSSO ) { … }
template <class Char>
inline void fbstring_core<Char>::shrinkSmall(const size_t delta) { … }
template <class Char>
inline void fbstring_core<Char>::shrinkMedium(const size_t delta) { … }
template <class Char>
inline void fbstring_core<Char>::shrinkLarge(const size_t delta) { … }
template <class Char>
class dummy_fbstring_core { … };
template <
typename E,
class T = std::char_traits<E>,
class A = std::allocator<E>,
class Storage = fbstring_core<E>>
class basic_fbstring {
static_assert(
std::is_same<A, std::allocator<E>>::value,
"fbstring ignores custom allocators");
template <typename Ex, typename... Args>
FOLLY_ALWAYS_INLINE static void enforce(bool condition, Args&&... args) { … }
bool isSane() const { … }
struct Invariant {
Invariant& operator=(const Invariant&) = delete;
explicit Invariant(const basic_fbstring& s) noexcept : s_(s) {
assert(s_.isSane());
}
~Invariant() noexcept { assert(s_.isSane()); }
private:
const basic_fbstring& s_;
};
public:
typedef T traits_type;
typedef typename traits_type::char_type value_type;
typedef A allocator_type;
typedef typename std::allocator_traits<A>::size_type size_type;
typedef typename std::allocator_traits<A>::difference_type difference_type;
typedef typename std::allocator_traits<A>::value_type& reference;
typedef typename std::allocator_traits<A>::value_type const& const_reference;
typedef typename std::allocator_traits<A>::pointer pointer;
typedef typename std::allocator_traits<A>::const_pointer const_pointer;
typedef E* iterator;
typedef const E* const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
static constexpr size_type npos = size_type(-1);
typedef std::true_type IsRelocatable;
private:
using string_view_type = std::basic_string_view<value_type, traits_type>;
static void procrustes(size_type& n, size_type nmax) { … }
static size_type traitsLength(const value_type* s);
struct string_view_ctor {};
FOLLY_NOINLINE basic_fbstring(
string_view_type view, const A&, string_view_ctor)
: … { … }
public:
basic_fbstring() noexcept : … { … }
basic_fbstring(std::nullptr_t) = delete;
explicit basic_fbstring(const A&) noexcept { … }
basic_fbstring(const basic_fbstring& str) : … { … }
basic_fbstring(basic_fbstring&& goner) noexcept
: … { … }
template <typename A2>
basic_fbstring(const std::basic_string<E, T, A2>& str)
: store_(str.data(), str.size()) { … }
basic_fbstring(
const basic_fbstring& str,
size_type pos,
size_type n = npos,
const A& = A()) { … }
FOLLY_NOINLINE
basic_fbstring(const value_type* s, const A& = A())
: … { … }
FOLLY_NOINLINE
basic_fbstring(const value_type* s, size_type n, const A& = A())
: … { … }
FOLLY_NOINLINE
basic_fbstring(size_type n, value_type c, const A& = A()) { … }
template <class InIt>
FOLLY_NOINLINE basic_fbstring(
InIt begin,
InIt end,
typename std::enable_if<
!std::is_same<InIt, value_type*>::value,
const A>::type&
= A()) { … }
FOLLY_NOINLINE
basic_fbstring(const value_type* b, const value_type* e, const A& = A())
: … { … }
basic_fbstring(
value_type* s, size_type n, size_type c, AcquireMallocatedString a)
: … { … }
FOLLY_NOINLINE
basic_fbstring(std::initializer_list<value_type> il) { … }
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>
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>
basic_fbstring(
const StringViewLike& view, size_type pos, size_type n, const A& a = A())
: basic_fbstring(
string_view_type(view).substr(pos, n), a, string_view_ctor{ … }
~basic_fbstring() noexcept { … }
basic_fbstring& operator=(const basic_fbstring& lhs);
basic_fbstring& operator=(basic_fbstring&& goner) noexcept;
template <typename A2>
basic_fbstring& operator=(const std::basic_string<E, T, A2>& rhs) { … }
std::basic_string<E, T, A> toStdString() const { … }
basic_fbstring& operator=(std::nullptr_t) = delete;
basic_fbstring& operator=(const value_type* s) { … }
basic_fbstring& operator=(value_type c);
template <typename TP>
typename std::enable_if<
std::is_convertible<
TP,
typename basic_fbstring<E, T, A, Storage>::value_type>::value &&
!std::is_same<
typename std::decay<TP>::type,
typename basic_fbstring<E, T, A, Storage>::value_type>::value,
basic_fbstring<E, T, A, Storage>&>::type
operator=(TP c) = delete;
basic_fbstring& operator=(std::initializer_list<value_type> il) { … }
operator string_view_type() const noexcept { return {data(), size()}; }
iterator begin() { … }
const_iterator begin() const { … }
const_iterator cbegin() const { … }
iterator end() { … }
const_iterator end() const { … }
const_iterator cend() const { … }
reverse_iterator rbegin() { … }
const_reverse_iterator rbegin() const { … }
const_reverse_iterator crbegin() const { … }
reverse_iterator rend() { … }
const_reverse_iterator rend() const { … }
const_reverse_iterator crend() const { … }
const value_type& front() const { … }
const value_type& back() const { … }
value_type& front() { … }
value_type& back() { … }
void pop_back() { … }
size_type size() const { … }
size_type length() const { … }
size_type max_size() const { … }
void resize(size_type n, value_type c = value_type());
size_type capacity() const { … }
void reserve(size_type res_arg = 0) { … }
void shrink_to_fit() { … }
void clear() { … }
bool empty() const { … }
const_reference operator[](size_type pos) const { … }
reference operator[](size_type pos) { … }
const_reference at(size_type n) const { … }
reference at(size_type n) { … }
basic_fbstring& operator+=(const basic_fbstring& str) { … }
basic_fbstring& operator+=(const value_type* s) { … }
basic_fbstring& operator+=(const value_type c) { … }
basic_fbstring& operator+=(std::initializer_list<value_type> il) { … }
basic_fbstring& append(const basic_fbstring& str);
basic_fbstring& append(
const basic_fbstring& str, const size_type pos, size_type n);
basic_fbstring& append(const value_type* s, size_type n);
basic_fbstring& append(const value_type* s) { … }
basic_fbstring& append(size_type n, value_type c);
template <class InputIterator>
basic_fbstring& append(InputIterator first, InputIterator last) { … }
basic_fbstring& append(std::initializer_list<value_type> il) { … }
void push_back(const value_type c) { … }
basic_fbstring& assign(const basic_fbstring& str) { … }
basic_fbstring& assign(basic_fbstring&& str) { … }
basic_fbstring& assign(
const basic_fbstring& str, const size_type pos, size_type n);
basic_fbstring& assign(const value_type* s, const size_type n);
basic_fbstring& assign(const value_type* s) { … }
basic_fbstring& assign(std::initializer_list<value_type> il) { … }
template <class ItOrLength, class ItOrChar>
basic_fbstring& assign(ItOrLength first_or_n, ItOrChar last_or_c) { … }
basic_fbstring& insert(size_type pos1, const basic_fbstring& str) { … }
basic_fbstring& insert(
size_type pos1, const basic_fbstring& str, size_type pos2, size_type n) { … }
basic_fbstring& insert(size_type pos, const value_type* s, size_type n) { … }
basic_fbstring& insert(size_type pos, const value_type* s) { … }
basic_fbstring& insert(size_type pos, size_type n, value_type c) { … }
iterator insert(const_iterator p, const value_type c) { … }
private:
typedef std::basic_istream<value_type, traits_type> istream_type;
istream_type& getlineImpl(istream_type& is, value_type delim);
public:
friend inline istream_type& getline(
istream_type& is, basic_fbstring& str, value_type delim) {
return str.getlineImpl(is, delim);
}
friend inline istream_type& getline(istream_type& is, basic_fbstring& str) {
return getline(is, str, '\n');
}
private:
iterator insertImplDiscr(
const_iterator i, size_type n, value_type c, std::true_type);
template <class InputIter>
iterator insertImplDiscr(
const_iterator i, InputIter b, InputIter e, std::false_type);
template <class FwdIterator>
iterator insertImpl(
const_iterator i,
FwdIterator s1,
FwdIterator s2,
std::forward_iterator_tag);
template <class InputIterator>
iterator insertImpl(
const_iterator i,
InputIterator b,
InputIterator e,
std::input_iterator_tag);
public:
template <class ItOrLength, class ItOrChar>
iterator insert(const_iterator p, ItOrLength first_or_n, ItOrChar last_or_c) { … }
iterator insert(const_iterator p, std::initializer_list<value_type> il) { … }
basic_fbstring& erase(size_type pos = 0, size_type n = npos) { … }
iterator erase(iterator position) { … }
iterator erase(iterator first, iterator last) { … }
basic_fbstring& replace(
size_type pos1, size_type n1, const basic_fbstring& str) { … }
basic_fbstring& replace(
size_type pos1,
size_type n1,
const basic_fbstring& str,
size_type pos2,
size_type n2) { … }
basic_fbstring& replace(size_type pos, size_type n1, const value_type* s) { … }
template <class StrOrLength, class NumOrChar>
basic_fbstring& replace(
size_type pos, size_type n1, StrOrLength s_or_n2, NumOrChar n_or_c) { … }
basic_fbstring& replace(iterator i1, iterator i2, const basic_fbstring& str) { … }
basic_fbstring& replace(iterator i1, iterator i2, const value_type* s) { … }
private:
basic_fbstring& replaceImplDiscr(
iterator i1,
iterator i2,
const value_type* s,
size_type n,
std::integral_constant<int, 2>);
basic_fbstring& replaceImplDiscr(
iterator i1,
iterator i2,
size_type n2,
value_type c,
std::integral_constant<int, 1>);
template <class InputIter>
basic_fbstring& replaceImplDiscr(
iterator i1,
iterator i2,
InputIter b,
InputIter e,
std::integral_constant<int, 0>);
private:
template <class FwdIterator>
bool replaceAliased(
iterator ,
iterator ,
FwdIterator ,
FwdIterator ,
std::false_type) { … }
template <class FwdIterator>
bool replaceAliased(
iterator i1, iterator i2, FwdIterator s1, FwdIterator s2, std::true_type);
template <class FwdIterator>
void replaceImpl(
iterator i1,
iterator i2,
FwdIterator s1,
FwdIterator s2,
std::forward_iterator_tag);
template <class InputIterator>
void replaceImpl(
iterator i1,
iterator i2,
InputIterator b,
InputIterator e,
std::input_iterator_tag);
public:
template <class T1, class T2>
basic_fbstring& replace(
iterator i1, iterator i2, T1 first_or_n_or_s, T2 last_or_c_or_n) { … }
size_type copy(value_type* s, size_type n, size_type pos = 0) const { … }
void swap(basic_fbstring& rhs) { … }
const value_type* c_str() const { … }
const value_type* data() const { … }
value_type* data() { … }
allocator_type get_allocator() const { … }
size_type find(const basic_fbstring& str, size_type pos = 0) const { … }
size_type find(
const value_type* needle, size_type pos, size_type nsize) const;
size_type find(const value_type* s, size_type pos = 0) const { … }
size_type find(value_type c, size_type pos = 0) const { … }
size_type rfind(const basic_fbstring& str, size_type pos = npos) const { … }
size_type rfind(const value_type* s, size_type pos, size_type n) const;
size_type rfind(const value_type* s, size_type pos = npos) const { … }
size_type rfind(value_type c, size_type pos = npos) const { … }
size_type find_first_of(const basic_fbstring& str, size_type pos = 0) const { … }
size_type find_first_of(
const value_type* s, size_type pos, size_type n) const;
size_type find_first_of(const value_type* s, size_type pos = 0) const { … }
size_type find_first_of(value_type c, size_type pos = 0) const { … }
size_type find_last_of(
const basic_fbstring& str, size_type pos = npos) const { … }
size_type find_last_of(const value_type* s, size_type pos, size_type n) const;
size_type find_last_of(const value_type* s, size_type pos = npos) const { … }
size_type find_last_of(value_type c, size_type pos = npos) const { … }
size_type find_first_not_of(
const basic_fbstring& str, size_type pos = 0) const { … }
size_type find_first_not_of(
const value_type* s, size_type pos, size_type n) const;
size_type find_first_not_of(const value_type* s, size_type pos = 0) const { … }
size_type find_first_not_of(value_type c, size_type pos = 0) const { … }
size_type find_last_not_of(
const basic_fbstring& str, size_type pos = npos) const { … }
size_type find_last_not_of(
const value_type* s, size_type pos, size_type n) const;
size_type find_last_not_of(const value_type* s, size_type pos = npos) const { … }
size_type find_last_not_of(value_type c, size_type pos = npos) const { … }
basic_fbstring substr(size_type pos = 0, size_type n = npos) const& { … }
basic_fbstring substr(size_type pos = 0, size_type n = npos) && { … }
int compare(const basic_fbstring& str) const { … }
int compare(size_type pos1, size_type n1, const basic_fbstring& str) const { … }
int compare(size_type pos1, size_type n1, const value_type* s) const { … }
int compare(
size_type pos1, size_type n1, const value_type* s, size_type n2) const { … }
int compare(
size_type pos1,
size_type n1,
const basic_fbstring& str,
size_type pos2,
size_type n2) const { … }
int compare(const value_type* s) const { … }
#if FOLLY_CPLUSPLUS >= 202002L
friend auto operator<=>(
const basic_fbstring& lhs, const basic_fbstring& rhs) {
return lhs.spaceship(rhs.data(), rhs.size());
}
friend auto operator<=>(const basic_fbstring& lhs, const char* rhs) {
return lhs.spaceship(rhs, traitsLength(rhs));
}
template <typename A2>
friend auto operator<=>(
const basic_fbstring& lhs, const std::basic_string<E, T, A2>& rhs) {
return lhs.spaceship(rhs.data(), rhs.size());
}
#endif
private:
#if FOLLY_CPLUSPLUS >= 202002L
auto spaceship(const value_type* rhsData, size_type rhsSize) const {
auto c = compare(0, size(), rhsData, rhsSize);
if (c == 0) {
return std::strong_ordering::equal;
} else if (c < 0) {
return std::strong_ordering::less;
} else {
return std::strong_ordering::greater;
}
}
#endif
Storage store_;
};
template <typename E, class T, class A, class S>
FOLLY_NOINLINE typename basic_fbstring<E, T, A, S>::size_type
basic_fbstring<E, T, A, S>::traitsLength(const value_type* s) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::operator=(
const basic_fbstring& lhs) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::operator=(
basic_fbstring&& goner) noexcept { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::operator=(
value_type c) { … }
template <typename E, class T, class A, class S>
inline void basic_fbstring<E, T, A, S>::resize(
const size_type n, const value_type c ) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
const basic_fbstring& str) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
const basic_fbstring& str, const size_type pos, size_type n) { … }
template <typename E, class T, class A, class S>
FOLLY_NOINLINE basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
const value_type* s, size_type n) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::append(
size_type n, value_type c) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::assign(
const basic_fbstring& str, const size_type pos, size_type n) { … }
template <typename E, class T, class A, class S>
FOLLY_NOINLINE basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::assign(
const value_type* s, const size_type n) { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::istream_type&
basic_fbstring<E, T, A, S>::getlineImpl(istream_type& is, value_type delim) { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::size_type
basic_fbstring<E, T, A, S>::find(
const value_type* needle,
const size_type pos,
const size_type nsize) const { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::iterator
basic_fbstring<E, T, A, S>::insertImplDiscr(
const_iterator i, size_type n, value_type c, std::true_type) { … }
template <typename E, class T, class A, class S>
template <class InputIter>
inline typename basic_fbstring<E, T, A, S>::iterator
basic_fbstring<E, T, A, S>::insertImplDiscr(
const_iterator i, InputIter b, InputIter e, std::false_type) { … }
template <typename E, class T, class A, class S>
template <class FwdIterator>
inline typename basic_fbstring<E, T, A, S>::iterator
basic_fbstring<E, T, A, S>::insertImpl(
const_iterator i,
FwdIterator s1,
FwdIterator s2,
std::forward_iterator_tag) { … }
template <typename E, class T, class A, class S>
template <class InputIterator>
inline typename basic_fbstring<E, T, A, S>::iterator
basic_fbstring<E, T, A, S>::insertImpl(
const_iterator i,
InputIterator b,
InputIterator e,
std::input_iterator_tag) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::replaceImplDiscr(
iterator i1,
iterator i2,
const value_type* s,
size_type n,
std::integral_constant<int, 2>) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::replaceImplDiscr(
iterator i1,
iterator i2,
size_type n2,
value_type c,
std::integral_constant<int, 1>) { … }
template <typename E, class T, class A, class S>
template <class InputIter>
inline basic_fbstring<E, T, A, S>& basic_fbstring<E, T, A, S>::replaceImplDiscr(
iterator i1,
iterator i2,
InputIter b,
InputIter e,
std::integral_constant<int, 0>) { … }
template <typename E, class T, class A, class S>
template <class FwdIterator>
inline bool basic_fbstring<E, T, A, S>::replaceAliased(
iterator i1, iterator i2, FwdIterator s1, FwdIterator s2, std::true_type) { … }
template <typename E, class T, class A, class S>
template <class FwdIterator>
inline void basic_fbstring<E, T, A, S>::replaceImpl(
iterator i1,
iterator i2,
FwdIterator s1,
FwdIterator s2,
std::forward_iterator_tag) { … }
template <typename E, class T, class A, class S>
template <class InputIterator>
inline void basic_fbstring<E, T, A, S>::replaceImpl(
iterator i1,
iterator i2,
InputIterator b,
InputIterator e,
std::input_iterator_tag) { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::size_type
basic_fbstring<E, T, A, S>::rfind(
const value_type* s, size_type pos, size_type n) const { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::size_type
basic_fbstring<E, T, A, S>::find_first_of(
const value_type* s, size_type pos, size_type n) const { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::size_type
basic_fbstring<E, T, A, S>::find_last_of(
const value_type* s, size_type pos, size_type n) const { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::size_type
basic_fbstring<E, T, A, S>::find_first_not_of(
const value_type* s, size_type pos, size_type n) const { … }
template <typename E, class T, class A, class S>
inline typename basic_fbstring<E, T, A, S>::size_type
basic_fbstring<E, T, A, S>::find_last_not_of(
const value_type* s, size_type pos, size_type n) const { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
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 basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs, basic_fbstring<E, T, A, S>&& rhs) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S> operator+(
basic_fbstring<E, T, A, S>&& lhs, basic_fbstring<E, T, A, S>&& rhs) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S> operator+(
const E* lhs, const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S> operator+(
const E* lhs, basic_fbstring<E, T, A, S>&& rhs) { … }
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) { … }
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) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs, const E* rhs) { … }
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) { … }
template <typename E, class T, class A, class S>
inline basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs, E rhs) { … }
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) { … }
template <typename E, class T, class A, class S>
inline bool operator==(
const basic_fbstring<E, T, A, S>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator==(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
delete;
template <typename E, class T, class A, class S>
inline bool operator==(
const typename basic_fbstring<E, T, A, S>::value_type* lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator==(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
delete;
template <typename E, class T, class A, class S>
inline bool operator==(
const basic_fbstring<E, T, A, S>& lhs,
const typename basic_fbstring<E, T, A, S>::value_type* rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator!=(
const basic_fbstring<E, T, A, S>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator!=(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
delete;
template <typename E, class T, class A, class S>
inline bool operator!=(
const typename basic_fbstring<E, T, A, S>::value_type* lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator!=(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
delete;
template <typename E, class T, class A, class S>
inline bool operator!=(
const basic_fbstring<E, T, A, S>& lhs,
const typename basic_fbstring<E, T, A, S>::value_type* rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator<(
const basic_fbstring<E, T, A, S>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator<(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
delete;
template <typename E, class T, class A, class S>
inline bool operator<(
const basic_fbstring<E, T, A, S>& lhs,
const typename basic_fbstring<E, T, A, S>::value_type* rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator<(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
delete;
template <typename E, class T, class A, class S>
inline bool operator<(
const typename basic_fbstring<E, T, A, S>::value_type* lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator>(
const basic_fbstring<E, T, A, S>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator>(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
delete;
template <typename E, class T, class A, class S>
inline bool operator>(
const basic_fbstring<E, T, A, S>& lhs,
const typename basic_fbstring<E, T, A, S>::value_type* rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator>(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
delete;
template <typename E, class T, class A, class S>
inline bool operator>(
const typename basic_fbstring<E, T, A, S>::value_type* lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator<=(
const basic_fbstring<E, T, A, S>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator<=(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
delete;
template <typename E, class T, class A, class S>
inline bool operator<=(
const basic_fbstring<E, T, A, S>& lhs,
const typename basic_fbstring<E, T, A, S>::value_type* rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator<=(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
delete;
template <typename E, class T, class A, class S>
inline bool operator<=(
const typename basic_fbstring<E, T, A, S>::value_type* lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator>=(
const basic_fbstring<E, T, A, S>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator>=(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
delete;
template <typename E, class T, class A, class S>
inline bool operator>=(
const basic_fbstring<E, T, A, S>& lhs,
const typename basic_fbstring<E, T, A, S>::value_type* rhs) { … }
template <typename E, class T, class A, class S>
inline bool operator>=(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
delete;
template <typename E, class T, class A, class S>
inline bool operator>=(
const typename basic_fbstring<E, T, A, S>::value_type* lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
#if FOLLY_CPLUSPLUS >= 202002
template <typename E, class T, class A, class S>
inline bool operator<=>(std::nullptr_t, const basic_fbstring<E, T, A, S>&) =
delete;
template <typename E, class T, class A, class S>
inline bool operator<=>(const basic_fbstring<E, T, A, S>&, std::nullptr_t) =
delete;
#endif
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) { … }
template <typename E, class T, class A, class S>
inline std::basic_istream<
typename basic_fbstring<E, T, A, S>::value_type,
typename basic_fbstring<E, T, A, S>::traits_type>&
operator>>(
std::basic_istream<
typename basic_fbstring<E, T, A, S>::value_type,
typename basic_fbstring<E, T, A, S>::traits_type>& is,
basic_fbstring<E, T, A, S>& str) { … }
template <typename E, class T, class A, class S>
inline std::basic_ostream<
typename basic_fbstring<E, T, A, S>::value_type,
typename basic_fbstring<E, T, A, S>::traits_type>&
operator<<(
std::basic_ostream<
typename basic_fbstring<E, T, A, S>::value_type,
typename basic_fbstring<E, T, A, S>::traits_type>& os,
const basic_fbstring<E, T, A, S>& str) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator==(
const basic_fbstring<E, T, A, S>& lhs,
const std::basic_string<E, T, A2>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator==(
const std::basic_string<E, T, A2>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator!=(
const basic_fbstring<E, T, A, S>& lhs,
const std::basic_string<E, T, A2>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator!=(
const std::basic_string<E, T, A2>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator<(
const basic_fbstring<E, T, A, S>& lhs,
const std::basic_string<E, T, A2>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator>(
const basic_fbstring<E, T, A, S>& lhs,
const std::basic_string<E, T, A2>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator<(
const std::basic_string<E, T, A2>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator>(
const std::basic_string<E, T, A2>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator<=(
const basic_fbstring<E, T, A, S>& lhs,
const std::basic_string<E, T, A2>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator>=(
const basic_fbstring<E, T, A, S>& lhs,
const std::basic_string<E, T, A2>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator<=(
const std::basic_string<E, T, A2>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
template <typename E, class T, class A, class S, class A2>
inline bool operator>=(
const std::basic_string<E, T, A2>& lhs,
const basic_fbstring<E, T, A, S>& rhs) { … }
fbstring;
IsRelocatable<basic_fbstring<T, R, A, S>>;
inline std::string toStdString(const folly::fbstring& s) { … }
inline const std::string& toStdString(const std::string& s) { … }
inline std::string&& toStdString(std::string&& s) { … }
}
#define FOLLY_FBSTRING_HASH1 …
#define FOLLY_FBSTRING_HASH …
namespace std {
FOLLY_FBSTRING_HASH
}
#undef FOLLY_FBSTRING_HASH
#undef FOLLY_FBSTRING_HASH1
FOLLY_POP_WARNING
#undef FBSTRING_DISABLE_SSO
namespace folly {
template <class T>
struct IsSomeString;
template <>
struct IsSomeString<fbstring> : std::true_type { … };
}
template <>
struct fmt::formatter<folly::fbstring> : private formatter<fmt::string_view> { … };