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