Re: [PATCH] Partial solution to LWG 523

2016-12-06 Thread Jonathan Wakely

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 Wakely 
Date:   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

2016-11-30 Thread Jonathan Wakely

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 Wakely 
Date:   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

2016-11-30 Thread Jonathan Wakely

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

2016-11-26 Thread Tim Shen
Also see discussions from libstdc++/71500.

Bootstrapped and tested on x86_64-linux-gnu.

Thanks!


-- 
Regards,
Tim Shen
commit 6c862a2b84578a651d458b09572551c8391082e4
Author: Tim Shen 
Date:   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