ebo.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. #include <boost/hana/detail/ebo.hpp>
  5. #include <boost/hana/assert.hpp>
  6. #include <string>
  7. #include <type_traits>
  8. #include <utility>
  9. namespace hana = boost::hana;
  10. using hana::detail::ebo;
  11. template <int> struct empty { };
  12. template <int> struct idx;
  13. #ifdef BOOST_HANA_WORKAROUND_MSVC_EMPTYBASE
  14. template <typename ...Bases> struct __declspec(empty_bases) inherit : Bases... { };
  15. #else
  16. template <typename ...Bases> struct inherit : Bases... { };
  17. #endif
  18. static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>>), "");
  19. static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>>), "");
  20. static_assert(sizeof(inherit<>) == sizeof(inherit<ebo<idx<0>, empty<0>>, ebo<idx<1>, empty<1>>, ebo<idx<2>, empty<2>>>), "");
  21. int main() {
  22. // Test default-construction
  23. {
  24. constexpr ebo<idx<0>, int> e;
  25. static_assert(hana::detail::ebo_get<idx<0>>(e) == 0, "");
  26. }
  27. // Test construction of a non-empty object
  28. {
  29. ebo<idx<0>, std::string> e{"foobar"};
  30. BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobar");
  31. }
  32. {
  33. ebo<idx<0>, std::string> e{};
  34. BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "");
  35. }
  36. // Test construction of a non default-constructible type
  37. {
  38. struct nodefault {
  39. nodefault() = delete;
  40. explicit nodefault(char const*) { }
  41. };
  42. ebo<idx<0>, nodefault> e{"foobar"};
  43. }
  44. // Get lvalue, const lvalue and rvalue with a non-empty type
  45. {
  46. ebo<idx<0>, std::string> e{"foobar"};
  47. std::string& s = hana::detail::ebo_get<idx<0>>(e);
  48. BOOST_HANA_RUNTIME_CHECK(s == "foobar");
  49. s = "foobaz";
  50. BOOST_HANA_RUNTIME_CHECK(hana::detail::ebo_get<idx<0>>(e) == "foobaz");
  51. }
  52. {
  53. ebo<idx<0>, std::string> const e{"foobar"};
  54. std::string const& s = hana::detail::ebo_get<idx<0>>(e);
  55. BOOST_HANA_RUNTIME_CHECK(s == "foobar");
  56. }
  57. {
  58. ebo<idx<0>, std::string> e{"foobar"};
  59. std::string&& s = hana::detail::ebo_get<idx<0>>(std::move(e));
  60. BOOST_HANA_RUNTIME_CHECK(s == "foobar");
  61. }
  62. // Get lvalue, const lvalue and rvalue with an empty type
  63. {
  64. ebo<idx<0>, empty<0>> e{};
  65. empty<0>& s = hana::detail::ebo_get<idx<0>>(e);
  66. (void)s;
  67. }
  68. {
  69. ebo<idx<0>, empty<0>> const e{};
  70. empty<0> const& s = hana::detail::ebo_get<idx<0>>(e);
  71. (void)s;
  72. }
  73. {
  74. ebo<idx<0>, empty<0>> e{};
  75. empty<0>&& s = hana::detail::ebo_get<idx<0>>(std::move(e));
  76. (void)s;
  77. }
  78. }