00001
00002
00003
00004
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
00037
00038
00039
00165 template < typename F,
00166 typename G>
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>
00175 result_type operator()(const U& x) const { return data_m.first()(data_m.second()(x)); }
00176
00177 template <typename U>
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,
00187 typename G>
00188 unary_compose<F, G> compose(F f, G g) { return unary_compose<F, G>(f, g); }
00189
00190
00191
00192 template < typename F,
00193 typename G,
00194 typename H = G>
00195 struct binary_compose
00196 {
00197 typedef typename F::result_type result_type;
00198
00199 template <typename T, typename U>
00200 result_type operator()(const T& x, const U& y) const { return f(g(x), h(y)); }
00201
00202 template <typename T, typename U>
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>
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>
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>
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>
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>
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>
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
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>
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>
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>
00472 inline transposer<F> f_transpose(F f)
00473 {
00474 return transposer<F>(f);
00475 }
00476
00478
00479
00480
00481 }
00482
00483
00484
00485 #endif
00486
00487