1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_COMMON_INDICES_HH
5 #define DUNE_COMMON_INDICES_HH
6 
7 #include <cstddef>
8 #include <type_traits>
9 #include <utility>
10 
11 #include <dune/common/keywords.hh>
12 
13 namespace Dune
14 {
15   /** \addtogroup Common
16    *  \{
17    */
18 
19   /** \brief An index constant with value i
20    *
21    * An index constant is a simple type alias for an integral_constant.
22    * Its main advantages are clarity (it is easier to see that code uses it
23    * as an index) and the fact that the integral type is fixed, reducing verbosity
24    * and avoiding the problem of maybe trying to overload / specialize using a different
25    * integral type.
26    */
27   template<std::size_t i>
28   using index_constant = std::integral_constant<std::size_t, i>;
29 
30 
31 
32   /** \brief Namespace with predefined compile time indices for the range [0,19]
33    *
34    * The predefined index objects in this namespace are `constexpr`, which allows them to
35    * be used in situations where a compile time constant is needed, e.g. for a template
36    * parameter. Apart from that, `constexpr` implies internal linkage, which helps to avoid
37    * ODR problems.
38    *
39    * The constants implicitly convert to their contained value, so you can for example write
40    *
41    * \code{.cc}
42    * std::array<int,_10> a;
43    * // the above line is equivalent to
44    * std::array<int,10> b;
45    * \endcode
46    *
47    */
48   namespace Indices
49   {
50     //! Compile time index with value 0.
51     DUNE_INLINE_VARIABLE constexpr index_constant< 0>  _0 = {};
52 
53     //! Compile time index with value 1.
54     DUNE_INLINE_VARIABLE constexpr index_constant< 1>  _1 = {};
55 
56     //! Compile time index with value 2.
57     DUNE_INLINE_VARIABLE constexpr index_constant< 2>  _2 = {};
58 
59     //! Compile time index with value 3.
60     DUNE_INLINE_VARIABLE constexpr index_constant< 3>  _3 = {};
61 
62     //! Compile time index with value 4.
63     DUNE_INLINE_VARIABLE constexpr index_constant< 4>  _4 = {};
64 
65     //! Compile time index with value 5.
66     DUNE_INLINE_VARIABLE constexpr index_constant< 5>  _5 = {};
67 
68     //! Compile time index with value 6.
69     DUNE_INLINE_VARIABLE constexpr index_constant< 6>  _6 = {};
70 
71     //! Compile time index with value 7.
72     DUNE_INLINE_VARIABLE constexpr index_constant< 7>  _7 = {};
73 
74     //! Compile time index with value 8.
75     DUNE_INLINE_VARIABLE constexpr index_constant< 8>  _8 = {};
76 
77     //! Compile time index with value 9.
78     DUNE_INLINE_VARIABLE constexpr index_constant< 9>  _9 = {};
79 
80     //! Compile time index with value 10.
81     DUNE_INLINE_VARIABLE constexpr index_constant<10> _10 = {};
82 
83     //! Compile time index with value 11.
84     DUNE_INLINE_VARIABLE constexpr index_constant<11> _11 = {};
85 
86     //! Compile time index with value 12.
87     DUNE_INLINE_VARIABLE constexpr index_constant<12> _12 = {};
88 
89     //! Compile time index with value 13.
90     DUNE_INLINE_VARIABLE constexpr index_constant<13> _13 = {};
91 
92     //! Compile time index with value 14.
93     DUNE_INLINE_VARIABLE constexpr index_constant<14> _14 = {};
94 
95     //! Compile time index with value 15.
96     DUNE_INLINE_VARIABLE constexpr index_constant<15> _15 = {};
97 
98     //! Compile time index with value 16.
99     DUNE_INLINE_VARIABLE constexpr index_constant<16> _16 = {};
100 
101     //! Compile time index with value 17.
102     DUNE_INLINE_VARIABLE constexpr index_constant<17> _17 = {};
103 
104     //! Compile time index with value 18.
105     DUNE_INLINE_VARIABLE constexpr index_constant<18> _18 = {};
106 
107     //! Compile time index with value 19.
108     DUNE_INLINE_VARIABLE constexpr index_constant<19> _19 = {};
109 
110   } // namespace Indices
111 
112   /**
113    * \brief Unpack an std::integer_sequence<I,i...> to std::integral_constant<I,i>...
114    *
115    * This forward all entries of the given std::integer_sequence
116    * as individual std::integral_constant arguments to the given callback.
117    *
118    * \param f Callback which has to accept unpacked values
119    * \param sequence Packed std::integer_sequence of values
120    * \returns Result of calling f with unpacked integers.
121    */
122   template<class F, class I, I... i>
unpackIntegerSequence(F && f,std::integer_sequence<I,i...> sequence)123   decltype(auto) unpackIntegerSequence(F&& f, std::integer_sequence<I, i...> sequence)
124   {
125     return f(std::integral_constant<I, i>()...);
126   }
127 
128 } //namespace Dune
129 
130 #endif // DUNE_COMMON_INDICES_HH
131