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:
parent
eafd2a91bb
commit
c96d8845be
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user