34#include "timemory/backends/dmp.hpp"
41#include "timemory/tpls/cereal/cereal.hpp"
66template <
typename... Types>
68:
public stack_bundle<mpl::available_t<type_list<Types...>>>
76 template <
typename... Tp>
94 template <
template <
typename>
class Op,
typename Tuple =
impl_type>
95 using operation_t =
typename bundle_type::template generic_operation<Op, Tuple>::type;
97 template <
template <
typename>
class Op,
typename Tuple =
impl_type>
99 typename bundle_type::template custom_operation<Op, Tuple>::type;
117 template <
typename T,
typename... U>
123 template <
typename... T>
127 template <
typename... T>
131 template <
typename... T>
161 static constexpr std::size_t
size() {
return std::tuple_size<tuple_type>::value; }
176 template <
typename... Tp>
180 template <
typename... Tp>
184 template <
typename... Tp>
188 template <
typename... Tp>
192 template <
typename... Args>
196 template <
typename... Tp,
typename... Args>
200 template <
typename... Tp,
typename... Args>
204 template <
typename... Args>
208 template <
typename... Tp,
typename... Args>
212 template <
typename... Tp,
typename... Args>
216 template <
typename... Args>
220 template <
typename... Args>
224 template <
typename... Args>
228 template <
typename... Args>
232 template <
typename... Args>
233 auto get(Args&&...)
const;
236 template <
typename... Args>
248 using bundle_type::get_prefix;
249 using bundle_type::get_scope;
250 using bundle_type::get_store;
251 using bundle_type::hash;
252 using bundle_type::key;
253 using bundle_type::laps;
254 using bundle_type::prefix;
259 template <
typename FuncT,
typename... Args>
260 decltype(
auto)
execute(FuncT&& func, Args&&... args)
263 std::forward<FuncT>(func)(std::forward<Args>(args)...));
268 template <
typename... Args>
272 apply_v::access<construct_t>(
m_data, std::forward<Args>(
_args)...);
273 return get_this_type();
286 return get_this_type();
300 return get_this_type();
306 template <
typename... Args>
310 return get_this_type();
316 template <
typename... Args>
320 return get_this_type();
324 template <
typename... Args>
328 return get_this_type();
334 template <
typename... Args>
338 return get_this_type();
343 template <
typename... Args>
346 return invoke<operation::add_secondary>(std::forward<Args>(
_args)...);
351 template <
typename... Args>
354 return invoke<operation::add_statistics>(std::forward<Args>(
_args)...);
359 template <
template <
typename>
class OpT,
typename... Args>
362 invoke::invoke<OpT>(
m_data, std::forward<Args>(
_args)...);
363 return get_this_type();
369 template <
template <
typename>
class OpT,
typename... Tp,
typename... Args>
373 std::forward<Args>(
_args)...);
374 return get_this_type();
380 template <
template <
typename>
class OpT,
typename... Tp,
typename... Args>
383 invoke_piecewise<OpT>(
385 std::forward<Args>(
_args)...);
386 return get_this_type();
390 template <typename T, enable_if_t<is_one_of<T, data_type>::value,
int> = 0>
393 return &(std::get<index_of<T, data_type>::value>(
m_data));
396 template <typename T, enable_if_t<is_one_of<T, data_type>::value,
int> = 0>
399 return &(std::get<index_of<T, data_type>::value>(
m_data));
402 template <typename T, enable_if_t<!is_one_of<T, data_type>::value,
int> = 0>
406 get(ptr, typeid_hash<T>());
407 return static_cast<T*
>(ptr);
413 apply_v::access<get_t>(
m_data, ptr, _hash);
414 return get_this_type();
418 template <
typename T,
typename FuncT>
419 decltype(
auto)
get(FuncT&& _func);
421 template <
typename T,
typename FuncT>
422 decltype(
auto)
get(FuncT&& _func)
const;
428 template <
typename U,
typename T = std::remove_po
inter_t<decay_t<U>>,
429 enable_if_t<trait::is_available<T>::value && is_one_of<T, data_type>::value,
439 typename T,
typename... Args,
443 using bundle_t =
decltype(std::get<0>(std::declval<user_bundle_types>()));
444 this->init<bundle_t>();
445 this->get<bundle_t>()->insert(component::factory::get_opaque<T>(m_scope),
446 component::factory::get_typeids<T>());
453 typename T,
typename... Args,
463 template <
typename... T,
typename... Args>
466 constexpr auto N =
sizeof...(T);
468 this->init<T>(std::forward<Args>(args)...));
474 template <
typename T,
typename Func,
typename... Args,
478 auto&& _obj = get<T>();
479 ((_obj).*(_func))(std::forward<Args>(
_args)...);
480 return get_this_type();
483 template <
typename T,
typename Func,
typename... Args,
487 return get_this_type();
501 template <
typename Op>
505 apply_v::access<minus_t>(
m_data, std::forward<Op>(rhs));
506 return get_this_type();
509 template <
typename Op>
513 apply_v::access<plus_t>(
m_data, std::forward<Op>(rhs));
514 return get_this_type();
517 template <
typename Op>
521 apply_v::access<multiply_t>(
m_data, std::forward<Op>(rhs));
522 return get_this_type();
525 template <
typename Op>
529 apply_v::access<divide_t>(
m_data, std::forward<Op>(rhs));
530 return get_this_type();
548 template <
typename Op>
552 return tmp *= std::forward<Op>(rhs);
555 template <
typename Op>
559 return tmp /= std::forward<Op>(rhs);
564 template <
bool Pr
intPrefix = true,
bool Pr
intLaps = true>
567 using printer_t =
typename bundle_type::print_type;
569 return get_this_type();
570 if(m_hash == 0 && skip_wo_hash)
571 return get_this_type();
572 std::stringstream ss_data;
573 apply_v::access_with_indices<printer_t>(
m_data, std::ref(ss_data),
false);
576 bundle_type::update_width();
578 if(_key.length() > 0)
580 std::stringstream ss_prefix;
581 std::stringstream ss_id;
582 ss_id <<
get_prefix() <<
" " << std::left << _key;
583 ss_prefix << std::setw(bundle_type::output_width()) << std::left
584 << ss_id.str() <<
" : ";
585 os << ss_prefix.str();
590 return get_this_type();
591 while(_s.find_last_of(
", ") == _s.length() - 1)
592 _s = _s.substr(0, _s.length() - 1);
594 return get_this_type();
596 if(m_laps > 0 && PrintLaps)
597 os <<
" [laps: " << m_laps <<
"]";
598 return get_this_type();
611 template <
typename Archive>
617 _key = keyitr->second;
619 ar(cereal::make_nvp(
"hash", m_hash), cereal::make_nvp(
"key", _key),
620 cereal::make_nvp(
"laps", m_laps));
627 PRINT_HERE(
"Warning! Hash for '%s' (%llu) != %llu", _key.c_str(),
628 (
unsigned long long) _hash, (
unsigned long long) m_hash);
632 ar.setNextName(
"data");
639 int64_t
laps()
const {
return bundle_type::laps(); }
641 uint64_t
hash()
const {
return bundle_type::hash(); }
644 auto prefix()
const {
return bundle_type::prefix(); }
645 auto get_prefix()
const {
return bundle_type::get_prefix(); }
649 TIMEMORY_INLINE
void rekey(uint64_t _hash);
661 using bundle_type::m_config;
662 using bundle_type::m_hash;
663 using bundle_type::m_is_active;
664 using bundle_type::m_is_pushed;
665 using bundle_type::m_laps;
666 using bundle_type::m_scope;
667 using bundle_type::m_store;
671 template <
template <
typename>
class OpT,
typename... Tp,
typename... Args>
675 this->get<Tp>(), std::forward<Args>(
_args)...));
688template <
typename... Types>
698template <
typename... Types>
708template <
typename... Types>
718template <
typename... Types>
719template <
typename T,
typename FuncT>
723 auto* _obj = this->get<T>();
725 return std::forward<FuncT>(_func)(_obj);
726 using return_type =
decltype(_func(std::declval<
decltype(_obj)>()));
728 if constexpr(std::is_void<decay_t<return_type>>::value)
730 else if constexpr(std::is_pointer<decay_t<return_type>>::value)
733 return decltype(_func(std::declval<
decltype(_obj)>())){};
735 return return_type();
741template <
typename... Types>
742template <
typename T,
typename FuncT>
746 auto* _obj = this->get<T>();
748 return std::forward<FuncT>(_func)(_obj);
749 using return_type =
decltype(_func(std::declval<
decltype(_obj)>()));
751 if constexpr(std::is_void<decay_t<return_type>>::value)
753 else if constexpr(std::is_pointer<decay_t<return_type>>::value)
754 return static_cast<decay_t<return_type>
>(
nullptr);
756 return decltype(_func(std::declval<
decltype(_obj)>())){};
758 return return_type();
765template <
typename... Types>
775template <
typename... Types>
780 return _obj.get_labeled();
795template <std::size_t N,
typename... Types>
796typename std::tuple_element<N, std::tuple<Types...>>::type&
799 return get<N>(obj.
data());
804template <std::size_t N,
typename... Types>
805const typename std::tuple_element<N, std::tuple<Types...>>::type&
806get(const ::tim::lightweight_tuple<Types...>& obj)
808 return get<N>(obj.data());
813template <std::size_t N,
typename... Types>
819 return get<N>(std::forward<obj_type>(obj).data());
This is a variadic component wrapper which provides the least amount of runtime and compilation overh...
static initializer_type & get_initializer()
lightweight_tuple clone(bool store, scope::config _scope=scope::get_default())
static constexpr std::size_t size()
mpl::append_type_t< quirk::auto_start, this_type > auto_type
this_type & operator-=(Op &&rhs)
this_type & measure(Args &&...)
generic
void set_prefix(const string_t &) const
this_type & invoke(Args &&... _args)
apply a user-defined operation to all the components
decltype(auto) get(FuncT &&_func) const
this_type & pop(mpl::piecewise_select< Tp... >)
selective pop
this_type & reset(Args &&...)
generic
this_type & operator-=(const this_type &rhs)
decltype(auto) get(FuncT &&_func)
get member functions finding component and applying lambda
void serialize(Archive &ar, const unsigned int)
static constexpr bool has_gotcha_v
friend std::ostream & operator<<(std::ostream &os, const this_type &obj)
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 & get(void *&ptr, size_t _hash) const
convert_t< tuple_type, lightweight_tuple<> > type
this_type & pop()
generic pop out of storage
this_type & store(Args &&... _args)
store a value
typename bundle_type::tuple_type tuple_type
typename bundle_type::reference_type reference_type
this_type & add_secondary(Args &&... _args)
perform an add_secondary operation. This operation allows components to add additional entries to sto...
typename bundle_type::data_type data_type
this_type & start(mpl::piecewise_select< Tp... >, Args &&...)
selective start
this_type & audit(Args &&... _args)
allow the components to inspect the incoming arguments before start or out-going return value before ...
this_type & stop(mpl::piecewise_select< Tp... >, Args &&...)
selective stop
this_type & assemble()
provide preliminary info to the objects with matching arguments. This is typically used to notify a c...
this_type & type_apply(Func &&, Args &&...)
auto get(Args &&...) const
generic
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 & print(std::ostream &os, bool skip_wo_hash=true) const
this_type & start(mpl::piecewise_ignore< Tp... >, Args &&...)
selective start
decltype(auto) execute(FuncT &&func, Args &&... args)
when chaining together operations, this function enables executing a function inside the chain
const bool & store() const
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...
lightweight_tuple()=default
std::function< void(this_type &)> initializer_type
this_type & assemble(Args &&... _args)
this_type & push(mpl::piecewise_select< Tp... >)
selective push
lightweight_tuple< Types... > this_type
typename bundle_type::size_type size_type
this_type & push()
generic push into storage
this_type & stop(mpl::piecewise_ignore< Tp... >, Args &&...)
selection stop
source_location::captured captured_location_t
utility::transient_function< void(this_type &)> transient_func_t
lightweight_tuple & operator=(lightweight_tuple &&)=default
this_type & mark_end(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
static constexpr bool has_user_bundle_v
static void init_storage()
requests the component initialize their storage
typename bundle_type::template custom_operation< Op, Tuple >::type custom_operation_t
auto get_labeled(Args &&...) const
generic
this_type & update_statistics(Args &&... _args)
perform an add_secondary operation. This operation allows components to add additional entries to sto...
friend this_type operator*(const this_type &lhs, Op &&rhs)
this_type & operator+=(Op &&rhs)
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 & stop(Args &&...)
stop all applicable components
typename bundle_type::user_bundle_types user_bundle_types
typename bundle_type::template generic_operation< Op, Tuple >::type operation_t
typename bundle_type::sample_type sample_type
this_type & construct(Args &&... _args)
construct the objects that have constructors with matching arguments
this_type & operator*=(Op &&rhs)
this_type & derive(Args &&... _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)
this_type & invoke(mpl::piecewise_ignore< Tp... >, Args &&... _args)
generic member function for invoking user-provided operations on a specific set of component types
this_type & pop(mpl::piecewise_ignore< Tp... >)
selective pop
lightweight_tuple(const lightweight_tuple &)=default
typename bundle_type::string_t string_t
this_type & mark_begin(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
lightweight_tuple & operator=(const lightweight_tuple &rhs)=default
this_type & operator/=(Op &&rhs)
this_type & set_scope(scope::config)
set scope configuration
typename bundle_type::impl_type impl_type
this_type & push(mpl::piecewise_ignore< Tp... >)
selective push
T * get()
get member functions taking either a type
data_type & data()
get tuple
auto initialize(Args &&... args)
variadic initialization
this_type & derive()
provide conclusive info to the objects with matching arguments. This is typically used by components ...
this_type & record(Args &&...)
generic
this_type & sample(Args &&...)
generic
lightweight_tuple(lightweight_tuple &&)=default
void rekey(const string_t &_key)
const data_type & get_data() const
this_type & start(Args &&...)
start all applicable components
friend class impl::base_bundle
#define IF_CONSTEXPR(...)
std::tuple_element< N, std::tuple< Types... > >::type & get(tim::auto_bundle< Tag, Types... > &obj)
hash_value_t add_hash_id(hash_map_ptr_t &_hash_map, string_view_cref_t _prefix)
add an string to the given hash-map (if it doesn't already exist) and return the hash
hash_map_ptr_t & get_hash_ids()
void assemble(TupleT< Tp... > &obj, Args &&... args)
void mark_begin(TupleT< Tp... > &obj, Args &&... args)
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
void audit(TupleT< Tp... > &obj, Args &&... args)
void store(TupleT< Tp... > &obj, Args &&... args)
auto serialize(ArchiveT &ar, TupleT< Tp... > &obj)
void derive(TupleT< Tp... > &obj, Args &&... args)
void mark_end(TupleT< Tp... > &obj, Args &&... args)
typename impl::remove_type< Tp, Types >::type remove_type_t
remove any instances of a type from a tuple/bundler
typename impl::append_type< Tp, Types >::type append_type_t
append type to a tuple/bundler
impl::filter_false< trait::is_available, T > available_t
typename impl::subtract< LhsT, RhsT >::type subtract_t
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 >)
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
std::array< char *, 4 > _args
typename std::decay< T >::type decay_t
Alias template for decay.
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
tim::mpl::apply< std::string > string
const std::string std::ostream * os
typename impl::is_one_of< Tp, Types > is_one_of
check if type is in expansion
auto get(const auto_bundle< Tag, Types... > &_obj)
typename impl::convert< T, U >::type convert_t
lightweight tuple-alternative for meta-programming logic
Declare the operations types.
Declare the storage types.
This operation class is similar to pointer_operator but can handle non-pointer types.
a variadic type which holds zero or more quirks that are passed to the constructor of a component bun...
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
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 TIMEMORY_FOLD_EXPRESSION(...)
#define TIMEMORY_FOLD_EXPANSION(TYPE, SIZE,...)