• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Louis Dionne 2013-2016
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>
12 namespace hana = boost::hana;
13 using hana::detail::ebo;
14 
15 
16 template <int> struct empty { };
17 template <int> struct idx;
18 #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
19 template <typename ...Bases> struct __declspec(empty_bases) inherit : Bases... { };
20 #else
21 template <typename ...Bases> struct inherit : Bases... { };
22 #endif
23 
24 static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>>), "");
25 static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>>), "");
26 static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>, ebo<idx<2>, empty<2>>>), "");
27 
28 
main()29 int main() {
30     // Test default-construction
31     {
32         constexpr ebo<idx<0>, int> e;
33         static_assert(hana::detail::ebo_get<idx<0>>(e) == 0, "");
34     }
35 
36     // Test construction of a non-empty object
37     {
38         ebo<idx<0>, std::string> e{"foobar"};
39         BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobar");
40     }
41 
42     {
43         ebo<idx<0>, std::string> e{};
44         BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "");
45     }
46 
47     // Test construction of a non default-constructible type
48     {
49         struct nodefault {
50             nodefault() = delete;
51             explicit nodefault(char const*) { }
52         };
53         ebo<idx<0>, nodefault> e{"foobar"};
54     }
55 
56     // Get lvalue, const lvalue and rvalue with a non-empty type
57     {
58         ebo<idx<0>, std::string> e{"foobar"};
59         std::string& s = hana::detail::ebo_get<idx<0>>(e);
60         BOOST_HANA_RUNTIME_CHECK(s == "foobar");
61         s = "foobaz";
62         BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobaz");
63     }
64 
65     {
66         ebo<idx<0>, std::string> const e{"foobar"};
67         std::string const& s = hana::detail::ebo_get<idx<0>>(e);
68         BOOST_HANA_RUNTIME_CHECK(s == "foobar");
69     }
70 
71     {
72         ebo<idx<0>, std::string> e{"foobar"};
73         std::string&& s = hana::detail::ebo_get<idx<0>>(std::move(e));
74         BOOST_HANA_RUNTIME_CHECK(s == "foobar");
75     }
76 
77     // Get lvalue, const lvalue and rvalue with an empty type
78     {
79         ebo<idx<0>, empty<0>> e{};
80         empty<0>& s = hana::detail::ebo_get<idx<0>>(e);
81         (void)s;
82     }
83 
84     {
85         ebo<idx<0>, empty<0>> const e{};
86         empty<0> const& s = hana::detail::ebo_get<idx<0>>(e);
87         (void)s;
88     }
89 
90     {
91         ebo<idx<0>, empty<0>> e{};
92         empty<0>&& s = hana::detail::ebo_get<idx<0>>(std::move(e));
93         (void)s;
94     }
95 }
96