extension_size.cpp 6.0 KB

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