34 #include "timemory/backends/dmp.hpp"
41 #include "timemory/tpls/cereal/cereal.hpp"
66 template <
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; }
170 template <
typename... Args>
172 template <
typename... Args>
174 template <
typename... Args>
176 template <
typename... Args>
178 template <
typename... Args>
180 template <
typename... Args>
182 template <
typename... Args>
183 auto get(Args&&...)
const;
184 template <
typename... Args>
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;
201 template <
typename FuncT,
typename... Args>
202 decltype(
auto)
execute(FuncT&& func, Args&&... args)
205 std::forward<FuncT>(func)(std::forward<Args>(args)...));
211 template <
typename... Args>
215 apply_v::access<construct_t>(
m_data, std::forward<Args>(_args)...);
252 template <
typename... Args>
263 template <
typename... Args>
273 template <
typename... Args>
284 template <
typename... Args>
295 template <
template <
typename>
class OpT,
typename... Args>
298 invoke::invoke<OpT>(
m_data, std::forward<Args>(_args)...);
307 template <
template <
typename>
class OpT,
typename... Tp,
typename... Args>
311 this->get<Tp>(), std::forward<Args>(_args)...));
318 template <typename T, enable_if_t<is_one_of<T, data_type>::value,
int> = 0>
321 return &(std::get<index_of<T, data_type>::value>(
m_data));
324 template <typename T, enable_if_t<is_one_of<T, data_type>::value,
int> = 0>
327 return &(std::get<index_of<T, data_type>::value>(
m_data));
330 template <typename T, enable_if_t<!is_one_of<T, data_type>::value,
int> = 0>
334 get(ptr, typeid_hash<T>());
335 return static_cast<T*
>(ptr);
341 apply_v::access<get_t>(
m_data, ptr, _hash);
349 template <
typename U,
typename T = std::remove_po
inter_t<decay_t<U>>,
350 enable_if_t<trait::is_available<T>::value && is_one_of<T, data_type>::value,
360 typename T,
typename... Args,
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>());
374 typename T,
typename... Args,
384 template <
typename... T,
typename... Args>
387 constexpr
auto N =
sizeof...(T);
389 this->init<T>(std::forward<Args>(args)...));
395 template <
typename T,
typename Func,
typename... Args,
399 auto&& _obj = get<T>();
400 ((_obj).*(_func))(std::forward<Args>(_args)...);
404 template <
typename T,
typename Func,
typename... Args,
422 template <
typename Op>
426 apply_v::access<minus_t>(
m_data, std::forward<Op>(rhs));
430 template <
typename Op>
434 apply_v::access<plus_t>(
m_data, std::forward<Op>(rhs));
438 template <
typename Op>
442 apply_v::access<multiply_t>(
m_data, std::forward<Op>(rhs));
446 template <
typename Op>
450 apply_v::access<divide_t>(
m_data, std::forward<Op>(rhs));
469 template <
typename Op>
473 return tmp *= std::forward<Op>(rhs);
476 template <
typename Op>
480 return tmp /= std::forward<Op>(rhs);
485 template <
bool Pr
intPrefix = true,
bool Pr
intLaps = true>
488 using printer_t =
typename bundle_type::print_type;
491 if(m_hash == 0 && skip_wo_hash)
493 std::stringstream ss_data;
494 apply_v::access_with_indices<printer_t>(
m_data, std::ref(ss_data),
false);
497 bundle_type::update_width();
499 if(_key.length() > 0)
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();
509 if(ss_data.str().length() > 0)
512 if(m_laps > 0 && PrintLaps)
513 os <<
" [laps: " << m_laps <<
"]";
522 obj.
print<
true,
true>(os);
528 template <
typename Archive>
534 _key = keyitr->second;
536 ar(cereal::make_nvp(
"hash", m_hash), cereal::make_nvp(
"key", _key),
537 cereal::make_nvp(
"laps", m_laps));
544 PRINT_HERE(
"Warning! Hash for '%s' (%llu) != %llu", _key.c_str(),
545 (
unsigned long long) _hash, (
unsigned long long) m_hash);
549 ar.setNextName(
"data");
556 int64_t
laps()
const {
return bundle_type::laps(); }
558 uint64_t
hash()
const {
return bundle_type::hash(); }
561 auto prefix()
const {
return bundle_type::prefix(); }
562 auto get_prefix()
const {
return bundle_type::get_prefix(); }
566 TIMEMORY_INLINE
void rekey(uint64_t _hash);
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;
590 template <
typename... Types>
600 template <
typename... Types>
610 template <
typename... Types>
620 template <
typename... Types>
630 template <
typename... Types>
635 return _obj.get_labeled();
650 template <std::size_t N,
typename... Types>
651 typename std::tuple_element<N, std::tuple<Types...>>::type&
654 return get<N>(obj.
data());
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)
663 return get<N>(obj.data());
668 template <std::size_t N,
typename... Types>
674 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...
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...
lightweight_tuple()=default
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
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(...)
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
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
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
auto get_labeled(const auto_bundle< Tag, Types... > &_obj)
hash_map_ptr_t & get_hash_ids()
tim::mpl::apply< std::string > string
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
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.
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.
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,...)