xref: /llvm-project/libcxx/include/__utility/integer_sequence.h (revision f69585235ec85d54e0f3fc41b2d5700430907f99)
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