File indexing completed on 2025-01-18 09:58:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #if !defined(G4PROFILER_ICC_)
0034 # define G4PROFILER_ICC_ 1
0035
0036 # include <functional>
0037 # include <type_traits>
0038 # include <tuple>
0039 # include <initializer_list>
0040 # include <string>
0041 # include <sstream>
0042
0043
0044 # include "PTL/Globals.hh"
0045
0046 # if defined(GEANT4_USE_TIMEMORY)
0047 # include <timemory/utility/utility.hpp>
0048 # endif
0049
0050 # if !defined(GEANT4_FOLD_EXPRESSION)
0051 # define GEANT4_FOLD_EXPRESSION(...) \
0052 ::G4Impl::consume_parameters( \
0053 ::std::initializer_list<int>{ (__VA_ARGS__, 0)... })
0054 # endif
0055
0056 # if !defined(G4PROFILER_ARG_SET)
0057 # define G4PROFILER_ARG_SET(...) G4TypeList<__VA_ARGS__>
0058 # endif
0059
0060
0061
0062
0063
0064
0065
0066
0067 template <typename... Types>
0068 struct G4TypeList;
0069
0070
0071
0072 template <typename... Types>
0073 struct G4CommonTypeList;
0074
0075
0076
0077 template <typename... Types>
0078 struct G4TypeListSize;
0079
0080 template <typename... Types>
0081 struct G4TypeListSize<G4TypeList<Types...>>
0082 {
0083 static constexpr size_t value = sizeof...(Types);
0084 };
0085
0086 template <typename... Types>
0087 struct G4TypeListSize<std::tuple<Types...>>
0088 {
0089 static constexpr size_t value = std::tuple_size<std::tuple<Types...>>::value;
0090 };
0091
0092 namespace G4Impl
0093 {
0094 template <typename Tp>
0095 std::string demangle()
0096 {
0097 # if defined(GEANT4_USE_TIMEMORY)
0098 return tim::demangle<Tp>();
0099 # else
0100 return typeid(Tp).name();
0101 # endif
0102 }
0103
0104 template <typename... Tp>
0105 void consume_parameters(Tp&&...)
0106 {}
0107
0108
0109 template <typename RetT, typename... Tail>
0110 struct Functors;
0111
0112 template <typename RetT, typename... Tail>
0113 struct Functors<RetT, G4TypeList<Tail...>>
0114 {
0115 using type = std::function<RetT(Tail...)>;
0116 };
0117
0118 template <typename RetT, typename... CommonT, typename... Tail>
0119 struct Functors<RetT, G4CommonTypeList<CommonT...>, G4TypeList<Tail...>>
0120 {
0121 using type = std::function<RetT(CommonT..., Tail...)>;
0122 };
0123
0124 template <typename RetT, typename... Types, typename... Tail>
0125 struct Functors<RetT, G4TypeList<G4TypeList<Types...>, Tail...>>
0126 {
0127 using type = std::tuple<std::function<RetT(Types...)>,
0128 typename Functors<RetT, Tail>::type...>;
0129 };
0130
0131 template <typename RetT, typename... CommonT, typename... Types,
0132 typename... Tail>
0133 struct Functors<RetT, G4CommonTypeList<CommonT...>,
0134 G4TypeList<G4TypeList<Types...>, Tail...>>
0135 {
0136 using type = std::tuple<
0137 std::function<RetT(CommonT..., Types...)>,
0138 typename Functors<RetT, G4CommonTypeList<CommonT...>, Tail>::type...>;
0139 };
0140
0141 template <typename RetT, typename... Tail>
0142 using Functors_t = typename Functors<RetT, Tail...>::type;
0143
0144 }
0145
0146
0147
0148
0149 template <typename Type, typename FuncT, typename RetT = void>
0150 struct FuncHandler
0151 {
0152 using this_type = FuncHandler<Type, FuncT, RetT>;
0153
0154
0155 template <typename Tp>
0156 using decay_t = typename std::decay<Tp>::type;
0157 template <bool Bv, typename Tp = void>
0158 using enable_if_t = typename std::enable_if<Bv, Tp>::type;
0159 template <size_t... Idx>
0160 using index_sequence = PTL::mpl::index_sequence<Idx...>;
0161 template <size_t NumT>
0162 using make_index_sequence = PTL::mpl::make_index_sequence<NumT>;
0163
0164 static constexpr size_t size = std::tuple_size<FuncT>::value;
0165
0166 FuncHandler(FuncT& _functors)
0167 : m_functors(_functors)
0168 {}
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 template <typename Func>
0181 void operator=(Func&& f)
0182 {
0183 assign(m_functors, std::forward<Func>(f), 0, make_index_sequence<size>{});
0184 }
0185
0186 private:
0187 FuncT& m_functors;
0188
0189 template <typename Tp>
0190 static enable_if_t<std::is_same<decay_t<Tp>, bool>::value, Tp>
0191 get_default_return_value()
0192 {
0193 return false;
0194 }
0195
0196 template <typename Tp>
0197 static enable_if_t<std::is_same<decay_t<Tp>, std::string>::value, Tp>
0198 get_default_return_value()
0199 {
0200
0201
0202 return std::string("label-functor-not-set-for-") + G4Impl::demangle<Tp>();
0203 }
0204
0205 template <typename Tp>
0206 static enable_if_t<std::is_pointer<decay_t<Tp>>::value, Tp>
0207 get_default_return_value()
0208 {
0209 return nullptr;
0210 }
0211
0212 private:
0213 using return_t = decay_t<RetT>;
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
0243 enable_if_t<sizeof...(Tail) == 0, int> = 0>
0244 static auto invoke(Tp& _obj, int, index_sequence<Idx, Tail...>,
0245 Args&&... _args)
0246 -> decltype(std::get<Idx>(_obj)(std::forward<Args>(_args)...), return_t{})
0247 {
0248
0249 if(std::get<Idx>(_obj))
0250 return std::get<Idx>(_obj)(std::forward<Args>(_args)...);
0251 else
0252 {
0253 std::stringstream ss;
0254 ss << "Error! Functor "
0255 << G4Impl::demangle<decltype(std::get<Idx>(_obj))>()
0256 << " was not set for " << G4Impl::demangle<Type>();
0257 throw std::runtime_error(ss.str());
0258 }
0259
0260 return get_default_return_value<return_t>();
0261 }
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
0272 enable_if_t<sizeof...(Tail) == 0, int> = 0>
0273 static auto invoke(Tp&, long, index_sequence<Idx, Tail...>, Args&&...)
0274 -> return_t
0275 {
0276
0277
0278
0279
0280
0281 static_assert(!std::is_same<Tp, Tp>::value, "Error! No valid functor!");
0282 throw std::runtime_error(
0283 "Error! No valid functor! This should have caused a compilation error!");
0284 return return_t{};
0285 }
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295 template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
0296 enable_if_t<(sizeof...(Tail) > 0), int> = 0>
0297 static auto invoke(Tp& _obj, int, index_sequence<Idx, Tail...>,
0298 Args&&... _args)
0299 -> decltype(std::get<Idx>(_obj)(std::forward<Args>(_args)...), return_t{})
0300 {
0301 return std::get<Idx>(_obj)(std::forward<Args>(_args)...);
0302 }
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313 template <typename Tp, size_t Idx, size_t... Tail, typename... Args,
0314 enable_if_t<(sizeof...(Tail) > 0), int> = 0>
0315 static auto invoke(Tp& _obj, long, index_sequence<Idx, Tail...>,
0316 Args&&... _args)
0317 -> decltype(invoke(_obj, 0, index_sequence<Tail...>{},
0318 std::forward<Args>(_args)...))
0319 {
0320 return invoke(_obj, 0, index_sequence<Tail...>{},
0321 std::forward<Args>(_args)...);
0322 }
0323
0324 private:
0325
0326
0327 template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
0328 enable_if_t<sizeof...(Tail) == 0, int> = 0>
0329 static auto assign(LhsT& _lhs, RhsT&& _rhs, int, index_sequence<Idx, Tail...>)
0330 -> decltype((std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs)), void())
0331 {
0332 std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs);
0333 }
0334
0335
0336
0337 template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
0338 enable_if_t<sizeof...(Tail) == 0, int> = 0>
0339 static void assign(LhsT&, RhsT&&, long, index_sequence<Idx, Tail...>)
0340 {
0341
0342
0343
0344
0345
0346 static_assert(!std::is_same<LhsT, LhsT>::value,
0347 "Error! No valid functor assignment!");
0348 throw std::runtime_error(
0349 "Error! No valid functor! This should have caused a compilation error!");
0350 }
0351
0352
0353
0354 template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
0355 enable_if_t<(sizeof...(Tail) > 0), int> = 0>
0356 static auto assign(LhsT& _lhs, RhsT&& _rhs, int, index_sequence<Idx, Tail...>)
0357 -> decltype((std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs)), void())
0358 {
0359 std::get<Idx>(_lhs) = std::forward<RhsT>(_rhs);
0360 }
0361
0362
0363
0364 template <typename LhsT, typename RhsT, size_t Idx, size_t... Tail,
0365 enable_if_t<(sizeof...(Tail) > 0), int> = 0>
0366 static void assign(LhsT& _lhs, RhsT&& _rhs, long,
0367 index_sequence<Idx, Tail...>)
0368 {
0369 assign(_lhs, std::forward<RhsT>(_rhs), 0, index_sequence<Tail...>{});
0370 }
0371
0372 public:
0373
0374
0375
0376
0377
0378 template <typename... Args>
0379 auto operator()(Args&&... _args)
0380 -> decltype(std::declval<this_type>().invoke(std::declval<FuncT&>(), 0,
0381 make_index_sequence<size>{},
0382 std::forward<Args>(_args)...))
0383 {
0384 return invoke(m_functors, 0, make_index_sequence<size>{},
0385 std::forward<Args>(_args)...);
0386 }
0387 };
0388
0389
0390
0391 #endif