Browse Source

meta: integral constant wrappers for intx_t and uintx_t added and fixed the type promotion on bit operations

doc
Christos Houtouridis 5 years ago
parent
commit
903e4641f4
3 changed files with 56 additions and 13 deletions
  1. +22
    -1
      include/utl/meta/integral.h
  2. +3
    -3
      include/utl/meta/operations.h
  3. +31
    -9
      test/tests/Tmeta.cpp

+ 22
- 1
include/utl/meta/integral.h View File

@@ -49,7 +49,7 @@ namespace meta {
//! integral_constant
//! An Integral Constant is a holder class for a compile-time value of an integral type.
//! Every Integral Constant is also a nullary Metafunction, returning itself.
//! Every Integral Constant is also a null-ary Metafunction, returning itself.
//! An integral constant object is implicitly convertible to the corresponding
//! run-time value of the wrapped integral type
//! @{
@@ -85,6 +85,27 @@ namespace meta {
using true_ = bool_<true>; //!< The type used as a compile-time boolean with true value.
using false_ = bool_<false>; //!< The type used as a compile-time boolean with false value.
//! int8_ type: integral constant wrapper for \c int8_t
template<int8_t _v>
using int8_ = integral_c<int8_t, _v>;
//! uint8_ type: integral constant wrapper for \c uint8_t
template<uint8_t _v>
using uint8_ = integral_c<uint8_t, _v>;
//! int16_ type: integral constant wrapper for \c int16_t
template<int16_t _v>
using int16_ = integral_c<int16_t, _v>;
//! uint16_ type: integral constant wrapper for \c uint16_t
template<uint16_t _v>
using uint16_ = integral_c<uint16_t, _v>;
//! int32_ type: integral constant wrapper for \c int32_t
template<int32_t _v>
using int32_ = integral_c<int32_t, _v>;
//! uint32_ type: integral constant wrapper for \c uint32_t
template<uint32_t _v>
using uint32_ = integral_c<uint32_t, _v>;
//! char_ type: integral constant wrapper for \c char
template<char _v>
using char_ = integral_c<char, _v>;


+ 3
- 3
include/utl/meta/operations.h View File

@@ -108,7 +108,7 @@ namespace meta {
//! @{
//! \return bitwise not (~) operation of its argument.
template <typename _T> using bitnot_ = integral_c<decltype(~_T()), ~_T()>;
template <typename _T> using bitnot_ = integral_c<typename _T::value_type, (typename _T::value_type)(~_T())>;
//! \return bitwise and (&) operation of its arguments
template <typename _Tp1, typename _Tp2>
using bitand_ = integral_c<decltype(_Tp1() & _Tp2()), _Tp1() & _Tp2()>;
@@ -121,10 +121,10 @@ namespace meta {
using bitxor_ = integral_c<decltype(_Tp1() ^ _Tp2()), _Tp1() ^ _Tp2()>;
//! \return the result of bitwise shift left (<<) operation on _Tp.
template <typename _Tp, typename shift>
using shift_left = integral_c<decltype(_Tp() << shift()), (_Tp() << shift())>;
using shift_left = integral_c<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() << shift())>;
//! \return the result of bitwise shift right (>>) operation on _Tp.
template <typename _Tp, typename shift>
using shift_right = integral_c<decltype(_Tp() >> shift()), (_Tp() >> shift())>;
using shift_right = integral_c<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() >> shift())>;
//! @}
}}
//!@}


+ 31
- 9
test/tests/Tmeta.cpp View File

@@ -48,8 +48,26 @@ namespace test_meta {
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_t_<0>::value_type>::value));
EXPECT_EQ(42U, index_t_<42U>::value);
@@ -88,11 +106,15 @@ namespace test_meta {
}
TEST(Tmeta_logical, BitOperations) {
EXPECT_EQ (0x00, (bitand_<int_<0x55>, int_<0xAA>>()));
EXPECT_EQ (0xFF, (bitor_<int_<0x55>, int_<0xAA>>()));
EXPECT_EQ (0xFA, (bitxor_<int_<0x55>, int_<0xAF>>()));
EXPECT_EQ (0x00, (bitnot_<int_<-1>>()));
//XXX: add shifts
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 (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>>()));
}
TEST(Tmeta_logical, TypeOperations) {
@@ -103,10 +125,10 @@ namespace test_meta {
EXPECT_EQ (true, (std::is_same<int_<42>, if_c<true, int_<42>, bool_<false>>>()));
EXPECT_EQ (true, (std::is_same<int_<42>, if_<bool_<true>, int_<42>, bool_<false>>>()));
EXPECT_EQ (true, (std::is_same<bool_<true>, or_<bool_<true>, bool_<false>>>()));
EXPECT_EQ (true, (std::is_same<bool_<false>, or_<bool_<false>, bool_<false>>>()));
EXPECT_EQ (true, (std::is_same<bool_<false>, and_<bool_<true>, bool_<false>>>()));
EXPECT_EQ (true, (std::is_same<bool_<true>, and_<bool_<true>, bool_<true>>>()));
EXPECT_EQ (true, (std::is_same<true_, or_<true_, false_>>()));
EXPECT_EQ (true, (std::is_same<false_, or_<false_, false_>>()));
EXPECT_EQ (true, (std::is_same<false_, and_<true_, false_>>()));
EXPECT_EQ (true, (std::is_same<true_, and_<true_, true_>>()));
EXPECT_EQ (true, (same_<Foo, Foo>()));
EXPECT_EQ (false, (same_<Foo, Bar>()));


Loading…
Cancel
Save