Changeset 1541


Ignore:
Timestamp:
Sep 30, 2008, 7:40:41 PM (13 years ago)
Author:
Peter
Message:

fixes #445 so iterator_traits detects when value_type is DataWeight?
and return weighted_iterator_tag. Also weighted_iterator_traits
recognize some normal cases; when reference_type is DataWeight?& or
const DataWeight?& weighted behaviour is performed.

Fixed some incorrect inclusion in WeightedIterator? and removed debug
code in StrideIterator?.

Location:
trunk/yat/utility
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/yat/utility/StrideIterator.h

    r1490 r1541  
    2323  along with yat. If not, see <http://www.gnu.org/licenses/>.
    2424*/
    25 
    26 // debug
    27 #include <iostream>
    2825
    2926#include "iterator_traits.h"
  • trunk/yat/utility/WeightedIterator.h

    r1538 r1541  
    2323*/
    2424
    25 #include <DataWeight.h>
    26 #include <DataWeightProxy.h>
     25#include "DataWeight.h"
     26#include "DataWeightProxy.h"
    2727
    2828#include <boost/iterator/iterator_facade.hpp>
  • trunk/yat/utility/iterator_traits.h

    r1487 r1541  
    2727
    2828#include <iterator>
    29 #include <vector>
    3029
    3130namespace theplu {
     
    4746  struct weighted_iterator_tag {};
    4847
     48
     49  /**
     50     \internal
     51
     52     used in weighted_iterator_traits
     53  */
     54  template <typename T>
     55  struct weighted_iterator_traits_detail {
     56    /**
     57       default is a iterator unweighted
     58    */
     59    typedef unweighted_iterator_tag type;
     60  }; 
     61
     62  /**
     63      \internal
     64
     65      specialization for iterators with value type DataWeight
     66  */
     67  template <>
     68  struct weighted_iterator_traits_detail<DataWeight> {
     69    /**
     70       Iterators with value type DataWeight is weighted
     71     */
     72    typedef weighted_iterator_tag type;
     73  }; 
     74
    4975  /**
    50       All iterators default to unweighted type. If you want your
    51       iterator to behave as weighted, you need to provide a
    52       specialization.
    53 
    54       \see Iterator and StrideIterator
     76      Metafunction to decide whether an iterator is weighted or
     77      non-weighted. This (default) implementation return unweighted,
     78      unless value_type of iterator is DataWeight in which case
     79      weighted is returned.
    5580  */
    5681  template <class T>
    57   struct weighted_iterator_traits {
    58   /**
    59       All iterators default to unweighted type
    60   */
    61     typedef unweighted_iterator_tag type;
    62   };
    63 
    64   /**
    65      Specialization for std::vector<DataWeight>::iterator
    66    */
    67   template<>
    68   struct weighted_iterator_traits<std::vector<DataWeight>::iterator> {
    69     /**
    70        iterator to vector<DataWeight> is weighted
    71     */
    72     typedef weighted_iterator_tag type;
    73   };
    74 
    75 
    76   /**
    77      Specialization for std::vector<DataWeight>::const_iterator
    78    */
    79   template<>
    80   struct weighted_iterator_traits<std::vector<DataWeight>::const_iterator> {
    81     /**
    82        const_iterator to vector<DataWeight> is weighted
    83     */
    84     typedef weighted_iterator_tag type;
     82  struct weighted_iterator_traits
     83  {
     84  private:
     85    typedef typename std::iterator_traits<T>::value_type value;
     86  public:
     87    /**
     88       \return weighted if value_type is DataWeight
     89     */
     90    typedef typename weighted_iterator_traits_detail<value>::type type;
    8591  };
    8692
     
    158164
    159165  /**
    160      \brief traits to make unweighted iterator work as in a weighted
    161 
    162      This class must be implemented for every iterator that can be weighted.
    163 
    164      \see StrideIterator and Container2DIterator
     166     \internal
     167
     168     This class is used in iterator_traits to separate different cases.
     169
     170     This the default implementation that could be used for unweighted
     171     iterators.
     172   */
     173  template <typename Iter, typename T >
     174  struct iterator_traits_detail
     175  {
     176    /**
     177       for unweighted data_reference is reference
     178    */
     179    typedef typename std::iterator_traits<Iter>::reference data_reference;
     180
     181    /**
     182       for unweighted weight_reference is a double
     183    */
     184    typedef double weight_reference;
     185
     186    /**
     187       Constructor just checking that iterator is unweighted
     188    */
     189    iterator_traits_detail(void)
     190    { check_iterator_is_unweighted(typename
     191                                   weighted_iterator_traits<Iter>::type());
     192    }
     193   
     194    /**
     195       \return * \a iter
     196    */
     197    data_reference data(Iter iter) const { return *iter; }
     198
     199    /**
     200       \return 1.0
     201    */
     202    weight_reference weight(Iter iter) const { return 1.0; }
     203  };
     204
     205
     206  /**
     207     specialization for weighted iterator with reference DataWeight&
     208   */
     209  template <typename Iter>
     210  struct iterator_traits_detail<Iter, DataWeight&> {
     211    /**
     212       for mutable weighted iterator data_reference is double&
     213    */
     214    typedef double& data_reference;
     215
     216    /**
     217       for mutable weighted iterator weight_reference is double&
     218    */
     219    typedef double& weight_reference;
     220
     221    /**
     222       \return reference to data of iterator
     223    */
     224    data_reference data(Iter iter) const { return iter->data(); }
     225
     226    /**
     227       \return reference to weight of iterator
     228    */
     229    weight_reference weight(Iter iter) const { return iter->weight(); }
     230  };
     231
     232
     233  /**
     234     specialization for weighted iterator with reference const DataWeight&
     235   */
     236  template <typename Iter>
     237  struct iterator_traits_detail<Iter, const DataWeight&> {
     238    /**
     239       for read-only weighted iterator data_reference is const double&
     240    */
     241    typedef const double& data_reference;
     242
     243    /**
     244       for read-only weighted iterator data_reference is const double&
     245    */
     246    typedef const double& weight_reference;
     247
     248    /**
     249       \return const reference to data of iterator
     250    */
     251    data_reference data(Iter iter) const { return iter->data(); }
     252
     253    /**
     254       \return const reference to weight of iterator
     255    */
     256    weight_reference weight(Iter iter) const { return iter->weight(); }
     257  };
     258
     259
     260  /**
     261     The purpose of this class is to allow polymorphism between
     262     weighted and unweighted iterators. It allows to access data and
     263     weight for both weighted and unweighted iterators.
     264
     265     This class works for unweighted iterators as well as weighted
     266     iterators as long as they have reference type DataWeight& or
     267     const DataWeight&.
     268
     269     For others, such as WeightedIterator for which reference type is
     270     a proxy class, this class should be specialized. For adaptors
     271     that have an underlying iterator (e.g. StrideIterator), this
     272     class should be specialized, so the class also works when the
     273     underlying is an iterator that is not overed by this class
     274     e.g. WeightedIterator.
    165275   */
    166   template <class Iter>
     276  template <typename Iter>
    167277  struct iterator_traits {
    168     /**
    169        \brief Default constructor
    170 
    171        Does nothing but check that Iter is unweighted (at compile time).
    172      */
    173     iterator_traits(void)
    174     {
    175       check_iterator_is_unweighted(typename weighted_iterator_traits<Iter>::type()); }
    176 
    177     /**
    178        An unweighted iterator has data_reference = reference
    179      */
    180     typedef typename std::iterator_traits<Iter>::reference data_reference;
    181 
    182     /**
    183        An unweighted iterator has a weight = 1.0 and since this is a
    184        temporary it is returned by value and weight_reference is double
    185      */
    186     typedef double weight_reference;
    187 
    188     /**
    189        \return data that is *iter
     278  private:
     279    typedef typename std::iterator_traits<Iter>::reference reference;
     280    typedef iterator_traits_detail<Iter, reference> traits;
     281  public:
     282    /**
     283       data_reference (type returned by data(void) is determined by
     284       iterator_traits_detail
     285     */
     286    typedef typename traits::data_reference data_reference;
     287
     288    /**
     289       data_reference (type returned by data(void) is determined by
     290       iterator_traits_detail
     291     */
     292    typedef typename traits::weight_reference weight_reference;
     293
     294    /**
     295       \return data
    190296    */
    191297    data_reference data(Iter iter) const
    192     { check_iterator_is_unweighted(iter); return *iter; }
    193 
    194     /**
    195        \return 1.0
    196     */
     298    { return traits().data(iter); }
     299
     300    /**
     301       \return
     302     */
    197303    weight_reference weight(Iter iter) const
    198     { check_iterator_is_unweighted(iter); return 1.0; }
    199 
    200   };
    201 
    202 
    203   /**
    204      Specialization for std::vector<DataWeight>::iterator
    205    */
    206   template <>
    207   struct iterator_traits<std::vector<DataWeight>::iterator> {
    208     /**
    209        mutable iterator
    210      */
    211     typedef double& data_reference;
    212 
    213     /**
    214        mutable iterator
    215      */
    216     typedef double& weight_reference;
    217 
    218     /**
    219        \return data using DataWeight::data()
    220     */
    221     data_reference data(std::vector<DataWeight>::iterator iter) const
    222     { return iter->data(); }
    223 
    224     /**
    225        \return weight using DataWeight::weight()
    226     */
    227     weight_reference weight(std::vector<DataWeight>::iterator iter) const
    228     { return iter->weight(); }
    229 
    230   };
    231 
    232 
    233   /**
    234      Specialization for std::vector<DataWeight>::const_iterator
    235    */
    236   template <>
    237   struct iterator_traits<std::vector<DataWeight>::const_iterator> {
    238     /**
    239        const iterator
    240      */
    241     typedef const double& data_reference;
    242 
    243     /**
    244        const iterator
    245      */
    246     typedef const double& weight_reference;
    247 
    248     /**
    249        \return data using DataWeight::data()
    250     */
    251     data_reference data(std::vector<DataWeight>::iterator iter) const
    252     { return iter->data(); }
    253 
    254     /**
    255        \return weight using DataWeight::weight()
    256     */
    257     weight_reference weight(std::vector<DataWeight>::iterator iter) const
    258     { return iter->weight(); }
    259 
    260   };
     304    { return traits().weight(iter); }
     305
     306  };
     307
    261308
    262309}}} // of namespace utility, yat, and theplu
Note: See TracChangeset for help on using the changeset viewer.