00001 #ifndef _theplu_yat_utility_weighted_iterator_
00002 #define _theplu_yat_utility_weighted_iterator_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "DataWeight.h"
00026 #include "DataWeightProxy.h"
00027
00028 #include <boost/iterator/iterator_facade.hpp>
00029
00030 #include <iterator>
00031
00032 namespace theplu {
00033 namespace yat {
00034 namespace utility {
00035
00039 template<typename DataIterator, typename WeightIterator>
00040 class WeightedIterator
00041 : public boost::iterator_facade<
00042 WeightedIterator<DataIterator, WeightIterator>,
00043 DataWeightProxy<DataIterator, WeightIterator>,
00044 typename std::iterator_traits<DataIterator>::iterator_category,
00045 DataWeightProxy<DataIterator, WeightIterator> >
00046
00047 {
00048 public:
00052 typedef DataIterator data_iterator;
00053
00057 typedef WeightIterator weight_iterator;
00058
00062 WeightedIterator(DataIterator d, WeightIterator w)
00063 : d_iter_(d), w_iter_(w)
00064 {}
00065
00069 const DataIterator& data_base(void) const { return d_iter_; }
00070
00074 const WeightIterator& weight_base(void) const { return w_iter_; }
00075
00079 DataWeightProxy<DataIterator, WeightIterator> operator[](int n) const
00080 {
00081 return DataWeightProxy<DataIterator, WeightIterator>(d_iter_+n,
00082 w_iter_+n);
00083 }
00084
00085
00094 template<typename D2, typename W2>
00095 WeightedIterator(WeightedIterator<D2, W2> other,
00096 typename boost::enable_if_convertible<D2,DataIterator>::type* = 0,
00097 typename boost::enable_if_convertible<W2,WeightIterator>::type* = 0)
00098 : d_iter_(other.data_base()), w_iter_(other.weight_base()) {}
00099
00100
00101 private:
00102 friend class boost::iterator_core_access;
00103
00104 DataIterator d_iter_;
00105 WeightIterator w_iter_;
00106
00107 void advance(size_t n)
00108 { std::advance(d_iter_, n); std::advance(w_iter_, n); }
00109
00110 void decrement(void) { --d_iter_; --w_iter_; }
00111
00112 typename std::iterator_traits<DataIterator>::difference_type
00113 distance_to(const WeightedIterator& other) const
00114 { return std::distance(d_iter_, other.d_iter_); }
00115
00116 utility::DataWeightProxy<DataIterator, WeightIterator>
00117 dereference(void) const
00118 { return DataWeightProxy<DataIterator, WeightIterator>(d_iter_,
00119 w_iter_);
00120 }
00121
00122 bool equal(const WeightedIterator& other) const
00123 { return d_iter_==other.d_iter_ && w_iter_==other.w_iter_; }
00124
00125 void increment(void) { ++d_iter_; ++w_iter_; }
00126
00127 };
00128
00134 template<typename DataIterator, typename WeightIterator>
00135 WeightedIterator<DataIterator, WeightIterator>
00136 weighted_iterator(DataIterator data, WeightIterator weight)
00137 {
00138 return WeightedIterator<DataIterator, WeightIterator>(data, weight);
00139 }
00140
00141
00145 template <typename DataIterator, typename WeightIterator>
00146 struct weighted_iterator_traits<WeightedIterator<DataIterator
00147 ,WeightIterator> >
00148 {
00152 typedef weighted_iterator_tag type;
00153 };
00154
00158 template <typename DataIterator, typename WeightIterator>
00159 struct iterator_traits<WeightedIterator<DataIterator, WeightIterator> >
00160 {
00161 private:
00162 typedef WeightedIterator<DataIterator,WeightIterator> WI;
00163 typedef typename WI::data_iterator data_iterator;
00164 typedef typename WI::weight_iterator weight_iterator;
00165 public:
00169 typedef typename
00170 std::iterator_traits<data_iterator>::reference data_reference;
00171
00175 typedef typename
00176 std::iterator_traits<weight_iterator>::reference weight_reference;
00177
00181 data_reference data(WI iter) const { return * iter.data_base(); }
00182
00186 weight_reference weight(WI iter) const { return * iter.weight_base(); }
00187 };
00188
00189 }}}
00190
00191 #endif