concept_check.hpp 31 KB

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