1 // -*- C++ -*- 2 3 // Copyright (C) 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 // (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, 26 // sell and distribute this software is granted provided this 27 // copyright notice appears in all copies. This software is provided 28 // "as is" without express or implied warranty, and with no claim as 29 // to its suitability for any purpose. 30 // 31 32 /** @file boost_concept_check.h 33 * This is an internal header file, included by other library headers. 34 * You should not attempt to use it directly. 35 */ 36 37 // GCC Note: based on version 1.12.0 of the Boost library. 38 39 #ifndef _BOOST_CONCEPT_CHECK_H 40 #define _BOOST_CONCEPT_CHECK_H 1 41 42 #pragma GCC system_header 43 44 #include <cstddef> // for ptrdiff_t, used next 45 #include <bits/stl_iterator_base_types.h> // for traits and tags 46 47 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 48 49 #define _IsUnused __attribute__ ((__unused__)) 50 51 // When the C-C code is in use, we would like this function to do as little 52 // as possible at runtime, use as few resources as possible, and hopefully 53 // be elided out of existence... hmmm. 54 template <class _Concept> 55 inline void __function_requires() 56 { 57 void (_Concept::*__x)() _IsUnused = &_Concept::__constraints; 58 } 59 60 // No definition: if this is referenced, there's a problem with 61 // the instantiating type not being one of the required integer types. 62 // Unfortunately, this results in a link-time error, not a compile-time error. 63 void __error_type_must_be_an_integer_type(); 64 void __error_type_must_be_an_unsigned_integer_type(); 65 void __error_type_must_be_a_signed_integer_type(); 66 67 // ??? Should the "concept_checking*" structs begin with more than _ ? 68 #define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \ 69 typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \ 70 template <_func##_type_var##_concept _Tp1> \ 71 struct _concept_checking##_type_var##_concept { }; \ 72 typedef _concept_checking##_type_var##_concept< \ 73 &_ns::_concept <_type_var>::__constraints> \ 74 _concept_checking_typedef##_type_var##_concept 75 76 #define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \ 77 typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \ 78 template <_func##_type_var1##_type_var2##_concept _Tp1> \ 79 struct _concept_checking##_type_var1##_type_var2##_concept { }; \ 80 typedef _concept_checking##_type_var1##_type_var2##_concept< \ 81 &_ns::_concept <_type_var1,_type_var2>::__constraints> \ 82 _concept_checking_typedef##_type_var1##_type_var2##_concept 83 84 #define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \ 85 typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \ 86 template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \ 87 struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \ 88 typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \ 89 &_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \ 90 _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept 91 92 #define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \ 93 typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \ 94 template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \ 95 struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \ 96 typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \ 97 &_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \ 98 _concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept 99 100 101 template <class _Tp1, class _Tp2> 102 struct _Aux_require_same { }; 103 104 template <class _Tp> 105 struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; }; 106 107 template <class _Tp1, class _Tp2> 108 struct _SameTypeConcept 109 { 110 void __constraints() { 111 typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required; 112 } 113 }; 114 115 template <class _Tp> 116 struct _IntegerConcept { 117 void __constraints() { 118 __error_type_must_be_an_integer_type(); 119 } 120 }; 121 template <> struct _IntegerConcept<short> { void __constraints() {} }; 122 template <> struct _IntegerConcept<unsigned short> { void __constraints(){} }; 123 template <> struct _IntegerConcept<int> { void __constraints() {} }; 124 template <> struct _IntegerConcept<unsigned int> { void __constraints() {} }; 125 template <> struct _IntegerConcept<long> { void __constraints() {} }; 126 template <> struct _IntegerConcept<unsigned long> { void __constraints() {} }; 127 template <> struct _IntegerConcept<long long> { void __constraints() {} }; 128 template <> struct _IntegerConcept<unsigned long long> 129 { void __constraints() {} }; 130 131 template <class _Tp> 132 struct _SignedIntegerConcept { 133 void __constraints() { 134 __error_type_must_be_a_signed_integer_type(); 135 } 136 }; 137 template <> struct _SignedIntegerConcept<short> { void __constraints() {} }; 138 template <> struct _SignedIntegerConcept<int> { void __constraints() {} }; 139 template <> struct _SignedIntegerConcept<long> { void __constraints() {} }; 140 template <> struct _SignedIntegerConcept<long long> { void __constraints(){}}; 141 142 template <class _Tp> 143 struct _UnsignedIntegerConcept { 144 void __constraints() { 145 __error_type_must_be_an_unsigned_integer_type(); 146 } 147 }; 148 template <> struct _UnsignedIntegerConcept<unsigned short> 149 { void __constraints() {} }; 150 template <> struct _UnsignedIntegerConcept<unsigned int> 151 { void __constraints() {} }; 152 template <> struct _UnsignedIntegerConcept<unsigned long> 153 { void __constraints() {} }; 154 template <> struct _UnsignedIntegerConcept<unsigned long long> 155 { void __constraints() {} }; 156 157 //=========================================================================== 158 // Basic Concepts 159 160 template <class _Tp> 161 struct _DefaultConstructibleConcept 162 { 163 void __constraints() { 164 _Tp __a _IsUnused; // require default constructor 165 } 166 }; 167 168 template <class _Tp> 169 struct _AssignableConcept 170 { 171 void __constraints() { 172 __a = __a; // require assignment operator 173 __const_constraints(__a); 174 } 175 void __const_constraints(const _Tp& __b) { 176 __a = __b; // const required for argument to assignment 177 } 178 _Tp __a; 179 // possibly should be "Tp* a;" and then dereference "a" in constraint 180 // functions? present way would require a default ctor, i think... 181 }; 182 183 template <class _Tp> 184 struct _CopyConstructibleConcept 185 { 186 void __constraints() { 187 _Tp __a(__b); // require copy constructor 188 _Tp* __ptr _IsUnused = &__a; // require address of operator 189 __const_constraints(__a); 190 } 191 void __const_constraints(const _Tp& __a) { 192 _Tp __c _IsUnused(__a); // require const copy constructor 193 const _Tp* __ptr _IsUnused = &__a; // require const address of operator 194 } 195 _Tp __b; 196 }; 197 198 // The SGI STL version of Assignable requires copy constructor and operator= 199 template <class _Tp> 200 struct _SGIAssignableConcept 201 { 202 void __constraints() { 203 _Tp __b _IsUnused(__a); 204 __a = __a; // require assignment operator 205 __const_constraints(__a); 206 } 207 void __const_constraints(const _Tp& __b) { 208 _Tp __c _IsUnused(__b); 209 __a = __b; // const required for argument to assignment 210 } 211 _Tp __a; 212 }; 213 214 template <class _From, class _To> 215 struct _ConvertibleConcept 216 { 217 void __constraints() { 218 _To __y _IsUnused = __x; 219 } 220 _From __x; 221 }; 222 223 // The C++ standard requirements for many concepts talk about return 224 // types that must be "convertible to bool". The problem with this 225 // requirement is that it leaves the door open for evil proxies that 226 // define things like operator|| with strange return types. Two 227 // possible solutions are: 228 // 1) require the return type to be exactly bool 229 // 2) stay with convertible to bool, and also 230 // specify stuff about all the logical operators. 231 // For now we just test for convertible to bool. 232 template <class _Tp> 233 void __aux_require_boolean_expr(const _Tp& __t) { 234 bool __x _IsUnused = __t; 235 } 236 237 // FIXME 238 template <class _Tp> 239 struct _EqualityComparableConcept 240 { 241 void __constraints() { 242 __aux_require_boolean_expr(__a == __b); 243 } 244 _Tp __a, __b; 245 }; 246 247 template <class _Tp> 248 struct _LessThanComparableConcept 249 { 250 void __constraints() { 251 __aux_require_boolean_expr(__a < __b); 252 } 253 _Tp __a, __b; 254 }; 255 256 // This is equivalent to SGI STL's LessThanComparable. 257 template <class _Tp> 258 struct _ComparableConcept 259 { 260 void __constraints() { 261 __aux_require_boolean_expr(__a < __b); 262 __aux_require_boolean_expr(__a > __b); 263 __aux_require_boolean_expr(__a <= __b); 264 __aux_require_boolean_expr(__a >= __b); 265 } 266 _Tp __a, __b; 267 }; 268 269 #define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \ 270 template <class _First, class _Second> \ 271 struct _NAME { \ 272 void __constraints() { (void)__constraints_(); } \ 273 bool __constraints_() { \ 274 return __a _OP __b; \ 275 } \ 276 _First __a; \ 277 _Second __b; \ 278 } 279 280 #define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \ 281 template <class _Ret, class _First, class _Second> \ 282 struct _NAME { \ 283 void __constraints() { (void)__constraints_(); } \ 284 _Ret __constraints_() { \ 285 return __a _OP __b; \ 286 } \ 287 _First __a; \ 288 _Second __b; \ 289 } 290 291 _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept); 292 _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept); 293 _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept); 294 _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept); 295 _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept); 296 _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept); 297 298 _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept); 299 _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept); 300 _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept); 301 _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept); 302 _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept); 303 304 #undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT 305 #undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT 306 307 //=========================================================================== 308 // Function Object Concepts 309 310 template <class _Func, class _Return> 311 struct _GeneratorConcept 312 { 313 void __constraints() { 314 const _Return& __r _IsUnused = __f();// require operator() member function 315 } 316 _Func __f; 317 }; 318 319 320 template <class _Func> 321 struct _GeneratorConcept<_Func,void> 322 { 323 void __constraints() { 324 __f(); // require operator() member function 325 } 326 _Func __f; 327 }; 328 329 template <class _Func, class _Return, class _Arg> 330 struct _UnaryFunctionConcept 331 { 332 void __constraints() { 333 __r = __f(__arg); // require operator() 334 } 335 _Func __f; 336 _Arg __arg; 337 _Return __r; 338 }; 339 340 template <class _Func, class _Arg> 341 struct _UnaryFunctionConcept<_Func, void, _Arg> { 342 void __constraints() { 343 __f(__arg); // require operator() 344 } 345 _Func __f; 346 _Arg __arg; 347 }; 348 349 template <class _Func, class _Return, class _First, class _Second> 350 struct _BinaryFunctionConcept 351 { 352 void __constraints() { 353 __r = __f(__first, __second); // require operator() 354 } 355 _Func __f; 356 _First __first; 357 _Second __second; 358 _Return __r; 359 }; 360 361 template <class _Func, class _First, class _Second> 362 struct _BinaryFunctionConcept<_Func, void, _First, _Second> 363 { 364 void __constraints() { 365 __f(__first, __second); // require operator() 366 } 367 _Func __f; 368 _First __first; 369 _Second __second; 370 }; 371 372 template <class _Func, class _Arg> 373 struct _UnaryPredicateConcept 374 { 375 void __constraints() { 376 __aux_require_boolean_expr(__f(__arg)); // require op() returning bool 377 } 378 _Func __f; 379 _Arg __arg; 380 }; 381 382 template <class _Func, class _First, class _Second> 383 struct _BinaryPredicateConcept 384 { 385 void __constraints() { 386 __aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool 387 } 388 _Func __f; 389 _First __a; 390 _Second __b; 391 }; 392 393 // use this when functor is used inside a container class like std::set 394 template <class _Func, class _First, class _Second> 395 struct _Const_BinaryPredicateConcept { 396 void __constraints() { 397 __const_constraints(__f); 398 } 399 void __const_constraints(const _Func& __fun) { 400 __function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >(); 401 // operator() must be a const member function 402 __aux_require_boolean_expr(__fun(__a, __b)); 403 } 404 _Func __f; 405 _First __a; 406 _Second __b; 407 }; 408 409 //=========================================================================== 410 // Iterator Concepts 411 412 template <class _Tp> 413 struct _TrivialIteratorConcept 414 { 415 void __constraints() { 416 // __function_requires< _DefaultConstructibleConcept<_Tp> >(); 417 __function_requires< _AssignableConcept<_Tp> >(); 418 __function_requires< _EqualityComparableConcept<_Tp> >(); 419 // typedef typename std::iterator_traits<_Tp>::value_type _V; 420 (void)*__i; // require dereference operator 421 } 422 _Tp __i; 423 }; 424 425 template <class _Tp> 426 struct _Mutable_TrivialIteratorConcept 427 { 428 void __constraints() { 429 __function_requires< _TrivialIteratorConcept<_Tp> >(); 430 *__i = *__j; // require dereference and assignment 431 } 432 _Tp __i, __j; 433 }; 434 435 template <class _Tp> 436 struct _InputIteratorConcept 437 { 438 void __constraints() { 439 __function_requires< _TrivialIteratorConcept<_Tp> >(); 440 // require iterator_traits typedef's 441 typedef typename std::iterator_traits<_Tp>::difference_type _Diff; 442 // __function_requires< _SignedIntegerConcept<_Diff> >(); 443 typedef typename std::iterator_traits<_Tp>::reference _Ref; 444 typedef typename std::iterator_traits<_Tp>::pointer _Pt; 445 typedef typename std::iterator_traits<_Tp>::iterator_category _Cat; 446 __function_requires< _ConvertibleConcept< 447 typename std::iterator_traits<_Tp>::iterator_category, 448 std::input_iterator_tag> >(); 449 ++__i; // require preincrement operator 450 __i++; // require postincrement operator 451 } 452 _Tp __i; 453 }; 454 455 template <class _Tp, class _ValueT> 456 struct _OutputIteratorConcept 457 { 458 void __constraints() { 459 __function_requires< _AssignableConcept<_Tp> >(); 460 ++__i; // require preincrement operator 461 __i++; // require postincrement operator 462 *__i++ = __t; // require postincrement and assignment 463 } 464 _Tp __i; 465 _ValueT __t; 466 }; 467 468 template <class _Tp> 469 struct _ForwardIteratorConcept 470 { 471 void __constraints() { 472 __function_requires< _InputIteratorConcept<_Tp> >(); 473 __function_requires< _DefaultConstructibleConcept<_Tp> >(); 474 __function_requires< _ConvertibleConcept< 475 typename std::iterator_traits<_Tp>::iterator_category, 476 std::forward_iterator_tag> >(); 477 typedef typename std::iterator_traits<_Tp>::reference _Ref; 478 _Ref __r _IsUnused = *__i; 479 } 480 _Tp __i; 481 }; 482 483 template <class _Tp> 484 struct _Mutable_ForwardIteratorConcept 485 { 486 void __constraints() { 487 __function_requires< _ForwardIteratorConcept<_Tp> >(); 488 *__i++ = *__i; // require postincrement and assignment 489 } 490 _Tp __i; 491 }; 492 493 template <class _Tp> 494 struct _BidirectionalIteratorConcept 495 { 496 void __constraints() { 497 __function_requires< _ForwardIteratorConcept<_Tp> >(); 498 __function_requires< _ConvertibleConcept< 499 typename std::iterator_traits<_Tp>::iterator_category, 500 std::bidirectional_iterator_tag> >(); 501 --__i; // require predecrement operator 502 __i--; // require postdecrement operator 503 } 504 _Tp __i; 505 }; 506 507 template <class _Tp> 508 struct _Mutable_BidirectionalIteratorConcept 509 { 510 void __constraints() { 511 __function_requires< _BidirectionalIteratorConcept<_Tp> >(); 512 __function_requires< _Mutable_ForwardIteratorConcept<_Tp> >(); 513 *__i-- = *__i; // require postdecrement and assignment 514 } 515 _Tp __i; 516 }; 517 518 519 template <class _Tp> 520 struct _RandomAccessIteratorConcept 521 { 522 void __constraints() { 523 __function_requires< _BidirectionalIteratorConcept<_Tp> >(); 524 __function_requires< _ComparableConcept<_Tp> >(); 525 __function_requires< _ConvertibleConcept< 526 typename std::iterator_traits<_Tp>::iterator_category, 527 std::random_access_iterator_tag> >(); 528 // ??? We don't use _Ref, are we just checking for "referenceability"? 529 typedef typename std::iterator_traits<_Tp>::reference _Ref; 530 531 __i += __n; // require assignment addition operator 532 __i = __i + __n; __i = __n + __i; // require addition with difference type 533 __i -= __n; // require assignment subtraction op 534 __i = __i - __n; // require subtraction with 535 // difference type 536 __n = __i - __j; // require difference operator 537 (void)__i[__n]; // require element access operator 538 } 539 _Tp __a, __b; 540 _Tp __i, __j; 541 typename std::iterator_traits<_Tp>::difference_type __n; 542 }; 543 544 template <class _Tp> 545 struct _Mutable_RandomAccessIteratorConcept 546 { 547 void __constraints() { 548 __function_requires< _RandomAccessIteratorConcept<_Tp> >(); 549 __function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >(); 550 __i[__n] = *__i; // require element access and assignment 551 } 552 _Tp __i; 553 typename std::iterator_traits<_Tp>::difference_type __n; 554 }; 555 556 //=========================================================================== 557 // Container Concepts 558 559 template <class _Container> 560 struct _ContainerConcept 561 { 562 typedef typename _Container::value_type _Value_type; 563 typedef typename _Container::difference_type _Difference_type; 564 typedef typename _Container::size_type _Size_type; 565 typedef typename _Container::const_reference _Const_reference; 566 typedef typename _Container::const_pointer _Const_pointer; 567 typedef typename _Container::const_iterator _Const_iterator; 568 569 void __constraints() { 570 __function_requires< _InputIteratorConcept<_Const_iterator> >(); 571 __function_requires< _AssignableConcept<_Container> >(); 572 const _Container __c; 573 __i = __c.begin(); 574 __i = __c.end(); 575 __n = __c.size(); 576 __n = __c.max_size(); 577 __b = __c.empty(); 578 } 579 bool __b; 580 _Const_iterator __i; 581 _Size_type __n; 582 }; 583 584 template <class _Container> 585 struct _Mutable_ContainerConcept 586 { 587 typedef typename _Container::value_type _Value_type; 588 typedef typename _Container::reference _Reference; 589 typedef typename _Container::iterator _Iterator; 590 typedef typename _Container::pointer _Pointer; 591 592 void __constraints() { 593 __function_requires< _ContainerConcept<_Container> >(); 594 __function_requires< _AssignableConcept<_Value_type> >(); 595 __function_requires< _InputIteratorConcept<_Iterator> >(); 596 597 __i = __c.begin(); 598 __i = __c.end(); 599 __c.swap(__c2); 600 } 601 _Iterator __i; 602 _Container __c, __c2; 603 }; 604 605 template <class _ForwardContainer> 606 struct _ForwardContainerConcept 607 { 608 void __constraints() { 609 __function_requires< _ContainerConcept<_ForwardContainer> >(); 610 typedef typename _ForwardContainer::const_iterator _Const_iterator; 611 __function_requires< _ForwardIteratorConcept<_Const_iterator> >(); 612 } 613 }; 614 615 template <class _ForwardContainer> 616 struct _Mutable_ForwardContainerConcept 617 { 618 void __constraints() { 619 __function_requires< _ForwardContainerConcept<_ForwardContainer> >(); 620 __function_requires< _Mutable_ContainerConcept<_ForwardContainer> >(); 621 typedef typename _ForwardContainer::iterator _Iterator; 622 __function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >(); 623 } 624 }; 625 626 template <class _ReversibleContainer> 627 struct _ReversibleContainerConcept 628 { 629 typedef typename _ReversibleContainer::const_iterator _Const_iterator; 630 typedef typename _ReversibleContainer::const_reverse_iterator 631 _Const_reverse_iterator; 632 633 void __constraints() { 634 __function_requires< _ForwardContainerConcept<_ReversibleContainer> >(); 635 __function_requires< _BidirectionalIteratorConcept<_Const_iterator> >(); 636 __function_requires< 637 _BidirectionalIteratorConcept<_Const_reverse_iterator> >(); 638 639 const _ReversibleContainer __c; 640 _Const_reverse_iterator __i = __c.rbegin(); 641 __i = __c.rend(); 642 } 643 }; 644 645 template <class _ReversibleContainer> 646 struct _Mutable_ReversibleContainerConcept 647 { 648 typedef typename _ReversibleContainer::iterator _Iterator; 649 typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator; 650 651 void __constraints() { 652 __function_requires<_ReversibleContainerConcept<_ReversibleContainer> >(); 653 __function_requires< 654 _Mutable_ForwardContainerConcept<_ReversibleContainer> >(); 655 __function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >(); 656 __function_requires< 657 _Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >(); 658 659 _Reverse_iterator __i = __c.rbegin(); 660 __i = __c.rend(); 661 } 662 _ReversibleContainer __c; 663 }; 664 665 template <class _RandomAccessContainer> 666 struct _RandomAccessContainerConcept 667 { 668 typedef typename _RandomAccessContainer::size_type _Size_type; 669 typedef typename _RandomAccessContainer::const_reference _Const_reference; 670 typedef typename _RandomAccessContainer::const_iterator _Const_iterator; 671 typedef typename _RandomAccessContainer::const_reverse_iterator 672 _Const_reverse_iterator; 673 674 void __constraints() { 675 __function_requires< 676 _ReversibleContainerConcept<_RandomAccessContainer> >(); 677 __function_requires< _RandomAccessIteratorConcept<_Const_iterator> >(); 678 __function_requires< 679 _RandomAccessIteratorConcept<_Const_reverse_iterator> >(); 680 681 const _RandomAccessContainer __c; 682 _Const_reference __r _IsUnused = __c[__n]; 683 } 684 _Size_type __n; 685 }; 686 687 template <class _RandomAccessContainer> 688 struct _Mutable_RandomAccessContainerConcept 689 { 690 typedef typename _RandomAccessContainer::size_type _Size_type; 691 typedef typename _RandomAccessContainer::reference _Reference; 692 typedef typename _RandomAccessContainer::iterator _Iterator; 693 typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator; 694 695 void __constraints() { 696 __function_requires< 697 _RandomAccessContainerConcept<_RandomAccessContainer> >(); 698 __function_requires< 699 _Mutable_ReversibleContainerConcept<_RandomAccessContainer> >(); 700 __function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >(); 701 __function_requires< 702 _Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >(); 703 704 _Reference __r _IsUnused = __c[__i]; 705 } 706 _Size_type __i; 707 _RandomAccessContainer __c; 708 }; 709 710 // A Sequence is inherently mutable 711 template <class _Sequence> 712 struct _SequenceConcept 713 { 714 typedef typename _Sequence::reference _Reference; 715 typedef typename _Sequence::const_reference _Const_reference; 716 717 void __constraints() { 718 // Matt Austern's book puts DefaultConstructible here, the C++ 719 // standard places it in Container 720 // function_requires< DefaultConstructible<Sequence> >(); 721 __function_requires< _Mutable_ForwardContainerConcept<_Sequence> >(); 722 __function_requires< _DefaultConstructibleConcept<_Sequence> >(); 723 724 _Sequence 725 __c _IsUnused(__n, __t), 726 __c2 _IsUnused(__first, __last); 727 728 __c.insert(__p, __t); 729 __c.insert(__p, __n, __t); 730 __c.insert(__p, __first, __last); 731 732 __c.erase(__p); 733 __c.erase(__p, __q); 734 735 _Reference __r _IsUnused = __c.front(); 736 737 __const_constraints(__c); 738 } 739 void __const_constraints(const _Sequence& __c) { 740 _Const_reference __r _IsUnused = __c.front(); 741 } 742 typename _Sequence::value_type __t; 743 typename _Sequence::size_type __n; 744 typename _Sequence::value_type *__first, *__last; 745 typename _Sequence::iterator __p, __q; 746 }; 747 748 template <class _FrontInsertionSequence> 749 struct _FrontInsertionSequenceConcept 750 { 751 void __constraints() { 752 __function_requires< _SequenceConcept<_FrontInsertionSequence> >(); 753 754 __c.push_front(__t); 755 __c.pop_front(); 756 } 757 _FrontInsertionSequence __c; 758 typename _FrontInsertionSequence::value_type __t; 759 }; 760 761 template <class _BackInsertionSequence> 762 struct _BackInsertionSequenceConcept 763 { 764 typedef typename _BackInsertionSequence::reference _Reference; 765 typedef typename _BackInsertionSequence::const_reference _Const_reference; 766 767 void __constraints() { 768 __function_requires< _SequenceConcept<_BackInsertionSequence> >(); 769 770 __c.push_back(__t); 771 __c.pop_back(); 772 _Reference __r _IsUnused = __c.back(); 773 } 774 void __const_constraints(const _BackInsertionSequence& __c) { 775 _Const_reference __r _IsUnused = __c.back(); 776 }; 777 _BackInsertionSequence __c; 778 typename _BackInsertionSequence::value_type __t; 779 }; 780 781 _GLIBCXX_END_NAMESPACE 782 783 #undef _IsUnused 784 785 #endif // _GLIBCXX_BOOST_CONCEPT_CHECK 786 787 788