HILA
Loading...
Searching...
No Matches
type_tools.h
1#ifndef TEMPLATE_TOOLS_H
2#define TEMPLATE_TOOLS_H
3
4#include <iostream>
5#include <assert.h>
6#include <sstream>
7
8#include "plumbing/defs.h"
9
10
11namespace hila {
12
13/////////////////////////////////////////////////////////////////////////////////
14/// is class type defined so that can be used in Field<type> -variables
15/// use the existence of type::base_type -element as a proxy for this
16/// use: hila::is_field_class_type<T>::value
17template <class, class = void>
18struct is_field_class_type : std::false_type {};
19
20template <class T>
21struct is_field_class_type<T, std::void_t<typename T::base_type>> : std::true_type {};
22
23/////////////////////////////////////////////////////////////////////////////////
24/// General routine to determine if type can be used in Field<type> -variables
25/// union of is_arithmetic and is_field_class_type
26/// use: hila::is_field_type<T>::value
27template <class, class = void>
28struct is_field_type : std::false_type {};
29
30template <class T>
31struct is_field_type<T, typename std::enable_if_t<is_field_class_type<T>::value ||
32 is_arithmetic<T>::value>> : std::true_type {
33};
34
35/////////////////////////////////////////////////////////////////////////////////
36/// Utility for obtaining the numeric base type of a class
37/// Use as "hila::arithmetic_type<T>"
38/// which returns the underlying arithmetic type used in class T (e.g. float, double
39/// etc.) if it is field class type. For other types returns the input type
40///
41///
42/// Alt form "typename base_type_struct<T>"
43
44template <typename T, typename Enable = void>
46 using type = T;
47};
48
49template <typename T>
50struct base_type_struct<T, typename std::enable_if_t<is_field_class_type<T>::value>> {
51 // In this case the base type is just T
52 using type = typename T::base_type;
53};
54
55template <typename T>
56using arithmetic_type = typename base_type_struct<T>::type;
57
58//////////////////////////////////////////////////////////////////////////////
59/// Get the inner type in nesting templates:
60/// inner_type<A<B<C>>>
61/// returns type B<C>
62/// If type is not field class type, returns input
63//////////////////////////////////////////////////////////////////////////////
64
65template <typename T, typename Enable = void>
67 using type = T;
68};
69
70template <typename T>
71struct inner_type_struct<T, typename std::enable_if_t<hila::is_field_class_type<T>::value>> {
72 using type = typename T::argument_type;
73};
74
75template <typename T>
76using inner_type = typename inner_type_struct<T>::type;
77
78//////////////////////////////////////////////////////////////////////////////
79/// Define boolean contains_type<A,B>::value, which returns true if
80/// type A "wraps" type B at some level
81/// Example:
82/// hila::contains_type<Vector<4,Complex<double>>>, Complex<double>>::value
83/// is true
84//////////////////////////////////////////////////////////////////////////////
85
86template <typename A, typename B, typename Enable = void>
87struct contains_type : std::integral_constant<bool, std::is_same<A, B>::value> {};
88
89template <typename A, typename B>
90struct contains_type<A, B, typename std::enable_if_t<hila::is_field_class_type<A>::value && !std::is_same<A,B>::value>>
91 : std::integral_constant<bool, hila::contains_type<hila::inner_type<A>, B>::value> {};
92
93template <typename A>
94struct contains_type<A, A> : std::integral_constant<bool, true> {};
95
96
97//////////////////////////////////////////////////////////////////////////////
98/// Helper operations to make generic templates for arithmetic operators
99/// e.g. hila::type_plus<A,B> gives the type of the operator a + b, where a is of type A
100/// and b type B.
101//////////////////////////////////////////////////////////////////////////////
102template <typename A, typename B>
103using type_plus = decltype(std::declval<A>() + std::declval<B>());
104template <typename A, typename B>
105using type_minus = decltype(std::declval<A>() - std::declval<B>());
106template <typename A, typename B>
107using type_mul = decltype(std::declval<A>() * std::declval<B>());
108template <typename A, typename B>
109using type_div = decltype(std::declval<A>() / std::declval<B>());
110
111
112//////////////////////////////////////////////////////////////////////////////
113/// Access variables as if arrays of scalar_type numbers
114///
115//////////////////////////////////////////////////////////////////////////////
116
117template <typename T>
118inline hila::arithmetic_type<T> get_number_in_var(const T &var, int i) {
119 return *(reinterpret_cast<const hila::arithmetic_type<T> *>(&var) + i);
120}
121template <typename T>
122inline void set_number_in_var(T &var, int i, const hila::arithmetic_type<T> val) {
123 *(reinterpret_cast<hila::arithmetic_type<T> *>(&var) + i) = val;
124}
125
126
127//////////////////////////////////////////////////////////////////////////////
128/// Helper functions
129/// hila::is_std_array<T>::value
130/// hila::is_std_vector<T>::value
131/// are true if the type T is std::array/std::vector, otherwise false
132///
133//////////////////////////////////////////////////////////////////////////////
134
135template<typename T>
136struct is_std_array : std::false_type {};
137
138template<typename T, std::size_t N>
139struct is_std_array<std::array<T, N>> : std::true_type {};
140
141template<typename T>
142struct is_std_vector : std::false_type {};
143
144template<typename T>
145struct is_std_vector<std::vector<T>> : std::true_type {};
146
147
148
149} // namespace hila
150
151#endif
This file defines all includes for HILA.
Implement hila::swap for gauge fields.
Definition array.h:981
decltype(std::declval< A >()+std::declval< B >()) type_plus
Definition type_tools.h:103
hila::arithmetic_type< T > get_number_in_var(const T &var, int i)
Definition type_tools.h:118