Micro template library A library for building device drivers
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

idx_sequence.h 3.5 KiB

il y a 4 ans
il y a 4 ans
il y a 4 ans
il y a 4 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*!
  2. * \file pack.h
  3. * \brief Template meta-programming parameter pack container
  4. *
  5. * Copyright (C) 2018-2019 Christos Choutouridis
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation, either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef __utl_meta_idx_sequence_h__
  21. #define __utl_meta_idx_sequence_h__
  22. #include <utl/core/impl.h>
  23. #include <utl/meta/integral.h>
  24. /*!
  25. * \ingroup meta
  26. * \defgroup index_sequence
  27. */
  28. //! @{
  29. namespace utl {
  30. namespace meta {
  31. /*!
  32. * Class template integer_sequence
  33. */
  34. template<typename _Tp, _Tp... _Idx>
  35. struct integer_sequence {
  36. using value_type = _Tp;
  37. static constexpr size_t size() noexcept {
  38. return sizeof...(_Idx);
  39. }
  40. };
  41. //! Alias template index_sequence
  42. template<index_t... _Idx>
  43. using index_sequence = integer_sequence<index_t, _Idx...>;
  44. //! make_integer_sequence
  45. //! @{
  46. namespace detail {
  47. // Stores a tuple of indices
  48. template<size_t... Idxs> struct index_tuple { };
  49. // Concatenates two index_tuples.
  50. template<typename It1, typename It2> struct it_cat_;
  51. template<size_t... It1, size_t... It2>
  52. struct it_cat_ <index_tuple<It1...>, index_tuple<It2...>> {
  53. using type = index_tuple<It1..., (It2 + sizeof...(It1))...>;
  54. };
  55. // Builds an index_tuple<0, 1, 2, ..., _Num-1>.
  56. template<size_t _Num>
  57. struct make_index_tuple_
  58. : it_cat_<eval<make_index_tuple_<_Num / 2>>,
  59. eval<make_index_tuple_<_Num - _Num / 2>>>
  60. { };
  61. // termination specialization for 1
  62. template<>
  63. struct make_index_tuple_<1> {
  64. using type = index_tuple<0>;
  65. };
  66. // termination specialization for 0
  67. template<>
  68. struct make_index_tuple_<0> {
  69. using type = index_tuple<>;
  70. };
  71. // factory type
  72. template<typename _Tp, _Tp _Num,
  73. typename _ISeq = eval<make_index_tuple_<_Num>>>
  74. struct make_integer_sequence_;
  75. template<typename _Tp, _Tp _Num, size_t... _Idx>
  76. struct make_integer_sequence_<_Tp, _Num, index_tuple<_Idx...>> {
  77. static_assert( _Num >= 0,
  78. "Cannot make integer sequence of negative length" );
  79. using type = integer_sequence<_Tp, static_cast<_Tp>(_Idx)...>;
  80. };
  81. }
  82. //! Alias template make_integer_sequence
  83. //! Complexity \f$ O(log N) \f$
  84. template<typename _Tp, _Tp N>
  85. using make_integer_sequence = eval<detail::make_integer_sequence_<_Tp, N>>;
  86. //! Alias template make_index_sequence
  87. //! Complexity \f$ O(log N) \f$
  88. template<index_t N>
  89. using make_index_sequence = make_integer_sequence<index_t, N>;
  90. //! Alias template index_sequence_for
  91. //! Complexity \f$ O(log N) \f$
  92. //! where N is sizeof...(_Ts)
  93. template<typename... _Ts>
  94. using index_sequence_for = make_index_sequence<sizeof...(_Ts)>;
  95. //! @}
  96. }}
  97. //! @}
  98. #endif /* __utl_meta_idx_sequence_h__ */