50template <
typename... Tp>
110template <
typename Tag,
typename BundleT,
typename TupleT>
112:
public api_bundle<Tag, typename TupleT::available_type>
114 template <
typename U>
115 using remove_pointer_decay_t = std::remove_pointer_t<decay_t<U>>;
117 template <
typename... Tp>
118 friend class impl::base_bundle;
120 template <
typename... Tp>
123 template <
typename... Tp>
126 template <
typename... Tp>
129 template <
typename... Tp>
132#if defined(TIMEMORY_USE_DEPRECATED)
133 template <
typename TupleC,
typename ListC>
136 template <
typename TupleC,
typename ListC>
140 using internal_tag = tim::variadic::impl::internal_tag;
163 template <
typename T,
typename... U>
167 template <
typename U>
170 return std::is_same<decay_t<U>,
this_type>::value;
176 template <
typename... T>
178 transient_func_t = get_initializer());
180 template <
typename... T>
182 transient_func_t = get_initializer());
184 template <
typename... T>
186 transient_func_t = get_initializer());
188 template <
typename... T>
190 transient_func_t = get_initializer());
192 template <
typename... T>
194 transient_func_t = get_initializer());
198 transient_func_t = get_initializer());
202 transient_func_t = get_initializer());
204 explicit bundle(
const captured_location_t& _loc,
bool _store =
true,
206 transient_func_t = get_initializer());
209 transient_func_t = get_initializer());
212 transient_func_t = get_initializer());
215 transient_func_t = get_initializer());
229 template <typename Op, enable_if_t<!is_this_type<Op>()> = 0>
232 invoke::invoke<operation::minus, Tag>(m_data, std::forward<Op>(rhs));
233 return get_this_type();
236 template <typename Op, enable_if_t<!is_this_type<Op>()> = 0>
239 invoke::invoke<operation::plus, Tag>(m_data, std::forward<Op>(rhs));
240 return get_this_type();
243 template <typename Op, enable_if_t<!is_this_type<Op>()> = 0>
246 invoke::invoke<operation::multiply, Tag>(m_data, std::forward<Op>(rhs));
247 return get_this_type();
250 template <typename Op, enable_if_t<!is_this_type<Op>()> = 0>
253 invoke::invoke<operation::divide, Tag>(m_data, std::forward<Op>(rhs));
254 return get_this_type();
261 template <
typename Op>
268 template <
typename Op>
277 obj.print<
true,
true>(
os);
290 template <
typename U>
293 using T = remove_pointer_decay_t<U>;
298 template <
typename U>
301 using T = remove_pointer_decay_t<U>;
308 template <
typename U>
315 template <
typename U>
318 using T = remove_pointer_decay_t<U>;
319 return can_stack_init<T>() || can_heap_init<T>() || can_placement_init<T>() ||
326 template <
typename U>
329 using T = remove_pointer_decay_t<U>;
330 return can_init<T>() && !can_stack_init<T>();
337 template <
typename U>
340 using T = remove_pointer_decay_t<U>;
341 return !can_stack_init<T>() && !can_heap_init<T>() &&
349 template <
typename U,
typename... Args,
typename T = remove_pointer_decay_t<U>,
353 return std::is_constructible<T, Args...>::value;
357 template <
typename U,
typename... Args,
typename T = remove_pointer_decay_t<U>,
368 template <
typename U,
typename T = remove_po
inter_decay_t<U>,
369 enable_if_t<trait::is_available<T>::value> = 0>
372 return std::is_default_constructible<T>::value;
376 template <
typename U,
typename T = remove_po
inter_decay_t<U>,
377 enable_if_t<!trait::is_available<T>::value> = 0>
385 static void init_storage();
394 template <
typename... Tp>
398 template <
typename... Tp>
402 template <
typename... Tp>
406 template <
typename... Tp>
410 template <
typename... Tp>
414 template <
typename... Tp>
418 template <
typename... Args>
422 template <
typename... Args>
426 template <
typename... Args>
430 template <
typename... Args>
434 template <
typename... Args>
438 template <
typename... Args>
442 template <
typename... Args>
446 template <
typename... Args>
450 template <
typename... Tp,
typename... Args>
454 template <
typename... Tp,
typename... Args>
458 template <
typename... Tp,
typename... Args>
462 template <
typename... Tp,
typename... Args>
465 using bundle_type::get_prefix;
466 using bundle_type::get_scope;
467 using bundle_type::get_store;
468 using bundle_type::hash;
469 using bundle_type::key;
470 using bundle_type::laps;
471 using bundle_type::prefix;
472 using bundle_type::size;
476 static constexpr uint64_t fixed_count();
479 static constexpr uint64_t optional_count();
486 template <
typename FuncT,
typename... Args>
487 decltype(
auto)
execute(FuncT&& func, Args&&... args);
490 template <
typename... Args>
496 template <
typename... Args>
503 template <
typename... Args>
507 template <
typename... Args>
512 template <
typename... Args>
517 template <
typename... Args>
521 template <
typename... Args>
526 template <
typename... Args>
531 template <
typename... Args>
536 template <
typename... Args>
541 template <
template <
typename>
class OpT,
typename... Args>
547 template <
template <
typename>
class OpT,
typename... Tp,
typename... Args>
553 template <
template <
typename>
class OpT,
typename... Tp,
typename... Args>
556 template <
bool Pr
intPrefix = true,
bool Pr
intLaps = true>
560 template <
typename... Args>
561 auto get(Args&&...)
const;
564 template <
typename... Args>
574 template <
typename U>
578 template <
typename U>
579 decltype(
auto)
get()
const;
582 template <
typename U,
typename FuncT>
583 decltype(
auto)
get(FuncT&&);
586 template <
typename U,
typename FuncT>
587 decltype(
auto)
get(FuncT&&)
const;
621 template <
typename U>
627 template <
typename U>
634 template <
typename U>
641 template <
typename U>
649 template <
typename U,
typename T = remove_po
inter_decay_t<U>,
typename... Args>
653 T*& _obj = std::get<index_of<T*, data_type>::value>(m_data);
658 printf(
"[bundle::init]> initializing type '%s'...\n",
659 demangle<T>().c_str());
661 if(!bundle_type::init_buffer())
663 _obj =
new T(std::forward<Args>(
_args)...);
667 T in(std::forward<Args>(
_args)...);
668 _obj = m_buffer->write(&in).second;
675 static std::atomic<int> _count(0);
680 "[bundle::init]> skipping re-initialization of type"
690 template <
typename U,
typename T = remove_po
inter_decay_t<U>,
typename... Args>
693 enable_if_t<!is_constructible<T, Args...>() && is_default_constructible<T>(),
696 T*& _obj = std::get<index_of<T*, data_type>::value>(m_data);
701 fprintf(stderr,
"[bundle::init]> initializing type '%s'...\n",
702 demangle<T>().c_str());
704 if(!bundle_type::init_buffer())
711 _obj = m_buffer->write(&in).second;
718 static std::atomic<int> _count(0);
722 "[bundle::init]> skipping re-initialization of type "
724 demangle<T>().c_str());
731 template <
typename U,
typename T = remove_po
inter_decay_t<U>,
typename... Args>
736 static std::atomic<int> _count(0);
740 "[bundle::init]> type exists as a heap-allocated instance "
741 "and stack-allocated instance: \"%s\"...\n",
742 demangle<T>().c_str());
745 T& _obj = std::get<index_of<T, data_type>::value>(m_data);
754 template <
typename U,
typename T = remove_po
inter_decay_t<U>,
typename... Args>
757 using bundle_t =
decay_t<
decltype(
758 std::get<0>(std::declval<typename bundle_type::user_bundle_types>()))>;
760 this->init<bundle_t>();
761 auto* _bundle = this->get<bundle_t>();
764 _bundle->insert(component::factory::get_opaque<T>(m_scope),
765 component::factory::get_typeids<T>());
773 template <
typename U,
typename T = remove_po
inter_decay_t<U>,
typename... Args>
776 bundle_type::has_user_bundle_v),
786 template <
typename... T,
typename... Args>
787 std::array<bool,
sizeof...(T)>
initialize(Args&&... args);
790 template <
typename... Tail>
794 template <
typename T,
typename Func,
typename... Args,
798 auto* _obj = get<T>();
799 ((*_obj).*(_func))(std::forward<Args>(
_args)...);
800 return get_this_type();
804 template <
typename T,
typename Func,
typename... Args,
809 template <
typename T,
typename Func,
typename... Args,
818 TIMEMORY_INLINE
void rekey(
const string_t& _key);
820 TIMEMORY_INLINE
void rekey(uint64_t _hash);
832 template <
typename T>
833 void set_scope(T* obj, internal_tag)
const;
835 template <
typename T>
840 using bundle_type::m_buffer;
841 using bundle_type::m_config;
842 using bundle_type::m_enabled;
843 using bundle_type::m_hash;
844 using bundle_type::m_is_active;
845 using bundle_type::m_is_pushed;
846 using bundle_type::m_laps;
847 using bundle_type::m_scope;
848 using bundle_type::m_store;
852 this_type& get_this_type() {
return static_cast<this_type&
>(*this); }
853 this_type& get_this_type()
const
855 return const_cast<this_type&
>(
static_cast<const this_type&
>(*this));
858 static this_type*& get_last_instance()
860 static thread_local this_type* _instance =
nullptr;
864 static void update_last_instance(this_type* _new_instance,
865 this_type*& _old_instance = get_last_instance(),
866 bool _stop_last =
false)
868 if(_stop_last && _old_instance && _old_instance != _new_instance)
869 _old_instance->stop();
870 _old_instance = _new_instance;
873 template <
template <
typename>
class OpT,
typename... Tp,
typename... Args>
874 void invoke_piecewise(type_list<Tp...>, Args&&...
_args);
878 template <
typename Archive>
879 void serialize(Archive& ar,
const unsigned int);
884template <
typename Tag,
typename BundleT,
typename TupleT>
895template <
typename Tag,
typename BundleT,
typename TupleT>
905template <
typename Tag,
typename BundleT,
typename TupleT>
906template <
typename FuncT,
typename... Args>
911 std::forward<FuncT>(func)(std::forward<Args>(args)...));
916template <
typename Tag,
typename BundleT,
typename TupleT>
921 return tim::variadic::impl::get<U, Tag>(m_data);
926template <
typename Tag,
typename BundleT,
typename TupleT>
931 return tim::variadic::impl::get<U, Tag>(m_data);
936template <
typename Tag,
typename BundleT,
typename TupleT>
937template <
typename U,
typename FuncT>
941 auto* _obj = tim::variadic::impl::get<U, Tag>(m_data);
943 return std::forward<FuncT>(_func)(_obj);
944 using return_type =
decltype(_func(std::declval<
decltype(_obj)>()));
946 if constexpr(std::is_void<decay_t<return_type>>::value)
948 else if constexpr(std::is_pointer<decay_t<return_type>>::value)
949 return static_cast<decay_t<return_type>
>(
nullptr);
951 return decltype(_func(std::declval<
decltype(_obj)>())){};
953 return return_type();
959template <
typename Tag,
typename BundleT,
typename TupleT>
960template <
typename U,
typename FuncT>
964 auto* _obj = tim::variadic::impl::get<U, Tag>(m_data);
966 return std::forward<FuncT>(_func)(_obj);
967 using return_type =
decltype(_func(std::declval<
decltype(_obj)>()));
969 if constexpr(std::is_void<decay_t<return_type>>::value)
971 else if constexpr(std::is_pointer<decay_t<return_type>>::value)
972 return static_cast<decay_t<return_type>
>(
nullptr);
974 return decltype(_func(std::declval<
decltype(_obj)>())){};
976 return return_type();
982template <
typename Tag,
typename BundleT,
typename TupleT>
989 return get<remove_pointer_decay_t<U>>();
994template <
typename Tag,
typename BundleT,
typename TupleT>
1001 return get<remove_pointer_decay_t<U>>();
1006template <
typename Tag,
typename BundleT,
typename TupleT>
1007template <
typename U>
1013 return std::get<index_of<remove_pointer_decay_t<U>,
data_type>::value>(m_data);
1018template <
typename Tag,
typename BundleT,
typename TupleT>
1019template <
typename U>
1025 return std::get<index_of<remove_pointer_decay_t<U>*,
data_type>::value>(m_data);
1030template <
typename Tag,
typename BundleT,
typename TupleT>
1040template <
typename Tag,
typename BundleT,
typename TupleT>
1050template <
typename Tag,
typename BundleT,
typename TupleT>
This is a variadic component wrapper where all components are optional at runtime....
This is a variadic component wrapper where all components are allocated on the stack and cannot be di...
auto get(Args &&...) const
returns a tuple of invoking get() on all the components
static constexpr bool is_default_constructible()
Query at compile-time whether type supports default construction. If type is not available,...
typename TupleT::template data_type< Tag > data_type
this_type & record(Args &&...)
requests each component perform a measurement
bool init(Args &&... _args, enable_if_t< can_stack_init< T >(), int >=0)
try to re-create a stack object with provided arguments
typename TupleT::template component_type< BundleT > component_type
this_type & start(mpl::lightweight, Args &&...)
variant of start() which excludes push()
typename TupleT::type_list_type type_list_type
this_type & reset(Args &&...)
invokes reset member function on all the components
this_type & mark(Args &&... _args)
mark an atomic event
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 & push(mpl::piecewise_ignore< Tp... >)
selective push
this_type & audit(Args &&... _args)
allow the components to inspect the incoming arguments before start or out-going return value before ...
typename TupleT::template type< BundleT > type
auto get_labeled(Args &&...) const
returns a tuple of the component label + invoking get() on all the components
this_type & operator-=(Op &&rhs)
bundle(bundle &&)=default
tim::variadic::impl::quirk_config< T, reference_type, U... > quirk_config
enable_if_t< will_heap_init< T >() &&!will_opaque_init< T >(), bool > init(Args &&... _args, enable_if_t< is_constructible< T, Args... >(), int >=0)
create an optional type that is in variadic list AND is available AND accepts arguments
typename bundle_type::size_type size_type
this_type & disable()
delete any optional types currently allocated
static constexpr bool can_stack_init()
Query at compile-time whether initialization can occur on the stack.
static constexpr bool will_heap_init()
Query at compile-time whether initialization will occur on the heap. can_heap_init<T>() && !...
enable_if_t< will_heap_init< T >() &&!will_opaque_init< T >(), bool > init(Args &&..., enable_if_t<!is_constructible< T, Args... >() &&is_default_constructible< T >(), long >=0)
create an optional type that is in variadic list AND is available but is not constructible with provi...
this_type & mark_end(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
this_type & stop(mpl::piecewise_ignore< Tp... >, Args &&...)
variant of stop() which gets applied to non-Tp types
decltype(auto) execute(FuncT &&func, Args &&... args)
when chaining together operations, this function enables executing a function inside the chain
const data_type & get_data() const
static constexpr bool will_opaque_init()
Query at compile-time whether initialization will happen with an opaque wrapper (i....
this_type & start(Args &&...)
invokes start on all the components
bool init(Args &&..., enable_if_t< will_opaque_init< T >(), long >=0)
if a type is not in variadic list but a tim::component::user_bundle is available, add it in there
static constexpr bool has_user_bundle()
Query at compile-time whether a user_bundle exists in the set of components. user_bundle are more res...
friend this_type operator+(this_type lhs, const this_type &rhs)
this_type & stop(mpl::piecewise_select< Tp... >, Args &&...)
variant of stop() which only gets applied to Tp types
this_type & sample(Args &&...)
requests each component take a sample (if supported)
enable_if_t<!trait::is_available< T >::value||!(is_one_of< T *, data_type >::value||is_one_of< T, data_type >::value||bundle_type::has_user_bundle_v), bool > init(Args &&...)
do nothing if type not available, not one of the variadic types, and there is no user bundle availabl...
this_type & invoke(mpl::piecewise_ignore< Tp... >, Args &&... _args)
generic member function for invoking user-provided operations on all types that are not listed
this_type & mark_begin(Args &&... _args)
mark a beginning position in the execution (typically used by asynchronous structures)
decltype(auto) get(FuncT &&)
get a component from the bundle and apply function if the pointer is valid
this_type & start(mpl::piecewise_ignore< Tp... >, Args &&...)
variant of start() which gets applied to non-Tp types
this_type & store(Args &&... _args)
store a value
this_type & construct(Args &&... _args)
construct the objects that have constructors with matching arguments
this_type & start(mpl::piecewise_select< Tp... >, Args &&...)
variant of start() which only gets applied to Tp types
this_type & type_apply(Func &&_func, Args &&... _args)
apply a member function to a stack type that is in variadic list AND is available
this_type & add_secondary(Args &&... _args)
perform an add_secondary operation. This operation allows components to add additional entries to sto...
this_type & operator*=(Op &&rhs)
this_type & push(mpl::piecewise_ignore< Tp... >, scope::config)
selective push with scope configuration
typename bundle_type::string_t string_t
typename TupleT::template this_type< BundleT > this_type
this_type & assemble(Args &&... _args)
provide preliminary info to the objects with matching arguments. This is typically used to notify a c...
typename TupleT::reference_type reference_type
this_type & stop(Args &&...)
invokes stop on all the components
this_type & operator/=(Op &&rhs)
this_type & measure(Args &&...)
requests each component record a measurment
static constexpr bool is_this_type()
Query whether type matches this_type.
friend this_type operator-(this_type lhs, const this_type &rhs)
this_type & invoke(Args &&... _args)
generic member function for invoking user-provided operations
this_type & stop(mpl::lightweight, Args &&...)
variant of stop() which excludes pop()
this_type & derive(Args &&... _args)
provide conclusive info to the objects with matching arguments. This is typically used by components ...
bundle & operator=(bundle &&)=default
decltype(auto) get() const
get a component from the bundle
decltype(auto) get()
get a component from the bundle
static constexpr bool can_heap_init()
Query at compile-time whether initialization can occur on the heap.
friend enable_if_t<!std::is_arithmetic< Op >::value, this_type > operator*(this_type lhs, const Op &rhs)
static constexpr bool is_constructible()
Query at compile-time whether type can be constructed with the given argument types....
this_type & print(std::ostream &os, bool _endl=false) const
this_type & type_apply(Func &&, Args &&...)
ignore applying a member function because the type is not present
static constexpr bool can_init()
Query at compile-time whether the specified type can be initialized.
this_type & operator+=(Op &&rhs)
this_type & update_statistics(Args &&... _args)
perform an add_secondary operation. This operation allows components to add additional entries to sto...
this_type & push(mpl::piecewise_select< Tp... >, scope::config)
selective push with scope configuration
static constexpr bool can_placement_init()
Query at compile-time whether initialization can occur via a placement new. Placement new init allows...
std::function< void(this_type &)> initializer_type
this_type & pop(mpl::piecewise_ignore< Tp... >)
selective pop
this_type & push(mpl::piecewise_select< Tp... >)
selective push
this_type & pop(mpl::piecewise_select< Tp... >)
selective pop
friend enable_if_t<!std::is_arithmetic< Op >::value, this_type > operator/(this_type lhs, const Op &rhs)
decltype(auto) get(FuncT &&) const
get a component from the bundle
friend std::ostream & operator<<(std::ostream &os, const bundle &obj)
#define IF_CONSTEXPR(...)
void serialize(std::string fname, exec_data< Counter > &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
void set_scope(TupleT< Tp... > &obj, Args &&... args)
void set_prefix(TupleT< Tp... > &obj, Args &&... args)
void store(TupleT< Tp... > &obj, Args &&... args)
void pop(TupleT< Tp... > &obj, Args &&... args)
void push(TupleT< Tp... > &obj, Args &&... args)
impl::filter_false< Predicate, std::tuple< Sequence... > > type
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 generic type for indicating that function call or constructor should be as lightweight as possible.
std::bitset< scope_count > data_type
std::array< Tp, N > & operator+=(std::array< Tp, N > &, Other &&)
std::array< Tp, N > & operator-=(std::array< Tp, N > &, const std::array< Tp, N > &)
A light-weight alternative to std::function. Pass any callback - including capturing lambdas - cheapl...
std::array< char *, 4 > _args
void initialize(CompList< CompTypes... > &obj, std::initializer_list< EnumT > components)
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.
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)
Static polymorphic base class for automatic start/stop bundlers.
Static polymorphic base class for component bundlers.
This is a variadic component wrapper which combines the features of tim::auto_tuple<T....
Declare the operations types.
The purpose of this operation class is construct an object with specific args.
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
trait that signifies that an implementation for the component is available. When this is set to false...
trait that designates the type is a user-bundle