aboutsummaryrefslogtreecommitdiff
path: root/include/EASTL/tuple.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/EASTL/tuple.h')
-rw-r--r--include/EASTL/tuple.h979
1 files changed, 0 insertions, 979 deletions
diff --git a/include/EASTL/tuple.h b/include/EASTL/tuple.h
deleted file mode 100644
index 3cbf644..0000000
--- a/include/EASTL/tuple.h
+++ /dev/null
@@ -1,979 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright (c) Electronic Arts Inc. All rights reserved.
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef EASTL_TUPLE_H
-#define EASTL_TUPLE_H
-
-#include <EASTL/internal/config.h>
-#include <EASTL/compare.h>
-#include <EASTL/functional.h>
-#include <EASTL/type_traits.h>
-#include <EASTL/utility.h>
-
-#include <EASTL/internal/tuple_fwd_decls.h>
-
-EA_DISABLE_VC_WARNING(4623) // warning C4623: default constructor was implicitly defined as deleted
-EA_DISABLE_VC_WARNING(4625) // warning C4625: copy constructor was implicitly defined as deleted
-EA_DISABLE_VC_WARNING(4510) // warning C4510: default constructor could not be generated
-
-#if EASTL_TUPLE_ENABLED
-
-namespace eastl
-{
-// non-recursive tuple implementation based on libc++ tuple implementation and description at
-// http://mitchnull.blogspot.ca/2012/06/c11-tuple-implementation-details-part-1.html
-
-// TupleTypes helper
-template <typename... Ts> struct TupleTypes {};
-
-// tuple_size helper
-template <typename T> class tuple_size {};
-template <typename T> class tuple_size<const T> : public tuple_size<T> {};
-template <typename T> class tuple_size<volatile T> : public tuple_size<T> {};
-template <typename T> class tuple_size<const volatile T> : public tuple_size<T> {};
-
-template <typename... Ts> class tuple_size<TupleTypes<Ts...>> : public integral_constant<size_t, sizeof...(Ts)> {};
-template <typename... Ts> class tuple_size<tuple<Ts...>> : public integral_constant<size_t, sizeof...(Ts)> {};
-
-#if EASTL_VARIABLE_TEMPLATES_ENABLED
- template <class T>
- EA_CONSTEXPR size_t tuple_size_v = tuple_size<T>::value;
-#endif
-
-namespace Internal
-{
- template <typename TupleIndices, typename... Ts>
- struct TupleImpl;
-} // namespace Internal
-
-template <typename Indices, typename... Ts>
-class tuple_size<Internal::TupleImpl<Indices, Ts...>> : public integral_constant<size_t, sizeof...(Ts)>
-{
-};
-
-// tuple_element helper to be able to isolate a type given an index
-template <size_t I, typename T>
-class tuple_element
-{
-};
-
-template <size_t I>
-class tuple_element<I, TupleTypes<>>
-{
-public:
- static_assert(I != I, "tuple_element index out of range");
-};
-
-template <typename H, typename... Ts>
-class tuple_element<0, TupleTypes<H, Ts...>>
-{
-public:
- typedef H type;
-};
-
-template <size_t I, typename H, typename... Ts>
-class tuple_element<I, TupleTypes<H, Ts...>>
-{
-public:
- typedef tuple_element_t<I - 1, TupleTypes<Ts...>> type;
-};
-
-// specialization for tuple
-template <size_t I, typename... Ts>
-class tuple_element<I, tuple<Ts...>>
-{
-public:
- typedef tuple_element_t<I, TupleTypes<Ts...>> type;
-};
-
-template <size_t I, typename... Ts>
-class tuple_element<I, const tuple<Ts...>>
-{
-public:
- typedef typename add_const<tuple_element_t<I, TupleTypes<Ts...>>>::type type;
-};
-
-template <size_t I, typename... Ts>
-class tuple_element<I, volatile tuple<Ts...>>
-{
-public:
- typedef typename add_volatile<tuple_element_t<I, TupleTypes<Ts...>>>::type type;
-};
-
-template <size_t I, typename... Ts>
-class tuple_element<I, const volatile tuple<Ts...>>
-{
-public:
- typedef typename add_cv<tuple_element_t<I, TupleTypes<Ts...>>>::type type;
-};
-
-// specialization for TupleImpl
-template <size_t I, typename Indices, typename... Ts>
-class tuple_element<I, Internal::TupleImpl<Indices, Ts...>> : public tuple_element<I, tuple<Ts...>>
-{
-};
-
-template <size_t I, typename Indices, typename... Ts>
-class tuple_element<I, const Internal::TupleImpl<Indices, Ts...>> : public tuple_element<I, const tuple<Ts...>>
-{
-};
-
-template <size_t I, typename Indices, typename... Ts>
-class tuple_element<I, volatile Internal::TupleImpl<Indices, Ts...>> : public tuple_element<I, volatile tuple<Ts...>>
-{
-};
-
-template <size_t I, typename Indices, typename... Ts>
-class tuple_element<I, const volatile Internal::TupleImpl<Indices, Ts...>> : public tuple_element<
- I, const volatile tuple<Ts...>>
-{
-};
-
-// attempt to isolate index given a type
-template <typename T, typename Tuple>
-struct tuple_index
-{
-};
-
-template <typename T>
-struct tuple_index<T, TupleTypes<>>
-{
- typedef void DuplicateTypeCheck;
- tuple_index() = delete; // tuple_index should only be used for compile-time assistance, and never be instantiated
- static const size_t index = 0;
-};
-
-template <typename T, typename... TsRest>
-struct tuple_index<T, TupleTypes<T, TsRest...>>
-{
- typedef int DuplicateTypeCheck;
- // after finding type T in the list of types, try to find type T in TsRest.
- // If we stumble back into this version of tuple_index, i.e. type T appears twice in the list of types, then DuplicateTypeCheck will be of type int, and the static_assert will fail.
- // If we don't, then we'll go through the version of tuple_index above, where all of the types have been exhausted, and DuplicateTypeCheck will be void.
- static_assert(is_void<typename tuple_index<T, TupleTypes<TsRest...>>::DuplicateTypeCheck>::value, "duplicate type T in tuple_vector::get<T>(); unique types must be provided in declaration, or only use get<size_t>()");
-
- static const size_t index = 0;
-};
-
-template <typename T, typename TsHead, typename... TsRest>
-struct tuple_index<T, TupleTypes<TsHead, TsRest...>>
-{
- typedef typename tuple_index<T, TupleTypes<TsRest...>>::DuplicateTypeCheck DuplicateTypeCheck;
- static const size_t index = tuple_index<T, TupleTypes<TsRest...>>::index + 1;
-};
-
-template <typename T, typename Indices, typename... Ts>
-struct tuple_index<T, Internal::TupleImpl<Indices, Ts...>> : public tuple_index<T, TupleTypes<Ts...>>
-{
-};
-
-
-namespace Internal
-{
- // swallow
- //
- // Provides a vessel to expand variadic packs.
- //
- template <typename... Ts>
- void swallow(Ts&&...) {}
-
-
- // TupleLeaf
- //
- template <size_t I, typename ValueType, bool IsEmpty = is_empty_v<ValueType>>
- class TupleLeaf;
-
- template <size_t I, typename ValueType, bool IsEmpty>
- inline void swap(TupleLeaf<I, ValueType, IsEmpty>& a, TupleLeaf<I, ValueType, IsEmpty>& b)
- {
- eastl::swap(a.getInternal(), b.getInternal());
- }
-
- template <size_t I, typename ValueType, bool IsEmpty>
- class TupleLeaf
- {
- public:
- TupleLeaf() : mValue() {}
- TupleLeaf(const TupleLeaf&) = default;
- TupleLeaf& operator=(const TupleLeaf&) = delete;
-
- // We shouldn't need this explicit constructor as it should be handled by the template below but OSX clang
- // is_constructible type trait incorrectly gives false for is_constructible<T&&, T&&>::value
- explicit TupleLeaf(ValueType&& v) : mValue(eastl::forward<ValueType>(v)) {}
-
- template <typename T, typename = typename enable_if<is_constructible<ValueType, T&&>::value>::type>
- explicit TupleLeaf(T&& t)
- : mValue(eastl::forward<T>(t))
- {
- }
-
- template <typename T>
- explicit TupleLeaf(const TupleLeaf<I, T>& t)
- : mValue(t.getInternal())
- {
- }
-
- template <typename T>
- TupleLeaf& operator=(T&& t)
- {
- mValue = eastl::forward<T>(t);
- return *this;
- }
-
- int swap(TupleLeaf& t)
- {
- eastl::Internal::swap(*this, t);
- return 0;
- }
-
- ValueType& getInternal() { return mValue; }
- const ValueType& getInternal() const { return mValue; }
-
- private:
- ValueType mValue;
- };
-
- // TupleLeaf: partial specialization for when we can use the Empty Base Class Optimization
- template <size_t I, typename ValueType>
- class TupleLeaf<I, ValueType, true> : private ValueType
- {
- public:
- // true_type / false_type constructors for case where ValueType is default constructible and should be value
- // initialized and case where it is not
- TupleLeaf(const TupleLeaf&) = default;
-
- template <typename T, typename = typename enable_if<is_constructible<ValueType, T&&>::value>::type>
- explicit TupleLeaf(T&& t)
- : ValueType(eastl::forward<T>(t))
- {
- }
-
- template <typename T>
- explicit TupleLeaf(const TupleLeaf<I, T>& t)
- : ValueType(t.getInternal())
- {
- }
-
- template <typename T>
- TupleLeaf& operator=(T&& t)
- {
- ValueType::operator=(eastl::forward<T>(t));
- return *this;
- }
-
- int swap(TupleLeaf& t)
- {
- eastl::Internal::swap(*this, t);
- return 0;
- }
-
- ValueType& getInternal() { return static_cast<ValueType&>(*this); }
- const ValueType& getInternal() const { return static_cast<const ValueType&>(*this); }
-
- private:
- TupleLeaf& operator=(const TupleLeaf&) = delete;
- };
-
-
-
- // MakeTupleTypes
- //
- //
- template <typename TupleTypes, typename Tuple, size_t Start, size_t End>
- struct MakeTupleTypesImpl;
-
- template <typename... Types, typename Tuple, size_t Start, size_t End>
- struct MakeTupleTypesImpl<TupleTypes<Types...>, Tuple, Start, End>
- {
- typedef typename remove_reference<Tuple>::type TupleType;
- typedef typename MakeTupleTypesImpl<
- TupleTypes<Types..., typename conditional<is_lvalue_reference<Tuple>::value,
- // append ref if Tuple is ref
- tuple_element_t<Start, TupleType>&,
- // append non-ref otherwise
- tuple_element_t<Start, TupleType>>::type>,
- Tuple, Start + 1, End>::type type;
- };
-
- template <typename... Types, typename Tuple, size_t End>
- struct MakeTupleTypesImpl<TupleTypes<Types...>, Tuple, End, End>
- {
- typedef TupleTypes<Types...> type;
- };
-
- template <typename Tuple>
- using MakeTupleTypes_t = typename MakeTupleTypesImpl<TupleTypes<>, Tuple, 0,
- tuple_size<typename remove_reference<Tuple>::type>::value>::type;
-
-
- // TupleImpl
- //
- //
- template <size_t I, typename Indices, typename... Ts>
- tuple_element_t<I, TupleImpl<Indices, Ts...>>& get(TupleImpl<Indices, Ts...>& t);
-
- template <size_t I, typename Indices, typename... Ts>
- const_tuple_element_t<I, TupleImpl<Indices, Ts...>>& get(const TupleImpl<Indices, Ts...>& t);
-
- template <size_t I, typename Indices, typename... Ts>
- tuple_element_t<I, TupleImpl<Indices, Ts...>>&& get(TupleImpl<Indices, Ts...>&& t);
-
- template <typename T, typename Indices, typename... Ts>
- T& get(TupleImpl<Indices, Ts...>& t);
-
- template <typename T, typename Indices, typename... Ts>
- const T& get(const TupleImpl<Indices, Ts...>& t);
-
- template <typename T, typename Indices, typename... Ts>
- T&& get(TupleImpl<Indices, Ts...>&& t);
-
- template <size_t... Indices, typename... Ts>
- struct TupleImpl<integer_sequence<size_t, Indices...>, Ts...> : public TupleLeaf<Indices, Ts>...
- {
- EA_CONSTEXPR TupleImpl() = default;
-
- // index_sequence changed to integer_sequence due to issues described below in VS2015 CTP 6.
- // https://connect.microsoft.com/VisualStudio/feedback/details/1126958/error-in-template-parameter-pack-expansion-of-std-index-sequence
- //
- template <typename... Us, typename... ValueTypes>
- explicit TupleImpl(integer_sequence<size_t, Indices...>, TupleTypes<Us...>, ValueTypes&&... values)
- : TupleLeaf<Indices, Ts>(eastl::forward<ValueTypes>(values))...
- {
- }
-
- template <typename OtherTuple>
- TupleImpl(OtherTuple&& t)
- : TupleLeaf<Indices, Ts>(eastl::forward<tuple_element_t<Indices, MakeTupleTypes_t<OtherTuple>>>(get<Indices>(t)))...
- {
- }
-
- template <typename OtherTuple>
- TupleImpl& operator=(OtherTuple&& t)
- {
- swallow(TupleLeaf<Indices, Ts>::operator=(
- eastl::forward<tuple_element_t<Indices, MakeTupleTypes_t<OtherTuple>>>(get<Indices>(t)))...);
- return *this;
- }
-
- TupleImpl& operator=(const TupleImpl& t)
- {
- swallow(TupleLeaf<Indices, Ts>::operator=(static_cast<const TupleLeaf<Indices, Ts>&>(t).getInternal())...);
- return *this;
- }
-
- void swap(TupleImpl& t) { swallow(TupleLeaf<Indices, Ts>::swap(static_cast<TupleLeaf<Indices, Ts>&>(t))...); }
- };
-
- template <size_t I, typename Indices, typename... Ts>
- inline tuple_element_t<I, TupleImpl<Indices, Ts...>>& get(TupleImpl<Indices, Ts...>& t)
- {
- typedef tuple_element_t<I, TupleImpl<Indices, Ts...>> Type;
- return static_cast<Internal::TupleLeaf<I, Type>&>(t).getInternal();
- }
-
- template <size_t I, typename Indices, typename... Ts>
- inline const_tuple_element_t<I, TupleImpl<Indices, Ts...>>& get(const TupleImpl<Indices, Ts...>& t)
- {
- typedef tuple_element_t<I, TupleImpl<Indices, Ts...>> Type;
- return static_cast<const Internal::TupleLeaf<I, Type>&>(t).getInternal();
- }
-
- template <size_t I, typename Indices, typename... Ts>
- inline tuple_element_t<I, TupleImpl<Indices, Ts...>>&& get(TupleImpl<Indices, Ts...>&& t)
- {
- typedef tuple_element_t<I, TupleImpl<Indices, Ts...>> Type;
- return static_cast<Type&&>(static_cast<Internal::TupleLeaf<I, Type>&>(t).getInternal());
- }
-
- template <typename T, typename Indices, typename... Ts>
- inline T& get(TupleImpl<Indices, Ts...>& t)
- {
- typedef tuple_index<T, TupleImpl<Indices, Ts...>> Index;
- return static_cast<Internal::TupleLeaf<Index::index, T>&>(t).getInternal();
- }
-
- template <typename T, typename Indices, typename... Ts>
- inline const T& get(const TupleImpl<Indices, Ts...>& t)
- {
- typedef tuple_index<T, TupleImpl<Indices, Ts...>> Index;
- return static_cast<const Internal::TupleLeaf<Index::index, T>&>(t).getInternal();
- }
-
- template <typename T, typename Indices, typename... Ts>
- inline T&& get(TupleImpl<Indices, Ts...>&& t)
- {
- typedef tuple_index<T, TupleImpl<Indices, Ts...>> Index;
- return static_cast<T&&>(static_cast<Internal::TupleLeaf<Index::index, T>&>(t).getInternal());
- }
-
-
- // TupleLike
- //
- // type-trait that determines if a type is an eastl::tuple or an eastl::pair.
- //
- template <typename T> struct TupleLike : public false_type {};
- template <typename T> struct TupleLike<const T> : public TupleLike<T> {};
- template <typename T> struct TupleLike<volatile T> : public TupleLike<T> {};
- template <typename T> struct TupleLike<const volatile T> : public TupleLike<T> {};
-
- template <typename... Ts>
- struct TupleLike<tuple<Ts...>> : public true_type {};
-
- template <typename First, typename Second>
- struct TupleLike<eastl::pair<First, Second>> : public true_type {};
-
-
- // TupleConvertible
- //
- //
- //
- template <bool IsSameSize, typename From, typename To>
- struct TupleConvertibleImpl : public false_type
- {
- };
-
- template <typename... FromTypes, typename... ToTypes>
- struct TupleConvertibleImpl<true, TupleTypes<FromTypes...>, TupleTypes<ToTypes...>>
- : public integral_constant<bool, conjunction<is_convertible<FromTypes, ToTypes>...>::value>
- {
- };
-
- template <typename From, typename To,
- bool = TupleLike<typename remove_reference<From>::type>::value,
- bool = TupleLike<typename remove_reference<To>::type>::value>
- struct TupleConvertible : public false_type
- {
- };
-
- template <typename From, typename To>
- struct TupleConvertible<From, To, true, true>
- : public TupleConvertibleImpl<tuple_size<typename remove_reference<From>::type>::value ==
- tuple_size<typename remove_reference<To>::type>::value,
- MakeTupleTypes_t<From>, MakeTupleTypes_t<To>>
- {
- };
-
-
- // TupleAssignable
- //
- //
- //
- template <bool IsSameSize, typename Target, typename From>
- struct TupleAssignableImpl : public false_type
- {
- };
-
- template <typename... TargetTypes, typename... FromTypes>
- struct TupleAssignableImpl<true, TupleTypes<TargetTypes...>, TupleTypes<FromTypes...>>
- : public bool_constant<conjunction<is_assignable<TargetTypes, FromTypes>...>::value>
- {
- };
-
- template <typename Target, typename From,
- bool = TupleLike<typename remove_reference<Target>::type>::value,
- bool = TupleLike<typename remove_reference<From>::type>::value>
- struct TupleAssignable : public false_type
- {
- };
-
- template <typename Target, typename From>
- struct TupleAssignable<Target, From, true, true>
- : public TupleAssignableImpl<
- tuple_size<typename remove_reference<Target>::type>::value ==
- tuple_size<typename remove_reference<From>::type>::value,
- MakeTupleTypes_t<Target>, MakeTupleTypes_t<From>>
- {
- };
-
-
- // TupleImplicitlyConvertible and TupleExplicitlyConvertible
- //
- // helpers for constraining conditionally-explicit ctors
- //
- template <bool IsSameSize, typename TargetType, typename... FromTypes>
- struct TupleImplicitlyConvertibleImpl : public false_type
- {
- };
-
-
- template <typename... TargetTypes, typename... FromTypes>
- struct TupleImplicitlyConvertibleImpl<true, TupleTypes<TargetTypes...>, FromTypes...>
- : public conjunction<
- is_constructible<TargetTypes, FromTypes>...,
- is_convertible<FromTypes, TargetTypes>...>
- {
- };
-
- template <typename TargetTupleType, typename... FromTypes>
- struct TupleImplicitlyConvertible
- : public TupleImplicitlyConvertibleImpl<
- tuple_size<TargetTupleType>::value == sizeof...(FromTypes),
- MakeTupleTypes_t<TargetTupleType>, FromTypes...>::type
- {
- };
-
- template<typename TargetTupleType, typename... FromTypes>
- using TupleImplicitlyConvertible_t = enable_if_t<TupleImplicitlyConvertible<TargetTupleType, FromTypes...>::value, bool>;
-
- template <bool IsSameSize, typename TargetType, typename... FromTypes>
- struct TupleExplicitlyConvertibleImpl : public false_type
- {
- };
-
- template <typename... TargetTypes, typename... FromTypes>
- struct TupleExplicitlyConvertibleImpl<true, TupleTypes<TargetTypes...>, FromTypes...>
- : public conjunction<
- is_constructible<TargetTypes, FromTypes>...,
- negation<conjunction<is_convertible<FromTypes, TargetTypes>...>>>
- {
- };
-
- template <typename TargetTupleType, typename... FromTypes>
- struct TupleExplicitlyConvertible
- : public TupleExplicitlyConvertibleImpl<
- tuple_size<TargetTupleType>::value == sizeof...(FromTypes),
- MakeTupleTypes_t<TargetTupleType>, FromTypes...>::type
- {
- };
-
- template<typename TargetTupleType, typename... FromTypes>
- using TupleExplicitlyConvertible_t = enable_if_t<TupleExplicitlyConvertible<TargetTupleType, FromTypes...>::value, bool>;
-
-
- // TupleEqual
- //
- //
- //
- template <size_t I>
- struct TupleEqual
- {
- template <typename Tuple1, typename Tuple2>
- bool operator()(const Tuple1& t1, const Tuple2& t2)
- {
- static_assert(tuple_size<Tuple1>::value == tuple_size<Tuple2>::value, "comparing tuples of different sizes.");
- return TupleEqual<I - 1>()(t1, t2) && get<I - 1>(t1) == get<I - 1>(t2);
- }
- };
-
- template <>
- struct TupleEqual<0>
- {
- template <typename Tuple1, typename Tuple2>
- bool operator()(const Tuple1&, const Tuple2&)
- {
- return true;
- }
- };
-
- // TupleLess
- //
- //
- //
- template <size_t I>
- struct TupleLess
- {
- template <typename Tuple1, typename Tuple2>
- bool operator()(const Tuple1& t1, const Tuple2& t2)
- {
- static_assert(tuple_size<Tuple1>::value == tuple_size<Tuple2>::value, "comparing tuples of different sizes.");
- return TupleLess<I - 1>()(t1, t2) || (!TupleLess<I - 1>()(t2, t1) && get<I - 1>(t1) < get<I - 1>(t2));
- }
- };
-
- template <>
- struct TupleLess<0>
- {
- template <typename Tuple1, typename Tuple2>
- bool operator()(const Tuple1&, const Tuple2&)
- {
- return false;
- }
- };
-
-
- // MakeTupleReturnImpl
- //
- //
- //
- template <typename T> struct MakeTupleReturnImpl { typedef T type; };
- template <typename T> struct MakeTupleReturnImpl<reference_wrapper<T>> { typedef T& type; };
-
- template <typename T>
- using MakeTupleReturn_t = typename MakeTupleReturnImpl<decay_t<T>>::type;
-
-
- // tuple_cat helpers
- //
- //
- //
-
- // TupleCat2Impl
- template <typename Tuple1, typename Is1, typename Tuple2, typename Is2>
- struct TupleCat2Impl;
-
- template <typename... T1s, size_t... I1s, typename... T2s, size_t... I2s>
- struct TupleCat2Impl<tuple<T1s...>, index_sequence<I1s...>, tuple<T2s...>, index_sequence<I2s...>>
- {
- using ResultType = tuple<T1s..., T2s...>;
-
- template <typename Tuple1, typename Tuple2>
- static inline ResultType DoCat2(Tuple1&& t1, Tuple2&& t2)
- {
- return ResultType(get<I1s>(eastl::forward<Tuple1>(t1))..., get<I2s>(eastl::forward<Tuple2>(t2))...);
- }
- };
-
- // TupleCat2
- template <typename Tuple1, typename Tuple2>
- struct TupleCat2;
-
- template <typename... T1s, typename... T2s>
- struct TupleCat2<tuple<T1s...>, tuple<T2s...>>
- {
- using Is1 = make_index_sequence<sizeof...(T1s)>;
- using Is2 = make_index_sequence<sizeof...(T2s)>;
- using TCI = TupleCat2Impl<tuple<T1s...>, Is1, tuple<T2s...>, Is2>;
- using ResultType = typename TCI::ResultType;
-
- template <typename Tuple1, typename Tuple2>
- static inline ResultType DoCat2(Tuple1&& t1, Tuple2&& t2)
- {
- return TCI::DoCat2(eastl::forward<Tuple1>(t1), eastl::forward<Tuple2>(t2));
- }
- };
-
- // TupleCat
- template <typename... Tuples>
- struct TupleCat;
-
- template <typename Tuple1, typename Tuple2, typename... TuplesRest>
- struct TupleCat<Tuple1, Tuple2, TuplesRest...>
- {
- using FirstResultType = typename TupleCat2<Tuple1, Tuple2>::ResultType;
- using ResultType = typename TupleCat<FirstResultType, TuplesRest...>::ResultType;
-
- template <typename TupleArg1, typename TupleArg2, typename... TupleArgsRest>
- static inline ResultType DoCat(TupleArg1&& t1, TupleArg2&& t2, TupleArgsRest&&... ts)
- {
- return TupleCat<FirstResultType, TuplesRest...>::DoCat(
- TupleCat2<TupleArg1, TupleArg2>::DoCat2(eastl::forward<TupleArg1>(t1), eastl::forward<TupleArg2>(t2)),
- eastl::forward<TupleArgsRest>(ts)...);
- }
- };
-
- template <typename Tuple1, typename Tuple2>
- struct TupleCat<Tuple1, Tuple2>
- {
- using TC2 = TupleCat2<Tuple1, remove_reference_t<Tuple2>>;
- using ResultType = typename TC2::ResultType;
-
- template <typename TupleArg1, typename TupleArg2>
- static inline ResultType DoCat(TupleArg1&& t1, TupleArg2&& t2)
- {
- return TC2::DoCat2(eastl::forward<TupleArg1>(t1), eastl::forward<TupleArg2>(t2));
- }
- };
-
-#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
- template <typename... T1s, typename... T2s, size_t... Is>
- constexpr auto TupleThreeWay(const tuple<T1s...>& t1, const tuple<T2s...>& t2, index_sequence<Is...> is)
- {
- std::common_comparison_category_t<synth_three_way_result<T1s, T2s>...> result = std::strong_ordering::equal;
- ((result = synth_three_way{}(get<Is>(t1), get<Is>(t2)), result != 0) || ...);
- return result;
- }
-#endif
-} // namespace Internal
-
-
-
-// tuple
-//
-// eastl::tuple is a fixed-size container of heterogeneous values. It is a
-// generalization of eastl::pair which hold only two heterogeneous values.
-//
-// https://en.cppreference.com/w/cpp/utility/tuple
-//
-template <typename... Ts>
-class tuple;
-
-template <typename T, typename... Ts>
-class tuple<T, Ts...>
-{
-public:
- EA_CONSTEXPR tuple() = default;
-
- template <typename T2 = T,
- Internal::TupleImplicitlyConvertible_t<tuple, const T2&, const Ts&...> = 0>
- EA_CONSTEXPR tuple(const T& t, const Ts&... ts)
- : mImpl(make_index_sequence<sizeof...(Ts) + 1>{}, Internal::MakeTupleTypes_t<tuple>{}, t, ts...)
- {
- }
-
- template <typename T2 = T,
- Internal::TupleExplicitlyConvertible_t<tuple, const T2&, const Ts&...> = 0>
- explicit EA_CONSTEXPR tuple(const T& t, const Ts&... ts)
- : mImpl(make_index_sequence<sizeof...(Ts) + 1>{}, Internal::MakeTupleTypes_t<tuple>{}, t, ts...)
- {
- }
-
- template <typename U, typename... Us,
- Internal::TupleImplicitlyConvertible_t<tuple, U, Us...> = 0>
- EA_CONSTEXPR tuple(U&& u, Us&&... us)
- : mImpl(make_index_sequence<sizeof...(Us) + 1>{}, Internal::MakeTupleTypes_t<tuple>{}, eastl::forward<U>(u),
- eastl::forward<Us>(us)...)
- {
- }
-
- template <typename U, typename... Us,
- Internal::TupleExplicitlyConvertible_t<tuple, U, Us...> = 0>
- explicit EA_CONSTEXPR tuple(U&& u, Us&&... us)
- : mImpl(make_index_sequence<sizeof...(Us) + 1>{}, Internal::MakeTupleTypes_t<tuple>{}, eastl::forward<U>(u),
- eastl::forward<Us>(us)...)
- {
- }
-
- template <typename OtherTuple,
- typename enable_if<Internal::TupleConvertible<OtherTuple, tuple>::value, bool>::type = false>
- tuple(OtherTuple&& t)
- : mImpl(eastl::forward<OtherTuple>(t))
- {
- }
-
- template <typename OtherTuple,
- typename enable_if<Internal::TupleAssignable<tuple, OtherTuple>::value, bool>::type = false>
- tuple& operator=(OtherTuple&& t)
- {
- mImpl.operator=(eastl::forward<OtherTuple>(t));
- return *this;
- }
-
- void swap(tuple& t) { mImpl.swap(t.mImpl); }
-
-private:
- typedef Internal::TupleImpl<make_index_sequence<sizeof...(Ts) + 1>, T, Ts...> Impl;
- Impl mImpl;
-
- template <size_t I, typename... Ts_>
- friend tuple_element_t<I, tuple<Ts_...>>& get(tuple<Ts_...>& t);
-
- template <size_t I, typename... Ts_>
- friend const_tuple_element_t<I, tuple<Ts_...>>& get(const tuple<Ts_...>& t);
-
- template <size_t I, typename... Ts_>
- friend tuple_element_t<I, tuple<Ts_...>>&& get(tuple<Ts_...>&& t);
-
- template <typename T_, typename... ts_>
- friend T_& get(tuple<ts_...>& t);
-
- template <typename T_, typename... ts_>
- friend const T_& get(const tuple<ts_...>& t);
-
- template <typename T_, typename... ts_>
- friend T_&& get(tuple<ts_...>&& t);
-};
-
-// template specialization for an empty tuple
-template <>
-class tuple<>
-{
-public:
- void swap(tuple&) {}
-};
-
-template <size_t I, typename... Ts>
-inline tuple_element_t<I, tuple<Ts...>>& get(tuple<Ts...>& t)
-{
- return get<I>(t.mImpl);
-}
-
-template <size_t I, typename... Ts>
-inline const_tuple_element_t<I, tuple<Ts...>>& get(const tuple<Ts...>& t)
-{
- return get<I>(t.mImpl);
-}
-
-template <size_t I, typename... Ts>
-inline tuple_element_t<I, tuple<Ts...>>&& get(tuple<Ts...>&& t)
-{
- return get<I>(eastl::move(t.mImpl));
-}
-
-template <typename T, typename... Ts>
-inline T& get(tuple<Ts...>& t)
-{
- return get<T>(t.mImpl);
-}
-
-template <typename T, typename... Ts>
-inline const T& get(const tuple<Ts...>& t)
-{
- return get<T>(t.mImpl);
-}
-
-template <typename T, typename... Ts>
-inline T&& get(tuple<Ts...>&& t)
-{
- return get<T>(eastl::move(t.mImpl));
-}
-
-template <typename... Ts>
-inline void swap(tuple<Ts...>& a, tuple<Ts...>& b)
-{
- a.swap(b);
-}
-
-
-// tuple operators
-//
-//
-template <typename... T1s, typename... T2s>
-inline bool operator==(const tuple<T1s...>& t1, const tuple<T2s...>& t2)
-{
- return Internal::TupleEqual<sizeof...(T1s)>()(t1, t2);
-}
-
-#if defined(EA_COMPILER_HAS_THREE_WAY_COMPARISON)
-template <typename... T1s, typename... T2s>
-inline constexpr std::common_comparison_category_t<synth_three_way_result<T1s, T2s>...> operator<=>(const tuple<T1s...>& t1, const tuple<T2s...>& t2)
-{
- return Internal::TupleThreeWay(t1, t2, make_index_sequence<sizeof...(T1s)>{});
-}
-#else
-template <typename... T1s, typename... T2s>
-inline bool operator<(const tuple<T1s...>& t1, const tuple<T2s...>& t2)
-{
- return Internal::TupleLess<sizeof...(T1s)>()(t1, t2);
-}
-
-template <typename... T1s, typename... T2s> inline bool operator!=(const tuple<T1s...>& t1, const tuple<T2s...>& t2) { return !(t1 == t2); }
-template <typename... T1s, typename... T2s> inline bool operator> (const tuple<T1s...>& t1, const tuple<T2s...>& t2) { return t2 < t1; }
-template <typename... T1s, typename... T2s> inline bool operator<=(const tuple<T1s...>& t1, const tuple<T2s...>& t2) { return !(t2 < t1); }
-template <typename... T1s, typename... T2s> inline bool operator>=(const tuple<T1s...>& t1, const tuple<T2s...>& t2) { return !(t1 < t2); }
-#endif
-
-// tuple_cat
-//
-//
-template <typename... Tuples>
-inline typename Internal::TupleCat<Tuples...>::ResultType tuple_cat(Tuples&&... ts)
-{
- return Internal::TupleCat<Tuples...>::DoCat(eastl::forward<Tuples>(ts)...);
-}
-
-
-// make_tuple
-//
-//
-template <typename... Ts>
-inline EA_CONSTEXPR tuple<Internal::MakeTupleReturn_t<Ts>...> make_tuple(Ts&&... values)
-{
- return tuple<Internal::MakeTupleReturn_t<Ts>...>(eastl::forward<Ts>(values)...);
-}
-
-
-// forward_as_tuple
-//
-//
-template <typename... Ts>
-inline EA_CONSTEXPR tuple<Ts&&...> forward_as_tuple(Ts&&... ts) EA_NOEXCEPT
-{
- return tuple<Ts&&...>(eastl::forward<Ts&&>(ts)...);
-}
-
-
-// ignore
-//
-// An object of unspecified type such that any value can be assigned to it with no effect.
-//
-// https://en.cppreference.com/w/cpp/utility/tuple/ignore
-//
-namespace Internal
-{
- struct ignore_t
- {
- ignore_t() = default;
-
- template <typename T>
- const ignore_t& operator=(const T&) const
- {
- return *this;
- }
- };
-}// namespace Internal
-
-static const Internal::ignore_t ignore;
-
-
-// tie
-//
-// Creates a tuple of lvalue references to its arguments or instances of eastl::ignore.
-//
-// https://en.cppreference.com/w/cpp/utility/tuple/tie
-//
-template <typename... Ts>
-inline EA_CONSTEXPR tuple<Ts&...> tie(Ts&... ts) EA_NOEXCEPT
-{
- return tuple<Ts&...>(ts...);
-}
-
-
-// apply
-//
-// Invoke a callable object using a tuple to supply the arguments.
-//
-// http://en.cppreference.com/w/cpp/utility/apply
-//
-namespace detail
-{
- template <class F, class Tuple, size_t... I>
- EA_CONSTEXPR decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>)
- {
- return invoke(eastl::forward<F>(f), get<I>(eastl::forward<Tuple>(t))...);
- }
-} // namespace detail
-
-template <class F, class Tuple>
-EA_CONSTEXPR decltype(auto) apply(F&& f, Tuple&& t)
-{
- return detail::apply_impl(eastl::forward<F>(f), eastl::forward<Tuple>(t),
- make_index_sequence<tuple_size_v<remove_reference_t<Tuple>>>{});
-}
-
-} // namespace eastl
-
-
-///////////////////////////////////////////////////////////////
-// C++17 structured bindings support for eastl::tuple
-//
-#ifndef EA_COMPILER_NO_STRUCTURED_BINDING
- #include <tuple>
- namespace std
- {
- // NOTE(rparolin): Some platform implementations didn't check the standard specification and implemented the
- // "tuple_size" and "tuple_element" primary template with as a struct. The standard specifies they are
- // implemented with the class keyword so we provide the template specializations as a class and disable the
- // generated warning.
- EA_DISABLE_CLANG_WARNING(-Wmismatched-tags)
-
- template <class... Ts>
- class tuple_size<::eastl::tuple<Ts...>> : public ::eastl::integral_constant<size_t, sizeof...(Ts)>
- {
- };
-
- template <size_t I, class... Ts>
- class tuple_element<I, ::eastl::tuple<Ts...>> : public ::eastl::tuple_element<I, ::eastl::tuple<Ts...>>
- {
- };
-
- EA_RESTORE_CLANG_WARNING()
- }
-#endif
-
-
-#endif // EASTL_TUPLE_ENABLED
-EA_RESTORE_VC_WARNING()
-EA_RESTORE_VC_WARNING()
-EA_RESTORE_VC_WARNING()
-#endif // EASTL_TUPLE_H