G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsTemplateTools.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsExport.h>
17 #include <utility>
18 #include <complex>
19 
20 namespace gismo
21 {
22 
23 namespace util {
24 
25 #if __cplusplus >= 201103L
26 //see also http://lists.boost.org/Archives/boost/2009/04/151209.php
27 // has_move_constructor is not working with MSVC up to VS2019
28 template <typename T> struct has_move_constructor
29 {
30  typedef char yes[1];
31  typedef char no[2];
32 
33  struct AmbiguousConverter
34  {
35  operator T&& ();
36  operator const T& ();
37  };
38  template <typename C> static no& test(decltype( new C( AmbiguousConverter{} )));
39  template <typename> static yes& test(...);
40  enum { value = (sizeof(test<T>(0)) == sizeof(yes)) };
41 };
42 #endif
43 
44 #if __cplusplus >= 201103L || _MSC_VER >= 1600
45 
46 using std::conditional;
47 using std::enable_if;
48 using std::false_type;
49 using std::integral_constant;
50 using std::is_base_of;
51 using std::is_integral;
52 using std::is_same;
53 using std::reference_wrapper;
54 using std::remove_const;
55 using std::remove_cv;
56 using std::remove_volatile;
57 using std::true_type;
58 using std::make_unsigned;
59 using std::make_signed;
60 using std::is_signed;
61 
62 # define GS_BIND1ST(_op,_arg) std::bind(_op, _arg, std::placeholders::_1)
63 # define GS_BIND2ND(_op,_arg) std::bind(_op, std::placeholders::_1, _arg)
64 
65 #else
66 
67 # define GS_BIND1ST(_op,_arg) std::bind1st(_op,_arg)
68 # define GS_BIND2ND(_op,_arg) std::bind2nd(_op,_arg)
69 
70 // template <typename T> struct has_move_constructor { enum { value = 0 }; };
71 
72 template<bool B, class T, class F> struct conditional { typedef T type; };
73 template<class T, class F> struct conditional<false, T, F> { typedef F type; };
74 
75 template<bool B, class T = void> struct enable_if {};
76 template<class T> struct enable_if<true, T> { typedef T type;};
77 
78 template<class T, class U> struct is_same { enum { value = 0 }; };
79 template<class T> struct is_same<T, T> { enum { value = 1 }; };
80 
81 template<typename U> struct is_pointer { static const bool value = false; };
82 template<typename U> struct is_pointer<U*> { static const bool value = true ; };
83 
84 template <typename B, typename D> struct Host
85 { operator B*() const; operator D*(); };
86 template <typename B, typename D>
87 struct is_base_of
88 {
89  typedef char (&yes)[1];
90  typedef char (&no)[2];
91  template <typename T> static yes check(D*, T);
92  static no check(B*, int);
93  static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
94 };
95 
96 template <class T>
97 class reference_wrapper
98 {
99 public:
100  typedef T type;
101 
102  reference_wrapper(const T& ref) : _ptr(&const_cast<T&>(ref)) { }
103  reference_wrapper(const reference_wrapper&o) : _ptr(o._ptr) { }
104 
105  reference_wrapper& operator=(const reference_wrapper& o)
106  { _ptr = o._ptr; return *this; }
107 
108  operator T& () const { return *_ptr; }
109  T& get() const { return *_ptr; }
110 
111 private:
112  T* _ptr;
113 };
114 
115 template<class T, T v>
116  struct integral_constant {
117  static const T value = v;
118  typedef T value_type;
119  typedef integral_constant type;
120  value_type operator()() const { return value; }
121 };
122 
123 typedef integral_constant<bool, true> true_type;
124 typedef integral_constant<bool, false> false_type;
125 
126 template<typename> struct is_integral_base : false_type {};
127 
128 template<> struct is_integral_base<bool> : true_type {};
129 template<> struct is_integral_base<char> : true_type {};
130 template<> struct is_integral_base<signed char> : true_type {};
131 template<> struct is_integral_base<unsigned char> : true_type {};
132 template<> struct is_integral_base<wchar_t> : true_type {};
133 template<> struct is_integral_base<short> : true_type {};
134 template<> struct is_integral_base<int> : true_type {};
135 template<> struct is_integral_base<long> : true_type {};
136 template<> struct is_integral_base<long long> : true_type {};
137 template<> struct is_integral_base<unsigned short> : true_type {};
138 template<> struct is_integral_base<unsigned int> : true_type {};
139 template<> struct is_integral_base<unsigned long> : true_type {};
140 template<> struct is_integral_base<unsigned long long> : true_type {};
141 
142 template< class T > struct remove_const { typedef T type; };
143 template< class T > struct remove_const<const T> { typedef T type; };
144 
145 template< class T > struct remove_volatile { typedef T type; };
146 template< class T > struct remove_volatile<volatile T> { typedef T type; };
147 
148 template< class T >
149 struct remove_cv { typedef typename remove_volatile<typename remove_const<T>::type>::type type; };
150 
151 template<typename T> struct is_integral: is_integral_base<typename remove_cv<T>::type> {};
152 
153 template<class T>
154 struct make_unsigned;
155 #define GISMO_MAKE_UNSIGNED(signed_type) \
156 template<> \
157 struct make_unsigned<signed signed_type> { \
158  typedef unsigned signed_type type; \
159 }; \
160 template<> \
161 struct make_unsigned<unsigned signed_type> { \
162  typedef unsigned signed_type type; \
163 };
164 template<>
165 struct make_unsigned<char> {
166  typedef unsigned char type;
167 };
168 GISMO_MAKE_UNSIGNED(char)
169 GISMO_MAKE_UNSIGNED(short)
170 GISMO_MAKE_UNSIGNED(int)
171 GISMO_MAKE_UNSIGNED(long)
172 GISMO_MAKE_UNSIGNED(long long)
173 #undef GISMO_MAKE_UNSIGNED
174 
175 template<class T>
176 struct make_signed;
177 #define GISMO_MAKE_SIGNED(unsigned_type) \
178 template<> \
179 struct make_signed<signed unsigned_type> { \
180  typedef signed unsigned_type type; \
181 }; \
182 template<> \
183 struct make_signed<unsigned unsigned_type> { \
184  typedef signed unsigned_type type; \
185 };
186 template<>
187 struct make_signed<char> {
188  typedef signed char type;
189 };
190 GISMO_MAKE_SIGNED(char)
191 GISMO_MAKE_SIGNED(short)
192 GISMO_MAKE_SIGNED(int)
193 GISMO_MAKE_SIGNED(long)
194 GISMO_MAKE_SIGNED(long long)
195 #undef GISMO_MAKE_SIGNED
196 
197 template<class T>
198 struct is_signed;
199 #define GISMO_IS_SIGNED(type) \
200 template<> \
201 struct is_signed<signed type> { \
202  static const bool value = true; \
203 }; \
204 template <> \
205 struct is_signed<unsigned type> { \
206  static const bool value = false; \
207 };
208 GISMO_IS_SIGNED(char)
209 GISMO_IS_SIGNED(short)
210 GISMO_IS_SIGNED(int)
211 GISMO_IS_SIGNED(long)
212 GISMO_IS_SIGNED(long long)
213 #undef GISMO_IS_SIGNED
214 
215 
216 #endif
217 
220 template<typename T> struct remove_pointer {typedef T type;};
221 template<typename T> struct remove_pointer<T*> {typedef typename remove_pointer<T>::type type;};
222 
225 template <class T> struct is_complex : public false_type {};
226 template <class T> struct is_complex<const T > : public is_complex<T>{};
227 template <class T> struct is_complex<volatile const T > : public is_complex<T>{};
228 template <class T> struct is_complex<volatile T > : public is_complex<T>{};
229 template <class T> struct is_complex<std::complex<T> > : public true_type{};
230 
232 template <class T>
233 typename make_unsigned<T>::type to_unsigned(T t) {
234  return t;
235 }
237 template <class T>
238 typename make_signed<T>::type to_signed(T t) {
239  return t;
240 }
241 
246 template<class T1, class T2>
247 bool less(T1 t1, T2 t2)
248 {
249  typedef typename util::make_signed<T1>::type signedT1;
250  typedef typename util::make_signed<T2>::type signedT2;
251  typedef typename util::make_unsigned<T1>::type unsignedT1;
252  typedef typename util::make_unsigned<T2>::type unsignedT2;
253 
254  if (is_signed<T1>::value == is_signed<T2>::value) // all is_signed are optimized out at compile time
255  {
256  if (is_signed<T1>::value) // both signed, cast to signedTx
257  return (static_cast<signedT1>(t1) < static_cast<signedT2>(t2));
258  else // both unsigned, cast to unsignedTx
259  return (static_cast<unsignedT1>(t1) < static_cast<unsignedT2>(t2));
260  }
261  if (is_signed<T1>::value && !is_signed<T2>::value)
262  {
263  if (t1 < 0)
264  return true;
265  return (static_cast<unsignedT1>(t1) < static_cast<unsignedT2>(t2));
266  }
267  if (!is_signed<T1>::value && is_signed<T2>::value)
268  {
269  if (t2 < 0)
270  return false;
271  return (static_cast<unsignedT1>(t1) < static_cast<unsignedT2>(t2));
272  }
273 }
274 
279 template<class T1, class T2>
280 bool less_equal(T1 t1, T2 t2)
281 {
282  typedef typename util::make_signed<T1>::type signedT1;
283  typedef typename util::make_signed<T2>::type signedT2;
284  typedef typename util::make_unsigned<T1>::type unsignedT1;
285  typedef typename util::make_unsigned<T2>::type unsignedT2;
286 
287  if (is_signed<T1>::value == is_signed<T2>::value) // all is_signed are optimized out at compile time
288  {
289  if (is_signed<T1>::value) // both signed, cast to signedTx
290  return (static_cast<signedT1>(t1) <= static_cast<signedT2>(t2));
291  else // both unsigned, cast to unsignedTx
292  return (static_cast<unsignedT1>(t1) <= static_cast<unsignedT2>(t2));
293  }
294  if (is_signed<T1>::value && !is_signed<T2>::value)
295  {
296  if (t1 < 0)
297  return true;
298  return (static_cast<unsignedT1>(t1) <= static_cast<unsignedT2>(t2));
299  }
300  if (!is_signed<T1>::value && is_signed<T2>::value)
301  {
302  if (t2 < 0)
303  return false;
304  return (static_cast<unsignedT1>(t1) <= static_cast<unsignedT2>(t2));
305  }
306 }
307 
312 template<class T1, class T2>
313 bool greater(T1 t1, T2 t2)
314 {
315  return less(t2, t1);
316 }
317 
322 template<class T1, class T2>
323 bool greater_equal(T1 t1, T2 t2)
324 {
325  return less_equal(t2, t1);
326 }
327 
332 template<class T1, class T2>
333 bool equal(T1 t1, T2 t2)
334 {
335  typedef typename util::make_signed<T1>::type signedT1;
336  typedef typename util::make_signed<T2>::type signedT2;
337  typedef typename util::make_unsigned<T1>::type unsignedT1;
338  typedef typename util::make_unsigned<T2>::type unsignedT2;
339 
340  if (is_signed<T1>::value == is_signed<T2>::value)
341  {
342  if (is_signed<T1>::value)
343  return static_cast<signedT1>(t1) == static_cast<signedT2>(t2);
344  else
345  return static_cast<unsignedT1>(t1) == static_cast<unsignedT2>(t2);
346  }
347  if (is_signed<T1>::value && !is_signed<T2>::value)
348  {
349  if (t1 < 0)
350  return false;
351  return (static_cast<unsignedT1>(t1) == static_cast<unsignedT2>(t2));
352  }
353  if (!is_signed<T1>::value && is_signed<T2>::value)
354  {
355  if (t2 < 0)
356  return false;
357  return (static_cast<unsignedT1>(t1) == static_cast<unsignedT2>(t2));
358  }
359 }
360 
361 } // end namespace util
362 
363 } // end namespace gismo
Print name of template type as a string.
Definition: gsUtils.h:234
bool less(T1 t1, T2 t2)
Definition: gsTemplateTools.h:247
bool greater(T1 t1, T2 t2)
Definition: gsTemplateTools.h:313
bool less_equal(T1 t1, T2 t2)
Definition: gsTemplateTools.h:280
Handles shared library creation and other class attributes.
make_unsigned< T >::type to_unsigned(T t)
Casts a type T to an unsigned one.
Definition: gsTemplateTools.h:233
bool greater_equal(T1 t1, T2 t2)
Definition: gsTemplateTools.h:323
Type trait is_complex&lt;T&gt; checks if type T is of type std::complex&lt;...&gt;
Definition: gsTemplateTools.h:225
make_signed< T >::type to_signed(T t)
Casts a type T to a signed one.
Definition: gsTemplateTools.h:238
bool equal(T1 t1, T2 t2)
Definition: gsTemplateTools.h:333
Remove pointer from type.
Definition: gsTemplateTools.h:220