comparison DEPENDENCIES/generic/include/boost/container/string.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
1 ////////////////////////////////////////////////////////////////////////////// 1 //////////////////////////////////////////////////////////////////////////////
2 // 2 //
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost 3 // (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file 4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 // 6 //
7 // See http://www.boost.org/libs/container for documentation. 7 // See http://www.boost.org/libs/container for documentation.
8 // 8 //
9 ////////////////////////////////////////////////////////////////////////////// 9 //////////////////////////////////////////////////////////////////////////////
10 10
11 #ifndef BOOST_CONTAINER_STRING_HPP 11 #ifndef BOOST_CONTAINER_STRING_HPP
12 #define BOOST_CONTAINER_STRING_HPP 12 #define BOOST_CONTAINER_STRING_HPP
13 13
14 #ifndef BOOST_CONFIG_HPP
15 # include <boost/config.hpp>
16 #endif
17
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
19 # pragma once
20 #endif
21
14 #include <boost/container/detail/config_begin.hpp> 22 #include <boost/container/detail/config_begin.hpp>
15 #include <boost/container/detail/workaround.hpp> 23 #include <boost/container/detail/workaround.hpp>
16
17 #include <boost/container/detail/workaround.hpp>
18 #include <boost/container/container_fwd.hpp> 24 #include <boost/container/container_fwd.hpp>
25 // container
26 #include <boost/container/allocator_traits.hpp>
27 #include <boost/container/new_allocator.hpp> //new_allocator
19 #include <boost/container/throw_exception.hpp> 28 #include <boost/container/throw_exception.hpp>
20 #include <boost/container/detail/utilities.hpp> 29 // container/detail
30 #include <boost/container/detail/alloc_helpers.hpp>
31 #include <boost/container/detail/allocator_version_traits.hpp>
32 #include <boost/container/detail/allocation_type.hpp>
33 #include <boost/container/detail/iterator.hpp>
21 #include <boost/container/detail/iterators.hpp> 34 #include <boost/container/detail/iterators.hpp>
22 #include <boost/container/detail/algorithms.hpp> 35 #include <boost/container/detail/min_max.hpp>
36 #include <boost/container/detail/mpl.hpp>
37 #include <boost/container/detail/next_capacity.hpp>
38 #include <boost/container/detail/to_raw_pointer.hpp>
23 #include <boost/container/detail/version_type.hpp> 39 #include <boost/container/detail/version_type.hpp>
24 #include <boost/container/detail/allocation_type.hpp> 40
25 #include <boost/container/allocator_traits.hpp> 41 #include <boost/move/utility_core.hpp>
26 #include <boost/container/detail/allocator_version_traits.hpp> 42 #include <boost/move/adl_move_swap.hpp>
27 #include <boost/container/detail/mpl.hpp>
28 #include <boost/move/utility.hpp>
29 #include <boost/static_assert.hpp> 43 #include <boost/static_assert.hpp>
44 #include <boost/intrusive/pointer_traits.hpp>
45 #include <boost/core/no_exceptions_support.hpp>
46 #include <boost/container/detail/minimal_char_traits_header.hpp>
30 #include <boost/functional/hash.hpp> 47 #include <boost/functional/hash.hpp>
31 #include <boost/intrusive/pointer_traits.hpp> 48
32 #include <boost/detail/no_exceptions_support.hpp> 49
33
34 #include <functional>
35 #include <string>
36 #include <utility>
37 #include <iterator>
38 #include <memory>
39 #include <algorithm> 50 #include <algorithm>
51 #include <functional> //bind2nd, etc.
40 #include <iosfwd> 52 #include <iosfwd>
41 #include <istream> 53 #include <istream>
42 #include <ostream> 54 #include <ostream>
43 #include <ios> 55 #include <ios>
44 #include <locale> 56 #include <locale>
45 #include <cstddef> 57 #include <cstddef>
46 #include <climits> 58 #include <climits>
47 #include <boost/container/detail/type_traits.hpp> 59 #include <boost/container/detail/type_traits.hpp>
48 #include <boost/detail/no_exceptions_support.hpp> 60 #include <boost/move/traits.hpp>
49 #include <boost/type_traits/has_trivial_destructor.hpp>
50 #include <boost/aligned_storage.hpp>
51 61
52 namespace boost { 62 namespace boost {
53 namespace container { 63 namespace container {
54 64
55 /// @cond 65 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
56 namespace container_detail { 66 namespace container_detail {
57 // ------------------------------------------------------------ 67 // ------------------------------------------------------------
58 // Class basic_string_base. 68 // Class basic_string_base.
59 69
60 // basic_string_base is a helper class that makes it it easier to write 70 // basic_string_base is a helper class that makes it it easier to write
61 // an exception-safe version of basic_string. The constructor allocates, 71 // an exception-safe version of basic_string. The constructor allocates,
62 // but does not initialize, a block of memory. The destructor 72 // but does not initialize, a block of memory. The destructor
63 // deallocates, but does not destroy elements within, a block of 73 // deallocates, but does not destroy elements within, a block of
65 // or else points to a block of memory that was allocated using string_base's 75 // or else points to a block of memory that was allocated using string_base's
66 // allocator and whose size is this->m_storage. 76 // allocator and whose size is this->m_storage.
67 template <class Allocator> 77 template <class Allocator>
68 class basic_string_base 78 class basic_string_base
69 { 79 {
70 BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_string_base) 80 basic_string_base & operator=(const basic_string_base &);
81 basic_string_base(const basic_string_base &);
71 82
72 typedef allocator_traits<Allocator> allocator_traits_type; 83 typedef allocator_traits<Allocator> allocator_traits_type;
73 public: 84 public:
74 typedef Allocator allocator_type; 85 typedef Allocator allocator_type;
75 typedef allocator_type stored_allocator_type; 86 typedef allocator_type stored_allocator_type;
76 typedef typename allocator_traits_type::pointer pointer; 87 typedef typename allocator_traits_type::pointer pointer;
77 typedef typename allocator_traits_type::value_type value_type; 88 typedef typename allocator_traits_type::value_type value_type;
78 typedef typename allocator_traits_type::size_type size_type; 89 typedef typename allocator_traits_type::size_type size_type;
79 typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits; 90 typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
84 95
85 basic_string_base(const allocator_type& a) 96 basic_string_base(const allocator_type& a)
86 : members_(a) 97 : members_(a)
87 { init(); } 98 { init(); }
88 99
100 basic_string_base(BOOST_RV_REF(allocator_type) a)
101 : members_(boost::move(a))
102 { this->init(); }
103
89 basic_string_base(const allocator_type& a, size_type n) 104 basic_string_base(const allocator_type& a, size_type n)
90 : members_(a) 105 : members_(a)
91 { 106 {
92 this->init(); 107 this->init();
93 this->allocate_initial_block(n); 108 this->allocate_initial_block(n);
94 } 109 }
95 110
96 basic_string_base(BOOST_RV_REF(basic_string_base) b)
97 : members_(boost::move(b.alloc()))
98 {
99 this->init();
100 this->swap_data(b);
101 }
102
103 ~basic_string_base() 111 ~basic_string_base()
104 { 112 {
105 if(!this->is_short()){ 113 if(!this->is_short()){
106 this->deallocate_block(); 114 this->deallocate_block();
107 this->is_short(true); 115 this->is_short(true);
108 } 116 }
109 } 117 }
147 unsigned char length : (CHAR_BIT - 1); 155 unsigned char length : (CHAR_BIT - 1);
148 }; 156 };
149 157
150 //This type has the same alignment and size as long_t but it's POD 158 //This type has the same alignment and size as long_t but it's POD
151 //so, unlike long_t, it can be placed in a union 159 //so, unlike long_t, it can be placed in a union
152 160
153 typedef typename boost::aligned_storage< sizeof(long_t), 161 typedef typename container_detail::aligned_storage
154 container_detail::alignment_of<long_t>::value>::type long_raw_t; 162 <sizeof(long_t), container_detail::alignment_of<long_t>::value>::type long_raw_t;
155 163
156 protected: 164 protected:
157 static const size_type MinInternalBufferChars = 8; 165 static const size_type MinInternalBufferChars = 8;
158 static const size_type AlignmentOfValueType = 166 static const size_type AlignmentOfValueType =
159 alignment_of<value_type>::value; 167 alignment_of<value_type>::value;
246 this->members_.m_repr.s.h.length = 0; 254 this->members_.m_repr.s.h.length = 0;
247 } 255 }
248 256
249 protected: 257 protected:
250 258
251 typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
252 typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
253 typedef container_detail::integral_constant<unsigned, 259 typedef container_detail::integral_constant<unsigned,
254 boost::container::container_detail::version<Allocator>::value> alloc_version; 260 boost::container::container_detail::version<Allocator>::value> alloc_version;
255 261
256 std::pair<pointer, bool> 262 pointer allocation_command(allocation_type command,
257 allocation_command(allocation_type command,
258 size_type limit_size, 263 size_type limit_size,
259 size_type preferred_size, 264 size_type &prefer_in_recvd_out_size,
260 size_type &received_size, pointer reuse = 0) 265 pointer &reuse)
261 { 266 {
262 if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){ 267 if(this->is_short() && (command & (expand_fwd | expand_bwd)) ){
263 reuse = pointer(); 268 reuse = 0;
264 command &= ~(expand_fwd | expand_bwd); 269 command &= ~(expand_fwd | expand_bwd);
265 } 270 }
266 return container_detail::allocator_version_traits<Allocator>::allocation_command 271 return container_detail::allocator_version_traits<Allocator>::allocation_command
267 (this->alloc(), command, limit_size, preferred_size, received_size, reuse); 272 (this->alloc(), command, limit_size, prefer_in_recvd_out_size, reuse);
268 } 273 }
269 274
270 size_type next_capacity(size_type additional_objects) const 275 size_type next_capacity(size_type additional_objects) const
271 { return get_next_capacity(allocator_traits_type::max_size(this->alloc()), this->priv_storage(), additional_objects); } 276 {
277 return next_capacity_calculator
278 <size_type, NextCapacityDouble /*NextCapacity60Percent*/>::
279 get( allocator_traits_type::max_size(this->alloc())
280 , this->priv_storage(), additional_objects );
281 }
272 282
273 void deallocate(pointer p, size_type n) 283 void deallocate(pointer p, size_type n)
274 { 284 {
275 if (p && (n > InternalBufferChars)) 285 if (p && (n > InternalBufferChars))
276 this->alloc().deallocate(p, n); 286 this->alloc().deallocate(p, n);
277 } 287 }
278 288
279 void construct(pointer p, const value_type &value = value_type()) 289 void construct(pointer p, const value_type &value = value_type())
304 void allocate_initial_block(size_type n) 314 void allocate_initial_block(size_type n)
305 { 315 {
306 if (n <= this->max_size()) { 316 if (n <= this->max_size()) {
307 if(n > InternalBufferChars){ 317 if(n > InternalBufferChars){
308 size_type new_cap = this->next_capacity(n); 318 size_type new_cap = this->next_capacity(n);
309 pointer p = this->allocation_command(allocate_new, n, new_cap, new_cap).first; 319 pointer reuse = 0;
320 pointer p = this->allocation_command(allocate_new, n, new_cap, reuse);
310 this->is_short(false); 321 this->is_short(false);
311 this->priv_long_addr(p); 322 this->priv_long_addr(p);
312 this->priv_long_size(0); 323 this->priv_long_size(0);
313 this->priv_storage(new_cap); 324 this->priv_storage(new_cap);
314 } 325 }
318 } 329 }
319 } 330 }
320 331
321 void deallocate_block() 332 void deallocate_block()
322 { this->deallocate(this->priv_addr(), this->priv_storage()); } 333 { this->deallocate(this->priv_addr(), this->priv_storage()); }
323 334
324 size_type max_size() const 335 size_type max_size() const
325 { return allocator_traits_type::max_size(this->alloc()) - 1; } 336 { return allocator_traits_type::max_size(this->alloc()) - 1; }
326 337
327 protected: 338 protected:
328 size_type priv_capacity() const 339 size_type priv_capacity() const
361 372
362 size_type priv_long_storage() const 373 size_type priv_long_storage() const
363 { return this->members_.m_repr.long_repr().storage; } 374 { return this->members_.m_repr.long_repr().storage; }
364 375
365 void priv_storage(size_type storage) 376 void priv_storage(size_type storage)
366 { 377 {
367 if(!this->is_short()) 378 if(!this->is_short())
368 this->priv_long_storage(storage); 379 this->priv_long_storage(storage);
369 } 380 }
370 381
371 void priv_long_storage(size_type storage) 382 void priv_long_storage(size_type storage)
372 { 383 {
373 this->members_.m_repr.long_repr().storage = storage; 384 this->members_.m_repr.long_repr().storage = storage;
374 } 385 }
375 386
376 size_type priv_size() const 387 size_type priv_size() const
377 { return this->is_short() ? this->priv_short_size() : this->priv_long_size(); } 388 { return this->is_short() ? this->priv_short_size() : this->priv_long_size(); }
381 392
382 size_type priv_long_size() const 393 size_type priv_long_size() const
383 { return this->members_.m_repr.long_repr().length; } 394 { return this->members_.m_repr.long_repr().length; }
384 395
385 void priv_size(size_type sz) 396 void priv_size(size_type sz)
386 { 397 {
387 if(this->is_short()) 398 if(this->is_short())
388 this->priv_short_size(sz); 399 this->priv_short_size(sz);
389 else 400 else
390 this->priv_long_size(sz); 401 this->priv_long_size(sz);
391 } 402 }
392 403
393 void priv_short_size(size_type sz) 404 void priv_short_size(size_type sz)
394 { 405 {
395 this->members_.m_repr.s.h.length = (unsigned char)sz; 406 this->members_.m_repr.s.h.length = (unsigned char)sz;
396 } 407 }
397 408
398 void priv_long_size(size_type sz) 409 void priv_long_size(size_type sz)
399 { 410 {
400 this->members_.m_repr.long_repr().length = sz; 411 this->members_.m_repr.long_repr().length = sz;
401 } 412 }
402 413
403 void swap_data(basic_string_base& other) 414 void swap_data(basic_string_base& other)
404 { 415 {
405 if(this->is_short()){ 416 if(this->is_short()){
406 if(other.is_short()){ 417 if(other.is_short()){
407 std::swap(this->members_.m_repr, other.members_.m_repr); 418 repr_t tmp(this->members_.m_repr);
419 this->members_.m_repr = other.members_.m_repr;
420 other.members_.m_repr = tmp;
408 } 421 }
409 else{ 422 else{
410 short_t short_backup(this->members_.m_repr.short_repr()); 423 short_t short_backup(this->members_.m_repr.short_repr());
411 long_t long_backup (other.members_.m_repr.long_repr()); 424 long_t long_backup (other.members_.m_repr.long_repr());
412 other.members_.m_repr.long_repr().~long_t(); 425 other.members_.m_repr.long_repr().~long_t();
423 ::new(&other.members_.m_repr.long_repr()) long_t; 436 ::new(&other.members_.m_repr.long_repr()) long_t;
424 other.members_.m_repr.long_repr() = long_backup; 437 other.members_.m_repr.long_repr() = long_backup;
425 this->members_.m_repr.short_repr() = short_backup; 438 this->members_.m_repr.short_repr() = short_backup;
426 } 439 }
427 else{ 440 else{
428 boost::container::swap_dispatch(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr()); 441 boost::adl_move_swap(this->members_.m_repr.long_repr(), other.members_.m_repr.long_repr());
429 } 442 }
430 } 443 }
431 } 444 }
432 }; 445 };
433 446
434 } //namespace container_detail { 447 } //namespace container_detail {
435 448
436 /// @endcond 449 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
437 450
438 //! The basic_string class represents a Sequence of characters. It contains all the 451 //! The basic_string class represents a Sequence of characters. It contains all the
439 //! usual operations of a Sequence, and, additionally, it contains standard string 452 //! usual operations of a Sequence, and, additionally, it contains standard string
440 //! operations such as search and concatenation. 453 //! operations such as search and concatenation.
441 //! 454 //!
461 //! 474 //!
462 //! In this implementation, begin(), 475 //! In this implementation, begin(),
463 //! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators. 476 //! end(), rbegin(), rend(), operator[], c_str(), and data() do not invalidate iterators.
464 //! In this implementation, iterators are only invalidated by member functions that 477 //! In this implementation, iterators are only invalidated by member functions that
465 //! explicitly change the string's contents. 478 //! explicitly change the string's contents.
479 //!
480 //! \tparam CharT The type of character it contains.
481 //! \tparam Traits The Character Traits type, which encapsulates basic character operations
482 //! \tparam Allocator The allocator, used for internal memory management.
466 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED 483 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
467 template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = std::allocator<CharT> > 484 template <class CharT, class Traits = std::char_traits<CharT>, class Allocator = new_allocator<CharT> >
468 #else 485 #else
469 template <class CharT, class Traits, class Allocator> 486 template <class CharT, class Traits, class Allocator>
470 #endif 487 #endif
471 class basic_string 488 class basic_string
472 : private container_detail::basic_string_base<Allocator> 489 : private container_detail::basic_string_base<Allocator>
473 { 490 {
474 /// @cond 491 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
475 private: 492 private:
476 typedef allocator_traits<Allocator> allocator_traits_type; 493 typedef allocator_traits<Allocator> allocator_traits_type;
477 BOOST_COPYABLE_AND_MOVABLE(basic_string) 494 BOOST_COPYABLE_AND_MOVABLE(basic_string)
478 typedef container_detail::basic_string_base<Allocator> base_t; 495 typedef container_detail::basic_string_base<Allocator> base_t;
479 static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars; 496 static const typename base_t::size_type InternalBufferChars = base_t::InternalBufferChars;
481 protected: 498 protected:
482 // Allocator helper class to use a char_traits as a function object. 499 // Allocator helper class to use a char_traits as a function object.
483 500
484 template <class Tr> 501 template <class Tr>
485 struct Eq_traits 502 struct Eq_traits
486 : public std::binary_function<typename Tr::char_type, 503 {
487 typename Tr::char_type, 504 //Compatibility with std::binary_function
488 bool> 505 typedef typename Tr::char_type first_argument_type;
489 { 506 typedef typename Tr::char_type second_argument_type;
490 bool operator()(const typename Tr::char_type& x, 507 typedef bool result_type;
491 const typename Tr::char_type& y) const 508
509 bool operator()(const first_argument_type& x, const second_argument_type& y) const
492 { return Tr::eq(x, y); } 510 { return Tr::eq(x, y); }
493 }; 511 };
494 512
495 template <class Tr> 513 template <class Tr>
496 struct Not_within_traits 514 struct Not_within_traits
497 : public std::unary_function<typename Tr::char_type, bool> 515 {
498 { 516 typedef typename Tr::char_type argument_type;
517 typedef bool result_type;
518
499 typedef const typename Tr::char_type* Pointer; 519 typedef const typename Tr::char_type* Pointer;
500 const Pointer m_first; 520 const Pointer m_first;
501 const Pointer m_last; 521 const Pointer m_last;
502 522
503 Not_within_traits(Pointer f, Pointer l) 523 Not_within_traits(Pointer f, Pointer l)
507 { 527 {
508 return std::find_if(m_first, m_last, 528 return std::find_if(m_first, m_last,
509 std::bind1st(Eq_traits<Tr>(), x)) == m_last; 529 std::bind1st(Eq_traits<Tr>(), x)) == m_last;
510 } 530 }
511 }; 531 };
512 /// @endcond 532 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
513 533
514 public: 534 public:
515 ////////////////////////////////////////////// 535 //////////////////////////////////////////////
516 // 536 //
517 // types 537 // types
527 typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type; 547 typedef typename ::boost::container::allocator_traits<Allocator>::difference_type difference_type;
528 typedef Allocator allocator_type; 548 typedef Allocator allocator_type;
529 typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type; 549 typedef BOOST_CONTAINER_IMPDEF(allocator_type) stored_allocator_type;
530 typedef BOOST_CONTAINER_IMPDEF(pointer) iterator; 550 typedef BOOST_CONTAINER_IMPDEF(pointer) iterator;
531 typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator; 551 typedef BOOST_CONTAINER_IMPDEF(const_pointer) const_iterator;
532 typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<iterator>) reverse_iterator; 552 typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<iterator>) reverse_iterator;
533 typedef BOOST_CONTAINER_IMPDEF(std::reverse_iterator<const_iterator>) const_reverse_iterator; 553 typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator<const_iterator>) const_reverse_iterator;
534 static const size_type npos = size_type(-1); 554 static const size_type npos = size_type(-1);
535 555
536 /// @cond 556 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
537 private: 557 private:
538 typedef constant_iterator<CharT, difference_type> cvalue_iterator; 558 typedef constant_iterator<CharT, difference_type> cvalue_iterator;
539 typedef typename base_t::allocator_v1 allocator_v1;
540 typedef typename base_t::allocator_v2 allocator_v2;
541 typedef typename base_t::alloc_version alloc_version; 559 typedef typename base_t::alloc_version alloc_version;
542 typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits; 560 typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
543 /// @endcond 561 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
544 562
545 public: // Constructor, destructor, assignment. 563 public: // Constructor, destructor, assignment.
546 ////////////////////////////////////////////// 564 //////////////////////////////////////////////
547 // 565 //
548 // construct/copy/destroy 566 // construct/copy/destroy
549 // 567 //
550 ////////////////////////////////////////////// 568 //////////////////////////////////////////////
551 /// @cond 569 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
552 struct reserve_t {}; 570 struct reserve_t {};
553 571
554 basic_string(reserve_t, size_type n, 572 basic_string(reserve_t, size_type n,
555 const allocator_type& a = allocator_type()) 573 const allocator_type& a = allocator_type())
556 //Select allocator as in copy constructor as reserve_t-based constructors 574 //Select allocator as in copy constructor as reserve_t-based constructors
557 //are two step copies optimized for capacity 575 //are two step copies optimized for capacity
558 : base_t( allocator_traits_type::select_on_container_copy_construction(a) 576 : base_t( allocator_traits_type::select_on_container_copy_construction(a)
559 , n + 1) 577 , n + 1)
560 { this->priv_terminate_string(); } 578 { this->priv_terminate_string(); }
561 579
562 /// @endcond 580 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
563 581
564 //! <b>Effects</b>: Default constructs a basic_string. 582 //! <b>Effects</b>: Default constructs a basic_string.
565 //! 583 //!
566 //! <b>Throws</b>: If allocator_type's default constructor throws. 584 //! <b>Throws</b>: If allocator_type's default constructor throws.
567 basic_string() 585 basic_string()
570 588
571 589
572 //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter. 590 //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter.
573 //! 591 //!
574 //! <b>Throws</b>: Nothing 592 //! <b>Throws</b>: Nothing
575 explicit basic_string(const allocator_type& a) BOOST_CONTAINER_NOEXCEPT 593 explicit basic_string(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW
576 : base_t(a) 594 : base_t(a)
577 { this->priv_terminate_string(); } 595 { this->priv_terminate_string(); }
578 596
579 //! <b>Effects</b>: Copy constructs a basic_string. 597 //! <b>Effects</b>: Copy constructs a basic_string.
580 //! 598 //!
581 //! <b>Postcondition</b>: x == *this. 599 //! <b>Postcondition</b>: x == *this.
582 //! 600 //!
583 //! <b>Throws</b>: If allocator_type's default constructor throws. 601 //! <b>Throws</b>: If allocator_type's default constructor or allocation throws.
584 basic_string(const basic_string& s) 602 basic_string(const basic_string& s)
585 : base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc())) 603 : base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
586 { 604 {
587 this->priv_terminate_string(); 605 this->priv_terminate_string();
588 this->assign(s.begin(), s.end()); 606 this->assign(s.begin(), s.end());
591 //! <b>Effects</b>: Move constructor. Moves s's resources to *this. 609 //! <b>Effects</b>: Move constructor. Moves s's resources to *this.
592 //! 610 //!
593 //! <b>Throws</b>: Nothing. 611 //! <b>Throws</b>: Nothing.
594 //! 612 //!
595 //! <b>Complexity</b>: Constant. 613 //! <b>Complexity</b>: Constant.
596 basic_string(BOOST_RV_REF(basic_string) s) BOOST_CONTAINER_NOEXCEPT 614 basic_string(BOOST_RV_REF(basic_string) s) BOOST_NOEXCEPT_OR_NOTHROW
597 : base_t(boost::move((base_t&)s)) 615 : base_t(boost::move(s.alloc()))
598 {} 616 {
617 if(s.alloc() == this->alloc()){
618 this->swap_data(s);
619 }
620 else{
621 this->assign(s.begin(), s.end());
622 }
623 }
599 624
600 //! <b>Effects</b>: Copy constructs a basic_string using the specified allocator. 625 //! <b>Effects</b>: Copy constructs a basic_string using the specified allocator.
601 //! 626 //!
602 //! <b>Postcondition</b>: x == *this. 627 //! <b>Postcondition</b>: x == *this.
603 //! 628 //!
667 this->priv_terminate_string(); 692 this->priv_terminate_string();
668 this->assign(n, c); 693 this->assign(n, c);
669 } 694 }
670 695
671 //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter, 696 //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
697 //! and is initialized by n default-initialized characters.
698 basic_string(size_type n, default_init_t, const allocator_type& a = allocator_type())
699 : base_t(a, n + 1)
700 {
701 this->priv_size(n);
702 this->priv_terminate_string();
703 }
704
705 //! <b>Effects</b>: Constructs a basic_string taking the allocator as parameter,
672 //! and a range of iterators. 706 //! and a range of iterators.
673 template <class InputIterator> 707 template <class InputIterator>
674 basic_string(InputIterator f, InputIterator l, const allocator_type& a = allocator_type()) 708 basic_string(InputIterator f, InputIterator l, const allocator_type& a = allocator_type())
675 : base_t(a) 709 : base_t(a)
676 { 710 {
681 //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated. 715 //! <b>Effects</b>: Destroys the basic_string. All used memory is deallocated.
682 //! 716 //!
683 //! <b>Throws</b>: Nothing. 717 //! <b>Throws</b>: Nothing.
684 //! 718 //!
685 //! <b>Complexity</b>: Constant. 719 //! <b>Complexity</b>: Constant.
686 ~basic_string() BOOST_CONTAINER_NOEXCEPT 720 ~basic_string() BOOST_NOEXCEPT_OR_NOTHROW
687 {} 721 {}
688 722
689 //! <b>Effects</b>: Copy constructs a string. 723 //! <b>Effects</b>: Copy constructs a string.
690 //! 724 //!
691 //! <b>Postcondition</b>: x == *this. 725 //! <b>Postcondition</b>: x == *this.
692 //! 726 //!
693 //! <b>Complexity</b>: Linear to the elements x contains. 727 //! <b>Complexity</b>: Linear to the elements x contains.
710 this->assign(x.begin(), x.end()); 744 this->assign(x.begin(), x.end());
711 } 745 }
712 return *this; 746 return *this;
713 } 747 }
714 748
715 //! <b>Effects</b>: Move constructor. Moves mx's resources to *this. 749 //! <b>Effects</b>: Move constructor. Moves x's resources to *this.
716 //! 750 //!
717 //! <b>Throws</b>: If allocator_type's copy constructor throws. 751 //! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
718 //! 752 //! is false and allocation throws
719 //! <b>Complexity</b>: Constant. 753 //!
720 basic_string& operator=(BOOST_RV_REF(basic_string) x) BOOST_CONTAINER_NOEXCEPT 754 //! <b>Complexity</b>: Constant if allocator_traits_type::
721 { 755 //! propagate_on_container_move_assignment is true or
722 if (&x != this){ 756 //! this->get>allocator() == x.get_allocator(). Linear otherwise.
723 allocator_type &this_alloc = this->alloc(); 757 basic_string& operator=(BOOST_RV_REF(basic_string) x)
724 allocator_type &x_alloc = x.alloc(); 758 BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
725 //If allocators are equal we can just swap pointers 759 || allocator_traits_type::is_always_equal::value)
726 if(this_alloc == x_alloc){ 760 {
727 //Destroy objects but retain memory in case x reuses it in the future 761 //for move constructor, no aliasing (&x != this) is assummed.
728 this->clear(); 762 BOOST_ASSERT(this != &x);
729 this->swap_data(x); 763 allocator_type &this_alloc = this->alloc();
730 //Move allocator if needed 764 allocator_type &x_alloc = x.alloc();
731 container_detail::bool_<allocator_traits_type:: 765 const bool propagate_alloc = allocator_traits_type::
732 propagate_on_container_move_assignment::value> flag; 766 propagate_on_container_move_assignment::value;
733 container_detail::move_alloc(this_alloc, x_alloc, flag); 767 container_detail::bool_<propagate_alloc> flag;
734 } 768 const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
735 //If unequal allocators, then do a one by one move 769 //Resources can be transferred if both allocators are
736 else{ 770 //going to be equal after this function (either propagated or already equal)
737 this->assign( x.begin(), x.end()); 771 if(propagate_alloc || allocators_equal){
738 } 772 //Destroy objects but retain memory in case x reuses it in the future
773 this->clear();
774 //Move allocator if needed
775 container_detail::move_alloc(this_alloc, x_alloc, flag);
776 //Nothrow swap
777 this->swap_data(x);
778 }
779 //Else do a one by one move
780 else{
781 this->assign( x.begin(), x.end());
739 } 782 }
740 return *this; 783 return *this;
741 } 784 }
742 785
743 //! <b>Effects</b>: Assignment from a null-terminated c-string. 786 //! <b>Effects</b>: Assignment from a null-terminated c-string.
751 //! <b>Effects</b>: Returns a copy of the internal allocator. 794 //! <b>Effects</b>: Returns a copy of the internal allocator.
752 //! 795 //!
753 //! <b>Throws</b>: If allocator's copy constructor throws. 796 //! <b>Throws</b>: If allocator's copy constructor throws.
754 //! 797 //!
755 //! <b>Complexity</b>: Constant. 798 //! <b>Complexity</b>: Constant.
756 allocator_type get_allocator() const BOOST_CONTAINER_NOEXCEPT 799 allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
757 { return this->alloc(); } 800 { return this->alloc(); }
758 801
759 //! <b>Effects</b>: Returns a reference to the internal allocator. 802 //! <b>Effects</b>: Returns a reference to the internal allocator.
760 //! 803 //!
761 //! <b>Throws</b>: Nothing 804 //! <b>Throws</b>: Nothing
762 //! 805 //!
763 //! <b>Complexity</b>: Constant. 806 //! <b>Complexity</b>: Constant.
764 //! 807 //!
765 //! <b>Note</b>: Non-standard extension. 808 //! <b>Note</b>: Non-standard extension.
766 stored_allocator_type &get_stored_allocator() BOOST_CONTAINER_NOEXCEPT 809 stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW
767 { return this->alloc(); } 810 { return this->alloc(); }
768 811
769 //! <b>Effects</b>: Returns a reference to the internal allocator. 812 //! <b>Effects</b>: Returns a reference to the internal allocator.
770 //! 813 //!
771 //! <b>Throws</b>: Nothing 814 //! <b>Throws</b>: Nothing
772 //! 815 //!
773 //! <b>Complexity</b>: Constant. 816 //! <b>Complexity</b>: Constant.
774 //! 817 //!
775 //! <b>Note</b>: Non-standard extension. 818 //! <b>Note</b>: Non-standard extension.
776 const stored_allocator_type &get_stored_allocator() const BOOST_CONTAINER_NOEXCEPT 819 const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW
777 { return this->alloc(); } 820 { return this->alloc(); }
778 821
779 ////////////////////////////////////////////// 822 //////////////////////////////////////////////
780 // 823 //
781 // iterators 824 // iterators
785 //! <b>Effects</b>: Returns an iterator to the first element contained in the vector. 828 //! <b>Effects</b>: Returns an iterator to the first element contained in the vector.
786 //! 829 //!
787 //! <b>Throws</b>: Nothing. 830 //! <b>Throws</b>: Nothing.
788 //! 831 //!
789 //! <b>Complexity</b>: Constant. 832 //! <b>Complexity</b>: Constant.
790 iterator begin() BOOST_CONTAINER_NOEXCEPT 833 iterator begin() BOOST_NOEXCEPT_OR_NOTHROW
791 { return this->priv_addr(); } 834 { return this->priv_addr(); }
792 835
793 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector. 836 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
794 //! 837 //!
795 //! <b>Throws</b>: Nothing. 838 //! <b>Throws</b>: Nothing.
796 //! 839 //!
797 //! <b>Complexity</b>: Constant. 840 //! <b>Complexity</b>: Constant.
798 const_iterator begin() const BOOST_CONTAINER_NOEXCEPT 841 const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW
799 { return this->priv_addr(); } 842 { return this->priv_addr(); }
800 843
801 //! <b>Effects</b>: Returns an iterator to the end of the vector. 844 //! <b>Effects</b>: Returns an iterator to the end of the vector.
802 //! 845 //!
803 //! <b>Throws</b>: Nothing. 846 //! <b>Throws</b>: Nothing.
804 //! 847 //!
805 //! <b>Complexity</b>: Constant. 848 //! <b>Complexity</b>: Constant.
806 iterator end() BOOST_CONTAINER_NOEXCEPT 849 iterator end() BOOST_NOEXCEPT_OR_NOTHROW
807 { return this->priv_end_addr(); } 850 { return this->priv_end_addr(); }
808 851
809 //! <b>Effects</b>: Returns a const_iterator to the end of the vector. 852 //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
810 //! 853 //!
811 //! <b>Throws</b>: Nothing. 854 //! <b>Throws</b>: Nothing.
812 //! 855 //!
813 //! <b>Complexity</b>: Constant. 856 //! <b>Complexity</b>: Constant.
814 const_iterator end() const BOOST_CONTAINER_NOEXCEPT 857 const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW
815 { return this->priv_end_addr(); } 858 { return this->priv_end_addr(); }
816 859
817 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning 860 //! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
818 //! of the reversed vector. 861 //! of the reversed vector.
819 //! 862 //!
820 //! <b>Throws</b>: Nothing. 863 //! <b>Throws</b>: Nothing.
821 //! 864 //!
822 //! <b>Complexity</b>: Constant. 865 //! <b>Complexity</b>: Constant.
823 reverse_iterator rbegin() BOOST_CONTAINER_NOEXCEPT 866 reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW
824 { return reverse_iterator(this->priv_end_addr()); } 867 { return reverse_iterator(this->priv_end_addr()); }
825 868
826 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 869 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
827 //! of the reversed vector. 870 //! of the reversed vector.
828 //! 871 //!
829 //! <b>Throws</b>: Nothing. 872 //! <b>Throws</b>: Nothing.
830 //! 873 //!
831 //! <b>Complexity</b>: Constant. 874 //! <b>Complexity</b>: Constant.
832 const_reverse_iterator rbegin() const BOOST_CONTAINER_NOEXCEPT 875 const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW
833 { return this->crbegin(); } 876 { return this->crbegin(); }
834 877
835 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end 878 //! <b>Effects</b>: Returns a reverse_iterator pointing to the end
836 //! of the reversed vector. 879 //! of the reversed vector.
837 //! 880 //!
838 //! <b>Throws</b>: Nothing. 881 //! <b>Throws</b>: Nothing.
839 //! 882 //!
840 //! <b>Complexity</b>: Constant. 883 //! <b>Complexity</b>: Constant.
841 reverse_iterator rend() BOOST_CONTAINER_NOEXCEPT 884 reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW
842 { return reverse_iterator(this->priv_addr()); } 885 { return reverse_iterator(this->priv_addr()); }
843 886
844 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end 887 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
845 //! of the reversed vector. 888 //! of the reversed vector.
846 //! 889 //!
847 //! <b>Throws</b>: Nothing. 890 //! <b>Throws</b>: Nothing.
848 //! 891 //!
849 //! <b>Complexity</b>: Constant. 892 //! <b>Complexity</b>: Constant.
850 const_reverse_iterator rend() const BOOST_CONTAINER_NOEXCEPT 893 const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW
851 { return this->crend(); } 894 { return this->crend(); }
852 895
853 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector. 896 //! <b>Effects</b>: Returns a const_iterator to the first element contained in the vector.
854 //! 897 //!
855 //! <b>Throws</b>: Nothing. 898 //! <b>Throws</b>: Nothing.
856 //! 899 //!
857 //! <b>Complexity</b>: Constant. 900 //! <b>Complexity</b>: Constant.
858 const_iterator cbegin() const BOOST_CONTAINER_NOEXCEPT 901 const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW
859 { return this->priv_addr(); } 902 { return this->priv_addr(); }
860 903
861 //! <b>Effects</b>: Returns a const_iterator to the end of the vector. 904 //! <b>Effects</b>: Returns a const_iterator to the end of the vector.
862 //! 905 //!
863 //! <b>Throws</b>: Nothing. 906 //! <b>Throws</b>: Nothing.
864 //! 907 //!
865 //! <b>Complexity</b>: Constant. 908 //! <b>Complexity</b>: Constant.
866 const_iterator cend() const BOOST_CONTAINER_NOEXCEPT 909 const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW
867 { return this->priv_end_addr(); } 910 { return this->priv_end_addr(); }
868 911
869 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning 912 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the beginning
870 //! of the reversed vector. 913 //! of the reversed vector.
871 //! 914 //!
872 //! <b>Throws</b>: Nothing. 915 //! <b>Throws</b>: Nothing.
873 //! 916 //!
874 //! <b>Complexity</b>: Constant. 917 //! <b>Complexity</b>: Constant.
875 const_reverse_iterator crbegin() const BOOST_CONTAINER_NOEXCEPT 918 const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW
876 { return const_reverse_iterator(this->priv_end_addr()); } 919 { return const_reverse_iterator(this->priv_end_addr()); }
877 920
878 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end 921 //! <b>Effects</b>: Returns a const_reverse_iterator pointing to the end
879 //! of the reversed vector. 922 //! of the reversed vector.
880 //! 923 //!
881 //! <b>Throws</b>: Nothing. 924 //! <b>Throws</b>: Nothing.
882 //! 925 //!
883 //! <b>Complexity</b>: Constant. 926 //! <b>Complexity</b>: Constant.
884 const_reverse_iterator crend() const BOOST_CONTAINER_NOEXCEPT 927 const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW
885 { return const_reverse_iterator(this->priv_addr()); } 928 { return const_reverse_iterator(this->priv_addr()); }
886 929
887 ////////////////////////////////////////////// 930 //////////////////////////////////////////////
888 // 931 //
889 // capacity 932 // capacity
893 //! <b>Effects</b>: Returns true if the vector contains no elements. 936 //! <b>Effects</b>: Returns true if the vector contains no elements.
894 //! 937 //!
895 //! <b>Throws</b>: Nothing. 938 //! <b>Throws</b>: Nothing.
896 //! 939 //!
897 //! <b>Complexity</b>: Constant. 940 //! <b>Complexity</b>: Constant.
898 bool empty() const BOOST_CONTAINER_NOEXCEPT 941 bool empty() const BOOST_NOEXCEPT_OR_NOTHROW
899 { return !this->priv_size(); } 942 { return !this->priv_size(); }
900 943
901 //! <b>Effects</b>: Returns the number of the elements contained in the vector. 944 //! <b>Effects</b>: Returns the number of the elements contained in the vector.
902 //! 945 //!
903 //! <b>Throws</b>: Nothing. 946 //! <b>Throws</b>: Nothing.
904 //! 947 //!
905 //! <b>Complexity</b>: Constant. 948 //! <b>Complexity</b>: Constant.
906 size_type size() const BOOST_CONTAINER_NOEXCEPT 949 size_type size() const BOOST_NOEXCEPT_OR_NOTHROW
907 { return this->priv_size(); } 950 { return this->priv_size(); }
908 951
909 //! <b>Effects</b>: Returns the number of the elements contained in the vector. 952 //! <b>Effects</b>: Returns the number of the elements contained in the vector.
910 //! 953 //!
911 //! <b>Throws</b>: Nothing. 954 //! <b>Throws</b>: Nothing.
912 //! 955 //!
913 //! <b>Complexity</b>: Constant. 956 //! <b>Complexity</b>: Constant.
914 size_type length() const BOOST_CONTAINER_NOEXCEPT 957 size_type length() const BOOST_NOEXCEPT_OR_NOTHROW
915 { return this->size(); } 958 { return this->size(); }
916 959
917 //! <b>Effects</b>: Returns the largest possible size of the vector. 960 //! <b>Effects</b>: Returns the largest possible size of the vector.
918 //! 961 //!
919 //! <b>Throws</b>: Nothing. 962 //! <b>Throws</b>: Nothing.
920 //! 963 //!
921 //! <b>Complexity</b>: Constant. 964 //! <b>Complexity</b>: Constant.
922 size_type max_size() const BOOST_CONTAINER_NOEXCEPT 965 size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW
923 { return base_t::max_size(); } 966 { return base_t::max_size(); }
924 967
925 //! <b>Effects</b>: Inserts or erases elements at the end such that 968 //! <b>Effects</b>: Inserts or erases elements at the end such that
926 //! the size becomes n. New elements are copy constructed from x. 969 //! the size becomes n. New elements are copy constructed from x.
927 //! 970 //!
943 //! 986 //!
944 //! <b>Complexity</b>: Linear to the difference between size() and new_size. 987 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
945 void resize(size_type n) 988 void resize(size_type n)
946 { resize(n, CharT()); } 989 { resize(n, CharT()); }
947 990
991
992 //! <b>Effects</b>: Inserts or erases elements at the end such that
993 //! the size becomes n. New elements are uninitialized.
994 //!
995 //! <b>Throws</b>: If memory allocation throws
996 //!
997 //! <b>Complexity</b>: Linear to the difference between size() and new_size.
998 //!
999 //! <b>Note</b>: Non-standard extension
1000 void resize(size_type n, default_init_t)
1001 {
1002 if (n <= this->size())
1003 this->erase(this->begin() + n, this->end());
1004 else{
1005 this->priv_reserve(n, false);
1006 this->priv_size(n);
1007 this->priv_terminate_string();
1008 }
1009 }
1010
948 //! <b>Effects</b>: Number of elements for which memory has been allocated. 1011 //! <b>Effects</b>: Number of elements for which memory has been allocated.
949 //! capacity() is always greater than or equal to size(). 1012 //! capacity() is always greater than or equal to size().
950 //! 1013 //!
951 //! <b>Throws</b>: Nothing. 1014 //! <b>Throws</b>: Nothing.
952 //! 1015 //!
953 //! <b>Complexity</b>: Constant. 1016 //! <b>Complexity</b>: Constant.
954 size_type capacity() const BOOST_CONTAINER_NOEXCEPT 1017 size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW
955 { return this->priv_capacity(); } 1018 { return this->priv_capacity(); }
956 1019
957 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no 1020 //! <b>Effects</b>: If n is less than or equal to capacity(), this call has no
958 //! effect. Otherwise, it is a request for allocation of additional memory. 1021 //! effect. Otherwise, it is a request for allocation of additional memory.
959 //! If the request is successful, then capacity() is greater than or equal to 1022 //! If the request is successful, then capacity() is greater than or equal to
960 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. 1023 //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged.
961 //! 1024 //!
962 //! <b>Throws</b>: If memory allocation allocation throws 1025 //! <b>Throws</b>: If memory allocation allocation throws
963 void reserve(size_type res_arg) 1026 void reserve(size_type res_arg)
964 { 1027 { this->priv_reserve(res_arg); }
965 if (res_arg > this->max_size()){
966 throw_length_error("basic_string::reserve max_size() exceeded");
967 }
968
969 if (this->capacity() < res_arg){
970 size_type n = container_detail::max_value(res_arg, this->size()) + 1;
971 size_type new_cap = this->next_capacity(n);
972 pointer new_start = this->allocation_command
973 (allocate_new, n, new_cap, new_cap).first;
974 size_type new_length = 0;
975
976 const pointer addr = this->priv_addr();
977 new_length += priv_uninitialized_copy
978 (addr, addr + this->priv_size(), new_start);
979 this->priv_construct_null(new_start + new_length);
980 this->deallocate_block();
981 this->is_short(false);
982 this->priv_long_addr(new_start);
983 this->priv_long_size(new_length);
984 this->priv_storage(new_cap);
985 }
986 }
987 1028
988 //! <b>Effects</b>: Tries to deallocate the excess of memory created 1029 //! <b>Effects</b>: Tries to deallocate the excess of memory created
989 //! with previous allocations. The size of the string is unchanged 1030 //! with previous allocations. The size of the string is unchanged
990 //! 1031 //!
991 //! <b>Throws</b>: Nothing 1032 //! <b>Throws</b>: Nothing
1028 //! from the beginning of the container. 1069 //! from the beginning of the container.
1029 //! 1070 //!
1030 //! <b>Throws</b>: Nothing. 1071 //! <b>Throws</b>: Nothing.
1031 //! 1072 //!
1032 //! <b>Complexity</b>: Constant. 1073 //! <b>Complexity</b>: Constant.
1033 reference operator[](size_type n) BOOST_CONTAINER_NOEXCEPT 1074 reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
1034 { return *(this->priv_addr() + n); } 1075 { return *(this->priv_addr() + n); }
1035 1076
1036 //! <b>Requires</b>: size() > n. 1077 //! <b>Requires</b>: size() > n.
1037 //! 1078 //!
1038 //! <b>Effects</b>: Returns a const reference to the nth element 1079 //! <b>Effects</b>: Returns a const reference to the nth element
1039 //! from the beginning of the container. 1080 //! from the beginning of the container.
1040 //! 1081 //!
1041 //! <b>Throws</b>: Nothing. 1082 //! <b>Throws</b>: Nothing.
1042 //! 1083 //!
1043 //! <b>Complexity</b>: Constant. 1084 //! <b>Complexity</b>: Constant.
1044 const_reference operator[](size_type n) const BOOST_CONTAINER_NOEXCEPT 1085 const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
1045 { return *(this->priv_addr() + n); } 1086 { return *(this->priv_addr() + n); }
1046 1087
1047 //! <b>Requires</b>: size() > n. 1088 //! <b>Requires</b>: size() > n.
1048 //! 1089 //!
1049 //! <b>Effects</b>: Returns a reference to the nth element 1090 //! <b>Effects</b>: Returns a reference to the nth element
1182 //! controlled by str. Leaves str in a valid but unspecified state. 1223 //! controlled by str. Leaves str in a valid but unspecified state.
1183 //! 1224 //!
1184 //! <b>Throws</b>: Nothing 1225 //! <b>Throws</b>: Nothing
1185 //! 1226 //!
1186 //! <b>Returns</b>: *this 1227 //! <b>Returns</b>: *this
1187 basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_CONTAINER_NOEXCEPT 1228 basic_string& assign(BOOST_RV_REF(basic_string) ms) BOOST_NOEXCEPT_OR_NOTHROW
1188 { return this->swap_data(ms), *this; } 1229 { return this->swap_data(ms), *this; }
1189 1230
1190 //! <b>Requires</b>: pos <= str.size() 1231 //! <b>Requires</b>: pos <= str.size()
1191 //! 1232 //!
1192 //! <b>Effects</b>: Determines the effective length rlen of the string to assign as 1233 //! <b>Effects</b>: Determines the effective length rlen of the string to assign as
1207 //! 1248 //!
1208 //! <b>Effects</b>: Replaces the string controlled by *this with a string of 1249 //! <b>Effects</b>: Replaces the string controlled by *this with a string of
1209 //! length n whose elements are a copy of those pointed to by s. 1250 //! length n whose elements are a copy of those pointed to by s.
1210 //! 1251 //!
1211 //! <b>Throws</b>: If memory allocation throws or length_error if n > max_size(). 1252 //! <b>Throws</b>: If memory allocation throws or length_error if n > max_size().
1212 //! 1253 //!
1213 //! <b>Returns</b>: *this 1254 //! <b>Returns</b>: *this
1214 basic_string& assign(const CharT* s, size_type n) 1255 basic_string& assign(const CharT* s, size_type n)
1215 { return this->assign(s, s + n); } 1256 { return this->assign(s, s + n); }
1216 1257
1217 //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT. 1258 //! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
1225 //! <b>Effects</b>: Equivalent to assign(basic_string(n, c)). 1266 //! <b>Effects</b>: Equivalent to assign(basic_string(n, c)).
1226 //! 1267 //!
1227 //! <b>Returns</b>: *this 1268 //! <b>Returns</b>: *this
1228 basic_string& assign(size_type n, CharT c) 1269 basic_string& assign(size_type n, CharT c)
1229 { return this->assign(cvalue_iterator(c, n), cvalue_iterator()); } 1270 { return this->assign(cvalue_iterator(c, n), cvalue_iterator()); }
1271
1272 //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
1273 //!
1274 //! <b>Returns</b>: *this
1275 basic_string& assign(const CharT* first, const CharT* last)
1276 {
1277 size_type n = static_cast<size_type>(last - first);
1278 this->reserve(n);
1279 CharT* ptr = container_detail::to_raw_pointer(this->priv_addr());
1280 Traits::copy(ptr, first, n);
1281 this->priv_construct_null(ptr + n);
1282 this->priv_size(n);
1283 return *this;
1284 }
1230 1285
1231 //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)). 1286 //! <b>Effects</b>: Equivalent to assign(basic_string(first, last)).
1232 //! 1287 //!
1233 //! <b>Returns</b>: *this 1288 //! <b>Returns</b>: *this
1234 template <class InputIter> 1289 template <class InputIter>
1392 { 1447 {
1393 const size_type n_pos = p - this->cbegin(); 1448 const size_type n_pos = p - this->cbegin();
1394 for ( ; first != last; ++first, ++p) { 1449 for ( ; first != last; ++first, ++p) {
1395 p = this->insert(p, *first); 1450 p = this->insert(p, *first);
1396 } 1451 }
1397 return this->begin() + n_pos; 1452 return this->begin() + n_pos;
1398 } 1453 }
1399 1454
1400 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) 1455 #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
1401 template <class ForwardIter> 1456 template <class ForwardIter>
1402 iterator insert(const_iterator p, ForwardIter first, ForwardIter last 1457 iterator insert(const_iterator p, ForwardIter first, ForwardIter last
1406 >::type * = 0 1461 >::type * = 0
1407 ) 1462 )
1408 { 1463 {
1409 const size_type n_pos = p - this->cbegin(); 1464 const size_type n_pos = p - this->cbegin();
1410 if (first != last) { 1465 if (first != last) {
1411 const size_type n = std::distance(first, last); 1466 const size_type n = boost::container::iterator_distance(first, last);
1412 const size_type old_size = this->priv_size(); 1467 const size_type old_size = this->priv_size();
1413 const size_type remaining = this->capacity() - old_size; 1468 const size_type remaining = this->capacity() - old_size;
1414 const pointer old_start = this->priv_addr(); 1469 const pointer old_start = this->priv_addr();
1415 bool enough_capacity = false; 1470 bool enough_capacity = false;
1416 std::pair<pointer, bool> allocation_ret;
1417 size_type new_cap = 0; 1471 size_type new_cap = 0;
1418 1472
1419 //Check if we have enough capacity 1473 //Check if we have enough capacity
1474 pointer hint = pointer();
1475 pointer allocation_ret = pointer();
1420 if (remaining >= n){ 1476 if (remaining >= n){
1421 enough_capacity = true; 1477 enough_capacity = true;
1422 } 1478 }
1423 else { 1479 else {
1424 //Otherwise expand current buffer or allocate new storage 1480 //Otherwise expand current buffer or allocate new storage
1425 new_cap = this->next_capacity(n); 1481 new_cap = this->next_capacity(n);
1482 hint = old_start;
1426 allocation_ret = this->allocation_command 1483 allocation_ret = this->allocation_command
1427 (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, 1484 (allocate_new | expand_fwd | expand_bwd, old_size + n + 1, new_cap, hint);
1428 new_cap, new_cap, old_start);
1429 1485
1430 //Check forward expansion 1486 //Check forward expansion
1431 if(old_start == allocation_ret.first){ 1487 if(old_start == allocation_ret){
1432 enough_capacity = true; 1488 enough_capacity = true;
1433 this->priv_storage(new_cap); 1489 this->priv_storage(new_cap);
1434 } 1490 }
1435 } 1491 }
1436 1492
1449 (elems_after - n) + 1); 1505 (elems_after - n) + 1);
1450 this->priv_copy(first, last, const_cast<CharT*>(container_detail::to_raw_pointer(p))); 1506 this->priv_copy(first, last, const_cast<CharT*>(container_detail::to_raw_pointer(p)));
1451 } 1507 }
1452 else { 1508 else {
1453 ForwardIter mid = first; 1509 ForwardIter mid = first;
1454 std::advance(mid, elems_after + 1); 1510 boost::container::iterator_advance(mid, elems_after + 1);
1455 1511
1456 priv_uninitialized_copy(mid, last, old_start + old_size + 1); 1512 priv_uninitialized_copy(mid, last, old_start + old_size + 1);
1457 const size_type newer_size = old_size + (n - elems_after); 1513 const size_type newer_size = old_size + (n - elems_after);
1458 this->priv_size(newer_size); 1514 this->priv_size(newer_size);
1459 priv_uninitialized_copy 1515 priv_uninitialized_copy
1462 this->priv_size(newer_size + elems_after); 1518 this->priv_size(newer_size + elems_after);
1463 this->priv_copy(first, mid, const_cast<CharT*>(container_detail::to_raw_pointer(p))); 1519 this->priv_copy(first, mid, const_cast<CharT*>(container_detail::to_raw_pointer(p)));
1464 } 1520 }
1465 } 1521 }
1466 else{ 1522 else{
1467 pointer new_start = allocation_ret.first; 1523 pointer new_start = allocation_ret;
1468 if(!allocation_ret.second){ 1524 if(!hint){
1469 //Copy data to new buffer 1525 //Copy data to new buffer
1470 size_type new_length = 0; 1526 size_type new_length = 0;
1471 //This can't throw, since characters are POD 1527 //This can't throw, since characters are POD
1472 new_length += priv_uninitialized_copy 1528 new_length += priv_uninitialized_copy
1473 (const_iterator(old_start), p, new_start); 1529 (const_iterator(old_start), p, new_start);
1525 if (pos > this->size()) 1581 if (pos > this->size())
1526 throw_out_of_range("basic_string::erase out of range position"); 1582 throw_out_of_range("basic_string::erase out of range position");
1527 const pointer addr = this->priv_addr(); 1583 const pointer addr = this->priv_addr();
1528 erase(addr + pos, addr + pos + container_detail::min_value(n, this->size() - pos)); 1584 erase(addr + pos, addr + pos + container_detail::min_value(n, this->size() - pos));
1529 return *this; 1585 return *this;
1530 } 1586 }
1531 1587
1532 //! <b>Effects</b>: Removes the character referred to by p. 1588 //! <b>Effects</b>: Removes the character referred to by p.
1533 //! 1589 //!
1534 //! <b>Throws</b>: Nothing 1590 //! <b>Throws</b>: Nothing
1535 //! 1591 //!
1536 //! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being 1592 //! <b>Returns</b>: An iterator which points to the element immediately following p prior to the element being
1537 //! erased. If no such element exists, end() is returned. 1593 //! erased. If no such element exists, end() is returned.
1538 iterator erase(const_iterator p) BOOST_CONTAINER_NOEXCEPT 1594 iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
1539 { 1595 {
1540 // The move includes the terminating null. 1596 // The move includes the terminating null.
1541 CharT * const ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p)); 1597 CharT * const ptr = const_cast<CharT*>(container_detail::to_raw_pointer(p));
1542 const size_type old_size = this->priv_size(); 1598 const size_type old_size = this->priv_size();
1543 Traits::move(ptr, 1599 Traits::move(ptr,
1553 //! 1609 //!
1554 //! <b>Throws</b>: Nothing 1610 //! <b>Throws</b>: Nothing
1555 //! 1611 //!
1556 //! <b>Returns</b>: An iterator which points to the element pointed to by last prior to 1612 //! <b>Returns</b>: An iterator which points to the element pointed to by last prior to
1557 //! the other elements being erased. If no such element exists, end() is returned. 1613 //! the other elements being erased. If no such element exists, end() is returned.
1558 iterator erase(const_iterator first, const_iterator last) BOOST_CONTAINER_NOEXCEPT 1614 iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
1559 { 1615 {
1560 CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first)); 1616 CharT * f = const_cast<CharT*>(container_detail::to_raw_pointer(first));
1561 if (first != last) { // The move includes the terminating null. 1617 if (first != last) { // The move includes the terminating null.
1562 const size_type num_erased = last - first; 1618 const size_type num_erased = last - first;
1563 const size_type old_size = this->priv_size(); 1619 const size_type old_size = this->priv_size();
1573 //! <b>Requires</b>: !empty() 1629 //! <b>Requires</b>: !empty()
1574 //! 1630 //!
1575 //! <b>Throws</b>: Nothing 1631 //! <b>Throws</b>: Nothing
1576 //! 1632 //!
1577 //! <b>Effects</b>: Equivalent to erase(size() - 1, 1). 1633 //! <b>Effects</b>: Equivalent to erase(size() - 1, 1).
1578 void pop_back() BOOST_CONTAINER_NOEXCEPT 1634 void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
1579 { 1635 {
1580 const size_type old_size = this->priv_size(); 1636 const size_type old_size = this->priv_size();
1581 Traits::assign(this->priv_addr()[old_size-1], CharT(0)); 1637 Traits::assign(this->priv_addr()[old_size-1], CharT(0));
1582 this->priv_size(old_size-1);; 1638 this->priv_size(old_size-1);;
1583 } 1639 }
1585 //! <b>Effects</b>: Erases all the elements of the vector. 1641 //! <b>Effects</b>: Erases all the elements of the vector.
1586 //! 1642 //!
1587 //! <b>Throws</b>: Nothing. 1643 //! <b>Throws</b>: Nothing.
1588 //! 1644 //!
1589 //! <b>Complexity</b>: Linear to the number of elements in the vector. 1645 //! <b>Complexity</b>: Linear to the number of elements in the vector.
1590 void clear() BOOST_CONTAINER_NOEXCEPT 1646 void clear() BOOST_NOEXCEPT_OR_NOTHROW
1591 { 1647 {
1592 if (!this->empty()) { 1648 if (!this->empty()) {
1593 Traits::assign(*this->priv_addr(), CharT(0)); 1649 Traits::assign(*this->priv_addr(), CharT(0));
1594 this->priv_size(0); 1650 this->priv_size(0);
1595 } 1651 }
1798 < !container_detail::is_convertible<ForwardIter, size_type>::value 1854 < !container_detail::is_convertible<ForwardIter, size_type>::value
1799 && !container_detail::is_input_iterator<ForwardIter>::value 1855 && !container_detail::is_input_iterator<ForwardIter>::value
1800 >::type * = 0 1856 >::type * = 0
1801 ) 1857 )
1802 { 1858 {
1803 difference_type n = std::distance(j1, j2); 1859 difference_type n = boost::container::iterator_distance(j1, j2);
1804 const difference_type len = i2 - i1; 1860 const difference_type len = i2 - i1;
1805 if (len >= n) { 1861 if (len >= n) {
1806 this->priv_copy(j1, j2, const_cast<CharT*>(container_detail::to_raw_pointer(i1))); 1862 this->priv_copy(j1, j2, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
1807 this->erase(i1 + n, i2); 1863 this->erase(i1 + n, i2);
1808 } 1864 }
1809 else { 1865 else {
1810 ForwardIter m = j1; 1866 ForwardIter m = j1;
1811 std::advance(m, len); 1867 boost::container::iterator_advance(m, len);
1812 this->priv_copy(j1, m, const_cast<CharT*>(container_detail::to_raw_pointer(i1))); 1868 this->priv_copy(j1, m, const_cast<CharT*>(container_detail::to_raw_pointer(i1)));
1813 this->insert(i2, m, j2); 1869 this->insert(i2, m, j2);
1814 } 1870 }
1815 return *this; 1871 return *this;
1816 } 1872 }
1839 //! <b>Effects</b>: *this contains the same sequence of characters that was in s, 1895 //! <b>Effects</b>: *this contains the same sequence of characters that was in s,
1840 //! s contains the same sequence of characters that was in *this. 1896 //! s contains the same sequence of characters that was in *this.
1841 //! 1897 //!
1842 //! <b>Throws</b>: Nothing 1898 //! <b>Throws</b>: Nothing
1843 void swap(basic_string& x) 1899 void swap(basic_string& x)
1900 BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
1901 || allocator_traits_type::is_always_equal::value)
1844 { 1902 {
1845 this->base_t::swap_data(x); 1903 this->base_t::swap_data(x);
1846 container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag; 1904 container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
1847 container_detail::swap_alloc(this->alloc(), x.alloc(), flag); 1905 container_detail::swap_alloc(this->alloc(), x.alloc(), flag);
1848 } 1906 }
1853 // 1911 //
1854 ////////////////////////////////////////////// 1912 //////////////////////////////////////////////
1855 1913
1856 //! <b>Requires</b>: The program shall not alter any of the values stored in the character array. 1914 //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
1857 //! 1915 //!
1858 //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()]. 1916 //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
1859 //! 1917 //!
1860 //! <b>Complexity</b>: constant time. 1918 //! <b>Complexity</b>: constant time.
1861 const CharT* c_str() const BOOST_CONTAINER_NOEXCEPT 1919 const CharT* c_str() const BOOST_NOEXCEPT_OR_NOTHROW
1862 { return container_detail::to_raw_pointer(this->priv_addr()); } 1920 { return container_detail::to_raw_pointer(this->priv_addr()); }
1863 1921
1864 //! <b>Requires</b>: The program shall not alter any of the values stored in the character array. 1922 //! <b>Requires</b>: The program shall not alter any of the values stored in the character array.
1865 //! 1923 //!
1866 //! <b>Returns</b>: Allocator pointer p such that p + i == &operator[](i) for each i in [0,size()]. 1924 //! <b>Returns</b>: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
1867 //! 1925 //!
1868 //! <b>Complexity</b>: constant time. 1926 //! <b>Complexity</b>: constant time.
1869 const CharT* data() const BOOST_CONTAINER_NOEXCEPT 1927 const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW
1870 { return container_detail::to_raw_pointer(this->priv_addr()); } 1928 { return container_detail::to_raw_pointer(this->priv_addr()); }
1871 1929
1872 ////////////////////////////////////////////// 1930 //////////////////////////////////////////////
1873 // 1931 //
1874 // string operations 1932 // string operations
2294 //! 2352 //!
2295 //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)). 2353 //! <b>Returns</b>: basic_string(*this, pos, n1).compare(basic_string(s, n2)).
2296 int compare(size_type pos1, size_type n1, const CharT* s) const 2354 int compare(size_type pos1, size_type n1, const CharT* s) const
2297 { return this->compare(pos1, n1, s, Traits::length(s)); } 2355 { return this->compare(pos1, n1, s, Traits::length(s)); }
2298 2356
2299 /// @cond 2357 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2300 private: 2358 private:
2359 void priv_reserve(size_type res_arg, const bool null_terminate = true)
2360 {
2361 if (res_arg > this->max_size()){
2362 throw_length_error("basic_string::reserve max_size() exceeded");
2363 }
2364
2365 if (this->capacity() < res_arg){
2366 size_type n = container_detail::max_value(res_arg, this->size()) + 1;
2367 size_type new_cap = this->next_capacity(n);
2368 pointer reuse = 0;
2369 pointer new_start = this->allocation_command(allocate_new, n, new_cap, reuse);
2370 size_type new_length = 0;
2371
2372 const pointer addr = this->priv_addr();
2373 new_length += priv_uninitialized_copy
2374 (addr, addr + this->priv_size(), new_start);
2375 if(null_terminate){
2376 this->priv_construct_null(new_start + new_length);
2377 }
2378 this->deallocate_block();
2379 this->is_short(false);
2380 this->priv_long_addr(new_start);
2381 this->priv_long_size(new_length);
2382 this->priv_storage(new_cap);
2383 }
2384 }
2385
2301 static int s_compare(const_pointer f1, const_pointer l1, 2386 static int s_compare(const_pointer f1, const_pointer l1,
2302 const_pointer f2, const_pointer l2) 2387 const_pointer f2, const_pointer l2)
2303 { 2388 {
2304 const difference_type n1 = l1 - f1; 2389 const difference_type n1 = l1 - f1;
2305 const difference_type n2 = l2 - f2; 2390 const difference_type n2 = l2 - f2;
2310 } 2395 }
2311 2396
2312 template<class AllocVersion> 2397 template<class AllocVersion>
2313 void priv_shrink_to_fit_dynamic_buffer 2398 void priv_shrink_to_fit_dynamic_buffer
2314 ( AllocVersion 2399 ( AllocVersion
2315 , typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v1> >::type* = 0) 2400 , typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_1> >::type* = 0)
2316 { 2401 {
2317 //Allocate a new buffer. 2402 //Allocate a new buffer.
2318 size_type real_cap = 0; 2403 size_type real_cap = 0;
2319 const pointer long_addr = this->priv_long_addr(); 2404 const pointer long_addr = this->priv_long_addr();
2320 const size_type long_size = this->priv_long_size(); 2405 const size_type long_size = this->priv_long_size();
2321 const size_type long_storage = this->priv_long_storage(); 2406 const size_type long_storage = this->priv_long_storage();
2322 //We can make this nothrow as chars are always NoThrowCopyables 2407 //We can make this nothrow as chars are always NoThrowCopyables
2323 BOOST_TRY{ 2408 BOOST_TRY{
2324 const std::pair<pointer, bool> ret = this->allocation_command 2409 pointer reuse = 0;
2325 (allocate_new, long_size+1, long_size+1, real_cap, long_addr); 2410 real_cap = long_size+1;
2411 const pointer ret = this->allocation_command(allocate_new, long_size+1, real_cap, reuse);
2326 //Copy and update 2412 //Copy and update
2327 Traits::copy( container_detail::to_raw_pointer(ret.first) 2413 Traits::copy( container_detail::to_raw_pointer(ret)
2328 , container_detail::to_raw_pointer(this->priv_long_addr()) 2414 , container_detail::to_raw_pointer(this->priv_long_addr())
2329 , long_size+1); 2415 , long_size+1);
2330 this->priv_long_addr(ret.first); 2416 this->priv_long_addr(ret);
2331 this->priv_storage(real_cap); 2417 this->priv_storage(real_cap);
2332 //And release old buffer 2418 //And release old buffer
2333 this->alloc().deallocate(long_addr, long_storage); 2419 this->alloc().deallocate(long_addr, long_storage);
2334 } 2420 }
2335 BOOST_CATCH(...){ 2421 BOOST_CATCH(...){
2339 } 2425 }
2340 2426
2341 template<class AllocVersion> 2427 template<class AllocVersion>
2342 void priv_shrink_to_fit_dynamic_buffer 2428 void priv_shrink_to_fit_dynamic_buffer
2343 ( AllocVersion 2429 ( AllocVersion
2344 , typename container_detail::enable_if<container_detail::is_same<AllocVersion, allocator_v2> >::type* = 0) 2430 , typename container_detail::enable_if<container_detail::is_same<AllocVersion, version_2> >::type* = 0)
2345 { 2431 {
2346 size_type received_size; 2432 size_type received_size = this->priv_long_size()+1;
2433 pointer hint = this->priv_long_addr();
2347 if(this->alloc().allocation_command 2434 if(this->alloc().allocation_command
2348 ( shrink_in_place | nothrow_allocation 2435 ( shrink_in_place | nothrow_allocation, this->priv_long_storage(), received_size, hint)){
2349 , this->priv_long_storage(), this->priv_long_size()+1
2350 , received_size, this->priv_long_addr()).first){
2351 this->priv_storage(received_size); 2436 this->priv_storage(received_size);
2352 } 2437 }
2353 } 2438 }
2354 2439
2355 void priv_construct_null(pointer p) 2440 void priv_construct_null(pointer p)
2425 template <class InputIter> 2510 template <class InputIter>
2426 basic_string& priv_replace_dispatch(const_iterator first, const_iterator last, 2511 basic_string& priv_replace_dispatch(const_iterator first, const_iterator last,
2427 InputIter f, InputIter l, 2512 InputIter f, InputIter l,
2428 container_detail::false_) 2513 container_detail::false_)
2429 { 2514 {
2430 typedef typename std::iterator_traits<InputIter>::iterator_category Category; 2515 typedef typename boost::container::iterator_traits<InputIter>::iterator_category Category;
2431 return this->priv_replace(first, last, f, l, Category()); 2516 return this->priv_replace(first, last, f, l, Category());
2432 } 2517 }
2433 2518
2434 /// @endcond 2519 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2435 }; 2520 };
2521
2522 #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
2436 2523
2437 //!Typedef for a basic_string of 2524 //!Typedef for a basic_string of
2438 //!narrow characters 2525 //!narrow characters
2439 typedef basic_string 2526 typedef basic_string
2440 <char 2527 <char
2441 ,std::char_traits<char> 2528 ,std::char_traits<char>
2442 ,std::allocator<char> > 2529 ,new_allocator<char> >
2443 string; 2530 string;
2444 2531
2445 //!Typedef for a basic_string of 2532 //!Typedef for a basic_string of
2446 //!narrow characters 2533 //!narrow characters
2447 typedef basic_string 2534 typedef basic_string
2448 <wchar_t 2535 <wchar_t
2449 ,std::char_traits<wchar_t> 2536 ,std::char_traits<wchar_t>
2450 ,std::allocator<wchar_t> > 2537 ,new_allocator<wchar_t> >
2451 wstring; 2538 wstring;
2539
2540 #endif
2452 2541
2453 // ------------------------------------------------------------ 2542 // ------------------------------------------------------------
2454 // Non-member functions. 2543 // Non-member functions.
2455 2544
2456 // Operator+ 2545 // Operator+
2457 2546
2458 template <class CharT, class Traits, class Allocator> inline 2547 template <class CharT, class Traits, class Allocator> inline
2459 basic_string<CharT,Traits,Allocator> 2548 basic_string<CharT,Traits,Allocator>
2460 operator+(const basic_string<CharT,Traits,Allocator>& x 2549 operator+(const basic_string<CharT,Traits,Allocator>& x
2461 ,const basic_string<CharT,Traits,Allocator>& y) 2550 ,const basic_string<CharT,Traits,Allocator>& y)
2462 { 2551 {
2463 typedef basic_string<CharT,Traits,Allocator> str_t; 2552 typedef basic_string<CharT,Traits,Allocator> str_t;
2469 return result; 2558 return result;
2470 } 2559 }
2471 2560
2472 template <class CharT, class Traits, class Allocator> inline 2561 template <class CharT, class Traits, class Allocator> inline
2473 basic_string<CharT, Traits, Allocator> operator+ 2562 basic_string<CharT, Traits, Allocator> operator+
2474 ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END mx 2563 ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
2475 , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END my) 2564 , BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
2476 { 2565 {
2477 mx += my; 2566 x += y;
2478 return boost::move(mx); 2567 return boost::move(x);
2479 } 2568 }
2480 2569
2481 template <class CharT, class Traits, class Allocator> inline 2570 template <class CharT, class Traits, class Allocator> inline
2482 basic_string<CharT, Traits, Allocator> operator+ 2571 basic_string<CharT, Traits, Allocator> operator+
2483 ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END mx 2572 ( BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END x
2484 , const basic_string<CharT,Traits,Allocator>& y) 2573 , const basic_string<CharT,Traits,Allocator>& y)
2485 { 2574 {
2486 mx += y; 2575 x += y;
2487 return boost::move(mx); 2576 return boost::move(x);
2488 } 2577 }
2489 2578
2490 template <class CharT, class Traits, class Allocator> inline 2579 template <class CharT, class Traits, class Allocator> inline
2491 basic_string<CharT, Traits, Allocator> operator+ 2580 basic_string<CharT, Traits, Allocator> operator+
2492 (const basic_string<CharT,Traits,Allocator>& x 2581 (const basic_string<CharT,Traits,Allocator>& x
2493 ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END my) 2582 ,BOOST_RV_REF_BEG basic_string<CharT, Traits, Allocator> BOOST_RV_REF_END y)
2494 { 2583 {
2495 my.insert(my.begin(), x.begin(), x.end()); 2584 y.insert(y.begin(), x.begin(), x.end());
2496 return boost::move(my); 2585 return boost::move(y);
2497 } 2586 }
2498 2587
2499 template <class CharT, class Traits, class Allocator> inline 2588 template <class CharT, class Traits, class Allocator> inline
2500 basic_string<CharT, Traits, Allocator> operator+ 2589 basic_string<CharT, Traits, Allocator> operator+
2501 (const CharT* s, basic_string<CharT, Traits, Allocator> y) 2590 (const CharT* s, basic_string<CharT, Traits, Allocator> y)
2502 { 2591 {
2503 y.insert(y.begin(), s, s + Traits::length(s)); 2592 y.insert(y.begin(), s, s + Traits::length(s));
2504 return y; 2593 return y;
2505 } 2594 }
2506 2595
2507 template <class CharT, class Traits, class Allocator> inline 2596 template <class CharT, class Traits, class Allocator> inline
2508 basic_string<CharT,Traits,Allocator> operator+ 2597 basic_string<CharT,Traits,Allocator> operator+
2509 (basic_string<CharT,Traits,Allocator> x, const CharT* s) 2598 (basic_string<CharT,Traits,Allocator> x, const CharT* s)
2510 { 2599 {
2511 x += s; 2600 x += s;
2512 return x; 2601 return x;
2518 { 2607 {
2519 y.insert(y.begin(), c); 2608 y.insert(y.begin(), c);
2520 return y; 2609 return y;
2521 } 2610 }
2522 2611
2523 template <class CharT, class Traits, class Allocator> inline 2612 template <class CharT, class Traits, class Allocator> inline
2524 basic_string<CharT,Traits,Allocator> operator+ 2613 basic_string<CharT,Traits,Allocator> operator+
2525 (basic_string<CharT,Traits,Allocator> x, const CharT c) 2614 (basic_string<CharT,Traits,Allocator> x, const CharT c)
2526 { 2615 {
2527 x += c; 2616 x += c;
2528 return x; 2617 return x;
2661 // Swap. 2750 // Swap.
2662 template <class CharT, class Traits, class Allocator> 2751 template <class CharT, class Traits, class Allocator>
2663 inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y) 2752 inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)
2664 { x.swap(y); } 2753 { x.swap(y); }
2665 2754
2666 /// @cond 2755 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2667 // I/O. 2756 // I/O.
2668 namespace container_detail { 2757 namespace container_detail {
2669 2758
2670 template <class CharT, class Traits> 2759 template <class CharT, class Traits>
2671 inline bool 2760 inline bool
2672 string_fill(std::basic_ostream<CharT, Traits>& os, 2761 string_fill(std::basic_ostream<CharT, Traits>& os,
2681 ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof()); 2770 ok = ok && !Traits::eq_int_type(buf->sputc(f), Traits::eof());
2682 return ok; 2771 return ok;
2683 } 2772 }
2684 2773
2685 } //namespace container_detail { 2774 } //namespace container_detail {
2686 /// @endcond 2775 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2687 2776
2688 template <class CharT, class Traits, class Allocator> 2777 template <class CharT, class Traits, class Allocator>
2689 std::basic_ostream<CharT, Traits>& 2778 std::basic_ostream<CharT, Traits>&
2690 operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,Allocator>& s) 2779 operator<<(std::basic_ostream<CharT, Traits>& os, const basic_string<CharT,Traits,Allocator>& s)
2691 { 2780 {
2700 const std::size_t w = os.width(0); 2789 const std::size_t w = os.width(0);
2701 std::basic_streambuf<CharT, Traits>* buf = os.rdbuf(); 2790 std::basic_streambuf<CharT, Traits>* buf = os.rdbuf();
2702 2791
2703 if (w != 0 && n < w) 2792 if (w != 0 && n < w)
2704 pad_len = w - n; 2793 pad_len = w - n;
2705 2794
2706 if (!left) 2795 if (!left)
2707 ok = container_detail::string_fill(os, buf, pad_len); 2796 ok = container_detail::string_fill(os, buf, pad_len);
2708 2797
2709 ok = ok && 2798 ok = ok &&
2710 buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n); 2799 buf->sputn(s.data(), std::streamsize(n)) == std::streamsize(n);
2711 2800
2712 if (left) 2801 if (left)
2754 } 2843 }
2755 else 2844 else
2756 s.push_back(c); 2845 s.push_back(c);
2757 } 2846 }
2758 } 2847 }
2759 2848
2760 // If we have read no characters, then set failbit. 2849 // If we have read no characters, then set failbit.
2761 if (s.size() == 0) 2850 if (s.size() == 0)
2762 is.setstate(std::ios_base::failbit); 2851 is.setstate(std::ios_base::failbit);
2763 } 2852 }
2764 else 2853 else
2765 is.setstate(std::ios_base::failbit); 2854 is.setstate(std::ios_base::failbit);
2766 2855
2767 return is; 2856 return is;
2768 } 2857 }
2769 2858
2770 template <class CharT, class Traits, class Allocator> 2859 template <class CharT, class Traits, class Allocator>
2771 std::basic_istream<CharT, Traits>& 2860 std::basic_istream<CharT, Traits>&
2772 getline(std::istream& is, basic_string<CharT,Traits,Allocator>& s,CharT delim) 2861 getline(std::istream& is, basic_string<CharT,Traits,Allocator>& s,CharT delim)
2773 { 2862 {
2774 typename basic_string<CharT,Traits,Allocator>::size_type nread = 0; 2863 typename basic_string<CharT,Traits,Allocator>::size_type nread = 0;
2775 typename std::basic_istream<CharT, Traits>::sentry sentry(is, true); 2864 typename std::basic_istream<CharT, Traits>::sentry sentry(is, true);
2797 is.setstate(std::ios_base::failbit); 2886 is.setstate(std::ios_base::failbit);
2798 2887
2799 return is; 2888 return is;
2800 } 2889 }
2801 2890
2802 template <class CharT, class Traits, class Allocator> 2891 template <class CharT, class Traits, class Allocator>
2803 inline std::basic_istream<CharT, Traits>& 2892 inline std::basic_istream<CharT, Traits>&
2804 getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s) 2893 getline(std::basic_istream<CharT, Traits>& is, basic_string<CharT,Traits,Allocator>& s)
2805 { 2894 {
2806 return getline(is, s, '\n'); 2895 return getline(is, s, '\n');
2807 } 2896 }
2812 return hash_range(v.begin(), v.end()); 2901 return hash_range(v.begin(), v.end());
2813 } 2902 }
2814 2903
2815 }} 2904 }}
2816 2905
2817 /// @cond 2906 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2818 2907
2819 namespace boost { 2908 namespace boost {
2820 2909
2821 //!has_trivial_destructor_after_move<> == true_type 2910 //!has_trivial_destructor_after_move<> == true_type
2822 //!specialization for optimizations 2911 //!specialization for optimizations
2823 template <class C, class T, class Allocator> 2912 template <class C, class T, class Allocator>
2824 struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> > 2913 struct has_trivial_destructor_after_move<boost::container::basic_string<C, T, Allocator> >
2825 : public ::boost::has_trivial_destructor_after_move<Allocator> 2914 {
2826 {}; 2915 typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
2916 static const bool value = ::boost::has_trivial_destructor_after_move<Allocator>::value &&
2917 ::boost::has_trivial_destructor_after_move<pointer>::value;
2918 };
2827 2919
2828 } 2920 }
2829 2921
2830 /// @endcond 2922 #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2831 2923
2832 #include <boost/container/detail/config_end.hpp> 2924 #include <boost/container/detail/config_end.hpp>
2833 2925
2834 #endif // BOOST_CONTAINER_STRING_HPP 2926 #endif // BOOST_CONTAINER_STRING_HPP