1 // Boost.Range library
2 //
3 // Copyright Thorsten Ottosen 2003-2004. 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
12 #include <boost/detail/workaround.hpp>
13
14 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
15 # pragma warn -8091 // suppress warning in Boost.Test
16 # pragma warn -8057 // unused argument argc/argv in Boost.Test
17 #endif
18
19 #include <boost/range.hpp>
20 #include <boost/test/test_tools.hpp>
21 #include <boost/test/unit_test.hpp>
22 #include <boost/static_assert.hpp>
23 #include <boost/cstdint.hpp>
24 #include <list>
25 #include <vector>
26
27 namespace boost_range_extension_size_test
28 {
29 class FooWithoutSize
30 {
31 typedef std::list<int> impl_t;
32
33 BOOST_STATIC_ASSERT((
34 boost::is_same<
35 boost::range_size<std::list<int> >::type,
36 std::list<int>::size_type
37 >::value));
38
39 typedef impl_t::const_iterator const_iterator;
40 typedef impl_t::iterator iterator;
41
42 public:
range_begin(const FooWithoutSize & obj)43 friend inline const_iterator range_begin(const FooWithoutSize& obj) { return obj.m_impl.begin(); }
range_begin(FooWithoutSize & obj)44 friend inline iterator range_begin(FooWithoutSize& obj) { return obj.m_impl.begin(); }
range_end(const FooWithoutSize & obj)45 friend inline const_iterator range_end(const FooWithoutSize& obj) { return obj.m_impl.end(); }
range_end(FooWithoutSize & obj)46 friend inline iterator range_end(FooWithoutSize& obj){ return obj.m_impl.end(); }
47
48 private:
49 impl_t m_impl;
50 };
51
52 template<typename SizeType>
53 class FooWithSize
54 {
55 public:
56 typedef SizeType size_type;
57 typedef boost::uint8_t* iterator;
58 typedef const boost::uint8_t* const_iterator;
59
60 const_iterator begin() const;
61 iterator begin();
62 const_iterator end() const;
63 iterator end();
64 };
65
66 BOOST_STATIC_ASSERT((
67 boost::is_same<
68 boost::uint8_t,
69 boost::range_size<FooWithSize<boost::uint8_t> >::type
70 >::value
71 ));
72
73 BOOST_STATIC_ASSERT((
74 boost::is_same<
75 boost::uint16_t,
76 boost::range_size<FooWithSize<boost::uint16_t> >::type
77 >::value
78 ));
79
80 BOOST_STATIC_ASSERT((
81 boost::is_same<
82 boost::uint32_t,
83 boost::range_size<FooWithSize<boost::uint32_t> >::type
84 >::value
85 ));
86
87 BOOST_STATIC_ASSERT((
88 boost::is_same<
89 boost::uint64_t,
90 boost::range_size<FooWithSize<boost::uint64_t> >::type
91 >::value
92 ));
93
94 class UdtSizeType
95 {
96 public:
97 typedef boost::uint16_t value_type;
98
UdtSizeType()99 UdtSizeType() : value_(0) { }
UdtSizeType(value_type value)100 UdtSizeType(value_type value) : value_(value) { }
101
operator value_type() const102 operator value_type() const { return value_; }
103
104 private:
105 value_type value_;
106 };
107
108 BOOST_STATIC_ASSERT((
109 boost::is_same<
110 UdtSizeType,
111 boost::range_size<FooWithSize<UdtSizeType> >::type
112 >::value
113 ));
114
115 class Foo2WithoutSize
116 {
117 public:
118 struct const_iterator
119 {
120 typedef std::forward_iterator_tag iterator_category;
121 typedef boost::int8_t difference_type;
122 typedef boost::int16_t value_type;
123 typedef value_type* pointer;
124 typedef value_type& reference;
125
126 reference operator*() const;
127 pointer operator->() const;
128 const_iterator& operator++();
129 const_iterator operator++(int);
130 bool operator==(const const_iterator&) const;
131 bool operator!=(const const_iterator&) const;
132 };
133
134 struct iterator : const_iterator
135 {
136 typedef const value_type* pointer;
137 typedef const value_type& reference;
138
139 reference operator*() const;
140 pointer operator->() const;
141
142 iterator& operator++();
143 iterator operator++(int);
144
145 bool operator==(const iterator&) const;
146 bool operator!=(const iterator&) const;
147 };
148
149 const_iterator begin() const;
150 iterator begin();
151 const_iterator end() const;
152 iterator end();
153 };
154
155 BOOST_STATIC_ASSERT((
156 boost::is_same<
157 boost::uint8_t,
158 boost::range_size<
159 ::boost_range_extension_size_test::Foo2WithoutSize>::type
160 >::value
161 ));
162 }
163
164 namespace boost
165 {
166 template<> struct range_iterator<const ::boost_range_extension_size_test::FooWithoutSize>
167 {
168 typedef std::list<int>::const_iterator type;
169 };
170
171 template<> struct range_iterator< ::boost_range_extension_size_test::FooWithoutSize>
172 {
173 typedef std::list<int>::iterator type;
174 };
175 }
176
177 namespace boost_range_extension_size_test
178 {
179 inline boost::range_size<FooWithoutSize>::type
range_calculate_size(const FooWithoutSize & rng)180 range_calculate_size(const FooWithoutSize& rng)
181 {
182 return 2u;
183 }
184 }
185
186 BOOST_STATIC_ASSERT((
187 boost::is_same<
188 boost::make_unsigned<std::ptrdiff_t>::type,
189 boost::range_size<
190 boost_range_extension_size_test::FooWithoutSize>::type
191 >::value
192 ));
193
194 typedef boost::make_unsigned<std::ptrdiff_t>::type t1;
195 typedef boost::range_size<boost_range_extension_size_test::FooWithoutSize>::type t1;
196
197 namespace
198 {
199
check_size_works_with_random_access()200 void check_size_works_with_random_access()
201 {
202 std::vector<int> container;
203 container.push_back(1);
204 BOOST_CHECK_EQUAL( boost::size(container), 1u );
205 }
206
check_extension_size()207 void check_extension_size()
208 {
209 BOOST_CHECK_EQUAL( boost::size(boost_range_extension_size_test::FooWithoutSize()), 2u );
210 }
211
212 } // anonymous namespace
213
214 using boost::unit_test::test_suite;
215
init_unit_test_suite(int argc,char * argv[])216 test_suite* init_unit_test_suite( int argc, char* argv[] )
217 {
218 test_suite* test = BOOST_TEST_SUITE( "Range Test Suite" );
219
220 test->add( BOOST_TEST_CASE( &check_size_works_with_random_access ));
221 test->add( BOOST_TEST_CASE( &check_extension_size ) );
222
223 return test;
224 }
225