/*!
* \file TmetaBasic.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 TmetaBasic {
using namespace utl;
using namespace meta;
/*
* Types to behave like Fixtures
*/
// Test type_of fixture
template struct Identity {
using type = T;
};
/*
* Test integral constant
*/
TEST(TmetaBasic, IntegrealType) {
EXPECT_EQ(true, (std::is_same>>::value));
EXPECT_EQ(true, (std::is_same>::value));
EXPECT_EQ(true, (std::is_same>>::value));
EXPECT_EQ(true, (std::is_same>>>::value));
}
TEST(TmetaBasic, 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(TmetaBasic, 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 selection operations
*/
TEST(TmetaBasic, Selection) {
struct Foo {};
struct Bar {};
EXPECT_EQ (true, (std::is_same, if_c, false_>>()));
EXPECT_EQ (true, (std::is_same, Foo>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same, if_, Bar>>()));
EXPECT_EQ (true, (std::is_same, Bar>>()));
EXPECT_EQ (true, (std::is_same, if_, int_<42>, Bar>>()));
EXPECT_EQ (true, (std::is_same, int_<42>, Foo>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (false,(std::is_same>()));
EXPECT_EQ (false,(std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
}
TEST(TmetaBasic, LogicalOperations) {
struct Foo {};
struct Bar {};
EXPECT_EQ (true, (std::is_same>::value));
EXPECT_EQ (true, (std::is_same>::value));
EXPECT_EQ (true, (std::is_same>::value));
EXPECT_EQ (true, (std::is_same>::value));
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, int_<0>, not_>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same,or_>>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same>()));
EXPECT_EQ (true, (std::is_same,or_, false_, not_, not_c, int_<1>>>()));
EXPECT_EQ (true, (std::is_same, not_, not_c>>()));
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, (same()));
EXPECT_EQ (false, (same()));
EXPECT_EQ (true, (not_same()));
}
/*
* Test integral constant arithmetic operations
*/
TEST(TmetaBasic, 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 integral constant comparison operations
*/
TEST(TmetaBasic, ComparisonOperations) {
EXPECT_EQ (true, (comp_eq, int_<7>>()));
EXPECT_EQ (true, (comp_eq, int_<-7>>()));
EXPECT_EQ (false, (comp_eq, int_<7>>()));
EXPECT_EQ (true, (comp_ne, int_<7>>()));
EXPECT_EQ (false, (comp_ne, int_<42>>()));
EXPECT_EQ (true, (comp_ne, int_<-42>>()));
EXPECT_EQ (true, (comp_lt, int_<43>>()));
EXPECT_EQ (true, (comp_lt, int_<-5>>()));
EXPECT_EQ (false, (comp_lt, int_<42>>()));
EXPECT_EQ (true, (comp_gt, int_<7>>()));
EXPECT_EQ (true, (comp_gt, int_<-42>>()));
EXPECT_EQ (false, (comp_gt, int_<42>>()));
EXPECT_EQ (true, (comp_le, int_<42>>()));
EXPECT_EQ (true, (comp_le, int_<42>>()));
EXPECT_EQ (true, (comp_le, int_<42>>()));
EXPECT_EQ (true, (comp_le, int_<-7>>()));
EXPECT_EQ (false, (comp_le, int_<7>>()));
EXPECT_EQ (false, (comp_le, int_<-42>>()));
EXPECT_EQ (true, (comp_ge, int_<7>>()));
EXPECT_EQ (true, (comp_ge, int_<-7>>()));
EXPECT_EQ (true, (comp_ge, int_<42>>()));
EXPECT_EQ (true, (comp_ge, int_<-7>>()));
EXPECT_EQ (false, (comp_ge, int_<43>>()));
EXPECT_EQ (false, (comp_ge, int_<42>>()));
}
/*
* Test integral constant bit operations
*/
TEST(TmetaBasic, 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 (0x0000, (bitand_, uint16_<0xAAAA>>()));
EXPECT_EQ (0xFFFF, (bitor_ , uint16_<0xAAAA>>()));
EXPECT_EQ (0xFFAA, (bitxor_, uint16_<0xAAFF>>()));
EXPECT_EQ (0x0000, (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>>()));
}
/*
* SFINAE
*/
template ::type::value>>
int check1 (T x) { return x; }
int check1 (...) { return 0; }
template ::type::value, void>>
int check2 (T x) { return x; }
int check2 (...) { return 0; }
TEST(TmetaBasic, Sfinae) {
EXPECT_EQ (42, check1(42));
EXPECT_EQ (0, check1(42.0));
EXPECT_EQ (0, check1());
EXPECT_EQ (42, check2(42));
EXPECT_EQ (0, check2(42.0));
EXPECT_EQ (0, check2());
}
}