From: Christopher Dykes Date: Wed, 15 Mar 2017 18:37:07 +0000 (-0700) Subject: Backport std::index_sequence and friends X-Git-Tag: v2017.03.20.00~6 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=2843ff12364e1159d99f2b96bcc4a5c428dad1fa;hp=58d67ca5d73517414666cdf65e5e788f07e5a233 Backport std::index_sequence and friends 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 --- diff --git a/folly/ApplyTuple.h b/folly/ApplyTuple.h index 41ac5337..3046e0fb 100644 --- a/folly/ApplyTuple.h +++ b/folly/ApplyTuple.h @@ -31,6 +31,8 @@ #include #include +#include + namespace folly { ////////////////////////////////////////////////////////////////////// @@ -38,15 +40,6 @@ namespace folly { namespace detail { namespace apply_tuple { -template -struct IndexSequence {}; - -template -struct MakeIndexSequence : MakeIndexSequence {}; - -template -struct MakeIndexSequence<0, Is...> : IndexSequence {}; - inline constexpr std::size_t sum() { return 0; } @@ -61,7 +54,7 @@ struct TupleSizeSum { }; template -using MakeIndexSequenceFromTuple = MakeIndexSequence< +using MakeIndexSequenceFromTuple = folly::make_index_sequence< TupleSizeSum::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 -inline constexpr auto call(F&& f, Tuple&& t, IndexSequence) +inline constexpr auto call(F&& f, Tuple&& t, folly::index_sequence) -> decltype( std::forward(f)(std::get(std::forward(t))...)) { return std::forward(f)(std::get(std::forward(t))...); } template -inline constexpr auto forwardTuple(Tuple&& t, IndexSequence) +inline constexpr auto forwardTuple(Tuple&& t, folly::index_sequence) -> decltype( std::forward_as_tuple(std::get(std::forward(t))...)) { return std::forward_as_tuple(std::get(std::forward(t))...); diff --git a/folly/FixedString.h b/folly/FixedString.h index f30ee507..ee052827 100644 --- a/folly/FixedString.h +++ b/folly/FixedString.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -286,7 +287,7 @@ struct Helper { std::size_t left_count, const Right& right, std::size_t right_count, - std::index_sequence is) noexcept { + folly::index_sequence 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) noexcept { + folly::index_sequence 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; + 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))..., @@ -567,7 +568,7 @@ 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 @@ -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) noexcept + folly::index_sequence) noexcept : data_{detail::fixedstring::char_at_( 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) noexcept + folly::index_sequence) noexcept : data_{detail::fixedstring::char_at_( 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{}} {} + folly::make_index_sequence{}} {} /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * 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{}); + folly::make_index_sequence{}); } /** @@ -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{}); + folly::make_index_sequence{}); } /** @@ -2750,7 +2751,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { M - 1u, b.data_, b.size_, - std::make_index_sequence{}); + folly::make_index_sequence{}); } /** @@ -2765,7 +2766,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { a.size_, detail::fixedstring::checkNullTerminated(b), M - 1u, - std::make_index_sequence{}); + folly::make_index_sequence{}); } /** @@ -2780,7 +2781,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { 1u, b.data_, b.size_, - std::make_index_sequence{}); + folly::make_index_sequence{}); } /** @@ -2795,7 +2796,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { a.size_, A{b, Char(0)}, 1u, - std::make_index_sequence{}); + folly::make_index_sequence{}); } }; @@ -2867,7 +2868,7 @@ constexpr BasicFixedString operator+( a.size(), detail::fixedstring::Helper::data_(b), b.size(), - std::make_index_sequence{}); + folly::make_index_sequence{}); } /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** diff --git a/folly/Utility.h b/folly/Utility.h index 385ed34a..f8f4f9bb 100644 --- a/folly/Utility.h +++ b/folly/Utility.h @@ -16,6 +16,7 @@ #pragma once +#include #include #include @@ -83,7 +84,7 @@ constexpr typename std::decay::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 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 +struct integer_sequence { + using value_type = T; + + static constexpr std::size_t size() noexcept { + return sizeof...(Ints); + } +}; + +template +using index_sequence = folly::integer_sequence; + +namespace detail { +template +struct make_index_sequence + : detail::make_index_sequence {}; + +template +struct make_index_sequence<0, Ints...> : folly::index_sequence {}; +} + +template +using make_index_sequence = detail::make_index_sequence; + #endif } diff --git a/folly/test/UtilityTest.cpp b/folly/test/UtilityTest.cpp index df8fa5d2..9b77e170 100644 --- a/folly/test/UtilityTest.cpp +++ b/folly/test/UtilityTest.cpp @@ -16,7 +16,7 @@ #include -#include +#include 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(); + 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()); +}