concept_check.hpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  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. #if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \
  293. && BOOST_WORKAROUND(__GNUC__, > 3)))
  294. // Declare a dummy construktor to make gcc happy.
  295. // It seems the compiler can not generate a sensible constructor when this is instantiated with a refence type.
  296. // (warning: non-static reference "const double& boost::UnaryFunction<YourClassHere>::arg"
  297. // in class without a constructor [-Wuninitialized])
  298. UnaryFunction();
  299. #endif
  300. Func f;
  301. Arg arg;
  302. };
  303. BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second))
  304. {
  305. BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void<Return>()); }
  306. private:
  307. void test(boost::mpl::false_)
  308. {
  309. f(first,second);
  310. Return r = f(first, second); // require operator()
  311. (void)r;
  312. }
  313. void test(boost::mpl::true_)
  314. {
  315. f(first,second);
  316. }
  317. Func f;
  318. First first;
  319. Second second;
  320. };
  321. BOOST_concept(UnaryPredicate,(Func)(Arg))
  322. {
  323. BOOST_CONCEPT_USAGE(UnaryPredicate) {
  324. require_boolean_expr(f(arg)); // require operator() returning bool
  325. }
  326. private:
  327. Func f;
  328. Arg arg;
  329. };
  330. BOOST_concept(BinaryPredicate,(Func)(First)(Second))
  331. {
  332. BOOST_CONCEPT_USAGE(BinaryPredicate) {
  333. require_boolean_expr(f(a, b)); // require operator() returning bool
  334. }
  335. private:
  336. Func f;
  337. First a;
  338. Second b;
  339. };
  340. // use this when functor is used inside a container class like std::set
  341. BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second))
  342. : BinaryPredicate<Func, First, Second>
  343. {
  344. BOOST_CONCEPT_USAGE(Const_BinaryPredicate) {
  345. const_constraints(f);
  346. }
  347. private:
  348. void const_constraints(const Func& fun) {
  349. // operator() must be a const member function
  350. require_boolean_expr(fun(a, b));
  351. }
  352. Func f;
  353. First a;
  354. Second b;
  355. };
  356. BOOST_concept(AdaptableGenerator,(Func)(Return))
  357. : Generator<Func, typename Func::result_type>
  358. {
  359. typedef typename Func::result_type result_type;
  360. BOOST_CONCEPT_USAGE(AdaptableGenerator)
  361. {
  362. BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
  363. }
  364. };
  365. BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg))
  366. : UnaryFunction<Func, typename Func::result_type, typename Func::argument_type>
  367. {
  368. typedef typename Func::argument_type argument_type;
  369. typedef typename Func::result_type result_type;
  370. ~AdaptableUnaryFunction()
  371. {
  372. BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
  373. BOOST_CONCEPT_ASSERT((Convertible<Arg, argument_type>));
  374. }
  375. };
  376. BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second))
  377. : BinaryFunction<
  378. Func
  379. , typename Func::result_type
  380. , typename Func::first_argument_type
  381. , typename Func::second_argument_type
  382. >
  383. {
  384. typedef typename Func::first_argument_type first_argument_type;
  385. typedef typename Func::second_argument_type second_argument_type;
  386. typedef typename Func::result_type result_type;
  387. ~AdaptableBinaryFunction()
  388. {
  389. BOOST_CONCEPT_ASSERT((Convertible<result_type, Return>));
  390. BOOST_CONCEPT_ASSERT((Convertible<First, first_argument_type>));
  391. BOOST_CONCEPT_ASSERT((Convertible<Second, second_argument_type>));
  392. }
  393. };
  394. BOOST_concept(AdaptablePredicate,(Func)(Arg))
  395. : UnaryPredicate<Func, Arg>
  396. , AdaptableUnaryFunction<Func, bool, Arg>
  397. {
  398. };
  399. BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second))
  400. : BinaryPredicate<Func, First, Second>
  401. , AdaptableBinaryFunction<Func, bool, First, Second>
  402. {
  403. };
  404. //===========================================================================
  405. // Iterator Concepts
  406. BOOST_concept(InputIterator,(TT))
  407. : Assignable<TT>
  408. , EqualityComparable<TT>
  409. {
  410. typedef typename boost::detail::iterator_traits<TT>::value_type value_type;
  411. typedef typename boost::detail::iterator_traits<TT>::difference_type difference_type;
  412. typedef typename boost::detail::iterator_traits<TT>::reference reference;
  413. typedef typename boost::detail::iterator_traits<TT>::pointer pointer;
  414. typedef typename boost::detail::iterator_traits<TT>::iterator_category iterator_category;
  415. BOOST_CONCEPT_USAGE(InputIterator)
  416. {
  417. BOOST_CONCEPT_ASSERT((SignedInteger<difference_type>));
  418. BOOST_CONCEPT_ASSERT((Convertible<iterator_category, std::input_iterator_tag>));
  419. TT j(i);
  420. (void)*i; // require dereference operator
  421. ++j; // require preincrement operator
  422. i++; // require postincrement operator
  423. }
  424. private:
  425. TT i;
  426. };
  427. BOOST_concept(OutputIterator,(TT)(ValueT))
  428. : Assignable<TT>
  429. {
  430. BOOST_CONCEPT_USAGE(OutputIterator) {
  431. ++i; // require preincrement operator
  432. i++; // require postincrement operator
  433. *i++ = t; // require postincrement and assignment
  434. }
  435. private:
  436. TT i, j;
  437. ValueT t;
  438. };
  439. BOOST_concept(ForwardIterator,(TT))
  440. : InputIterator<TT>
  441. {
  442. BOOST_CONCEPT_USAGE(ForwardIterator)
  443. {
  444. BOOST_CONCEPT_ASSERT((Convertible<
  445. BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category
  446. , std::forward_iterator_tag
  447. >));
  448. typename InputIterator<TT>::reference r = *i;
  449. ignore_unused_variable_warning(r);
  450. }
  451. private:
  452. TT i;
  453. };
  454. BOOST_concept(Mutable_ForwardIterator,(TT))
  455. : ForwardIterator<TT>
  456. {
  457. BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) {
  458. *i++ = *i; // require postincrement and assignment
  459. }
  460. private:
  461. TT i;
  462. };
  463. BOOST_concept(BidirectionalIterator,(TT))
  464. : ForwardIterator<TT>
  465. {
  466. BOOST_CONCEPT_USAGE(BidirectionalIterator)
  467. {
  468. BOOST_CONCEPT_ASSERT((Convertible<
  469. BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category
  470. , std::bidirectional_iterator_tag
  471. >));
  472. --i; // require predecrement operator
  473. i--; // require postdecrement operator
  474. }
  475. private:
  476. TT i;
  477. };
  478. BOOST_concept(Mutable_BidirectionalIterator,(TT))
  479. : BidirectionalIterator<TT>
  480. , Mutable_ForwardIterator<TT>
  481. {
  482. BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator)
  483. {
  484. *i-- = *i; // require postdecrement and assignment
  485. }
  486. private:
  487. TT i;
  488. };
  489. BOOST_concept(RandomAccessIterator,(TT))
  490. : BidirectionalIterator<TT>
  491. , Comparable<TT>
  492. {
  493. BOOST_CONCEPT_USAGE(RandomAccessIterator)
  494. {
  495. BOOST_CONCEPT_ASSERT((Convertible<
  496. BOOST_DEDUCED_TYPENAME BidirectionalIterator<TT>::iterator_category
  497. , std::random_access_iterator_tag
  498. >));
  499. i += n; // require assignment addition operator
  500. i = i + n; i = n + i; // require addition with difference type
  501. i -= n; // require assignment subtraction operator
  502. i = i - n; // require subtraction with difference type
  503. n = i - j; // require difference operator
  504. (void)i[n]; // require element access operator
  505. }
  506. private:
  507. TT a, b;
  508. TT i, j;
  509. typename boost::detail::iterator_traits<TT>::difference_type n;
  510. };
  511. BOOST_concept(Mutable_RandomAccessIterator,(TT))
  512. : RandomAccessIterator<TT>
  513. , Mutable_BidirectionalIterator<TT>
  514. {
  515. BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator)
  516. {
  517. i[n] = *i; // require element access and assignment
  518. }
  519. private:
  520. TT i;
  521. typename boost::detail::iterator_traits<TT>::difference_type n;
  522. };
  523. //===========================================================================
  524. // Container s
  525. BOOST_concept(Container,(C))
  526. : Assignable<C>
  527. {
  528. typedef typename C::value_type value_type;
  529. typedef typename C::difference_type difference_type;
  530. typedef typename C::size_type size_type;
  531. typedef typename C::const_reference const_reference;
  532. typedef typename C::const_pointer const_pointer;
  533. typedef typename C::const_iterator const_iterator;
  534. BOOST_CONCEPT_USAGE(Container)
  535. {
  536. BOOST_CONCEPT_ASSERT((InputIterator<const_iterator>));
  537. const_constraints(c);
  538. }
  539. private:
  540. void const_constraints(const C& cc) {
  541. i = cc.begin();
  542. i = cc.end();
  543. n = cc.size();
  544. n = cc.max_size();
  545. b = cc.empty();
  546. }
  547. C c;
  548. bool b;
  549. const_iterator i;
  550. size_type n;
  551. };
  552. BOOST_concept(Mutable_Container,(C))
  553. : Container<C>
  554. {
  555. typedef typename C::reference reference;
  556. typedef typename C::iterator iterator;
  557. typedef typename C::pointer pointer;
  558. BOOST_CONCEPT_USAGE(Mutable_Container)
  559. {
  560. BOOST_CONCEPT_ASSERT((
  561. Assignable<typename Mutable_Container::value_type>));
  562. BOOST_CONCEPT_ASSERT((InputIterator<iterator>));
  563. i = c.begin();
  564. i = c.end();
  565. c.swap(c2);
  566. }
  567. private:
  568. iterator i;
  569. C c, c2;
  570. };
  571. BOOST_concept(ForwardContainer,(C))
  572. : Container<C>
  573. {
  574. BOOST_CONCEPT_USAGE(ForwardContainer)
  575. {
  576. BOOST_CONCEPT_ASSERT((
  577. ForwardIterator<
  578. typename ForwardContainer::const_iterator
  579. >));
  580. }
  581. };
  582. BOOST_concept(Mutable_ForwardContainer,(C))
  583. : ForwardContainer<C>
  584. , Mutable_Container<C>
  585. {
  586. BOOST_CONCEPT_USAGE(Mutable_ForwardContainer)
  587. {
  588. BOOST_CONCEPT_ASSERT((
  589. Mutable_ForwardIterator<
  590. typename Mutable_ForwardContainer::iterator
  591. >));
  592. }
  593. };
  594. BOOST_concept(ReversibleContainer,(C))
  595. : ForwardContainer<C>
  596. {
  597. typedef typename
  598. C::const_reverse_iterator
  599. const_reverse_iterator;
  600. BOOST_CONCEPT_USAGE(ReversibleContainer)
  601. {
  602. BOOST_CONCEPT_ASSERT((
  603. BidirectionalIterator<
  604. typename ReversibleContainer::const_iterator>));
  605. BOOST_CONCEPT_ASSERT((BidirectionalIterator<const_reverse_iterator>));
  606. const_constraints(c);
  607. }
  608. private:
  609. void const_constraints(const C& cc)
  610. {
  611. const_reverse_iterator i = cc.rbegin();
  612. i = cc.rend();
  613. }
  614. C c;
  615. };
  616. BOOST_concept(Mutable_ReversibleContainer,(C))
  617. : Mutable_ForwardContainer<C>
  618. , ReversibleContainer<C>
  619. {
  620. typedef typename C::reverse_iterator reverse_iterator;
  621. BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer)
  622. {
  623. typedef typename Mutable_ForwardContainer<C>::iterator iterator;
  624. BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<iterator>));
  625. BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator<reverse_iterator>));
  626. reverse_iterator i = c.rbegin();
  627. i = c.rend();
  628. }
  629. private:
  630. C c;
  631. };
  632. BOOST_concept(RandomAccessContainer,(C))
  633. : ReversibleContainer<C>
  634. {
  635. typedef typename C::size_type size_type;
  636. typedef typename C::const_reference const_reference;
  637. BOOST_CONCEPT_USAGE(RandomAccessContainer)
  638. {
  639. BOOST_CONCEPT_ASSERT((
  640. RandomAccessIterator<
  641. typename RandomAccessContainer::const_iterator
  642. >));
  643. const_constraints(c);
  644. }
  645. private:
  646. void const_constraints(const C& cc)
  647. {
  648. const_reference r = cc[n];
  649. ignore_unused_variable_warning(r);
  650. }
  651. C c;
  652. size_type n;
  653. };
  654. BOOST_concept(Mutable_RandomAccessContainer,(C))
  655. : Mutable_ReversibleContainer<C>
  656. , RandomAccessContainer<C>
  657. {
  658. private:
  659. typedef Mutable_RandomAccessContainer self;
  660. public:
  661. BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer)
  662. {
  663. BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::iterator>));
  664. BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator<typename self::reverse_iterator>));
  665. typename self::reference r = c[i];
  666. ignore_unused_variable_warning(r);
  667. }
  668. private:
  669. typename Mutable_ReversibleContainer<C>::size_type i;
  670. C c;
  671. };
  672. // A Sequence is inherently mutable
  673. BOOST_concept(Sequence,(S))
  674. : Mutable_ForwardContainer<S>
  675. // Matt Austern's book puts DefaultConstructible here, the C++
  676. // standard places it in Container --JGS
  677. // ... so why aren't we following the standard? --DWA
  678. , DefaultConstructible<S>
  679. {
  680. BOOST_CONCEPT_USAGE(Sequence)
  681. {
  682. S
  683. c(n),
  684. c2(n, t),
  685. c3(first, last);
  686. c.insert(p, t);
  687. c.insert(p, n, t);
  688. c.insert(p, first, last);
  689. c.erase(p);
  690. c.erase(p, q);
  691. typename Sequence::reference r = c.front();
  692. ignore_unused_variable_warning(c);
  693. ignore_unused_variable_warning(c2);
  694. ignore_unused_variable_warning(c3);
  695. ignore_unused_variable_warning(r);
  696. const_constraints(c);
  697. }
  698. private:
  699. void const_constraints(const S& c) {
  700. typename Sequence::const_reference r = c.front();
  701. ignore_unused_variable_warning(r);
  702. }
  703. typename S::value_type t;
  704. typename S::size_type n;
  705. typename S::value_type* first, *last;
  706. typename S::iterator p, q;
  707. };
  708. BOOST_concept(FrontInsertionSequence,(S))
  709. : Sequence<S>
  710. {
  711. BOOST_CONCEPT_USAGE(FrontInsertionSequence)
  712. {
  713. c.push_front(t);
  714. c.pop_front();
  715. }
  716. private:
  717. S c;
  718. typename S::value_type t;
  719. };
  720. BOOST_concept(BackInsertionSequence,(S))
  721. : Sequence<S>
  722. {
  723. BOOST_CONCEPT_USAGE(BackInsertionSequence)
  724. {
  725. c.push_back(t);
  726. c.pop_back();
  727. typename BackInsertionSequence::reference r = c.back();
  728. ignore_unused_variable_warning(r);
  729. const_constraints(c);
  730. }
  731. private:
  732. void const_constraints(const S& cc) {
  733. typename BackInsertionSequence::const_reference
  734. r = cc.back();
  735. ignore_unused_variable_warning(r);
  736. };
  737. S c;
  738. typename S::value_type t;
  739. };
  740. BOOST_concept(AssociativeContainer,(C))
  741. : ForwardContainer<C>
  742. , DefaultConstructible<C>
  743. {
  744. typedef typename C::key_type key_type;
  745. typedef typename C::key_compare key_compare;
  746. typedef typename C::value_compare value_compare;
  747. typedef typename C::iterator iterator;
  748. BOOST_CONCEPT_USAGE(AssociativeContainer)
  749. {
  750. i = c.find(k);
  751. r = c.equal_range(k);
  752. c.erase(k);
  753. c.erase(i);
  754. c.erase(r.first, r.second);
  755. const_constraints(c);
  756. BOOST_CONCEPT_ASSERT((BinaryPredicate<key_compare,key_type,key_type>));
  757. typedef typename AssociativeContainer::value_type value_type_;
  758. BOOST_CONCEPT_ASSERT((BinaryPredicate<value_compare,value_type_,value_type_>));
  759. }
  760. // Redundant with the base concept, but it helps below.
  761. typedef typename C::const_iterator const_iterator;
  762. private:
  763. void const_constraints(const C& cc)
  764. {
  765. ci = cc.find(k);
  766. n = cc.count(k);
  767. cr = cc.equal_range(k);
  768. }
  769. C c;
  770. iterator i;
  771. std::pair<iterator,iterator> r;
  772. const_iterator ci;
  773. std::pair<const_iterator,const_iterator> cr;
  774. typename C::key_type k;
  775. typename C::size_type n;
  776. };
  777. BOOST_concept(UniqueAssociativeContainer,(C))
  778. : AssociativeContainer<C>
  779. {
  780. BOOST_CONCEPT_USAGE(UniqueAssociativeContainer)
  781. {
  782. C c(first, last);
  783. pos_flag = c.insert(t);
  784. c.insert(first, last);
  785. ignore_unused_variable_warning(c);
  786. }
  787. private:
  788. std::pair<typename C::iterator, bool> pos_flag;
  789. typename C::value_type t;
  790. typename C::value_type* first, *last;
  791. };
  792. BOOST_concept(MultipleAssociativeContainer,(C))
  793. : AssociativeContainer<C>
  794. {
  795. BOOST_CONCEPT_USAGE(MultipleAssociativeContainer)
  796. {
  797. C c(first, last);
  798. pos = c.insert(t);
  799. c.insert(first, last);
  800. ignore_unused_variable_warning(c);
  801. ignore_unused_variable_warning(pos);
  802. }
  803. private:
  804. typename C::iterator pos;
  805. typename C::value_type t;
  806. typename C::value_type* first, *last;
  807. };
  808. BOOST_concept(SimpleAssociativeContainer,(C))
  809. : AssociativeContainer<C>
  810. {
  811. BOOST_CONCEPT_USAGE(SimpleAssociativeContainer)
  812. {
  813. typedef typename C::key_type key_type;
  814. typedef typename C::value_type value_type;
  815. BOOST_MPL_ASSERT((boost::is_same<key_type,value_type>));
  816. }
  817. };
  818. BOOST_concept(PairAssociativeContainer,(C))
  819. : AssociativeContainer<C>
  820. {
  821. BOOST_CONCEPT_USAGE(PairAssociativeContainer)
  822. {
  823. typedef typename C::key_type key_type;
  824. typedef typename C::value_type value_type;
  825. typedef typename C::mapped_type mapped_type;
  826. typedef std::pair<const key_type, mapped_type> required_value_type;
  827. BOOST_MPL_ASSERT((boost::is_same<value_type,required_value_type>));
  828. }
  829. };
  830. BOOST_concept(SortedAssociativeContainer,(C))
  831. : AssociativeContainer<C>
  832. , ReversibleContainer<C>
  833. {
  834. BOOST_CONCEPT_USAGE(SortedAssociativeContainer)
  835. {
  836. C
  837. c(kc),
  838. c2(first, last),
  839. c3(first, last, kc);
  840. p = c.upper_bound(k);
  841. p = c.lower_bound(k);
  842. r = c.equal_range(k);
  843. c.insert(p, t);
  844. ignore_unused_variable_warning(c);
  845. ignore_unused_variable_warning(c2);
  846. ignore_unused_variable_warning(c3);
  847. const_constraints(c);
  848. }
  849. void const_constraints(const C& c)
  850. {
  851. kc = c.key_comp();
  852. vc = c.value_comp();
  853. cp = c.upper_bound(k);
  854. cp = c.lower_bound(k);
  855. cr = c.equal_range(k);
  856. }
  857. private:
  858. typename C::key_compare kc;
  859. typename C::value_compare vc;
  860. typename C::value_type t;
  861. typename C::key_type k;
  862. typedef typename C::iterator iterator;
  863. typedef typename C::const_iterator const_iterator;
  864. typedef SortedAssociativeContainer self;
  865. iterator p;
  866. const_iterator cp;
  867. std::pair<typename self::iterator,typename self::iterator> r;
  868. std::pair<typename self::const_iterator,typename self::const_iterator> cr;
  869. typename C::value_type* first, *last;
  870. };
  871. // HashedAssociativeContainer
  872. } // namespace boost
  873. # include <boost/concept/detail/concept_undef.hpp>
  874. #endif // BOOST_CONCEPT_CHECKS_HPP