Commit 08969df3 authored by Joe Loser's avatar Joe Loser Committed by Facebook Github Bot

Cut backport of std::index_sequence and friends (#1022)

Summary:
- Backporting `std::index_sequence`, `std::integer_sequence`, and other
  associated template aliases such as `index_sequence_for` and
  `make_index_sequence` is not needed as Folly requires C++14. These
  functions and template aliases are available in C++14 standard libraries,
  including GCC 4.9.
Pull Request resolved: https://github.com/facebook/folly/pull/1022

Reviewed By: Orvid

Differential Revision: D14119891

Pulled By: yfeldblum

fbshipit-source-id: 5ba55cc91495cf488cebfa1ebe82c0ff919e9840
parent f28c81ee
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <folly/Utility.h> #include <folly/Utility.h>
#include <folly/detail/FingerprintPolynomial.h> #include <folly/detail/FingerprintPolynomial.h>
#include <utility>
namespace folly { namespace folly {
namespace detail { namespace detail {
...@@ -52,33 +54,37 @@ struct FingerprintTablePoly<127> { ...@@ -52,33 +54,37 @@ struct FingerprintTablePoly<127> {
}; };
template <typename D, size_t S0, size_t... I0> template <typename D, size_t S0, size_t... I0>
constexpr auto copy_table(D const (&table)[S0], index_sequence<I0...>) { constexpr auto copy_table(D const (&table)[S0], std::index_sequence<I0...>) {
using array = std::array<D, S0>; using array = std::array<D, S0>;
return array{{table[I0]...}}; return array{{table[I0]...}};
} }
template <typename D, size_t S0> template <typename D, size_t S0>
constexpr auto copy_table(D const (&table)[S0]) { constexpr auto copy_table(D const (&table)[S0]) {
return copy_table(table, make_index_sequence<S0>{}); return copy_table(table, std::make_index_sequence<S0>{});
} }
template <typename D, size_t S0, size_t S1, size_t... I0> template <typename D, size_t S0, size_t S1, size_t... I0>
constexpr auto copy_table(D const (&table)[S0][S1], index_sequence<I0...>) { constexpr auto copy_table(
D const (&table)[S0][S1],
std::index_sequence<I0...>) {
using array = std::array<std::array<D, S1>, S0>; using array = std::array<std::array<D, S1>, S0>;
return array{{copy_table(table[I0])...}}; return array{{copy_table(table[I0])...}};
} }
template <typename D, size_t S0, size_t S1> template <typename D, size_t S0, size_t S1>
constexpr auto copy_table(D const (&table)[S0][S1]) { constexpr auto copy_table(D const (&table)[S0][S1]) {
return copy_table(table, make_index_sequence<S0>{}); return copy_table(table, std::make_index_sequence<S0>{});
} }
template <typename D, size_t S0, size_t S1, size_t S2, size_t... I0> template <typename D, size_t S0, size_t S1, size_t S2, size_t... I0>
constexpr auto copy_table(D const (&table)[S0][S1][S2], index_sequence<I0...>) { constexpr auto copy_table(
D const (&table)[S0][S1][S2],
std::index_sequence<I0...>) {
using array = std::array<std::array<std::array<D, S2>, S1>, S0>; using array = std::array<std::array<std::array<D, S2>, S1>, S0>;
return array{{copy_table(table[I0])...}}; return array{{copy_table(table[I0])...}};
} }
template <typename D, size_t S0, size_t S1, size_t S2> template <typename D, size_t S0, size_t S1, size_t S2>
constexpr auto copy_table(D const (&table)[S0][S1][S2]) { constexpr auto copy_table(D const (&table)[S0][S1][S2]) {
return copy_table(table, make_index_sequence<S0>{}); return copy_table(table, std::make_index_sequence<S0>{});
} }
template <size_t Deg> template <size_t Deg>
......
...@@ -271,7 +271,7 @@ struct Helper { ...@@ -271,7 +271,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,
folly::index_sequence<Is...> is) noexcept { std::index_sequence<Is...> is) noexcept {
return {left, left_count, right, right_count, is}; return {left, left_count, right, right_count, is};
} }
...@@ -284,7 +284,7 @@ struct Helper { ...@@ -284,7 +284,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,
folly::index_sequence<Is...> is) noexcept { std::index_sequence<Is...> is) noexcept {
return {left, return {left,
left_size, left_size,
left_pos, left_pos,
...@@ -528,13 +528,13 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -528,13 +528,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 = folly::make_index_sequence<N>; using Indices = std::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,
folly::index_sequence<Is...>, std::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))...,
...@@ -545,7 +545,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -545,7 +545,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
constexpr BasicFixedString( constexpr BasicFixedString(
std::size_t count, std::size_t count,
Char ch, Char ch,
folly::index_sequence<Is...>) noexcept std::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
...@@ -555,7 +555,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -555,7 +555,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,
folly::index_sequence<Is...>) noexcept std::index_sequence<Is...>) noexcept
: data_{detail::fixedstring::char_at_<Char>( : data_{detail::fixedstring::char_at_<Char>(
left, left,
left_size, left_size,
...@@ -575,7 +575,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -575,7 +575,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,
folly::index_sequence<Is...>) noexcept std::index_sequence<Is...>) noexcept
: data_{detail::fixedstring::char_at_<Char>( : data_{detail::fixedstring::char_at_<Char>(
left, left,
left_size, left_size,
...@@ -664,7 +664,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -664,7 +664,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
: BasicFixedString{ : BasicFixedString{
that.data_, that.data_,
that.size_, that.size_,
folly::make_index_sequence<(M < N ? M : N)>{}, std::make_index_sequence<(M < N ? M : N)>{},
pos, pos,
detail::fixedstring::checkOverflow( detail::fixedstring::checkOverflow(
detail::fixedstring::checkOverflowOrNpos( detail::fixedstring::checkOverflowOrNpos(
...@@ -685,7 +685,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -685,7 +685,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,
folly::make_index_sequence<M - 1u>{}} {} std::make_index_sequence<M - 1u>{}} {}
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
* Construct from a `const Char*` and count * Construct from a `const Char*` and count
...@@ -1872,7 +1872,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -1872,7 +1872,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),
folly::make_index_sequence<N + M>{}); std::make_index_sequence<N + M>{});
} }
/** /**
...@@ -1972,7 +1972,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -1972,7 +1972,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),
folly::make_index_sequence<N + M - 1u>{}); std::make_index_sequence<N + M - 1u>{});
} }
/** /**
...@@ -2851,7 +2851,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -2851,7 +2851,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
M - 1u, M - 1u,
b.data_, b.data_,
b.size_, b.size_,
folly::make_index_sequence<N + M - 1u>{}); std::make_index_sequence<N + M - 1u>{});
} }
/** /**
...@@ -2866,7 +2866,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -2866,7 +2866,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
a.size_, a.size_,
detail::fixedstring::checkNullTerminated(b), detail::fixedstring::checkNullTerminated(b),
M - 1u, M - 1u,
folly::make_index_sequence<N + M - 1u>{}); std::make_index_sequence<N + M - 1u>{});
} }
/** /**
...@@ -2881,7 +2881,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -2881,7 +2881,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
1u, 1u,
b.data_, b.data_,
b.size_, b.size_,
folly::make_index_sequence<N + 1u>{}); std::make_index_sequence<N + 1u>{});
} }
/** /**
...@@ -2896,7 +2896,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase { ...@@ -2896,7 +2896,7 @@ class BasicFixedString : private detail::fixedstring::FixedStringBase {
a.size_, a.size_,
A{b, Char(0)}, A{b, Char(0)},
1u, 1u,
folly::make_index_sequence<N + 1u>{}); std::make_index_sequence<N + 1u>{});
} }
}; };
...@@ -2977,7 +2977,7 @@ constexpr BasicFixedString<Char, N + M> operator+( ...@@ -2977,7 +2977,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(),
folly::make_index_sequence<N + M>{}); std::make_index_sequence<N + M>{});
} }
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
......
...@@ -575,8 +575,8 @@ struct Synchronized : public SynchronizedBase< ...@@ -575,8 +575,8 @@ struct Synchronized : public SynchronizedBase<
: Synchronized{std::piecewise_construct, : Synchronized{std::piecewise_construct,
std::move(datumArgs), std::move(datumArgs),
std::move(mutexArgs), std::move(mutexArgs),
make_index_sequence<sizeof...(DatumArgs)>{}, std::make_index_sequence<sizeof...(DatumArgs)>{},
make_index_sequence<sizeof...(MutexArgs)>{}} {} std::make_index_sequence<sizeof...(MutexArgs)>{}} {}
/** /**
* Copy assignment operator; deprecated * Copy assignment operator; deprecated
...@@ -811,8 +811,8 @@ struct Synchronized : public SynchronizedBase< ...@@ -811,8 +811,8 @@ struct Synchronized : public SynchronizedBase<
std::piecewise_construct_t, std::piecewise_construct_t,
std::tuple<DatumArgs...> datumArgs, std::tuple<DatumArgs...> datumArgs,
std::tuple<MutexArgs...> mutexArgs, std::tuple<MutexArgs...> mutexArgs,
index_sequence<IndicesOne...>, std::index_sequence<IndicesOne...>,
index_sequence<IndicesTwo...>) std::index_sequence<IndicesTwo...>)
: datum_{std::get<IndicesOne>(std::move(datumArgs))...}, : datum_{std::get<IndicesOne>(std::move(datumArgs))...},
mutex_{std::get<IndicesTwo>(std::move(mutexArgs))...} {} mutex_{std::get<IndicesTwo>(std::move(mutexArgs))...} {}
......
...@@ -310,7 +310,7 @@ struct RemoveTry<TupleType<folly::Try<Types>...>> { ...@@ -310,7 +310,7 @@ struct RemoveTry<TupleType<folly::Try<Types>...>> {
}; };
template <std::size_t... Indices, typename Tuple> template <std::size_t... Indices, typename Tuple>
auto unwrapTryTupleImpl(folly::index_sequence<Indices...>, Tuple&& instance) { auto unwrapTryTupleImpl(std::index_sequence<Indices...>, Tuple&& instance) {
using std::get; using std::get;
using ReturnType = typename RemoveTry<typename std::decay<Tuple>::type>::type; using ReturnType = typename RemoveTry<typename std::decay<Tuple>::type>::type;
return ReturnType{(get<Indices>(std::forward<Tuple>(instance)).value())...}; return ReturnType{(get<Indices>(std::forward<Tuple>(instance)).value())...};
...@@ -320,7 +320,7 @@ auto unwrapTryTupleImpl(folly::index_sequence<Indices...>, Tuple&& instance) { ...@@ -320,7 +320,7 @@ auto unwrapTryTupleImpl(folly::index_sequence<Indices...>, Tuple&& instance) {
template <typename Tuple> template <typename Tuple>
auto unwrapTryTuple(Tuple&& instance) { auto unwrapTryTuple(Tuple&& instance) {
using TupleDecayed = typename std::decay<Tuple>::type; using TupleDecayed = typename std::decay<Tuple>::type;
using Seq = folly::make_index_sequence<std::tuple_size<TupleDecayed>::value>; using Seq = std::make_index_sequence<std::tuple_size<TupleDecayed>::value>;
return try_detail::unwrapTryTupleImpl(Seq{}, std::forward<Tuple>(instance)); return try_detail::unwrapTryTupleImpl(Seq{}, std::forward<Tuple>(instance));
} }
......
...@@ -108,91 +108,6 @@ constexpr like_t<Src, Dst>&& forward_like(Dst&& dst) noexcept { ...@@ -108,91 +108,6 @@ constexpr like_t<Src, Dst>&& forward_like(Dst&& dst) noexcept {
return static_cast<like_t<Src, Dst>&&>(std::forward<Dst>(dst)); return static_cast<like_t<Src, Dst>&&>(std::forward<Dst>(dst));
} }
namespace utility_detail {
template <typename...>
struct make_seq_cat;
template <
template <typename T, T...> class S,
typename T,
T... Ta,
T... Tb,
T... Tc>
struct make_seq_cat<S<T, Ta...>, S<T, Tb...>, S<T, Tc...>> {
using type =
S<T,
Ta...,
(sizeof...(Ta) + Tb)...,
(sizeof...(Ta) + sizeof...(Tb) + Tc)...>;
};
// Not parameterizing by `template <typename T, T...> class, typename` because
// clang precisely v4.0 fails to compile that. Note that clang v3.9 and v5.0
// handle that code correctly.
//
// For this to work, `S0` is required to be `Sequence<T>` and `S1` is required
// to be `Sequence<T, 0>`.
template <std::size_t Size>
struct make_seq {
template <typename S0, typename S1>
using apply = typename make_seq_cat<
typename make_seq<Size / 2>::template apply<S0, S1>,
typename make_seq<Size / 2>::template apply<S0, S1>,
typename make_seq<Size % 2>::template apply<S0, S1>>::type;
};
template <>
struct make_seq<1> {
template <typename S0, typename S1>
using apply = S1;
};
template <>
struct make_seq<0> {
template <typename S0, typename S1>
using apply = S0;
};
} // namespace utility_detail
#if __cpp_lib_integer_sequence || _MSC_VER
/* using override */ using std::index_sequence;
/* using override */ using std::integer_sequence;
#else
// TODO: Remove after upgrading to C++14 baseline
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 = integer_sequence<std::size_t, Ints...>;
#endif
#if FOLLY_HAS_BUILTIN(__make_integer_seq) || _MSC_FULL_VER >= 190023918
template <typename T, std::size_t Size>
using make_integer_sequence = __make_integer_seq<integer_sequence, T, Size>;
#else
template <typename T, std::size_t Size>
using make_integer_sequence = typename utility_detail::make_seq<
Size>::template apply<integer_sequence<T>, integer_sequence<T, 0>>;
#endif
template <std::size_t Size>
using make_index_sequence = make_integer_sequence<std::size_t, Size>;
template <class... T>
using index_sequence_for = make_index_sequence<sizeof...(T)>;
/** /**
* Backports from C++17 of: * Backports from C++17 of:
* std::in_place_t * std::in_place_t
......
...@@ -63,7 +63,7 @@ namespace array_detail { ...@@ -63,7 +63,7 @@ namespace array_detail {
template <typename MakeItem, std::size_t... Index> template <typename MakeItem, std::size_t... Index>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN constexpr auto make_array_with( FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN constexpr auto make_array_with(
MakeItem const& make, MakeItem const& make,
index_sequence<Index...>) { std::index_sequence<Index...>) {
return std::array<decltype(make(0)), sizeof...(Index)>{{make(Index)...}}; return std::array<decltype(make(0)), sizeof...(Index)>{{make(Index)...}};
} }
} // namespace array_detail } // namespace array_detail
...@@ -73,7 +73,7 @@ FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN constexpr auto make_array_with( ...@@ -73,7 +73,7 @@ FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN constexpr auto make_array_with(
// Constructs a std::array<..., Size> with elements m(i) for i in [0, Size). // Constructs a std::array<..., Size> with elements m(i) for i in [0, Size).
template <std::size_t Size, typename MakeItem> template <std::size_t Size, typename MakeItem>
constexpr auto make_array_with(MakeItem const& make) { constexpr auto make_array_with(MakeItem const& make) {
return array_detail::make_array_with(make, make_index_sequence<Size>{}); return array_detail::make_array_with(make, std::make_index_sequence<Size>{});
} }
} // namespace folly } // namespace folly
...@@ -207,7 +207,7 @@ void for_each_range_impl(index_constant<1>, Sequence&& range, Func& func) { ...@@ -207,7 +207,7 @@ void for_each_range_impl(index_constant<1>, Sequence&& range, Func& func) {
*/ */
template <typename Sequence, typename Func, std::size_t... Indices> template <typename Sequence, typename Func, std::size_t... Indices>
void for_each_tuple_impl( void for_each_tuple_impl(
index_sequence<Indices...>, std::index_sequence<Indices...>,
Sequence&& seq, Sequence&& seq,
Func& func) { Func& func) {
using _ = int[]; using _ = int[];
...@@ -246,7 +246,9 @@ void for_each_tuple_impl(index_constant<2>, Sequence&& seq, Func& func) { ...@@ -246,7 +246,9 @@ void for_each_tuple_impl(index_constant<2>, Sequence&& seq, Func& func) {
// optimization over manual template "tail recursion" unrolling // optimization over manual template "tail recursion" unrolling
using size = std::tuple_size<typename std::decay<Sequence>::type>; using size = std::tuple_size<typename std::decay<Sequence>::type>;
for_each_tuple_impl( for_each_tuple_impl(
make_index_sequence<size::value>{}, std::forward<Sequence>(seq), func); std::make_index_sequence<size::value>{},
std::forward<Sequence>(seq),
func);
} }
template <typename Sequence, typename Func> template <typename Sequence, typename Func>
void for_each_tuple_impl(index_constant<1>, Sequence&& seq, Func& func) { void for_each_tuple_impl(index_constant<1>, Sequence&& seq, Func& func) {
......
...@@ -252,15 +252,16 @@ class emplace_iterator_base<Derived, EmplaceImpl, false> ...@@ -252,15 +252,16 @@ class emplace_iterator_base<Derived, EmplaceImpl, false>
*/ */
template <typename... Args> template <typename... Args>
Derived& operator=(emplace_args<Args...>& args) { Derived& operator=(emplace_args<Args...>& args) {
return unpackAndEmplace(args, index_sequence_for<Args...>{}); return unpackAndEmplace(args, std::index_sequence_for<Args...>{});
} }
template <typename... Args> template <typename... Args>
Derived& operator=(const emplace_args<Args...>& args) { Derived& operator=(const emplace_args<Args...>& args) {
return unpackAndEmplace(args, index_sequence_for<Args...>{}); return unpackAndEmplace(args, std::index_sequence_for<Args...>{});
} }
template <typename... Args> template <typename... Args>
Derived& operator=(emplace_args<Args...>&& args) { Derived& operator=(emplace_args<Args...>&& args) {
return unpackAndEmplace(std::move(args), index_sequence_for<Args...>{}); return unpackAndEmplace(
std::move(args), std::index_sequence_for<Args...>{});
} }
// No-ops. // No-ops.
...@@ -284,17 +285,17 @@ class emplace_iterator_base<Derived, EmplaceImpl, false> ...@@ -284,17 +285,17 @@ class emplace_iterator_base<Derived, EmplaceImpl, false>
protected: protected:
template <typename Args, std::size_t... I> template <typename Args, std::size_t... I>
Derived& unpackAndEmplace(Args& args, index_sequence<I...>) { Derived& unpackAndEmplace(Args& args, std::index_sequence<I...>) {
this->emplace(get_emplace_arg<I>(args)...); this->emplace(get_emplace_arg<I>(args)...);
return static_cast<Derived&>(*this); return static_cast<Derived&>(*this);
} }
template <typename Args, std::size_t... I> template <typename Args, std::size_t... I>
Derived& unpackAndEmplace(const Args& args, index_sequence<I...>) { Derived& unpackAndEmplace(const Args& args, std::index_sequence<I...>) {
this->emplace(get_emplace_arg<I>(args)...); this->emplace(get_emplace_arg<I>(args)...);
return static_cast<Derived&>(*this); return static_cast<Derived&>(*this);
} }
template <typename Args, std::size_t... I> template <typename Args, std::size_t... I>
Derived& unpackAndEmplace(Args&& args, index_sequence<I...>) { Derived& unpackAndEmplace(Args&& args, std::index_sequence<I...>) {
this->emplace(get_emplace_arg<I>(std::move(args))...); this->emplace(get_emplace_arg<I>(std::move(args))...);
return static_cast<Derived&>(*this); return static_cast<Derived&>(*this);
} }
...@@ -323,16 +324,16 @@ class emplace_iterator_base<Derived, EmplaceImpl, true> ...@@ -323,16 +324,16 @@ class emplace_iterator_base<Derived, EmplaceImpl, true>
*/ */
template <typename... Args> template <typename... Args>
Derived& operator=(std::pair<Args...>& args) { Derived& operator=(std::pair<Args...>& args) {
return this->unpackAndEmplace(args, index_sequence_for<Args...>{}); return this->unpackAndEmplace(args, std::index_sequence_for<Args...>{});
} }
template <typename... Args> template <typename... Args>
Derived& operator=(const std::pair<Args...>& args) { Derived& operator=(const std::pair<Args...>& args) {
return this->unpackAndEmplace(args, index_sequence_for<Args...>{}); return this->unpackAndEmplace(args, std::index_sequence_for<Args...>{});
} }
template <typename... Args> template <typename... Args>
Derived& operator=(std::pair<Args...>&& args) { Derived& operator=(std::pair<Args...>&& args) {
return this->unpackAndEmplace( return this->unpackAndEmplace(
std::move(args), index_sequence_for<Args...>{}); std::move(args), std::index_sequence_for<Args...>{});
} }
/** /**
...@@ -341,16 +342,16 @@ class emplace_iterator_base<Derived, EmplaceImpl, true> ...@@ -341,16 +342,16 @@ class emplace_iterator_base<Derived, EmplaceImpl, true>
*/ */
template <typename... Args> template <typename... Args>
Derived& operator=(std::tuple<Args...>& args) { Derived& operator=(std::tuple<Args...>& args) {
return this->unpackAndEmplace(args, index_sequence_for<Args...>{}); return this->unpackAndEmplace(args, std::index_sequence_for<Args...>{});
} }
template <typename... Args> template <typename... Args>
Derived& operator=(const std::tuple<Args...>& args) { Derived& operator=(const std::tuple<Args...>& args) {
return this->unpackAndEmplace(args, index_sequence_for<Args...>{}); return this->unpackAndEmplace(args, std::index_sequence_for<Args...>{});
} }
template <typename... Args> template <typename... Args>
Derived& operator=(std::tuple<Args...>&& args) { Derived& operator=(std::tuple<Args...>&& args) {
return this->unpackAndEmplace( return this->unpackAndEmplace(
std::move(args), index_sequence_for<Args...>{}); std::move(args), std::index_sequence_for<Args...>{});
} }
// We need all of these explicit defaults because the custom operator= // We need all of these explicit defaults because the custom operator=
......
...@@ -496,7 +496,7 @@ struct AsTypeList_<T<Ts...>> { ...@@ -496,7 +496,7 @@ struct AsTypeList_<T<Ts...>> {
using type = TypeList<Ts...>; using type = TypeList<Ts...>;
}; };
template <class T, T... Is> template <class T, T... Is>
struct AsTypeList_<folly::integer_sequence<T, Is...>> { struct AsTypeList_<std::integer_sequence<T, Is...>> {
using type = TypeList<std::integral_constant<T, Is>...>; using type = TypeList<std::integral_constant<T, Is>...>;
}; };
} // namespace impl } // namespace impl
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <folly/experimental/Select64.h> #include <folly/experimental/Select64.h>
#include <cstdint> #include <cstdint>
#include <utility>
#include <folly/ConstexprMath.h> #include <folly/ConstexprMath.h>
#include <folly/Portability.h> #include <folly/Portability.h>
...@@ -39,13 +40,13 @@ constexpr std::uint8_t selectInByte(std::size_t i, std::size_t j) { ...@@ -39,13 +40,13 @@ constexpr std::uint8_t selectInByte(std::size_t i, std::size_t j) {
template <std::size_t... I, std::size_t J> template <std::size_t... I, std::size_t J>
constexpr auto makeSelectInByteNestedArray( constexpr auto makeSelectInByteNestedArray(
index_sequence<I...>, std::index_sequence<I...>,
index_constant<J>) { index_constant<J>) {
return std::array<std::uint8_t, sizeof...(I)>{{selectInByte(I, J)...}}; return std::array<std::uint8_t, sizeof...(I)>{{selectInByte(I, J)...}};
} }
template <typename Is, std::size_t... J> template <typename Is, std::size_t... J>
constexpr auto makeSelectInByteArray(Is is, index_sequence<J...>) { constexpr auto makeSelectInByteArray(Is is, std::index_sequence<J...>) {
using inner = std::array<std::uint8_t, Is::size()>; using inner = std::array<std::uint8_t, Is::size()>;
using outer = std::array<inner, sizeof...(J)>; using outer = std::array<inner, sizeof...(J)>;
return outer{{makeSelectInByteNestedArray(is, index_constant<J>{})...}}; return outer{{makeSelectInByteNestedArray(is, index_constant<J>{})...}};
...@@ -55,8 +56,8 @@ constexpr auto makeSelectInByteArray(Is is, index_sequence<J...>) { ...@@ -55,8 +56,8 @@ constexpr auto makeSelectInByteArray(Is is, index_sequence<J...>) {
FOLLY_STORAGE_CONSTEXPR std::array<std::array<std::uint8_t, 256>, 8> const FOLLY_STORAGE_CONSTEXPR std::array<std::array<std::uint8_t, 256>, 8> const
kSelectInByte = makeSelectInByteArray( kSelectInByte = makeSelectInByteArray(
make_index_sequence<256>{}, std::make_index_sequence<256>{},
make_index_sequence<8>{}); std::make_index_sequence<8>{});
} // namespace detail } // namespace detail
} // namespace folly } // namespace folly
...@@ -33,7 +33,7 @@ namespace folly { ...@@ -33,7 +33,7 @@ namespace folly {
*/ */
template <typename Tuple> template <typename Tuple>
using index_sequence_for_tuple = using index_sequence_for_tuple =
make_index_sequence<std::tuple_size<Tuple>::value>; std::make_index_sequence<std::tuple_size<Tuple>::value>;
namespace detail { namespace detail {
namespace apply_tuple { namespace apply_tuple {
...@@ -45,7 +45,8 @@ struct ApplyInvoke { ...@@ -45,7 +45,8 @@ struct ApplyInvoke {
using seq = index_sequence_for_tuple<std::remove_reference_t<T>>; using seq = index_sequence_for_tuple<std::remove_reference_t<T>>;
template <typename F, typename T, std::size_t... I> template <typename F, typename T, std::size_t... I>
static constexpr auto invoke_(F&& f, T&& t, index_sequence<I...>) noexcept( static constexpr auto
invoke_(F&& f, T&& t, std::index_sequence<I...>) noexcept(
is_nothrow_invocable<F&&, decltype(get<I>(std::declval<T>()))...>::value) is_nothrow_invocable<F&&, decltype(get<I>(std::declval<T>()))...>::value)
-> invoke_result_t<F&&, decltype(get<I>(std::declval<T>()))...> { -> invoke_result_t<F&&, decltype(get<I>(std::declval<T>()))...> {
return invoke(static_cast<F&&>(f), get<I>(static_cast<T&&>(t))...); return invoke(static_cast<F&&>(f), get<I>(static_cast<T&&>(t))...);
...@@ -57,7 +58,8 @@ template < ...@@ -57,7 +58,8 @@ template <
std::size_t... Indices, std::size_t... Indices,
typename ReturnTuple = typename ReturnTuple =
std::tuple<decltype(get<Indices>(std::declval<Tuple>()))...>> std::tuple<decltype(get<Indices>(std::declval<Tuple>()))...>>
auto forward_tuple(Tuple&& tuple, index_sequence<Indices...>) -> ReturnTuple { auto forward_tuple(Tuple&& tuple, std::index_sequence<Indices...>)
-> ReturnTuple {
return ReturnTuple{get<Indices>(std::forward<Tuple>(tuple))...}; return ReturnTuple{get<Indices>(std::forward<Tuple>(tuple))...};
} }
} // namespace adl } // namespace adl
......
...@@ -33,10 +33,11 @@ struct PartialConstructFromCallable {}; ...@@ -33,10 +33,11 @@ struct PartialConstructFromCallable {};
template <typename F, typename Tuple> template <typename F, typename Tuple>
class Partial { class Partial {
using Indexes = make_index_sequence<std::tuple_size<Tuple>{}>; using Indexes = std::make_index_sequence<std::tuple_size<Tuple>{}>;
template <typename Self, std::size_t... I, typename... Args> template <typename Self, std::size_t... I, typename... Args>
static auto invokeForward(Self&& self, index_sequence<I...>, Args&&... args) static auto
invokeForward(Self&& self, std::index_sequence<I...>, Args&&... args)
-> decltype(invoke( -> decltype(invoke(
std::declval<Self>().f_, std::declval<Self>().f_,
std::get<I>(std::declval<Self>().stored_args_)..., std::get<I>(std::declval<Self>().stored_args_)...,
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <array> #include <array>
#include <memory> #include <memory>
#include <utility>
namespace { namespace {
...@@ -429,24 +430,23 @@ TEST(MakeFromTupleTest, make_from_tuple) { ...@@ -429,24 +430,23 @@ TEST(MakeFromTupleTest, make_from_tuple) {
} }
TEST(MakeIndexSequenceFromTuple, Basic) { TEST(MakeIndexSequenceFromTuple, Basic) {
using folly::index_sequence;
using folly::index_sequence_for_tuple; using folly::index_sequence_for_tuple;
using OneElementTuple = std::tuple<int>; using OneElementTuple = std::tuple<int>;
using TwoElementTuple = std::tuple<int>; using TwoElementTuple = std::tuple<int>;
EXPECT_TRUE((std::is_same< EXPECT_TRUE((std::is_same<
index_sequence_for_tuple<OneElementTuple>, index_sequence_for_tuple<OneElementTuple>,
index_sequence<0>>::value)); std::index_sequence<0>>::value));
EXPECT_TRUE((std::is_same< EXPECT_TRUE((std::is_same<
index_sequence_for_tuple<const OneElementTuple>, index_sequence_for_tuple<const OneElementTuple>,
index_sequence<0>>::value)); std::index_sequence<0>>::value));
EXPECT_TRUE((std::is_same< EXPECT_TRUE((std::is_same<
index_sequence_for_tuple<TwoElementTuple>, index_sequence_for_tuple<TwoElementTuple>,
index_sequence<0>>::value)); std::index_sequence<0>>::value));
EXPECT_TRUE((std::is_same< EXPECT_TRUE((std::is_same<
index_sequence_for_tuple<const TwoElementTuple>, index_sequence_for_tuple<const TwoElementTuple>,
index_sequence<0>>::value)); std::index_sequence<0>>::value));
} }
TEST(ApplyResult, Basic) { TEST(ApplyResult, Basic) {
......
...@@ -1420,7 +1420,7 @@ namespace detail { ...@@ -1420,7 +1420,7 @@ namespace detail {
template <typename V, typename... Fs, std::size_t... Is> template <typename V, typename... Fs, std::size_t... Is>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN void FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN void
foreach_(index_sequence<Is...>, V&& v, Fs&&... fs) { foreach_(std::index_sequence<Is...>, V&& v, Fs&&... fs) {
using _ = int[]; using _ = int[];
void(_{0, (void(v(index_constant<Is>{}, static_cast<Fs&&>(fs))), 0)...}); void(_{0, (void(v(index_constant<Is>{}, static_cast<Fs&&>(fs))), 0)...});
} }
...@@ -1428,7 +1428,7 @@ template <typename V, typename... Fs> ...@@ -1428,7 +1428,7 @@ template <typename V, typename... Fs>
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN void foreach( FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN void foreach(
V&& v, V&& v,
Fs&&... fs) { Fs&&... fs) {
using _ = index_sequence_for<Fs...>; using _ = std::index_sequence_for<Fs...>;
foreach_(_{}, static_cast<V&&>(v), static_cast<Fs&&>(fs)...); foreach_(_{}, static_cast<V&&>(v), static_cast<Fs&&>(fs)...);
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <folly/hash/detail/ChecksumDetail.h> #include <folly/hash/detail/ChecksumDetail.h>
#include <array> #include <array>
#include <utility>
#include <folly/Bits.h> #include <folly/Bits.h>
#include <folly/ConstexprMath.h> #include <folly/ConstexprMath.h>
...@@ -61,7 +62,7 @@ struct gf_powers_memo<0, m> { ...@@ -61,7 +62,7 @@ struct gf_powers_memo<0, m> {
template <uint32_t m> template <uint32_t m>
struct gf_powers_make { struct gf_powers_make {
template <size_t... i> template <size_t... i>
constexpr auto operator()(index_sequence<i...>) const { constexpr auto operator()(std::index_sequence<i...>) const {
return std::array<uint32_t, sizeof...(i)>{{gf_powers_memo<i, m>::value...}}; return std::array<uint32_t, sizeof...(i)>{{gf_powers_memo<i, m>::value...}};
} }
}; };
...@@ -124,9 +125,9 @@ static constexpr uint32_t crc32_m = 0xedb88320; ...@@ -124,9 +125,9 @@ static constexpr uint32_t crc32_m = 0xedb88320;
* Pre-calculated powers tables for crc32c and crc32. * Pre-calculated powers tables for crc32c and crc32.
*/ */
static constexpr std::array<uint32_t, 62> const crc32c_powers = static constexpr std::array<uint32_t, 62> const crc32c_powers =
gf_powers_make<crc32c_m>{}(make_index_sequence<62>{}); gf_powers_make<crc32c_m>{}(std::make_index_sequence<62>{});
static constexpr std::array<uint32_t, 62> const crc32_powers = static constexpr std::array<uint32_t, 62> const crc32_powers =
gf_powers_make<crc32_m>{}(make_index_sequence<62>{}); gf_powers_make<crc32_m>{}(std::make_index_sequence<62>{});
template <typename F> template <typename F>
static uint32_t crc32_append_zeroes( static uint32_t crc32_append_zeroes(
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <folly/init/Init.h> #include <folly/init/Init.h>
#include <folly/json.h> #include <folly/json.h>
#include <utility>
using namespace folly; using namespace folly;
namespace { namespace {
...@@ -100,7 +102,7 @@ BENCHMARK_RELATIVE(intAppend_format) { ...@@ -100,7 +102,7 @@ BENCHMARK_RELATIVE(intAppend_format) {
BENCHMARK_DRAW_LINE(); BENCHMARK_DRAW_LINE();
template <size_t... Indexes> template <size_t... Indexes>
int snprintf20Numbers(int i, index_sequence<Indexes...>) { int snprintf20Numbers(int i, std::index_sequence<Indexes...>) {
static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes"); static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes");
return snprintf( return snprintf(
bigBuf.data(), bigBuf.data(),
...@@ -115,13 +117,13 @@ int snprintf20Numbers(int i, index_sequence<Indexes...>) { ...@@ -115,13 +117,13 @@ int snprintf20Numbers(int i, index_sequence<Indexes...>) {
BENCHMARK(bigFormat_snprintf, iters) { BENCHMARK(bigFormat_snprintf, iters) {
while (iters--) { while (iters--) {
for (int i = -100; i < 100; i++) { for (int i = -100; i < 100; i++) {
snprintf20Numbers(i, make_index_sequence<20>()); snprintf20Numbers(i, std::make_index_sequence<20>());
} }
} }
} }
template <size_t... Indexes> template <size_t... Indexes>
decltype(auto) format20Numbers(int i, index_sequence<Indexes...>) { decltype(auto) format20Numbers(int i, std::index_sequence<Indexes...>) {
static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes"); static_assert(20 == sizeof...(Indexes), "Must have exactly 20 indexes");
return format( return format(
"{} {} {} {} {}" "{} {} {} {} {}"
...@@ -142,8 +144,9 @@ BENCHMARK_RELATIVE(bigFormat_format, iters) { ...@@ -142,8 +144,9 @@ BENCHMARK_RELATIVE(bigFormat_format, iters) {
while (iters--) { while (iters--) {
for (int i = -100; i < 100; i++) { for (int i = -100; i < 100; i++) {
p = bigBuf.data(); p = bigBuf.data();
suspender.dismissing( suspender.dismissing([&] {
[&] { format20Numbers(i, make_index_sequence<20>())(writeToBuf); }); format20Numbers(i, std::make_index_sequence<20>())(writeToBuf);
});
} }
} }
} }
......
...@@ -90,28 +90,6 @@ TEST_F(UtilityTest, forward_like) { ...@@ -90,28 +90,6 @@ TEST_F(UtilityTest, forward_like) {
EXPECT_EQ(&x, std::addressof(as_mutable(folly::forward_like<char const>(x)))); EXPECT_EQ(&x, std::addressof(as_mutable(folly::forward_like<char const>(x))));
} }
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());
// check our own implementation even when the builtin is available
using seq4 = typename folly::utility_detail::make_seq<5>::template apply<
folly::integer_sequence<int>,
folly::integer_sequence<int, 0>>;
EXPECT_EQ(5, seq4{}.size());
EXPECT_TRUE((std::is_same<seq4::value_type, int>::value));
using seq4_expected = folly::integer_sequence<int, 0, 1, 2, 3, 4>;
EXPECT_TRUE((std::is_same<seq4, seq4_expected>::value));
}
TEST_F(UtilityTest, MoveOnly) { TEST_F(UtilityTest, MoveOnly) {
class FooBar : folly::MoveOnly { class FooBar : folly::MoveOnly {
int a; int a;
......
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