This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: basic regex implementation


On 10 June 2010 13:53, Stephen M. Webb wrote:
>
>> A comment on the C++0x regex spec, rather than your implementation:
>> It's my understanding that users are not supposed to instantiate
>> sub_match objects, or at least shouldn't need to, as doing so results
>> in an uninitialised "matched" member. I intend to file an NB comment
>> suggesting a deleted default constructor. ?There could be a private
>> constructor which is used internally by the library. ?If you have any
>> comments on that point I'd be glad to hear them.
>
> The problem with making sub_match constructors private is that the
> implementation of the match engine(s) and token_iterator engine(s) could get
> pretty hairy, or else sub_match would have to have so many friends it should
> have its own page on Facebook. ?A sub_match is effectively a POD, and if a
> user creates a POD without initializing it he or she can keep both halves.

:-)

> I think a safer design might have been to make sub_match.matched a member
> function and provide non-trivial constructors. ?Then again, keeping it
> PODlike simplifies implementing the rest iof the regex library.

It's certainly not a POD, as it has a base class with non-trivial
constructors and the iterator types can be non-POD too.  That means
you can't use aggregate initialization, and even value-initialization
(which calls the implicitly-defined default ctor) will not init the
bool member.

Consider:
sub_match sm = sub_match();
if (sm.matched) {
  frobnicate(sm.first, sm.second);
}

It's OK for the iterators to be singular, as long as you can check
sm.matched. But a default-constructed sub_match has an uninitialised
'matched'  -- I think it should either be safely initialised (via a
non-trivial default constructor) or it should not be possible for
users to default construct a sub_match.


The problem of needing lots of friends can be solved easily in a
couple of ways.  With a private helper function:

template<typename BiIter>
constexpr sub_match
__mksm();

template<class BiIter>
class sub_match {
private:
    friend constexpr sub_match __mksm<BiIter>();
    struct __tag { };
    sub_match( __tag );
...
};

template<typename BiIter>
constexpr inline sub_match
__mksm() { return sub_match<BiIter, BiIter>( __tag() ); }

Only that function needs to be a friend of sub_match. The
implementation can use that anywhere it needs to create a sub_match.
Users shouldn't be using anything called __mksm but if they do, they
only have themselves to blame if it goes wrong.

Or just have a public constructor taking a __tag type. Again, users
who use it do so at their own risk, but the documented interface
doesn't allow them to create an object with uninitialised members.

> It would be interesting to hear what the Committee has to say on the matter.

Look out for a ballot comment from the UK on the matter, if I get time
to write it.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]