source: trunk/test/weighted_iterator_archetype.h @ 3315

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

added inclusion of boost iterator_facade header. refs #803.

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