Skip to content

Commit

Permalink
Implement LWG-3767 codecvt<charN_t, char8_t, mbstate_t> incorrectly…
Browse files Browse the repository at this point in the history
… added to locale (#4542)

Co-authored-by: Stephan T. Lavavej <[email protected]>
  • Loading branch information
frederick-vs-ja and StephanTLavavej authored Apr 9, 2024
1 parent 06b286c commit 9465bb0
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 13 deletions.
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) \
&& !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

0 comments on commit 9465bb0

Please sign in to comment.