timemory  3.2.1
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
lightweight_tuple.hpp
Go to the documentation of this file.
1 // MIT License
2 //
3 // Copyright (c) 2020, The Regents of the University of California,
4 // through Lawrence Berkeley National Laboratory (subject to receipt of any
5 // required approvals from the U.S. Dept. of Energy). All rights reserved.
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //
25 
26 /** \file timemory/variadic/lightweight_tuple.hpp
27  * This is the C++ class that bundles together components and enables
28  * operation on the components as a single entity
29  *
30  */
31 
32 #pragma once
33 
34 #include "timemory/backends/dmp.hpp"
36 #include "timemory/mpl/apply.hpp"
37 #include "timemory/mpl/filters.hpp"
41 #include "timemory/tpls/cereal/cereal.hpp"
47 
48 #include <cstdint>
49 #include <cstdio>
50 #include <fstream>
51 #include <functional>
52 #include <iomanip>
53 #include <ios>
54 #include <iostream>
55 #include <string>
56 
57 namespace tim
58 {
59 /// \class tim::lightweight_tuple
60 /// \tparam Types Specification of the component types to bundle together
61 ///
62 /// \brief This is a variadic component wrapper which provides the least amount of
63 /// runtime and compilation overhead.
64 ///
65 ///
66 template <typename... Types>
68 : public stack_bundle<mpl::available_t<type_list<Types...>>>
70 {
71 protected:
74  using impl_type = typename bundle_type::impl_type;
75 
76  template <typename... Tp>
77  friend class impl::base_bundle;
78 
79 public:
81 
82  using this_type = lightweight_tuple<Types...>;
83  using type_list_type = type_list<Types...>;
84 
86  using tuple_type = typename bundle_type::tuple_type;
87  using sample_type = typename bundle_type::sample_type;
88  using reference_type = typename bundle_type::reference_type;
89  using user_bundle_types = typename bundle_type::user_bundle_types;
90 
91  using size_type = typename bundle_type::size_type;
92  using string_t = typename bundle_type::string_t;
93 
94  template <template <typename> class Op, typename Tuple = impl_type>
95  using operation_t = typename bundle_type::template generic_operation<Op, Tuple>::type;
96 
97  template <template <typename> class Op, typename Tuple = impl_type>
99  typename bundle_type::template custom_operation<Op, Tuple>::type;
100 
104  using initializer_type = std::function<void(this_type&)>;
106 
107  static constexpr bool has_gotcha_v = bundle_type::has_gotcha_v;
108  static constexpr bool has_user_bundle_v = bundle_type::has_user_bundle_v;
109 
110 public:
112  {
113  static initializer_type _instance = [](this_type&) {};
114  return _instance;
115  }
116 
117  template <typename T, typename... U>
118  using quirk_config = tim::variadic::impl::quirk_config<T, type_list<Types...>, U...>;
119 
120 public:
121  lightweight_tuple() = default;
122 
123  template <typename... T>
124  explicit lightweight_tuple(const string_t& key, quirk::config<T...> = {},
126 
127  template <typename... T>
130 
131  template <typename... T>
132  explicit lightweight_tuple(size_t _hash, quirk::config<T...> = {},
134 
135  explicit lightweight_tuple(size_t _hash, scope::config _scope,
137 
138  explicit lightweight_tuple(const string_t& key, scope::config _scope,
140 
141  explicit lightweight_tuple(const captured_location_t& loc, scope::config _scope,
143 
145 
146  //------------------------------------------------------------------------//
147  // Copy construct and assignment
148  //------------------------------------------------------------------------//
150  lightweight_tuple(lightweight_tuple&&) noexcept = default;
151 
152  lightweight_tuple& operator=(const lightweight_tuple& rhs) = default;
153  lightweight_tuple& operator=(lightweight_tuple&&) noexcept = default;
154 
155  lightweight_tuple clone(bool store, scope::config _scope = scope::get_default());
156 
157 public:
158  //----------------------------------------------------------------------------------//
159  // public static functions
160  //
161  static constexpr std::size_t size() { return std::tuple_size<tuple_type>::value; }
162  /// requests the component initialize their storage
163  static void init_storage();
164 
165  //----------------------------------------------------------------------------------//
166  // public member functions
167  //
168  this_type& push();
169  this_type& pop();
170  template <typename... Args>
171  this_type& measure(Args&&...);
172  template <typename... Args>
173  this_type& sample(Args&&...);
174  template <typename... Args>
175  this_type& start(Args&&...);
176  template <typename... Args>
177  this_type& stop(Args&&...);
178  template <typename... Args>
179  this_type& record(Args&&...);
180  template <typename... Args>
181  this_type& reset(Args&&...);
182  template <typename... Args>
183  auto get(Args&&...) const;
184  template <typename... Args>
185  auto get_labeled(Args&&...) const;
186  data_type& data();
187  const data_type& data() const;
189 
190  using bundle_type::get_prefix;
191  using bundle_type::get_scope;
192  using bundle_type::get_store;
193  using bundle_type::hash;
194  using bundle_type::key;
195  using bundle_type::laps;
196  using bundle_type::prefix;
197  using bundle_type::store;
198 
199  /// when chaining together operations, this function enables executing a function
200  /// inside the chain
201  template <typename FuncT, typename... Args>
202  decltype(auto) execute(FuncT&& func, Args&&... args)
203  {
204  return mpl::execute(*this,
205  std::forward<FuncT>(func)(std::forward<Args>(args)...));
206  }
207 
208  //----------------------------------------------------------------------------------//
209  /// construct the objects that have constructors with matching arguments
210  //
211  template <typename... Args>
212  this_type& construct(Args&&... _args)
213  {
214  using construct_t = operation_t<operation::construct>;
215  apply_v::access<construct_t>(m_data, std::forward<Args>(_args)...);
216  return *this;
217  }
218 
219  //----------------------------------------------------------------------------------//
220  /// provide preliminary info to the objects with matching arguments. This is typically
221  /// used to notify a component that it has been bundled alongside another component
222  /// that it can extract data from.
223  //
225 
226  template <typename... Args, size_t N = sizeof...(Args), enable_if_t<N != 0, int> = 0>
227  this_type& assemble(Args&&... _args)
228  {
229  invoke::assemble(m_data, std::forward<Args>(_args)...);
230  return *this;
231  }
232 
233  //----------------------------------------------------------------------------------//
234  /// provide conclusive info to the objects with matching arguments. This is typically
235  /// used by components to extract data from another component it has been bundled
236  /// alongside, e.g. the cpu_util component can extract data from \ref
237  /// tim::component::wall_clock and \ref tim::component::cpu_clock
238  //
240 
241  template <typename... Args, size_t N = sizeof...(Args), enable_if_t<N != 0, int> = 0>
242  this_type& derive(Args&&... _args)
243  {
244  invoke::derive(m_data, std::forward<Args>(_args)...);
245  return *this;
246  }
247 
248  //----------------------------------------------------------------------------------//
249  /// mark a beginning position in the execution (typically used by asynchronous
250  /// structures)
251  //
252  template <typename... Args>
253  this_type& mark_begin(Args&&... _args)
254  {
255  invoke::mark_begin(m_data, std::forward<Args>(_args)...);
256  return *this;
257  }
258 
259  //----------------------------------------------------------------------------------//
260  /// mark a beginning position in the execution (typically used by asynchronous
261  /// structures)
262  //
263  template <typename... Args>
264  this_type& mark_end(Args&&... _args)
265  {
266  invoke::mark_end(m_data, std::forward<Args>(_args)...);
267  return *this;
268  }
269 
270  //----------------------------------------------------------------------------------//
271  /// store a value
272  //
273  template <typename... Args>
274  this_type& store(Args&&... _args)
275  {
276  invoke::store(m_data, std::forward<Args>(_args)...);
277  return *this;
278  }
279 
280  //----------------------------------------------------------------------------------//
281  /// allow the components to inspect the incoming arguments before start
282  /// or out-going return value before returning (typically using in GOTCHA components)
283  //
284  template <typename... Args>
285  this_type& audit(Args&&... _args)
286  {
287  invoke::audit(m_data, std::forward<Args>(_args)...);
288  return *this;
289  }
290 
291  //----------------------------------------------------------------------------------//
292  /// apply a user-defined operation to all the components
293  /// \tparam OpT Operation struct
294  //
295  template <template <typename> class OpT, typename... Args>
296  this_type& invoke(Args&&... _args)
297  {
298  invoke::invoke<OpT>(m_data, std::forward<Args>(_args)...);
299  return *this;
300  }
301 
302  //----------------------------------------------------------------------------------//
303  /// generic member function for invoking user-provided operations on a specific
304  /// set of component types
305  /// \tparam OpT Operation struct
306  //
307  template <template <typename> class OpT, typename... Tp, typename... Args>
309  {
311  this->get<Tp>(), std::forward<Args>(_args)...));
312  return *this;
313  }
314 
315  //----------------------------------------------------------------------------------//
316  /// get member functions taking either a type
317  //
318  template <typename T, enable_if_t<is_one_of<T, data_type>::value, int> = 0>
319  T* get()
320  {
321  return &(std::get<index_of<T, data_type>::value>(m_data));
322  }
323 
324  template <typename T, enable_if_t<is_one_of<T, data_type>::value, int> = 0>
325  const T* get() const
326  {
327  return &(std::get<index_of<T, data_type>::value>(m_data));
328  }
329 
330  template <typename T, enable_if_t<!is_one_of<T, data_type>::value, int> = 0>
331  T* get() const
332  {
333  void* ptr = nullptr;
334  get(ptr, typeid_hash<T>());
335  return static_cast<T*>(ptr);
336  }
337 
338  this_type& get(void*& ptr, size_t _hash) const
339  {
340  using get_t = operation_t<operation::get>;
341  apply_v::access<get_t>(m_data, ptr, _hash);
342  return const_cast<this_type&>(*this);
343  }
344 
345  //----------------------------------------------------------------------------------//
346  /// this is a simple alternative to get<T>() when used from SFINAE in operation
347  /// namespace which has a struct get also templated. Usage there can cause error
348  /// with older compilers
349  template <typename U, typename T = std::remove_pointer_t<decay_t<U>>,
350  enable_if_t<trait::is_available<T>::value && is_one_of<T, data_type>::value,
351  int> = 0>
353  {
354  return get<T>();
355  }
356 
357  //----------------------------------------------------------------------------------//
358 
359  template <
360  typename T, typename... Args,
362  bool init(Args&&...)
363  {
364  using bundle_t = decltype(std::get<0>(std::declval<user_bundle_types>()));
365  this->init<bundle_t>();
366  this->get<bundle_t>()->insert(component::factory::get_opaque<T>(m_scope),
367  component::factory::get_typeids<T>());
368  return true;
369  }
370 
371  //----------------------------------------------------------------------------------//
372 
373  template <
374  typename T, typename... Args,
376  bool init(Args&&...)
377  {
379  }
380 
381  //----------------------------------------------------------------------------------//
382  /// variadic initialization
383  //
384  template <typename... T, typename... Args>
385  auto initialize(Args&&... args)
386  {
387  constexpr auto N = sizeof...(T);
388  return TIMEMORY_FOLD_EXPANSION(bool, N,
389  this->init<T>(std::forward<Args>(args)...));
390  }
391 
392  //----------------------------------------------------------------------------------//
393  /// apply a member function to a type that is in variadic list AND is available
394  ///
395  template <typename T, typename Func, typename... Args,
397  this_type& type_apply(Func&& _func, Args&&... _args)
398  {
399  auto&& _obj = get<T>();
400  ((_obj).*(_func))(std::forward<Args>(_args)...);
401  return *this;
402  }
403 
404  template <typename T, typename Func, typename... Args,
406  this_type& type_apply(Func&&, Args&&...)
407  {
408  return *this;
409  }
410 
411  //----------------------------------------------------------------------------------//
412  // this_type operators
413  //
414  this_type& operator-=(const this_type& rhs);
416  this_type& operator+=(const this_type& rhs);
418 
419  //----------------------------------------------------------------------------------//
420  // generic operators
421  //
422  template <typename Op>
424  {
425  using minus_t = operation_t<operation::minus>;
426  apply_v::access<minus_t>(m_data, std::forward<Op>(rhs));
427  return *this;
428  }
429 
430  template <typename Op>
432  {
433  using plus_t = operation_t<operation::plus>;
434  apply_v::access<plus_t>(m_data, std::forward<Op>(rhs));
435  return *this;
436  }
437 
438  template <typename Op>
440  {
441  using multiply_t = operation_t<operation::multiply>;
442  apply_v::access<multiply_t>(m_data, std::forward<Op>(rhs));
443  return *this;
444  }
445 
446  template <typename Op>
448  {
449  using divide_t = operation_t<operation::divide>;
450  apply_v::access<divide_t>(m_data, std::forward<Op>(rhs));
451  return *this;
452  }
453 
454  //----------------------------------------------------------------------------------//
455  // friend operators
456  //
457  friend this_type operator+(const this_type& lhs, const this_type& rhs)
458  {
459  this_type tmp(lhs);
460  return tmp += rhs;
461  }
462 
463  friend this_type operator-(const this_type& lhs, const this_type& rhs)
464  {
465  this_type tmp(lhs);
466  return tmp -= rhs;
467  }
468 
469  template <typename Op>
470  friend this_type operator*(const this_type& lhs, Op&& rhs)
471  {
472  this_type tmp(lhs);
473  return tmp *= std::forward<Op>(rhs);
474  }
475 
476  template <typename Op>
477  friend this_type operator/(const this_type& lhs, Op&& rhs)
478  {
479  this_type tmp(lhs);
480  return tmp /= std::forward<Op>(rhs);
481  }
482 
483  //----------------------------------------------------------------------------------//
484  //
485  template <bool PrintPrefix = true, bool PrintLaps = true>
486  this_type& print(std::ostream& os, bool skip_wo_hash = true) const
487  {
488  using printer_t = typename bundle_type::print_type;
489  if(size() == 0)
490  return const_cast<this_type&>(*this);
491  if(m_hash == 0 && skip_wo_hash)
492  return const_cast<this_type&>(*this);
493  std::stringstream ss_data;
494  apply_v::access_with_indices<printer_t>(m_data, std::ref(ss_data), false);
495  IF_CONSTEXPR(PrintPrefix)
496  {
497  bundle_type::update_width();
498  auto _key = key();
499  if(_key.length() > 0)
500  {
501  std::stringstream ss_prefix;
502  std::stringstream ss_id;
503  ss_id << get_prefix() << " " << std::left << _key;
504  ss_prefix << std::setw(bundle_type::output_width()) << std::left
505  << ss_id.str() << " : ";
506  os << ss_prefix.str();
507  }
508  }
509  if(ss_data.str().length() > 0)
510  {
511  os << ss_data.str();
512  if(m_laps > 0 && PrintLaps)
513  os << " [laps: " << m_laps << "]";
514  }
515  return const_cast<this_type&>(*this);
516  }
517 
518  //----------------------------------------------------------------------------------//
519  //
520  friend std::ostream& operator<<(std::ostream& os, const this_type& obj)
521  {
522  obj.print<true, true>(os);
523  return os;
524  }
525 
526  //----------------------------------------------------------------------------------//
527  //
528  template <typename Archive>
529  void serialize(Archive& ar, const unsigned int)
530  {
531  std::string _key = {};
532  auto keyitr = get_hash_ids()->find(m_hash);
533  if(keyitr != get_hash_ids()->end())
534  _key = keyitr->second;
535 
536  ar(cereal::make_nvp("hash", m_hash), cereal::make_nvp("key", _key),
537  cereal::make_nvp("laps", m_laps));
538 
539  if(keyitr == get_hash_ids()->end())
540  {
541  auto _hash = add_hash_id(_key);
542  if(_hash != m_hash)
543  {
544  PRINT_HERE("Warning! Hash for '%s' (%llu) != %llu", _key.c_str(),
545  (unsigned long long) _hash, (unsigned long long) m_hash);
546  }
547  }
548 
549  ar.setNextName("data");
550  ar.startNode();
552  ar.finishNode();
553  }
554 
555 public:
556  int64_t laps() const { return bundle_type::laps(); }
557  std::string key() const { return bundle_type::key(); }
558  uint64_t hash() const { return bundle_type::hash(); }
559  bool& store() { return bundle_type::store(); }
560  const bool& store() const { return bundle_type::store(); }
561  auto prefix() const { return bundle_type::prefix(); }
562  auto get_prefix() const { return bundle_type::get_prefix(); }
563 
564  TIMEMORY_INLINE void rekey(const string_t& _key);
565  TIMEMORY_INLINE void rekey(const captured_location_t& _loc);
566  TIMEMORY_INLINE void rekey(uint64_t _hash);
567 
568 protected:
569  // protected member functions
571  const data_type& get_data() const;
572  void set_prefix(const string_t&) const;
573  void set_prefix(size_t) const;
574 
575 protected:
576  // objects
577  using bundle_type::m_config;
578  using bundle_type::m_hash;
579  using bundle_type::m_is_active;
580  using bundle_type::m_is_pushed;
581  using bundle_type::m_laps;
582  using bundle_type::m_scope;
583  using bundle_type::m_store;
585 };
586 
587 //
588 //----------------------------------------------------------------------------------//
589 //
590 template <typename... Types>
591 void
593 {
594  m_hash = add_hash_id(_key);
595  set_prefix(_key);
596 }
597 //
598 //----------------------------------------------------------------------------------//
599 //
600 template <typename... Types>
601 void
603 {
604  m_hash = _loc.get_hash();
605  set_prefix(_loc.get_hash());
606 }
607 //
608 //----------------------------------------------------------------------------------//
609 //
610 template <typename... Types>
611 void
613 {
614  m_hash = _hash;
615  set_prefix(_hash);
616 }
617 //
618 //======================================================================================//
619 
620 template <typename... Types>
621 auto
623  -> decltype(std::declval<lightweight_tuple<Types...>>().get())
624 {
625  return _obj.get();
626 }
627 
628 //--------------------------------------------------------------------------------------//
629 
630 template <typename... Types>
631 auto
633  -> decltype(std::declval<lightweight_tuple<Types...>>().get_labeled())
634 {
635  return _obj.get_labeled();
636 }
637 
638 //--------------------------------------------------------------------------------------//
639 
640 } // namespace tim
641 
642 //======================================================================================//
643 //
644 // std::get operator
645 //
646 namespace std
647 {
648 //--------------------------------------------------------------------------------------//
649 
650 template <std::size_t N, typename... Types>
651 typename std::tuple_element<N, std::tuple<Types...>>::type&
653 {
654  return get<N>(obj.data());
655 }
656 
657 //--------------------------------------------------------------------------------------//
658 
659 template <std::size_t N, typename... Types>
660 const typename std::tuple_element<N, std::tuple<Types...>>::type&
661 get(const ::tim::lightweight_tuple<Types...>& obj)
662 {
663  return get<N>(obj.data());
664 }
665 
666 //--------------------------------------------------------------------------------------//
667 
668 template <std::size_t N, typename... Types>
669 auto
671  -> decltype(get<N>(std::forward<::tim::lightweight_tuple<Types...>>(obj).data()))
672 {
673  using obj_type = ::tim::lightweight_tuple<Types...>;
674  return get<N>(std::forward<obj_type>(obj).data());
675 }
676 
677 //======================================================================================//
678 } // namespace std
679 
680 //--------------------------------------------------------------------------------------//
This is a variadic component wrapper which provides the least amount of runtime and compilation overh...
data_type & get_data()
lightweight_tuple clone(bool store, scope::config _scope=scope::get_default())
this_type & assemble()
provide preliminary info to the objects with matching arguments. This is typically used to notify a c...
static constexpr std::size_t size()
this_type & get(void *&ptr, size_t _hash) const
this_type & print(std::ostream &os, bool skip_wo_hash=true) const
mpl::append_type_t< quirk::auto_start, this_type > auto_type
this_type & operator-=(Op &&rhs)
void set_prefix(const string_t &) const
static initializer_type & get_initializer()
this_type & mark_begin(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
this_type & type_apply(Func &&_func, Args &&... _args)
apply a member function to a type that is in variadic list AND is available
this_type & operator-=(const this_type &rhs)
void serialize(Archive &ar, const unsigned int)
static constexpr bool has_gotcha_v
convert_t< tuple_type, lightweight_tuple<> > type
T * get()
get member functions taking either a type
typename bundle_type::tuple_type tuple_type
typename bundle_type::reference_type reference_type
this_type & stop(Args &&...)
this_type & measure(Args &&...)
lightweight_tuple(lightweight_tuple &&) noexcept=default
typename bundle_type::data_type data_type
const bool & store() const
this_type & type_apply(Func &&, Args &&...)
auto get(Args &&...) const
this_type & invoke(mpl::piecewise_select< Tp... >, Args &&... _args)
generic member function for invoking user-provided operations on a specific set of component types
this_type & construct(Args &&... _args)
construct the objects that have constructors with matching arguments
mpl::remove_type_t< quirk::auto_start, this_type > component_type
tim::variadic::impl::quirk_config< T, type_list< Types... >, U... > quirk_config
this_type & operator+=(const this_type &rhs)
this_type & operator/=(Op &&rhs)
const data_type & get_data() const
decltype(auto) execute(FuncT &&func, Args &&... args)
when chaining together operations, this function enables executing a function inside the chain
this_type & reset(Args &&...)
friend this_type operator/(const this_type &lhs, Op &&rhs)
auto get_component()
this is a simple alternative to get<T>() when used from SFINAE in operation namespace which has a str...
std::function< void(this_type &)> initializer_type
this_type & derive()
provide conclusive info to the objects with matching arguments. This is typically used by components ...
lightweight_tuple< Types... > this_type
typename bundle_type::size_type size_type
source_location::captured captured_location_t
std::string key() const
utility::transient_function< void(this_type &)> transient_func_t
this_type & mark_end(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
this_type & sample(Args &&...)
this_type & start(Args &&...)
static constexpr bool has_user_bundle_v
static void init_storage()
requests the component initialize their storage
this_type & invoke(Args &&... _args)
apply a user-defined operation to all the components
typename bundle_type::template custom_operation< Op, Tuple >::type custom_operation_t
auto get_labeled(Args &&...) const
friend this_type operator*(const this_type &lhs, Op &&rhs)
typename bundle_type::user_bundle_types user_bundle_types
this_type & audit(Args &&... _args)
allow the components to inspect the incoming arguments before start or out-going return value before ...
typename bundle_type::template generic_operation< Op, Tuple >::type operation_t
this_type & operator*=(Op &&rhs)
typename bundle_type::sample_type sample_type
this_type & operator+=(Op &&rhs)
this_type & record(Args &&...)
friend this_type operator-(const this_type &lhs, const this_type &rhs)
friend this_type operator+(const this_type &lhs, const this_type &rhs)
lightweight_tuple(const lightweight_tuple &)=default
typename bundle_type::string_t string_t
this_type & set_scope(scope::config)
this_type & store(Args &&... _args)
store a value
typename bundle_type::impl_type impl_type
this_type & assemble(Args &&... _args)
auto initialize(Args &&... args)
variadic initialization
this_type & derive(Args &&... _args)
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
void rekey(const string_t &_key)
friend class impl::base_bundle
#define IF_CONSTEXPR(...)
Definition: language.hpp:72
std::string string_t
Definition: library.cpp:56
void assemble(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:850
void mark_begin(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:474
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:756
void audit(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:921
void store(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:546
auto serialize(ArchiveT &ar, TupleT< Tp... > &obj)
void derive(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:886
void mark_end(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:510
typename impl::remove_type< Tp, Types >::type remove_type_t
remove any instances of a type from a tuple/bundler
Definition: filters.hpp:392
typename impl::append_type< Tp, Types >::type append_type_t
append type to a tuple/bundler
Definition: filters.hpp:388
auto execute(BundleT &&_bundle, FuncT &&_func, Args &&... _args, enable_if_t< is_invocable< FuncT, Args... >::value &&!std::is_void< std::result_of_t< FuncT(Args...)>>::value, int >)
impl::filter_false< trait::is_available, T > available_t
Definition: available.hpp:324
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
Definition: kokkosp.cpp:38
std::string string_t
Definition: utility.hpp:105
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
Definition: types.hpp:190
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
hash_map_ptr_t & get_hash_ids()
tim::mpl::apply< std::string > string
Definition: macros.hpp:52
hash_value_t add_hash_id(hash_map_ptr_t &_hash_map, const string_view_t &_prefix)
add an string to the given hash-map (if it doesn't already exist) and return the hash
Definition: types.hpp:187
typename impl::is_one_of< Tp, Types > is_one_of
check if type is in expansion
Definition: types.hpp:738
auto get(const auto_bundle< Tag, Types... > &_obj)
typename impl::convert< T, U >::type convert_t
Definition: types.hpp:816
lightweight tuple-alternative for meta-programming logic
Definition: types.hpp:233
Declare the operations types.
The declaration for the types for settings without definitions.
Declare the storage types.
This operation class is similar to pointer_operator but can handle non-pointer types.
Definition: generic.hpp:55
a variadic type which holds zero or more quirks that are passed to the constructor of a component bun...
Definition: quirks.hpp:39
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
Definition: types.hpp:446
const hash_value_t & get_hash() const
convert_t< mpl::non_placeholder_t< mpl::non_quirk_t< type_list< Types... > >>, std::tuple<> > data_type
#define PRINT_HERE(...)
Definition: macros.hpp:147
#define TIMEMORY_FOLD_EXPRESSION(...)
Definition: types.hpp:55
#define TIMEMORY_FOLD_EXPANSION(TYPE, SIZE,...)
Definition: types.hpp:63