logging: add a LogConfig class and parsing code
[folly.git] / folly / FixedString.h
index ee0528271b2d5b5d1fd3ed01725f0b9d9c8c7c06..ece7691b74d09b43a7e0b413394cce2b939410eb 100644 (file)
 #include <type_traits>
 #include <utility>
 
+#include <folly/ConstexprMath.h>
+#include <folly/Portability.h>
+#include <folly/Range.h>
 #include <folly/Utility.h>
 #include <folly/portability/BitsFunctexcept.h>
 #include <folly/portability/Constexpr.h>
 
-// Define FOLLY_USE_CPP14_CONSTEXPR to be true if the compiler's C++14
-// constexpr support is "good enough".
-#ifndef FOLLY_USE_CPP14_CONSTEXPR
-#if defined(__clang__)
-#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201300L
-#elif defined(__GNUC__)
-#define FOLLY_USE_CPP14_CONSTEXPR __cplusplus >= 201304L
-#else
-#define FOLLY_USE_CPP14_CONSTEXPR 0 // MSVC?
-#endif
-#endif
-
-#if FOLLY_USE_CPP14_CONSTEXPR
-#define FOLLY_CPP14_CONSTEXPR constexpr
-#else
-#define FOLLY_CPP14_CONSTEXPR inline
-#endif
-
 namespace folly {
 
 template <class Char, std::size_t N>
@@ -119,7 +104,7 @@ 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__ <= 4
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 5
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Warray-bounds"
 #endif
@@ -318,7 +303,7 @@ struct Helper {
   }
 };
 
-#if defined(__GNUC__) && !defined(__CLANG__) && __GNUC__ <= 4
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 4
 #pragma GCC diagnostic pop
 #endif
 
@@ -330,18 +315,6 @@ FOLLY_CPP14_CONSTEXPR void constexpr_swap(T& a, T& b) noexcept(
   b = std::move(tmp);
 }
 
-// FUTURE: use const_log2 to fold instantiations of BasicFixedString together.
-// All BasicFixedString<C, N> instantiations could share the implementation
-// of BasicFixedString<C, M>, where M is the next highest power of 2 after N.
-//
-// Also, because of alignment of the data_ and size_ members, N should never be
-// smaller than `(alignof(std::size_t)/sizeof(C))-1` (-1 because of the null
-// terminator). OR, create a specialization for BasicFixedString<C, 0u> that
-// does not have a size_ member, since it is unnecessary.
-constexpr std::size_t const_log2(std::size_t N, std::size_t log2 = 0u) {
-  return N / 2u == 0u ? log2 : const_log2(N / 2u, log2 + 1u);
-}
-
 // For constexpr reverse iteration over a BasicFixedString
 template <class T>
 struct ReverseIterator {
@@ -436,11 +409,7 @@ struct ReverseIterator {
 } // namespace fixedstring
 } // namespace detail
 
-// Defined in folly/Range.h
-template <class Iter>
-class Range;
-
-// Defined in folly/Hash.h
+// Defined in folly/hash/Hash.h
 std::uint32_t hsieh_hash32_buf(const void* buf, std::size_t len);
 
 /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** *
@@ -548,6 +517,15 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
   friend class BasicFixedString;
   friend struct detail::fixedstring::Helper;
 
+  // FUTURE: use constexpr_log2 to fold instantiations of BasicFixedString
+  // together. All BasicFixedString<C, N> instantiations could share the
+  // implementation of BasicFixedString<C, M>, where M is the next highest power
+  // of 2 after N.
+  //
+  // Also, because of alignment of the data_ and size_ members, N should never
+  // be smaller than `(alignof(std::size_t)/sizeof(C))-1` (-1 because of the
+  // null terminator). OR, create a specialization for BasicFixedString<C, 0u>
+  // that does not have a size_ member, since it is unnecessary.
   Char data_[N + 1u]; // +1 for the null terminator
   std::size_t size_; // Nbr of chars, not incl. null terminator. size_ <= N.
 
@@ -812,29 +790,6 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     return *this;
   }
 
