source: branches/0.14-stable/yat/utility/concept_check.h @ 3569

Last change on this file since 3569 was 3569, checked in by Peter, 6 years ago

std::iterator_traits<T>::value_type does not work on OSX when T is an
incrementable iterator (not single pass). As this must work for an
iterator that models concept Data Iterator, add single pass iterator
as an requirement, test for it in the concept check class (plus a few
more fixes) and turn off the test in
'test/weighted_iterator_archetype.cc'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
1#ifndef _theplu_yat_utility_concept_check_
2#define _theplu_yat_utility_concept_check_
3
4// $Id: concept_check.h 3569 2017-01-09 03:43:08Z peter $
5
6/*
7  Copyright (C) 2010, 2011, 2013, 2015, 2016, 2017 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// always include config first
26#include "config_public.h"
27
28#include "iterator_traits.h"
29#include "WeightedIteratorArchetype.h"
30
31#include <boost/concept_archetype.hpp>
32#include <boost/concept_check.hpp>
33#include <boost/iterator/iterator_archetypes.hpp>
34#include <boost/iterator/iterator_concepts.hpp>
35
36namespace theplu {
37namespace yat {
38namespace utility {
39
40  /**
41     \brief Concept check for \ref concept_container_2d
42
43     This class is intended to be used in a <a
44     href="\boost_url/concept_check/using_concept_check.htm">
45     BOOST_CONCEPT_ASSERT </a>
46
47     \code
48     template<class T>
49     void some_function(const T& t)
50     {
51     BOOST_CONCEPT_ASSERT((Container2D<T>));
52     ...
53     }
54     \endcode
55
56     \since New in yat 0.7
57  */
58  template <class T>
59  class Container2D
60  {
61  public:
62#ifdef YAT_HAVE_BOOST_CONCEPT_WITH_CONSTRUCTOR
63    /// Default constructor
64    Container2D(void) {}
65#endif
66
67    /// value_type
68    typedef typename T::value_type value_type;
69    /// const_reference
70    typedef typename T::const_reference const_reference;
71    /// const_iterator
72    typedef typename T::const_iterator const_iterator;
73    /// const_row_iterator
74    typedef typename T::const_row_iterator const_row_iterator;
75    /// const_column_iterator
76    typedef typename T::const_column_iterator const_column_iterator;
77
78    /**
79       \brief function doing the concept test
80     */
81    BOOST_CONCEPT_USAGE(Container2D)
82    {
83      const_iterator iter_ = t_.begin();
84      iter_ = t_.end();
85      const_row_iterator row_iter_ = t_.begin_row(0);
86      row_iter_ = t_.end_row(0);
87      const_column_iterator col_iter_ = t_.begin_column(0);
88      col_iter_ = t_.end_column(0);
89      const_reference r = t_(0,0);
90      value_ = r;
91      size_t n = t_.rows();
92      n = t_.columns();
93      some_func(n);
94      using boost_concepts::ReadableIterator;
95      BOOST_CONCEPT_ASSERT((ReadableIterator<const_iterator>));
96      BOOST_CONCEPT_ASSERT((ReadableIterator<const_row_iterator>));
97      BOOST_CONCEPT_ASSERT((ReadableIterator<const_column_iterator>));
98    }
99
100  private:
101    void some_func(size_t x) const {}
102    T t_;
103    value_type value_;
104  };
105
106  /**
107     \brief Concept check for \ref concept_mutable_container_2d
108
109     This class is intended to be used in a <a
110     href="\boost_url/concept_check/using_concept_check.htm">
111     BOOST_CONCEPT_ASSERT </a>
112
113     \code
114     template<class T>
115     void some_function(const T& t)
116     {
117     BOOST_CONCEPT_ASSERT((Mutable_Container2D<T>));
118     ...
119     }
120     \endcode
121
122     \since New in yat 0.7
123  */
124  template <class T>
125  class Mutable_Container2D : public Container2D<T>
126  {
127  public:
128    /// reference
129    typedef typename T::reference reference;
130    /// iterator
131    typedef typename T::iterator iterator;
132    /// row_iterator
133    typedef typename T::row_iterator row_iterator;
134    /// column_iterator
135    typedef typename T::column_iterator column_iterator;
136
137    /**
138       \brief function doing the concept test
139     */
140    BOOST_CONCEPT_USAGE(Mutable_Container2D)
141    {
142      iterator iter_ = t_.begin();
143      iter_ = t_.end();
144      row_iterator row_iter_ = t_.begin_row(0);
145      row_iter_ = t_.end_row(0);
146      column_iterator col_iter_ = t_.begin_column(0);
147      col_iter_ = t_.end_column(0);
148      reference r = t_(0,0);
149      t_(0,0) = r;
150      using boost::Mutable_RandomAccessIterator; // just to avoid long lines
151      BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<iterator>));
152      BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<row_iterator>));
153      BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<column_iterator>));
154    }
155  private:
156    T t_;
157  };
158
159
160  /**
161     \brief Concept check for \trivial_iterator
162
163     This class is intended to be used in a <a
164     href="\boost_url/concept_check/using_concept_check.htm">
165     BOOST_CONCEPT_ASSERT </a>
166
167     \code
168     template<class Iterator>
169     void some_function(const Iterator& it)
170     {
171     BOOST_CONCEPT_ASSERT((TrivialIterator<Iterator>));
172     ...
173     }
174     \endcode
175
176     \since New in yat 0.7
177  */
178  template <class T>
179  class TrivialIterator
180    : public boost::Assignable<T>
181    , public boost::EqualityComparable<T>
182    , public boost::DefaultConstructible<T>
183
184  {
185  public:
186    /// iterator_category
187    typedef typename std::iterator_traits<T>::iterator_category iterator_category;
188    /// value_type
189    typedef typename std::iterator_traits<T>::value_type value_type;
190    /// difference_type
191    typedef typename std::iterator_traits<T>::difference_type difference_type;
192    /// pointer
193    typedef typename std::iterator_traits<T>::pointer pointer;
194    /// reference
195    typedef typename std::iterator_traits<T>::reference reference;
196
197    /**
198       \brief function doing the concept test
199     */
200    BOOST_CONCEPT_USAGE(TrivialIterator)
201    {
202      T t;
203      value_ = *t;
204    }
205  private:
206    value_type value_;
207  };
208
209  /**
210     \brief Concept check for \ref concept_data_iterator
211
212     This class is intended to be used in a <a
213     href="\boost_url/concept_check/using_concept_check.htm">
214     BOOST_CONCEPT_ASSERT </a>
215
216     \code
217     template<class Iterator>
218     void some_function(const Iterator& it)
219     {
220     BOOST_CONCEPT_ASSERT((DataIteratorConcept<Iterator>));
221     ...
222     }
223     \endcode
224
225     \since New in yat 0.7
226  */
227  template <class T>
228  class DataIteratorConcept
229  {
230  public:
231    /// tag
232    typedef typename weighted_iterator_traits<T>::type tag;
233    /// value_type
234    typedef typename std::iterator_traits<T>::value_type value_type;
235
236    /**
237       \brief function doing the concept test
238     */
239    BOOST_CONCEPT_USAGE(DataIteratorConcept)
240    {
241      BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIterator<T>));
242      BOOST_CONCEPT_ASSERT((boost_concepts::SinglePassIterator<T>));
243      tag t;
244      constraints(t);
245    }
246  private:
247    void constraints(yat::utility::unweighted_iterator_tag t) const
248    { 
249      BOOST_CONCEPT_ASSERT((boost::Convertible<value_type, double>));
250    }
251
252    void constraints(yat::utility::weighted_iterator_tag t) const
253    {
254      BOOST_CONCEPT_ASSERT((boost::Convertible<value_type, DataWeight>));
255    }
256  };
257
258
259  /**
260     \brief Concept check for a \ref concept_distance
261
262     This class is intended to be used in a <a
263     href="\boost_url/concept_check/using_concept_check.htm">
264     BOOST_CONCEPT_ASSERT </a>
265
266     \code
267     template<class Distance>
268     void some_function(double x)
269     {
270     BOOST_CONCEPT_ASSERT((DistanceConcept<Distance>));
271     ...
272     }
273     \endcode
274
275     \since New in yat 0.7
276  */
277  template <class T>
278  class DistanceConcept : public boost::CopyConstructible<T>
279  {
280  public:
281    /**
282       \brief function doing the concept test
283     */
284    BOOST_CONCEPT_USAGE(DistanceConcept)
285    {
286      using boost::iterator_archetypes::readable_iterator_t;
287      using boost::forward_traversal_tag;
288      boost::iterator_archetype<double, readable_iterator_t,
289                                forward_traversal_tag> unweighted;
290      WeightedIteratorArchetype<readable_iterator_t, forward_traversal_tag>
291        weighted;
292      double d=0;
293      d += distance_(unweighted, unweighted, unweighted);
294      d += distance_(unweighted, unweighted, weighted);
295      d += distance_(weighted, weighted, unweighted);
296      d += distance_(weighted, weighted, weighted);
297      // avoid compiler warning
298      func(d);
299    }
300  private:
301    void func(double x) {}
302    T distance_;
303  };
304
305}}} // of namespace utility, yat, and theplu
306#endif
Note: See TracBrowser for help on using the repository browser.