/* @copyright Louis Dionne 2015 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #include #include #include #include #include #include using namespace boost::hana; struct T { }; struct U; using Function = void(); void function() { } int main() { ////////////////////////////////////////////////////////////////////////// // Type interface and helper functions ////////////////////////////////////////////////////////////////////////// { // make { BOOST_HANA_CONSTANT_CHECK(equal( make(T{}), decltype_(T{}) )); BOOST_HANA_CONSTANT_CHECK(equal( make(type), decltype_(type) )); // make sure we don't read from non-constexpr variables { auto t = type; auto x = 1; constexpr auto r1 = make(t); (void)r1; constexpr auto r2 = make(x); (void)r2; } } // decltype_ { T t; BOOST_HANA_CONSTANT_CHECK(equal( decltype_(T{}), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(t), type )); // [cv-qualified] reference types BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); // [cv-qualified] rvalue reference types BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(static_cast(t)), type )); // decltype_(type) is the identity function auto const type_const = type; auto const& type_const_ref = type; auto& type_ref = type; auto&& type_ref_ref = static_cast(type_ref); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(type), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(type_const), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(type_const_ref), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(type_ref), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(type_ref_ref), type )); // make sure we don't read from non-constexpr variables { auto t = type; auto x = 1; constexpr auto r1 = decltype_(t); (void)r1; constexpr auto r2 = decltype_(x); (void)r2; } // decltype_ with builtin arrays, function pointers and other weirdos { using A = T[3]; A a; A& a_ref = a; A const& a_const_ref = a; BOOST_HANA_CONSTANT_CHECK(equal( decltype_(a), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(a_ref), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(a_const_ref), type )); } { using Fptr = int(*)(); Fptr f; Fptr& f_ref = f; Fptr const& f_const_ref = f; BOOST_HANA_CONSTANT_CHECK(equal( decltype_(f), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(f_ref), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(f_const_ref), type )); } { Function& function_ref = function; BOOST_HANA_CONSTANT_CHECK(equal( decltype_(function), type )); BOOST_HANA_CONSTANT_CHECK(equal( decltype_(function_ref), type )); } } // sizeof_ { BOOST_HANA_CONSTANT_CHECK(equal( sizeof_(T{}), size_t )); BOOST_HANA_CONSTANT_CHECK(equal( sizeof_(type), size_t )); // make sure we don't read from non-constexpr variables { auto t = type; auto x = 1; constexpr auto r1 = sizeof_(t); (void)r1; constexpr auto r2 = sizeof_(x); (void)r2; } } // alignof_ { BOOST_HANA_CONSTANT_CHECK(equal( alignof_(T{}), size_t )); BOOST_HANA_CONSTANT_CHECK(equal( alignof_(type), size_t )); // make sure we don't read from non-constexpr variables { auto t = type; auto x = 1; constexpr auto r1 = alignof_(t); (void)r1; constexpr auto r2 = alignof_(x); (void)r2; } } // nested ::type { static_assert(std::is_same)::type, T>{}, ""); } // unary + { auto& ref = type; auto const& cref = type; auto&& rref = type; auto val = type; BOOST_HANA_CONSTANT_CHECK(equal(val, +val)); BOOST_HANA_CONSTANT_CHECK(equal(val, +ref)); BOOST_HANA_CONSTANT_CHECK(equal(val, +cref)); BOOST_HANA_CONSTANT_CHECK(equal(val, +rref)); static_assert(!std::is_reference{}, ""); static_assert(!std::is_reference{}, ""); static_assert(!std::is_reference{}, ""); static_assert(!std::is_reference{}, ""); using T1 = decltype(+val)::type; using T2 = decltype(+ref)::type; using T3 = decltype(+cref)::type; using T4 = decltype(+rref)::type; } // `decltype(type)` should inherit `_type` { static_assert(std::is_base_of<_type, decltype(type)>{}, ""); } } ////////////////////////////////////////////////////////////////////////// // Comparable ////////////////////////////////////////////////////////////////////////// { // equal { BOOST_HANA_CONSTANT_CHECK(equal(type, type)); BOOST_HANA_CONSTANT_CHECK(not_(equal(type, type))); BOOST_HANA_CONSTANT_CHECK(not_(equal(type, type))); BOOST_HANA_CONSTANT_CHECK(not_(equal(type, type))); BOOST_HANA_CONSTANT_CHECK(equal(type, type)); BOOST_HANA_CONSTANT_CHECK(equal(type, type)); BOOST_HANA_CONSTANT_CHECK(not_(equal(type, type))); BOOST_HANA_CONSTANT_CHECK(not_(equal(type, type))); BOOST_HANA_CONSTANT_CHECK(equal(type, type)); // make sure we don't read from a non-constexpr variable in equal auto t = type; static_assert(equal(t, type), ""); } // laws auto types = make( type, type, type, type, type, type, type ); test::TestComparable{types}; } }