Tomographer  v1.0a
Tomographer C++ Framework Documentation
util.h
Go to the documentation of this file.
1 /* This file is part of the Tomographer project, which is distributed under the
2  * terms of the MIT license.
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2015 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef TOMOGRAPHER_TOOLS_UTILS_H
28 #define TOMOGRAPHER_TOOLS_UTILS_H
29 
36 #include <type_traits>
37 
38 #include <Eigen/Core> // Eigen::Dynamic
39 
41 
42 
43 // -----------------------------------------------------------------------------
44 // Define functions with printf-safe arguments, with compiler-generated warnings
45 // -----------------------------------------------------------------------------
46 
47 
48 // The PRINTFX_ARGS_SAFE macros are defined here, so that in the future we may support a
49 // wider range of compilers which may not understand the __attribute__(format)
50 // instruction.
51 
52 
72 #define PRINTF1_ARGS_SAFE __attribute__ ((__format__ (__printf__, 1, 2)))
73 
75 #define PRINTF2_ARGS_SAFE __attribute__ ((__format__ (__printf__, 2, 3)))
76 
78 #define PRINTF3_ARGS_SAFE __attribute__ ((__format__ (__printf__, 3, 4)))
79 
81 #define PRINTF4_ARGS_SAFE __attribute__ ((__format__ (__printf__, 4, 5)))
82 
83 
84 
85 // -----------------------------------------------------------------------------
86 // Some C++ helpers
87 // -----------------------------------------------------------------------------
88 
89 namespace Tomographer
90 {
91 namespace Tools
92 {
93 
94 // taken from http://stackoverflow.com/a/25510879/1694896
95 
96 namespace tomo_internal {
97  template <typename F>
98  struct FinalAction {
99  FinalAction(F f) : clean_{f} {}
100  ~FinalAction() { clean_(); }
101  F clean_;
102  };
103 } // namespace tomo_internal
104 
116 template <typename F>
117 inline tomo_internal::FinalAction<F> finally(F f)
118 {
119  return tomo_internal::FinalAction<F>(f);
120 }
121 
122 
123 
124 
125 
126 
127 // -----------------------------------------------------------------------------
128 
129 
144 template<typename T_, int Value>
146 {
147 public:
149  typedef T_ T;
151  static constexpr T ValueAtCTime = Value;
152 
154  inline static_or_dynamic() { }
160  inline explicit static_or_dynamic(T val) {
161  assert(val == ValueAtCTime);
162  (void)val; // silence "unused parameter" warning
163  }
164 
169  inline T value() const { return ValueAtCTime; }
170 
175  inline T operator()() const { return ValueAtCTime; }
176 };
177 
182 template<typename T_>
183 class static_or_dynamic<T_, Eigen::Dynamic>
184 {
185 public:
187  typedef T_ T;
189  static constexpr T ValueAtCTime = Eigen::Dynamic;
190 
192  static_or_dynamic() = delete; // no default constructor.
197  inline explicit static_or_dynamic(T val) : _dyn_value(val) { }
198 
200  inline T value() const { return _dyn_value; }
202  inline T operator()() const { return value(); }
203 private:
205  const T _dyn_value;
206 };
207 
208 
209 // -----------------------------------------------------------------------------
210 
211 
220 template<typename T_, bool enabled>
222 {
224  typedef T_ T;
226  static constexpr bool is_enabled = false;
227 
229  template<typename... Args>
230  explicit store_if_enabled(Args...) { }
231 };
236 template<typename T_>
237 struct store_if_enabled<T_, true>
238 {
240  typedef T_ T;
242  static constexpr bool is_enabled = true;
243 
245  T value;
246 
248  template<typename... ArgTypes>
249  explicit store_if_enabled(const ArgTypes& ... args) : value(args...) { }
250 };
251 
256 template<typename T>
257 inline std::ostream & operator<<(std::ostream & str, store_if_enabled<T, false> /*val*/)
258 {
259  return str << "[-]";
260 }
265 template<typename T>
266 inline std::ostream & operator<<(std::ostream & str, store_if_enabled<T, true> val)
267 {
268  return str << val.value;
269 }
270 
271 
272 
273 // -----------------------------------------------------------------------------
274 
277 inline constexpr bool is_power_of_two(int N)
278 {
279  // taken from http://stackoverflow.com/q/10585450/1694896
280  return N && !(N & (N - 1));
281 }
282 
283 
284 
285 
286 // -----------------------------------------------------------------------------
287 
288 
289 
294 #define TOMO_FUNCTION __PRETTY_FUNCTION__
295 
296 
297 
298 namespace tomo_internal {
299 // logic taken from KLatexFormula/klftools: klfdefs.cpp / klfShortFuncSignature()
300 struct extractFuncName_helper {
301  struct extracted {
302  const std::size_t decl_pos;
303  const conststr extr;
304  constexpr extracted(std::size_t dp, const conststr& s) : decl_pos(dp), extr(s) { }
305  };
306  static constexpr conststr alltofirstparen(const conststr& s)
307  {
308  return s.substr(0, s.find(conststr("("), 0, s.size()));
309  }
310  static constexpr std::size_t declpos_from_found_spc(std::size_t found_pos)
311  {
312  return found_pos == std::string::npos ? 0 : found_pos + 1;
313  }
314  static constexpr std::size_t pos_decl(const conststr& s)
315  {
316  return ((s.size() > 2)
317  ? declpos_from_found_spc(s.rfind(conststr(" "), std::string::npos))
318  : 0);
319  }
320  static constexpr extracted allfromfirstspace(const conststr& s)
321  {
322  return extracted(pos_decl(s),
323  s.substr_e(pos_decl(s),
324  s.size()));
325  }
326  static constexpr extracted do_extract(const conststr& funcname)
327  {
328  return allfromfirstspace(alltofirstparen(funcname));
329  }
330  static constexpr conststr extract_choose(const extracted& do_extracted,
331  const conststr& funcname)
332  {
333  return (do_extracted.extr.substr(0,8) == conststr("operator")
334  ? funcname.substr(do_extracted.decl_pos)
335  : do_extracted.extr);
336  }
337  static constexpr conststr extract(const conststr& funcname)
338  {
339  return extract_choose(do_extract(funcname), funcname);
340  }
341 }; // helper struct
342 } // namespace tomo_internal
343 
344 
350 constexpr inline conststr extractFuncName(const conststr & funcname)
351 {
352  return tomo_internal::extractFuncName_helper::extract(funcname);
353 }
354 
355 
356 
357 
363 #define TOMO_STATIC_ASSERT_EXPR(...) \
364  static_assert(__VA_ARGS__, #__VA_ARGS__)
365 
366 
367 
368 // -----------------------------------------------------------------------------
369 
370 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
371 // WARNING!!! CHECK OUT http://stackoverflow.com/q/29363532/1694896
372 // FOR VERY SUBTLE BUGS....... :( :( -- TEST WITH INTEL ICC!!
373 #define TOMOGRAPHER_ENABLED_IF(...) \
374  template<bool _dummy__enabledif = false, \
375  typename std::enable_if<_dummy__enabledif || (__VA_ARGS__), bool>::type \
376  _dummy__enabledif2 = false>
377 #define TOMOGRAPHER_ENABLED_IF_TMPL(...) \
378  bool _dummy__enabledif = false, \
379  typename std::enable_if<_dummy__enabledif || (__VA_ARGS__), bool>::type \
380  _dummy__enabledif2 = true
381 #endif
382 
383 
384 } // namespace Tools
385 } // namespace Tomographer
386 
387 
388 
389 #endif
Base namespace for the Tomographer project.
Definition: dmmhrw.h:51
store_if_enabled(const ArgTypes &...args)
Constructor. Any arguments are passed to the value's constructor.
Definition: util.h:249
T value() const
Get the value stored.
Definition: util.h:169
static constexpr T ValueAtCTime
The value, if stored at compile-time, or Eigen::Dynamic.
Definition: util.h:151
static constexpr bool is_enabled
Whether we're storing a value or not – by default no.
Definition: util.h:226
static_or_dynamic()
Default Constructor. Only if the value is stored at compile-time.
Definition: util.h:154
T_ T
The type we're storing.
Definition: util.h:224
T operator()() const
See static_or_dynamic::operator()()
Definition: util.h:202
static_or_dynamic(T val)
Constructor which initializes the value to val.
Definition: util.h:197
T value
This property keeps the value we're supposed to store.
Definition: util.h:245
Utility that stores a data type if a compile-time flag is enabled.
Definition: util.h:221
T operator()() const
Get the value stored.
Definition: util.h:175
A constexpr string type, suitable for basic compile-time string processing.
T_ T
Type of the value we are storing.
Definition: util.h:149
T value() const
See static_or_dynamic::value()
Definition: util.h:200
constexpr bool is_power_of_two(int N)
Return true if the argument is a power of two, false otherwise.
Definition: util.h:277
constexpr conststr extractFuncName(const conststr &funcname)
Extract the function name from its signature.
Definition: util.h:350
A type which stores a value possibly known at compile-time.
Definition: util.h:145
static_or_dynamic(T val)
Constructor with an explicit value.
Definition: util.h:160
A constexpr string type.
Definition: conststr.h:54
store_if_enabled(Args...)
Constructor.
Definition: util.h:230
STL class.