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 "concept_check.h"
00038 #include "DataWeight.h"
00039 #include "Exception.h"
00040
00041 #include <boost/concept_check.hpp>
00042 #include <boost/iterator/transform_iterator.hpp>
00043 #include <boost/mpl/if.hpp>
00044 #include <boost/type_traits/add_const.hpp>
00045 #include <boost/type_traits/is_const.hpp>
00046 #include <boost/type_traits/remove_reference.hpp>
00047
00048 #include <algorithm>
00049 #include <cmath>
00050 #include <exception>
00051 #include <functional>
00052 #include <iterator>
00053 #include <map>
00054 #include <ostream>
00055 #include <sstream>
00056 #include <string>
00057 #include <utility>
00058 #include <vector>
00059
00060
00061
00062
00063 #ifndef YAT_STD_DISABLE
00064 namespace std {
00065
00069
00070
00071 template <class T1, class T2>
00072 std::ostream& operator<<(std::ostream& out, const std::pair<T1,T2>& p)
00073 { out << p.first << "\t" << p.second; return out; }
00074
00075 }
00076 #endif
00077
00078 namespace theplu {
00079 namespace yat {
00080 namespace utility {
00081
00085 template<typename T>
00086 struct abs : std::unary_function<T, T>
00087 {
00091 inline T operator()(T x) const
00092 { return std::abs(x); }
00093 };
00094
00095
00106 template<typename Pointer>
00107 struct Dereferencer :
00108 public std::unary_function<Pointer,
00109 typename std::iterator_traits<Pointer>::reference>
00110 {
00114 Dereferencer(void)
00115 { BOOST_CONCEPT_ASSERT((TrivialIterator<Pointer>)); }
00116
00120 typename std::iterator_traits<Pointer>::reference
00121 operator()(Pointer ti) const { return *ti; }
00122 };
00123
00124
00148 template<class F, class G, class H>
00149 class compose_f_gx_hy :
00150 public std::binary_function<typename G::argument_type,
00151 typename H::argument_type,
00152 typename F::result_type>
00153 {
00154 public:
00158 compose_f_gx_hy(F f, G g, H h)
00159 : f_(f), g_(g), h_(h)
00160 {
00161 BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
00162 , typename F::first_argument_type>));
00163 BOOST_CONCEPT_ASSERT((boost::Convertible<typename H::result_type
00164 , typename F::second_argument_type>));
00165
00166 }
00167
00171 typename F::result_type
00172 operator()(typename G::argument_type x,
00173 typename H::argument_type y) const
00174 {
00175 return f_(g_(x), h_(y));
00176 }
00177
00178 private:
00179 F f_;
00180 G g_;
00181 H h_;
00182 };
00183
00191 template<class F, class G, class H>
00192 compose_f_gx_hy<F, G, H> make_compose_f_gx_hy(F f, G g, H h)
00193 {
00194 return compose_f_gx_hy<F,G,H>(f,g,h);
00195 }
00196
00197
00219 template<class F, class G>
00220 class compose_f_gxy :
00221 public std::binary_function<typename G::first_argument_type,
00222 typename G::second_argument_type,
00223 typename F::result_type>
00224 {
00225 public:
00229 compose_f_gxy(F f, G g)
00230 : f_(f), g_(g)
00231 {
00232 BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
00233 , typename F::argument_type>));
00234 }
00235
00239 typename F::result_type
00240 operator()(typename G::first_argument_type x,
00241 typename G::second_argument_type y) const
00242 {
00243 return f_(g_(x,y));
00244 }
00245
00246 private:
00247 F f_;
00248 G g_;
00249 };
00250
00260 template<class F, class G>
00261 compose_f_gxy<F, G> make_compose_f_gxy(F f, G g)
00262 {
00263 return compose_f_gxy<F,G>(f,g);
00264 }
00265
00266
00287 template<class F, class G>
00288 class compose_f_gx : public std::unary_function<typename G::argument_type,
00289 typename F::result_type>
00290 {
00291 public:
00295 compose_f_gx(F f, G g)
00296 : f_(f), g_(g)
00297 {
00298 BOOST_CONCEPT_ASSERT((boost::Convertible<typename G::result_type
00299 , typename F::argument_type>));
00300 }
00301
00305 typename F::result_type
00306 operator()(typename G::argument_type x) const
00307 {
00308 return f_(g_(x));
00309 }
00310
00311 private:
00312 F f_;
00313 G g_;
00314 };
00315
00325 template<class F, class G>
00326 compose_f_gx<F, G> make_compose_f_gx(F f, G g)
00327 {
00328 return compose_f_gx<F,G>(f,g);
00329 }
00330
00331
00339 template<typename T>
00340 struct Exp : std::unary_function<T, T>
00341 {
00345 inline T operator()(T x) const
00346 { return std::exp(x); }
00347 };
00348
00354 template<typename T>
00355 struct Identity : public std::unary_function<T, T>
00356 {
00358 T operator()(T arg) const { return arg; }
00359 };
00360
00361
00371 template <typename Key, typename Tp, typename Compare, typename Alloc>
00372 const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& k);
00373
00374
00387 template<typename InputIterator, typename Key, typename Comp>
00388 void inverse(InputIterator first, InputIterator last,
00389 std::map<Key, std::vector<size_t>, Comp >& m)
00390 {
00391 BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
00392 BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
00393 m.clear();
00394 for (size_t i=0; first!=last; ++i, ++first)
00395 m[*first].push_back(i);
00396 }
00397
00406 template<typename Key, typename InputIterator, typename Comp>
00407 void inverse(InputIterator first, InputIterator last,
00408 std::multimap<Key, size_t, Comp>& m)
00409 {
00410 BOOST_CONCEPT_ASSERT((boost::InputIterator<InputIterator>));
00411 BOOST_CONCEPT_ASSERT((boost::Convertible<typename std::iterator_traits<InputIterator>::value_type, Key>));
00412 m.clear();
00413 for (size_t i=0; first!=last; ++i, ++first)
00414 m.insert(std::make_pair(*first, i));
00415 }
00416
00417
00438 template<typename T>
00439 struct less_nan : std::binary_function<T, T, bool>
00440 {
00446 inline bool operator()(T x, T y) const
00447 {
00448 if (std::isnan(x))
00449 return false;
00450 if (std::isnan(y))
00451 return true;
00452 return x<y;
00453 }
00454 };
00455
00456
00460 template<>
00461 struct less_nan<DataWeight>
00462 : std::binary_function<DataWeight, DataWeight, bool>
00463 {
00467 inline bool operator()(const DataWeight& x, const DataWeight& y) const
00468 {
00469 less_nan<double> compare;
00470 return compare(x.data(), y.data());
00471 }
00472 };
00473
00474
00482 template<typename T>
00483 class Log : std::unary_function<T, T>
00484 {
00485 public:
00489 Log(void)
00490 : log_base_(1.0) {}
00491
00495 explicit Log(double base) : log_base_(std::log(base)) {}
00496
00500 inline T operator()(T x) const
00501 { return std::log(x)/log_base_; }
00502
00503 private:
00504 double log_base_;
00505 };
00506
00510 template <typename T>
00511 T max(const T& a, const T& b, const T& c)
00512 {
00513 return std::max(std::max(a,b),c);
00514 }
00515
00516
00520 template <typename T>
00521 T max(const T& a, const T& b, const T& c, const T& d)
00522 {
00523 return std::max(std::max(a,b), std::max(c,d));
00524 }
00525
00526
00530 template <typename T>
00531 T max(const T& a, const T& b, const T& c, const T& d, const T& e)
00532 {
00533 return std::max(max(a,b,c,d), e);
00534 }
00535
00536
00540 template <typename T>
00541 T max(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f)
00542 {
00543 return std::max(max(a,b,c,d), std::max(e,f));
00544 }
00545
00546
00554 template <class T1,class T2>
00555 struct pair_value_compare
00556 {
00561 inline bool operator()(const std::pair<T1,T2>& x,
00562 const std::pair<T1,T2>& y) {
00563 return ((x.second<y.second) ||
00564 (!(y.second<x.second) && (x.first<y.first)));
00565 }
00566 };
00567
00575 template <class Pair>
00576 struct PairFirst
00577 {
00583 typedef typename boost::mpl::if_<
00584 typename boost::is_const<Pair>::type,
00585 typename boost::add_const<typename Pair::first_type>::type&,
00586 typename Pair::first_type&>::type result_type;
00587
00591 typedef Pair& argument_type;
00592
00596 inline result_type operator()(argument_type p) const
00597 { return p.first; }
00598
00599 };
00600
00601
00609 template <class Pair>
00610 struct PairSecond
00611 {
00617 typedef typename boost::mpl::if_<
00618 typename boost::is_const<Pair>::type,
00619 typename boost::add_const<typename Pair::second_type>::type&,
00620 typename Pair::second_type&>::type result_type;
00621
00625 typedef Pair& argument_type;
00626
00630 inline result_type operator()(argument_type p) const
00631 { return p.second; }
00632
00633 };
00634
00635
00653 template<class Iter>
00654 boost::transform_iterator<
00655 PairFirst<typename boost::remove_reference<
00656 typename std::iterator_traits<Iter>::reference
00657 >::type>,
00658 Iter> pair_first_iterator(Iter i)
00659 {
00660
00661
00662 typedef typename std::iterator_traits<Iter>::reference ref_type;
00663 typedef typename boost::remove_reference<ref_type>::type val_type;
00664 typedef PairFirst<val_type> PF;
00665 return boost::transform_iterator<PF, Iter>(i, PF());
00666 }
00667
00668
00684 template<class Iter>
00685 boost::transform_iterator<
00686 PairSecond<typename boost::remove_reference<
00687 typename std::iterator_traits<Iter>::reference
00688 >::type>,
00689 Iter> pair_second_iterator(Iter i)
00690 {
00691
00692
00693 typedef typename std::iterator_traits<Iter>::reference ref_type;
00694 typedef typename boost::remove_reference<ref_type>::type val_type;
00695 typedef PairSecond<val_type> PS;
00696 return boost::transform_iterator<PS, Iter>(i, PS());
00697 }
00698
00699
00728 template<typename Pointer, class Compare>
00729 compose_f_gx_hy<Compare, Dereferencer<Pointer>, Dereferencer<Pointer> >
00730 make_ptr_compare(Pointer p, Compare compare)
00731 {
00732 return make_compose_f_gx_hy(compare, Dereferencer<Pointer>(),
00733 Dereferencer<Pointer>());
00734 }
00735
00742 template<typename Pointer>
00743 compose_f_gx_hy<std::less<typename std::iterator_traits<Pointer>::value_type>,
00744 Dereferencer<Pointer>, Dereferencer<Pointer> >
00745 make_ptr_compare(Pointer p)
00746 {
00747 typedef typename std::iterator_traits<Pointer>::value_type value_type;
00748 BOOST_CONCEPT_ASSERT((boost::LessThanComparable<value_type>));
00749 std::less<value_type> compare;
00750 return make_ptr_compare(p, compare);
00751 }
00752
00753
00757 std::string& to_lower(std::string& s);
00758
00762 std::string& to_upper(std::string& s);
00763
00764
00765
00766
00767 template <typename Key, typename Tp, typename Compare, typename Alloc>
00768 const Tp& get(const std::map<Key, Tp, Compare, Alloc>& m, const Key& key)
00769 {
00770 typename std::map<Key, Tp, Compare, Alloc>::const_iterator iter(m.find(key));
00771 if (iter==m.end()) {
00772 std::stringstream ss;
00773 ss << "yat: get(const Map&, const Key&): Key not found in Map\n";
00774 throw runtime_error(ss.str());
00775 }
00776 return iter->second;
00777 }
00778
00779
00780
00781 }}}
00782
00783 #endif