/*! * \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_t */ TEST(Tmeta, 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>>())); } }