aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2021-11-17 10:46:18 +0000
committerJonathan Wakely <jwakely@redhat.com>2021-11-17 17:28:44 +0000
commit5a9572e486a8556116aa842d68c1ac8a0bdf0a0b (patch)
treeab8f880903de0047b12d4109993c741a235f8936 /libcpp
parent6afa1083c6ee7b31629fb0c16299b952cb17868c (diff)
downloadgcc-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