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

<locale>: Hide some non-Standard functions of locale::id #5067

Merged
merged 4 commits into from
Nov 8, 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
2 changes: 1 addition & 1 deletion stl/inc/locale
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ protected:
_EXPORT_STD template <class _Facet>
_NODISCARD bool has_facet(const locale& _Loc) noexcept {
_BEGIN_LOCK(_LOCK_LOCALE) // the thread lock, make get atomic
size_t _Id = _Facet::id;
size_t _Id = _Facet::id._Get_index();
return _Loc._Getfacet(_Id) || _Facet::_Getcat() != static_cast<size_t>(-1);
_END_LOCK()
}
Expand Down
22 changes: 17 additions & 5 deletions stl/inc/xlocale
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,18 @@ public:

class _CRTIMP2_PURE_IMPORT id { // identifier stamp, unique for each distinct kind of facet
public:
#ifdef _CRTBLD // TRANSITION, ABI: preserved for binary compatibility
__CLR_OR_THIS_CALL id(size_t _Val = 0) : _Id(_Val) {}
#else // ^^^ defined(_CRTBLD) / !defined(_CRTBLD) vvv
template <int = 0> // TRANSITION, ABI
id() noexcept /* strengthened */ {}
#endif // ^^^ !defined(_CRTBLD) ^^^

id(const id&) = delete;
id& operator=(const id&) = delete;

__CLR_OR_THIS_CALL operator size_t() { // get stamp, with lazy allocation
template <int = 0> // TRANSITION, ABI
size_t _Get_index() { // get stamp, with lazy allocation
if (_Id == 0) { // still zero, allocate stamp
_BEGIN_LOCK(_LOCK_LOCALE)
if (_Id == 0) {
Expand All @@ -90,8 +96,14 @@ public:
return _Id;
}

#ifdef _CRTBLD // TRANSITION, ABI: preserved for binary compatibility
__CLR_OR_THIS_CALL operator size_t() {
return _Get_index();
}
#endif // defined(_CRTBLD)

private:
size_t _Id; // the identifier stamp
size_t _Id = 0; // the identifier stamp

__PURE_APPDOMAIN_GLOBAL static int _Id_cnt;
};
Expand Down Expand Up @@ -223,7 +235,7 @@ public:
_CATCH_END

_Locimp* _Newimp = _Locimp::_New_Locimp(*_Ptr);
_Newimp->_Addfac(_Facptr, _Facet::id);
_Newimp->_Addfac(_Facptr, _Facet::id._Get_index());
_Newimp->_Catmask = none;
_Newimp->_Name = "*";
return locale{_Secret_locale_construct_tag{}, _Newimp};
Expand All @@ -232,7 +244,7 @@ public:
template <class _Facet>
locale(const locale& _Loc, const _Facet* _Facptr) : _Ptr(_Locimp::_New_Locimp(*_Loc._Ptr)) {
if (_Facptr) { // replace facet
_Ptr->_Addfac(const_cast<_Facet*>(_Facptr), _Facet::id);
_Ptr->_Addfac(const_cast<_Facet*>(_Facptr), _Facet::id._Get_index());
_Ptr->_Catmask = none;
_Ptr->_Name = "*";
}
Expand Down Expand Up @@ -421,7 +433,7 @@ const _Facet& __CRTDECL use_facet(const locale& _Loc) { // get facet reference f
_BEGIN_LOCK(_LOCK_LOCALE) // the thread lock, make get atomic
const locale::facet* _Psave = _Facetptr<_Facet>::_Psave; // static pointer to lazy facet

const size_t _Id = _Facet::id;
const size_t _Id = _Facet::id._Get_index();
const locale::facet* _Pf = _Loc._Getfacet(_Id);

if (!_Pf) {
Expand Down
4 changes: 2 additions & 2 deletions stl/src/locale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ _MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL locale::global(const locale& loc) {
if ((_CATMASK(Facet::_Getcat()) & cat) == 0) { \
; \
} else if (ptrloc == nullptr) { \
ptrimp->_Addfac(new Facet(lobj), Facet::id); \
ptrimp->_Addfac(new Facet(lobj), Facet::id._Get_index()); \
} else { \
ptrimp->_Addfac( \
const_cast<locale::facet*>(static_cast<const locale::facet*>(&_STD use_facet<Facet>(*ptrloc))), \
Facet::id); \
Facet::id._Get_index()); \
}

using _Tc1 = ctype<char>;
Expand Down
10 changes: 5 additions & 5 deletions stl/src/locale0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,15 @@ __PURE_APPDOMAIN_GLOBAL locale::_Locimp* locale::_Locimp::_Clocptr = nullptr; //

__PURE_APPDOMAIN_GLOBAL int locale::id::_Id_cnt = 0; // unique id counter for facets

__PURE_APPDOMAIN_GLOBAL locale::id ctype<char>::id(0);
__PURE_APPDOMAIN_GLOBAL locale::id ctype<char>::id{};

__PURE_APPDOMAIN_GLOBAL locale::id ctype<wchar_t>::id(0);
__PURE_APPDOMAIN_GLOBAL locale::id ctype<wchar_t>::id{};

__PURE_APPDOMAIN_GLOBAL locale::id codecvt<wchar_t, char, mbstate_t>::id(0);
__PURE_APPDOMAIN_GLOBAL locale::id codecvt<wchar_t, char, mbstate_t>::id{};

__PURE_APPDOMAIN_GLOBAL locale::id ctype<unsigned short>::id(0);
__PURE_APPDOMAIN_GLOBAL locale::id ctype<unsigned short>::id{};

__PURE_APPDOMAIN_GLOBAL locale::id codecvt<unsigned short, char, mbstate_t>::id(0);
__PURE_APPDOMAIN_GLOBAL locale::id codecvt<unsigned short, char, mbstate_t>::id{};

_MRTIMP2_PURE const locale& __CLRCALL_PURE_OR_CDECL locale::classic() { // get reference to "C" locale
#if !defined(_M_CEE_PURE)
Expand Down
6 changes: 3 additions & 3 deletions stl/src/wlocale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ _STD_BEGIN
if ((_CATMASK(Facet::_Getcat()) & cat) == 0) { \
; \
} else if (ptrloc == nullptr) { \
ptrimp->_Addfac(new Facet(lobj), Facet::id); \
ptrimp->_Addfac(new Facet(lobj), Facet::id._Get_index()); \
} else { \
ptrimp->_Addfac( \
const_cast<locale::facet*>(static_cast<const locale::facet*>(&_STD use_facet<Facet>(*ptrloc))), \
Facet::id); \
Facet::id._Get_index()); \
}

// moved from locale to ease subsetting
Expand All @@ -36,7 +36,7 @@ using _Tw10 = moneypunct<wchar_t, true>;
using _Tw11 = time_get<wchar_t>;
using _Tw12 = time_put<wchar_t>;
using _Tw13 = codecvt<wchar_t, char, _Mbstatet>;
__PURE_APPDOMAIN_GLOBAL locale::id time_put<wchar_t>::id(0);
__PURE_APPDOMAIN_GLOBAL locale::id time_put<wchar_t>::id{};

void __CLRCALL_OR_CDECL locale::_Locimp::_Makewloc(const _Locinfo& lobj, locale::category cat, _Locimp* ptrimp,
const locale* ptrloc) { // setup wide part of a new locale
Expand Down
4 changes: 2 additions & 2 deletions stl/src/xlocale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ _STD_BEGIN
if ((_CATMASK(Facet::_Getcat()) & cat) == 0) { \
; \
} else if (ptrloc == nullptr) { \
ptrimp->_Addfac(new Facet(lobj), Facet::id); \
ptrimp->_Addfac(new Facet(lobj), Facet::id._Get_index()); \
} else { \
ptrimp->_Addfac( \
const_cast<locale::facet*>(static_cast<const locale::facet*>(&_STD use_facet<Facet>(*ptrloc))), \
Facet::id); \
Facet::id._Get_index()); \
}

// moved from locale to ease subsetting
Expand Down
18 changes: 18 additions & 0 deletions tests/std/tests/Dev09_056375_locale_cleanup/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

#include <cassert>
#include <cstdio>
#include <cwchar>
#include <locale>
#include <type_traits>

#pragma warning(push) // TRANSITION, OS-23694920
#pragma warning(disable : 4668) // 'MEOW' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
Expand Down Expand Up @@ -47,6 +49,22 @@ STATIC_ASSERT(!is_implicitly_default_constructible<locale::facet>);
STATIC_ASSERT(!is_implicitly_default_constructible<ctype<char>>);
STATIC_ASSERT(!is_implicitly_default_constructible<ctype<wchar_t>>);

// Test mandatory locale::id properties and strengthened exception specification.
STATIC_ASSERT(is_nothrow_default_constructible_v<locale::id>); // strengthened
STATIC_ASSERT(!is_copy_constructible_v<locale::id>);
STATIC_ASSERT(!is_move_constructible_v<locale::id>);
STATIC_ASSERT(!is_copy_assignable_v<locale::id>);
STATIC_ASSERT(!is_move_assignable_v<locale::id>);
STATIC_ASSERT(is_nothrow_destructible_v<locale::id>);

// Test that non-Standard locale::id constructor and conversion function are not user-visible.
STATIC_ASSERT(!is_constructible_v<locale::id, size_t>);
STATIC_ASSERT(!is_constructible_v<size_t, locale::id>);
STATIC_ASSERT(!is_constructible_v<size_t, locale::id&>);
STATIC_ASSERT(!is_convertible_v<size_t, locale::id>);
STATIC_ASSERT(!is_convertible_v<locale::id, size_t>);
STATIC_ASSERT(!is_convertible_v<locale::id&, size_t>);

void test_dll() {
puts("Calling dll");
#ifdef _M_CEE
Expand Down