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 setting tim::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 satisfy is_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 and tim::audit::outgoing can be added to overloads to distinguish whether the double type in double exp(double val) is val 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 where data_tracker<unsigned int, ...> might be provided another integral type, such as int.

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...> to std::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.