// Copyright Louis Dionne 2013-2016 // 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 namespace hana = boost::hana; using hana::detail::ebo; template struct empty { }; template struct idx; #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE template struct __declspec(empty_bases) inherit : Bases... { }; #else template struct inherit : Bases... { }; #endif static_assert(sizeof(inherit<>) == sizeof(inherit, empty<0>>>), ""); static_assert(sizeof(inherit<>) == sizeof(inherit, empty<0>>, ebo, empty<1>>>), ""); static_assert(sizeof(inherit<>) == sizeof(inherit, empty<0>>, ebo, empty<1>>, ebo, empty<2>>>), ""); int main() { // Test default-construction { constexpr ebo, int> e; static_assert(hana::detail::ebo_get>(e) == 0, ""); } // Test construction of a non-empty object { ebo, std::string> e{"foobar"}; BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get>(e) == "foobar"); } { ebo, std::string> e{}; BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get>(e) == ""); } // Test construction of a non default-constructible type { struct nodefault { nodefault() = delete; explicit nodefault(char const*) { } }; ebo, nodefault> e{"foobar"}; } // Get lvalue, const lvalue and rvalue with a non-empty type { ebo, std::string> e{"foobar"}; std::string& s = hana::detail::ebo_get>(e); BOOST_HANA_RUNTIME_CHECK(s == "foobar"); s = "foobaz"; BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get>(e) == "foobaz"); } { ebo, std::string> const e{"foobar"}; std::string const& s = hana::detail::ebo_get>(e); BOOST_HANA_RUNTIME_CHECK(s == "foobar"); } { ebo, std::string> e{"foobar"}; std::string&& s = hana::detail::ebo_get>(std::move(e)); BOOST_HANA_RUNTIME_CHECK(s == "foobar"); } // Get lvalue, const lvalue and rvalue with an empty type { ebo, empty<0>> e{}; empty<0>& s = hana::detail::ebo_get>(e); (void)s; } { ebo, empty<0>> const e{}; empty<0> const& s = hana::detail::ebo_get>(e); (void)s; } { ebo, empty<0>> e{}; empty<0>&& s = hana::detail::ebo_get>(std::move(e)); (void)s; } }