Tomographer  v2.0
Tomographer C++ Framework Documentation
valuecalculator.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) 2016 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_VALUECALCULATOR_H
28 #define TOMOGRAPHER_VALUECALCULATOR_H
29 
30 
33 
34 
43 namespace Tomographer {
44 
45 
46 
47 namespace tomo_internal {
48 
49 //
50 // helper for getValue()
51 //
52 template<int NumValueCalculators, typename ValueType, typename... ValueCalculators>
53 struct MplxVC_getval_helper
54 {
55  template<typename PointType, int IterI = 0,
56  TOMOGRAPHER_ENABLED_IF_TMPL(IterI < NumValueCalculators)>
57  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
58  {
59  if (IterI == _i) {
60  return std::get<IterI>(_valcalcs).getValue(std::forward<PointType>(x));
61  }
62  return getValue<PointType, IterI+1>(_i, _valcalcs, std::forward<PointType>(x));
63  }
64  //
65  template<typename PointType, int IterI = 0,
66  TOMOGRAPHER_ENABLED_IF_TMPL(IterI == NumValueCalculators)>
67  static inline ValueType getValue(const int, const std::tuple<ValueCalculators...> & , PointType&& )
68  {
69  tomographer_assert(false && "Invalid i: i>=NumValueCalculators or i<0");
70  return ValueType();// silence ICC "missing return statement" warning
71  }
72 };
73 // a few specializations, for optimizing a chain of if's to a faster switch statement
74 template<typename ValueType, typename... ValueCalculators>
75 struct MplxVC_getval_helper<1, ValueType, ValueCalculators...>
76 {
77  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 1) ;
78  template<typename PointType>
79  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
80  {
81  tomographer_assert(_i == 0 && "i != 0 but NumValueCalculators == 1");(void)_i;
82  return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
83  }
84 };
85 //--
86 template<typename ValueType, typename... ValueCalculators>
87 struct MplxVC_getval_helper<2, ValueType, ValueCalculators...>
88 {
89  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 2) ;
90  template<typename PointType>
91  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
92  {
93  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
94  switch (_i) {
95  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
96  default: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
97  }
98  }
99 };
100 //--
101 template<typename ValueType, typename... ValueCalculators>
102 struct MplxVC_getval_helper<3, ValueType, ValueCalculators...>
103 {
104  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 3) ;
105  template<typename PointType>
106  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
107  {
108  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
109  switch (_i) {
110  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
111  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
112  default: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
113  }
114  }
115 };
116 //--
117 template<typename ValueType, typename... ValueCalculators>
118 struct MplxVC_getval_helper<4, ValueType, ValueCalculators...>
119 {
120  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 4) ;
121  template<typename PointType>
122  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
123  {
124  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
125  switch (_i) {
126  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
127  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
128  case 2: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
129  default: return std::get<3>(_valcalcs).getValue(std::forward<PointType>(x));
130  }
131  }
132 };
133 //--
134 template<typename ValueType, typename... ValueCalculators>
135 struct MplxVC_getval_helper<5, ValueType, ValueCalculators...>
136 {
137  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 5) ;
138  template<typename PointType>
139  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
140  {
141  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
142  switch (_i) {
143  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
144  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
145  case 2: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
146  case 3: return std::get<3>(_valcalcs).getValue(std::forward<PointType>(x));
147  default: return std::get<4>(_valcalcs).getValue(std::forward<PointType>(x));
148  }
149  }
150 };
151 //--
152 template<typename ValueType, typename... ValueCalculators>
153 struct MplxVC_getval_helper<6, ValueType, ValueCalculators...>
154 {
155  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 6) ;
156  template<typename PointType>
157  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
158  {
159  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
160  switch (_i) {
161  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
162  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
163  case 2: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
164  case 3: return std::get<3>(_valcalcs).getValue(std::forward<PointType>(x));
165  case 4: return std::get<4>(_valcalcs).getValue(std::forward<PointType>(x));
166  default: return std::get<5>(_valcalcs).getValue(std::forward<PointType>(x));
167  }
168  }
169 };
170 
171 } // namespace tomo_internal
172 
173 
174 
175 
176 
177 
183 template<typename ValueType_, typename... ValueCalculators>
185  : public virtual Tools::NeedOwnOperatorNew<ValueCalculators...>::ProviderType
186 {
187 public:
188  typedef ValueType_ ValueType;
189 
190  static constexpr int NumValueCalculators = sizeof...(ValueCalculators);
191  static constexpr int NumStaticallyOptimizedIfs = 6;
192 
193  // typedef std::tuple<ValueCalculators&...> ValueCalculatorsRefTupleType;
194  typedef std::tuple<ValueCalculators...> ValueCalculatorsTupleType;
195 
196 private:
197  ValueCalculatorsTupleType _valcalcs;
198 
199  const int _i;
200 
201 public:
202 
211  template<typename... Args>
212  inline MultiplexorValueCalculator(const int i, Args&&... valcalcs)
213  : _valcalcs(std::forward<Args>(valcalcs)...), _i(i)
214  {
215  }
216 
218  template<int I>
219  inline const typename std::tuple_element<I, ValueCalculatorsTupleType>::type & getValueCalculator() const
220  {
221  return std::get<I>(_valcalcs);
222  }
223 
225  template<int I, typename PointType>
226  inline ValueType getValueI(PointType&& x) const
227  {
228  return getValueCalculator<I>().getValue(std::forward<PointType>(x));
229  }
230 
236  template<typename PointType>
237  inline ValueType getValue(PointType&& x) const
238  {
239  return tomo_internal::MplxVC_getval_helper<
240  NumValueCalculators,ValueType,ValueCalculators...
241  >::getValue(_i, _valcalcs, std::forward<PointType>(x));
242  }
243 
244 };
245 
246 
247 
248 } // namespace Tomographer
249 
250 
251 
252 
253 #endif
A ValueCalculator-instance which the choice of which ValueCalculator to use at run-time.
#define TOMO_STATIC_ASSERT_EXPR(...)
Tool for static assertions without message.
Definition: cxxutil.h:59
Base namespace for the Tomographer project.
Definition: densellh.h:44
Provide appropriate operator new() definitions for a structure which has a member of the given stored...
STL namespace.
const std::tuple_element< I, ValueCalculatorsTupleType >::type & getValueCalculator() const
Get a particular value calculator [static index].
ValueType getValueI(PointType &&x) const
Calculate the value at the given point, using the I-th value calculator.
ValueType getValue(PointType &&x) const
The main method which computes the value according to the pre-chosen ValueCalculator.
Some C++ utilities, with a tad of C++11 tricks.
Managing the need for specific overrides to operator new() for some types (especially Eigen types) ...
MultiplexorValueCalculator(const int i, Args &&...valcalcs)
Constructor.