Commit 2843ff12 authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot

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
parent 58d67ca5
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <tuple> #include <tuple>
#include <utility> #include <utility>
#include <folly/Utility.h>
namespace folly { namespace folly {
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
...@@ -38,15 +40,6 @@ namespace folly { ...@@ -38,15 +40,6 @@ namespace folly {
namespace detail { namespace detail {
namespace apply_tuple { 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() { inline constexpr std::size_t sum() {
return 0; return 0;
} }
...@@ -61,7 +54,7 @@ struct TupleSizeSum { ...@@ -61,7 +54,7 @@ struct TupleSizeSum {
}; };
template <typename... Tuples> template <typename... Tuples>
using MakeIndexSequenceFromTuple = MakeIndexSequence< using MakeIndexSequenceFromTuple = folly::make_index_sequence<
TupleSizeSum<typename std::decay<Tuples>::type...>::value>; TupleSizeSum<typename std::decay<Tuples>::type...>::value>;
// This is to allow using this with pointers to member functions, // 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)) { ...@@ -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> 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( -> decltype(
std::forward<F>(f)(std::get<Indexes>(std::forward<Tuple>(t))...)) { std::forward<F>(f)(std::get<Indexes>(std::forward<Tuple>(t))...)) {
return 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> 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( -> decltype(
std::forward_as_tuple(std::get<Indexes>(std::forward<Tuple>(t))...)) { std::forward_as_tuple(std::get<Indexes>(std::forward<Tuple>(t))...)) {
return std::forward_as_tuple(std::get<Indexes>(std::forward<Tuple>(t))...); return std::forward_as_tuple(std::get<Indexes>(std::forward<Tuple>(t))...);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <folly/Utility.h>
#include <folly/portability/BitsFunctexcept.h> #include <folly/portability/BitsFunctexcept.h>
#include <folly/portability/Constexpr.h> #include <folly/portability/Constexpr.h>
...@@ -286,7 +287,7 @@ struct Helper { ...@@ -286,7 +287,7 @@ struct Helper {
std::size_t left_count, std::size_t left_count,
const Right& right, const Right& right,
std::size_t right_count, 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}; return {left, left_count, right, right_count, is};
} }
...@@ -299,7 +300,7 @@ struct Helper { ...@@ -299,7 +300,7 @@ struct Helper {
const Right& right, const Right& right,
std::size_t right_pos, std::size_t right_pos,
std::size_t right_count, std::size_t right_count,
std::index_sequence<Is...> is) noexcept { folly::index_sequence<Is...> is) noexcept {
return {left, return {left,
left_size, left_size,
left_pos, left_pos,
...@@ -550,13 +551,13 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -550,13 +551,13 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
Char data_[N + 1u]; // +1 for the null terminator Char data_[N + 1u]; // +1 for the null terminator
std::size_t size_; // Nbr of chars, not incl. null terminator. size_ <= N. 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> template <class That, std::size_t... Is>
constexpr BasicFixedString( constexpr BasicFixedString(
const That& that, const That& that,
std::size_t size, std::size_t size,
std::index_sequence<Is...>, folly::index_sequence<Is...>,
std::size_t pos = 0, std::size_t pos = 0,
std::size_t count = npos) noexcept std::size_t count = npos) noexcept
: data_{(Is < (size - pos) && Is < count ? that[Is + pos] : Char(0))..., : data_{(Is < (size - pos) && Is < count ? that[Is + pos] : Char(0))...,
...@@ -567,7 +568,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -567,7 +568,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
constexpr BasicFixedString( constexpr BasicFixedString(
std::size_t count, std::size_t count,
Char ch, Char ch,
std::index_sequence<Is...>) noexcept folly::index_sequence<Is...>) noexcept
: data_{((Is < count) ? ch : Char(0))..., Char(0)}, size_{count} {} : data_{((Is < count) ? ch : Char(0))..., Char(0)}, size_{count} {}
// Concatenation constructor // Concatenation constructor
...@@ -577,7 +578,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -577,7 +578,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
std::size_t left_size, std::size_t left_size,
const Right& right, const Right& right,
std::size_t right_size, std::size_t right_size,
std::index_sequence<Is...>) noexcept folly::index_sequence<Is...>) noexcept
: data_{detail::fixedstring::char_at_<Char>( : data_{detail::fixedstring::char_at_<Char>(
left, left,
left_size, left_size,
...@@ -597,7 +598,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -597,7 +598,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
const Right& right, const Right& right,
std::size_t right_pos, std::size_t right_pos,
std::size_t right_count, std::size_t right_count,
std::index_sequence<Is...>) noexcept folly::index_sequence<Is...>) noexcept
: data_{detail::fixedstring::char_at_<Char>( : data_{detail::fixedstring::char_at_<Char>(
left, left,
left_size, left_size,
...@@ -686,7 +687,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -686,7 +687,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
: BasicFixedString{ : BasicFixedString{
that.data_, that.data_,
that.size_, that.size_,
std::make_index_sequence<(M < N ? M : N)>{}, folly::make_index_sequence<(M < N ? M : N)>{},
pos, pos,
detail::fixedstring::checkOverflow( detail::fixedstring::checkOverflow(
detail::fixedstring::checkOverflowOrNpos( detail::fixedstring::checkOverflowOrNpos(
...@@ -707,7 +708,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -707,7 +708,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
constexpr /* implicit */ BasicFixedString(const Char (&that)[M]) noexcept constexpr /* implicit */ BasicFixedString(const Char (&that)[M]) noexcept
: BasicFixedString{detail::fixedstring::checkNullTerminated(that), : BasicFixedString{detail::fixedstring::checkNullTerminated(that),
M - 1u, M - 1u,
std::make_index_sequence<M - 1u>{}} {} folly::make_index_sequence<M - 1u>{}} {}
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
* Construct from a `const Char*` and count * Construct from a `const Char*` and count
...@@ -1884,7 +1885,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -1884,7 +1885,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
detail::fixedstring::checkOverflow(that_pos, that.size_), detail::fixedstring::checkOverflow(that_pos, that.size_),
detail::fixedstring::checkOverflowOrNpos( detail::fixedstring::checkOverflowOrNpos(
that_count, that.size_ - that_pos), 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 { ...@@ -1984,7 +1985,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
detail::fixedstring::checkNullTerminated(that), detail::fixedstring::checkNullTerminated(that),
detail::fixedstring::checkOverflow(that_pos, M - 1u), detail::fixedstring::checkOverflow(that_pos, M - 1u),
detail::fixedstring::checkOverflowOrNpos(that_count, M - 1u - that_pos), 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 { ...@@ -2750,7 +2751,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
M - 1u, M - 1u,
b.data_, b.data_,
b.size_, 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 { ...@@ -2765,7 +2766,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
a.size_, a.size_,
detail::fixedstring::checkNullTerminated(b), detail::fixedstring::checkNullTerminated(b),
M - 1u, 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 { ...@@ -2780,7 +2781,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
1u, 1u,
b.data_, b.data_,
b.size_, b.size_,
std::make_index_sequence<N + 1u>{}); folly::make_index_sequence<N + 1u>{});
} }
/** /**
...@@ -2795,7 +2796,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -2795,7 +2796,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
a.size_, a.size_,
A{b, Char(0)}, A{b, Char(0)},
1u, 1u,
std::make_index_sequence<N + 1u>{}); folly::make_index_sequence<N + 1u>{});
} }
}; };
...@@ -2867,7 +2868,7 @@ constexpr BasicFixedString<Char, N + M> operator+( ...@@ -2867,7 +2868,7 @@ constexpr BasicFixedString<Char, N + M> operator+(
a.size(), a.size(),
detail::fixedstring::Helper::data_(b), detail::fixedstring::Helper::data_(b),
b.size(), b.size(),
std::make_index_sequence<N + M>{}); folly::make_index_sequence<N + M>{});
} }
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#pragma once #pragma once
#include <cstdint>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
...@@ -83,7 +84,7 @@ constexpr typename std::decay<T>::type copy(T&& value) noexcept( ...@@ -83,7 +84,7 @@ constexpr typename std::decay<T>::type copy(T&& value) noexcept(
*/ */
#if __cpp_lib_as_const || _MSC_VER #if __cpp_lib_as_const || _MSC_VER
/* using override */ using std::as_const /* using override */ using std::as_const;
#else #else
...@@ -95,5 +96,39 @@ constexpr T const& as_const(T& t) noexcept { ...@@ -95,5 +96,39 @@ constexpr T const& as_const(T& t) noexcept {
template <class T> template <class T>
void as_const(T const&&) = delete; 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 #endif
} }
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <folly/Utility.h> #include <folly/Utility.h>
#include <gtest/gtest.h> #include <folly/portability/GTest.h>
namespace { namespace {
...@@ -75,3 +75,16 @@ TEST_F(UtilityTest, as_const) { ...@@ -75,3 +75,16 @@ TEST_F(UtilityTest, as_const) {
EXPECT_EQ(&s, &folly::as_const(s)); EXPECT_EQ(&s, &folly::as_const(s));
EXPECT_TRUE(noexcept(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());
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment