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: |
34 | virtual ~shape() |
35 | { |
36 | } |
37 | |
38 | 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> |
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 | |
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 | |
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 | |