• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Range library
2 //
3 //  Copyright Neil Groves 2014. 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 
11 #include <boost/range/iterator.hpp>
12 #include <boost/static_assert.hpp>
13 #include <boost/type_traits/is_same.hpp>
14 #include <boost/type_traits/is_base_of.hpp>
15 #include <boost/type_traits/decay.hpp>
16 
17 #include <boost/test/test_tools.hpp>
18 #include <boost/test/unit_test.hpp>
19 
20 #include <vector>
21 
22 namespace boost_range_test
23 {
24 
25 struct point
26 {
27     int x;
28     int y;
29 };
30 
31 class shape
32 {
33 public:
~shape()34     virtual ~shape()
35     {
36     }
37 
points() const38     const std::vector<point>& points() const
39     {
40         return m_points;
41     }
42 
43 private:
44     std::vector<point> m_points;
45 };
46 
47 class rectangle : public shape
48 {
49 };
50 
51 class circle : public shape
52 {
53 };
54 
55 class container
56 {
57     typedef std::vector<point> impl_t;
58 };
59 
60 } // namespace boost_range_test
61 
62 namespace boost
63 {
64     template<typename T>
65     struct range_mutable_iterator<
66             T,
67             typename boost::enable_if<
68                 boost::is_base_of<
69                     boost_range_test::shape,
70                     typename boost::remove_reference<
71                         typename boost::remove_cv<T>::type
72                     >::type
73                 >
74             >::type
75         >
76     {
77         typedef std::vector<boost_range_test::point>::iterator type;
78     };
79 
80     template<typename T>
81     struct range_const_iterator<
82             T,
83             typename boost::enable_if<
84                 boost::is_base_of<
85                     boost_range_test::shape,
86                     typename boost::remove_reference<
87                         typename boost::remove_cv<T>::type
88                     >::type
89                 >
90             >::type
91         >
92     {
93         typedef std::vector<boost_range_test::point>::const_iterator type;
94     };
95 
96     template<>
97     struct range_mutable_iterator<boost_range_test::container>
98     {
99         typedef std::vector<boost_range_test::point>::iterator type;
100     };
101 
102     template<>
103     struct range_const_iterator<boost_range_test::container>
104     {
105         typedef std::vector<boost_range_test::point>::const_iterator type;
106     };
107 }
108 
109 namespace boost_range_test
110 {
111     template<typename Shape>
test_iterator_impl()112     void test_iterator_impl()
113     {
114         BOOST_STATIC_ASSERT((
115             boost::is_same<
116                 std::vector<point>::iterator,
117                 typename boost::range_iterator<Shape>::type
118             >::value));
119 
120         BOOST_STATIC_ASSERT((
121             boost::is_same<
122                 std::vector<point>::const_iterator,
123                 typename boost::range_iterator<const Shape>::type
124             >::value));
125 
126     #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
127         BOOST_STATIC_ASSERT((
128             boost::is_same<
129                 std::vector<point>::iterator,
130                 typename boost::range_iterator<Shape&&>::type
131             >::value));
132     #endif
133     }
134 
test_iterator()135     void test_iterator()
136     {
137         test_iterator_impl<shape>();
138         test_iterator_impl<rectangle>();
139         test_iterator_impl<circle>();
140 
141         test_iterator_impl<container>();
142     }
143 } // namespace boost_range_test
144 
init_unit_test_suite(int argc,char * argv[])145 boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
146 {
147     boost::unit_test::test_suite* test =
148         BOOST_TEST_SUITE("Boost.Range range_iterator meta-function");
149 
150     test->add(BOOST_TEST_CASE(&boost_range_test::test_iterator));
151 
152     return test;
153 }
154