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/detail/wrong.hpp>
7 #include <boost/hana/fwd/hash.hpp>
8 #include <boost/hana/set.hpp>
9 #include <boost/hana/type.hpp>
10 
11 #include <utility>
12 namespace hana = boost::hana;
13 
14 
15 // This test makes sure that we do not instantiate rogue constructors when
16 // doing copies and moves
17 
18 template <int i>
19 struct Trap {
20     Trap() = default;
21     Trap(Trap const&) = default;
22 #ifndef BOOST_HANA_WORKAROUND_MSVC_MULTIPLECTOR_106654
23     Trap(Trap&) = default;
24 #endif
25     Trap(Trap&&) = default;
26 
27     template <typename X>
TrapTrap28     Trap(X&&) {
29         static_assert(hana::detail::wrong<X>{},
30         "this constructor must not be instantiated");
31     }
32 };
33 
34 template <int i, int j>
operator ==(Trap<i> const &,Trap<j> const &)35 constexpr auto operator==(Trap<i> const&, Trap<j> const&)
36 { return hana::bool_c<i == j>; }
37 
38 template <int i, int j>
operator !=(Trap<i> const &,Trap<j> const &)39 constexpr auto operator!=(Trap<i> const&, Trap<j> const&)
40 { return hana::bool_c<i != j>; }
41 
42 namespace boost { namespace hana {
43     template <int i>
44     struct hash_impl<Trap<i>> {
applyboost::hana::hash_impl45         static constexpr auto apply(Trap<i> const&)
46         { return hana::type_c<Trap<i>>; };
47     };
48 }}
49 
main()50 int main() {
51     {
52         auto expr = hana::make_set(Trap<0>{});
53         auto implicit_copy = expr;
54         decltype(expr) explicit_copy(expr);
55 
56         (void)implicit_copy;
57         (void)explicit_copy;
58     }
59     {
60         auto expr = hana::make_set(Trap<0>{});
61         auto implicit_move = std::move(expr);
62         decltype(expr) explicit_move(std::move(implicit_move));
63 
64         (void)implicit_move;
65         (void)explicit_move;
66     }
67 }
68