LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/

Simple traits for the implementation of other traits. More...

Namespaces

 util::details
 

Classes

struct  util::self_type< T >
 Trait returning the very same type as in the template argument. More...
 
struct  util::always_false_type< typename >
 A std::false_type with a template argument. More...
 
struct  util::always_true_type< typename >
 A std::true_type with a template argument. More...
 

Typedefs

template<typename T >
using util::self_t = typename self_type< T >::type
 The very same type as in the template argument. More...
 
template<bool Value>
using util::bool_constant = std::integral_constant< bool, Value >
 
template<typename BoolTrait >
using util::negation = bool_constant<!BoolTrait::value >
 
template<typename A , typename B >
using util::is_not_same = negation< std::is_same< A, B >>
 

Variables

template<typename >
constexpr bool util::always_false_v = false
 A templated constant, always false. More...
 
template<typename >
constexpr bool util::always_true_v = true
 A template constant always true. More...
 
template<typename T >
void util::staticDumpClassName ()
 Helper to determine the type of a variable at compilation time. More...
 
template<typename T >
void util::staticDumpClassName (T)
 Helper to determine the type of a variable at compilation time. More...
 
template<typename Target , typename... T>
using util::count_type_in_list = details::count_type_in_list_impl< Target, T... >
 Returns how many of the types in T exactly match Target. More...
 
template<std::size_t N, typename... T>
using util::typelist_element_type = std::tuple_element< N, std::tuple< T... >>
 Returns the N type of the type list. More...
 
template<std::size_t N, typename... T>
using util::typelist_element_t = typename typelist_element_type< N, T... >::type
 Direct access to the value in typelist_element_type. More...
 
template<typename Target , typename... T>
using util::type_is_in = details::type_is_in_impl< Target, T... >
 Holds whether the Target type is among the ones in the T pack. More...
 
template<typename Target , typename... T>
constexpr unsigned int util::count_type_in_list_v = count_type_in_list<Target, T...>()
 Direct access to the value in count_type_in_list. More...
 
template<typename Target , typename... T>
constexpr bool util::type_is_in_v = type_is_in<Target, T...>()
 Direct access to the value in type_is_in. More...
 

Detailed Description

Simple traits for the implementation of other traits.

Typedef Documentation

template<bool Value>
using util::bool_constant = typedef std::integral_constant<bool, Value>
Todo:
Replace all uses with std::bool_constant when C++17 is adopted

Definition at line 168 of file MetaUtils.h.

template<typename Target , typename... T>
using util::count_type_in_list = typedef details::count_type_in_list_impl<Target, T...>

Returns how many of the types in T exactly match Target.

Definition at line 107 of file TupleLookupByTag.h.

template<typename A , typename B >
using util::is_not_same = typedef negation<std::is_same<A, B>>

The negation of std::is_same.

Todo:
Switch to std::negation in implementation when C++17 is adopted

Definition at line 178 of file MetaUtils.h.

template<typename BoolTrait >
using util::negation = typedef bool_constant<!BoolTrait::value>
Todo:
Replace all uses with std::negation when C++17 is adopted

Definition at line 173 of file MetaUtils.h.

template<typename T >
using util::self_t = typedef typename self_type<T>::type

The very same type as in the template argument.

Definition at line 63 of file MetaUtils.h.

template<typename Target , typename... T>
using util::type_is_in = typedef details::type_is_in_impl<Target, T...>

Holds whether the Target type is among the ones in the T pack.

Definition at line 125 of file TupleLookupByTag.h.

template<std::size_t N, typename... T>
using util::typelist_element_t = typedef typename typelist_element_type<N, T...>::type

Direct access to the value in typelist_element_type.

Definition at line 120 of file TupleLookupByTag.h.

template<std::size_t N, typename... T>
using util::typelist_element_type = typedef std::tuple_element<N, std::tuple<T...>>

Returns the N type of the type list.

Definition at line 116 of file TupleLookupByTag.h.

Function Documentation

template<typename T >
void util::staticDumpClassName ( )

Helper to determine the type of a variable at compilation time.

Template Parameters
Ttype to be investigated

It may be difficult to understand which type is being used in a failing static assertion or in some complicate metaprogramming code (is there any other kind?), especially when due to a compilation failure the code can't be run. This class is supposed to help by forcing the compiler to a halt, and it is devised so that the compiler should print in the error message what it thinks the type T is.

An example of usage:

#include "MetaUtils.h"
void f() {
constexpr auto v = 5U - 6U; // which type is `v` of?
}

For example, Clang 5.0.1 emits these errors:

