yat  0.12.3pre
iterator_traits.h
1 #ifndef _theplu_yat_utility_iterator_traits_
2 #define _theplu_yat_utility_iterator_traits_
3 
4 // $Id: iterator_traits.h 3188 2014-03-25 10:24:29Z 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 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/mpl/logical.hpp>
30 #include <boost/type_traits/is_const.hpp>
31 #include <boost/type_traits/is_convertible.hpp>
32 #include <boost/type_traits/is_same.hpp>
33 #include <boost/type_traits/remove_reference.hpp>
34 #include <boost/utility/enable_if.hpp>
35 
36 #include <iterator>
37 
38 namespace theplu {
39 namespace yat {
40 namespace utility {
41 
47 
55 
56 
58 
59 namespace detail {
65  template <typename T, typename Enable = void>
66  struct weighted_iterator_traits_detail {
70  typedef unweighted_iterator_tag type;
71  };
72 
78  template <typename T>
79  struct weighted_iterator_traits_detail<T, typename boost::enable_if<typename boost::is_convertible<T, DataWeight> >::type > {
83  typedef weighted_iterator_tag type;
84  };
85 
86 } // namespace detail
87 
89 
90 
98  template <class Iterator>
100  {
101  private:
102  typedef typename std::iterator_traits<Iterator>::value_type value;
103  public:
108  typedef typename detail::weighted_iterator_traits_detail<value>::type type;
109  };
110 
111 
113 namespace detail {
121  template <class T1, class T2>
122  struct unweighted_type_and {
126  typedef weighted_iterator_tag type;
127  };
128 
135  template <>
136  struct unweighted_type_and<unweighted_iterator_tag, unweighted_iterator_tag> {
140  typedef unweighted_iterator_tag type;
141  };
142 } // namespace detail
143 
145 
146 
152  template <class T1, class T2>
154  private:
155  typedef typename weighted_iterator_traits<T1>::type w_type1;
156  typedef typename weighted_iterator_traits<T2>::type w_type2;
157  public:
159  typedef typename detail::unweighted_type_and<w_type1, w_type2>::type type;
160  };
161 
165  template <class T1, class T2, class T3>
167  private:
168  typedef typename weighted_if_any2<T1, T2>::type tmp;
169  typedef typename weighted_iterator_traits<T3>::type w_type3;
170  public:
172  typedef typename detail::unweighted_type_and<tmp, w_type3>::type type;
173  };
174 
176  namespace detail {
182  inline void
184  } // namespace detail
185 
187 
193  template <class Iter>
195  { detail::check_iterator_is_unweighted(typename
197  }
198 
199 
201 namespace detail {
202 
212  typedef char yes;
219  typedef char (&no)[2];
228  yes has_mutable(double&);
236  template<typename T>
237  no has_mutable(const T&);
238 
246  template <class Iter>
247  struct iter_has_mutable_data
248  {
250  static Iter iter;
252  static const bool value =
253  sizeof(has_mutable((*iter).data())) == sizeof(yes);
254  };
255 
256 
264  template <class Iter>
265  struct iter_has_mutable_weight
266  {
268  static Iter iter;
270  static const bool value =
271  sizeof(has_mutable((*iter).weight())) == sizeof(yes);
272  };
273 
274 
286  template<typename Iter>
287  struct is_weighted
288  : public boost::is_same<weighted_iterator_tag
289  , typename weighted_iterator_traits<Iter>::type>
290  {};
291 
297  template<typename Iter>
298  struct is_unweighted
299  : public boost::is_same<unweighted_iterator_tag
300  , typename weighted_iterator_traits<Iter>::type>
301  {};
302 
303 
311  template <typename Iter, typename Enable = void>
312  struct iterator_traits_detail {
316  typedef typename std::iterator_traits<Iter>::reference data_reference;
317 
321  typedef const double weight_reference;
322 
326  data_reference data(Iter iter) const { return *iter; }
327 
331  weight_reference weight(Iter iter) const { return 1.0; }
332  };
333 
338  template<bool>
339  struct mutable_reference {
341  typedef const double type;
342  };
343 
348  template<>
349  struct mutable_reference<true> {
351  typedef double& type;
352  };
353 
354 
360  // we need remove_reference because is_const seems to not work on const&
361  template <typename Iter>
362  struct iterator_traits_detail<Iter,
363  typename boost::enable_if<is_weighted<Iter> >::type >
364  {
369  typedef
370  typename mutable_reference<iter_has_mutable_data<Iter>::value>::type
371  data_reference;
372 
377  typedef
378  typename mutable_reference<iter_has_mutable_weight<Iter>::value>::type
379  weight_reference;
380 
384  data_reference data(Iter iter) const { return (*iter).data(); }
385 
389  weight_reference weight(Iter iter) const { return (*iter).weight(); }
390  };
391 
392 } // namespace detail
393 
395 
396 
405  template <typename Iter>
407  private:
408  typedef detail::iterator_traits_detail<Iter> traits;
409  public:
419  typedef typename traits::data_reference data_reference;
420 
429  typedef typename traits::weight_reference weight_reference;
430 
434  data_reference data(Iter iter) const
435  { return traits().data(iter); }
436 
440  weight_reference weight(Iter iter) const
441  { return traits().weight(iter); }
442 
443  };
444 
445 }}} // of namespace utility, yat, and theplu
446 
447 #endif
detail::weighted_iterator_traits_detail< value >::type type
Definition: iterator_traits.h:108
data_reference data(Iter iter) const
Definition: iterator_traits.h:434
Definition: iterator_traits.h:406
Definition: iterator_traits.h:46
Definition: iterator_traits.h:54
Definition: iterator_traits.h:99
void check_iterator_is_unweighted(Iter iter)
check (at compile time) that iterator is unweighted.
Definition: iterator_traits.h:194
traits::data_reference data_reference
Definition: iterator_traits.h:419
Definition: iterator_traits.h:166
traits::weight_reference weight_reference
Definition: iterator_traits.h:429
detail::unweighted_type_and< tmp, w_type3 >::type type
return unweighted if all are unweighted
Definition: iterator_traits.h:172
weight_reference weight(Iter iter) const
Definition: iterator_traits.h:440
detail::unweighted_type_and< w_type1, w_type2 >::type type
return unweighted if both are unweighted
Definition: iterator_traits.h:159
Definition: iterator_traits.h:153

Generated on Mon Jun 1 2015 12:29:52 for yat by  doxygen 1.8.5