This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: std::regex: inserting std::wregex to std::vector loses some std::wregex values
- From: Tim Shen <timshen at google dot com>
- To: Jonathan Wakely <jwakely at redhat dot com>
- Cc: Paolo Carlini <paolo dot carlini at oracle dot com>, Jonathan Wakely <jwakely dot gcc at gmail dot com>, Stefan Schweter <stefan at schweter dot it>, "libstdc++" <libstdc++ at gcc dot gnu dot org>
- Date: Mon, 15 Sep 2014 09:46:58 -0700
- Subject: Re: std::regex: inserting std::wregex to std::vector loses some std::wregex values
- Authentication-results: sourceware.org; auth=none
- References: <540C6873 dot 9030205 at schweter dot it> <CAH6eHdSdmAdo420reU92ujW+nT63H431vsuP9YzZo5YQPj1T3A at mail dot gmail dot com> <CAG4ZjNkti0p=XAdhDYeXbcUx3mtqxH4P-U5F9DXmahG1=0b1Dg at mail dot gmail dot com> <CAG4ZjNmwG1VYrA2cnw7_hhxcHukC01U-DOzfpdjbZhcLgLP_sQ at mail dot gmail dot com> <54156B0B dot 2050006 at oracle dot com> <CAG4ZjNm_PzVYhyonUGOq3fMK8Drj9FNseXepKCts_SGzF=LSkQ at mail dot gmail dot com> <20140915101056 dot GS22778 at redhat dot com>
On Mon, Sep 15, 2014 at 3:10 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> With this patch basic_regex::_M_traits becames a pointer, but that
> pointer becomes null after a move - is that safe?
>
> It looks wrong to allocate a traits object in the default constructor
> but not in the move constructor, and to allow _M_traits to be null
> following assign(), e.g. does this work OK after your patch?
>
> std::regex r;
> std::regex rr = std::move(r);
> r.assign("a");
> regex_match("a", r);
No it doesn't, sorry. The reason _M_traits can't be nullptr is imbue()
and getloc(), so should we implement move constructor using default
construction and swap?
> Would it make sense to store the traits object inside the NFA, instead
> of having it separate but tightly coupled to the NFA by references?
I've tried to do so before; it's better of course, but we still need
either _M_automaton or _M_automaton._M_traits to be heap allocated.
More over, it has to be non-null because of imbue() and getloc(), no
matter where it resides.
What do you think is the best practice here?
> I think for the 4.9 branch we could fix the copy constructor so it
> doesn't cause sharing of the NFA and then change the move constructor
> to also perform a copy, like so:
>
> diff --git a/libstdc++-v3/include/bits/regex.h
> b/libstdc++-v3/include/bits/regex.h
> index 9dc83fd..5a9dd78 100644
> --- a/libstdc++-v3/include/bits/regex.h
> +++ b/libstdc++-v3/include/bits/regex.h
> @@ -474,16 +474,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> *
> * @param __rhs A @p regex object.
> */
> - basic_regex(const basic_regex& __rhs) = default;
> + basic_regex(const basic_regex& __rhs)
> + : basic_regex(__rhs._M_original_str, __rhs._M_flags)
> + { }
>
> /**
> * @brief Move-constructs a basic regular expression.
> *
> * @param __rhs A @p regex object.
> */
> - basic_regex(const basic_regex&& __rhs) noexcept
> - : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits),
> - _M_automaton(std::move(__rhs._M_automaton))
> + basic_regex(basic_regex&& __rhs)
> + : basic_regex(__rhs)
> { }
>
> /**
>
> This will be slower, and not noexcept, but avoids the dangling
> references.
That works but too bad for efficiency :( sorry again :(
--
Regards,
Tim Shen