Loading [MathJax]/jax/output/HTML-CSS/config.js
Tomographerv4.1
Tomographer C++ Framework Documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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  * Copyright (c) 2017 Caltech, Institute for Quantum Information and Matter, Philippe Faist
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 #ifndef TOMOGRAPHER_VALUECALCULATOR_H
29 #define TOMOGRAPHER_VALUECALCULATOR_H
30 
31 
34 
35 
44 namespace Tomographer {
45 
46 
47 
48 namespace tomo_internal {
49 
50 //
51 // helper for getValue()
52 //
53 template<int NumValueCalculators, typename ValueType, typename... ValueCalculators>
54 struct MplxVC_getval_helper
55 {
56  template<typename PointType, int IterI = 0,
57  TOMOGRAPHER_ENABLED_IF_TMPL(IterI < NumValueCalculators)>
58  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
59  {
60  if (IterI == _i) {
61  return std::get<IterI>(_valcalcs).getValue(std::forward<PointType>(x));
62  }
63  return getValue<PointType, IterI+1>(_i, _valcalcs, std::forward<PointType>(x));
64  }
65  //
66  template<typename PointType, int IterI = 0,
67  TOMOGRAPHER_ENABLED_IF_TMPL(IterI == NumValueCalculators)>
68  static inline ValueType getValue(const int, const std::tuple<ValueCalculators...> & , PointType&& )
69  {
70  tomographer_assert(false && "Invalid i: i>=NumValueCalculators or i<0");
71  return ValueType();// silence ICC "missing return statement" warning
72  }
73 };
74 // a few specializations, for optimizing a chain of if's to a faster switch statement
75 template<typename ValueType, typename... ValueCalculators>
76 struct MplxVC_getval_helper<1, ValueType, ValueCalculators...>
77 {
78  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 1) ;
79  template<typename PointType>
80  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
81  {
82  tomographer_assert(_i == 0 && "i != 0 but NumValueCalculators == 1");(void)_i;
83  return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
84  }
85 };
86 //--
87 template<typename ValueType, typename... ValueCalculators>
88 struct MplxVC_getval_helper<2, ValueType, ValueCalculators...>
89 {
90  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 2) ;
91  template<typename PointType>
92  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
93  {
94  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
95  switch (_i) {
96  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
97  default: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
98  }
99  }
100 };
101 //--
102 template<typename ValueType, typename... ValueCalculators>
103 struct MplxVC_getval_helper<3, ValueType, ValueCalculators...>
104 {
105  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 3) ;
106  template<typename PointType>
107  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
108  {
109  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
110  switch (_i) {
111  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
112  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
113  default: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
114  }
115  }
116 };
117 //--
118 template<typename ValueType, typename... ValueCalculators>
119 struct MplxVC_getval_helper<4, ValueType, ValueCalculators...>
120 {
121  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 4) ;
122  template<typename PointType>
123  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
124  {
125  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
126  switch (_i) {
127  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
128  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
129  case 2: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
130  default: return std::get<3>(_valcalcs).getValue(std::forward<PointType>(x));
131  }
132  }
133 };
134 //--
135 template<typename ValueType, typename... ValueCalculators>
136 struct MplxVC_getval_helper<5, ValueType, ValueCalculators...>
137 {
138  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 5) ;
139  template<typename PointType>
140  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
141  {
142  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
143  switch (_i) {
144  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
145  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
146  case 2: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
147  case 3: return std::get<3>(_valcalcs).getValue(std::forward<PointType>(x));
148  default: return std::get<4>(_valcalcs).getValue(std::forward<PointType>(x));
149  }
150  }
151 };
152 //--
153 template<typename ValueType, typename... ValueCalculators>
154 struct MplxVC_getval_helper<6, ValueType, ValueCalculators...>
155 {
156  TOMO_STATIC_ASSERT_EXPR(sizeof...(ValueCalculators) == 6) ;
157  template<typename PointType>
158  static inline ValueType getValue(const int _i, const std::tuple<ValueCalculators...> & _valcalcs, PointType&& x)
159  {
160  tomographer_assert(_i >= 0 && _i < (int)sizeof...(ValueCalculators) && "i out of range");
161  switch (_i) {
162  case 0: return std::get<0>(_valcalcs).getValue(std::forward<PointType>(x));
163  case 1: return std::get<1>(_valcalcs).getValue(std::forward<PointType>(x));
164  case 2: return std::get<2>(_valcalcs).getValue(std::forward<PointType>(x));
165  case 3: return std::get<3>(_valcalcs).getValue(std::forward<PointType>(x));
166  case 4: return std::get<4>(_valcalcs).getValue(std::forward<PointType>(x));
167  default: return std::get<5>(_valcalcs).getValue(std::forward<PointType>(x));
168  }
169  }
170 };
171 
172 } // namespace tomo_internal
173 
174 
175 
176 
177 
178 
184 template<typename ValueType_, typename... ValueCalculators>
185 TOMOGRAPHER_EXPORT class MultiplexorValueCalculator
186  : public virtual Tools::NeedOwnOperatorNew<ValueCalculators...>::ProviderType
187 {
188 public:
189  typedef ValueType_ ValueType;
190 
191  static constexpr int NumValueCalculators = sizeof...(ValueCalculators);
192  static constexpr int NumStaticallyOptimizedIfs = 6;
193 
194  // typedef std::tuple<ValueCalculators&...> ValueCalculatorsRefTupleType;
195  typedef std::tuple<ValueCalculators...> ValueCalculatorsTupleType;
196 
197 private:
198  ValueCalculatorsTupleType _valcalcs;
199 
200  const int _i;
201 
202 public:
203 
212  template<typename... Args>
213  inline MultiplexorValueCalculator(const int i, Args&&... valcalcs)
214  : _valcalcs(std::forward<Args>(valcalcs)...), _i(i)
215  {
216  }
217 
219  template<int I>
220  inline const typename std::tuple_element<I, ValueCalculatorsTupleType>::type & getValueCalculator() const
221  {
222  return std::get<I>(_valcalcs);
223  }
224 
226  template<int I, typename PointType>
227  inline ValueType getValueI(PointType&& x) const
228  {
229  return getValueCalculator<I>().getValue(std::forward<PointType>(x));
230  }
231 
237  template<typename PointType>
238  inline ValueType getValue(PointType&& x) const
239  {
240  return tomo_internal::MplxVC_getval_helper<
241  NumValueCalculators,ValueType,ValueCalculators...
242  >::getValue(_i, _valcalcs, std::forward<PointType>(x));
243  }
244 
245 };
246 
247 
248 
249 } // namespace Tomographer
250 
251 
252 
253 
254 #endif
A ValueCalculator-instance which the choice of which ValueCalculator to use at run-time.
Base namespace for the Tomographer project.
Definition: densellh.h:45
MultiplexorValueCalculator(const int i, Args &&... valcalcs)
Constructor.
Provide appropriate operator new() definitions for a structure which has a member of the given stored...
STL namespace.
ValueType getValue(PointType &&x) const
The main method which computes the value according to the pre-chosen ValueCalculator.
const std::tuple_element< I, ValueCalculatorsTupleType >::type & getValueCalculator() const
Get a particular value calculator [static index].
#define TOMO_STATIC_ASSERT_EXPR(...)
Tool for static assertions without message.
Definition: cxxdefs.h:76
ValueType getValueI(PointType &&x) const
Calculate the value at the given point, using the I-th value calculator.
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) ...
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:83