43#include <initializer_list>
52#if !defined(TIMEMORY_FOLD_EXPRESSION)
54# define TIMEMORY_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
56# define TIMEMORY_FOLD_EXPRESSION(...) \
57 ::tim::consume_parameters(::std::initializer_list<int>{ (__VA_ARGS__, 0)... })
63#if !defined(TIMEMORY_FOLD_EXPANSION)
64# define TIMEMORY_FOLD_EXPANSION(TYPE, SIZE, ...) \
65 std::array<TYPE, SIZE>({ (::tim::consume_parameters(), __VA_ARGS__)... });
70#if !defined(TIMEMORY_RETURN_FOLD_EXPRESSION)
71# define TIMEMORY_RETURN_FOLD_EXPRESSION(...) \
72 ::std::make_tuple((::tim::consume_parameters(), __VA_ARGS__)...)
77#if !defined(TIMEMORY_DECLARE_EXTERN_TEMPLATE)
78# define TIMEMORY_DECLARE_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
83#if !defined(TIMEMORY_INSTANTIATE_EXTERN_TEMPLATE)
84# define TIMEMORY_INSTANTIATE_EXTERN_TEMPLATE(...) template __VA_ARGS__;
89#if !defined(TIMEMORY_ESC)
90# define TIMEMORY_ESC(...) __VA_ARGS__
95#if !defined(TIMEMORY_DELETED_OBJECT)
96# define TIMEMORY_DELETED_OBJECT(NAME) \
98 NAME(const NAME&) = delete; \
99 NAME(NAME&&) = delete; \
100 NAME& operator=(const NAME&) = delete; \
101 NAME& operator=(NAME&&) = delete;
106#if !defined(TIMEMORY_DELETE_COPY_MOVE_OBJECT)
107# define TIMEMORY_DELETE_COPY_MOVE_OBJECT(NAME) \
108 NAME(const NAME&) = delete; \
109 NAME(NAME&&) = delete; \
110 NAME& operator=(const NAME&) = delete; \
111 NAME& operator=(NAME&&) = delete;
116#if !defined(TIMEMORY_DEFAULT_MOVE_ONLY_OBJECT)
117# define TIMEMORY_DEFAULT_MOVE_ONLY_OBJECT(NAME) \
118 NAME(const NAME&) = delete; \
119 NAME(NAME&&) noexcept = default; \
120 NAME& operator=(const NAME&) = delete; \
121 NAME& operator=(NAME&&) noexcept = default;
126#if !defined(TIMEMORY_DEFAULT_OBJECT)
127# define TIMEMORY_DEFAULT_OBJECT(NAME) \
128 TIMEMORY_HOST_DEVICE_FUNCTION NAME() = default; \
129 NAME(const NAME&) = default; \
130 NAME(NAME&&) noexcept = default; \
131 NAME& operator=(const NAME&) = default; \
132 NAME& operator=(NAME&&) noexcept = default;
137#if !defined(TIMEMORY_EXCEPTION)
138# define TIMEMORY_EXCEPTION(...) \
140 std::stringstream _errmsg; \
141 _errmsg << __VA_ARGS__; \
142 perror(_errmsg.str().c_str()); \
143 std::cerr << _errmsg.str() << std::endl; \
144 std::exit(EXIT_FAILURE); \
150#if !defined(TIMEMORY_TESTING_EXCEPTION) && defined(TIMEMORY_INTERNAL_TESTING)
151# define TIMEMORY_TESTING_EXCEPTION(...) \
153 TIMEMORY_EXCEPTION(__VA_ARGS__) \
155#elif !defined(TIMEMORY_TESTING_EXCEPTION)
156# define TIMEMORY_TESTING_EXCEPTION(...) \
162#if !defined(TIMEMORY_TUPLE_ACCESSOR)
163# define TIMEMORY_TUPLE_ACCESSOR(INDEX, TUPLE, NAME) \
164 auto& NAME() { return std::get<INDEX>(TUPLE); } \
165 const auto& NAME() const { return std::get<INDEX>(TUPLE); }
173template <
typename Tp, Tp Num>
177template <
size_t... Idx>
185template <
typename... Types>
189template <
bool B,
typename T =
int>
196template <
bool B,
typename Lhs,
typename Rhs>
231template <
typename... Tp>
239template <
size_t Idx,
typename Tp>
240struct type_list_element;
244template <
size_t Idx,
size_t TargIdx,
typename... Tail>
245struct type_list_element;
247template <
size_t Idx,
size_t TargIdx>
248struct type_list_element<Idx, TargIdx>
254 static_assert(TargIdx < Idx + 2,
"Error! Index exceeded size of of type_list");
257template <
size_t Idx,
size_t TargIdx,
typename Tp,
typename... Tail>
258struct type_list_element<Idx, TargIdx, Tp, Tail...>
262 typename type_list_element<Idx + 1, TargIdx, Tail...>::type>;
266template <
size_t Idx,
typename... Types>
267struct type_list_element<Idx,
type_list<Types...>>
269 using type =
typename internal::type_list_element<0, Idx, Types...>::type;
272template <
size_t Idx,
typename Tp>
279template <
typename... ArgsT>
280TIMEMORY_ALWAYS_INLINE
void
290template <
typename Tp,
typename DeleterT,
typename Tag>
332template <
typename... Tp>
336template <
typename... Tp>
358struct tree : std::integral_constant<int, 2>
376struct flat : std::integral_constant<int, 0>
398static constexpr size_t scope_count = 3;
410 static input_type _instance{ {
false,
false,
false } };
416template <
typename Arg,
size_t... Idx>
417static TIMEMORY_INLINE
auto
420 static_assert(
sizeof...(Idx) <= scope_count,
"Error! Bad index sequence size");
428template <
size_t... Idx>
429static TIMEMORY_INLINE
auto
432 static_assert(
sizeof...(Idx) <= scope_count,
"Error! Bad index sequence size");
439static TIMEMORY_INLINE
auto
442 return generate(
get_fields(), make_index_sequence<scope_count>{});
463 :
data_type(std::forward<data_type>(obj))
471 explicit config(
bool _flat,
bool _timeline)
476 explicit config(
bool _flat,
bool _timeline,
bool _tree)
493 template <
typename Arg,
typename... Args,
495 std::is_same<Arg, flat>::value ||
496 std::is_same<Arg, timeline>::value),
498 explicit config(Arg&& arg, Args&&... args)
500 *
this += std::forward<Arg>(arg);
513 data_type::operator=(rhs);
520 data_type::operator=(std::forward<data_type>(rhs));
524 template <
typename T, std::enable_if_t<(std::is_same<T, tree>::value ||
525 std::is_same<T, flat>::value ||
526 std::is_same<T, timeline>::value),
530 this->data_type::set(T::value,
true);
534 using data_type::set;
536 template <
typename T, std::enable_if_t<(std::is_same<T, tree>::value ||
537 std::is_same<T, flat>::value ||
538 std::is_same<T, timeline>::value),
542 this->data_type::set(T::value, val);
546 TIMEMORY_NODISCARD
bool is_flat()
const {
return this->test(flat::value); }
547 TIMEMORY_NODISCARD
bool is_timeline()
const {
return this->test(timeline::value); }
552 return this->none() || (this->test(tree::value) && !this->test(flat::value));
556 return (is_flat() && is_timeline());
560 return (is_tree() && is_timeline());
563 template <
bool ForceFlatT>
566 return (ForceFlatT) ?
true : this->test(flat::value);
569 template <
bool ForceTreeT,
bool ForceTimeT>
574 : ((ForceTimeT) ?
false
575 : (this->none() || (this->test(tree::value) &&
576 !this->test(flat::value))));
581 std::stringstream ss;
582 ss << std::boolalpha <<
"tree: " << obj.
is_tree() <<
", flat: " << obj.
is_flat()
584 <<
". Values: flat::value = " << obj.test(flat::value)
585 <<
", timeline::value = " << obj.test(timeline::value)
586 <<
", tree::value = " << obj.test(tree::value);
591 template <
typename ForceTreeT = false_type,
typename ForceFlatT = false_type,
592 typename ForceTimeT = false_type>
595 static_assert(!(ForceTreeT::value && ForceFlatT::value),
596 "Error! Type cannot enforce tree-based call-stack depth storage "
597 "and flat call-stack depth storage simulatenously");
601 if(ForceFlatT::value || is_flat())
614 template <
typename ForceTreeT = false_type,
typename ForceFlatT = false_type,
615 typename ForceTimeT = false_type>
616 uint64_t
compute_hash(uint64_t _id, uint64_t _depth, uint64_t& _counter)
624 if(is_tree<ForceTreeT::value, ForceTimeT::value>() ||
625 is_flat<ForceFlatT::value>())
629 if(ForceTimeT::value || is_timeline())
639static TIMEMORY_INLINE config
640get_default() TIMEMORY_HOT;
641TIMEMORY_INLINE config
642operator+(config _lhs, tree) TIMEMORY_HOT;
643TIMEMORY_INLINE config
644operator+(config _lhs, flat) TIMEMORY_HOT;
645TIMEMORY_INLINE config
646operator+(config _lhs, timeline) TIMEMORY_HOT;
647TIMEMORY_INLINE config
648operator+(config _lhs, config _rhs) TIMEMORY_HOT;
652static TIMEMORY_INLINE auto
653get_default() -> config
655 return config{ get_default_bitset() };
663 _lhs.
set(tree::value,
true);
672 _lhs.
set(flat::value,
true);
681 _lhs.
set(timeline::value,
true);
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 = []() {};
802template <
size_t Idx,
typename... Types>
805 using type =
typename tim::type_list_element<Idx,
tim::type_list<Types...>>::type;
817template <
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,...
hash_value_t get_combined_hash_id(hash_value_t _lhs, Tp &&_rhs)
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.
input_type & get_fields()
config operator+(config _lhs, config _rhs)
std::array< bool, scope_count > input_type
std::bitset< scope_count > data_type
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
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
const std::string std::ostream * os
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.
void consume_parameters(ArgsT &&...)
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)
friend std::ostream & operator<<(std::ostream &os, const config &obj)
config(data_type &&obj) noexcept
config(const config &)=default
config(config &&) noexcept=default
config & operator=(data_type &&rhs) noexcept
config & set(bool val=true)
uint64_t compute_depth(uint64_t _current)
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)
config(const data_type &obj)
provides an object which can be returned from functions that will execute the lambda provided during ...
destructor & operator=(destructor &&rhs) noexcept
destructor(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