Tomographer  v2.0
Tomographer C++ Framework Documentation
needownoperatornew.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_TOOLS_NEEDOWNOPERATORNEW_H
28 #define TOMOGRAPHER_TOOLS_NEEDOWNOPERATORNEW_H
29 
38 #include <type_traits>
39 
40 #include <Eigen/Eigen> // EIGEN_MAKE_ALIGNED_OPERATOR_NEW
41 
42 #include <tomographer2/tools/cxxutil.h> // tomo_internal::sfinae_yes, tomo_internal::sfinae_no
43 
44 
45 namespace Tomographer {
46 namespace Tools {
47 
57  template<typename T>
59 };
60 
61 
62 namespace tomo_internal {
63 
64 // see http://stackoverflow.com/a/9154394/1694896
65 template<typename T> static auto test_has_ownopnewprovidertype_member(int)
66  -> typename sfinae_yes<typename T::OperatorNewProviderType>::yes&;
67 template<typename T> static auto test_has_ownopnewprovidertype_member(long)
68  -> typename sfinae_no<>::no&;
69 template<typename T>
70 struct has_ownopnewprovidertype_member {
71  static constexpr bool value = (sizeof(tomo_internal::test_has_ownopnewprovidertype_member<T>(0))
72  == sizeof(typename tomo_internal::sfinae_yes<>::yes));
73 };
74 template<bool has_own_provider, typename T>
75 struct need_own_op_new_prov_helper {
76  typedef NoSpecialOperatorNewProvider ProviderType;
77 };
78 template<typename T>
79 struct need_own_op_new_prov_helper<true, T> {
80  typedef typename T::OperatorNewProviderType ProviderType;
81 };
82 } // namespace tomo_internal
83 
84 
114 template<typename... Types>
116  // will be specialized appropriately.
117 };
118 
119 
123 template<typename T>
125  typedef typename tomo_internal::need_own_op_new_prov_helper<
127  T
129  ProviderType;
130 
131  typedef typename ProviderType::template OperatorNewAllocatorType<T>::Type AllocatorType;
132 };
133 
134 
135 
136 
137 //
138 // for Eigen types
139 //
140 
145 public:
146  EIGEN_MAKE_ALIGNED_OPERATOR_NEW ;
148 
149  template<typename T> struct OperatorNewAllocatorType {
151  };
152 
153 #ifdef TOMOGRAPHER_TEST_TOOLS_NEEDOWNOPERATORNEW_DEBUG_MEMBERS
154  // DEBUG: provide something we can test that it is indeed eigen-aligned
156  : EigenAlignedOperatorNewIsActive(true)
157  {
158  }
159  const bool EigenAlignedOperatorNewIsActive;
160 #endif
161 };
162 
163 
166 
167  // prevent inadvertently inheriting this class instead of
168  // EigenAlignedOperatorNewProvider:
169  NeedEigenAlignedOperatorNew() = delete;
170 };
171 
172 
173 template<typename Scalar, int FixedRows, int FixedCols, int Options, int MaxRows, int MaxCols>
174 struct NeedOwnOperatorNew<Eigen::Matrix<Scalar,FixedRows,FixedCols,Options,MaxRows,MaxCols> >
175  : public NeedEigenAlignedOperatorNew { };
176 
177 template<typename Scalar, int FixedRows, int FixedCols, int Options, int MaxRows, int MaxCols>
178 struct NeedOwnOperatorNew<Eigen::Array<Scalar,FixedRows,FixedCols,Options,MaxRows,MaxCols> >
179  : public NeedEigenAlignedOperatorNew { };
180 
181 
182 
183 
184 //
185 // Dark magic for allowing a struct to have several members of possibly different struct
186 // types (such as a ValueCalculator and a HistogramTypes), each of which might possibly
187 // require their own operator-new-providers; those super-structures should inherit from
188 // NeedOwnOperatorNew<Type1,Type2,Type3,...>::ProviderType , which resolves to the
189 // provider-type of all these types if they are the same (or if they don't require a
190 // provider-type).
191 //
192 
193 template<typename Type1, typename Type2, typename... OtherTypes>
194 struct NeedOwnOperatorNew<Type1, Type2, OtherTypes...>;
195 
196 
197 namespace tomo_internal {
198 
199 template<bool same_provider_type, bool t1_trivial_provider, bool t2_trivial_provider,
200  typename Type1, typename Type2, typename... OtherTypes>
201 struct need_own_operator_new_combination_helper {
202  // missing ProviderType member, will generate runtime error.
203  static_assert(!same_provider_type && !t1_trivial_provider && !t2_trivial_provider,
204  "ERROR: you have a type which requested a NeedOwnOperatorNew<T1,T2> "
205  "with incompatible needs.") ;
206 };
207 // case same_provider_type == true
208 template<bool t1_trivial_provider, bool t2_trivial_provider,
209  typename Type1, typename Type2, typename... OtherTypes>
210 struct need_own_operator_new_combination_helper<true, t1_trivial_provider, t2_trivial_provider,
211  Type1, Type2, OtherTypes...> {
212  // Type1 and Type2 have same provider, all ok, so continue and recurse on the other types:
213  typedef typename NeedOwnOperatorNew<Type1, OtherTypes...>::ProviderType ProviderType;
214 };
215 // case t1_trivial_provider == true
216 template<bool t2_trivial_provider,
217  typename Type1, typename Type2, typename... OtherTypes>
218 struct need_own_operator_new_combination_helper<false, true, t2_trivial_provider,
219  Type1, Type2, OtherTypes...> {
220  // all ok, use Type2's provider, and recurse on the other types
221  typedef typename NeedOwnOperatorNew<Type2, OtherTypes...>::ProviderType ProviderType;
222 };
223 // case t2_trivial_provider == true (and t1_trivial_provider == false, otherwise see case above)
224 template<typename Type1, typename Type2, typename... OtherTypes>
225 struct need_own_operator_new_combination_helper<false, false, true,
226  Type1, Type2, OtherTypes...> {
227  // all ok, use Type2's provider, and recurse on the other types
228  typedef typename NeedOwnOperatorNew<Type1, OtherTypes...>::ProviderType ProviderType;
229 };
230 
231 
232 } // namespace tomo_internal
233 
234 
235 template<typename Type1, typename Type2, typename... OtherTypes>
236 struct NeedOwnOperatorNew<Type1, Type2, OtherTypes...>
237 {
238  typedef tomo_internal::need_own_operator_new_combination_helper<
241  std::is_same<typename NeedOwnOperatorNew<Type1>::ProviderType,
245  Type1, Type2, OtherTypes...
246  > ProviderType;
247 };
248 
249 
250 
251 
252 
253 } // namespace Tools
254 } // namespace Tomographer
255 
256 
257 
258 #endif
Provides correct operator-new implementation for Eigen types via the NeedOwnOperatorNew mechanism...
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 class.
Some C++ utilities, with a tad of C++11 tricks.
VarValueDecoder< T >::RetType value(const Var &var)
Access the value of the given variable, as a C++ type.
Definition: ezmatio.h:854
Provider for regular types which don&#39;t need any special operator-new implementation (see NeedOwnOpera...