C++ Concepts¶
Concepts are used to provide the template meta-programming information
about the intented use of a type. For example, concepts::is_component<T>::value
is used
to test whether the type T
is a component and thus, should be continue to
try to provide some functionality for that component. In general, each concept::is_<CONCEPT>
can be activated by inheriting from concepts::<CONCEPT>
. Every concept can be
activated or deactivated by specializing
concept::is_<CONCEPT>
to inherit from std::true_type
or std::false_type
, respectively.
When available, timemory uses the inheritance method so that down-stream users can
perform a template specialization (which overrides the inheritance) is the need arises.
Inheritable Concepts¶
-
template<typename Tp>
struct is_empty¶ concept that specifies that a variadic type is empty
-
template<typename Tp>
struct is_null_type¶ concept that specifies that a type is not a useful type
-
template<typename Tp>
struct is_placeholder¶ concept that specifies that a type is not necessarily marked as not available but is still a dummy type
-
template<typename Tp>
struct is_component¶ concept that specifies that a type is a component. Components are used to perform some measurement, capability, or logging implementation. Adding this concept can be performs through inheriting from tim::component::base, inheriting from tim::concepts::component, or specializing either tim::concepts::is_component or tim::trait::is_component (with the latter being deprecated).
-
template<typename Tp>
struct is_quirk_type¶ concept that specifies that a type is a quirk. Quirks are used to modify the traditional behavior of component bundles slightly. E.g. disable calling start in the constructor of an auto_tuple.
-
template<typename Tp>
struct is_api¶ concept that specifies that a type is an API. APIs are used to designate different project implementations, different external library tools, etc.
-
template<typename Tp>
struct is_variadic¶ concept that specifies that a type is a generic variadic wrapper
-
template<typename Tp>
struct is_wrapper¶ concept that specifies that a type is a timemory variadic wrapper
-
template<typename Tp>
struct is_stack_wrapper¶ concept that specifies that a type is a timemory variadic wrapper and components are stack-allocated
-
template<typename Tp>
struct is_heap_wrapper¶ concept that specifies that a type is a timemory variadic wrapper and components are heap-allocated
-
template<typename Tp>
struct is_mixed_wrapper¶ concept that specifies that a type is a timemory variadic wrapper and variadic types are mix of stack- and heap- allocated
-
template<typename Tp>
struct is_tagged¶ concept that specifies that a type’s template parameters include a API specific tag as one of the template parameters (usually first)
-
template<typename Tp>
struct is_comp_wrapper¶ concept that specifies that a type is a timemory variadic wrapper that does not perform auto start/stop, e.g. component_{tuple,list,hybrid}
-
template<typename Tp>
struct is_auto_wrapper¶ concept that specifies that a type is a timemory variadic wrapper that performs auto start/stop, e.g. auto_{tuple,list,hybrid}
-
template<typename Tp>
struct is_runtime_configurable¶ concept that specifies that a type is used to modify behavior at runtime. For example, the tim::component::user_bundle component is runtime configurable bc it allows you insert components at runtime. The timing category (
tim::category::timing
) is another example of a type that is runtime configurable settingtim::trait::runtime_enabled<tim::category::timing>::set(false);
will disable (at runtime) all the types which are part of the timing API. It should be noted that types which satisfyis_runtime_configurable<Tp>::value == true
(e.g. tim::component::user_bundle) are not eligible to be inserted into other runtime configurable components; i.e. you cannot insert/add tim::component::user_trace_bundle into tim::component::user_global_bundle, etc. This restriction is primarily due to the significant increase in compile-time that arises from allowing this behavior.
-
template<typename Tp>
struct is_external_function_wrapper¶ concept that specifies that a component type wraps external functions
-
template<typename Tp>
struct is_phase_id¶ concept that specifies that a type is used for identifying a phase in some measurement. For example,
tim::audit::incoming
andtim::audit::outgoing
can be added to overloads to distinguish whether thedouble
type indouble exp(double val)
isval
or whether it is the return value.struct exp_wrapper_A { // unable to distingush whether "val" is input or output void audit(double val) { ... } }; struct exp_wrapper_B { // able to distingush whether "val" is input or output void audit(audit::incoming, double val) { ... } void audit(audit::outgoing, double val) { ... } };
Non-Inheritable Concepts¶
-
template<typename Lhs, typename Rhs>
struct is_acceptable_conversion¶ This concept designates that is safe to perform a
static_cast<Lhs>(rhs)
where needed. This is primarily used in the tim::component::data_tracker wheredata_tracker<unsigned int, ...>
might be provided another integral type, such asint
.- tparam Lhs
the provided type
- tparam Rhs
the target type
-
template<typename T>
struct tuple_type¶ This concept is used to express how to convert a given type into a
std::tuple
, e.g.tim::component_tuple<T...>
tostd::tuple<T...>
. It is necessary for types like tim::component_bundle where certain template parameters are tags.
-
template<typename T>
struct auto_type¶ This concept is used to express how to convert a component bundler into another component bundler which performs automatic starting upon construction.
-
template<typename T>
struct component_type¶ This concept is used to express how to convert a component bundler which automatically starts upon construction into a type that requires an explicit call to start.