sub_range.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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/sub_range.hpp>
  16. #include <boost/range/as_literal.hpp>
  17. #include <boost/test/unit_test.hpp>
  18. #include <boost/test/test_tools.hpp>
  19. #include <iostream>
  20. #include <string>
  21. #include <vector>
  22. namespace boost_range_test
  23. {
  24. namespace
  25. {
  26. void check_sub_range()
  27. {
  28. typedef std::string::iterator iterator;
  29. typedef std::string::const_iterator const_iterator;
  30. typedef boost::iterator_range<iterator> irange;
  31. typedef boost::iterator_range<const_iterator> cirange;
  32. std::string str = "hello world";
  33. const std::string cstr = "const world";
  34. irange r = boost::make_iterator_range( str );
  35. r = boost::make_iterator_range( str.begin(), str.end() );
  36. cirange r2 = boost::make_iterator_range( cstr );
  37. r2 = boost::make_iterator_range( cstr.begin(), cstr.end() );
  38. r2 = boost::make_iterator_range( str );
  39. typedef boost::sub_range<std::string> srange;
  40. typedef boost::sub_range<const std::string> csrange;
  41. srange s = r;
  42. BOOST_CHECK( r == r );
  43. BOOST_CHECK( s == r );
  44. s = boost::make_iterator_range( str );
  45. csrange s2 = r;
  46. s2 = r2;
  47. s2 = boost::make_iterator_range( cstr );
  48. BOOST_CHECK( r2 == r2 );
  49. BOOST_CHECK( s2 != r2 );
  50. s2 = boost::make_iterator_range( str );
  51. BOOST_CHECK( !(s != s) );
  52. BOOST_CHECK( r.begin() == s.begin() );
  53. BOOST_CHECK( r2.begin()== s2.begin() );
  54. BOOST_CHECK( r.end() == s.end() );
  55. BOOST_CHECK( r2.end() == s2.end() );
  56. BOOST_CHECK_EQUAL( r.size(), s.size() );
  57. BOOST_CHECK_EQUAL( r2.size(), s2.size() );
  58. //#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
  59. // if( !(bool)r )
  60. // BOOST_CHECK( false );
  61. // if( !(bool)r2 )
  62. // BOOST_CHECK( false );
  63. // if( !(bool)s )
  64. // BOOST_CHECK( false );
  65. // if( !(bool)s2 )
  66. // BOOST_CHECK( false );
  67. //#else
  68. if( !r )
  69. BOOST_CHECK( false );
  70. if( !r2 )
  71. BOOST_CHECK( false );
  72. if( !s )
  73. BOOST_CHECK( false );
  74. if( !s2 )
  75. BOOST_CHECK( false );
  76. //#endif
  77. std::cout << r << r2 << s << s2;
  78. std::string res = boost::copy_range<std::string>( r );
  79. BOOST_CHECK_EQUAL_COLLECTIONS( res.begin(), res.end(), r.begin(), r.end() );
  80. r.empty();
  81. s.empty();
  82. r.size();
  83. s.size();
  84. //
  85. // As of range v2 not legal anymore.
  86. //
  87. //irange singular_irange;
  88. //BOOST_CHECK( singular_irange.empty() );
  89. //BOOST_CHECK( singular_irange.size() == 0 );
  90. //
  91. //srange singular_srange;
  92. //BOOST_CHECK( singular_srange.empty() );
  93. //BOOST_CHECK( singular_srange.size() == 0 );
  94. //
  95. //BOOST_CHECK( empty( singular_irange ) );
  96. //BOOST_CHECK( empty( singular_srange ) );
  97. //
  98. srange rr = boost::make_iterator_range( str );
  99. BOOST_CHECK( rr.equal( r ) );
  100. rr = boost::make_iterator_range( str.begin(), str.begin() + 5 );
  101. BOOST_CHECK( rr == boost::as_literal("hello") );
  102. BOOST_CHECK( rr != boost::as_literal("hell") );
  103. BOOST_CHECK( rr < boost::as_literal("hello dude") );
  104. BOOST_CHECK( boost::as_literal("hello") == rr );
  105. BOOST_CHECK( boost::as_literal("hell") != rr );
  106. BOOST_CHECK( ! (boost::as_literal("hello dude") < rr ) );
  107. irange rrr = rr;
  108. BOOST_CHECK( rrr == rr );
  109. BOOST_CHECK( !( rrr != rr ) );
  110. BOOST_CHECK( !( rrr < rr ) );
  111. const irange cr = boost::make_iterator_range( str );
  112. BOOST_CHECK_EQUAL( cr.front(), 'h' );
  113. BOOST_CHECK_EQUAL( cr.back(), 'd' );
  114. BOOST_CHECK_EQUAL( cr[1], 'e' );
  115. BOOST_CHECK_EQUAL( cr(1), 'e' );
  116. rrr = boost::make_iterator_range( str, 1, -1 );
  117. BOOST_CHECK( rrr == boost::as_literal("ello worl") );
  118. rrr = boost::make_iterator_range( rrr, -1, 1 );
  119. BOOST_CHECK( rrr == str );
  120. rrr.front() = 'H';
  121. rrr.back() = 'D';
  122. rrr[1] = 'E';
  123. BOOST_CHECK( rrr == boost::as_literal("HEllo worlD") );
  124. }
  125. template<class T>
  126. void check_mutable_type(T&)
  127. {
  128. BOOST_STATIC_ASSERT(!boost::is_const<T>::value);
  129. }
  130. template<class T>
  131. void check_constant_type(T&)
  132. {
  133. BOOST_STATIC_ASSERT(boost::is_const<T>::value);
  134. }
  135. template<class Range, class Iterator>
  136. void check_is_const_iterator(Iterator it)
  137. {
  138. BOOST_STATIC_ASSERT((
  139. boost::is_same<
  140. BOOST_DEDUCED_TYPENAME boost::range_iterator<
  141. BOOST_DEDUCED_TYPENAME boost::add_const<Range>::type
  142. >::type,
  143. Iterator
  144. >::value));
  145. }
  146. template<class Range, class Iterator>
  147. void check_is_iterator(Iterator it)
  148. {
  149. BOOST_STATIC_ASSERT((
  150. boost::is_same<
  151. BOOST_DEDUCED_TYPENAME boost::range_iterator<
  152. BOOST_DEDUCED_TYPENAME boost::remove_const<Range>::type
  153. >::type,
  154. Iterator
  155. >::value));
  156. }
  157. void const_propagation_mutable_collection(void)
  158. {
  159. typedef std::vector<int> coll_t;
  160. typedef boost::sub_range<coll_t> sub_range_t;
  161. coll_t c;
  162. c.push_back(0);
  163. sub_range_t rng(c);
  164. const sub_range_t crng(c);
  165. check_is_iterator<sub_range_t>(rng.begin());
  166. check_is_iterator<sub_range_t>(rng.end());
  167. check_is_const_iterator<sub_range_t>(crng.begin());
  168. check_is_const_iterator<sub_range_t>(crng.end());
  169. check_mutable_type(rng[0]);
  170. check_mutable_type(rng.front());
  171. check_mutable_type(rng.back());
  172. check_constant_type(crng[0]);
  173. check_constant_type(crng.front());
  174. check_constant_type(crng.back());
  175. }
  176. void const_propagation_const_collection(void)
  177. {
  178. typedef std::vector<int> coll_t;
  179. typedef boost::sub_range<const coll_t> sub_range_t;
  180. coll_t c;
  181. c.push_back(0);
  182. sub_range_t rng(c);
  183. const sub_range_t crng(c);
  184. check_is_const_iterator<sub_range_t>(rng.begin());
  185. check_is_const_iterator<sub_range_t>(rng.end());
  186. check_is_const_iterator<sub_range_t>(crng.begin());
  187. check_is_const_iterator<sub_range_t>(crng.end());
  188. check_constant_type(rng[0]);
  189. check_constant_type(rng.front());
  190. check_constant_type(rng.back());
  191. check_constant_type(crng[0]);
  192. check_constant_type(crng.front());
  193. check_constant_type(crng.back());
  194. }
  195. inline void test_advance()
  196. {
  197. std::vector<int> l;
  198. l.push_back(1);
  199. l.push_back(2);
  200. typedef boost::sub_range<std::vector<int> > rng_t;
  201. rng_t r1(l.begin(), l.end());
  202. BOOST_CHECK(r1.advance_begin(1).advance_end(-1).empty());
  203. rng_t r2(l.begin(), l.end());
  204. BOOST_CHECK_EQUAL(r2.advance_begin(1).size(), 1u);
  205. rng_t r3(l.begin(), l.end());
  206. BOOST_CHECK_EQUAL(r3.advance_end(-1).size(), 1u);
  207. }
  208. void ticket_10514()
  209. {
  210. typedef std::vector<int> vec_t;
  211. typedef boost::sub_range<vec_t> range_t;
  212. vec_t v(10);
  213. range_t r(v.begin(), v.end());
  214. const range_t& cr = r;
  215. range_t copy_r = cr;
  216. BOOST_CHECK(r.begin() == copy_r.begin());
  217. BOOST_CHECK(r.end() == copy_r.end());
  218. BOOST_CHECK(cr.begin() == copy_r.begin());
  219. BOOST_CHECK(cr.end() == copy_r.end());
  220. }
  221. } // anonymous namespace
  222. } // namespace boost_range_test
  223. boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
  224. {
  225. boost::unit_test::test_suite* test =
  226. BOOST_TEST_SUITE( "Boost.Range sub_range test suite" );
  227. test->add(BOOST_TEST_CASE(&boost_range_test::check_sub_range));
  228. test->add(BOOST_TEST_CASE(
  229. &boost_range_test::const_propagation_const_collection));
  230. test->add(BOOST_TEST_CASE(
  231. &boost_range_test::const_propagation_mutable_collection));
  232. test->add(BOOST_TEST_CASE(&boost_range_test::test_advance));
  233. test->add(BOOST_TEST_CASE(&boost_range_test::ticket_10514));
  234. return test;
  235. }