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(BOOST_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
27namespace 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:
43 friend inline const_iterator range_begin(const FooWithoutSize& obj) { return obj.m_impl.begin(); }
44 friend inline iterator range_begin(FooWithoutSize& obj) { return obj.m_impl.begin(); }
45 friend inline const_iterator range_end(const FooWithoutSize& obj) { return obj.m_impl.end(); }
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
99 UdtSizeType() : value_(0) { }
100 UdtSizeType(value_type value) : value_(value) { }
101
102 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
164namespace 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
177namespace boost_range_extension_size_test
178{
179 inline boost::range_size<FooWithoutSize>::type
180 range_calculate_size(const FooWithoutSize& rng)
181 {
182 return 2u;
183 }
184}
185
186BOOST_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
194typedef boost::make_unsigned<std::ptrdiff_t>::type t1;
195typedef boost::range_size<boost_range_extension_size_test::FooWithoutSize>::type t1;
196
197namespace
198{
199
200void check_size_works_with_random_access()
201{
202 std::vector<int> container;
203 container.push_back(x: 1);
204 BOOST_CHECK_EQUAL( boost::size(container), 1u );
205}
206
207void check_extension_size()
208{
209 BOOST_CHECK_EQUAL( boost::size(boost_range_extension_size_test::FooWithoutSize()), 2u );
210}
211
212} // anonymous namespace
213
214using boost::unit_test::test_suite;
215
216test_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

source code of boost/libs/range/test/extension_size.cpp