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: Jonathan Wakely <jwakely at redhat dot com>
- To: Tim Shen <timshen at google dot com>
- Cc: Paolo Carlini <paolo dot carlini at oracle dot com>, Stefan Schweter <stefan at schweter dot it>, libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Tue, 16 Sep 2014 10:23:53 +0100
- 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> <CAG4ZjNkizOzm+L4T9PRCJp2Ss2LdZYC4Uq02T0DGJpf=77yWWg at mail dot gmail dot com>
On 15/09/14 09:46 -0700, Tim Shen wrote:
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?
As Paolo points out, that means allocating in the move constructor,
which isn't conforming.
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.
That's fine, compiling a regex is going to have to use the heap at
some point.
More over, it has to be non-null because of imbue() and getloc(), no
matter where it resides.
Ah yes, that implies we need a traits object even when we have no
automaton.
We could allocate something on demand in basic_regex::getloc() but it
is const, which would mean having a mutable member with locks to be
thread-safe, so I don't like that approach.
What do you think is the best practice here?
Figure out the forces affecting the design.
* basic_regex move constructor/assignment must be noexcept. This
implies the traits and NFA must be heap-allocated or must also have
non-throwing moves.
* It must be possible to re-populate a basic_regex with assign() or
operator= so moving must not leave it in an invalid state.
* Must be able to access and change the locale in a basic_regex, even
if it was default-constructed or moved-from.
* The locale is managed by the traits object, so it must be possible
to access the traits object of a basic_regex in any state. That
would be a problem for my suggestion of putting the traits inside
the automaton (because there may not be an automaton for some
basic_regex objects).
With those points in mind your original design is a good fit, with the
traits object stored directly as a member of the basic_regex, and the
automaton on the heap (but in a unique_ptr not shared_ptr so it is not
shared by multiple basic_regex objects, and copying the NFA in the
basic_regex copy constructor). That needs adjusting to avoid dangling
references. That could be done by replacing the references with
pointers, and when ownership of the automaton moves from one
basic_regex to another you would need to update all the pointers to
point to the traits object of the new owner.
You also mentioned not storing any references to the traits in the
automaton and passing it in when it executes, how difficult would that
be?