yat/utility/WeightedIterator.h

Code
Comments
Other
Rev Date Author Line
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 4 // $Id$
1527 24 Sep 08 peter 5
1527 24 Sep 08 peter 6 /*
3459 21 Jan 16 peter 7   Copyright (C) 2008, 2009, 2010, 2016 Peter Johansson
1527 24 Sep 08 peter 8
1527 24 Sep 08 peter 9   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 11   The yat library is free software; you can redistribute it and/or
1527 24 Sep 08 peter 12   modify it under the terms of the GNU General Public License as
1527 24 Sep 08 peter 13   published by the Free Software Foundation; either version 3 of the
1527 24 Sep 08 peter 14   License, or (at your option) any later version.
1527 24 Sep 08 peter 15
1527 24 Sep 08 peter 16   The yat library is distributed in the hope that it will be useful,
1527 24 Sep 08 peter 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
1527 24 Sep 08 peter 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1527 24 Sep 08 peter 19   General Public License for more details.
1527 24 Sep 08 peter 20
1527 24 Sep 08 peter 21   You should have received a copy of the GNU General Public License
1527 24 Sep 08 peter 22   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 45       /// Determines which traversal concept (see boost iterator
3459 21 Jan 16 peter 46       /// traversal concept) the WeightedIterator is marked as. The
3459 21 Jan 16 peter 47       /// class looks at iterator_traversal from DataIterator and
3459 21 Jan 16 peter 48       /// WeightIterator and returns the simplest of them (e.g. if
3459 21 Jan 16 peter 49       /// DataIterator is bidirectional_iterator and WeightIterator is
3459 21 Jan 16 peter 50       /// 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 57         /// \return the least advanced type
3459 21 Jan 16 peter 58         /// 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 67      \brief WeightedIterator
2202 21 Feb 10 peter 68
2202 21 Feb 10 peter 69      Adaptor enabling to make two unweighted iterators to behave like
2375 13 Dec 10 peter 70      a \ref concept_weighted_iterator. The data part corresponds to
2375 13 Dec 10 peter 71      the data_iterator and the weight corresponds to the
2375 13 Dec 10 peter 72      weight_iterator.
2375 13 Dec 10 peter 73
3459 21 Jan 16 peter 74      \c WeightedIterator is a \ref concept_weighted_iterator and its
3459 21 Jan 16 peter 75      \c value_type is \c DataWeight. However due to the nature of this
3459 21 Jan 16 peter 76      adaptor there are no physical \c DataWeight in memory that \c
3459 21 Jan 16 peter 77      WeightedIterator points to, so its \c reference_type is not \c
3459 21 Jan 16 peter 78      DataWeight& but a \c DataWeightProxy. As a proxy is used, which
3459 21 Jan 16 peter 79      is not allowed in a \forward_iterator, WeightedIterator is a
3459 21 Jan 16 peter 80      \input_iterator.
2375 13 Dec 10 peter 81
3461 22 Jan 16 peter 82      Although WeightedIterator is tagged a \input_iterator, more
3461 22 Jan 16 peter 83      advanced traversal is implemented if supported by underlying
3461 22 Jan 16 peter 84      iterators. If underlying iterators support random access
3461 22 Jan 16 peter 85      traversal, e.g., WeightedIterator supports it as well and
3461 22 Jan 16 peter 86      boost::iterator_traversal<T>::type is set appropriately (see
3461 22 Jan 16 peter 87      \random_access_traversal_iterator).
3461 22 Jan 16 peter 88
3461 22 Jan 16 peter 89      Type Requirements:
3461 22 Jan 16 peter 90      - \c DataWeightProxy<DataIterator, WeightIterator> is a valid
3459 21 Jan 16 peter 91      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 105        \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 110        \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 115        \brief Default Constructor.
2202 21 Feb 10 peter 116
2202 21 Feb 10 peter 117        Created iterator is not dereferencable
2202 21 Feb 10 peter 118
2202 21 Feb 10 peter 119        \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 125        \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 132        \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 137        \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 142        \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 152        \brief Conversion constructor.
3457 12 Jan 16 peter 153
1527 24 Sep 08 peter 154        Create a WeightIterator<Base> from a
1527 24 Sep 08 peter 155        WeightIterator<B2>. Possible if B2 is convertible to a
1527 24 Sep 08 peter 156        Base. Constructor allows implicit conversions such as iterator
1527 24 Sep 08 peter 157        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 195      \brief convenient function to create WeightedIterator
1527 24 Sep 08 peter 196
1527 24 Sep 08 peter 197      Convenient function in same fashion as std::make_pair.
1887 31 Mar 09 peter 198
1887 31 Mar 09 peter 199      \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