From: Jonathan Wakely Date: Fri, 19 Dec 2014 18:16:39 +0000 (+0000) Subject: New std::string implementation. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=34a2b7558b37707a17e1f2ba5298f94a88807492;p=gcc.git New std::string implementation. * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI): Remove. (GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI, GLIBCXX_DEFAULT_ABI): Add. * configure.ac: Use new macros. * configure: Regenerate. * Makefile.in: Regenerate. * doc/Makefile.in: Regenerate. * libsupc++/Makefile.in: Regenerate. * po/Makefile.in: Regenerate. * src/Makefile.in: Regenerate. * testsuite/Makefile.in: Regenerate. * include/Makefile.am: Set _GLIBCXX_USE_DUAL_ABI. * include/Makefile.in: Regenerate. * config/abi/pre/gnu.ver: Export symbols related to new std::string. Tighten old patterns to not match new symbols. * config/locale/generic/monetary_members.cc: Guard some definitions to not compile with new ABI. * config/locale/gnu/monetary_members.cc: Likewise. * config/locale/gnu/numeric_members.cc: Prevent double-free. * config/os/gnu-linux/ldbl-extra.ver: Add new __gnu_cxx_ldbl128 exports. Tighten old patterns. * doc/xml/manual/configure.xml: Document new configure options. * doc/html/*: Regenerate. * include/bits/basic_string.h (__cxx11::basic_string): Define new non-reference-counted implementation in inline namespace __cxx11. (stoi, stol, stoll, stof, stod, stold, to_string): Conditionally use inline namespace. (literals::string_literals::operator"): Conditionally use abi-tag. * include/bits/basic_string.tcc (__cxx11::basic_string): Define. * include/bits/c++config: Define _GLIBCXX_USE_DUAL_ABI and LDBL_CXX11_ABI namespace macros. * include/bits/locale_classes.h (locale::name()): Use abi_tag when new ABI is in use. (locale::_S_twinned_facets): New static member. (locale::facet::__shim): Declare new type. (locale::_facet::_M_sso_shim, locale::_facet::_M_cow_shim): New functions for creating shims. (locale::_Impl::_M_facet_unchecked): New member function for use during construction. (locale::_Impl::_M_init_extra): New member functions to create second version of some facets. (collate, collate_byname): Use abi_tag when new ABI is in use. * include/bits/locale_facets.h: Add _GLIBCXX_NUM_CXX11_FACETS macro. (numpunct, numpunct_byname): Use __cxx11 namespace. (num_get::_M_extract_float, num_get::_M_extract_int): Use abi_tag when new ABI is in use. (num_get::__do_get, num_put::__do_put): Do not declare long double compat functions for new ABI. * include/bits/locale_facets.tcc (num_get, num_put): Use abi_tag on definitions. (numpunct, numpunct_byname): Qualify explicit instantiations. * include/bits/locale_facets_nonio.h (time_get, time_get_byname, moneypunct, moneypunct_byname, money_get, money_put, messages, messages_byname): Use new inline namespace macros. (money_get::__do_get, money_put::__do_put): Do not declare long double compat functions for new ABI. * include/bits/locale_facets_nonio.tcc (money_get, money_put): Use new namespace macros. (money_get::__do_get, money_put::__do_put): Do not define for new ABI. * include/bits/localefwd.h (numpunct, numpunct_byname, collate, collate_byname, time_get, time_get_byname, moneypunct, moneypunct_byname, money_get, money_put, messages, messages_byname): Use new namespace macros. * include/bits/regex.h: Use inline namespace macros. * include/bits/stl_list.h (_List_base, list): Use inline namespace instead of abi-tag. * include/bits/stringfwd.h (basic_string): Use namespace macros. * include/std/iosfwd (basic_stringbuf, basic_istringstream, basic_ostringstream, basic_stringstream): Likewise. * include/std/sstream: Likewise. (basic_stringbuf::__xfer_bufptrs): Update streambuf pointers on move. * include/std/stdexcept (__cow_string, __sso_string): New types for indirectly using std::string with either ABI. (logic_error, runtime_error): Replace std::string member with __cow_string when new ABI is in use. Declare non-inline copy constructor and assignment operator. Declare const char* constructors. (domain_error, invalid_argument, length_error, out_of_range, range_error, overflow_error, underflow_error): Declare const char* constructors. * include/std/system_error (error_category): Replace with new definition in inline namespace _V2. (error_code::message, error_condition::message): Use abi_tag on functions returning std::string. * python/libstdcxx/v6/printers.py (StdStringPrinter): Handle new ABI. * src/c++11/Makefile.am: Add new files. * src/c++11/Makefile.in: Regenerate. * src/c++11/compatibility-c++0x.cc: Compile with old std::string ABI. Define old error_category symbols. * src/c++11/cow-fstream-inst.cc: New. Instantiate fstream members using old std::string ABI. * src/c++11/cow-locale_init.cc (locale::_Impl::_M_init_extra): Define. * src/c++11/cow-shim_facets.cc: Define shim facets using old ABI. * src/c++11/cow-sstream-inst.cc: Instantiate stringstreams using old std::string ABI. * src/c++11/cow-stdexcept.cc: Define new constructors and assignment operators. (__cow_string, error_category::_M_message): Define. * src/c++11/cow-string-inst.cc: Explicit instantiations using old std::string. Include src/c++98/istream-string.cc. * src/c++11/cow-wstring-inst.cc: Explicit instantiations using old std::wstring. * src/c++11/cxx11-hash_tr1.cc: Explicit instantiations using new string. * src/c++11/cxx11-ios_failure.cc: Add sanity check. * src/c++11/cxx11-locale-inst.cc: Instantiate facets using new std::string. * src/c++11/cxx11-shim_facets.cc: Define shim facets using new ABI. * src/c++11/cxx11-stdexcept.cc: Define constructors taking new std::string. * src/c++11/cxx11-wlocale-inst.cc: Instantiate facets using new std::wstring. * src/c++11/fstream-inst.cc: Compile with new ABI. * src/c++11/functexcept.cc: Compile with old ABI. * src/c++11/random.cc: Compile with new ABI. * src/c++11/sstream-inst.cc: Compile with new ABI. * src/c++11/string-inst.cc: Explicit instantiations for new string. * src/c++11/system_error.cc (__sso_string, error_category::_M_message): Define. * src/c++11/wstring-inst.cc: Compile with new ABI. * src/c++98/Makefile.am: Compile some host files twice for old and new std::string. Add new files. * src/c++98/Makefile.in: Regenerate. * src/c++98/compatibility-ldbl.cc: Compile with old ABI. * src/c++98/compatibility.cc: Likewise. * src/c++98/concept-inst.cc: Likewise. * src/c++98/hash_tr1.cc: Likewise. * src/c++98/istream-string.cc: New file defining functions that work with istream and std::string moved from ... * src/c++98/istream.cc: ... here. * src/c++98/cow-istream-string.cc: Recompile istream-string.cc with old ABI. * src/c++98/locale-inst.cc: Adjust facet instantiations to work for either ABI. * src/c++98/locale.cc (locale::_M_install_facet, locale::_M_install_cache): Handle twinned facets. * src/c++98/locale-facets.cc: Compile with old std::string ABI. (__verify_grouping): Define new overload and old std::string version. * src/c++98/locale_init.cc: Initialize twinned facets. * src/c++98/localename.cc: Likewise. * src/c++98/misc-inst.cc: Instantiate C++98-only std::string members. (__verify_grouping): Define new std::string version. * src/c++98/stdexcept.cc: Compile with old std::string ABI. * src/c++98/wlocale-inst.cc: Likewise. * testsuite/18_support/50594.cc: Adjust to work with SSO strings. * testsuite/21_strings/basic_string/capacity/1.cc: Likewise. * testsuite/21_strings/basic_string/capacity/char/1.cc: Likewise. * testsuite/21_strings/basic_string/capacity/char/18654.cc: Likewise. * testsuite/21_strings/basic_string/capacity/char/2.cc: Likewise. * testsuite/21_strings/basic_string/capacity/wchar_t/1.cc: Likewise. * testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc: Likewise. * testsuite/21_strings/headers/string/synopsis.cc: Use inline namespace macros. * testsuite/23_containers/headers/list/synopsis.cc: Likewise. * testsuite/27_io/basic_ios/copyfmt/char/1.cc: Set dg-options so correct exception type can be caught. * testsuite/27_io/basic_ios/exceptions/char/1.cc: Likewise. * testsuite/27_io/basic_istream/extractors_arithmetic/char/ exceptions_failbit.cc: Likewise. * testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/ exceptions_failbit.cc: Likewise. * testsuite/27_io/basic_istream/extractors_other/char/ exceptions_null.cc: Likewise. * testsuite/27_io/basic_istream/extractors_other/wchar_t/ exceptions_null.cc: Likewise. * testsuite/27_io/basic_istream/sentry/char/12297.cc: Likewise. * testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc: Likewise. * testsuite/27_io/basic_ostream/inserters_other/char/ exceptions_null.cc: Likewise. * testsuite/27_io/basic_ostream/inserters_other/wchar_t/ exceptions_null.cc: Likewise. * testsuite/27_io/ios_base/storage/2.cc: Likewise. * testsuite/27_io/ios_base/failure/cxx11.cc: Disable for old ABI. * testsuite/ext/profile/mutex_extensions_neg.cc: Adjust dg-error. * testsuite/libstdc++-prettyprinters/libfundts.cc: Use old ABI. * testsuite/libstdc++-prettyprinters/simple.cc: Likewise. * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. * testsuite/libstdc++-prettyprinters/whatis.cc: Likewise. * testsuite/util/exception/safety.h: Adjust member function types for new std::string. * testsuite/util/testsuite_abi.cc: Add new version and ignore __float128 symbols in __cxx11 namespace. From-SVN: r218964 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2405bb55908..a46a2b6d0d3 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,187 @@ +2014-12-19 Jonathan Wakely + + * acinclude.m4 (GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI): Remove. + (GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI, GLIBCXX_DEFAULT_ABI): Add. + * configure.ac: Use new macros. + * configure: Regenerate. + * Makefile.in: Regenerate. + * doc/Makefile.in: Regenerate. + * libsupc++/Makefile.in: Regenerate. + * po/Makefile.in: Regenerate. + * src/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + * include/Makefile.am: Set _GLIBCXX_USE_DUAL_ABI. + * include/Makefile.in: Regenerate. + * config/abi/pre/gnu.ver: Export symbols related to new std::string. + Tighten old patterns to not match new symbols. + * config/locale/generic/monetary_members.cc: Guard some definitions + to not compile with new ABI. + * config/locale/gnu/monetary_members.cc: Likewise. + * config/locale/gnu/numeric_members.cc: Prevent double-free. + * config/os/gnu-linux/ldbl-extra.ver: Add new __gnu_cxx_ldbl128 + exports. Tighten old patterns. + * doc/xml/manual/configure.xml: Document new configure options. + * doc/html/*: Regenerate. + * include/bits/basic_string.h (__cxx11::basic_string): Define new + non-reference-counted implementation in inline namespace __cxx11. + (stoi, stol, stoll, stof, stod, stold, to_string): Conditionally use + inline namespace. + (literals::string_literals::operator"): Conditionally use abi-tag. + * include/bits/basic_string.tcc (__cxx11::basic_string): Define. + * include/bits/c++config: Define _GLIBCXX_USE_DUAL_ABI and + LDBL_CXX11_ABI namespace macros. + * include/bits/locale_classes.h (locale::name()): Use abi_tag when + new ABI is in use. + (locale::_S_twinned_facets): New static member. + (locale::facet::__shim): Declare new type. + (locale::_facet::_M_sso_shim, locale::_facet::_M_cow_shim): New + functions for creating shims. + (locale::_Impl::_M_facet_unchecked): New member function for use + during construction. + (locale::_Impl::_M_init_extra): New member functions to create second + version of some facets. + (collate, collate_byname): Use abi_tag when new ABI is in use. + * include/bits/locale_facets.h: Add _GLIBCXX_NUM_CXX11_FACETS macro. + (numpunct, numpunct_byname): Use __cxx11 namespace. + (num_get::_M_extract_float, num_get::_M_extract_int): Use abi_tag + when new ABI is in use. + (num_get::__do_get, num_put::__do_put): Do not declare long double + compat functions for new ABI. + * include/bits/locale_facets.tcc (num_get, num_put): Use abi_tag on + definitions. + (numpunct, numpunct_byname): Qualify explicit instantiations. + * include/bits/locale_facets_nonio.h (time_get, time_get_byname, + moneypunct, moneypunct_byname, money_get, money_put, messages, + messages_byname): Use new inline namespace macros. + (money_get::__do_get, money_put::__do_put): Do not declare long + double compat functions for new ABI. + * include/bits/locale_facets_nonio.tcc (money_get, money_put): Use + new namespace macros. + (money_get::__do_get, money_put::__do_put): Do not define for new ABI. + * include/bits/localefwd.h (numpunct, numpunct_byname, collate, + collate_byname, time_get, time_get_byname, moneypunct, + moneypunct_byname, money_get, money_put, messages, messages_byname): + Use new namespace macros. + * include/bits/regex.h: Use inline namespace macros. + * include/bits/stl_list.h (_List_base, list): Use inline namespace + instead of abi-tag. + * include/bits/stringfwd.h (basic_string): Use namespace macros. + * include/std/iosfwd (basic_stringbuf, basic_istringstream, + basic_ostringstream, basic_stringstream): Likewise. + * include/std/sstream: Likewise. + (basic_stringbuf::__xfer_bufptrs): Update streambuf pointers on move. + * include/std/stdexcept (__cow_string, __sso_string): New types for + indirectly using std::string with either ABI. + (logic_error, runtime_error): Replace std::string member with + __cow_string when new ABI is in use. Declare non-inline copy + constructor and assignment operator. Declare const char* constructors. + (domain_error, invalid_argument, length_error, out_of_range, + range_error, overflow_error, underflow_error): Declare const char* + constructors. + * include/std/system_error (error_category): Replace with new + definition in inline namespace _V2. + (error_code::message, error_condition::message): Use abi_tag on + functions returning std::string. + * python/libstdcxx/v6/printers.py (StdStringPrinter): Handle new ABI. + * src/c++11/Makefile.am: Add new files. + * src/c++11/Makefile.in: Regenerate. + * src/c++11/compatibility-c++0x.cc: Compile with old std::string ABI. + Define old error_category symbols. + * src/c++11/cow-fstream-inst.cc: New. Instantiate fstream members + using old std::string ABI. + * src/c++11/cow-locale_init.cc (locale::_Impl::_M_init_extra): Define. + * src/c++11/cow-shim_facets.cc: Define shim facets using old ABI. + * src/c++11/cow-sstream-inst.cc: Instantiate stringstreams using old + std::string ABI. + * src/c++11/cow-stdexcept.cc: Define new constructors and assignment + operators. + (__cow_string, error_category::_M_message): Define. + * src/c++11/cow-string-inst.cc: Explicit instantiations using old + std::string. Include src/c++98/istream-string.cc. + * src/c++11/cow-wstring-inst.cc: Explicit instantiations using old + std::wstring. + * src/c++11/cxx11-hash_tr1.cc: Explicit instantiations using new + string. + * src/c++11/cxx11-ios_failure.cc: Add sanity check. + * src/c++11/cxx11-locale-inst.cc: Instantiate facets using new + std::string. + * src/c++11/cxx11-shim_facets.cc: Define shim facets using new ABI. + * src/c++11/cxx11-stdexcept.cc: Define constructors taking new + std::string. + * src/c++11/cxx11-wlocale-inst.cc: Instantiate facets using + new std::wstring. + * src/c++11/fstream-inst.cc: Compile with new ABI. + * src/c++11/functexcept.cc: Compile with old ABI. + * src/c++11/random.cc: Compile with new ABI. + * src/c++11/sstream-inst.cc: Compile with new ABI. + * src/c++11/string-inst.cc: Explicit instantiations for new string. + * src/c++11/system_error.cc (__sso_string, error_category::_M_message): + Define. + * src/c++11/wstring-inst.cc: Compile with new ABI. + * src/c++98/Makefile.am: Compile some host files twice for old and + new std::string. Add new files. + * src/c++98/Makefile.in: Regenerate. + * src/c++98/compatibility-ldbl.cc: Compile with old ABI. + * src/c++98/compatibility.cc: Likewise. + * src/c++98/concept-inst.cc: Likewise. + * src/c++98/hash_tr1.cc: Likewise. + * src/c++98/istream-string.cc: New file defining functions that + work with istream and std::string moved from ... + * src/c++98/istream.cc: ... here. + * src/c++98/cow-istream-string.cc: Recompile istream-string.cc with + old ABI. + * src/c++98/locale-inst.cc: Adjust facet instantiations to work for + either ABI. + * src/c++98/locale.cc (locale::_M_install_facet, + locale::_M_install_cache): Handle twinned facets. + * src/c++98/locale-facets.cc: Compile with old std::string ABI. + (__verify_grouping): Define new overload and old std::string version. + * src/c++98/locale_init.cc: Initialize twinned facets. + * src/c++98/localename.cc: Likewise. + * src/c++98/misc-inst.cc: Instantiate C++98-only std::string members. + (__verify_grouping): Define new std::string version. + * src/c++98/stdexcept.cc: Compile with old std::string ABI. + * src/c++98/wlocale-inst.cc: Likewise. + * testsuite/18_support/50594.cc: Adjust to work with SSO strings. + * testsuite/21_strings/basic_string/capacity/1.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/char/1.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/char/18654.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/char/2.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/wchar_t/1.cc: Likewise. + * testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc: + Likewise. + * testsuite/21_strings/headers/string/synopsis.cc: Use inline + namespace macros. + * testsuite/23_containers/headers/list/synopsis.cc: Likewise. + * testsuite/27_io/basic_ios/copyfmt/char/1.cc: Set dg-options so + correct exception type can be caught. + * testsuite/27_io/basic_ios/exceptions/char/1.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_arithmetic/char/ + exceptions_failbit.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/ + exceptions_failbit.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_other/char/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_istream/extractors_other/wchar_t/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_istream/sentry/char/12297.cc: Likewise. + * testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc: Likewise. + * testsuite/27_io/basic_ostream/inserters_other/char/ + exceptions_null.cc: Likewise. + * testsuite/27_io/basic_ostream/inserters_other/wchar_t/ + exceptions_null.cc: Likewise. + * testsuite/27_io/ios_base/storage/2.cc: Likewise. + * testsuite/27_io/ios_base/failure/cxx11.cc: Disable for old ABI. + * testsuite/ext/profile/mutex_extensions_neg.cc: Adjust dg-error. + * testsuite/libstdc++-prettyprinters/libfundts.cc: Use old ABI. + * testsuite/libstdc++-prettyprinters/simple.cc: Likewise. + * testsuite/libstdc++-prettyprinters/simple11.cc: Likewise. + * testsuite/libstdc++-prettyprinters/whatis.cc: Likewise. + * testsuite/util/exception/safety.h: Adjust member function types + for new std::string. + * testsuite/util/testsuite_abi.cc: Add new version and ignore + __float128 symbols in __cxx11 namespace. + 2014-12-17 Tim Shen PR libstdc++/64302 diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in index bede542535d..961d840f45f 100644 --- a/libstdc++-v3/Makefile.in +++ b/libstdc++-v3/Makefile.in @@ -244,6 +244,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 0229609df2c..db357d6d731 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3832,24 +3832,57 @@ AC_DEFUN([GLIBCXX_CHECK_SDT_H], [ ]) dnl -dnl Check if the user wants the new C++11-conforming ABI. +dnl Control whether the library should define symbols for old and new ABIs. +dnl This affects definitions of strings, stringstreams and locale facets. dnl -dnl --disable-libstdcxx-cxx11-abi will use old ABI for all types. +dnl --disable-libstdcxx-dual-abi will use old ABI for all types. dnl dnl Defines: -dnl _GLIBCXX_USE_ABI_TAG (always defined, either to 1 or 0) +dnl _GLIBCXX_USE_DUAL_ABI (always defined, either to 1 or 0) dnl -AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI], [ - AC_ARG_ENABLE([libstdcxx-cxx11-abi], - AC_HELP_STRING([--disable-libstdcxx-cxx11-abi], - [disable the C++11-conforming ABI]),, - [enable_libstdcxx_cxx11_abi=yes]) - if test x"$enable_libstdcxx_cxx11_abi" != xyes; then - AC_MSG_NOTICE([C++11-conforming ABI is disabled]) +AC_DEFUN([GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI], [ + GLIBCXX_ENABLE(libstdcxx-dual-abi,$1,,[support two versions of std::string]) + if test x"$enable_libstdcxx_dual_abi" != xyes; then + AC_MSG_NOTICE([dual ABI is disabled]) + default_libstdcxx_abi="c++98" fi - GLIBCXX_CONDITIONAL(ENABLE_CXX11_ABI, test $enable_libstdcxx_cxx11_abi = yes) + GLIBCXX_CONDITIONAL(ENABLE_DUAL_ABI, test $enable_libstdcxx_dual_abi = yes) ]) +dnl +dnl Check to see which ABI should be enabled by default. +dnl +dnl --with-default-libstdcxx-abi={c++98,c++11} +dnl +dnl Defines: +dnl _GLIBCXX_USE_CXX11_ABI (always defined, either to 1 or 0) +dnl +AC_DEFUN([GLIBCXX_DEFAULT_ABI], [ + if test x$enable_libstdcxx_dual_abi = xyes; then + AC_MSG_CHECKING([for default std::string ABI to use]) + AC_ARG_WITH([default-libstdcxx-abi], + AS_HELP_STRING([--with-default-libstdcxx-abi], + [set the std::string ABI to use by default]), + [case "$withval" in + c++98|gnu++98|c++03|gnu++03) default_libstdcxx_abi="c++98" ;; + c++1?|gnu++1?) default_libstdcxx_abi="c++11" ;; + *) AC_MSG_ERROR([Invalid argument for --with-default-libstdcxx-abi]) ;; + esac], + [default_libstdcxx_abi="c++11"]) + AC_MSG_RESULT(${default_libstdcxx_abi}) + fi + if test $default_libstdcxx_abi = "c++11"; then + glibcxx_cxx11_abi=1 + glibcxx_cxx98_abi=0 + else + glibcxx_cxx11_abi=0 + glibcxx_cxx98_abi=1 + fi + AC_SUBST(glibcxx_cxx98_abi) + GLIBCXX_CONDITIONAL(ENABLE_CXX11_ABI, test $glibcxx_cxx11_abi = 1) +]) + + # Macros from the top-level gcc directory. m4_include([../config/gc++filt.m4]) m4_include([../config/tls.m4]) diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 5893f1b28cf..8ba8ed4dba9 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -73,7 +73,7 @@ GLIBCXX_3.4 { # std::[d-g]*; std::d[a-d]*; std::d[f-n]*; - std::domain_error::d*; +# std::domain_error::d*; # std::domain_error::~d*; std::d[p-z]*; std::e[a-q]*; @@ -82,7 +82,7 @@ GLIBCXX_3.4 { std::gslice*; std::h[^a]*; std::i[a-m]*; - std::invalid_argument::i*; +# std::invalid_argument::i*; # std::invalid_argument::~i*; # std::ios_base::[A-Ha-z]*; std::ios_base::[A-Ha-e]*; @@ -103,9 +103,8 @@ GLIBCXX_3.4 { std::istrstream*; std::i[t-z]*; std::[A-Zj-k]*; - std::length_error::l*; +# std::length_error::l*; # std::length_error::~l*; - std::logic_error*; std::locale::[A-Za-e]*; std::locale::facet::[A-Za-z]*; std::locale::facet::_S_get_c_locale*; @@ -115,13 +114,20 @@ GLIBCXX_3.4 { std::locale::[A-Zg-h]*; std::locale::id::[A-Za-z]*; std::locale::id::_M_id*; - std::locale::[A-Zj-z]*; + std::locale::[A-Zj-m]*; +# std::locale::name(); + std::locale::none*; + std::locale::numeric*; + std::locale::[A-Zn-z]*; std::locale::_[A-Ha-z]*; std::locale::_Impl::[A-Za-z]*; # std::locale::_Impl::_M_[A-Za-z]*; std::locale::_[J-Ra-z]*; std::locale::_S_normalize_category*; std::locale::_[T-Za-z]*; +# std::logic_error::l*; + std::logic_error::what*; +# std::logic_error::~l*; # std::[A-Zm-r]*; # std::[A-Zm]*; std::[A-Z]*; @@ -133,16 +139,19 @@ GLIBCXX_3.4 { std::nu[^m]*; std::num[^e]*; std::ostrstream*; - std::out_of_range::o*; +# std::out_of_range::o*; # std::out_of_range::~o*; - std::overflow_error::o*; +# std::overflow_error::o*; # std::overflow_error::~o*; # std::[p-q]*; - std::r[^ae]*; - std::range_error::r*; + std::r[^aeu]*; +# std::range_error::r*; # std::range_error::~r*; # std::re[^t]*; # std::rethrow_exception +# std::runtime_error::r* + std::runtime_error::what*; +# std::runtime_error::~r*; std::set_new_handler*; std::set_terminate*; std::set_unexpected*; @@ -158,7 +167,7 @@ GLIBCXX_3.4 { std::tr1::h[^a]*; std::t[s-z]*; # std::[A-Zu-z]*; - std::underflow_error::u*; +# std::underflow_error::u*; # std::underflow_error::~u*; std::uncaught_exception*; std::unexpected*; @@ -337,19 +346,19 @@ GLIBCXX_3.4 { _ZNSt19basic_istringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[RS]*; _ZNSt19basic_istringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED*; _ZNSt19basic_istringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3str*; - _ZNKSt19basic_istringstream*; + _ZNKSt19basic_istringstreamI*; # std::basic_ostringstream _ZNSt19basic_ostringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[RS]*; _ZNSt19basic_ostringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED*; _ZNSt19basic_ostringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3str*; - _ZNKSt19basic_ostringstream*; + _ZNKSt19basic_ostringstreamI*; # std::basic_stringstream _ZNSt18basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[RS]*; _ZNSt18basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EED*; _ZNSt18basic_stringstreamI[cw]St11char_traitsI[cw]ESaI[cw]EE3str*; - _ZNKSt18basic_stringstream*; + _ZNKSt18basic_stringstreamI*; # std::basic_iostream constructors (except move), destructors _ZNSdC[12]Ev; @@ -447,10 +456,10 @@ GLIBCXX_3.4 { _ZNSt13basic_istreamIwSt11char_traitsIwEErsE*[^g]; # std::istream operators and extractors - _ZSt7getlineI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istream*; + _ZSt7getlineI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RSbI*; _ZSt2wsI[cw]St11char_traitsI[cw]EE*; _ZStrsI[cw]St11char_traitsI[cw]EERSt13basic_istream*; - _ZStrsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istream*; + _ZStrsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RSbI*; _ZStrsISt11char_traitsI[cw]EERSt13basic_istream*; _ZStrsId[cw]St11char_traitsI[cw]EERSt13basic_istream*; _ZStrsIe[cw]St11char_traitsI[cw]EERSt13basic_istream*; @@ -484,7 +493,7 @@ GLIBCXX_3.4 { _ZSt4end[ls]I[cw]St11char_traitsI[cw]EERSt13basic_ostream*; _ZSt5flushI[cw]St11char_traitsI[cw]EERSt13basic_ostream*; _ZStlsI[cw]St11char_traitsI[cw]EERSt13basic_ostream*; - _ZStlsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_ostream*; + _ZStlsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_ostreamIT_T0_ES7_RKSbI*; _ZStlsISt11char_traitsI[cw]EERSt13basic_ostream*; _ZStlsId[cw]St11char_traitsI[cw]EERSt13basic_ostream*; _ZStlsIe[cw]St11char_traitsI[cw]EERSt13basic_ostream*; @@ -493,6 +502,9 @@ GLIBCXX_3.4 { # std::locale destructors _ZNSt6localeD*; + # std::locale::name() returning old std::string + _ZNKSt6locale4nameEv; + # std::locale::facet destructors _ZNSt6locale5facetD*; @@ -529,16 +541,23 @@ GLIBCXX_3.4 { _ZNSt12ctype_bynameI[cw]*; # std::num_get - _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[2-9]*; + _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE14_M_extract_intI*; + _ZNKSt7num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE16_M_extract_floatI*; # std::num_put - _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[2-9]*; + _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE1[234]*; + _ZNKSt7num_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE15_M_insert_floatI*; # std::money_get - _ZNKSt9money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt9money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[2-9]*; + _ZNKSt9money_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE10_M_extractILb[01]EEES3_S3_S3_RSt8ios_baseRSt12_Ios_IostateRSs; # std::money_put - _ZNKSt9money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE*; + _ZNKSt9money_putI[cw]St19ostreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[1-8]*; + _ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE9_M_insertILb[01]EEES3_S3_RSt8ios_basecRKSs; + _ZNKSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb[01]EEES3_S3_RSt8ios_basewRKSbIwS2_SaIwEE; # std::time_get _ZNSt8time_get*; @@ -679,7 +698,13 @@ GLIBCXX_3.4 { _ZTVSt[0-9][0-9]a*; _ZTVSt10bad_typeid; _ZTVSt13bad_exception; - _ZTVSt[0-9][0-9]basic*; +# _ZTVSt[0-9][0-9]basic*; + _ZTVSt1[34]basic*; + _ZTVSt15basic_streambufI*; + _ZTVSt15basic_stringbufI*; + _ZTVSt18basic_stringstreamI*; + _ZTVSt19basic_istringstreamI*; + _ZTVSt19basic_ostringstreamI*; _ZTVSt[0-9][0-9][c-d]*; _ZTVSt[0-9][0-9][g-k]*; _ZTVSt11logic_error; @@ -701,7 +726,17 @@ GLIBCXX_3.4 { # VTT structure _ZTTS[a-z]; _ZTTSt[0-9][A-Za-z]*; - _ZTTSt[0-9][0-9][A-Za-z]*; +# _ZTTSt[0-9][0-9][A-Za-z]*; + _ZTTSt1[0-4]*; + _ZTTSt15a*; + _ZTTSt15basic_streambufI*; + _ZTTSt15basic_stringbufI*; + _ZTTSt15[c-z]*; + _ZTTSt1[67]*; + _ZTTSt18basic_stringstreamI*; + _ZTTSt19basic_istringstreamI*; + _ZTTSt19basic_ostringstreamI*; + _ZTTSt[2-9]*; # typeinfo structure _ZTIS[a-z]; @@ -712,7 +747,13 @@ GLIBCXX_3.4 { _ZTISt[0-9][0-9]a*; _ZTISt10bad_typeid; _ZTISt13bad_exception; - _ZTISt[0-9][0-9]basic*; +# _ZTISt[0-9][0-9]basic*; + _ZTISt1[34]basic*; + _ZTISt15basic_streambufI*; + _ZTISt15basic_stringbufI*; + _ZTISt18basic_stringstreamI*; + _ZTISt19basic_istringstreamI*; + _ZTISt19basic_ostringstreamI*; _ZTISt[0-9][0-9][c-d]*; _ZTISt[0-9][0-9][g-k]*; _ZTISt11logic_error; @@ -749,7 +790,13 @@ GLIBCXX_3.4 { _ZTSSt[0-9][0-9]a*; _ZTSSt10bad_typeid; _ZTSSt13bad_exception; - _ZTSSt[0-9][0-9]basic*; +# _ZTSSt[0-9][0-9]basic*; + _ZTSSt1[34]basic*; + _ZTSSt15basic_stringbufI*; + _ZTSSt15basic_streambufI*; + _ZTSSt18basic_stringstreamI*; + _ZTSSt19basic_istringstreamI*; + _ZTSSt19basic_ostringstreamI*; _ZTSSt[0-9][0-9][c-d]*; _ZTSSt[0-9][0-9][g-k]*; _ZTSSt11logic_error; @@ -779,8 +826,33 @@ GLIBCXX_3.4 { _ZNSt13bad_exceptionD*; # function-scope static objects requires a guard variable. - _ZGVNSt[^1]*; - _ZGVNSt1[^7]*; + _ZGVNSt[2-6]*; + _ZGVNSt7collateI[cw]*; + _ZGVNSt7num_getI[cw]*; + _ZGVNSt7num_putI[cw]*; + _ZGVNSt8messagesI[cw]*; + _ZGVNSt8numpunctI[cw]*; + _ZGVNSt8time_getI[cw]*; + _ZGVNSt8time_putI[cw]*; + _ZGVNSt9money_getI[cw]*; + _ZGVNSt9money_putI[cw]*; + _ZGVNSt1[^07]*; + _ZGVNSt10moneypunctI[cw]Lb[01]*; + + # exception constructors taking std::string + _ZNSt11logic_errorC[12]ERKSs; + _ZNSt13runtime_errorC[12]ERKSs; + _ZNSt11range_errorC[12]ERKSs; + _ZNSt12domain_errorC[12]ERKSs; + _ZNSt12length_errorC[12]ERKSs; + _ZNSt12out_of_rangeC[12]ERKSs; + _ZNSt14overflow_errorC[12]ERKSs; + _ZNSt15underflow_errorC[12]ERKSs; + _ZNSt16invalid_argumentC[12]ERKSs; + + # complete, deleting and base destructors + _ZNSt11logic_errorD[012]Ev; + _ZNSt13runtime_errorD[012]Ev; # complete and deleting destructors where base destructors should not # be exported. @@ -793,10 +865,42 @@ GLIBCXX_3.4 { _ZNSt16invalid_argumentD[01]Ev; # virtual function thunks - _ZThn8_NS*; - _ZThn16_NS*; - _ZTv0_n12_NS*; - _ZTv0_n24_NS*; +# _ZThn8_NS*; + _ZThn8_NS[dio]*; + _ZThn8_NSt1[0-9]a*; + _ZThn8_NSt1[34]basic*; + _ZThn8_NSt18basic_stringstreamI*; + _ZThn8_NSt19basic_[io]stringstreamI*; + _ZThn8_NSt1[0-9][c-z]*; + _ZThn8_NSt[2-9][a-z0-9]*; +# _ZThn16_NS*; + _ZThn16_NS[dio]*; + _ZThn16_NSt1[0-9]a*; + _ZThn16_NSt1[34]basic*; + _ZThn16_NSt18basic_stringstreamI*; + _ZThn16_NSt19basic_[io]stringstreamI*; + _ZThn16_NSt1[0-9][c-z]*; + _ZThn16_NSt[2-9][a-z0-9]*; +# _ZTv0_n12_NS*; + _ZTv0_n12_NS[dio]*; + _ZTv0_n12_NSt1[0-9]a*; + _ZTv0_n12_NSt1[34]basic*; + _ZTv0_n12_NSt15basic_streambufI*; + _ZTv0_n12_NSt15basic_stringbufI*; + _ZTv0_n12_NSt18basic_stringstreamI*; + _ZTv0_n12_NSt19basic_[io]stringstreamI*; + _ZTv0_n12_NSt1[0-9][c-z]*; + _ZTv0_n12_NSt[2-9][a-z0-9]*; +# _ZTv0_n24_NS*; + _ZTv0_n24_NS[dio]*; + _ZTv0_n24_NSt1[0-9]a*; + _ZTv0_n24_NSt1[34]basic*; + _ZTv0_n24_NSt15basic_streambufI*; + _ZTv0_n24_NSt15basic_stringbufI*; + _ZTv0_n24_NSt18basic_stringstreamI*; + _ZTv0_n24_NSt19basic_[io]stringstreamI*; + _ZTv0_n24_NSt1[0-9][c-z]*; + _ZTv0_n24_NSt[2-9][a-z0-9]*; # stub functions from libmath sinf; @@ -1034,7 +1138,7 @@ GLIBCXX_3.4.10 { _ZNKSt4hashISsEclESs; _ZNKSt4hashIeEclEe; - _ZSt17__verify_grouping*; + _ZSt17__verify_groupingPKc[mj]RKSs; _ZNSt8__detail12__prime_listE; _ZNSt3tr18__detail12__prime_listE; @@ -1390,10 +1494,15 @@ GLIBCXX_3.4.18 { # Names inside the 'extern' block are demangled names. extern "C++" { - std::random_device::*; std::__detail::_Prime_rehash_policy::*; }; + _ZNSt13random_device14_M_init_pretr1ERKSs; + _ZNSt13random_device16_M_getval_pretr1Ev; + _ZNSt13random_device7_M_finiEv; + _ZNSt13random_device7_M_initERKSs; + _ZNSt13random_device9_M_getvalEv; + # std::this_thread::__sleep_for _ZNSt11this_thread11__sleep_for*; @@ -1487,7 +1596,7 @@ GLIBCXX_3.4.21 { _ZNKSt8ios_base7failureB5cxx114whatEv; _ZNSt8ios_base7failureB5cxx11C[12]ERKSs; _ZNSt8ios_base7failureB5cxx11C[12]EPKcRKSt10error_code; - _ZNSt8ios_base7failureB5cxx11C[12]ERKSsB5cxx11; + _ZNSt8ios_base7failureB5cxx11C[12]ERKNSt7__cxx1112basic_string*; _ZNSt8ios_base7failureB5cxx11C[12]ERKSsB5cxx11RKSt10error_code; _ZNSt8ios_base7failureB5cxx11D[012]Ev; _ZTINSt8ios_base7failureB5cxx11E; @@ -1506,6 +1615,139 @@ GLIBCXX_3.4.21 { # std::__future_base::_State_baseV2::_Make_ready::_M_set() _ZNSt13__future_base13_State_baseV211_Make_ready6_M_setEv; + # ABI-tagged std::basic_string + _ZNSt7__cxx1112basic_string*; + _ZNKSt7__cxx1112basic_string*; + + # ABI-tagged stringstreams + _ZNSt7__cxx1115basic_stringbuf*; + _ZNSt7__cxx1118basic_stringstream*; + _ZNSt7__cxx1119basic_istringstream*; + _ZNSt7__cxx1119basic_ostringstream*; + _ZNKSt7__cxx1115basic_stringbuf*; + _ZNKSt7__cxx1118basic_stringstream*; + _ZNKSt7__cxx1119basic_istringstream*; + _ZNKSt7__cxx1119basic_ostringstream*; + _ZT[ISTV]NSt7__cxx1115basic_stringbuf*; + _ZT[ISTV]NSt7__cxx1118basic_stringstream*; + _ZT[ISTV]NSt7__cxx1119basic_istringstream*; + _ZT[ISTV]NSt7__cxx1119basic_ostringstream*; + _ZThn8_NSt7__cxx1118basic_stringstream*; + _ZThn16_NSt7__cxx1118basic_stringstream*; + _ZTv0_n12_NSt7__cxx1115basic_stringbuf*; + _ZTv0_n12_NSt7__cxx1118basic_stringstream*; + _ZTv0_n12_NSt7__cxx1119basic_istringstream*; + _ZTv0_n12_NSt7__cxx1119basic_ostringstream*; + _ZTv0_n24_NSt7__cxx1115basic_stringbuf*; + _ZTv0_n24_NSt7__cxx1118basic_stringstream*; + _ZTv0_n24_NSt7__cxx1119basic_istringstream*; + _ZTv0_n24_NSt7__cxx1119basic_ostringstream*; + + # I/O functions for ABI-tagged basic_string + _ZSt7getlineI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_string*; + _ZStlsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_string*; + _ZStrsI[cw]St11char_traitsI[cw]ESaI[cw]EERSt13basic_istreamIT_T0_ES7_RNSt7__cxx1112basic_string*; + + # std::locale::name() returning new std::string + _ZNKSt6locale4nameB5cxx11Ev; + + # ABI-tagged locale facets + _ZT[ISTV]NSt7__cxx117collateI[cw]*; + _ZT[ISTV]NSt7__cxx1114collate_bynameI[cw]*; + _ZT[ISTV]NSt7__cxx118messagesI[cw]*; + _ZT[ISTV]NSt7__cxx1115messages_bynameI[cw]*; + _ZT[ISTV]NSt7__cxx119money_getI[cw]*; + _ZT[ISTV]NSt7__cxx119money_putI[cw]*; + _ZT[ISTV]NSt7__cxx1110moneypunctI[cw]Lb[01]*; + _ZT[ISTV]NSt7__cxx1117moneypunct_bynameI[cw]Lb[01]*; + _ZT[ISTV]NSt7__cxx118numpunctI[cw]*; + _ZT[ISTV]NSt7__cxx1115numpunct_bynameI[cw]*; + _ZT[ISTV]NSt7__cxx118time_getI[cw]*; + _ZT[ISTV]NSt7__cxx1115time_get_bynameI[cw]*; + + # guard vars for new facet::id globals + _ZGVNSt7__cxx117collateI[cw]*; + _ZGVNSt7__cxx118messagesI[cw]*; + _ZGVNSt7__cxx1110moneypunctI[cw]Lb[01]*; + _ZGVNSt7__cxx119money_getI[cw]*; + _ZGVNSt7__cxx119money_putI[cw]*; + _ZGVNSt7__cxx118numpunctI[cw]*; + _ZGVNSt7__cxx118time_getI[cw]*; + + _ZNSt7__cxx117collateI*; + _ZNSt7__cxx1114collate_bynameI*; + _ZNSt7__cxx118messagesI*; + _ZNSt7__cxx1115messages_bynameI*; + _ZNSt7__cxx119money_getI*; + _ZNSt7__cxx119money_putI*; + _ZNSt7__cxx1110moneypunctI*; + _ZNSt7__cxx1117moneypunct_bynameI*; + _ZNSt7__cxx118numpunctI*; + _ZNSt7__cxx1115numpunct_bynameI*; + _ZNSt7__cxx118time_getI*; + _ZNSt7__cxx1115time_get_bynameI*; + + _ZNKSt7__cxx117collateI*; + _ZNKSt7__cxx118messagesI*; + _ZNKSt7__cxx119money_getI*; + _ZNKSt7__cxx119money_putI*; + _ZNKSt7__cxx1110moneypunctI*; + _ZNKSt7__cxx118numpunctI*; + _ZNKSt7__cxx118time_getI*; + + _ZSt9has_facetINSt7__cxx117collate*; + _ZSt9has_facetINSt7__cxx118messages*; + _ZSt9has_facetINSt7__cxx119money_get*; + _ZSt9has_facetINSt7__cxx119money_put*; + _ZSt9has_facetINSt7__cxx1110moneypunct*; + _ZSt9has_facetINSt7__cxx118numpunct*; + _ZSt9has_facetINSt7__cxx118time_get*; + _ZSt9use_facetINSt7__cxx117collate*; + _ZSt9use_facetINSt7__cxx118messages*; + _ZSt9use_facetINSt7__cxx119money_get*; + _ZSt9use_facetINSt7__cxx119money_put*; + _ZSt9use_facetINSt7__cxx1110moneypunct*; + _ZSt9use_facetINSt7__cxx118numpunct*; + _ZSt9use_facetINSt7__cxx118time_get*; + + _ZSt17__verify_groupingPKc[mj]RKNSt7__cxx1112basic_string*; + + _ZNSt3_V214error_category*; + _ZNKSt3_V214error_category*; + _ZTVNSt3_V214error_categoryE; + _ZTINSt3_V214error_categoryE; + _ZNSt3_V215system_categoryEv; + _ZNSt3_V216generic_categoryEv; + + # New exception constructors + _ZNSt11logic_errorC[12]EPKc; + _ZNSt11logic_errorC[12]ERKS_; + _ZNSt11logic_erroraSERKS_; + _ZNSt11logic_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt11range_errorC[12]EPKc; + _ZNSt11range_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt12domain_errorC[12]EPKc; + _ZNSt12domain_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt12length_errorC[12]EPKc; + _ZNSt12length_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt12out_of_rangeC[12]EPKc; + _ZNSt12out_of_rangeC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt13runtime_errorC[12]EPKc; + _ZNSt13runtime_errorC[12]ERKS_; + _ZNSt13runtime_erroraSERKS_; + _ZNSt13runtime_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt14overflow_errorC[12]EPKc; + _ZNSt14overflow_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt15underflow_errorC[12]EPKc; + _ZNSt15underflow_errorC[12]ERKNSt7__cxx1112basic_string*; + _ZNSt16invalid_argumentC[12]EPKc; + _ZNSt16invalid_argumentC[12]ERKNSt7__cxx1112basic_string*; + + _ZNSt13random_device14_M_init_pretr1ERKNSt7__cxx1112basic_string*; + _ZNSt13random_device7_M_initERKNSt7__cxx1112basic_string*; + + _ZNKSt3tr14hashINSt7__cxx1112basic_string*; + } GLIBCXX_3.4.20; diff --git a/libstdc++-v3/config/locale/generic/monetary_members.cc b/libstdc++-v3/config/locale/generic/monetary_members.cc index b4f27a46103..20eabe1013a 100644 --- a/libstdc++-v3/config/locale/generic/monetary_members.cc +++ b/libstdc++-v3/config/locale/generic/monetary_members.cc @@ -34,11 +34,16 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +// This file might be compiled twice, but we only want to define the members +// of money_base once. +#if ! _GLIBCXX_USE_CXX11_ABI + // Construct and return valid pattern consisting of some combination of: // space none symbol sign value money_base::pattern money_base::_S_construct_pattern(char, char, char) throw() { return _S_default_pattern; } +#endif template<> void diff --git a/libstdc++-v3/config/locale/gnu/monetary_members.cc b/libstdc++-v3/config/locale/gnu/monetary_members.cc index 25cdfd0b6ca..820ced2c9f8 100644 --- a/libstdc++-v3/config/locale/gnu/monetary_members.cc +++ b/libstdc++-v3/config/locale/gnu/monetary_members.cc @@ -35,6 +35,10 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +// This file might be compiled twice, but we only want to define the members +// of money_base once. +#if ! _GLIBCXX_USE_CXX11_ABI + // Construct and return valid pattern consisting of some combination of: // space none symbol sign value money_base::pattern @@ -201,6 +205,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } return __ret; } +#endif template<> void diff --git a/libstdc++-v3/config/locale/gnu/numeric_members.cc b/libstdc++-v3/config/locale/gnu/numeric_members.cc index 8af7cf68eee..69ac176ff42 100644 --- a/libstdc++-v3/config/locale/gnu/numeric_members.cc +++ b/libstdc++-v3/config/locale/gnu/numeric_members.cc @@ -117,6 +117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (_M_data->_M_grouping_size) delete [] _M_data->_M_grouping; + _M_data->_M_grouping = 0; delete _M_data; } @@ -209,6 +210,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (_M_data->_M_grouping_size) delete [] _M_data->_M_grouping; + _M_data->_M_grouping = 0; delete _M_data; } #endif diff --git a/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver b/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver index 3dd0336306c..5ef4a6cb6e1 100644 --- a/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver +++ b/libstdc++-v3/config/os/gnu-linux/ldbl-extra.ver @@ -9,7 +9,17 @@ GLIBCXX_LDBL_3.4 { _ZSt14__convert_to_vIgEvPKcRT_RSt12_Ios_IostateRKP*; _ZStlsIg[cw]St11char_traitsI[cw]EERSt13basic_ostreamIT0_T1_ES6_RKSt7complexIT_E; _ZStrsIg[cw]St11char_traitsI[cw]EERSt13basic_istreamIT0_T1_ES6_RSt7complexIT_E; - *__gnu_cxx_ldbl128*; + *__gnu_cxx_ldbl128[1-6]*; + *St9has_facetINSt17__gnu_cxx_ldbl1287*; + *St9use_facetINSt17__gnu_cxx_ldbl1287*; + *__gnu_cxx_ldbl1287num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE[CD][0-2]E?; + *__gnu_cxx_ldbl1287num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE2idE; + *__gnu_cxx_ldbl1287num_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEEE; + *__gnu_cxx_ldbl1287num_getI[cw]*getE*; + *__gnu_cxx_ldbl1287num_getI[cw]*14_M_extract_intI*; + *__gnu_cxx_ldbl1287num_getI[cw]*16_M_extract_floatE*; + *__gnu_cxx_ldbl1287num_putI[cw]*; + *__gnu_cxx_ldbl128[8-9]*; }; # Corresponding to exports in GLIBCXX_3.4.9, not GLIBCXX_3.4.7 @@ -25,6 +35,11 @@ GLIBCXX_LDBL_3.4.10 { _ZNKSt4hashIgEclEg; } GLIBCXX_LDBL_3.4.7; +GLIBCXX_LDBL_3.4.21 { + __gnu_cxx_ldbl1287num_getI[cw]*14_M_extract_intB5cxx11*; + __gnu_cxx_ldbl1287num_getI[cw]*16_M_extract_floatB5cxx11*; +} GLIBCXX_LDBL_3.4.10; + CXXABI_LDBL_1.3 { _ZT[IS]g; _ZT[IS]Pg; diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 3f8ecf15622..be9337fcec0 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -645,6 +645,9 @@ GLIBCXX_LDBL_COMPAT_FALSE GLIBCXX_LDBL_COMPAT_TRUE ENABLE_CXX11_ABI_FALSE ENABLE_CXX11_ABI_TRUE +glibcxx_cxx98_abi +ENABLE_DUAL_ABI_FALSE +ENABLE_DUAL_ABI_TRUE ENABLE_VISIBILITY_FALSE ENABLE_VISIBILITY_TRUE libtool_VERSION @@ -882,7 +885,8 @@ with_system_libunwind enable_linux_futex enable_symvers enable_libstdcxx_visibility -enable_libstdcxx_cxx11_abi +enable_libstdcxx_dual_abi +with_default_libstdcxx_abi enable_libstdcxx_threads with_gxx_include_dir enable_version_specific_runtime_libs @@ -1578,8 +1582,8 @@ Optional Features: [default=yes] --enable-libstdcxx-visibility enables visibility safe usage [default=yes] - --disable-libstdcxx-cxx11-abi - disable the C++11-conforming ABI + --enable-libstdcxx-dual-abi + support two versions of std::string [default=yes] --enable-libstdcxx-threads enable C++11 threads support [default=auto] --enable-version-specific-runtime-libs @@ -1602,6 +1606,8 @@ Optional Packages: --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-system-libunwind use installed libunwind + --with-default-libstdcxx-abi + set the std::string ABI to use by default --with-gxx-include-dir=DIR installation directory for include files @@ -11531,7 +11537,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11534 "configure" +#line 11540 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11637,7 +11643,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11640 "configure" +#line 11646 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15057,7 +15063,7 @@ fi # # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style. cat > conftest.$ac_ext << EOF -#line 15060 "configure" +#line 15066 "configure" struct S { ~S(); }; void bar(); void foo() @@ -15409,7 +15415,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 15412 "configure" +#line 15418 "configure" int main() { typedef bool atomic_type; @@ -15444,7 +15450,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15447 "configure" +#line 15453 "configure" int main() { typedef short atomic_type; @@ -15479,7 +15485,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15482 "configure" +#line 15488 "configure" int main() { // NB: _Atomic_word not necessarily int. @@ -15515,7 +15521,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15518 "configure" +#line 15524 "configure" int main() { typedef long long atomic_type; @@ -15594,7 +15600,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15597 "configure" +#line 15603 "configure" int main() { _Decimal32 d1; @@ -15636,7 +15642,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15639 "configure" +#line 15645 "configure" template struct same { typedef T2 type; }; @@ -15670,7 +15676,7 @@ $as_echo "$enable_int128" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15673 "configure" +#line 15679 "configure" template struct same { typedef T2 type; }; @@ -78166,20 +78172,56 @@ $as_echo "$as_me: visibility supported: $enable_libstdcxx_visibility" >&6;} - # Check whether --enable-libstdcxx-cxx11-abi was given. -if test "${enable_libstdcxx_cxx11_abi+set}" = set; then : - enableval=$enable_libstdcxx_cxx11_abi; + # Check whether --enable-libstdcxx-dual-abi was given. +if test "${enable_libstdcxx_dual_abi+set}" = set; then : + enableval=$enable_libstdcxx_dual_abi; + case "$enableval" in + yes|no) ;; + *) as_fn_error "Argument to enable/disable libstdcxx-dual-abi must be yes or no" "$LINENO" 5 ;; + esac + else - enable_libstdcxx_cxx11_abi=yes + enable_libstdcxx_dual_abi=yes fi - if test x"$enable_libstdcxx_cxx11_abi" != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: C++11-conforming ABI is disabled" >&5 -$as_echo "$as_me: C++11-conforming ABI is disabled" >&6;} + + if test x"$enable_libstdcxx_dual_abi" != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: dual ABI is disabled" >&5 +$as_echo "$as_me: dual ABI is disabled" >&6;} + default_libstdcxx_abi="c++98" fi + if test x$enable_libstdcxx_dual_abi = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for default std::string ABI to use" >&5 +$as_echo_n "checking for default std::string ABI to use... " >&6; } + +# Check whether --with-default-libstdcxx-abi was given. +if test "${with_default_libstdcxx_abi+set}" = set; then : + withval=$with_default_libstdcxx_abi; case "$withval" in + c++98|gnu++98|c++03|gnu++03) default_libstdcxx_abi="c++98" ;; + c++1?|gnu++1?) default_libstdcxx_abi="c++11" ;; + *) as_fn_error "Invalid argument for --with-default-libstdcxx-abi" "$LINENO" 5 ;; + esac +else + default_libstdcxx_abi="c++11" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${default_libstdcxx_abi}" >&5 +$as_echo "${default_libstdcxx_abi}" >&6; } + fi + if test $default_libstdcxx_abi = "c++11"; then + glibcxx_cxx11_abi=1 + glibcxx_cxx98_abi=0 + else + glibcxx_cxx11_abi=0 + glibcxx_cxx98_abi=1 + fi + + + + ac_ldbl_compat=no case "$target" in powerpc*-*-linux* | \ @@ -79332,7 +79374,16 @@ else fi - if test $enable_libstdcxx_cxx11_abi = yes; then + if test $enable_libstdcxx_dual_abi = yes; then + ENABLE_DUAL_ABI_TRUE= + ENABLE_DUAL_ABI_FALSE='#' +else + ENABLE_DUAL_ABI_TRUE='#' + ENABLE_DUAL_ABI_FALSE= +fi + + + if test $glibcxx_cxx11_abi = 1; then ENABLE_CXX11_ABI_TRUE= ENABLE_CXX11_ABI_FALSE='#' else @@ -79758,6 +79809,10 @@ if test -z "${ENABLE_VISIBILITY_TRUE}" && test -z "${ENABLE_VISIBILITY_FALSE}"; as_fn_error "conditional \"ENABLE_VISIBILITY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ENABLE_DUAL_ABI_TRUE}" && test -z "${ENABLE_DUAL_ABI_FALSE}"; then + as_fn_error "conditional \"ENABLE_DUAL_ABI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ENABLE_CXX11_ABI_TRUE}" && test -z "${ENABLE_CXX11_ABI_FALSE}"; then as_fn_error "conditional \"ENABLE_CXX11_ABI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 135d536e1b2..7a7c1d820fa 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -368,7 +368,8 @@ AC_SUBST(libtool_VERSION) GLIBCXX_ENABLE_LIBSTDCXX_VISIBILITY([yes]) -GLIBCXX_ENABLE_LIBSTDCXX_CXX11_ABI([yes]) +GLIBCXX_ENABLE_LIBSTDCXX_DUAL_ABI([yes]) +GLIBCXX_DEFAULT_ABI ac_ldbl_compat=no case "$target" in diff --git a/libstdc++-v3/doc/Makefile.in b/libstdc++-v3/doc/Makefile.in index 85f6e3f3031..d1f05007898 100644 --- a/libstdc++-v3/doc/Makefile.in +++ b/libstdc++-v3/doc/Makefile.in @@ -218,6 +218,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/doc/html/manual/configure.html b/libstdc++-v3/doc/html/manual/configure.html index e1ca43c9822..6453f08d2e7 100644 --- a/libstdc++-v3/doc/html/manual/configure.html +++ b/libstdc++-v3/doc/html/manual/configure.html @@ -227,6 +227,15 @@ facilities, which might be undesirable in a low-memory environment or when standard error is not available. This option disables those messages. This option does not change the library ABI. +

--disable-libstdcxx-dual-abi

+ Disable support for the new, C++11-conforming std::string + implementation. This option changes the library ABI. +

--with-default-libstdcxx-abi

+ By default, the new std::string implementation will be + declared and a macro must be defined to declare the old implementation + instead. That default can be reversed by configuring the library with + --with-default-libstdcxx-abi=c++98. + This option does not change the library ABI.

--enable-vtable-verify[default]

Use -fvtable-verify=std to compile the C++ runtime with instrumentation for vtable verification. All virtual functions in the standard library will be verified at runtime. diff --git a/libstdc++-v3/doc/html/manual/using_exceptions.html b/libstdc++-v3/doc/html/manual/using_exceptions.html index f1dd0996758..00e9d38f315 100644 --- a/libstdc++-v3/doc/html/manual/using_exceptions.html +++ b/libstdc++-v3/doc/html/manual/using_exceptions.html @@ -310,4 +310,4 @@ is called. GCC Bug 25191: exception_defines.h #defines try/catch - .

+ .

\ No newline at end of file diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml index 717cca713ee..a6e0c212cff 100644 --- a/libstdc++-v3/doc/xml/manual/configure.xml +++ b/libstdc++-v3/doc/xml/manual/configure.xml @@ -382,6 +382,25 @@ +--disable-libstdcxx-dual-abi + + + Disable support for the new, C++11-conforming std::string + implementation. This option changes the library ABI. + + + +--with-default-libstdcxx-abi + + + By default, the new std::string implementation will be + declared and a macro must be defined to declare the old implementation + instead. That default can be reversed by configuring the library with + --with-default-libstdcxx-abi=c++98. + This option does not change the library ABI. + + + --enable-vtable-verify[default] Use -fvtable-verify=std to compile the C++ diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index e6edc732779..2594d761d90 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -1129,6 +1129,14 @@ stamp-visibility: echo 0 > stamp-visibility endif +if ENABLE_DUAL_ABI +stamp-dual-abi: + echo 1 > stamp-dual-abi +else +stamp-dual-abi: + echo 0 > stamp-dual-abi +endif + if ENABLE_CXX11_ABI stamp-cxx11-abi: echo 1 > stamp-cxx11-abi @@ -1146,11 +1154,13 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ stamp-namespace-version \ stamp-visibility \ stamp-extern-template \ + stamp-dual-abi \ stamp-cxx11-abi @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\ ns_version=`cat stamp-namespace-version` ;\ visibility=`cat stamp-visibility` ;\ externtemplate=`cat stamp-extern-template` ;\ + dualabi=`cat stamp-dual-abi` ;\ cxx11abi=`cat stamp-cxx11-abi` ;\ ldbl_compat='s,g,g,' ;\ grep "^[ ]*#[ ]*define[ ][ ]*_GLIBCXX_LONG_DOUBLE_COMPAT[ ][ ]*1[ ]*$$" \ @@ -1160,6 +1170,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ -e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \ -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \ -e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \ + -e "s,define _GLIBCXX_USE_DUAL_ABI, define _GLIBCXX_USE_DUAL_ABI $$dualabi," \ -e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \ -e "$$ldbl_compat" \ < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 2ade448de98..3e5d82ec43b 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -216,6 +216,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ @@ -1539,6 +1540,11 @@ stamp-host: ${host_headers} ${bits_host_headers} ${ext_host_headers} ${host_head @ENABLE_VISIBILITY_FALSE@stamp-visibility: @ENABLE_VISIBILITY_FALSE@ echo 0 > stamp-visibility +@ENABLE_DUAL_ABI_TRUE@stamp-dual-abi: +@ENABLE_DUAL_ABI_TRUE@ echo 1 > stamp-dual-abi +@ENABLE_DUAL_ABI_FALSE@stamp-dual-abi: +@ENABLE_DUAL_ABI_FALSE@ echo 0 > stamp-dual-abi + @ENABLE_CXX11_ABI_TRUE@stamp-cxx11-abi: @ENABLE_CXX11_ABI_TRUE@ echo 1 > stamp-cxx11-abi @ENABLE_CXX11_ABI_FALSE@stamp-cxx11-abi: @@ -1553,11 +1559,13 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ stamp-namespace-version \ stamp-visibility \ stamp-extern-template \ + stamp-dual-abi \ stamp-cxx11-abi @date=`cat ${toplevel_srcdir}/gcc/DATESTAMP` ;\ ns_version=`cat stamp-namespace-version` ;\ visibility=`cat stamp-visibility` ;\ externtemplate=`cat stamp-extern-template` ;\ + dualabi=`cat stamp-dual-abi` ;\ cxx11abi=`cat stamp-cxx11-abi` ;\ ldbl_compat='s,g,g,' ;\ grep "^[ ]*#[ ]*define[ ][ ]*_GLIBCXX_LONG_DOUBLE_COMPAT[ ][ ]*1[ ]*$$" \ @@ -1567,6 +1575,7 @@ ${host_builddir}/c++config.h: ${CONFIG_HEADER} \ -e "s,define _GLIBCXX_INLINE_VERSION, define _GLIBCXX_INLINE_VERSION $$ns_version," \ -e "s,define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY, define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY $$visibility," \ -e "s,define _GLIBCXX_EXTERN_TEMPLATE$$, define _GLIBCXX_EXTERN_TEMPLATE $$externtemplate," \ + -e "s,define _GLIBCXX_USE_DUAL_ABI, define _GLIBCXX_USE_DUAL_ABI $$dualabi," \ -e "s,define _GLIBCXX_USE_CXX11_ABI, define _GLIBCXX_USE_CXX11_ABI $$cxx11abi," \ -e "$$ldbl_compat" \ < ${glibcxx_srcdir}/include/bits/c++config > $@ ;\ diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 89189656bcd..77293848b0b 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -37,6 +37,7 @@ #pragma GCC system_header #include +#include #include #if __cplusplus >= 201103L #include @@ -46,6 +47,2399 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if _GLIBCXX_USE_CXX11_ABI +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** + * @class basic_string basic_string.h + * @brief Managing sequences of characters and character-like objects. + * + * @ingroup strings + * @ingroup sequences + * + * @tparam _CharT Type of character + * @tparam _Traits Traits for character type, defaults to + * char_traits<_CharT>. + * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. + * + * Meets the requirements of a container, a + * reversible container, and a + * sequence. Of the + * optional sequence requirements, only + * @c push_back, @c at, and @c %array access are supported. + */ + template + class basic_string + { + typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template + rebind<_CharT>::other _Char_alloc_type; + typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; + + // Types: + public: + typedef _Traits traits_type; + typedef typename _Traits::char_type value_type; + typedef _Char_alloc_type allocator_type; + typedef typename _Alloc_traits::size_type size_type; + typedef typename _Alloc_traits::difference_type difference_type; + typedef typename _Alloc_traits::reference reference; + typedef typename _Alloc_traits::const_reference const_reference; + typedef typename _Alloc_traits::pointer pointer; + typedef typename _Alloc_traits::const_pointer const_pointer; + typedef __gnu_cxx::__normal_iterator iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + + /// Value returned by various member functions when they fail. + static const size_type npos = static_cast(-1); + + private: + // type used for positions in insert, erase etc. +#if __cplusplus < 201103L + typedef iterator __const_iterator; +#else + typedef const_iterator __const_iterator; +#endif + + // Use empty-base optimization: http://www.cantrip.org/emptyopt.html + struct _Alloc_hider : allocator_type // TODO check __is_final + { + _Alloc_hider(pointer __dat, const _Alloc& __a = _Alloc()) + : allocator_type(__a), _M_p(__dat) { } + + pointer _M_p; // The actual data. + }; + + _Alloc_hider _M_dataplus; + size_type _M_string_length; + + enum { _S_local_capacity = 16 / sizeof(_CharT) - 1 }; + + union + { + _CharT _M_local_buf[_S_local_capacity + 1]; + size_type _M_allocated_capacity; + }; + + void + _M_data(pointer __p) + { _M_dataplus._M_p = __p; } + + void + _M_length(size_type __length) + { _M_string_length = __length; } + + pointer + _M_data() const + { return _M_dataplus._M_p; } + + pointer + _M_local_data() + { +#if __cplusplus >= 201103L + return std::pointer_traits::pointer_to(*_M_local_buf); +#else + return pointer(_M_local_buf); +#endif + } + + const_pointer + _M_local_data() const + { +#if __cplusplus >= 201103L + return std::pointer_traits::pointer_to(*_M_local_buf); +#else + return const_pointer(_M_local_buf); +#endif + } + + void + _M_capacity(size_type __capacity) + { _M_allocated_capacity = __capacity; } + + void + _M_set_length(size_type __n) + { + _M_length(__n); + traits_type::assign(_M_data()[__n], _CharT()); + } + + bool + _M_is_local() const + { return _M_data() == _M_local_data(); } + + // Create & Destroy + pointer + _M_create(size_type&, size_type); + + void + _M_dispose() + { + if (!_M_is_local()) + _M_destroy(_M_allocated_capacity); + } + + void + _M_destroy(size_type __size) throw() + { _Alloc_traits::deallocate(_M_get_allocator(), _M_data(), __size + 1); } + + // _M_construct_aux is used to implement the 21.3.1 para 15 which + // requires special behaviour if _InIterator is an integral type + template + void + _M_construct_aux(_InIterator __beg, _InIterator __end, + std::__false_type) + { + typedef typename iterator_traits<_InIterator>::iterator_category _Tag; + _M_construct(__beg, __end, _Tag()); + } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 438. Ambiguity in the "do the right thing" clause + template + void + _M_construct_aux(_Integer __beg, _Integer __end, std::__true_type) + { _M_construct_aux_2(static_cast(__beg), __end); } + + void + _M_construct_aux_2(size_type __req, _CharT __c) + { _M_construct(__req, __c); } + + template + void + _M_construct(_InIterator __beg, _InIterator __end) + { + typedef typename std::__is_integer<_InIterator>::__type _Integral; + _M_construct_aux(__beg, __end, _Integral()); + } + + // For Input Iterators, used in istreambuf_iterators, etc. + template + void + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag); + + // For forward_iterators up to random_access_iterators, used for + // string::iterator, _CharT*, etc. + template + void + _M_construct(_FwdIterator __beg, _FwdIterator __end, + std::forward_iterator_tag); + + void + _M_construct(size_type __req, _CharT __c); + + allocator_type& + _M_get_allocator() + { return _M_dataplus; } + + const allocator_type& + _M_get_allocator() const + { return _M_dataplus; } + + private: + +#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST + // The explicit instantiations in misc-inst.cc require this due to + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063 + template::__value + && !__are_same<_Tp, const _CharT*>::__value + && !__are_same<_Tp, iterator>::__value + && !__are_same<_Tp, const_iterator>::__value> + struct __enable_if_not_native_iterator + { typedef basic_string& __type; }; + template + struct __enable_if_not_native_iterator<_Tp, false> { }; +#endif + + size_type + _M_check(size_type __pos, const char* __s) const + { + if (__pos > this->size()) + __throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > " + "this->size() (which is %zu)"), + __s, __pos, this->size()); + return __pos; + } + + void + _M_check_length(size_type __n1, size_type __n2, const char* __s) const + { + if (this->max_size() - (this->size() - __n1) < __n2) + __throw_length_error(__N(__s)); + } + + + // NB: _M_limit doesn't check for a bad __pos value. + size_type + _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT + { + const bool __testoff = __off < this->size() - __pos; + return __testoff ? __off : this->size() - __pos; + } + + // True if _Rep and source do not overlap. + bool + _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT + { + return (less()(__s, _M_data()) + || less()(_M_data() + this->size(), __s)); + } + + // When __n = 1 way faster than the general multichar + // traits_type::copy/move/assign. + static void + _S_copy(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::copy(__d, __s, __n); + } + + static void + _S_move(_CharT* __d, const _CharT* __s, size_type __n) + { + if (__n == 1) + traits_type::assign(*__d, *__s); + else + traits_type::move(__d, __s, __n); + } + + static void + _S_assign(_CharT* __d, size_type __n, _CharT __c) + { + if (__n == 1) + traits_type::assign(*__d, __c); + else + traits_type::assign(__d, __n, __c); + } + + // _S_copy_chars is a separate template to permit specialization + // to optimize for the common case of pointers as iterators. + template + static void + _S_copy_chars(_CharT* __p, _Iterator __k1, _Iterator __k2) + _GLIBCXX_NOEXCEPT + { + for (; __k1 != __k2; ++__k1, ++__p) + traits_type::assign(*__p, *__k1); // These types are off. + } + + static void + _S_copy_chars(_CharT* __p, iterator __k1, iterator __k2) _GLIBCXX_NOEXCEPT + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, const_iterator __k1, const_iterator __k2) + _GLIBCXX_NOEXCEPT + { _S_copy_chars(__p, __k1.base(), __k2.base()); } + + static void + _S_copy_chars(_CharT* __p, _CharT* __k1, _CharT* __k2) _GLIBCXX_NOEXCEPT + { _S_copy(__p, __k1, __k2 - __k1); } + + static void + _S_copy_chars(_CharT* __p, const _CharT* __k1, const _CharT* __k2) + _GLIBCXX_NOEXCEPT + { _S_copy(__p, __k1, __k2 - __k1); } + + static int + _S_compare(size_type __n1, size_type __n2) _GLIBCXX_NOEXCEPT + { + const difference_type __d = difference_type(__n1 - __n2); + + if (__d > __gnu_cxx::__numeric_traits::__max) + return __gnu_cxx::__numeric_traits::__max; + else if (__d < __gnu_cxx::__numeric_traits::__min) + return __gnu_cxx::__numeric_traits::__min; + else + return int(__d); + } + + void + _M_assign(const basic_string& __rcs); + + void + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2); + + void + _M_erase(size_type __pos, size_type __n); + + public: + // Construct/copy/destroy: + // NB: We overload ctors in some cases instead of using default + // arguments, per 17.4.4.4 para. 2 item 2. + + /** + * @brief Default constructor creates an empty string. + */ + basic_string() _GLIBCXX_NOEXCEPT + : _M_dataplus(_M_local_data()) + { _M_set_length(0); } + + /** + * @brief Construct an empty string using allocator @a a. + */ + explicit + basic_string(const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { _M_set_length(0); } + + /** + * @brief Construct string with copy of value of @a __str. + * @param __str Source string. + */ + basic_string(const basic_string& __str) + : _M_dataplus(_M_local_data(), __str._M_get_allocator()) // TODO A traits + { _M_construct(__str._M_data(), __str._M_data() + __str.length()); } + + /** + * @brief Construct string as copy of a substring. + * @param __str Source string. + * @param __pos Index of first character to copy from. + * @param __n Number of characters to copy (default remainder). + */ + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2402. [this constructor] shouldn't use Allocator() + basic_string(const basic_string& __str, size_type __pos, + size_type __n = npos) + : _M_dataplus(_M_local_data()) + { + const _CharT* __start = __str._M_data() + + __str._M_check(__pos, "basic_string::basic_string"); + _M_construct(__start, __start + __str._M_limit(__pos, __n)); + } + + /** + * @brief Construct string as copy of a substring. + * @param __str Source string. + * @param __pos Index of first character to copy from. + * @param __n Number of characters to copy (default remainder). + * @param __a Allocator to use. + */ + basic_string(const basic_string& __str, size_type __pos, + size_type __n, const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { + const _CharT* __start + = __str._M_data() + __str._M_check(__pos, "string::string"); + _M_construct(__start, __start + __str._M_limit(__pos, __n)); + } + + /** + * @brief Construct string initialized by a character %array. + * @param __s Source character %array. + * @param __n Number of characters to copy. + * @param __a Allocator to use (default is default allocator). + * + * NB: @a __s must have at least @a __n characters, '\\0' + * has no special meaning. + */ + basic_string(const _CharT* __s, size_type __n, + const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__s, __s + __n); } + + /** + * @brief Construct string as copy of a C string. + * @param __s Source C string. + * @param __a Allocator to use (default is default allocator). + */ + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); } + + /** + * @brief Construct string as multiple characters. + * @param __n Number of characters. + * @param __c Character to use. + * @param __a Allocator to use (default is default allocator). + */ + basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__n, __c); } + +#if __cplusplus >= 201103L + /** + * @brief Move construct string. + * @param __str Source string. + * + * The newly-created string contains the exact contents of @a __str. + * @a __str is a valid, but unspecified string. + **/ + basic_string(basic_string&& __str) noexcept + : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator())) + { + if (__str._M_is_local()) + { + if (__str.length()) + traits_type::copy(_M_local_buf, __str._M_local_buf, + _S_local_capacity + 1); + } + else + { + _M_data(__str._M_data()); + _M_capacity(__str._M_allocated_capacity); + } + + // Must use _M_length() here not _M_set_length() because + // basic_stringbuf relies on writing into unallocated capacity so + // we mess up the contents if we put a '\0' in the string. + _M_length(__str.length()); + __str._M_data(__str._M_local_data()); + __str._M_set_length(0); + } + + /** + * @brief Construct string from an initializer %list. + * @param __l std::initializer_list of characters. + * @param __a Allocator to use (default is default allocator). + */ + basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__l.begin(), __l.end()); } + + basic_string(const basic_string& __str, const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__str.begin(), __str.end()); } + + basic_string(basic_string&& __str, const _Alloc& __a) + : _M_dataplus(_M_local_data(), __a) + { + if (__str.get_allocator() == __a) + *this = std::move(__str); + else + _M_construct(__str.begin(), __str.end()); + } + +#endif // C++11 + + /** + * @brief Construct string as copy of a range. + * @param __beg Start of range. + * @param __end End of range. + * @param __a Allocator to use (default is default allocator). + */ +#if __cplusplus >= 201103L + template> +#else + template +#endif + basic_string(_InputIterator __beg, _InputIterator __end, + const _Alloc& __a = _Alloc()) + : _M_dataplus(_M_local_data(), __a) + { _M_construct(__beg, __end); } + + /** + * @brief Destroy the string instance. + */ + ~basic_string() + { _M_dispose(); } + + /** + * @brief Assign the value of @a str to this string. + * @param __str Source string. + */ + basic_string& + operator=(const basic_string& __str) + { return this->assign(__str); } + + /** + * @brief Copy contents of @a s into this string. + * @param __s Source null-terminated string. + */ + basic_string& + operator=(const _CharT* __s) + { return this->assign(__s); } + + /** + * @brief Set value to string of length 1. + * @param __c Source character. + * + * Assigning to a character makes this string length 1 and + * (*this)[0] == @a c. + */ + basic_string& + operator=(_CharT __c) + { + this->assign(1, __c); + return *this; + } + +#if __cplusplus >= 201103L + /** + * @brief Move assign the value of @a str to this string. + * @param __str Source string. + * + * The contents of @a str are moved into this string (without copying). + * @a str is a valid, but unspecified string. + **/ + // PR 58265, this should be noexcept. + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2063. Contradictory requirements for string move assignment + basic_string& + operator=(basic_string&& __str) + { + this->swap(__str); + return *this; + } + + /** + * @brief Set value to string constructed from initializer %list. + * @param __l std::initializer_list. + */ + basic_string& + operator=(initializer_list<_CharT> __l) + { + this->assign(__l.begin(), __l.size()); + return *this; + } +#endif // C++11 + + // Iterators: + /** + * Returns a read/write iterator that points to the first character in + * the %string. + */ + iterator + begin() _GLIBCXX_NOEXCEPT + { return iterator(_M_data()); } + + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + begin() const _GLIBCXX_NOEXCEPT + { return const_iterator(_M_data()); } + + /** + * Returns a read/write iterator that points one past the last + * character in the %string. + */ + iterator + end() _GLIBCXX_NOEXCEPT + { return iterator(_M_data() + this->size()); } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + end() const _GLIBCXX_NOEXCEPT + { return const_iterator(_M_data() + this->size()); } + + /** + * Returns a read/write reverse iterator that points to the last + * character in the %string. Iteration is done in reverse element + * order. + */ + reverse_iterator + rbegin() _GLIBCXX_NOEXCEPT + { return reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + rbegin() const _GLIBCXX_NOEXCEPT + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first character in the %string. Iteration is done in reverse + * element order. + */ + reverse_iterator + rend() _GLIBCXX_NOEXCEPT + { return reverse_iterator(this->begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + rend() const _GLIBCXX_NOEXCEPT + { return const_reverse_iterator(this->begin()); } + +#if __cplusplus >= 201103L + /** + * Returns a read-only (constant) iterator that points to the first + * character in the %string. + */ + const_iterator + cbegin() const noexcept + { return const_iterator(this->_M_data()); } + + /** + * Returns a read-only (constant) iterator that points one past the + * last character in the %string. + */ + const_iterator + cend() const noexcept + { return const_iterator(this->_M_data() + this->size()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to the last character in the %string. Iteration is done in + * reverse element order. + */ + const_reverse_iterator + crbegin() const noexcept + { return const_reverse_iterator(this->end()); } + + /** + * Returns a read-only (constant) reverse iterator that points + * to one before the first character in the %string. Iteration + * is done in reverse element order. + */ + const_reverse_iterator + crend() const noexcept + { return const_reverse_iterator(this->begin()); } +#endif + + public: + // Capacity: + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + size() const _GLIBCXX_NOEXCEPT + { return _M_string_length; } + + /// Returns the number of characters in the string, not including any + /// null-termination. + size_type + length() const _GLIBCXX_NOEXCEPT + { return _M_string_length; } + + /// Returns the size() of the largest possible %string. + size_type + max_size() const _GLIBCXX_NOEXCEPT + { return (_Alloc_traits::max_size(_M_get_allocator()) - 1) / 2; } + + /** + * @brief Resizes the %string to the specified number of characters. + * @param __n Number of characters the %string should contain. + * @param __c Character to fill any new elements. + * + * This function will %resize the %string to the specified + * number of characters. If the number is smaller than the + * %string's current size the %string is truncated, otherwise + * the %string is extended and new elements are %set to @a __c. + */ + void + resize(size_type __n, _CharT __c); + + /** + * @brief Resizes the %string to the specified number of characters. + * @param __n Number of characters the %string should contain. + * + * This function will resize the %string to the specified length. If + * the new size is smaller than the %string's current size the %string + * is truncated, otherwise the %string is extended and new characters + * are default-constructed. For basic types such as char, this means + * setting them to 0. + */ + void + resize(size_type __n) + { this->resize(__n, _CharT()); } + +#if __cplusplus >= 201103L + /// A non-binding request to reduce capacity() to size(). + void + shrink_to_fit() noexcept + { + if (capacity() > size()) + { + __try + { reserve(0); } + __catch(...) + { } + } + } +#endif + + /** + * Returns the total number of characters that the %string can hold + * before needing to allocate more memory. + */ + size_type + capacity() const _GLIBCXX_NOEXCEPT + { + return _M_is_local() ? size_type(_S_local_capacity) + : _M_allocated_capacity; + } + + /** + * @brief Attempt to preallocate enough memory for specified number of + * characters. + * @param __res_arg Number of characters required. + * @throw std::length_error If @a __res_arg exceeds @c max_size(). + * + * This function attempts to reserve enough memory for the + * %string to hold the specified number of characters. If the + * number requested is more than max_size(), length_error is + * thrown. + * + * The advantage of this function is that if optimal code is a + * necessity and the user can determine the string length that will be + * required, the user can reserve the memory in %advance, and thus + * prevent a possible reallocation of memory and copying of %string + * data. + */ + void + reserve(size_type __res_arg = 0); + + /** + * Erases the string, making it empty. + */ + void + clear() _GLIBCXX_NOEXCEPT + { _M_set_length(0); } + + /** + * Returns true if the %string is empty. Equivalent to + * *this == "". + */ + bool + empty() const _GLIBCXX_NOEXCEPT + { return this->size() == 0; } + + // Element access: + /** + * @brief Subscript access to the data contained in the %string. + * @param __pos The index of the character to access. + * @return Read-only (constant) reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + const_reference + operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT + { + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + return _M_data()[__pos]; + } + + /** + * @brief Subscript access to the data contained in the %string. + * @param __pos The index of the character to access. + * @return Read/write reference to the character. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and + * out_of_range lookups are not defined. (For checked lookups + * see at().) + */ + reference + operator[](size_type __pos) + { + // Allow pos == size() both in C++98 mode, as v3 extension, + // and in C++11 mode. + _GLIBCXX_DEBUG_ASSERT(__pos <= size()); + // In pedantic mode be strict in C++98 mode. + _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size()); + return _M_data()[__pos]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param __n The index of the character to access. + * @return Read-only (const) reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + const_reference + at(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range_fmt(__N("basic_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); + return _M_data()[__n]; + } + + /** + * @brief Provides access to the data contained in the %string. + * @param __n The index of the character to access. + * @return Read/write reference to the character. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is + * first checked that it is in the range of the string. The function + * throws out_of_range if the check fails. + */ + reference + at(size_type __n) + { + if (__n >= size()) + __throw_out_of_range_fmt(__N("basic_string::at: __n " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __n, this->size()); + return _M_data()[__n]; + } + +#if __cplusplus >= 201103L + /** + * Returns a read/write reference to the data at the first + * element of the %string. + */ + reference + front() noexcept + { return operator[](0); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %string. + */ + const_reference + front() const noexcept + { return operator[](0); } + + /** + * Returns a read/write reference to the data at the last + * element of the %string. + */ + reference + back() noexcept + { return operator[](this->size() - 1); } + + /** + * Returns a read-only (constant) reference to the data at the + * last element of the %string. + */ + const_reference + back() const noexcept + { return operator[](this->size() - 1); } +#endif + + // Modifiers: + /** + * @brief Append a string to this string. + * @param __str The string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const basic_string& __str) + { return this->append(__str); } + + /** + * @brief Append a C string. + * @param __s The C string to append. + * @return Reference to this string. + */ + basic_string& + operator+=(const _CharT* __s) + { return this->append(__s); } + + /** + * @brief Append a character. + * @param __c The character to append. + * @return Reference to this string. + */ + basic_string& + operator+=(_CharT __c) + { + this->push_back(__c); + return *this; + } + +#if __cplusplus >= 201103L + /** + * @brief Append an initializer_list of characters. + * @param __l The initializer_list of characters to be appended. + * @return Reference to this string. + */ + basic_string& + operator+=(initializer_list<_CharT> __l) + { return this->append(__l.begin(), __l.size()); } +#endif // C++11 + + /** + * @brief Append a string to this string. + * @param __str The string to append. + * @return Reference to this string. + */ + basic_string& + append(const basic_string& __str) + { return _M_append(__str._M_data(), __str.size()); } + + /** + * @brief Append a substring. + * @param __str The string to append. + * @param __pos Index of the first character of str to append. + * @param __n The number of characters to append. + * @return Reference to this string. + * @throw std::out_of_range if @a __pos is not a valid index. + * + * This function appends @a __n characters from @a __str + * starting at @a __pos to this string. If @a __n is is larger + * than the number of available characters in @a __str, the + * remainder of @a __str is appended. + */ + basic_string& + append(const basic_string& __str, size_type __pos, size_type __n) + { return _M_append(__str._M_data() + + __str._M_check(__pos, "basic_string::append"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Append a C substring. + * @param __s The C string to append. + * @param __n The number of characters to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + _M_check_length(size_type(0), __n, "basic_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append a C string. + * @param __s The C string to append. + * @return Reference to this string. + */ + basic_string& + append(const _CharT* __s) + { + __glibcxx_requires_string(__s); + const size_type __n = traits_type::length(__s); + _M_check_length(size_type(0), __n, "basic_string::append"); + return _M_append(__s, __n); + } + + /** + * @brief Append multiple characters. + * @param __n The number of characters to append. + * @param __c The character to use. + * @return Reference to this string. + * + * Appends __n copies of __c to this string. + */ + basic_string& + append(size_type __n, _CharT __c) + { return _M_replace_aux(this->size(), size_type(0), __n, __c); } + +#if __cplusplus >= 201103L + /** + * @brief Append an initializer_list of characters. + * @param __l The initializer_list of characters to append. + * @return Reference to this string. + */ + basic_string& + append(initializer_list<_CharT> __l) + { return this->append(__l.begin(), __l.size()); } +#endif // C++11 + + /** + * @brief Append a range of characters. + * @param __first Iterator referencing the first character to append. + * @param __last Iterator marking the end of the range. + * @return Reference to this string. + * + * Appends characters in the range [__first,__last) to this string. + */ +#if __cplusplus >= 201103L + template> +#else + template +#endif + basic_string& + append(_InputIterator __first, _InputIterator __last) + { return this->replace(end(), end(), __first, __last); } + + /** + * @brief Append a single character. + * @param __c Character to append. + */ + void + push_back(_CharT __c) + { + const size_type __size = this->size(); + if (__size + 1 > this->capacity()) + this->_M_mutate(__size, size_type(0), 0, size_type(1)); + traits_type::assign(this->_M_data()[__size], __c); + this->_M_set_length(__size + 1); + } + + /** + * @brief Set value to contents of another string. + * @param __str Source string to use. + * @return Reference to this string. + */ + basic_string& + assign(const basic_string& __str) + { + this->_M_assign(__str); + return *this; + } + +#if __cplusplus >= 201103L + /** + * @brief Set value to contents of another string. + * @param __str Source string to use. + * @return Reference to this string. + * + * This function sets this string to the exact contents of @a __str. + * @a __str is a valid, but unspecified string. + */ + basic_string& + assign(basic_string&& __str) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2063. Contradictory requirements for string move assignment + return *this = std::move(__str); + } +#endif // C++11 + + /** + * @brief Set value to a substring of a string. + * @param __str The string to use. + * @param __pos Index of the first character of str. + * @param __n Number of characters to use. + * @return Reference to this string. + * @throw std::out_of_range if @a pos is not a valid index. + * + * This function sets this string to the substring of @a __str + * consisting of @a __n characters at @a __pos. If @a __n is + * is larger than the number of available characters in @a + * __str, the remainder of @a __str is used. + */ + basic_string& + assign(const basic_string& __str, size_type __pos, size_type __n) + { return _M_replace(size_type(0), this->size(), __str._M_data() + + __str._M_check(__pos, "basic_string::assign"), + __str._M_limit(__pos, __n)); } + + /** + * @brief Set value to a C substring. + * @param __s The C string to use. + * @param __n Number of characters to use. + * @return Reference to this string. + * + * This function sets the value of this string to the first @a __n + * characters of @a __s. If @a __n is is larger than the number of + * available characters in @a __s, the remainder of @a __s is used. + */ + basic_string& + assign(const _CharT* __s, size_type __n) + { + __glibcxx_requires_string_len(__s, __n); + return _M_replace(size_type(0), this->size(), __s, __n); + } + + /** + * @brief Set value to contents of a C string. + * @param __s The C string to use. + * @return Reference to this string. + * + * This function sets the value of this string to the value of @a __s. + * The data is copied, so there is no dependence on @a __s once the + * function returns. + */ + basic_string& + assign(const _CharT* __s) + { + __glibcxx_requires_string(__s); + return _M_replace(size_type(0), this->size(), __s, + traits_type::length(__s)); + } + + /** + * @brief Set value to multiple characters. + * @param __n Length of the resulting string. + * @param __c The character to use. + * @return Reference to this string. + * + * This function sets the value of this string to @a __n copies of + * character @a __c. + */ + basic_string& + assign(size_type __n, _CharT __c) + { return _M_replace_aux(size_type(0), this->size(), __n, __c); } + + /** + * @brief Set value to a range of characters. + * @param __first Iterator referencing the first character to append. + * @param __last Iterator marking the end of the range. + * @return Reference to this string. + * + * Sets value of string to characters in the range [__first,__last). + */ +#if __cplusplus >= 201103L + template> +#else + template +#endif + basic_string& + assign(_InputIterator __first, _InputIterator __last) + { return this->replace(begin(), end(), __first, __last); } + +#if __cplusplus >= 201103L + /** + * @brief Set value to an initializer_list of characters. + * @param __l The initializer_list of characters to assign. + * @return Reference to this string. + */ + basic_string& + assign(initializer_list<_CharT> __l) + { return this->assign(__l.begin(), __l.size()); } +#endif // C++11 + +#if __cplusplus >= 201103L + /** + * @brief Insert multiple characters. + * @param __p Const_iterator referencing location in string to + * insert at. + * @param __n Number of characters to insert + * @param __c The character to insert. + * @return Iterator referencing the first inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a __n copies of character @a __c starting at the + * position referenced by iterator @a __p. If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + iterator + insert(const_iterator __p, size_type __n, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + const size_type __pos = __p - begin(); + this->replace(__p, __p, __n, __c); + return iterator(this->_M_data() + __pos); + } +#else + /** + * @brief Insert multiple characters. + * @param __p Iterator referencing location in string to insert at. + * @param __n Number of characters to insert + * @param __c The character to insert. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts @a __n copies of character @a __c starting at the + * position referenced by iterator @a __p. If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + void + insert(iterator __p, size_type __n, _CharT __c) + { this->replace(__p, __p, __n, __c); } +#endif + +#if __cplusplus >= 201103L + /** + * @brief Insert a range of characters. + * @param __p Const_iterator referencing location in string to + * insert at. + * @param __beg Start of range. + * @param __end End of range. + * @return Iterator referencing the first inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [beg,end). If adding characters + * causes the length to exceed max_size(), length_error is + * thrown. The value of the string doesn't change if an error + * is thrown. + */ + template> + iterator + insert(const_iterator __p, _InputIterator __beg, _InputIterator __end) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + const size_type __pos = __p - begin(); + this->replace(__p, __p, __beg, __end); + return iterator(this->_M_data() + __pos); + } +#else + /** + * @brief Insert a range of characters. + * @param __p Iterator referencing location in string to insert at. + * @param __beg Start of range. + * @param __end End of range. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts characters in range [__beg,__end). If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + template + void + insert(iterator __p, _InputIterator __beg, _InputIterator __end) + { this->replace(__p, __p, __beg, __end); } +#endif + +#if __cplusplus >= 201103L + /** + * @brief Insert an initializer_list of characters. + * @param __p Iterator referencing location in string to insert at. + * @param __l The initializer_list of characters to insert. + * @throw std::length_error If new length exceeds @c max_size(). + */ + void + insert(iterator __p, initializer_list<_CharT> __l) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + this->insert(__p - begin(), __l.begin(), __l.size()); + } +#endif // C++11 + + /** + * @brief Insert value of a string. + * @param __pos1 Iterator referencing location in string to insert at. + * @param __str The string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts value of @a __str starting at @a __pos1. If adding + * characters causes the length to exceed max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str) + { return this->replace(__pos1, size_type(0), + __str._M_data(), __str.size()); } + + /** + * @brief Insert a substring. + * @param __pos1 Iterator referencing location in string to insert at. + * @param __str The string to insert. + * @param __pos2 Start of characters in str to insert. + * @param __n Number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos1 > size() or + * @a __pos2 > @a str.size(). + * + * Starting at @a pos1, insert @a __n character of @a __str + * beginning with @a __pos2. If adding characters causes the + * length to exceed max_size(), length_error is thrown. If @a + * __pos1 is beyond the end of this string or @a __pos2 is + * beyond the end of @a __str, out_of_range is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + insert(size_type __pos1, const basic_string& __str, + size_type __pos2, size_type __n) + { return this->replace(__pos1, size_type(0), __str._M_data() + + __str._M_check(__pos2, "basic_string::insert"), + __str._M_limit(__pos2, __n)); } + + /** + * @brief Insert a C substring. + * @param __pos Iterator referencing location in string to insert at. + * @param __s The C string to insert. + * @param __n The number of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a __pos is beyond the end of this + * string. + * + * Inserts the first @a __n characters of @a __s starting at @a + * __pos. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a __pos is beyond + * end(), out_of_range is thrown. The value of the string + * doesn't change if an error is thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s, size_type __n) + { return this->replace(__pos, size_type(0), __s, __n); } + + /** + * @brief Insert a C string. + * @param __pos Iterator referencing location in string to insert at. + * @param __s The C string to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Inserts the first @a n characters of @a __s starting at @a __pos. If + * adding characters causes the length to exceed max_size(), + * length_error is thrown. If @a __pos is beyond end(), out_of_range is + * thrown. The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + insert(size_type __pos, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, size_type(0), __s, + traits_type::length(__s)); + } + + /** + * @brief Insert multiple characters. + * @param __pos Index in string to insert at. + * @param __n Number of characters to insert + * @param __c The character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * @throw std::out_of_range If @a __pos is beyond the end of this + * string. + * + * Inserts @a __n copies of character @a __c starting at index + * @a __pos. If adding characters causes the length to exceed + * max_size(), length_error is thrown. If @a __pos > length(), + * out_of_range is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + insert(size_type __pos, size_type __n, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::insert"), + size_type(0), __n, __c); } + + /** + * @brief Insert one character. + * @param __p Iterator referencing position in string to insert at. + * @param __c The character to insert. + * @return Iterator referencing newly inserted char. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Inserts character @a __c at position referenced by @a __p. + * If adding character causes the length to exceed max_size(), + * length_error is thrown. If @a __p is beyond end of string, + * out_of_range is thrown. The value of the string doesn't + * change if an error is thrown. + */ + iterator + insert(__const_iterator __p, _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(__p >= begin() && __p <= end()); + const size_type __pos = __p - begin(); + _M_replace_aux(__pos, size_type(0), size_type(1), __c); + return iterator(_M_data() + __pos); + } + + /** + * @brief Remove characters. + * @param __pos Index of first character to remove (default 0). + * @param __n Number of characters to remove (default remainder). + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * + * Removes @a __n characters from this string starting at @a + * __pos. The length of the string is reduced by @a __n. If + * there are < @a __n characters to remove, the remainder of + * the string is truncated. If @a __p is beyond end of string, + * out_of_range is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + erase(size_type __pos = 0, size_type __n = npos) + { + this->_M_erase(_M_check(__pos, "basic_string::erase"), + _M_limit(__pos, __n)); + return *this; + } + + /** + * @brief Remove one character. + * @param __position Iterator referencing the character to remove. + * @return iterator referencing same location after removal. + * + * Removes the character at @a __position from this string. The value + * of the string doesn't change if an error is thrown. + */ + iterator + erase(__const_iterator __position) + { + _GLIBCXX_DEBUG_PEDASSERT(__position >= begin() + && __position < end()); + const size_type __pos = __position - begin(); + this->_M_erase(__pos, size_type(1)); + return iterator(_M_data() + __pos); + } + + /** + * @brief Remove a range of characters. + * @param __first Iterator referencing the first character to remove. + * @param __last Iterator referencing the end of the range. + * @return Iterator referencing location of first after removal. + * + * Removes the characters in the range [first,last) from this string. + * The value of the string doesn't change if an error is thrown. + */ + iterator + erase(__const_iterator __first, __const_iterator __last) + { + _GLIBCXX_DEBUG_PEDASSERT(__first >= begin() && __first <= __last + && __last <= end()); + const size_type __pos = __first - begin(); + this->_M_erase(__pos, __last - __first); + return iterator(this->_M_data() + __pos); + } + +#if __cplusplus >= 201103L + /** + * @brief Remove the last character. + * + * The string must be non-empty. + */ + void + pop_back() noexcept + { _M_erase(size()-1, 1); } +#endif // C++11 + + /** + * @brief Replace characters with value from another string. + * @param __pos Index of first character to replace. + * @param __n Number of characters to be replaced. + * @param __str String to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos is beyond the end of this + * string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos,__pos+__n) from + * this string. In place, the value of @a __str is inserted. + * If @a __pos is beyond end of string, out_of_range is thrown. + * If the length of the result exceeds max_size(), length_error + * is thrown. The value of the string doesn't change if an + * error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n, const basic_string& __str) + { return this->replace(__pos, __n, __str._M_data(), __str.size()); } + + /** + * @brief Replace characters with value from another string. + * @param __pos1 Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __str String to insert. + * @param __pos2 Index of first character of str to use. + * @param __n2 Number of characters from str to use. + * @return Reference to this string. + * @throw std::out_of_range If @a __pos1 > size() or @a __pos2 > + * __str.size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos1,__pos1 + n) from this + * string. In place, the value of @a __str is inserted. If @a __pos is + * beyond end of string, out_of_range is thrown. If the length of the + * result exceeds max_size(), length_error is thrown. The value of the + * string doesn't change if an error is thrown. + */ + basic_string& + replace(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) + { return this->replace(__pos1, __n1, __str._M_data() + + __str._M_check(__pos2, "basic_string::replace"), + __str._M_limit(__pos2, __n2)); } + + /** + * @brief Replace characters with value of a C substring. + * @param __pos Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __s C string to insert. + * @param __n2 Number of characters from @a s to use. + * @return Reference to this string. + * @throw std::out_of_range If @a pos1 > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos,__pos + __n1) + * from this string. In place, the first @a __n2 characters of + * @a __s are inserted, or all of @a __s if @a __n2 is too large. If + * @a __pos is beyond end of string, out_of_range is thrown. If + * the length of result exceeds max_size(), length_error is + * thrown. The value of the string doesn't change if an error + * is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) + { + __glibcxx_requires_string_len(__s, __n2); + return _M_replace(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __s, __n2); + } + + /** + * @brief Replace characters with value of a C string. + * @param __pos Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __s C string to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__pos,__pos + __n1) + * from this string. In place, the characters of @a __s are + * inserted. If @a __pos is beyond end of string, out_of_range + * is thrown. If the length of result exceeds max_size(), + * length_error is thrown. The value of the string doesn't + * change if an error is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__pos, __n1, __s, traits_type::length(__s)); + } + + /** + * @brief Replace characters with multiple characters. + * @param __pos Index of first character to replace. + * @param __n1 Number of characters to be replaced. + * @param __n2 Number of characters to insert. + * @param __c Character to insert. + * @return Reference to this string. + * @throw std::out_of_range If @a __pos > size(). + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [pos,pos + n1) from this + * string. In place, @a __n2 copies of @a __c are inserted. + * If @a __pos is beyond end of string, out_of_range is thrown. + * If the length of result exceeds max_size(), length_error is + * thrown. The value of the string doesn't change if an error + * is thrown. + */ + basic_string& + replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c) + { return _M_replace_aux(_M_check(__pos, "basic_string::replace"), + _M_limit(__pos, __n1), __n2, __c); } + + /** + * @brief Replace range of characters with string. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __str String value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * the value of @a __str is inserted. If the length of result + * exceeds max_size(), length_error is thrown. The value of + * the string doesn't change if an error is thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const basic_string& __str) + { return this->replace(__i1, __i2, __str._M_data(), __str.size()); } + + /** + * @brief Replace range of characters with C substring. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __s C string value to insert. + * @param __n Number of characters from s to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * the first @a __n characters of @a __s are inserted. If the + * length of result exceeds max_size(), length_error is thrown. + * The value of the string doesn't change if an error is + * thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const _CharT* __s, size_type __n) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + return this->replace(__i1 - begin(), __i2 - __i1, __s, __n); + } + + /** + * @brief Replace range of characters with C string. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __s C string value to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * the characters of @a __s are inserted. If the length of + * result exceeds max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, const _CharT* __s) + { + __glibcxx_requires_string(__s); + return this->replace(__i1, __i2, __s, traits_type::length(__s)); + } + + /** + * @brief Replace range of characters with multiple characters + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __n Number of characters to insert. + * @param __c Character to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * @a __n copies of @a __c are inserted. If the length of + * result exceeds max_size(), length_error is thrown. The + * value of the string doesn't change if an error is thrown. + */ + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, size_type __n, + _CharT __c) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __c); + } + + /** + * @brief Replace range of characters with range. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __k1 Iterator referencing start of range to insert. + * @param __k2 Iterator referencing end of range to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * characters in the range [__k1,__k2) are inserted. If the + * length of result exceeds max_size(), length_error is thrown. + * The value of the string doesn't change if an error is + * thrown. + */ +#if __cplusplus >= 201103L + template> + basic_string& + replace(const_iterator __i1, const_iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->_M_replace_dispatch(__i1, __i2, __k1, __k2, + std::__false_type()); + } +#else + template +#ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST + typename __enable_if_not_native_iterator<_InputIterator>::__type +#else + basic_string& +#endif + replace(iterator __i1, iterator __i2, + _InputIterator __k1, _InputIterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return _M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral()); + } +#endif + + // Specializations for the common case of pointer and iterator: + // useful to avoid the overhead of temporary buffering in _M_replace. + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + _CharT* __k1, _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const _CharT* __k1, const _CharT* __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1, __k2 - __k1); + } + + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + iterator __k1, iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + + basic_string& + replace(__const_iterator __i1, __const_iterator __i2, + const_iterator __k1, const_iterator __k2) + { + _GLIBCXX_DEBUG_PEDASSERT(begin() <= __i1 && __i1 <= __i2 + && __i2 <= end()); + __glibcxx_requires_valid_range(__k1, __k2); + return this->replace(__i1 - begin(), __i2 - __i1, + __k1.base(), __k2 - __k1); + } + +#if __cplusplus >= 201103L + /** + * @brief Replace range of characters with initializer_list. + * @param __i1 Iterator referencing start of range to replace. + * @param __i2 Iterator referencing end of range to replace. + * @param __l The initializer_list of characters to insert. + * @return Reference to this string. + * @throw std::length_error If new length exceeds @c max_size(). + * + * Removes the characters in the range [__i1,__i2). In place, + * characters in the range [__k1,__k2) are inserted. If the + * length of result exceeds max_size(), length_error is thrown. + * The value of the string doesn't change if an error is + * thrown. + */ + basic_string& replace(const_iterator __i1, const_iterator __i2, + initializer_list<_CharT> __l) + { return this->replace(__i1, __i2, __l.begin(), __l.end()); } +#endif // C++11 + + private: + template + basic_string& + _M_replace_dispatch(const_iterator __i1, const_iterator __i2, + _Integer __n, _Integer __val, __true_type) + { return _M_replace_aux(__i1 - begin(), __i2 - __i1, __n, __val); } + + template + basic_string& + _M_replace_dispatch(const_iterator __i1, const_iterator __i2, + _InputIterator __k1, _InputIterator __k2, + __false_type); + + basic_string& + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c); + + basic_string& + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2); + + basic_string& + _M_append(const _CharT* __s, size_type __n); + + public: + + /** + * @brief Copy substring into C string. + * @param __s C string to copy value into. + * @param __n Number of characters to copy. + * @param __pos Index of first character to copy. + * @return Number of characters actually copied + * @throw std::out_of_range If __pos > size(). + * + * Copies up to @a __n characters starting at @a __pos into the + * C string @a __s. If @a __pos is %greater than size(), + * out_of_range is thrown. + */ + size_type + copy(_CharT* __s, size_type __n, size_type __pos = 0) const; + + /** + * @brief Swap contents with another string. + * @param __s String to swap with. + * + * Exchanges the contents of this string with that of @a __s in constant + * time. + */ + void + swap(basic_string& __s) _GLIBCXX_NOEXCEPT; + + // String operations: + /** + * @brief Return const pointer to null-terminated contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + c_str() const _GLIBCXX_NOEXCEPT + { return _M_data(); } + + /** + * @brief Return const pointer to contents. + * + * This is a handle to internal data. Do not modify or dire things may + * happen. + */ + const _CharT* + data() const _GLIBCXX_NOEXCEPT + { return _M_data(); } + + /** + * @brief Return copy of allocator used to construct this string. + */ + allocator_type + get_allocator() const _GLIBCXX_NOEXCEPT + { return _M_get_allocator(); } + + /** + * @brief Find position of a C substring. + * @param __s C string to locate. + * @param __pos Index of character to search from. + * @param __n Number of characters from @a s to search for. + * @return Index of start of first occurrence. + * + * Starting from @a __pos, searches forward for the first @a + * __n characters in @a __s within this string. If found, + * returns the index where it begins. If not found, returns + * npos. + */ + size_type + find(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a string. + * @param __str String to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a __pos, searches forward for value of @a __str within + * this string. If found, returns the index where it begins. If not + * found, returns npos. + */ + size_type + find(const basic_string& __str, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT + { return this->find(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a C string. + * @param __s C string to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of start of first occurrence. + * + * Starting from @a __pos, searches forward for the value of @a + * __s within this string. If found, returns the index where + * it begins. If not found, returns npos. + */ + size_type + find(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for @a __c within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT; + + /** + * @brief Find last position of a string. + * @param __str String to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of start of last occurrence. + * + * Starting from @a __pos, searches backward for value of @a + * __str within this string. If found, returns the index where + * it begins. If not found, returns npos. + */ + size_type + rfind(const basic_string& __str, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT + { return this->rfind(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a C substring. + * @param __s C string to locate. + * @param __pos Index of character to search back from. + * @param __n Number of characters from s to search for. + * @return Index of start of last occurrence. + * + * Starting from @a __pos, searches backward for the first @a + * __n characters in @a __s within this string. If found, + * returns the index where it begins. If not found, returns + * npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a C string. + * @param __s C string to locate. + * @param __pos Index of character to start search at (default end). + * @return Index of start of last occurrence. + * + * Starting from @a __pos, searches backward for the value of + * @a __s within this string. If found, returns the index + * where it begins. If not found, returns npos. + */ + size_type + rfind(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->rfind(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for @a __c within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT; + + /** + * @brief Find position of a character of string. + * @param __str String containing characters to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for one of the + * characters of @a __str within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_first_of(const basic_string& __str, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT + { return this->find_first_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character of C substring. + * @param __s String containing characters to locate. + * @param __pos Index of character to search from. + * @param __n Number of characters from s to search for. + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for one of the + * first @a __n characters of @a __s within this string. If + * found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find position of a character of C string. + * @param __s String containing characters to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for one of the + * characters of @a __s within this string. If found, returns + * the index where it was found. If not found, returns npos. + */ + size_type + find_first_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for the character + * @a __c within this string. If found, returns the index + * where it was found. If not found, returns npos. + * + * Note: equivalent to find(__c, __pos). + */ + size_type + find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT + { return this->find(__c, __pos); } + + /** + * @brief Find last position of a character of string. + * @param __str String containing characters to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for one of the + * characters of @a __str within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_last_of(const basic_string& __str, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT + { return this->find_last_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character of C substring. + * @param __s C string containing characters to locate. + * @param __pos Index of character to search back from. + * @param __n Number of characters from s to search for. + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for one of the + * first @a __n characters of @a __s within this string. If + * found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos, size_type __n) const; + + /** + * @brief Find last position of a character of C string. + * @param __s C string containing characters to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for one of the + * characters of @a __s within this string. If found, returns + * the index where it was found. If not found, returns npos. + */ + size_type + find_last_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a character. + * @param __c Character to locate. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for @a __c within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + * + * Note: equivalent to rfind(__c, __pos). + */ + size_type + find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT + { return this->rfind(__c, __pos); } + + /** + * @brief Find position of a character not in string. + * @param __str String containing characters to avoid. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character not contained + * in @a __str within this string. If found, returns the index where it + * was found. If not found, returns npos. + */ + size_type + find_first_not_of(const basic_string& __str, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT + { return this->find_first_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find position of a character not in C substring. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search from. + * @param __n Number of characters from __s to consider. + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character not + * contained in the first @a __n characters of @a __s within + * this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + + /** + * @brief Find position of a character not in C string. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character not + * contained in @a __s within this string. If found, returns + * the index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(const _CharT* __s, size_type __pos = 0) const + { + __glibcxx_requires_string(__s); + return this->find_first_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find position of a different character. + * @param __c Character to avoid. + * @param __pos Index of character to search from (default 0). + * @return Index of first occurrence. + * + * Starting from @a __pos, searches forward for a character + * other than @a __c within this string. If found, returns the + * index where it was found. If not found, returns npos. + */ + size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const + _GLIBCXX_NOEXCEPT; + + /** + * @brief Find last position of a character not in string. + * @param __str String containing characters to avoid. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character + * not contained in @a __str within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_last_not_of(const basic_string& __str, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT + { return this->find_last_not_of(__str.data(), __pos, __str.size()); } + + /** + * @brief Find last position of a character not in C substring. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search back from. + * @param __n Number of characters from s to consider. + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character not + * contained in the first @a __n characters of @a __s within this string. + * If found, returns the index where it was found. If not found, + * returns npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos, + size_type __n) const; + /** + * @brief Find last position of a character not in C string. + * @param __s C string containing characters to avoid. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character + * not contained in @a __s within this string. If found, + * returns the index where it was found. If not found, returns + * npos. + */ + size_type + find_last_not_of(const _CharT* __s, size_type __pos = npos) const + { + __glibcxx_requires_string(__s); + return this->find_last_not_of(__s, __pos, traits_type::length(__s)); + } + + /** + * @brief Find last position of a different character. + * @param __c Character to avoid. + * @param __pos Index of character to search back from (default end). + * @return Index of last occurrence. + * + * Starting from @a __pos, searches backward for a character other than + * @a __c within this string. If found, returns the index where it was + * found. If not found, returns npos. + */ + size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const + _GLIBCXX_NOEXCEPT; + + /** + * @brief Get a substring. + * @param __pos Index of first character (default 0). + * @param __n Number of characters in substring (default remainder). + * @return The new string. + * @throw std::out_of_range If __pos > size(). + * + * Construct and return a new string using the @a __n + * characters starting at @a __pos. If the string is too + * short, use the remainder of the characters. If @a __pos is + * beyond the end of the string, out_of_range is thrown. + */ + basic_string + substr(size_type __pos = 0, size_type __n = npos) const + { return basic_string(*this, + _M_check(__pos, "basic_string::substr"), __n); } + + /** + * @brief Compare to a string. + * @param __str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a + * __str, 0 if their values are equivalent, or > 0 if this + * string is ordered after @a __str. Determines the effective + * length rlen of the strings to compare as the smallest of + * size() and str.size(). The function then compares the two + * strings by calling traits::compare(data(), str.data(),rlen). + * If the result of the comparison is nonzero returns it, + * otherwise the shorter one is ordered first. + */ + int + compare(const basic_string& __str) const + { + const size_type __size = this->size(); + const size_type __osize = __str.size(); + const size_type __len = std::min(__size, __osize); + + int __r = traits_type::compare(_M_data(), __str.data(), __len); + if (!__r) + __r = _S_compare(__size, __osize); + return __r; + } + + /** + * @brief Compare substring to a string. + * @param __pos Index of first character of substring. + * @param __n Number of characters in substring. + * @param __str String to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n characters + * starting at @a __pos. Returns an integer < 0 if the + * substring is ordered before @a __str, 0 if their values are + * equivalent, or > 0 if the substring is ordered after @a + * __str. Determines the effective length rlen of the strings + * to compare as the smallest of the length of the substring + * and @a __str.size(). The function then compares the two + * strings by calling + * traits::compare(substring.data(),str.data(),rlen). If the + * result of the comparison is nonzero returns it, otherwise + * the shorter one is ordered first. + */ + int + compare(size_type __pos, size_type __n, const basic_string& __str) const; + + /** + * @brief Compare substring to a substring. + * @param __pos1 Index of first character of substring. + * @param __n1 Number of characters in substring. + * @param __str String to compare against. + * @param __pos2 Index of first character of substring of str. + * @param __n2 Number of characters in substring of str. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n1 + * characters starting at @a __pos1. Form the substring of @a + * __str from the @a __n2 characters starting at @a __pos2. + * Returns an integer < 0 if this substring is ordered before + * the substring of @a __str, 0 if their values are equivalent, + * or > 0 if this substring is ordered after the substring of + * @a __str. Determines the effective length rlen of the + * strings to compare as the smallest of the lengths of the + * substrings. The function then compares the two strings by + * calling + * traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen). + * If the result of the comparison is nonzero returns it, + * otherwise the shorter one is ordered first. + */ + int + compare(size_type __pos1, size_type __n1, const basic_string& __str, + size_type __pos2, size_type __n2) const; + + /** + * @brief Compare to a C string. + * @param __s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Returns an integer < 0 if this string is ordered before @a __s, 0 if + * their values are equivalent, or > 0 if this string is ordered after + * @a __s. Determines the effective length rlen of the strings to + * compare as the smallest of size() and the length of a string + * constructed from @a __s. The function then compares the two strings + * by calling traits::compare(data(),s,rlen). If the result of the + * comparison is nonzero returns it, otherwise the shorter one is + * ordered first. + */ + int + compare(const _CharT* __s) const; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 5 String::compare specification questionable + /** + * @brief Compare substring to a C string. + * @param __pos Index of first character of substring. + * @param __n1 Number of characters in substring. + * @param __s C string to compare against. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n1 + * characters starting at @a pos. Returns an integer < 0 if + * the substring is ordered before @a __s, 0 if their values + * are equivalent, or > 0 if the substring is ordered after @a + * __s. Determines the effective length rlen of the strings to + * compare as the smallest of the length of the substring and + * the length of a string constructed from @a __s. The + * function then compares the two string by calling + * traits::compare(substring.data(),__s,rlen). If the result of + * the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s) const; + + /** + * @brief Compare substring against a character %array. + * @param __pos Index of first character of substring. + * @param __n1 Number of characters in substring. + * @param __s character %array to compare against. + * @param __n2 Number of characters of s. + * @return Integer < 0, 0, or > 0. + * + * Form the substring of this string from the @a __n1 + * characters starting at @a __pos. Form a string from the + * first @a __n2 characters of @a __s. Returns an integer < 0 + * if this substring is ordered before the string from @a __s, + * 0 if their values are equivalent, or > 0 if this substring + * is ordered after the string from @a __s. Determines the + * effective length rlen of the strings to compare as the + * smallest of the length of the substring and @a __n2. The + * function then compares the two strings by calling + * traits::compare(substring.data(),s,rlen). If the result of + * the comparison is nonzero returns it, otherwise the shorter + * one is ordered first. + * + * NB: s must have at least n2 characters, '\\0' has + * no special meaning. + */ + int + compare(size_type __pos, size_type __n1, const _CharT* __s, + size_type __n2) const; + }; +_GLIBCXX_END_NAMESPACE_CXX11 +#else // !_GLIBCXX_USE_CXX11_ABI + // Reference-counted COW string implentation + /** * @class basic_string basic_string.h * @brief Managing sequences of characters and character-like objects. @@ -2371,6 +4765,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION compare(size_type __pos, size_type __n1, const _CharT* __s, size_type __n2) const; }; +#endif // !_GLIBCXX_USE_CXX11_ABI // operator+ /** @@ -2419,7 +4814,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template inline basic_string<_CharT, _Traits, _Alloc> operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, - const _CharT* __rhs) + const _CharT* __rhs) { basic_string<_CharT, _Traits, _Alloc> __str(__lhs); __str.append(__rhs); @@ -2737,6 +5132,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_string<_CharT, _Traits, _Alloc>& __rhs) { __lhs.swap(__rhs); } + /** * @brief Read stream into a string. * @param __is Input stream. @@ -2852,6 +5248,7 @@ _GLIBCXX_END_NAMESPACE_VERSION namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // 21.4 Numeric Conversions [string.conversions]. inline int @@ -3058,6 +5455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace @@ -3147,21 +5545,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline namespace string_literals { + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string operator""s(const char* __str, size_t __len) { return basic_string{__str, __len}; } #ifdef _GLIBCXX_USE_WCHAR_T + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string operator""s(const wchar_t* __str, size_t __len) { return basic_string{__str, __len}; } #endif #ifdef _GLIBCXX_USE_C99_STDINT_TR1 + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string operator""s(const char16_t* __str, size_t __len) { return basic_string{__str, __len}; } + _GLIBCXX_DEFAULT_ABI_TAG inline basic_string operator""s(const char32_t* __str, size_t __len) { return basic_string{__str, __len}; } diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index f8907c0dd6a..30b3f4bd96e 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -33,6 +33,8 @@ // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers to ISO-14882. +// Non-reference-counted implementation written by Paolo Carlini and +// updated by Jonathan Wakely for ISO-14882-2011. #ifndef _BASIC_STRING_TCC #define _BASIC_STRING_TCC 1 @@ -45,6 +47,448 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if _GLIBCXX_USE_CXX11_ABI + + template + const typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>::npos; + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + swap(basic_string& __s) _GLIBCXX_NOEXCEPT + { + if (this == &__s) + return; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + // TODO propagation traits + std::__alloc_swap::_S_do_it(_M_get_allocator(), + __s._M_get_allocator()); + + if (_M_is_local()) + if (__s._M_is_local()) + { + if (length() && __s.length()) + { + _CharT __tmp_data[_S_local_capacity + 1]; + traits_type::copy(__tmp_data, __s._M_local_buf, + _S_local_capacity + 1); + traits_type::copy(__s._M_local_buf, _M_local_buf, + _S_local_capacity + 1); + traits_type::copy(_M_local_buf, __tmp_data, + _S_local_capacity + 1); + } + else if (__s.length()) + { + traits_type::copy(_M_local_buf, __s._M_local_buf, + _S_local_capacity + 1); + _M_length(__s.length()); + __s._M_set_length(0); + return; + } + else if (length()) + { + traits_type::copy(__s._M_local_buf, _M_local_buf, + _S_local_capacity + 1); + __s._M_length(length()); + _M_set_length(0); + return; + } + } + else + { + const size_type __tmp_capacity = __s._M_allocated_capacity; + traits_type::copy(__s._M_local_buf, _M_local_buf, + _S_local_capacity + 1); + _M_data(__s._M_data()); + __s._M_data(__s._M_local_buf); + _M_capacity(__tmp_capacity); + } + else + { + const size_type __tmp_capacity = _M_allocated_capacity; + if (__s._M_is_local()) + { + traits_type::copy(_M_local_buf, __s._M_local_buf, + _S_local_capacity + 1); + __s._M_data(_M_data()); + _M_data(_M_local_buf); + } + else + { + pointer __tmp_ptr = _M_data(); + _M_data(__s._M_data()); + __s._M_data(__tmp_ptr); + _M_capacity(__s._M_allocated_capacity); + } + __s._M_capacity(__tmp_capacity); + } + + const size_type __tmp_length = length(); + _M_length(__s.length()); + __s._M_length(__tmp_length); + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::pointer + basic_string<_CharT, _Traits, _Alloc>:: + _M_create(size_type& __capacity, size_type __old_capacity) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 83. String::npos vs. string::max_size() + if (__capacity > max_size()) + std::__throw_length_error(__N("basic_string::_M_create")); + + // The below implements an exponential growth policy, necessary to + // meet amortized linear time requirements of the library: see + // http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html. + if (__capacity > __old_capacity && __capacity < 2 * __old_capacity) + { + __capacity = 2 * __old_capacity; + // Never allocate a string bigger than max_size. + if (__capacity > max_size()) + __capacity = max_size(); + } + + // NB: Need an array of char_type[__capacity], plus a terminating + // null char_type() element. + return _Alloc_traits::allocate(_M_get_allocator(), __capacity + 1); + } + + // NB: This is the special case for Input Iterators, used in + // istreambuf_iterators, etc. + // Input Iterators have a cost structure very different from + // pointers, calling for a different coding style. + template + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::input_iterator_tag) + { + size_type __len = 0; + size_type __capacity = size_type(_S_local_capacity); + + while (__beg != __end && __len < __capacity) + { + _M_data()[__len++] = *__beg; + ++__beg; + } + + __try + { + while (__beg != __end) + { + if (__len == __capacity) + { + // Allocate more space. + __capacity = __len + 1; + pointer __another = _M_create(__capacity, __len); + this->_S_copy(__another, _M_data(), __len); + _M_dispose(); + _M_data(__another); + _M_capacity(__capacity); + } + _M_data()[__len++] = *__beg; + ++__beg; + } + } + __catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__len); + } + + template + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_construct(_InIterator __beg, _InIterator __end, + std::forward_iterator_tag) + { + // NB: Not required, but considered best practice. + if (__gnu_cxx::__is_null_pointer(__beg) && __beg != __end) + std::__throw_logic_error(__N("basic_string::" + "_M_construct null not valid")); + + size_type __dnew = static_cast(std::distance(__beg, __end)); + + if (__dnew > size_type(_S_local_capacity)) + { + _M_data(_M_create(__dnew, size_type(0))); + _M_capacity(__dnew); + } + + // Check for out_of_range and length_error exceptions. + __try + { this->_S_copy_chars(_M_data(), __beg, __end); } + __catch(...) + { + _M_dispose(); + __throw_exception_again; + } + + _M_set_length(__dnew); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_construct(size_type __n, _CharT __c) + { + if (__n > size_type(_S_local_capacity)) + { + _M_data(_M_create(__n, size_type(0))); + _M_capacity(__n); + } + + if (__n) + this->_S_assign(_M_data(), __n, __c); + + _M_set_length(__n); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_assign(const basic_string& __str) + { + if (this != &__str) + { + const size_type __rsize = __str.length(); + const size_type __capacity = capacity(); + + if (__rsize > __capacity) + { + size_type __new_capacity = __rsize; + pointer __tmp = _M_create(__new_capacity, __capacity); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__new_capacity); + } + + if (__rsize) + this->_S_copy(_M_data(), __str._M_data(), __rsize); + + _M_set_length(__rsize); + } + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + reserve(size_type __res) + { + // Make sure we don't shrink below the current size. + if (__res < length()) + __res = length(); + + const size_type __capacity = capacity(); + if (__res != __capacity) + { + if (__res > __capacity + || __res > size_type(_S_local_capacity)) + { + pointer __tmp = _M_create(__res, __capacity); + this->_S_copy(__tmp, _M_data(), length() + 1); + _M_dispose(); + _M_data(__tmp); + _M_capacity(__res); + } + else if (!_M_is_local()) + { + this->_S_copy(_M_local_data(), _M_data(), length() + 1); + _M_destroy(__capacity); + _M_data(_M_local_data()); + } + } + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_mutate(size_type __pos, size_type __len1, const _CharT* __s, + size_type __len2) + { + const size_type __how_much = length() - __pos - __len1; + + size_type __new_capacity = length() + __len2 - __len1; + pointer __r = _M_create(__new_capacity, capacity()); + + if (__pos) + this->_S_copy(__r, _M_data(), __pos); + if (__s && __len2) + this->_S_copy(__r + __pos, __s, __len2); + if (__how_much) + this->_S_copy(__r + __pos + __len2, + _M_data() + __pos + __len1, __how_much); + + _M_dispose(); + _M_data(__r); + _M_capacity(__new_capacity); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + _M_erase(size_type __pos, size_type __n) + { + const size_type __how_much = length() - __pos - __n; + + if (__how_much && __n) + this->_S_move(_M_data() + __pos, _M_data() + __pos + __n, __how_much); + + _M_set_length(length() - __n); + } + + template + void + basic_string<_CharT, _Traits, _Alloc>:: + resize(size_type __n, _CharT __c) + { + const size_type __size = this->size(); + if (__size < __n) + this->append(__n - __size, __c); + else if (__n < __size) + this->_M_erase(__n, __size - __n); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_append(const _CharT* __s, size_type __n) + { + const size_type __len = __n + this->size(); + + if (__len <= this->capacity()) + { + if (__n) + this->_S_copy(this->_M_data() + this->size(), __s, __n); + } + else + this->_M_mutate(this->size(), size_type(0), __s, __n); + + this->_M_set_length(__len); + return *this; + } + + template + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_dispatch(const_iterator __i1, const_iterator __i2, + _InputIterator __k1, _InputIterator __k2, + std::__false_type) + { + const basic_string __s(__k1, __k2); + const size_type __n1 = __i2 - __i1; + return _M_replace(__i1 - begin(), __n1, __s._M_data(), + __s.size()); + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2, + _CharT __c) + { + _M_check_length(__n1, __n2, "basic_string::_M_replace_aux"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __n2 - __n1; + + if (__new_size <= this->capacity()) + { + _CharT* __p = this->_M_data() + __pos1; + + const size_type __how_much = __old_size - __pos1 - __n1; + if (__how_much && __n1 != __n2) + this->_S_move(__p + __n2, __p + __n1, __how_much); + } + else + this->_M_mutate(__pos1, __n1, 0, __n2); + + if (__n2) + this->_S_assign(this->_M_data() + __pos1, __n2, __c); + + this->_M_set_length(__new_size); + return *this; + } + + template + basic_string<_CharT, _Traits, _Alloc>& + basic_string<_CharT, _Traits, _Alloc>:: + _M_replace(size_type __pos, size_type __len1, const _CharT* __s, + const size_type __len2) + { + _M_check_length(__len1, __len2, "basic_string::_M_replace"); + + const size_type __old_size = this->size(); + const size_type __new_size = __old_size + __len2 - __len1; + + if (__new_size <= this->capacity()) + { + _CharT* __p = this->_M_data() + __pos; + + const size_type __how_much = __old_size - __pos - __len1; + if (_M_disjunct(__s)) + { + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2) + this->_S_copy(__p, __s, __len2); + } + else + { + // Work in-place. + if (__len2 && __len2 <= __len1) + this->_S_move(__p, __s, __len2); + if (__how_much && __len1 != __len2) + this->_S_move(__p + __len2, __p + __len1, __how_much); + if (__len2 > __len1) + { + if (__s + __len2 <= __p + __len1) + this->_S_move(__p, __s, __len2); + else if (__s >= __p + __len1) + this->_S_copy(__p, __s + __len2 - __len1, __len2); + else + { + const size_type __nleft = (__p + __len1) - __s; + this->_S_move(__p, __s, __nleft); + this->_S_copy(__p + __nleft, __p + __len2, + __len2 - __nleft); + } + } + } + } + else + this->_M_mutate(__pos, __len1, __s, __len2); + + this->_M_set_length(__new_size); + return *this; + } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + _S_copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } + +#else // !_GLIBCXX_USE_CXX11_ABI + template const typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: @@ -686,6 +1130,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_copy(_M_data() + __pos1, __s, __n2); return *this; } + + template + typename basic_string<_CharT, _Traits, _Alloc>::size_type + basic_string<_CharT, _Traits, _Alloc>:: + copy(_CharT* __s, size_type __n, size_type __pos) const + { + _M_check(__pos, "basic_string::copy"); + __n = _M_limit(__pos, __n); + __glibcxx_requires_string_len(__s, __n); + if (__n) + _M_copy(__s, _M_data() + __pos, __n); + // 21.3.5.7 par 3: do not append null. (good.) + return __n; + } +#endif // !_GLIBCXX_USE_CXX11_ABI template basic_string<_CharT, _Traits, _Alloc> @@ -717,20 +1176,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __str; } - template - typename basic_string<_CharT, _Traits, _Alloc>::size_type - basic_string<_CharT, _Traits, _Alloc>:: - copy(_CharT* __s, size_type __n, size_type __pos) const - { - _M_check(__pos, "basic_string::copy"); - __n = _M_limit(__pos, __n); - __glibcxx_requires_string_len(__s, __n); - if (__n) - _M_copy(__s, _M_data() + __pos, __n); - // 21.3.5.7 par 3: do not append null. (good.) - return __n; - } - template typename basic_string<_CharT, _Traits, _Alloc>::size_type basic_string<_CharT, _Traits, _Alloc>:: diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 337f1e51c63..cffb065ce18 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -193,14 +193,30 @@ namespace std #endif } -// Use abi_tag("cxx11") +#define _GLIBCXX_USE_DUAL_ABI + +#if ! _GLIBCXX_USE_DUAL_ABI +// Ignore any pre-defined value of _GLIBCXX_USE_CXX11_ABI +# undef _GLIBCXX_USE_CXX11_ABI +#endif + #ifndef _GLIBCXX_USE_CXX11_ABI #define _GLIBCXX_USE_CXX11_ABI #endif #if _GLIBCXX_USE_CXX11_ABI +namespace std +{ + inline namespace __cxx11 __attribute__((abi_tag)) { } +} +# define _GLIBCXX_NAMESPACE_CXX11 __cxx11:: +# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 namespace __cxx11 { +# define _GLIBCXX_END_NAMESPACE_CXX11 } # define _GLIBCXX_DEFAULT_ABI_TAG _GLIBCXX_ABI_TAG_CXX11 #else +# define _GLIBCXX_NAMESPACE_CXX11 +# define _GLIBCXX_BEGIN_NAMESPACE_CXX11 +# define _GLIBCXX_END_NAMESPACE_CXX11 # define _GLIBCXX_DEFAULT_ABI_TAG #endif @@ -370,6 +386,15 @@ namespace std # define _GLIBCXX_BEGIN_NAMESPACE_LDBL # define _GLIBCXX_END_NAMESPACE_LDBL #endif +#if _GLIBCXX_USE_CXX11_ABI +# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_CXX11 +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_CXX11 +# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_CXX11 +#else +# define _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_NAMESPACE_LDBL +# define _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL +# define _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 _GLIBCXX_END_NAMESPACE_LDBL +#endif // Assert. #if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PARALLEL) diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h index 6dd452ad1ab..9c1f8e77b75 100644 --- a/libstdc++-v3/include/bits/locale_classes.h +++ b/libstdc++-v3/include/bits/locale_classes.h @@ -212,6 +212,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @brief Return locale name. * @return Locale name or "*" if unnamed. */ + _GLIBCXX_DEFAULT_ABI_TAG string name() const; @@ -321,6 +322,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void _M_coalesce(const locale& __base, const locale& __add, category __cat); + +#if _GLIBCXX_USE_CXX11_ABI + static const id* const _S_twinned_facets[]; +#endif }; @@ -419,6 +424,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION facet& operator=(const facet&); // Not defined. + + class __shim; + + const facet* _M_sso_shim(const id*) const; + const facet* _M_cow_shim(const id*) const; }; @@ -563,8 +573,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_init_facet(_Facet* __facet) { _M_install_facet(&_Facet::id, __facet); } + template + void + _M_init_facet_unchecked(_Facet* __facet) + { + __facet->_M_add_reference(); + _M_facets[_Facet::id._M_id()] = __facet; + } + void _M_install_cache(const facet*, size_t); + + void _M_init_extra(facet**); + void _M_init_extra(void*, void*, const char*, const char*); }; @@ -581,7 +602,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * collate facet. */ template - class collate : public locale::facet + class _GLIBCXX_NAMESPACE_CXX11 collate : public locale::facet { public: // Types: @@ -755,7 +776,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// class collate_byname [22.2.4.2]. template - class collate_byname : public collate<_CharT> + class _GLIBCXX_NAMESPACE_CXX11 collate_byname : public collate<_CharT> { public: //@{ diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 234693bd416..ce1ffae965a 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -54,8 +54,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // NB: Don't instantiate required wchar_t facets if no wchar_t support. #ifdef _GLIBCXX_USE_WCHAR_T # define _GLIBCXX_NUM_FACETS 28 +# define _GLIBCXX_NUM_CXX11_FACETS 16 #else # define _GLIBCXX_NUM_FACETS 14 +# define _GLIBCXX_NUM_CXX11_FACETS 8 #endif // Convert string to numeric value of type _Tp and store results. @@ -1623,6 +1625,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template numpunct. * @ingroup locales @@ -1896,6 +1900,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~numpunct_byname() { } }; +_GLIBCXX_END_NAMESPACE_CXX11 + _GLIBCXX_BEGIN_NAMESPACE_LDBL /** @@ -2107,11 +2113,13 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL /// Destructor. virtual ~num_get() { } + _GLIBCXX_DEFAULT_ABI_TAG iter_type _M_extract_float(iter_type, iter_type, ios_base&, ios_base::iostate&, string&) const; template + _GLIBCXX_DEFAULT_ABI_TAG iter_type _M_extract_int(iter_type, iter_type, ios_base&, ios_base::iostate&, _ValueT&) const; diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 200e099b2a5..3a4aedc1fb6 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -143,6 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_LDBL template + _GLIBCXX_DEFAULT_ABI_TAG _InIter num_get<_CharT, _InIter>:: _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, @@ -368,6 +369,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL template template + _GLIBCXX_DEFAULT_ABI_TAG _InIter num_get<_CharT, _InIter>:: _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, @@ -1290,8 +1292,8 @@ _GLIBCXX_END_NAMESPACE_LDBL // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. #if _GLIBCXX_EXTERN_TEMPLATE - extern template class numpunct; - extern template class numpunct_byname; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname; extern template class _GLIBCXX_NAMESPACE_LDBL num_get; extern template class _GLIBCXX_NAMESPACE_LDBL num_put; extern template class ctype_byname; @@ -1329,8 +1331,8 @@ _GLIBCXX_END_NAMESPACE_LDBL has_facet >(const locale&); #ifdef _GLIBCXX_USE_WCHAR_T - extern template class numpunct; - extern template class numpunct_byname; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct; + extern template class _GLIBCXX_NAMESPACE_CXX11 numpunct_byname; extern template class _GLIBCXX_NAMESPACE_LDBL num_get; extern template class _GLIBCXX_NAMESPACE_LDBL num_put; extern template class ctype_byname; diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.h b/libstdc++-v3/include/bits/locale_facets_nonio.h index 1b0aff9b5c5..9c629e240d7 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.h +++ b/libstdc++-v3/include/bits/locale_facets_nonio.h @@ -347,6 +347,8 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template time_get. * @ingroup locales @@ -694,6 +696,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~time_get_byname() { } }; +_GLIBCXX_END_NAMESPACE_CXX11 + /** * @brief Primary class template time_put. * @ingroup locales @@ -918,6 +922,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template moneypunct. * @ingroup locales @@ -1346,7 +1352,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template const bool moneypunct_byname<_CharT, _Intl>::intl; -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_CXX11 + +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 /** * @brief Primary class template money_get. @@ -1462,7 +1470,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL * value returned. @see get() for details. */ // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type __do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, double& __units) const; @@ -1484,7 +1493,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL ios_base::iostate& __err, string_type& __digits) const; // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io, ios_base::iostate& __err, long double& __units) const; @@ -1605,7 +1615,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL * @return Iterator after writing. */ // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, double __units) const; @@ -1639,7 +1650,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL const string_type& __digits) const; // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, long double __units) const; @@ -1654,7 +1666,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL template locale::id money_put<_CharT, _OutIter>::id; -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 /** * @brief Messages facet base class providing catalog typedef. @@ -1665,6 +1677,8 @@ _GLIBCXX_END_NAMESPACE_LDBL typedef int catalog; }; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + /** * @brief Primary class template messages. * @ingroup locales @@ -1886,6 +1900,8 @@ _GLIBCXX_END_NAMESPACE_LDBL { } }; +_GLIBCXX_END_NAMESPACE_CXX11 + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index 42c3504667e..200168da250 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -128,7 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template template @@ -348,7 +348,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL return __beg; } -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 template _InIter money_get<_CharT, _InIter>:: @@ -559,7 +560,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL return __s; } -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ + && _GLIBCXX_USE_CXX11_ABI == 0 template _OutIter money_put<_CharT, _OutIter>:: @@ -614,7 +616,7 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL { return __intl ? _M_insert(__s, __io, __fill, __digits) : _M_insert(__s, __io, __fill, __digits); } -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 // NB: Not especially useful. Without an ios_base object or some // kind of locale reference, we are left clawing at the air where @@ -1222,8 +1224,8 @@ _GLIBCXX_END_NAMESPACE_LDBL extern template class moneypunct; extern template class moneypunct_byname; extern template class moneypunct_byname; - extern template class _GLIBCXX_NAMESPACE_LDBL money_get; - extern template class _GLIBCXX_NAMESPACE_LDBL money_put; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put; extern template class __timepunct; extern template class time_put; extern template class time_put_byname; @@ -1297,8 +1299,8 @@ _GLIBCXX_END_NAMESPACE_LDBL extern template class moneypunct; extern template class moneypunct_byname; extern template class moneypunct_byname; - extern template class _GLIBCXX_NAMESPACE_LDBL money_get; - extern template class _GLIBCXX_NAMESPACE_LDBL money_put; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get; + extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put; extern template class __timepunct; extern template class time_put; extern template class time_put_byname; diff --git a/libstdc++-v3/include/bits/localefwd.h b/libstdc++-v3/include/bits/localefwd.h index 3025c226110..aa24a980d79 100644 --- a/libstdc++-v3/include/bits/localefwd.h +++ b/libstdc++-v3/include/bits/localefwd.h @@ -150,21 +150,27 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL template > class num_put; _GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class numpunct; template class numpunct_byname; +_GLIBCXX_END_NAMESPACE_CXX11 +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // 22.2.4 collation template class collate; - template class - collate_byname; + template + class collate_byname; +_GLIBCXX_END_NAMESPACE_CXX11 // 22.2.5 date and time class time_base; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template > class time_get; template > class time_get_byname; +_GLIBCXX_END_NAMESPACE_CXX11 template > class time_put; template > @@ -172,23 +178,27 @@ _GLIBCXX_END_NAMESPACE_LDBL // 22.2.6 money class money_base; -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template > class money_get; template > class money_put; -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class moneypunct; template class moneypunct_byname; +_GLIBCXX_END_NAMESPACE_CXX11 // 22.2.7 message retrieval class messages_base; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class messages; template class messages_byname; +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 80b1de85a49..acdac5e72eb 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -31,12 +31,14 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class basic_regex; template class match_results; +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION namespace __detail @@ -71,6 +73,7 @@ _GLIBCXX_END_NAMESPACE_VERSION } _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @addtogroup regex @@ -1939,6 +1942,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION match_results<_Bi_iter, _Alloc>& __rhs) { __lhs.swap(__rhs); } +_GLIBCXX_END_NAMESPACE_CXX11 + // [7.11.2] Function template regex_match /** * @name Matching, Searching, and Replacing @@ -2407,6 +2412,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION //@} +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + // std [28.12] Class template regex_iterator /** * An iterator adaptor that will provide repeated calls of regex_search over @@ -2770,6 +2777,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif //@} // group regex + +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 5f66afdaa50..7e8e85c162a 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -292,10 +292,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const _List_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT { return __x._M_node != __y._M_node; } - +_GLIBCXX_BEGIN_NAMESPACE_CXX11 /// See bits/stl_deque.h's _Deque_base for an explanation. template - class _GLIBCXX_DEFAULT_ABI_TAG _List_base + class _List_base { protected: // NOTA BENE @@ -504,7 +504,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * %empty. */ template > - class _GLIBCXX_DEFAULT_ABI_TAG list : protected _List_base<_Tp, _Alloc> + class list : protected _List_base<_Tp, _Alloc> { // concept requirements typedef typename _Alloc::value_type _Alloc_value_type; @@ -1790,6 +1790,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER __builtin_abort(); } }; +_GLIBCXX_END_NAMESPACE_CXX11 /** * @brief List equality comparison. diff --git a/libstdc++-v3/include/bits/stringfwd.h b/libstdc++-v3/include/bits/stringfwd.h index 132b88e4122..13cf027cfdb 100644 --- a/libstdc++-v3/include/bits/stringfwd.h +++ b/libstdc++-v3/include/bits/stringfwd.h @@ -52,35 +52,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct char_traits; + template<> struct char_traits; + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> struct char_traits; +#endif + +#if ((__cplusplus >= 201103L) \ + && defined(_GLIBCXX_USE_C99_STDINT_TR1)) + template<> struct char_traits; + template<> struct char_traits; +#endif + +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template, typename _Alloc = allocator<_CharT> > class basic_string; - template<> struct char_traits; - /// A string of @c char typedef basic_string string; #ifdef _GLIBCXX_USE_WCHAR_T - template<> struct char_traits; - /// A string of @c wchar_t typedef basic_string wstring; #endif #if ((__cplusplus >= 201103L) \ && defined(_GLIBCXX_USE_C99_STDINT_TR1)) - - template<> struct char_traits; - template<> struct char_traits; - /// A string of @c char16_t typedef basic_string u16string; /// A string of @c char32_t typedef basic_string u32string; - #endif + +_GLIBCXX_END_NAMESPACE_CXX11 + /** @} */ _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/iosfwd b/libstdc++-v3/include/std/iosfwd index ed8af5c48d6..c770adad28d 100644 --- a/libstdc++-v3/include/std/iosfwd +++ b/libstdc++-v3/include/std/iosfwd @@ -88,6 +88,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template > class basic_iostream; + +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template, typename _Alloc = allocator<_CharT> > class basic_stringbuf; @@ -104,6 +107,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Alloc = allocator<_CharT> > class basic_stringstream; +_GLIBCXX_END_NAMESPACE_CXX11 + template > class basic_filebuf; diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream index f074edaf2e1..a46e197e7fb 100644 --- a/libstdc++-v3/include/std/sstream +++ b/libstdc++-v3/include/std/sstream @@ -41,6 +41,7 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // [27.7.1] template class basic_stringbuf /** @@ -63,6 +64,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template class basic_stringbuf : public basic_streambuf<_CharT, _Traits> { + struct __xfer_bufptrs; public: // Types: typedef _CharT char_type; @@ -117,9 +119,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_stringbuf(const basic_stringbuf&) = delete; basic_stringbuf(basic_stringbuf&& __rhs) - : __streambuf_type(static_cast(__rhs)), - _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) - { __rhs._M_stringbuf_init(__rhs._M_mode); } + : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this)) + { __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); } // 27.8.2.2 Assign and swap: @@ -129,18 +130,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION basic_stringbuf& operator=(basic_stringbuf&& __rhs) { + __xfer_bufptrs __st{__rhs, this}; const __streambuf_type& __base = __rhs; __streambuf_type::operator=(__base); this->pubimbue(__rhs.getloc()); _M_mode = __rhs._M_mode; _M_string = std::move(__rhs._M_string); - __rhs._M_stringbuf_init(__rhs._M_mode); + __rhs._M_sync(const_cast(__rhs._M_string.data()), 0, 0); return *this; } void swap(basic_stringbuf& __rhs) { + __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; + __xfer_bufptrs __r_st{__rhs, this}; __streambuf_type& __base = __rhs; __streambuf_type::swap(__base); __rhs.pubimbue(this->pubimbue(__rhs.getloc())); @@ -185,7 +189,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void str(const __string_type& __s) { - // Cannot use _M_string = __s, since v3 strings are COW. + // Cannot use _M_string = __s, since v3 strings are COW + // (not always true now but assign() always works). _M_string.assign(__s.data(), __s.size()); _M_stringbuf_init(_M_mode); } @@ -286,6 +291,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // interface of basic_streambuf, taking just an int. void _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); + + private: +#if __cplusplus >= 201103L +#if _GLIBCXX_USE_CXX11_ABI + // This type captures the state of the gptr / pptr pointers as offsets + // so they can be restored in another object after moving the string. + struct __xfer_bufptrs + { + __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to) + : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1} + { + const _CharT* __str = __from._M_string.data(); + if (__from.eback()) + { + _M_goff[0] = __from.eback() - __str; + _M_goff[1] = __from.gptr() - __str; + _M_goff[2] = __from.egptr() - __str; + } + if (__from.pbase()) + { + _M_poff[0] = __from.pbase() - __str; + _M_poff[1] = __from.pptr() - __from.pbase(); + _M_poff[2] = __from.epptr() - __str; + } + } + + ~__xfer_bufptrs() + { + char_type* __str = const_cast(_M_to->_M_string.data()); + if (_M_goff[0] != -1) + _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]); + if (_M_poff[0] != -1) + _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]); + } + + basic_stringbuf* _M_to; + off_type _M_goff[3]; + off_type _M_poff[3]; + }; +#else + // This type does nothing when using Copy-On-Write strings. + struct __xfer_bufptrs + { + __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { } + }; +#endif + + // The move constructor initializes an __xfer_bufptrs temporary then + // delegates to this constructor to performs moves during its lifetime. + basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&) + : __streambuf_type(static_cast(__rhs)), + _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) + { } +#endif }; @@ -747,6 +806,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __x.swap(__y); } #endif +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept index ff18405eb26..c927f0539bb 100644 --- a/libstdc++-v3/include/std/stdexcept +++ b/libstdc++-v3/include/std/stdexcept @@ -42,6 +42,64 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#if _GLIBCXX_USE_DUAL_ABI +#if _GLIBCXX_USE_CXX11_ABI + // Emulates an old COW string when the new std::string is in use. + struct __cow_string + { + union { + const char* _M_p; + char _M_bytes[sizeof(_M_p)]; + }; + + __cow_string(); + __cow_string(const std::string&); + __cow_string(const char*, size_t); + __cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; + __cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT; + ~__cow_string(); +#if __cplusplus >= 201103L + __cow_string(__cow_string&&) noexcept; + __cow_string& operator=(__cow_string&&) noexcept; +#endif + }; + + typedef basic_string __sso_string; +#else // _GLIBCXX_USE_CXX11_ABI + typedef basic_string __cow_string; + + // Emulates a new SSO string when the old std::string is in use. + struct __sso_string + { + struct __str + { + const char* _M_p; + size_t _M_string_length; + char _M_local_buf[16]; + }; + + union { + __str _M_s; + char _M_bytes[sizeof(_M_s)]; + }; + + __sso_string() _GLIBCXX_USE_NOEXCEPT; + __sso_string(const std::string&); + __sso_string(const char*, size_t); + __sso_string(const __sso_string&); + __sso_string& operator=(const __sso_string&); + ~__sso_string(); +#if __cplusplus >= 201103L + __sso_string(__sso_string&&) noexcept; + __sso_string& operator=(__sso_string&&) noexcept; +#endif + }; +#endif // _GLIBCXX_USE_CXX11_ABI +#else // _GLIBCXX_USE_DUAL_ABI + typedef basic_string __sso_string; + typedef basic_string __cow_string; +#endif + /** * @addtogroup exceptions * @{ @@ -54,13 +112,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ class logic_error : public exception { - string _M_msg; + __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit logic_error(const string& __arg); +#if __cplusplus >= 201103L + explicit + logic_error(const char*); +#endif + +#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS + logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT; + logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT; +#endif + virtual ~logic_error() _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of @@ -75,6 +143,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit domain_error(const string& __arg); +#if __cplusplus >= 201103L + explicit domain_error(const char*); +#endif virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -83,6 +154,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit invalid_argument(const string& __arg); +#if __cplusplus >= 201103L + explicit invalid_argument(const char*); +#endif virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT; }; @@ -92,6 +166,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit length_error(const string& __arg); +#if __cplusplus >= 201103L + explicit length_error(const char*); +#endif virtual ~length_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -101,6 +178,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit out_of_range(const string& __arg); +#if __cplusplus >= 201103L + explicit out_of_range(const char*); +#endif virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT; }; @@ -111,13 +191,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ class runtime_error : public exception { - string _M_msg; + __cow_string _M_msg; public: /** Takes a character string describing the error. */ explicit runtime_error(const string& __arg); +#if __cplusplus >= 201103L + explicit + runtime_error(const char*); +#endif + +#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS + runtime_error(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; + runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT; +#endif + virtual ~runtime_error() _GLIBCXX_USE_NOEXCEPT; /** Returns a C-style character string describing the general cause of @@ -131,6 +221,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit range_error(const string& __arg); +#if __cplusplus >= 201103L + explicit range_error(const char*); +#endif virtual ~range_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -139,6 +232,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit overflow_error(const string& __arg); +#if __cplusplus >= 201103L + explicit overflow_error(const char*); +#endif virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT; }; @@ -147,6 +243,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { public: explicit underflow_error(const string& __arg); +#if __cplusplus >= 201103L + explicit underflow_error(const char*); +#endif virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT; }; diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error index ed17f554bca..786445e1c53 100644 --- a/libstdc++-v3/include/std/system_error +++ b/libstdc++-v3/include/std/system_error @@ -46,7 +46,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class error_code; class error_condition; - class error_category; class system_error; /// is_error_code_enum @@ -61,16 +60,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct is_error_condition_enum : public true_type { }; + inline namespace _V2 { /// error_category class error_category { public: -#ifdef _GLIBCXX_COMPATIBILITY_CXX0X - error_category() noexcept; -#else constexpr error_category() noexcept = default; -#endif virtual ~error_category(); @@ -80,9 +76,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION virtual const char* name() const noexcept = 0; + // We need two different virtual functions here, one returning a + // COW string and one returning an SSO string. Their positions in the + // vtable must be consistent for dynamic dispatch to work, but which one + // the name "message()" finds depends on which ABI the caller is using. +#if _GLIBCXX_USE_CXX11_ABI + private: + _GLIBCXX_DEFAULT_ABI_TAG + virtual __cow_string + _M_message(int) const; + + public: + _GLIBCXX_DEFAULT_ABI_TAG + virtual string + message(int) const = 0; +#else virtual string message(int) const = 0; + private: + virtual __sso_string + _M_message(int) const; +#endif + + public: virtual error_condition default_error_condition(int __i) const noexcept; @@ -109,6 +126,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_CONST const error_category& system_category() noexcept; _GLIBCXX_CONST const error_category& generic_category() noexcept; + } // end inline namespace + error_code make_error_code(errc) noexcept; template @@ -156,6 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION error_condition default_error_condition() const noexcept; + _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } @@ -231,6 +251,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const error_category& category() const noexcept { return *_M_cat; } + _GLIBCXX_DEFAULT_ABI_TAG string message() const { return category().message(value()); } diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in index 1c7270a69d3..9a1d725e360 100644 --- a/libstdc++-v3/libsupc++/Makefile.in +++ b/libstdc++-v3/libsupc++/Makefile.in @@ -280,6 +280,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in index 52f5256a6ce..46538de3ffc 100644 --- a/libstdc++-v3/po/Makefile.in +++ b/libstdc++-v3/po/Makefile.in @@ -216,6 +216,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in index 7d0c8ac413e..739edcb9126 100644 --- a/libstdc++-v3/python/Makefile.in +++ b/libstdc++-v3/python/Makefile.in @@ -240,6 +240,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 48ecb678cf3..cf5c3f1c480 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -660,6 +660,7 @@ class StdStringPrinter: def __init__(self, typename, val): self.val = val + self.new_string = typename.find("::__cxx11::basic_string") != -1 def to_string(self): # Make sure &string works, too. @@ -671,13 +672,18 @@ class StdStringPrinter: # the string according to length, not according to first null # encountered. ptr = self.val ['_M_dataplus']['_M_p'] - realtype = type.unqualified ().strip_typedefs () - reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer () - header = ptr.cast(reptype) - 1 - len = header.dereference ()['_M_length'] + if self.new_string: + length = self.val['_M_string_length'] + # https://sourceware.org/bugzilla/show_bug.cgi?id=17728 + ptr = ptr.cast(ptr.type.strip_typedefs()) + else: + realtype = type.unqualified ().strip_typedefs () + reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer () + header = ptr.cast(reptype) - 1 + length = header.dereference ()['_M_length'] if hasattr(ptr, "lazy_string"): - return ptr.lazy_string (length = len) - return ptr.string (length = len) + return ptr.lazy_string (length = length) + return ptr.string (length = length) def display_hint (self): return 'string' @@ -1266,6 +1272,7 @@ def build_libstdcxx_dictionary (): # In order from: # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html libstdcxx_printer.add_version('std::', 'basic_string', StdStringPrinter) + libstdcxx_printer.add_version('std::', '__cxx11::basic_string', StdStringPrinter) libstdcxx_printer.add_container('std::', 'bitset', StdBitsetPrinter) libstdcxx_printer.add_container('std::', 'deque', StdDequePrinter) libstdcxx_printer.add_container('std::', 'list', StdListPrinter) diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index cd3943b1afc..d1b5ab21fe4 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -267,6 +267,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am index 71306db4b00..c4345af34a6 100644 --- a/libstdc++-v3/src/c++11/Makefile.am +++ b/libstdc++-v3/src/c++11/Makefile.am @@ -39,9 +39,14 @@ ctype_configure_char.cc: ${glibcxx_srcdir}/$(OS_INC_SRCDIR)/ctype_configure_char ctype_members.cc: ${glibcxx_srcdir}/$(CCTYPE_CC) $(LN_S) ${glibcxx_srcdir}/$(CCTYPE_CC) . || true -if ENABLE_CXX11_ABI +if ENABLE_DUAL_ABI cxx11_abi_sources = \ - cxx11-ios_failure.cc + cow-locale_init.cc \ + cow-shim_facets.cc \ + cxx11-hash_tr1.cc \ + cxx11-ios_failure.cc \ + cxx11-shim_facets.cc \ + cxx11-stdexcept.cc else cxx11_abi_sources = endif @@ -49,6 +54,7 @@ endif sources = \ chrono.cc \ condition_variable.cc \ + cow-stdexcept.cc \ ctype.cc \ debug.cc \ functexcept.cc \ @@ -69,9 +75,22 @@ sources = \ ${cxx11_abi_sources} \ ${host_sources} +if ENABLE_DUAL_ABI +extra_string_inst_sources = \ + cow-fstream-inst.cc \ + cow-sstream-inst.cc \ + cow-string-inst.cc \ + cow-wstring-inst.cc \ + cxx11-locale-inst.cc \ + cxx11-wlocale-inst.cc +else +extra_string_inst_sources = +endif + if ENABLE_EXTERN_TEMPLATE # XTEMPLATE_FLAGS = -fno-implicit-templates inst_sources = \ + $(extra_string_inst_sources) \ ext11-inst.cc \ fstream-inst.cc \ ios-inst.cc \ diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in index dd9e110f768..2ce23f9e497 100644 --- a/libstdc++-v3/src/c++11/Makefile.in +++ b/libstdc++-v3/src/c++11/Makefile.in @@ -67,20 +67,28 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libc__11convenience_la_LIBADD = -@ENABLE_CXX11_ABI_TRUE@am__objects_1 = cxx11-ios_failure.lo +@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-locale_init.lo \ +@ENABLE_DUAL_ABI_TRUE@ cow-shim_facets.lo cxx11-hash_tr1.lo \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-ios_failure.lo \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-shim_facets.lo cxx11-stdexcept.lo am__objects_2 = ctype_configure_char.lo ctype_members.lo -am__objects_3 = chrono.lo condition_variable.lo ctype.lo debug.lo \ - functexcept.lo functional.lo future.lo hash_c++0x.lo \ - hashtable_c++0x.lo ios.lo limits.lo mutex.lo placeholders.lo \ - random.lo regex.lo shared_ptr.lo snprintf_lite.lo \ - system_error.lo thread.lo $(am__objects_1) $(am__objects_2) -@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = ext11-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ fstream-inst.lo ios-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ iostream-inst.lo istream-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ ostream-inst.lo sstream-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ streambuf-inst.lo string-inst.lo \ -@ENABLE_EXTERN_TEMPLATE_TRUE@ wstring-inst.lo -am_libc__11convenience_la_OBJECTS = $(am__objects_3) $(am__objects_4) +am__objects_3 = chrono.lo condition_variable.lo cow-stdexcept.lo \ + ctype.lo debug.lo functexcept.lo functional.lo future.lo \ + hash_c++0x.lo hashtable_c++0x.lo ios.lo limits.lo mutex.lo \ + placeholders.lo random.lo regex.lo shared_ptr.lo \ + snprintf_lite.lo system_error.lo thread.lo $(am__objects_1) \ + $(am__objects_2) +@ENABLE_DUAL_ABI_TRUE@am__objects_4 = cow-fstream-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@ cow-sstream-inst.lo cow-string-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@ cow-wstring-inst.lo cxx11-locale-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-wlocale-inst.lo +@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_5 = $(am__objects_4) \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ ext11-inst.lo fstream-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ ios-inst.lo iostream-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ istream-inst.lo ostream-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ sstream-inst.lo streambuf-inst.lo \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ string-inst.lo wstring-inst.lo +am_libc__11convenience_la_OBJECTS = $(am__objects_3) $(am__objects_5) libc__11convenience_la_OBJECTS = $(am_libc__11convenience_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = @@ -240,6 +248,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ @@ -323,13 +332,19 @@ host_sources = \ ctype_configure_char.cc \ ctype_members.cc -@ENABLE_CXX11_ABI_FALSE@cxx11_abi_sources = -@ENABLE_CXX11_ABI_TRUE@cxx11_abi_sources = \ -@ENABLE_CXX11_ABI_TRUE@ cxx11-ios_failure.cc +@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = +@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \ +@ENABLE_DUAL_ABI_TRUE@ cow-locale_init.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-shim_facets.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-hash_tr1.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-ios_failure.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-shim_facets.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-stdexcept.cc sources = \ chrono.cc \ condition_variable.cc \ + cow-stdexcept.cc \ ctype.cc \ debug.cc \ functexcept.cc \ @@ -350,11 +365,21 @@ sources = \ ${cxx11_abi_sources} \ ${host_sources} +@ENABLE_DUAL_ABI_FALSE@extra_string_inst_sources = +@ENABLE_DUAL_ABI_TRUE@extra_string_inst_sources = \ +@ENABLE_DUAL_ABI_TRUE@ cow-fstream-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-sstream-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-string-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cow-wstring-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-locale-inst.cc \ +@ENABLE_DUAL_ABI_TRUE@ cxx11-wlocale-inst.cc + # XTEMPLATE_FLAGS = @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = # XTEMPLATE_FLAGS = -fno-implicit-templates @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \ +@ENABLE_EXTERN_TEMPLATE_TRUE@ $(extra_string_inst_sources) \ @ENABLE_EXTERN_TEMPLATE_TRUE@ ext11-inst.cc \ @ENABLE_EXTERN_TEMPLATE_TRUE@ fstream-inst.cc \ @ENABLE_EXTERN_TEMPLATE_TRUE@ ios-inst.cc \ diff --git a/libstdc++-v3/src/c++11/compatibility-c++0x.cc b/libstdc++-v3/src/c++11/compatibility-c++0x.cc index 3c83561e703..a5546607c54 100644 --- a/libstdc++-v3/src/c++11/compatibility-c++0x.cc +++ b/libstdc++-v3/src/c++11/compatibility-c++0x.cc @@ -23,8 +23,18 @@ // . #define _GLIBCXX_COMPATIBILITY_CXX0X +#define _GLIBCXX_USE_CXX11_ABI 0 +#define error_category error_categoryxx +#define system_category system_categoryxx +#define generic_category generic_categoryxx +#define _V2 _V2xx #include #include +#include +#undef error_category +#undef system_category +#undef generic_category +#undef _V2 #if __cplusplus < 201103L # error "compatibility-c++0x.cc must be compiled with -std=gnu++0x" @@ -120,9 +130,125 @@ namespace std _GLIBCXX_VISIBILITY(default) constexpr bool system_clock::is_monotonic; } // namespace chrono + // gcc-5 replaces this with _V2::error_category + class error_category + { + public: + error_category() noexcept; + + virtual ~error_category(); + + error_category(const error_category&) = delete; + error_category& operator=(const error_category&) = delete; + + virtual const char* + name() const noexcept = 0; + + virtual string + message(int) const = 0; + + virtual error_condition + default_error_condition(int __i) const noexcept; + + virtual bool + equivalent(int __i, const error_condition& __cond) const noexcept; + + virtual bool + equivalent(const error_code& __code, int __i) const noexcept; + + bool + operator<(const error_category& __other) const noexcept + { return less()(this, &__other); } + + bool + operator==(const error_category& __other) const noexcept + { return this == &__other; } + + bool + operator!=(const error_category& __other) const noexcept + { return this != &__other; } + }; + // gcc-4.9.0 // LWG 2145 changes this constructor to constexpr i.e. inline error_category::error_category() noexcept = default; -} + error_category::~error_category() noexcept = default; + + namespace + { + using std::string; + + struct generic_error_category : public std::error_category + { + virtual const char* + name() const noexcept + { return "generic"; } + + virtual string + message(int i) const + { + // XXX locale issues: how does one get or set loc. + // _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc) + return string(strerror(i)); + } + }; + + struct system_error_category : public std::error_category + { + virtual const char* + name() const noexcept + { return "system"; } + + virtual string + message(int i) const + { + // XXX locale issues: how does one get or set loc. + // _GLIBCXX_HAVE_STRERROR_L, strerror_l(i, cloc) + return string(strerror(i)); + } + }; + + const generic_error_category generic_category_instance{}; + const system_error_category system_category_instance{}; + } + + const error_category& + system_category() noexcept { return system_category_instance; } + + const error_category& + generic_category() noexcept { return generic_category_instance; } + + namespace _V2 + { + _GLIBCXX_CONST const error_categoryxx& system_category() noexcept; + _GLIBCXX_CONST const error_categoryxx& generic_category() noexcept; + } + + error_condition + error_category::default_error_condition(int __i) const noexcept + { + if (*this == system_category()) + return error_condition(__i, _V2::system_category()); + return error_condition(__i, _V2::generic_category()); + } + + bool + error_category::equivalent(int __i, + const error_condition& __cond) const noexcept + { return default_error_condition(__i) == __cond; } + + bool + error_category::equivalent(const error_code& __code, int __i) const noexcept + { + if (*this == system_category() + && __code.category() == _V2::system_category()) + return __code.value() == __i; + if (*this == generic_category() + && __code.category() == _V2::generic_category()) + return __code.value() == __i; + return false; + } + +} #endif diff --git a/libstdc++-v3/src/c++11/cow-fstream-inst.cc b/libstdc++-v3/src/c++11/cow-fstream-inst.cc new file mode 100644 index 00000000000..8e373683bb7 --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-fstream-inst.cc @@ -0,0 +1,78 @@ +// Explicit instantiation file. + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template basic_filebuf* + basic_filebuf::open(const std::string&, ios_base::openmode); + template + basic_ifstream:: + basic_ifstream(const std::string&, ios_base::openmode); + template void + basic_ifstream::open(const std::string&, ios_base::openmode); + template + basic_ofstream:: + basic_ofstream(const std::string&, ios_base::openmode); + template void + basic_ofstream::open(const std::string&, ios_base::openmode); + template + basic_fstream::basic_fstream(const std::string&, ios_base::openmode); + template void + basic_fstream::open(const std::string&, ios_base::openmode); + +#ifdef _GLIBCXX_USE_WCHAR_T + template basic_filebuf* + basic_filebuf::open(const std::string&, ios_base::openmode); + template + basic_ifstream:: + basic_ifstream(const std::string&, ios_base::openmode); + template void + basic_ifstream::open(const std::string&, ios_base::openmode); + template + basic_ofstream:: + basic_ofstream(const std::string&, ios_base::openmode); + template void + basic_ofstream::open(const std::string&, ios_base::openmode); + template + basic_fstream:: + basic_fstream(const std::string&, ios_base::openmode); + template void + basic_fstream::open(const std::string&, ios_base::openmode); +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++11/cow-locale_init.cc b/libstdc++-v3/src/c++11/cow-locale_init.cc new file mode 100644 index 00000000000..f48af64c27d --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-locale_init.cc @@ -0,0 +1,194 @@ +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// Instantiate the facets using old std::string ABI. +#define _GLIBCXX_USE_CXX11_ABI 0 +#include + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace +{ + typedef char fake_collate_c[sizeof(std::collate)] + __attribute__ ((aligned(__alignof__(std::collate)))); + fake_collate_c collate_c; + + typedef char fake_numpunct_c[sizeof(numpunct)] + __attribute__ ((aligned(__alignof__(numpunct)))); + fake_numpunct_c numpunct_c; + + typedef char fake_moneypunct_c[sizeof(moneypunct)] + __attribute__ ((aligned(__alignof__(moneypunct)))); + fake_moneypunct_c moneypunct_ct; + fake_moneypunct_c moneypunct_cf; + + typedef char fake_money_get_c[sizeof(money_get)] + __attribute__ ((aligned(__alignof__(money_get)))); + fake_money_get_c money_get_c; + + typedef char fake_money_put_c[sizeof(money_put)] + __attribute__ ((aligned(__alignof__(money_put)))); + fake_money_put_c money_put_c; + + typedef char fake_time_get_c[sizeof(time_get)] + __attribute__ ((aligned(__alignof__(time_get)))); + fake_time_get_c time_get_c; + + typedef char fake_messages_c[sizeof(messages)] + __attribute__ ((aligned(__alignof__(messages)))); + fake_messages_c messages_c; + +#ifdef _GLIBCXX_USE_WCHAR_T + typedef char fake_wollate_w[sizeof(std::collate)] + __attribute__ ((aligned(__alignof__(std::collate)))); + fake_wollate_w collate_w; + + typedef char fake_numpunct_w[sizeof(numpunct)] + __attribute__ ((aligned(__alignof__(numpunct)))); + fake_numpunct_w numpunct_w; + + typedef char fake_moneypunct_w[sizeof(moneypunct)] + __attribute__ ((aligned(__alignof__(moneypunct)))); + fake_moneypunct_w moneypunct_wt; + fake_moneypunct_w moneypunct_wf; + + typedef char fake_money_get_w[sizeof(money_get)] + __attribute__ ((aligned(__alignof__(money_get)))); + fake_money_get_w money_get_w; + + typedef char fake_money_put_w[sizeof(money_put)] + __attribute__ ((aligned(__alignof__(money_put)))); + fake_money_put_w money_put_w; + + typedef char fake_time_get_w[sizeof(time_get)] + __attribute__ ((aligned(__alignof__(time_get)))); + fake_time_get_w time_get_w; + + typedef char fake_messages_w[sizeof(messages)] + __attribute__ ((aligned(__alignof__(messages)))); + fake_messages_w messages_w; +#endif +} // anonymous namespace + + void + locale::_Impl::_M_init_extra(facet** caches) + { + auto __npc = static_cast<__numpunct_cache*>(caches[0]); + auto __mpcf = static_cast<__moneypunct_cache*>(caches[1]); + auto __mpct = static_cast<__moneypunct_cache*>(caches[2]); + + _M_init_facet_unchecked(new (&numpunct_c) numpunct(__npc, 1)); + _M_init_facet_unchecked(new (&collate_c) std::collate(1)); + _M_init_facet_unchecked(new (&moneypunct_cf) moneypunct(__mpcf, 1)); + _M_init_facet_unchecked(new (&moneypunct_ct) moneypunct(__mpct, 1)); + _M_init_facet_unchecked(new (&money_get_c) money_get(1)); + _M_init_facet_unchecked(new (&money_put_c) money_put(1)); + _M_init_facet_unchecked(new (&time_get_c) time_get(1)); + _M_init_facet_unchecked(new (&messages_c) std::messages(1)); +#ifdef _GLIBCXX_USE_WCHAR_T + auto __npw = static_cast<__numpunct_cache*>(caches[3]); + auto __mpwf = static_cast<__moneypunct_cache*>(caches[4]); + auto __mpwt = static_cast<__moneypunct_cache*>(caches[5]); + + _M_init_facet_unchecked(new (&numpunct_w) numpunct(__npw, 1)); + _M_init_facet_unchecked(new (&collate_w) std::collate(1)); + _M_init_facet_unchecked(new (&moneypunct_wf) moneypunct(__mpwf, 1)); + _M_init_facet_unchecked(new (&moneypunct_wt) moneypunct(__mpwt, 1)); + _M_init_facet_unchecked(new (&money_get_w) money_get(1)); + _M_init_facet_unchecked(new (&money_put_w) money_put(1)); + _M_init_facet_unchecked(new (&time_get_w) time_get(1)); + _M_init_facet_unchecked(new (&messages_w) std::messages(1)); +#endif + + _M_caches[numpunct::id._M_id()] = __npc; + _M_caches[moneypunct::id._M_id()] = __mpcf; + _M_caches[moneypunct::id._M_id()] = __mpct; +#ifdef _GLIBCXX_USE_WCHAR_T + _M_caches[numpunct::id._M_id()] = __npw; + _M_caches[moneypunct::id._M_id()] = __mpwf; + _M_caches[moneypunct::id._M_id()] = __mpwt; +#endif + } + + void + locale::_Impl::_M_init_extra(void* cloc, void* clocm, + const char* __s, const char* __smon) + { + auto& __cloc = *static_cast<__c_locale*>(cloc); + + _M_init_facet_unchecked(new numpunct(__cloc)); + _M_init_facet_unchecked(new std::collate(__cloc)); + _M_init_facet_unchecked(new moneypunct(__cloc, 0)); + _M_init_facet_unchecked(new moneypunct(__cloc, 0)); + _M_init_facet_unchecked(new money_get); + _M_init_facet_unchecked(new money_put); + _M_init_facet_unchecked(new time_get); + _M_init_facet_unchecked(new std::messages(__cloc, __s)); + +#ifdef _GLIBCXX_USE_WCHAR_T + auto& __clocm = *static_cast<__c_locale*>(clocm); + + _M_init_facet_unchecked(new numpunct(__cloc)); + _M_init_facet_unchecked(new std::collate(__cloc)); + _M_init_facet_unchecked(new moneypunct(__clocm, __smon)); + _M_init_facet_unchecked(new moneypunct(__clocm, __smon)); + _M_init_facet_unchecked(new money_get); + _M_init_facet_unchecked(new money_put); + _M_init_facet_unchecked(new time_get); + _M_init_facet_unchecked(new std::messages(__cloc, __s)); +#endif + } + +// TODO should be in another file + string + locale::name() const + { + string __ret; + if (!_M_impl->_M_names[0]) + __ret = '*'; + else if (_M_impl->_M_check_same_name()) + __ret = _M_impl->_M_names[0]; + else + { + __ret.reserve(128); + __ret += _S_categories[0]; + __ret += '='; + __ret += _M_impl->_M_names[0]; + for (size_t __i = 1; __i < _S_categories_size; ++__i) + { + __ret += ';'; + __ret += _S_categories[__i]; + __ret += '='; + __ret += _M_impl->_M_names[__i]; + } + } + return __ret; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} diff --git a/libstdc++-v3/src/c++11/cow-shim_facets.cc b/libstdc++-v3/src/c++11/cow-shim_facets.cc new file mode 100644 index 00000000000..1373f4b2dcc --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-shim_facets.cc @@ -0,0 +1,35 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file bits/locale_classes.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{locale} + */ + +// +// ISO C++ 14882: 22.1 Locales +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "cxx11-shim_facets.cc" diff --git a/libstdc++-v3/src/c++11/cow-sstream-inst.cc b/libstdc++-v3/src/c++11/cow-sstream-inst.cc new file mode 100644 index 00000000000..fdd57aa32c9 --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-sstream-inst.cc @@ -0,0 +1,34 @@ +// Explicit instantiation file. + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "sstream-inst.cc" + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc new file mode 100644 index 00000000000..1bec98c372e --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc @@ -0,0 +1,153 @@ +// Methods for Exception Support for -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 19.1 Exception classes +// + +// All exception classes still use the classic COW std::string. +#define _GLIBCXX_USE_CXX11_ABI 0 +#define _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS 1 +#define __cow_string __cow_stringxxx +#include +#include +#undef __cow_string + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // Copy constructors and assignment operators defined using COW std::string + + logic_error::logic_error(const logic_error& e) noexcept + : _M_msg(e._M_msg) { } + + logic_error& logic_error::operator=(const logic_error& e) noexcept + { _M_msg = e._M_msg; return *this; } + + runtime_error::runtime_error(const runtime_error& e) noexcept + : _M_msg(e._M_msg) { } + + runtime_error& + runtime_error::operator=(const runtime_error& e) noexcept + { _M_msg = e._M_msg; return *this; } + + // New C++11 constructors: + + logic_error::logic_error(const char* __arg) + : exception(), _M_msg(__arg) { } + + domain_error::domain_error(const char* __arg) + : logic_error(__arg) { } + + invalid_argument::invalid_argument(const char* __arg) + : logic_error(__arg) { } + + length_error::length_error(const char* __arg) + : logic_error(__arg) { } + + out_of_range::out_of_range(const char* __arg) + : logic_error(__arg) { } + + runtime_error::runtime_error(const char* __arg) + : exception(), _M_msg(__arg) { } + + range_error::range_error(const char* __arg) + : runtime_error(__arg) { } + + overflow_error::overflow_error(const char* __arg) + : runtime_error(__arg) { } + + underflow_error::underflow_error(const char* __arg) + : runtime_error(__arg) { } + +#if _GLIBCXX_USE_DUAL_ABI + // Converting constructor from COW std::string to SSO string. + __sso_string::__sso_string(const string& s) + : __sso_string(s.c_str(), s.length()) { } + + // Redefine __cow_string so that we can define and export its members + // in terms of the COW std::string. + struct __cow_string + { + union { + const char* _M_p; + char _M_bytes[sizeof(_M_p)]; + std::string _M_str; + }; + + __cow_string(); + __cow_string(const std::string& s); + __cow_string(const char*, size_t n); + __cow_string(const __cow_string&) noexcept; + __cow_string& operator=(const __cow_string&) noexcept; + ~__cow_string(); + __cow_string(__cow_string&&) noexcept; + __cow_string& operator=(__cow_string&&) noexcept; + }; + + __cow_string::__cow_string() : _M_str() { } + + __cow_string::__cow_string(const std::string& s) : _M_str(s) { } + + __cow_string::__cow_string(const char* s, size_t n) : _M_str(s, n) { } + + __cow_string::__cow_string(const __cow_string& s) noexcept + : _M_str(s._M_str) { } + + __cow_string& + __cow_string::operator=(const __cow_string& s) noexcept + { + _M_str = s._M_str; + return *this; + } + + __cow_string::~__cow_string() { _M_str.~basic_string(); } + + __cow_string::__cow_string(__cow_string&& s) noexcept + : _M_str(std::move(s._M_str)) { } + + __cow_string& + __cow_string::operator=(__cow_string&& s) noexcept + { + _M_str = std::move(s._M_str); + return *this; + } + + static_assert(sizeof(__cow_string) == sizeof(std::string), + "sizeof(std::string) has changed"); + static_assert(alignof(__cow_string) == alignof(std::string), + "alignof(std::string) has changed"); +#endif + + // Return error_category::message() as an SSO string + __sso_string + error_category::_M_message(int i) const + { + string msg = this->message(i); + return {msg.c_str(), msg.length()}; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++11/cow-string-inst.cc b/libstdc++-v3/src/c++11/cow-string-inst.cc new file mode 100644 index 00000000000..45811cbbb22 --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-string-inst.cc @@ -0,0 +1,120 @@ +// Reference-counted COW string instantiations -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 21 Strings library +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "string-inst.cc" + +#include +#include + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // These came from c++98/misc-inst.cc, repeat them for COW string + // string related to iostreams. + template + basic_istream& + operator>>(basic_istream&, string&); + template + basic_ostream& + operator<<(basic_ostream&, const string&); + template + basic_istream& + getline(basic_istream&, string&, char); + template + basic_istream& + getline(basic_istream&, string&); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 +#include +#if defined __i386__ || defined __x86_64__ +# include +#endif +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ + void + random_device::_M_init(const std::string& token) + { + const char *fname = token.c_str(); + + if (token == "default") + { +#if (defined __i386__ || defined __x86_64__) && defined _GLIBCXX_X86_RDRAND + unsigned int eax, ebx, ecx, edx; + // Check availability of cpuid and, for now at least, also the + // CPU signature for Intel's + if (__get_cpuid_max(0, &ebx) > 0 && ebx == signature_INTEL_ebx) + { + __cpuid(1, eax, ebx, ecx, edx); + if (ecx & bit_RDRND) + { + _M_file = nullptr; + return; + } + } +#endif + + fname = "/dev/urandom"; + } + else if (token != "/dev/urandom" && token != "/dev/random") + fail: + std::__throw_runtime_error(__N("random_device::" + "random_device(const std::string&)")); + + _M_file = static_cast(std::fopen(fname, "rb")); + if (!_M_file) + goto fail; + } + + void + random_device::_M_init_pretr1(const std::string& token) + { + unsigned long __seed = 5489UL; + if (token != "mt19937") + { + const char* __nptr = token.c_str(); + char* __endptr; + __seed = std::strtoul(__nptr, &__endptr, 0); + if (*__nptr == '\0' || *__endptr != '\0') + std::__throw_runtime_error(__N("random_device::random_device" + "(const std::string&)")); + } + _M_mt.seed(__seed); + } +} // namespace +#endif diff --git a/libstdc++-v3/src/c++11/cow-wstring-inst.cc b/libstdc++-v3/src/c++11/cow-wstring-inst.cc new file mode 100644 index 00000000000..de1709dbe8c --- /dev/null +++ b/libstdc++-v3/src/c++11/cow-wstring-inst.cc @@ -0,0 +1,64 @@ +// Reference-counted COW wide string instantiations -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 21 Strings library +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include + +#ifdef _GLIBCXX_USE_WCHAR_T +#define C wchar_t +#include "string-inst.cc" + +#include +#include + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // XXX these came from c++98/misc-inst.cc, repeat them for COW string + // string related to iostreams + template + basic_istream& + operator>>(basic_istream&, wstring&); + template + basic_ostream& + operator<<(basic_ostream&, const wstring&); + template + basic_istream& + getline(basic_istream&, wstring&, wchar_t); + template + basic_istream& + getline(basic_istream&, wstring&); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace +#endif diff --git a/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc new file mode 100644 index 00000000000..2b710d2a62f --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-hash_tr1.cc @@ -0,0 +1,59 @@ +// std::tr1::hash definitions with new string -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +#include +namespace std _GLIBCXX_VISIBILITY(default) +{ + namespace tr1 + { + template<> + size_t + hash::operator()(string __s) const + { return _Fnv_hash::hash(__s.data(), __s.length()); } + + template<> + size_t + hash::operator()(const string& __s) const + { return _Fnv_hash::hash(__s.data(), __s.length()); } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + size_t + hash::operator()(wstring __s) const + { return _Fnv_hash::hash(__s.data(), __s.length() * sizeof(wchar_t)); } + + template<> + size_t + hash::operator()(const wstring& __s) const + { return _Fnv_hash::hash(__s.data(), __s.length() * sizeof(wchar_t)); } +#endif + } +} diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc index 143d70e5e93..0663de2fa95 100644 --- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc +++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc @@ -26,8 +26,13 @@ // ISO C++ 14882:2011: 27.5.3.1.1 Class ios_base::failure // +#define _GLIBCXX_USE_CXX11_ABI 1 #include +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + namespace { struct io_error_category : std::error_category diff --git a/libstdc++-v3/src/c++11/cxx11-locale-inst.cc b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc new file mode 100644 index 00000000000..9c1a1c1333f --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-locale-inst.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 22.1 Locales +// + +// Facet instantiations using new ABI strings. + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +#ifndef C +# define C char +# define C_is_char +#endif +# include "../c++98/locale-inst.cc" diff --git a/libstdc++-v3/src/c++11/cxx11-shim_facets.cc b/libstdc++-v3/src/c++11/cxx11-shim_facets.cc new file mode 100644 index 00000000000..92990a9201c --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-shim_facets.cc @@ -0,0 +1,813 @@ +// Locale support -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 22.1 Locales +// + +// This file defines classes that behave like the standard predefined locale +// facets (collate, money_get etc.) except that they forward all virtual +// functions to another facet which uses a different std::string ABI, +// converting between string types as needed. +// When a user replaces one of the relevant facets the corresponding shim in +// this file is used so that the replacement facet can be used (via the shim) +// in code that uses the other std::string ABI from the replacing code. + +#ifndef _GLIBCXX_USE_CXX11_ABI +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif +#include + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ + // Base class of facet shims, holds a reference to the underlying facet + // that the shim forwards to. + class locale::facet::__shim + { + public: + const facet* _M_get() const { return _M_facet; } + + __shim(const __shim&) = delete; + __shim& operator=(const __shim&) = delete; + + protected: + explicit + __shim(const facet* __f) : _M_facet(__f) { __f->_M_add_reference(); } + + ~__shim() { _M_facet->_M_remove_reference(); } + + private: + const facet* _M_facet; + }; + +namespace __facet_shims +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + namespace // unnamed + { + template + void __destroy_string(void* p) + { + static_cast*>(p)->~basic_string(); + } + } // namespace + + // Manages a buffer of uninitialized memory that can store a std::string + // or std::wstring, using either ABI, and convert to the other ABI. + class __any_string + { + struct __attribute__((may_alias)) __str_rep + { + union { + const void* _M_p; + char* _M_pc; + wchar_t* _M_pwc; + }; + size_t _M_len; + char _M_unused[16]; + + operator const char*() const { return _M_pc; } + operator const wchar_t*() const { return _M_pwc; } + }; + union { + __str_rep _M_str; + char _M_bytes[sizeof(__str_rep)]; + }; + using __dtor_func = void(*)(void*); + __dtor_func _M_dtor = nullptr; + +#if _GLIBCXX_USE_CXX11_ABI + // SSO strings overlay the entire __str_rep structure. + static_assert(sizeof(std::string) == sizeof(__str_rep), + "std::string changed size!"); +#else + // COW strings overlay just the pointer, the length is stored manually. + static_assert(sizeof(std::string) == sizeof(__str_rep::_M_p), + "std::string changed size!"); +#endif +# ifdef _GLIBCXX_USE_WCHAR_T + static_assert(sizeof(std::wstring) == sizeof(std::string), + "std::wstring and std::string are different sizes!"); +# endif + + public: + __any_string() = default; + ~__any_string() { if (_M_dtor) _M_dtor(_M_bytes); } + + __any_string(const __any_string&) = delete; + __any_string& operator=(const __any_string&) = delete; + + // Store a string (and its length if needed) in the buffer and + // set _M_dtor to the function that runs the right destructor. + template + __any_string& + operator=(const basic_string& s) + { + if (_M_dtor) + _M_dtor(_M_bytes); + ::new(_M_bytes) basic_string(s); +#if ! _GLIBCXX_USE_CXX11_ABI + _M_str._M_len = s.length(); +#endif + _M_dtor = __destroy_string; + return *this; + } + + // Create a new string with a copy of the characters in the stored string. + // The returned object will match the caller's string ABI, even when the + // stored string doesn't. + template + operator basic_string() const + { + if (!_M_dtor) + __throw_logic_error("uninitialized __any_string"); + return basic_string(static_cast(_M_str), _M_str._M_len); + } + }; + + // This file is compiled twice, with and without this macro defined. + // Define tag types to distinguish between the two cases and to allow + // overloading on the tag. + using current_abi = __bool_constant<_GLIBCXX_USE_CXX11_ABI>; + using other_abi = __bool_constant; + + using facet = locale::facet; + + // Declare the functions that shims defined in this file will call to + // perform work in the context of the other ABI. + // These will be defined when this file is recompiled for the other ABI + // (at which point what is now "current_abi" will become "other_abi"). + + template + void + __numpunct_fill_cache(other_abi, const facet*, __numpunct_cache*, + const char*&, size_t&); + + template + int + __collate_compare(other_abi, const facet*, const C*, const C*, + const C*, const C*); + + template + void + __collate_transform(other_abi, const facet*, __any_string&, + const C*, const C*); + + template + time_base::dateorder + __time_get_dateorder(other_abi, const facet* f); + + template + istreambuf_iterator + __time_get(other_abi, const facet* f, + istreambuf_iterator beg, istreambuf_iterator end, + ios_base& io, ios_base::iostate& err, tm* t, char which); + + template + void + __moneypunct_fill_cache(other_abi, const facet*, + __moneypunct_cache*); + + template + istreambuf_iterator + __money_get(other_abi, const facet*, + istreambuf_iterator, istreambuf_iterator, + bool, ios_base&, ios_base::iostate&, + long double*, __any_string*); + + template + ostreambuf_iterator + __money_put(other_abi, const facet*, ostreambuf_iterator, bool, + ios_base&, C, long double, const __any_string*); + + template + messages_base::catalog + __messages_open(other_abi, const facet*, const char*, size_t, + const locale&); + + template + void + __messages_get(other_abi, const facet*, __any_string&, + messages_base::catalog, int, int, const C*, size_t); + + template + void + __messages_close(other_abi, const facet*, messages_base::catalog); + + namespace // unnamed + { + template + struct numpunct_shim : std::numpunct<_CharT>, facet::__shim + { + typedef typename numpunct<_CharT>::__cache_type __cache_type; + + // f must point to a type derived from numpunct[abi:other] + numpunct_shim(const facet* f, __cache_type* c = new __cache_type) + : std::numpunct<_CharT>(c), __shim(f), _M_cache(c) + { + __numpunct_fill_cache(other_abi{}, f, c, _M_grouping, + _M_grouping_size); + } + + ~numpunct_shim() { delete[] _M_grouping; } + + virtual string + do_grouping() const + { return string(_M_grouping, _M_grouping_size); } + + // No need to override other virtual functions, the base definitions + // will return the cached data. + + __cache_type* _M_cache; + // numpunct uses __numpunct_cache::_M_grouping for its own purposes + // so we can't store that in the cache + const char* _M_grouping; + size_t _M_grouping_size; + }; + + template class numpunct_shim; + template class numpunct_shim; + + template + struct collate_shim : std::collate<_CharT>, facet::__shim + { + typedef basic_string<_CharT> string_type; + + // f must point to a type derived from collate[abi:other] + collate_shim(const facet* f) : __shim(f) { } + + virtual int + do_compare(const _CharT* lo1, const _CharT* hi1, + const _CharT* lo2, const _CharT* hi2) const + { + return __collate_compare(other_abi{}, _M_get(), + lo1, hi1, lo2, hi2); + } + + virtual string_type + do_transform(const _CharT* lo, const _CharT* hi) const + { + __any_string st; + __collate_transform(other_abi{}, _M_get(), st, lo, hi); + return st; + } + }; + + template class collate_shim; + template class collate_shim; + + template + struct time_get_shim : std::time_get<_CharT>, facet::__shim + { + typedef typename std::time_get<_CharT>::iter_type iter_type; + typedef typename std::time_get<_CharT>::char_type char_type; + + // f must point to a type derived from time_get[abi:other] + time_get_shim(const facet* f) : __shim(f) { } + + virtual time_base::dateorder + do_date_order() const + { return __time_get_dateorder<_CharT>(other_abi{}, _M_get()); } + + virtual iter_type + do_get_time(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 't'); + } + + virtual iter_type + do_get_date(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'd'); + } + + virtual iter_type + do_get_weekday(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'w'); + } + + virtual iter_type + do_get_monthname(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'm'); + } + + virtual iter_type + do_get_year(iter_type beg, iter_type end, ios_base& io, + ios_base::iostate& err, tm* t) const + { + return __time_get(other_abi{}, _M_get(), beg, end, io, err, t, + 'y'); + } + }; + + template + struct moneypunct_shim : std::moneypunct<_CharT, _Intl>, facet::__shim + { + typedef typename moneypunct<_CharT, _Intl>::__cache_type __cache_type; + + // f must point to a type derived from moneypunct[abi:other] + moneypunct_shim(const facet* f, __cache_type* c = new __cache_type) + : std::moneypunct<_CharT, _Intl>(c), __shim(f), _M_cache(c) + { + __moneypunct_fill_cache(other_abi{}, f, c); + } + + ~moneypunct_shim() + { + // stop GNU locale's ~moneypunct() from freeing these strings + _M_cache->_M_grouping_size = 0; + _M_cache->_M_curr_symbol_size = 0; + _M_cache->_M_positive_sign_size = 0; + _M_cache->_M_negative_sign_size = 0; + } + + // No need to override any virtual functions, the base definitions + // will return the cached data. + + __cache_type* _M_cache; + }; + + template class moneypunct_shim; + template class moneypunct_shim; + template class moneypunct_shim; + template class moneypunct_shim; + + template + struct money_get_shim : std::money_get<_CharT>, facet::__shim + { + typedef typename std::money_get<_CharT>::iter_type iter_type; + typedef typename std::money_get<_CharT>::char_type char_type; + typedef typename std::money_get<_CharT>::string_type string_type; + + // f must point to a type derived from money_get[abi:other] + money_get_shim(const facet* f) : __shim(f) { } + + virtual iter_type + do_get(iter_type s, iter_type end, bool intl, ios_base& io, + ios_base::iostate& err, long double& units) const + { + ios_base::iostate err2 = ios_base::goodbit; + long double units2; + s = __money_get(other_abi{}, _M_get(), s, end, intl, io, err2, + &units2, nullptr); + if (err2 == ios_base::goodbit) + units = units2; + else + err = err2; + return s; + } + + virtual iter_type + do_get(iter_type s, iter_type end, bool intl, ios_base& io, + ios_base::iostate& err, string_type& digits) const + { + __any_string st; + ios_base::iostate err2 = ios_base::goodbit; + s = __money_get(other_abi{}, _M_get(), s, end, intl, io, err2, + nullptr, &st); + if (err2 == ios_base::goodbit) + digits = st; + else + err = err2; + return s; + } + }; + + template class money_get_shim; + template class money_get_shim; + + template + struct money_put_shim : std::money_put<_CharT>, facet::__shim + { + typedef typename std::money_put<_CharT>::iter_type iter_type; + typedef typename std::money_put<_CharT>::char_type char_type; + typedef typename std::money_put<_CharT>::string_type string_type; + + // f must point to a type derived from money_put[abi:other] + money_put_shim(const facet* f) : __shim(f) { } + + virtual iter_type + do_put(iter_type s, bool intl, ios_base& io, + char_type fill, long double units) const + { + return __money_put(other_abi{}, _M_get(), s, intl, io, fill, units, + nullptr); + } + + virtual iter_type + do_put(iter_type s, bool intl, ios_base& io, + char_type fill, const string_type& digits) const + { + __any_string st; + st = digits; + return __money_put(other_abi{}, _M_get(), s, intl, io, fill, 0.L, + &st); + } + }; + + template class money_put_shim; + template class money_put_shim; + + + template + struct messages_shim : std::messages<_CharT>, facet::__shim + { + typedef messages_base::catalog catalog; + typedef basic_string<_CharT> string_type; + + // f must point to a type derived from messages[abi:other] + messages_shim(const facet* f) : __shim(f) { } + + virtual catalog + do_open(const basic_string& s, const locale& l) const + { + return __messages_open<_CharT>(other_abi{}, _M_get(), + s.c_str(), s.size(), l); + } + + virtual string_type + do_get(catalog c, int set, int msgid, const string_type& dfault) const + { + __any_string st; + __messages_get(other_abi{}, _M_get(), st, c, set, msgid, + dfault.c_str(), dfault.size()); + return st; + } + + virtual void + do_close(catalog c) const + { + __messages_close<_CharT>(other_abi{}, _M_get(), c); + } + }; + + template class messages_shim; + template class messages_shim; + + template + inline size_t + __copy(const C*& dest, const basic_string& s) + { + auto len = s.length(); + C* p = new C[len+1]; + s.copy(p, len); + p[len] = '\0'; + dest = p; + return len; + } + + } // namespace + + // Now define and instantiate the functions that will be called by the + // shim facets defined when this file is recompiled for the other ABI. + + template + void + __numpunct_fill_cache(current_abi, const facet* f, __numpunct_cache* c, + const char*& grouping, size_t& grouping_size) + { + auto* m = static_cast*>(f); + + c->_M_decimal_point = m->decimal_point(); + c->_M_thousands_sep = m->thousands_sep(); + + c->_M_truename = nullptr; + c->_M_falsename = nullptr; + // set _M_allocated so that if any allocation fails the previously + // allocated strings will be deleted in ~__numpunct_c() + c->_M_allocated = true; + + c->_M_truename_size = __copy(c->_M_truename, m->truename()); + c->_M_falsename_size = __copy(c->_M_falsename, m->falsename()); + // Set grouping last as it is only deleted by ~numpunct_shim() which + // won't run if this function throws an exception. + grouping_size = __copy(grouping, m->grouping()); + } + + template void + __numpunct_fill_cache(current_abi, const facet*, __numpunct_cache*, + const char*&, size_t&); + + template void + __numpunct_fill_cache(current_abi, const facet*, __numpunct_cache*, + const char*&, size_t&); + + template + int + __collate_compare(current_abi, const facet* f, const C* lo1, const C* hi1, + const C* lo2, const C* hi2) + { + return static_cast*>(f)->compare(lo1, hi1, lo2, hi2); + } + + template int + __collate_compare(current_abi, const facet*, const char*, const char*, + const char*, const char*); + + template int + __collate_compare(current_abi, const facet*, const wchar_t*, const wchar_t*, + const wchar_t*, const wchar_t*); + + template + void + __collate_transform(current_abi, const facet* f, __any_string& st, + const C* __lo, const C* __hi) + { + auto* c = static_cast*>(f); + st = c->transform(__lo, __hi); + } + + template void + __collate_transform(current_abi, const facet*, __any_string&, + const char*, const char*); + + template void + __collate_transform(current_abi, const facet*, __any_string&, + const wchar_t*, const wchar_t*); + + template + void + __moneypunct_fill_cache(current_abi, const facet* f, + __moneypunct_cache* c) + { + auto* m = static_cast*>(f); + + c->_M_decimal_point = m->decimal_point(); + c->_M_thousands_sep = m->thousands_sep(); + c->_M_frac_digits = m->frac_digits(); + + c->_M_grouping = nullptr; + c->_M_curr_symbol = nullptr; + c->_M_positive_sign = nullptr; + c->_M_negative_sign = nullptr; + // set _M_allocated so that if any allocation fails the previously + // allocated strings will be deleted in ~__moneypunct_c() + c->_M_allocated = true; + + c->_M_grouping_size = __copy(c->_M_grouping, m->grouping()); + c->_M_curr_symbol_size = __copy(c->_M_curr_symbol, m->curr_symbol()); + c->_M_positive_sign_size + = __copy(c->_M_positive_sign, m->positive_sign()); + c->_M_negative_sign_size + = __copy(c->_M_negative_sign, m->negative_sign()); + + c->_M_pos_format = m->pos_format(); + c->_M_neg_format = m->neg_format(); + } + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache*); + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache*); + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache*); + + template void + __moneypunct_fill_cache(current_abi, const facet*, + __moneypunct_cache*); + + template + messages_base::catalog + __messages_open(current_abi, const facet* f, const char* s, size_t n, + const locale& l) + { + auto* m = static_cast*>(f); + string str(s, n); + return m->open(str, l); + } + + template messages_base::catalog + __messages_open(current_abi, const facet*, const char*, size_t, + const locale&); + + template messages_base::catalog + __messages_open(current_abi, const facet*, const char*, size_t, + const locale&); + + template + void + __messages_get(current_abi, const facet* f, __any_string& st, + messages_base::catalog c, int set, int msgid, + const C* s, size_t n) + { + auto* m = static_cast*>(f); + st = m->get(c, set, msgid, basic_string(s, n)); + } + + template void + __messages_get(current_abi, const facet*, __any_string&, + messages_base::catalog, int, int, const char*, size_t); + + template void + __messages_get(current_abi, const facet*, __any_string&, + messages_base::catalog, int, int, const wchar_t*, size_t); + + template + void + __messages_close(current_abi, const facet* f, messages_base::catalog c) + { + static_cast*>(f)->close(c); + } + + template void + __messages_close(current_abi, const facet*, messages_base::catalog c); + + template void + __messages_close(current_abi, const facet*, + messages_base::catalog c); + + template + time_base::dateorder + __time_get_dateorder(current_abi, const facet* f) + { return static_cast*>(f)->date_order(); } + + template time_base::dateorder + __time_get_dateorder(current_abi, const facet*); + + template time_base::dateorder + __time_get_dateorder(current_abi, const facet*); + + template + istreambuf_iterator + __time_get(current_abi, const facet* f, + istreambuf_iterator beg, istreambuf_iterator end, + ios_base& io, ios_base::iostate& err, tm* t, char which) + { + auto* g = static_cast*>(f); + switch(which) + { + case 't': + return g->get_time(beg, end, io, err, t); + case 'd': + return g->get_date(beg, end, io, err, t); + case 'w': + return g->get_weekday(beg, end, io, err, t); + case 'm': + return g->get_monthname(beg, end, io, err, t); + case 'y': + return g->get_year(beg, end, io, err, t); + default: + __builtin_unreachable(); + } + } + + template istreambuf_iterator + __time_get(current_abi, const facet*, + istreambuf_iterator, istreambuf_iterator, + ios_base&, ios_base::iostate&, tm*, char); + + template istreambuf_iterator + __time_get(current_abi, const facet*, + istreambuf_iterator, istreambuf_iterator, + ios_base&, ios_base::iostate&, tm*, char); + + template + istreambuf_iterator + __money_get(current_abi, const facet* f, + istreambuf_iterator s, istreambuf_iterator end, + bool intl, ios_base& str, ios_base::iostate& err, + long double* units, __any_string* digits) + { + auto* m = static_cast*>(f); + if (units) + return m->get(s, end, intl, str, err, *units); + basic_string digits2; + s = m->get(s, end, intl, str, err, digits2); + if (err == ios_base::goodbit) + *digits = digits2; + return s; + } + + template istreambuf_iterator + __money_get(current_abi, const facet*, + istreambuf_iterator, istreambuf_iterator, + bool, ios_base&, ios_base::iostate&, + long double*, __any_string*); + + template istreambuf_iterator + __money_get(current_abi, const facet*, + istreambuf_iterator, istreambuf_iterator, + bool, ios_base&, ios_base::iostate&, + long double*, __any_string*); + + template + ostreambuf_iterator + __money_put(current_abi, const facet* f, ostreambuf_iterator s, + bool intl, ios_base& io, C fill, long double units, + const __any_string* digits) + { + auto* m = static_cast*>(f); + if (digits) + return m->put(s, intl, io, fill, *digits); + else + return m->put(s, intl, io, fill, units); + } + + template ostreambuf_iterator + __money_put(current_abi, const facet*, ostreambuf_iterator, + bool, ios_base&, char, long double, const __any_string*); + + template ostreambuf_iterator + __money_put(current_abi, const facet*, ostreambuf_iterator, + bool, ios_base&, wchar_t, long double, const __any_string*); + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace __facet_shims + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + // Create a new shim facet of type WHICH that forwards calls to F. + // F is the replacement facet provided by the user, WHICH is the ID of + // F's "other ABI twin" which we are replacing with a shim. + const locale::facet* +#if _GLIBCXX_USE_CXX11_ABI + locale::facet::_M_sso_shim(const locale::id* which) const +#else + locale::facet::_M_cow_shim(const locale::id* which) const +#endif + { + using namespace __facet_shims; + + // If this is already a shim just use its underlying facet. + if (auto* p = dynamic_cast(this)) + return p->_M_get(); + + if (which == &numpunct::id) + return new numpunct_shim{this}; + if (which == &std::collate::id) + return new collate_shim{this}; + if (which == &time_get::id) + return new time_get_shim{this}; + if (which == &money_get::id) + return new money_get_shim{this}; + if (which == &money_put::id) + return new money_put_shim{this}; + if (which == &moneypunct::id) + return new moneypunct_shim{this}; + if (which == &moneypunct::id) + return new moneypunct_shim{this}; + if (which == &std::messages::id) + return new messages_shim{this}; +#ifdef _GLIBCXX_USE_WCHAR_T + if (which == &numpunct::id) + return new numpunct_shim{this}; + if (which == &std::collate::id) + return new collate_shim{this}; + if (which == &time_get::id) + return new time_get_shim{this}; + if (which == &money_get::id) + return new money_get_shim{this}; + if (which == &money_put::id) + return new money_put_shim{this}; + if (which == &moneypunct::id) + return new moneypunct_shim{this}; + if (which == &moneypunct::id) + return new moneypunct_shim{this}; + if (which == &std::messages::id) + return new messages_shim{this}; +#endif + __throw_logic_error("cannot create shim for unknown locale::facet"); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std diff --git a/libstdc++-v3/src/c++11/cxx11-stdexcept.cc b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc new file mode 100644 index 00000000000..64158c7c552 --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-stdexcept.cc @@ -0,0 +1,78 @@ +// Methods for Exception Support for -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 19.1 Exception classes +// + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include + +#if ! _GLIBCXX_USE_DUAL_ABI +# error This file should not be compiled for this configuration. +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // These constructors take an abi-tagged std::string and use it to + // initialize an untagged COW std::string in _M_msg. + + logic_error::logic_error(const string& __arg) + : _M_msg(__arg) { } + + runtime_error::runtime_error(const string& __arg) + : _M_msg(__arg) { } + + // These constructors take an abi-tagged std::string and pass it to the + // base class constructors defined above. + + domain_error::domain_error(const string& __arg) + : logic_error(__arg) { } + + invalid_argument::invalid_argument(const string& __arg) + : logic_error(__arg) { } + + length_error::length_error(const string& __arg) + : logic_error(__arg) { } + + out_of_range::out_of_range(const string& __arg) + : logic_error(__arg) { } + + range_error::range_error(const string& __arg) + : runtime_error(__arg) { } + + overflow_error::overflow_error(const string& __arg) + : runtime_error(__arg) { } + + underflow_error::underflow_error(const string& __arg) + : runtime_error(__arg) { } + + // Converting constructor from ABI-tagged std::string to COW string. + __cow_string::__cow_string(const string& s) + : __cow_string(s.c_str(), s.length()) { } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc new file mode 100644 index 00000000000..ba993556f70 --- /dev/null +++ b/libstdc++-v3/src/c++11/cxx11-wlocale-inst.cc @@ -0,0 +1,32 @@ +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 22.1 Locales +// + +#define _GLIBCXX_USE_CXX11_ABI 1 +#include +#ifdef _GLIBCXX_USE_WCHAR_T +#define C wchar_t +#include "cxx11-locale-inst.cc" +#endif diff --git a/libstdc++-v3/src/c++11/fstream-inst.cc b/libstdc++-v3/src/c++11/fstream-inst.cc index 0ef5fc47e94..2e3e1740c8a 100644 --- a/libstdc++-v3/src/c++11/fstream-inst.cc +++ b/libstdc++-v3/src/c++11/fstream-inst.cc @@ -26,6 +26,7 @@ // ISO C++ 14882: // +#define _GLIBCXX_USE_CXX11_ABI 1 #include namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/src/c++11/functexcept.cc b/libstdc++-v3/src/c++11/functexcept.cc index d184bfc0b6c..9d05502e77c 100644 --- a/libstdc++-v3/src/c++11/functexcept.cc +++ b/libstdc++-v3/src/c++11/functexcept.cc @@ -20,6 +20,9 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +// We don't want to change the type thrown by __throw_ios_failure (yet?) +#define _GLIBCXX_USE_CXX11_ABI 0 + #include #include #include diff --git a/libstdc++-v3/src/c++11/random.cc b/libstdc++-v3/src/c++11/random.cc index f61daeacb50..cb25f00853f 100644 --- a/libstdc++-v3/src/c++11/random.cc +++ b/libstdc++-v3/src/c++11/random.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 1 #include #ifdef _GLIBCXX_USE_C99_STDINT_TR1 diff --git a/libstdc++-v3/src/c++11/sstream-inst.cc b/libstdc++-v3/src/c++11/sstream-inst.cc index 728946ef474..ea89fbfb506 100644 --- a/libstdc++-v3/src/c++11/sstream-inst.cc +++ b/libstdc++-v3/src/c++11/sstream-inst.cc @@ -26,6 +26,11 @@ // ISO C++ 14882: // +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the new SSO std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=0. +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif #include namespace std _GLIBCXX_VISIBILITY(default) diff --git a/libstdc++-v3/src/c++11/string-inst.cc b/libstdc++-v3/src/c++11/string-inst.cc index f19a0b0e9d6..a892d5d52d9 100644 --- a/libstdc++-v3/src/c++11/string-inst.cc +++ b/libstdc++-v3/src/c++11/string-inst.cc @@ -29,6 +29,12 @@ // Written by Jason Merrill based upon the specification by Takanori Adachi // in ANSI X3J16/94-0013R2. Rewritten by Nathan Myers. +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the new SSO std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=0. +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif + #include // Instantiation configuration. @@ -49,7 +55,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Only one template keyword allowed here. // See core issue #46 (NAD) - // http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_closed.html#46 + // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#46 template S::basic_string(C*, C*, const allocator&); @@ -59,6 +65,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template S::basic_string(S::iterator, S::iterator, const allocator&); +#if _GLIBCXX_USE_CXX11_ABI + template + void + S::_M_construct(S::iterator, S::iterator, forward_iterator_tag); + + template + void + S::_M_construct(S::const_iterator, S::const_iterator, + forward_iterator_tag); + + template + void + S::_M_construct(C*, C*, forward_iterator_tag); + + template + void + S::_M_construct(const C*, const C*, forward_iterator_tag); + +#else // !_GLIBCXX_USE_CXX11_ABI + template C* S::_S_construct(S::iterator, S::iterator, @@ -72,6 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION C* S::_S_construct(const C*, const C*, const allocator&, forward_iterator_tag); +#endif _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++11/system_error.cc b/libstdc++-v3/src/c++11/system_error.cc index 5bd59f0e6bb..30e480db9ec 100644 --- a/libstdc++-v3/src/c++11/system_error.cc +++ b/libstdc++-v3/src/c++11/system_error.cc @@ -23,10 +23,13 @@ // . +#define _GLIBCXX_USE_CXX11_ABI 1 +#define __sso_string __sso_stringxxx #include #include #include #include +#undef __sso_string namespace { @@ -73,10 +76,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION error_category::~error_category() noexcept = default; const error_category& - system_category() noexcept { return system_category_instance; } + _V2::system_category() noexcept { return system_category_instance; } const error_category& - generic_category() noexcept { return generic_category_instance; } + _V2::generic_category() noexcept { return generic_category_instance; } system_error::~system_error() noexcept = default; @@ -97,5 +100,80 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION error_code::default_error_condition() const noexcept { return category().default_error_condition(value()); } +#if _GLIBCXX_USE_CXX11_ABI + // Return error_category::message() as a COW string + __cow_string + error_category::_M_message(int i) const + { + string msg = this->message(i); + return {msg.c_str(), msg.length()}; + } +#endif + +#if _GLIBCXX_USE_DUAL_ABI + // Redefine __sso_string so that we can define and export its members + // in terms of the SSO std::string. + struct __sso_string + { + struct __str + { + const char* _M_p; + size_t _M_string_length; + char _M_local_buf[16]; + }; + + union { + __str _M_s; + char _M_bytes[sizeof(_M_s)]; + std::string _M_str; + }; + + __sso_string(); + __sso_string(const std::string& s); + __sso_string(const char*, size_t n); + __sso_string(const __sso_string&) noexcept; + __sso_string& operator=(const __sso_string&) noexcept; + ~__sso_string(); + __sso_string(__sso_string&&) noexcept; + __sso_string& operator=(__sso_string&&) noexcept; + }; + + __sso_string::__sso_string() : _M_str() { } + +#if _GLIBCXX_USE_CXX11_ABI + static_assert(sizeof(__sso_string) == sizeof(std::string), + "sizeof(std::string) has changed"); + static_assert(alignof(__sso_string) == alignof(std::string), + "alignof(std::string) has changed"); + + // This constructor is defined in src/c++11/cow-stdexcept.cc for COW strings + __sso_string::__sso_string(const std::string& s) : _M_str(s) { } +#endif + + __sso_string::__sso_string(const char* s, size_t n) : _M_str(s, n) { } + + __sso_string::__sso_string(const __sso_string& s) noexcept + : _M_str(s._M_str) { } + + __sso_string& + __sso_string::operator=(const __sso_string& s) noexcept + { + _M_str = s._M_str; + return *this; + } + + __sso_string::~__sso_string() { _M_str.~basic_string(); } + + __sso_string::__sso_string(__sso_string&& s) noexcept + : _M_str(std::move(s._M_str)) { } + + __sso_string& + __sso_string::operator=(__sso_string&& s) noexcept + { + _M_str = std::move(s._M_str); + return *this; + } +#endif // _GLIBCXX_USE_DUAL_ABI + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++11/wstring-inst.cc b/libstdc++-v3/src/c++11/wstring-inst.cc index 8c9f9017ad2..65425b0ad39 100644 --- a/libstdc++-v3/src/c++11/wstring-inst.cc +++ b/libstdc++-v3/src/c++11/wstring-inst.cc @@ -26,6 +26,7 @@ // ISO C++ 14882: 21 Strings library // +#define _GLIBCXX_USE_CXX11_ABI 1 #include #ifdef _GLIBCXX_USE_WCHAR_T diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am index 9afe904cd2b..e3e540d64f6 100644 --- a/libstdc++-v3/src/c++98/Makefile.am +++ b/libstdc++-v3/src/c++98/Makefile.am @@ -27,9 +27,18 @@ noinst_LTLIBRARIES = libc++98convenience.la headers = +if ENABLE_DUAL_ABI +cow_string_host_sources = \ + collate_members_cow.cc \ + messages_members_cow.cc \ + monetary_members_cow.cc \ + numeric_members_cow.cc +endif + # Source files linked in via configuration/make substitution for a # particular host. host_sources = \ + $(cow_string_host_sources) \ atomicity.cc \ codecvt_members.cc \ collate_members.cc \ @@ -60,6 +69,20 @@ atomicity_file = ${glibcxx_srcdir}/$(ATOMICITY_SRCDIR)/atomicity.h atomicity.cc: ${atomicity_file} $(LN_S) ${atomicity_file} ./atomicity.cc || true +if ENABLE_DUAL_ABI +collate_members_cow.cc: ${glibcxx_srcdir}/$(CCOLLATE_CC) + $(LN_S) ${glibcxx_srcdir}/$(CCOLLATE_CC) ./$@ || true + +messages_members_cow.cc: ${glibcxx_srcdir}/$(CMESSAGES_CC) + $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_CC) ./$@ || true + +monetary_members_cow.cc: ${glibcxx_srcdir}/$(CMONEY_CC) + $(LN_S) ${glibcxx_srcdir}/$(CMONEY_CC) ./$@ || true + +numeric_members_cow.cc: ${glibcxx_srcdir}/$(CNUMERIC_CC) + $(LN_S) ${glibcxx_srcdir}/$(CNUMERIC_CC) ./$@ || true +endif + # Source files linked in via configuration/make substitution for a # particular host, but with ad hoc naming rules. host_sources_extra = \ @@ -72,6 +95,12 @@ c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC) basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC) $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true +if ENABLE_DUAL_ABI +cxx11_abi_sources = \ + cow-istream-string.cc +else +cxx11_abi_sources = +endif if ENABLE_EXTERN_TEMPLATE # XTEMPLATE_FLAGS = -fno-implicit-templates @@ -117,8 +146,10 @@ sources = \ strstream.cc \ tree.cc \ istream.cc \ + istream-string.cc \ streambuf.cc \ valarray.cc \ + ${cxx11_abi_sources} \ ${host_sources} \ ${host_sources_extra} @@ -126,6 +157,27 @@ vpath % $(top_srcdir)/src/c++98 libc__98convenience_la_SOURCES = $(sources) +if ENABLE_DUAL_ABI +GLIBCXX_ABI_FLAGS = -D_GLIBCXX_USE_CXX11_ABI=@glibcxx_cxx98_abi@ +# Use special rules to compile with the non-default string ABI. +collate_members_cow.lo: collate_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +collate_members_cow.o: collate_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +messages_members_cow.lo: messages_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +messages_members_cow.o: messages_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +monetary_members_cow.lo: monetary_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +monetary_members_cow.o: monetary_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +numeric_members_cow.lo: numeric_members_cow.cc + $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +numeric_members_cow.o: numeric_members_cow.cc + $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +endif + # Use special rules for the deprecated source files so that they find # deprecated include files. GLIBCXX_INCLUDE_DIR=$(glibcxx_builddir)/include diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in index 9d937927ed7..bd8fd3d778d 100644 --- a/libstdc++-v3/src/c++98/Makefile.in +++ b/libstdc++-v3/src/c++98/Makefile.in @@ -67,25 +67,31 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libc__98convenience_la_LIBADD = -am__objects_1 = atomicity.lo codecvt_members.lo collate_members.lo \ - messages_members.lo monetary_members.lo numeric_members.lo \ - time_members.lo -@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_2 = allocator-inst.lo \ +@ENABLE_DUAL_ABI_TRUE@am__objects_1 = cow-istream-string.lo +@ENABLE_DUAL_ABI_TRUE@am__objects_2 = collate_members_cow.lo \ +@ENABLE_DUAL_ABI_TRUE@ messages_members_cow.lo \ +@ENABLE_DUAL_ABI_TRUE@ monetary_members_cow.lo \ +@ENABLE_DUAL_ABI_TRUE@ numeric_members_cow.lo +am__objects_3 = $(am__objects_2) atomicity.lo codecvt_members.lo \ + collate_members.lo messages_members.lo monetary_members.lo \ + numeric_members.lo time_members.lo +@ENABLE_EXTERN_TEMPLATE_TRUE@am__objects_4 = allocator-inst.lo \ @ENABLE_EXTERN_TEMPLATE_TRUE@ concept-inst.lo ext-inst.lo \ @ENABLE_EXTERN_TEMPLATE_TRUE@ locale-inst.lo misc-inst.lo \ @ENABLE_EXTERN_TEMPLATE_TRUE@ wlocale-inst.lo -am__objects_3 = parallel_settings.lo -am__objects_4 = basic_file.lo c++locale.lo $(am__objects_2) \ - $(am__objects_3) -am__objects_5 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \ +am__objects_5 = parallel_settings.lo +am__objects_6 = basic_file.lo c++locale.lo $(am__objects_4) \ + $(am__objects_5) +am__objects_7 = bitmap_allocator.lo pool_allocator.lo mt_allocator.lo \ codecvt.lo complex_io.lo globals_io.lo hash_tr1.lo \ hashtable_tr1.lo ios_failure.lo ios_init.lo ios_locale.lo \ list.lo list-aux.lo list-aux-2.lo list_associated.lo \ list_associated-2.lo locale.lo locale_init.lo locale_facets.lo \ localename.lo math_stubs_float.lo math_stubs_long_double.lo \ - stdexcept.lo strstream.lo tree.lo istream.lo streambuf.lo \ - valarray.lo $(am__objects_1) $(am__objects_4) -am_libc__98convenience_la_OBJECTS = $(am__objects_5) + stdexcept.lo strstream.lo tree.lo istream.lo istream-string.lo \ + streambuf.lo valarray.lo $(am__objects_1) $(am__objects_3) \ + $(am__objects_6) +am_libc__98convenience_la_OBJECTS = $(am__objects_7) libc__98convenience_la_OBJECTS = $(am_libc__98convenience_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = @@ -245,6 +251,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ @@ -321,10 +328,17 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES) # Convenience library for C++98 runtime. noinst_LTLIBRARIES = libc++98convenience.la headers = +@ENABLE_DUAL_ABI_TRUE@cow_string_host_sources = \ +@ENABLE_DUAL_ABI_TRUE@ collate_members_cow.cc \ +@ENABLE_DUAL_ABI_TRUE@ messages_members_cow.cc \ +@ENABLE_DUAL_ABI_TRUE@ monetary_members_cow.cc \ +@ENABLE_DUAL_ABI_TRUE@ numeric_members_cow.cc + # Source files linked in via configuration/make substitution for a # particular host. host_sources = \ + $(cow_string_host_sources) \ atomicity.cc \ codecvt_members.cc \ collate_members.cc \ @@ -341,6 +355,10 @@ host_sources_extra = \ basic_file.cc c++locale.cc \ ${inst_sources} ${parallel_sources} +@ENABLE_DUAL_ABI_FALSE@cxx11_abi_sources = +@ENABLE_DUAL_ABI_TRUE@cxx11_abi_sources = \ +@ENABLE_DUAL_ABI_TRUE@ cow-istream-string.cc + # XTEMPLATE_FLAGS = @ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources = @@ -383,12 +401,15 @@ sources = \ strstream.cc \ tree.cc \ istream.cc \ + istream-string.cc \ streambuf.cc \ valarray.cc \ + ${cxx11_abi_sources} \ ${host_sources} \ ${host_sources_extra} libc__98convenience_la_SOURCES = $(sources) +@ENABLE_DUAL_ABI_TRUE@GLIBCXX_ABI_FLAGS = -D_GLIBCXX_USE_CXX11_ABI=@glibcxx_cxx98_abi@ # Use special rules for the deprecated source files so that they find # deprecated include files. @@ -710,6 +731,18 @@ time_members.cc: ${glibcxx_srcdir}/$(CTIME_CC) atomicity.cc: ${atomicity_file} $(LN_S) ${atomicity_file} ./atomicity.cc || true +@ENABLE_DUAL_ABI_TRUE@collate_members_cow.cc: ${glibcxx_srcdir}/$(CCOLLATE_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CCOLLATE_CC) ./$@ || true + +@ENABLE_DUAL_ABI_TRUE@messages_members_cow.cc: ${glibcxx_srcdir}/$(CMESSAGES_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CMESSAGES_CC) ./$@ || true + +@ENABLE_DUAL_ABI_TRUE@monetary_members_cow.cc: ${glibcxx_srcdir}/$(CMONEY_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CMONEY_CC) ./$@ || true + +@ENABLE_DUAL_ABI_TRUE@numeric_members_cow.cc: ${glibcxx_srcdir}/$(CNUMERIC_CC) +@ENABLE_DUAL_ABI_TRUE@ $(LN_S) ${glibcxx_srcdir}/$(CNUMERIC_CC) ./$@ || true + c++locale.cc: ${glibcxx_srcdir}/$(CLOCALE_CC) $(LN_S) ${glibcxx_srcdir}/$(CLOCALE_CC) ./$@ || true @@ -717,6 +750,23 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC) $(LN_S) ${glibcxx_srcdir}/$(BASIC_FILE_CC) ./$@ || true vpath % $(top_srcdir)/src/c++98 +# Use special rules to compile with the non-default string ABI. +@ENABLE_DUAL_ABI_TRUE@collate_members_cow.lo: collate_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@collate_members_cow.o: collate_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@messages_members_cow.lo: messages_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@messages_members_cow.o: messages_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@monetary_members_cow.lo: monetary_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@monetary_members_cow.o: monetary_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@numeric_members_cow.lo: numeric_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@numeric_members_cow.o: numeric_members_cow.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $< strstream.lo: strstream.cc $(LTCXXCOMPILE) -I$(GLIBCXX_INCLUDE_DIR)/backward -Wno-deprecated -c $< strstream.o: strstream.cc diff --git a/libstdc++-v3/src/c++98/compatibility-ldbl.cc b/libstdc++-v3/src/c++98/compatibility-ldbl.cc index bbef3b25f7d..1543d403250 100644 --- a/libstdc++-v3/src/c++98/compatibility-ldbl.cc +++ b/libstdc++-v3/src/c++98/compatibility-ldbl.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 0 #include #include #include diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc index b33cbe75682..2d432e7f972 100644 --- a/libstdc++-v3/src/c++98/compatibility.cc +++ b/libstdc++-v3/src/c++98/compatibility.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 0 #include #if defined(_GLIBCXX_SYMVER_GNU) && defined(_GLIBCXX_SHARED) \ diff --git a/libstdc++-v3/src/c++98/concept-inst.cc b/libstdc++-v3/src/c++98/concept-inst.cc index 9ac9920229a..fd374f811f9 100644 --- a/libstdc++-v3/src/c++98/concept-inst.cc +++ b/libstdc++-v3/src/c++98/concept-inst.cc @@ -29,6 +29,7 @@ // explicitly instantiate the initial set of symbols; compiling this file // with -fimplicit-templates will take care of the rest for us. +#define _GLIBCXX_USE_CXX11_ABI 0 #include #ifdef _GLIBCXX_CONCEPT_CHECKS diff --git a/libstdc++-v3/src/c++98/cow-istream-string.cc b/libstdc++-v3/src/c++98/cow-istream-string.cc new file mode 100644 index 00000000000..32723bb2309 --- /dev/null +++ b/libstdc++-v3/src/c++98/cow-istream-string.cc @@ -0,0 +1,30 @@ +// Input streams operating on strings -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#define _GLIBCXX_USE_CXX11_ABI 0 +#include "istream-string.cc" diff --git a/libstdc++-v3/src/c++98/hash_tr1.cc b/libstdc++-v3/src/c++98/hash_tr1.cc index 57547bb0e5e..1a7430043a0 100644 --- a/libstdc++-v3/src/c++98/hash_tr1.cc +++ b/libstdc++-v3/src/c++98/hash_tr1.cc @@ -22,6 +22,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 0 #include #include diff --git a/libstdc++-v3/src/c++98/istream-string.cc b/libstdc++-v3/src/c++98/istream-string.cc new file mode 100644 index 00000000000..4580adcacdd --- /dev/null +++ b/libstdc++-v3/src/c++98/istream-string.cc @@ -0,0 +1,291 @@ +// Input streams operating on strings-*- C++ -*- + +// Copyright (C) 2004-2014 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +// +// ISO C++ 14882: 27.6.1 Input streams +// + +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the new SSO std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=0. +# define _GLIBCXX_USE_CXX11_ABI 1 +#endif +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template<> + basic_istream& + operator>>(basic_istream& __in, basic_string& __str) + { + typedef basic_istream __istream_type; + typedef __istream_type::int_type __int_type; + typedef __istream_type::traits_type __traits_type; + typedef __istream_type::__streambuf_type __streambuf_type; + typedef __istream_type::__ctype_type __ctype_type; + typedef basic_string __string_type; + typedef __string_type::size_type __size_type; + + __size_type __extracted = 0; + ios_base::iostate __err = ios_base::goodbit; + __istream_type::sentry __cerb(__in, false); + if (__cerb) + { + __try + { + __str.erase(); + const streamsize __w = __in.width(); + const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) + : __str.max_size(); + const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); + const __int_type __eof = __traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !__traits_type::eq_int_type(__c, __eof) + && !__ct.is(ctype_base::space, + __traits_type::to_char_type(__c))) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__n - __extracted)); + if (__size > 1) + { + __size = (__ct.scan_is(ctype_base::space, + __sb->gptr() + 1, + __sb->gptr() + __size) + - __sb->gptr()); + __str.append(__sb->gptr(), __size); + __sb->__safe_gbump(__size); + __extracted += __size; + __c = __sb->sgetc(); + } + else + { + __str += __traits_type::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + } + + if (__traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + __in.width(0); + } + __catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + + template<> + basic_istream& + getline(basic_istream& __in, basic_string& __str, + char __delim) + { + typedef basic_istream __istream_type; + typedef __istream_type::int_type __int_type; + typedef __istream_type::char_type __char_type; + typedef __istream_type::traits_type __traits_type; + typedef __istream_type::__streambuf_type __streambuf_type; + typedef basic_string __string_type; + typedef __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::goodbit; + __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + __try + { + __str.erase(); + const __int_type __idelim = __traits_type::to_int_type(__delim); + const __int_type __eof = __traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !__traits_type::eq_int_type(__c, __eof) + && !__traits_type::eq_int_type(__c, __idelim)) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__n - __extracted)); + if (__size > 1) + { + const __char_type* __p = __traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + __str.append(__sb->gptr(), __size); + __sb->__safe_gbump(__size); + __extracted += __size; + __c = __sb->sgetc(); + } + else + { + __str += __traits_type::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + } + + if (__traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (__traits_type::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + __catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } + +#ifdef _GLIBCXX_USE_WCHAR_T + template<> + basic_istream& + getline(basic_istream& __in, basic_string& __str, + wchar_t __delim) + { + typedef basic_istream __istream_type; + typedef __istream_type::int_type __int_type; + typedef __istream_type::char_type __char_type; + typedef __istream_type::traits_type __traits_type; + typedef __istream_type::__streambuf_type __streambuf_type; + typedef basic_string __string_type; + typedef __string_type::size_type __size_type; + + __size_type __extracted = 0; + const __size_type __n = __str.max_size(); + ios_base::iostate __err = ios_base::goodbit; + __istream_type::sentry __cerb(__in, true); + if (__cerb) + { + __try + { + __str.erase(); + const __int_type __idelim = __traits_type::to_int_type(__delim); + const __int_type __eof = __traits_type::eof(); + __streambuf_type* __sb = __in.rdbuf(); + __int_type __c = __sb->sgetc(); + + while (__extracted < __n + && !__traits_type::eq_int_type(__c, __eof) + && !__traits_type::eq_int_type(__c, __idelim)) + { + streamsize __size = std::min(streamsize(__sb->egptr() + - __sb->gptr()), + streamsize(__n - __extracted)); + if (__size > 1) + { + const __char_type* __p = __traits_type::find(__sb->gptr(), + __size, + __delim); + if (__p) + __size = __p - __sb->gptr(); + __str.append(__sb->gptr(), __size); + __sb->__safe_gbump(__size); + __extracted += __size; + __c = __sb->sgetc(); + } + else + { + __str += __traits_type::to_char_type(__c); + ++__extracted; + __c = __sb->snextc(); + } + } + + if (__traits_type::eq_int_type(__c, __eof)) + __err |= ios_base::eofbit; + else if (__traits_type::eq_int_type(__c, __idelim)) + { + ++__extracted; + __sb->sbumpc(); + } + else + __err |= ios_base::failbit; + } + __catch(__cxxabiv1::__forced_unwind&) + { + __in._M_setstate(ios_base::badbit); + __throw_exception_again; + } + __catch(...) + { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 91. Description of operator>> and getline() for string<> + // might cause endless loop + __in._M_setstate(ios_base::badbit); + } + } + if (!__extracted) + __err |= ios_base::failbit; + if (__err) + __in.setstate(__err); + return __in; + } +#endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace diff --git a/libstdc++-v3/src/c++98/istream.cc b/libstdc++-v3/src/c++98/istream.cc index c6dc0d60456..f0b024ed677 100644 --- a/libstdc++-v3/src/c++98/istream.cc +++ b/libstdc++-v3/src/c++98/istream.cc @@ -273,169 +273,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __in; } - template<> - basic_istream& - operator>>(basic_istream& __in, basic_string& __str) - { - typedef basic_istream __istream_type; - typedef __istream_type::int_type __int_type; - typedef __istream_type::traits_type __traits_type; - typedef __istream_type::__streambuf_type __streambuf_type; - typedef __istream_type::__ctype_type __ctype_type; - typedef basic_string __string_type; - typedef __string_type::size_type __size_type; - - __size_type __extracted = 0; - ios_base::iostate __err = ios_base::goodbit; - __istream_type::sentry __cerb(__in, false); - if (__cerb) - { - __try - { - __str.erase(); - const streamsize __w = __in.width(); - const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) - : __str.max_size(); - const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); - const __int_type __eof = __traits_type::eof(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (__extracted < __n - && !__traits_type::eq_int_type(__c, __eof) - && !__ct.is(ctype_base::space, - __traits_type::to_char_type(__c))) - { - streamsize __size = std::min(streamsize(__sb->egptr() - - __sb->gptr()), - streamsize(__n - __extracted)); - if (__size > 1) - { - __size = (__ct.scan_is(ctype_base::space, - __sb->gptr() + 1, - __sb->gptr() + __size) - - __sb->gptr()); - __str.append(__sb->gptr(), __size); - __sb->__safe_gbump(__size); - __extracted += __size; - __c = __sb->sgetc(); - } - else - { - __str += __traits_type::to_char_type(__c); - ++__extracted; - __c = __sb->snextc(); - } - } - - if (__traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - __in.width(0); - } - __catch(__cxxabiv1::__forced_unwind&) - { - __in._M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 91. Description of operator>> and getline() for string<> - // might cause endless loop - __in._M_setstate(ios_base::badbit); - } - } - if (!__extracted) - __err |= ios_base::failbit; - if (__err) - __in.setstate(__err); - return __in; - } - - template<> - basic_istream& - getline(basic_istream& __in, basic_string& __str, - char __delim) - { - typedef basic_istream __istream_type; - typedef __istream_type::int_type __int_type; - typedef __istream_type::char_type __char_type; - typedef __istream_type::traits_type __traits_type; - typedef __istream_type::__streambuf_type __streambuf_type; - typedef basic_string __string_type; - typedef __string_type::size_type __size_type; - - __size_type __extracted = 0; - const __size_type __n = __str.max_size(); - ios_base::iostate __err = ios_base::goodbit; - __istream_type::sentry __cerb(__in, true); - if (__cerb) - { - __try - { - __str.erase(); - const __int_type __idelim = __traits_type::to_int_type(__delim); - const __int_type __eof = __traits_type::eof(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (__extracted < __n - && !__traits_type::eq_int_type(__c, __eof) - && !__traits_type::eq_int_type(__c, __idelim)) - { - streamsize __size = std::min(streamsize(__sb->egptr() - - __sb->gptr()), - streamsize(__n - __extracted)); - if (__size > 1) - { - const __char_type* __p = __traits_type::find(__sb->gptr(), - __size, - __delim); - if (__p) - __size = __p - __sb->gptr(); - __str.append(__sb->gptr(), __size); - __sb->__safe_gbump(__size); - __extracted += __size; - __c = __sb->sgetc(); - } - else - { - __str += __traits_type::to_char_type(__c); - ++__extracted; - __c = __sb->snextc(); - } - } - - if (__traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (__traits_type::eq_int_type(__c, __idelim)) - { - ++__extracted; - __sb->sbumpc(); - } - else - __err |= ios_base::failbit; - } - __catch(__cxxabiv1::__forced_unwind&) - { - __in._M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 91. Description of operator>> and getline() for string<> - // might cause endless loop - __in._M_setstate(ios_base::badbit); - } - } - if (!__extracted) - __err |= ios_base::failbit; - if (__err) - __in.setstate(__err); - return __in; - } - #ifdef _GLIBCXX_USE_WCHAR_T template<> basic_istream& @@ -596,91 +433,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } return *this; } - - template<> - basic_istream& - getline(basic_istream& __in, basic_string& __str, - wchar_t __delim) - { - typedef basic_istream __istream_type; - typedef __istream_type::int_type __int_type; - typedef __istream_type::char_type __char_type; - typedef __istream_type::traits_type __traits_type; - typedef __istream_type::__streambuf_type __streambuf_type; - typedef basic_string __string_type; - typedef __string_type::size_type __size_type; - - __size_type __extracted = 0; - const __size_type __n = __str.max_size(); - ios_base::iostate __err = ios_base::goodbit; - __istream_type::sentry __cerb(__in, true); - if (__cerb) - { - __try - { - __str.erase(); - const __int_type __idelim = __traits_type::to_int_type(__delim); - const __int_type __eof = __traits_type::eof(); - __streambuf_type* __sb = __in.rdbuf(); - __int_type __c = __sb->sgetc(); - - while (__extracted < __n - && !__traits_type::eq_int_type(__c, __eof) - && !__traits_type::eq_int_type(__c, __idelim)) - { - streamsize __size = std::min(streamsize(__sb->egptr() - - __sb->gptr()), - streamsize(__n - __extracted)); - if (__size > 1) - { - const __char_type* __p = __traits_type::find(__sb->gptr(), - __size, - __delim); - if (__p) - __size = __p - __sb->gptr(); - __str.append(__sb->gptr(), __size); - __sb->__safe_gbump(__size); - __extracted += __size; - __c = __sb->sgetc(); - } - else - { - __str += __traits_type::to_char_type(__c); - ++__extracted; - __c = __sb->snextc(); - } - } - - if (__traits_type::eq_int_type(__c, __eof)) - __err |= ios_base::eofbit; - else if (__traits_type::eq_int_type(__c, __idelim)) - { - ++__extracted; - __sb->sbumpc(); - } - else - __err |= ios_base::failbit; - } - __catch(__cxxabiv1::__forced_unwind&) - { - __in._M_setstate(ios_base::badbit); - __throw_exception_again; - } - __catch(...) - { - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 91. Description of operator>> and getline() for string<> - // might cause endless loop - __in._M_setstate(ios_base::badbit); - } - } - if (!__extracted) - __err |= ios_base::failbit; - if (__err) - __in.setstate(__err); - return __in; - } #endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/locale-inst.cc b/libstdc++-v3/src/c++98/locale-inst.cc index f4d03d96129..dd479218483 100644 --- a/libstdc++-v3/src/c++98/locale-inst.cc +++ b/libstdc++-v3/src/c++98/locale-inst.cc @@ -26,6 +26,15 @@ // ISO C++ 14882: 22.1 Locales // +#ifndef _GLIBCXX_USE_CXX11_ABI +// Instantiations in this file use the old COW std::string ABI unless included +// by another file which defines _GLIBCXX_USE_CXX11_ABI=1. Some instantiations +// are guarded by a check for !_GLIBCXX_USE_CXX11_ABI so that they are only +// instantiated once, because they are not tagged with abi_tag so should not +// be instantiated twice. +# define _GLIBCXX_USE_CXX11_ABI 0 +#endif + #include // Instantiation configuration. @@ -39,13 +48,17 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_BEGIN_NAMESPACE_VERSION // moneypunct, money_get, and money_put - template class moneypunct; - template class moneypunct; +#if ! _GLIBCXX_USE_CXX11_ABI template struct __moneypunct_cache; template struct __moneypunct_cache; +#endif +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template class moneypunct; + template class moneypunct; template class moneypunct_byname; template class moneypunct_byname; -_GLIBCXX_BEGIN_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_CXX11 +_GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 template class money_get >; template class money_put >; template @@ -71,15 +84,21 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL money_put >:: _M_insert(ostreambuf_iterator, ios_base&, C, const string_type&) const; -_GLIBCXX_END_NAMESPACE_LDBL +_GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 // numpunct, numpunct_byname, num_get, and num_put - template class numpunct; +#if ! _GLIBCXX_USE_CXX11_ABI template struct __numpunct_cache; +#endif +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + template class numpunct; template class numpunct_byname; +_GLIBCXX_END_NAMESPACE_CXX11 _GLIBCXX_BEGIN_NAMESPACE_LDBL +#if ! _GLIBCXX_USE_CXX11_ABI template class num_get >; - template class num_put >; +#endif + template istreambuf_iterator num_get >:: @@ -124,6 +143,9 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL unsigned long long&) const; #endif +#if ! _GLIBCXX_USE_CXX11_ABI + template class num_put >; + template ostreambuf_iterator num_put >:: @@ -161,33 +183,47 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL num_put >:: _M_insert_float(ostreambuf_iterator, ios_base&, C, char, long double) const; +#endif _GLIBCXX_END_NAMESPACE_LDBL // time_get and time_put +#if ! _GLIBCXX_USE_CXX11_ABI template class __timepunct; template struct __timepunct_cache; template class time_put >; template class time_put_byname >; +#endif +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class time_get >; template class time_get_byname >; +_GLIBCXX_END_NAMESPACE_CXX11 // messages +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class messages; template class messages_byname; +_GLIBCXX_END_NAMESPACE_CXX11 // ctype +#if ! _GLIBCXX_USE_CXX11_ABI inline template class __ctype_abstract_base; template class ctype_byname; +#endif // codecvt +#if ! _GLIBCXX_USE_CXX11_ABI inline template class __codecvt_abstract_base; template class codecvt_byname; +#endif // collate +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class collate; template class collate_byname; +_GLIBCXX_END_NAMESPACE_CXX11 // use_facet +#if ! _GLIBCXX_USE_CXX11_ABI template const ctype& use_facet >(const locale&); @@ -195,6 +231,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template const codecvt& use_facet >(const locale&); +#endif template const collate& @@ -204,6 +241,7 @@ _GLIBCXX_END_NAMESPACE_LDBL const numpunct& use_facet >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template const num_put& use_facet >(const locale&); @@ -211,6 +249,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template const num_get& use_facet >(const locale&); +#endif template const moneypunct& @@ -228,6 +267,7 @@ _GLIBCXX_END_NAMESPACE_LDBL const money_get& use_facet >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template const __timepunct& use_facet<__timepunct >(const locale&); @@ -235,6 +275,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template const time_put& use_facet >(const locale&); +#endif template const time_get& @@ -245,6 +286,7 @@ _GLIBCXX_END_NAMESPACE_LDBL use_facet >(const locale&); // has_facet +#if ! _GLIBCXX_USE_CXX11_ABI template bool has_facet >(const locale&); @@ -252,6 +294,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template bool has_facet >(const locale&); +#endif template bool @@ -261,6 +304,7 @@ _GLIBCXX_END_NAMESPACE_LDBL bool has_facet >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template bool has_facet >(const locale&); @@ -268,6 +312,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template bool has_facet >(const locale&); +#endif template bool @@ -281,6 +326,7 @@ _GLIBCXX_END_NAMESPACE_LDBL bool has_facet >(const locale&); +#if ! _GLIBCXX_USE_CXX11_ABI template bool has_facet<__timepunct >(const locale&); @@ -288,6 +334,7 @@ _GLIBCXX_END_NAMESPACE_LDBL template bool has_facet >(const locale&); +#endif template bool @@ -322,7 +369,8 @@ _GLIBCXX_END_NAMESPACE_VERSION } // namespace // XXX GLIBCXX_ABI Deprecated -#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined C_is_char +#if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined C_is_char \ + && _GLIBCXX_USE_CXX11_ABI == 0 #define _GLIBCXX_LDBL_COMPAT(dbl, ldbl) \ extern "C" void ldbl (void) __attribute__ ((alias (#dbl), weak)) diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc index 79882322a5e..a12bba77e0c 100644 --- a/libstdc++-v3/src/c++98/locale.cc +++ b/libstdc++-v3/src/c++98/locale.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 1 #include #include #include // For getenv @@ -118,6 +119,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return *this; } + _GLIBCXX_DEFAULT_ABI_TAG string locale::name() const { @@ -357,6 +359,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const facet*& __fpr = _M_facets[__index]; if (__fpr) { +#if _GLIBCXX_USE_DUAL_ABI + // If this is a twinned facet replace its twin with a shim. + for (const id* const* p = _S_twinned_facets; *p != 0; p += 2) + { + if (p[0]->_M_id() == __index) + { + // replacing the old ABI facet, also replace new ABI twin + const facet*& __fpr2 = _M_facets[p[1]->_M_id()]; + if (__fpr2) + { + const facet* __fp2 = __fp->_M_sso_shim(p[1]); + __fp2->_M_add_reference(); + __fpr2->_M_remove_reference(); + __fpr2 = __fp2; + } + break; + } + else if (p[1]->_M_id() == __index) + { + // replacing the new ABI facet, also replace old ABI twin + const facet*& __fpr2 = _M_facets[p[0]->_M_id()]; + if (__fpr2) + { + const facet* __fp2 = __fp->_M_cow_shim(p[0]); + __fp2->_M_add_reference(); + __fpr2->_M_remove_reference(); + __fpr2 = __fp2; + } + break; + } + } +#endif // Replacing an existing facet. Order matters. __fpr->_M_remove_reference(); __fpr = __fp; @@ -391,6 +425,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_install_cache(const facet* __cache, size_t __index) { __gnu_cxx::__scoped_lock sentry(get_locale_cache_mutex()); +#if _GLIBCXX_USE_DUAL_ABI + // If this cache is for one of the facets that is instantiated twice, + // for old and new std::string ABI, install it in both slots. + size_t __index2 = -1; + for (const id* const* p = _S_twinned_facets; *p != 0; p += 2) + { + if (p[0]->_M_id() == __index) + { + __index2 = p[1]->_M_id(); + break; + } + else if (p[1]->_M_id() == __index) + { + __index2 = __index; + __index = p[0]->_M_id(); + break; + } + } +#endif if (_M_caches[__index] != 0) { // Some other thread got in first. @@ -400,6 +453,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __cache->_M_add_reference(); _M_caches[__index] = __cache; +#if _GLIBCXX_USE_DUAL_ABI + if (__index2 != size_t(-1)) + { + __cache->_M_add_reference(); + _M_caches[__index2] = __cache; + } +#endif } } diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc index b3ca5dc8c9d..808d93721b7 100644 --- a/libstdc++-v3/src/c++98/locale_facets.cc +++ b/libstdc++-v3/src/c++98/locale_facets.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 0 #include namespace std _GLIBCXX_VISIBILITY(default) @@ -97,11 +98,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION *__fptr = '\0'; } - bool - __verify_grouping(const char* __grouping, size_t __grouping_size, - const string& __grouping_tmp) throw() + // This function is not exported but is needed internally, by the versions + // of __verify_grouping below and in src/c++11/cxx11-locale-inst.cc + extern bool + __verify_grouping_impl(const char* __grouping, size_t __grouping_size, + const char* __grouping_tmp, size_t __grouping_tmp_size) { - const size_t __n = __grouping_tmp.size() - 1; + const size_t __n = __grouping_tmp_size - 1; const size_t __min = std::min(__n, size_t(__grouping_size - 1)); size_t __i = __n; bool __test = true; @@ -122,5 +125,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __test; } + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) throw() + { + return __verify_grouping_impl(__grouping, __grouping_size, + __grouping_tmp.c_str(), + __grouping_tmp.size()); + } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc index c007648d37b..f9683fc21d1 100644 --- a/libstdc++-v3/src/c++98/locale_init.cc +++ b/libstdc++-v3/src/c++98/locale_init.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 1 #include #include #include // For getenv, free. @@ -28,8 +29,37 @@ #include #include +#if _GLIBCXX_USE_DUAL_ABI +// This file is compiled with the new std::string ABI so std::numpunct +// refers to std::__cxx11::numpunct. These declarations let us refer +// to the other facets instantiated with the old ABI. +# define _GLIBCXX_LOC_ID(mangled) extern std::locale::id mangled +_GLIBCXX_LOC_ID(_ZNSt8numpunctIcE2idE); +_GLIBCXX_LOC_ID(_ZNSt7collateIcE2idE); +_GLIBCXX_LOC_ID(_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIcLb0EE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIcLb1EE2idE); +_GLIBCXX_LOC_ID(_ZNSt8messagesIcE2idE); +# ifdef _GLIBCXX_USE_WCHAR_T +_GLIBCXX_LOC_ID(_ZNSt8numpunctIwE2idE); +_GLIBCXX_LOC_ID(_ZNSt7collateIwE2idE); +_GLIBCXX_LOC_ID(_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIwLb0EE2idE); +_GLIBCXX_LOC_ID(_ZNSt10moneypunctIwLb1EE2idE); +_GLIBCXX_LOC_ID(_ZNSt8messagesIwE2idE); +# endif +#endif + + namespace { + const int num_facets = _GLIBCXX_NUM_FACETS + + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0); + __gnu_cxx::__mutex& get_locale_mutex() { @@ -57,11 +87,11 @@ namespace typedef char fake_facet_vec[sizeof(locale::facet*)] __attribute__ ((aligned(__alignof__(locale::facet*)))); - fake_facet_vec facet_vec[_GLIBCXX_NUM_FACETS]; + fake_facet_vec facet_vec[num_facets]; typedef char fake_cache_vec[sizeof(locale::facet*)] __attribute__ ((aligned(__alignof__(locale::facet*)))); - fake_cache_vec cache_vec[_GLIBCXX_NUM_FACETS]; + fake_cache_vec cache_vec[num_facets]; typedef char fake_ctype_c[sizeof(std::ctype)] __attribute__ ((aligned(__alignof__(std::ctype)))); @@ -355,7 +385,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif 0 }; - + const locale::id* const* const locale::_Impl::_S_facet_categories[] = { @@ -369,10 +399,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 0 }; +#if _GLIBCXX_USE_DUAL_ABI + // Facets that are instantiated for both the COW and SSO std::string ABIs. + // The COW ABI version must come first, followed by its SSO twin. + const locale::id* const locale::_S_twinned_facets[] = { + &::_ZNSt8numpunctIcE2idE, + &numpunct::id, + &::_ZNSt7collateIcE2idE, + &std::collate::id, + &::_ZNSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE, + &time_get::id, + &::_ZNSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2idE, + &money_get::id, + &::_ZNSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE, + &money_put::id, + &::_ZNSt10moneypunctIcLb0EE2idE, + &moneypunct::id, + &::_ZNSt10moneypunctIcLb1EE2idE, + &moneypunct::id, + &::_ZNSt8messagesIcE2idE, + &std::messages::id, +# ifdef _GLIBCXX_USE_WCHAR_T + &::_ZNSt8numpunctIwE2idE, + &numpunct::id, + &::_ZNSt7collateIwE2idE, + &std::collate::id, + &::_ZNSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE, + &time_get::id, + &::_ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE, + &money_get::id, + &::_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE, + &money_put::id, + &::_ZNSt10moneypunctIwLb0EE2idE, + &moneypunct::id, + &::_ZNSt10moneypunctIwLb1EE2idE, + &moneypunct::id, + &::_ZNSt8messagesIwE2idE, + &std::messages::id, +# endif + 0, 0 + }; +#endif + // Construct "C" _Impl. locale::_Impl:: _Impl(size_t __refs) throw() - : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS), + : _M_refcount(__refs), _M_facets(0), _M_facets_size(num_facets), _M_caches(0), _M_names(0) { _M_facets = new (&facet_vec) const facet*[_M_facets_size](); @@ -448,8 +520,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_init_facet(new (&time_get_w) time_get(1)); _M_init_facet(new (&time_put_w) time_put(1)); _M_init_facet(new (&messages_w) std::messages(1)); -#endif - +#endif + +#if _GLIBCXX_USE_DUAL_ABI + facet* extra[] = { __npc, __mpcf, __mpct +# ifdef _GLIBCXX_USE_WCHAR_T + , __npw, __mpwf, __mpwt +# endif + }; + + _M_init_extra(extra); +#endif + // This locale is safe to pre-cache, after all the facets have // been created and installed. _M_caches[numpunct::id._M_id()] = __npc; diff --git a/libstdc++-v3/src/c++98/localename.cc b/libstdc++-v3/src/c++98/localename.cc index 589f8c6617d..282471f121a 100644 --- a/libstdc++-v3/src/c++98/localename.cc +++ b/libstdc++-v3/src/c++98/localename.cc @@ -20,6 +20,7 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . +#define _GLIBCXX_USE_CXX11_ABI 1 #include #include #include @@ -170,10 +171,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +const int num_facets = _GLIBCXX_NUM_FACETS + + (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0); + // Construct named _Impl. locale::_Impl:: _Impl(const char* __s, size_t __refs) - : _M_refcount(__refs), _M_facets(0), _M_facets_size(_GLIBCXX_NUM_FACETS), + : _M_refcount(__refs), _M_facets(0), _M_facets_size(num_facets), _M_caches(0), _M_names(0) { // Initialize the underlying locale model, which also checks to @@ -264,6 +268,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_init_facet(new time_put); _M_init_facet(new std::messages(__cloc, __s)); #endif + +#if _GLIBCXX_USE_DUAL_ABI + _M_init_extra(&__cloc, &__clocm, __s, __smon); +#endif + locale::facet::_S_destroy_c_locale(__cloc); if (__clocm != __cloc) locale::facet::_S_destroy_c_locale(__clocm); diff --git a/libstdc++-v3/src/c++98/misc-inst.cc b/libstdc++-v3/src/c++98/misc-inst.cc index 540e76d468c..989218f6e7e 100644 --- a/libstdc++-v3/src/c++98/misc-inst.cc +++ b/libstdc++-v3/src/c++98/misc-inst.cc @@ -26,6 +26,8 @@ // ISO C++ 14882: // +#define _GLIBCXX_USE_CXX11_ABI 1 +#define _GLIBCXX_DISAMBIGUATE_REPLACE_INST 1 #include #include #include @@ -62,5 +64,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION getline(basic_istream&, wstring&); #endif +#if _GLIBCXX_USE_CXX11_ABI + // C++98 members that are not instantiated by src/c++11/string-inst.cc + // because they changed in C++11 to take const_iterator parameters. + template string::iterator string::erase(iterator); + template void string::insert(iterator, iterator, iterator); + template string::iterator string::insert(iterator, char); + template string& string::replace(iterator, iterator, size_type, char); + template string& string::replace(iterator, iterator, char*, char*); + template string& string::replace(iterator, iterator, iterator, iterator); + template string& + string::replace(iterator, iterator, const_iterator, const_iterator); + +#ifdef _GLIBCXX_USE_WCHAR_T + template wstring::iterator wstring::erase(iterator); + template void wstring::insert(iterator, iterator, iterator); + template wstring::iterator wstring::insert(iterator, wchar_t); + template wstring& wstring::replace(iterator, iterator, size_type, wchar_t); + template wstring& wstring::replace(iterator, iterator, wchar_t*, wchar_t*); + template wstring& wstring::replace(iterator, iterator, iterator, iterator); + template wstring& + wstring::replace(iterator, iterator, const_iterator, const_iterator); +#endif + + // XXX this doesn't belong in an -inst.cc file + // Defined in src/c++98/locale_facets.cc + _GLIBCXX_PURE bool + __verify_grouping_impl(const char* __grouping, size_t __grouping_size, + const char* __grouping_tmp, size_t __n); + + bool + __verify_grouping(const char* __grouping, size_t __grouping_size, + const string& __grouping_tmp) throw() + { + return __verify_grouping_impl(__grouping, __grouping_size, + __grouping_tmp.c_str(), + __grouping_tmp.size()); + } +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/stdexcept.cc b/libstdc++-v3/src/c++98/stdexcept.cc index c3fdc380ac5..25c75f405a1 100644 --- a/libstdc++-v3/src/c++98/stdexcept.cc +++ b/libstdc++-v3/src/c++98/stdexcept.cc @@ -26,6 +26,8 @@ // ISO C++ 14882: 19.1 Exception classes // +// All exception classes still use the classic COW std::string. +#define _GLIBCXX_USE_CXX11_ABI 0 #include #include diff --git a/libstdc++-v3/src/c++98/wlocale-inst.cc b/libstdc++-v3/src/c++98/wlocale-inst.cc index 2bcfa985e19..85ab48aa419 100644 --- a/libstdc++-v3/src/c++98/wlocale-inst.cc +++ b/libstdc++-v3/src/c++98/wlocale-inst.cc @@ -26,6 +26,8 @@ // ISO C++ 14882: 22.1 Locales // +// Instantiate locales using COW std::wstring ABI +#define _GLIBCXX_USE_CXX11_ABI 0 #include #ifdef _GLIBCXX_USE_WCHAR_T diff --git a/libstdc++-v3/testsuite/18_support/50594.cc b/libstdc++-v3/testsuite/18_support/50594.cc index 27538af76ad..54448279c3d 100644 --- a/libstdc++-v3/testsuite/18_support/50594.cc +++ b/libstdc++-v3/testsuite/18_support/50594.cc @@ -59,7 +59,7 @@ void test01() bool test __attribute__((unused)) = true; { - std::string s = "Hello World."; + std::string s = "Hello World, this is not a small string."; } VERIFY( user_new_called ); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc index eb4565c4fcd..32d4ec0375b 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/1.cc @@ -140,7 +140,11 @@ void test01() VERIFY( sz04 >= 100 ); str02.reserve(); sz03 = str02.capacity(); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sz03 < 100); +#else VERIFY( sz03 == 0 ); +#endif sz03 = str02.size() + 5; str02.resize(sz03); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc index 29bb91eae94..dc15b252422 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/1.cc @@ -36,7 +36,11 @@ void test01() VERIFY( sz02 >= 100 ); str01.reserve(); sz01 = str01.capacity(); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sz01 < 100); +#else VERIFY( sz01 == 0 ); +#endif sz01 = str01.size() + 5; str01.resize(sz01); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc index d1e0d69ce80..9a54b6b402c 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc @@ -36,10 +36,13 @@ void test01() typedef string::size_type size_type; - // Our current implementation provides exact shrink-to-size - // and shrink-to-fit (in the future, maybe this will change - // for short strings). +#if _GLIBCXX_USE_CXX11_ABI + // Can't shrink below small string size. + const size_type minsize = 2 << 3; +#else + // Exact shrink-to-size and shrink-to-fit const size_type minsize = 2 << 0; +#endif const size_type maxsize = 2 << MAX_SIZE; for (size_type i = minsize; i <= maxsize; i *= 2) { diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc index 8e520688400..333fe151b5e 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/2.cc @@ -32,7 +32,7 @@ void test02() // str01 becomes shared std::string str02 = str01; str01.reserve(1); - VERIFY( str01.capacity() == 12 ); + VERIFY( str01.capacity() >= 12 ); } int main() diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc index 150a8f8a32b..8efc7151fbc 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/1.cc @@ -36,7 +36,11 @@ void test01() VERIFY( sz02 >= 100 ); str01.reserve(); sz01 = str01.capacity(); +#if _GLIBCXX_USE_CXX11_ABI + VERIFY( sz01 < 100); +#else VERIFY( sz01 == 0 ); +#endif sz01 = str01.size() + 5; str01.resize(sz01); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc index e4cd85c953f..855578dc4af 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc @@ -36,10 +36,13 @@ void test01() typedef wstring::size_type size_type; - // Our current implementation provides exact shrink-to-size - // and shrink-to-fit (in the future, maybe this will change - // for short strings). +#if _GLIBCXX_USE_CXX11_ABI + // Can't shrink below small string size. + const size_type minsize = 2 << 1; +#else + // Exact shrink-to-size and shrink-to-fit const size_type minsize = 2 << 0; +#endif const size_type maxsize = 2 << MAX_SIZE; for (size_type i = minsize; i <= maxsize; i *= 2) { diff --git a/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc b/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc index 95b8e9b3518..ff14038f1fa 100644 --- a/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc +++ b/libstdc++-v3/testsuite/21_strings/headers/string/synopsis.cc @@ -26,9 +26,11 @@ namespace std { template <> struct char_traits; template <> struct char_traits; +_GLIBCXX_BEGIN_NAMESPACE_CXX11 // lib.basic.string, basic_string: template class basic_string; +_GLIBCXX_END_NAMESPACE_CXX11 template basic_string diff --git a/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc b/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc index dc9330b9f98..8b76de75823 100644 --- a/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc +++ b/libstdc++-v3/testsuite/23_containers/headers/list/synopsis.cc @@ -21,7 +21,9 @@ #include namespace std { +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class list; +_GLIBCXX_END_NAMESPACE_CXX11 template bool operator==(const list& x, const list&); diff --git a/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc index 306d22f4d89..577daccade9 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ios/copyfmt/char/1.cc @@ -17,6 +17,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } // 27.4.4.2 basic_ios member functions diff --git a/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc b/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc index 4359ca847f4..0fe273914a3 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ios/exceptions/char/1.cc @@ -17,6 +17,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } // 27.4.4.2 basic_ios member functions diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc index 23064dbad35..e390b9ecf86 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/char/exceptions_failbit.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include #include diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc index 133c5d7768a..6588a8ae5d8 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/exceptions_failbit.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include #include diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc index d1ce3adedfd..d73b3025e3b 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/char/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include #include diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc index 1e64cb2f435..f609d0441ae 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/wchar_t/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include #include diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc index f9dbb0519af..80486529895 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/12297.cc @@ -18,6 +18,9 @@ // 27.6.1.1.2 class basic_istream::sentry +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } + #include #include diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc index 8d884184766..1e3fc01397b 100644 --- a/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc +++ b/libstdc++-v3/testsuite/27_io/basic_istream/sentry/wchar_t/12297.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } // 27.6.1.1.2 class basic_istream::sentry diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc index 564f43a0573..781b5f0b6b1 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/char/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include #include diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc index c769ecbc1f8..8539340ecbe 100644 --- a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_other/wchar_t/exceptions_null.cc @@ -15,6 +15,8 @@ // with this library; see the file COPYING3. If not see // . +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } #include #include diff --git a/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc b/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc index 14534fdfb04..f1e1af2df95 100644 --- a/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc +++ b/libstdc++-v3/testsuite/27_io/headers/sstream/synopsis.cc @@ -20,6 +20,7 @@ #include namespace std { +_GLIBCXX_BEGIN_NAMESPACE_CXX11 template class basic_stringbuf; typedef basic_stringbuf stringbuf; @@ -39,4 +40,5 @@ namespace std { class basic_stringstream; typedef basic_stringstream stringstream; typedef basic_stringstream wstringstream; +_GLIBCXX_END_NAMESPACE_CXX11 } diff --git a/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc index a3276e1c5bd..29d1b63ad87 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/failure/cxx11.cc @@ -20,6 +20,7 @@ #include #include +#if _GLIBCXX_USE_CXX11_ABI using test_type = std::ios_base::failure; static_assert( std::is_base_of::value, "base" ); @@ -50,3 +51,6 @@ main() test01(); test02(); } +#else +int main() { } +#endif diff --git a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc index 2304b1a2649..0a2ed8c8d86 100644 --- a/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc +++ b/libstdc++-v3/testsuite/27_io/ios_base/storage/2.cc @@ -28,6 +28,9 @@ // Radar 6467884: 10.X systems are not robust when paging space is exceeded // { dg-skip-if "" { *-*-darwin* && lp64 } { "*" } { "" } } +// The library still throws the original definition of std::ios::failure +// { dg-options "-D_GLIBCXX_USE_CXX11_ABI=0" } + #include #include #include diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in index 7100a64f98f..ac64520f77f 100644 --- a/libstdc++-v3/testsuite/Makefile.in +++ b/libstdc++-v3/testsuite/Makefile.in @@ -216,6 +216,7 @@ glibcxx_POFILES = @glibcxx_POFILES@ glibcxx_builddir = @glibcxx_builddir@ glibcxx_compiler_pic_flag = @glibcxx_compiler_pic_flag@ glibcxx_compiler_shared_flag = @glibcxx_compiler_shared_flag@ +glibcxx_cxx98_abi = @glibcxx_cxx98_abi@ glibcxx_localedir = @glibcxx_localedir@ glibcxx_lt_pic_flag = @glibcxx_lt_pic_flag@ glibcxx_prefixdir = @glibcxx_prefixdir@ diff --git a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc index 5597c57d239..76e045d195c 100644 --- a/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc +++ b/libstdc++-v3/testsuite/ext/profile/mutex_extensions_neg.cc @@ -25,4 +25,4 @@ #include -// { dg-error "multiple inlined namespaces" "" { target *-*-* } 290 } +// { dg-error "multiple inlined namespaces" "" { target *-*-* } 306 } diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc index e2f99a1bd6d..2c42b7daf4f 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/libfundts.cc @@ -18,6 +18,9 @@ // with this library; see the file COPYING3. If not see // . +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include #include #include diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc index 030207aa67c..167a7116d59 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple.cc @@ -20,6 +20,9 @@ // with this library; see the file COPYING3. If not see // . +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include #include #include diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc index e94bea6ec84..fc2e03cd707 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/simple11.cc @@ -20,6 +20,9 @@ // with this library; see the file COPYING3. If not see // . +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include #include #include diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc index b3989720abc..76ba1b8fc9c 100644 --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/whatis.cc @@ -18,6 +18,9 @@ // with this library; see the file COPYING3. If not see // . +// Type printers only recognize the old std::string for now. +#define _GLIBCXX_USE_CXX11_ABI 0 + #include #include #include diff --git a/libstdc++-v3/testsuite/util/exception/safety.h b/libstdc++-v3/testsuite/util/exception/safety.h index bb3f0a22f4d..22dff63c4ef 100644 --- a/libstdc++-v3/testsuite/util/exception/safety.h +++ b/libstdc++-v3/testsuite/util/exception/safety.h @@ -255,6 +255,7 @@ namespace __gnu_test : _F_erase_point(&_Tp::erase), _F_erase_range(&_Tp::erase) { } }; +#if _GLIBCXX_USE_CXX11_ABI == 0 || __cplusplus < 201103L // Specialization, old C++03 signature. template struct erase_base> @@ -269,6 +270,7 @@ namespace __gnu_test : _F_erase_point(&container_type::erase), _F_erase_range(&container_type::erase) { } }; +#endif // Specialization, as forward_list has erase_after. template @@ -676,9 +678,15 @@ namespace __gnu_test { typedef std::basic_string<_Tp1, _Tp2, _Tp3> container_type; typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; typedef typename container_type::value_type value_type; +#if _GLIBCXX_USE_CXX11_ABI == 0 || __cplusplus < 201103L iterator (container_type::* _F_insert_point)(iterator, value_type); +#else + iterator (container_type::* _F_insert_point)(const_iterator, + value_type); +#endif insert_base() : _F_insert_point(&container_type::insert) { } }; diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 15b05dcb957..958ec0ff750 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -201,6 +201,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_3.4.19"); known_versions.push_back("GLIBCXX_3.4.20"); known_versions.push_back("GLIBCXX_3.4.21"); + known_versions.push_back("GLIBCXX_LDBL_3.4.21"); known_versions.push_back("CXXABI_1.3"); known_versions.push_back("CXXABI_LDBL_1.3"); known_versions.push_back("CXXABI_1.3.1"); @@ -239,7 +240,8 @@ check_version(symbol& test, bool added) // Check that long double compatibility symbols demangled as // __float128 and regular __float128 symbols are put into some _LDBL_ // or _FLOAT128 version name. - if (added && test.demangled_name.find("__float128") != std::string::npos) + if (added && test.demangled_name.find("__float128") != std::string::npos + && test.demangled_name.find("std::__cxx11::") != 0) { if (test.version_name.find("_LDBL_") == std::string::npos && test.version_name.find("_FLOAT128") == std::string::npos)