diff options
Diffstat (limited to 'libcxx/include/__utility/integer_sequence.h')
| -rw-r--r-- | libcxx/include/__utility/integer_sequence.h | 77 | 
1 files changed, 76 insertions, 1 deletions
| diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h index 633f1333e247..257b4301c086 100644 --- a/libcxx/include/__utility/integer_sequence.h +++ b/libcxx/include/__utility/integer_sequence.h @@ -10,7 +10,8 @@  #define _LIBCPP___UTILITY_INTEGER_SEQUENCE_H  #include <__config> -#include <type_traits> +#include <__type_traits/is_integral.h> +#include <cstddef>  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)  #  pragma GCC system_header @@ -18,6 +19,72 @@  _LIBCPP_BEGIN_NAMESPACE_STD +template <size_t...> struct __tuple_indices; + +template <class _IdxType, _IdxType... _Values> +struct __integer_sequence { +  template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType> +  using __convert = _ToIndexSeq<_ToIndexType, _Values...>; + +  template <size_t _Sp> +  using __to_tuple_indices = __tuple_indices<(_Values + _Sp)...>; +}; + +#if !__has_builtin(__make_integer_seq) || defined(_LIBCPP_TESTING_FALLBACK_MAKE_INTEGER_SEQUENCE) + +namespace __detail { + +template<typename _Tp, size_t ..._Extra> struct __repeat; +template<typename _Tp, _Tp ..._Np, size_t ..._Extra> struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...> { +  typedef _LIBCPP_NODEBUG __integer_sequence<_Tp, +                           _Np..., +                           sizeof...(_Np) + _Np..., +                           2 * sizeof...(_Np) + _Np..., +                           3 * sizeof...(_Np) + _Np..., +                           4 * sizeof...(_Np) + _Np..., +                           5 * sizeof...(_Np) + _Np..., +                           6 * sizeof...(_Np) + _Np..., +                           7 * sizeof...(_Np) + _Np..., +                           _Extra...> type; +}; + +template<size_t _Np> struct __parity; +template<size_t _Np> struct __make : __parity<_Np % 8>::template __pmake<_Np> {}; + +template<> struct __make<0> { typedef __integer_sequence<size_t> type; }; +template<> struct __make<1> { typedef __integer_sequence<size_t, 0> type; }; +template<> struct __make<2> { typedef __integer_sequence<size_t, 0, 1> type; }; +template<> struct __make<3> { typedef __integer_sequence<size_t, 0, 1, 2> type; }; +template<> struct __make<4> { typedef __integer_sequence<size_t, 0, 1, 2, 3> type; }; +template<> struct __make<5> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4> type; }; +template<> struct __make<6> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5> type; }; +template<> struct __make<7> { typedef __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6> type; }; + +template<> struct __parity<0> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type> {}; }; +template<> struct __parity<1> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1> {}; }; +template<> struct __parity<2> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<3> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<4> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<5> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<6> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; +template<> struct __parity<7> { template<size_t _Np> struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1> {}; }; + +} // namespace detail + +#endif + +#if __has_builtin(__make_integer_seq) +template <size_t _Ep, size_t _Sp> +using __make_indices_imp = +    typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template +    __to_tuple_indices<_Sp>; +#else +template <size_t _Ep, size_t _Sp> +using __make_indices_imp = +    typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>; + +#endif +  #if _LIBCPP_STD_VER > 11  template<class _Tp, _Tp... _Ip> @@ -71,6 +138,14 @@ template<size_t _Np>  template<class... _Tp>      using index_sequence_for = make_index_sequence<sizeof...(_Tp)>; +#  if _LIBCPP_STD_VER > 17 +// Executes __func for every element in an index_sequence. +template <size_t... _Index, class _Function> +_LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) { +    (__func.template operator()<_Index>(), ...); +} +#  endif // _LIBCPP_STD_VER > 17 +  #endif // _LIBCPP_STD_VER > 11  _LIBCPP_END_NAMESPACE_STD | 
