]> git.ipfire.org Git - thirdparty/gcc.git/commit - libstdc++-v3/config/abi/pre/gnu.ver
libstdc++: Avoid redundant checks in std::use_facet [PR103755]
authorJonathan Wakely <jwakely@redhat.com>
Wed, 9 Nov 2022 21:44:31 +0000 (21:44 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Fri, 11 Nov 2022 04:00:58 +0000 (04:00 +0000)
commitb3ac43a3c05744d62a963d656bed782fc867ad79
tree18b46c22d56372621932f6e33f2b8f09ca52085a
parentd3fe767c16e7c528e4fc71c8a68ac14b4573d880
libstdc++: Avoid redundant checks in std::use_facet [PR103755]

We do not need to do bounds checks or a runtime dynamic_cast when using
std::has_facet and std::use_facet to access the default facets that are
guaranteed to be present in every std::locale object. We can just index
straight into the array and use a static_cast for the conversion.

This patch adds a new std::__try_use_facet function that is like
std::use_facet but returns a pointer, so can be used to implement both
std::has_facet and std::use_facet. We can then do the necessary
metaprogramming to skip the redundant checks in std::__try_use_facet.

To avoid having to export (or hide) instantiations of the new function
from libstdc++.so the instantiations are given hidden visibility. This
allows them to be used in the library, but user code will instantiate it
again using the definition in the header. That would happen anyway,
because there are no explicit instantiation declarations for any of
std::has_facet, std::use_facet, or the new std::__try_use_facet.

libstdc++-v3/ChangeLog:

PR libstdc++/103755
* config/abi/pre/gnu.ver: Tighten patterns for facets in the
base version. Add exports for __try_use_facet.
* include/bits/basic_ios.tcc (basic_ios::_M_cache_locale): Use
__try_use_facet instead of has_facet and use_facet.
* include/bits/fstream.tcc (basic_filebuf::basic_filebuf()):
Likewise.
(basic_filebuf::imbue): Likewise.
* include/bits/locale_classes.h (locale, locale::id)
(locale::_Impl): Declare __try_use_facet as a friend.
* include/bits/locale_classes.tcc (__try_use_facet): Define new
function template with special cases for default facets.
(has_facet, use_facet): Call __try_use_facet.
* include/bits/locale_facets.tcc (__try_use_facet): Declare
explicit instantiations.
* include/bits/locale_facets_nonio.tcc (__try_use_facet):
Likewise.
* src/c++11/locale-inst-monetary.h (INSTANTIATE_FACET_ACCESSORS):
Use new macro for facet accessor instantiations.
* src/c++11/locale-inst-numeric.h (INSTANTIATE_FACET_ACCESSORS):
Likewise.
* src/c++11/locale-inst.cc (INSTANTIATE_USE_FACET): Define new
macro for instantiating __try_use_facet and use_facet.
(INSTANTIATE_FACET_ACCESSORS): Define new macro for also
defining has_facet.
* src/c++98/compatibility-ldbl.cc (__try_use_facet):
Instantiate.
* testsuite/22_locale/ctype/is/string/89728_neg.cc: Adjust
expected errors.
12 files changed:
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/bits/basic_ios.tcc
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/bits/locale_classes.h
libstdc++-v3/include/bits/locale_classes.tcc
libstdc++-v3/include/bits/locale_facets.tcc
libstdc++-v3/include/bits/locale_facets_nonio.tcc
libstdc++-v3/src/c++11/locale-inst-monetary.h
libstdc++-v3/src/c++11/locale-inst-numeric.h
libstdc++-v3/src/c++11/locale-inst.cc
libstdc++-v3/src/c++98/compatibility-ldbl.cc
libstdc++-v3/testsuite/22_locale/ctype/is/string/89728_neg.cc