Use a faster ElemFromList.

This commit is contained in:
Hosein Ghahramanzadeh 2019-10-11 21:54:11 +03:30
parent b180d8de00
commit c6225200d7

View File

@ -1124,9 +1124,25 @@ struct MakeIndexSequence
template <> template <>
struct MakeIndexSequence<0> : IndexSequence<> {}; struct MakeIndexSequence<0> : IndexSequence<> {};
template <size_t> template <std::size_t, typename T>
struct Ignore { struct ListElem {
Ignore(...); // NOLINT using type = T;
};
template <typename IndexSeq, typename... Ts>
struct ElemFromListImpl;
template <std::size_t... Is, typename... Ts>
struct ElemFromListImpl<IndexSequence<Is...>, Ts...> : ListElem<Is, Ts>... {};
template <std::size_t I, typename... Ts>
struct ElemFromList {
template <typename Type>
static Type get_type(const ListElem<I, Type>&);
using type = decltype(
get_type(ElemFromListImpl<typename MakeIndexSequence<sizeof...(Ts)>::type,
Ts...>()));
}; };
template <typename T> template <typename T>
@ -1154,37 +1170,10 @@ struct EnableIfAll
: EnableIfAllImpl<T, typename MakeIndexSequence<sizeof...(Cs)>::type, : EnableIfAllImpl<T, typename MakeIndexSequence<sizeof...(Cs)>::type,
Cs...> {}; Cs...> {};
template <std::size_t>
struct EmptyListElem {};
template <typename T>
struct ListElem {
using type = T;
};
template <typename>
struct ElemFromListImpl;
template <size_t... I>
struct ElemFromListImpl<IndexSequence<I...>> {
// We make Ignore a template to solve a problem with MSVC.
// A non-template Ignore would work fine with `decltype(Ignore(I))...`, but
// MSVC doesn't understand how to deal with that pack expansion.
// Use `0 * I` to have a single instantiation of Ignore.
template <typename R>
static R Apply(Ignore<0 * I>..., R (*)(), ...);
};
template <size_t N, typename... T>
struct ElemFromList {
using type =
decltype(ElemFromListImpl<typename MakeIndexSequence<N>::type>::Apply(
static_cast<T (*)()>(nullptr)...));
};
template <typename T, std::size_t I> template <typename T, std::size_t I>
struct FlatTupleElem { struct FlatTupleElem {
T value; T value;
FlatTupleElem() noexcept(std::is_nothrow_constructible<T>::value) : value() {} FlatTupleElem() = default;
template <typename Arg, typename = typename EnableIfAll< template <typename Arg, typename = typename EnableIfAll<
void, std::is_constructible<T, Arg>::value>::type> void, std::is_constructible<T, Arg>::value>::type>
@ -1192,12 +1181,11 @@ struct FlatTupleElem {
}; };
template <typename IndexSeq, typename... Ts> template <typename IndexSeq, typename... Ts>
class FlatTupleBase; struct FlatTupleBase;
template <std::size_t... Is, typename... Ts> template <std::size_t... Is, typename... Ts>
class FlatTupleBase<IndexSequence<Is...>, Ts...> : FlatTupleElem<Ts, Is>... { struct FlatTupleBase<IndexSequence<Is...>, Ts...> : FlatTupleElem<Ts, Is>... {
public: FlatTupleBase() = default;
FlatTupleBase() {}
template <typename... Args, template <typename... Args,
typename = typename EnableIfAll< typename = typename EnableIfAll<
@ -1251,8 +1239,7 @@ class FlatTupleBase<IndexSequence<Is...>, Ts...> : FlatTupleElem<Ts, Is>... {
template <typename... Ts> template <typename... Ts>
struct FlatTuple struct FlatTuple
: FlatTupleBase<typename MakeIndexSequence<sizeof...(Ts)>::type, Ts...> { : FlatTupleBase<typename MakeIndexSequence<sizeof...(Ts)>::type, Ts...> {
FlatTuple() {} FlatTuple() = default;
template < template <
typename... Args, typename... Args,
typename = typename EnableIfAll< typename = typename EnableIfAll<