Mercurial > hg > vamp-build-and-test
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 |