concept_check.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. //
  2. // (C) Copyright Jeremy Siek 2000.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Revision History:
  8. // 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek)
  9. // 02 April 2001: Removed limits header altogether. (Jeremy Siek)
  10. // 01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
  11. //
  12. // See http://www.boost.org/libs/concept_check for documentation.
  13. #ifndef BOOST_CONCEPT_CHECKS_HPP
  14. # define BOOST_CONCEPT_CHECKS_HPP
  15. # include <boost/concept/assert.hpp>
  16. # include <boost/iterator.hpp>
  17. # include <boost/type_traits/conversion_traits.hpp>
  18. # include <utility>
  19. # include <boost/type_traits/is_same.hpp>
  20. # include <boost/type_traits/is_void.hpp>
  21. # include <boost/mpl/assert.hpp>
  22. # include <boost/mpl/bool.hpp>
  23. # include <boost/detail/workaround.hpp>
  24. # include <boost/detail/iterator.hpp>
  25. # include <boost/concept/usage.hpp>
  26. # include <boost/concept/detail/concept_def.hpp>
  27. namespace boost
  28. {
  29. //
  30. // Backward compatibility
  31. //
  32. template <class Model>
  33. inline void function_requires(Model* = 0)
  34. {
  35. BOOST_CONCEPT_ASSERT((Model));
  36. }
  37. template <class T> inline void ignore_unused_variable_warning(T const&) {}
  38. # define BOOST_CLASS_REQUIRE(type_var, ns, concept) \
  39. BOOST_CONCEPT_ASSERT((ns::concept<type_var>))
  40. # define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \
  41. BOOST_CONCEPT_ASSERT((ns::concept<type_var1,type_var2>))
  42. # define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \
  43. BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3>))
  44. # define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \
  45. BOOST_CONCEPT_ASSERT((ns::concept<tv1,tv2,tv3,tv4>))
  46. //
  47. // Begin concept definitions
  48. //
  49. BOOST_concept(Integer, (T))
  50. {
  51. BOOST_CONCEPT_USAGE(Integer)
  52. {
  53. x.error_type_must_be_an_integer_type();
  54. }
  55. private:
  56. T x;
  57. };
  58. template <> struct Integer<signed char> {};
  59. template <> struct Integer<unsigned char> {};
  60. template <> struct Integer<short> {};
  61. template <> struct Integer<unsigned short> {};
  62. template <> struct Integer<int> {};
  63. template <> struct Integer<unsigned int> {};
  64. template <> struct Integer<long> {};
  65. template <> struct Integer<unsigned long> {};
  66. # if defined(BOOST_HAS_LONG_LONG)
  67. template <> struct Integer< ::boost::long_long_type> {};
  68. template <> struct Integer< ::boost::ulong_long_type> {};
  69. # elif defined(BOOST_HAS_MS_INT64)
  70. template <> struct Integer<__int64> {};
  71. template <> struct Integer<unsigned __int64> {};
  72. # endif
  73. BOOST_concept(SignedInteger,(T)) {
  74. BOOST_CONCEPT_USAGE(SignedInteger) {
  75. x.error_type_must_be_a_signed_integer_type();
  76. }
  77. private:
  78. T x;
  79. };
  80. template <> struct SignedInteger<signed char> { };
  81. template <> struct SignedInteger<short> {};
  82. template <> struct SignedInteger<int> {};
  83. template <> struct SignedInteger<long> {};
  84. # if defined(BOOST_HAS_LONG_LONG)
  85. template <> struct SignedInteger< ::boost::long_long_type> {};
  86. # elif defined(BOOST_HAS_MS_INT64)
  87. template <> struct SignedInteger<__int64> {};
  88. # endif
  89. BOOST_concept(UnsignedInteger,(T)) {
  90. BOOST_CONCEPT_USAGE(UnsignedInteger) {
  91. x.error_type_must_be_an_unsigned_integer_type();
  92. }
  93. private:
  94. T x;
  95. };
  96. template <> struct UnsignedInteger<unsigned char> {};
  97. template <> struct UnsignedInteger<unsigned short> {};
  98. template <> struct UnsignedInteger<unsigned int> {};
  99. template <> struct UnsignedInteger<unsigned long> {};
  100. # if defined(BOOST_HAS_LONG_LONG)
  101. template <> struct UnsignedInteger< ::boost::ulong_long_type> {};
  102. # elif defined(BOOST_HAS_MS_INT64)
  103. template <> struct UnsignedInteger<unsigned __int64> {};
  104. # endif
  105. //===========================================================================
  106. // Basic Concepts
  107. BOOST_concept(DefaultConstructible,(TT))
  108. {
  109. BOOST_CONCEPT_USAGE(DefaultConstructible) {
  110. TT a; // require default constructor
  111. ignore_unused_variable_warning(a);
  112. }
  113. };
  114. BOOST_concept(Assignable,(TT))
  115. {
  116. BOOST_CONCEPT_USAGE(Assignable) {
  117. #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
  118. a = a; // require assignment operator
  119. #endif
  120. const_constraints(a);
  121. }
  122. private:
  123. void const_constraints(const TT& b) {
  124. #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
  125. a = b; // const required for argument to assignment
  126. #else
  127. ignore_unused_variable_warning(b);
  128. #endif
  129. }
  130. private:
  131. TT a;
  132. };
  133. BOOST_concept(CopyConstructible,(TT))
  134. {
  135. BOOST_CONCEPT_USAGE(CopyConstructible) {
  136. TT a(b); // require copy constructor
  137. TT* ptr = &a; // require address of operator
  138. const_constraints(a);
  139. ignore_unused_variable_warning(ptr);
  140. }
  141. private:
  142. void const_constraints(const TT& a) {
  143. TT c(a); // require const copy constructor
  144. const TT* ptr = &a; // require const address of operator
  145. ignore_unused_variable_warning(c);
  146. ignore_unused_variable_warning(ptr);
  147. }
  148. TT b;
  149. };
  150. #if (defined _MSC_VER)
  151. # pragma warning( push )
  152. # pragma warning( disable : 4510 ) // default constructor could not be generated
  153. # pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required
  154. #endif
  155. // The SGI STL version of Assignable requires copy constructor and operator=
  156. BOOST_concept(SGIAssignable,(TT))
  157. {
  158. BOOST_CONCEPT_USAGE(SGIAssignable) {
  159. TT b(a);
  160. #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
  161. a = a; // require assignment operator
  162. #endif
  163. const_constraints(a);
  164. ignore_unused_variable_warning(b);
  165. }
  166. private:
  167. void const_constraints(const TT& b) {
  168. TT c(b);
  169. #if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL
  170. a = b; // const required for argument to assignment
  171. #endif
  172. ignore_unused_variable_warning(c);
  173. }
  174. TT a;
  175. };
  176. #if (defined _MSC_VER)
  177. # pragma warning( pop )
  178. #endif
  179. BOOST_concept(Convertible,(X)(Y))
  180. {
  181. BOOST_CONCEPT_USAGE(Convertible) {
  182. Y y = x;
  183. ignore_unused_variable_warning(y);
  184. }
  185. private:
  186. X x;
  187. };
  188. // The C++ standard requirements for many concepts talk about return
  189. // types that must be "convertible to bool". The problem with this
  190. // requirement is that it leaves the door open for evil proxies that
  191. // define things like operator|| with strange return types. Two
  192. // possible solutions are:
  193. // 1) require the return type to be exactly bool
  194. // 2) stay with convertible to bool, and also
  195. // specify stuff about all the logical operators.
  196. // For now we just test for convertible to bool.
  197. template <class TT>
  198. void require_boolean_expr(const TT& t) {
  199. bool x = t;
  200. ignore_unused_variable_warning(x);
  201. }
  202. BOOST_concept(EqualityComparable,(TT))
  203. {
  204. BOOST_CONCEPT_USAGE(EqualityComparable) {
  205. require_boolean_expr(a == b);
  206. require_boolean_expr(a != b);
  207. }
  208. private:
  209. TT a, b;
  210. };
  211. BOOST_concept(LessThanComparable,(TT))
  212. {
  213. BOOST_CONCEPT_USAGE(LessThanComparable) {
  214. require_boolean_expr(a < b);
  215. }
  216. private:
  217. TT a, b;
  218. };
  219. // This is equivalent to SGI STL's LessThanComparable.
  220. BOOST_concept(Comparable,(TT))
  221. {
  222. BOOST_CONCEPT_USAGE(Comparable) {
  223. require_boolean_expr(a < b);
  224. require_boolean_expr(a > b);
  225. require_boolean_expr(a <= b);
  226. require_boolean_expr(a >= b);
  227. }
  228. private:
  229. TT a, b;
  230. };
  231. #define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \
  232. BOOST_concept(NAME, (First)(Second)) \
  233. { \
  234. BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
  235. private: \
  236. bool constraints_() { return a OP b; } \
  237. First a; \
  238. Second b; \
  239. }
  240. #define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \
  241. BOOST_concept(NAME, (Ret)(First)(Second)) \
  242. { \
  243. BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \
  244. private: \
  245. Ret constraints_() { return a OP b; } \
  246. First a; \
  247. Second b; \
  248. }
  249. BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp);
  250. BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp);
  251. BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp);
  252. BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp);
  253. BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp);
  254. BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp);
  255. BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp);
  256. BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp);
  257. BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp);
  258. BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp);
  259. BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp);
  260. //===========================================================================
  261. // Function Object Concepts
  262. BOOST_concept(Generator,(Func)(Return))
  263. {
  264. BOOST_CONCEPT_USAGE(Generator) { test(is_void<Return>()); }
  265. private:
  266. void test(boost::mpl::false_)
  267. {
  268. // Do we really want a reference here?
  269. const Return& r = f();
  270. ignore_unused_variable_warning(r);
  271. }
  272. void test(boost::mpl::true_)
  273. {
  274. f();
  275. }
  276. Func f;
  277. };
  278. BOOST_concept(UnaryFunction,(Func)(Return)(Arg))
  279. {
  280. BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void<Return>()); }
  281. private:
  282. void test(boost::mpl::false_)
  283. {
  284. f(arg); // "priming the pump" this way keeps msvc6 happy (ICE)
  285. Return r = f(arg);
  286. ignore_unused_variable_warning(r);
  287. }
  288. void test(boost::mpl::true_)
  289. {
  290. f(arg);
  291. }
  292. Func f;
  293. Arg arg;
  294. };
  295. BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
  296. {
  297. BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
  298. private:
  299. void test(boost::mpl::false_)
  300. {
  301. f(first,second);
  302. Return r = f(first, second); // require operator()
  303. (void)r;
  304. }
  305. void test(boost::mpl::true_)
  306. {
  307. f(first,second);
  308. }
  309. Func f;
  310. First first;
  311. Second second;
  312. };
  313. BOOST_concept(UnaryPredicate,(Func)(Arg))
  314. {
  315. BOOST_CONCEPT_USAGE(UnaryPredicate) {
  316. require_boolean_expr(f(arg)); // require operator() returning bool
  317. }
  318. private:
  319. Func f;
  320. Arg arg;
  321. };
  322. BOOST_concept(BinaryPredicate,(Func)(First)(Second))
  323. {
  324. BOOST_CONCEPT_USAGE(BinaryPredicate) {
  325. require_boolean_expr(f(a, b)); // require operator() returning bool
  326. }
  327. private:
  328. Func f;
  329. First a;
  330. Second b;
  331. };
  332. // use this when functor is used inside a container class like std::set
  333. BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
  334. : BinaryPredicate<Func, First, Second>
  335. {
  336. BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
  337. const_constraints(f);
  338. }
  339. private:
  340. void const_constraints(const Func& fun) {
  341. // operator() must be a const member function
  342. require_boolean_expr(fun(a, b));
  343. }
  344. Func f;
  345. First a;
  346. Second b;
  347. };
  348. BOOST_concept(AdaptableGenerator,(Func)(Return))
  349. : Generator<Func, typename Func::result_type>
  350. {
  351. typedef typename Func::result_type result_type;
  352. BOOST_CONCEPT_USAGE(AdaptableGenerator)
  353. {
  354. BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
  355. }
  356. };
  357. BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
  358. : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
  359. {
  360. typedef typename Func::argument_type argument_type;
  361. typedef typename Func::result_type result_type;
  362. ~AdaptableUnaryFunction()
  363. {
  364. BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
  365. BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
  366. }
  367. };
  368. BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
  369. : BinaryFunction<
  370. Func
  371. , typename Func::result_type
  372. , typename Func::first_argument_type
  373. , typename Func::second_argument_type
  374. >
  375. {
  376. typedef typename Func::first_argument_type first_argument_type;
  377. typedef typename Func::second_argument_type second_argument_type;
  378. typedef typename Func::result_type result_type;
  379. ~AdaptableBinaryFunction()
  380. {
  381. BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
  382. BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
  383. BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
  384. }
  385. };
  386. BOOST_concept(AdaptablePredicate,(Func)(Arg))
  387. : UnaryPredicate<Func, Arg>
  388. , AdaptableUnaryFunction<Func, bool, Arg>
  389. {
  390. };
  391. BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
  392. : BinaryPredicate<Func, First, Second>
  393. , AdaptableBinaryFunction<Func, bool, First, Second>
  394. {
  395. };
  396. //===========================================================================
  397. // Iterator Concepts
  398. BOOST_concept(InputIterator,(TT))
  399. : Assignable<TT>
  400. , EqualityComparable<TT>
  401. {
  402. typedef typename boost::detail::iterator_traits<TT>::value_type value_type;
  403. typedef typename boost::detail::iterator_traits<TT>::difference_type difference_type;
  404. typedef typename boost::detail::iterator_traits<TT>::reference reference;
  405. typedef typename boost::detail::iterator_traits<TT>::pointer pointer;
  406. typedef typename boost::detail::iterator_traits<TT>::iterator_category iterator_category;
  407. BOOST_CONCEPT_USAGE(InputIterator)
  408. {
  409. BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
  410. BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
  411. TT j(i);
  412. (void)*i; // require dereference operator
  413. ++j; // require preincrement operator
  414. i++; // require postincrement operator
  415. }
  416. private:
  417. TT i;
  418. };
  419. BOOST_concept(OutputIterator,(TT)(ValueT))
  420. : Assignable<TT>
  421. {
  422. BOOST_CONCEPT_USAGE(OutputIterator) {
  423. ++i; // require preincrement operator
  424. i++; // require postincrement operator
  425. *i++ = t; // require postincrement and assignment
  426. }
  427. private:
  428. TT i, j;
  429. ValueT t;
  430. };
  431. BOOST_concept(ForwardIterator,(TT))
  432. : InputIterator<TT>
  433. {
  434. BOOST_CONCEPT_USAGE(ForwardIterator)
  435. {
  436. BOOST_CONCEPT_ASSERT((Convertible<
  437. BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
  438. , std::forward_iterator_tag
  439. >));
  440. typename InputIterator<TT>::reference r = *i;
  441. ignore_unused_variable_warning(r);
  442. }
  443. private:
  444. TT i;
  445. };
  446. BOOST_concept(Mutable_ForwardIterator,(TT))
  447. : ForwardIterator<TT>
  448. {
  449. BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
  450. *i++ = *i; // require postincrement and assignment
  451. }
  452. private:
  453. TT i;
  454. };
  455. BOOST_concept(BidirectionalIterator,(TT))
  456. : ForwardIterator<TT>
  457. {
  458. BOOST_CONCEPT_USAGE(BidirectionalIterator)
  459. {
  460. BOOST_CONCEPT_ASSERT((Convertible<
  461. BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
  462. , std::bidirectional_iterator_tag
  463. >));
  464. --i; // require predecrement operator
  465. i--; // require postdecrement operator
  466. }
  467. private:
  468. TT i;
  469. };
  470. BOOST_concept(Mutable_BidirectionalIterator,(TT))
  471. : BidirectionalIterator<TT>
  472. , Mutable_ForwardIterator<TT>
  473. {
  474. BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
  475. {
  476. *i-- = *i; // require postdecrement and assignment
  477. }
  478. private:
  479. TT i;
  480. };
  481. BOOST_concept(RandomAccessIterator,(TT))
  482. : BidirectionalIterator<TT>
  483. , Comparable<TT>
  484. {
  485. BOOST_CONCEPT_USAGE(RandomAccessIterator)
  486. {
  487. BOOST_CONCEPT_ASSERT((Convertible<
  488. BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
  489. , std::random_access_iterator_tag
  490. >));
  491. i += n; // require assignment addition operator
  492. i = i + n; i = n + i; // require addition with difference type
  493. i -= n; // require assignment subtraction operator
  494. i = i - n; // require subtraction with difference type
  495. n = i - j; // require difference operator
  496. (void)i[n]; // require element access operator
  497. }
  498. private:
  499. TT a, b;
  500. TT i, j;
  501. typename boost::detail::iterator_traits<TT>::difference_type n;
  502. };
  503. BOOST_concept(Mutable_RandomAccessIterator,(TT))
  504. : RandomAccessIterator<TT>
  505. , Mutable_BidirectionalIterator<TT>
  506. {
  507. BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
  508. {
  509. i[n] = *i; // require element access and assignment
  510. }
  511. private:
  512. TT i;
  513. typename boost::detail::iterator_traits<TT>::difference_type n;
  514. };
  515. //===========================================================================
  516. // Container s
  517. BOOST_concept(Container,(C))
  518. : Assignable<C>
  519. {
  520. typedef typename C::value_type value_type;
  521. typedef typename C::difference_type difference_type;
  522. typedef typename C::size_type size_type;
  523. typedef typename C::const_reference const_reference;
  524. typedef typename C::const_pointer const_pointer;
  525. typedef typename C::const_iterator const_iterator;
  526. BOOST_CONCEPT_USAGE(Container)
  527. {
  528. BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
  529. const_constraints(c);
  530. }
  531. private:
  532. void const_constraints(const C& cc) {
  533. i = cc.begin();
  534. i = cc.end();
  535. n = cc.size();
  536. n = cc.max_size();
  537. b = cc.empty();
  538. }
  539. C c;
  540. bool b;
  541. const_iterator i;
  542. size_type n;
  543. };
  544. BOOST_concept(Mutable_Container,(C))
  545. : Container<C>
  546. {
  547. typedef typename C::reference reference;
  548. typedef typename C::iterator iterator;
  549. typedef typename C::pointer pointer;
  550. BOOST_CONCEPT_USAGE(Mutable_Container)
  551. {
  552. BOOST_CONCEPT_ASSERT((
  553. Assignable<typename Mutable_Container::value_type>));
  554. BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
  555. i = c.begin();
  556. i = c.end();
  557. c.swap(c2);
  558. }
  559. private:
  560. iterator i;
  561. C c, c2;
  562. };
  563. BOOST_concept(ForwardContainer,(C))
  564. : Container<C>
  565. {
  566. BOOST_CONCEPT_USAGE(ForwardContainer)
  567. {
  568. BOOST_CONCEPT_ASSERT((
  569. ForwardIterator<
  570. typename ForwardContainer::const_iterator
  571. >));
  572. }
  573. };
  574. BOOST_concept(Mutable_ForwardContainer,(C))
  575. : ForwardContainer<C>
  576. , Mutable_Container<C>
  577. {
  578. BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
  579. {
  580. BOOST_CONCEPT_ASSERT((
  581. Mutable_ForwardIterator<
  582. typename Mutable_ForwardContainer::iterator
  583. >));
  584. }
  585. };
  586. BOOST_concept(ReversibleContainer,(C))
  587. : ForwardContainer<C>
  588. {
  589. typedef typename
  590. C::const_reverse_iterator
  591. const_reverse_iterator;
  592. BOOST_CONCEPT_USAGE(ReversibleContainer)
  593. {
  594. BOOST_CONCEPT_ASSERT((
  595. BidirectionalIterator<
  596. typename ReversibleContainer::const_iterator>));
  597. BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
  598. const_constraints(c);
  599. }
  600. private:
  601. void const_constraints(const C& cc)
  602. {
  603. const_reverse_iterator i = cc.rbegin();
  604. i = cc.rend();
  605. }
  606. C c;
  607. };
  608. BOOST_concept(Mutable_ReversibleContainer,(C))
  609. : Mutable_ForwardContainer<C>
  610. , ReversibleContainer<C>
  611. {
  612. typedef typename C::reverse_iterator reverse_iterator;
  613. BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
  614. {
  615. typedef typename Mutable_ForwardContainer<C>::iterator iterator;
  616. BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
  617. BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
  618. reverse_iterator i = c.rbegin();
  619. i = c.rend();
  620. }
  621. private:
  622. C c;
  623. };
  624. BOOST_concept(RandomAccessContainer,(C))
  625. : ReversibleContainer<C>
  626. {
  627. typedef typename C::size_type size_type;
  628. typedef typename C::const_reference const_reference;
  629. BOOST_CONCEPT_USAGE(RandomAccessContainer)
  630. {
  631. BOOST_CONCEPT_ASSERT((
  632. RandomAccessIterator<
  633. typename RandomAccessContainer::const_iterator
  634. >));
  635. const_constraints(c);
  636. }
  637. private:
  638. void const_constraints(const C& cc)
  639. {
  640. const_reference r = cc[n];
  641. ignore_unused_variable_warning(r);
  642. }
  643. C c;
  644. size_type n;
  645. };
  646. BOOST_concept(Mutable_RandomAccessContainer,(C))
  647. : Mutable_ReversibleContainer<C>
  648. , RandomAccessContainer<C>
  649. {
  650. private:
  651. typedef Mutable_RandomAccessContainer self;
  652. public:
  653. BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
  654. {
  655. BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
  656. BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
  657. typename self::reference r = c[i];
  658. ignore_unused_variable_warning(r);
  659. }
  660. private:
  661. typename Mutable_ReversibleContainer<C>::size_type i;
  662. C c;
  663. };
  664. // A Sequence is inherently mutable
  665. BOOST_concept(Sequence,(S))
  666. : Mutable_ForwardContainer<S>
  667. // Matt Austern's book puts DefaultConstructible here, the C++
  668. // standard places it in Container --JGS
  669. // ... so why aren't we following the standard? --DWA
  670. , DefaultConstructible<S>
  671. {
  672. BOOST_CONCEPT_USAGE(Sequence)
  673. {
  674. S
  675. c(n),
  676. c2(n, t),
  677. c3(first, last);
  678. c.insert(p, t);
  679. c.insert(p, n, t);
  680. c.insert(p, first, last);
  681. c.erase(p);
  682. c.erase(p, q);
  683. typename Sequence::reference r = c.front();
  684. ignore_unused_variable_warning(c);
  685. ignore_unused_variable_warning(c2);
  686. ignore_unused_variable_warning(c3);
  687. ignore_unused_variable_warning(r);
  688. const_constraints(c);
  689. }
  690. private:
  691. void const_constraints(const S& c) {
  692. typename Sequence::const_reference r = c.front();
  693. ignore_unused_variable_warning(r);
  694. }
  695. typename S::value_type t;
  696. typename S::size_type n;
  697. typename S::value_type* first, *last;
  698. typename S::iterator p, q;
  699. };
  700. BOOST_concept(FrontInsertionSequence,(S))
  701. : Sequence<S>
  702. {
  703. BOOST_CONCEPT_USAGE(FrontInsertionSequence)
  704. {
  705. c.push_front(t);
  706. c.pop_front();
  707. }
  708. private:
  709. S c;
  710. typename S::value_type t;
  711. };
  712. BOOST_concept(BackInsertionSequence,(S))
  713. : Sequence<S>
  714. {
  715. BOOST_CONCEPT_USAGE(BackInsertionSequence)
  716. {
  717. c.push_back(t);
  718. c.pop_back();
  719. typename BackInsertionSequence::reference r = c.back();
  720. ignore_unused_variable_warning(r);
  721. const_constraints(c);
  722. }
  723. private:
  724. void const_constraints(const S& cc) {
  725. typename BackInsertionSequence::const_reference
  726. r = cc.back();
  727. ignore_unused_variable_warning(r);
  728. };
  729. S c;
  730. typename S::value_type t;
  731. };
  732. BOOST_concept(AssociativeContainer,(C))
  733. : ForwardContainer<C>
  734. , DefaultConstructible<C>
  735. {
  736. typedef typename C::key_type key_type;
  737. typedef typename C::key_compare key_compare;
  738. typedef typename C::value_compare value_compare;
  739. typedef typename C::iterator iterator;
  740. BOOST_CONCEPT_USAGE(AssociativeContainer)
  741. {
  742. i = c.find(k);
  743. r = c.equal_range(k);
  744. c.erase(k);
  745. c.erase(i);
  746. c.erase(r.first, r.second);
  747. const_constraints(c);
  748. BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
  749. typedef typename AssociativeContainer::value_type value_type_;
  750. BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
  751. }
  752. // Redundant with the base concept, but it helps below.
  753. typedef typename C::const_iterator const_iterator;
  754. private:
  755. void const_constraints(const C& cc)
  756. {
  757. ci = cc.find(k);
  758. n = cc.count(k);
  759. cr = cc.equal_range(k);
  760. }
  761. C c;
  762. iterator i;
  763. std::pair<iterator,iterator> r;
  764. const_iterator ci;
  765. std::pair<const_iterator,const_iterator> cr;
  766. typename C::key_type k;
  767. typename C::size_type n;
  768. };
  769. BOOST_concept(UniqueAssociativeContainer,(C))
  770. : AssociativeContainer<C>
  771. {
  772. BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
  773. {
  774. C c(first, last);
  775. pos_flag = c.insert(t);
  776. c.insert(first, last);
  777. ignore_unused_variable_warning(c);
  778. }
  779. private:
  780. std::pair<typename C::iterator, bool> pos_flag;
  781. typename C::value_type t;
  782. typename C::value_type* first, *last;
  783. };
  784. BOOST_concept(MultipleAssociativeContainer,(C))
  785. : AssociativeContainer<C>
  786. {
  787. BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
  788. {
  789. C c(first, last);
  790. pos = c.insert(t);
  791. c.insert(first, last);
  792. ignore_unused_variable_warning(c);
  793. ignore_unused_variable_warning(pos);
  794. }
  795. private:
  796. typename C::iterator pos;
  797. typename C::value_type t;
  798. typename C::value_type* first, *last;
  799. };
  800. BOOST_concept(SimpleAssociativeContainer,(C))
  801. : AssociativeContainer<C>
  802. {
  803. BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
  804. {
  805. typedef typename C::key_type key_type;
  806. typedef typename C::value_type value_type;
  807. BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
  808. }
  809. };
  810. BOOST_concept(PairAssociativeContainer,(C))
  811. : AssociativeContainer<C>
  812. {
  813. BOOST_CONCEPT_USAGE(PairAssociativeContainer)
  814. {
  815. typedef typename C::key_type key_type;
  816. typedef typename C::value_type value_type;
  817. typedef typename C::mapped_type mapped_type;
  818. typedef std::pair<const key_type, mapped_type> required_value_type;
  819. BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
  820. }
  821. };
  822. BOOST_concept(SortedAssociativeContainer,(C))
  823. : AssociativeContainer<C>
  824. , ReversibleContainer<C>
  825. {
  826. BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
  827. {
  828. C
  829. c(kc),
  830. c2(first, last),
  831. c3(first, last, kc);
  832. p = c.upper_bound(k);
  833. p = c.lower_bound(k);
  834. r = c.equal_range(k);
  835. c.insert(p, t);
  836. ignore_unused_variable_warning(c);
  837. ignore_unused_variable_warning(c2);
  838. ignore_unused_variable_warning(c3);
  839. const_constraints(c);
  840. }
  841. void const_constraints(const C& c)
  842. {
  843. kc = c.key_comp();
  844. vc = c.value_comp();
  845. cp = c.upper_bound(k);
  846. cp = c.lower_bound(k);
  847. cr = c.equal_range(k);
  848. }
  849. private:
  850. typename C::key_compare kc;
  851. typename C::value_compare vc;
  852. typename C::value_type t;
  853. typename C::key_type k;
  854. typedef typename C::iterator iterator;
  855. typedef typename C::const_iterator const_iterator;
  856. typedef SortedAssociativeContainer self;
  857. iterator p;
  858. const_iterator cp;
  859. std::pair<typename self::iterator,typename self::iterator> r;
  860. std::pair<typename self::const_iterator,typename self::const_iterator> cr;
  861. typename C::value_type* first, *last;
  862. };
  863. // HashedAssociativeContainer
  864. } // namespace boost
  865. # include <boost/concept/detail/concept_undef.hpp>
  866. #endif // BOOST_CONCEPT_CHECKS_HPP