/*!
* \file Tmeta.cpp
*
* Copyright (C) 2018 Christos Choutouridis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
*/
#include
#include
#include
namespace test_meta {
using namespace utl;
using namespace meta;
/*
* Types to behave like Fixtures
*/
// Test type_of fixture
template struct Identity {
using type = T;
};
template struct MfunBin {
using type = int;
};
template struct MfunBin_i {
using type = int;
};
template struct MfunUn1 {
using type = int;
};
template struct MfunUn2 {
using type = int;
};
template struct Pred_isInt {
using type = std::is_integral;
};
template struct Pred_isVoid {
using type = std::is_void;
};
/*
* Test integral constant
*/
TEST(Tmeta, IntegrealType) {
EXPECT_EQ(true, (std::is_same>>::value));
}
TEST(Tmeta, IntegrealConstant) {
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(true, (std::is_same::type::value_type>::value));
EXPECT_EQ(42, (integral_::value_type(42)));
EXPECT_EQ(42, (integral_()));
}
TEST(Tmeta, BasicTypes) {
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(true, bool_::value);
EXPECT_EQ(true, (std::is_same::value));
EXPECT_EQ(false, false_::value);
EXPECT_EQ(true, (std::is_same::value));
EXPECT_EQ(true, true_::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42, int8_<42>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42u, uint8_<42u>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42, int16_<42>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42u, uint16_<42u>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42, int32_<42>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42u, uint32_<42u>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42, char_<42>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42, int_<42>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42, long_<42>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42U, index_<42U>::value);
EXPECT_EQ(true, (std::is_same::value_type>::value));
EXPECT_EQ(42U, size_<42U>::value);
EXPECT_EQ(sizeof(int), sizeof_::value);
EXPECT_EQ(alignof(int), alignof_::value);
EXPECT_EQ(static_cast(-1), Npos::value);
}
/*
* Test integral constant arithmetic operations
*/
TEST(Tmeta, ArithmeticOperations) {
EXPECT_EQ (int_<42>(), inc>());
EXPECT_EQ (int_<42>(), dec>());
EXPECT_EQ (int_<42>(), (add, add, int_<2>>>()));
EXPECT_EQ (int_<42>(), (sub, int_<66>>()));
EXPECT_EQ (int_<42>(), (mult, mult, int_<2>>>()));
EXPECT_EQ (int_<42>(), (divide, int_<5>>()));
EXPECT_EQ (int_<42>(), negate>());
EXPECT_EQ (int_< 1>(), (modulo, int_<42>>()));
}
/*
* Test logical
*/
TEST(Tmeta, ComparisonOperations) {
EXPECT_EQ (true, (std::is_same, not_c>::value));
EXPECT_EQ (true, (comp_eq, int_<7>>()));
EXPECT_EQ (true, (comp_ne, int_<7>>()));
EXPECT_EQ (true, (comp_lt, int_<43>>()));
EXPECT_EQ (true, (comp_gt, int_<42>>()));
EXPECT_EQ (true, (comp_le, int_<42>>()));
EXPECT_EQ (true, (comp_ge, int_<42>>()));
}
TEST(Tmeta, BitOperations) {
EXPECT_EQ (0x00, (bitand_, uint8_<0xAA>>()));
EXPECT_EQ (0xFF, (bitor_ , uint8_<0xAA>>()));
EXPECT_EQ (0xFA, (bitxor_, uint8_<0xAF>>()));
EXPECT_EQ (0x00, (bitnot_>()));
EXPECT_EQ (0x04, (shift_left, uint8_<2>>()));
EXPECT_EQ (0x00, (shift_left, uint8_<1>>()));
EXPECT_EQ (0x02, (shift_right, uint8_<2>>()));
EXPECT_EQ (0x00, (shift_right, uint8_<1>>()));
}
TEST(Tmeta, TypeOperations) {
struct Foo {};
struct Bar {};
EXPECT_EQ (true, (std::is_same, not_>>()));
EXPECT_EQ (true, (std::is_same, if_c, bool_>>()));
EXPECT_EQ (true, (std::is_same, if_, int_<42>, bool_>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (same_()));
EXPECT_EQ (false, (same_()));
EXPECT_EQ (true, (not_same_()));
}
/*
* Test void
*/
TEST(Tmeta_void, VoidType) {
struct Foo {};
struct Bar {};
EXPECT_EQ(true, (std::is_same>()));
}
/*
* Test invoke
*/
TEST(Tmeta, Invoke) {
using Q = quote;
using Qi = quote_i;
using Q1 = quote;
using Q2 = quote;
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (is_applicable_t()));
EXPECT_EQ (false, (is_applicable_t()));
EXPECT_EQ (true, (is_applicable_qt()));
EXPECT_EQ (false, (is_applicable_qt()));
EXPECT_EQ (true, (is_applicable_it()));
EXPECT_EQ (false, (is_applicable_it()));
EXPECT_EQ (true, (std::is_same::type, MfunBin>()));
EXPECT_EQ (true, (std::is_same::type, nil_>()));
EXPECT_EQ (true, (std::is_same::type, MfunBin_i<7, 42>>()));
EXPECT_EQ (true, (std::is_same::type, nil_>()));
EXPECT_EQ (true, (std::is_same, nil_>()));
EXPECT_EQ (true, (std::is_same, MfunBin>()));
EXPECT_EQ (true, (std::is_same, int_<42>>, MfunBin_i<7, 42>>()));
EXPECT_EQ (true, (std::is_same>, nil_>()));
EXPECT_EQ (true, (std::is_same, int>, MfunUn1>>()));
EXPECT_EQ (true, (std::is_same<
invoke, int_<7>, int_<42>>,
MfunUn1>>
>()));
EXPECT_EQ (true, (std::is_same<
invoke, int_<42>>,
MfunUn1>
>()));
EXPECT_EQ (true, (std::is_same, long>, MfunBin>()));
EXPECT_EQ (true, (std::is_same, long>, MfunBin>()));
}
/*
* Test typelist
*/
TEST(Tmeta_typelist, Basics) {
using l1 = typelist;
using l2 = typelist;
using l3 = typelist<>;
EXPECT_EQ (true, (std::is_same::times<3>>()));
EXPECT_EQ (true, (std::is_same::times<2>>()));
EXPECT_EQ (true, (std::is_same::times<3>>()));
EXPECT_EQ (true, (std::is_same::times<0>>()));
EXPECT_EQ (true, (std::is_same, pair>()));
EXPECT_EQ (true, (std::is_same, int>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (3, size());
EXPECT_EQ (true, empty());
// pass typelist to an invocable
EXPECT_EQ (true, (std::is_same, typelist>
>,
MfunBin
>()));
}
TEST(Tmeta_typelist, Element_access) {
using l = typelist;
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
}
TEST(Tmeta_typelist, Concat) {
using l1 = typelist;
using l2 = typelist;
using l3 = typelist;
using l4 = typelist<>;
using conc = typelist;
EXPECT_EQ(true, (std::is_same>()));
EXPECT_EQ(true, (std::is_same>()));
EXPECT_EQ(true, (std::is_same>()));
EXPECT_EQ(true, (std::is_same>()));
}
template struct F {}; // binary invocable
TEST(Tmeta_typelist, Fold) {
struct X1 {};
struct X2 {};
struct X3 {};
struct X4 {};
using Q = quote;
EXPECT_EQ(true, (std::is_same, void, Q>, void>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F, X2>>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F, X2>, X3>>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F, X2>, X3>, X4>>()));
EXPECT_EQ(true, (std::is_same, void, Q>, void>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F>>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F>>>()));
EXPECT_EQ(true, (std::is_same, void, Q>, F>>>>()));
}
TEST(Tmeta_typelist, PushPopReverse) {
using list = typelist ;
using l_char = typelist ;
using l_cc = typelist ;
using char_l = typelist ;
using cc_l = typelist;
using rev = typelist;
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
}
TEST(Tmeta_typelist, Transform) {
using QBin = quote;
using QUn = quote;
using l1 = typelist;
using l2 = typelist;
using r = typelist;
using r_ulazy = typelist , MfunUn1, MfunUn1>;
using r_blazy = typelist , MfunBin, MfunBin>;
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
}
TEST(Tmeta_typelist, Find) {
using l1 = typelist ;
using l2 = typelist ;
using l3 = typelist ;
using empty = typelist<>;
EXPECT_EQ(true, (std::is_same, find_if>>()));
EXPECT_EQ(true, (std::is_same>>()));
EXPECT_EQ(true, (std::is_same>>()));
EXPECT_EQ(true, (std::is_same, find>()));
EXPECT_EQ(true, (std::is_same>>()));
EXPECT_EQ(true, (std::is_same>>()));
EXPECT_EQ(true, (std::is_same>>()));
EXPECT_EQ(true, (std::is_same>()));
}
TEST(Tmeta_typelist, Count) {
using list = typelist;
using empty = typelist<>;
EXPECT_EQ (true, (std::is_same, count_if>>()));
EXPECT_EQ (true, (std::is_same, count_if>>()));
EXPECT_EQ (true, (std::is_same, count_if>>()));
EXPECT_EQ (true, (std::is_same, count_if>()));
EXPECT_EQ (true, (std::is_same, count>()));
}
TEST(Tmeta_typelist, Filter) {
using Q1 = quote;
using Q2 = quote;
using list = typelist;
using filtered = typelist;
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same, filter, Q1>>()));
EXPECT_EQ (true, (std::is_same, filter>()));
}
TEST(Tmeta_typelist, Replace) {
using Q = quote;
using list = typelist;
using res = typelist;
using repl = typelist;
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same, replace_if, Q, void>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
}
TEST (Tmeta_typelist, AllAnyNone) {
using l1 = typelist;
using l2 = typelist;
EXPECT_EQ (true, (std::is_same>>()));
EXPECT_EQ (true, (std::is_same>>()));
EXPECT_EQ (true, (std::is_same>>()));
EXPECT_EQ (true, (std::is_same>>()));
EXPECT_EQ (true, (std::is_same>>()));
EXPECT_EQ (true, (std::is_same>>()));
}
}