Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement LWG-3767 codecvt<charN_t, char8_t, mbstate_t> incorrectly added to locale #4542

Merged
merged 4 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 69 additions & 10 deletions stl/inc/xlocale
Original file line number Diff line number Diff line change
Expand Up @@ -1397,7 +1397,7 @@ struct _NODISCARD _Codecvt_guard {
};

extern "C++" template <>
class codecvt<char16_t, char8_t, mbstate_t> : public codecvt_base {
class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt<char16_t, char8_t, mbstate_t> : public codecvt_base {
// facet for converting between UTF-16 and UTF-8 sequences
public:
using intern_type = char16_t;
Expand Down Expand Up @@ -1678,7 +1678,7 @@ protected:
};

extern "C++" template <>
class codecvt<char32_t, char8_t, mbstate_t> : public codecvt_base {
class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt<char32_t, char8_t, mbstate_t> : public codecvt_base {
// facet for converting between UTF-32 and UTF-8 sequences
public:
using intern_type = char32_t;
Expand Down Expand Up @@ -2321,26 +2321,85 @@ private:
#endif // defined(_NATIVE_WCHAR_T_DEFINED) && !_ENFORCE_FACET_SPECIALIZATIONS

_EXPORT_STD template <class _Elem, class _Byte, class _Statype>
class codecvt_byname : public codecvt<_Elem, _Byte, _Statype> { // codecvt for named locale
class codecvt_byname : public codecvt<_Elem, _Byte, _Statype> {
public:
static_assert(!_ENFORCE_FACET_SPECIALIZATIONS
|| _Is_any_of_v<codecvt_byname,
#ifdef __cpp_char8_t
codecvt_byname<char16_t, char8_t, mbstate_t>, codecvt_byname<char32_t, char8_t, mbstate_t>,
#endif // defined(__cpp_char8_t)
codecvt_byname<char, char, mbstate_t>, codecvt_byname<wchar_t, char, mbstate_t>>,
|| _Is_any_of_v<codecvt_byname, codecvt_byname<char, char, mbstate_t>,
codecvt_byname<wchar_t, char, mbstate_t>>,
_FACET_SPECIALIZATION_MESSAGE);

explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0)
: codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Locname), _Refs) {} // construct for named locale
: codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Locname), _Refs) {}

explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0)
: codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Str.c_str()), _Refs) {}

protected:
__CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {}
};

_STL_DISABLE_DEPRECATED_WARNING

template <>
class _CXX20_DEPRECATE_CODECVT_FACETS codecvt_byname<char16_t, char, mbstate_t>
: public codecvt<char16_t, char, mbstate_t> {
public:
explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0)
: codecvt(_Locinfo(_Locname), _Refs) {}

explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0)
: codecvt(_Locinfo(_Str.c_str()), _Refs) {}

protected:
__CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {}
};

template <>
class _CXX20_DEPRECATE_CODECVT_FACETS codecvt_byname<char32_t, char, mbstate_t>
: public codecvt<char32_t, char, mbstate_t> {
public:
explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0)
: codecvt(_Locinfo(_Locname), _Refs) {}

explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0)
: codecvt(_Locinfo(_Str.c_str()), _Refs) {}

protected:
__CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {}
};

#ifdef __cpp_char8_t
template <>
class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt_byname<char16_t, char8_t, mbstate_t>
: public codecvt<char16_t, char8_t, mbstate_t> {
public:
explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0)
: codecvt(_Locinfo(_Locname), _Refs) {}

explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0)
: codecvt<_Elem, _Byte, _Statype>(_Locinfo(_Str.c_str()), _Refs) {} // construct for named locale
: codecvt(_Locinfo(_Str.c_str()), _Refs) {}

protected:
__CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {}
};

template <>
class _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS codecvt_byname<char32_t, char8_t, mbstate_t>
: public codecvt<char32_t, char8_t, mbstate_t> {
public:
explicit __CLR_OR_THIS_CALL codecvt_byname(const char* _Locname, size_t _Refs = 0)
: codecvt(_Locinfo(_Locname), _Refs) {}

explicit __CLR_OR_THIS_CALL codecvt_byname(const string& _Str, size_t _Refs = 0)
: codecvt(_Locinfo(_Str.c_str()), _Refs) {}

protected:
__CLR_OR_THIS_CALL ~codecvt_byname() noexcept override {}
};
#endif // defined(__cpp_char8_t)

_STL_RESTORE_DEPRECATED_WARNING

#define _XA 0x100 // extra alphabetic
#define _BB _CONTROL // BEL, BS, etc.
#define _CN _SPACE // CR, FF, HT, NL, VT
Expand Down
17 changes: 14 additions & 3 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1253,8 +1253,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
[[deprecated("warning STL4020: " \
"std::codecvt<char16_t, char, mbstate_t>, std::codecvt<char32_t, char, mbstate_t>, " \
"std::codecvt_byname<char16_t, char, mbstate_t>, and std::codecvt_byname<char32_t, char, mbstate_t> " \
"are deprecated in C++20 and replaced by specializations with a second argument of type char8_t. " \
"You can define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING " \
"are deprecated in C++20. You can define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING " \
"or _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to suppress this warning.")]]
#else // ^^^ warning enabled / warning disabled vvv
#define _CXX20_DEPRECATE_CODECVT_FACETS
Expand Down Expand Up @@ -1514,7 +1513,19 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect
#define _DEPRECATE_TR1_RANDOM
#endif // ^^^ warning disabled ^^^

// next warning number: STL4047
#if _HAS_CXX20 && defined(__cpp_char8_t) && !defined(_SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING) \
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
&& !defined(_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS)
#define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS \
[[deprecated( \
"warning STL4047: std::codecvt<char16_t, char8_t, mbstate_t>, std::codecvt<char32_t, char8_t, mbstate_t>, " \
"std::codecvt_byname<char16_t, char8_t, mbstate_t>, and std::codecvt_byname<char32_t, char8_t, mbstate_t> " \
"are deprecated by LWG-3767. You can define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING or " \
"_SILENCE_ALL_CXX20_DEPRECATION_WARNINGS to suppress this warning.")]]
#else // ^^^ warning enabled / warning disabled vvv
#define _CXX20_DEPRECATE_CODECVT_CHAR8_T_FACETS
#endif // ^^^ warning disabled ^^^

// next warning number: STL4048

// next error number: STL1006

Expand Down
1 change: 1 addition & 0 deletions tests/std/tests/Dev09_056375_locale_cleanup/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING

#include <cassert>
#include <cstdio>
Expand Down
1 change: 1 addition & 0 deletions tests/std/tests/VSO_0397980_codecvt_length/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#define _SILENCE_CXX20_CODECVT_FACETS_DEPRECATION_WARNING
#define _SILENCE_CXX20_CODECVT_CHAR8_T_FACETS_DEPRECATION_WARNING

#undef _ENFORCE_FACET_SPECIALIZATIONS
#define _ENFORCE_FACET_SPECIALIZATIONS 0
Expand Down