G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
20namespace gismo
21{
22
23namespace 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
28template <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
46using std::conditional;
47using std::enable_if;
48using std::false_type;
49using std::integral_constant;
50using std::is_base_of;
51using std::is_integral;
52using std::is_same;
53using std::reference_wrapper;
54using std::remove_const;
55using std::remove_cv;
56using std::remove_volatile;
57using std::true_type;
58using std::make_unsigned;
59using std::make_signed;
60using 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
72template<bool B, class T, class F> struct conditional { typedef T type; };
73template<class T, class F> struct conditional<false, T, F> { typedef F type; };
74
75template<bool B, class T = void> struct enable_if {};
76template<class T> struct enable_if<true, T> { typedef T type;};
77
78template<class T, class U> struct is_same { enum { value = 0 }; };
79template<class T> struct is_same<T, T> { enum { value = 1 }; };
80
81template<typename U> struct is_pointer { static const bool value = false; };
82template<typename U> struct is_pointer<U*> { static const bool value = true ; };
83
84template <typename B, typename D> struct Host
85{ operator B*() const; operator D*(); };
86template <typename B, typename D>
87struct 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
96template <class T>
97class reference_wrapper
98{
99public:
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
111private:
112 T* _ptr;
113};
114
115template<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
123typedef integral_constant<bool, true> true_type;
124typedef integral_constant<bool, false> false_type;
125
126template<typename> struct is_integral_base : false_type {};
127
128template<> struct is_integral_base<bool> : true_type {};
129template<> struct is_integral_base<char> : true_type {};
130template<> struct is_integral_base<signed char> : true_type {};
131template<> struct is_integral_base<unsigned char> : true_type {};
132template<> struct is_integral_base<wchar_t> : true_type {};
133template<> struct is_integral_base<short> : true_type {};
134template<> struct is_integral_base<int> : true_type {};
135template<> struct is_integral_base<long> : true_type {};
136template<> struct is_integral_base<long long> : true_type {};
137template<> struct is_integral_base<unsigned short> : true_type {};
138template<> struct is_integral_base<unsigned int> : true_type {};
139template<> struct is_integral_base<unsigned long> : true_type {};
140template<> struct is_integral_base<unsigned long long> : true_type {};
141
142template< class T > struct remove_const { typedef T type; };
143template< class T > struct remove_const<const T> { typedef T type; };
144
145template< class T > struct remove_volatile { typedef T type; };
146template< class T > struct remove_volatile<volatile T> { typedef T type; };
147
148template< class T >
149struct remove_cv { typedef typename remove_volatile<typename remove_const<T>::type>::type type; };
150
151template<typename T> struct is_integral: is_integral_base<typename remove_cv<T>::type> {};
152
153template<class T>
154struct make_unsigned;
155#define GISMO_MAKE_UNSIGNED(signed_type) \
156template<> \
157struct make_unsigned<signed signed_type> { \
158 typedef unsigned signed_type type; \
159}; \
160template<> \
161struct make_unsigned<unsigned signed_type> { \
162 typedef unsigned signed_type type; \
163};
164template<>
165struct make_unsigned<char> {
166 typedef unsigned char type;
167};
168GISMO_MAKE_UNSIGNED(char)
169GISMO_MAKE_UNSIGNED(short)
170GISMO_MAKE_UNSIGNED(int)
171GISMO_MAKE_UNSIGNED(long)
172GISMO_MAKE_UNSIGNED(long long)
173#undef GISMO_MAKE_UNSIGNED
174
175template<class T>
176struct make_signed;
177#define GISMO_MAKE_SIGNED(unsigned_type) \
178template<> \
179struct make_signed<signed unsigned_type> { \
180 typedef signed unsigned_type type; \
181}; \
182template<> \
183struct make_signed<unsigned unsigned_type> { \
184 typedef signed unsigned_type type; \
185};
186template<>
187struct make_signed<char> {
188 typedef signed char type;
189};
190GISMO_MAKE_SIGNED(char)
191GISMO_MAKE_SIGNED(short)
192GISMO_MAKE_SIGNED(int)
193GISMO_MAKE_SIGNED(long)
194GISMO_MAKE_SIGNED(long long)
195#undef GISMO_MAKE_SIGNED
196
197template<class T>
198struct is_signed;
199#define GISMO_IS_SIGNED(type) \
200template<> \
201struct is_signed<signed type> { \
202 static const bool value = true; \
203}; \
204template <> \
205struct is_signed<unsigned type> { \
206 static const bool value = false; \
207};
208GISMO_IS_SIGNED(char)
209GISMO_IS_SIGNED(short)
210GISMO_IS_SIGNED(int)
211GISMO_IS_SIGNED(long)
212GISMO_IS_SIGNED(long long)
213#undef GISMO_IS_SIGNED
214
215
216#endif
217
220template<typename T> struct remove_pointer {typedef T type;};
221template<typename T> struct remove_pointer<T*> {typedef typename remove_pointer<T>::type type;};
222
225template <class T> struct is_complex : public false_type {};
226template <class T> struct is_complex<const T > : public is_complex<T>{};
227template <class T> struct is_complex<volatile const T > : public is_complex<T>{};
228template <class T> struct is_complex<volatile T > : public is_complex<T>{};
229template <class T> struct is_complex<std::complex<T> > : public true_type{};
230
232template <class T>
233typename make_unsigned<T>::type to_unsigned(T t) {
234 return t;
235}
237template <class T>
238typename make_signed<T>::type to_signed(T t) {
239 return t;
240}
241
246template<class T1, class T2>
247bool 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
279template<class T1, class T2>
280bool 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
312template<class T1, class T2>
313bool greater(T1 t1, T2 t2)
314{
315 return less(t2, t1);
316}
317
322template<class T1, class T2>
323bool greater_equal(T1 t1, T2 t2)
324{
325 return less_equal(t2, t1);
326}
327
332template<class T1, class T2>
333bool 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
Handles shared library creation and other class attributes.
bool less_equal(T1 t1, T2 t2)
Definition gsTemplateTools.h:280
bool less(T1 t1, T2 t2)
Definition gsTemplateTools.h:247
bool greater_equal(T1 t1, T2 t2)
Definition gsTemplateTools.h:323
make_signed< T >::type to_signed(T t)
Casts a type T to a signed one.
Definition gsTemplateTools.h:238
make_unsigned< T >::type to_unsigned(T t)
Casts a type T to an unsigned one.
Definition gsTemplateTools.h:233
The G+Smo namespace, containing all definitions for the library.
This namespace gathers several utility functions for miscellaneous tasks.
Type trait is_complex<T> checks if type T is of type std::complex<...>
Definition gsTemplateTools.h:225
Remove pointer from type.
Definition gsTemplateTools.h:220
Print name of template type as a string.
Definition gsUtils.h:235