stlab.adobe.com Adobe Systems Incorporated

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 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google