[PATCH] D66148: [SemanticTypedef] Provide a semantic typedef class and operators

David Greene via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 14 08:23:37 PDT 2019


greened added a comment.

In D66148#1628669 <https://reviews.llvm.org/D66148#1628669>, @nliber wrote:

> A strong motivation for using this over `enum class` should be provided.  The default behavior is too minimalistic.


There will be follow-on commits that add types with rich semantics.  A `StrongBoolean` is one of them.  This is just the bare minimum to get feedback and set the foundation.  Doing this in a modular way provides the most flexibility which in my mind is what you want from foundation classes.

> In my experience, the reason people use `bool`, `int`, `string`, etc. is because they provide a rich set of operations out of the box:  assignment, comparison, implicit conversions, etc.

I don't think we want implicit conversions in the base `SemanticTypedef` class.  We can add flexibility to interoperate with other types later on.  I have prototyped almost all of this.

> `enum class` also provides most of those operations (other than implicit conversion) and has two benefits: it introduces a new type, and it makes it easy to name constants.  `SemanticTypedef`, on the other hand, provides almost no operations without a lot more declaration.

`enum class` is certainly useful in many situations where this would be an inferior solution.  `SemanticTypedef` is useful in places where `enum class` is less so.  For example, `enum class` won't work with any non-integral type.

> If you use derivation (as opposed to using/typedef), you don't even get the converting constructor without an extra declaration.  While derivation does have a benefit (you don't have to invent a tag type), it has a fairly high cost.

Can you elaborate on what you see as the high cost?  I'm just trying to understand your perspective.  As noted in the comments, nothing here precludes making use of `using` aliases rather than CRTP, though you lose some type safety.  I find CRTP much more convenient.

> Also, public derivation is used (not strictly necessary for introducing friend functions but necessary for everything else) even though this does not model an is-a relationship.

I agree this is one area where the model isn't great.  One can't state that the mixins should always be inherited privately because assignment, for example, requires the operator to be a member of the class and not just a friend.

> The idea for using CRTP for this has been here for over two decades (e.g. Boost.Operators is one of the oldest Boost libraries) and yet, for the most part, hasn't caught on.

Boost.Operators is overkill for this kind of thing and I suspect the same is true for other use-cases.  With Boost.Operators you still have to define what the base operators do.  For `SemanticTypedef` we know we want to operators to forward to the operators for the underlying type, so the client has no need to provide definitions of the operators.

> It is rare to have a value type that does not have assignment or equality comparisons (and hashing, as that goes along with equality comparisons).  The default should minimally provide this behavior.

I disagree.  Boolean flags, for example, often don't need any of that.

Can you sketch out what you'd like to see in a strong typedef facility?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66148/new/

https://reviews.llvm.org/D66148





More information about the llvm-commits mailing list