1 /*!
2 @file
3 Adapts `std::pair` for use with Hana.
4 
5 @copyright Louis Dionne 2013-2017
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)
8  */
9 
10 #ifndef BOOST_HANA_EXT_STD_PAIR_HPP
11 #define BOOST_HANA_EXT_STD_PAIR_HPP
12 
13 #include <boost/hana/config.hpp>
14 #include <boost/hana/fwd/core/make.hpp>
15 #include <boost/hana/fwd/core/tag_of.hpp>
16 #include <boost/hana/fwd/first.hpp>
17 #include <boost/hana/fwd/second.hpp>
18 
19 #include <utility>
20 
21 
22 #ifdef BOOST_HANA_DOXYGEN_INVOKED
23 namespace std {
24     //! @ingroup group-ext-std
25     //! Adaptation of `std::pair` for Hana.
26     //!
27     //!
28     //! Modeled concepts
29     //! ----------------
30     //! A `std::pair` models exactly the same concepts as a `hana::pair`.
31     //! Please refer to the documentation of `hana::pair` for details.
32     //!
33     //! @include example/ext/std/pair.cpp
34     template <typename First, typename Second>
35     struct pair { };
36 }
37 #endif
38 
39 
40 BOOST_HANA_NAMESPACE_BEGIN
41     namespace ext { namespace std { struct pair_tag; }}
42 
43     template <typename First, typename Second>
44     struct tag_of<std::pair<First, Second>> {
45         using type = ext::std::pair_tag;
46     };
47 
48     //////////////////////////////////////////////////////////////////////////
49     // Product
50     //////////////////////////////////////////////////////////////////////////
51     template <>
52     struct make_impl<ext::std::pair_tag> {
53         template <typename X, typename Y>
applymake_impl54         static constexpr decltype(auto) apply(X&& x, Y&& y) {
55             return std::make_pair(static_cast<X&&>(x),
56                                   static_cast<Y&&>(y));
57         }
58     };
59 
60     template <>
61     struct first_impl<ext::std::pair_tag> {
62         template <typename T, typename U>
applyfirst_impl63         static constexpr T const& apply(std::pair<T, U> const& p)
64         {  return p.first; }
65 
66         template <typename T, typename U>
applyfirst_impl67         static constexpr T& apply(std::pair<T, U>& p)
68         {  return p.first; }
69 
70         template <typename T, typename U>
applyfirst_impl71         static constexpr T&& apply(std::pair<T, U>&& p)
72         {  return static_cast<T&&>(p.first); }
73     };
74 
75     template <>
76     struct second_impl<ext::std::pair_tag> {
77         template <typename T, typename U>
applysecond_impl78         static constexpr U const& apply(std::pair<T, U> const& p)
79         {  return p.second; }
80 
81         template <typename T, typename U>
applysecond_impl82         static constexpr U& apply(std::pair<T, U>& p)
83         {  return p.second; }
84 
85         template <typename T, typename U>
applysecond_impl86         static constexpr U&& apply(std::pair<T, U>&& p)
87         {  return static_cast<U&&>(p.second); }
88     };
89 BOOST_HANA_NAMESPACE_END
90 
91 #endif // !BOOST_HANA_EXT_STD_PAIR_HPP
92