1 // Copyright Louis Dionne 2013-2017
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/bool.hpp>
6 #include <boost/hana/fwd/hash.hpp>
7 #include <boost/hana/set.hpp>
8 #include <boost/hana/type.hpp>
9
10 #include <type_traits>
11 namespace hana = boost::hana;
12
13
14 template <int i>
15 struct NoDefault {
16 NoDefault() = delete;
17 NoDefault(NoDefault const&) = default;
NoDefaultNoDefault18 constexpr explicit NoDefault(int) { }
19 };
20
21 template <int i, int j>
operator ==(NoDefault<i> const &,NoDefault<j> const &)22 auto operator==(NoDefault<i> const&, NoDefault<j> const&) { return hana::bool_<i == j>{}; }
23 template <int i, int j>
operator !=(NoDefault<i> const &,NoDefault<j> const &)24 auto operator!=(NoDefault<i> const&, NoDefault<j> const&) { return hana::bool_<i != j>{}; }
25
26 template <int i>
27 struct Default {
28 Default() = default;
29 Default(Default const&) = default;
DefaultDefault30 constexpr explicit Default(int) { }
31 };
32
33 template <int i, int j>
operator ==(Default<i> const &,Default<j> const &)34 auto operator==(Default<i> const&, Default<j> const&) { return hana::bool_<i == j>{}; }
35 template <int i, int j>
operator !=(Default<i> const &,Default<j> const &)36 auto operator!=(Default<i> const&, Default<j> const&) { return hana::bool_<i != j>{}; }
37
38 namespace boost { namespace hana {
39 template <int i>
40 struct hash_impl<NoDefault<i>> {
applyboost::hana::hash_impl41 static constexpr auto apply(NoDefault<i> const&)
42 { return hana::type_c<NoDefault<i>>; };
43 };
44
45 template <int i>
46 struct hash_impl<Default<i>> {
applyboost::hana::hash_impl47 static constexpr auto apply(Default<i> const&)
48 { return hana::type_c<Default<i>>; };
49 };
50 }}
51
main()52 int main() {
53 {
54 auto set0 = hana::make_set();
55 static_assert(std::is_default_constructible<decltype(set0)>{}, "");
56
57 auto set1 = hana::make_set(Default<0>(int{}));
58 static_assert(std::is_default_constructible<decltype(set1)>{}, "");
59
60 auto set2 = hana::make_set(Default<0>(int{}), Default<1>(int{}));
61 static_assert(std::is_default_constructible<decltype(set2)>{}, "");
62
63 auto set3 = hana::make_set(Default<0>(int{}), NoDefault<1>(int{}), Default<2>(int{}));
64 static_assert(!std::is_default_constructible<decltype(set3)>{}, "");
65 }
66
67 {
68 auto set1 = hana::make_set(NoDefault<0>(int{}));
69 static_assert(!std::is_default_constructible<decltype(set1)>{}, "");
70
71 auto set2 = hana::make_set(NoDefault<0>(int{}), NoDefault<1>(int{}));
72 static_assert(!std::is_default_constructible<decltype(set2)>{}, "");
73
74 auto set3 = hana::make_set(NoDefault<0>(int{}), NoDefault<1>(int{}), NoDefault<2>(int{}));
75 static_assert(!std::is_default_constructible<decltype(set3)>{}, "");
76 }
77 }