[libcxx-commits] [PATCH] D106205: [libcxx][ranges] Add `counted_iterator`.

Zoe Carver via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 27 10:47:10 PDT 2021


zoecarver marked 6 inline comments as done.
zoecarver added inline comments.


================
Comment at: libcxx/include/__iterator/counted_iterator.h:234
+  {
+    _LIBCPP_ASSERT(-__n <= __count_, "Cannot advance iterator back before begin.");
+    __current_ -= __n;
----------------
Quuxplusone wrote:
> This assertion is... confusing. My impression is that `__count_ >= 0` is a class invariant. So `-__n > __count_` would happen only when the user is trying to decrease by a large negative value, e.g. `it -= -42;` when `it.count() < 42`.
> So the assertion is(?) correct; but the message should be more like `"Attempted to advance a counted_iterator beyond the end of its range"`. (Compare the grammar to other `_LIBCPP_ASSERT`s, e.g. in `<list>`.)
Yes, I'll update the message to make it a bit clearer. Good idea. 


================
Comment at: libcxx/include/__iterator/counted_iterator.h:273
+  {
+    _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range.");
+    return ranges::iter_move(__i.__current_);
----------------
Quuxplusone wrote:
> I recommend `"Attempted to iter_move a non-dereferenceable counted_iterator"`
I think what I have now is a bit clearer. If we answer the question, "why is the iterator non-dereferenceable" then we get the message I have here. And I think that's actually a simpler message; it gets the user to their solution more quickly. 


================
Comment at: libcxx/include/__iterator/counted_iterator.h:107
+  _LIBCPP_HIDE_FROM_ABI
+  constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; }
+
----------------
Quuxplusone wrote:
> cjdb wrote:
> > ldionne wrote:
> > > Are you testing the `noexcept`-ness of this method in your tests? If not, you should, especially since it's in the spec.
> > Why did the noexcept specifier removed? It's not a difficult one to get right and is arguably useful.
> `noexcept` specifiers are useful if-and-only-if someone has a use for them. For any function whose noexceptness is never used, marking it `noexcept` is unhelpful — and in fact may be harmful, because (even though I agree //this one// is "easy to get right") as soon as you get even //one// `noexcept` wrong, you end up with a rogue `std::terminate`. It is possible to introduce a bug by adding `noexcept`; it is not possible to introduce a bug by leaving it off. Combine this with the general mantra "The best code is no code," and you end up with my standard advice: Use `noexcept` on move constructors to avoid the vector pessimization, and (in libc++) use it where it's mandated by the paper standard, but otherwise play it safe and keep it simple.
> Why did the noexcept specifier removed? It's not a difficult one to get right and is arguably useful.

The noexcept specifier wasn't removed, this comment just moved. 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D106205



More information about the libcxx-commits mailing list