33#include <unordered_set>
37#if defined(TIMEMORY_USE_EXTERN) && !defined(TIMEMORY_USE_COMPONENT_EXTERN)
38# define TIMEMORY_USE_COMPONENT_EXTERN
41#if !defined(TIMEMORY_USE_COMPONENT_EXTERN) && !defined(TIMEMORY_COMPONENT_SOURCE) && \
42 !defined(TIMEMORY_COMPONENT_HEADER_MODE)
43# define TIMEMORY_COMPONENT_HEADER_MODE
53#if !defined(TIMEMORY_DECLARE_COMPONENT)
54# define TIMEMORY_DECLARE_COMPONENT(NAME) \
64 struct is_component<component::NAME> : true_type \
77#if !defined(TIMEMORY_DECLARE_API_COMPONENTS)
78# define TIMEMORY_DECLARE_API_COMPONENTS(API, ...) \
84 struct api_components<API, void> \
86 using type = type_list<__VA_ARGS__>; \
99#if !defined(TIMEMORY_SET_COMPONENT_API)
100# define TIMEMORY_SET_COMPONENT_API(COMP, ...) \
106 struct component_apis<COMP> \
108 using type = type_list<__VA_ARGS__>; \
121#if !defined(TIMEMORY_SET_TEMPLATE_COMPONENT_API)
122# define TIMEMORY_SET_TEMPLATE_COMPONENT_API(TARGS, TSPECIAL, ...) \
128 struct component_apis<TSPECIAL> \
130 using type = type_list<__VA_ARGS__>; \
143#if !defined(TIMEMORY_BUNDLE_INDEX)
144# define TIMEMORY_BUNDLE_INDEX(NAME, IDX) \
147 namespace component \
149 static constexpr size_t NAME = IDX; \
161#if !defined(TIMEMORY_DECLARE_TEMPLATE_COMPONENT)
162# define TIMEMORY_DECLARE_TEMPLATE_COMPONENT(NAME, ...) \
165 namespace component \
167 template <__VA_ARGS__> \
179#if !defined(TIMEMORY_TEMPLATE_COMPONENT)
180# define TIMEMORY_TEMPLATE_COMPONENT(NAME, TEMPLATE_PARAM, ...) \
183 namespace component \
185 template <TEMPLATE_PARAM> \
190 template <TEMPLATE_PARAM> \
191 struct is_component<component::NAME<__VA_ARGS__>> : true_type \
204#if !defined(TIMEMORY_COMPONENT_ALIAS)
205# define TIMEMORY_COMPONENT_ALIAS(NAME, ...) \
208 namespace component \
210 using NAME = __VA_ARGS__; \
222#if !defined(TIMEMORY_PROPERTY_SPECIALIZATION) && !defined(TIMEMORY_DISABLE_PROPERTIES)
223# define TIMEMORY_PROPERTY_SPECIALIZATION(TYPE, ENUM, ID, ...) \
226 namespace component \
229 struct properties<TYPE> : static_properties<TYPE> \
232 using value_type = TIMEMORY_COMPONENT; \
233 static constexpr value_type value = ENUM; \
234 static constexpr bool specialized() { return true; } \
235 static const char* enum_string() \
237 static const char* _enum = #ENUM; \
238 return static_cast<const char*>(&_enum[9]); \
240 static const char* id() { return ID; } \
241 static const idset_t& ids() \
243 static auto _instance = []() { \
244 auto _val = idset_t{ ID, __VA_ARGS__ }; \
245 if(_val.find("") != _val.end()) \
251 template <typename Archive> \
252 void save(Archive& ar, const unsigned int) const \
254 ar(cereal::make_nvp("value", ENUM), \
255 cereal::make_nvp("enum", std::string{ enum_string() }), \
256 cereal::make_nvp("id", std::string{ id() }), \
257 cereal::make_nvp("ids", ids())); \
259 template <typename Archive> \
260 void load(Archive&, const unsigned int) \
262 TIMEMORY_COMPONENT operator()() { return ENUM; } \
264 constexpr operator TIMEMORY_COMPONENT() const { return ENUM; } \
267 struct enumerator<ENUM> : properties<TYPE> \
270 static constexpr bool value = ::tim::trait::is_available<TYPE>::value; \
272 static constexpr bool specialized() { return true; } \
276#elif !defined(TIMEMORY_PROPERTY_SPECIALIZATION) && defined(TIMEMORY_DISABLE_PROPERTIES)
277# define TIMEMORY_PROPERTY_SPECIALIZATION(...)
287#if !defined(TIMEMORY_METADATA_SPECIALIZATION) && !defined(TIMEMORY_DISABLE_METADATA)
288# define TIMEMORY_METADATA_SPECIALIZATION(TYPE, LABEL, BASIC_DESC, ...) \
291 namespace component \
294 struct metadata<TYPE> \
297 using value_type = TIMEMORY_COMPONENT; \
299 static constexpr bool specialized() { return true; } \
300 static constexpr value_type value = properties<TYPE>::value; \
301 static std::string name() { return LABEL; } \
302 static std::string label() { return LABEL; } \
303 static std::string description() { return BASIC_DESC; } \
304 static std::string extra_description() \
306 return TIMEMORY_JOIN(" ", __VA_ARGS__); \
311#elif !defined(TIMEMORY_METADATA_SPECIALIZATION) && defined(TIMEMORY_DISABLE_METADATA)
312# define TIMEMORY_METADATA_SPECIALIZATION(...)
322#if !defined(TIMEMORY_TOOLSET_ALIAS)
323# define TIMEMORY_TOOLSET_ALIAS(NAME, WRAPPER, ...) \
326 namespace component \
330 using NAME = WRAPPER<__VA_ARGS__>; \
334 using tim::component::aliases::NAME;
343#if !defined(_EXTERN_NAME_COMBINE)
344# define _EXTERN_NAME_COMBINE(X, Y) X##Y
349#if !defined(_EXTERN_TUPLE_ALIAS)
350# define _EXTERN_TUPLE_ALIAS(Y) _EXTERN_NAME_COMBINE(extern_tuple_, Y)
355#if !defined(_EXTERN_LIST_ALIAS)
356# define _EXTERN_LIST_ALIAS(Y) _EXTERN_NAME_COMBINE(extern_list_, Y)
361#if !defined(TIMEMORY_INITIALIZE_STORAGE)
362# define TIMEMORY_INITIALIZE_STORAGE(...) \
367 namespace initialization \
371 using namespace ::tim::component; \
372 namespace component = ::tim::component; \
373 auto _TIM_STORAGE_INIT(__COUNTER__) = \
374 ::tim::storage_initializer::get<__VA_ARGS__>(); \
383#if !defined(TIMEMORY_STORAGE_INITIALIZER)
384# define TIMEMORY_STORAGE_INITIALIZER(...) TIMEMORY_INITIALIZE_STORAGE(__VA_ARGS__)
389#if !defined(TIMEMORY_EXTERN_STORAGE_ALIASES)
390# define TIMEMORY_EXTERN_STORAGE_ALIASES \
395 template <typename T> \
396 using storage_t = storage<T, typename T::value_type>; \
397 template <typename T> \
398 using storage_impl_t = impl::storage<T, trait::uses_value_storage<T>::value>; \
399 template <typename T> \
400 using storage_deleter_t = impl::storage_deleter<storage_impl_t<T>>; \
401 template <typename T> \
402 using storage_pointer_t = \
403 std::unique_ptr<alias::storage_impl_t<T>, alias::storage_deleter_t<T>>; \
410#if !defined(TIMEMORY_DECLARE_EXTERN_STORAGE)
411# define TIMEMORY_DECLARE_EXTERN_STORAGE(TYPE) \
412 TIMEMORY_EXTERN_STORAGE_ALIASES \
415 extern template class impl::storage<TYPE, \
416 trait::uses_value_storage<TYPE>::value>; \
417 extern template class storage<TYPE, typename TYPE::value_type>; \
418 extern template class singleton<alias::storage_impl_t<TYPE>, \
419 alias::storage_pointer_t<TYPE>, TIMEMORY_API>; \
420 extern template storage_singleton<alias::storage_t<TYPE>>* \
421 get_storage_singleton<alias::storage_t<TYPE>>(); \
422 extern template storage_initializer storage_initializer::get<TYPE>(); \
425 extern template struct data<TYPE>; \
426 extern template struct graph<TYPE>; \
427 extern template struct result<TYPE>; \
428 extern template struct tree<TYPE>; \
435#if !defined(TIMEMORY_INSTANTIATE_EXTERN_STORAGE)
436# define TIMEMORY_INSTANTIATE_EXTERN_STORAGE(TYPE) \
437 TIMEMORY_EXTERN_STORAGE_ALIASES \
440 template class impl::storage<TYPE, trait::uses_value_storage<TYPE>::value>; \
441 template class storage<TYPE, typename TYPE::value_type>; \
442 template class singleton<alias::storage_impl_t<TYPE>, \
443 alias::storage_pointer_t<TYPE>, TIMEMORY_API>; \
444 template storage_singleton<alias::storage_t<TYPE>>* \
445 get_storage_singleton<alias::storage_t<TYPE>>(); \
446 template storage_initializer storage_initializer::get<TYPE>(); \
449 template struct data<TYPE>; \
450 template struct graph<TYPE>; \
451 template struct result<TYPE>; \
452 template struct tree<TYPE>; \
457 using namespace ::tim::component; \
458 namespace component = ::tim::component; \
459 auto _TIM_STORAGE_INIT(__COUNTER__) = ::tim::storage_initializer::get<TYPE>(); \
469#if !defined(TIMEMORY_DECLARE_EXTERN_OPERATIONS)
470# define TIMEMORY_DECLARE_EXTERN_OPERATIONS(TYPE, HAS_DATA) \
473 namespace component \
477 extern template opaque get_opaque<TYPE>(); \
478 extern template opaque get_opaque<TYPE>(scope::config); \
479 extern template std::set<size_t> get_typeids<TYPE>(); \
482 namespace operation \
486 extern template struct add_secondary<TYPE, trait::secondary_data<TYPE>::value>; \
487 extern template struct serialization_base<TYPE>; \
488 extern template struct serialization<TYPE, is_enabled<TYPE>::value>; \
490 extern template struct add_secondary<TYPE>; \
491 extern template struct add_statistics<TYPE>; \
492 extern template struct assemble<TYPE>; \
493 extern template struct audit<TYPE>; \
494 extern template struct cache<TYPE>; \
495 extern template struct cleanup<TYPE>; \
496 extern template struct construct<TYPE>; \
497 extern template struct copy<TYPE>; \
498 extern template struct derive<TYPE>; \
499 extern template struct fini<TYPE>; \
500 extern template struct fini_storage<TYPE>; \
501 extern template struct echo_measurement<TYPE, trait::echo_enabled<TYPE>::value>; \
502 extern template struct extra_serialization<TYPE>; \
503 extern template struct get<TYPE>; \
504 extern template struct get_is_flat<TYPE, true>; \
505 extern template struct get_is_flat<TYPE, false>; \
506 extern template struct get_is_invalid<TYPE, true>; \
507 extern template struct get_is_invalid<TYPE, false>; \
508 extern template struct get_is_on_stack<TYPE, true>; \
509 extern template struct get_is_on_stack<TYPE, false>; \
510 extern template struct get_depth<TYPE, 0>; \
511 extern template struct init<TYPE>; \
512 extern template struct init_storage<TYPE>; \
513 extern template struct is_running<TYPE, true>; \
514 extern template struct is_running<TYPE, false>; \
515 extern template struct minus<TYPE>; \
516 extern template struct plus<TYPE>; \
517 extern template struct pop_node<TYPE>; \
518 extern template struct print<TYPE>; \
519 extern template struct print_header<TYPE>; \
520 extern template struct print_statistics<TYPE>; \
521 extern template struct print_storage<TYPE>; \
522 extern template struct push_node<TYPE>; \
523 extern template struct record<TYPE>; \
524 extern template struct reset<TYPE>; \
525 extern template struct serialization<TYPE>; \
526 extern template struct set_depth_change<TYPE>; \
527 extern template struct set_is_flat<TYPE>; \
528 extern template struct set_is_invalid<TYPE>; \
529 extern template struct set_is_on_stack<TYPE>; \
530 extern template struct set_iterator<TYPE>; \
531 extern template struct set_prefix<TYPE>; \
532 extern template struct set_scope<TYPE>; \
533 extern template struct set_state<TYPE>; \
534 extern template struct set_started<TYPE>; \
535 extern template struct set_stopped<TYPE>; \
536 extern template struct store<TYPE>; \
539 extern template struct dmp_get<TYPE, enabled_value_storage<TYPE>::value>; \
540 extern template struct get<TYPE, enabled_value_storage<TYPE>::value>; \
541 extern template struct merge<TYPE, enabled_value_storage<TYPE>::value>; \
542 extern template struct mpi_get<TYPE, enabled_value_storage<TYPE>::value>; \
543 extern template struct print<TYPE, enabled_value_storage<TYPE>::value>; \
544 extern template struct upc_get<TYPE, enabled_value_storage<TYPE>::value>; \
552#if !defined(TIMEMORY_INSTANTIATE_EXTERN_OPERATIONS)
553# define TIMEMORY_INSTANTIATE_EXTERN_OPERATIONS(TYPE, HAS_DATA) \
556 namespace component \
560 template opaque get_opaque<TYPE>(); \
561 template opaque get_opaque<TYPE>(scope::config); \
562 template std::set<size_t> get_typeids<TYPE>(); \
565 namespace operation \
569 template struct add_secondary<TYPE, trait::secondary_data<TYPE>::value>; \
570 template struct serialization_base<TYPE>; \
571 template struct serialization<TYPE, is_enabled<TYPE>::value>; \
573 template struct add_secondary<TYPE>; \
574 template struct add_statistics<TYPE>; \
575 template struct assemble<TYPE>; \
576 template struct audit<TYPE>; \
577 template struct cache<TYPE>; \
578 template struct cleanup<TYPE>; \
579 template struct construct<TYPE>; \
580 template struct copy<TYPE>; \
581 template struct derive<TYPE>; \
582 template struct echo_measurement<TYPE, trait::echo_enabled<TYPE>::value>; \
583 template struct extra_serialization<TYPE>; \
584 template struct fini<TYPE>; \
585 template struct fini_storage<TYPE>; \
586 template struct get<TYPE>; \
587 template struct get_is_flat<TYPE, true>; \
588 template struct get_is_flat<TYPE, false>; \
589 template struct get_is_invalid<TYPE, true>; \
590 template struct get_is_invalid<TYPE, false>; \
591 template struct get_is_on_stack<TYPE, true>; \
592 template struct get_is_on_stack<TYPE, false>; \
593 template struct get_depth<TYPE, 0>; \
594 template struct init<TYPE>; \
595 template struct init_storage<TYPE>; \
596 template struct is_running<TYPE, true>; \
597 template struct is_running<TYPE, false>; \
598 template struct minus<TYPE>; \
599 template struct plus<TYPE>; \
600 template struct pop_node<TYPE>; \
601 template struct print<TYPE>; \
602 template struct print_header<TYPE>; \
603 template struct print_statistics<TYPE>; \
604 template struct print_storage<TYPE>; \
605 template struct push_node<TYPE>; \
606 template struct record<TYPE>; \
607 template struct reset<TYPE>; \
608 template struct serialization<TYPE>; \
609 template struct set_depth_change<TYPE>; \
610 template struct set_is_flat<TYPE>; \
611 template struct set_is_invalid<TYPE>; \
612 template struct set_is_on_stack<TYPE>; \
613 template struct set_iterator<TYPE>; \
614 template struct set_prefix<TYPE>; \
615 template struct set_scope<TYPE>; \
616 template struct set_state<TYPE>; \
617 template struct set_started<TYPE>; \
618 template struct set_stopped<TYPE>; \
619 template struct store<TYPE>; \
622 template struct dmp_get<TYPE, enabled_value_storage<TYPE>::value>; \
623 template struct get<TYPE, enabled_value_storage<TYPE>::value>; \
624 template struct merge<TYPE, enabled_value_storage<TYPE>::value>; \
625 template struct mpi_get<TYPE, enabled_value_storage<TYPE>::value>; \
626 template struct print<TYPE, enabled_value_storage<TYPE>::value>; \
627 template struct upc_get<TYPE, enabled_value_storage<TYPE>::value>; \
635#if defined(TIMEMORY_COMPONENT_SOURCE)
639# if !defined(TIMEMORY_EXTERN_OPERATIONS)
640# define TIMEMORY_EXTERN_OPERATIONS(COMPONENT_NAME, HAS_DATA) \
641 TIMEMORY_INSTANTIATE_EXTERN_OPERATIONS(TIMEMORY_ESC(COMPONENT_NAME), HAS_DATA)
646# if !defined(TIMEMORY_EXTERN_STORAGE)
647# define TIMEMORY_EXTERN_STORAGE(...) \
648 TIMEMORY_INSTANTIATE_EXTERN_STORAGE(__VA_ARGS__)
653# if !defined(TIMEMORY_EXTERN_TEMPLATE)
654# define TIMEMORY_EXTERN_TEMPLATE(...) template __VA_ARGS__;
659#elif defined(TIMEMORY_USE_COMPONENT_EXTERN)
663# if !defined(TIMEMORY_EXTERN_OPERATIONS)
664# define TIMEMORY_EXTERN_OPERATIONS(COMPONENT_NAME, HAS_DATA) \
665 TIMEMORY_DECLARE_EXTERN_OPERATIONS(TIMEMORY_ESC(COMPONENT_NAME), HAS_DATA)
670# if !defined(TIMEMORY_EXTERN_STORAGE)
671# define TIMEMORY_EXTERN_STORAGE(...) TIMEMORY_DECLARE_EXTERN_STORAGE(__VA_ARGS__)
676# if !defined(TIMEMORY_EXTERN_TEMPLATE)
677# define TIMEMORY_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
686# if !defined(TIMEMORY_EXTERN_OPERATIONS)
687# define TIMEMORY_EXTERN_OPERATIONS(...)
692# if !defined(TIMEMORY_EXTERN_STORAGE)
693# define TIMEMORY_EXTERN_STORAGE(...)
698# if !defined(TIMEMORY_EXTERN_TEMPLATE)
699# define TIMEMORY_EXTERN_TEMPLATE(...)
708#if !defined(TIMEMORY_EXTERN_COMPONENT)
709# define TIMEMORY_EXTERN_COMPONENT(NAME, HAS_DATA, ...) \
710 TIMEMORY_EXTERN_TEMPLATE( \
711 struct tim::component::base<TIMEMORY_ESC(tim::component::NAME), \
713 TIMEMORY_EXTERN_OPERATIONS(TIMEMORY_ESC(component::NAME), HAS_DATA) \
714 TIMEMORY_EXTERN_STORAGE(TIMEMORY_ESC(component::NAME))
719#if !defined(TIMEMORY_DECLARE_EXTERN_COMPONENT)
720# define TIMEMORY_DECLARE_EXTERN_COMPONENT(NAME, HAS_DATA, ...) \
721 TIMEMORY_DECLARE_EXTERN_TEMPLATE( \
722 struct tim::component::base<TIMEMORY_ESC(tim::component::NAME), \
724 TIMEMORY_DECLARE_EXTERN_OPERATIONS(TIMEMORY_ESC(component::NAME), HAS_DATA) \
725 TIMEMORY_DECLARE_EXTERN_STORAGE(TIMEMORY_ESC(component::NAME))
730#if !defined(TIMEMORY_INSTANTIATE_EXTERN_COMPONENT)
731# define TIMEMORY_INSTANTIATE_EXTERN_COMPONENT(NAME, HAS_DATA, ...) \
732 TIMEMORY_INSTANTIATE_EXTERN_TEMPLATE( \
733 struct tim::component::base<TIMEMORY_ESC(tim::component::NAME), \
735 TIMEMORY_INSTANTIATE_EXTERN_OPERATIONS(TIMEMORY_ESC(component::NAME), HAS_DATA) \
736 TIMEMORY_INSTANTIATE_EXTERN_STORAGE(TIMEMORY_ESC(component::NAME))