diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2021-11-17 10:46:18 +0000 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2021-11-17 17:28:44 +0000 |
commit | 5a9572e486a8556116aa842d68c1ac8a0bdf0a0b (patch) | |
tree | ab8f880903de0047b12d4109993c741a235f8936 /libcpp | |
parent | 6afa1083c6ee7b31629fb0c16299b952cb17868c (diff) | |
download | gcc-5a9572e486a8556116aa842d68c1ac8a0bdf0a0b.zip gcc-5a9572e486a8556116aa842d68c1ac8a0bdf0a0b.tar.gz gcc-5a9572e486a8556116aa842d68c1ac8a0bdf0a0b.tar.bz2 |
libstdc++: Simplify std::string constructors
Several std::basic_string constructors dispatch to one of the
two-argument overloads of _M_construct, which then dispatches again to
_M_construct_aux to detect whether the arguments are iterators or not.
That then dispatches to one of _M_construct(size_type, char_type) or
_M_construct(Iter, Iter, iterator_traits<Iter>::iterator_category{}).
For most of those constructors this is a waste of time, because we know
the arguments are already iterators. For basic_string(const CharT*) and
basic_string(initializer_list<C>) we know that we call _M_construct with
two pointers, and for basic_string(const basic_string&) we call it with
two const_iterators. Those constructors can call the three-argument
overload of _M_construct with the iterator category tag right away,
without the intermediate dispatching.
The case where this doesn't apply is basic_string(InputIter, InputIter),
but for C++11 and later this is constrained so we know it's an iterator
here as well. We can restrict the dispatching in this constructor to
only be done for C++98 and to call _M_construct_aux directly, which
allows us to remove the two-argument _M_construct(InputIter, InputIter)
overload entirely.
N.B. When calling the three-arg _M_construct with pointers or string
iterators, we pass forward_iterator_tag not random_access_iterator_tag.
This is because it makes no difference which overload gets called, and
simplifies overload resolution to not have to do a base-to-derived
check. If we ever add a new overload of M_construct for random access
iterators we would have to revisit this, but that seems unlikely.
This patch also moves the __is_null_pointer checks from the three-arg
_M_construct into the constructors where a null pointer argument is
actually possible. This avoids redundant checks where we know we have a
non-null pointer, or don't have a pointer at all.
Finally, this patch replaces some try-blocks with an RAII type, so that
memory is deallocated during unwinding. This avoids the overhead of
catching and rethrowing an exception.
libstdc++-v3/ChangeLog:
* include/bits/basic_string.h (_M_construct_aux): Only define
for C++98. Remove constexpr.
(_M_construct_aux_2): Likewise.
(_M_construct(InputIter, InputIter)): Remove.
(basic_string(const basic_string&)): Call _M_construct with
iterator category argument.
(basic_string(const basic_string&, size_type, const Alloc&)):
Likewise.
(basic_string(const basic_string&, size_type, size_type)):
Likewise.
(basic_string(const charT*, size_type, const Alloc&)): Likewise.
Check for null pointer.
(basic_string(const charT*, const Alloc&)): Likewise.
(basic_string(initializer_list<charT>, const Alloc&)): Call
_M_construct with iterator category argument.
(basic_string(const basic_string&, const Alloc&)): Likewise.
(basic_string(basic_string&&, const Alloc&)): Likewise.
(basic_string(_InputIter, _InputIter, const Alloc&)): Likewise
for C++11 and later, call _M_construct_aux for C++98.
* include/bits/basic_string.tcc
(_M_construct(I, I, input_iterator_tag)): Replace try-block with
RAII type.
(_M_construct(I, I, forward_iterator_tag)): Likewise. Remove
__is_null_pointer check.
Diffstat (limited to 'libcpp')
0 files changed, 0 insertions, 0 deletions