00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef PREDICATE_ITERATOR_H
00024 #define PREDICATE_ITERATOR_H
00025
00026 #include "boost/shared_ptr.hpp"
00027 #include <iterator>
00028 #include <vector>
00029 #include <cassert>
00030
00031 namespace BTK {
00032
00033 template <class Predicate, class Iterator>
00034 class MatchListStrategy {
00035 public:
00036 typedef typename Iterator::value_type value_type;
00037 typedef value_type & reference;
00038 typedef Iterator iterator_type;
00039 typedef Predicate predicate_type;
00040
00041 MatchListStrategy(Iterator const & begin,
00042 Iterator const & end,
00043 Predicate const & pred = Predicate()) :
00044 _iterator(begin), _end(end),
00045 _match_list(new std::vector<bool>()), _cur(0)
00046 {
00047 Iterator i(begin);
00048
00049
00050
00051 if (begin == end) {
00052 _match_list->push_back(false);
00053 } else {
00054
00055
00056 while (i != end) {
00057 if (pred(*i++))
00058 _match_list->push_back(true);
00059 else
00060 _match_list->push_back(false);
00061 }
00062
00063
00064 if (!(*_match_list)[0]) advance();
00065 }
00066 };
00067
00068 void advance()
00069 {
00070
00071
00072 while (_iterator != _end) {
00073 ++_cur;
00074 ++_iterator;
00075
00076 if (!(*_match_list)[_cur]) continue;
00077 else return;
00078 }
00079 }
00080
00081 reference dereference() const { return *_iterator; }
00082 const Iterator base() const { return _iterator; }
00083
00084 MatchListStrategy & operator=(MatchListStrategy const & rhs)
00085 {
00086 _iterator = rhs._iterator;
00087 _end = rhs._end;
00088 _match_list = rhs._match_list;
00089 _cur = rhs._cur;
00090 }
00091
00092 private:
00093 Iterator _iterator;
00094 Iterator _end;
00095 boost::shared_ptr<std::vector<bool> > _match_list;
00096 std::vector<bool>::size_type _cur;
00097 };
00098
00099 template <class Predicate, class Iterator>
00100 class PointerListStrategy {
00101 public:
00102 typedef typename Iterator::value_type value_type;
00103 typedef typename Iterator::reference reference;
00104 typedef Iterator iterator_type;
00105 typedef Predicate predicate_type;
00106
00107
00108 PointerListStrategy(Iterator const & begin,
00109 Iterator const & end,
00110 Predicate const & pred = Predicate()) :
00111 _match_list(new std::vector<Iterator>()), _cur()
00112 {
00113
00114 for (Iterator i(begin); i != end; ++i) {
00115 if (pred(*i)) {
00116 _match_list->push_back(i);
00117 }
00118 }
00119
00120
00121
00122 _match_list->push_back(end);
00123
00124 _cur = _match_list->begin();
00125 }
00126
00127 void advance() { ++_cur; }
00128
00129 reference dereference() const { return **_cur; }
00130
00131 Iterator base() const { return *_cur; }
00132
00133 PointerListStrategy & operator=(PointerListStrategy const & rhs)
00134 {
00135 _match_list = rhs._match_list;
00136 _cur = rhs._cur;
00137 }
00138
00139 private:
00140 boost::shared_ptr<std::vector<Iterator> > _match_list;
00141 typename std::vector<Iterator>::iterator _cur;
00142 };
00143
00167 template <class Predicate, class Iterator,
00168 class Strategy = PointerListStrategy<Predicate,Iterator> >
00169 class PredicateIterator
00170 {
00171 public:
00172
00180 typedef std::forward_iterator_tag iterator_category;
00181
00182 typedef typename std::iterator_traits<Iterator>::value_type
00183 value_type;
00184
00185 typedef typename std::iterator_traits<Iterator>::difference_type
00186 difference_type;
00187
00188 typedef typename std::iterator_traits<Iterator>::pointer
00189 pointer;
00190
00191 typedef typename std::iterator_traits<Iterator>::reference
00192 reference;
00194
00199 typedef PredicateIterator<Predicate,Iterator,Strategy> self_type;
00200 typedef Iterator iterator_type;
00201 typedef Predicate predicate_type;
00202 typedef Strategy strategy_type;
00204
00210 PredicateIterator(Iterator const & begin,
00211 Iterator const & end,
00212 Predicate const & p = Predicate()) :
00213 _predicate(p), _strategy(begin,end,p) {}
00214
00220 PredicateIterator(Iterator const & end,
00221 Predicate const & p = Predicate()) :
00222 _predicate(p), _strategy(end,end,p) {}
00223
00225 inline self_type & operator++()
00226 {
00227 _strategy.advance();
00228 return *this;
00229 }
00230
00232 inline self_type operator++(int)
00233 {
00234 self_type tmp(*this);
00235 _strategy.advance();
00236 return tmp;
00237 }
00238
00243 bool inline operator==(self_type const & rhs) const
00244 {
00245 return (_strategy.base() == rhs._strategy.base());
00246 }
00247
00248 bool inline operator!=(self_type const & rhs) const
00249 {
00250 return (_strategy.base() != rhs._strategy.base());
00251 }
00252
00253 bool inline operator==(Iterator const & rhs) const
00254 {
00255 return _strategy.base() == rhs;
00256 }
00257
00258 bool inline operator!=(Iterator const & rhs) const
00259 {
00260 return _strategy.base() != rhs;
00261 }
00262
00263 friend bool operator==(Iterator const & lhs,
00264 self_type const & rhs)
00265 {
00266 return (lhs == rhs._iterator);
00267 }
00268
00269 friend bool operator!=(Iterator const & lhs,
00270 self_type const & rhs)
00271 {
00272 return (lhs != rhs._iterator);
00273 }
00275
00277 inline reference operator*() const
00278 {
00279 return _strategy.dereference();
00280 }
00281
00283 inline pointer operator->() const
00284 {
00285
00286
00287
00288 return &(_strategy.dereference());
00289 }
00290
00291 inline self_type & operator=(self_type const & rhs)
00292 {
00293 _predicate = rhs._predicate;
00294 _strategy = rhs._strategy;
00295 return *this;
00296 }
00297
00298 private:
00299 Predicate _predicate;
00300 Strategy _strategy;
00301 };
00302
00307 template <class Predicate, class Iterator>
00308 inline PredicateIterator<Predicate,Iterator>
00309 make_predicate_iterator(Iterator const & begin,
00310 Iterator const & end,
00311 Predicate const & p)
00312 {
00313 return PredicateIterator<Predicate,Iterator>(begin,end,p);
00314 }
00315
00316 template <class Predicate, class Iterator>
00317 inline PredicateIterator<Predicate,Iterator>
00318 make_predicate_iterator(Iterator const & end,
00319 Predicate const & p)
00320 {
00321 return PredicateIterator<Predicate,Iterator>(end,p);
00322 }
00324
00325 };
00326
00327 #endif // PREDICATE_ITERATOR_H