/*! * \file TmetaTypelist.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 TmetaTypelist { 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 high order metaFun tools */ TEST(TmetaTypelist, Invoke) { using W = wrap ; using Wi = wrap_i; using W1 = wrap; using W2 = wrap; using Q = quote; using Qi = quote_i; using Q1 = quote; using Q2 = quote; // identity EXPECT_EQ (true, (std::is_same>>())); EXPECT_EQ (true, (std::is_same>())); EXPECT_EQ (true, (std::is_same>())); // invoke, check that invoke un-wraps and un-quotes staff EXPECT_EQ (true, (std::is_same< invoke, int, char>, MfunBin >())); EXPECT_EQ (true, (std::is_same< invoke, int, char>, MfunBin >())); EXPECT_EQ (true, (std::is_same< invoke, int_<7>, int_<42>>, MfunBin_i<7, 42> >())); EXPECT_EQ (true, (std::is_same< invoke, int_<7>, int_<42>>, MfunBin_i<7, 42> >())); // Wrap EXPECT_EQ (true, (std::is_same< wrap::template apply, MfunBin >())); EXPECT_EQ (false, (std::is_same< wrap::template apply, MfunBin >())); EXPECT_EQ (true, (std::is_same< wrap_i::template apply, int_<42>>, MfunBin_i<7, 42> >())); EXPECT_EQ (false, (std::is_same< wrap_i::template apply, int_<42>>, MfunBin_i<42, 7> >())); // applicable trait 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_qt())); EXPECT_EQ (false, (is_applicable_qt())); EXPECT_EQ (true, (is_applicable_it())); EXPECT_EQ (false, (is_applicable_it())); // defer 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_>())); // quote EXPECT_EQ (true, (std::is_same< quote::template apply, MfunBin >())); EXPECT_EQ (false,(std::is_same< quote::template apply, MfunBin >())); EXPECT_EQ (true, (std::is_same< quote_i::template apply< int_<7>, int_<42>>, MfunBin_i<7, 42> >())); EXPECT_EQ (false,(std::is_same< quote_i::template apply< int_<7>, int_<42>>, MfunBin_i<42, 7> >())); // compose EXPECT_EQ (true, (std::is_same, int>, MfunUn1>())); EXPECT_EQ (true, (std::is_same, int>, MfunUn1>>())); EXPECT_EQ (true, (std::is_same, int>, MfunUn1>())); 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, int>, MfunUn1>())); EXPECT_EQ (true, (std::is_same, int>, MfunUn1>>())); EXPECT_EQ (true, (std::is_same< invoke, int_<7>, int_<42>>, MfunUn1>> >())); // bind EXPECT_EQ (true, (std::is_same, long>, MfunBin>())); EXPECT_EQ (true, (std::is_same, long>, MfunBin>())); // Check the case of ill formed parameter composition. Quote must save us EXPECT_EQ (true, (std::is_same< nil_, invoke >())); EXPECT_EQ (true, (std::is_same< nil_, invoke> >())); EXPECT_EQ (true, (std::is_same< MfunUn1>, invoke, int_<42>> >())); } /* * Test typelist */ TEST(TmetaTypelist, 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::times<0>>())); EXPECT_EQ (true, (std::is_same, pair>())); EXPECT_EQ (true, (std::is_same, int>>())); EXPECT_EQ (true, (std::is_same>())); EXPECT_EQ (3U, size()); EXPECT_EQ (0U, size()); EXPECT_EQ (true, empty()); // pass typelist to an invocable EXPECT_EQ (true, (std::is_same< apply_t, typelist>, MfunUn1 >())); EXPECT_EQ (true, (std::is_same< apply_t, typelist>, MfunBin >())); } TEST(TmetaTypelist, ElementAccess) { 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>>())); EXPECT_EQ (true, (std::is_same>())); EXPECT_EQ (true, (std::is_same>())); } TEST(TmetaTypelist, 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(TmetaTypelist, 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(TmetaTypelist, 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< char_l, push_front >())); EXPECT_EQ (true, (std::is_same< cc_l, push_front >())); EXPECT_EQ (true, (std::is_same< list, pop_front >())); EXPECT_EQ (true, (std::is_same< l_char, push_back >())); EXPECT_EQ (true, (std::is_same< l_cc, push_back >())); EXPECT_EQ (true, (std::is_same< list, pop_back >())); EXPECT_EQ (true, (std::is_same< rev, reverse >())); } TEST(TmetaTypelist, Transform) { using QBin = quote; // both metafuctions return int 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(TmetaTypelist, 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(TmetaTypelist, 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(TmetaTypelist, 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>())); EXPECT_EQ (true, (std::is_same, filter, Q1>>())); } TEST(TmetaTypelist, 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, replace_if, Q, void>>())); EXPECT_EQ (true, (std::is_same>())); EXPECT_EQ (true, (std::is_same, replace, char, void>>())); } TEST (TmetaTypelist, AllAnyNone) { using l1 = typelist; using l2 = typelist; using l3 = 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>>())); EXPECT_EQ (true, (std::is_same>>())); EXPECT_EQ (true, (std::is_same>>())); } }