CASM  1.1.0
A Clusters Approach to Statistical Mechanics
CASM_TMP.hh
Go to the documentation of this file.
1 #ifndef CASM_TMP_HH
2 #define CASM_TMP_HH
3 
4 #include <cassert>
5 #include <iterator>
6 #include <string>
7 #include <tuple>
8 #include <type_traits>
9 
10 #include "casm/misc/CRTPBase.hh"
11 
12 namespace CASM {
13 
14 template <typename T>
15 struct traits;
16 
17 template <bool B, class T = void>
18 using enable_if_t = typename std::enable_if<B, T>::type;
19 
20 namespace CASM_TMP {
21 
22 // ---------------------
23 
25 template <typename... Args>
26 void ignore_returnvalues(Args &&...) {}
27 
28 // ---------------------
29 
31 template <typename... Ts>
32 struct make_void {
33  typedef void type;
34 };
35 
37 template <typename... Ts>
38 using void_t = typename make_void<Ts...>::type;
39 
44 template <typename T, typename = void>
45 struct is_iterator : std::false_type {};
46 
51 template <typename T>
52 struct is_iterator<
53  T, void_t<decltype(++std::declval<T &>()), decltype(*std::declval<T &>()),
54  decltype(std::declval<T &>() == std::declval<T &>())>>
55  : std::true_type {};
56 
62 template <typename T>
63 using enable_if_iterator = std::enable_if<is_iterator<T>::type::value, void>;
64 
70 template <typename T, typename V>
71 using enable_if_iterator_of = std::enable_if<
73  std::is_same<typename std::iterator_traits<T>::value_type,
74  V>::type::value,
75  void>;
76 
77 template <bool IsConst, typename T>
78 using ConstSwitch = typename std::conditional<IsConst, const T, T>::type;
79 
80 // ---------------------
81 
84 template <typename T>
85 struct UnaryIdentity {
86  T operator()(T const &arg) const { return arg; }
87 };
88 
91 template <typename OutputType>
93  ConstantFunctor(OutputType const &_const) : m_const(_const) {}
94 
95  template <typename... Args>
96  OutputType operator()(Args const &... args) const {
97  return m_const;
98  }
99 
100  private:
101  OutputType m_const;
102 };
103 
104 // ---------------------
105 
107 template <typename Container,
108  typename _value_type = typename Container::value_type,
109  typename _size_type = typename Container::size_type>
111  typedef _value_type value_type;
112  typedef _size_type size_type;
113 
115  BracketAccess &operator=(const BracketAccess &) { return *this; };
116 
118  value_type &operator()(Container &container, size_type index) const {
119  return container[index];
120  }
121 
123  const value_type &operator()(const Container &container,
124  size_type index) const {
125  return container[index];
126  }
127 
129  value_type &operator()(Container &container, size_type i, size_type j) const {
130  return container[i][j];
131  }
132 
134  const value_type &operator()(const Container &container, size_type i,
135  size_type j) const {
136  return container[i][j];
137  }
138 
140  static value_type &at(Container &container, size_type index) {
141  return container[index];
142  }
143 
145  static const value_type &at(const Container &container, size_type index) {
146  return container[index];
147  }
148 
150  static value_type &at(Container &container, size_type i, size_type j) {
151  return container[i][j];
152  }
153 
155  static const value_type &at(const Container &container, size_type i,
156  size_type j) {
157  return container[i][j];
158  }
159 };
160 
162 template <typename Container,
163  typename _value_type = typename Container::value_type,
164  typename _size_type = typename Container::size_type>
166  typedef _value_type value_type;
167  typedef _size_type size_type;
168 
170  ParenthesesAccess &operator=(const ParenthesesAccess &) { return *this; };
171 
173  value_type &operator()(Container &container, size_type index) const {
174  return container(index);
175  }
176 
178  const value_type &operator()(const Container &container,
179  size_type index) const {
180  return container(index);
181  }
182 
184  value_type &operator()(Container &container, size_type i, size_type j) const {
185  return container(i, j);
186  }
187 
189  const value_type &operator()(const Container &container, size_type i,
190  size_type j) const {
191  return container(i, j);
192  }
193 
195  static value_type &at(Container &container, size_type index) {
196  return container(index);
197  }
198 
200  static const value_type &at(const Container &container, size_type index) {
201  return container(index);
202  }
203 
205  static value_type &at(Container &container, size_type i, size_type j) {
206  return container(i, j);
207  }
208 
210  static const value_type &at(const Container &container, size_type i,
211  size_type j) {
212  return container(i, j);
213  }
214 };
215 
216 // ----------------------------------------
217 
218 template <int I>
220  template <typename TupleType, typename F>
221  static void eval(F f) {
222  typedef typename std::tuple_element<I - 1, TupleType>::type ElementType;
223  f.template eval<ElementType>();
224  for_each_type_impl<I - 1>::template eval<TupleType, F>(f);
225  }
226 };
227 
228 template <>
230  template <typename TupleType, typename F>
231  static void eval(F f) {
232  typedef typename std::tuple_element<0, TupleType>::type ElementType;
233  return f.template eval<ElementType>();
234  }
235 };
236 
237 template <typename TupleType, typename F>
238 void for_each_type(F f = F()) {
240  TupleType, F>(f);
241 }
242 
243 // ----------------------------------------
244 
245 template <int I>
247  template <typename TupleType, typename F>
248  static void eval(std::string name, F f) {
249  typedef typename std::tuple_element<I - 1, TupleType>::type ElementType;
251  f.template eval<ElementType>();
252  }
253  for_type_impl<I - 1>::template eval<TupleType, F>(name, f);
254  }
255 };
256 
257 template <>
258 struct for_type_impl<1> {
259  template <typename TupleType, typename F>
260  static void eval(std::string name, F f) {
261  typedef typename std::tuple_element<0, TupleType>::type ElementType;
263  f.template eval<ElementType>();
264  }
265  }
266 };
267 
268 template <typename TupleType, typename F>
269 void for_type(std::string name, F f = F()) {
271  TupleType, F>(name, f);
272 }
273 
274 // ----------------------------------------
275 
276 template <int I>
278  template <typename TupleType, typename F>
279  static void eval(std::string short_name, F f) {
280  typedef typename std::tuple_element<I - 1, TupleType>::type ElementType;
281  if (traits<ElementType>::short_name == short_name) {
282  f.template eval<ElementType>();
283  }
284  for_type_short_impl<I - 1>::template eval<TupleType, F>(short_name, f);
285  }
286 };
287 
288 template <>
290  template <typename TupleType, typename F>
291  static void eval(std::string short_name, F f) {
292  typedef typename std::tuple_element<0, TupleType>::type ElementType;
293  if (traits<ElementType>::short_name == short_name) {
294  f.template eval<ElementType>();
295  }
296  }
297 };
298 
299 template <typename TupleType, typename F>
300 void for_type_short(std::string short_name, F f = F()) {
302  TupleType, F>(short_name, f);
303 }
304 
305 // ----------------------------------------
306 
307 template <int I, bool IsLast>
309  template <typename TupleType, typename F>
310  static void eval(F f) {
311  f.template eval<I>();
313  I + 1>::template eval<TupleType, F>(f);
314  }
315 };
316 
317 template <int I>
318 struct for_each_element_impl<I, true> {
319  template <typename TupleType, typename F>
320  static void eval(F f) {
321  return f.template eval<I>();
322  }
323 };
324 
327 template <typename TupleType, typename F>
328 void for_each_element(F f = F()) {
330  1>::template eval<TupleType, F>(f);
331 }
332 
333 // -------------------------------------------
334 
335 template <typename T, typename Tuple>
336 struct has_type;
337 
338 template <typename T>
339 struct has_type<T, std::tuple<>> : std::false_type {};
340 
341 template <typename T, typename U, typename... Ts>
342 struct has_type<T, std::tuple<U, Ts...>> : has_type<T, std::tuple<Ts...>> {};
343 
344 template <typename T, typename... Ts>
345 struct has_type<T, std::tuple<T, Ts...>> : std::true_type {};
346 
347 } // namespace CASM_TMP
348 
349 } // namespace CASM
350 
351 #endif
void for_each_type(F f=F())
Definition: CASM_TMP.hh:238
void for_type_short(std::string short_name, F f=F())
Definition: CASM_TMP.hh:300
void for_type(std::string name, F f=F())
Definition: CASM_TMP.hh:269
std::enable_if< is_iterator< T >::type::value, void > enable_if_iterator
Template alias to enable a template function via SFINAE for any iterator.
Definition: CASM_TMP.hh:63
void for_each_element(F f=F())
Call f.eval<I>(), for int I in range [0, std::tuple_size<TupleType>::value)
Definition: CASM_TMP.hh:328
std::enable_if< is_iterator< T >::type::value &&std::is_same< typename std::iterator_traits< T >::value_type, V >::type::value, void > enable_if_iterator_of
Template alias to enable a template function via SFINAE for an iterator with value_type V.
Definition: CASM_TMP.hh:75
typename std::conditional< IsConst, const T, T >::type ConstSwitch
Definition: CASM_TMP.hh:78
typename make_void< Ts... >::type void_t
Alias for void, to help SFINAE work.
Definition: CASM_TMP.hh:38
void ignore_returnvalues(Args &&...)
Enables calling a function on each argument in a parameter pack.
Definition: CASM_TMP.hh:26
Traits const & traits(std::string const &dof_key)
Lookup DoFType::Traits in the global dictionary.
Definition: DoFTraits.cc:46
Main CASM namespace.
Definition: APICommand.hh:8
typename std::enable_if< B, T >::type enable_if_t
Definition: CASM_TMP.hh:18
GenericDatumFormatter< std::string, DataObject > name()
Definition: stream_io.hh:24
Helper Functor for Counter container access using operator[].
Definition: CASM_TMP.hh:110
static const value_type & at(const Container &container, size_type i, size_type j)
Identical to 'return container[i][j];'.
Definition: CASM_TMP.hh:155
const value_type & operator()(const Container &container, size_type index) const
Identical to 'return container[index];'.
Definition: CASM_TMP.hh:123
BracketAccess & operator=(const BracketAccess &)
Definition: CASM_TMP.hh:115
static value_type & at(Container &container, size_type index)
Identical to 'return container[index];'.
Definition: CASM_TMP.hh:140
static const value_type & at(const Container &container, size_type index)
Identical to 'return container[index];'.
Definition: CASM_TMP.hh:145
const value_type & operator()(const Container &container, size_type i, size_type j) const
Identical to 'return container[i][j];'.
Definition: CASM_TMP.hh:134
value_type & operator()(Container &container, size_type index) const
Identical to 'return container[index];'.
Definition: CASM_TMP.hh:118
value_type & operator()(Container &container, size_type i, size_type j) const
Identical to 'return container[i][j];'.
Definition: CASM_TMP.hh:129
static value_type & at(Container &container, size_type i, size_type j)
Identical to 'return container[i][j];'.
Definition: CASM_TMP.hh:150
N-nary function that behaves as a constant (i.e. transform(arg1,arg2,...) == constant is true)
Definition: CASM_TMP.hh:92
OutputType operator()(Args const &... args) const
Definition: CASM_TMP.hh:96
ConstantFunctor(OutputType const &_const)
Definition: CASM_TMP.hh:93
Helper Functor for Counter container access using operator()
Definition: CASM_TMP.hh:165
value_type & operator()(Container &container, size_type index) const
Identical to 'return container(index);'.
Definition: CASM_TMP.hh:173
static const value_type & at(const Container &container, size_type index)
Identical to 'return container(index);'.
Definition: CASM_TMP.hh:200
static value_type & at(Container &container, size_type index)
Identical to 'return container(index);'.
Definition: CASM_TMP.hh:195
const value_type & operator()(const Container &container, size_type index) const
Identical to 'return container(index);'.
Definition: CASM_TMP.hh:178
static value_type & at(Container &container, size_type i, size_type j)
Identical to 'return container(i,j);'.
Definition: CASM_TMP.hh:205
const value_type & operator()(const Container &container, size_type i, size_type j) const
Identical to 'return container(index);'.
Definition: CASM_TMP.hh:189
static const value_type & at(const Container &container, size_type i, size_type j)
Identical to 'return container(i,j);'.
Definition: CASM_TMP.hh:210
value_type & operator()(Container &container, size_type i, size_type j) const
Identical to 'return container(index);'.
Definition: CASM_TMP.hh:184
ParenthesesAccess & operator=(const ParenthesesAccess &)
Definition: CASM_TMP.hh:170
Unary transformation that behaves as Identity (i.e. transform(arg) == arg is true)
Definition: CASM_TMP.hh:85
T operator()(T const &arg) const
Definition: CASM_TMP.hh:86
static void eval(std::string name, F f)
Definition: CASM_TMP.hh:260
static void eval(std::string name, F f)
Definition: CASM_TMP.hh:248
static void eval(std::string short_name, F f)
Definition: CASM_TMP.hh:291
static void eval(std::string short_name, F f)
Definition: CASM_TMP.hh:279
Base type inherits from std::false_type if T is not iterator.
Definition: CASM_TMP.hh:45
Alias for void, to help SFINAE work.
Definition: CASM_TMP.hh:32