/Src/Dependencies/Boost/boost/concept_check.hpp

http://hadesmem.googlecode.com/ · C++ Header · 1083 lines · 875 code · 139 blank · 69 comment · 10 complexity · 189cdc1c541c61ae8cfbec9c71bddaff MD5 · raw file

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