1 // Boost.Range library
2 //
3 //  Copyright Neil Groves 2010. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see http://www.boost.org/libs/range/
9 //
10 // Acknowledgments:
11 // Ticket #8341: Arno Schoedl - improved handling of has_range_iterator upon
12 // use-cases where T was const.
13 #ifndef BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
14 #define BOOST_RANGE_HAS_ITERATOR_HPP_INCLUDED
15 
16 #include <boost/mpl/bool.hpp>
17 #include <boost/mpl/eval_if.hpp>
18 #include <boost/mpl/has_xxx.hpp>
19 #include <boost/range/iterator.hpp>
20 #include <boost/type_traits/remove_reference.hpp>
21 #include <boost/utility/enable_if.hpp>
22 
23 namespace boost
24 {
25     namespace range_detail
26     {
27         BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
28 
29         template<class T, class Enabler = void>
30         struct has_range_iterator_impl
31             : boost::mpl::false_
32         {
33         };
34 
35         template<class T>
36         struct has_range_iterator_impl<
37             T,
38             BOOST_DEDUCED_TYPENAME ::boost::enable_if<
39                 BOOST_DEDUCED_TYPENAME mpl::eval_if<is_const<T>,
40                     has_type<boost::range_const_iterator<
41                                 BOOST_DEDUCED_TYPENAME remove_const<T>::type> >,
42                     has_type<boost::range_mutable_iterator<T> >
43                 >::type
44             >::type
45         >
46             : boost::mpl::true_
47         {
48         };
49 
50         template<class T, class Enabler = void>
51         struct has_range_const_iterator_impl
52             : boost::mpl::false_
53         {
54         };
55 
56         template<class T>
57         struct has_range_const_iterator_impl<
58             T,
59             BOOST_DEDUCED_TYPENAME ::boost::enable_if<
60                 has_type<boost::range_const_iterator<T> >
61             >::type
62         >
63             : boost::mpl::true_
64         {
65         };
66 
67     } // namespace range_detail
68 
69     template<class T>
70     struct has_range_iterator
71         : range_detail::has_range_iterator_impl<
72             BOOST_DEDUCED_TYPENAME remove_reference<T>::type>
73     {};
74 
75     template<class T>
76     struct has_range_const_iterator
77         : range_detail::has_range_const_iterator_impl<
78             BOOST_DEDUCED_TYPENAME remove_reference<T>::type>
79     {};
80 } // namespace boost
81 
82 #endif // include guard
83 
84