00001 #ifndef _theplu_yat_utility_stl_utility_
00002 #define _theplu_yat_utility_stl_utility_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036
00037 #include "DataWeight.h"
00038
00039 #include <boost/concept_check.hpp>
00040 #include <boost/iterator/transform_iterator.hpp>
00041 #include <boost/mpl/if.hpp>
00042 #include <boost/type_traits/add_const.hpp>
00043 #include <boost/type_traits/is_const.hpp>
00044 #include <boost/type_traits/remove_reference.hpp>
00045
00046 #include <algorithm>
00047 #include <cmath>
00048 #include <functional>
00049 #include <map>
00050 #include <ostream>
00051 #include <string>
00052 #include <utility>
00053 #include <vector>
00054
00055
00056
00057
00058 #ifndef YAT_STD_DISABLE
00059 namespace std {
00060
00064
00065
00066 template <class T1, class T2>
00067 std::ostream& operator<<(std::ostream& out, const std::pair<T1,T2>& p)
00068 { out << p.first << "\t" << p.second; return out; }
00069
00070 }
00071 #endif
00072
00073 namespace theplu {
00074 namespace yat {
00075 namespace utility {
00076
00080 template<typename T>
00081 struct abs : std::unary_function<T, T>
00082 {
00086 inline T operator()(T x) const
00087 { return std::abs(x); }
00088 };
00089
00090
00104 template<class F, class G, class H>
00105 class compose_f_gx_hy : std::binary_function<typename G::argument_type,
00106 typename H::argument_type,
00107 typename F::result_type>
00108 {
00109 public:
00113 compose_f_gx_hy(F f, G g, H h)
00114 : f_(f), g_(g), h_(h) {}
00115
00119 typename F::result_type
00120 operator()(typename G::argument_type x,
00121 typename H::argument_type y) const
00122 {
00123 return f_(g_(x), h_(y));
00124 }
00125
00126 private:
00127 F f_;
00128 G g_;
00129 H h_;
00130 };
00131
00137 template<class F, class G, class H>
00138 compose_f_gx_hy<F, G, H> make_compose_f_gx_hy(F f, G g, H h)
00139 {
00140 return compose_f_gx_hy<F,G,H>(f,g,h);
00141 }
00142
00150 template<typename T>
00151 struct Exp : std::unary_function<T, T>
00152 {
00156 inline T operator()(T x) const
00157 { return std::exp(x); }
00158 };
00159
00172 template<typename InputIterator, typename Key, typename Comp>
00173 void inverse(InputIterator first, InputIterator last,
00174 std::map<Key, std::vector<size_t>, Comp >& m)
00175 {
00176 BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
00177 BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
00178 m.clear();
00179 for (size_t i=0; first!=last; ++i, ++first)
00180 m[*first].push_back(i);
00181 }
00182
00191 template<typename Key, typename InputIterator, typename Comp>
00192 void inverse(InputIterator first, InputIterator last,
00193 std::multimap<Key, size_t, Comp>& m)
00194 {
00195 BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
00196 BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
00197 m.clear();
00198 for (size_t i=0; first!=last; ++i, ++first)
00199 m.insert(std::make_pair(*first, i));
00200 }
00201
00202
00223 template<typename T>
00224 struct less_nan : std::binary_function<T, T, bool>
00225 {
00231 inline bool operator()(T x, T y) const
00232 {
00233 if (std::isnan(x))
00234 return false;
00235 if (std::isnan(y))
00236 return true;
00237 return x<y;
00238 }
00239 };
00240
00241
00245 template<>
00246 struct less_nan<DataWeight>
00247 : std::binary_function<DataWeight, DataWeight, bool>
00248 {
00252 inline bool operator()(const DataWeight& x, const DataWeight& y) const
00253 {
00254 less_nan<double> compare;
00255 return compare(x.data(), y.data());
00256 }
00257 };
00258
00259
00267 template<typename T>
00268 class Log : std::unary_function<T, T>
00269 {
00270 public:
00274 Log(void)
00275 : log_base_(1.0) {}
00276
00280 explicit Log(double base) : log_base_(std::log(base)) {}
00281
00285 inline T operator()(T x) const
00286 { return std::log(x)/log_base_; }
00287
00288 private:
00289 double log_base_;
00290 };
00291
00295 template <typename T>
00296 T max(const T& a, const T& b, const T& c)
00297 {
00298 return std::max(std::max(a,b),c);
00299 }
00300
00301
00305 template <typename T>
00306 T max(const T& a, const T& b, const T& c, const T& d)
00307 {
00308 return std::max(std::max(a,b), std::max(c,d));
00309 }
00310
00311
00315 template <typename T>
00316 T max(const T& a, const T& b, const T& c, const T& d, const T& e)
00317 {
00318 return std::max(max(a,b,c,d), e);
00319 }
00320
00321
00325 template <typename T>
00326 T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
00327 {
00328 return std::max(max(a,b,c,d), std::max(e,f));
00329 }
00330
00331
00339 template <class T1,class T2>
00340 struct pair_value_compare
00341 {
00346 inline bool operator()(const std::pair<T1,T2>& x,
00347 const std::pair<T1,T2>& y) {
00348 return ((x.second<y.second) ||
00349 (!(y.second<x.second) && (x.first<y.first)));
00350 }
00351 };
00352
00360 template <class Pair>
00361 struct PairFirst
00362 {
00368 typedef typename boost::mpl::if_<
00369 typename boost::is_const<Pair>::type,
00370 typename boost::add_const<typename Pair::first_type>::type&,
00371 typename Pair::first_type&>::type result_type;
00372
00376 typedef Pair& argument_type;
00377
00381 inline result_type operator()(argument_type p) const
00382 { return p.first; }
00383
00384 };
00385
00386
00394 template <class Pair>
00395 struct PairSecond
00396 {
00402 typedef typename boost::mpl::if_<
00403 typename boost::is_const<Pair>::type,
00404 typename boost::add_const<typename Pair::second_type>::type&,
00405 typename Pair::second_type&>::type result_type;
00406
00410 typedef Pair& argument_type;
00411
00415 inline result_type operator()(argument_type p) const
00416 { return p.second; }
00417
00418 };
00419
00420
00438 template<class Iter>
00439 boost::transform_iterator<
00440 PairFirst<typename boost::remove_reference<
00441 typename std::iterator_traits<Iter>::reference
00442 >::type>,
00443 Iter> pair_first_iterator(Iter i)
00444 {
00445
00446
00447 typedef typename std::iterator_traits<Iter>::reference ref_type;
00448 typedef typename boost::remove_reference<ref_type>::type val_type;
00449 typedef PairFirst<val_type> PF;
00450 return boost::transform_iterator<PF, Iter>(i, PF());
00451 }
00452
00453
00469 template<class Iter>
00470 boost::transform_iterator<
00471 PairSecond<typename boost::remove_reference<
00472 typename std::iterator_traits<Iter>::reference
00473 >::type>,
00474 Iter> pair_second_iterator(Iter i)
00475 {
00476
00477
00478 typedef typename std::iterator_traits<Iter>::reference ref_type;
00479 typedef typename boost::remove_reference<ref_type>::type val_type;
00480 typedef PairSecond<val_type> PS;
00481 return boost::transform_iterator<PS, Iter>(i, PS());
00482 }
00483
00484
00485
00486
00490 std::string& to_lower(std::string& s);
00491
00495 std::string& to_upper(std::string& s);
00496
00497 }}}
00498
00499 #endif