1527 |
24 Sep 08 |
peter |
1 |
#ifndef _theplu_yat_utility_weighted_iterator_ |
1527 |
24 Sep 08 |
peter |
2 |
#define _theplu_yat_utility_weighted_iterator_ |
1527 |
24 Sep 08 |
peter |
3 |
|
1527 |
24 Sep 08 |
peter |
// $Id$ |
1527 |
24 Sep 08 |
peter |
5 |
|
1527 |
24 Sep 08 |
peter |
6 |
/* |
3459 |
21 Jan 16 |
peter |
Copyright (C) 2008, 2009, 2010, 2016 Peter Johansson |
1527 |
24 Sep 08 |
peter |
8 |
|
1527 |
24 Sep 08 |
peter |
This file is part of the yat library, http://dev.thep.lu.se/yat |
1527 |
24 Sep 08 |
peter |
10 |
|
1527 |
24 Sep 08 |
peter |
The yat library is free software; you can redistribute it and/or |
1527 |
24 Sep 08 |
peter |
modify it under the terms of the GNU General Public License as |
1527 |
24 Sep 08 |
peter |
published by the Free Software Foundation; either version 3 of the |
1527 |
24 Sep 08 |
peter |
License, or (at your option) any later version. |
1527 |
24 Sep 08 |
peter |
15 |
|
1527 |
24 Sep 08 |
peter |
The yat library is distributed in the hope that it will be useful, |
1527 |
24 Sep 08 |
peter |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
1527 |
24 Sep 08 |
peter |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1527 |
24 Sep 08 |
peter |
General Public License for more details. |
1527 |
24 Sep 08 |
peter |
20 |
|
1527 |
24 Sep 08 |
peter |
You should have received a copy of the GNU General Public License |
1527 |
24 Sep 08 |
peter |
along with yat. If not, see <http://www.gnu.org/licenses/>. |
1527 |
24 Sep 08 |
peter |
23 |
*/ |
1527 |
24 Sep 08 |
peter |
24 |
|
1541 |
30 Sep 08 |
peter |
25 |
#include "DataWeight.h" |
1541 |
30 Sep 08 |
peter |
26 |
#include "DataWeightProxy.h" |
1537 |
26 Sep 08 |
peter |
27 |
|
3459 |
21 Jan 16 |
peter |
28 |
#include <boost/iterator/is_readable_iterator.hpp> |
1531 |
24 Sep 08 |
peter |
29 |
#include <boost/iterator/iterator_facade.hpp> |
3459 |
21 Jan 16 |
peter |
30 |
#include <boost/mpl/and.hpp> |
3459 |
21 Jan 16 |
peter |
31 |
#include <boost/mpl/bool.hpp> |
3459 |
21 Jan 16 |
peter |
32 |
#include <boost/mpl/eval_if.hpp> |
3459 |
21 Jan 16 |
peter |
33 |
#include <boost/type_traits/is_convertible.hpp> |
3459 |
21 Jan 16 |
peter |
34 |
#include <boost/utility/enable_if.hpp> |
1531 |
24 Sep 08 |
peter |
35 |
|
1532 |
24 Sep 08 |
peter |
36 |
#include <iterator> |
1532 |
24 Sep 08 |
peter |
37 |
|
1527 |
24 Sep 08 |
peter |
38 |
namespace theplu { |
1527 |
24 Sep 08 |
peter |
39 |
namespace yat { |
1527 |
24 Sep 08 |
peter |
40 |
namespace utility { |
1527 |
24 Sep 08 |
peter |
41 |
|
3459 |
21 Jan 16 |
peter |
42 |
namespace detail { |
3459 |
21 Jan 16 |
peter |
43 |
namespace weighted_iterator { |
3459 |
21 Jan 16 |
peter |
44 |
|
3459 |
21 Jan 16 |
peter |
/// Determines which traversal concept (see boost iterator |
3459 |
21 Jan 16 |
peter |
/// traversal concept) the WeightedIterator is marked as. The |
3459 |
21 Jan 16 |
peter |
/// class looks at iterator_traversal from DataIterator and |
3459 |
21 Jan 16 |
peter |
/// WeightIterator and returns the simplest of them (e.g. if |
3459 |
21 Jan 16 |
peter |
/// DataIterator is bidirectional_iterator and WeightIterator is |
3459 |
21 Jan 16 |
peter |
/// forward_iterator, then forward_iterator will be returned). |
3459 |
21 Jan 16 |
peter |
51 |
template<typename DataIterator, typename WeightIterator> |
3459 |
21 Jan 16 |
peter |
52 |
class Traversal |
3459 |
21 Jan 16 |
peter |
53 |
{ |
3459 |
21 Jan 16 |
peter |
54 |
typedef typename boost::iterator_traversal<DataIterator>::type T1; |
3459 |
21 Jan 16 |
peter |
55 |
typedef typename boost::iterator_traversal<WeightIterator>::type T2; |
3459 |
21 Jan 16 |
peter |
56 |
public: |
3459 |
21 Jan 16 |
peter |
/// \return the least advanced type |
3459 |
21 Jan 16 |
peter |
/// if T1 is convertible to T2 (T1 is more advanced) return T2 |
3459 |
21 Jan 16 |
peter |
59 |
typedef typename boost::mpl::if_< |
3459 |
21 Jan 16 |
peter |
60 |
boost::is_convertible<T1, T2>, T2, T1>::type type; |
3459 |
21 Jan 16 |
peter |
61 |
}; |
3459 |
21 Jan 16 |
peter |
62 |
|
3459 |
21 Jan 16 |
peter |
63 |
} // end of weighted_iterator namespace |
3459 |
21 Jan 16 |
peter |
64 |
} // end of detail namespace |
3459 |
21 Jan 16 |
peter |
65 |
|
1527 |
24 Sep 08 |
peter |
66 |
/** |
1537 |
26 Sep 08 |
peter |
\brief WeightedIterator |
2202 |
21 Feb 10 |
peter |
68 |
|
2202 |
21 Feb 10 |
peter |
Adaptor enabling to make two unweighted iterators to behave like |
2375 |
13 Dec 10 |
peter |
a \ref concept_weighted_iterator. The data part corresponds to |
2375 |
13 Dec 10 |
peter |
the data_iterator and the weight corresponds to the |
2375 |
13 Dec 10 |
peter |
weight_iterator. |
2375 |
13 Dec 10 |
peter |
73 |
|
3459 |
21 Jan 16 |
peter |
\c WeightedIterator is a \ref concept_weighted_iterator and its |
3459 |
21 Jan 16 |
peter |
\c value_type is \c DataWeight. However due to the nature of this |
3459 |
21 Jan 16 |
peter |
adaptor there are no physical \c DataWeight in memory that \c |
3459 |
21 Jan 16 |
peter |
WeightedIterator points to, so its \c reference_type is not \c |
3459 |
21 Jan 16 |
peter |
DataWeight& but a \c DataWeightProxy. As a proxy is used, which |
3459 |
21 Jan 16 |
peter |
is not allowed in a \forward_iterator, WeightedIterator is a |
3459 |
21 Jan 16 |
peter |
\input_iterator. |
2375 |
13 Dec 10 |
peter |
81 |
|
3461 |
22 Jan 16 |
peter |
Although WeightedIterator is tagged a \input_iterator, more |
3461 |
22 Jan 16 |
peter |
advanced traversal is implemented if supported by underlying |
3461 |
22 Jan 16 |
peter |
iterators. If underlying iterators support random access |
3461 |
22 Jan 16 |
peter |
traversal, e.g., WeightedIterator supports it as well and |
3461 |
22 Jan 16 |
peter |
boost::iterator_traversal<T>::type is set appropriately (see |
3461 |
22 Jan 16 |
peter |
\random_access_traversal_iterator). |
3461 |
22 Jan 16 |
peter |
88 |
|
3461 |
22 Jan 16 |
peter |
Type Requirements: |
3461 |
22 Jan 16 |
peter |
- \c DataWeightProxy<DataIterator, WeightIterator> is a valid |
3459 |
21 Jan 16 |
peter |
expression. |
1527 |
24 Sep 08 |
peter |
92 |
*/ |
1527 |
24 Sep 08 |
peter |
93 |
template<typename DataIterator, typename WeightIterator> |
1527 |
24 Sep 08 |
peter |
94 |
class WeightedIterator |
1531 |
24 Sep 08 |
peter |
95 |
: public boost::iterator_facade< |
1531 |
24 Sep 08 |
peter |
96 |
WeightedIterator<DataIterator, WeightIterator>, |
2375 |
13 Dec 10 |
peter |
97 |
DataWeight, |
3459 |
21 Jan 16 |
peter |
98 |
typename |
3459 |
21 Jan 16 |
peter |
99 |
detail::weighted_iterator::Traversal<DataIterator, WeightIterator>::type, |
1537 |
26 Sep 08 |
peter |
100 |
DataWeightProxy<DataIterator, WeightIterator> > |
3457 |
12 Jan 16 |
peter |
101 |
|
1527 |
24 Sep 08 |
peter |
102 |
{ |
1527 |
24 Sep 08 |
peter |
103 |
public: |
1527 |
24 Sep 08 |
peter |
104 |
/** |
1538 |
27 Sep 08 |
peter |
\brief DataIterator |
1538 |
27 Sep 08 |
peter |
106 |
*/ |
1543 |
01 Oct 08 |
peter |
107 |
typedef DataIterator data_iterator; |
1538 |
27 Sep 08 |
peter |
108 |
|
1538 |
27 Sep 08 |
peter |
109 |
/** |
1538 |
27 Sep 08 |
peter |
\brief DataIterator |
1538 |
27 Sep 08 |
peter |
111 |
*/ |
1543 |
01 Oct 08 |
peter |
112 |
typedef WeightIterator weight_iterator; |
1538 |
27 Sep 08 |
peter |
113 |
|
1538 |
27 Sep 08 |
peter |
114 |
/** |
2202 |
21 Feb 10 |
peter |
\brief Default Constructor. |
2202 |
21 Feb 10 |
peter |
116 |
|
2202 |
21 Feb 10 |
peter |
Created iterator is not dereferencable |
2202 |
21 Feb 10 |
peter |
118 |
|
2202 |
21 Feb 10 |
peter |
\since New in yat 0.6 |
2202 |
21 Feb 10 |
peter |
120 |
*/ |
2202 |
21 Feb 10 |
peter |
121 |
WeightedIterator(void) |
2202 |
21 Feb 10 |
peter |
122 |
{} |
2202 |
21 Feb 10 |
peter |
123 |
|
2202 |
21 Feb 10 |
peter |
124 |
/** |
1527 |
24 Sep 08 |
peter |
\brief Constructor |
1527 |
24 Sep 08 |
peter |
126 |
*/ |
1527 |
24 Sep 08 |
peter |
127 |
WeightedIterator(DataIterator d, WeightIterator w) |
1527 |
24 Sep 08 |
peter |
128 |
: d_iter_(d), w_iter_(w) |
1527 |
24 Sep 08 |
peter |
129 |
{} |
3457 |
12 Jan 16 |
peter |
130 |
|
1538 |
27 Sep 08 |
peter |
131 |
/** |
1538 |
27 Sep 08 |
peter |
\return const reference to underlying data iterator |
1538 |
27 Sep 08 |
peter |
133 |
*/ |
1538 |
27 Sep 08 |
peter |
134 |
const DataIterator& data_base(void) const { return d_iter_; } |
1527 |
24 Sep 08 |
peter |
135 |
|
1527 |
24 Sep 08 |
peter |
136 |
/** |
1538 |
27 Sep 08 |
peter |
\return const reference to underlying weight iterator |
1538 |
27 Sep 08 |
peter |
138 |
*/ |
1538 |
27 Sep 08 |
peter |
139 |
const WeightIterator& weight_base(void) const { return w_iter_; } |
1538 |
27 Sep 08 |
peter |
140 |
|
1538 |
27 Sep 08 |
peter |
141 |
/** |
1537 |
26 Sep 08 |
peter |
\brief element operator |
1537 |
26 Sep 08 |
peter |
143 |
*/ |
1537 |
26 Sep 08 |
peter |
144 |
DataWeightProxy<DataIterator, WeightIterator> operator[](int n) const |
1537 |
26 Sep 08 |
peter |
145 |
{ |
3457 |
12 Jan 16 |
peter |
146 |
return DataWeightProxy<DataIterator, WeightIterator>(d_iter_+n, |
3457 |
12 Jan 16 |
peter |
147 |
w_iter_+n); |
3457 |
12 Jan 16 |
peter |
148 |
} |
1537 |
26 Sep 08 |
peter |
149 |
|
3457 |
12 Jan 16 |
peter |
150 |
|
1537 |
26 Sep 08 |
peter |
151 |
/** |
3457 |
12 Jan 16 |
peter |
\brief Conversion constructor. |
3457 |
12 Jan 16 |
peter |
153 |
|
1527 |
24 Sep 08 |
peter |
Create a WeightIterator<Base> from a |
1527 |
24 Sep 08 |
peter |
WeightIterator<B2>. Possible if B2 is convertible to a |
1527 |
24 Sep 08 |
peter |
Base. Constructor allows implicit conversions such as iterator |
1527 |
24 Sep 08 |
peter |
to const_iterator. |
1527 |
24 Sep 08 |
peter |
158 |
*/ |
1527 |
24 Sep 08 |
peter |
159 |
template<typename D2, typename W2> |
1527 |
24 Sep 08 |
peter |
160 |
WeightedIterator(WeightedIterator<D2, W2> other, |
1527 |
24 Sep 08 |
peter |
161 |
typename boost::enable_if_convertible<D2,DataIterator>::type* = 0, |
1527 |
24 Sep 08 |
peter |
162 |
typename boost::enable_if_convertible<W2,WeightIterator>::type* = 0) |
1538 |
27 Sep 08 |
peter |
163 |
: d_iter_(other.data_base()), w_iter_(other.weight_base()) {} |
1527 |
24 Sep 08 |
peter |
164 |
|
1538 |
27 Sep 08 |
peter |
165 |
|
1527 |
24 Sep 08 |
peter |
166 |
private: |
1531 |
24 Sep 08 |
peter |
167 |
friend class boost::iterator_core_access; |
1531 |
24 Sep 08 |
peter |
168 |
|
1527 |
24 Sep 08 |
peter |
169 |
DataIterator d_iter_; |
1527 |
24 Sep 08 |
peter |
170 |
WeightIterator w_iter_; |
3457 |
12 Jan 16 |
peter |
171 |
|
1532 |
24 Sep 08 |
peter |
172 |
void advance(size_t n) |
1532 |
24 Sep 08 |
peter |
173 |
{ std::advance(d_iter_, n); std::advance(w_iter_, n); } |
1532 |
24 Sep 08 |
peter |
174 |
|
1532 |
24 Sep 08 |
peter |
175 |
void decrement(void) { --d_iter_; --w_iter_; } |
3457 |
12 Jan 16 |
peter |
176 |
|
3457 |
12 Jan 16 |
peter |
177 |
typename std::iterator_traits<DataIterator>::difference_type |
1532 |
24 Sep 08 |
peter |
178 |
distance_to(const WeightedIterator& other) const |
1532 |
24 Sep 08 |
peter |
179 |
{ return std::distance(d_iter_, other.d_iter_); } |
1532 |
24 Sep 08 |
peter |
180 |
|
3457 |
12 Jan 16 |
peter |
181 |
utility::DataWeightProxy<DataIterator, WeightIterator> |
3457 |
12 Jan 16 |
peter |
182 |
dereference(void) const |
3457 |
12 Jan 16 |
peter |
183 |
{ return DataWeightProxy<DataIterator, WeightIterator>(d_iter_, |
3457 |
12 Jan 16 |
peter |
184 |
w_iter_); |
1537 |
26 Sep 08 |
peter |
185 |
} |
1531 |
24 Sep 08 |
peter |
186 |
|
1532 |
24 Sep 08 |
peter |
187 |
bool equal(const WeightedIterator& other) const |
1532 |
24 Sep 08 |
peter |
188 |
{ return d_iter_==other.d_iter_ && w_iter_==other.w_iter_; } |
1532 |
24 Sep 08 |
peter |
189 |
|
1531 |
24 Sep 08 |
peter |
190 |
void increment(void) { ++d_iter_; ++w_iter_; } |
1531 |
24 Sep 08 |
peter |
191 |
|
1527 |
24 Sep 08 |
peter |
192 |
}; |
1527 |
24 Sep 08 |
peter |
193 |
|
1527 |
24 Sep 08 |
peter |
194 |
/** |
1527 |
24 Sep 08 |
peter |
\brief convenient function to create WeightedIterator |
1527 |
24 Sep 08 |
peter |
196 |
|
1527 |
24 Sep 08 |
peter |
Convenient function in same fashion as std::make_pair. |
1887 |
31 Mar 09 |
peter |
198 |
|
1887 |
31 Mar 09 |
peter |
\relates WeightedIterator |
1527 |
24 Sep 08 |
peter |
200 |
*/ |
1527 |
24 Sep 08 |
peter |
201 |
template<typename DataIterator, typename WeightIterator> |
3457 |
12 Jan 16 |
peter |
202 |
WeightedIterator<DataIterator, WeightIterator> |
1527 |
24 Sep 08 |
peter |
203 |
weighted_iterator(DataIterator data, WeightIterator weight) |
1527 |
24 Sep 08 |
peter |
204 |
{ |
1527 |
24 Sep 08 |
peter |
205 |
return WeightedIterator<DataIterator, WeightIterator>(data, weight); |
1527 |
24 Sep 08 |
peter |
206 |
} |
3457 |
12 Jan 16 |
peter |
207 |
|
1527 |
24 Sep 08 |
peter |
208 |
}}} // of namespace utility, yat, and theplu |
1527 |
24 Sep 08 |
peter |
209 |
|
1527 |
24 Sep 08 |
peter |
210 |
#endif |