-  /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
-   * Conversion to folly::Range
-   * \return `Range<Iter>{begin(), end()}`
-   */
-  template <
-      class Iter,
-      class = typename std::enable_if<
-          std::is_convertible<Char*, Iter>::value>::type>
-  FOLLY_CPP14_CONSTEXPR /* implicit */ operator Range<Iter>() noexcept {
-    return {begin(), end()};
-  }
-
-  /**
-   * \overload
-   */
-  template <
-      class Iter,
-      class = typename std::enable_if<
-          std::is_convertible<const Char*, Iter>::value>::type>
-  constexpr /* implicit */ operator Range<Iter>() const noexcept {
-    return {begin(), end()};
-  }
-
   /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
    * Conversion to folly::Range
    * \return `Range<Char*>{begin(), end()}`
@@ -1287,8 +1242,9 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
       std::size_t count,
       Char ch) noexcept(false) {
     detail::fixedstring::checkOverflow(count, N - size_);
-    for (std::size_t i = 0u; i < count; ++i)
+    for (std::size_t i = 0u; i < count; ++i) {
       data_[size_ + i] = ch;
+    }
     size_ += count;
     data_[size_] = Char(0);
     return *this;
@@ -1335,8 +1291,9 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     detail::fixedstring::checkOverflow(pos, that.size_);
     count = detail::fixedstring::checkOverflowOrNpos(count, that.size_ - pos);
     detail::fixedstring::checkOverflow(count, N - size_);
-    for (std::size_t i = 0u; i < count; ++i)
+    for (std::size_t i = 0u; i < count; ++i) {
       data_[size_ + i] = that.data_[pos + i];
+    }
     size_ += count;
     data_[size_] = Char(0);
     return *this;
@@ -1363,8 +1320,9 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
       const Char* that,
       std::size_t count) noexcept(false) {
     detail::fixedstring::checkOverflow(count, N - size_);
-    for (std::size_t i = 0u; i < count; ++i)
+    for (std::size_t i = 0u; i < count; ++i) {
       data_[size_ + i] = that[i];
+    }
     size_ += count;
     data_[size_] = Char(0);
     return *this;
@@ -1606,6 +1564,13 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     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
@@ -1618,6 +1583,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<const Char*> that) const noexcept(false) {
+    return compare(this_pos, this_count, that.begin(), that.size());
+  }
+
   /**
    * Compare two strings for lexicographical ordering.
    *
@@ -1648,6 +1623,18 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
         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}`
@@ -2043,8 +2030,9 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
   copy(Char* dest, std::size_t count, std::size_t pos) const noexcept(false) {
     detail::fixedstring::checkOverflow(pos, size_);
     for (std::size_t i = 0u; i < count; ++i) {
-      if (i + pos == size_)
+      if (i + pos == size_) {
         return size_;
+      }
       dest[i] = data_[i + pos];
     }
     return count;
@@ -2660,6 +2648,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     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 {
@@ -2675,6 +2681,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     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 {
@@ -2694,6 +2718,28 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
                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 {
@@ -2709,6 +2755,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     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 {
@@ -2724,6 +2788,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     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 {
@@ -2739,6 +2821,24 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
     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
    */
@@ -2800,6 +2900,15 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
   }
 };
 
+template <class C, std::size_t N>
+inline std::basic_ostream<C>& operator<<(
+    std::basic_ostream<C>& os,
+    const BasicFixedString<C, N>& string) {
+  using StreamSize = decltype(os.width());
+  os.write(string.begin(), static_cast<StreamSize>(string.size()));
+  return os;
+}
+
 /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
  * Symmetric relational operators
  */
@@ -2901,7 +3010,7 @@ 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.
 constexpr const std::size_t& npos = detail::fixedstring::FixedStringBase::npos;
-}
+} // namespace
 
 #if defined(__GNUC__)
 #pragma GCC diagnostic push
@@ -2954,8 +3063,8 @@ FOLLY_DEFINE_FIXED_STRING_UDL(64)
 FOLLY_DEFINE_FIXED_STRING_UDL(128)
 
 #undef FOLLY_DEFINE_FIXED_STRING_UDL
-}
-}
+} // namespace string_literals
+} // namespace literals
 
 // TODO:
 // // numeric conversions:
@@ -2990,4 +3099,4 @@ FOLLY_DEFINE_FIXED_STRING_UDL(128)
 // constexpr FixedString</*...*/> to_fixed_string_ll() noexcept
 // template <unsigned long long val>
 // constexpr FixedString</*...*/> to_fixed_string_ull() noexcept;
-}
+} // namespace folly