3 Defines `boost::hana::pair`.
5 @copyright Louis Dionne 2013-2016
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
10 #ifndef BOOST_HANA_PAIR_HPP
11 #define BOOST_HANA_PAIR_HPP
13 #include <boost/hana/fwd/pair.hpp>
15 #include <boost/hana/basic_tuple.hpp>
16 #include <boost/hana/config.hpp>
17 #include <boost/hana/detail/decay.hpp>
18 #include <boost/hana/detail/intrinsics.hpp>
19 #include <boost/hana/detail/operators/adl.hpp>
20 #include <boost/hana/detail/operators/comparable.hpp>
21 #include <boost/hana/detail/operators/orderable.hpp>
22 #include <boost/hana/fwd/core/make.hpp>
23 #include <boost/hana/fwd/first.hpp>
24 #include <boost/hana/fwd/second.hpp>
26 #include <type_traits>
30 BOOST_HANA_NAMESPACE_BEGIN
31 //////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////
35 template <typename First, typename Second>
36 struct pair : detail::operators::adl<pair<First, Second>> {
37 template <typename ...dummy, typename = typename std::enable_if<
38 BOOST_HANA_TT_IS_CONSTRUCTIBLE(First, dummy...) &&
39 BOOST_HANA_TT_IS_CONSTRUCTIBLE(Second, dummy...)
45 template <typename ...dummy, typename = typename std::enable_if<
46 BOOST_HANA_TT_IS_CONSTRUCTIBLE(First, First const&, dummy...) &&
47 BOOST_HANA_TT_IS_CONSTRUCTIBLE(Second, Second const&, dummy...)
49 constexpr pair(First const& first, Second const& second)
50 : storage_{first, second}
53 template <typename T, typename U, typename = typename std::enable_if<
54 BOOST_HANA_TT_IS_CONVERTIBLE(T&&, First) &&
55 BOOST_HANA_TT_IS_CONVERTIBLE(U&&, Second)
57 constexpr pair(T&& t, U&& u)
58 : storage_{static_cast<T&&>(t), static_cast<U&&>(u)}
61 template <typename T, typename U, typename = typename std::enable_if<
62 BOOST_HANA_TT_IS_CONVERTIBLE(T const&, First) &&
63 BOOST_HANA_TT_IS_CONVERTIBLE(U const&, Second)
65 constexpr pair(pair<T, U> const& other)
66 : storage_{hana::get_impl<0>(other.storage_),
67 hana::get_impl<1>(other.storage_)}
70 template <typename T, typename U, typename = typename std::enable_if<
71 BOOST_HANA_TT_IS_CONVERTIBLE(T&&, First) &&
72 BOOST_HANA_TT_IS_CONVERTIBLE(U&&, Second)
74 constexpr pair(pair<T, U>&& other)
75 : storage_{static_cast<T&&>(hana::get_impl<0>(other.storage_)),
76 static_cast<U&&>(hana::get_impl<1>(other.storage_))}
79 template <typename T, typename U, typename = typename std::enable_if<
80 BOOST_HANA_TT_IS_ASSIGNABLE(First&, T const&) &&
81 BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U const&)
83 constexpr pair& operator=(pair<T, U> const& other) {
84 hana::get_impl<0>(storage_) = hana::get_impl<0>(other.storage_);
85 hana::get_impl<1>(storage_) = hana::get_impl<1>(other.storage_);
89 template <typename T, typename U, typename = typename std::enable_if<
90 BOOST_HANA_TT_IS_ASSIGNABLE(First&, T&&) &&
91 BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U&&)
93 constexpr pair& operator=(pair<T, U>&& other) {
94 hana::get_impl<0>(storage_) = static_cast<T&&>(hana::get_impl<0>(other.storage_));
95 hana::get_impl<1>(storage_) = static_cast<U&&>(hana::get_impl<1>(other.storage_));
99 using hana_tag = pair_tag;
100 basic_tuple<First, Second> storage_;
104 //////////////////////////////////////////////////////////////////////////
106 //////////////////////////////////////////////////////////////////////////
109 struct comparable_operators<pair_tag> {
110 static constexpr bool value = true;
113 struct orderable_operators<pair_tag> {
114 static constexpr bool value = true;
118 //////////////////////////////////////////////////////////////////////////
120 //////////////////////////////////////////////////////////////////////////
122 struct make_impl<pair_tag> {
123 template <typename F, typename S>
124 static constexpr pair<
125 typename detail::decay<F>::type,
126 typename detail::decay<S>::type
127 > apply(F&& f, S&& s) {
128 return {static_cast<F&&>(f), static_cast<S&&>(s)};
133 struct first_impl<pair_tag> {
134 template <typename P>
135 static constexpr decltype(auto) apply(P&& p)
136 { return hana::get_impl<0>(static_cast<P&&>(p).storage_); }
140 struct second_impl<pair_tag> {
141 template <typename P>
142 static constexpr decltype(auto) apply(P&& p)
143 { return hana::get_impl<1>(static_cast<P&&>(p).storage_); }
145 BOOST_HANA_NAMESPACE_END
147 #endif // !BOOST_HANA_PAIR_HPP