In file included from metatest.cpp:1:
./MetaUtils.h:217:7: error: static_assert failed "ClassNameStaticDumper<T>: look for T in the error message context"
static_assert(
^
./MetaUtils.h:228:39: note: in instantiation of template class 'util::details::ClassNameStaticDumper<unsigned int>' requested here
void staticDumpClassName() { (void) details::ClassNameStaticDumper<T>(); }
^
./MetaUtils.h:195:46: note: in instantiation of function template specialization 'util::staticDumpClassName<unsigned int>' requested here
[[noreturn]] void staticDumpClassName(T) { staticDumpClassName<T>(); }
^
metatest.cpp:5:16: note: in instantiation of function template specialization 'util::staticDumpClassName<unsigned int>' requested here
^
1 error generated.

From the first "note" we can see that the type of v is unsigned int. Note that if v is not copiable, an additional error will be emitted. To avoid that, the type can be specified as template parameter, as in util::staticDumpClassName<decltype(v)>(). The same program is processed by GNU GCC with an error message: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from metatest.cpp:1:0: MetaUtils.h: In instantiation of ‘struct util::details::ClassNameStaticDumper<unsigned int>’: MetaUtils.h:248:48: required from ‘void util::staticDumpClassName() [with T = unsigned int]’ MetaUtils.h:215:68: required from ‘void util::staticDumpClassName(T) [with T = unsigned int]’ metatest.cpp:5:30: required from here MetaUtils.h:237:7: error: static assertion failed: ClassNameStaticDumper<T>: look for T in the error message context static_assert( ^~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ where the type is mentioned in all the three context lines.

Definition at line 274 of file MetaUtils.h.

274 { (void) details::ClassNameStaticDumper<T>(); }
template<typename T >
void util::staticDumpClassName ( )

Helper to determine the type of a variable at compilation time.

Template Parameters
Ttype to be investigated

It may be difficult to understand which type is being used in a failing static assertion or in some complicate metaprogramming code (is there any other kind?), especially when due to a compilation failure the code can't be run. This class is supposed to help by forcing the compiler to a halt, and it is devised so that the compiler should print in the error message what it thinks the type T is.

An example of usage:

#include "MetaUtils.h"
void f() {
constexpr auto v = 5U - 6U; // which type is `v` of?
}

For example, Clang 5.0.1 emits these errors:

In file included from metatest.cpp:1:
./MetaUtils.h:217:7: error: static_assert failed "ClassNameStaticDumper<T>: look for T in the error message context"
static_assert(
^
./MetaUtils.h:228:39: note: in instantiation of template class 'util::details::ClassNameStaticDumper<unsigned int>' requested here
void staticDumpClassName() { (void) details::ClassNameStaticDumper<T>(); }
^
./MetaUtils.h:195:46: note: in instantiation of function template specialization 'util::staticDumpClassName<unsigned int>' requested here
[[noreturn]] void staticDumpClassName(T) { staticDumpClassName<T>(); }
^
metatest.cpp:5:16: note: in instantiation of function template specialization 'util::staticDumpClassName<unsigned int>' requested here
^
1 error generated.

From the first "note" we can see that the type of v is unsigned int. Note that if v is not copiable, an additional error will be emitted. To avoid that, the type can be specified as template parameter, as in util::staticDumpClassName<decltype(v)>(). The same program is processed by GNU GCC with an error message: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from metatest.cpp:1:0: MetaUtils.h: In instantiation of ‘struct util::details::ClassNameStaticDumper<unsigned int>’: MetaUtils.h:248:48: required from ‘void util::staticDumpClassName() [with T = unsigned int]’ MetaUtils.h:215:68: required from ‘void util::staticDumpClassName(T) [with T = unsigned int]’ metatest.cpp:5:30: required from here MetaUtils.h:237:7: error: static assertion failed: ClassNameStaticDumper<T>: look for T in the error message context static_assert( ^~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ where the type is mentioned in all the three context lines.

Definition at line 241 of file MetaUtils.h.

241 { staticDumpClassName<T>(); }

Variable Documentation

template<typename >
constexpr bool util::always_false_v = false

A templated constant, always false.

See also
util::always_false_type, util::always_true_v

This constant allows a static_assert to fail only when the template type it's in is being instantiated:

template <typename T>
struct MandatoryCustomizationPoint {
static_assert(util::always_false_v<T>, "You have to specialize!");
};
template <typename T>
struct MandatoryCustomizationPoint<std::vector<T>> {
using type = typename std::vector<T>::reference;
};

In this example, using std::false_type might have tipped the compiler to trigger the assertion failure even if the class is not instantiated.

Definition at line 113 of file MetaUtils.h.

template<typename >
constexpr bool util::always_true_v = true

A template constant always true.

See also
util::always_true_type, util::always_false_v

This is one way to allow to specialize for classes with a certain type:

template <typename T, typename = void>
class ReferenceTypeExtractor {
static_assert(util::always_false_v<T>, "Type has no reference!");
};
template <typename Cont>
struct ReferenceTypeExtractor
<Cont, std::enable_if_t<util::always_true_v<typename Cont::value_type>>>
{
using type = typename Cont::reference;
};

Definition at line 162 of file MetaUtils.h.

template<typename Target , typename... T>
constexpr unsigned int util::count_type_in_list_v = count_type_in_list<Target, T...>()

Direct access to the value in count_type_in_list.

Definition at line 112 of file TupleLookupByTag.h.

template<typename Target , typename... T>
constexpr bool util::type_is_in_v = type_is_in<Target, T...>()

Direct access to the value in type_is_in.

Definition at line 129 of file TupleLookupByTag.h.