Difference between revisions of "cpp/named req/SequenceContainer"
Ben.Hymers (Talk | contribs) (Correction: renaming emplace(p, t) to insert since there is no such emplace requirement (ref. [sequence.reqmts])) |
(+missing requirements) |
||
Line 5: | Line 5: | ||
===Requirements=== | ===Requirements=== | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | The type {{tt|X}} satisfies {{tt|SequenceContainer}} if | ||
+ | |||
+ | * The type {{tt|X}} satisfies {{concept|Container}}, and | ||
+ | * The type {{tt|X::iterator}} satisfies {{concept|ForwardIterator}}, and | ||
+ | * The type {{tt|X::const_iterator}} satisfies {{concept|ForwardIterator}}, and | ||
+ | |||
+ | Given | ||
+ | * {{tt|T}}, the element type of {{tt|X}} | ||
+ | * {{tt|A}}, the allocator type of {{tt|X}}: {{c|X::allocator_type}} if it exists, otherwise {{c|std::allocator<T>}} | ||
+ | * {{tt|a}}, [[cpp/language/value_category|rvalue]] expression of type of type {{tt|X}} | ||
+ | * {{tt|p}}, a valid const iterator into {{tt|a}} | ||
+ | * {{tt|q}}, a valid dereferenceable const iterator into {{tt|a}} | ||
+ | * {{tt|q1}} and {{tt|q2}}, two const iterators into {{tt|a}} such that {{c|[q1, q2)}} is a valid range | ||
+ | * {{tt|i}} and {{tt|j}}, {{concept|InputIterator}}s such that {{c|[i, j)}} is a valid range and that the iterators refer to elements implicitly convertible to {{tt|value_type}} | ||
+ | * {{tt|il}}, an object of type {{c|std::initializer_list<value_type>}} | ||
+ | * {{tt|n}}, a value of type {{c|X::size_type}} | ||
+ | * {{tt|t}}, an lvalue or const rvalue of type {{c|X::value_type}} | ||
+ | * {{tt|rv}}, a non-const rvalue of type {{c|X::value_type}} | ||
+ | * {{tt|Args}}: a template parameter pack | ||
+ | * {{tt|args}}: a function parameter pack with the pattern {{c|Arg&&}} | ||
+ | |||
+ | The following expressions must be valid and have their specified effects for all sequence containers except {{lc|std::array}}: | ||
{|class=wikitable | {|class=wikitable | ||
!expression||return type||effects||precondition||postcondition | !expression||return type||effects||precondition||postcondition | ||
|- | |- | ||
− | |{{c|X(n,t)}} | + | |{{c|X(n, t)}} |
+ | {{c|X a(n, t)}} | ||
+ | | | ||
+ | |Constructs the sequence container holding {{ttb|n}} copies of {{ttb|t}} | ||
+ | |{{tt|T}} {{concept|CopyInsertable}} into {{tt|X}} | ||
+ | |{{c|std::distance(begin(),end()) {{==}} n}} | ||
|- | |- | ||
− | |{{c|X(i,j)}} | + | |{{c|X(i, j)}} |
+ | {{c|X a(i, j)}} | ||
| | | | ||
− | + | |Constructs the sequence container equal, element-wise, to the range {{tt|[i,j)}} | |
− | * {{mark|only for std::vector}} If the iterators are not {{concept|ForwardIterator}}s, T must be {{concept|CopyInsertable}} | + | | {{tt|T}} is {{concept|EmplaceConstructible}} from {{tt|*i}} into {{tt|X}} |
− | |{{c|1=std::distance(begin(),end()) == | + | {{mark|only for std::vector}} If the iterators are not {{concept|ForwardIterator}}s, T must be {{concept|CopyInsertable}} |
− | std::distance(i,j)}} | + | |{{c|1=std::distance(begin(),end()) == std::distance(i,j)}} |
|- | |- | ||
− | |{{c|X(il)}}|| || {{c|X(il.begin(),il.end())}} || || | + | |{{c|X(il)}}|| || {{c|X(il.begin(), il.end())}}>|| || |
|- | |- | ||
− | |{{c|1=a = il}}||{{c|X&}}||Assigns the range represented by {{ttb|il}} into {{ttb|a}} | + | |{{c|1=a = il}}||{{c|X&}}||Assigns the range represented by {{ttb|il}} into {{ttb|a}}<ref>{{lc|std::array}} supports assignment from a braced-init-list, but not from an {{lc|std::initializer_list}}</ref> |
| T {{concept|CopyInsertable}} and {{concept|CopyAssignable}} | | T {{concept|CopyInsertable}} and {{concept|CopyAssignable}} | ||
| Existing elements of {{ttb|a}} are destroyed or assigned to | | Existing elements of {{ttb|a}} are destroyed or assigned to | ||
|- | |- | ||
− | |{{c|a.emplace(p,args)}}||iterator | + | |{{c|a.emplace(p,args)}}||{{tt|iterator}} |
− | |Insert an object constructed with {{c|std::forward<Args>(args)}} before {{ttb|p}} | + | |Insert an object of type {{tt|T}}, constructed with {{c|std::forward<Args>(args)}} before {{ttb|p}} |
− | | | + | |{{tt|T}} {{concept|CopyInsertable}} |
− | + | {{mark|for std::vector and std::deque}} {{tt|T}} {{concept|MoveAssignable}} and {{concept|MoveInsertable}} | |
− | + | |Returned iterator points at the element constructed from {{tt|args}} into {{tt|a}} | |
− | | | + | |
|- | |- | ||
− | |{{c|a.insert(p,t)}}||iterator | + | |{{c|a.insert(p,t)}}||{{tt|iterator}} |
|Inserts a copy of {{ttb|t}} before {{ttb|p}} | |Inserts a copy of {{ttb|t}} before {{ttb|p}} | ||
− | | | + | |{{tt|T}} {{concept|CopyInsertable}} |
− | + | {{mark|for std::vector and std::deque}} {{tt|T}} {{concept|CopyAssignable}} or {{concept|MoveAssignable}} | |
− | + | |Returned iterator points at the copy of {{tt|t}} inserted into {{tt|a}} | |
− | | | + | |- |
+ | |{{c|a.insert(p,rv)}}||{{tt|iterator}} | ||
+ | |Inserts a copy of {{ttb|rv}} before {{ttb|p}}, possibly using move semantics | ||
+ | |{{tt|T}} {{concept|MoveInsertable}} | ||
+ | {{mark|for std::vector and std::deque}} {{tt|T}} {{concept|MoveAssignable}} | ||
+ | |Returned iterator points at the copy of {{tt|rv}} inserted into {{tt|a}} | ||
|- | |- | ||
− | |{{c|a.insert(p,n,t)}}||iterator||Inserts {{ttb|n}} copies of {{ttb|t}} before {{ttb|p}} | + | |{{c|a.insert(p,n,t)}}||{{tt|iterator}}||Inserts {{ttb|n}} copies of {{ttb|t}} before {{ttb|p}} |
− | | T {{concept|CopyInsertable}} and {{concept|CopyAssignable}} | + | |{{tt|T}} {{concept|CopyInsertable}} and {{concept|CopyAssignable}} |
− | | | + | |Returned iterator points at the copy of the first element inserted into {{tt|a}} or is {{tt|p}} for {{c|1=n==0}} |
|- | |- | ||
− | |{{c|a.insert(p,i,j)}}||iterator||Inserts copies of elements in {{tt|[i, j)}} before {{ttb|p}} | + | |{{c|a.insert(p,i,j)}}||{{tt|iterator}}||Inserts copies of elements in {{tt|[i, j)}} before {{ttb|p}} |
− | | | + | | T {{concept|EmplaceConstructible}} and {{ttb|i}} and {{ttb|j}} are not in {{ttb|a}} |
− | + | {{mark|only for std::vector}} If the iterators are not {{concept|ForwardIterator}}s, T must be {{concept|MoveInsertable}} and {{concept|MoveAssignable}} | |
− | + | |Each iterator in {{tt|[i,j)}} is dereferenced once. Returned iterator points at the copy of the first element inserted into {{tt|a}} or is {{tt|p}} for {{c|1=i==j}} | |
− | + | ||
− | + | ||
|- | |- | ||
− | |{{c|a.insert(p, il)}}||iterator||{{c|a.insert(p,il.begin(),il.end())}}|| || | + | |{{c|a.insert(p, il)}}||{{tt|iterator}}||{{c|a.insert(p,il.begin(),il.end())}}|| ||Returned iterator points at the copy of the first element inserted into {{tt|a}} or is {{tt|p}} if {{tt|il}} is empty. |
|- | |- | ||
− | |{{c|a.erase(q)}}||iterator||Erases the element pointed to by q | + | |{{c|a.erase(q)}}||{{tt|iterator}}||Erases the element pointed to by {{tt|q}} |
|{{mark|std::deque, std::vector}} T {{concept|MoveAssignable}} | |{{mark|std::deque, std::vector}} T {{concept|MoveAssignable}} | ||
− | | | + | |Returned iterator points at the element that was immediately following {{tt|q}} prior to erasure, or {{c|a.end()}} if no such element exists. |
|- | |- | ||
− | |{{c|a.erase( | + | |{{c|a.erase(q1,q2)}}||{{tt|iterator}}||Erases elements in {{tt|[p,q)}}||{{mark|std::deque, std::vector}} T {{concept|MoveAssignable}}||Returned iterator points at the element that was pointed by {{tt|q2}} prior to any erasure, or {{c|a.end()}} if no such element exists. |
|- | |- | ||
− | |{{c|a.clear()}}||void||Destroys all elements in {{ttb|a}}|| || | + | |{{c|a.clear()}}||{{tt|void}}||Destroys all elements in {{ttb|a}}|| || |
− | + | All references, pointers, and iterators are invalidated, including the end iterator. {{c|1=a.empty() == true}}. | |
− | + | ||
|- | |- | ||
− | |{{c|a.assign(i,j)}}||void||Replaces elements in a with a copy of {{tt|[i, j)}} | + | |{{c|a.assign(i,j)}}||{{tt|void}}||Replaces elements in a with a copy of {{tt|[i, j)}} |
− | | | + | |{{tt|T}} {{concept|EmplaceConstructible}} and {{ttb|i}}, {{ttb|j}} not in {{ttb|a}} |
− | + | {{mark|std::vector}} If not {{concept|ForwardIterator}}. {{tt|T}} {{concept|MoveInsertable}} | |
− | + | ||
− | + | ||
|Each iterator in {{tt|[i,j)}} is dereferenced once | |Each iterator in {{tt|[i,j)}} is dereferenced once | ||
|- | |- | ||
− | |{{c|a.assign(il)}}||void||{{c|a.assign(il.begin(),il.end())}}|| || | + | |{{c|a.assign(il)}}||{{tt|void}}||{{c|a.assign(il.begin(),il.end())}}|| || |
|- | |- | ||
− | |{{c|a.assign(n,t)}}||void | + | |{{c|a.assign(n,t)}}||{{tt|void}} |
|Replaces elements in {{ttb|a}} with {{ttb|n}} copies of {{ttb|t}} | |Replaces elements in {{ttb|a}} with {{ttb|n}} copies of {{ttb|t}} | ||
|T {{concept|CopyInsertable}} and {{concept|CopyAssignable}} | |T {{concept|CopyInsertable}} and {{concept|CopyAssignable}} | ||
| | | | ||
|- | |- | ||
+ | !colspan=5|notes | ||
+ | |- | ||
+ | |colspan=5|<references/> | ||
+ | |} | ||
+ | |||
+ | The following expressions must be valid and have their specified effects for the sequence containers named: | ||
+ | |||
+ | {|class=wikitable | ||
+ | !expression||return type||effects||preconditions||containers | ||
+ | |- | ||
+ | |{{c|a.front()}} | ||
+ | |{{tt|reference}} | ||
+ | {{tt|const_reference}} for const a | ||
+ | |Equivalent to {{c|*a.begin()}} | ||
+ | | | ||
+ | |(all) | ||
+ | |- | ||
+ | |{{c|a.back()}} | ||
+ | |{{tt|void}} | ||
+ | |Equivalent to {{c|1={ auto tmp = a.end(); --tmp; return *tmp; } }} | ||
+ | | | ||
+ | |{{lc|std::basic_string}} {{lc|std::array}} {{lc|std::deque}} {{lc|std::vector}} | ||
+ | |- | ||
+ | |{{c|a.emplace_front(args)}} | ||
+ | |{{tt|void}} | ||
+ | |Prepends a {{tt|T}} constructed with {{c|std::forward<Args>(args)...}} | ||
+ | |{{tt|T}} {{concept|EmplaceConstructible}} into {{tt|X}} from {{tt|args}} | ||
+ | |{{lc|std::deque}} {{lc|std::forward_list}} {{lc|std::list}} | ||
+ | |- | ||
+ | |{{c|a.emplace_back(args)}} | ||
+ | |{{tt|void}} | ||
+ | |Appends a {{tt|T}} constructed with {{c|std::forward<Args>(args)...}} | ||
+ | |{{tt|T}} {{concept|EmplaceConstructible}} into {{tt|X}} from {{tt|args}} | ||
+ | {{mark|std::vector only}} {{tt|T}} {{concept|MoveInsertable}} into {{tt|X}} | ||
+ | |{{lc|std::deque}} {{lc|std::list}} {{lc|std::vector}} | ||
+ | |- | ||
+ | |{{c|a.push_font(t)}} | ||
+ | |{{tt|void}} | ||
+ | |Prepends a copy of {{tt|t}} | ||
+ | |{{tt|T}} {{concept|CopyInsertable}} into {{tt|X}} | ||
+ | |{{lc|std::deque}} {{lc|std::forward_list}} {{lc|std::list}} | ||
+ | |- | ||
+ | |{{c|a.push_front(rv)}} | ||
+ | |{{tt|void}} | ||
+ | |Prepends a copy of {{tt|rv}}, possibly using move semantics | ||
+ | |{{tt|T}} {{concept|MoveInsertable}} into {{tt|X}} | ||
+ | |{{lc|std::deque}} {{lc|std::forward_list}} {{lc|std::list}} | ||
+ | |- | ||
+ | |{{c|a.push_back(t)}} | ||
+ | |{{tt|void}} | ||
+ | |Appends a copy of {{tt|t}} | ||
+ | |{{tt|T}} {{concept|CopyInsertable}} into {{tt|X}} | ||
+ | |{{lc|std::basic_string}} {{lc|std::deque}} {{lc|std::list}} {{lc|std::vector}} | ||
+ | |- | ||
+ | |{{c|a.push_back(rv)}} | ||
+ | |{{tt|void}} | ||
+ | |Appends a copy of {{tt|rv}}, possibly using move semantics | ||
+ | |{{tt|T}} {{concept|MoveInsertable}} into {{tt|X}} | ||
+ | |{{lc|std::basic_string}} {{lc|std::deque}} {{lc|std::list}} {{lc|std::vector}} | ||
+ | |- | ||
+ | |{{c|a.pop_front()}} | ||
+ | |{{tt|void}} | ||
+ | |Destroys the first element. | ||
+ | |{{c|1=a.empty() == false}} | ||
+ | |{{lc|std::deque}} {{lc|std::forward_list}} {{lc|std::list}} | ||
+ | |- | ||
+ | |{{c|a.pop_back()}} | ||
+ | |Destroys the last element | ||
+ | |{{c|1=a.empty() == false}} | ||
+ | |{{lc|std::basic_string}} {{lc|std::deque}} {{lc|std::list}} {{lc|std::vector}} | ||
+ | |- | ||
+ | |{{c|a[n]}} | ||
+ | |{{tt|reference}} | ||
+ | {{tt|const_reference}} for const a | ||
+ | |Equivalent to {{c|*(n + a.begin())}} | ||
+ | | | ||
+ | |{{lc|std::basic_string}} {{lc|std::array}} {{lc|std::deque}} {{lc|std::vector}} | ||
+ | |- | ||
+ | |{{c|a.at(n)}} | ||
+ | |{{tt|reference}} | ||
+ | {{tt|const_reference}} for const a | ||
+ | |Equivalent to {{c|*(n + a.begin())}}, except that {{lc|out_of_range}} is thrown if {{c|1=n>=size()}} | ||
+ | | | ||
+ | |{{lc|std::basic_string}} {{lc|std::array}} {{lc|std::deque}} {{lc|std::vector}} | ||
|} | |} | ||
− | + | Additionally, for every sequence container, the constructor template that takes two input iterators and the member function template overloads of {{tt|insert()}}, {{tt|append()}}, {{tt|assign()}}, {{tt|replace()}} that take two input iterators do not participate in overload resolution if the their template arguments does not satisfy {{concept|InputIterator}}. | |
− | {{ | + | |
===SequenceContainers in the standard library=== | ===SequenceContainers in the standard library=== | ||
{{dsc begin}} | {{dsc begin}} | ||
+ | {{dsc inc | cpp/string/dsc basic_string}} | ||
{{dsc inc | cpp/container/dsc array}} | {{dsc inc | cpp/container/dsc array}} | ||
{{dsc inc | cpp/container/dsc vector}} | {{dsc inc | cpp/container/dsc vector}} |
Revision as of 06:32, 20 March 2015
Template:cpp/concept/title Template:cpp/concept/navbar
A SequenceContainer
is a Template:concept that stores objects of the same type in a linear arrangement.
Requirements
The type X
satisfies SequenceContainer
if
- The type
X
satisfies Template:concept, and - The type
X::iterator
satisfies Template:concept, and - The type
X::const_iterator
satisfies Template:concept, and
Given
-
T
, the element type ofX
-
A
, the allocator type ofX
: X::allocator_type if it exists, otherwise std::allocator<T> -
a
, rvalue expression of type of typeX
-
p
, a valid const iterator intoa
-
q
, a valid dereferenceable const iterator intoa
-
q1
andq2
, two const iterators intoa
such that [q1, q2) is a valid range -
i
andj
, Template:concepts such that [i, j) is a valid range and that the iterators refer to elements implicitly convertible tovalue_type
-
il
, an object of type std::initializer_list<value_type> -
n
, a value of type X::size_type -
t
, an lvalue or const rvalue of type X::value_type -
rv
, a non-const rvalue of type X::value_type -
Args
: a template parameter pack -
args
: a function parameter pack with the pattern Arg&&
The following expressions must be valid and have their specified effects for all sequence containers except std::array:
expression | return type | effects | precondition | postcondition |
---|---|---|---|---|
X(n, t)
X a(n, t) |
Constructs the sequence container holding n copies of t
|
T Template:concept into X
|
std::distance(begin(),end()) == n | |
X(i, j)
X a(i, j) |
Constructs the sequence container equal, element-wise, to the range [i,j)
|
T is Template:concept from *i into X
(only for std::vector) If the iterators are not Template:concepts, T must be Template:concept |
std::distance(begin(),end()) == std::distance(i,j) | |
X(il) | X(il.begin(), il.end())> | |||
a = il | X& | Assigns the range represented by il into a [1]
|
T Template:concept and Template:concept | Existing elements of a are destroyed or assigned to
|
a.emplace(p,args) | iterator
|
Insert an object of type T , constructed with std::forward<Args>(args) before p
|
T Template:concept
(for std::vector and std::deque) |
Returned iterator points at the element constructed from args into a
|
a.insert(p,t) | iterator
|
Inserts a copy of t before p
|
T Template:concept
(for std::vector and std::deque) |
Returned iterator points at the copy of t inserted into a
|
a.insert(p,rv) | iterator
|
Inserts a copy of rv before p , possibly using move semantics
|
T Template:concept
(for std::vector and std::deque) |
Returned iterator points at the copy of rv inserted into a
|
a.insert(p,n,t) | iterator |
Inserts n copies of t before p
|
T Template:concept and Template:concept
|
Returned iterator points at the copy of the first element inserted into a or is p for n==0
|
a.insert(p,i,j) | iterator |
Inserts copies of elements in [i, j) before p
|
T Template:concept and i and j are not in a
(only for std::vector) If the iterators are not Template:concepts, T must be Template:concept and Template:concept |
Each iterator in [i,j) is dereferenced once. Returned iterator points at the copy of the first element inserted into a or is p for i==j
|
a.insert(p, il) | iterator |
a.insert(p,il.begin(),il.end()) | Returned iterator points at the copy of the first element inserted into a or is p if il is empty.
| |
a.erase(q) | iterator |
Erases the element pointed to by q
|
(std::deque, std::vector) T Template:concept | Returned iterator points at the element that was immediately following q prior to erasure, or a.end() if no such element exists.
|
a.erase(q1,q2) | iterator |
Erases elements in [p,q) |
(std::deque, std::vector) T Template:concept | Returned iterator points at the element that was pointed by q2 prior to any erasure, or a.end() if no such element exists.
|
a.clear() | void |
Destroys all elements in a |
All references, pointers, and iterators are invalidated, including the end iterator. a.empty() == true. | |
a.assign(i,j) | void |
Replaces elements in a with a copy of [i, j)
|
T Template:concept and i , j not in a
(std::vector) If not Template:concept. |
Each iterator in [i,j) is dereferenced once
|
a.assign(il) | void |
a.assign(il.begin(),il.end()) | ||
a.assign(n,t) | void
|
Replaces elements in a with n copies of t
|
T Template:concept and Template:concept | |
notes | ||||
|
The following expressions must be valid and have their specified effects for the sequence containers named:
expression | return type | effects | preconditions | containers |
---|---|---|---|---|
a.front() | reference
|
Equivalent to *a.begin() | (all) | |
a.back() | void
|
Equivalent to { auto tmp = a.end(); --tmp; return *tmp; } | std::basic_string std::array std::deque std::vector | |
a.emplace_front(args) | void
|
Prepends a T constructed with std::forward<Args>(args)...
|
T Template:concept into X from args
|
std::deque std::forward_list std::list |
a.emplace_back(args) | void
|
Appends a T constructed with std::forward<Args>(args)...
|
T Template:concept into X from args
(std::vector only) |
std::deque std::list std::vector |
a.push_font(t) | void
|
Prepends a copy of t
|
T Template:concept into X
|
std::deque std::forward_list std::list |
a.push_front(rv) | void
|
Prepends a copy of rv , possibly using move semantics
|
T Template:concept into X
|
std::deque std::forward_list std::list |
a.push_back(t) | void
|
Appends a copy of t
|
T Template:concept into X
|
std::basic_string std::deque std::list std::vector |
a.push_back(rv) | void
|
Appends a copy of rv , possibly using move semantics
|
T Template:concept into X
|
std::basic_string std::deque std::list std::vector |
a.pop_front() | void
|
Destroys the first element. | a.empty() == false | std::deque std::forward_list std::list |
a.pop_back() | Destroys the last element | a.empty() == false | std::basic_string std::deque std::list std::vector | |
a[n] | reference
|
Equivalent to *(n + a.begin()) | std::basic_string std::array std::deque std::vector | |
a.at(n) | reference
|
Equivalent to *(n + a.begin()), except that out_of_range is thrown if n>=size() | std::basic_string std::array std::deque std::vector |
Additionally, for every sequence container, the constructor template that takes two input iterators and the member function template overloads of insert()
, append()
, assign()
, replace()
that take two input iterators do not participate in overload resolution if the their template arguments does not satisfy Template:concept.
SequenceContainers in the standard library
stores and manipulates sequences of characters (class template) | |
(C++11) |
fixed-sized inplace contiguous array (class template) |
dynamic contiguous array (class template) | |
double-ended queue (class template) | |
(C++11) |
singly-linked list (class template) |
doubly-linked list (class template) |
Trade-offs / usage notes
std::array | Fast access but fixed number of elements |
std::vector | Fast access but mostly inefficient insertions/deletions |
std::list std::forward_list |
Efficient insertion/deletion in the middle of the sequence |
std::deque | Efficient insertion/deletion at the beginning and at the end of the sequence |