X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FFixedString.h;h=935cd8214b2489188ded057cf0b9146ed6e94730;hp=0f00e6edd32c7beffa4f30b2597108ed09d3c33d;hb=46c5dbce6c04234ae0185d3fadb62556c7e7625b;hpb=77d5e54744c2ab78ffc06e26085bf18725ec73e1 diff --git a/folly/FixedString.h b/folly/FixedString.h index 0f00e6ed..935cd821 100644 --- a/folly/FixedString.h +++ b/folly/FixedString.h @@ -1,5 +1,5 @@ /* - * 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. @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -72,16 +74,6 @@ constexpr std::size_t FixedStringBase_::npos; using FixedStringBase = FixedStringBase_<>; -template -constexpr std::size_t size(const Char (&)[N]) noexcept { - return N - 1u; -} - -template -constexpr std::size_t size(const BasicFixedString& s) noexcept { - return s.size(); -} - // Intentionally NOT constexpr. By making this not constexpr, we make // checkOverflow below ill-formed in a constexpr context when the condition // it's testing for fails. In this way, precondition violations are reported @@ -102,19 +94,11 @@ constexpr std::size_t checkOverflowOrNpos(std::size_t i, std::size_t max) { } // Intentionally NOT constexpr. See note above for assertOutOfBounds -inline void assertOutOfBoundsNothrow() { - assert(false && "Array index out of bounds in BasicFixedString"); -} - -constexpr std::size_t checkOverflowNothrow(std::size_t i, std::size_t max) { - return i <= max ? i : (assertOutOfBoundsNothrow(), i); -} - -// Intentionally NOT constexpr. See note above for assertOutOfBounds -inline void assertNotNullTerminated() noexcept { +[[noreturn]] inline void assertNotNullTerminated() noexcept { assert( false && "Non-null terminated string used to initialize a BasicFixedString"); + std::terminate(); // Fail hard, fail fast. } // Parsing help for human readers: the following is a constexpr noexcept @@ -134,6 +118,13 @@ constexpr const Char (&checkNullTerminated(const Char (&a)[N]) noexcept)[N] { enum class Cmp : int { LT = -1, EQ = 0, GT = 1 }; +// Rather annoyingly, GCC's -Warray-bounds warning issues false positives for +// this code. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61971 +#if defined(__GNUC__) && !defined(__CLANG__) && __GNUC__ <= 5 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + template constexpr Cmp compare_( const Left& left, @@ -169,18 +160,21 @@ constexpr bool equal_( } template -constexpr Char -char_at_(const Left& left, const Right& right, std::size_t i) noexcept { - return i < fixedstring::size(left) +constexpr Char char_at_( + const Left& left, + std::size_t left_count, + const Right& right, + std::size_t right_count, + std::size_t i) noexcept { + return i < left_count ? left[i] - : i < (fixedstring::size(left) + fixedstring::size(right)) - ? right[i - fixedstring::size(left)] - : Char(0); + : i < (left_count + right_count) ? right[i - left_count] : Char(0); } template constexpr Char char_at_( const Left& left, + std::size_t left_size, std::size_t left_pos, std::size_t left_count, const Right& right, @@ -189,11 +183,10 @@ constexpr Char char_at_( std::size_t i) noexcept { return i < left_pos ? left[i] - : (i < right_count + left_pos - ? right[i - left_pos + right_pos] - : (i < fixedstring::size(left) - left_count + right_count - ? left[i - right_count + left_count] - : Char(0))); + : (i < right_count + left_pos ? right[i - left_pos + right_pos] + : (i < left_size - left_count + right_count + ? left[i - right_count + left_count] + : Char(0))); } template @@ -216,14 +209,14 @@ find_one_of_at_(Char ch, const Right& right, std::size_t pos) noexcept { template constexpr std::size_t find_( const Left& left, + std::size_t left_size, const Right& right, std::size_t pos, std::size_t count) noexcept { - return find_at_(left, right, pos, count) - ? pos - : fixedstring::size(left) <= pos + count + return find_at_(left, right, pos, count) ? pos + : left_size <= pos + count ? FixedStringBase::npos - : find_(left, right, pos + 1u, count); + : find_(left, left_size, right, pos + 1u, count); } template @@ -241,27 +234,27 @@ constexpr std::size_t rfind_( template constexpr std::size_t find_first_of_( const Left& left, + std::size_t left_size, const Right& right, std::size_t pos, std::size_t count) noexcept { - return find_one_of_at_(left[pos], right, count) - ? pos - : fixedstring::size(left) <= pos + 1u + return find_one_of_at_(left[pos], right, count) ? pos + : left_size <= pos + 1u ? FixedStringBase::npos - : find_first_of_(left, right, pos + 1u, count); + : find_first_of_(left, left_size, right, pos + 1u, count); } template constexpr std::size_t find_first_not_of_( const Left& left, + std::size_t left_size, const Right& right, std::size_t pos, std::size_t count) noexcept { - return !find_one_of_at_(left[pos], right, count) - ? pos - : fixedstring::size(left) <= pos + 1u + return !find_one_of_at_(left[pos], right, count) ? pos + : left_size <= pos + 1u ? FixedStringBase::npos - : find_first_not_of_(left, right, pos + 1u, count); + : find_first_not_of_(left, left_size, right, pos + 1u, count); } template @@ -292,24 +285,44 @@ struct Helper { template static constexpr BasicFixedString concat_( const Left& left, + std::size_t left_count, const Right& right, - std::index_sequence is) noexcept { - return {left, right, is}; + std::size_t right_count, + folly::index_sequence is) noexcept { + return {left, left_count, right, right_count, is}; } template static constexpr BasicFixedString replace_( const Left& left, + std::size_t left_size, std::size_t left_pos, std::size_t left_count, const Right& right, std::size_t right_pos, std::size_t right_count, - std::index_sequence is) noexcept { - return {left, left_pos, left_count, right, right_pos, right_count, is}; + folly::index_sequence is) noexcept { + return {left, + left_size, + left_pos, + left_count, + right, + right_pos, + right_count, + is}; + } + + template + static constexpr const Char ( + &data_(const BasicFixedString& that) noexcept)[N + 1u] { + return that.data_; } }; +#if defined(__GNUC__) && !defined(__CLANG__) && __GNUC__ <= 4 +#pragma GCC diagnostic pop +#endif + template FOLLY_CPP14_CONSTEXPR void constexpr_swap(T& a, T& b) noexcept( noexcept(a = T(std::move(a)))) { @@ -424,10 +437,6 @@ struct ReverseIterator { } // namespace fixedstring } // namespace detail -// Defined in folly/Range.h -template -class Range; - // Defined in folly/Hash.h std::uint32_t hsieh_hash32_buf(const void* buf, std::size_t len); @@ -491,7 +500,7 @@ std::uint32_t hsieh_hash32_buf(const void* buf, std::size_t len); * of types `FixedString<4>`, `FixedString<8>`, etc. For example: * \par * \code - * using namespace folly::StringLiterals; + * using namespace folly::string_literals; * constexpr auto hello = "hello"_fs8; // A FixedString<8> containing "hello" * \endcode * \par @@ -503,7 +512,7 @@ std::uint32_t hsieh_hash32_buf(const void* buf, std::size_t len); * the right size. For example: * \par * \code - * using namespace folly::StringLiterals; + * using namespace folly::string_literals; * // NOTE: Only works on compilers with GNU extensions enabled. Clang and * // gcc support this (-Wgnu-string-literal-operator-template): * constexpr auto hello = "hello"_fs; // A FixedString<5> containing "hello" @@ -539,13 +548,13 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { Char data_[N + 1u]; // +1 for the null terminator std::size_t size_; // Nbr of chars, not incl. null terminator. size_ <= N. - using Indices = std::make_index_sequence; + using Indices = folly::make_index_sequence; template constexpr BasicFixedString( const That& that, std::size_t size, - std::index_sequence, + folly::index_sequence, std::size_t pos = 0, std::size_t count = npos) noexcept : data_{(Is < (size - pos) && Is < count ? that[Is + pos] : Char(0))..., @@ -556,31 +565,40 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { constexpr BasicFixedString( std::size_t count, Char ch, - std::index_sequence) noexcept + folly::index_sequence) noexcept : data_{((Is < count) ? ch : Char(0))..., Char(0)}, size_{count} {} // Concatenation constructor template constexpr BasicFixedString( const Left& left, + std::size_t left_size, const Right& right, - std::index_sequence) noexcept - : data_{detail::fixedstring::char_at_(left, right, Is)..., Char(0)}, - size_{detail::fixedstring::size(left) + - detail::fixedstring::size(right)} {} + std::size_t right_size, + folly::index_sequence) noexcept + : data_{detail::fixedstring::char_at_( + left, + left_size, + right, + right_size, + Is)..., + Char(0)}, + size_{left_size + right_size} {} // Replace constructor template constexpr BasicFixedString( const Left& left, + std::size_t left_size, std::size_t left_pos, std::size_t left_count, const Right& right, std::size_t right_pos, std::size_t right_count, - std::index_sequence) noexcept + folly::index_sequence) noexcept : data_{detail::fixedstring::char_at_( left, + left_size, left_pos, left_count, right, @@ -588,7 +606,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { right_count, Is)..., Char(0)}, - size_{detail::fixedstring::size(left) - left_count + right_count} {} + size_{left_size - left_count + right_count} {} public: using size_type = std::size_t; @@ -666,7 +684,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { : BasicFixedString{ that.data_, that.size_, - std::make_index_sequence<(M < N ? M : N)>{}, + folly::make_index_sequence<(M < N ? M : N)>{}, pos, detail::fixedstring::checkOverflow( detail::fixedstring::checkOverflowOrNpos( @@ -687,7 +705,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { constexpr /* implicit */ BasicFixedString(const Char (&that)[M]) noexcept : BasicFixedString{detail::fixedstring::checkNullTerminated(that), M - 1u, - std::make_index_sequence{}} {} + folly::make_index_sequence{}} {} /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * Construct from a `const Char*` and count @@ -1153,7 +1171,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { #ifdef NDEBUG return data_[i]; #else - return data_[detail::fixedstring::checkOverflowNothrow(i, size_)]; + return data_[detail::fixedstring::checkOverflow(i, size_)]; #endif } @@ -1164,21 +1182,21 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { #ifdef NDEBUG return data_[i]; #else - return data_[detail::fixedstring::checkOverflowNothrow(i, size_)]; + return data_[detail::fixedstring::checkOverflow(i, size_)]; #endif } /** * \note Equivalent to `(*this)[0]` */ - FOLLY_CPP14_CONSTEXPR Char& front() noexcept(false) { + FOLLY_CPP14_CONSTEXPR Char& front() noexcept { return (*this)[0u]; } /** * \overload */ - constexpr const Char& front() const noexcept(false) { + constexpr const Char& front() const noexcept { return (*this)[0u]; } @@ -1186,22 +1204,22 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { * \note Equivalent to `at(size()-1)` * \pre `!empty()` */ - FOLLY_CPP14_CONSTEXPR Char& back() noexcept(false) { + FOLLY_CPP14_CONSTEXPR Char& back() noexcept { #ifdef NDEBUG return data_[size_ - 1u]; #else - return data_[size_ - detail::fixedstring::checkOverflowNothrow(1u, size_)]; + return data_[size_ - detail::fixedstring::checkOverflow(1u, size_)]; #endif } /** * \overload */ - constexpr const Char& back() const noexcept(false) { + constexpr const Char& back() const noexcept { #ifdef NDEBUG return data_[size_ - 1u]; #else - return data_[size_ - detail::fixedstring::checkOverflowNothrow(1u, size_)]; + return data_[size_ - detail::fixedstring::checkOverflow(1u, size_)]; #endif } @@ -1315,7 +1333,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { count = detail::fixedstring::checkOverflowOrNpos(count, that.size_ - pos); detail::fixedstring::checkOverflow(count, N - size_); for (std::size_t i = 0u; i < count; ++i) - data_[size_ + i] = that[pos + i]; + data_[size_ + i] = that.data_[pos + i]; size_ += count; data_[size_] = Char(0); return *this; @@ -1567,11 +1585,11 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t that_pos, std::size_t that_count) const noexcept(false) { return static_cast(detail::fixedstring::compare_( - *this, + data_, detail::fixedstring::checkOverflow(this_pos, size_), detail::fixedstring::checkOverflow(this_count, size_ - this_pos) + this_pos, - that, + that.data_, detail::fixedstring::checkOverflow(that_pos, that.size_), detail::fixedstring::checkOverflow(that_count, that.size_ - that_pos) + that_pos)); @@ -1585,6 +1603,13 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return compare(0u, size_, that, folly::constexpr_strlen(that)); } + /** + * \overload + */ + constexpr int compare(Range that) const noexcept { + return compare(0u, size_, that.begin(), that.size()); + } + /** * Compare two strings for lexicographical ordering. * \note Equivalent to @@ -1597,6 +1622,16 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return compare(this_pos, this_count, that, folly::constexpr_strlen(that)); } + /** + * \overload + */ + constexpr int compare( + std::size_t this_pos, + std::size_t this_count, + Range that) const noexcept(false) { + return compare(this_pos, this_count, that.begin(), that.size()); + } + /** * Compare two strings for lexicographical ordering. * @@ -1618,7 +1653,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const Char* that, std::size_t that_count) const noexcept(false) { return static_cast(detail::fixedstring::compare_( - *this, + data_, detail::fixedstring::checkOverflow(this_pos, size_), detail::fixedstring::checkOverflowOrNpos(this_count, size_ - this_pos) + this_pos, @@ -1627,6 +1662,18 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { that_count)); } + constexpr int compare( + std::size_t this_pos, + std::size_t this_count, + Range that, + std::size_t that_count) const noexcept(false) { + return compare( + this_pos, + this_count, + that.begin(), + detail::fixedstring::checkOverflow(that_count, that.size())); + } + /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * Return a substring from `pos` to the end of the string. * \note Equivalent to `BasicFixedString{*this, pos}` @@ -1747,7 +1794,8 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const Char* that, std::size_t that_count) noexcept(false) { return *this = detail::fixedstring::Helper::replace_( - *this, + data_, + size_, detail::fixedstring::checkOverflow(this_pos, size_), detail::fixedstring::checkOverflowOrNpos( this_count, size_ - this_pos), @@ -1855,14 +1903,15 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t that_pos, std::size_t that_count) const noexcept(false) { return detail::fixedstring::Helper::replace_( - *this, + data_, + size_, detail::fixedstring::checkOverflow(this_pos, size_), detail::fixedstring::checkOverflowOrNpos(this_count, size_ - this_pos), - that, + that.data_, detail::fixedstring::checkOverflow(that_pos, that.size_), detail::fixedstring::checkOverflowOrNpos( that_count, that.size_ - that_pos), - std::make_index_sequence{}); + folly::make_index_sequence{}); } /** @@ -1955,13 +2004,14 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t that_pos, std::size_t that_count) const noexcept(false) { return detail::fixedstring::Helper::replace_( - *this, + data_, + size_, detail::fixedstring::checkOverflow(this_pos, size_), detail::fixedstring::checkOverflowOrNpos(this_count, size_ - this_pos), detail::fixedstring::checkNullTerminated(that), detail::fixedstring::checkOverflow(that_pos, M - 1u), detail::fixedstring::checkOverflowOrNpos(that_count, M - 1u - that_pos), - std::make_index_sequence{}); + folly::make_index_sequence{}); } /** @@ -2075,7 +2125,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const BasicFixedString& that, std::size_t pos) const noexcept(false) { return that.size_ <= size_ - detail::fixedstring::checkOverflow(pos, size_) - ? detail::fixedstring::find_(*this, that, pos, that.size_) + ? detail::fixedstring::find_(data_, size_, that.data_, pos, that.size_) : npos; } @@ -2114,7 +2164,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t pos, std::size_t count) const noexcept(false) { return count <= size_ - detail::fixedstring::checkOverflow(pos, size_) - ? detail::fixedstring::find_(*this, that, pos, count) + ? detail::fixedstring::find_(data_, size_, that, pos, count) : npos; } @@ -2136,7 +2186,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { using A = const Char[1u]; return 0u == size_ - detail::fixedstring::checkOverflow(pos, size_) ? npos - : detail::fixedstring::find_(*this, A{ch}, pos, 1u); + : detail::fixedstring::find_(data_, size_, A{ch}, pos, 1u); } /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** @@ -2161,8 +2211,8 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t pos) const noexcept(false) { return that.size_ <= size_ ? detail::fixedstring::rfind_( - *this, - that, + data_, + that.data_, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - that.size_), @@ -2206,7 +2256,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t count) const noexcept(false) { return count <= size_ ? detail::fixedstring::rfind_( - *this, + data_, that, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), @@ -2234,7 +2284,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return 0u == size_ ? npos : detail::fixedstring::rfind_( - *this, + data_, A{ch}, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - 1u), @@ -2262,7 +2312,8 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t pos) const noexcept(false) { return size_ == detail::fixedstring::checkOverflow(pos, size_) ? npos - : detail::fixedstring::find_first_of_(*this, that, pos, that.size_); + : detail::fixedstring::find_first_of_( + data_, size_, that.data_, pos, that.size_); } /** @@ -2303,7 +2354,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t count) const noexcept(false) { return size_ == detail::fixedstring::checkOverflow(pos, size_) ? npos - : detail::fixedstring::find_first_of_(*this, that, pos, count); + : detail::fixedstring::find_first_of_(data_, size_, that, pos, count); } /** @@ -2324,7 +2375,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { using A = const Char[1u]; return size_ == detail::fixedstring::checkOverflow(pos, size_) ? npos - : detail::fixedstring::find_first_of_(*this, A{ch}, pos, 1u); + : detail::fixedstring::find_first_of_(data_, size_, A{ch}, pos, 1u); } /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** @@ -2347,7 +2398,8 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t pos) const noexcept(false) { return size_ == detail::fixedstring::checkOverflow(pos, size_) ? npos - : detail::fixedstring::find_first_not_of_(*this, that, pos, that.size_); + : detail::fixedstring::find_first_not_of_( + data_, size_, that.data_, pos, that.size_); } /** @@ -2388,7 +2440,8 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { std::size_t count) const noexcept(false) { return size_ == detail::fixedstring::checkOverflow(pos, size_) ? npos - : detail::fixedstring::find_first_not_of_(*this, that, pos, count); + : detail::fixedstring::find_first_not_of_( + data_, size_, that, pos, count); } /** @@ -2408,7 +2461,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { noexcept(false) { using A = const Char[1u]; return 1u <= size_ - detail::fixedstring::checkOverflow(pos, size_) - ? detail::fixedstring::find_first_not_of_(*this, A{ch}, pos, 1u) + ? detail::fixedstring::find_first_not_of_(data_, size_, A{ch}, pos, 1u) : npos; } @@ -2434,8 +2487,8 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return 0u == size_ ? npos : detail::fixedstring::find_last_of_( - *this, - that, + data_, + that.data_, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - 1u), that.size_); @@ -2480,7 +2533,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return 0u == size_ ? npos : detail::fixedstring::find_last_of_( - *this, + data_, that, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - 1u), @@ -2506,7 +2559,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return 0u == size_ ? npos : detail::fixedstring::find_last_of_( - *this, + data_, A{ch}, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - 1u), @@ -2535,8 +2588,8 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return 0u == size_ ? npos : detail::fixedstring::find_last_not_of_( - *this, - that, + data_, + that.data_, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - 1u), that.size_); @@ -2581,7 +2634,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return 0u == size_ ? npos : detail::fixedstring::find_last_not_of_( - *this, + data_, that, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - 1u), @@ -2607,7 +2660,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return 0u == size_ ? npos : detail::fixedstring::find_last_not_of_( - *this, + data_, A{ch}, folly::constexpr_min( detail::fixedstring::checkOverflow(pos, size_), size_ - 1u), @@ -2621,7 +2674,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const Char* a, const BasicFixedString& b) noexcept { return detail::fixedstring::equal_( - a, folly::constexpr_strlen(a), b, b.size()); + a, folly::constexpr_strlen(a), b.data_, b.size_); } /** @@ -2633,6 +2686,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return b == a; } + /** + * \overload + */ + friend constexpr bool operator==( + Range a, + const BasicFixedString& b) noexcept { + return detail::fixedstring::equal_(a.begin(), a.size(), b.data_, b.size_); + } + + /** + * \overload + */ + friend constexpr bool operator==( + const BasicFixedString& a, + Range b) noexcept { + return b == a; + } + friend constexpr bool operator!=( const Char* a, const BasicFixedString& b) noexcept { @@ -2648,12 +2719,30 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return !(b == a); } + /** + * \overload + */ + friend constexpr bool operator!=( + Range a, + const BasicFixedString& b) noexcept { + return !(a == b); + } + + /** + * \overload + */ + friend constexpr bool operator!=( + const BasicFixedString& a, + Range b) noexcept { + return !(a == b); + } + friend constexpr bool operator<( const Char* a, const BasicFixedString& b) noexcept { return detail::fixedstring::Cmp::LT == detail::fixedstring::compare_( - a, 0u, folly::constexpr_strlen(a), b, 0u, b.size_); + a, 0u, folly::constexpr_strlen(a), b.data_, 0u, b.size_); } /** @@ -2664,7 +2753,29 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const Char* b) noexcept { return detail::fixedstring::Cmp::LT == detail::fixedstring::compare_( - a, 0u, a.size_, b, 0u, folly::constexpr_strlen(b)); + a.data_, 0u, a.size_, b, 0u, folly::constexpr_strlen(b)); + } + + /** + * \overload + */ + friend constexpr bool operator<( + Range a, + const BasicFixedString& b) noexcept { + return detail::fixedstring::Cmp::LT == + detail::fixedstring::compare_( + a.begin(), 0u, a.size(), b.data_, 0u, b.size_); + } + + /** + * \overload + */ + friend constexpr bool operator<( + const BasicFixedString& a, + Range b) noexcept { + return detail::fixedstring::Cmp::LT == + detail::fixedstring::compare_( + a.data_, 0u, a.size_, b.begin(), 0u, b.size()); } friend constexpr bool operator>( @@ -2682,6 +2793,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return b < a; } + /** + * \overload + */ + friend constexpr bool operator>( + Range a, + const BasicFixedString& b) noexcept { + return b < a; + } + + /** + * \overload + */ + friend constexpr bool operator>( + const BasicFixedString& a, + Range b) noexcept { + return b < a; + } + friend constexpr bool operator<=( const Char* a, const BasicFixedString& b) noexcept { @@ -2697,6 +2826,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return !(b < a); } + /** + * \overload + */ + friend constexpr bool operator<=( + Range const& a, + const BasicFixedString& b) noexcept { + return !(b < a); + } + + /** + * \overload + */ + friend constexpr bool operator<=( + const BasicFixedString& a, + Range b) noexcept { + return !(b < a); + } + friend constexpr bool operator>=( const Char* a, const BasicFixedString& b) noexcept { @@ -2712,6 +2859,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { return !(a < b); } + /** + * \overload + */ + friend constexpr bool operator>=( + Range a, + const BasicFixedString& b) noexcept { + return !(a < b); + } + + /** + * \overload + */ + friend constexpr bool operator>=( + const BasicFixedString& a, + Range const& b) noexcept { + return !(a < b); + } + /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * Asymmetric concatenation */ @@ -2721,8 +2886,10 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const BasicFixedString& b) noexcept { return detail::fixedstring::Helper::concat_( detail::fixedstring::checkNullTerminated(a), - b, - std::make_index_sequence{}); + M - 1u, + b.data_, + b.size_, + folly::make_index_sequence{}); } /** @@ -2733,9 +2900,11 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const BasicFixedString& a, const Char (&b)[M]) noexcept { return detail::fixedstring::Helper::concat_( - a, + a.data_, + a.size_, detail::fixedstring::checkNullTerminated(b), - std::make_index_sequence{}); + M - 1u, + folly::make_index_sequence{}); } /** @@ -2746,7 +2915,11 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { const BasicFixedString& b) noexcept { using A = const Char[2u]; return detail::fixedstring::Helper::concat_( - A{a, Char(0)}, b, std::make_index_sequence{}); + A{a, Char(0)}, + 1u, + b.data_, + b.size_, + folly::make_index_sequence{}); } /** @@ -2757,7 +2930,11 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { Char b) noexcept { using A = const Char[2u]; return detail::fixedstring::Helper::concat_( - a, A{b, Char(0)}, std::make_index_sequence{}); + a.data_, + a.size_, + A{b, Char(0)}, + 1u, + folly::make_index_sequence{}); } }; @@ -2768,7 +2945,11 @@ template constexpr bool operator==( const BasicFixedString& a, const BasicFixedString& b) noexcept { - return detail::fixedstring::equal_(a, a.size(), b, b.size()); + return detail::fixedstring::equal_( + detail::fixedstring::Helper::data_(a), + a.size(), + detail::fixedstring::Helper::data_(b), + b.size()); } template @@ -2783,7 +2964,13 @@ constexpr bool operator<( const BasicFixedString& a, const BasicFixedString& b) noexcept { return detail::fixedstring::Cmp::LT == - detail::fixedstring::compare_(a, 0u, a.size(), b, 0u, b.size()); + detail::fixedstring::compare_( + detail::fixedstring::Helper::data_(a), + 0u, + a.size(), + detail::fixedstring::Helper::data_(b), + 0u, + b.size()); } template @@ -2815,7 +3002,11 @@ constexpr BasicFixedString operator+( const BasicFixedString& a, const BasicFixedString& b) noexcept { return detail::fixedstring::Helper::concat_( - a, b, std::make_index_sequence{}); + detail::fixedstring::Helper::data_(a), + a.size(), + detail::fixedstring::Helper::data_(b), + b.size(), + folly::make_index_sequence{}); } /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** @@ -2842,8 +3033,8 @@ FOLLY_CPP14_CONSTEXPR void swap( a.swap(b); } -inline namespace Literals { -inline namespace StringLiterals { +inline namespace literals { +inline namespace string_literals { inline namespace { // "const std::size_t&" is so that folly::npos has the same address in every // translation unit. This is to avoid potential violations of the ODR. @@ -2862,7 +3053,7 @@ constexpr const std::size_t& npos = detail::fixedstring::FixedStringBase::npos; * \par Example: * \par * \code - * using namespace folly::StringLiterals; + * using namespace folly::string_literals; * constexpr auto hello = "hello world!"_fs; * \endcode *