#include <type_traits>
#include <utility>
+#include <folly/Range.h>
#include <folly/Utility.h>
#include <folly/portability/BitsFunctexcept.h>
#include <folly/portability/Constexpr.h>
} // namespace fixedstring
} // namespace detail
-// Defined in folly/Range.h
-template <class Iter>
-class Range;
-
// Defined in folly/Hash.h
std::uint32_t hsieh_hash32_buf(const void* buf, std::size_t len);
return compare(0u, size_, that, folly::constexpr_strlen(that));
}
+ /**
+ * \overload
+ */
+ constexpr int compare(Range<const Char*> that) const noexcept {
+ return compare(0u, size_, that.begin(), that.size());
+ }
+
/**
* Compare two strings for lexicographical ordering.
* \note Equivalent to
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<const Char*> that) const noexcept(false) {
+ return compare(this_pos, this_count, that.begin(), that.size());
+ }
+
/**
* Compare two strings for lexicographical ordering.
*
that_count));
}
+ constexpr int compare(
+ std::size_t this_pos,
+ std::size_t this_count,
+ Range<const Char*> 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}`
return b == a;
}
+ /**
+ * \overload
+ */
+ friend constexpr bool operator==(
+ Range<const Char*> 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<const Char*> b) noexcept {
+ return b == a;
+ }
+
friend constexpr bool operator!=(
const Char* a,
const BasicFixedString& b) noexcept {
return !(b == a);
}
+ /**
+ * \overload
+ */
+ friend constexpr bool operator!=(
+ Range<const Char*> a,
+ const BasicFixedString& b) noexcept {
+ return !(a == b);
+ }
+
+ /**
+ * \overload
+ */
+ friend constexpr bool operator!=(
+ const BasicFixedString& a,
+ Range<const Char*> b) noexcept {
+ return !(a == b);
+ }
+
friend constexpr bool operator<(
const Char* a,
const BasicFixedString& b) noexcept {
a.data_, 0u, a.size_, b, 0u, folly::constexpr_strlen(b));
}
+ /**
+ * \overload
+ */
+ friend constexpr bool operator<(
+ Range<const Char*> 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<const Char*> b) noexcept {
+ return detail::fixedstring::Cmp::LT ==
+ detail::fixedstring::compare_(
+ a.data_, 0u, a.size_, b.begin(), 0u, b.size());
+ }
+
friend constexpr bool operator>(
const Char* a,
const BasicFixedString& b) noexcept {
return b < a;
}
+ /**
+ * \overload
+ */
+ friend constexpr bool operator>(
+ Range<const Char*> a,
+ const BasicFixedString& b) noexcept {
+ return b < a;
+ }
+
+ /**
+ * \overload
+ */
+ friend constexpr bool operator>(
+ const BasicFixedString& a,
+ Range<const Char*> b) noexcept {
+ return b < a;
+ }
+
friend constexpr bool operator<=(
const Char* a,
const BasicFixedString& b) noexcept {
return !(b < a);
}
+ /**
+ * \overload
+ */
+ friend constexpr bool operator<=(
+ Range<const Char*> const& a,
+ const BasicFixedString& b) noexcept {
+ return !(b < a);
+ }
+
+ /**
+ * \overload
+ */
+ friend constexpr bool operator<=(
+ const BasicFixedString& a,
+ Range<const Char*> b) noexcept {
+ return !(b < a);
+ }
+
friend constexpr bool operator>=(
const Char* a,
const BasicFixedString& b) noexcept {
return !(a < b);
}
+ /**
+ * \overload
+ */
+ friend constexpr bool operator>=(
+ Range<const Char*> a,
+ const BasicFixedString& b) noexcept {
+ return !(a < b);
+ }
+
+ /**
+ * \overload
+ */
+ friend constexpr bool operator>=(
+ const BasicFixedString& a,
+ Range<const Char*> const& b) noexcept {
+ return !(a < b);
+ }
+
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
* Asymmetric concatenation
*/
static_assert(tmp3 == "aaa", "");
}
+TEST(FixedStringCompareTest, CompareStdString) {
+ constexpr folly::FixedString<10> tmp1{"aaaaaaaaaa"};
+ std::string const tmp2{"aaaaaaaaaba"};
+ EXPECT_EQ(-1, tmp1.compare(tmp2));
+ // These are specifically testing the operators, and so we can't rely
+ // on whever the implementation details of EXPECT_<OP> might be.
+ EXPECT_FALSE(tmp1 == tmp2);
+ EXPECT_FALSE(tmp2 == tmp1);
+ EXPECT_TRUE(tmp1 != tmp2);
+ EXPECT_TRUE(tmp2 != tmp1);
+ EXPECT_TRUE(tmp1 < tmp2);
+ EXPECT_FALSE(tmp2 < tmp1);
+ EXPECT_TRUE(tmp1 <= tmp2);
+ EXPECT_FALSE(tmp2 <= tmp1);
+ EXPECT_FALSE(tmp1 > tmp2);
+ EXPECT_TRUE(tmp2 > tmp1);
+ EXPECT_FALSE(tmp1 >= tmp2);
+ EXPECT_TRUE(tmp2 >= tmp1);
+}
+
#if FOLLY_USE_CPP14_CONSTEXPR
constexpr folly::FixedString<20> constexpr_append_string_test() {
folly::FixedString<20> a{"hello"}, b{"X world!"};