00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ADOBE_ALGORITHM_UPPER_BOUND_HPP
00010 #define ADOBE_ALGORITHM_UPPER_BOUND_HPP
00011
00012 #include <adobe/config.hpp>
00013
00014 #include <algorithm>
00015 #include <cassert>
00016 #include <iterator>
00017
00018 #include <boost/bind.hpp>
00019 #include <boost/next_prior.hpp>
00020 #include <boost/range/begin.hpp>
00021 #include <boost/range/end.hpp>
00022 #include <boost/type_traits/is_same.hpp>
00023 #include <boost/utility/enable_if.hpp>
00024
00025 #include <adobe/functional.hpp>
00026
00027
00028
00029 namespace adobe {
00030 namespace implementation {
00031
00032
00033
00034 template < typename I,
00035 typename N,
00036 typename T,
00037 typename C,
00038 typename P>
00039 I upper_bound_n(I f, N n, const T& x, C c, P p)
00040 {
00041 assert(!(n < 0) && "FATAL (sparent) : n must be >= 0");
00042
00043 while (n != 0)
00044 {
00045 N h = n >> 1;
00046
00047 I m = boost::next(f, h);
00048
00049 if (!c(x, p(*m))) { f = boost::next(m); n -= h + N(1); }
00050 else { n = h; }
00051 }
00052 return f;
00053 }
00054
00055
00056
00057 }
00058
00059
00060
00069
00070
00071 template < typename I,
00072 typename N,
00073 typename T>
00074 inline I upper_bound_n(I f, N n, const T& x)
00075 {
00076 return implementation::upper_bound_n(f, n, x, less(), identity<T>());
00077 }
00078
00079
00080
00081 template < typename I,
00082 typename N,
00083 typename T,
00084 typename C>
00085 inline I upper_bound_n(I f, N n, const T& x, C c)
00086 {
00087 return implementation::upper_bound_n(f, n, x, boost::bind(c, _1, _2), identity<T>());
00088 }
00089
00090
00091
00092 template < typename I,
00093 typename N,
00094 typename T,
00095 typename C,
00096 typename P>
00097 inline I upper_bound_n(I f, N n, const T& x, C c, P p)
00098 {
00099 return implementation::upper_bound_n(f, n, x, boost::bind(c, _1, _2), boost::bind(p, _1));
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 namespace fn { } using namespace fn;
00111 namespace fn {
00112
00113
00114
00115 template < typename I,
00116 typename T>
00117 inline I upper_bound(I f, I l, const T& x)
00118 {
00119 return std::upper_bound(f, l, x);
00120 }
00121
00122
00123
00124 template < typename I,
00125 typename T,
00126 typename C>
00127 inline I upper_bound(I f, I l, const T& x, C c)
00128 {
00129 return std::upper_bound(f, l, x, boost::bind(c, _1, _2));
00130 }
00131
00132
00133
00134 template < typename I,
00135 typename T,
00136 typename C,
00137 typename P>
00138 inline I upper_bound(I f, I l, const T& x, C c, P p)
00139 {
00140 return upper_bound_n(f, std::distance(f, l), x, c, p);
00141 }
00142
00143
00144
00145 template < typename I,
00146 typename T,
00147 typename C,
00148 typename P>
00149 inline
00150 typename boost::lazy_disable_if<boost::is_same<I, T>, boost::range_iterator<I> >::type
00151 upper_bound(I& r, const T& x, C c, P p)
00152 { return adobe::upper_bound(boost::begin(r), boost::end(r), x, c, p); }
00153
00154
00155
00156 template < typename I,
00157 typename T,
00158 typename C,
00159 typename P>
00160 inline
00161 typename boost::lazy_disable_if<boost::is_same<I, T>, boost::range_const_iterator<I> >::type
00162 upper_bound(const I& r, const T& x, C c, P p)
00163 { return adobe::upper_bound(boost::begin(r), boost::end(r), x, c, p); }
00164
00165
00171 template <class ForwardRange, class T>
00172 inline typename boost::range_iterator<ForwardRange>::type upper_bound(ForwardRange& range, const T& value)
00173 {
00174 return std::upper_bound(boost::begin(range), boost::end(range), value);
00175 }
00176
00182 template <class ForwardRange, class T>
00183 inline typename boost::range_const_iterator<ForwardRange>::type upper_bound(const ForwardRange& range, const T& value)
00184 {
00185 return std::upper_bound(boost::begin(range), boost::end(range), value);
00186 }
00187
00198 template <typename I, class T, class Compare>
00199 inline typename boost::lazy_disable_if<boost::is_same<I, T>, boost::range_iterator<I> >::type
00200 upper_bound(I& range, const T& value, Compare comp)
00201 {
00202 return adobe::upper_bound(boost::begin(range), boost::end(range), value, comp);
00203 }
00204
00210 template <class I, class T, class Compare>
00211 inline typename boost::lazy_disable_if<boost::is_same<I, T>, boost::range_const_iterator<I> >::type
00212 upper_bound(const I& range, const T& value, Compare comp)
00213 {
00214 return adobe::upper_bound(boost::begin(range), boost::end(range), value, comp);
00215 }
00216
00217
00218
00219 }
00220 }
00221
00222
00223
00224 #endif
00225
00226