source: trunk/yat/utility/WeightedIterator.h @ 1703

Last change on this file since 1703 was 1543, checked in by Peter, 13 years ago

fixes #368

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1#ifndef _theplu_yat_utility_weighted_iterator_
2#define _theplu_yat_utility_weighted_iterator_
3
4// $Id: WeightedIterator.h 1543 2008-10-01 03:53:04Z peter $
5
6/*
7  Copyright (C) 2008 Peter Johansson
8
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "DataWeight.h"
26#include "DataWeightProxy.h"
27
28#include <boost/iterator/iterator_facade.hpp>
29
30#include <iterator>
31
32namespace theplu {
33namespace yat {
34namespace utility {
35
36  /**
37     \brief WeightedIterator
38  */
39  template<typename DataIterator, typename WeightIterator>
40  class WeightedIterator
41    : public boost::iterator_facade<
42    WeightedIterator<DataIterator, WeightIterator>,
43    DataWeightProxy<DataIterator, WeightIterator>,
44    typename std::iterator_traits<DataIterator>::iterator_category,
45    DataWeightProxy<DataIterator, WeightIterator> >
46   
47  {
48  public:
49    /**
50       \brief DataIterator
51     */
52    typedef DataIterator data_iterator;
53
54    /**
55       \brief DataIterator
56     */
57    typedef WeightIterator weight_iterator;
58
59    /**
60       \brief Constructor
61     */
62    WeightedIterator(DataIterator d, WeightIterator w)
63      : d_iter_(d), w_iter_(w)
64    {}
65   
66    /**
67       \return const reference to underlying data iterator
68     */
69    const DataIterator& data_base(void) const { return d_iter_; }
70
71    /**
72       \return const reference to underlying weight iterator
73     */
74    const WeightIterator& weight_base(void) const { return w_iter_; }
75
76    /**
77       \brief element operator
78     */
79    DataWeightProxy<DataIterator, WeightIterator> operator[](int n) const
80    {
81      return DataWeightProxy<DataIterator, WeightIterator>(d_iter_+n, 
82                                                           w_iter_+n); 
83    }     
84   
85
86    /**
87       \brief Conversion constructor.
88       
89       Create a WeightIterator<Base> from a
90       WeightIterator<B2>. Possible if B2 is convertible to a
91       Base. Constructor allows implicit conversions such as iterator
92       to const_iterator.
93     */
94    template<typename D2, typename W2>
95    WeightedIterator(WeightedIterator<D2, W2> other,
96            typename boost::enable_if_convertible<D2,DataIterator>::type* = 0,
97            typename boost::enable_if_convertible<W2,WeightIterator>::type* = 0)
98      : d_iter_(other.data_base()), w_iter_(other.weight_base()) {}
99
100
101  private:
102    friend class boost::iterator_core_access;
103
104    DataIterator d_iter_;
105    WeightIterator w_iter_;
106   
107    void advance(size_t n)
108    { std::advance(d_iter_, n); std::advance(w_iter_, n); }
109
110    void decrement(void) { --d_iter_; --w_iter_; }
111   
112    typename std::iterator_traits<DataIterator>::difference_type
113    distance_to(const WeightedIterator& other) const
114    { return std::distance(d_iter_, other.d_iter_); }
115
116    utility::DataWeightProxy<DataIterator, WeightIterator> 
117    dereference(void) const 
118    { return DataWeightProxy<DataIterator, WeightIterator>(d_iter_, 
119                                                           w_iter_); 
120    }
121
122    bool equal(const WeightedIterator& other) const
123    { return d_iter_==other.d_iter_ && w_iter_==other.w_iter_; }
124
125    void increment(void) { ++d_iter_; ++w_iter_; }
126
127  };
128
129  /**
130     \brief convenient function to create WeightedIterator
131
132     Convenient function in same fashion as std::make_pair.
133   */
134  template<typename DataIterator, typename WeightIterator>
135  WeightedIterator<DataIterator, WeightIterator> 
136  weighted_iterator(DataIterator data, WeightIterator weight)
137  {
138    return WeightedIterator<DataIterator, WeightIterator>(data, weight);
139  }
140 
141
142  /**
143     Specialization for WeightedIterator
144   */
145  template <typename DataIterator, typename WeightIterator>
146  struct weighted_iterator_traits<WeightedIterator<DataIterator
147                                                   ,WeightIterator> >
148  {
149    /**
150       WeightedIterator is weighted
151     */
152    typedef weighted_iterator_tag type;
153  };
154
155  /**
156     Specialization for WeightedIterator
157   */
158  template <typename DataIterator, typename WeightIterator>
159  struct iterator_traits<WeightedIterator<DataIterator, WeightIterator> >
160  {
161  private:
162    typedef WeightedIterator<DataIterator,WeightIterator> WI;
163    typedef typename WI::data_iterator data_iterator;
164    typedef typename WI::weight_iterator weight_iterator;
165  public:
166    /**
167       data_reference is same reference of data_iterator_base
168     */
169    typedef typename 
170    std::iterator_traits<data_iterator>::reference data_reference;
171
172    /**
173       weight_reference is same reference of weight_iterator_base
174     */
175    typedef typename 
176    std::iterator_traits<weight_iterator>::reference weight_reference;
177
178    /**
179       \return dereferenced data_iterator
180     */
181    data_reference data(WI iter) const { return * iter.data_base(); }
182
183    /**
184       \return dereferenced weight_iterator
185     */
186    weight_reference weight(WI iter) const { return * iter.weight_base(); }
187  };
188
189}}} // of namespace utility, yat, and theplu
190
191#endif
Note: See TracBrowser for help on using the repository browser.