41 class __crt_cached_ptd_host
80 enum class locale_status :
unsigned char
83 updated_on_construction,
88 : _ptd(
nullptr), _current_global_state_index_valid(
false), _locale_status(locale_status::uninitialized)
92 _locale_pointers = *
locale;
93 _locale_status = locale_status::updated_on_construction;
95 else if (!__acrt_locale_changed())
98 _locale_status = locale_status::updated_on_construction;
102 ~__crt_cached_ptd_host()
throw()
104 if (_locale_status == locale_status::updated_via_ptd)
108 __acrt_enable_global_locale_sync(_ptd);
111 if (_current_errno.valid())
113 get_raw_ptd()->_terrno = _current_errno.unsafe_value();
116 if (_current_doserrno.valid())
118 get_raw_ptd()->_tdoserrno = _current_doserrno.unsafe_value();
122 __crt_cached_ptd_host(__crt_cached_ptd_host
const&) =
delete;
123 __crt_cached_ptd_host& operator=(__crt_cached_ptd_host
const&) =
delete;
128 return &_locale_pointers;
131 size_t get_current_global_state_index()
throw()
133 return check_synchronize_global_state_index();
138 return check_synchronize_per_thread_data();
143 return try_synchronize_per_thread_data();
146 template <
typename T>
159 T set(
T new_value)
throw()
166 T value_or(
T const alternative)
const throw()
177 return _valid && _value ==
value;
183 explicit guard(cached&
parent)
throw()
196 guard(guard
const&) =
delete;
197 guard& operator=(guard
const&) =
delete;
215 guard create_guard()
throw()
227 cached(cached
const&) =
default;
228 cached(cached&&) =
default;
230 cached& operator=(cached
const&) =
default;
231 cached& operator=(cached&&) =
default;
237 auto& get_errno()
throw()
239 return _current_errno;
242 auto& get_doserrno()
throw()
244 return _current_doserrno;
248 __forceinline
void update_locale()
throw()
250 if (_locale_status == locale_status::uninitialized)
252 update_locale_slow();
256 void update_locale_slow()
throw()
265 ptd_ptr, &_locale_pointers.locinfo, _current_global_state_index
269 ptd_ptr, &_locale_pointers.mbcinfo, _current_global_state_index
276 __acrt_disable_global_locale_sync(ptd_ptr);
277 _locale_status = locale_status::updated_via_ptd;
285 if (force_synchronize_per_thread_data() ==
nullptr)
297 return force_synchronize_per_thread_data();
306 __crt_scoped_get_last_error_reset
const last_error_reset;
310 check_synchronize_global_state_index(last_error_reset)
314 size_t check_synchronize_global_state_index()
throw()
316 if (!_current_global_state_index_valid)
318 __crt_scoped_get_last_error_reset
const last_error_reset;
319 return force_synchronize_global_state_index(last_error_reset);
322 return _current_global_state_index;
325 size_t check_synchronize_global_state_index(__crt_scoped_get_last_error_reset
const& last_error_reset)
throw()
327 if (!_current_global_state_index_valid)
329 return force_synchronize_global_state_index(last_error_reset);
332 return _current_global_state_index;
335 size_t force_synchronize_global_state_index(__crt_scoped_get_last_error_reset
const& last_error_reset)
throw()
337 _current_global_state_index = __crt_state_management::get_current_state_index(last_error_reset);
338 _current_global_state_index_valid =
true;
340 return _current_global_state_index;
345 size_t _current_global_state_index;
346 bool _current_global_state_index_valid;
349 locale_status _locale_status;
351 cached<errno_t> _current_errno;
352 cached<unsigned long> _current_doserrno;
356 namespace __crt_state_management
361 template <
typename T>
362 T& dual_state_global<T>::value(__crt_cached_ptd_host&
ptd)
throw()
364 return _value[
ptd.get_current_global_state_index()];
367 template <
typename T>
368 T const& dual_state_global<T>::value(__crt_cached_ptd_host&
ptd)
const throw()
370 return _value[
ptd.get_current_global_state_index()];
391#ifndef _ALLOW_OLD_VALIDATE_MACROS
393 #undef _INVALID_PARAMETER
395 #undef _VALIDATE_CLEAR_OSSERR_RETURN
396 #undef _VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE
397 #undef _VALIDATE_RETURN
398 #undef _VALIDATE_RETURN_ERRCODE
399 #undef _VALIDATE_RETURN_ERRCODE_NOEXC
400 #undef _VALIDATE_RETURN_NOERRNO
401 #undef _VALIDATE_RETURN_NOEXC
402 #undef _VALIDATE_RETURN_VOID
404 #undef _ERRCHECK_SPRINTF
405 #undef _VALIDATE_STREAM_ANSI_RETURN
406 #undef _CHECK_FH_RETURN
407 #undef _CHECK_FH_CLEAR_OSSERR_RETURN
408 #undef _CHECK_FH_CLEAR_OSSERR_RETURN_ERRCODE
409 #undef _VALIDATE_CLEAR_OSSERR_RETURN
419 #define _UCRT_INVALID_PARAMETER(ptd, expr) _invalid_parameter_internal(expr, __FUNCTIONW__, __FILEW__, __LINE__, 0, ptd)
421 #define _UCRT_INVALID_PARAMETER(ptd, expr) _invalid_parameter_internal(nullptr, nullptr, nullptr, 0, 0, ptd)
424#define _UCRT_VALIDATE_CLEAR_OSSERR_RETURN(ptd, expr, errorcode, retexpr) \
426 int _Expr_val = !!(expr); \
427 _ASSERT_EXPR((_Expr_val), _CRT_WIDE(#expr)); \
430 (ptd).get_doserrno().set(0L); \
431 (ptd).get_errno().set((errorcode)); \
432 _UCRT_INVALID_PARAMETER((ptd), _CRT_WIDE(#expr)); \
437#define _UCRT_VALIDATE_CLEAR_OSSERR_RETURN_ERRCODE(ptd, expr, errorcode) \
439 int _Expr_val = !!(expr); \
440 _ASSERT_EXPR((_Expr_val), _CRT_WIDE(#expr)); \
443 (ptd).get_doserrno().set(0L); \
444 (ptd).get_errno().set((errorcode)); \
445 _UCRT_INVALID_PARAMETER((ptd), _CRT_WIDE(#expr)); \
446 return (errorcode); \
450#define _UCRT_VALIDATE_RETURN(ptd, expr, errorcode, retexpr) \
452 int _Expr_val = !!(expr); \
453 _ASSERT_EXPR((_Expr_val), _CRT_WIDE(#expr)); \
456 (ptd).get_errno().set((errorcode)); \
457 _UCRT_INVALID_PARAMETER((ptd), _CRT_WIDE(#expr)); \
462#define _UCRT_VALIDATE_RETURN_ERRCODE(ptd, expr, errorcode) \
464 int _Expr_val = !!(expr); \
465 _ASSERT_EXPR((_Expr_val), _CRT_WIDE(#expr)); \
468 (ptd).get_errno().set((errorcode)); \
469 _UCRT_INVALID_PARAMETER((ptd), _CRT_WIDE(#expr)); \
470 return (errorcode); \
474#define _UCRT_VALIDATE_RETURN_ERRCODE_NOEXC(ptd, expr, errorcode) \
478 return (ptd).get_errno().set((errorcode)); \
482#define _UCRT_VALIDATE_RETURN_NOERRNO(ptd, expr, retexpr) \
484 int _Expr_val = !!(expr); \
485 _ASSERT_EXPR((_Expr_val), _CRT_WIDE(#expr)); \
488 _UCRT_INVALID_PARAMETER((ptd), _CRT_WIDE(#expr)); \
493#define _UCRT_VALIDATE_RETURN_NOEXC(ptd, expr, errorcode, retexpr) \
497 (ptd).get_errno().set((errorcode)); \
502#define _UCRT_VALIDATE_RETURN_VOID(ptd, expr, errorcode) \
504 int _Expr_val = !!(expr); \
505 _ASSERT_EXPR((_Expr_val), _CRT_WIDE(#expr)); \
508 (ptd).get_errno().set((errorcode)); \
509 _UCRT_INVALID_PARAMETER((ptd), _CRT_WIDE(#expr)); \
516#define _UCRT_VALIDATE_STREAM_ANSI_RETURN(ptd, stream, errorcode, retexpr) \
518 __crt_stdio_stream const _Stream((stream)); \
520 _UCRT_VALIDATE_RETURN((ptd), ( \
521 (_Stream.is_string_backed()) || \
522 (fn = _fileno(_Stream.public_stream()), \
523 ((_textmode_safe(fn) == __crt_lowio_text_mode::ansi) && \
524 !_tm_unicode_safe(fn)))), \
525 (errorcode), (retexpr)) \
528#define _UCRT_CHECK_FH_RETURN(ptd, handle, errorcode, retexpr) \
530 if ((handle) == _NO_CONSOLE_FILENO) \
532 (ptd).get_errno().set((errorcode)); \
537#define _UCRT_CHECK_FH_CLEAR_OSSERR_RETURN(ptd, handle, errorcode, retexpr) \
539 if ((handle) == _NO_CONSOLE_FILENO) \
541 (ptd).get_doserrno().set(0L); \
542 (ptd).get_errno().set((errorcode)); \
547#define _UCRT_CHECK_FH_CLEAR_OSSERR_RETURN_ERRCODE(ptd, handle, retexpr) \
549 if ((handle) == _NO_CONSOLE_FILENO) \
551 (ptd).get_doserrno().set(0L); \
556#define _UCRT_VALIDATE_CLEAR_OSSERR_RETURN(ptd, expr, errorcode, retexpr) \
558 int _Expr_val = !!(expr); \
559 _ASSERT_EXPR((_Expr_val), _CRT_WIDE(#expr)); \
562 (ptd).get_doserrno().set(0L); \
563 (ptd).get_errno().set((errorcode)); \
564 _UCRT_INVALID_PARAMETER((ptd), _CRT_WIDE(#expr)); \
static WCHAR * get_locale(void)
__crt_locale_pointers __acrt_initial_locale_pointers
#define _PER_THREAD_LOCALE_BIT
_CRT_BEGIN_C_HEADER __acrt_ptd *__cdecl __acrt_getptd_noexit_explicit(__crt_scoped_get_last_error_reset const &, size_t global_state_index)
result_buffer_count char *const _In_ int const _In_ bool const _In_ unsigned const _In_ STRFLT const _In_ bool const _Inout_ __crt_cached_ptd_host &ptd throw()
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
#define check(expected, result)
void __acrt_update_multibyte_info_explicit(__acrt_ptd *const ptd, __crt_multibyte_data **const multibyte_info, size_t const current_global_state_index)
void __acrt_update_locale_info_explicit(__acrt_ptd *const ptd, __crt_locale_data **const locale_info, size_t const current_global_state_index)
__crt_multibyte_data * _multibyte_info
__crt_locale_data * _locale_info
#define _CRT_END_C_HEADER
#define _CRT_BEGIN_C_HEADER