C++17 is_integral trait implementation This is a C++17 is_integral trait implementation.

Most implementations exhaust all integral types: 


bool
char, char16_t, char32_t, wchar_t
[unsigned] short
[unsigned] [long [long]] int


However, it is possible that the implementation defines some extended signed integer types and extended unsigned integer types. One workaround is to exhaust all the implementations using #ifdefs, but this workaround is not theoretically (in the language lawyer's point of view) portable. For example, if Mickey Mouse just rolls out a brand-new standard-conforming extended integer type, such workarounds fail.

I theorized that for any type T, is_integral&lt;T&gt;::value is true if and only if it is convertible to std::intmax_t or std::uintmax_t via a non-narrowing standard conversion sequence. I tried to deploy this fact, enforcing the two restrictions respectively, by:


using the so-called "uniform initialization" syntax (formally list-initialization) to prevent narrowing conversions; and
using a dummy class (which I call a generator class) with a conversion operator to prevent user-defined conversion sequences.


I tested with the cases of standard integral types (expecting true,) standard floating point types (expecting false,) user-defined types convertible to some standard integral type (expecting false.) All tests passed.

Here is my code, within 40 lines.

// C++17 is_integral implementation
// which handles extended integer types
// in a portable way
// (without resorting to #ifdef chains)

#include &lt;cinttypes&gt; // for std::intmax_t, std::uintmax_t
#include &lt;type_traits&gt; // for std::is_same, std::bool_constant
                       // can be trivially defined manually, just lazy

namespace my_std {
    namespace detail {
        // Generator type to bypass user-defined conversions
        template &lt;typename T&gt;
        struct Generator {
            operator T();
        };
        // helper type to designate substitution failure
        struct Failed {};
        // check functions (exploit SFINAE)
        // uses brace syntax to prevent narrowing conversions
        template &lt;typename T&gt;
        auto check_signed(int) -&gt; decltype(std::intmax_t{Generator&lt;T&gt;{}});
        template &lt;typename T&gt;
        auto check_signed(...) -&gt; Failed;
        template &lt;typename T&gt;
        auto check_unsigned(int) -&gt; decltype(std::uintmax_t{Generator&lt;T&gt;{}});
        template &lt;typename T&gt;
        auto check_unsigned(...) -&gt; Failed;
        // function invoker trait
        template &lt;typename T&gt;
        struct Int_trait {
            static constexpr bool is_signed_int = !std::is_same_v&lt;
                Failed, decltype(check_signed&lt;T&gt;(0))
            &gt;;
            static constexpr bool is_unsigned_int = !std::is_same_v&lt;
                Failed, decltype(check_unsigned&lt;T&gt;(0))
            &gt;;
            static constexpr bool is_int = is_signed_int || is_unsigned_int;
        };
    }
    // "the" trait
    template &lt;typename T&gt;
    struct is_integral
        :std::bool_constant&lt;detail::Int_trait&lt;T&gt;::is_int&gt;
        { };
}


Any criticism or suggestion is highly appreciated!

&lt;joke&gt;The absolute best implementation with maximum portability and simplicity and clarity that is guaranteed to work on all machines is:

#include &lt;type_traits&gt;
namespace my_std {
    template &lt;typename T&gt;
    struct is_integral
        :std::is_integral&lt;T&gt;
        { };
}


&lt;/joke&gt;
I tested with the cases of standard integral types (expecting true,) standard floating point types (expecting false,) user-defined types convertible to some standard integral type (expecting false.) All tests passed.


You should have tested with all the other kinds of types in C++. Reference types, pointer types, enum types, nullptr_t, void, pointer-to-member types, etc. etc.

Your is_integral incorrectly reports that int&amp; is an integral type. (Godbolt.)

It's not a hard fix, of course; but the code-review feedback is "Write more tests."