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 #ifndef TEST_SUPPORT_MINIMAL_PRODUCT_HPP
6 #define TEST_SUPPORT_MINIMAL_PRODUCT_HPP
7 
8 #include <boost/hana/fwd/core/make.hpp>
9 #include <boost/hana/fwd/first.hpp>
10 #include <boost/hana/fwd/second.hpp>
11 
12 #include <type_traits>
13 
14 
15 struct MinimalProduct;
16 
17 template <typename X, typename Y>
18 struct product_t {
19     X fst;
20     Y snd;
21     using hana_tag = MinimalProduct;
22 };
23 
24 struct make_minimal_product {
25     template <typename T, typename U>
26     constexpr product_t<typename std::decay<T>::type,
27                         typename std::decay<U>::type>
operator ()make_minimal_product28     operator()(T&& t, U&& u) const {
29         return {static_cast<T&&>(t), static_cast<U&&>(u)};
30     }
31 };
32 
33 constexpr make_minimal_product minimal_product{};
34 
35 namespace boost { namespace hana {
36     //////////////////////////////////////////////////////////////////////////
37     // Product
38     //////////////////////////////////////////////////////////////////////////
39     template <>
40     struct make_impl<MinimalProduct> {
41         template <typename X, typename Y>
applyboost::hana::make_impl42         static constexpr auto apply(X x, Y y)
43         { return ::minimal_product(x, y); }
44     };
45 
46     template <>
47     struct first_impl<MinimalProduct> {
48         template <typename P>
applyboost::hana::first_impl49         static constexpr decltype(auto) apply(P&& p)
50         { return p.fst; }
51     };
52 
53     template <>
54     struct second_impl<MinimalProduct> {
55         template <typename P>
applyboost::hana::second_impl56         static constexpr decltype(auto) apply(P&& p)
57         { return p.snd; }
58     };
59 }} // end namespace boost::hana
60 
61 #endif // !TEST_SUPPORT_MINIMAL_PRODUCT_HPP
62