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

Last change on this file since 1887 was 1887, checked in by Peter, 12 years ago

closes #512. added relates tag in namespace utility.

  • 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 1887 2009-03-31 17:38:16Z peter $
5
6/*
7  Copyright (C) 2008, 2009 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     \relates WeightedIterator
135   */
136  template<typename DataIterator, typename WeightIterator>
137  WeightedIterator<DataIterator, WeightIterator> 
138  weighted_iterator(DataIterator data, WeightIterator weight)
139  {
140    return WeightedIterator<DataIterator, WeightIterator>(data, weight);
141  }
142 
143
144  /**
145     Specialization for WeightedIterator
146   */
147  template <typename DataIterator, typename WeightIterator>
148  struct weighted_iterator_traits<WeightedIterator<DataIterator
149                                                   ,WeightIterator> >
150  {
151    /**
152       WeightedIterator is weighted
153     */
154    typedef weighted_iterator_tag type;
155  };
156
157  /**
158     Specialization for WeightedIterator
159   */
160  template <typename DataIterator, typename WeightIterator>
161  struct iterator_traits<WeightedIterator<DataIterator, WeightIterator> >
162  {
163  private:
164    typedef WeightedIterator<DataIterator,WeightIterator> WI;
165    typedef typename WI::data_iterator data_iterator;
166    typedef typename WI::weight_iterator weight_iterator;
167  public:
168    /**
169       data_reference is same reference of data_iterator_base
170     */
171    typedef typename 
172    std::iterator_traits<data_iterator>::reference data_reference;
173
174    /**
175       weight_reference is same reference of weight_iterator_base
176     */
177    typedef typename 
178    std::iterator_traits<weight_iterator>::reference weight_reference;
179
180    /**
181       \return dereferenced data_iterator
182     */
183    data_reference data(WI iter) const { return * iter.data_base(); }
184
185    /**
186       \return dereferenced weight_iterator
187     */
188    weight_reference weight(WI iter) const { return * iter.weight_base(); }
189  };
190
191}}} // of namespace utility, yat, and theplu
192
193#endif
Note: See TracBrowser for help on using the repository browser.