ARB
arbtools.h
Go to the documentation of this file.
1 // ==================================================================== //
2 // //
3 // File : arbtools.h //
4 // Purpose : small general purpose helper classes //
5 // //
6 // //
7 // Coded by Ralf Westram (coder@reallysoft.de) in August 2003 //
8 // Copyright Department of Microbiology (Technical University Munich) //
9 // //
10 // Visit our web site at: http://www.arb-home.de/ //
11 // //
12 // //
13 // ==================================================================== //
14 
15 #ifndef ARBTOOLS_H
16 #define ARBTOOLS_H
17 
18 #ifndef _GLIBCXX_NEW
19 #include <new>
20 #endif
21 #ifndef CXXFORWARD_H
22 #include <cxxforward.h>
23 #endif
24 #ifndef _GLIBCXX_CMATH
25 #include <cmath>
26 #endif
27 
28 // Base class for classes that may not be copied, neither via copy
29 // constructor or assignment operator.
30 // (Note: see also class RefPtr below)
31 
32 #ifdef Cxx11
33 struct Noncopyable {
34  Noncopyable(const Noncopyable& other) = delete;
35  Noncopyable& operator= (const Noncopyable&) = delete;
36  Noncopyable() {}
37 };
38 #else
39 class Noncopyable {
40  Noncopyable(const Noncopyable&);
41  Noncopyable& operator = (const Noncopyable&);
42 public:
44 };
45 #endif
46 
47 
48 // helper macros to make inplace-reconstruction less obfuscated
49 #define INPLACE_RECONSTRUCT(type,this) \
50  do { \
51  (this)->~type(); \
52  ::new(this) type(); \
53  } while(0)
54 
55 #define INPLACE_COPY_RECONSTRUCT(type,this,other) \
56  do { \
57  (this)->~type(); \
58  ::new(this) type(other); \
59  } while(0)
60 
61 #define DECLARE_ASSIGNMENT_OPERATOR(T) \
62  T& operator = (const T& other) { \
63  INPLACE_COPY_RECONSTRUCT(T, this, other); \
64  return *this; \
65  }
66 
67 
68 // class to hold a pointer to an object owned by somebody else.
69 // (useful to avoid warnings about missing copy-ctor/op=)
70 template <typename T> class RefPtr {
71  T *ptr;
72 public:
73  RefPtr(T *ptr_) : ptr(ptr_) {}
74  RefPtr(const RefPtr<T>& other) : ptr(other.ptr) {}
76  ~RefPtr() {}
77 
78  operator T*() const { return ptr; }
79 
80  const T *operator->() const { return ptr; }
81  T *operator->() { return ptr; }
82 
83  const T& operator*() const { return *ptr; }
84  T& operator*() { return *ptr; }
85 
86  T*& pointer_ref() { return ptr; }
87 };
88 
89 
90 // generic below/above predicates
91 template<typename T>
92 class isBelow {
93  T t;
94 public:
95  isBelow(T t_) : t(t_) {}
96  bool operator()(T o) { return o<t; }
97 };
98 
99 template<typename T>
100 class isAbove {
101  T t;
102 public:
103  isAbove(T t_) : t(t_) {}
104  bool operator()(T o) { return o>t; }
105 };
106 
107 
108 // typedef iterator types
109 #define DEFINE_NAMED_ITERATORS(type,name) \
110  typedef type::iterator name##Iter; \
111  typedef type::const_iterator name##CIter; \
112  typedef type::reverse_iterator name##RIter; \
113  typedef type::const_reverse_iterator name##CRIter
114 
115 #define DEFINE_ITERATORS(type) DEFINE_NAMED_ITERATORS(type,type)
116 
117 // macro to cast custom function signatures into generic signatures
118 // (allowing to suppress gcc 8.1++ warnings provided by -Wcast-function-type)
119 // sync with ../AISC_COM/C/aisc_global.h@AISC_CASTSIG
120 #define CASTSIG(sig,cb) ((sig)((void*)(cb)))
121 
122 // locally modify a value, restore on destruction
123 template<typename T>
124 class LocallyModify : virtual Noncopyable {
125  T& var;
126  T prevValue;
127 public:
128  // common pitfall: LocallyModify<int>(variable);
129  // wanted: LocallyModify<int> NAME(variable);
130 
131  LocallyModify(T& var_, T localValue) : var(var_), prevValue(var) { var = localValue; } // protect + change
132  explicit LocallyModify(T& var_) : var(var_), prevValue(var) {} // protect only
133  ~LocallyModify() { var = prevValue; }
134 
135  T old_value() const { return prevValue; }
136 };
137 
138 // disallow_type
139 // (useful to deny template instantiation with specific types)
140 template <typename T, typename U> struct different_types {};
141 template <typename T> struct different_types<T,T>;
142 template <typename T, typename U> struct disallow_type {
143  // Usage example:
144  // disallow_type<T, AW_CL>::here();
145  // where 'T' is a template parameter
146 
148  static inline void here(){}
149 };
150 
151 // StrictlyAliased_BasePtrRef allows to pass a 'DERIVED*&'
152 // to a function which expects a 'BASE*&'
153 // without breaking strict aliasing rules
154 template <typename DERIVED, typename BASE>
156  DERIVED*& user_ptr;
157  BASE *forwarded_ptr;
158 
159 public:
161  : user_ptr(ptr),
162  forwarded_ptr(ptr)
163  {}
165  user_ptr = static_cast<DERIVED*>(forwarded_ptr);
166  }
167 
168  BASE*& forward() { return forwarded_ptr; }
169 };
170 
171 // NAN/INF checks
172 // replace c99 macros isnan, isnormal and isinf. isinf is broken for gcc 4.4.3; see ../CORE/arb_diff.cxx@isinf
173 
174 template <typename T> CONSTEXPR_INLINE bool is_nan(const T& n) { return n != n; }
175 template <typename T> CONSTEXPR_INLINE bool is_nan_or_inf(const T& n) { return is_nan(0*n); }
176 template <typename T> CONSTEXPR_INLINE bool is_normal(const T& n) { return n != 0 && !is_nan_or_inf(n); }
177 template <typename T> CONSTEXPR_INLINE bool is_inf(const T& n) { return !is_nan(n) && is_nan_or_inf(n); }
178 
179 CONSTEXPR_INLINE int double_diff_2_cmp(const double d) {
180  return d<0 ? -1 : (d>0 ? 1 : 0);
181 }
182 CONSTEXPR_INLINE int double_cmp(const double d1, const double d2) {
184  return double_diff_2_cmp(d1-d2);
185 }
186 CONSTEXPR_INLINE int float_diff_2_cmp(const float f) {
187  return f<0 ? -1 : (f>0 ? 1 : 0);
188 }
189 CONSTEXPR_INLINE int float_cmp(const float f1, const float f2) {
191  return float_diff_2_cmp(f1-f2);
192 }
194  return L<0 ? -1 : (L>0 ? 1 : 0);
195 }
196 CONSTEXPR_INLINE int long_cmp(const long L1, const long L2) {
198  return long_diff_2_cmp(L1-L2);
199 }
200 
201 template <typename NUM>
204  return val ? log10(val)+1 : 1;
205 }
206 template <typename NUM>
209  return val<0 ? calc_digits(-val)+1 : calc_digits(val);
210 }
211 
212 #else
213 #error arbtools.h included twice
214 #endif // ARBTOOLS_H
215 
LocallyModify(T &var_)
Definition: arbtools.h:132
Noncopyable()
Definition: arbtools.h:43
CONSTEXPR_INLINE int calc_signed_digits(NUM val)
Definition: arbtools.h:207
CONSTEXPR_INLINE int calc_digits(NUM val)
Definition: arbtools.h:202
CONSTEXPR_INLINE bool is_nan(const T &n)
Definition: arbtools.h:174
CONSTEXPR_INLINE bool is_normal(const T &n)
Definition: arbtools.h:176
isAbove(T t_)
Definition: arbtools.h:103
T *& pointer_ref()
Definition: arbtools.h:86
CONSTEXPR_INLINE bool is_nan_or_inf(const T &n)
Definition: arbtools.h:175
CONSTEXPR_INLINE int long_diff_2_cmp(const long L)
Definition: arbtools.h:193
isBelow(T t_)
Definition: arbtools.h:95
RefPtr(T *ptr_)
Definition: arbtools.h:73
CONSTEXPR_INLINE bool is_inf(const T &n)
Definition: arbtools.h:177
bool operator()(T o)
Definition: arbtools.h:104
CONSTEXPR_INLINE int float_cmp(const float f1, const float f2)
Definition: arbtools.h:189
T * operator->()
Definition: arbtools.h:81
RefPtr(const RefPtr< T > &other)
Definition: arbtools.h:74
CONSTEXPR_INLINE int float_diff_2_cmp(const float f)
Definition: arbtools.h:186
#define CONSTEXPR_INLINE
Definition: cxxforward.h:92
const T & operator*() const
Definition: arbtools.h:83
T & operator*()
Definition: arbtools.h:84
DECLARE_ASSIGNMENT_OPERATOR(RefPtr< T >)
static void here()
Definition: arbtools.h:148
bool operator()(T o)
Definition: arbtools.h:96
StrictlyAliased_BasePtrRef(DERIVED *&ptr)
Definition: arbtools.h:160
const T * operator->() const
Definition: arbtools.h:80
~RefPtr()
Definition: arbtools.h:76
T old_value() const
Definition: arbtools.h:135
Definition: trnsprob.h:20
different_types< T, U > wrong_type_used
Definition: arbtools.h:147
CONSTEXPR_INLINE int double_cmp(const double d1, const double d2)
Definition: arbtools.h:182
LocallyModify(T &var_, T localValue)
Definition: arbtools.h:131
CONSTEXPR_INLINE int double_diff_2_cmp(const double d)
Definition: arbtools.h:179
CONSTEXPR_INLINE int long_cmp(const long L1, const long L2)
Definition: arbtools.h:196