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