These traits identify what "kind" of type some type T is. These are split into two groups:
primary traits which are all mutually exclusive, and composite traits that
are compositions of one or more primary traits.

For any given type, exactly one primary type trait will inherit from true_type,
and all the others will inherit from false_type,
in other words these traits are mutually exclusive.

This means that is_integral<T>::value
and is_floating_point<T>::value
will only ever be true for built-in types; if you want to check for a user-defined
class type that behaves "as if" it is an integral or floating
point type, then use the std::numeric_limitstemplate instead.