functional.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 #ifndef ADOBE_FUNCTIONAL_HPP 00010 #define ADOBE_FUNCTIONAL_HPP 00011 00012 #include <adobe/config.hpp> 00013 00014 #include <functional> 00015 #include <utility> 00016 00017 #include <boost/compressed_pair.hpp> 00018 #include <boost/tuple/tuple.hpp> 00019 00020 #include <adobe/functional/operator.hpp> 00021 #include <adobe/functional/is_member.hpp> 00022 #include <adobe/utility/pair.hpp> 00023 00024 /*************************************************************************************************/ 00025 00026 namespace adobe { 00027 00028 /*************************************************************************************************/ 00029 00035 /* 00036 REVISIT (sparent) : Documentation for delete_ptr moved to adobe/functional.hpp because doxygen 00037 1.4.3 cannot handle the template specializations. 00038 */ 00039 00165 template < typename F, // models UnaryFunction 00166 typename G> // models UnaryFunction -> argument_type(F) 00167 struct unary_compose 00168 { 00169 typedef typename F::result_type result_type; 00170 00171 unary_compose() { } 00172 unary_compose(F f, G g) : data_m(f, g) { } 00173 00174 template <typename U> // U models Regular 00175 result_type operator()(const U& x) const { return data_m.first()(data_m.second()(x)); } 00176 00177 template <typename U> // U models Regular 00178 result_type operator()(U& x) const { return data_m.first()(data_m.second()(x)); } 00179 00180 private: 00181 boost::compressed_pair<F, G> data_m; 00182 }; 00183 00184 /*************************************************************************************************/ 00185 00186 template < typename F, // models UnaryFunction 00187 typename G> // models UnaryFunction -> argument_type(F) 00188 unary_compose<F, G> compose(F f, G g) { return unary_compose<F, G>(f, g); } 00189 00190 /*************************************************************************************************/ 00191 00192 template < typename F, // models BinaryFunction 00193 typename G, // models UnaryFunction -> argument_type(F, 0); 00194 typename H = G> // models UnaryFunction -> argument_type(F, 1); 00195 struct binary_compose 00196 { 00197 typedef typename F::result_type result_type; 00198 00199 template <typename T, typename U> // models Regular 00200 result_type operator()(const T& x, const U& y) const { return f(g(x), h(y)); } 00201 00202 template <typename T, typename U> // models Regular 00203 result_type operator()(T& x, U& y) const { return f(g(x), h(y)); } 00204 00205 F f; 00206 G g; 00207 H h; 00208 }; 00209 00210 /*************************************************************************************************/ 00211 00212 template <int N, typename T> // T is boost::tuple<> 00213 struct element 00214 { 00215 typedef typename boost::tuples::element<N, T>::type type; 00216 }; 00217 00218 template <typename T1, typename T2> 00219 struct element<0, std::pair<T1, T2> > 00220 { 00221 typedef typename std::pair<T1, T2>::first_type type; 00222 }; 00223 00224 template <typename T1, typename T2> 00225 struct element<1, std::pair<T1, T2> > 00226 { 00227 typedef typename std::pair<T1, T2>::second_type type; 00228 }; 00229 00230 template <typename T1, typename T2> 00231 struct element<0, pair<T1, T2> > 00232 { 00233 typedef typename pair<T1, T2>::first_type type; 00234 }; 00235 00236 template <typename T1, typename T2> 00237 struct element<1, pair<T1, T2> > 00238 { 00239 typedef typename pair<T1, T2>::second_type type; 00240 }; 00241 00242 /*************************************************************************************************/ 00243 00244 template <int N, typename T> // T is pair or tuple 00245 struct get_element : std::unary_function<T, typename element<N, T>::type> 00246 { 00247 typename element<N, T>::type& operator()(T& x) const 00248 { return boost::get<N>(x); } 00249 00250 const typename element<N, T>::type& operator()(const T& x) const 00251 { return boost::get<N>(x); } 00252 }; 00253 00254 /*************************************************************************************************/ 00255 00256 template <typename T1, typename T2> // T is pair or tuple 00257 struct get_element<0, std::pair<T1, T2> > : 00258 std::unary_function<std::pair<T1, T2>, typename std::pair<T1, T2>::first_type> 00259 { 00260 typedef std::pair<T1, T2> argument_type; 00261 typedef typename argument_type::first_type result_type; 00262 00263 result_type& operator()(argument_type& x) const 00264 { return x.first; } 00265 00266 const result_type& operator()(const argument_type& x) const 00267 { return x.first; } 00268 }; 00269 00270 /*************************************************************************************************/ 00271 00272 template <typename T1, typename T2> // T is pair or tuple 00273 struct get_element<0, pair<T1, T2> > : 00274 std::unary_function<pair<T1, T2>, typename pair<T1, T2>::first_type> 00275 { 00276 typedef pair<T1, T2> argument_type; 00277 typedef typename argument_type::first_type result_type; 00278 00279 result_type& operator()(argument_type& x) const 00280 { return x.first; } 00281 00282 const result_type& operator()(const argument_type& x) const 00283 { return x.first; } 00284 }; 00285 00286 /*************************************************************************************************/ 00287 00288 template <typename T1, typename T2> // T is pair or tuple 00289 struct get_element<1, std::pair<T1, T2> > : 00290 std::unary_function<std::pair<T1, T2>, typename std::pair<T1, T2>::second_type> 00291 { 00292 typedef std::pair<T1, T2> argument_type; 00293 typedef typename argument_type::second_type result_type; 00294 00295 result_type& operator()(argument_type& x) const 00296 { return x.second; } 00297 00298 const result_type& operator()(const argument_type& x) const 00299 { return x.second; } 00300 }; 00301 00302 /*************************************************************************************************/ 00303 00304 template <typename T1, typename T2> // T is pair or tuple 00305 struct get_element<1, pair<T1, T2> > : 00306 std::unary_function<pair<T1, T2>, typename pair<T1, T2>::second_type> 00307 { 00308 typedef pair<T1, T2> argument_type; 00309 typedef typename argument_type::second_type result_type; 00310 00311 result_type& operator()(argument_type& x) const 00312 { return x.second; } 00313 00314 const result_type& operator()(const argument_type& x) const 00315 { return x.second; } 00316 }; 00317 00318 /*************************************************************************************************/ 00319 00320 template <typename T> 00321 struct always_true : std::unary_function<T, bool> 00322 { 00323 bool operator()(const T&) const { return true; } 00324 }; 00325 00326 /*************************************************************************************************/ 00327 00328 template <class Result> 00329 struct generator_t 00330 { 00331 typedef Result result_type; 00332 }; 00333 00334 /*************************************************************************************************/ 00335 00336 00337 template <typename T> 00338 struct sequence_t 00339 #if !defined(ADOBE_NO_DOCUMENTATION) 00340 : generator_t<T> 00341 #endif 00342 { 00343 explicit sequence_t(const T& x) : data_m(x) { } 00344 T operator () () { return data_m++; } 00345 private: 00346 T data_m; 00347 }; 00348 00349 /*************************************************************************************************/ 00350 00351 template <class T, typename R, class Compare> 00352 struct compare_members_t : std::binary_function<T, T, bool> 00353 { 00354 compare_members_t(R T::* member, Compare compare) : 00355 compare_m(compare), 00356 member_m(member) 00357 { } 00358 00359 bool operator () (const T& x, const T& y) const 00360 { return compare_m(x.*member_m, y.*member_m); } 00361 00362 bool operator () (const T& x, const R& y) const 00363 { return compare_m(x.*member_m, y); } 00364 00365 bool operator () (const R& x, const T& y) const 00366 { return compare_m(x, y.*member_m); } 00367 00368 private: 00369 00370 /* 00371 REVISIT (sparent) : This could probably use an empty member optimization. 00372 */ 00373 00374 Compare compare_m; 00375 R T::* member_m; 00376 }; 00377 00378 template <class T, typename R> 00379 compare_members_t<T, R, std::less<R> > compare_members(R T::* member) 00380 { 00381 return compare_members_t<T, R, std::less<R> >(member, std::less<R>() ); 00382 } 00383 00384 template <class T, typename R, class Compare> 00385 compare_members_t<T, R, Compare> compare_members(R T::* member, Compare compare) 00386 { 00387 return compare_members_t<T, R, Compare>(member, compare); 00388 } 00389 00390 /*************************************************************************************************/ 00391 00392 template <class T, typename R> 00393 struct mem_data_t : std::unary_function<T, R&> 00394 { 00395 mem_data_t() { } 00396 00397 explicit mem_data_t(R T::* member) : 00398 member_m(member) 00399 { } 00400 00401 R& operator () (T& x) const 00402 { return x.*member_m; } 00403 00404 const R& operator () (const T& x) const 00405 { return x.*member_m; } 00406 00407 private: 00408 R T::* member_m; 00409 }; 00410 00411 template <class T, typename R> 00412 struct mem_data_t<const T, R> : std::unary_function<T, const R&> 00413 { 00414 explicit mem_data_t(R T::* member) : 00415 member_m(member) 00416 { } 00417 00418 const R& operator () (const T& x) const 00419 { return x.*member_m; } 00420 00421 private: 00422 R T::* member_m; 00423 }; 00424 00425 template <class T, typename R> 00426 mem_data_t<T, R> mem_data(R T::* member) 00427 { 00428 return mem_data_t<T, R>(member); 00429 } 00430 00431 /*************************************************************************************************/ 00432 00433 template <typename O> // O models StrictWeakOrdering 00434 struct equivalent : std::binary_function<typename O::first_argument_type, 00435 typename O::second_argument_type, 00436 bool> 00437 { 00438 public: 00439 explicit equivalent(const O& x) : o_m(x) { } 00440 00441 bool operator()( const typename O::first_argument_type& x, 00442 const typename O::second_argument_type& y) const 00443 { return !o_m(x, y) && !o_m(y, x); } 00444 private: 00445 O o_m; 00446 }; 00447 00448 /*************************************************************************************************/ 00449 00450 template <class F> // F models a BinaryFunction 00451 struct transposer : std::binary_function<typename F::second_argument_type, 00452 typename F::first_argument_type, 00453 typename F::result_type> 00454 { 00455 typedef typename F::second_argument_type first_argument_type; 00456 typedef typename F::first_argument_type second_argument_type; 00457 typedef typename F::result_type result_type; 00458 00459 F fun; 00460 00461 transposer(const F& f) : 00462 fun(f) 00463 { } 00464 00465 result_type operator()(const first_argument_type& x, const second_argument_type& y) const 00466 { 00467 return fun(y, x); 00468 } 00469 }; 00470 00471 template <typename F> // F models BinaryFunction 00472 inline transposer<F> f_transpose(F f) 00473 { 00474 return transposer<F>(f); 00475 } 00476 00478 00479 /*************************************************************************************************/ 00480 00481 } // namespace adobe 00482 00483 /*************************************************************************************************/ 00484 00485 #endif 00486 00487 /*************************************************************************************************/ |