Fix the O(n^2) instationation of the internal tuple.

This change vastly improves the compilation time, and memory consumption.
This commit is contained in:
Hosein Ghahramanzadeh 2019-08-03 22:47:00 +04:30
parent eafd2a91bb
commit c96d8845be

View File

@ -1148,30 +1148,39 @@ struct ElemFromList {
static_cast<T (*)()>(nullptr)...)); static_cast<T (*)()>(nullptr)...));
}; };
template <typename... T> template <typename T, std::size_t I>
class FlatTuple; struct FlatTupleElem {
T value;
FlatTupleElem() : value() {}
template <typename Derived, size_t I> template <typename Arg>
struct FlatTupleElemBase; explicit FlatTupleElem(Arg &&arg) : value(std::forward<Arg>(arg)) {}
template <typename... T, size_t I>
struct FlatTupleElemBase<FlatTuple<T...>, I> {
using value_type = typename ElemFromList<I, T...>::type;
FlatTupleElemBase() = default;
explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {}
value_type value;
}; };
template <typename Derived, typename Idx> template <typename IndexSeq, typename... Ts>
struct FlatTupleBase; class FlatTupleBase;
template <size_t... Idx, typename... T> template <std::size_t... Is, typename... Ts>
struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>> class FlatTupleBase<IndexSequence<Is...>, Ts...>
: FlatTupleElemBase<FlatTuple<T...>, Idx>... { : FlatTupleElem<Ts, Is>... {
using Indices = IndexSequence<Idx...>; public:
FlatTupleBase() = default; FlatTupleBase() {}
explicit FlatTupleBase(T... t)
: FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {} template <typename... Args>
explicit FlatTupleBase(Args&&... args)
: FlatTupleElem<Ts, Is>(std::forward<Args>(args))... {}
template <std::size_t I>
const typename ElemFromList<I, Ts...>::type& Get() const {
return static_cast<const FlatTupleElem<
typename ElemFromList<I, Ts...>::type, I>*>(this)->value;
}
template <std::size_t I>
typename ElemFromList<I, Ts...>::type& Get() {
return static_cast<FlatTupleElem<typename ElemFromList<I, Ts...>::type,
I>*>(this)->value;
}
}; };
// Analog to std::tuple but with different tradeoffs. // Analog to std::tuple but with different tradeoffs.
@ -1183,25 +1192,16 @@ struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
// regardless of T... // regardless of T...
// MakeIndexSequence, on the other hand, it is recursive but with an // MakeIndexSequence, on the other hand, it is recursive but with an
// instantiation depth of O(ln(N)). // instantiation depth of O(ln(N)).
template <typename... T>
class FlatTuple
: private FlatTupleBase<FlatTuple<T...>,
typename MakeIndexSequence<sizeof...(T)>::type> {
using Indices = typename FlatTuple::FlatTupleBase::Indices;
public: template <typename... Ts>
FlatTuple() = default; struct FlatTuple
explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {} : FlatTupleBase<typename MakeIndexSequence<sizeof...(Ts)>::type, Ts...> {
FlatTuple() {}
template <size_t I> template <typename... Args>
const typename ElemFromList<I, T...>::type& Get() const { explicit FlatTuple(Args&&... args)
return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value; : FlatTupleBase<typename MakeIndexSequence<sizeof...(Ts)>::type, Ts...>(
} std::forward<Args>(args)...){}
template <size_t I>
typename ElemFromList<I, T...>::type& Get() {
return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
}
}; };
// Utility functions to be called with static_assert to induce deprecation // Utility functions to be called with static_assert to induce deprecation