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