source: trunk/test/weighted_iterator_archetype.h @ 3314

Last change on this file since 3314 was 3314, checked in by Peter, 8 years ago

new test class: weighted_iterator_archetype. refs #803

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.9 KB
Line 
1#ifndef _theplu_yat_test_weighted_iterator_archetype
2#define _theplu_yat_test_weighted_iterator_archetype
3
4// $Id: weighted_iterator_archetype.h 3314 2014-09-13 06:22:10Z peter $
5
6/*
7  Copyright (C) 2014 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 <yat/utility/DataWeight.h>
26#include <yat/utility/DataWeightProxy.h>
27
28#include <boost/iterator/iterator_archetypes.hpp>
29#include <boost/iterator/iterator_concepts.hpp>
30
31namespace theplu {
32namespace yat {
33namespace test {
34
35  // argument to iterators that are not default constructible
36  struct ctor_arg {};
37
38  // perhaps the stuff below should live in its own namespace, since
39  // no one is really expected to use these classes other than the
40  // weighted_iterator_archetype class below.
41
42  struct bogus {};
43
44  template<class AccessCategory> struct Reference {};
45
46  template<>
47  struct Reference<boost::iterator_archetypes::readable_iterator_t>
48  {
49    typedef const utility::DataWeightProxy<const double*, const double*> type;
50  };
51
52
53  template<>
54  struct Reference<boost::iterator_archetypes::readable_writable_iterator_t>
55  {
56    typedef utility::DataWeightProxy<double*, double*> type;
57  };
58
59  template<class TraversalCategory> struct Difference {};
60
61  template<>
62  struct Difference<boost::incrementable_traversal_tag>
63  { typedef bogus type; };
64
65  template<>
66  struct Difference<boost::single_pass_traversal_tag>
67  { typedef bogus type; };
68
69  template<>
70  struct Difference<boost::forward_traversal_tag>
71  { typedef int type; };
72
73  template<>
74  struct Difference<boost::bidirectional_traversal_tag>
75  { typedef int type; };
76
77  template<>
78  struct Difference<boost::random_access_traversal_tag>
79  { typedef int type; };
80
81
82  /*
83    The purpose of this class is to complement
84    boost::iterator_archetype, which doesn't work well when the
85    value_type is DataWeight (weighted iterator) and reference is not
86    DataWeight&. In that case boost::iterator_archetype creates a
87    proxy class that doesn't work well with yat's machinery to detect
88    whether an iterator is weighted or not. Instead we should use this
89    class below for testing. It returns DataWeightProxy from operator*
90    and works as intended.
91
92    Template arguments:
93
94    AccessCategory: either
95    boost::iterator_archetypes::readable_iterator_t
96    (for const iterator) or
97    boost::iterator_archetypes::readable_writable_iterator_t
98    (for mutable iterator)
99
100    Only writable iterators are not allowed because a weighted
101    iterator must be readable in order to ensure that value_type is
102    defined.
103
104    TraversalCategory is one of the boost categories:
105    boost::incrementable_traversal_tag
106    boost::single_pass_traversal_tag
107    boost::forward_traversal_tag
108    boost::bidirectional_traversal_tag
109    boost::random_access_traversal_tag
110   */
111  template<typename AccessCategory, typename TraversalCategory>
112  class weighted_iterator_archetype
113    : public boost::iterator_facade<
114    weighted_iterator_archetype<AccessCategory, TraversalCategory>
115    , utility::DataWeight
116    , TraversalCategory
117    , typename Reference<AccessCategory>::type
118    , typename Difference<TraversalCategory>::type>
119  {
120    typedef weighted_iterator_archetype<AccessCategory, TraversalCategory> me;
121  public:
122    // constructors
123    weighted_iterator_archetype(void) { is_forward(TraversalCategory()); }
124    weighted_iterator_archetype(ctor_arg arg) {}
125
126    // Create an iterator from a mutable iterator, i.e., this is a
127    // copy constructor if if mutable, otherwise conversion from
128    // mutable to const iterator.
129    weighted_iterator_archetype(const weighted_iterator_archetype<boost::iterator_archetypes::readable_writable_iterator_t, TraversalCategory>& other)
130    {}
131
132  private:
133    friend class boost::iterator_core_access;
134
135    typename Reference<AccessCategory>::type
136    dereference(void) const
137    { return typename Reference<AccessCategory>::type(NULL, NULL); }
138
139    bool equal(const me& other) const
140    { is_single_pass(TraversalCategory()); return true; }
141    void increment(void) {}
142
143    // only for bidirectional iterators
144    void decrement(void)
145    { is_bidirectional(TraversalCategory()); }
146
147    // only for random access
148    int distance_to(const me& other) const
149    { is_random(TraversalCategory()); return 0; }
150
151    void advance(int) { is_random(TraversalCategory()); }
152
153    void is_single_pass(boost::single_pass_traversal_tag) const {}
154    void is_forward(boost::forward_traversal_tag) const {}
155    void is_bidirectional(boost::bidirectional_traversal_tag) const {}
156    void is_random(boost::random_access_traversal_tag) const {}
157
158   
159  };
160
161}}}
162#endif
Note: See TracBrowser for help on using the repository browser.