Re: [PATCH] Partial solution to LWG 523
On 30/11/16 14:45 +, Jonathan Wakely wrote: On 30/11/16 13:03 +, Jonathan Wakely wrote: On 26/11/16 16:27 -0800, Tim Shen wrote: diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 953aa87..2fb70b7 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1000,7 +1000,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION element_type& operator*() const noexcept { - __glibcxx_assert(_M_ptr != nullptr); + __glibcxx_assert(_M_get() != nullptr); return *_M_get(); } Oops, thanks, but let's fix this separately (I'll do it now) so the rest of the patch only touches regex stuff. I've fixed that with this patch, committed to trunk. There's a similar problem in the __shared_ptr_access specialization for shared_ptr, fixed by this patch. commit b69bee71a9eaa91f3a6fae875d702c9d39b02354 Author: Jonathan WakelyDate: Tue Dec 6 14:13:54 2016 + Fix debug mode assertion for std::shared_ptr * include/bits/shared_ptr_base.h (__shared_ptr_access ::operator->()): Fix assertion. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 2fb70b7..7e02043 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -983,8 +983,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION element_type* operator->() const noexcept { - _GLIBCXX_DEBUG_PEDASSERT(_M_get() != nullptr); - return static_cast*>(this)->get(); + auto __ptr = static_cast*>(this)->get(); + _GLIBCXX_DEBUG_PEDASSERT(__ptr != nullptr); + return __ptr; } };
Re: [PATCH] Partial solution to LWG 523
On 30/11/16 13:03 +, Jonathan Wakely wrote: On 26/11/16 16:27 -0800, Tim Shen wrote: diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 953aa87..2fb70b7 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1000,7 +1000,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION element_type& operator*() const noexcept { - __glibcxx_assert(_M_ptr != nullptr); + __glibcxx_assert(_M_get() != nullptr); return *_M_get(); } Oops, thanks, but let's fix this separately (I'll do it now) so the rest of the patch only touches regex stuff. I've fixed that with this patch, committed to trunk. commit 18ee83fae4fef2fc720ef6aef0754377e6fe29e8 Author: Jonathan WakelyDate: Wed Nov 30 13:11:50 2016 + Fix condition in shared_ptr assertion 2016-11-30 Tim Shen * include/bits/shared_ptr_base.h (__shared_ptr_access ::operator*()): Fix assertion. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 953aa87..2fb70b7 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1000,7 +1000,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION element_type& operator*() const noexcept { - __glibcxx_assert(_M_ptr != nullptr); + __glibcxx_assert(_M_get() != nullptr); return *_M_get(); }
Re: [PATCH] Partial solution to LWG 523
On 26/11/16 16:27 -0800, Tim Shen wrote: @@ -235,23 +242,86 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StrTransT _M_transform(_CharT __ch) const { - return _M_transform_impl(__ch, typename integral_constant::type()); + _StrTransT __str = _StrTransT(1, __ch); I know the copy will be elided, but this could be: _StrTransT __str(1, __ch); Not a big deal though. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 953aa87..2fb70b7 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1000,7 +1000,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION element_type& operator*() const noexcept { - __glibcxx_assert(_M_ptr != nullptr); + __glibcxx_assert(_M_get() != nullptr); return *_M_get(); } Oops, thanks, but let's fix this separately (I'll do it now) so the rest of the patch only touches regex stuff. diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/icase.cc b/libstdc++-v3/testsuite/28_regex/traits/char/icase.cc new file mode 100644 index 000..6b2d9ee --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/traits/char/icase.cc @@ -0,0 +1,75 @@ +// { dg_do run } +// { dg-do run { target c++11 } } The first dg-do should be removed. OK for trunk with those changes, thanks.
[PATCH] Partial solution to LWG 523
Also see discussions from libstdc++/71500. Bootstrapped and tested on x86_64-linux-gnu. Thanks! -- Regards, Tim Shen commit 6c862a2b84578a651d458b09572551c8391082e4 Author: Tim ShenDate: Sat Nov 26 12:36:20 2016 -0800 2016-11-26 Tim Shen PR libstdc++/71500 * include/bits/regex.h (basic_regex::basic_regex): Use ECMAScript when the syntax is not specified. * include/bits/regex_compiler.h (_RegexTranslator, _RegexTranslatorBase): Partially support icase in ranges. * include/bits/regex_compiler.tcc (_BracketMatcher::_M_apply): Refactor _M_apply to make the control flow easier to follow, and call _M_translator._M_match_range as added previously. * include/bits/shared_ptr_base.h: Fix a typo that causes many debug check failures. * testsuite/28_regex/traits/char/icase.cc: Add new tests. * testsuite/28_regex/traits/char/user_defined.cc: Add new tests. diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index aadf312..224d3db 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -762,7 +762,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 template basic_regex(_FwdIter __first, _FwdIter __last, locale_type __loc, flag_type __f) - : _M_flags(__f), _M_loc(std::move(__loc)), + : _M_flags((__f & (ECMAScript | basic | extended | awk | grep | egrep)) + ? __f : (__f | ECMAScript)), + _M_loc(std::move(__loc)), _M_automaton(__detail::__compile_nfa<_FwdIter, _Rx_traits>( std::move(__first), std::move(__last), _M_loc, _M_flags)) { } diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h index 410d61b..964fb28 100644 --- a/libstdc++-v3/include/bits/regex_compiler.h +++ b/libstdc++-v3/include/bits/regex_compiler.h @@ -30,6 +30,15 @@ namespace std _GLIBCXX_VISIBILITY(default) { +_GLIBCXX_BEGIN_NAMESPACE_VERSION +_GLIBCXX_BEGIN_NAMESPACE_CXX11 + + template +class regex_traits; + +_GLIBCXX_END_NAMESPACE_CXX11 +_GLIBCXX_END_NAMESPACE_VERSION + namespace __detail { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -207,17 +216,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [28.13.14] template -class _RegexTranslator +class _RegexTranslatorBase { public: typedef typename _TraitsT::char_type _CharT; typedef typename _TraitsT::string_type _StringT; - typedef typename std::conditional<__collate, - _StringT, - _CharT>::type _StrTransT; + typedef _StringT _StrTransT; explicit - _RegexTranslator(const _TraitsT& __traits) + _RegexTranslatorBase(const _TraitsT& __traits) : _M_traits(__traits) { } @@ -235,23 +242,86 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _StrTransT _M_transform(_CharT __ch) const { - return _M_transform_impl(__ch, typename integral_constant ::type()); + _StrTransT __str = _StrTransT(1, __ch); + return _M_traits.transform(__str.begin(), __str.end()); } -private: + // See LWG 523. It's not efficiently implementable when _TraitsT is not + // std::regex_traits<>, and __collate is true. See specializations for + // implementations of other cases. + bool + _M_match_range(const _StrTransT& __first, const _StrTransT& __last, +const _StrTransT& __s) const + { return __first <= __s && __s <= __last; } + +protected: + bool _M_in_range_icase(_CharT __first, _CharT __last, _CharT __ch) const + { + typedef std::ctype<_CharT> __ctype_type; + const auto& __fctyp = use_facet<__ctype_type>(this->_M_traits.getloc()); + auto __lower = __fctyp.tolower(__ch); + auto __upper = __fctyp.toupper(__ch); + return (__first <= __lower && __lower <= __last) + || (__first <= __upper && __upper <= __last); + } + + const _TraitsT& _M_traits; +}; + + template +class _RegexTranslator +: public _RegexTranslatorBase<_TraitsT, __icase, __collate> +{ +public: + typedef _RegexTranslatorBase<_TraitsT, __icase, __collate> _Base; + using _Base::_Base; +}; + + template +class _RegexTranslator<_TraitsT, __icase, false> +: public _RegexTranslatorBase<_TraitsT, __icase, false> +{ +public: + typedef _RegexTranslatorBase<_TraitsT, __icase, false> _Base; + typedef typename _Base::_CharT _CharT; + typedef _CharT _StrTransT; + + using _Base::_Base; + _StrTransT - _M_transform_impl(_CharT __ch, false_type) const + _M_transform(_CharT __ch) const { return __ch; } - _StrTransT - _M_transform_impl(_CharT