DGtal  0.9.2
IteratorCirculatorTraits.h
1 
17 #pragma once
18 
29 #if defined(IteratorCirculatorTraits_RECURSES)
30 #error Recursive header files inclusion detected in IteratorCirculatorTraits.h
31 #else // defined(IteratorCirculatorTraits_RECURSES)
32 
33 #define IteratorCirculatorTraits_RECURSES
34 
35 #if !defined IteratorCirculatorTraits_h
36 
37 #define IteratorCirculatorTraits_h
38 
40 // Inclusions
41 #include<iterator>
42 #include<boost/iterator/iterator_categories.hpp>
43 #include<boost/iterator/iterator_facade.hpp>
45 
46 namespace DGtal
47 {
48 
50 // tag classes for type (either Iterator or Circulator)
51 struct IteratorType {};
52 struct CirculatorType {};
53 
55 // tag classes for traversal category (Foward, Bidirectional, RandomAccess)
56 // valid for both iterator and circulator
57 struct ForwardCategory {};
60 
62 namespace detail
63 {
64 
66 
75  template <typename IC>
77  {
78  typedef char yes[1];
79  typedef char no[2];
80 
81  template <typename C>
82  static yes& test(typename C::Type*);
83 
84  template <typename C>
85  static no& test(...);
86 
87  BOOST_STATIC_CONSTANT(bool, value = sizeof(test<IC>(0)) == sizeof(yes));
88  };
89 
91 
98  //default (for iterator type)
99  template <typename IC, typename ICType>
101  {
102  BOOST_STATIC_CONSTANT(bool, value = false);
103  };
104 
105  //specialization for circulator type
106  template <typename IC>
108  {
109  BOOST_STATIC_CONSTANT(bool, value = true);
110  };
111 
113 
125  //default (there is no nested type called 'Type')
126  template <typename IC, bool flagHasNestedTypeCalledType = false>
127  struct IsCirculator
128  {
129  BOOST_STATIC_CONSTANT(bool, value = false);
130  };
131 
132  //specialization if there is a nested type called 'Type'
133  template <typename IC>
134  struct IsCirculator<IC,true>
135  {
137  BOOST_STATIC_CONSTANT(bool, value = IsCirculatorHelper::value);
138  };
139 
140 } //namespace detail
141 
143 
150 template <typename IC>
152 {
154  BOOST_STATIC_CONSTANT(bool, value = IsCirculatorHelper::value);
155 };
156 
157 namespace detail
158 {
160 
168  template<bool b = false>
170  {
171  typedef IteratorType Type;
172  };
173  template<>
175  {
177  };
178 }//namespace detail
179 
181 
189 template<typename IC>
191 public:
193 };
194 
195 //NB. To add a third type of iterator (let's say 'ThirdType'),
196 //you should add a meta function 'IsThird' (like 'IsCirculator')
197 //and add a boolean template parameter in IteratorCirculatorTypeImpl
198 //so that IteratorCirculatorTypeImpl can be specialized to define
199 //the nested type 'Type' as 'ThirdType'.
200 
202 
211 //default
212 template <typename C>
214  typedef C Category;
215 };
216 
217 //for STL iterators
218 template <>
219 struct ToDGtalCategory<std::forward_iterator_tag> {
221 };
222 
223 template <>
224 struct ToDGtalCategory<std::bidirectional_iterator_tag> {
226 };
227 
228 template <>
229 struct ToDGtalCategory<std::random_access_iterator_tag> {
231 };
232 
233 //for boost traversal categories
234 template <>
235 struct ToDGtalCategory<boost::forward_traversal_tag> {
237 };
238 
239 template <>
240 struct ToDGtalCategory<boost::bidirectional_traversal_tag> {
242 };
243 
244 template <>
245 struct ToDGtalCategory<boost::random_access_traversal_tag> {
247 };
248 
249 
250 
251 
252 #if (((BOOST_VERSION /100000)==1) && ((BOOST_VERSION / 100 % 1000 )<57))
253  template <>
254  struct ToDGtalCategory<boost::detail::iterator_category_with_traversal<std::input_iterator_tag,boost::forward_traversal_tag> > {
255  typedef ForwardCategory Category;
256  };
257  template <>
258  struct ToDGtalCategory<boost::detail::iterator_category_with_traversal<std::input_iterator_tag,boost::bidirectional_traversal_tag> > {
259  typedef BidirectionalCategory Category;
260  };
261 
262  template <>
263  struct ToDGtalCategory<boost::detail::iterator_category_with_traversal<std::input_iterator_tag,boost::random_access_traversal_tag> > {
264  typedef RandomAccessCategory Category;
265  };
266 #else
267  template <>
268  struct ToDGtalCategory<boost::iterators::detail::iterator_category_with_traversal<std::input_iterator_tag,boost::forward_traversal_tag> > {
270  };
271  template <>
272  struct ToDGtalCategory<boost::iterators::detail::iterator_category_with_traversal<std::input_iterator_tag,boost::bidirectional_traversal_tag> > {
274  };
275 
276  template <>
277  struct ToDGtalCategory<boost::iterators::detail::iterator_category_with_traversal<std::input_iterator_tag,boost::random_access_traversal_tag> > {
279  };
280 #endif
281 
282 
284 
293 template <typename IC>
295 
296  typedef typename IteratorCirculatorType<IC>::Type
298 
299  typedef typename ToDGtalCategory
300  <typename boost::iterator_category<IC>::type>::Category
302 
303  typedef typename IC::value_type Value;
304  typedef typename IC::difference_type Difference;
305  typedef typename IC::pointer Pointer;
306  typedef typename IC::reference Reference;
307 
308 };
309 
310 template <class T>
312  typedef IteratorType Type;
314  typedef T Value;
315  typedef ptrdiff_t Difference;
316  typedef T* Pointer;
317  typedef T& Reference;
318 };
319 
320 template <class T>
321 struct IteratorCirculatorTraits<T const*>
322 {
323  typedef IteratorType Type;
325  typedef T Value;
326  typedef ptrdiff_t Difference;
327  typedef T const* Pointer;
328  typedef T const& Reference;
329 };
330 
331 } // namespace DGtal
332 
333 // //
335 
336 #endif // !defined IteratorCirculatorTraits_h
337 
338 #undef IteratorCirculatorTraits_RECURSES
339 #endif // else defined(IteratorCirculatorTraits_RECURSES)
Aim: Defines the Iterator or Circulator type as a nested type according to the value of b...
Definition: Boost.dox:28
BOOST_STATIC_CONSTANT(bool, value=IsCirculatorHelper::value)
static yes & test(typename C::Type *)
STL namespace.
Aim: Checks whether type IC is a circular or a classical iterator. Static value set to 'true' for a c...
Aim: Provides the type of IC as a nested type: either IteratorType or CirculatorType.
Aim: Checks whether type IC is a circular or a classical iterator. Static value set to 'true' for a c...
detail::IteratorCirculatorTypeImpl< IsCirculator< IC >::value >::Type Type
detail::IsCirculator< IC, detail::HasNestedTypeType< IC >::value > IsCirculatorHelper
Aim: Provides the DGtal category matching C {ForwardCategory,BidirectionalCategory,RandomAccessCategory}.
IsCirculatorFromType< IC, typename IC::Type > IsCirculatorHelper
Aim: Checks whether type IC has a nested type called 'Type' or not. NB: from en.wikipedia.org/wiki/Substitution_failure_is_not_an_error NB: to avoid various compiler issues, we use BOOST_STATIC_CONSTANT according to http://www.boost.org/development/int_const_guidelines.html.
ToDGtalCategory< typename boost::iterator_category< IC >::type >::Category Category
Aim: Provides nested types for both iterators and circulators: Type, Category, Value, Difference, Pointer and Reference.
BOOST_STATIC_CONSTANT(bool, value=sizeof(test< IC >(0))==sizeof(yes))
BOOST_STATIC_CONSTANT(bool, value=false)
BOOST_STATIC_CONSTANT(bool, value=false)
Aim: In order to check whether type IC is a circular or a classical iterator, the nested type called ...
DGtal is the top-level namespace which contains all DGtal functions and types.
IteratorCirculatorType< IC >::Type Type