diff --git a/stl/inc/__msvc_iter_core.hpp b/stl/inc/__msvc_iter_core.hpp index fe41efa81c..8a326b97c3 100644 --- a/stl/inc/__msvc_iter_core.hpp +++ b/stl/inc/__msvc_iter_core.hpp @@ -18,6 +18,25 @@ _STL_DISABLE_CLANG_WARNINGS #undef new _STD_BEGIN +template +struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type + +template +struct _Has_allocator_type<_Ty, _Alloc, void_t> + : is_convertible<_Alloc, typename _Ty::allocator_type>::type {}; + +_EXPORT_STD struct allocator_arg_t { // tag type for added allocator argument + explicit allocator_arg_t() = default; +}; + +_EXPORT_STD _INLINE_VAR constexpr allocator_arg_t allocator_arg{}; + +_EXPORT_STD template +struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type {}; + +_EXPORT_STD template +_INLINE_VAR constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value; + // from _EXPORT_STD struct input_iterator_tag {}; diff --git a/stl/inc/chrono b/stl/inc/chrono index d896c9e282..aa4db5e1c7 100644 --- a/stl/inc/chrono +++ b/stl/inc/chrono @@ -4145,7 +4145,7 @@ namespace chrono { --_Width; } - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; char* _Ptr = _Ac; if (_First != _Last && _Width > 0) { const char _Ch = _Ctype_fac.narrow(*_First); diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 8703f28b12..13193dc15f 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -24,29 +24,6 @@ template // TRANSITION, CWG-2518: false value attached to a dependent name (for static_assert) _INLINE_VAR constexpr bool _Always_false = false; -_EXPORT_STD template -struct integer_sequence { // sequence of integer parameters - static_assert(is_integral_v<_Ty>, "integer_sequence requires T to be an integral type."); - - using value_type = _Ty; - - _NODISCARD static constexpr size_t size() noexcept { - return sizeof...(_Vals); - } -}; - -_EXPORT_STD template -using make_integer_sequence = __make_integer_seq; - -_EXPORT_STD template -using index_sequence = integer_sequence; - -_EXPORT_STD template -using make_index_sequence = make_integer_sequence; - -_EXPORT_STD template -using index_sequence_for = make_index_sequence; - template struct _Conjunction { // handle false trait or last trait using type = _First; diff --git a/stl/inc/utility b/stl/inc/utility index 1a27f5e42e..c3a70f4cb8 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -31,6 +31,29 @@ _STL_DISABLE_CLANG_WARNINGS #undef new _STD_BEGIN +_EXPORT_STD template +struct integer_sequence { // sequence of integer parameters + static_assert(is_integral_v<_Ty>, "integer_sequence requires T to be an integral type."); + + using value_type = _Ty; + + _NODISCARD static constexpr size_t size() noexcept { + return sizeof...(_Vals); + } +}; + +_EXPORT_STD template +using make_integer_sequence = __make_integer_seq; + +_EXPORT_STD template +using index_sequence = integer_sequence; + +_EXPORT_STD template +using make_index_sequence = make_integer_sequence; + +_EXPORT_STD template +using index_sequence_for = make_index_sequence; + _EXPORT_STD template _NODISCARD constexpr const _Ty&(max) (const _Ty& _Left, const _Ty& _Right, _Pr _Pred) noexcept( noexcept(_Pred(_Left, _Right))) /* strengthened */ { @@ -107,27 +130,6 @@ _EXPORT_STD struct piecewise_construct_t { // tag type for pair tuple arguments _EXPORT_STD _INLINE_VAR constexpr piecewise_construct_t piecewise_construct{}; -template -struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type - -template -struct _Has_allocator_type<_Ty, _Alloc, void_t> - : is_convertible<_Alloc, typename _Ty::allocator_type>::type {}; // tests for suitable _Ty::allocator_type - -_EXPORT_STD struct allocator_arg_t { // tag type for added allocator argument - explicit allocator_arg_t() = default; -}; - -_EXPORT_STD _INLINE_VAR constexpr allocator_arg_t allocator_arg{}; - -_EXPORT_STD template -struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type { - // determine whether _Ty has an allocator_type member type -}; - -_EXPORT_STD template -_INLINE_VAR constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value; - _EXPORT_STD template class tuple; diff --git a/stl/inc/xlocnum b/stl/inc/xlocnum index 11b92958db..47a0b964ee 100644 --- a/stl/inc/xlocnum +++ b/stl/inc/xlocnum @@ -36,6 +36,8 @@ _END_EXTERN_C_UNLESS_PURE _STD_BEGIN +_INLINE_VAR constexpr size_t _Max_int_dig = 32; // integer properties + inline double _Stodx_v3(const char* _Str, char** _Endptr, int* _Perr) noexcept { // convert string to double int& _Errno_ref = errno; // Nonzero cost, pay it once const int _Orig = _Errno_ref; @@ -364,7 +366,7 @@ protected: break; } } else { // get long value - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; const auto _Parse_result = _Parse_int_with_locale(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field if (_Parse_result._Base < 0) { @@ -399,7 +401,7 @@ protected: virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned short& _Val) const { // get unsigned short from [_First, _Last) into _Val _Adl_verify_range(_First, _Last); - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; const auto _Parse_result = _Parse_int_with_locale(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field if (_Parse_result._Base < 0) { // ditto "fails to convert the entire field" @@ -451,7 +453,7 @@ protected: virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long& _Val) const { // get long from [_First, _Last) into _Val _Adl_verify_range(_First, _Last); - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; const auto _Parse_result = _Parse_int_with_locale(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field if (_Parse_result._Base < 0) { // ditto "fails to convert the entire field" @@ -477,7 +479,7 @@ protected: virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long& _Val) const { // get unsigned long from [_First, _Last) into _Val _Adl_verify_range(_First, _Last); - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; const auto _Parse_result = _Parse_int_with_locale(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field if (_Parse_result._Base < 0) { // ditto "fails to convert the entire field" @@ -503,7 +505,7 @@ protected: virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long long& _Val) const { // get long long from [_First, _Last) into _Val _Adl_verify_range(_First, _Last); - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; const auto _Parse_result = _Parse_int_with_locale(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field if (_Parse_result._Base < 0) { // ditto "fails to convert the entire field" @@ -529,7 +531,7 @@ protected: virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, unsigned long long& _Val) const { // get unsigned long long from [_First, _Last) into _Val _Adl_verify_range(_First, _Last); - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; const auto _Parse_result = _Parse_int_with_locale(_Ac, _First, _Last, _Iosbase.flags(), _Iosbase.getloc()); // gather field if (_Parse_result._Base < 0) { // ditto "fails to convert the entire field" @@ -552,6 +554,8 @@ protected: return _First; } +#define _MAX_SIG_DIG_V2 768 +#define _MAX_EXP_DIG 8 // for parsing floating-point numbers // Size of char buffer used by num_get::do_get() for float/double/long double #define _FLOATING_BUFFER_SIZE (_MAX_EXP_DIG + _MAX_SIG_DIG_V2 + 16) @@ -607,6 +611,7 @@ protected: return _First; } #undef _FLOATING_BUFFER_SIZE +#undef _MAX_EXP_DIG virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, long double& _Val) const { // get long double from [_First, _Last) into _Val @@ -620,7 +625,7 @@ protected: virtual _InIt __CLR_OR_THIS_CALL do_get(_InIt _First, _InIt _Last, ios_base& _Iosbase, ios_base::iostate& _State, void*& _Val) const { // get void pointer from [_First, _Last) into _Val _Adl_verify_range(_First, _Last); - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; const auto _Parse_result = _Parse_int_with_locale(_Ac, _First, _Last, ios_base::hex, _Iosbase.getloc()); // gather field if (_Parse_result._Base < 0) { // ditto "fails to convert the entire field" @@ -730,7 +735,7 @@ private: string _Groups(1, static_cast(_Seendigit)); // Groups are detected in the reversed order of _Groups. size_t _Groups_arr_idx = 0; - for (char* const _Pe = &_Ac[_MAX_INT_DIG - 1]; _First != _Last; ++_First) { // look for digits and separators + for (char* const _Pe = &_Ac[_Max_int_dig - 1]; _First != _Last; ++_First) { // look for digits and separators size_t _Idx = _STD _Find_elem(_Atoms, *_First); if (_Idx < _Dlen) { // got a digit, characterize it and add to group size *_Ptr = _Src[_Idx]; @@ -1118,6 +1123,7 @@ private: return _Parse_result._Base < 0 ? ~_Parse_result._Base : _Parse_result._Base; } +#define _MAX_SIG_DIG_V1 36 // TRANSITION, ABI // TRANSITION, ABI: Sentinel value used by num_get::do_get() // to enable correct "V2" behavior in _Getffld() and _Getffldx() #define _ENABLE_V2_BEHAVIOR 1000000000 @@ -1159,6 +1165,8 @@ private: } #undef _ENABLE_V2_BEHAVIOR +#undef _MAX_SIG_DIG_V1 +#undef _MAX_SIG_DIG_V2 }; #ifdef __clang__ @@ -1313,7 +1321,7 @@ protected: #pragma warning(disable : 4774) // format string expected in argument N is not a string literal (/Wall) virtual _OutIt __CLR_OR_THIS_CALL do_put( _OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long _Val) const { // put formatted long to _Dest - char _Buf[2 * _MAX_INT_DIG]; + char _Buf[2 * _Max_int_dig]; char _Fmt[6]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, @@ -1322,7 +1330,7 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long _Val) const { // put formatted unsigned long to _Dest - char _Buf[2 * _MAX_INT_DIG]; + char _Buf[2 * _Max_int_dig]; char _Fmt[6]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, @@ -1331,7 +1339,7 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put( _OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, long long _Val) const { // put formatted long long to _Dest - char _Buf[2 * _MAX_INT_DIG]; + char _Buf[2 * _Max_int_dig]; char _Fmt[8]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, @@ -1340,7 +1348,7 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, unsigned long long _Val) const { // put formatted unsigned long long to _Dest - char _Buf[2 * _MAX_INT_DIG]; + char _Buf[2 * _Max_int_dig]; char _Fmt[8]; return _Iput(_Dest, _Iosbase, _Fill, _Buf, @@ -1398,7 +1406,7 @@ protected: virtual _OutIt __CLR_OR_THIS_CALL do_put( _OutIt _Dest, ios_base& _Iosbase, _Elem _Fill, const void* _Val) const { // put formatted void pointer to _Dest - char _Buf[2 * _MAX_INT_DIG]; + char _Buf[2 * _Max_int_dig]; return _Iput( _Dest, _Iosbase, _Fill, _Buf, static_cast(_CSTD sprintf_s(_Buf, sizeof(_Buf), "%p", _Val))); diff --git a/stl/inc/xloctime b/stl/inc/xloctime index 5a72b853c3..722feeb330 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -25,7 +25,7 @@ ios_base::iostate _Getint_v2(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& const ctype<_Elem>& _Ctype_fac) { // get integer in range [_Lo, _Hi] from [_First, _Last) _STL_INTERNAL_CHECK(0 <= _Hi && _Hi <= 9999); const int _Hi_digits = (_Hi <= 9 ? 1 : _Hi <= 99 ? 2 : _Hi <= 999 ? 3 : 4); - char _Ac[_MAX_INT_DIG]; + char _Ac[_Max_int_dig]; char* _Ep; char* _Ptr = _Ac; char _Ch; @@ -55,7 +55,7 @@ ios_base::iostate _Getint_v2(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& *_Ptr++ = '0'; // replace one or more with single zero } - for (char* const _Pe = &_Ac[_MAX_INT_DIG - 1]; + for (char* const _Pe = &_Ac[_Max_int_dig - 1]; _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_read < _Hi_digits; ++_Digits_read, (void) ++_First) { // copy digits *_Ptr = _Ch; diff --git a/stl/inc/yvals.h b/stl/inc/yvals.h index 59107cf813..438543e7f2 100644 --- a/stl/inc/yvals.h +++ b/stl/inc/yvals.h @@ -318,12 +318,6 @@ _EMIT_STL_WARNING(STL4001, "/clr:pure is deprecated and will be REMOVED."); #endif #endif // _CRTDATA2_IMPORT -// integer properties -#define _MAX_EXP_DIG 8 // for parsing numerics -#define _MAX_INT_DIG 32 -#define _MAX_SIG_DIG_V1 36 // TRANSITION, ABI -#define _MAX_SIG_DIG_V2 768 - #define _LOCK_LOCALE 0 #define _LOCK_MALLOC 1 #define _LOCK_STREAM 2 diff --git a/tests/tr1/tests/type_traits1/test.cpp b/tests/tr1/tests/type_traits1/test.cpp index d07015289b..bcae4d2ef0 100644 --- a/tests/tr1/tests/type_traits1/test.cpp +++ b/tests/tr1/tests/type_traits1/test.cpp @@ -449,46 +449,6 @@ static void t_is_member_function_pointer() { // test is_member_function_pointer< CHECK(STD is_member_function_pointer::value); } -void t_sequence() { // test integer_sequence - typedef STD integer_sequence s0; - CHECK_TYPE(size_t, s0::value_type); - CHECK_INT(s0().size(), 0); - - typedef STD integer_sequence s1; - CHECK_TYPE(size_t, s1::value_type); - CHECK_INT(s1().size(), 1); - - typedef STD integer_sequence s2; - CHECK_TYPE(size_t, s2::value_type); - CHECK_INT(s2().size(), 2); - - typedef STD make_integer_sequence si0; - CHECK_TYPE(si0, STD integer_sequence); - - typedef STD make_integer_sequence si1; - typedef STD integer_sequence si1a; - CHECK_TYPE(si1, si1a); - - typedef STD make_integer_sequence si2; - typedef STD integer_sequence si2a; - CHECK_TYPE(si2, si2a); - - typedef STD make_index_sequence<2> si2b; - - typedef STD index_sequence_for si2d; - CHECK_TYPE(si2b, si2d); - - CHECK_TYPE(s0, STD index_sequence<>); - - CHECK_TYPE(s1, STD index_sequence<2>); - - typedef STD index_sequence<4, 5> s2x; - CHECK_TYPE(s2, s2x); - - typedef STD index_sequence<0, 1> si2c; - CHECK_TYPE(si2b, si2c); -} - void t_aliases() { // test template aliases typedef int Ty; @@ -558,7 +518,5 @@ void test_main() { // test type traits t_is_member_object_pointer(); t_is_member_function_pointer(); - t_sequence(); - t_aliases(); } diff --git a/tests/tr1/tests/utility/test.cpp b/tests/tr1/tests/utility/test.cpp index 8112bc8d66..4539c62e4d 100644 --- a/tests/tr1/tests/utility/test.cpp +++ b/tests/tr1/tests/utility/test.cpp @@ -15,7 +15,49 @@ Pair_ic p0; void fun() { // do nothing } +void t_sequence() { // test integer_sequence + typedef STD integer_sequence s0; + CHECK_TYPE(size_t, s0::value_type); + CHECK_INT(s0().size(), 0); + + typedef STD integer_sequence s1; + CHECK_TYPE(size_t, s1::value_type); + CHECK_INT(s1().size(), 1); + + typedef STD integer_sequence s2; + CHECK_TYPE(size_t, s2::value_type); + CHECK_INT(s2().size(), 2); + + typedef STD make_integer_sequence si0; + CHECK_TYPE(si0, STD integer_sequence); + + typedef STD make_integer_sequence si1; + typedef STD integer_sequence si1a; + CHECK_TYPE(si1, si1a); + + typedef STD make_integer_sequence si2; + typedef STD integer_sequence si2a; + CHECK_TYPE(si2, si2a); + + typedef STD make_index_sequence<2> si2b; + + typedef STD index_sequence_for si2d; + CHECK_TYPE(si2b, si2d); + + CHECK_TYPE(s0, STD index_sequence<>); + + CHECK_TYPE(s1, STD index_sequence<2>); + + typedef STD index_sequence<4, 5> s2x; + CHECK_TYPE(s2, s2x); + + typedef STD index_sequence<0, 1> si2c; + CHECK_TYPE(si2b, si2c); +} + void test_main() { // test basic workings of utility definitions + t_sequence(); + Pair_ic p1 = p0, p2(3, 'a'); CHECK_INT(p1.first, 0);