algorithm.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. // Boost.Range library
  2. //
  3. // Copyright Thorsten Ottosen 2006. 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. // (C) Copyright Eric Niebler 2004.
  11. // Use, modification and distribution are subject to the
  12. // Boost Software License, Version 1.0. (See accompanying file
  13. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  14. /*
  15. Revision history:
  16. 13 December 2004 : Initial version.
  17. */
  18. #ifdef _MSC_VER
  19. // The 'secure' library warnings produce so much noise that it makes it
  20. // impossible to see more useful warnings.
  21. #define _SCL_SECURE_NO_WARNINGS
  22. #endif
  23. #ifdef _MSC_VER
  24. // counting_iterator generates a warning about truncating an integer
  25. #pragma warning(push)
  26. #pragma warning(disable : 4244)
  27. #endif
  28. #include <boost/iterator/counting_iterator.hpp>
  29. #ifdef _MSC_VER
  30. template ::boost::counting_iterator<int>;
  31. #pragma warning(pop)
  32. #endif
  33. #include <boost/assign.hpp>
  34. #include <boost/config.hpp>
  35. #include <boost/array.hpp>
  36. #include <boost/bind.hpp>
  37. #include <boost/range/numeric.hpp>
  38. #include <boost/range/algorithm.hpp>
  39. #include <boost/range/value_type.hpp>
  40. #include <boost/range/size_type.hpp>
  41. #include <boost/range/size.hpp>
  42. #include <boost/test/test_tools.hpp>
  43. #include <boost/test/unit_test.hpp>
  44. #include <boost/iterator/iterator_traits.hpp>
  45. #include <algorithm>
  46. #include <cstdlib>
  47. #include <set>
  48. #include <list>
  49. #include <vector>
  50. #include <iterator>
  51. #include <functional>
  52. ///////////////////////////////////////////////////////////////////////////////
  53. // dummy function object, used with algorithms
  54. //
  55. struct null_fun
  56. {
  57. template<typename T>
  58. void operator()(T const &t) const
  59. {
  60. }
  61. };
  62. ///////////////////////////////////////////////////////////////////////////////
  63. // dummy predicate, used with algorithms
  64. //
  65. struct null_pred
  66. {
  67. template<typename T>
  68. bool operator()(T const &t) const
  69. {
  70. return t == T();
  71. }
  72. };
  73. ///////////////////////////////////////////////////////////////////////////////
  74. // dummy unary op, used with algorithms
  75. //
  76. struct null_op1
  77. {
  78. template<typename T>
  79. T const & operator()(T const & t) const
  80. {
  81. return t;
  82. }
  83. };
  84. ///////////////////////////////////////////////////////////////////////////////
  85. // dummy binary op, used with algorithms
  86. //
  87. struct null_op2
  88. {
  89. template<typename T,typename U>
  90. T const & operator()(T const & t, U const & u) const
  91. {
  92. return t;
  93. }
  94. };
  95. template<typename Rng>
  96. void test_random_algorithms(Rng & rng, std::random_access_iterator_tag)
  97. {
  98. typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
  99. typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
  100. typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type
  101. size_type BOOST_RANGE_UNUSED;
  102. typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type
  103. iterator_category BOOST_RANGE_UNUSED;
  104. // just make sure these compile (for now)
  105. if(0)
  106. {
  107. boost::random_shuffle(rng);
  108. // Must be a value since random_shuffle must take the generator by
  109. // reference to match the standard.
  110. null_op1 rng_generator;
  111. boost::random_shuffle(rng, rng_generator);
  112. boost::sort(rng);
  113. boost::sort(rng, std::less<value_type>());
  114. boost::stable_sort(rng);
  115. boost::stable_sort(rng, std::less<value_type>());
  116. boost::partial_sort(rng, boost::begin(rng));
  117. boost::partial_sort(rng, boost::begin(rng), std::less<value_type>());
  118. boost::nth_element(rng, boost::begin(rng));
  119. boost::nth_element(rng, boost::begin(rng), std::less<value_type>());
  120. boost::push_heap(rng);
  121. boost::push_heap(rng, std::less<value_type>());
  122. boost::pop_heap(rng);
  123. boost::pop_heap(rng, std::less<value_type>());
  124. boost::make_heap(rng);
  125. boost::make_heap(rng, std::less<value_type>());
  126. boost::sort_heap(rng);
  127. boost::sort_heap(rng, std::less<value_type>());
  128. }
  129. }
  130. template<typename Rng>
  131. void test_random_algorithms(Rng & rng, std::input_iterator_tag)
  132. {
  133. // no-op
  134. }
  135. template<typename Rng>
  136. void test_algorithms(Rng & rng)
  137. {
  138. typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
  139. typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
  140. typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type size_type;
  141. typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type iterator_category;
  142. // just make sure these compile (for now)
  143. if(0)
  144. {
  145. value_type val = value_type();
  146. value_type rng2[] = {value_type(),value_type(),value_type()};
  147. typedef value_type* iterator2;
  148. value_type out[100] = {};
  149. typedef value_type* out_iterator;
  150. null_fun f = null_fun();
  151. iterator i = iterator();
  152. bool b = bool();
  153. out_iterator o = out_iterator();
  154. size_type s = size_type();
  155. f = boost::for_each(rng, null_fun());
  156. i = boost::find(rng, val);
  157. i = boost::find_if(rng, null_pred());
  158. i = boost::find_end(rng, rng2);
  159. i = boost::find_end(rng, rng2, std::equal_to<value_type>());
  160. i = boost::find_first_of(rng, rng2);
  161. i = boost::find_first_of(rng, rng2, std::equal_to<value_type>());
  162. i = boost::adjacent_find(rng);
  163. i = boost::adjacent_find(rng, std::equal_to<value_type>());
  164. s = boost::count(rng, val);
  165. s = boost::count_if(rng, null_pred());
  166. std::pair<iterator,iterator2> p1;
  167. p1 = boost::mismatch(rng, rng2);
  168. p1 = boost::mismatch(rng, rng2, std::equal_to<value_type>());
  169. b = boost::equal(rng, rng2);
  170. b = boost::equal(rng, rng2, std::equal_to<value_type>());
  171. i = boost::search(rng, rng2);
  172. i = boost::search(rng, rng2, std::equal_to<value_type>());
  173. o = boost::copy(rng, boost::begin(out));
  174. o = boost::copy_backward(rng, boost::end(out));
  175. o = boost::transform(rng, boost::begin(out), null_op1());
  176. o = boost::transform(rng, rng2, boost::begin(out), null_op2());
  177. boost::replace(rng, val, val);
  178. boost::replace_if(rng, null_pred(), val);
  179. /*
  180. o = boost::replace_copy(rng, boost::begin(out), val, val);
  181. o = boost::replace_copy_if(rng, boost::begin(out), null_pred(), val);
  182. */
  183. boost::fill(rng, val);
  184. //
  185. // size requires RandomAccess
  186. //
  187. //boost::fill_n(rng, boost::size(rng), val);
  188. //boost::fill_n(rng, std::distance(boost::begin(rng),boost::end(rng)),val);
  189. boost::generate(rng, &std::rand);
  190. //
  191. // size requires RandomAccess
  192. //
  193. //boost::generate_n(rng, boost::size(rng), &std::rand);
  194. //boost::generate_n(rng,std::distance(boost::begin(rng),boost::end(rng)), &std::rand);
  195. i = boost::remove(rng, val);
  196. i = boost::remove_if(rng, null_pred());
  197. /*
  198. o = boost::remove_copy(rng, boost::begin(out), val);
  199. o = boost::remove_copy_if(rng, boost::begin(out), null_pred());
  200. */
  201. typename boost::range_return<Rng, boost::return_begin_found>::type rrng = boost::unique(rng);
  202. rrng = boost::unique(rng, std::equal_to<value_type>());
  203. /*
  204. o = boost::unique_copy(rng, boost::begin(out));
  205. o = boost::unique_copy(rng, boost::begin(out), std::equal_to<value_type>());
  206. */
  207. boost::reverse(rng);
  208. /*
  209. o = boost::reverse_copy(rng, boost::begin(out));
  210. */
  211. boost::rotate(rng, boost::begin(rng));
  212. /*
  213. o = boost::rotate_copy(rng, boost::begin(rng), boost::begin(out));
  214. */
  215. i = boost::partition(rng, null_pred());
  216. i = boost::stable_partition(rng, null_pred());
  217. /*
  218. o = boost::partial_sort_copy(rng, out);
  219. o = boost::partial_sort_copy(rng, out, std::less<value_type>());
  220. */
  221. i = boost::lower_bound(rng, val);
  222. i = boost::lower_bound(rng, val, std::less<value_type>());
  223. i = boost::upper_bound(rng, val);
  224. i = boost::upper_bound(rng, val, std::less<value_type>());
  225. std::pair<iterator,iterator> p2;
  226. p2 = boost::equal_range(rng, val);
  227. p2 = boost::equal_range(rng, val, std::less<value_type>());
  228. b = boost::binary_search(rng, val);
  229. b = boost::binary_search(rng, val, std::less<value_type>());
  230. boost::inplace_merge(rng, boost::begin(rng));
  231. boost::inplace_merge(rng, boost::begin(rng), std::less<value_type>());
  232. b = boost::includes(rng, rng2);
  233. b = boost::includes(rng, rng2, std::equal_to<value_type>());
  234. o = boost::set_union(rng, rng2, boost::begin(out));
  235. o = boost::set_union(rng, rng2, boost::begin(out), std::equal_to<value_type>());
  236. o = boost::set_intersection(rng, rng2, boost::begin(out));
  237. o = boost::set_intersection(rng, rng2, boost::begin(out), std::equal_to<value_type>());
  238. o = boost::set_difference(rng, rng2, boost::begin(out));
  239. o = boost::set_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
  240. o = boost::set_symmetric_difference(rng, rng2, boost::begin(out));
  241. o = boost::set_symmetric_difference(rng, rng2, boost::begin(out), std::equal_to<value_type>());
  242. i = boost::min_element(rng);
  243. i = boost::min_element(rng, std::less<value_type>());
  244. i = boost::max_element(rng);
  245. i = boost::max_element(rng, std::less<value_type>());
  246. b = boost::lexicographical_compare(rng, rng);
  247. b = boost::lexicographical_compare(rng, rng, std::equal_to<value_type>());
  248. b = boost::next_permutation(rng);
  249. b = boost::next_permutation(rng, std::less<value_type>());
  250. b = boost::prev_permutation(rng);
  251. b = boost::prev_permutation(rng, std::less<value_type>());
  252. /////////////////////////////////////////////////////////////////////
  253. // numeric algorithms
  254. /////////////////////////////////////////////////////////////////////
  255. val = boost::accumulate( rng, val );
  256. val = boost::accumulate( rng, val, null_op2() );
  257. val = boost::inner_product( rng, rng, val );
  258. val = boost::inner_product( rng, rng, val,
  259. null_op2(), null_op2() );
  260. o = boost::partial_sum( rng, boost::begin(out) );
  261. o = boost::partial_sum( rng, boost::begin(out), null_op2() );
  262. o = boost::adjacent_difference( rng, boost::begin(out) );
  263. o = boost::adjacent_difference( rng, boost::begin(out),
  264. null_op2() );
  265. boost::ignore_unused_variable_warning(b);
  266. }
  267. // test the algorithms that require a random-access range
  268. test_random_algorithms(rng, iterator_category());
  269. }
  270. int* addr(int &i) { return &i; }
  271. bool true_(int) { return true; }
  272. ///////////////////////////////////////////////////////////////////////////////
  273. // test_main
  274. //
  275. void simple_compile_test()
  276. {
  277. // int_iterator
  278. typedef ::boost::counting_iterator<int> int_iterator;
  279. // define come containers
  280. std::list<int> my_list(int_iterator(1),int_iterator(6));
  281. std::vector<int> my_vector(int_iterator(1),int_iterator(6));
  282. std::pair<std::vector<int>::iterator,std::vector<int>::iterator> my_pair(my_vector.begin(),my_vector.end());
  283. // test the algorithms with list and const list
  284. test_algorithms(my_list);
  285. test_algorithms(my_vector);
  286. test_algorithms(my_pair);
  287. std::vector<int> v;
  288. std::vector<int>& cv = v;
  289. using namespace boost;
  290. #define BOOST_RANGE_RETURNS_TEST( function_name, cont ) \
  291. function_name (cont); \
  292. function_name <return_found> (cont); \
  293. function_name <return_next> (cont); \
  294. function_name <return_prior> (cont); \
  295. function_name <return_begin_found> (cont); \
  296. function_name <return_begin_next> (cont); \
  297. function_name <return_begin_prior> (cont); \
  298. function_name <return_found_end> (cont); \
  299. function_name <return_next_end>(cont); \
  300. function_name <return_prior_end>(cont);
  301. BOOST_RANGE_RETURNS_TEST( adjacent_find, cv );
  302. BOOST_RANGE_RETURNS_TEST( adjacent_find, v );
  303. BOOST_RANGE_RETURNS_TEST( max_element, cv );
  304. BOOST_RANGE_RETURNS_TEST( max_element, v );
  305. BOOST_RANGE_RETURNS_TEST( min_element, cv );
  306. BOOST_RANGE_RETURNS_TEST( min_element, v );
  307. BOOST_RANGE_RETURNS_TEST( unique, v );
  308. #undef BOOST_RANGE_RETURNS_TEST
  309. #define BOOST_RANGE_RETURNS_TEST1( function_name, cont, arg1 ) \
  310. function_name (cont, arg1); \
  311. function_name <return_found> (cont, arg1); \
  312. function_name <return_next> (cont, arg1); \
  313. function_name <return_prior> (cont, arg1); \
  314. function_name <return_begin_found> (cont, arg1); \
  315. function_name <return_begin_next> (cont, arg1); \
  316. function_name <return_begin_prior> (cont, arg1); \
  317. function_name <return_found_end> (cont, arg1); \
  318. function_name <return_next_end>(cont, arg1); \
  319. function_name <return_prior_end>(cont, arg1);
  320. BOOST_RANGE_RETURNS_TEST1( adjacent_find, cv, std::less<int>() );
  321. BOOST_RANGE_RETURNS_TEST1( adjacent_find, v, std::less<int>() );
  322. BOOST_RANGE_RETURNS_TEST1( find, cv, 0 );
  323. BOOST_RANGE_RETURNS_TEST1( find, v, 0 );
  324. BOOST_RANGE_RETURNS_TEST1( find_end, cv, cv );
  325. BOOST_RANGE_RETURNS_TEST1( find_end, cv, v );
  326. BOOST_RANGE_RETURNS_TEST1( find_end, v, cv );
  327. BOOST_RANGE_RETURNS_TEST1( find_end, v, v );
  328. BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, cv );
  329. BOOST_RANGE_RETURNS_TEST1( find_first_of, cv, v );
  330. BOOST_RANGE_RETURNS_TEST1( find_first_of, v, cv );
  331. BOOST_RANGE_RETURNS_TEST1( find_first_of, v, v );
  332. BOOST_RANGE_RETURNS_TEST1( find_if, cv, std::negate<int>() );
  333. BOOST_RANGE_RETURNS_TEST1( find_if, v, std::negate<int>() );
  334. BOOST_RANGE_RETURNS_TEST1( search, cv, cv );
  335. BOOST_RANGE_RETURNS_TEST1( search, cv, v );
  336. BOOST_RANGE_RETURNS_TEST1( search, v, cv );
  337. BOOST_RANGE_RETURNS_TEST1( search, v, v );
  338. BOOST_RANGE_RETURNS_TEST1( remove, v, 0 );
  339. BOOST_RANGE_RETURNS_TEST1( remove_if, v, std::negate<int>() );
  340. BOOST_RANGE_RETURNS_TEST1( lower_bound, cv, 0 );
  341. BOOST_RANGE_RETURNS_TEST1( lower_bound, v, 0 );
  342. BOOST_RANGE_RETURNS_TEST1( max_element, cv, std::less<int>() );
  343. BOOST_RANGE_RETURNS_TEST1( max_element, v, std::less<int>() );
  344. BOOST_RANGE_RETURNS_TEST1( min_element, cv, std::less<int>() );
  345. BOOST_RANGE_RETURNS_TEST1( min_element, v, std::less<int>() );
  346. BOOST_RANGE_RETURNS_TEST1( upper_bound, cv, 0 );
  347. BOOST_RANGE_RETURNS_TEST1( upper_bound, v, 0 );
  348. BOOST_RANGE_RETURNS_TEST1( partition, cv, std::negate<int>() );
  349. BOOST_RANGE_RETURNS_TEST1( partition, v, std::negate<int>() );
  350. BOOST_RANGE_RETURNS_TEST1( stable_partition, cv, std::negate<int>() );
  351. BOOST_RANGE_RETURNS_TEST1( stable_partition, v, std::negate<int>() );
  352. #undef BOOST_RANGE_RETURNS_TEST1
  353. #define BOOST_RANGE_RETURNS_TEST2( function_name, arg1, arg2 ) \
  354. function_name (v, arg1, arg2); \
  355. function_name <return_found> (v, arg1, arg2); \
  356. function_name <return_next> (v, arg1, arg2); \
  357. function_name <return_prior> (v, arg1, arg2); \
  358. function_name <return_begin_found> (v, arg1, arg2); \
  359. function_name <return_begin_next> (v, arg1, arg2); \
  360. function_name <return_begin_prior> (v, arg1, arg2); \
  361. function_name <return_found_end> (v, arg1, arg2); \
  362. function_name <return_next_end>(v, arg1, arg2); \
  363. function_name <return_prior_end>(v, arg1, arg2);
  364. BOOST_RANGE_RETURNS_TEST2( find_end, v, std::less<int>() );
  365. BOOST_RANGE_RETURNS_TEST2( find_first_of, v, std::less<int>() );
  366. BOOST_RANGE_RETURNS_TEST2( boost::search, v, std::less<int>() );
  367. BOOST_RANGE_RETURNS_TEST2( lower_bound, 0, std::less<int>() );
  368. BOOST_RANGE_RETURNS_TEST2( upper_bound, 0, std::less<int>() );
  369. #undef BOOST_RANGE_RETURNS_TEST2
  370. }
  371. using boost::unit_test::test_suite;
  372. test_suite* init_unit_test_suite( int argc, char* argv[] )
  373. {
  374. using namespace boost;
  375. test_suite* test = BOOST_TEST_SUITE( "Range Test Suite - Algorithm" );
  376. test->add( BOOST_TEST_CASE( &simple_compile_test ) );
  377. return test;
  378. }