stl_concept_covering.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. // (C) Copyright Jeremy Siek 2000-2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #include <algorithm>
  6. #include <numeric>
  7. #include <boost/config.hpp>
  8. #include <boost/concept_check.hpp>
  9. #include <boost/concept_archetype.hpp>
  10. /*
  11. This file uses the archetype classes to find out which concepts
  12. actually *cover* the STL algorithms true requirements. The
  13. archetypes/concepts chosen do not necessarily match the C++ standard
  14. or the SGI STL documentation, but instead were chosen based on the
  15. minimal concepts that current STL implementations require, which in
  16. many cases is less stringent than the standard. In some places there
  17. was significant differences in the implementations' requirements and
  18. in those places macros were used to select different requirements,
  19. the purpose being to document what the requirements of various
  20. implementations are. It is an open issue as to whether the C++
  21. standard should be changed to reflect these weaker requirements.
  22. */
  23. /**
  24. * Input iterator - explanation from Peter Dimov:
  25. *
  26. * Requirements say that *it is convertible to the value_type, and it is, in
  27. * our case. The problem however is that op== is a template and the first
  28. * argument fails deduction. std::find is specified in terms of the exact
  29. * expression `*it == value`, so if it doesn't compile (and it doesn't),
  30. * `find(it, it, value)` won't compile either.
  31. *
  32. * To address this, the no_proxy variant of the input iterator is used
  33. * instead.
  34. */
  35. #define BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE input_iterator_archetype_no_proxy
  36. boost::detail::dummy_constructor dummy_cons;
  37. // This is a special concept needed for std::swap_ranges.
  38. // It is mutually convertible, and also SGIAssignable
  39. template <class T>
  40. class mutually_convertible_archetype
  41. {
  42. private:
  43. mutually_convertible_archetype() { }
  44. public:
  45. mutually_convertible_archetype(const mutually_convertible_archetype&) { }
  46. mutually_convertible_archetype&
  47. operator=(const mutually_convertible_archetype&)
  48. { return *this; }
  49. mutually_convertible_archetype(boost::detail::dummy_constructor) { }
  50. template <class U>
  51. mutually_convertible_archetype&
  52. operator=(const mutually_convertible_archetype<U>&)
  53. { return *this; }
  54. };
  55. // for std::accumulate
  56. namespace accum
  57. {
  58. typedef boost::sgi_assignable_archetype<> Ret;
  59. struct T {
  60. T(const Ret&) { }
  61. T(boost::detail::dummy_constructor x) { }
  62. };
  63. typedef boost::null_archetype<> Tin;
  64. Ret operator+(const T&, const Tin&) {
  65. return Ret(dummy_cons);
  66. }
  67. }
  68. // for std::shuffle
  69. namespace shuffle
  70. {
  71. struct URBG {
  72. typedef unsigned int result_type;
  73. result_type BOOST_CONSTEXPR static min() { return 0; }
  74. result_type BOOST_CONSTEXPR static max() { return 1; }
  75. result_type operator()() { return 1; }
  76. };
  77. }
  78. // for std::inner_product
  79. namespace inner_prod
  80. {
  81. typedef boost::sgi_assignable_archetype<> RetAdd;
  82. typedef boost::sgi_assignable_archetype<> RetMult;
  83. struct T {
  84. T(const RetAdd&) { }
  85. T(boost::detail::dummy_constructor x) { }
  86. };
  87. typedef boost::null_archetype<int> Tin1;
  88. typedef boost::null_archetype<char> Tin2;
  89. }
  90. namespace boost { // so Koenig lookup will find
  91. inner_prod::RetMult
  92. operator*(const inner_prod::Tin1&, const inner_prod::Tin2&) {
  93. return inner_prod::RetMult(dummy_cons);
  94. }
  95. inner_prod::RetAdd
  96. operator+(const inner_prod::T&,
  97. const inner_prod::RetMult&) {
  98. return inner_prod::RetAdd(dummy_cons);
  99. }
  100. }
  101. // for std::partial_sum and adj_diff
  102. namespace part_sum
  103. {
  104. class T {
  105. public:
  106. typedef boost::sgi_assignable_archetype<> Ret;
  107. T(const Ret&) { }
  108. T(boost::detail::dummy_constructor x) { }
  109. private:
  110. T() { }
  111. };
  112. T::Ret operator+(const T&, const T&) {
  113. return T::Ret(dummy_cons);
  114. }
  115. T::Ret operator-(const T&, const T&) {
  116. return T::Ret(dummy_cons);
  117. }
  118. }
  119. // for std::power
  120. namespace power_stuff {
  121. struct monoid_archetype {
  122. monoid_archetype(boost::detail::dummy_constructor x) { }
  123. };
  124. boost::multipliable_archetype<monoid_archetype>
  125. identity_element
  126. (std::multiplies< boost::multipliable_archetype<monoid_archetype> >)
  127. {
  128. return boost::multipliable_archetype<monoid_archetype>(dummy_cons);
  129. }
  130. }
  131. struct tag1 { };
  132. struct tag2 { };
  133. int
  134. main()
  135. {
  136. using namespace boost;
  137. //===========================================================================
  138. // Non-mutating Algorithms
  139. {
  140. input_iterator_archetype< null_archetype<> > in;
  141. unary_function_archetype< null_archetype<> , null_archetype<> >
  142. f(dummy_cons);
  143. std::for_each(in, in, f);
  144. }
  145. // gcc bug
  146. {
  147. typedef equality_comparable2_first_archetype<> Left;
  148. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE< Left > in;
  149. equality_comparable2_second_archetype<> value(dummy_cons);
  150. in = std::find(in, in, value);
  151. }
  152. {
  153. typedef null_archetype<> T;
  154. input_iterator_archetype<T> in;
  155. unary_predicate_archetype<T> pred(dummy_cons);
  156. in = std::find_if(in, in, pred);
  157. }
  158. {
  159. forward_iterator_archetype< equality_comparable_archetype<> > fo;
  160. fo = std::adjacent_find(fo, fo);
  161. }
  162. {
  163. forward_iterator_archetype<
  164. convertible_to_archetype< null_archetype<> > > fo;
  165. binary_predicate_archetype<null_archetype<> , null_archetype<> >
  166. pred(dummy_cons);
  167. fo = std::adjacent_find(fo, fo, pred);
  168. }
  169. // gcc bug
  170. {
  171. typedef equal_op_first_archetype<> Left;
  172. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> in;
  173. typedef equal_op_second_archetype<> Right;
  174. forward_iterator_archetype<Right> fo;
  175. in = std::find_first_of(in, in, fo, fo);
  176. }
  177. {
  178. typedef equal_op_first_archetype<> Left;
  179. typedef BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> InIter;
  180. InIter in;
  181. function_requires< InputIterator<InIter> >();
  182. equal_op_second_archetype<> value(dummy_cons);
  183. std::iterator_traits<InIter>::difference_type
  184. n = std::count(in, in, value);
  185. ignore_unused_variable_warning(n);
  186. }
  187. {
  188. typedef input_iterator_archetype< null_archetype<> > InIter;
  189. InIter in;
  190. unary_predicate_archetype<null_archetype<> > pred(dummy_cons);
  191. std::iterator_traits<InIter>::difference_type
  192. n = std::count_if(in, in, pred);
  193. ignore_unused_variable_warning(n);
  194. }
  195. // gcc bug
  196. {
  197. typedef equal_op_first_archetype<> Left;
  198. typedef BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> InIter1;
  199. InIter1 in1;
  200. typedef equal_op_second_archetype<> Right;
  201. typedef BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Right> InIter2;
  202. InIter2 in2;
  203. std::pair<InIter1, InIter2> p = std::mismatch(in1, in1, in2);
  204. ignore_unused_variable_warning(p);
  205. }
  206. {
  207. typedef input_iterator_archetype<null_archetype<> > InIter;
  208. InIter in1, in2;
  209. binary_predicate_archetype<null_archetype<> , null_archetype<> >
  210. pred(dummy_cons);
  211. std::pair<InIter, InIter> p = std::mismatch(in1, in1, in2, pred);
  212. ignore_unused_variable_warning(p);
  213. }
  214. // gcc bug
  215. {
  216. typedef equality_comparable2_first_archetype<> Left;
  217. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Left> in1;
  218. typedef equality_comparable2_second_archetype<> Right;
  219. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Right> in2;
  220. bool b = std::equal(in1, in1, in2);
  221. ignore_unused_variable_warning(b);
  222. }
  223. {
  224. input_iterator_archetype< null_archetype<> >
  225. in1, in2;
  226. binary_predicate_archetype<null_archetype<> , null_archetype<> >
  227. pred(dummy_cons);
  228. bool b = std::equal(in1, in1, in2, pred);
  229. ignore_unused_variable_warning(b);
  230. }
  231. {
  232. typedef equality_comparable2_first_archetype<> Left;
  233. forward_iterator_archetype<Left> fo1;
  234. typedef equality_comparable2_second_archetype<> Right;
  235. forward_iterator_archetype<Right> fo2;
  236. fo1 = std::search(fo1, fo1, fo2, fo2);
  237. }
  238. {
  239. typedef equality_comparable2_first_archetype<
  240. convertible_to_archetype<null_archetype<> > > Left;
  241. forward_iterator_archetype<Left> fo1;
  242. typedef equality_comparable2_second_archetype<
  243. convertible_to_archetype<null_archetype<> > > Right;
  244. forward_iterator_archetype<Right> fo2;
  245. binary_predicate_archetype<null_archetype<> , null_archetype<> >
  246. pred(dummy_cons);
  247. fo1 = std::search(fo1, fo1, fo2, fo2, pred);
  248. }
  249. {
  250. typedef equality_comparable2_first_archetype<> Left;
  251. forward_iterator_archetype<Left> fo;
  252. equality_comparable2_second_archetype<> value(dummy_cons);
  253. int n = 1;
  254. fo = std::search_n(fo, fo, n, value);
  255. }
  256. {
  257. forward_iterator_archetype<
  258. convertible_to_archetype<null_archetype<> > > fo;
  259. convertible_to_archetype<null_archetype<> > value(dummy_cons);
  260. binary_predicate_archetype<null_archetype<> , null_archetype<> >
  261. pred(dummy_cons);
  262. int n = 1;
  263. fo = std::search_n(fo, fo, n, value, pred);
  264. }
  265. {
  266. typedef equality_comparable2_first_archetype<> Left;
  267. forward_iterator_archetype<Left> fo1;
  268. typedef equality_comparable2_second_archetype<null_archetype<> > Right;
  269. forward_iterator_archetype<Right> fo2;
  270. fo1 = std::find_end(fo1, fo1, fo2, fo2);
  271. }
  272. {
  273. // equality comparable required because find_end() calls search
  274. typedef equality_comparable2_first_archetype<
  275. convertible_to_archetype<null_archetype<> > > Left;
  276. forward_iterator_archetype<Left> fo1;
  277. typedef equality_comparable2_second_archetype<
  278. convertible_to_archetype<null_archetype<> > > Right;
  279. forward_iterator_archetype<Right> fo2;
  280. binary_predicate_archetype<null_archetype<> , null_archetype<> >
  281. pred(dummy_cons);
  282. fo1 = std::find_end(fo1, fo1, fo2, fo2, pred);
  283. }
  284. //===========================================================================
  285. // Mutating Algorithms
  286. {
  287. typedef null_archetype<> T;
  288. input_iterator_archetype<T> in;
  289. output_iterator_archetype<T> out(dummy_cons);
  290. out = std::copy(in, in, out);
  291. }
  292. {
  293. typedef assignable_archetype<> OutT;
  294. typedef convertible_to_archetype<OutT> InT;
  295. bidirectional_iterator_archetype<InT> bid_in;
  296. mutable_bidirectional_iterator_archetype<OutT> bid_out;
  297. bid_out = std::copy_backward(bid_in, bid_in, bid_out);
  298. }
  299. {
  300. sgi_assignable_archetype<> a(dummy_cons), b(dummy_cons);
  301. std::swap(a, b);
  302. }
  303. {
  304. typedef sgi_assignable_archetype<> T;
  305. mutable_forward_iterator_archetype<T> a, b;
  306. std::iter_swap(a, b);
  307. }
  308. #if 0
  309. {
  310. // fails on gcc 7.3 and clang 6.0
  311. typedef mutually_convertible_archetype<int> Tin;
  312. typedef mutually_convertible_archetype<char> Tout;
  313. mutable_forward_iterator_archetype<Tin> fi1;
  314. mutable_forward_iterator_archetype<Tout> fi2;
  315. fi2 = std::swap_ranges(fi1, fi1, fi2);
  316. }
  317. #endif
  318. {
  319. typedef null_archetype<int> Tin;
  320. typedef null_archetype<char> Tout;
  321. input_iterator_archetype<Tin> in;
  322. output_iterator_archetype<Tout> out(dummy_cons);
  323. unary_function_archetype<null_archetype<> ,
  324. convertible_to_archetype<Tout> > op(dummy_cons);
  325. out = std::transform(in, in, out, op);
  326. }
  327. {
  328. typedef null_archetype<int> Tin1;
  329. typedef null_archetype<char> Tin2;
  330. typedef null_archetype<double> Tout;
  331. input_iterator_archetype<Tin1> in1;
  332. input_iterator_archetype<Tin2> in2;
  333. output_iterator_archetype<Tout> out(dummy_cons);
  334. binary_function_archetype<Tin1, Tin2,
  335. convertible_to_archetype<Tout> > op(dummy_cons);
  336. out = std::transform(in1, in1, in2, out, op);
  337. }
  338. {
  339. typedef equality_comparable2_first_archetype<
  340. assignable_archetype<> > FT;
  341. mutable_forward_iterator_archetype<FT> fi;
  342. equality_comparable2_second_archetype<
  343. convertible_to_archetype<FT> > value(dummy_cons);
  344. std::replace(fi, fi, value, value);
  345. }
  346. {
  347. typedef null_archetype<> PredArg;
  348. typedef assignable_archetype<
  349. convertible_to_archetype<PredArg> > FT;
  350. mutable_forward_iterator_archetype<FT> fi;
  351. unary_predicate_archetype<PredArg> pred(dummy_cons);
  352. convertible_to_archetype<FT> value(dummy_cons);
  353. std::replace_if(fi, fi, pred, value);
  354. }
  355. #if !defined(BOOST_MSVC) || BOOST_WORKAROUND(BOOST_MSVC, > 1900)
  356. // fails on MSVC 2015 and earlier
  357. {
  358. // Issue, the use of ?: inside replace_copy() complicates things
  359. typedef equal_op_first_archetype<> Tin;
  360. typedef null_archetype<> Tout;
  361. typedef equal_op_second_archetype< convertible_to_archetype<Tout> > T;
  362. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin> in;
  363. output_iterator_archetype<Tout> out(dummy_cons);
  364. T value(dummy_cons);
  365. out = std::replace_copy(in, in, out, value, value);
  366. }
  367. {
  368. // The issue of ?: also affects this function
  369. typedef null_archetype<> Tout;
  370. typedef assignable_archetype< convertible_to_archetype<Tout> > Tin;
  371. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin> in;
  372. output_iterator_archetype<Tout> out(dummy_cons);
  373. unary_predicate_archetype<Tin> pred(dummy_cons);
  374. Tin value(dummy_cons);
  375. out = std::replace_copy_if(in, in, out, pred, value);
  376. }
  377. #endif
  378. {
  379. typedef assignable_archetype<> FT;
  380. mutable_forward_iterator_archetype<FT> fi;
  381. typedef convertible_to_archetype<FT> T;
  382. T value(dummy_cons);
  383. std::fill(fi, fi, value);
  384. }
  385. #if !defined(BOOST_MSVC) || BOOST_WORKAROUND(BOOST_MSVC, >= 1700)
  386. // fails on MSVC 2010
  387. {
  388. typedef null_archetype<> Tout;
  389. typedef convertible_to_archetype<Tout> T;
  390. output_iterator_archetype<Tout> out(dummy_cons);
  391. T value(dummy_cons);
  392. int n = 1;
  393. out = std::fill_n(out, n, value);
  394. }
  395. #endif
  396. {
  397. typedef assignable_archetype<> FT;
  398. typedef convertible_to_archetype<FT> Ret;
  399. mutable_forward_iterator_archetype<FT> fi;
  400. generator_archetype<Ret> gen;
  401. std::generate(fi, fi, gen);
  402. }
  403. {
  404. typedef assignable_archetype<> FT;
  405. typedef convertible_to_archetype<FT> Ret;
  406. mutable_forward_iterator_archetype<FT> fi;
  407. generator_archetype<Ret> gen;
  408. int n = 1;
  409. std::generate_n(fi, n, gen);
  410. }
  411. {
  412. typedef assignable_archetype< equality_comparable2_first_archetype<> > FT;
  413. typedef equality_comparable2_second_archetype<> T;
  414. mutable_forward_iterator_archetype<FT> fi;
  415. T value(dummy_cons);
  416. fi = std::remove(fi, fi, value);
  417. }
  418. {
  419. typedef assignable_archetype<> FT;
  420. mutable_forward_iterator_archetype<FT> fi;
  421. typedef null_archetype<> PredArg;
  422. unary_predicate_archetype<PredArg> pred(dummy_cons);
  423. fi = std::remove_if(fi, fi, pred);
  424. }
  425. // gcc bug
  426. {
  427. typedef null_archetype<> Tout;
  428. typedef equality_comparable2_first_archetype<
  429. convertible_to_archetype<Tout> > Tin;
  430. typedef equality_comparable2_second_archetype<> T;
  431. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin> in;
  432. output_iterator_archetype<Tout> out(dummy_cons);
  433. T value(dummy_cons);
  434. out = std::remove_copy(in, in, out, value);
  435. }
  436. {
  437. typedef null_archetype<> T;
  438. input_iterator_archetype<T> in;
  439. output_iterator_archetype<T> out(dummy_cons);
  440. unary_predicate_archetype<T> pred(dummy_cons);
  441. out = std::remove_copy_if(in, in, out, pred);
  442. }
  443. {
  444. typedef sgi_assignable_archetype< equality_comparable_archetype<> > T;
  445. mutable_forward_iterator_archetype<T> fi;
  446. fi = std::unique(fi, fi);
  447. }
  448. {
  449. typedef null_archetype<int> Arg1;
  450. typedef null_archetype<char> Arg2;
  451. typedef sgi_assignable_archetype<
  452. convertible_to_archetype<Arg1,
  453. convertible_to_archetype<Arg2> > > FT;
  454. mutable_forward_iterator_archetype<FT> fi;
  455. binary_predicate_archetype<Arg1, Arg2> pred(dummy_cons);
  456. fi = std::unique(fi, fi, pred);
  457. }
  458. // gcc bug
  459. {
  460. typedef equality_comparable_archetype< sgi_assignable_archetype<> > T;
  461. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<T> in;
  462. output_iterator_archetype<T> out(dummy_cons);
  463. out = std::unique_copy(in, in, out);
  464. }
  465. {
  466. typedef sgi_assignable_archetype<> T;
  467. input_iterator_archetype<T> in;
  468. output_iterator_archetype<T> out(dummy_cons);
  469. binary_predicate_archetype<T, T> pred(dummy_cons);
  470. out = std::unique_copy(in, in, out, pred);
  471. }
  472. {
  473. typedef sgi_assignable_archetype<> T;
  474. mutable_bidirectional_iterator_archetype<T> bi;
  475. std::reverse(bi, bi);
  476. }
  477. {
  478. typedef null_archetype<> Tout;
  479. typedef convertible_to_archetype<Tout> Tin;
  480. bidirectional_iterator_archetype<Tin> bi;
  481. output_iterator_archetype<Tout> out(dummy_cons);
  482. out = std::reverse_copy(bi, bi, out);
  483. }
  484. {
  485. typedef sgi_assignable_archetype<> T;
  486. mutable_forward_iterator_archetype<T> fi;
  487. // Issue, SGI STL is not have void return type, C++ standard does
  488. std::rotate(fi, fi, fi);
  489. }
  490. {
  491. typedef null_archetype<> Tout;
  492. typedef convertible_to_archetype<Tout> FT;
  493. forward_iterator_archetype<FT> fi;
  494. output_iterator_archetype<Tout> out(dummy_cons);
  495. out = std::rotate_copy(fi, fi, fi, out);
  496. }
  497. #ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE
  498. {
  499. typedef sgi_assignable_archetype<> T;
  500. mutable_random_access_iterator_archetype<T> ri;
  501. std::random_shuffle(ri, ri);
  502. }
  503. {
  504. typedef sgi_assignable_archetype<> T;
  505. mutable_random_access_iterator_archetype<T> ri;
  506. unary_function_archetype<std::ptrdiff_t, std::ptrdiff_t> ran(dummy_cons);
  507. std::random_shuffle(ri, ri, ran);
  508. }
  509. #else
  510. {
  511. typedef sgi_assignable_archetype<> T;
  512. mutable_random_access_iterator_archetype<T> ri;
  513. shuffle::URBG urbg;
  514. std::shuffle(ri, ri, urbg);
  515. }
  516. #endif
  517. {
  518. typedef null_archetype<> PredArg;
  519. typedef sgi_assignable_archetype<convertible_to_archetype<PredArg> > FT;
  520. mutable_bidirectional_iterator_archetype<FT> bi;
  521. unary_predicate_archetype<PredArg> pred(dummy_cons);
  522. bi = std::partition(bi, bi, pred);
  523. }
  524. #ifndef BOOST_MSVC
  525. {
  526. // fails on MSVC
  527. typedef null_archetype<> PredArg;
  528. typedef sgi_assignable_archetype<convertible_to_archetype<PredArg> > FT;
  529. mutable_forward_iterator_archetype<FT> fi;
  530. unary_predicate_archetype<PredArg> pred(dummy_cons);
  531. fi = std::stable_partition(fi, fi, pred);
  532. }
  533. #endif
  534. //===========================================================================
  535. // Sorting Algorithms
  536. {
  537. typedef sgi_assignable_archetype<
  538. less_than_comparable_archetype<> > T;
  539. mutable_random_access_iterator_archetype<T> ri;
  540. std::sort(ri, ri);
  541. }
  542. {
  543. typedef null_archetype<> Arg;
  544. typedef sgi_assignable_archetype<
  545. convertible_to_archetype<Arg> > T;
  546. mutable_random_access_iterator_archetype<T> ri;
  547. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  548. std::sort(ri, ri, comp);
  549. }
  550. {
  551. typedef less_than_comparable_archetype<
  552. sgi_assignable_archetype<> > ValueType;
  553. mutable_random_access_iterator_archetype<ValueType> ri;
  554. std::stable_sort(ri, ri);
  555. }
  556. {
  557. typedef null_archetype<> Arg;
  558. typedef sgi_assignable_archetype<
  559. convertible_to_archetype<Arg> > ValueType;
  560. mutable_random_access_iterator_archetype<ValueType> ri;
  561. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  562. std::stable_sort(ri, ri, comp);
  563. }
  564. {
  565. typedef sgi_assignable_archetype<
  566. less_than_comparable_archetype<> > T;
  567. mutable_random_access_iterator_archetype<T> ri;
  568. std::partial_sort(ri, ri, ri);
  569. }
  570. {
  571. typedef null_archetype<> Arg;
  572. typedef sgi_assignable_archetype<
  573. convertible_to_archetype<Arg> > T;
  574. mutable_random_access_iterator_archetype<T> ri;
  575. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  576. std::partial_sort(ri, ri, ri, comp);
  577. }
  578. // gcc bug
  579. {
  580. // This could be formulated so that the two iterators are not
  581. // required to have the same value type, but it is messy.
  582. typedef sgi_assignable_archetype<
  583. less_than_comparable_archetype<> > T;
  584. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<T> in;
  585. mutable_random_access_iterator_archetype<T> ri_out;
  586. ri_out = std::partial_sort_copy(in, in , ri_out, ri_out);
  587. }
  588. {
  589. typedef sgi_assignable_archetype<> T;
  590. input_iterator_archetype<T> in;
  591. mutable_random_access_iterator_archetype<T> ri_out;
  592. binary_predicate_archetype<T, T> comp(dummy_cons);
  593. ri_out = std::partial_sort_copy(in, in , ri_out, ri_out, comp);
  594. }
  595. {
  596. typedef sgi_assignable_archetype< less_than_comparable_archetype<> > T;
  597. mutable_random_access_iterator_archetype<T> ri;
  598. std::nth_element(ri, ri, ri);
  599. }
  600. {
  601. typedef null_archetype<int> Arg1;
  602. typedef null_archetype<char> Arg2;
  603. typedef sgi_assignable_archetype<
  604. convertible_to_archetype<Arg1,
  605. convertible_to_archetype<Arg2> > > T;
  606. mutable_random_access_iterator_archetype<T> ri;
  607. binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
  608. std::nth_element(ri, ri, ri, comp);
  609. }
  610. {
  611. #if defined(__KCC)
  612. // The KAI version of this uses a one-argument less-than function
  613. // object.
  614. typedef less_than_comparable_archetype<> T;
  615. typedef convertible_to_archetype<T> FT;
  616. #else
  617. typedef less_than_op_first_archetype<> FT;
  618. typedef less_than_op_second_archetype<> T;
  619. #endif
  620. forward_iterator_archetype<FT> fi;
  621. T value(dummy_cons);
  622. fi = std::lower_bound(fi, fi, value);
  623. }
  624. {
  625. typedef null_archetype<int> Arg1;
  626. typedef null_archetype<char> Arg2;
  627. typedef convertible_to_archetype<Arg1> FT;
  628. typedef convertible_to_archetype<Arg2> T;
  629. forward_iterator_archetype<FT> fi;
  630. T value(dummy_cons);
  631. binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
  632. fi = std::lower_bound(fi, fi, value, comp);
  633. }
  634. {
  635. #if defined(__KCC)
  636. typedef less_than_comparable_archetype<> T;
  637. typedef convertible_to_archetype<T> FT;
  638. #else
  639. // Note, order of T,FT is flipped from lower_bound
  640. typedef less_than_op_second_archetype<> FT;
  641. typedef less_than_op_first_archetype<> T;
  642. #endif
  643. forward_iterator_archetype<FT> fi;
  644. T value(dummy_cons);
  645. fi = std::upper_bound(fi, fi, value);
  646. }
  647. {
  648. typedef null_archetype<int> Arg1;
  649. typedef null_archetype<char> Arg2;
  650. // Note, order of T,FT is flipped from lower_bound
  651. typedef convertible_to_archetype<Arg1> T;
  652. typedef convertible_to_archetype<Arg2> FT;
  653. forward_iterator_archetype<FT> fi;
  654. T value(dummy_cons);
  655. binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
  656. fi = std::upper_bound(fi, fi, value, comp);
  657. }
  658. #if !defined(BOOST_MSVC) || BOOST_WORKAROUND(BOOST_MSVC, >= 1900)
  659. // Fails on MSVC 2013 and earlier
  660. {
  661. #if defined(__KCC)
  662. typedef less_than_comparable_archetype<> T;
  663. typedef convertible_to_archetype<T> FT;
  664. #else
  665. typedef less_than_op_first_archetype<
  666. less_than_op_second_archetype< null_archetype<>, optag2>, optag1> FT;
  667. typedef less_than_op_second_archetype<
  668. less_than_op_first_archetype< null_archetype<>, optag2>, optag1> T;
  669. #endif
  670. typedef forward_iterator_archetype<FT> FIter;
  671. FIter fi;
  672. T value(dummy_cons);
  673. std::pair<FIter,FIter> p = std::equal_range(fi, fi, value);
  674. ignore_unused_variable_warning(p);
  675. }
  676. #endif
  677. {
  678. typedef null_archetype<int> Arg1;
  679. typedef null_archetype<char> Arg2;
  680. typedef convertible_to_archetype<Arg1,
  681. convertible_to_archetype<Arg2> > FT;
  682. typedef convertible_to_archetype<Arg2,
  683. convertible_to_archetype<Arg1> > T;
  684. typedef forward_iterator_archetype<FT> FIter;
  685. FIter fi;
  686. T value(dummy_cons);
  687. binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
  688. std::pair<FIter,FIter> p = std::equal_range(fi, fi, value, comp);
  689. ignore_unused_variable_warning(p);
  690. }
  691. {
  692. #if defined(__KCC)
  693. typedef less_than_op_first_archetype< less_than_comparable_archetype<> > T;
  694. typedef less_than_op_second_archetype< convertible_to_archetype<T> > FT;
  695. #else
  696. typedef less_than_op_first_archetype<
  697. less_than_op_second_archetype<null_archetype<>, optag2>, optag1> FT;
  698. typedef less_than_op_second_archetype<
  699. less_than_op_first_archetype<null_archetype<>, optag2>, optag1> T;
  700. #endif
  701. forward_iterator_archetype<FT> fi;
  702. T value(dummy_cons);
  703. bool b = std::binary_search(fi, fi, value);
  704. ignore_unused_variable_warning(b);
  705. }
  706. {
  707. typedef null_archetype<int> Arg1;
  708. typedef null_archetype<char> Arg2;
  709. typedef convertible_to_archetype<Arg1,
  710. convertible_to_archetype<Arg2> > FT;
  711. typedef convertible_to_archetype<Arg2,
  712. convertible_to_archetype<Arg1> > T;
  713. typedef forward_iterator_archetype<FT> FIter;
  714. FIter fi;
  715. T value(dummy_cons);
  716. binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
  717. bool b = std::binary_search(fi, fi, value, comp);
  718. ignore_unused_variable_warning(b);
  719. }
  720. {
  721. typedef null_archetype<> Tout;
  722. typedef less_than_op_first_archetype<
  723. less_than_op_second_archetype<
  724. convertible_to_archetype<Tout>, optag2>, optag1 > Tin1;
  725. typedef less_than_op_second_archetype<
  726. less_than_op_first_archetype<
  727. convertible_to_archetype<Tout>, optag2> ,optag1> Tin2;
  728. // gcc bug
  729. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin1> in1;
  730. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin2> in2;
  731. output_iterator_archetype<Tout> out(dummy_cons);
  732. out = std::merge(in1, in1, in2, in2, out);
  733. out = std::set_union(in1, in1, in2, in2, out);
  734. out = std::set_intersection(in1, in1, in2, in2, out);
  735. out = std::set_difference(in1, in1, in2, in2, out);
  736. out = std::set_symmetric_difference(in1, in1, in2, in2, out);
  737. }
  738. {
  739. typedef null_archetype<> T;
  740. input_iterator_archetype<T> in1;
  741. input_iterator_archetype<T,2> in2;
  742. output_iterator_archetype<T> out(dummy_cons);
  743. binary_predicate_archetype<T, T> comp(dummy_cons);
  744. out = std::merge(in1, in1, in2, in2, out, comp);
  745. out = std::set_union(in1, in1, in2, in2, out, comp);
  746. out = std::set_intersection(in1, in1, in2, in2, out, comp);
  747. out = std::set_difference(in1, in1, in2, in2, out, comp);
  748. out = std::set_symmetric_difference(in1, in1, in2, in2, out, comp);
  749. }
  750. {
  751. typedef sgi_assignable_archetype<
  752. less_than_comparable_archetype<> > T;
  753. mutable_bidirectional_iterator_archetype<T> bi;
  754. std::inplace_merge(bi, bi, bi);
  755. }
  756. {
  757. typedef null_archetype<> Arg;
  758. typedef sgi_assignable_archetype<
  759. convertible_to_archetype<Arg> > T;
  760. mutable_bidirectional_iterator_archetype<T> bi;
  761. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  762. std::inplace_merge(bi, bi, bi, comp);
  763. }
  764. // gcc bug
  765. {
  766. typedef less_than_op_first_archetype<
  767. less_than_op_second_archetype<null_archetype<>, optag1>, optag2> Tin1;
  768. typedef less_than_op_second_archetype<
  769. less_than_op_first_archetype<null_archetype<>, optag1>, optag2> Tin2;
  770. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin1> in1;
  771. BOOST_CONCEPT_CHECK_COMPATIBLE_INPUT_ITERATOR_ARCHETYPE<Tin2> in2;
  772. bool b = std::includes(in1, in1, in2, in2);
  773. b = std::lexicographical_compare(in1, in1, in2, in2);
  774. ignore_unused_variable_warning(b);
  775. }
  776. {
  777. typedef null_archetype<int> Tin;
  778. input_iterator_archetype<Tin> in1;
  779. input_iterator_archetype<Tin,1> in2;
  780. binary_predicate_archetype<Tin, Tin> comp(dummy_cons);
  781. bool b = std::includes(in1, in1, in2, in2, comp);
  782. b = std::lexicographical_compare(in1, in1, in2, in2, comp);
  783. ignore_unused_variable_warning(b);
  784. }
  785. {
  786. typedef sgi_assignable_archetype<
  787. less_than_comparable_archetype<> > T;
  788. mutable_random_access_iterator_archetype<T> ri;
  789. std::push_heap(ri, ri);
  790. std::pop_heap(ri, ri);
  791. std::make_heap(ri, ri);
  792. std::sort_heap(ri, ri);
  793. }
  794. {
  795. typedef null_archetype<> Arg;
  796. typedef sgi_assignable_archetype<
  797. convertible_to_archetype<Arg> > T;
  798. mutable_random_access_iterator_archetype<T> ri;
  799. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  800. std::push_heap(ri, ri, comp);
  801. std::pop_heap(ri, ri, comp);
  802. std::make_heap(ri, ri, comp);
  803. std::sort_heap(ri, ri, comp);
  804. }
  805. {
  806. typedef less_than_comparable_archetype<> T;
  807. T a(dummy_cons), b(dummy_cons);
  808. BOOST_USING_STD_MIN();
  809. BOOST_USING_STD_MAX();
  810. const T& c = min BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
  811. const T& d = max BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
  812. ignore_unused_variable_warning(c);
  813. ignore_unused_variable_warning(d);
  814. }
  815. {
  816. typedef null_archetype<> Arg;
  817. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  818. typedef convertible_to_archetype<Arg> T;
  819. T a(dummy_cons), b(dummy_cons);
  820. BOOST_USING_STD_MIN();
  821. BOOST_USING_STD_MAX();
  822. const T& c = min BOOST_PREVENT_MACRO_SUBSTITUTION(a, b, comp);
  823. const T& d = max BOOST_PREVENT_MACRO_SUBSTITUTION(a, b, comp);
  824. ignore_unused_variable_warning(c);
  825. ignore_unused_variable_warning(d);
  826. }
  827. {
  828. typedef less_than_comparable_archetype<> T;
  829. forward_iterator_archetype<T> fi;
  830. fi = std::min_element(fi, fi);
  831. fi = std::max_element(fi, fi);
  832. }
  833. {
  834. typedef null_archetype<> Arg;
  835. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  836. typedef convertible_to_archetype<Arg> T;
  837. forward_iterator_archetype<T> fi;
  838. fi = std::min_element(fi, fi, comp);
  839. fi = std::max_element(fi, fi, comp);
  840. }
  841. {
  842. typedef sgi_assignable_archetype<
  843. less_than_comparable_archetype<> > T;
  844. mutable_bidirectional_iterator_archetype<T> bi;
  845. bool b = std::next_permutation(bi, bi);
  846. b = std::prev_permutation(bi, bi);
  847. ignore_unused_variable_warning(b);
  848. }
  849. {
  850. typedef null_archetype<> Arg;
  851. binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
  852. typedef sgi_assignable_archetype<
  853. convertible_to_archetype<Arg> > T;
  854. mutable_bidirectional_iterator_archetype<T> bi;
  855. bool b = std::next_permutation(bi, bi, comp);
  856. b = std::prev_permutation(bi, bi, comp);
  857. ignore_unused_variable_warning(b);
  858. }
  859. //===========================================================================
  860. // Generalized Numeric Algorithms
  861. {
  862. // Bummer, couldn't use plus_op because of a problem with
  863. // mutually recursive types.
  864. input_iterator_archetype<accum::Tin> in;
  865. accum::T init(dummy_cons);
  866. init = std::accumulate(in, in, init);
  867. }
  868. {
  869. typedef null_archetype<int> Arg1;
  870. typedef null_archetype<char> Arg2;
  871. typedef sgi_assignable_archetype<
  872. convertible_to_archetype<Arg1> > T;
  873. typedef convertible_to_archetype<T> Ret;
  874. input_iterator_archetype<Arg2> in;
  875. T init(dummy_cons);
  876. binary_function_archetype<Arg1, Arg2, Ret> op(dummy_cons);
  877. init = std::accumulate(in, in, init, op);
  878. }
  879. {
  880. input_iterator_archetype<inner_prod::Tin1> in1;
  881. input_iterator_archetype<inner_prod::Tin2> in2;
  882. inner_prod::T init(dummy_cons);
  883. init = std::inner_product(in1, in1, in2, init);
  884. }
  885. {
  886. typedef null_archetype<int> MultArg1;
  887. typedef null_archetype<char> MultArg2;
  888. typedef null_archetype<short> AddArg1;
  889. typedef null_archetype<long> AddArg2;
  890. typedef sgi_assignable_archetype<
  891. convertible_to_archetype<AddArg1> > T;
  892. typedef convertible_to_archetype<AddArg2> RetMult;
  893. typedef convertible_to_archetype<T> RetAdd;
  894. input_iterator_archetype<MultArg1> in1;
  895. input_iterator_archetype<MultArg2> in2;
  896. T init(dummy_cons);
  897. binary_function_archetype<MultArg1, MultArg2, RetMult> mult_op(dummy_cons);
  898. binary_function_archetype<AddArg1, AddArg2, RetAdd> add_op(dummy_cons);
  899. init = std::inner_product(in1, in1, in2, init, add_op, mult_op);
  900. }
  901. {
  902. input_iterator_archetype<part_sum::T> in;
  903. output_iterator_archetype<part_sum::T> out(dummy_cons);
  904. out = std::partial_sum(in, in, out);
  905. }
  906. {
  907. typedef sgi_assignable_archetype<> T;
  908. input_iterator_archetype<T> in;
  909. output_iterator_archetype<T> out(dummy_cons);
  910. binary_function_archetype<T, T, T> add_op(dummy_cons);
  911. out = std::partial_sum(in, in, out, add_op);
  912. binary_function_archetype<T, T, T> subtract_op(dummy_cons);
  913. out = std::adjacent_difference(in, in, out, subtract_op);
  914. }
  915. {
  916. input_iterator_archetype<part_sum::T> in;
  917. output_iterator_archetype<part_sum::T> out(dummy_cons);
  918. out = std::adjacent_difference(in, in, out);
  919. }
  920. return 0;
  921. }