find.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_ALGORITHM_FIND_HPP 00010 #define ADOBE_ALGORITHM_FIND_HPP 00011 00012 #include <adobe/config.hpp> 00013 00014 #include <algorithm> 00015 #include <utility> 00016 00017 #include <boost/range/begin.hpp> 00018 #include <boost/range/end.hpp> 00019 #include <boost/next_prior.hpp> 00020 #include <boost/bind.hpp> 00021 00022 /*************************************************************************************************/ 00023 00024 namespace adobe { 00025 00026 /*************************************************************************************************/ 00039 /*************************************************************************************************/ 00040 00056 /*************************************************************************************************/ 00057 00058 /*************************************************************************************************/ 00073 /*************************************************************************************************/ 00079 template <class InputIterator, class Predicate> 00080 inline InputIterator find_if_not(InputIterator first, InputIterator last, Predicate pred) 00081 { 00082 return std::find_if(first, last, !boost::bind(pred, _1)); 00083 } 00084 00090 template <class InputRange, class Predicate> 00091 inline typename boost::range_iterator<InputRange>::type 00092 find_if_not(InputRange& range, Predicate pred) 00093 { 00094 return adobe::find_if_not(boost::begin(range), boost::end(range), pred); 00095 } 00096 00102 template <class InputRange, class Predicate> 00103 inline typename boost::range_const_iterator<InputRange>::type 00104 find_if_not(const InputRange& range, Predicate pred) 00105 { 00106 return adobe::find_if_not(boost::begin(range), boost::end(range), pred); 00107 } 00108 00109 /*************************************************************************************************/ 00110 00114 template <class InputIterator, class T> 00115 inline InputIterator find_not(InputIterator first, InputIterator last, const T& value) 00116 { 00117 return std::find_if(first, last, boost::bind(std::not_equal_to<T>(), value, _1)); 00118 } 00119 00125 template <class InputRange, class T> 00126 inline typename boost::range_iterator<InputRange>::type 00127 find_not(InputRange& range, const T& value) 00128 { 00129 return adobe::find_not(boost::begin(range), boost::end(range), value); 00130 } 00131 00137 template <class InputRange, class T> 00138 inline typename boost::range_const_iterator<InputRange>::type 00139 find_not(const InputRange& range, const T& value) 00140 { 00141 return adobe::find_not(boost::begin(range), boost::end(range), value); 00142 } 00143 00144 00149 template <class InputRange, class T> 00150 inline typename boost::range_iterator<InputRange>::type 00151 find(InputRange& range, const T& value) 00152 { 00153 return std::find(boost::begin(range), boost::end(range), value); 00154 } 00155 00161 template <class InputRange, class T> 00162 inline typename boost::range_const_iterator<InputRange>::type 00163 find(const InputRange& range, const T& value) 00164 { 00165 return std::find(boost::begin(range), boost::end(range), value); 00166 } 00167 00173 template <class InputIterator, class Predicate> 00174 inline InputIterator find_if(InputIterator first, InputIterator last, Predicate pred) 00175 { 00176 return std::find_if(first, last, boost::bind(pred, _1)); 00177 } 00178 00184 template <class InputRange, class Predicate> 00185 inline typename boost::range_iterator<InputRange>::type 00186 find_if(InputRange& range, Predicate pred) 00187 { 00188 return adobe::find_if(boost::begin(range), boost::end(range), pred); 00189 } 00190 00196 template <class InputRange, class Predicate> 00197 inline typename boost::range_const_iterator<InputRange>::type 00198 find_if(const InputRange& range, Predicate pred) 00199 { 00200 return adobe::find_if(boost::begin(range), boost::end(range), pred); 00201 } 00202 00207 template < typename I, // I models ForwardIterator 00208 typename T> // T is value_type(I) 00209 std::pair<I, I> find_range(I f, I l, const T& x) 00210 { 00211 f = std::find(f, l, x); 00212 if (f != l) l = find_not(boost::next(f), l, x); 00213 return std::make_pair(f, l); 00214 } 00215 00220 template < typename I, // I models ForwardIterator 00221 typename P> // P models UnaryPredicate(value_type(I)) 00222 std::pair<I, I> find_range_if(I f, I l, P p) 00223 { 00224 f = adobe::find_if(f, l, p); 00225 if (f != l) l = adobe::find_if_not(boost::next(f), l, p); 00226 return std::make_pair(f, l); 00227 } 00228 00234 template <class ForwardRange1, class ForwardRange2> 00235 inline typename boost::range_iterator<ForwardRange1>::type 00236 find_end(ForwardRange1& range1, const ForwardRange2& range2) 00237 { 00238 return std::find_end(boost::begin(range1), boost::end(range1), 00239 boost::begin(range2), boost::end(range2)); 00240 } 00241 00247 template <class ForwardRange1, class ForwardRange2> 00248 inline typename boost::range_const_iterator<ForwardRange1>::type 00249 find_end(const ForwardRange1& range1, const ForwardRange2& range2) 00250 { 00251 return std::find_end(boost::begin(range1), boost::end(range1), 00252 boost::begin(range2), boost::end(range2)); 00253 } 00254 00260 template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate> 00261 inline ForwardIterator1 find_end(ForwardIterator1 first1, ForwardIterator1 last1, 00262 ForwardIterator2 first2, ForwardIterator2 last2, 00263 BinaryPredicate comp) 00264 { 00265 return std::find_end(first1, last1, first2, last2, boost::bind(comp, _1, _2)); 00266 } 00267 00273 template <class ForwardRange1, class ForwardRange2, class BinaryPredicate> 00274 inline typename boost::range_iterator<ForwardRange1>::type 00275 find_end(ForwardRange1& range1, const ForwardRange2& range2, BinaryPredicate comp) 00276 { 00277 return adobe::find_end(boost::begin(range1), boost::end(range1), 00278 boost::begin(range2), boost::end(range2), 00279 comp); 00280 } 00281 00287 template <class ForwardRange1, class ForwardRange2, class BinaryPredicate> 00288 inline typename boost::range_const_iterator<ForwardRange1>::type 00289 find_end(const ForwardRange1& range1, const ForwardRange2& range2, BinaryPredicate comp) 00290 { 00291 return adobe::find_end(boost::begin(range1), boost::end(range1), 00292 boost::begin(range2), boost::end(range2), 00293 comp); 00294 } 00295 00296 #if 0 00297 00298 // find_first_of is a bad algorithm. Use find_first_of_set until we provide a better predicate. 00299 00305 template <class InputRange, class ForwardRange> 00306 inline typename boost::range_iterator<InputRange>::type 00307 find_first_of(InputRange& range1, const ForwardRange& range2) 00308 { 00309 return std::find_first_of(boost::begin(range1), boost::end(range1), 00310 boost::begin(range2), boost::end(range2)); 00311 } 00312 00318 template <class InputRange, class ForwardRange> 00319 inline typename boost::range_const_iterator<InputRange>::type 00320 find_first_of(const InputRange& range1, const ForwardRange& range2) 00321 { 00322 return std::find_first_of(boost::begin(range1), boost::end(range1), 00323 boost::begin(range2), boost::end(range2)); 00324 } 00325 00331 template <class InputIterator, class ForwardIterator, class BinaryPredicate> 00332 inline InputIterator find_first_of(InputIterator first1, InputIterator last1, 00333 ForwardIterator first2, ForwardIterator last2, 00334 BinaryPredicate comp) 00335 00336 { 00337 return std::find_first_of(first1, last1, first2, last2, boost::bind(comp, _1, _2)); 00338 } 00339 00345 template <class InputRange, class ForwardRange, class BinaryPredicate> 00346 inline typename boost::range_iterator<InputRange>::type 00347 find_first_of(InputRange& range1, const ForwardRange& range2, BinaryPredicate comp) 00348 { 00349 return adobe::find_first_of(boost::begin(range1), boost::end(range1), 00350 boost::begin(range2), boost::end(range2), 00351 comp); 00352 } 00353 00359 template <class InputRange, class ForwardRange, class BinaryPredicate> 00360 inline typename boost::range_const_iterator<InputRange>::type 00361 find_first_of(const InputRange& range1, const ForwardRange& range2, BinaryPredicate comp) 00362 { 00363 return adobe::find_first_of(boost::begin(range1), boost::end(range1), 00364 boost::begin(range2), boost::end(range2), 00365 comp); 00366 } 00367 00368 #endif 00369 00375 template <class ForwardRange> 00376 inline typename boost::range_iterator<ForwardRange>::type adjacent_find(ForwardRange& range) 00377 { 00378 return std::adjacent_find(boost::begin(range), boost::end(range)); 00379 } 00380 00386 template <class ForwardRange> 00387 inline typename boost::range_const_iterator<ForwardRange>::type 00388 adjacent_find(const ForwardRange& range) 00389 { 00390 return std::adjacent_find(boost::begin(range), boost::end(range)); 00391 } 00392 00398 template <class ForwardIterator, class BinaryPredicate> 00399 inline ForwardIterator 00400 adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate pred) 00401 { 00402 return std::adjacent_find(first, last, boost::bind(pred, _1, _2)); 00403 } 00404 00410 template <class ForwardRange, class BinaryPredicate> 00411 inline typename boost::range_iterator<ForwardRange>::type 00412 adjacent_find(ForwardRange& range, BinaryPredicate pred) 00413 { 00414 return adobe::adjacent_find(boost::begin(range), boost::end(range), pred); 00415 } 00416 00422 template <class ForwardRange, class BinaryPredicate> 00423 inline typename boost::range_const_iterator<ForwardRange>::type 00424 adjacent_find(const ForwardRange& range, BinaryPredicate pred) 00425 { 00426 return adobe::adjacent_find(boost::begin(range), boost::end(range), pred); 00427 } 00428 00429 /*************************************************************************************************/ 00430 00431 } // namespace adobe 00432 00433 /*************************************************************************************************/ 00434 00435 #endif 00436 00437 /*************************************************************************************************/ |