Revert D5393697: [Folly] Add an sfmt19937 benchmark
[folly.git] / folly / Utility.h
index a76925057362dadf7a3fbc48f16fd91f287a9b45..dbe552f02aac940b79c34b2708ae18e4c4201d75 100644 (file)
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <cstdint>
 #include <type_traits>
 #include <utility>
 
@@ -68,4 +69,202 @@ constexpr typename std::decay<T>::type copy(T&& value) noexcept(
     noexcept(typename std::decay<T>::type(std::forward<T>(value)))) {
   return std::forward<T>(value);
 }
+
+/**
+ * A simple helper for getting a constant reference to an object.
+ *
+ * Example:
+ *
+ *   std::vector<int> v{1,2,3};
+ *   // The following two lines are equivalent:
+ *   auto a = const_cast<const std::vector<int>&>(v).begin();
+ *   auto b = folly::as_const(v).begin();
+ *
+ * Like C++17's std::as_const. See http://wg21.link/p0007
+ */
+#if __cpp_lib_as_const || _MSC_VER
+
+/* using override */ using std::as_const;
+
+#else
+
+template <class T>
+constexpr T const& as_const(T& t) noexcept {
+  return t;
+}
+
+template <class T>
+void as_const(T const&&) = delete;
+
+#endif
+
+#if __cpp_lib_integer_sequence || _MSC_VER
+
+/* using override */ using std::integer_sequence;
+/* using override */ using std::index_sequence;
+/* using override */ using std::make_index_sequence;
+
+#else
+
+template <class T, T... Ints>
+struct integer_sequence {
+  using value_type = T;
+
+  static constexpr std::size_t size() noexcept {
+    return sizeof...(Ints);
+  }
+};
+
+template <std::size_t... Ints>
+using index_sequence = folly::integer_sequence<std::size_t, Ints...>;
+
+namespace detail {
+template <std::size_t N, std::size_t... Ints>
+struct make_index_sequence
+    : detail::make_index_sequence<N - 1, N - 1, Ints...> {};
+
+template <std::size_t... Ints>
+struct make_index_sequence<0, Ints...> : folly::index_sequence<Ints...> {};
+}
+
+template <std::size_t N>
+using make_index_sequence = detail::make_index_sequence<N>;
+
+#endif
+
+/**
+ *  Backports from C++17 of:
+ *    std::in_place_t
+ *    std::in_place_type_t
+ *    std::in_place_index_t
+ *    std::in_place
+ *    std::in_place_type
+ *    std::in_place_index
+ */
+
+struct in_place_tag {};
+template <class>
+struct in_place_type_tag {};
+template <std::size_t>
+struct in_place_index_tag {};
+
+using in_place_t = in_place_tag (&)(in_place_tag);
+template <class T>
+using in_place_type_t = in_place_type_tag<T> (&)(in_place_type_tag<T>);
+template <std::size_t I>
+using in_place_index_t = in_place_index_tag<I> (&)(in_place_index_tag<I>);
+
+inline in_place_tag in_place(in_place_tag = {}) {
+  return {};
+}
+template <class T>
+inline in_place_type_tag<T> in_place_type(in_place_type_tag<T> = {}) {
+  return {};
+}
+template <std::size_t I>
+inline in_place_index_tag<I> in_place_index(in_place_index_tag<I> = {}) {
+  return {};
+}
+
+/**
+ * Initializer lists are a powerful compile time syntax introduced in C++11
+ * but due to their often conflicting syntax they are not used by APIs for
+ * construction.
+ *
+ * Further standard conforming compilers *strongly* favor an
+ * std::initalizer_list overload for construction if one exists.  The
+ * following is a simple tag used to disambiguate construction with
+ * initializer lists and regular uniform initialization.
+ *
+ * For example consider the following case
+ *
+ *  class Something {
+ *  public:
+ *    explicit Something(int);
+ *    Something(std::intiializer_list<int>);
+ *
+ *    operator int();
+ *  };
+ *
+ *  ...
+ *  Something something{1}; // SURPRISE!!
+ *
+ * The last call to instantiate the Something object will go to the
+ * initializer_list overload.  Which may be surprising to users.
+ *
+ * If however this tag was used to disambiguate such construction it would be
+ * easy for users to see which construction overload their code was referring
+ * to.  For example
+ *
+ *  class Something {
+ *  public:
+ *    explicit Something(int);
+ *    Something(folly::initlist_construct_t, std::initializer_list<int>);
+ *
+ *    operator int();
+ *  };
+ *
+ *  ...
+ *  Something something_one{1}; // not the initializer_list overload
+ *  Something something_two{folly::initlist_construct, {1}}; // correct
+ */
+struct initlist_construct_t {};
+constexpr initlist_construct_t initlist_construct{};
+
+/**
+ * A simple function object that passes its argument through unchanged.
+ *
+ * Example:
+ *
+ *   int i = 42;
+ *   int &j = Identity()(i);
+ *   assert(&i == &j);
+ *
+ * Warning: passing a prvalue through Identity turns it into an xvalue,
+ * which can effect whether lifetime extension occurs or not. For instance:
+ *
+ *   auto&& x = std::make_unique<int>(42);
+ *   cout << *x ; // OK, x refers to a valid unique_ptr.
+ *
+ *   auto&& y = Identity()(std::make_unique<int>(42));
+ *   cout << *y ; // ERROR: y did not lifetime-extend the unique_ptr. It
+ *                // is no longer valid
+ */
+struct Identity {
+  using is_transparent = void;
+  template <class T>
+  constexpr T&& operator()(T&& x) const noexcept {
+    return static_cast<T&&>(x);
+  }
+};
+
+namespace moveonly_ { // Protection from unintended ADL.
+
+/**
+ * Disallow copy but not move in derived types. This is essentially
+ * boost::noncopyable (the implementation is almost identical) but it
+ * doesn't delete move constructor and move assignment.
+ */
+class MoveOnly {
+ protected:
+  constexpr MoveOnly() = default;
+  ~MoveOnly() = default;
+
+  MoveOnly(MoveOnly&&) = default;
+  MoveOnly& operator=(MoveOnly&&) = default;
+  MoveOnly(const MoveOnly&) = delete;
+  MoveOnly& operator=(const MoveOnly&) = delete;
+};
+
+} // namespace moveonly_
+
+using MoveOnly = moveonly_::MoveOnly;
+
+/**
+ * Backport from C++17 of std::launder
+ */
+template <typename T>
+constexpr T* launder(T* in) {
+  return (in + 1) - 1;
 }
+} // namespace folly