DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/interprocess for documentation. // ////////////////////////////////////////////////////////////////////////////// // // This file comes from SGI's stl_vector.h file. Modified by Ion Gaztanaga. // Renaming, isolating and porting to generic algorithms. Pointer typedef // set to allocator::pointer to allow placing it in shared memory. // /////////////////////////////////////////////////////////////////////////////// // Copyright (c) 1994 // Hewlett-Packard Company // // Permission to use, copy, modify, distribute and sell this software // and its documentation for any purpose is hereby granted without fee, // provided that the above copyright notice appear in all copies and // that both that copyright notice and this permission notice appear // in supporting documentation. Hewlett-Packard Company makes no // representations about the suitability of this software for any // purpose. It is provided "as is" without express or implied warranty. // // // Copyright (c) 1996 // Silicon Graphics Computer Systems, Inc. // // Permission to use, copy, modify, distribute and sell this software // and its documentation for any purpose is hereby granted without fee, // provided that the above copyright notice appear in all copies and // that both that copyright notice and this permission notice appear // in supporting documentation. Silicon Graphics makes no // representations about the suitability of this software for any // purpose. It is provided "as is" without express or implied warranty. #ifndef BOOST_INTERPROCESS_VECTOR_HPP #define BOOST_INTERPROCESS_VECTOR_HPP #if (defined _MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace boost { namespace interprocess { /// @cond namespace detail { //! Const vector_iterator used to iterate through a vector. template
class vector_const_iterator : public std::iterator
::value_type ,typename std::iterator_traits
::difference_type ,typename pointer_to_other
::value_type >::type ,const typename std::iterator_traits
::value_type &> { public: typedef const typename std::iterator_traits
::value_type value_type; typedef typename std::iterator_traits
::difference_type difference_type; typedef typename pointer_to_other
::type pointer; typedef value_type& reference; /// @cond protected: Pointer m_ptr; public: Pointer get_ptr() const { return m_ptr; } explicit vector_const_iterator(Pointer ptr) : m_ptr(ptr){} /// @endcond public: //Constructors vector_const_iterator() : m_ptr(0){} //Pointer like operators reference operator*() const { return *m_ptr; } const value_type * operator->() const { return detail::get_pointer(m_ptr); } reference operator[](difference_type off) const { return m_ptr[off]; } //Increment / Decrement vector_const_iterator& operator++() { ++m_ptr; return *this; } vector_const_iterator operator++(int) { Pointer tmp = m_ptr; ++*this; return vector_const_iterator(tmp); } vector_const_iterator& operator--() { --m_ptr; return *this; } vector_const_iterator operator--(int) { Pointer tmp = m_ptr; --*this; return vector_const_iterator(tmp); } //Arithmetic vector_const_iterator& operator+=(difference_type off) { m_ptr += off; return *this; } vector_const_iterator operator+(difference_type off) const { return vector_const_iterator(m_ptr+off); } friend vector_const_iterator operator+(difference_type off, const vector_const_iterator& right) { return vector_const_iterator(off + right.m_ptr); } vector_const_iterator& operator-=(difference_type off) { m_ptr -= off; return *this; } vector_const_iterator operator-(difference_type off) const { return vector_const_iterator(m_ptr-off); } difference_type operator-(const vector_const_iterator& right) const { return m_ptr - right.m_ptr; } //Comparison operators bool operator== (const vector_const_iterator& r) const { return m_ptr == r.m_ptr; } bool operator!= (const vector_const_iterator& r) const { return m_ptr != r.m_ptr; } bool operator< (const vector_const_iterator& r) const { return m_ptr < r.m_ptr; } bool operator<= (const vector_const_iterator& r) const { return m_ptr <= r.m_ptr; } bool operator> (const vector_const_iterator& r) const { return m_ptr > r.m_ptr; } bool operator>= (const vector_const_iterator& r) const { return m_ptr >= r.m_ptr; } }; //! Iterator used to iterate through a vector template
class vector_iterator : public vector_const_iterator
{ public: explicit vector_iterator(Pointer ptr) : vector_const_iterator
(ptr) {} public: typedef typename std::iterator_traits
::value_type value_type; typedef typename vector_const_iterator
::difference_type difference_type; typedef Pointer pointer; typedef value_type& reference; //Constructors vector_iterator() {} //Pointer like operators reference operator*() const { return *this->m_ptr; } value_type* operator->() const { return detail::get_pointer(this->m_ptr); } reference operator[](difference_type off) const { return this->m_ptr[off]; } //Increment / Decrement vector_iterator& operator++() { ++this->m_ptr; return *this; } vector_iterator operator++(int) { pointer tmp = this->m_ptr; ++*this; return vector_iterator(tmp); } vector_iterator& operator--() { --this->m_ptr; return *this; } vector_iterator operator--(int) { vector_iterator tmp = *this; --*this; return vector_iterator(tmp); } // Arithmetic vector_iterator& operator+=(difference_type off) { this->m_ptr += off; return *this; } vector_iterator operator+(difference_type off) const { return vector_iterator(this->m_ptr+off); } friend vector_iterator operator+(difference_type off, const vector_iterator& right) { return vector_iterator(off + right.m_ptr); } vector_iterator& operator-=(difference_type off) { this->m_ptr -= off; return *this; } vector_iterator operator-(difference_type off) const { return vector_iterator(this->m_ptr-off); } difference_type operator-(const vector_const_iterator
& right) const { return static_cast
&>(*this) - right; } }; //!This struct deallocates and allocated memory template
struct vector_alloc_holder { typedef typename A::pointer pointer; typedef typename A::size_type size_type; typedef typename A::value_type value_type; static const bool trivial_dctr = boost::has_trivial_destructor
::value; static const bool trivial_dctr_after_move = has_trivial_destructor_after_move
::value || trivial_dctr; static const bool trivial_copy = has_trivial_copy
::value; static const bool nothrow_copy = has_nothrow_copy
::value; static const bool trivial_assign = has_trivial_assign
::value; static const bool nothrow_assign = has_nothrow_assign
::value; //Constructor, does not throw vector_alloc_holder(const A &a) : members_(a) {} //Constructor, does not throw vector_alloc_holder(const vector_alloc_holder
&h) : members_(h.alloc()) {} //Destructor ~vector_alloc_holder() { this->prot_deallocate(); } typedef detail::integral_constant
allocator_v1; typedef detail::integral_constant
allocator_v2; typedef detail::integral_constant
::value> alloc_version; std::pair
allocation_command(allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse = 0) { return allocation_command(command, limit_size, preferred_size, received_size, reuse, alloc_version()); } std::pair
allocation_command(allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse, allocator_v1) { (void)limit_size; (void)reuse; if(!(command & allocate_new)) return std::pair
(0, 0); received_size = preferred_size; return std::make_pair(this->alloc().allocate(received_size), false); } std::pair
allocation_command(allocation_type command, size_type limit_size, size_type preferred_size, size_type &received_size, const pointer &reuse, allocator_v2) { return this->alloc().allocation_command(command, limit_size, preferred_size, received_size, reuse); } size_type next_capacity(size_type additional_objects) const { return get_next_capacity(this->alloc().max_size(), this->members_.m_capacity, additional_objects); } struct members_holder : public A { private: members_holder(const members_holder&); public: members_holder(const A &alloc) : A(alloc), m_start(0), m_size(0), m_capacity(0) {} pointer m_start; size_type m_size; size_type m_capacity; } members_; protected: void prot_deallocate() { if(!this->members_.m_capacity) return; this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); this->members_.m_start = 0; this->members_.m_size = 0; this->members_.m_capacity = 0; } void destroy(value_type* p) { if(!trivial_dctr) detail::get_pointer(p)->~value_type(); } void destroy_n(value_type* p, size_type n) { if(!trivial_dctr) for(; n--; ++p) p->~value_type(); } A &alloc() { return members_; } const A &alloc() const { return members_; } }; } //namespace detail { /// @endcond //! A vector is a sequence that supports random access to elements, constant //! time insertion and removal of elements at the end, and linear time insertion //! and removal of elements at the beginning or in the middle. The number of //! elements in a vector may vary dynamically; memory management is automatic. //! boost::interprocess::vector is similar to std::vector but it's compatible //! with shared memory and memory mapped files. template
class vector : private detail::vector_alloc_holder
{ /// @cond typedef vector
self_t; typedef detail::vector_alloc_holder
base_t; /// @endcond public: //! The type of object, T, stored in the vector typedef T value_type; //! Pointer to T typedef typename A::pointer pointer; //! Const pointer to T typedef typename A::const_pointer const_pointer; //! Reference to T typedef typename A::reference reference; //! Const reference to T typedef typename A::const_reference const_reference; //! An unsigned integral type typedef typename A::size_type size_type; //! A signed integral type typedef typename A::difference_type difference_type; //! The allocator type typedef A allocator_type; //! The random access iterator typedef detail::vector_iterator
iterator; //! The random access const_iterator typedef detail::vector_const_iterator
const_iterator; //! Iterator used to iterate backwards through a vector. typedef std::reverse_iterator
reverse_iterator; //! Const iterator used to iterate backwards through a vector. typedef std::reverse_iterator
const_reverse_iterator; //! The stored allocator type typedef allocator_type stored_allocator_type; /// @cond private: typedef typename base_t::allocator_v1 allocator_v1; typedef typename base_t::allocator_v2 allocator_v2; typedef typename base_t::alloc_version alloc_version; typedef constant_iterator
cvalue_iterator; typedef repeat_iterator
repeat_it; typedef detail::move_iterator
repeat_move_it; //This is the anti-exception array destructor //to deallocate values already constructed typedef typename detail::if_c
,detail::scoped_destructor_n
>::type OldArrayDestructor; //This is the anti-exception array destructor //to destroy objects created with copy construction typedef typename detail::if_c
,detail::scoped_destructor_n
>::type UCopiedArrayDestructor; //This is the anti-exception array deallocator typedef typename detail::if_c
,detail::scoped_array_deallocator
>::type UCopiedArrayDeallocator; //This is the optimized move iterator for copy constructors //so that std::copy and similar can use memcpy typedef typename detail::if_c
>::type copy_move_it; //This is the optimized move iterator for assignments //so that std::uninitialized_copy and similar can use memcpy typedef typename detail::if_c
>::type assign_move_it; /// @endcond public: //!
Effects
: Constructs a vector taking the allocator as parameter. //! //!
Throws
: If allocator_type's copy constructor throws. //! //!
Complexity
: Constant. explicit vector(const A& a = A()) : base_t(a) {} //!
Effects
: Constructs a vector that will use a copy of allocator a //! and inserts n copies of value. //! //!
Throws
: If allocator_type's default constructor or copy constructor //! throws or T's default or copy constructor throws. //! //!
Complexity
: Linear to n. vector(size_type n, const T& value = T(), const allocator_type& a = allocator_type()) : base_t(a) { this->insert(this->end(), n, value); } //!
Effects
: Copy constructs a vector. //! //!
Postcondition
: x == *this. //! //!
Complexity
: Linear to the elements x contains. vector(const vector
& x) : base_t((base_t&)x) { *this = x; } //!
Effects
: Move constructor. Moves mx's resources to *this. //! //!
Throws
: If allocator_type's copy constructor throws. //! //!
Complexity
: Constant. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE vector(const detail::moved_object
>& mx) : base_t(mx.get()) { this->swap(mx.get()); } #else vector(vector
&& mx) : base_t(mx) { this->swap(mx); } #endif //!
Effects
: Constructs a vector that will use a copy of allocator a //! and inserts a copy of the range [first, last) in the vector. //! //!
Throws
: If allocator_type's default constructor or copy constructor //! throws or T's constructor taking an dereferenced InIt throws. //! //!
Complexity
: Linear to the range [first, last). template
vector(InIt first, InIt last, const allocator_type& a = allocator_type()) : base_t(a) { this->assign(first, last); } //!
Effects
: Destroys the vector. All stored values are destroyed //! and used memory is deallocated. //! //!
Throws
: Nothing. //! //!
Complexity
: Linear to the number of elements. ~vector() { this->priv_destroy_all(); } //!
Effects
: Returns an iterator to the first element contained in the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. iterator begin() { return iterator(this->members_.m_start); } //!
Effects
: Returns a const_iterator to the first element contained in the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. const_iterator begin() const { return const_iterator(this->members_.m_start); } //!
Effects
: Returns an iterator to the end of the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. iterator end() { return iterator(this->members_.m_start + this->members_.m_size); } //!
Effects
: Returns a const_iterator to the end of the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. const_iterator end() const { return const_iterator(this->members_.m_start + this->members_.m_size); } //!
Effects
: Returns a reverse_iterator pointing to the beginning //! of the reversed vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. reverse_iterator rbegin() { return reverse_iterator(this->end()); } //!
Effects
: Returns a const_reverse_iterator pointing to the beginning //! of the reversed vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. const_reverse_iterator rbegin()const { return const_reverse_iterator(this->end());} //!
Effects
: Returns a reverse_iterator pointing to the end //! of the reversed vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. reverse_iterator rend() { return reverse_iterator(this->begin()); } //!
Effects
: Returns a const_reverse_iterator pointing to the end //! of the reversed vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. const_reverse_iterator rend() const { return const_reverse_iterator(this->begin()); } //!
Requires
: !empty() //! //!
Effects
: Returns a reference to the first element //! from the beginning of the container. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. reference front() { return *this->members_.m_start; } //!
Requires
: !empty() //! //!
Effects
: Returns a const reference to the first element //! from the beginning of the container. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. const_reference front() const { return *this->members_.m_start; } //!
Requires
: !empty() //! //!
Effects
: Returns a reference to the first element //! from the beginning of the container. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. reference back() { return this->members_.m_start[this->members_.m_size - 1]; } //!
Requires
: !empty() //! //!
Effects
: Returns a const reference to the first element //! from the beginning of the container. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. const_reference back() const { return this->members_.m_start[this->members_.m_size - 1]; } //!
Effects
: Returns the number of the elements contained in the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. size_type size() const { return this->members_.m_size; } //!
Effects
: Returns the largest possible size of the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. size_type max_size() const { return this->alloc().max_size(); } //!
Effects
: Number of elements for which memory has been allocated. //! capacity() is always greater than or equal to size(). //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. size_type capacity() const { return this->members_.m_capacity; } //!
Effects
: Returns true if the vector contains no elements. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. bool empty() const { return !this->members_.m_size; } //!
Requires
: size() < n. //! //!
Effects
: Returns a reference to the nth element //! from the beginning of the container. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. reference operator[](size_type n) { return this->members_.m_start[n]; } //!
Requires
: size() < n. //! //!
Effects
: Returns a const reference to the nth element //! from the beginning of the container. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. const_reference operator[](size_type n) const { return this->members_.m_start[n]; } //!
Requires
: size() < n. //! //!
Effects
: Returns a reference to the nth element //! from the beginning of the container. //! //!
Throws
: std::range_error if n >= size() //! //!
Complexity
: Constant. reference at(size_type n) { this->priv_check_range(n); return this->members_.m_start[n]; } //!
Requires
: size() < n. //! //!
Effects
: Returns a const reference to the nth element //! from the beginning of the container. //! //!
Throws
: std::range_error if n >= size() //! //!
Complexity
: Constant. const_reference at(size_type n) const { this->priv_check_range(n); return this->members_.m_start[n]; } //!
Effects
: Returns a copy of the internal allocator. //! //!
Throws
: If allocator's copy constructor throws. //! //!
Complexity
: Constant. allocator_type get_allocator() const { return this->alloc(); } const stored_allocator_type &get_stored_allocator() const { return this->alloc(); } stored_allocator_type &get_stored_allocator() { return this->alloc(); } //!
Effects
: If n is less than or equal to capacity(), this call has no //! effect. Otherwise, it is a request for allocation of additional memory. //! If the request is successful, then capacity() is greater than or equal to //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. //! //!
Throws
: If memory allocation allocation throws or T's copy constructor throws. void reserve(size_type new_cap) { if (this->capacity() < new_cap){ //There is not enough memory, allocate a new //buffer or expand the old one. bool same_buffer_start; size_type real_cap = 0; std::pair
ret = this->allocation_command (allocate_new | expand_fwd | expand_bwd, new_cap, new_cap, real_cap, this->members_.m_start); //Check for forward expansion same_buffer_start = ret.second && this->members_.m_start == ret.first; if(same_buffer_start){ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_expand_fwd; #endif this->members_.m_capacity = real_cap; } //If there is no forward expansion, move objects else{ //We will reuse insert code, so create a dummy input iterator copy_move_it dummy_it(detail::get_pointer(this->members_.m_start)); //Backwards (and possibly forward) expansion if(ret.second){ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_expand_bwd; #endif this->priv_range_insert_expand_backwards ( detail::get_pointer(ret.first) , real_cap , detail::get_pointer(this->members_.m_start) , dummy_it , dummy_it , 0); } //New buffer else{ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_alloc; #endif this->priv_range_insert_new_allocation ( detail::get_pointer(ret.first) , real_cap , detail::get_pointer(this->members_.m_start) , dummy_it , dummy_it); } } } } //!
Effects
: Makes *this contain the same elements as x. //! //!
Postcondition
: this->size() == x.size(). *this contains a copy //! of each of x's elements. //! //!
Throws
: If memory allocation throws or T's copy constructor throws. //! //!
Complexity
: Linear to the number of elements in x. vector
& operator=(const vector
& x) { if (&x != this){ this->assign(x.members_.m_start, x.members_.m_start + x.members_.m_size); } return *this; } //!
Effects
: Move assignment. All mx's values are transferred to *this. //! //!
Postcondition
: x.empty(). *this contains a the elements x had //! before the function. //! //!
Throws
: If allocator_type's copy constructor throws. //! //!
Complexity
: Constant. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE vector
& operator=(const detail::moved_object
>& mx) { vector
&x = mx.get(); if (&x != this){ this->swap(x); x.clear(); } return *this; } #else vector
& operator=(vector
&& mx) { vector
&x = mx; if (&x != this){ this->swap(x); x.clear(); } return *this; } #endif //!
Effects
: Assigns the n copies of val to *this. //! //!
Throws
: If memory allocation throws or T's copy constructor throws. //! //!
Complexity
: Linear to n. void assign(size_type n, const value_type& val) { this->assign(cvalue_iterator(val, n), cvalue_iterator()); } //!
Effects
: Assigns the the range [first, last) to *this. //! //!
Throws
: If memory allocation throws or //! T's constructor from dereferencing InpIt throws. //! //!
Complexity
: Linear to n. template
void assign(InIt first, InIt last) { //Dispatch depending on integer/iterator const bool aux_boolean = detail::is_convertible
::value; typedef detail::bool_
Result; this->priv_assign_dispatch(first, last, Result()); } //!
Effects
: Inserts a copy of x at the end of the vector. //! //!
Throws
: If memory allocation throws or //! T's copy constructor throws. //! //!
Complexity
: Amortized constant time. void push_back(const T& x) { if (this->members_.m_size < this->members_.m_capacity){ //There is more memory, just construct a new object at the end new(detail::get_pointer(this->members_.m_start) + this->members_.m_size)value_type(x); ++this->members_.m_size; } else{ this->insert(this->end(), x); } } //!
Effects
: Constructs a new element in the end of the vector //! and moves the resources of mx to this new element. //! //!
Throws
: If memory allocation throws. //! //!
Complexity
: Amortized constant time. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE void push_back(const detail::moved_object
& mx) { if (this->members_.m_size < this->members_.m_capacity){ //There is more memory, just construct a new object at the end new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx); ++this->members_.m_size; } else{ this->insert(this->end(), mx); } } #else void push_back(T && mx) { if (this->members_.m_size < this->members_.m_capacity){ //There is more memory, just construct a new object at the end new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(move(mx)); ++this->members_.m_size; } else{ this->insert(this->end(), move(mx)); } } #endif //!
Effects
: Swaps the contents of *this and x. //! If this->allocator_type() != x.allocator_type() //! allocators are also swapped. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. void swap(vector
& x) { allocator_type &this_al = this->alloc(), &other_al = x.alloc(); //Just swap internals detail::do_swap(this->members_.m_start, x.members_.m_start); detail::do_swap(this->members_.m_size, x.members_.m_size); detail::do_swap(this->members_.m_capacity, x.members_.m_capacity); if (this_al != other_al){ detail::do_swap(this_al, other_al); } } //!
Effects
: Swaps the contents of *this and x. //! If this->allocator_type() != x.allocator_type() //! allocators are also swapped. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE void swap(const detail::moved_object
>& mx) { vector
&x = mx.get(); this->swap(x); } #else void swap(vector
&& mx) { vector
&x = mx; this->swap(x); } #endif //!
Requires
: position must be a valid iterator of *this. //! //!
Effects
: Insert a copy of x before position. //! //!
Throws
: If memory allocation throws or x's copy constructor throws. //! //!
Complexity
: If position is begin() or end(), amortized constant time //! Linear time otherwise. iterator insert(iterator position, const T& x) { //Just call more general insert(pos, size, value) and return iterator size_type n = position - begin(); this->insert(position, (size_type)1, x); return iterator(this->members_.m_start + n); } //!
Requires
: position must be a valid iterator of *this. //! //!
Effects
: Insert a new element before position with mx's resources. //! //!
Throws
: If memory allocation throws. //! //!
Complexity
: If position is begin() or end(), amortized constant time //! Linear time otherwise. #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE iterator insert(iterator position, const detail::moved_object
&mx) { //Just call more general insert(pos, size, value) and return iterator size_type n = position - begin(); this->insert(position ,repeat_move_it(repeat_it(mx.get(), 1)) ,repeat_move_it(repeat_it())); return iterator(this->members_.m_start + n); } #else iterator insert(iterator position, T &&mx) { //Just call more general insert(pos, size, value) and return iterator size_type n = position - begin(); this->insert(position ,repeat_move_it(repeat_it(mx, 1)) ,repeat_move_it(repeat_it())); return iterator(this->members_.m_start + n); } #endif //!
Requires
: pos must be a valid iterator of *this. //! //!
Effects
: Insert a copy of the [first, last) range before pos. //! //!
Throws
: If memory allocation throws, T's constructor from a //! dereferenced InpIt throws or T's copy constructor throws. //! //!
Complexity
: Linear to std::distance [first, last). template
void insert(iterator pos, InIt first, InIt last) { //Dispatch depending on integer/iterator const bool aux_boolean = detail::is_convertible
::value; typedef detail::bool_
Result; this->priv_insert_dispatch(pos, first, last, Result()); } //!
Requires
: pos must be a valid iterator of *this. //! //!
Effects
: Insert n copies of x before pos. //! //!
Throws
: If memory allocation throws or T's copy constructor throws. //! //!
Complexity
: Linear to n. void insert (iterator p, size_type n, const T& x) { this->insert(p, cvalue_iterator(x, n), cvalue_iterator()); } //!
Effects
: Removes the last element from the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Constant time. void pop_back() { //Destroy last element --this->members_.m_size; this->destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size); } //!
Effects
: Erases the element at position pos. //! //!
Throws
: Nothing. //! //!
Complexity
: Linear to the elements between pos and the //! last element. Constant if pos is the first or the last element. iterator erase(const_iterator position) { T *pos = detail::get_pointer(position.get_ptr()); T *beg = detail::get_pointer(this->members_.m_start); std::copy(assign_move_it(pos + 1), assign_move_it(beg + this->members_.m_size), pos); --this->members_.m_size; //Destroy last element base_t::destroy(detail::get_pointer(this->members_.m_start) + this->members_.m_size); return iterator(position.get_ptr()); } //!
Effects
: Erases the elements pointed by [first, last). //! //!
Throws
: Nothing. //! //!
Complexity
: Linear to the distance between first and last. iterator erase(const_iterator first, const_iterator last) { if (first != last){ // worth doing, copy down over hole T* end_pos = detail::get_pointer(this->members_.m_start) + this->members_.m_size; T* ptr = detail::get_pointer(std::copy (assign_move_it(detail::get_pointer(last.get_ptr())) ,assign_move_it(end_pos) ,detail::get_pointer(first.get_ptr()) )); size_type destroyed = (end_pos - ptr); this->destroy_n(ptr, destroyed); this->members_.m_size -= destroyed; } return iterator(first.get_ptr()); } //!
Effects
: Inserts or erases elements at the end such that //! the size becomes n. New elements are copy constructed from x. //! //!
Throws
: If memory allocation throws, or T's copy constructor throws. //! //!
Complexity
: Linear to the difference between size() and new_size. void resize(size_type new_size, const T& x) { pointer finish = this->members_.m_start + this->members_.m_size; if (new_size < size()){ //Destroy last elements this->erase(iterator(this->members_.m_start + new_size), this->end()); } else{ //Insert new elements at the end this->insert(iterator(finish), new_size - this->size(), x); } } //!
Effects
: Inserts or erases elements at the end such that //! the size becomes n. New elements are default constructed. //! //!
Throws
: If memory allocation throws, or T's copy constructor throws. //! //!
Complexity
: Linear to the difference between size() and new_size. void resize(size_type new_size) { if (new_size < this->size()){ //Destroy last elements this->erase(iterator(this->members_.m_start + new_size), this->end()); } else{ size_type n = new_size - this->size(); this->reserve(new_size); T *ptr = detail::get_pointer(this->members_.m_start + this->members_.m_size); while(n--){ //Default construct new(ptr++)T(); ++this->members_.m_size; } } } //!
Effects
: Erases all the elements of the vector. //! //!
Throws
: Nothing. //! //!
Complexity
: Linear to the number of elements in the vector. void clear() { this->priv_destroy_all(); } /// @cond //!
Effects
: Tries to deallocate the excess of memory created //! with previous allocations. The size of the vector is unchanged //! //!
Throws
: If memory allocation throws, or T's copy constructor throws. //! //!
Complexity
: Linear to size(). void shrink_to_fit() { priv_shrink_to_fit(alloc_version()); } private: void priv_shrink_to_fit(allocator_v1) { if(this->members_.m_capacity){ if(!size()){ this->prot_deallocate(); } else{ //This would not work with stateful allocators vector
(*this).swap(*this); } } } void priv_shrink_to_fit(allocator_v2) { if(this->members_.m_capacity){ if(!size()){ this->prot_deallocate(); } else{ size_type received_size; this->alloc().allocation_command(shrink_in_place, this->size(), this->capacity() ,received_size, this->members_.m_start); } } } void priv_destroy_all() { this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size); this->members_.m_size = 0; } template
void priv_range_insert(pointer pos, FwdIt first, FwdIt last, std::forward_iterator_tag) { if (first != last){ size_type n = std::distance(first, last); //Check if we have enough memory or try to expand current memory size_type remaining = this->members_.m_capacity - this->members_.m_size; bool same_buffer_start; std::pair
ret; size_type real_cap = this->members_.m_capacity; //Check if we already have room if (n <= remaining){ same_buffer_start = true; } else{ //There is not enough memory, allocate a new //buffer or expand the old one. size_type new_cap = this->next_capacity(n); ret = this->allocation_command (allocate_new | expand_fwd | expand_bwd, this->members_.m_size + n, new_cap, real_cap, this->members_.m_start); //Check for forward expansion same_buffer_start = ret.second && this->members_.m_start == ret.first; if(same_buffer_start){ this->members_.m_capacity = real_cap; } } //If we had room or we have expanded forward if (same_buffer_start){ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_expand_fwd; #endif this->priv_range_insert_expand_forward (detail::get_pointer(pos), first, last, n); } //Backwards (and possibly forward) expansion else if(ret.second){ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_expand_bwd; #endif this->priv_range_insert_expand_backwards ( detail::get_pointer(ret.first) , real_cap , detail::get_pointer(pos) , first , last , n); } //New buffer else{ #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS ++this->num_alloc; #endif this->priv_range_insert_new_allocation ( detail::get_pointer(ret.first) , real_cap , detail::get_pointer(pos) , first , last); } } } template
void priv_range_insert_expand_forward (T* pos, FwdIt first, FwdIt last, size_type n) { //There is enough memory T* old_finish = detail::get_pointer(this->members_.m_start) + this->members_.m_size; const size_type elems_after = old_finish - pos; if (elems_after > n){ //New elements can be just copied. //Move to uninitialized memory last objects std::uninitialized_copy(copy_move_it(old_finish - n), copy_move_it(old_finish), old_finish); this->members_.m_size += n; //Copy previous to last objects to the initialized end std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish - n), old_finish); //Insert new objects in the pos std::copy(first, last, detail::get_pointer(pos)); } else { //The new elements don't fit in the [pos, end()) range. Copy //to the beginning of the unallocated zone the last new elements. FwdIt mid = first; std::advance(mid, elems_after); std::uninitialized_copy(mid, last, old_finish); this->members_.m_size += n - elems_after; //Copy old [pos, end()) elements to the uninitialized memory std::uninitialized_copy ( copy_move_it(detail::get_pointer(pos)) , copy_move_it(old_finish) , detail::get_pointer(this->members_.m_start) + this->members_.m_size); this->members_.m_size += elems_after; //Copy first new elements in pos std::copy(first, mid, detail::get_pointer(pos)); } } template
void priv_range_insert_new_allocation (T* new_start, size_type new_cap, T* pos, FwdIt first, FwdIt last) { T* new_finish = new_start; T *old_finish; //Anti-exception rollbacks UCopiedArrayDeallocator scoped_alloc(new_start, this->alloc(), new_cap); UCopiedArrayDestructor construted_values_destroyer(new_start, 0u); //Initialize with [begin(), pos) old buffer //the start of the new buffer new_finish = std::uninitialized_copy ( copy_move_it(detail::get_pointer(this->members_.m_start)) , copy_move_it(detail::get_pointer(pos)) , old_finish = new_finish); construted_values_destroyer.increment_size(new_finish - old_finish); //Initialize new objects, starting from previous point new_finish = std::uninitialized_copy (first, last, old_finish = new_finish); construted_values_destroyer.increment_size(new_finish - old_finish); //Initialize from the rest of the old buffer, //starting from previous point new_finish = std::uninitialized_copy ( copy_move_it(detail::get_pointer(pos)) , copy_move_it(detail::get_pointer(this->members_.m_start) + this->members_.m_size) , detail::get_pointer(new_finish)); //All construction successful, disable rollbacks construted_values_destroyer.release(); scoped_alloc.release(); //Destroy and deallocate old elements //If there is allocated memory, destroy and deallocate if(this->members_.m_start != 0){ if(!base_t::trivial_dctr_after_move) this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size); this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); } this->members_.m_start = new_start; this->members_.m_size = new_finish - new_start; this->members_.m_capacity = new_cap; } template
void priv_range_insert_expand_backwards (T* new_start, size_type new_capacity, T* pos, FwdIt first, FwdIt last, size_type n) { //Backup old data T* old_start = detail::get_pointer(this->members_.m_start); T* old_finish = old_start + this->members_.m_size; size_type old_size = this->members_.m_size; //We can have 8 possibilities: const size_type elemsbefore = (size_type)(pos - old_start); const size_type s_before = (size_type)(old_start - new_start); //Update the vector buffer information to a safe state this->members_.m_start = new_start; this->members_.m_capacity = new_capacity; this->members_.m_size = 0; //If anything goes wrong, this object will destroy //all the old objects to fulfill previous vector state OldArrayDestructor old_values_destroyer(old_start, old_size); //Check if s_before is so big that even copying the old data + new data //there is a gap between the new data and the old data if(s_before >= (old_size + n)){ //Old situation: // _________________________________________________________ //| raw_mem | old_begin | old_end | //| __________________________________|___________|_________| // //New situation: // _________________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|__________|_________|________________________| // //Copy first old values before pos, after that the //new objects boost::interprocess::uninitialized_copy_copy (copy_move_it(old_start), copy_move_it(detail::get_pointer(pos)), first, last, detail::get_pointer(new_start)); UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore); //Now initialize the rest of memory with the last old values std::uninitialized_copy ( copy_move_it(detail::get_pointer(pos)) , copy_move_it(old_finish) , detail::get_pointer(new_start) + elemsbefore + n); //All new elements correctly constructed, avoid new element destruction new_values_destroyer.release(); this->members_.m_size = old_size + n; //Old values destroyed automatically with "old_values_destroyer" //when "old_values_destroyer" goes out of scope unless the have trivial //destructor after move. if(base_t::trivial_dctr_after_move) old_values_destroyer.release(); } //Check if s_before is so big that divides old_end else if(difference_type(s_before) >= difference_type(elemsbefore + n)){ //Old situation: // __________________________________________________ //| raw_mem | old_begin | old_end | //| ___________________________|___________|_________| // //New situation: // __________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|__________|_________|_________________| // //Copy first old values before pos, after that the //new objects boost::interprocess::uninitialized_copy_copy ( copy_move_it(old_start) , copy_move_it(detail::get_pointer(pos)) , first, last, detail::get_pointer(new_start)); UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore); size_type raw_gap = s_before - (elemsbefore + n); //Now initialize the rest of s_before memory with the //first of elements after new values std::uninitialized_copy ( copy_move_it(detail::get_pointer(pos)) , copy_move_it(detail::get_pointer(pos) + raw_gap) , detail::get_pointer(new_start) + elemsbefore + n); //All new elements correctly constructed, avoid new element destruction new_values_destroyer.release(); //All new elements correctly constructed, avoid old element destruction old_values_destroyer.release(); //Update size since we have a contiguous buffer this->members_.m_size = old_size + s_before; //Now copy remaining last objects in the old buffer begin T *to_destroy = std::copy(assign_move_it(detail::get_pointer(pos) + raw_gap), assign_move_it(old_finish), old_start); //Now destroy redundant elements except if they were moved and //they have trivial destructor after move size_type n_destroy = old_finish - to_destroy; if(!base_t::trivial_dctr_after_move) this->destroy_n(to_destroy, n_destroy); this->members_.m_size -= n_destroy; } else{ //Check if we have to do the insertion in two phases //since maybe s_before is not big enough and //the buffer was expanded both sides // //Old situation: // _________________________________________________ //| raw_mem | old_begin + old_end | raw_mem | //|_________|_____________________|_________________| // //New situation with do_after: // _________________________________________________ //| old_begin + new + old_end | raw_mem | //|___________________________________|_____________| // //New without do_after: // _________________________________________________ //| old_begin + new + old_end | raw_mem | //|____________________________|____________________| // bool do_after = n > s_before; FwdIt before_end = first; //If we have to expand both sides, //we will play if the first new values so //calculate the upper bound of new values if(do_after){ std::advance(before_end, s_before); } //Now we can have two situations: the raw_mem of the //beginning divides the old_begin, or the new elements: if (s_before <= elemsbefore) { //The raw memory divides the old_begin group: // //If we need two phase construction (do_after) //new group is divided in new = new_beg + new_end groups //In this phase only new_beg will be inserted // //Old situation: // _________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|_________|___________|_________|_________________| // //New situation with do_after(1): //This is not definitive situation, the second phase //will include // _________________________________________________ //| old_begin | new_beg | old_end | raw_mem | //|___________|_________|_________|_________________| // //New situation without do_after: // _________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|_____|_________|_____________________| // //Copy the first part of old_begin to raw_mem T *start_n = old_start + difference_type(s_before); std::uninitialized_copy ( copy_move_it(old_start) , copy_move_it(start_n) , detail::get_pointer(new_start)); //The buffer is all constructed until old_end, //release destroyer and update size old_values_destroyer.release(); this->members_.m_size = old_size + s_before; //Now copy the second part of old_begin overwriting himself T* next = std::copy(assign_move_it(start_n), assign_move_it(detail::get_pointer(pos)), old_start); if(do_after){ //Now copy the new_beg elements std::copy(first, before_end, detail::get_pointer(next)); } else{ //Now copy the all the new elements T* move_start = std::copy(first, last, detail::get_pointer(next)); //Now displace old_end elements T* move_end = std::copy(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish), detail::get_pointer(move_start)); //Destroy remaining moved elements from old_end except if //they have trivial destructor after being moved difference_type n_destroy = s_before - n; if(!base_t::trivial_dctr_after_move) this->destroy_n(move_end, n_destroy); this->members_.m_size -= n_destroy; } } else { //The raw memory divides the new elements // //If we need two phase construction (do_after) //new group is divided in new = new_beg + new_end groups //In this phase only new_beg will be inserted // //Old situation: // _______________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|_______________|___________|_________|_________________| // //New situation with do_after(): // ____________________________________________________ //| old_begin | new_beg | old_end | raw_mem | //|___________|_______________|_________|______________| // //New situation without do_after: // ______________________________________________________ //| old_begin | new | old_end | raw_mem | //|___________|_____|_________|__________________________| // //First copy whole old_begin and part of new to raw_mem FwdIt mid = first; size_type n_new_init = difference_type(s_before) - elemsbefore; std::advance(mid, n_new_init); boost::interprocess::uninitialized_copy_copy ( copy_move_it(old_start) , copy_move_it(detail::get_pointer(pos)) , first, mid, detail::get_pointer(new_start)); //The buffer is all constructed until old_end, //release destroyer and update size old_values_destroyer.release(); this->members_.m_size = old_size + s_before; if(do_after){ //Copy new_beg part std::copy(mid, before_end, old_start); } else{ //Copy all new elements T* move_start = std::copy(mid, last, old_start); //Displace old_end T* move_end = std::copy(copy_move_it(detail::get_pointer(pos)), copy_move_it(old_finish), detail::get_pointer(move_start)); //Destroy remaining moved elements from old_end except if they //have trivial destructor after being moved difference_type n_destroy = s_before - n; if(!base_t::trivial_dctr_after_move) this->destroy_n(move_end, n_destroy); this->members_.m_size -= n_destroy; } } //This is only executed if two phase construction is needed //This can be executed without exception handling since we //have to just copy and append in raw memory and //old_values_destroyer has been released in phase 1. if(do_after){ //The raw memory divides the new elements // //Old situation: // ______________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|______________|___________|____________|______________| // //New situation with do_after(1): // _______________________________________________________ //| old_begin + new_beg | new_end |old_end | raw_mem | //|__________________________|_________|________|_________| // //New situation with do_after(2): // ______________________________________________________ //| old_begin + new | old_end |raw | //|_______________________________________|_________|____| // const size_type n_after = n - s_before; const difference_type elemsafter = old_size - elemsbefore; //The new_end part is [first + (n - n_after), last) std::advance(first, n - n_after); //We can have two situations: if (elemsafter > difference_type(n_after)){ //The raw_mem from end will divide displaced old_end // //Old situation: // ______________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|______________|___________|____________|______________| // //New situation with do_after(1): // _______________________________________________________ //| old_begin + new_beg | new_end |old_end | raw_mem | //|__________________________|_________|________|_________| // //First copy the part of old_end raw_mem T* finish_n = old_finish - difference_type(n_after); std::uninitialized_copy ( copy_move_it(detail::get_pointer(finish_n)) , copy_move_it(old_finish) , old_finish); this->members_.m_size += n_after; //Displace the rest of old_end to the new position std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(detail::get_pointer(finish_n)), old_finish); //Now overwrite with new_end std::copy(first, last, detail::get_pointer(pos)); } else { //The raw_mem from end will divide new_end part // //Old situation: // _____________________________________________________________ //| raw_mem | old_begin | old_end | raw_mem | //|______________|___________|____________|_____________________| // //New situation with do_after(2): // _____________________________________________________________ //| old_begin + new_beg | new_end |old_end | raw_mem | //|__________________________|_______________|________|_________| // FwdIt mid = first; std::advance(mid, elemsafter); //First initialize data in raw memory boost::interprocess::uninitialized_copy_copy ( mid, last , copy_move_it(detail::get_pointer(pos)) , copy_move_it(old_finish) , old_finish); this->members_.m_size += n_after; //Now copy the part of new_end over constructed elements std::copy(first, mid, detail::get_pointer(pos)); } } } } template
void priv_range_insert(iterator pos, InIt first, InIt last, std::input_iterator_tag) { //Insert range before the pos position std::copy(std::inserter(*this, pos), first, last); } template
void priv_assign_aux(InIt first, InIt last, std::input_iterator_tag) { //Overwrite all elements we can from [first, last) iterator cur = begin(); for ( ; first != last && cur != end(); ++cur, ++first){ *cur = *first; } if (first == last){ //There are no more elements in the sequence, erase remaining this->erase(cur, end()); } else{ //There are more elements in the range, insert the remaining ones this->insert(this->end(), first, last); } } template
void priv_assign_aux(FwdIt first, FwdIt last, std::forward_iterator_tag) { size_type n = std::distance(first, last); //Check if we have enough memory or try to expand current memory size_type remaining = this->members_.m_capacity - this->members_.m_size; bool same_buffer_start; std::pair
ret; size_type real_cap = this->members_.m_capacity; if (n <= remaining){ same_buffer_start = true; } else{ //There is not enough memory, allocate a new buffer size_type new_cap = this->next_capacity(n); ret = this->allocation_command (allocate_new | expand_fwd | expand_bwd, this->size() + n, new_cap, real_cap, this->members_.m_start); same_buffer_start = ret.second && this->members_.m_start == ret.first; if(same_buffer_start){ this->members_.m_capacity = real_cap; } } if(same_buffer_start){ T *start = detail::get_pointer(this->members_.m_start); if (this->size() >= n){ //There is memory, but there are more old elements than new ones //Overwrite old elements with new ones std::copy(first, last, start); //Destroy remaining old elements this->destroy_n(start + n, this->members_.m_size - n); this->members_.m_size = n; } else{ //There is memory, but there are less old elements than new ones //First overwrite some old elements with new ones FwdIt mid = first; std::advance(mid, this->size()); T *end = std::copy(first, mid, start); //Initialize the remaining new elements in the uninitialized memory std::uninitialized_copy(mid, last, end); this->members_.m_size = n; } } else if(!ret.second){ UCopiedArrayDeallocator scoped_alloc(ret.first, this->alloc(), real_cap); std::uninitialized_copy(first, last, detail::get_pointer(ret.first)); scoped_alloc.release(); //Destroy and deallocate old buffer if(this->members_.m_start != 0){ this->destroy_n(detail::get_pointer(this->members_.m_start), this->members_.m_size); this->alloc().deallocate(this->members_.m_start, this->members_.m_capacity); } this->members_.m_start = ret.first; this->members_.m_size = n; this->members_.m_capacity = real_cap; } else{ //Backwards expansion //If anything goes wrong, this object will destroy //all old objects T *old_start = detail::get_pointer(this->members_.m_start); size_type old_size = this->members_.m_size; OldArrayDestructor old_values_destroyer(old_start, old_size); //If something goes wrong size will be 0 //but holding the whole buffer this->members_.m_size = 0; this->members_.m_start = ret.first; this->members_.m_capacity = real_cap; //Backup old buffer data size_type old_offset = old_start - detail::get_pointer(ret.first); size_type first_count = min_value(n, old_offset); FwdIt mid = boost::interprocess::n_uninitialized_copy_n (first, first_count, detail::get_pointer(ret.first)); if(old_offset > n){ //All old elements will be destroyed by "old_values_destroyer" this->members_.m_size = n; } else{ //We have constructed objects from the new begin until //the old end so release the rollback destruction old_values_destroyer.release(); this->members_.m_start = ret.first; this->members_.m_size = first_count + old_size; //Now overwrite the old values size_type second_count = min_value(old_size, n - first_count); mid = copy_n(mid, second_count, old_start); //Check if we still have to append elements in the //uninitialized end if(second_count == old_size){ boost::interprocess::n_uninitialized_copy_n ( mid , n - first_count - second_count , old_start + old_size); } else{ //We have to destroy some old values this->destroy_n (old_start + second_count, old_size - second_count); this->members_.m_size = n; } this->members_.m_size = n; } } } template
void priv_assign_dispatch(Integer n, Integer val, detail::true_) { this->assign((size_type) n, (T) val); } template
void priv_assign_dispatch(InIt first, InIt last, detail::false_) { //Dispatch depending on integer/iterator typedef typename std::iterator_traits
::iterator_category ItCat; this->priv_assign_aux(first, last, ItCat()); } template
void priv_insert_dispatch( iterator pos, Integer n, Integer val, detail::true_) { this->insert(pos, (size_type)n, (T)val); } template
void priv_insert_dispatch(iterator pos, InIt first, InIt last, detail::false_) { //Dispatch depending on integer/iterator typedef typename std::iterator_traits
::iterator_category ItCat; this->priv_range_insert(pos.get_ptr(), first, last, ItCat()); } void priv_check_range(size_type n) const { //If n is out of range, throw an out_of_range exception if (n >= size()) throw std::out_of_range("vector::at"); } #ifdef BOOST_INTERPROCESS_VECTOR_ALLOC_STATS public: unsigned int num_expand_fwd; unsigned int num_expand_bwd; unsigned int num_alloc; void reset_alloc_stats() { num_expand_fwd = num_expand_bwd = num_alloc = 0; } #endif /// @endcond }; template
inline bool operator==(const vector
& x, const vector
& y) { //Check first size and each element if needed return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); } template
inline bool operator!=(const vector
& x, const vector
& y) { //Check first size and each element if needed return x.size() != y.size() || !std::equal(x.begin(), x.end(), y.begin()); } template
inline bool operator<(const vector
& x, const vector
& y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE template
inline void swap(vector
& x, vector
& y) { x.swap(y); } template
inline void swap(const detail::moved_object
>& x, vector
& y) { x.get().swap(y); } template
inline void swap(vector
&x, const detail::moved_object
>& y) { x.swap(y.get()); } #else template
inline void swap(vector
&&x, vector
&&y) { x.swap(y); } #endif /// @cond //!This class is movable template
struct is_movable
> { enum { value = true }; }; //!has_trivial_destructor_after_move<> == true_type //!specialization for optimizations template
struct has_trivial_destructor_after_move
> { enum { value = has_trivial_destructor
::value }; }; /// @endcond } //namespace interprocess { } //namespace boost { #include
#endif // #ifndef BOOST_INTERPROCESS_VECTOR_HPP
vector.hpp
Page URL
File URL
Prev
9/9 Next
Download
( 70 KB )
Note: The DriveHQ service banners will NOT be displayed if the file owner is a paid member.
Comments
Total ratings:
0
Average rating:
Not Rated
Would you like to comment?
Join DriveHQ
for a free account, or
Logon
if you are already a member.