50template <
typename Op,
typename Tag,
typename... Types>
55 template <
typename Arg,
typename... Args>
59 template <
typename... Args>
64template <
typename... Types>
69 template <
typename Arg,
typename... Args>
73 template <
typename... Args>
78template <
typename... Types>
83 template <
typename Arg,
typename... Args>
87 template <
typename... Args>
97class common_base_bundle
101 using size_type = int64_t;
103 using captured_location_t = source_location::captured;
107 TIMEMORY_DEFAULT_OBJECT(common_base_bundle)
109 common_base_bundle(scope::config&& _config,
hash_value_t _hash)
117 int64_t laps()
const {
return m_laps; }
118 bool store()
const {
return m_store(); }
121 bool get_store()
const {
return m_store(); }
123 int64_t get_laps()
const {
return m_laps; }
124 const scope::config& get_scope()
const {
return m_scope; }
126 void store(
bool v) { m_store(v); }
127 void set_store(
bool v) { m_store(v); }
128 void set_laps(int64_t v) { m_laps = v; }
130 common_base_bundle&
operator+=(
const common_base_bundle& rhs)
132 m_laps += rhs.m_laps;
136 common_base_bundle&
operator-=(
const common_base_bundle& rhs)
138 m_laps -= rhs.m_laps;
143 scope::config m_scope = scope::get_default();
146 utility::bit_flags<6> m_config = {};
147 std::shared_ptr<base::ring_buffer> m_buffer = {
nullptr };
161 TIMEMORY_INLINE
bool m_enabled()
const {
return m_config.test<EnabledIdx>(); }
162 TIMEMORY_INLINE
bool m_store()
const {
return m_config.test<StoreIdx>(); }
163 TIMEMORY_INLINE
bool m_explicit_push()
const {
return m_config.test<ExPushIdx>(); }
164 TIMEMORY_INLINE
bool m_explicit_pop()
const {
return m_config.test<ExPopIdx>(); }
165 TIMEMORY_INLINE
bool m_is_pushed()
const {
return m_config.test<PushedIdx>(); }
166 TIMEMORY_INLINE
bool m_is_active()
const {
return m_config.test<ActiveIdx>(); }
168 TIMEMORY_INLINE
void m_enabled(
bool v) { m_config.set<EnabledIdx>(v); }
169 TIMEMORY_INLINE
void m_store(
bool v) { m_config.set<StoreIdx>(v); }
170 TIMEMORY_INLINE
void m_explicit_push(
bool v) {
return m_config.set<ExPushIdx>(v); }
171 TIMEMORY_INLINE
void m_explicit_pop(
bool v) {
return m_config.set<ExPopIdx>(v); }
172 TIMEMORY_INLINE
void m_is_pushed(
bool v) { m_config.set<PushedIdx>(v); }
173 TIMEMORY_INLINE
void m_is_active(
bool v) { m_config.set<ActiveIdx>(v); }
176template <
typename... Types>
182template <
typename Tag,
typename... Types>
183class base_bundle<Tag, Types...>
184:
public common_base_bundle
185,
public concepts::variadic
186,
public concepts::wrapper
189 using tag_type = Tag;
190 using impl_type = std::tuple<Types...>;
191 using sample_type =
typename tim::variadic::impl::bundle<impl_type>::sample_type;
192 using tuple_type =
typename tim::variadic::impl::bundle<impl_type>::tuple_type;
193 using reference_type =
194 typename tim::variadic::impl::bundle<impl_type>::reference_type;
195 using print_type =
typename tim::variadic::impl::bundle<impl_type>::print_type;
197 using user_bundle_types =
200 template <
template <
typename>
class Op,
typename... T>
201 using generic_operation = tim::variadic::impl::generic_operation<Op, tag_type, T...>;
203 template <
template <
typename>
class Op,
typename... T>
204 using custom_operation = tim::variadic::impl::custom_operation<Op, T...>;
206 template <
template <
typename>
class Op,
typename TupleT = tuple_type>
207 using operation_t =
typename generic_operation<Op, TupleT>::type;
209 template <
template <
typename>
class Op,
typename TupleT = tuple_type>
210 using custom_operation_t =
211 typename tim::variadic::impl::custom_operation<Op, TupleT>::type;
213 template <
typename U>
214 using sample_type_t = tim::variadic::impl::sample_type_t<U>;
218 static constexpr bool empty() {
return (size() == 0); }
219 static constexpr size_t size() {
return sizeof...(Types); }
221 template <
typename... T>
222 static auto get_scope_config()
224 return scope::config{ quirk_config<quirk::flat_scope, T...>::value,
225 quirk_config<quirk::timeline_scope, T...>::value,
226 quirk_config<quirk::tree_scope, T...>::value };
229 template <
typename... T>
230 static auto get_store_config()
232 return !quirk_config<quirk::no_store, T...>::value;
238 static constexpr bool has_user_bundle_v =
242 base_bundle&
operator+=(
const base_bundle& rhs)
248 base_bundle&
operator-=(
const base_bundle& rhs)
255 using ctor_params_t = std::tuple<hash_value_t, bool, scope::config>;
258 template <
typename U = impl_type>
259 base_bundle(ctor_params_t _params = ctor_params_t(
260 0, tim::variadic::impl::global_enabled(), scope::get_default()),
261 enable_if_t<std::tuple_size<U>::value != 0,
int> = 0)
262 : common_base_bundle{
std::
get<2>(_params) + get_scope_config(),
266 m_store(m_enabled() && std::get<1>(_params) && get_store_config());
269 template <
typename U = impl_type>
270 base_bundle(ctor_params_t = ctor_params_t(),
271 enable_if_t<std::tuple_size<U>::value == 0,
int> = 0)
274 ~base_bundle() =
default;
275 base_bundle(
const base_bundle&) =
default;
276 base_bundle(base_bundle&&) =
default;
277 base_bundle& operator=(
const base_bundle&) =
default;
278 base_bundle& operator=(base_bundle&&) =
default;
288 void compute_width(
const string_t& _key)
const
290 output_width(_key.length() + get_prefix().length() + 1);
293 void update_width()
const { compute_width(key()); }
295 const auto& prefix()
const {
return get_persistent_data().prefix; }
296 const auto& get_prefix()
const {
return prefix(); }
298 using common_base_bundle::m_buffer;
299 using common_base_bundle::m_config;
300 using common_base_bundle::m_hash;
301 using common_base_bundle::m_laps;
302 using common_base_bundle::m_scope;
306 if(m_buffer.get() ==
nullptr)
308 static auto _size = []() {
314 m_buffer = std::make_shared<base::ring_buffer>(_size,
false);
315 return m_buffer !=
nullptr;
317 return m_buffer->is_full();
322 static int64_t output_width(int64_t
width = 0)
324 return get_persistent_data().get_width(
width);
329 template <
typename... T>
336 template <
typename... T>
340 return (tim::variadic::impl::global_enabled()) ?
add_hash_id(_key) : 0;
343 template <
typename... T>
344 static hash_value_t handle_key(type_list<T...>,
const captured_location_t& _loc,
347 return _loc.get_hash();
350 template <
typename... T,
typename... U>
351 static scope::config handle_scope(type_list<T...>, scope::config _scope,
355 return _scope + get_scope_config<T..., U...>();
358 template <
typename... T,
typename... U>
359 static scope::config handle_scope(type_list<T...>, quirk::config<U...>,
362 return scope::get_default() + get_scope_config<T..., U...>();
365 template <
typename... T,
typename... U>
366 static bool handle_store(type_list<T...>,
bool _enable, quirk::config<U...>,
369 return get_store_config<T..., U...>() && _enable &&
370 tim::variadic::impl::global_enabled();
373 template <
typename... T,
typename... U>
374 static bool handle_store(type_list<T...>, std::true_type, quirk::config<U...>,
377 return get_store_config<T..., U...>() && tim::variadic::impl::global_enabled();
380 template <
typename... T,
typename... U>
381 static bool handle_store(type_list<T...>, std::false_type, quirk::config<U...>,
384 return get_store_config<T..., U...>();
388 template <
typename... T>
395 template <
typename... T>
396 static hash_value_t handle_key(type_list<T...>,
const captured_location_t&,
402 template <
typename... T,
typename... U>
403 static auto handle_scope(type_list<T...>, scope::config, quirk::config<U...>,
406 return scope::config{};
409 template <
typename... T,
typename... U>
410 static auto handle_scope(type_list<T...>, quirk::config<U...>,
413 return scope::config{};
416 template <
typename... T,
typename... U>
417 static bool handle_store(type_list<T...>,
bool, quirk::config<U...>,
423 template <
typename... T,
typename... U>
424 static bool handle_store(type_list<T...>, std::true_type, quirk::config<U...>,
430 template <
typename... T,
typename... U>
431 static bool handle_store(type_list<T...>, std::false_type, quirk::config<U...>,
438 template <
typename... T,
typename KeyT,
typename StoreT,
typename ScopeT,
440 static auto handle(type_list<T...> _types, KeyT&& _key, StoreT&& _store,
441 ScopeT&& _scope, QuirkT&& _quirk)
443 return ctor_params_t{ handle_key(_types, std::forward<KeyT>(_key)),
444 handle_store(_types, std::forward<StoreT>(_store),
445 std::forward<QuirkT>(_quirk)),
446 handle_scope(_types, std::forward<ScopeT>(_scope),
447 std::forward<QuirkT>(_quirk)) };
450 template <
typename... T,
typename KeyT,
typename StoreT>
451 static auto handle(type_list<T...> _types, KeyT&& _key, StoreT&& _store,
452 scope::config _scope)
454 return handle(_types, std::forward<KeyT>(_key), std::forward<StoreT>(_store),
455 _scope, quirk::config<>{});
458 template <
typename... T,
typename KeyT,
typename StoreT,
typename... U>
459 static auto handle(type_list<T...> _types, KeyT&& _key, StoreT&& _store,
460 quirk::config<U...> _quirk)
462 return ctor_params_t{ handle_key(_types, std::forward<KeyT>(_key)),
463 handle_store(_types, std::forward<StoreT>(_store), _quirk),
464 handle_scope(_types, _quirk) };
467 template <
typename... T,
typename Tp,
typename TupleT,
typename FuncT,
typename... U>
468 static void init(type_list<T...>, Tp& _this, TupleT&& _data, FuncT&& _init,
469 quirk::config<U...> = quirk::config<>{},
472 if(tim::variadic::impl::global_enabled())
474 IF_CONSTEXPR(!quirk_config<quirk::no_init, T..., U...>::value)
478 _this.m_explicit_push(quirk_config<quirk::explicit_push, T..., U...>::value);
479 _this.m_explicit_pop(quirk_config<quirk::explicit_pop, T..., U...>::value);
480 _this.set_prefix(_this.get_hash());
482 IF_CONSTEXPR(quirk_config<quirk::auto_start, T..., U...>::value)
489 template <
typename... T,
typename Tp,
typename TupleT,
typename FuncT,
typename... U>
490 static void init(type_list<T...>, Tp&, TupleT&&, FuncT&&,
491 quirk::config<U...> = quirk::config<>{},
497 template <
typename T,
typename... U>
498 using quirk_config = tim::variadic::impl::quirk_config<T,
type_list<Types...>, U...>;
501 struct persistent_data
503 int64_t get_width(int64_t _w)
507 auto&& memorder_v = std::memory_order_relaxed;
508 int64_t propose_width;
509 int64_t current_width;
510 auto compute = [&]() {
return std::max(
width.load(memorder_v), _w); };
511 while((propose_width = compute()) >
512 (current_width =
width.load(memorder_v)))
514 width.compare_exchange_strong(current_width, propose_width,
517 return width.load(memorder_v);
523 std::atomic<int64_t>
width{ 0 };
527 if(!dmp::is_initialized())
531 static uint16_t _width = 1;
533 _width =
std::max(_width, (uint16_t)(log10(dmp::size()) + 1));
534 std::stringstream ss;
536 ss <<
"|" << std::setw(_width) << dmp::rank() <<
">>> ";
543 static persistent_data& get_persistent_data()
545 static persistent_data _instance{};
552template <
typename Tag,
typename... Types>
553class base_bundle<Tag,
std::tuple<Types...>> :
public base_bundle<Tag, Types...>
560 template <
typename... Args>
561 base_bundle(Args&&... args)
562 : base_bundle<Tag, Types...>(
std::forward<Args>(args)...)
566template <
typename Tag,
typename... Types>
567class base_bundle<Tag,
type_list<Types...>> :
public base_bundle<Tag, Types...>
574 template <
typename... Args>
575 base_bundle(Args&&... args)
576 : base_bundle<Tag, Types...>(
std::forward<Args>(args)...)
584template <
typename... Types>
586:
public impl::base_bundle<TIMEMORY_API, Types...>
593 template <
typename... Args>
595 : impl::base_bundle<
TIMEMORY_API, Types...>(
std::forward<Args>(args)...)
599template <
typename... Types>
600struct stack_bundle<
std::tuple<Types...>>
601:
public impl::base_bundle<TIMEMORY_API, Types...>
602,
public concepts::stack_wrapper
608 template <
typename... Args>
610 : impl::base_bundle<
TIMEMORY_API, Types...>(
std::forward<Args>(args)...)
614template <
typename... Types>
616:
public impl::base_bundle<TIMEMORY_API, Types...>
623 template <
typename... Args>
625 : impl::base_bundle<
TIMEMORY_API, Types...>(
std::forward<Args>(args)...)
631template <
typename ApiT,
typename... Types>
634 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
635 impl::base_bundle<ApiT, std::tuple<>>>
640 "Error! The first template parameter of an 'api_bundle' must "
641 "statisfy the 'is_api' concept");
645 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
646 impl::base_bundle<ApiT, std::tuple<>>>;
654 template <
typename... Args>
660template <
typename ApiT,
typename... Types>
661struct api_bundle<ApiT,
std::tuple<Types...>>
663 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
664 impl::base_bundle<ApiT, std::tuple<>>>
665,
public concepts::tagged
666,
public concepts::comp_wrapper
669 "Error! The first template parameter of an 'api_bundle' must "
670 "statisfy the 'is_api' concept");
673 conditional_t<trait::is_available<ApiT>::value,
674 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
675 impl::base_bundle<ApiT, std::tuple<>>>;
677 conditional_t<trait::is_available<ApiT>::value,
683 template <
typename... Args>
701 using base_bundle_type::init_buffer;
702 using base_bundle_type::m_buffer;
703 using base_bundle_type::m_config;
704 using base_bundle_type::m_hash;
705 using base_bundle_type::m_laps;
706 using base_bundle_type::m_scope;
709template <
typename ApiT,
typename... Types>
712 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
713 impl::base_bundle<ApiT, std::tuple<>>>
718 "Error! The first template parameter of an 'api_bundle' must "
719 "statisfy the 'is_api' concept");
723 impl::base_bundle<ApiT, remove_pointer_t<Types>...>,
724 impl::base_bundle<ApiT, std::tuple<>>>;
733 template <
typename... Args>
751 using base_bundle_type::init_buffer;
752 using base_bundle_type::m_buffer;
753 using base_bundle_type::m_config;
754 using base_bundle_type::m_hash;
755 using base_bundle_type::m_laps;
756 using base_bundle_type::m_scope;
#define IF_CONSTEXPR(...)
::tim::statistics< Tp > max(::tim::statistics< Tp > lhs, const Tp &rhs)
::tim::statistics< tuple<> > & operator+=(::tim::statistics< tuple<> > &_lhs, const Tp &)
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
bool get_hash_identifier(const hash_map_ptr_t &_hash_map, const hash_alias_ptr_t &_hash_alias, hash_value_t _hash_id, std::string *&_ret)
void set_scope(TupleT< Tp... > &obj, Args &&... args)
void store(TupleT< Tp... > &obj, Args &&... args)
impl::filter_false< Predicate, std::tuple< Sequence... > > type
impl::filter_true< concepts::is_quirk_type, T > non_quirk_t
impl::filter_true< concepts::is_placeholder, T > non_placeholder_t
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 > &)
std::string string_view_t
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
void init(Args &&... args)
tim::mpl::apply< std::string > string
auto get(const auto_bundle< Tag, Types... > &_obj)
typename std::conditional< B, Lhs, Rhs >::type conditional_t
typename impl::convert< T, U >::type convert_t
lightweight tuple-alternative for meta-programming logic
Declare the operations types.
conditional_t< trait::is_available< ApiT >::value, impl::base_bundle< ApiT, remove_pointer_t< Types >... >, impl::base_bundle< ApiT, std::tuple<> > > base_bundle_type
conditional_t< trait::is_available< ApiT >::value, mpl::non_placeholder_t< mpl::non_quirk_t< std::tuple< Types... > > >, std::tuple<> > data_type
api_bundle & operator-=(const api_bundle &rhs)
api_bundle(Args &&... args)
api_bundle & operator+=(const api_bundle &rhs)
api_bundle(Args &&... args)
conditional_t< trait::is_available< ApiT >::value, mpl::non_placeholder_t< mpl::non_quirk_t< std::tuple< Types... > > >, std::tuple<> > data_type
conditional_t< trait::is_available< ApiT >::value, impl::base_bundle< ApiT, remove_pointer_t< Types >... >, impl::base_bundle< ApiT, std::tuple<> > > base_bundle_type
concept that specifies that a type is an API. APIs are used to designate different project implementa...
static constexpr bool value
static constexpr size_t value
auto operator()(Args &&...) const
generic_counter(Arg &&, Args &&...)
auto operator()(Args &&...) const
generic_deleter(Arg &&, Args &&...)
auto operator()(Args &&...) const
generic_operator(Arg &&, Args &&...)
This operation class is similar to pointer_operator but can handle non-pointer types.
convert_t< mpl::non_placeholder_t< mpl::non_quirk_t< type_list< Types... > > >, std::tuple<> > data_type
stack_bundle(Args &&... args)
convert_t< mpl::non_placeholder_t< mpl::non_quirk_t< type_list< Types... > > >, std::tuple<> > data_type
stack_bundle(Args &&... args)
static bool get(enable_if_t< is_available< U >::value &&get_value< U >(), int >=0)
GET specialization if component is available.
#define TIMEMORY_FOLD_EXPRESSION(...)