Backport std::index_sequence and friends
authorChristopher Dykes <cdykes@fb.com>
Wed, 15 Mar 2017 18:37:07 +0000 (11:37 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 15 Mar 2017 18:49:49 +0000 (11:49 -0700)
Summary:
To GCC 4.8, because it's not *quite* dead yet.

This is needed to get FixedString working properly on GCC 4.8

Reviewed By: yfeldblum

Differential Revision: D4646026

fbshipit-source-id: 075df04e479bd2b11f6538da2ed3e78b59956621

folly/ApplyTuple.h
folly/FixedString.h
folly/Utility.h
folly/test/UtilityTest.cpp

index 41ac5337dec4df1366b72ebc4f88de2967011816..3046e0fbce99de7cbf7ea387dcb69bff223f8863 100644 (file)
@@ -31,6 +31,8 @@
 #include <tuple>
 #include <utility>
 
+#include <folly/Utility.h>
+
 namespace folly {
 
 //////////////////////////////////////////////////////////////////////
@@ -38,15 +40,6 @@ namespace folly {
 namespace detail {
 namespace apply_tuple {
 
-template <std::size_t...>
-struct IndexSequence {};
-
-template <std::size_t N, std::size_t... Is>
-struct MakeIndexSequence : MakeIndexSequence<N - 1, N - 1, Is...> {};
-
-template <std::size_t... Is>
-struct MakeIndexSequence<0, Is...> : IndexSequence<Is...> {};
-
 inline constexpr std::size_t sum() {
   return 0;
 }
@@ -61,7 +54,7 @@ struct TupleSizeSum {
 };
 
 template <typename... Tuples>
-using MakeIndexSequenceFromTuple = MakeIndexSequence<
+using MakeIndexSequenceFromTuple = folly::make_index_sequence<
     TupleSizeSum<typename std::decay<Tuples>::type...>::value>;
 
 // This is to allow using this with pointers to member functions,
@@ -76,14 +69,14 @@ inline constexpr auto makeCallable(M(C::*d)) -> decltype(std::mem_fn(d)) {
 }
 
 template <class F, class Tuple, std::size_t... Indexes>
-inline constexpr auto call(F&& f, Tuple&& t, IndexSequence<Indexes...>)
+inline constexpr auto call(F&& f, Tuple&& t, folly::index_sequence<Indexes...>)
     -> decltype(
         std::forward<F>(f)(std::get<Indexes>(std::forward<Tuple>(t))...)) {
   return std::forward<F>(f)(std::get<Indexes>(std::forward<Tuple>(t))...);
 }
 
 template <class Tuple, std::size_t... Indexes>
-inline constexpr auto forwardTuple(Tuple&& t, IndexSequence<Indexes...>)
+inline constexpr auto forwardTuple(Tuple&& t, folly::index_sequence<Indexes...>)
     -> decltype(
         std::forward_as_tuple(std::get<Indexes>(std::forward<Tuple>(t))...)) {
   return std::forward_as_tuple(std::get<Indexes>(std::forward<Tuple>(t))...);
index f30ee507fcc03e7944e2c2976ef740a34470ea7a..ee0528271b2d5b5d1fd3ed01725f0b9d9c8c7c06 100644 (file)
@@ -28,6 +28,7 @@
 #include <type_traits>
 #include <utility>
 
+#include <folly/Utility.h>
 #include <folly/portability/BitsFunctexcept.h>
 #include <folly/portability/Constexpr.h>
 
@@ -286,7 +287,7 @@ struct Helper {
       std::size_t left_count,
       const Right& right,
       std::size_t right_count,
-      std::index_sequence<Is...> is) noexcept {
+      folly::index_sequence<Is...> is) noexcept {
     return {left, left_count, right, right_count, is};
   }
 
@@ -299,7 +300,7 @@ struct Helper {
       const Right& right,
       std::size_t right_pos,
       std::size_t right_count,
-      std::index_sequence<Is...> is) noexcept {
+      folly::index_sequence<Is...> is) noexcept {
     return {left,
             left_size,
             left_pos,
@@ -550,13 +551,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<N>;
+  using Indices = folly::make_index_sequence<N>;
 
   template <class That, std::size_t... Is>
   constexpr BasicFixedString(
       const That& that,
       std::size_t size,
-      std::index_sequence<Is...>,
+      folly::index_sequence<Is...>,
       std::size_t pos = 0,
       std::size_t count = npos) noexcept
       : data_{(Is < (size - pos) && Is < count ? that[Is + pos] : Char(0))...,
@@ -567,7 +568,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
   constexpr BasicFixedString(
       std::size_t count,
       Char ch,
-      std::index_sequence<Is...>) noexcept
+      folly::index_sequence<Is...>) noexcept
       : data_{((Is < count) ? ch : Char(0))..., Char(0)}, size_{count} {}
 
   // Concatenation constructor
@@ -577,7 +578,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
       std::size_t left_size,
       const Right& right,
       std::size_t right_size,
-      std::index_sequence<Is...>) noexcept
+      folly::index_sequence<Is...>) noexcept
       : data_{detail::fixedstring::char_at_<Char>(
                   left,
                   left_size,
@@ -597,7 +598,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
       const Right& right,
       std::size_t right_pos,
       std::size_t right_count,
-      std::index_sequence<Is...>) noexcept
+      folly::index_sequence<Is...>) noexcept
       : data_{detail::fixedstring::char_at_<Char>(
                   left,
                   left_size,
@@ -686,7 +687,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(
@@ -707,7 +708,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<M - 1u>{}} {}
+                         folly::make_index_sequence<M - 1u>{}} {}
 
   /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
    * Construct from a `const Char*` and count
@@ -1884,7 +1885,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
         detail::fixedstring::checkOverflow(that_pos, that.size_),
         detail::fixedstring::checkOverflowOrNpos(
             that_count, that.size_ - that_pos),
-        std::make_index_sequence<N + M>{});
+        folly::make_index_sequence<N + M>{});
   }
 
   /**
@@ -1984,7 +1985,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
         detail::fixedstring::checkNullTerminated(that),
         detail::fixedstring::checkOverflow(that_pos, M - 1u),
         detail::fixedstring::checkOverflowOrNpos(that_count, M - 1u - that_pos),
-        std::make_index_sequence<N + M - 1u>{});
+        folly::make_index_sequence<N + M - 1u>{});
   }
 
   /**
@@ -2750,7 +2751,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
         M - 1u,
         b.data_,
         b.size_,
-        std::make_index_sequence<N + M - 1u>{});
+        folly::make_index_sequence<N + M - 1u>{});
   }
 
   /**
@@ -2765,7 +2766,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
         a.size_,
         detail::fixedstring::checkNullTerminated(b),
         M - 1u,
-        std::make_index_sequence<N + M - 1u>{});
+        folly::make_index_sequence<N + M - 1u>{});
   }
 
   /**
@@ -2780,7 +2781,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
         1u,
         b.data_,
         b.size_,
-        std::make_index_sequence<N + 1u>{});
+        folly::make_index_sequence<N + 1u>{});
   }
 
   /**
@@ -2795,7 +2796,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
         a.size_,
         A{b, Char(0)},
         1u,
-        std::make_index_sequence<N + 1u>{});
+        folly::make_index_sequence<N + 1u>{});
   }
 };
 
@@ -2867,7 +2868,7 @@ constexpr BasicFixedString<Char, N + M> operator+(
       a.size(),
       detail::fixedstring::Helper::data_(b),
       b.size(),
-      std::make_index_sequence<N + M>{});
+      folly::make_index_sequence<N + M>{});
 }
 
 /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
index 385ed34ac7d52b5329df8dc59aecc23400b4c4c9..f8f4f9bb07d5e5a94156f04f46f43637ed4b7098 100644 (file)
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <cstdint>
 #include <type_traits>
 #include <utility>
 
@@ -83,7 +84,7 @@ constexpr typename std::decay<T>::type copy(T&& value) noexcept(
  */
 #if __cpp_lib_as_const || _MSC_VER
 
-/* using override */ using std::as_const
+/* using override */ using std::as_const;
 
 #else
 
@@ -95,5 +96,39 @@ constexpr T const& as_const(T& t) noexcept {
 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
 }
index df8fa5d23b8063bddf40bc7e84d336045f44fb16..9b77e170099aacf96ec1b887f33eec0731f6d4ba 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <folly/Utility.h>
 
-#include <gtest/gtest.h>
+#include <folly/portability/GTest.h>
 
 namespace {
 
@@ -75,3 +75,16 @@ TEST_F(UtilityTest, as_const) {
   EXPECT_EQ(&s, &folly::as_const(s));
   EXPECT_TRUE(noexcept(folly::as_const(s)));
 }
+
+TEST(FollyIntegerSequence, core) {
+  constexpr auto seq = folly::integer_sequence<int, 0, 3, 2>();
+  static_assert(seq.size() == 3, "");
+  EXPECT_EQ(3, seq.size());
+
+  auto seq2 = folly::index_sequence<0, 4, 3>();
+  EXPECT_EQ(3, seq2.size());
+
+  constexpr auto seq3 = folly::make_index_sequence<3>();
+  static_assert(seq3.size() == 3, "");
+  EXPECT_EQ(3, seq3.size());
+}