The library proposed on this paper is a lite one
Didn't we agree that nested namespaces in std should be abolished? I can't find the paper proposing it, and I don't know whether it was accepted or not, but I completely agree.
Having to write `std::uuids::make_uuid()` is a bit repetitive. No need for a nested namespace IMO.The library proposed on this paper is a lite oneDid you mean "light" instead of "lite"?For the sake of consistency, I propose you name the two string conversion functions `to_string` and template it like std::bitset::to_string did. The constructor of uuid for the two string types should also be templated.Shouldn't you be using std::byte instead of std::uint8_t?
you have an implementation, great! On what compilers was it tested?
is there a way to use it without dynamic memory allocation?
Didn't we agree that nested namespaces in std should be abolished? I can't find the paper proposing it, and I don't know whether it was accepted or not, but I completely agree. Having to write `std::uuids::make_uuid()` is a bit repetitive. No need for a nested namespace IMO.
There was a paper discussing it, but that doesn't mean there was agreement with that paper.
That being said, the proposal contains 1 class, 2 enums, and a small number of functions. That's hardly a good reason to stick them in a namespace, regardless of the question of nested namespaces in `std`.
Shouldn't you be using std::byte instead of std::uint8_t?
For the sake of consistency, I propose you name the two string conversion functions `to_string` and template it like std::bitset::to_string did. The constructor of uuid for the two string types should also be templated.
Conversion to string should probably be a free function std::to_string.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
I'd rather remove any mention of std::wstring and only deal with narrow strings.]
Parsing string representation should accept std::string_view instead of std::string.
I think, parsing should be a separate algorithm rather than a constructor. I think, the current convention is std::from_chars.
http://en.cppreference.com/w/cpp/utility/from_chars
This constructor:
explicit uuid(uint8_t const * const bytes);
is potentially unsafe. Yes, we know `bytes` should point to 16 bytes, but this interface makes it not obvious and not enforceable. I would rather replace this constructor and std::array-based one with this:
template< typename ForwardIterator >
explicit uuid(ForwardIterator bytes_begin, ForwardIterator bytes_end);
This also follows the conventions of other sequences/containers in the standard library.
The default constructor should not be explicit. It should be constexpr and noexcept.
Where does uuid_variant come from and why is it necessary? I may be forgetting, but I don't remember RFC4122 mentioning variants.
8. Random UUID generation algorithm should accept the random number generator. The proposal should not require the implementation to use some pre-defined, possibly global RNG. It should allow reusing the RNG to generate multiple UUIDs. I would also name the algorithm something like `generate_random_uuid`.
9. I still think the proposal should include other means of generating UUIDs, such as generating UUID from a name. When generating from a name, the algorithm should also accept the hashing function to use.
10. I would like the proposal to explicitly mention that the alignment of the `uuid` type is allowed and encouraged to be higher than 1, if it allows for a faster implementation (read: using vector instructions). Also, the proposal should make clear that the internal representation may not be a straightforward array of bytes and may have arbitrary endianness. This means that iterators should not be defined as pointers.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4eaedd85-d3ff-4b9f-a357-ac2ebe8d9bd6%40isocpp.org.
is there a way to use it without dynamic memory allocation?What sort of dynamic memory allocation? Apologizes, but not sure I get the question.
is there a way to use it without dynamic memory allocation?What sort of dynamic memory allocation? Apologizes, but not sure I get the question.
Shouldn't you be using std::byte instead of std::uint8_t?My thoughts were that I want to make it simply constructible from an array of unsigned chars, without having to explicitly convert every single one to std::byte. But I see there is a consensus std::byte should be the one to go with, so I will do that.
For the sake of consistency, I propose you name the two string conversion functions `to_string` and template it like std::bitset::to_string did. The constructor of uuid for the two string types should also be templated.
Conversion to string should probably be a free function std::to_string.
http://en.cppreference.com/w/cpp/string/basic_string/to_stringI have considered that myself and after some thoughts I decided to go with member functions string()/wstring(). The reason for that was I have seen the same thing was done for filesystem::path, which is the newest library to the standard, so I though that should be a good model. You seem to think that is not the case.
I'd rather remove any mention of std::wstring and only deal with narrow strings.]Can you please explain why?
I think, parsing should be a separate algorithm rather than a constructor. I think, the current convention is std::from_chars.
http://en.cppreference.com/w/cpp/utility/from_chars
This constructor:
explicit uuid(uint8_t const * const bytes);
is potentially unsafe. Yes, we know `bytes` should point to 16 bytes, but this interface makes it not obvious and not enforceable. I would rather replace this constructor and std::array-based one with this:
template< typename ForwardIterator >
explicit uuid(ForwardIterator bytes_begin, ForwardIterator bytes_end);
This also follows the conventions of other sequences/containers in the standard library.I was having my own doubts about that particular constructor. I followed your suggestion and removed it and added an iterator based constructor.
8. Random UUID generation algorithm should accept the random number generator. The proposal should not require the implementation to use some pre-defined, possibly global RNG. It should allow reusing the RNG to generate multiple UUIDs. I would also name the algorithm something like `generate_random_uuid`.
9. I still think the proposal should include other means of generating UUIDs, such as generating UUID from a name. When generating from a name, the algorithm should also accept the hashing function to use.
10. I would like the proposal to explicitly mention that the alignment of the `uuid` type is allowed and encouraged to be higher than 1, if it allows for a faster implementation (read: using vector instructions). Also, the proposal should make clear that the internal representation may not be a straightforward array of bytes and may have arbitrary endianness. This means that iterators should not be defined as pointers.I need a bit more time to think about those ones.
template <typename UniformRandomNumberGenerator>class uuid_random_generator{public:typedef uuid result_type;uuid_random_generator();explicit uuid_random_generator(UniformRandomNumberGenerator& gen);explicit uuid_random_generator(UniformRandomNumberGenerator* pGen);uuid operator()();};
class uuid_default_generator{public:typedef uuid result_type;uuid operator()();};
uuid make_uuid(){return uuid_default_generator{}();}template <typename Generator>uuid make_uuid(Generator & g){return g();}
auto id1 = make_uuid();uuid_default_generator dgen;auto id2 = make_uuid(dgen);auto id3 = make_uuid(dgen);std::random_device rd;std::mt19937 mtgen(rd());uuid_random_generator<std::mt19937> rgen(mtgen);auto id4 = make_uuid(rgen);auto id5 = make_uuid(rgen);
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/50277626-6c7a-38db-ac37-463d0aac5caf%40gmail.com.
On 12/20/17 11:27, Thiago Macieira wrote:
> On terça-feira, 19 de dezembro de 2017 15:18:46 PST Andrey Semashev wrote:
>> How exactly such a machine operates in 8-bit environment? How does one
>> represent a 128-bit message on such a machine? I can imagine multiple
>> possibilities, and none of them looks suitable to me, unless I'm missing
>> something.
>
> You tell me.
Sorry, it works backwards. I have no idea. None of what I could imagine
makes sense, so I consider the idea of supporting non-8-bit machines
nonsensical. If you can suggest a sensible way to support those
machines, please do.
>> - What to do with the padding, especially when importing the UUID into
>> std::uuid? The padding bits must not be part of the UUID value, so the
>> bits bust be either masked or the conversion should fail. The latter I
>> find unacceptable, because all the normal world expects this operation
>> to never fail and be noexcept.
>
> If you consider the UUID as a char[16], I don't see why that would be a
> problem at all.
That should be unsigned char[16]. The problem is that unsigned char[16]
does not represent a 128-bit value on a non-8-bit machine. For example,
two 144-bit "UUIDs" may not compare equal because of the padding bits.
You have to define the meaning and behavior with regard to the bits that
are not part of the UUID value. That, in turn, may penalize 8-bit machines.
We could approach the problem of generating uuids in a similar manner as done in boost::uuid. We could have generator like this one that uses a random number generator (and a uniform distribution) to produce uuids:template <typename UniformRandomNumberGenerator>class uuid_random_generator{public:typedef uuid result_type;uuid_random_generator();explicit uuid_random_generator(UniformRandomNumberGenerator& gen);explicit uuid_random_generator(UniformRandomNumberGenerator* pGen);uuid operator()();};
I would propose a "default generator" one that may rely on the operating system uuid support, as make_uuid() does in my current proposal.class uuid_default_generator{public:typedef uuid result_type;uuid operator()();};
Then, we could have two overloads for make_uuid() that would look like this:uuid make_uuid(){return uuid_default_generator{}();}template <typename Generator>uuid make_uuid(Generator & g){return g();}
This would enable users to write their own generators, such as one that is based on name hashing, and use them with make_uuid.That would allow us to write code like the following:auto id1 = make_uuid();uuid_default_generator dgen;auto id2 = make_uuid(dgen);auto id3 = make_uuid(dgen);std::random_device rd;std::mt19937 mtgen(rd());uuid_random_generator<std::mt19937> rgen(mtgen);auto id4 = make_uuid(rgen);auto id5 = make_uuid(rgen);
--
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/NjVdCCf0tlk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/95c3a4d5-4bd0-facd-68f9-9fb09ddf47b8%40gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2248745.fYPvmxbhEj%40tjmaciei-mobl1.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASzy2bwCr1-6N2URPLF14hgjJUr5gEbUSsoC9gddzVP%2BhA%40mail.gmail.com.
- conversion functions string() and wstring() have been removed; non-member functions to_string() and to_wstring() have been added instead
On 01/22/18 12:10, Marius Bancila wrote:
Again, the link to the project is https://github.com/mariusbancila/stduuid, and to the proposal: https://github.com/mariusbancila/stduuid/blob/master/paper.md.
- I believe, `swap` should be overloaded, not specialized.
- I think `uuid_default_generator` still has to provide some guarantees on the produced UUIDs. Having a generator that produces noone knows what is hardly useful. I assume it is supposed to produce random UUIDs using some system-specific source of randomness, so why not say that? Also, if it is a random generator, its name should reflect that.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2B1jQaQ_mFS4h0gwN8GMRGRnHXqy_kUHdXXHQbPJL0RnA%40mail.gmail.com.
the signature of std::hash may be correct but the implementation leaves a lot to be desired. There's too much overhead in converting the uuid to a string and then hashing the string.
On Mon, Jan 22, 2018 at 11:31 AM, j c <james.a...@gmail.com> wrote:the signature of std::hash may be correct but the implementation leaves a lot to be desired. There's too much overhead in converting the uuid to a string and then hashing the string.FWIW, I agree that the std::hash implementation should be improved by vendors if possible. However:(1) The semantics seem correct to me. I think it is at least slightly valuable for std::hash<>(uu) and std::hash<>(uu.to_string()) to have the same integer value. Or, equivalently, for std::hash<>(s) and std::hash<>(uuid(s)) to have the same integer value.
Would it be acceptable to make it constexpr, noexcept or (preferably) both? That would preclude the slow, allocating stringstream approach without mandating any particular implementation.
The section "Iterators constructors" lists two examples, neither of which uses iterators to construct UUID.
The "Capacity" section should probably be named "Size" since you describe the `size` method there. Also, `nil` has nothing to do with size, and its description is better moved elsewhere.
I believe, `swap` should be overloaded, not specialized.
Why is `uuid_variant::future` needed?
`uuid::uuid_const_iterator` and `uuid::uuid_iterator` don't need to be in the specification. The type of the iterators can simply be specified as implementation-defined.
typedef /*implementation-defined*/ iterator; // see [uuid]
using const_iterator = implementation-defined; // see [uuid]
I don't think std::hash<std::uuid> should be string-based at all, but we're discussing the proposal, and it doesn't need to suggest a particular implementation of the specialization. In fact, I think it should *not* suggest a particular implementation.
I think `uuid_default_generator` still has to provide some guarantees on the produced UUIDs. Having a generator that produces noone knows what is hardly useful. I assume it is supposed to produce random UUIDs using some system-specific source of randomness, so why not say that? Also, if it is a random generator, its name should reflect that.
Yes. Please never ever name anything "default_"-anything. There are two conflicting meanings for "default_" in the C++ standard:
(1) "Default" as in "the best one to use." There will be a reason that it is the best one. State that reason. For example, "my::mt19937" is a good name for a default random number engine, and "my::sha256" is a good name for the default hash.
(2) "Default" as in "implementation-defined." Such a typedef will never be used by anyone, because its behavior will not be portable. Prefer to eliminate such useless cruft from the wording completely.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BPp40k0wLva_6iF1mApOeq0ycNt94cjYeAUD-TC_XYNQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASwAinGU4xSiTO513TTU-47YKymHQC5YnBv_QidTa5Tt0A%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbitwUMo2%3Dvp4_7AH_d3YfsYYpQn-81BWUE9VFXeVg4_GZA%40mail.gmail.com.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0%2BPp40k0wLva_6iF1mApOeq0ycNt94cjYeAUD-TC_XYNQ%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASwAinGU4xSiTO513TTU-47YKymHQC5YnBv_QidTa5Tt0A%40mail.gmail.com.
--Be seeing you,Tony
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbitwUMo2%3Dvp4_7AH_d3YfsYYpQn-81BWUE9VFXeVg4_GZA%40mail.gmail.com.
On 06/14/18 06:11, Tony V E wrote:
The committee discussed this paper briefly on Saturday, at the very end of the week.
Some comments (a mix of just my opinions, and LEWG comments)
- rename nil to is_nil (or remove altogether - checking == {} works)
is_nil could be more efficient.
Basically, we want a class that is not much more than 16 bytes gathered up. They should almost always be treated as a whole, not parts. So once you have the unique bytes inside the uuid, you can be sure that they stay unique (as unique as wherever you constructed them from).
The invariant of the class is the uniqueness. You can't actually guarantee that, but you can at least guarantee that a uuid (if not nil) _maintains_ the invariant, if you assume all uuids are correct on construction.
I don't agree. Uniqueness is not an invariant of a UUID. It's an invariant of a random UUID generator, although technically it's not guaranteed. As for UUID, as soon as it it constructed, it's just an id. It doesn't have to be unique (e.g. you can copy it or you can construct multiple UUIDs from the same bytes).
(Would be interesting to consider move-only, to maintain uniqueness)
I don't think having it movable only would be useful.
On 06/14/18 06:11, Tony V E wrote:
The committee discussed this paper briefly on Saturday, at the very end of the week.
Some comments (a mix of just my opinions, and LEWG comments)
- remove container-like stuff: size and iterators, typedefs, etc - just have a to_span() function that returns a span<const std::byte, 16>
(it probably never should have had mutable iterators, btw - we don't want to allow changing single bytes in a uuid)
Oh, wait - you were saying that the internal representation might not be just bytes - is that important?
This was my suggestion. I don't think we should use a span to expose the contents of uuid because it mandates representation (an array of bytes, big endian). This will harm performance. The point of iterators is that they may not be just pointers. For example, they could be reverse iterators on little endian machines.
If we had iterator_range, we could use that. As long as we don't, I think exposing iterators is the best we can do.
I think we need to standardize the order. Construction from a sequence of bytes should give the same uuid on all machines.
The order of bytes exposed by uuid's iterators must be fixed, as it is fixed in RFC. The important part is that the bytes stored in the implementation can have a different order and, actually, can be stored not as bytes but as words or a SIMD vector. The conversion logic is hidden in the iterators.
The constructor from bytes would accept the portable representation (equivalent to RFC) and convert it to the internal representation.
And we also need to define how the bytes turn into strings.
Basically, I would say the byte order turns directly into string order. For bytes a,b,c,d... you get string "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp"
The string format is described in the RFC, we could reproduce it in the wording.
- remove state_size. sizeof(uuid) is good enough (Hmm, although it is technically not guaranteed to be == 16, unless we add that in writing. But it doesn't matter - use size() on the returned span)
I think, uuid::size() should do. Using sizeof to determine the size of the UUID doesn't feel right.
- rename nil to is_nil (or remove altogether - checking == {} works)
is_nil could be more efficient.
Basically, we want a class that is not much more than 16 bytes gathered up. They should almost always be treated as a whole, not parts. So once you have the unique bytes inside the uuid, you can be sure that they stay unique (as unique as wherever you constructed them from).
The invariant of the class is the uniqueness. You can't actually guarantee that, but you can at least guarantee that a uuid (if not nil) _maintains_ the invariant, if you assume all uuids are correct on construction.
I don't agree. Uniqueness is not an invariant of a UUID. It's an invariant of a random UUID generator, although technically it's not guaranteed. As for UUID, as soon as it it constructed, it's just an id. It doesn't have to be unique (e.g. you can copy it or you can construct multiple UUIDs from the same bytes).
(Would be interesting to consider move-only, to maintain uniqueness)
I don't think having it movable only would be useful.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b06d1b8d-a1c9-5d85-c3d0-d56d8b93d9ee%40gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6CTRS5yDCRikb3zgwkkxzvpZyJf6iwRn%2B%2BxzzEP01YDpA%40mail.gmail.com.
On Thu, Jun 14, 2018 at 10:03 PM, Thiago Macieira <thi...@macieira.org> wrote:
> On Thursday, 14 June 2018 02:01:16 PDT Andrey Semashev wrote:
>> > - remove container-like stuff: size and iterators, typedefs, etc - just
>> > have a to_span() function that returns a span<const std::byte, 16>
>> > (it probably never should have had mutable iterators, btw - we don't
>> > want to allow changing single bytes in a uuid)
>> >
>> > Oh, wait - you were saying that the internal representation might not be
>> > just bytes - is that important?
>>
>> This was my suggestion. I don't think we should use a span to expose the
>> contents of uuid because it mandates representation (an array of bytes,
>> big endian). This will harm performance. The point of iterators is that
>> they may not be just pointers. For example, they could be reverse
>> iterators on little endian machines.
>
> Right, it may not work to provide a function returning std::span<byte, 16>,
> but instead a std::array<byte, 16> to get the actual bytes, if one needs them
> for some reason.
This would mean that in order to export portable representation one
would have to copy the bytes as std::array first and then copy bytes
from that array to where they need to be (e.g. a shared memory region
or write to a file). In this case it might be better to have an export
method of std::uuid that takes an output iterator, which will receive
the bytes.
> For example, the implementation on Windows may want to be layout-compatible
> with the GUID structure[1] to facilitate copying to and from that type (QUuid
> does that). As a side-effect, it means the first 8 bytes are not in the
> correct order for a byte-level access on little-endian machines.
I'm not sure having std::uuid layout compatible with GUID would be
helpful. Users would have to perform a reinterpret_cast in order to
employ this feature, and this would be generally UB and certainly not
something we want to encourage.
> By the way, what's the policy on allowing the implementation to provide member
> functions to convert to and from native structures like GUID?
We have native_handle() in std::mutex and std::condition_variable. We
could add something like this to std::uuid, but frankly, I would
prefer if std::uuid didn't use GUID as implementation as it would make
its ordering inefficient.
The committee discussed this paper briefly on Saturday, at the very end of the week.Some comments (a mix of just my opinions, and LEWG comments)- don't construct from a string_view. Make that a "factory" function. ie a static member function uuid from_string(string_view). Either return nil uuid on error, or throw an exception. (Note that nil is a valid result, so returning nil means you don't know if it is an error or a valid parse, unfortunately. Might also consider expected<uuid> but nothing else in the STL uses expected (and it is not in the STL yet))It should be a function because it is doing parsing, which feels more like a function (takes input, gives output) than a constructor.
- construct from a fixed-size span<const std::byte, 16>. This makes "wrong size" not your problem.
- not sure whether the iterator constructor should stay - I suppose it is useful for non-contiguous cases. Committee might make it UB if it is not 16 bytes.
- remove container-like stuff: size and iterators, typedefs, etc - just have a to_span() function that returns a span<const std::byte, 16>(it probably never should have had mutable iterators, btw - we don't want to allow changing single bytes in a uuid)Oh, wait - you were saying that the internal representation might not be just bytes - is that important?
I think we need to standardize the order. Construction from a sequence of bytes should give the same uuid on all machines.
And we also need to define how the bytes turn into strings.
- remove state_size. sizeof(uuid) is good enough (Hmm, although it is technically not guaranteed to be == 16, unless we add that in writing. But it doesn't matter - use size() on the returned span)
- rename nil to is_nil (or remove altogether - checking == {} works)
- add assignment from another uuid
- should be trivially copyable, etc
Basically, we want a class that is not much more than 16 bytes gathered up. They should almost always be treated as a whole, not parts. So once you have the unique bytes inside the uuid, you can be sure that they stay unique (as unique as wherever you constructed them from).The invariant of the class is the uniqueness. You can't actually guarantee that, but you can at least guarantee that a uuid (if not nil) _maintains_ the invariant, if you assume all uuids are correct on construction.(Would be interesting to consider move-only, to maintain uniqueness)
On Thu, Jun 14, 2018 at 11:09 PM, Tony V E <tvan...@gmail.com> wrote:
> OK, revising, based on latest emails:
>
> On Wed, Jun 13, 2018 at 11:11 PM, Tony V E <tvan...@gmail.com> wrote:
>>
>> - construct from a fixed-size span<const std::byte, 16>. This makes "wrong
>> size" not your problem.
>
> still yes. Except uint8_t.
> We need to say that the order matches the RFC
Personally, I'd prefer span<const T, 16> where T is one of std::byte,
unsigned char, signed char or char. std::byte is rather cumbersome to
use, most of the time you get some variant of char from external
sources.
uint8_t would limit std::uuid to only platforms with 8-bit bytes. This
is probably unnecessary.
>> - not sure whether the iterator constructor should stay - I suppose it is
>> useful for non-contiguous cases. Committee might make it UB if it is not 16
>> bytes.
>
> Do we even need the end iterator?
Some implementations might want to use it for debugging purposes.
>> - remove container-like stuff: size and iterators, typedefs, etc - just
>> have a to_span() function that returns a span<const std::byte, 16>
>> (it probably never should have had mutable iterators, btw - we don't want
>> to allow changing single bytes in a uuid)
>>
>> Oh, wait - you were saying that the internal representation might not be
>> just bytes - is that important?
>
> OK, so keep the container interface. But only const_iterators. Not
> mutable.
> Is that a problem for writing into an existing uuid? Construct a new one
> and assign? Let the compiler optimize it.
> Or do we need the mutable iterators? They seem wrong to me.
I'd be ok with only const_iterators.
>> - should be trivially copyable, etc
>
> yes?
I don't see an immediate use case that requires trivial copyability,
but if it happens to be trivially copyable, why not.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6Djfqg17%2BCRyX4qxWA0YuEAk6doySZQ6Q-e5MFp5V9zYA%40mail.gmail.com.
On Thu, Jun 14, 2018 at 11:01 PM, 'Edward Catmur' via ISO C++ Standard
- Future Proposals <std-pr...@isocpp.org> wrote:
> On Thu, Jun 14, 2018 at 8:26 PM, Andrey Semashev <andrey....@gmail.com>
> wrote:
>> On Thu, Jun 14, 2018 at 10:03 PM, Thiago Macieira <thi...@macieira.org>
>> wrote:
>> >
>> > Right, it may not work to provide a function returning std::span<byte,
>> > 16>,
>> > but instead a std::array<byte, 16> to get the actual bytes, if one needs
>> > them
>> > for some reason.
>>
>> This would mean that in order to export portable representation one
>> would have to copy the bytes as std::array first and then copy bytes
>> from that array to where they need to be (e.g. a shared memory region
>> or write to a file). In this case it might be better to have an export
>> method of std::uuid that takes an output iterator, which will receive
>> the bytes.
>
> With Ranges TS one can write ranges::copy(uuid.as_bytes(), OutputIterator).
> I don't think an export() method would really add anything.
If as_bytes() returns std::span<std::byte, 16> then the problem with
enforced internal representation remains.
On Thu, Jun 14, 2018 at 11:09 PM, Tony V E <tvan...@gmail.com> wrote:
> OK, revising, based on latest emails:
>
> On Wed, Jun 13, 2018 at 11:11 PM, Tony V E <tvan...@gmail.com> wrote:
>>
>> - construct from a fixed-size span<const std::byte, 16>. This makes "wrong
>> size" not your problem.
>
> still yes. Except uint8_t.
> We need to say that the order matches the RFC
Personally, I'd prefer span<const T, 16> where T is one of std::byte,
unsigned char, signed char or char. std::byte is rather cumbersome to
use, most of the time you get some variant of char from external
sources.
uint8_t would limit std::uuid to only platforms with 8-bit bytes. This
is probably unnecessary.
>> - not sure whether the iterator constructor should stay - I suppose it is
>> useful for non-contiguous cases. Committee might make it UB if it is not 16
>> bytes.
>
> Do we even need the end iterator?
Some implementations might want to use it for debugging purposes.
>> - remove container-like stuff: size and iterators, typedefs, etc - just
>> have a to_span() function that returns a span<const std::byte, 16>
>> (it probably never should have had mutable iterators, btw - we don't want
>> to allow changing single bytes in a uuid)
>>
>> Oh, wait - you were saying that the internal representation might not be
>> just bytes - is that important?
>
> OK, so keep the container interface. But only const_iterators. Not
> mutable.
> Is that a problem for writing into an existing uuid? Construct a new one
> and assign? Let the compiler optimize it.
> Or do we need the mutable iterators? They seem wrong to me.
I'd be ok with only const_iterators.
>> - should be trivially copyable, etc
>
> yes?
I don't see an immediate use case that requires trivial copyability,
but if it happens to be trivially copyable, why not.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6Djfqg17%2BCRyX4qxWA0YuEAk6doySZQ6Q-e5MFp5V9zYA%40mail.gmail.com.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6Djfqg17%2BCRyX4qxWA0YuEAk6doySZQ6Q-e5MFp5V9zYA%40mail.gmail.com.
--Be seeing you,Tony
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbivzYngSA3G0yLr42Yap-Pn7C9TvdWdQsq0vbwUVZRKdmA%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASxNbbrEPSycOPJPAiUtxLY6mTtGqjkGhYoT%2B9M5g4ByrA%40mail.gmail.com.
Does it really make sense to provide a free function as_bytes? I don't think we want that, at least I don't :)
On Wednesday, June 27, 2018 at 10:56:38 AM UTC-4, Nicolas Lesser wrote:Does it really make sense to provide a free function as_bytes? I don't think we want that, at least I don't :)Yes. `std::as_bytes` is a free function from `span` that takes any `span` and returns a byte array to its sequence. So it makes sense that if a UUID is considered span-like, then it should be convertible with a similar interface.
Now granted, I'm not sure it's a good idea, but that's more due to lifetime issues.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALmDwq1NC4Z8%2BqdYw54zo_DOS%3D%3DwKOFmMfj9NVm%3DgjHEVu5LXQ%40mail.gmail.com.
Thank you for all the feedback here. I was a bit busy but finally made some time to look into all the recent discussions here and summarize the things that should be done in order to move further.Here is a list of changes I have done based on the feedback:
- Removed string constructors and replaced with free overloaded function from_string().
- Parsing strings to uuid throws exception uuid_error instead of creating a nil uuid when the operation fails.
- {} included in the supported format for parsing, i.e. "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}".
- Removed state_size.
- Renamed member function nil() to is_nil().
- The default constructor is defaulted.
- Added a conversion construct from std::span<std::byte, 16>.
- Added the free function as_bytes() to convert the uuid into a view of its underlying bytes.
- Constructing a uuid from a range with a size other than 16 is undefined behaviour.
- Removed mutable iterators (but preserved the constant iterators).
- Removed typedefs and others container-like parts.
- Defined the correlation between the internal UUID bytes and the string representation.
- Added UUID layout and byte order specification from the RFC 4122 document.
To be honest, I am unsure whether the member function size() should stay or not. As we don't want to make the uuid a container-like type perhaps this should be removed too.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6Djfqg17%2BCRyX4qxWA0YuEAk6doySZQ6Q-e5MFp5V9zYA%40mail.gmail.com.
--Be seeing you,Tony
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbivzYngSA3G0yLr42Yap-Pn7C9TvdWdQsq0vbwUVZRKdmA%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASxNbbrEPSycOPJPAiUtxLY6mTtGqjkGhYoT%2B9M5g4ByrA%40mail.gmail.com.
You seem to have a lot of functions/constructors that need constexpr :)
- uuid(std::span) -> std::span is constexpr enabled, so I don't see a reason for this not to be constexpr
- uuid(FwdIt, FwdIt) -> this can also be constexpr
- swaps are now constexpr if possible (P0879), which in your case is okay
- begin and end can also be constexpr, there isn't a reason not to
- as_bytes can also be constexpr as std::span is constexpr enabled
- operator==, operator!= and operator< can also be constexpr
Is there a reason why there are a member and non member functions for operator== and operator<?
Does it really make sense to provide a free function as_bytes? I don't think we want that, at least I don't :)
I think it makes sense to use operator<=> instead of operator== and operator!= (as an additional benefit, you can then use uuid as a non-type template parameter).
I'm not an LWG person, but I think that everywhere in the standard library using type = ... is used instead of typedef.
from_string needs to be a static function inside of uuid. ie
uuid id = uuid::from_string("00....");
We can't take the name "from_string" for all of std and use it only for uuid. If anything, some day there may be a templatized from_string
int x = from_string<int>("00...");
uuid id = from_string<uuid>("00....");
But uuid::from_string is easier, as it doesn't open up a big discussion about a generalized from_string<>
why allow the non-const access version of as_bytes?
Is this the same as RFC 4122?
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6Djfqg17%2BCRyX4qxWA0YuEAk6doySZQ6Q-e5MFp5V9zYA%40mail.gmail.com.
--Be seeing you,Tony
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbivzYngSA3G0yLr42Yap-Pn7C9TvdWdQsq0vbwUVZRKdmA%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASxNbbrEPSycOPJPAiUtxLY6mTtGqjkGhYoT%2B9M5g4ByrA%40mail.gmail.com.
--Be seeing you,Tony
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbiuO%3D6vMbwCnaDUD%3DdZ1bc0-Xf5qqyzJhfisqpubW-2gaA%40mail.gmail.com.
Is there a reason why there are a member and non member functions for operator== and operator<?They are all non-member.
I think it makes sense to use operator<=> instead of operator== and operator!= (as an additional benefit, you can then use uuid as a non-type template parameter).My initial idea was to only be able to compare uuid for equality. operator < is necessary to be able to use uuids with associative containers. It does not really make sense to compare whether a uuid is less than another for any other reasons. Should we want to have all these comparison operators, then yes, it makes more sense to use the <=> operator.constexpr auto operator <=>(uuid const & lhs, uuid const & rhs) noexcept;
Alternatively, recognize that unordered_map/set are associative containers that don't require an ordering.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0Jx%3DUAqczN0FVNu9DqxWrahjf8Wk-tELna_KCMCJOHPRg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASxTLX6eQa%2BZTR4ay60q_FryMYUucGmw4UVxVW-PP4X8ZA%40mail.gmail.com.
R
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0Jx%3DUAqczN0FVNu9DqxWrahjf8Wk-tELna_KCMCJOHPRg%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASxTLX6eQa%2BZTR4ay60q_FryMYUucGmw4UVxVW-PP4X8ZA%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbL1k9qZynhba5sa49JnLSv1r4z7jVzWobECQjHEw8tLQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkUK%2BMfxCy_qvC6a84UnkSwxRQyo7Bhc3-DXJC6E8mHJNw%40mail.gmail.com.
An ordering of UUIDs is very much important for implementing unique() and flatsets.
I would argue against inclusion of any type that can meet Stepanov Regular (Regular + TotallyOrdered) but does not.
G
R
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0Jx%3DUAqczN0FVNu9DqxWrahjf8Wk-tELna_KCMCJOHPRg%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CA%2BgtASxTLX6eQa%2BZTR4ay60q_FryMYUucGmw4UVxVW-PP4X8ZA%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbL1k9qZynhba5sa49JnLSv1r4z7jVzWobECQjHEw8tLQ%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkUK%2BMfxCy_qvC6a84UnkSwxRQyo7Bhc3-DXJC6E8mHJNw%40mail.gmail.com.
On Thursday, 5 July 2018 07:52:16 PDT Richard Hodges wrote:
> Therefore to build one into a library seems like an error to me.
And yet placing such a type in containers that require ordering operations is
a useful use-case too. Sorting is an internal detail of that container, not a
specific goal (though of course people may come to use it).
How do we solve this?
Also, please note that UUID would have multiple sorting possibilities. For
example, which of these two sort first?
00000001-0000-0000-0000-000000000000
01000000-0000-0000-0000-000000000000
Many implementations treat UUIDs as a sequence of components, the first of
which is a 32-bit number.
Ditto for
01000000-0000-0000-0000-000000000000
00000000-0000-0000-0000-000000000001
Another valid implementation would be a plain 16-byte compare (SSE2
instruction PCMPGT), which due to x86's little-endianness placing the MSB in
the last byte would make the second one be sorted first.
Whatever solution we come up with, it should be made clear that the order is
not specified and thus cannot be relied upon to be cross-platform.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2276247.eLH75cpEnP%40tjmaciei-mobl1.
On Thursday, 5 July 2018 07:52:16 PDT Richard Hodges wrote:
> Therefore to build one into a library seems like an error to me.
And yet placing such a type in containers that require ordering operations is
a useful use-case too. Sorting is an internal detail of that container, not a
specific goal (though of course people may come to use it).
On Thursday, July 5, 2018 at 11:09:59 AM UTC-4, Thiago Macieira wrote:On Thursday, 5 July 2018 07:52:16 PDT Richard Hodges wrote:
> Therefore to build one into a library seems like an error to me.
And yet placing such a type in containers that require ordering operations is
a useful use-case too. Sorting is an internal detail of that container, not a
specific goal (though of course people may come to use it).I think that rather depends on the container in question. While you could say that `map`/`flat_map`'s primary purpose is to allow you to quickly access values through keys (with sorting being an implementation detail, despite it being the basis of the container's range interface), the primary purpose of `set`/`flat_set` is to be sorted. To be able to iterate through a list of items in a specific order.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCPTnAHFag_KjbyJg5Sk3EvE7kO3Aa7Kub4kqPWu8nfRaA%40mail.gmail.com.
For me UUID appears to be just random string.
On Thu, 5 Jul 2018, 19:09 Dejan Milosavljevic, <dmi...@gmail.com> wrote:For me UUID appears to be just random string.It is. It holds no meaning, but it is unique, which means there will be some people using it in a searchable manner (it is an identifier, after all).
For this reason and this reason alone, ordering makes sense. And if some ordering is provided by stdlib, I see no reason why users should jump through hoops to use it (e.g. through explicit use of a uuid_order).
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCO0Kdrp5k1HTU%2BoNHNgTrJkkNdfqS4uNH9Msa92RZ%2BxrQ%40mail.gmail.com.
The pedant in me agrees that ordering of UUIDs is meaningless and that implementing it would be misleading and maybe even lend itself to abuse.The lazy part of me thinks that searching for a UUID will be in enough demand to justify the inclusion of ordering. Although a UUID is a wasteful key to use in terms of binary size (by definition of a UUID - it's big enough to prevent any collisions on a vast scale), it is still something that goes on a lot. It makes no sense for a user to have to implement this ordering themselves, so along this line of thought a uuid_order is justified.Or is it?Including a uuid_order operation is also misleading for the same reasons that an in-built ordering is, and providing it would just mean an unnecessary step for something that we would be implicitly supporting by including uuid_order in the first place.
On Thursday, July 5, 2018 at 7:24:13 PM UTC+2, Jake Arkinstall wrote:The pedant in me agrees that ordering of UUIDs is meaningless and that implementing it would be misleading and maybe even lend itself to abuse.The lazy part of me thinks that searching for a UUID will be in enough demand to justify the inclusion of ordering. Although a UUID is a wasteful key to use in terms of binary size (by definition of a UUID - it's big enough to prevent any collisions on a vast scale), it is still something that goes on a lot. It makes no sense for a user to have to implement this ordering themselves, so along this line of thought a uuid_order is justified.Or is it?Including a uuid_order operation is also misleading for the same reasons that an in-built ordering is, and providing it would just mean an unnecessary step for something that we would be implicitly supporting by including uuid_order in the first place.But if it named `uuid_lexical_order` or `uuid_byte_order`? standard could provide both or even more. User will chose best version that fit his goals or he will roll its own.
One could argue that lexicographical ordering is not semantically sensical (a string built up of arbitrary symbols that don't have much meaning on their own, but still have a defined ordering by consensus just so we can find stuff easier), but it's still used so heavily in the real world that its functionality is built in. We include it for booleans (equally nonsensical). And I guarantee that the vast majority of overloads of operator< are for convenience rather than any truly logical meaning.So the lazy side of me is winning over the pedantic side. I definitely agree that ordering of UUIDs is nonsensical, but what it lacks in sense it more than makes up for in real world use.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4e8d1fd8-3fae-4e0d-9b6c-b301850fc33d%40isocpp.org.
On Tue, Jul 3, 2018 at 9:21 AM, Tony V E <tvan...@gmail.com> wrote:On Fri, Jun 29, 2018 at 3:43 AM, Nicolas Lesser <blitz...@gmail.com> wrote:Is there a reason why there are a member and non member functions for operator== and operator<?They are all non-member.Whoops, didn't realize they were were friends.I think it makes sense to use operator<=> instead of operator== and operator!= (as an additional benefit, you can then use uuid as a non-type template parameter).My initial idea was to only be able to compare uuid for equality. operator < is necessary to be able to use uuids with associative containers. It does not really make sense to compare whether a uuid is less than another for any other reasons. Should we want to have all these comparison operators, then yes, it makes more sense to use the <=> operator.constexpr auto operator <=>(uuid const & lhs, uuid const & rhs) noexcept;Just because we don't want the others operators doesn't mean we can't use the spaceship operator:constexpr std::strong_equality operator<=>(uuid const&, uuid const&) noexcept = default;The operator< can always be provided as an extra overload.If we only want map/set interop, then define a std::less<uuid>, not operator<.Please don't do this.You should never explicitly specialize std::less<T> for any type, ever. The primary reason is that it breaks all the user's expectations. The secondary reason is that it won't always work! Heterogeneous containers use std::less<>, not std::less<T>.
If your type has operator<, then it should have the full complement of < <= == >= > != (which in C++2a means "it should have operator<=>").Orthogonally to that consideration, std::less<T>'s whole purpose is to expose the semantics of everybody's operator< in a consistent and functorish way.Your proposal has nothing to do with std::less, and therefore should not touch it.If you really hate comparison operators for some reason, then the STL-favored thing to do is add a free function named foo_less with the semantics you want for your comparator, and force people to type outusing uuidset_t = std::set<std::uuid, std::foo_less>;However, we can tell that this is probably a bad idea in your case by considering what is the appropriate name for "foo_less" in this case. It's comparing uuids, and it's comparing them on the only thing it makes sense to compare uuids on — their values — so the logical name for the free function is "uuid_less".using uuidset_t = std::set<std::uuid, std::uuid_less>;But C++ has a better way to spell "uuid_less(const uuid&, const uuid&)"! That spelling is very old-school-C. The C++-ish spelling for "uuid_less" is...bool operator<(const uuid&, const uuid&);This conveys the same information — "compares uuids, for less-than" — but it conveys it in a shorter and simpler way that also composes (semi)nicely with generic containers such as std::set and std::map.Alternatively, recognize that unordered_map/set are associative containers that don't require an ordering.I personally wouldn't mind if std::uuid, like std::byte, didn't have any "less-than" operation at all, and if you wanted to compare them (binary-search an array of them, whatever) you had to cast them to string or something. But that's because I wouldn't use std::uuid much. If I did use it, I'd probably notice the lack and complain about it.(And I say this as someone who has often railed against the dangers of tuple::operator< and optional::operator<. Consistency is, etc.)–Arthur
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0Jx%3DUAqczN0FVNu9DqxWrahjf8Wk-tELna_KCMCJOHPRg%40mail.gmail.com.
On Thu, 5 Jul 2018 at 22:55, <inkwizyt...@gmail.com> wrote:
On Thursday, July 5, 2018 at 7:24:13 PM UTC+2, Jake Arkinstall wrote:The pedant in me agrees that ordering of UUIDs is meaningless and that implementing it would be misleading and maybe even lend itself to abuse.The lazy part of me thinks that searching for a UUID will be in enough demand to justify the inclusion of ordering. Although a UUID is a wasteful key to use in terms of binary size (by definition of a UUID - it's big enough to prevent any collisions on a vast scale), it is still something that goes on a lot. It makes no sense for a user to have to implement this ordering themselves, so along this line of thought a uuid_order is justified.Or is it?Including a uuid_order operation is also misleading for the same reasons that an in-built ordering is, and providing it would just mean an unnecessary step for something that we would be implicitly supporting by including uuid_order in the first place.But if it named `uuid_lexical_order` or `uuid_byte_order`? standard could provide both or even more. User will chose best version that fit his goals or he will roll its own.What would be the motivating use case for such a utility?Without a compelling one, this would just represent more code to maintain without reason.