1 /*
2  *          Copyright Andrey Semashev 2007 - 2015.
3  * Distributed under the Boost Software License, Version 1.0.
4  *    (See accompanying file LICENSE_1_0.txt or copy at
5  *          http://www.boost.org/LICENSE_1_0.txt)
6  */
7 /*!
8  * \file   bind.hpp
9  * \author Andrey Semashev
10  * \date   30.03.2008
11  *
12  * This header contains function object adapters.
13  * This is a lightweight alternative to what Boost.Phoenix and Boost.Bind provides.
14  */
15 
16 #ifndef BOOST_LOG_UTILITY_FUNCTIONAL_BIND_HPP_INCLUDED_
17 #define BOOST_LOG_UTILITY_FUNCTIONAL_BIND_HPP_INCLUDED_
18 
19 #include <boost/type_traits/remove_cv.hpp>
20 #include <boost/log/detail/config.hpp>
21 #include <boost/log/detail/header.hpp>
22 
23 #ifdef BOOST_HAS_PRAGMA_ONCE
24 #pragma once
25 #endif
26 
27 namespace boost {
28 
29 BOOST_LOG_OPEN_NAMESPACE
30 
31 namespace aux {
32 
33 template< typename T >
34 struct make_arg_type
35 {
36     typedef T const& type;
37 };
38 
39 template< typename T >
40 struct make_arg_type< T& >
41 {
42     typedef T& type;
43 };
44 
45 } // namespace aux
46 
47 //! First argument binder
48 template< typename FunT, typename FirstArgT >
49 struct binder1st :
50     private FunT
51 {
52     typedef typename FunT::result_type result_type;
53 
binder1stboost::binder1st54     binder1st(FunT const& fun, typename aux::make_arg_type< FirstArgT >::type arg) : FunT(fun), m_arg(arg) {}
55 
operator ()boost::binder1st56     result_type operator() () const
57     {
58         return FunT::operator()(m_arg);
59     }
60 
61     template< typename T0 >
operator ()boost::binder1st62     result_type operator() (T0 const& arg0) const
63     {
64         return FunT::operator()(m_arg, arg0);
65     }
66 
67     template< typename T0, typename T1 >
operator ()boost::binder1st68     result_type operator() (T0 const& arg0, T1 const& arg1) const
69     {
70         return FunT::operator()(m_arg, arg0, arg1);
71     }
72 
73 private:
74     FirstArgT m_arg;
75 };
76 
77 //! First argument binder
78 template< typename FunT, typename FirstArgT >
79 struct binder1st< FunT&, FirstArgT >
80 {
81     typedef typename remove_cv< FunT >::type::result_type result_type;
82 
binder1stboost::binder1st83     binder1st(FunT& fun, typename aux::make_arg_type< FirstArgT >::type arg) : m_fun(fun), m_arg(arg) {}
84 
operator ()boost::binder1st85     result_type operator() () const
86     {
87         return m_fun(m_arg);
88     }
89 
90     template< typename T0 >
operator ()boost::binder1st91     result_type operator() (T0 const& arg0) const
92     {
93         return m_fun(m_arg, arg0);
94     }
95 
96     template< typename T0, typename T1 >
operator ()boost::binder1st97     result_type operator() (T0 const& arg0, T1 const& arg1) const
98     {
99         return m_fun(m_arg, arg0, arg1);
100     }
101 
102 private:
103     FunT& m_fun;
104     FirstArgT m_arg;
105 };
106 
107 template< typename FunT, typename FirstArgT >
bind1st(FunT fun,FirstArgT const & arg)108 BOOST_FORCEINLINE binder1st< FunT, FirstArgT > bind1st(FunT fun, FirstArgT const& arg)
109 {
110     return binder1st< FunT, FirstArgT >(fun, arg);
111 }
112 
113 template< typename FunT, typename FirstArgT >
bind1st(FunT fun,FirstArgT & arg)114 BOOST_FORCEINLINE binder1st< FunT, FirstArgT > bind1st(FunT fun, FirstArgT& arg)
115 {
116     return binder1st< FunT, FirstArgT >(fun, arg);
117 }
118 
119 //! Second argument binder
120 template< typename FunT, typename SecondArgT >
121 struct binder2nd :
122     private FunT
123 {
124     typedef typename FunT::result_type result_type;
125 
binder2ndboost::binder2nd126     binder2nd(FunT const& fun, typename aux::make_arg_type< SecondArgT >::type arg) : FunT(fun), m_arg(arg) {}
127 
128     template< typename T >
operator ()boost::binder2nd129     result_type operator() (T const& arg) const
130     {
131         return FunT::operator()(arg, m_arg);
132     }
133 
134     template< typename T0, typename T1 >
operator ()boost::binder2nd135     result_type operator() (T0 const& arg0, T1 const& arg1) const
136     {
137         return FunT::operator()(arg0, m_arg, arg1);
138     }
139 
140 private:
141     SecondArgT m_arg;
142 };
143 
144 //! Second argument binder
145 template< typename FunT, typename SecondArgT >
146 struct binder2nd< FunT&, SecondArgT >
147 {
148     typedef typename remove_cv< FunT >::type::result_type result_type;
149 
binder2ndboost::binder2nd150     binder2nd(FunT& fun, typename aux::make_arg_type< SecondArgT >::type arg) : m_fun(fun), m_arg(arg) {}
151 
152     template< typename T >
operator ()boost::binder2nd153     result_type operator() (T const& arg) const
154     {
155         return m_fun(arg, m_arg);
156     }
157 
158     template< typename T0, typename T1 >
operator ()boost::binder2nd159     result_type operator() (T0 const& arg0, T1 const& arg1) const
160     {
161         return m_fun(arg0, m_arg, arg1);
162     }
163 
164 private:
165     FunT& m_fun;
166     SecondArgT m_arg;
167 };
168 
169 template< typename FunT, typename SecondArgT >
bind2nd(FunT fun,SecondArgT const & arg)170 BOOST_FORCEINLINE binder2nd< FunT, SecondArgT > bind2nd(FunT fun, SecondArgT const& arg)
171 {
172     return binder2nd< FunT, SecondArgT >(fun, arg);
173 }
174 
175 template< typename FunT, typename SecondArgT >
bind2nd(FunT fun,SecondArgT & arg)176 BOOST_FORCEINLINE binder2nd< FunT, SecondArgT > bind2nd(FunT fun, SecondArgT& arg)
177 {
178     return binder2nd< FunT, SecondArgT >(fun, arg);
179 }
180 
181 //! Third argument binder
182 template< typename FunT, typename ThirdArgT >
183 struct binder3rd :
184     private FunT
185 {
186     typedef typename FunT::result_type result_type;
187 
binder3rdboost::binder3rd188     binder3rd(FunT const& fun, typename aux::make_arg_type< ThirdArgT >::type arg) : FunT(fun), m_arg(arg) {}
189 
190     template< typename T0, typename T1 >
operator ()boost::binder3rd191     result_type operator() (T0 const& arg0, T1 const& arg1) const
192     {
193         return FunT::operator()(arg0, arg1, m_arg);
194     }
195 
196 private:
197     ThirdArgT m_arg;
198 };
199 
200 //! Third argument binder
201 template< typename FunT, typename ThirdArgT >
202 struct binder3rd< FunT&, ThirdArgT >
203 {
204     typedef typename remove_cv< FunT >::type::result_type result_type;
205 
binder3rdboost::binder3rd206     binder3rd(FunT& fun, typename aux::make_arg_type< ThirdArgT >::type arg) : m_fun(fun), m_arg(arg) {}
207 
208     template< typename T0, typename T1 >
operator ()boost::binder3rd209     result_type operator() (T0 const& arg0, T1 const& arg1) const
210     {
211         return m_fun(arg0, arg1, m_arg);
212     }
213 
214 private:
215     FunT& m_fun;
216     ThirdArgT m_arg;
217 };
218 
219 template< typename FunT, typename ThirdArgT >
bind3rd(FunT fun,ThirdArgT const & arg)220 BOOST_FORCEINLINE binder3rd< FunT, ThirdArgT > bind3rd(FunT fun, ThirdArgT const& arg)
221 {
222     return binder3rd< FunT, ThirdArgT >(fun, arg);
223 }
224 
225 template< typename FunT, typename ThirdArgT >
bind3rd(FunT fun,ThirdArgT & arg)226 BOOST_FORCEINLINE binder3rd< FunT, ThirdArgT > bind3rd(FunT fun, ThirdArgT& arg)
227 {
228     return binder3rd< FunT, ThirdArgT >(fun, arg);
229 }
230 
231 BOOST_LOG_CLOSE_NAMESPACE // namespace log
232 
233 } // namespace boost
234 
235 #include <boost/log/detail/footer.hpp>
236 
237 #endif // BOOST_LOG_UTILITY_FUNCTIONAL_BIND_HPP_INCLUDED_
238