This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++14 status.
Section: 24.3.11.3 [vector.capacity], 24.3.8.3 [deque.capacity] Status: C++14 Submitter: Nikolay Ivchenkov Opened: 2011-02-20 Last modified: 2016-01-28
Priority: Not Prioritized
View other active issues in [vector.capacity].
View all other issues in [vector.capacity].
View all issues with C++14 status.
Discussion:
I have several questions with regard to the working paper N3225 (C++0x working draft):
Where the working draft specifies preconditions for shrink_to_fit member function of std::vector and std::deque?
Where the working draft specifies preconditions for 'void reserve(size_type n)' member function of std::vector?
Does a call to 'void resize(size_type sz)' of std::vector require the element type to be DefaultConstructible? If yes, why such requirement is not listed in the Requires paragraph?
Does a call to 'void resize(size_type sz)' of std::vector require the element type to be MoveAssignable because the call erase(begin() + sz, end()) mentioned in the Effects paragraph would require the element type to be MoveAssignable?
Why CopyInsertable requirement is used for 'void resize(size_type sz)' of std::vector instead of MoveInsertable requirement?
[2011-06-12: Daniel comments and provides wording]
According to my understanding of the mental model of vector (and to some parts for deque) the some requirements are missing in the standard as response to above questions:
I agree that we are currently missing to specify the preconditions of the reserve function. My interpretation of the mental model of this function is that it should work for move-only types, which seems to be supported by the wording used in 24.3.11.3 [vector.capacity] p2:
[…] If an exception is thrown other than by the move constructor of a non-CopyInsertable type, there are no effects.
Given this statement, the appropriate requirement is MoveInsertable into the vector.
In addition to above mentioned items, the proposed resolution adds a linear complexity bound for shrink_to_fit and attempts to resolve the related issue 2066.
[ 2011 Bloomington ]
Move to Ready.
Note for editor: we do not normally refer to 'linear time' for complexity requirements, but there is agreement that any clean-up of such wording is editorial.
Proposed resolution:
This wording is relative to the FDIS.
Edit 24.3.8.3 [deque.capacity] as indicated [Remark: The suggested change of p4 is not redundant, because CopyInsertable is not necessarily a refinement of MoveInsertable in contrast to the fact that CopyConstructible is a refinement of MoveConstructible]:
void resize(size_type sz);-1- Effects: If sz <= size(), equivalent to
-2- Requires: T shall be MoveInsertable into *this and DefaultConstructible.erase(begin() + sz, end());calling pop_back() size() - sz times. If size() < sz, appends sz - size() value-initialized elements to the sequence.
void resize(size_type sz, const T& c);-3- Effects: If sz <= size(), equivalent to calling pop_back() size() - sz times. If size() < sz, appends sz - size() copies of c to the sequence.
if (sz > size()) insert(end(), sz-size(), c); else if (sz < size()) erase(begin()+sz, end()); else ; // do nothing-4- Requires: T shall be MoveInsertable into *this and CopyInsertable into *this.
void shrink_to_fit();-?- Requires: T shall be MoveInsertable into *this.
-?- Complexity: Takes at most linear time in the size of the sequence. -5- Remarks: shrink_to_fit is a non-binding request to reduce memory use but does not change the size of the sequence. [ Note: The request is non-binding to allow latitude for implementation-specific optimizations. — end note ]
Edit 24.3.11.3 [vector.capacity] as indicated including edits that also resolve 2066 [Remark: The combined listing of MoveInsertable and CopyInsertable before p12 is not redundant, because CopyInsertable is not necessarily a refinement of MoveInsertable in contrast to the fact that CopyConstructible is a refinement of MoveConstructible]:
[…]
void reserve(size_type n);-?- Requires: T shall be MoveInsertable into *this.
-2- Effects: A directive that informs a vector of a planned change in size, so that it can manage the storage allocation accordingly. After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise. Reallocation happens at this point if and only if the current capacity is less than the argument of reserve(). If an exception is thrown other than by the move constructor of a non-CopyInsertable type, there are no effects. -3- Complexity: It does not change the size of the sequence and takes at most linear time in the size of the sequence. -4- Throws: length_error if n > max_size().[footnote 266] -5- Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. It is guaranteed that no reallocation takes place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the value of capacity().
void shrink_to_fit();-?- Requires: T shall be MoveInsertable into *this.
-?- Complexity: Takes at most linear time in the size of the sequence. -6- Remarks: shrink_to_fit is a non-binding request to reduce capacity() to size(). [ Note: The request is non-binding to allow latitude for implementation-specific optimizations. — end note ] If an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no effects.
[…]
void resize(size_type sz);-9- Effects: If sz <= size(), equivalent to
-10- Requires: T shall beerase(begin() + sz, end());calling pop_back() size() - sz times. If size() < sz, appends sz - size() value-initialized elements to the sequence.CopyMoveInsertable into *this and DefaultConstructible. -??- Remarks: If an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no effects.
void resize(size_type sz, const T& c);-11- Effects: If sz <= size(), equivalent to calling pop_back() size() - sz times. If size() < sz, appends sz - size() copies of c to the sequence.
if (sz > size()) insert(end(), sz-size(), c); else if (sz < size()) erase(begin()+sz, end()); else ; // do nothing-??- Requires: T shall be MoveInsertable into *this and CopyInsertable into *this.
-12-RequiresRemarks: If an exception is thrown other than by the move constructor of a non-CopyInsertable T there are no effects.