test_type_traits.cpp

Back to Type traits

test/pastel/sys/

// Description: Testing for type traits
// DocumentationOf: type_traits.h

#include "test/test_init.h"

#include "pastel/sys/type_traits.h"

namespace
{

        template <
            typename Type,
            typename = typename std::enable_if<!std::is_same<Type, Type>::value>::type>
        struct FailingTest;

        template <
            typename Type,
            typename = typename std::enable_if<std::is_same<Type, integer>::value>::type>
        struct IntegerTest;

}

TEST_CASE("Compiles (type_traits)")
{
    PASTEL_STATIC_ASSERT(!(Compiles<FailingTest, integer>::value));
    PASTEL_STATIC_ASSERT((Compiles<IntegerTest, integer>::value));
    PASTEL_STATIC_ASSERT(!(Compiles<IntegerTest, float>::value));
}

namespace
{

    template <
        typename Left,
        typename Right>
    struct Plus_
    : std::integral_constant<integer, Left::value + Right::value>
    {};

}

TEST_CASE("Fold (type_traits)")
{
    using Identity = std::integral_constant<integer, 0>;
    {
        using Sum = Fold<Plus_, Identity>;
    }
    {
        using Sum = Fold<Plus_, Identity>;
        PASTEL_STATIC_ASSERT(Sum::value == Identity::value);
    }
    {
        using Sum = 
            Fold<Plus_,
                Identity,
                std::integral_constant<integer, 1>
            >;

        PASTEL_STATIC_ASSERT(Sum::value == 1);
    }
    {
        using Sum = 
            Fold<
                Plus_,
                Identity,
                std::integral_constant<integer, 1>,
                std::integral_constant<integer, 2>,
                std::integral_constant<integer, 3>
            >;

        PASTEL_STATIC_ASSERT(Sum::value == 6);
    }
}

namespace
{

    template <typename...>
    class A_Template
    {};

    using A0 = A_Template<>;
    using A1 = A_Template<int>;
    using A2 = A_Template<int, float>;

    template <typename...>
    class B_Template
    {};

    using B0 = B_Template<>;
    using B1 = B_Template<int>;
    using B2 = B_Template<int, float>;

}

TEST_CASE("IsTemplateInstance (type_traits)")
{
    PASTEL_STATIC_ASSERT((IsTemplateInstance<A0, A_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<A1, A_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<A2, A_Template>::value));

    PASTEL_STATIC_ASSERT((IsTemplateInstance<const volatile A0&, A_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<const volatile A1&, A_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<const volatile A2&, A_Template>::value));

    PASTEL_STATIC_ASSERT((!IsTemplateInstance<B0, A_Template>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateInstance<B1, A_Template>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateInstance<B2, A_Template>::value));

    PASTEL_STATIC_ASSERT((!IsTemplateInstance<const volatile B0&, A_Template>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateInstance<const volatile B1&, A_Template>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateInstance<const volatile B2&, A_Template>::value));

    PASTEL_STATIC_ASSERT((IsTemplateInstance<B0, B_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<B1, B_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<B2, B_Template>::value));

    PASTEL_STATIC_ASSERT((IsTemplateInstance<const volatile B0&&, B_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<const volatile B1&&, B_Template>::value));
    PASTEL_STATIC_ASSERT((IsTemplateInstance<const volatile B2&&, B_Template>::value));

    PASTEL_STATIC_ASSERT((!IsTemplateInstance<A0, B_Template>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateInstance<A1, B_Template>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateInstance<A2, B_Template>::value));
}

namespace
{

    class C0
        : public B0
    {};

    class C1
        : public B1
    {};

    class C2
        : public B2
    {};

}

TEST_CASE("IsTemplateBaseOf (type_traits)")
{
    PASTEL_STATIC_ASSERT((IsTemplateBaseOf<B_Template, C0>::value));
    PASTEL_STATIC_ASSERT((IsTemplateBaseOf<B_Template, C1>::value));
    PASTEL_STATIC_ASSERT((IsTemplateBaseOf<B_Template, C2>::value));

    PASTEL_STATIC_ASSERT((!IsTemplateBaseOf<A_Template, C0>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateBaseOf<A_Template, C1>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateBaseOf<A_Template, C2>::value));

    PASTEL_STATIC_ASSERT((!IsTemplateBaseOf<A_Template, A0>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateBaseOf<A_Template, A1>::value));
    PASTEL_STATIC_ASSERT((!IsTemplateBaseOf<A_Template, A2>::value));
}

TEST_CASE("TemplateBase (type_traits)")
{
    PASTEL_STATIC_ASSERT((
        std::is_same<TemplateBase<B_Template, C0>, B0>::value));
    PASTEL_STATIC_ASSERT((
        std::is_same<TemplateBase<B_Template, C1>, B1>::value));
    PASTEL_STATIC_ASSERT((
        std::is_same<TemplateBase<B_Template, C2>, B2>::value));
    PASTEL_STATIC_ASSERT((
        std::is_same<TemplateBase<A_Template, C0>, void>::value));
    PASTEL_STATIC_ASSERT((
        std::is_same<TemplateBase<B_Template, A0>, void>::value));
}

TEST_CASE("And (type_traits)")
{
    PASTEL_STATIC_ASSERT((And<>::value));

    PASTEL_STATIC_ASSERT((And<std::true_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::false_type>::value));

    PASTEL_STATIC_ASSERT((!And<std::false_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::true_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::false_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((And<std::true_type, std::true_type>::value));

    PASTEL_STATIC_ASSERT((!And<std::false_type, std::false_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::false_type, std::false_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::false_type, std::true_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::false_type, std::true_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::true_type, std::false_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::true_type, std::false_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((!And<std::true_type, std::true_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((And<std::true_type, std::true_type, std::true_type>::value));

    PASTEL_STATIC_ASSERT(!(And<std::is_same<void, void>, std::is_same<void, int>>::value));
}

TEST_CASE("Or (type_traits)")
{
    PASTEL_STATIC_ASSERT((!Or<>::value));

    PASTEL_STATIC_ASSERT((Or<std::true_type>::value));
    PASTEL_STATIC_ASSERT((!Or<std::false_type>::value));

    PASTEL_STATIC_ASSERT((!Or<std::false_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::true_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::false_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::true_type, std::true_type>::value));

    PASTEL_STATIC_ASSERT((!Or<std::false_type, std::false_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::false_type, std::false_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::false_type, std::true_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::false_type, std::true_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::true_type, std::false_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::true_type, std::false_type, std::true_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::true_type, std::true_type, std::false_type>::value));
    PASTEL_STATIC_ASSERT((Or<std::true_type, std::true_type, std::true_type>::value));
}

TEST_CASE("Not (type_traits)")
{
    PASTEL_STATIC_ASSERT((Not<std::true_type>::value == false));
    PASTEL_STATIC_ASSERT((Not<std::false_type>::value == true));
}