This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Extend EnumeratedArray
ClosedPublic

Authored by jsilvanus on Oct 10 2022, 8:46 AM.

Details

Summary

EnumeratedArray is essentially a wrapper around a fixed-size
array that uses enum values instead of integers as indices.

  • Add iterator support (begin/end/rbegin/rend), which enables the use of iterator/range based algorithms on EnumeratedArrays.
  • Add common container typedefs (value_type etc.), allowing drop-in replacements of other containers in cases relying on these.
  • Add a constructor that takes an std::initializer_list<T>.
  • Make the size() function const.
  • Add empty().

Iterator support slightly lowers the protection from non-type-safe accesses,
because iterator arithmetic is not enum-based, and one can now use
*(begin() + IntIndex). However, it is and was also always possible to
just cast arbitrary indices to the enum type.

Diff Detail

Event Timeline

jsilvanus created this revision.Oct 10 2022, 8:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 10 2022, 8:46 AM
jsilvanus requested review of this revision.Oct 10 2022, 8:46 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 10 2022, 8:46 AM
jsilvanus updated this revision to Diff 466518.Oct 10 2022, 8:49 AM

Fix line order.

jsilvanus updated this revision to Diff 466529.Oct 10 2022, 9:13 AM

Add unit tests.

jsilvanus edited the summary of this revision. (Show Details)

Generally looks OK - few stylistic-y nits.

llvm/include/llvm/ADT/EnumeratedArray.h
46

might also want a deduction guide for this?

53

No need to use the inline keyword for member functions defined in the class body. (it doesn't change the linkagee, though it does hint the compiler towards inlining more - which, without perf investigation, is probably not what we want to do by default)

54

don't need the const here - we don't usually use top level const (& the auto will deduce non-const anyway)

llvm/unittests/ADT/EnumeratedArrayTest.cpp
53

generally prefer value initialization (with =) rather than direct initialization, then it can't get confused with other ctors - easier to read (as a reader I know it's calling an implicit ctor, which is more likely to be the "simple" thing)

67

Don't need the {} here, I think?
(& again, we usually don't bother with top-level const on local variables in LLVM code)

jsilvanus updated this revision to Diff 468141.Oct 17 2022, 2:40 AM

Implement review feedback.

jsilvanus marked 4 inline comments as done.Oct 17 2022, 2:44 AM

Thanks for the review! I've implemented all your suggestions, except for the deduction guide, cf. the inline comment.

llvm/include/llvm/ADT/EnumeratedArray.h
46

You mean a deduction guide for EnumeratedArray? How would we identify the enum type?

53

Ok, done.
I was trying to stick to the existing style, but I'm fine with cleaning this up.

54

Ok, done.

llvm/unittests/ADT/EnumeratedArrayTest.cpp
53

Ok, done!

67

We need a const object or reference to test that size() and empty() can be called on consts. This was not the case before this patch.
With a const object, clang requires the explicit {} initializer, because EnumeratedArray has no user-provided default constructor.

To avoid all this, I removed the const and the {}, and instead use a const reference for the tests.

dblaikie added inline comments.Oct 17 2022, 5:23 PM
llvm/include/llvm/ADT/EnumeratedArray.h
46

Ah, yeah, fair point - can't deduce all the template parameters just from the list of values.

53

ah, right, sorry, had missed that - if you like you could fix the style up in a separate patch (don't need to send a change like that for review - can commit it directly/post-commit review) before this one to simplify the diff here.

llvm/unittests/ADT/EnumeratedArrayTest.cpp
67

Ah, thanks for explaining - I'm OK either way, just missed/didn't understand. Maybe this change is good though, with the ConstArray name making it clear/more self-documenting about why it exists.

90–102

I wonder if maybe you can use gmock ElementsAre https://github.com/google/googletest/blob/main/docs/reference/matchers.md to simplify these? (I guess the reverse ones are a bit harder unless you use llvm::reverse, which might be more complexity/broader surface area than is desirable - guess you could make_range of rbegin+rend manually, which would probably be OK?)

109–124

Since these are static_asserts, they don't benefit from being in a test function (the test function will do nothing) - maybe pull them out/leave them at the top level?

jsilvanus updated this revision to Diff 468505.Oct 18 2022, 5:57 AM
jsilvanus marked 4 inline comments as done.

Implement review feedback:

  • use gmock's ElementsAre to simplify tests
  • move static_asserts out of non-needed test function
dblaikie accepted this revision.Oct 18 2022, 7:58 AM

Looks good, thanks!

This revision is now accepted and ready to land.Oct 18 2022, 7:58 AM
This revision was automatically updated to reflect the committed changes.