1// Copyright Louis Dionne 2013-2022
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4
5#include <boost/hana/detail/ebo.hpp>
6
7#include <boost/hana/assert.hpp>
8
9#include <string>
10#include <type_traits>
11#include <utility>
12namespace hana = boost::hana;
13using hana::detail::ebo;
14
15
16template <int> struct empty { };
17template <int> struct idx;
18#ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
19template <typename ...Bases> struct __declspec(empty_bases) inherit : Bases... { };
20#else
21template <typename ...Bases> struct inherit : Bases... { };
22#endif
23
24#ifndef BOOST_HANA_CONFIG_CLANG_CL // MSVC doesn't implement EBO in all cases
25static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>>), "");
26static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>>), "");
27static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>, ebo<idx<2>, empty<2>>>), "");
28#endif
29
30int main() {
31 // Test default-construction
32 {
33 constexpr ebo<idx<0>, int> e;
34 static_assert(hana::detail::ebo_get<idx<0>>(x: e) == 0, "");
35 }
36
37 // Test construction of a non-empty object
38 {
39 ebo<idx<0>, std::string> e{"foobar"};
40 BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobar");
41 }
42
43 {
44 ebo<idx<0>, std::string> e{};
45 BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "");
46 }
47
48 // Test construction of a non default-constructible type
49 {
50 struct nodefault {
51 nodefault() = delete;
52 explicit nodefault(char const*) { }
53 };
54 ebo<idx<0>, nodefault> e{"foobar"};
55 }
56
57 // Get lvalue, const lvalue and rvalue with a non-empty type
58 {
59 ebo<idx<0>, std::string> e{"foobar"};
60 std::string& s = hana::detail::ebo_get<idx<0>>(x&: e);
61 BOOST_HANA_RUNTIME_CHECK(s == "foobar");
62 s = "foobaz";
63 BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobaz");
64 }
65
66 {
67 ebo<idx<0>, std::string> const e{"foobar"};
68 std::string const& s = hana::detail::ebo_get<idx<0>>(x: e);
69 BOOST_HANA_RUNTIME_CHECK(s == "foobar");
70 }
71
72 {
73 ebo<idx<0>, std::string> e{"foobar"};
74 std::string&& s = hana::detail::ebo_get<idx<0>>(x: std::move(e));
75 BOOST_HANA_RUNTIME_CHECK(s == "foobar");
76 }
77
78 // Get lvalue, const lvalue and rvalue with an empty type
79 {
80 ebo<idx<0>, empty<0>> e{};
81 empty<0>& s = hana::detail::ebo_get<idx<0>>(x&: e);
82 (void)s;
83 }
84
85 {
86 ebo<idx<0>, empty<0>> const e{};
87 empty<0> const& s = hana::detail::ebo_get<idx<0>>(x: e);
88 (void)s;
89 }
90
91 {
92 ebo<idx<0>, empty<0>> e{};
93 empty<0>&& s = hana::detail::ebo_get<idx<0>>(x: std::move(e));
94 (void)s;
95 }
96}
97

source code of boost/libs/hana/test/detail/ebo.cpp