1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file utility.hpp
3 /// Proto callables for things found in the std \<utility\> header
4 //
5 //  Copyright 2010 Eric Niebler. Distributed under the Boost
6 //  Software License, Version 1.0. (See accompanying file
7 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 
9 #ifndef BOOST_PROTO_FUNCTIONAL_STD_UTILITY_HPP_EAN_11_27_2010
10 #define BOOST_PROTO_FUNCTIONAL_STD_UTILITY_HPP_EAN_11_27_2010
11 
12 #include <utility>
13 #include <boost/type_traits/remove_const.hpp>
14 #include <boost/type_traits/remove_reference.hpp>
15 #include <boost/proto/proto_fwd.hpp>
16 
17 namespace boost { namespace proto { namespace functional
18 {
19     /// \brief A PolymorphicFunctionObject type that invokes the
20     /// \c std::make_pair() algorithm on its arguments.
21     ///
22     /// A PolymorphicFunctionObject type that invokes the
23     /// \c std::make_pair() algorithm on its arguments.
24     struct make_pair
25     {
26         BOOST_PROTO_CALLABLE()
27 
28         template<typename Sig>
29         struct result;
30 
31         template<typename This, typename First, typename Second>
32         struct result<This(First, Second)>
33         {
34             typedef
35                 std::pair<
36                     typename remove_const<typename remove_reference<First>::type>::type
37                   , typename remove_const<typename remove_reference<Second>::type>::type
38                 >
39             type;
40         };
41 
42         template<typename First, typename Second>
operator ()boost::proto::functional::make_pair43         std::pair<First, Second> operator()(First const &first, Second const &second) const
44         {
45             return std::make_pair(first, second);
46         }
47     };
48 
49     /// \brief A PolymorphicFunctionObject type that returns
50     /// the first element of a std::pair.
51     ///
52     /// A PolymorphicFunctionObject type that returns
53     /// the first element of a std::pair..
54     struct first
55     {
56         BOOST_PROTO_CALLABLE()
57 
58         template<typename Sig>
59         struct result;
60 
61         template<typename This, typename Pair>
62         struct result<This(Pair)>
63         {
64             typedef typename Pair::first_type type;
65         };
66 
67         template<typename This, typename Pair>
68         struct result<This(Pair &)>
69         {
70             typedef typename Pair::first_type &type;
71         };
72 
73         template<typename This, typename Pair>
74         struct result<This(Pair const &)>
75         {
76             typedef typename Pair::first_type const &type;
77         };
78 
79         template<typename Pair>
operator ()boost::proto::functional::first80         typename Pair::first_type &operator()(Pair &pair) const
81         {
82             return pair.first;
83         }
84 
85         template<typename Pair>
operator ()boost::proto::functional::first86         typename Pair::first_type const &operator()(Pair const &pair) const
87         {
88             return pair.first;
89         }
90     };
91 
92     /// \brief A PolymorphicFunctionObject type that returns
93     /// the second element of a std::pair.
94     ///
95     /// A PolymorphicFunctionObject type that returns
96     /// the second element of a std::pair..
97     struct second
98     {
99         BOOST_PROTO_CALLABLE()
100 
101         template<typename Sig>
102         struct result;
103 
104         template<typename This, typename Pair>
105         struct result<This(Pair)>
106         {
107             typedef typename Pair::second_type type;
108         };
109 
110         template<typename This, typename Pair>
111         struct result<This(Pair &)>
112         {
113             typedef typename Pair::second_type &type;
114         };
115 
116         template<typename This, typename Pair>
117         struct result<This(Pair const &)>
118         {
119             typedef typename Pair::second_type const &type;
120         };
121 
122         template<typename Pair>
operator ()boost::proto::functional::second123         typename Pair::second_type &operator()(Pair &pair) const
124         {
125             return pair.second;
126         }
127 
128         template<typename Pair>
operator ()boost::proto::functional::second129         typename Pair::second_type const &operator()(Pair const &pair) const
130         {
131             return pair.second;
132         }
133     };
134 
135 }}}
136 
137 #endif
138