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