yat  0.14.5pre
iterator_traits.h
1 #ifndef _theplu_yat_utility_iterator_traits_
2 #define _theplu_yat_utility_iterator_traits_
3 
4 // $Id: iterator_traits.h 3550 2017-01-03 05:41:02Z peter $
5 
6 /*
7  Copyright (C) 2007 Jari Häkkinen, Peter Johansson
8  Copyright (C) 2008 Jari Häkkinen, Peter Johansson, Markus Ringnér
9  Copyright (C) 2010, 2011, 2014, 2016 Peter Johansson
10 
11  This file is part of the yat library, http://dev.thep.lu.se/yat
12 
13  The yat library is free software; you can redistribute it and/or
14  modify it under the terms of the GNU General Public License as
15  published by the Free Software Foundation; either version 3 of the
16  License, or (at your option) any later version.
17 
18  The yat library is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with yat. If not, see <http://www.gnu.org/licenses/>.
25 */
26 
27 #include "DataWeight.h"
28 
29 #include <boost/iterator/iterator_traits.hpp>
30 #include <boost/mpl/logical.hpp>
31 #include <boost/type_traits/is_const.hpp>
32 #include <boost/type_traits/is_convertible.hpp>
33 #include <boost/type_traits/is_same.hpp>
34 #include <boost/type_traits/remove_reference.hpp>
35 #include <boost/utility/enable_if.hpp>
36 
37 #include <iterator>
38 
39 namespace theplu {
40 namespace yat {
41 namespace utility {
42 
48 
56 
57 
59 
60 namespace detail {
66  template <typename T, typename Enable = void>
67  struct weighted_iterator_traits_detail {
71  typedef unweighted_iterator_tag type;
72  };
73 
79  template <typename T>
80  struct weighted_iterator_traits_detail<T, typename boost::enable_if<typename boost::is_convertible<T, DataWeight> >::type > {
84  typedef weighted_iterator_tag type;
85  };
86 
87 } // namespace detail
88 
90 
91 
104  template <class Iterator>
106  {
107  private:
108  typedef typename boost::iterator_value<Iterator>::type value;
109  public:
114  typedef typename detail::weighted_iterator_traits_detail<value>::type type;
115  };
116 
117 
119 namespace detail {
127  template <class T1, class T2>
128  struct unweighted_type_and {
132  typedef weighted_iterator_tag type;
133  };
134 
141  template <>
142  struct unweighted_type_and<unweighted_iterator_tag, unweighted_iterator_tag> {
146  typedef unweighted_iterator_tag type;
147  };
148 } // namespace detail
149 
151 
152 
158  template <class T1, class T2>
160  private:
161  typedef typename weighted_iterator_traits<T1>::type w_type1;
162  typedef typename weighted_iterator_traits<T2>::type w_type2;
163  public:
165  typedef typename detail::unweighted_type_and<w_type1, w_type2>::type type;
166  };
167 
171  template <class T1, class T2, class T3>
173  private:
174  typedef typename weighted_if_any2<T1, T2>::type tmp;
175  typedef typename weighted_iterator_traits<T3>::type w_type3;
176  public:
178  typedef typename detail::unweighted_type_and<tmp, w_type3>::type type;
179  };
180 
182  namespace detail {
188  inline void
190  } // namespace detail
191 
193 
199  template <class Iter>
201  { detail::check_iterator_is_unweighted(typename
203  }
204 
205 
207 namespace detail {
208 
218  typedef char yes;
225  typedef char (&no)[2];
234  yes has_mutable(double&);
242  template<typename T>
243  no has_mutable(const T&);
244 
252  template <class Iter>
253  struct iter_has_mutable_data
254  {
256  static Iter iter;
258  static const bool value =
259  sizeof(has_mutable((*iter).data())) == sizeof(yes);
260  };
261 
262 
270  template <class Iter>
271  struct iter_has_mutable_weight
272  {
274  static Iter iter;
276  static const bool value =
277  sizeof(has_mutable((*iter).weight())) == sizeof(yes);
278  };
279 
280 
292  template<typename Iter>
293  struct is_weighted
294  : public boost::is_same<weighted_iterator_tag
295  , typename weighted_iterator_traits<Iter>::type>
296  {};
297 
303  template<typename Iter>
304  struct is_unweighted
305  : public boost::is_same<unweighted_iterator_tag
306  , typename weighted_iterator_traits<Iter>::type>
307  {};
308 
309 
317  template <typename Iter, typename Enable = void>
318  struct iterator_traits_detail {
322  typedef typename std::iterator_traits<Iter>::reference data_reference;
323 
327  typedef const double weight_reference;
328 
332  data_reference data(Iter iter) const { return *iter; }
333 
337  weight_reference weight(Iter iter) const { return 1.0; }
338  };
339 
344  template<bool>
345  struct mutable_reference {
347  typedef const double type;
348  };
349 
354  template<>
355  struct mutable_reference<true> {
357  typedef double& type;
358  };
359 
360 
366  // we need remove_reference because is_const seems to not work on const&
367  template <typename Iter>
368  struct iterator_traits_detail<Iter,
369  typename boost::enable_if<is_weighted<Iter> >::type >
370  {
375  typedef
376  typename mutable_reference<iter_has_mutable_data<Iter>::value>::type
377  data_reference;
378 
383  typedef
384  typename mutable_reference<iter_has_mutable_weight<Iter>::value>::type
385  weight_reference;
386 
390  data_reference data(Iter iter) const { return (*iter).data(); }
391 
395  weight_reference weight(Iter iter) const { return (*iter).weight(); }
396  };
397 
398 } // namespace detail
399 
401 
402 
411  template <typename Iter>
413  private:
414  typedef detail::iterator_traits_detail<Iter> traits;
415  public:
425  typedef typename traits::data_reference data_reference;
426 
435  typedef typename traits::weight_reference weight_reference;
436 
440  data_reference data(Iter iter) const
441  { return traits().data(iter); }
442 
446  weight_reference weight(Iter iter) const
447  { return traits().weight(iter); }
448 
449  };
450 
451 }}} // of namespace utility, yat, and theplu
452 
453 #endif
detail::weighted_iterator_traits_detail< value >::type type
Definition: iterator_traits.h:114
data_reference data(Iter iter) const
Definition: iterator_traits.h:440
Definition: iterator_traits.h:412
Definition: iterator_traits.h:47
Definition: iterator_traits.h:55
Definition: iterator_traits.h:105
void check_iterator_is_unweighted(Iter iter)
check (at compile time) that iterator is unweighted.
Definition: iterator_traits.h:200
traits::data_reference data_reference
Definition: iterator_traits.h:425
Definition: iterator_traits.h:172
traits::weight_reference weight_reference
Definition: iterator_traits.h:435
detail::unweighted_type_and< tmp, w_type3 >::type type
return unweighted if all are unweighted
Definition: iterator_traits.h:178
weight_reference weight(Iter iter) const
Definition: iterator_traits.h:446
detail::unweighted_type_and< w_type1, w_type2 >::type type
return unweighted if both are unweighted
Definition: iterator_traits.h:165
Definition: iterator_traits.h:159

Generated on Tue Sep 26 2017 02:33:29 for yat by  doxygen 1.8.5