Boost logo

Boost :

Subject: Re: [boost] [uuid] Interface
From: Andy Tompkins (atompkins_at_[hidden])
Date: 2008-12-18 13:37:35


On Fri, 12 Dec 2008 15:42:32 -0500, "Scott McMurray"
<me22.ca+boost_at_[hidden]> said:
> On Fri, Dec 12, 2008 at 11:44, Andy Tompkins <atompkins_at_[hidden]>
> wrote:
> > Here is what I see the interface looking like based on feedback
> > from the review so far. It would, of course, be split into
> > different header files.
> >
>
> I like it.
>
> > // no default constructor
> > private:
> > uuid();
>
> Great in theory, but I think it'll break
> lexical_cast<uuid>("21f7f8de-8051-5b89-8680-0195ef798b6a"), since the
> lexical_cast wants to default-construct the target type into which it
> will read.

Your right! Hmm. I want to be able to use lexical_cast as above, but I
also don't want a default constructor.
I think I will optionally include/exclude the default constructor with a
#define. And I think a more explicit way to convert a string
representation of a uuid to a uuid should be included. Something like
the following:

template <typename ch, typename char_traits, typename allocator>
uuid from_string(std::basic_string<ch, char_traits, allocator> const&
s);
uuid from_string(const char* name);
uuid from_string(const wchar_t* name);

OR

class string_generator //not a good name
{
public:
  typedef uuid result_type;

  template <typename ch, typename char_traits, typename allocator>
  uuid operator()(std::basic_string<ch, char_traits, allocator> const&
  name);
  
  uuid operator()(const char* name); // use std::strlen
  uuid operator()(const wchar_t* name); // use std::wcslen
};

> > // valid expression
> > // generator() - result type must be convertible to a uuid
> > template <typename Generator>
> > explicit uuid(Generator & generator);
> >
>
> Does this use the Concept defined at the end?

Yes.

> Also, when is uuid(gen) significantly more convenient than
> uuid(gen())? I'd have thought that the copy constructor was plenty.

It is more convenient than the copy constructor for generators like
random_generator. Eg:

random_generator<> gen;
uuid u(gen);

instead of

uuid u = gen();
or
uuid u(gen());

It is _significantly_ more convenient? I guess not. Hmm, good point.

> > // assert(std::distance(begin, end) >= 16);
> > template <typename ByteInputIterator>
> > uuid(ByteInputIterator begin, ByteInputIterator end);
> >
>
> Glad to see the exception is gone.
>
> >
> > bool is_nil() const;
> >
> > operator unspecified_bool_type() const; // return !is_nil();
> >
>
> shared_ptr.hpp says
>
> // operator! is redundant, but some compilers need it
>
> so providing it might be good; I don't know.

Sure, I don't mind putting it in. I'm happy to follow
shared_ptr's lead on this.

> > // removed get/set_showbraces (does anybody want/use them?)
> > template <typename ch, typename char_traits>
> > std::basic_ostream<ch, char_traits>& operator<<(std::basic_ostream<ch,
> > char_traits>& os, uuid const& u);
> > template <typename ch, typename char_traits>
> > std::basic_istream<ch, char_traits>& operator>>(std::basic_istream<ch,
> > char_traits>& os, uuid& u);
> >
>
> So long as reading still can handle them, it's probably easy enough to
> stream the brackets explicitly if desired, so that seems a fine
> decision. (The statics in headers always makes be nervous.)

I removed them because of the statics. operator>> can continue
to handle them. I agree that it's easy to stream them explicitly, or
create a modifier to use similar to:

uuid u;
cout << with_braces(u);
 
> > class nil_generator // always generates a nil uuid
> > {
> > public:
> > typedef uuid result_type;
> > uuid operator()();
> > };
> > uuid nil(); // easy to use function - should it be included?
> >
>
> Might as well include it, I guess.

Yes, so that one can create a nil uuid explicitly.

> On that note, are you including the name-based UUID name spaces anywhere?

No, I didn't. But I can.

> > // I guess technically a transformer since it does not have a zero
> > argument
> > // operator()
> > class name_based_generator // uses sha1 hash
> > {
>
> On the assumption that an MD5 version would be a reasonable extension,
> what about templating this on the hasher, defaulting to the sha1 one?
>
> That way both the defaults would have the <>, for consistency
> (random_generator<> and name_based_generator<>).

Good idea. But there is no md5 implementation in boost, and I'm not
planning to write one (unless there is significant demand).

> Speaking of which, the version_type enum entry and the generator for
> random UUIDs don't really match, since the former has number_based
> (paralleling the name_based enum entry and generator) but the latter
> does not. random_number_based_generator is admittedly getting rather
> unwieldy, though.

Good point. Maybe just random_based_generator and version_random_based.

> > uuid operator()(const wchar_t* name); // use std::wcslen
> >
>
> What happens here if there are wchar_ts in the stream outside of 0xFF?

This function will treat the stream a sequence of bytes and will have
the
same effect as using the ByteInputIterator version on the stream. So
each wchar_t will be treated as sizeof(wchar_t) bytes.

> > class windows_generator // uses UuidCreate
> > class linux_generator // used uuid_generate
> > typedef ... native_generator;
> >
>
> Should these be parametrized at all? Or do people just want defaults,
> if they want platform ones?

It sounds like people just want defaults. It is also easy to create a
generator using one of these as a pattern to use a different platform
function/parameter.

> > using uuids::uuid; // so nobody has to type boost::uuids::uuid
> >
>
> Good.
>
> >
> > /*
> > uuid Generator concept
> >
> > Notation:
> > X - a type that is a model of uuid generator
> > x - an object of type X
> >
> > Associated Types:
> > Result Type - X::result_type - this must be convertible to
> > boost::uuids::uuid
> >
> > Valid Expressions:
> > x() - return a boost::uuids::uuid
> > */
> >
>
> If result_type allows convertible, then the x() should probably return
> a result_type, not strictly a uuid.

Good point.

> What's this used for?

I am just trying to add flexibility.

> Would it worth be adding one for message UUID generators too?

What do you mean by message uuid generators?

> Thanks for your work on this,
> ~ Scott

Regards,
  Andy Tompkins


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk