@@ -49,7 +49,7 @@ namespace meta { | |||||
//! integral_constant | //! integral_constant | ||||
//! An Integral Constant is a holder class for a compile-time value of an integral type. | //! 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 | //! An integral constant object is implicitly convertible to the corresponding | ||||
//! run-time value of the wrapped integral type | //! 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 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. | 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 | //! char_ type: integral constant wrapper for \c char | ||||
template<char _v> | template<char _v> | ||||
using char_ = integral_c<char, _v>; | using char_ = integral_c<char, _v>; | ||||
@@ -108,7 +108,7 @@ namespace meta { | |||||
//! @{ | //! @{ | ||||
//! \return bitwise not (~) operation of its argument. | //! \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 | //! \return bitwise and (&) operation of its arguments | ||||
template <typename _Tp1, typename _Tp2> | template <typename _Tp1, typename _Tp2> | ||||
using bitand_ = integral_c<decltype(_Tp1() & _Tp2()), _Tp1() & _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()>; | using bitxor_ = integral_c<decltype(_Tp1() ^ _Tp2()), _Tp1() ^ _Tp2()>; | ||||
//! \return the result of bitwise shift left (<<) operation on _Tp. | //! \return the result of bitwise shift left (<<) operation on _Tp. | ||||
template <typename _Tp, typename shift> | 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. | //! \return the result of bitwise shift right (>>) operation on _Tp. | ||||
template <typename _Tp, typename shift> | 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())>; | |||||
//! @} | //! @} | ||||
}} | }} | ||||
//!@} | //!@} | ||||
@@ -48,8 +48,26 @@ namespace test_meta { | |||||
EXPECT_EQ(false, false_::value); | EXPECT_EQ(false, false_::value); | ||||
EXPECT_EQ(true, (std::is_same<bool, true_::value_type>::value)); | EXPECT_EQ(true, (std::is_same<bool, true_::value_type>::value)); | ||||
EXPECT_EQ(true, true_::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(true, (std::is_same<int, int_<0>::value_type>::value)); | ||||
EXPECT_EQ(42, int_<42>::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(true, (std::is_same<index_t, index_t_<0>::value_type>::value)); | ||||
EXPECT_EQ(42U, index_t_<42U>::value); | EXPECT_EQ(42U, index_t_<42U>::value); | ||||
@@ -88,11 +106,15 @@ namespace test_meta { | |||||
} | } | ||||
TEST(Tmeta_logical, BitOperations) { | 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) { | 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_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<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 (true, (same_<Foo, Foo>())); | ||||
EXPECT_EQ (false, (same_<Foo, Bar>())); | EXPECT_EQ (false, (same_<Foo, Bar>())); | ||||