C++QEDCore  v2 Milestone 10
a framework for simulating open quantum dynamics – core
TMP_Tools.h
Go to the documentation of this file.
1 // Copyright András Vukics 2006–2014. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt)
2 // -*- C++ -*-
4 #ifndef CPPQEDCORE_UTILS_TMP_TOOLS_H_INCLUDED
5 #define CPPQEDCORE_UTILS_TMP_TOOLS_H_INCLUDED
6 
8 
15 #ifndef BLITZ_ARRAY_LARGEST_RANK
16 #define BLITZ_ARRAY_LARGEST_RANK 11
17 #endif // BLITZ_ARRAY_LARGEST_RANK
18 
19 
21 #ifndef FUSION_MAX_VECTOR_SIZE
22 #define FUSION_MAX_VECTOR_SIZE 20
23 #endif // FUSION_MAX_VECTOR_SIZE
24 
25 
27 #ifndef FUSION_MAX_LIST_SIZE
28 #define FUSION_MAX_LIST_SIZE FUSION_MAX_VECTOR_SIZE
29 #endif // FUSION_MAX_LIST_SIZE
30 
31 #include <boost/type_traits/add_const.hpp>
32 #include <boost/type_traits/remove_reference.hpp>
33 #include <boost/type_traits/remove_const.hpp>
34 
35 
36 #include <boost/mpl/range_c.hpp>
37 #include <boost/mpl/vector_c.hpp>
38 #include <boost/mpl/vector.hpp>
39 #include <boost/mpl/eval_if.hpp>
40 #include <boost/mpl/identity.hpp>
41 #include <boost/mpl/int.hpp>
42 #include <boost/mpl/find_if.hpp>
43 #include <boost/mpl/equal.hpp>
44 
45 #define DEFINE_TYPED_STATIC_CONST(typeDescription,typeName,variableName) typedef typeDescription typeName; static const typeName variableName;
46 
47 #define DEFINE_INITIALIZE_TYPED_STATIC_CONST(typeDescription,typeName,variableName) typedef typeDescription typeName; static const typeName variableName=typeName();
48 
49 
51 namespace tmptools {
52 
53 
55 template<typename T>
56 struct RemoveConstReference : boost::remove_const<typename boost::remove_reference<T>::type>
57 {};
58 
59 
61 template<typename T, bool ADD_CONST>
63  : boost::mpl::eval_if_c<ADD_CONST,boost::add_const<T>,boost::mpl::identity<T> > {};
64 
65 
67 template<unsigned N, int Nbeg> struct Range : boost::mpl::range_c<int,Nbeg,Nbeg+N> {};
68 
69 
71 template<int N> struct Ordinals : Range<N,0> {};
72 
73 
75 template<unsigned N1, unsigned N2> struct Power : boost::mpl::int_<N1*Power<N1,N2-1>::value> {};
76 
78 template<unsigned N1> struct Power<N1,0> : boost::mpl::int_<1> {};
82 
92 template<typename Seq, typename ICW>
93 struct numerical_contains : boost::mpl::not_<boost::is_same<typename boost::mpl::find_if<Seq,
94  boost::mpl::equal_to<boost::mpl::_,ICW>
95  >::type,
96  typename boost::mpl::end<Seq>::type
97  >
98  > {};
99 
101 template<typename Seq, typename T, T VALUE>
102 struct numerical_contains_c : numerical_contains<Seq,boost::mpl::integral_c<T,VALUE> > {};
103 
104 
105 namespace details {
106 
107 template<typename T1, typename T2>
108 struct value_equal : boost::mpl::bool_<T1::value==T2::value>
109 {};
110 
111 } // details
112 
113 
115 
118 template<typename Seq1, typename Seq2>
119 struct numerical_equal : boost::mpl::equal<Seq1,Seq2,details::value_equal<boost::mpl::_1,boost::mpl::_2> >
120 {};
121 
122 
124 template<int N>
125 struct AssertEvenAndDivideBy2 : boost::mpl::int_<N/2>
126 {
127  static_assert( 2*(N/2)==N , "Argument not even" );
128 };
129 
130 
132 
133 template<int N1, int N2, bool IS_EXCLUSIVE=true>
134 struct pair_c;
135 
137 template<int N1, int N2>
138 struct pair_c<N1,N2,false>
139 {
140  // enum { first=N1, second=N2 };
141 
142  static const int first =N1;
143  static const int second=N2;
144 
146  template<int MIN, int MAX>
147  struct SanityCheck
148  {
149  static_assert( N1>=MIN && N2>=MIN && N1<=MAX && N2<=MAX , "pair_c sanity check failed" );
150  };
153 };
154 
155 // Apparently, in the above, the static const is DECLARED only. Some compilers (including gcc in some circumstances) need to have them DEFINED as well, which is done below. Cf EffC++ 3rd Edition, item 2.
156 
157 template<int N1, int N2>
159 
160 template<int N1, int N2>
162 
163 
165 template<int N1, int N2>
166 struct pair_c<N1,N2,true> : pair_c<N1,N2,false>
167 {
168  static_assert( N1!=N2 , "pair_c with equal elements" );
169 };
170 
171 
173 //
174 // A nonnegative compile-time integer vector
175 //
177 
178 
179 namespace details {
180 
181 template<int V>
182 struct ArgumentDispatcher : boost::mpl::integral_c<int,V>
183 {
184  static_assert( V>=0 , "Negative element in nonnegative vector" );
185 };
186 
187 } // details
188 
190 
199 template<int... V>
200 struct Vector : boost::mpl::vector_c<int,details::ArgumentDispatcher<V>::value...> {};
201 
202 
203 typedef Vector<> V_Empty;
204 
205 
206 } // tmptools
207 
208 
209 
210 #endif // CPPQEDCORE_UTILS_TMP_TOOLS_H_INCLUDED
A compile-time pair of integers.
Definition: TMP_Tools.h:134
Applies add_const if ADD_CONST = true.
Definition: TMP_Tools.h:62
Calculates the power @ compile time.
Definition: TMP_Tools.h:75
Determines the numerical equality of two compile-time sequences.
Definition: TMP_Tools.h:119
Provokes a compile-time error if N is not even, otherwise acts as a Boost.MPL int_ integral constant ...
Definition: TMP_Tools.h:125
The _c version of numerical_contains, which expects a value instead of an integral constant wrapper...
Definition: TMP_Tools.h:102
Combines remove_const and remove_reference
Definition: TMP_Tools.h:56
Template metaprogramming tools.
Definition: TMP_Tools.h:51
Determines whether a compile-time sequence “numerically contains” a given value.
Definition: TMP_Tools.h:93
A non-negative compile-time vector.
Definition: TMP_Tools.h:200
Sequence of ordinals 0 ... N-1 based on Range.
Definition: TMP_Tools.h:71
An integer range_c starting with Nbeg and having N elements (Nbeg ... Nbeg+N-1)
Definition: TMP_Tools.h:67