From c7f918d0681828afdbddfdcc354b6f3dfc2a7b68 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Thu, 7 Feb 2013 13:09:19 +0000 Subject: [PATCH] Import new libc++ to vendor branch. --- include/__config | 6 ++ include/algorithm | 4 +- include/array | 3 + include/atomic | 22 ++++-- include/cmath | 90 +++++++++++---------- include/functional | 2 +- include/future | 8 +- include/istream | 1 + include/iterator | 4 +- include/limits | 188 ++++++++++++++++++++++++++++++++++++++++++++ include/locale | 20 +++-- include/memory | 5 +- include/ostream | 13 +-- include/random | 122 ++++++++++++++++++++++++++++ include/regex | 21 +++++ include/string | 2 +- include/type_traits | 23 +++++- include/vector | 6 +- src/chrono.cpp | 4 + src/debug.cpp | 2 +- src/exception.cpp | 8 +- src/future.cpp | 2 +- src/hash.cpp | 20 +++-- src/locale.cpp | 150 ++++++++++++++++++++++------------- src/string.cpp | 136 +++++++++++++++++--------------- src/thread.cpp | 6 +- 26 files changed, 654 insertions(+), 214 deletions(-) diff --git a/include/__config b/include/__config index 203be7616cc1..8617b8668424 100644 --- a/include/__config +++ b/include/__config @@ -66,6 +66,12 @@ # endif #endif // _WIN32 +#ifdef __linux__ +# if defined(__GNUC__) && _GNUC_VER >= 403 +# define _LIBCP_HAS_IS_BASE_OF +# endif +#endif + #ifdef __sun__ # include # ifdef _LITTLE_ENDIAN diff --git a/include/algorithm b/include/algorithm index 0f6107bdde05..e24f9793c50b 100644 --- a/include/algorithm +++ b/include/algorithm @@ -1528,10 +1528,10 @@ copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) // copy_backward -template +template inline _LIBCPP_INLINE_VISIBILITY _OutputIterator -__copy_backward(_InputIterator __first, _InputIterator __last, _OutputIterator __result) +__copy_backward(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { while (__first != __last) *--__result = *--__last; diff --git a/include/array b/include/array index 029bfd00a5c0..f4a3020aeae7 100644 --- a/include/array +++ b/include/array @@ -310,6 +310,7 @@ _LIBCPP_INLINE_VISIBILITY inline _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT { + static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)"); return __a[_Ip]; } @@ -318,6 +319,7 @@ _LIBCPP_INLINE_VISIBILITY inline const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT { + static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)"); return __a[_Ip]; } @@ -328,6 +330,7 @@ _LIBCPP_INLINE_VISIBILITY inline _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { + static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); return _VSTD::move(__a[_Ip]); } diff --git a/include/atomic b/include/atomic index 6dffdb21fde4..db67e7625b81 100644 --- a/include/atomic +++ b/include/atomic @@ -33,6 +33,7 @@ template T kill_dependency(T y) noexcept; // lock-free property +#define ATOMIC_BOOL_LOCK_FREE unspecified #define ATOMIC_CHAR_LOCK_FREE unspecified #define ATOMIC_CHAR16_T_LOCK_FREE unspecified #define ATOMIC_CHAR32_T_LOCK_FREE unspecified @@ -41,6 +42,7 @@ template T kill_dependency(T y) noexcept; #define ATOMIC_INT_LOCK_FREE unspecified #define ATOMIC_LONG_LOCK_FREE unspecified #define ATOMIC_LLONG_LOCK_FREE unspecified +#define ATOMIC_POINTER_LOCK_FREE unspecified // flag type and operations @@ -472,6 +474,7 @@ template // Atomics for standard typedef types +typedef atomic atomic_bool; typedef atomic atomic_char; typedef atomic atomic_schar; typedef atomic atomic_uchar; @@ -1454,6 +1457,7 @@ atomic_signal_fence(memory_order __m) _NOEXCEPT // Atomics for standard typedef types +typedef atomic atomic_bool; typedef atomic atomic_char; typedef atomic atomic_schar; typedef atomic atomic_uchar; @@ -1499,14 +1503,16 @@ typedef atomic atomic_uintmax_t; // lock-free property -#define ATOMIC_CHAR_LOCK_FREE 0 -#define ATOMIC_CHAR16_T_LOCK_FREE 0 -#define ATOMIC_CHAR32_T_LOCK_FREE 0 -#define ATOMIC_WCHAR_T_LOCK_FREE 0 -#define ATOMIC_SHORT_LOCK_FREE 0 -#define ATOMIC_INT_LOCK_FREE 0 -#define ATOMIC_LONG_LOCK_FREE 0 -#define ATOMIC_LLONG_LOCK_FREE 0 +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif // !__has_feature(cxx_atomic) diff --git a/include/cmath b/include/cmath index d3fbfe6d23f6..bd6034413eef 100644 --- a/include/cmath +++ b/include/cmath @@ -137,21 +137,21 @@ long double tanhl(long double x); // C99 -bool signbit(floating_point x); +bool signbit(arithmetic x); -int fpclassify(floating_point x); +int fpclassify(arithmetic x); -bool isfinite(floating_point x); -bool isinf(floating_point x); -bool isnan(floating_point x); -bool isnormal(floating_point x); +bool isfinite(arithmetic x); +bool isinf(arithmetic x); +bool isnan(arithmetic x); +bool isnormal(arithmetic x); -bool isgreater(floating_point x, floating_point y); -bool isgreaterequal(floating_point x, floating_point y); -bool isless(floating_point x, floating_point y); -bool islessequal(floating_point x, floating_point y); -bool islessgreater(floating_point x, floating_point y); -bool isunordered(floating_point x, floating_point y); +bool isgreater(arithmetic x, arithmetic y); +bool isgreaterequal(arithmetic x, arithmetic y); +bool isless(arithmetic x, arithmetic y); +bool islessequal(arithmetic x, arithmetic y); +bool islessgreater(arithmetic x, arithmetic y); +bool isunordered(arithmetic x, arithmetic y); floating_point acosh (arithmetic x); float acoshf(float x); @@ -325,10 +325,10 @@ __libcpp_signbit(_A1 __x) _NOEXCEPT template inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type +typename std::enable_if::value, bool>::type signbit(_A1 __x) _NOEXCEPT { - return __libcpp_signbit(__x); + return __libcpp_signbit((typename std::__promote<_A1>::type)__x); } #endif // signbit @@ -349,10 +349,10 @@ __libcpp_fpclassify(_A1 __x) _NOEXCEPT template inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, int>::type +typename std::enable_if::value, int>::type fpclassify(_A1 __x) _NOEXCEPT { - return __libcpp_fpclassify(__x); + return __libcpp_fpclassify((typename std::__promote<_A1>::type)__x); } #endif // fpclassify @@ -373,10 +373,10 @@ __libcpp_isfinite(_A1 __x) _NOEXCEPT template inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type +typename std::enable_if::value, bool>::type isfinite(_A1 __x) _NOEXCEPT { - return __libcpp_isfinite(__x); + return __libcpp_isfinite((typename std::__promote<_A1>::type)__x); } #endif // isfinite @@ -397,10 +397,10 @@ __libcpp_isinf(_A1 __x) _NOEXCEPT template inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type +typename std::enable_if::value, bool>::type isinf(_A1 __x) _NOEXCEPT { - return __libcpp_isinf(__x); + return __libcpp_isinf((typename std::__promote<_A1>::type)__x); } #endif // isinf @@ -421,10 +421,10 @@ __libcpp_isnan(_A1 __x) _NOEXCEPT template inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type +typename std::enable_if::value, bool>::type isnan(_A1 __x) _NOEXCEPT { - return __libcpp_isnan(__x); + return __libcpp_isnan((typename std::__promote<_A1>::type)__x); } #endif // isnan @@ -445,10 +445,10 @@ __libcpp_isnormal(_A1 __x) _NOEXCEPT template inline _LIBCPP_INLINE_VISIBILITY -typename std::enable_if::value, bool>::type +typename std::enable_if::value, bool>::type isnormal(_A1 __x) _NOEXCEPT { - return __libcpp_isnormal(__x); + return __libcpp_isnormal((typename std::__promote<_A1>::type)__x); } #endif // isnormal @@ -471,13 +471,14 @@ template inline _LIBCPP_INLINE_VISIBILITY typename std::enable_if < - std::is_floating_point<_A1>::value && - std::is_floating_point<_A2>::value, + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, bool >::type isgreater(_A1 __x, _A2 __y) _NOEXCEPT { - return __libcpp_isgreater(__x, __y); + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isgreater((type)__x, (type)__y); } #endif // isgreater @@ -500,13 +501,14 @@ template inline _LIBCPP_INLINE_VISIBILITY typename std::enable_if < - std::is_floating_point<_A1>::value && - std::is_floating_point<_A2>::value, + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, bool >::type isgreaterequal(_A1 __x, _A2 __y) _NOEXCEPT { - return __libcpp_isgreaterequal(__x, __y); + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isgreaterequal((type)__x, (type)__y); } #endif // isgreaterequal @@ -529,13 +531,14 @@ template inline _LIBCPP_INLINE_VISIBILITY typename std::enable_if < - std::is_floating_point<_A1>::value && - std::is_floating_point<_A2>::value, + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, bool >::type isless(_A1 __x, _A2 __y) _NOEXCEPT { - return __libcpp_isless(__x, __y); + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isless((type)__x, (type)__y); } #endif // isless @@ -558,13 +561,14 @@ template inline _LIBCPP_INLINE_VISIBILITY typename std::enable_if < - std::is_floating_point<_A1>::value && - std::is_floating_point<_A2>::value, + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, bool >::type islessequal(_A1 __x, _A2 __y) _NOEXCEPT { - return __libcpp_islessequal(__x, __y); + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_islessequal((type)__x, (type)__y); } #endif // islessequal @@ -587,13 +591,14 @@ template inline _LIBCPP_INLINE_VISIBILITY typename std::enable_if < - std::is_floating_point<_A1>::value && - std::is_floating_point<_A2>::value, + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, bool >::type islessgreater(_A1 __x, _A2 __y) _NOEXCEPT { - return __libcpp_islessgreater(__x, __y); + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_islessgreater((type)__x, (type)__y); } #endif // islessgreater @@ -616,13 +621,14 @@ template inline _LIBCPP_INLINE_VISIBILITY typename std::enable_if < - std::is_floating_point<_A1>::value && - std::is_floating_point<_A2>::value, + std::is_arithmetic<_A1>::value && + std::is_arithmetic<_A2>::value, bool >::type isunordered(_A1 __x, _A2 __y) _NOEXCEPT { - return __libcpp_isunordered(__x, __y); + typedef typename std::__promote<_A1, _A2>::type type; + return __libcpp_isunordered((type)__x, (type)__y); } #endif // isunordered diff --git a/include/functional b/include/functional index ec5c5e593334..3bee1ed1a0a3 100644 --- a/include/functional +++ b/include/functional @@ -1088,7 +1088,7 @@ class _LIBCPP_VISIBLE function<_Rp(_ArgTypes...)> public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { typedef __function::__base<_Rp(_ArgTypes...)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; + typename aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; template diff --git a/include/future b/include/future index cf552a9f3035..fa605e7d07f0 100644 --- a/include/future +++ b/include/future @@ -470,7 +470,11 @@ public: {return (__state_ & __constructed) || (__exception_ != nullptr);} _LIBCPP_INLINE_VISIBILITY - void __set_future_attached() {__state_ |= __future_attached;} + void __set_future_attached() + { + lock_guard __lk(__mut_); + __state_ |= __future_attached; + } _LIBCPP_INLINE_VISIBILITY bool __has_future_attached() const {return __state_ & __future_attached;} @@ -1753,7 +1757,7 @@ template class __packaged_task_function<_Rp(_ArgTypes...)> { typedef __packaged_task_base<_Rp(_ArgTypes...)> __base; - aligned_storage<3*sizeof(void*)>::type __buf_; + typename aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; public: diff --git a/include/istream b/include/istream index dc1c52be639a..3979e1407061 100644 --- a/include/istream +++ b/include/istream @@ -1243,6 +1243,7 @@ template streamsize basic_istream<_CharT, _Traits>::readsome(char_type* __s, streamsize __n) { + __gc_ = 0; streamsize __c = this->rdbuf()->in_avail(); switch (__c) { diff --git a/include/iterator b/include/iterator index bc0ce4759ce7..b23310b0940d 100644 --- a/include/iterator +++ b/include/iterator @@ -822,9 +822,9 @@ private: public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(0) {} _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT - : __sbuf_(__s.rdbuf()) {__test_for_eof();} + : __sbuf_(__s.rdbuf()) {} _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT - : __sbuf_(__s) {__test_for_eof();} + : __sbuf_(__s) {} _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT : __sbuf_(__p.__sbuf_) {} diff --git a/include/limits b/include/limits index 68e63366abec..f089a794dc1e 100644 --- a/include/limits +++ b/include/limits @@ -478,6 +478,53 @@ public: static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; }; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::digits10; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits<_Tp>::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits<_Tp>::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits<_Tp>::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits<_Tp>::round_style; + template class _LIBCPP_VISIBLE numeric_limits : private numeric_limits<_Tp> @@ -524,6 +571,53 @@ public: static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; }; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits::round_style; + template class _LIBCPP_VISIBLE numeric_limits : private numeric_limits<_Tp> @@ -570,6 +664,53 @@ public: static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; }; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits::round_style; + template class _LIBCPP_VISIBLE numeric_limits : private numeric_limits<_Tp> @@ -616,6 +757,53 @@ public: static _LIBCPP_CONSTEXPR const float_round_style round_style = __base::round_style; }; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_specialized; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits; +template + _LIBCPP_CONSTEXPR const int numeric_limits::digits10; +template + const int numeric_limits::max_digits10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_signed; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_integer; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_exact; +template + _LIBCPP_CONSTEXPR const int numeric_limits::radix; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::min_exponent10; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent; +template + _LIBCPP_CONSTEXPR const int numeric_limits::max_exponent10; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_infinity; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_quiet_NaN; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_signaling_NaN; +template + _LIBCPP_CONSTEXPR const float_denorm_style numeric_limits::has_denorm; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::has_denorm_loss; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_iec559; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_bounded; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::is_modulo; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::traps; +template + _LIBCPP_CONSTEXPR const bool numeric_limits::tinyness_before; +template + _LIBCPP_CONSTEXPR const float_round_style numeric_limits::round_style; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_LIMITS diff --git a/include/locale b/include/locale index f04a36b43990..91893757c8fb 100644 --- a/include/locale +++ b/include/locale @@ -354,7 +354,7 @@ size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, #endif } -_LIBCPP_ALWAYS_INLINE inline +inline int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -368,7 +368,7 @@ int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) { return __res; } -_LIBCPP_ALWAYS_INLINE inline +inline int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -382,7 +382,7 @@ int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) return __res; } -_LIBCPP_ALWAYS_INLINE inline +inline int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -396,7 +396,7 @@ int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { return __res; } -_LIBCPP_ALWAYS_INLINE inline +inline int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { va_list __va; va_start(__va, __format); @@ -830,11 +830,11 @@ __num_get_signed_integral(const char* __a, const char* __a_end, { if (__a != __a_end) { - int __save_errno = errno; + typename remove_reference::type __save_errno = errno; errno = 0; char *__p2; long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); - int __current_errno = errno; + typename remove_reference::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; if (__p2 != __a_end) @@ -870,11 +870,11 @@ __num_get_unsigned_integral(const char* __a, const char* __a_end, __err = ios_base::failbit; return 0; } - int __save_errno = errno; + typename remove_reference::type __save_errno = errno; errno = 0; char *__p2; unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); - int __current_errno = errno; + typename remove_reference::type __current_errno = errno; if (__current_errno == 0) errno = __save_errno; if (__p2 != __a_end) @@ -2895,6 +2895,10 @@ template locale::id moneypunct<_CharT, _International>::id; +template +const bool +moneypunct<_CharT, _International>::intl; + _LIBCPP_EXTERN_TEMPLATE(class moneypunct) _LIBCPP_EXTERN_TEMPLATE(class moneypunct) _LIBCPP_EXTERN_TEMPLATE(class moneypunct) diff --git a/include/memory b/include/memory index 4c12ad93ab86..f80d699fc0d4 100644 --- a/include/memory +++ b/include/memory @@ -1571,7 +1571,10 @@ struct _LIBCPP_VISIBLE allocator_traits __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) { while (__end1 != __begin1) - construct(__a, _VSTD::__to_raw_pointer(--__end2), _VSTD::move_if_noexcept(*--__end1)); + { + construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1)); + --__end2; + } } template diff --git a/include/ostream b/include/ostream index 9d26a41e8295..b3b6df573d04 100644 --- a/include/ostream +++ b/include/ostream @@ -1100,17 +1100,8 @@ basic_ostream<_CharT, _Traits>::write(const char_type* __s, streamsize __n) sentry __sen(*this); if (__sen && __n) { - typedef ostreambuf_iterator<_CharT, _Traits> _Op; - _Op __o(*this); - for (; __n; --__n, ++__o, ++__s) - { - *__o = *__s; - if (__o.failed()) - { - this->setstate(ios_base::badbit); - break; - } - } + if (this->rdbuf()->sputn(__s, __n) != __n) + this->setstate(ios_base::badbit); } #ifndef _LIBCPP_NO_EXCEPTIONS } diff --git a/include/random b/include/random index d838289551ca..04d942bc8766 100644 --- a/include/random +++ b/include/random @@ -1930,6 +1930,22 @@ private: linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x); }; +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier; + +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::increment; + +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::modulus; + +template + _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type + linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed; + template template void @@ -2227,6 +2243,90 @@ private: __rshift(result_type) {return result_type(0);} }; +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c; + +template + _LIBCPP_CONSTEXPR const size_t + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::initialization_multiplier; + +template + _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type + mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed; + template @@ -2551,6 +2651,19 @@ private: void __seed(_Sseq& __q, integral_constant); }; +template + _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size; + +template + _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag; + +template + _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag; + +template + _LIBCPP_CONSTEXPR const typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::result_type + subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed; + template void subtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd, @@ -2822,6 +2935,12 @@ public: discard_block_engine<_Eng, _Pp, _Rp>& __x); }; +template + _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size; + +template + _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block; + template typename discard_block_engine<_Engine, __p, __r>::result_type discard_block_engine<_Engine, __p, __r>::operator()() @@ -3314,6 +3433,9 @@ private: } }; +template + _LIBCPP_CONSTEXPR const size_t shuffle_order_engine<_Engine, __k>::table_size; + template bool operator==( diff --git a/include/regex b/include/regex index 7505f2ea3295..982500f35ffc 100644 --- a/include/regex +++ b/include/regex @@ -2842,6 +2842,27 @@ private: template friend class __lookahead; }; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::icase; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::nosubs; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::optimize; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::collate; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::ECMAScript; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::basic; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::extended; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::awk; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::grep; +template + const regex_constants::syntax_option_type basic_regex<_CharT, _Traits>::egrep; + template void basic_regex<_CharT, _Traits>::swap(basic_regex& __r) diff --git a/include/string b/include/string index 5bf42f023a41..1a70467940c7 100644 --- a/include/string +++ b/include/string @@ -3374,7 +3374,7 @@ basic_string<_CharT, _Traits, _Allocator>::find_first_not_of(value_type __c, { const_pointer __p = data(); const_pointer __pe = __p + __sz; - for (const_pointer __ps = __p + __pos; __p != __pe; ++__ps) + for (const_pointer __ps = __p + __pos; __ps != __pe; ++__ps) if (!traits_type::eq(*__ps, __c)) return static_cast(__ps - __p); } diff --git a/include/type_traits b/include/type_traits index 26c37dfa0c74..8f1c6024c71d 100644 --- a/include/type_traits +++ b/include/type_traits @@ -617,7 +617,28 @@ struct _LIBCPP_VISIBLE is_base_of #else // __has_feature(is_base_of) -#error is_base_of not implemented. +namespace __is_base_of_imp +{ +template +struct _Dst +{ + _Dst(const volatile _Tp &); +}; +template +struct _Src +{ + operator const volatile _Tp &(); + template operator const _Dst<_Up> &(); +}; +template struct __one { typedef char type; }; +template typename __one(declval<_Src<_Dp> >()))>::type __test(int); +template __two __test(...); +} + +template +struct _LIBCPP_VISIBLE is_base_of + : public integral_constant::value && + sizeof(__is_base_of_imp::__test<_Bp, _Dp>(0)) == 2> {}; #endif // __has_feature(is_base_of) diff --git a/include/vector b/include/vector index 0c2806828334..876b7e5676bd 100644 --- a/include/vector +++ b/include/vector @@ -1458,7 +1458,8 @@ vector<_Tp, _Allocator>::__push_back_slow_path(_Up& __x) allocator_type& __a = this->__alloc(); __split_buffer __v(__recommend(size() + 1), size(), __a); // __v.push_back(_VSTD::forward<_Up>(__x)); - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_++), _VSTD::forward<_Up>(__x)); + __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Up>(__x)); + __v.__end_++; __swap_out_circular_buffer(__v); } @@ -1505,7 +1506,8 @@ vector<_Tp, _Allocator>::__emplace_back_slow_path(_Args&&... __args) allocator_type& __a = this->__alloc(); __split_buffer __v(__recommend(size() + 1), size(), __a); // __v.emplace_back(_VSTD::forward<_Args>(__args)...); - __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_++), _VSTD::forward<_Args>(__args)...); + __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(__v.__end_), _VSTD::forward<_Args>(__args)...); + __v.__end_++; __swap_out_circular_buffer(__v); } diff --git a/src/chrono.cpp b/src/chrono.cpp index 73c83ee084e9..1ce2e2807a37 100644 --- a/src/chrono.cpp +++ b/src/chrono.cpp @@ -24,6 +24,8 @@ namespace chrono // system_clock +const bool system_clock::is_steady; + system_clock::time_point system_clock::now() _NOEXCEPT { @@ -46,6 +48,8 @@ system_clock::from_time_t(time_t t) _NOEXCEPT // steady_clock +const bool steady_clock::is_steady; + #if __APPLE__ // mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of // nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom diff --git a/src/debug.cpp b/src/debug.cpp index b8af4dde7749..f3a0262d1d5e 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -23,7 +23,7 @@ __get_db() { static __libcpp_db db; return &db; -}; +} _LIBCPP_VISIBLE const __libcpp_db* diff --git a/src/exception.cpp b/src/exception.cpp index 0dbb6604a560..0cd182b716cb 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -33,7 +33,7 @@ #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION) #define HAVE_DEPENDENT_EH_ABI 1 #endif -#else // __has_include() +#elif !defined(__GLIBCXX__) // __has_include() static std::terminate_handler __terminate_handler; static std::unexpected_handler __unexpected_handler; #endif // __has_include() @@ -41,7 +41,7 @@ namespace std { -#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) +#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__) // libcxxrt provides implementations of these functions itself. unexpected_handler @@ -99,7 +99,7 @@ terminate() _NOEXCEPT } #endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) -#ifndef LIBCXXRT +#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) bool uncaught_exception() _NOEXCEPT { #if __APPLE__ || defined(_LIBCPPABI_VERSION) @@ -124,7 +124,7 @@ const char* exception::what() const _NOEXCEPT #endif // _LIBCPPABI_VERSION #endif //LIBCXXRT -#ifndef _LIBCPPABI_VERSION +#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__) bad_exception::~bad_exception() _NOEXCEPT { diff --git a/src/future.cpp b/src/future.cpp index feb37e42db4e..7d9a5b5da69a 100644 --- a/src/future.cpp +++ b/src/future.cpp @@ -78,8 +78,8 @@ __assoc_sub_state::set_value() throw future_error(make_error_code(future_errc::promise_already_satisfied)); #endif __state_ |= __constructed | ready; - __lk.unlock(); __cv_.notify_all(); + __lk.unlock(); } void diff --git a/src/hash.cpp b/src/hash.cpp index 6f30d5a60581..a013500218e0 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -10,6 +10,9 @@ #include "__hash_table" #include "algorithm" #include "stdexcept" +#include "type_traits" + +#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" _LIBCPP_BEGIN_NAMESPACE_STD @@ -144,21 +147,23 @@ const unsigned indices[] = // are fewer potential primes to search, and fewer potential primes to divide // against. +template inline _LIBCPP_INLINE_VISIBILITY -void -__check_for_overflow(size_t N, integral_constant) +typename enable_if<_Sz == 4, void>::type +__check_for_overflow(size_t N) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#ifndef _LIBCPP_NO_EXCEPTIONS if (N > 0xFFFFFFFB) throw overflow_error("__next_prime overflow"); #endif } +template inline _LIBCPP_INLINE_VISIBILITY -void -__check_for_overflow(size_t N, integral_constant) +typename enable_if<_Sz == 8, void>::type +__check_for_overflow(size_t N) { -#ifndef _LIBCPP_NO_EXCEPTIONS +#ifndef _LIBCPP_NO_EXCEPTIONS if (N > 0xFFFFFFFFFFFFFFC5ull) throw overflow_error("__next_prime overflow"); #endif @@ -174,8 +179,7 @@ __next_prime(size_t n) return *std::lower_bound(small_primes, small_primes + N, n); // Else n > largest small_primes // Check for overflow - __check_for_overflow(n, integral_constant()); + __check_for_overflow(n); // Start searching list of potential primes: L * k0 + indices[in] const size_t M = sizeof(indices) / sizeof(indices[0]); // Select first potential prime >= n diff --git a/src/locale.cpp b/src/locale.cpp index 542c0d7a20ff..53a8a4cc1f08 100644 --- a/src/locale.cpp +++ b/src/locale.cpp @@ -81,8 +81,35 @@ make(A0 a0, A1 a1, A2 a2) return *(T*)&buf; } +template +inline +_LIBCPP_CONSTEXPR +size_t +countof(const T (&)[N]) +{ + return N; } +template +inline +_LIBCPP_CONSTEXPR +size_t +countof(const T * const begin, const T * const end) +{ + return static_cast(end - begin); +} + +} + +const locale::category locale::none; +const locale::category locale::collate; +const locale::category locale::ctype; +const locale::category locale::monetary; +const locale::category locale::numeric; +const locale::category locale::time; +const locale::category locale::messages; +const locale::category locale::all; + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" @@ -197,6 +224,11 @@ locale::__imp::__imp(const string& name, size_t refs) #endif // _LIBCPP_NO_EXCEPTIONS } +// NOTE avoid the `base class should be explicitly initialized in the +// copy constructor` warning emitted by GCC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wextra" + locale::__imp::__imp(const __imp& other) : facets_(max(N, other.facets_.size())), name_(other.name_) @@ -207,6 +239,8 @@ locale::__imp::__imp(const __imp& other) facets_[i]->__add_shared(); } +#pragma GCC diagnostic pop + locale::__imp::__imp(const __imp& other, const string& name, locale::category c) : facets_(N), name_("*") @@ -691,6 +725,19 @@ collate_byname::do_transform(const char_type* lo, const char_type* hi) // template <> class ctype; +const ctype_base::mask ctype_base::space; +const ctype_base::mask ctype_base::print; +const ctype_base::mask ctype_base::cntrl; +const ctype_base::mask ctype_base::upper; +const ctype_base::mask ctype_base::lower; +const ctype_base::mask ctype_base::alpha; +const ctype_base::mask ctype_base::digit; +const ctype_base::mask ctype_base::punct; +const ctype_base::mask ctype_base::xdigit; +const ctype_base::mask ctype_base::blank; +const ctype_base::mask ctype_base::alnum; +const ctype_base::mask ctype_base::graph; + locale::id ctype::id; ctype::~ctype() @@ -843,7 +890,7 @@ ctype::do_toupper(char_type c) const return isascii(c) ? static_cast(_DefaultRuneLocale.__mapupper[static_cast(c)]) : c; #elif defined(__GLIBC__) - return isascii(c) ? __classic_upper_table()[c] : c; + return isascii(c) ? __classic_upper_table()[static_cast(c)] : c; #else return (isascii(c) && islower_l(c, __cloc())) ? c-'a'+'A' : c; #endif @@ -857,7 +904,7 @@ ctype::do_toupper(char_type* low, const char_type* high) const *low = isascii(*low) ? static_cast(_DefaultRuneLocale.__mapupper[static_cast(*low)]) : *low; #elif defined(__GLIBC__) - *low = isascii(*low) ? __classic_upper_table()[*low] : *low; + *low = isascii(*low) ? __classic_upper_table()[static_cast(*low)] : *low; #else *low = (isascii(*low) && islower_l(*low, __cloc())) ? *low-'a'+'A' : *low; #endif @@ -871,7 +918,7 @@ ctype::do_tolower(char_type c) const return isascii(c) ? static_cast(_DefaultRuneLocale.__maplower[static_cast(c)]) : c; #elif defined(__GLIBC__) - return isascii(c) ? __classic_lower_table()[c] : c; + return isascii(c) ? __classic_lower_table()[static_cast(c)] : c; #else return (isascii(c) && isupper_l(c, __cloc())) ? c-'A'+'a' : c; #endif @@ -884,7 +931,7 @@ ctype::do_tolower(char_type* low, const char_type* high) const #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE *low = isascii(*low) ? static_cast(_DefaultRuneLocale.__maplower[static_cast(*low)]) : *low; #elif defined(__GLIBC__) - *low = isascii(*low) ? __classic_lower_table()[*low] : *low; + *low = isascii(*low) ? __classic_lower_table()[static_cast(*low)] : *low; #else *low = (isascii(*low) && isupper_l(*low, __cloc())) ? *low-'A'+'a' : *low; #endif @@ -1207,7 +1254,7 @@ ctype_byname::do_narrow(char_type c, char dfault) const #else int r = __wctob_l(c, __l); #endif - return r != WEOF ? static_cast(r) : dfault; + return r != static_cast(WEOF) ? static_cast(r) : dfault; } const wchar_t* @@ -1220,7 +1267,7 @@ ctype_byname::do_narrow(const char_type* low, const char_type* high, ch #else int r = __wctob_l(*low, __l); #endif - *dest = r != WEOF ? static_cast(r) : dfault; + *dest = r != static_cast(WEOF) ? static_cast(r) : dfault; } return low; } @@ -2619,7 +2666,6 @@ utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, codecvt_mode mode = codecvt_mode(0)) { const uint8_t* frm_nxt = frm; - frm_nxt = frm; if (mode & consume_header) { if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) @@ -2752,7 +2798,6 @@ utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end, codecvt_mode mode = codecvt_mode(0)) { const uint8_t* frm_nxt = frm; - frm_nxt = frm; if (mode & consume_header) { if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE) @@ -2847,7 +2892,6 @@ utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end, codecvt_mode mode = codecvt_mode(0)) { const uint8_t* frm_nxt = frm; - frm_nxt = frm; if (mode & consume_header) { if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF) @@ -4559,6 +4603,7 @@ __time_get::~__time_get() } #pragma clang diagnostic ignored "-Wmissing-field-initializers" +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" template <> string @@ -4578,7 +4623,7 @@ __time_get_storage::__analyze(char fmt, const ctype& ct) char f[3] = {0}; f[0] = '%'; f[1] = fmt; - size_t n = strftime_l(buf, 100, f, &t, __loc_); + size_t n = strftime_l(buf, countof(buf), f, &t, __loc_); char* bb = buf; char* be = buf + n; string result; @@ -4724,15 +4769,15 @@ __time_get_storage::__analyze(char fmt, const ctype& ct) char f[3] = {0}; f[0] = '%'; f[1] = fmt; - strftime_l(buf, 100, f, &t, __loc_); + strftime_l(buf, countof(buf), f, &t, __loc_); wchar_t wbuf[100]; wchar_t* wbb = wbuf; mbstate_t mb = {0}; const char* bb = buf; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); #else - size_t j = __mbsrtowcs_l( wbb, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = __mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -4870,26 +4915,26 @@ __time_get_storage::init(const ctype& ct) for (int i = 0; i < 7; ++i) { t.tm_wday = i; - strftime_l(buf, 100, "%A", &t, __loc_); + strftime_l(buf, countof(buf), "%A", &t, __loc_); __weeks_[i] = buf; - strftime_l(buf, 100, "%a", &t, __loc_); + strftime_l(buf, countof(buf), "%a", &t, __loc_); __weeks_[i+7] = buf; } // __months_ for (int i = 0; i < 12; ++i) { t.tm_mon = i; - strftime_l(buf, 100, "%B", &t, __loc_); + strftime_l(buf, countof(buf), "%B", &t, __loc_); __months_[i] = buf; - strftime_l(buf, 100, "%b", &t, __loc_); + strftime_l(buf, countof(buf), "%b", &t, __loc_); __months_[i+12] = buf; } // __am_pm_ t.tm_hour = 1; - strftime_l(buf, 100, "%p", &t, __loc_); + strftime_l(buf, countof(buf), "%p", &t, __loc_); __am_pm_[0] = buf; t.tm_hour = 13; - strftime_l(buf, 100, "%p", &t, __loc_); + strftime_l(buf, countof(buf), "%p", &t, __loc_); __am_pm_[1] = buf; __c_ = __analyze('c', ct); __r_ = __analyze('r', ct); @@ -4903,7 +4948,6 @@ __time_get_storage::init(const ctype& ct) { tm t = {0}; char buf[100]; - size_t be; wchar_t wbuf[100]; wchar_t* wbe; mbstate_t mb = {0}; @@ -4911,25 +4955,25 @@ __time_get_storage::init(const ctype& ct) for (int i = 0; i < 7; ++i) { t.tm_wday = i; - be = strftime_l(buf, 100, "%A", &t, __loc_); + strftime_l(buf, countof(buf), "%A", &t, __loc_); mb = mbstate_t(); const char* bb = buf; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #else - size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __weeks_[i].assign(wbuf, wbe); - be = strftime_l(buf, 100, "%a", &t, __loc_); + strftime_l(buf, countof(buf), "%a", &t, __loc_); mb = mbstate_t(); bb = buf; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #else - j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -4940,25 +4984,25 @@ __time_get_storage::init(const ctype& ct) for (int i = 0; i < 12; ++i) { t.tm_mon = i; - be = strftime_l(buf, 100, "%B", &t, __loc_); + strftime_l(buf, countof(buf), "%B", &t, __loc_); mb = mbstate_t(); const char* bb = buf; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #else - size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __months_[i].assign(wbuf, wbe); - be = strftime_l(buf, 100, "%b", &t, __loc_); + strftime_l(buf, countof(buf), "%b", &t, __loc_); mb = mbstate_t(); bb = buf; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #else - j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -4967,26 +5011,26 @@ __time_get_storage::init(const ctype& ct) } // __am_pm_ t.tm_hour = 1; - be = strftime_l(buf, 100, "%p", &t, __loc_); + strftime_l(buf, countof(buf), "%p", &t, __loc_); mb = mbstate_t(); const char* bb = buf; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #else - size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); wbe = wbuf + j; __am_pm_[0].assign(wbuf, wbe); t.tm_hour = 13; - be = strftime_l(buf, 100, "%p", &t, __loc_); + strftime_l(buf, countof(buf), "%p", &t, __loc_); mb = mbstate_t(); bb = buf; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #else - j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, __loc_); + j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -5249,7 +5293,7 @@ __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm, char fmt[] = {'%', __fmt, __mod, 0}; if (__mod != 0) swap(fmt[1], fmt[2]); - size_t n = strftime_l(__nb, static_cast(__ne-__nb), fmt, __tm, __loc_); + size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_); __ne = __nb + n; } @@ -5263,9 +5307,9 @@ __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, mbstate_t mb = {0}; const char* __nb = __nar; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_); + size_t j = mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); #else - size_t j = __mbsrtowcs_l(__wb, &__nb, 100, &mb, __loc_); + size_t j = __mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -5788,9 +5832,9 @@ moneypunct_byname::init(const char* nm) mbstate_t mb = {0}; const char* bb = lc->currency_symbol; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #else - size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -5807,9 +5851,9 @@ moneypunct_byname::init(const char* nm) mb = mbstate_t(); bb = lc->positive_sign; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #else - j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -5823,9 +5867,9 @@ moneypunct_byname::init(const char* nm) mb = mbstate_t(); bb = lc->negative_sign; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #else - j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -5871,9 +5915,9 @@ moneypunct_byname::init(const char* nm) mbstate_t mb = {0}; const char* bb = lc->int_curr_symbol; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - size_t j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + size_t j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #else - size_t j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + size_t j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -5894,9 +5938,9 @@ moneypunct_byname::init(const char* nm) mb = mbstate_t(); bb = lc->positive_sign; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #else - j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); @@ -5914,9 +5958,9 @@ moneypunct_byname::init(const char* nm) mb = mbstate_t(); bb = lc->negative_sign; #ifdef _LIBCPP_LOCALE__L_EXTENSIONS - j = mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #else - j = __mbsrtowcs_l(wbuf, &bb, sizeof(wbuf)/sizeof(wbuf[0]), &mb, loc.get()); + j = __mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get()); #endif if (j == size_t(-1)) __throw_runtime_error("locale not supported"); diff --git a/src/string.cpp b/src/string.cpp index 750ba284e366..40723e74a156 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -31,17 +31,17 @@ stoi(const string& str, size_t* idx, int base) { char* ptr; const char* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; long r = strtol(p, &ptr, base); - if (r < numeric_limits::min() || numeric_limits::max() < r) - ptr = const_cast(p); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoi: no conversion"); + if (errno_save == ERANGE || r < numeric_limits::min() || + numeric_limits::max() < r) throw out_of_range("stoi: out of range"); + if (ptr == p) + throw invalid_argument("stoi: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return static_cast(r); @@ -52,17 +52,17 @@ stoi(const wstring& str, size_t* idx, int base) { wchar_t* ptr; const wchar_t* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; long r = wcstol(p, &ptr, base); - if (r < numeric_limits::min() || numeric_limits::max() < r) - ptr = const_cast(p); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoi: no conversion"); + if (errno_save == ERANGE || r < numeric_limits::min() || + numeric_limits::max() < r) throw out_of_range("stoi: out of range"); + if (ptr == p) + throw invalid_argument("stoi: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return static_cast(r); @@ -73,15 +73,16 @@ stol(const string& str, size_t* idx, int base) { char* ptr; const char* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; long r = strtol(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stol: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stol: out of range"); + if (ptr == p) + throw invalid_argument("stol: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -92,15 +93,16 @@ stol(const wstring& str, size_t* idx, int base) { wchar_t* ptr; const wchar_t* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; long r = wcstol(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stol: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stol: out of range"); + if (ptr == p) + throw invalid_argument("stol: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -111,15 +113,16 @@ stoul(const string& str, size_t* idx, int base) { char* ptr; const char* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; unsigned long r = strtoul(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoul: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stoul: out of range"); + if (ptr == p) + throw invalid_argument("stoul: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -130,15 +133,16 @@ stoul(const wstring& str, size_t* idx, int base) { wchar_t* ptr; const wchar_t* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; unsigned long r = wcstoul(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoul: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stoul: out of range"); + if (ptr == p) + throw invalid_argument("stoul: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -149,15 +153,16 @@ stoll(const string& str, size_t* idx, int base) { char* ptr; const char* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; long long r = strtoll(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoll: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stoll: out of range"); + if (ptr == p) + throw invalid_argument("stoll: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -168,15 +173,16 @@ stoll(const wstring& str, size_t* idx, int base) { wchar_t* ptr; const wchar_t* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; long long r = wcstoll(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoll: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stoll: out of range"); + if (ptr == p) + throw invalid_argument("stoll: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -187,15 +193,16 @@ stoull(const string& str, size_t* idx, int base) { char* ptr; const char* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; unsigned long long r = strtoull(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoull: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stoull: out of range"); + if (ptr == p) + throw invalid_argument("stoull: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -206,15 +213,16 @@ stoull(const wstring& str, size_t* idx, int base) { wchar_t* ptr; const wchar_t* const p = str.c_str(); + typename remove_reference::type errno_save = errno; + errno = 0; unsigned long long r = wcstoull(p, &ptr, base); - if (ptr == p) - { + swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS - if (r == 0) - throw invalid_argument("stoull: no conversion"); + if (errno_save == ERANGE) throw out_of_range("stoull: out of range"); + if (ptr == p) + throw invalid_argument("stoull: no conversion"); #endif // _LIBCPP_NO_EXCEPTIONS - } if (idx) *idx = static_cast(ptr - p); return r; @@ -225,9 +233,9 @@ stof(const string& str, size_t* idx) { char* ptr; const char* const p = str.c_str(); - int errno_save = errno; + typename remove_reference::type errno_save = errno; errno = 0; - double r = strtod(p, &ptr); + float r = strtof(p, &ptr); swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS if (errno_save == ERANGE) @@ -237,7 +245,7 @@ stof(const string& str, size_t* idx) #endif // _LIBCPP_NO_EXCEPTIONS if (idx) *idx = static_cast(ptr - p); - return static_cast(r); + return r; } float @@ -245,9 +253,9 @@ stof(const wstring& str, size_t* idx) { wchar_t* ptr; const wchar_t* const p = str.c_str(); - int errno_save = errno; + typename remove_reference::type errno_save = errno; errno = 0; - double r = wcstod(p, &ptr); + float r = wcstof(p, &ptr); swap(errno, errno_save); #ifndef _LIBCPP_NO_EXCEPTIONS if (errno_save == ERANGE) @@ -257,7 +265,7 @@ stof(const wstring& str, size_t* idx) #endif // _LIBCPP_NO_EXCEPTIONS if (idx) *idx = static_cast(ptr - p); - return static_cast(r); + return r; } double @@ -265,7 +273,7 @@ stod(const string& str, size_t* idx) { char* ptr; const char* const p = str.c_str(); - int errno_save = errno; + typename remove_reference::type errno_save = errno; errno = 0; double r = strtod(p, &ptr); swap(errno, errno_save); @@ -285,7 +293,7 @@ stod(const wstring& str, size_t* idx) { wchar_t* ptr; const wchar_t* const p = str.c_str(); - int errno_save = errno; + typename remove_reference::type errno_save = errno; errno = 0; double r = wcstod(p, &ptr); swap(errno, errno_save); @@ -305,7 +313,7 @@ stold(const string& str, size_t* idx) { char* ptr; const char* const p = str.c_str(); - int errno_save = errno; + typename remove_reference::type errno_save = errno; errno = 0; long double r = strtold(p, &ptr); swap(errno, errno_save); @@ -325,7 +333,7 @@ stold(const wstring& str, size_t* idx) { wchar_t* ptr; const wchar_t* const p = str.c_str(); - int errno_save = errno; + typename remove_reference::type errno_save = errno; errno = 0; long double r = wcstold(p, &ptr); swap(errno, errno_save); diff --git a/src/thread.cpp b/src/thread.cpp index 8747adf0b595..b2bd07e9d3ba 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -67,8 +67,10 @@ thread::hardware_concurrency() _NOEXCEPT return n; #elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && defined(_SC_NPROCESSORS_ONLN) long result = sysconf(_SC_NPROCESSORS_ONLN); - if (result < 0 || result > UINT_MAX) - result = 0; + // sysconf returns -1 if the name is invalid, the option does not exist or + // does not have a definite limit. + if (result == -1) + return 0; return result; #else // defined(CTL_HW) && defined(HW_NCPU) // TODO: grovel through /proc or check cpuid on x86 and similar