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 @@
#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))...);
......
......@@ -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>{});
}
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
......
......@@ -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
}
......@@ -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());
}
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