TmetaBasic.cpp
Go to the documentation of this file.
#include <utl/meta/meta.h>
#include <gtest/gtest.h>
#include <type_traits>
namespace TmetaBasic {
using namespace utl;
using namespace meta;
/*
* Types to behave like Fixtures
*/
// Test type_of fixture
template<class T> struct Identity {
using type = T;
};
/*
* Test integral constant
*/
TEST(TmetaBasic, IntegrealType) {
EXPECT_EQ(true, (std::is_same<int, eval<Identity<int>>>::value));
EXPECT_EQ(true, (std::is_same<nil_, eval<nil_>>::value));
EXPECT_EQ(true, (std::is_same<nil_, eval<eval<nil_>>>::value));
EXPECT_EQ(true, (std::is_same<nil_, eval<eval<eval<nil_>>>>::value));
}
TEST(TmetaBasic, IntegrealConstant) {
EXPECT_EQ(true, (std::is_same<int, integral_<int, 42>::value_type>::value));
EXPECT_EQ(true, (std::is_same<int, integral_<int, 42>::type::value_type>::value));
EXPECT_EQ(42, (integral_<int, 0>::value_type(42)));
EXPECT_EQ(42, (integral_<int, 42>()));
}
TEST(TmetaBasic, BasicTypes) {
EXPECT_EQ(true, (std::is_same<bool, bool_<false>::value_type>::value));
EXPECT_EQ(true, bool_<true>::value);
EXPECT_EQ(true, (std::is_same<bool, false_::value_type>::value));
EXPECT_EQ(false, false_::value);
EXPECT_EQ(true, (std::is_same<bool, true_::value_type>::value));
EXPECT_EQ(true, true_::value);
EXPECT_EQ(true, (std::is_same<int8_t, int8_<0>::value_type>::value));
EXPECT_EQ(42, int8_<42>::value);
EXPECT_EQ(true, (std::is_same<uint8_t, uint8_<0>::value_type>::value));
EXPECT_EQ(42u, uint8_<42u>::value);
EXPECT_EQ(true, (std::is_same<int16_t, int16_<0>::value_type>::value));
EXPECT_EQ(42, int16_<42>::value);
EXPECT_EQ(true, (std::is_same<uint16_t, uint16_<0>::value_type>::value));
EXPECT_EQ(42u, uint16_<42u>::value);
EXPECT_EQ(true, (std::is_same<int32_t, int32_<0>::value_type>::value));
EXPECT_EQ(42, int32_<42>::value);
EXPECT_EQ(true, (std::is_same<uint32_t, uint32_<0>::value_type>::value));
EXPECT_EQ(42u, uint32_<42u>::value);
EXPECT_EQ(true, (std::is_same<char, char_<0>::value_type>::value));
EXPECT_EQ(42, char_<42>::value);
EXPECT_EQ(true, (std::is_same<int, int_<0>::value_type>::value));
EXPECT_EQ(42, int_<42>::value);
EXPECT_EQ(true, (std::is_same<long, long_<0>::value_type>::value));
EXPECT_EQ(42, long_<42>::value);
EXPECT_EQ(true, (std::is_same<index_t, index_<0>::value_type>::value));
EXPECT_EQ(42U, index_<42U>::value);
EXPECT_EQ(true, (std::is_same<size_t, size_<0>::value_type>::value));
EXPECT_EQ(42U, size_<42U>::value);
EXPECT_EQ(sizeof(int), sizeof_<int>::value);
EXPECT_EQ(alignof(int), alignof_<int>::value);
EXPECT_EQ(static_cast<index_t>(-1), Npos::value);
}
/*
* Test integral constant selection operations
*/
TEST(TmetaBasic, Selection) {
struct Foo {};
struct Bar {};
EXPECT_EQ (true, (std::is_same<int_<42>, if_c<true, int_<42>, false_>>()));
EXPECT_EQ (true, (std::is_same<Foo, if_c<false, int_<42>, Foo>>()));
EXPECT_EQ (true, (std::is_same<Foo, if_c<42, Foo, Bar>>()));
EXPECT_EQ (true, (std::is_same<int_<42>, if_<true_, int_<42>, Bar>>()));
EXPECT_EQ (true, (std::is_same<Bar, if_<false_, int_<42>, Bar>>()));
EXPECT_EQ (true, (std::is_same<int_<42>, if_<int_<1>, int_<42>, Bar>>()));
EXPECT_EQ (true, (std::is_same<Foo, if_<int_<0>, int_<42>, Foo>>()));
EXPECT_EQ (true, (std::is_same<true_, first_of<true_, false_>>()));
EXPECT_EQ (false,(std::is_same<true_, first_of<false_, true_>>()));
EXPECT_EQ (false,(std::is_same<true_, second_of<true_, false_>>()));
EXPECT_EQ (true, (std::is_same<true_, second_of<false_, true_>>()));
}
TEST(TmetaBasic, LogicalOperations) {
struct Foo {};
struct Bar {};
EXPECT_EQ (true, (std::is_same<true_, not_c<false>>::value));
EXPECT_EQ (true, (std::is_same<false_, not_c<true>>::value));
EXPECT_EQ (true, (std::is_same<false_, not_c<1>>::value));
EXPECT_EQ (true, (std::is_same<true_, not_c<0>>::value));
EXPECT_EQ (true, (std::is_same<true_, not_<false_>>()));
EXPECT_EQ (true, (std::is_same<false_, not_<true_>>()));
EXPECT_EQ (true, (std::is_same<true_, not_<int_<0>>>()));
EXPECT_EQ (true, (std::is_same<false_, not_<int_<1>>>()));
EXPECT_EQ (true, (std::is_same<false_, or_<false_, false_, not_c<true>, int_<0>, not_<true_>>>()));
EXPECT_EQ (true, (std::is_same<false_, or_<>>()));
EXPECT_EQ (true, (std::is_same<int_<1>,or_<int_<1>>>()));
EXPECT_EQ (true, (std::is_same<true_, or_<true_>>()));
EXPECT_EQ (true, (std::is_same<true_, or_<false_, true_>>()));
EXPECT_EQ (true, (std::is_same<true_, or_<false_, false_, true_>>()));
EXPECT_EQ (true, (std::is_same<int_<1>,or_<int_<0>, false_, not_<true_>, not_c<true>, int_<1>>>()));
EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_, int_<1>, not_<false_>, not_c<false>>>()));
EXPECT_EQ (true, (std::is_same<true_, and_<>>()));
EXPECT_EQ (true, (std::is_same<true_, and_<true_>>()));
EXPECT_EQ (true, (std::is_same<false_, and_<false_>>()));
EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_>>()));
EXPECT_EQ (true, (std::is_same<false_, and_<true_, false_>>()));
EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_, true_>>()));
EXPECT_EQ (true, (std::is_same<false_, and_<true_, true_, false_>>()));
EXPECT_EQ (true, (same_<Foo, Foo>()));
EXPECT_EQ (false, (same_<Foo, Bar>()));
EXPECT_EQ (true, (not_same_<Foo, Bar>()));
}
/*
* Test integral constant arithmetic operations
*/
TEST(TmetaBasic, ArithmeticOperations) {
EXPECT_EQ (int_<42>(), inc<int_<41>>());
EXPECT_EQ (int_<42>(), dec<int_<43>>());
EXPECT_EQ (int_<42>(), (add<int_<23>, add<int_<17>, int_<2>>>()));
EXPECT_EQ (int_<42>(), (sub<int_<108>, int_<66>>()));
EXPECT_EQ (int_<42>(), (mult<int_<7>, mult<int_<3>, int_<2>>>()));
EXPECT_EQ (int_<42>(), (divide<int_<210>, int_<5>>()));
EXPECT_EQ (int_<42>(), negate<int_<-42>>());
EXPECT_EQ (int_< 1>(), (modulo<int_<43>, int_<42>>()));
}
/*
* Test integral constant comparison operations
*/
TEST(TmetaBasic, ComparisonOperations) {
EXPECT_EQ (true, (comp_eq<int_<7>, int_<7>>()));
EXPECT_EQ (true, (comp_eq<int_<-7>, int_<-7>>()));
EXPECT_EQ (false, (comp_eq<int_<42>, int_<7>>()));
EXPECT_EQ (true, (comp_ne<int_<42>, int_<7>>()));
EXPECT_EQ (false, (comp_ne<int_<42>, int_<42>>()));
EXPECT_EQ (true, (comp_ne<int_<42>, int_<-42>>()));
EXPECT_EQ (true, (comp_lt<int_<42>, int_<43>>()));
EXPECT_EQ (true, (comp_lt<int_<-7>, int_<-5>>()));
EXPECT_EQ (false, (comp_lt<int_<43>, int_<42>>()));
EXPECT_EQ (true, (comp_gt<int_<42>, int_<7>>()));
EXPECT_EQ (true, (comp_gt<int_<7>, int_<-42>>()));
EXPECT_EQ (false, (comp_gt<int_<7>, int_<42>>()));
EXPECT_EQ (true, (comp_le<int_<7>, int_<42>>()));
EXPECT_EQ (true, (comp_le<int_<-7>, int_<42>>()));
EXPECT_EQ (true, (comp_le<int_<42>, int_<42>>()));
EXPECT_EQ (true, (comp_le<int_<-7>, int_<-7>>()));
EXPECT_EQ (false, (comp_le<int_<42>, int_<7>>()));
EXPECT_EQ (false, (comp_le<int_<7>, int_<-42>>()));
EXPECT_EQ (true, (comp_ge<int_<42>, int_<7>>()));
EXPECT_EQ (true, (comp_ge<int_<42>, int_<-7>>()));
EXPECT_EQ (true, (comp_ge<int_<42>, int_<42>>()));
EXPECT_EQ (true, (comp_ge<int_<-7>, int_<-7>>()));
EXPECT_EQ (false, (comp_ge<int_<42>, int_<43>>()));
EXPECT_EQ (false, (comp_ge<int_<-7>, int_<42>>()));
}
/*
* Test integral constant bit operations
*/
TEST(TmetaBasic, BitOperations) {
EXPECT_EQ (0x00, (bitand_<uint8_<0x55>, uint8_<0xAA>>()));
EXPECT_EQ (0xFF, (bitor_ <uint8_<0x55>, uint8_<0xAA>>()));
EXPECT_EQ (0xFA, (bitxor_<uint8_<0x55>, uint8_<0xAF>>()));
EXPECT_EQ (0x00, (bitnot_<uint8_<-1>>()));
EXPECT_EQ (0x0000, (bitand_<uint16_<0x5555>, uint16_<0xAAAA>>()));
EXPECT_EQ (0xFFFF, (bitor_ <uint16_<0x5555>, uint16_<0xAAAA>>()));
EXPECT_EQ (0xFFAA, (bitxor_<uint16_<0x5555>, uint16_<0xAAFF>>()));
EXPECT_EQ (0x0000, (bitnot_<uint16_<-1>>()));
EXPECT_EQ (0x04, (shift_left<uint8_<0x01>, uint8_<2>>()));
EXPECT_EQ (0x00, (shift_left<uint8_<0x80>, uint8_<1>>()));
EXPECT_EQ (0x02, (shift_right<uint8_<0x08>, uint8_<2>>()));
EXPECT_EQ (0x00, (shift_right<uint8_<0x01>, uint8_<1>>()));
}
/*
* SFINAE
*/
template <typename T, typename =when<same_<T, int>::type::value>>
int check1 (T x) { return x; }
int check1 (...) { return 0; }
template <typename T, typename =enable_if_t<same_<T, int>::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());
}
}
utl::meta::first_of
T1 first_of
Select the first type of a type sequence.
Definition: selection.h:76
meta.h
Include all meta library.
utl::meta::uint8_
integral_< uint8_t, v > uint8_
uint8_ type: integral constant wrapper for uint8_t
Definition: integral.h:76
utl::meta::comp_eq
bool_< _Tp1()==_Tp2()> comp_eq
Definition: operations.h:184
utl::meta::shift_right
integral_< typename _Tp::value_type,(typename _Tp::value_type)(_Tp() > > shift())> shift_right
Definition: operations.h:221
utl::meta::comp_ne
not_< comp_eq< _Tp1, _Tp2 > > comp_ne
Not equal.
Definition: operations.h:189
utl::meta::int8_
integral_< int8_t, v > int8_
int8_ type: integral constant wrapper for int8_t
Definition: integral.h:73
utl::meta::if_
if_c< If::type::value, Args... > if_
Select one type or another depending on a compile-time Boolean type.
Definition: selection.h:66
utl::meta::bitand_
integral_< decltype(_Tp1() &_Tp2()), _Tp1() &_Tp2()> bitand_
Definition: operations.h:208
utl::meta::negate
integral_< decltype(-_Tp()), -_Tp()> negate
Negation.
Definition: operations.h:138
utl::meta::sub
add< _Tp1, negate< _Tp2 > > sub
Substruction.
Definition: operations.h:165
utl::meta::mult
integral_< decltype(_Tp2() *_Tp2()), _Tp1() *_Tp2() > mult
Multiplication.
Definition: operations.h:150
utl::meta::true_
bool_< true > true_
The type used as a compile-time boolean with true value.
Definition: integral.h:68
utl::meta::if_c
eval< detail::if_c_< B, Args... > > if_c
Select one type or another depending on a compile-time Boolean.
Definition: selection.h:62
TmetaBasic::TEST
TEST(TmetaBasic, IntegrealType)
Definition: TmetaBasic.cpp:39
utl::meta::second_of
T2 second_of
Select the second type of a type sequence.
Definition: selection.h:79
utl::meta::comp_lt
bool_<(_Tp1()< _Tp2())> comp_lt
Definition: operations.h:186
utl::meta::size_
integral_< size_t, v > size_
size_ type: integral constant wrapper for size_t a.k.a std::size_t
Definition: integral.h:110
utl::meta::bitor_
integral_< decltype(_Tp1()|_Tp2()), _Tp1()|_Tp2()> bitor_
Definition: operations.h:211
utl::meta::bitnot_
integral_< typename _T::value_type,(typename _T::value_type)(~_T())> bitnot_
Definition: operations.h:205
gtest.h
utl::meta::long_
integral_< long, v > long_
long_ type: integral constant wrapper for long
Definition: integral.h:102
utl::meta::nil_
Definition: integral.h:43
utl::meta::integral_
std::integral_constant< Tp, v > integral_
Definition: integral.h:58
utl::meta::modulo
integral_< decltype(_Tp1() % _Tp2()), _Tp1() % _Tp2() > modulo
Modulo.
Definition: operations.h:162
utl::meta::comp_gt
comp_lt< _Tp2, _Tp1 > comp_gt
Greater than.
Definition: operations.h:191
utl::meta::shift_left
integral_< typename _Tp::value_type,(typename _Tp::value_type)(_Tp()<< shift())> shift_left
Definition: operations.h:218
utl::meta::int_
integral_< int, v > int_
int_ type: integral constant wrapper for int
Definition: integral.h:98
utl::meta::false_
bool_< false > false_
The type used as a compile-time boolean with false value.
Definition: integral.h:69
utl::meta::add
integral_< decltype(_Tp1()+_Tp2()), _Tp1()+_Tp2() > add
Addition.
Definition: operations.h:144
utl::meta::eval
typename Tp::type eval
Type alias for Tp::type. Used to evaluate/extract return type of metafunctions.
Definition: integral.h:49
utl::meta::char_
integral_< char, v > char_
char_ type: integral constant wrapper for char
Definition: integral.h:94
utl::meta::not_c
bool_<!B > not_c
Negate the bool constant parameter.
Definition: operations.h:43
utl::meta::uint16_
integral_< uint16_t, v > uint16_
uint16_ type: integral constant wrapper for uint16_t
Definition: integral.h:83
utl
STL&#39;s core language concepts.
Definition: _1wire.h:30
utl::meta::same_
Definition: operations.h:102
utl::meta::bitxor_
integral_< decltype(_Tp1() ^ _Tp2()), _Tp1() ^ _Tp2()> bitxor_
Definition: operations.h:215
utl::meta::index_
integral_< index_t, v > index_
index_ type: integral constant wrapper for index_t a.k.a std::size_t
Definition: integral.h:106
utl::meta::alignof_
size_< alignof(Tp)> alignof_
Definition: integral.h:120
utl::meta::dec
add< _Tp, int_<-1 > > dec
decrease
Definition: operations.h:173
TmetaBasic::check1
int check1(T x)
Definition: TmetaBasic.cpp:222
utl::meta::comp_ge
not_< comp_lt< _Tp1, _Tp2 > > comp_ge
Greater or equal.
Definition: operations.h:195
TmetaBasic::Identity::type
T type
Definition: TmetaBasic.cpp:33
utl::meta::bool_
integral_< bool, v > bool_
bool_ type: integral constant wrapper for bool
Definition: integral.h:66
utl::index_t
size_t index_t
index_t and size_t mend to be interchangeable
Definition: types.h:38
utl::meta::divide
integral_< decltype(_Tp2()/_Tp2()), _Tp1()/_Tp2() > divide
Division.
Definition: operations.h:156
utl::meta::int32_
integral_< int32_t, v > int32_
int32_ type: integral constant wrapper for int32_t
Definition: integral.h:87
TmetaBasic::check2
int check2(T x)
Definition: TmetaBasic.cpp:226
utl::meta::sizeof_
size_< sizeof(Tp)> sizeof_
Definition: integral.h:115
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:16643
utl::meta::not_same_
not_< eval< same_< _T1, _T2 > >> not_same_
Definition: operations.h:111
utl::meta::or_
eval< detail::_or_< _Ts... > > or_
Definition: operations.h:70
utl::meta::not_
not_c< _Tp::type::value > not_
not
Definition: operations.h:47
utl::meta::and_
eval< detail::_and_< _Ts... > > and_
Definition: operations.h:96
TmetaBasic
Definition: TmetaBasic.cpp:24
utl::meta::uint32_
integral_< uint32_t, v > uint32_
uint32_ type: integral constant wrapper for uint32_t
Definition: integral.h:90
utl::meta::int16_
integral_< int16_t, v > int16_
int16_ type: integral constant wrapper for int16_t
Definition: integral.h:80
utl::meta::comp_le
not_< comp_lt< _Tp2, _Tp1 > > comp_le
Less or equal.
Definition: operations.h:193
TmetaBasic::Identity
Definition: TmetaBasic.cpp:32
utl::meta::inc
add< _Tp, int_< 1 > > inc
Increase.
Definition: operations.h:169