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