42 #include <initializer_list>
47 #include <type_traits>
51 #if !defined(TIMEMORY_FOLD_EXPRESSION)
53 # define TIMEMORY_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
55 # define TIMEMORY_FOLD_EXPRESSION(...) \
56 ::tim::consume_parameters(::std::initializer_list<int>{ (__VA_ARGS__, 0)... })
62 #if !defined(TIMEMORY_FOLD_EXPANSION)
63 # define TIMEMORY_FOLD_EXPANSION(TYPE, SIZE, ...) \
64 std::array<TYPE, SIZE>({ (::tim::consume_parameters(), __VA_ARGS__)... });
69 #if !defined(TIMEMORY_RETURN_FOLD_EXPRESSION)
70 # define TIMEMORY_RETURN_FOLD_EXPRESSION(...) \
71 ::std::make_tuple((::tim::consume_parameters(), __VA_ARGS__)...)
76 #if !defined(TIMEMORY_DECLARE_EXTERN_TEMPLATE)
77 # define TIMEMORY_DECLARE_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
82 #if !defined(TIMEMORY_INSTANTIATE_EXTERN_TEMPLATE)
83 # define TIMEMORY_INSTANTIATE_EXTERN_TEMPLATE(...) template __VA_ARGS__;
88 #if !defined(TIMEMORY_ESC)
89 # define TIMEMORY_ESC(...) __VA_ARGS__
94 #if !defined(TIMEMORY_DELETED_OBJECT)
95 # define TIMEMORY_DELETED_OBJECT(NAME) \
97 NAME(const NAME&) = delete; \
98 NAME(NAME&&) = delete; \
99 NAME& operator=(const NAME&) = delete; \
100 NAME& operator=(NAME&&) = delete;
105 #if !defined(TIMEMORY_DELETE_COPY_MOVE_OBJECT)
106 # define TIMEMORY_DELETE_COPY_MOVE_OBJECT(NAME) \
107 NAME(const NAME&) = delete; \
108 NAME(NAME&&) = delete; \
109 NAME& operator=(const NAME&) = delete; \
110 NAME& operator=(NAME&&) = delete;
115 #if !defined(TIMEMORY_DEFAULT_MOVE_ONLY_OBJECT)
116 # define TIMEMORY_DEFAULT_MOVE_ONLY_OBJECT(NAME) \
117 NAME(const NAME&) = delete; \
118 NAME(NAME&&) noexcept = default; \
119 NAME& operator=(const NAME&) = delete; \
120 NAME& operator=(NAME&&) noexcept = default;
125 #if !defined(TIMEMORY_DEFAULT_OBJECT)
126 # define TIMEMORY_DEFAULT_OBJECT(NAME) \
128 NAME(const NAME&) = default; \
129 NAME(NAME&&) noexcept = default; \
130 NAME& operator=(const NAME&) = default; \
131 NAME& operator=(NAME&&) noexcept = default;
136 #if !defined(TIMEMORY_EXCEPTION)
137 # define TIMEMORY_EXCEPTION(...) \
139 std::stringstream _errmsg; \
140 _errmsg << __VA_ARGS__; \
141 perror(_errmsg.str().c_str()); \
142 std::cerr << _errmsg.str() << std::endl; \
143 std::exit(EXIT_FAILURE); \
149 #if !defined(TIMEMORY_TESTING_EXCEPTION) && defined(TIMEMORY_INTERNAL_TESTING)
150 # define TIMEMORY_TESTING_EXCEPTION(...) \
152 TIMEMORY_EXCEPTION(__VA_ARGS__) \
154 #elif !defined(TIMEMORY_TESTING_EXCEPTION)
155 # define TIMEMORY_TESTING_EXCEPTION(...) \
161 #if !defined(TIMEMORY_TUPLE_ACCESSOR)
162 # define TIMEMORY_TUPLE_ACCESSOR(INDEX, TUPLE, NAME) \
163 auto& NAME() { return std::get<INDEX>(TUPLE); } \
164 const auto& NAME() const { return std::get<INDEX>(TUPLE); }
173 template <
typename Tp, Tp Num>
177 template <
size_t... Idx>
181 template <
size_t Num>
185 template <
typename... Types>
189 template <
bool B,
typename T =
int>
193 template <
typename T>
196 template <
bool B,
typename Lhs,
typename Rhs>
199 template <
typename T>
202 template <
typename T>
210 template <
typename T>
216 template <
typename T>
231 template <
typename... Tp>
239 template <
size_t Idx,
typename Tp>
240 struct type_list_element;
244 template <
size_t Idx,
size_t TargIdx,
typename... Tail>
245 struct type_list_element;
247 template <
size_t Idx,
size_t TargIdx>
248 struct type_list_element<Idx, TargIdx>
254 static_assert(TargIdx < Idx + 2,
"Error! Index exceeded size of of type_list");
257 template <
size_t Idx,
size_t TargIdx,
typename Tp,
typename... Tail>
258 struct type_list_element<Idx, TargIdx, Tp, Tail...>
262 typename type_list_element<Idx + 1, TargIdx, Tail...>::type>;
266 template <
size_t Idx,
typename... Types>
267 struct type_list_element<Idx,
type_list<Types...>>
269 using type =
typename internal::type_list_element<0, Idx, Types...>::type;
272 template <
size_t Idx,
typename Tp>
279 template <
typename... ArgsT>
280 TIMEMORY_ALWAYS_INLINE
void
290 template <
typename Tp,
typename DeleterT,
typename Tag>
332 template <
typename... Tp>
354 struct tree : std::integral_constant<int, 2>
372 struct flat : std::integral_constant<int, 0>
394 static constexpr
size_t scope_count = 3;
403 static input_type _instance{ {
false,
false,
false } };
409 template <
typename Arg,
size_t... Idx>
410 static TIMEMORY_HOT_INLINE
auto
413 static_assert(
sizeof...(Idx) <= scope_count,
"Error! Bad index sequence size");
421 template <
size_t... Idx>
422 static TIMEMORY_HOT_INLINE
auto
425 static_assert(
sizeof...(Idx) <= scope_count,
"Error! Bad index sequence size");
432 static TIMEMORY_HOT_INLINE
auto
435 return generate(
get_fields(), make_index_sequence<scope_count>{});
456 :
data_type(std::forward<data_type>(obj))
464 explicit config(
bool _flat,
bool _timeline)
469 explicit config(
bool _flat,
bool _timeline,
bool _tree)
475 :
config(false, false, false)
479 :
config(true, false, false)
483 :
config(false, true, false)
486 template <
typename Arg,
typename... Args,
488 std::is_same<Arg, flat>::value ||
489 std::is_same<Arg, timeline>::value),
491 explicit config(Arg&& arg, Args&&... args)
493 *
this += std::forward<Arg>(arg);
506 data_type::operator=(rhs);
513 data_type::operator=(std::forward<data_type>(rhs));
517 template <
typename T, std::enable_if_t<(std::is_same<T, tree>::value ||
518 std::is_same<T, flat>::value ||
519 std::is_same<T, timeline>::value),
523 this->data_type::set(T::value,
true);
527 using data_type::set;
529 template <
typename T, std::enable_if_t<(std::is_same<T, tree>::value ||
530 std::is_same<T, flat>::value ||
531 std::is_same<T, timeline>::value),
535 this->data_type::set(T::value, val);
539 TIMEMORY_NODISCARD
bool is_flat()
const {
return this->test(flat::value); }
540 TIMEMORY_NODISCARD
bool is_timeline()
const {
return this->test(timeline::value); }
545 return this->none() || (this->test(tree::value) && !this->test(flat::value));
549 return (is_flat() && is_timeline());
553 return (is_tree() && is_timeline());
556 template <
bool ForceFlatT>
559 return (ForceFlatT) ? true : this->test(flat::value);
562 template <
bool ForceTreeT,
bool ForceTimeT>
567 : ((ForceTimeT) ?
false
568 : (this->none() || (this->test(tree::value) &&
569 !this->test(flat::value))));
574 std::stringstream ss;
575 ss << std::boolalpha <<
"tree: " << obj.
is_tree() <<
", flat: " << obj.
is_flat()
577 <<
". Values: flat::value = " << obj.test(flat::value)
578 <<
", timeline::value = " << obj.test(timeline::value)
579 <<
", tree::value = " << obj.test(tree::value);
584 template <
typename ForceTreeT = false_type,
typename ForceFlatT = false_type,
585 typename ForceTimeT = false_type>
588 static_assert(!(ForceTreeT::value && ForceFlatT::value),
589 "Error! Type cannot enforce tree-based call-stack depth storage "
590 "and flat call-stack depth storage simulatenously");
594 if(ForceFlatT::value || is_flat())
607 template <
typename ForceTreeT = false_type,
typename ForceFlatT = false_type,
608 typename ForceTimeT = false_type>
609 uint64_t
compute_hash(uint64_t _id, uint64_t _depth, uint64_t& _counter)
617 if(is_tree<ForceTreeT::value, ForceTimeT::value>() ||
618 is_flat<ForceFlatT::value>())
624 if(ForceTimeT::value || is_timeline())
639 static TIMEMORY_INLINE config
640 get_default() TIMEMORY_HOT;
641 TIMEMORY_INLINE config
642 operator+(config _lhs, tree) TIMEMORY_HOT;
643 TIMEMORY_INLINE config
644 operator+(config _lhs, flat) TIMEMORY_HOT;
645 TIMEMORY_INLINE config
646 operator+(config _lhs, timeline) TIMEMORY_HOT;
647 TIMEMORY_INLINE config
648 operator+(config _lhs, config _rhs) TIMEMORY_HOT;
652 static TIMEMORY_HOT_INLINE auto
653 get_default() -> config
655 return config{ get_default_bitset() };
660 TIMEMORY_HOT_INLINE
auto
663 _lhs.
set(tree::value,
true);
669 TIMEMORY_HOT_INLINE
auto
672 _lhs.
set(flat::value,
true);
678 TIMEMORY_HOT_INLINE
auto
681 _lhs.
set(timeline::value,
true);
687 TIMEMORY_HOT_INLINE
auto
701 template <
typename FuncT>
703 : m_functor(std::forward<FuncT>(_func))
712 : m_functor(std::move(rhs.m_functor))
714 rhs.m_functor = []() {};
721 m_functor = std::move(rhs.m_functor);
722 rhs.m_functor = []() {};
730 std::function<void()> m_functor = []() {};
802 template <
size_t Idx,
typename... Types>
805 using type =
typename tim::type_list_element<Idx,
tim::type_list<Types...>>::type;
817 template <
typename Tp>
825 #if !defined(TIMEMORY_SET_CLASS_VERSION)
826 # define TIMEMORY_SET_CLASS_VERSION(VERSION_NUMBER, ...) \
834 struct StaticVersion<__VA_ARGS__> \
836 static constexpr std::uint32_t version = VERSION_NUMBER; \
843 #if !defined(TIMEMORY_GET_CLASS_VERSION)
844 # define TIMEMORY_GET_CLASS_VERSION(...) \
845 ::tim::cereal::detail::StaticVersion<__VA_ARGS__>::version
a generic type for prioritizing a function call to the base class over derived functions,...
void audit(TupleT< Tp... > &obj, Args &&... args)
Dummy struct for meta-programming to designate that a component activates it's features at the first ...
Dummy struct for meta-programming to designate that a component activates its features in {global,...
a generic type for indicating that function call or constructor should be as lightweight as possible.
config operator+(config _lhs, config _rhs)
std::array< bool, scope_count > input_type
std::bitset< scope_count > data_type
input_type & get_fields()
typename std::remove_cv< T >::type remove_cv_t
std::make_integer_sequence< size_t, Num > make_index_sequence
Alias template make_index_sequence.
std::integral_constant< int, N > priority_constant
std::make_integer_sequence< Tp, Num > make_integer_sequence
Alias template make_integer_sequence.
typename std::remove_const< T >::type remove_const_t
typename type_list_element< Idx, Tp >::type type_list_element_t
void consume_parameters(ArgsT &&...) TIMEMORY_HIDDEN
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.
typename identity< T >::type identity_t
hash_value_t get_combined_hash_id(hash_value_t _lhs, Tp &&_rhs)
std::make_index_sequence< sizeof...(Types)> index_sequence_for
Alias template index_sequence_for.
typename std::conditional< B, Lhs, Rhs >::type conditional_t
std::integer_sequence< size_t, Idx... > index_sequence
Alias template index_sequence.
lightweight tuple-alternative for meta-programming logic
Used by component audit member function to designate the parameters being passed are incoming (e....
Used by component audit member function to designate the parameters being passed are outgoing (e....
this is a placeholder type for optional type-traits. It is used as the default type for the type-trai...
this data type encodes the options of storage scope. The default is hierarchical (tree) scope....
config(Arg &&arg, Args &&... args)
config(data_type &&obj) noexcept
config(const config &)=default
config(config &&) noexcept=default
uint64_t compute_depth(uint64_t _current)
config & set(bool val=true)
config & operator=(data_type &&rhs) noexcept
bool is_tree_timeline() const
bool is_flat_timeline() const
config(bool _flat, bool _timeline, bool _tree)
uint64_t compute_hash(uint64_t _id, uint64_t _depth, uint64_t &_counter)
config(bool _flat, bool _timeline)
friend std::ostream & operator<<(std::ostream &os, const config &obj)
config(const data_type &obj)
provides an object which can be returned from functions that will execute the lambda provided during ...
destructor(destructor &&rhs) noexcept
destructor & operator=(destructor &&rhs) noexcept
destructor(const destructor &)=delete
destructor & operator=(const destructor &)=delete
destructor(FuncT &&_func)
Dummy struct to designates flat (no hierarchy) storage. When flat scoping is globally enabled,...
Dummy struct to designates timeline (hierarchical, non-duplicated) storage. It is meaningless by itse...
Dummy struct to designates tree (hierarchical) storage. This scope (default) maintains nesting in the...
#define TIMEMORY_FOLD_EXPRESSION(...)
typename typename typename