169d5a666SChristopher Di Bella //===----------------------------------------------------------------------===// 269d5a666SChristopher Di Bella // 369d5a666SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 469d5a666SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 569d5a666SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 669d5a666SChristopher Di Bella // 769d5a666SChristopher Di Bella //===----------------------------------------------------------------------===// 869d5a666SChristopher Di Bella 969d5a666SChristopher Di Bella #ifndef _LIBCPP___UTILITY_INTEGER_SEQUENCE_H 1069d5a666SChristopher Di Bella #define _LIBCPP___UTILITY_INTEGER_SEQUENCE_H 1169d5a666SChristopher Di Bella 1269d5a666SChristopher Di Bella #include <__config> 13e99c4906SNikolas Klauser #include <__cstddef/size_t.h> 14947dfc95SNikolas Klauser #include <__type_traits/is_integral.h> 1569d5a666SChristopher Di Bella 1669d5a666SChristopher Di Bella #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1769d5a666SChristopher Di Bella # pragma GCC system_header 1869d5a666SChristopher Di Bella #endif 1969d5a666SChristopher Di Bella 2069d5a666SChristopher Di Bella _LIBCPP_BEGIN_NAMESPACE_STD 2169d5a666SChristopher Di Bella 229783f28cSLouis Dionne template <size_t...> 239783f28cSLouis Dionne struct __tuple_indices; 242d52c6bfSNikolas Klauser 252d52c6bfSNikolas Klauser template <class _IdxType, _IdxType... _Values> 262d52c6bfSNikolas Klauser struct __integer_sequence { 272d52c6bfSNikolas Klauser template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType> 28*f6958523SNikolas Klauser using __convert _LIBCPP_NODEBUG = _ToIndexSeq<_ToIndexType, _Values...>; 292d52c6bfSNikolas Klauser 302d52c6bfSNikolas Klauser template <size_t _Sp> 31*f6958523SNikolas Klauser using __to_tuple_indices _LIBCPP_NODEBUG = __tuple_indices<(_Values + _Sp)...>; 322d52c6bfSNikolas Klauser }; 332d52c6bfSNikolas Klauser 342d52c6bfSNikolas Klauser #if __has_builtin(__make_integer_seq) 352d52c6bfSNikolas Klauser template <size_t _Ep, size_t _Sp> 36*f6958523SNikolas Klauser using __make_indices_imp _LIBCPP_NODEBUG = 379783f28cSLouis Dionne typename __make_integer_seq<__integer_sequence, size_t, _Ep - _Sp>::template __to_tuple_indices<_Sp>; 3821c7bc51SNikolas Klauser #elif __has_builtin(__integer_pack) 392d52c6bfSNikolas Klauser template <size_t _Ep, size_t _Sp> 40*f6958523SNikolas Klauser using __make_indices_imp _LIBCPP_NODEBUG = 4121c7bc51SNikolas Klauser typename __integer_sequence<size_t, __integer_pack(_Ep - _Sp)...>::template __to_tuple_indices<_Sp>; 4221c7bc51SNikolas Klauser #else 4321c7bc51SNikolas Klauser # error "No known way to get an integer pack from the compiler" 442d52c6bfSNikolas Klauser #endif 452d52c6bfSNikolas Klauser 464f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 14 4769d5a666SChristopher Di Bella 4869d5a666SChristopher Di Bella template <class _Tp, _Tp... _Ip> 499783f28cSLouis Dionne struct _LIBCPP_TEMPLATE_VIS integer_sequence { 5069d5a666SChristopher Di Bella typedef _Tp value_type; 519783f28cSLouis Dionne static_assert(is_integral<_Tp>::value, "std::integer_sequence can only be instantiated with an integral type"); 529783f28cSLouis Dionne static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return sizeof...(_Ip); } 5369d5a666SChristopher Di Bella }; 5469d5a666SChristopher Di Bella 5569d5a666SChristopher Di Bella template <size_t... _Ip> 5669d5a666SChristopher Di Bella using index_sequence = integer_sequence<size_t, _Ip...>; 5769d5a666SChristopher Di Bella 5821c7bc51SNikolas Klauser # if __has_builtin(__make_integer_seq) 5969d5a666SChristopher Di Bella 6069d5a666SChristopher Di Bella template <class _Tp, _Tp _Ep> 6121c7bc51SNikolas Klauser using make_integer_sequence _LIBCPP_NODEBUG = __make_integer_seq<integer_sequence, _Tp, _Ep>; 6221c7bc51SNikolas Klauser 6321c7bc51SNikolas Klauser # elif __has_builtin(__integer_pack) 6421c7bc51SNikolas Klauser 6521c7bc51SNikolas Klauser template <class _Tp, _Tp _SequenceSize> 6621c7bc51SNikolas Klauser using make_integer_sequence _LIBCPP_NODEBUG = integer_sequence<_Tp, __integer_pack(_SequenceSize)...>; 6769d5a666SChristopher Di Bella 6869d5a666SChristopher Di Bella # else 6921c7bc51SNikolas Klauser # error "No known way to get an integer pack from the compiler" 7069d5a666SChristopher Di Bella # endif 7169d5a666SChristopher Di Bella 7269d5a666SChristopher Di Bella template <size_t _Np> 7369d5a666SChristopher Di Bella using make_index_sequence = make_integer_sequence<size_t, _Np>; 7469d5a666SChristopher Di Bella 7569d5a666SChristopher Di Bella template <class... _Tp> 7669d5a666SChristopher Di Bella using index_sequence_for = make_index_sequence<sizeof...(_Tp)>; 7769d5a666SChristopher Di Bella 784f15267dSNikolas Klauser # if _LIBCPP_STD_VER >= 20 79eb6e13cbSMark de Wever // Executes __func for every element in an index_sequence. 80eb6e13cbSMark de Wever template <size_t... _Index, class _Function> 81eb6e13cbSMark de Wever _LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_Index...>, _Function __func) { 82eb6e13cbSMark de Wever (__func.template operator()<_Index>(), ...); 83eb6e13cbSMark de Wever } 844f15267dSNikolas Klauser # endif // _LIBCPP_STD_VER >= 20 85eb6e13cbSMark de Wever 864f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 14 8769d5a666SChristopher Di Bella 8869d5a666SChristopher Di Bella _LIBCPP_END_NAMESPACE_STD 8969d5a666SChristopher Di Bella 9069d5a666SChristopher Di Bella #endif // _LIBCPP___UTILITY_INTEGER_SEQUENCE_H 91