Page MenuHomePhabricator

[libcxx][views] Add drop_view.
ClosedPublic

Authored by zoecarver on May 6 2021, 5:41 PM.

Details

Reviewers
cjdb
ldionne
EricWF
Quuxplusone
Group Reviewers
Restricted Project
Commits
rG560170fa2de5: [libcxx][views] Add drop_view.
Summary

The first view in the libc++ ranges library 🚀

Diff Detail

Unit TestsFailed

TimeTest
970 mslibcxx CI GCC Current/C++20 > libc++.std/ranges/range_adaptors/range_drop::base.pass.cpp
Script: -- : 'COMPILED WITH'; /usr/bin/g++-11 /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/std/ranges/range.adaptors/range.drop/base.pass.cpp -v -include /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support/nasty_macros.h -nostdinc++ -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1 -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/include/c++build -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support -std=c++2b -Werror -Wall -Wextra -Wshadow -Wundef -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type -Wno-aligned-allocation-unavailable -Wno-atomic-alignment -Wno-sized-deallocation -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -D_LIBCPP_DISABLE_AVAILABILITY -Wno-macro-redefined -D_LIBCPP_HAS_THREAD_API_PTHREAD -Wno-macro-redefined -D_LIBCPP_ABI_VERSION=1 -lc++experimental -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -nodefaultlibs -lc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc -latomic -o /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/test/std/ranges/range.adaptors/range.drop/Output/base.pass.cpp.dir/t.tmp.exe
1,230 mslibcxx CI GCC Current/C++20 > libc++.std/ranges/range_adaptors/range_drop::begin.pass.cpp
Script: -- : 'COMPILED WITH'; /usr/bin/g++-11 /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp -v -include /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support/nasty_macros.h -nostdinc++ -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1 -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/include/c++build -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support -std=c++2b -Werror -Wall -Wextra -Wshadow -Wundef -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type -Wno-aligned-allocation-unavailable -Wno-atomic-alignment -Wno-sized-deallocation -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -D_LIBCPP_DISABLE_AVAILABILITY -Wno-macro-redefined -D_LIBCPP_HAS_THREAD_API_PTHREAD -Wno-macro-redefined -D_LIBCPP_ABI_VERSION=1 -lc++experimental -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -nodefaultlibs -lc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc -latomic -o /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/test/std/ranges/range.adaptors/range.drop/Output/begin.pass.cpp.dir/t.tmp.exe
1,060 mslibcxx CI GCC Current/C++20 > libc++.std/ranges/range_adaptors/range_drop::ctad.compile.pass.cpp
Script: -- : 'COMPILED WITH'; /usr/bin/g++-11 /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/std/ranges/range.adaptors/range.drop/ctad.compile.pass.cpp -v -include /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support/nasty_macros.h -nostdinc++ -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1 -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/include/c++build -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support -std=c++2b -Werror -Wall -Wextra -Wshadow -Wundef -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type -Wno-aligned-allocation-unavailable -Wno-atomic-alignment -Wno-sized-deallocation -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -D_LIBCPP_DISABLE_AVAILABILITY -Wno-macro-redefined -D_LIBCPP_HAS_THREAD_API_PTHREAD -Wno-macro-redefined -D_LIBCPP_ABI_VERSION=1 -fsyntax-only
980 mslibcxx CI GCC Current/C++20 > libc++.std/ranges/range_adaptors/range_drop::end.pass.cpp
Script: -- : 'COMPILED WITH'; /usr/bin/g++-11 /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/std/ranges/range.adaptors/range.drop/end.pass.cpp -v -include /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support/nasty_macros.h -nostdinc++ -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1 -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/include/c++build -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support -std=c++2b -Werror -Wall -Wextra -Wshadow -Wundef -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type -Wno-aligned-allocation-unavailable -Wno-atomic-alignment -Wno-sized-deallocation -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -D_LIBCPP_DISABLE_AVAILABILITY -Wno-macro-redefined -D_LIBCPP_HAS_THREAD_API_PTHREAD -Wno-macro-redefined -D_LIBCPP_ABI_VERSION=1 -lc++experimental -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -nodefaultlibs -lc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc -latomic -o /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/test/std/ranges/range.adaptors/range.drop/Output/end.pass.cpp.dir/t.tmp.exe
2,510 mslibcxx CI GCC Current/C++20 > libc++.std/ranges/range_adaptors/range_drop::general.pass.cpp
Script: -- : 'COMPILED WITH'; /usr/bin/g++-11 /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/std/ranges/range.adaptors/range.drop/general.pass.cpp -v -include /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support/nasty_macros.h -nostdinc++ -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/include/c++/v1 -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/include/c++build -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -I/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/libcxx/test/support -std=c++2b -Werror -Wall -Wextra -Wshadow -Wundef -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type -Wno-aligned-allocation-unavailable -Wno-atomic-alignment -Wno-sized-deallocation -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -Wno-unused-local-typedef -D_LIBCPP_DISABLE_AVAILABILITY -Wno-macro-redefined -D_LIBCPP_HAS_THREAD_API_PTHREAD -Wno-macro-redefined -D_LIBCPP_ABI_VERSION=1 -lc++experimental -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -L/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -Wl,-rpath,/home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/./lib -nodefaultlibs -lc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc -latomic -o /home/libcxx-builder/.buildkite-agent/builds/c672756769f6-1/llvm-project/libcxx-ci/build/generic-gcc/projects/libcxx/test/std/ranges/range.adaptors/range.drop/Output/general.pass.cpp.dir/t.tmp.exe
View Full Test Results (6 Failed)

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
zoecarver marked 4 inline comments as done.May 7 2021, 4:11 PM

Apply some of the comments.

I still need to:
-> Add a test for move-only input-iterator.
-> Expand the const tests.
-> Add tests for all_t CTAD.

tcanens added inline comments.May 8 2021, 5:01 AM
libcxx/include/__ranges/drop_view.h
57

I'd put __count before __base - see https://lists.isocpp.org/lib/2020/09/17540.php.

cjdb added inline comments.May 8 2021, 12:10 PM
libcxx/include/__ranges/drop_view.h
42

__cache_base is a bit too general a name.

45

@tcanens is this a non-propagating cache?

tcanens added inline comments.May 8 2021, 12:32 PM
libcxx/include/__ranges/drop_view.h
45

Yep. This is the original use case of non-propagating-cache in range-v3.

zoecarver added inline comments.May 10 2021, 9:10 AM
libcxx/include/__ranges/drop_view.h
45

Where in the standard does it say this is a non-propagating cache? Or is that what your paper does?

62

Unfortunately, I just realized that all iterators model input or output iterator, so I think we'll have to stick with forward_range.

cjdb added inline comments.
libcxx/include/__ranges/drop_view.h
45

The standard is very underspecified in what kind of cache is necessary here. I just checked, and range-v3 and cmcstl2 disagree on what kind of cache is necessary: range-v3 uses a non-propagating cache; cmcstl2 switches between a non-propagating cache and a simple cache, depending on whether or not we have a forwarding-range (which I think is now borrowed_range).
I'm inclined to support Tim's opinion here, because it's simpler, and doesn't need to introduce a __cached_position type that's dependent on __non_propagating_cache. Any opinions @CaseyCarter?

tcanens added inline comments.May 10 2021, 9:46 AM
libcxx/include/__ranges/drop_view.h
45

Where in the standard does it say this is a non-propagating cache? Or is that what your paper does?

It falls out of the fact that nothing in the standard allows "take a drop_view, call begin() on it, copy it, and call begin() on the copy" to not work.

zoecarver updated this revision to Diff 344559.May 11 2021, 2:05 PM

Add tests for views::all ctad.

zoecarver planned changes to this revision.May 20 2021, 12:07 PM

I need to update this to use semiregular box.

cjdb requested changes to this revision.Jun 10 2021, 8:59 AM

Please update according to the recent changes made by P2325.

ldionne requested changes to this revision.Jun 21 2021, 9:36 AM
  • Some of my comments (especially about splitting tests) also apply to other in-flight reviews like transform_view.
  • Please don't forget to mark comments as done when they're not relevant anymore (whether they have been implemented or you've decided you wouldn't do it), so it's easy to keep track of things.

I'll wait for this to be rebased onto non_propagating_cache before I re-review the implementation.

libcxx/test/std/ranges/range.adaptors/range.drop/range.drop.view.pass.cpp
1 ↗(On Diff #344559)

Please split this into more files as it makes sense. Each file tests one thing, and what's being tested is at the top of level in a comment, as we always do.

23 ↗(On Diff #343544)

I'll actually disagree here - I think it's good to stay minimal when we don't lose anything doing so.

There was quite a bit of discussion offline about the need to invalidate the cached begin() or not. I think we now all agree that we must not propagate the cached value on copies or moves. Here's what I ended up with that is not dependent on non_propagating_cache (we can go back afterwards and perhaps simplify some of this if we have non_propagating_cache):

namespace ranges {
  template<class _Range>
  concept __simple_view =
    view<_Range> && range<const _Range> &&
    same_as<sentinel_t<_Range>, iterator_t<const _Range>> &&
    same_as<iterator_t<_Range>, sentinel_t<const _Range>>;

  template<view _View>
  class drop_view
    : public view_interface<drop_view<_View>>,
  {
    static constexpr _UseCache = forward_range<_View> && !random_access_range<_View>;
    using _Cache = optional<iterator_t<_View>>;
    struct _Empty { };
    [[no_unique_address]] conditional_t<_UseCache, _Cache, _Empty> __cached_begin_;

    _View __base_;
    range_difference_t<_View> __count_;

public:
    constexpr drop_view() requires default_­initializable<_View> 
      : __cached_begin_(), __base_(), __count_(0) 
    { }

    constexpr drop_view(_View __base, range_difference_t<_View> __count)
      : __cached_begin_(), __base_(_VSTD::move(__base)), __count_(__count) {
      _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
    }

    constexpr drop_view(drop_view const& __other) 
      : __cached_begin_() // purposefully not propagating the cached value
      , __base_(__other.__base_)
      , __count_(__other.__count_)
    { }

    constexpr drop_view(drop_view&& __other) 
      : __cached_begin_() // purposefully not propagating the cached value
      , __base_(_VSTD::move(__other.__base_))
      , __count_(_VSTD::move(other.__count_))
    { }

    constexpr drop_view& operator=(drop_view const& __other) {
      if constexpr (_UseCache) {
        __cached_begin_.reset();
      }
      __base_ = __other.__base_;
      __count_ = __other.__count_;
      return *this;
    }

    constexpr drop_view& operator=(drop_view&& __other) {
      if constexpr (_UseCache) {
        __cached_begin_.reset();
        __other.__cached_begin_.reset();
      }
      __base_ = _VSTD::move(__other.__base_);
      __count_ = _VSTD::move(__other.__count_);
      return *this;
    }

    constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
    constexpr _View base() && { return _VSTD::move(__base_); }

    constexpr auto begin()
      requires (!(__simple_view<_View> && random_access_range<const _View> && sized_range<const _View>))
    {
      if constexpr (_UseCache) {
        if (__cached_begin_.empty())
          __cached_begin_ = ranges​::​next(ranges​::​begin(__base_­), __count_­, ranges​::​end(__base_­));
        return *__cached_begin_;

      } else {
        return ranges​::​next(ranges​::​begin(__base_­), __count_­, ranges​::​end(__base_­));
      }
    }

    constexpr auto begin() const
      requires random_access_range<const _View> && sized_range<const _View>
    {
      return ranges​::​next(ranges​::​begin(__base_­), __count_­, ranges​::​end(__base_­));
    }

    constexpr auto end()
      requires (!__simple_view<_View>)
    { return ranges::end(__base_); }

    constexpr auto end() const
      requires range<const _View>
    { return ranges::end(__base_); }

    static constexpr auto __size(auto& __self) {
      const auto __s = ranges::size(__self.__base_);
      const auto __c = static_cast<decltype(__s)>(__self.__count_);
      return __s < __c ? 0 : __s - __c;
    }

    constexpr auto size()
      requires sized_range<_View>
    { return drop_view::__size(*this); }

    constexpr auto size() const
      requires sized_range<const _View>
    { return drop_view::__size(*this); }
  };

  template<class _Range>
  drop_view(_Range&&, range_difference_t<_Range>)
    -> drop_view<views::all_t<_Range>>;
} // namespace ranges
zoecarver updated this revision to Diff 353505.Jun 21 2021, 3:43 PM
  • Split up tests.
  • Use std::optional as a non-propagating cache (and add a test).
zoecarver marked 13 inline comments as done.Jun 21 2021, 3:50 PM
zoecarver added inline comments.
libcxx/include/__ranges/drop_view.h
36

This was already done.

42

I'm going to leave it at the top. I don't really see a reason to put it at the bottom, especially when classes have private members by default.

45

For posterity: marking this whole chain as resolved after our discussion on discord.

libcxx/test/std/ranges/range.adaptors/range.drop/range.drop.view.pass.cpp
20 ↗(On Diff #344559)

Remove this.

zoecarver marked 3 inline comments as done.Jun 21 2021, 3:53 PM
zoecarver updated this revision to Diff 353506.Jun 21 2021, 3:54 PM

Apply a few remaining review comments.

Quuxplusone added inline comments.Jun 21 2021, 4:28 PM
libcxx/include/__ranges/drop_view.h
42

I'm going to leave it at the top

Please do as @ldionne says, and follow libc++ style. Private/data members go at the bottom (and data members get a suffix-underscore; thanks for addressing that part already).
Also, please consider putting __cached_begin_ in front of __count_, for layout reasons. It's more likely that _View begins with an _Empty member than that _View::difference_type does.

@ldionne wrote:

Here's what I ended up with that is not dependent on non_propagating_cache (we can go back afterwards and perhaps simplify some of this if we have non_propagating_cache)

FYI, that looks pretty nice to me. And then non_propagating_cache would just be a thin wrapper around an optional — all it needs to provide is .has_value(), .get() (maybe more than one ref-qualification of .get()?), .assign (i.e. the-equivalent-of-operator=, not the-equivalent-of-.emplace), and a default constructor. One might reasonably say "If Louis' code works, then why do we even want a factored-out non_propagating_cache type?" But, I answer, it's still useful to wrap optional, in order to reduce its surface area to just these four necessary bits.

cjdb accepted this revision.Jun 21 2021, 5:01 PM

Per offline discussion, I'm okay with this going ahead, provided we return to add __non_propagating_cache once I've landed it.

libcxx/include/__ranges/drop_view.h
133

Please line up requires-clauses with the start of the function declaration. Small clause (such as this) can go on the same line.

I've usually turned a blind eye to this because comments about formatting are noise that lead to unproductive debates, and my intention has been to get clang-format to take care of this inconsistency in one fell swoop. Having said that, since I don't know when I'll be able to apply the tool project-wide and not get something weird, it's probably worth adopting the "official" libc++ style for future contributors' sakes.

141–144

Does this need to be fixed?

libcxx/test/std/ranges/range.adaptors/range.drop/general.pass.cpp
61

I like that you're using this!

tcanens added inline comments.Jun 21 2021, 5:13 PM
libcxx/include/__ranges/drop_view.h
37

The cache needs to be used for random access ranges too unless the range is also sized.

Quuxplusone added inline comments.Jun 21 2021, 6:03 PM
libcxx/include/__ranges/drop_view.h
133

FWIW, I agree about "unproductive debates" ;) but if there's an official libc++ style, it's always been "indent the subordinate clause by one level."

template<class T>
  requires foo<T>
auto bar()
  -> decltype(baz)
{
  return quux;
}

I don't think your insistence on following clang-format's (broken) formatting guidance here is helpful to the project. I predict that clang-format will eventually implement C++20 formatting, and then it'll be good that Zoe's been following the "indent requires-clauses" style.

cjdb added inline comments.Jun 21 2021, 6:42 PM
libcxx/include/__ranges/drop_view.h
133
ldionne requested changes to this revision.Jun 22 2021, 8:56 AM

I would like to see tests for the constructors. They're going to be simple tests, but we should be testing everything systematically. Elsewhere we have xxxx.ctor.pass.cpp tests. Also, can you please explicitly mark where you're testing each overload of begin() and end()?

I've got a few comments, but they are pretty small. We should be able to land this today.

libcxx/include/__ranges/drop_view.h
49

noexcept(is_nothrow_default_constructible_v<_View>)?

Also, this should be tested.

66

I think __cached_begin_(nullopt) might be clearer - it's a nice reminder that we're not default-constructing the iterator itself, but only an optional. (here and elsewhere)

133

I had not realized that the WP was indenting requires-clauses, but I think it might make sense to try to follow that. @cjdb is there a reason why you went for no indentation in the first place?

What I care most about is that we're consistent and that our code is readable and idiomatic as much as possible. Is there an established way of formatting those in the community?

libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp
13

Those should describe what's being tested in the test. We've always done that in libc++, and frankly it's quite useful to know exactly what's being tested (especially since we love to have subtly different overloads of functions in the stdlib).

This revision now requires changes to proceed.Jun 22 2021, 8:56 AM
zoecarver added inline comments.Jun 22 2021, 9:14 AM
libcxx/include/__ranges/drop_view.h
37

Why does the range being sized matter? Doesn't a random access range provide amortized constant-time complexity for element lookup (which is the requirement for drop_view)?

42

I reordered these based on Tim's suggestion:

I'd put count before base - see https://lists.isocpp.org/lib/2020/09/17540.php.

But you're right, I think cached_begin should still come first (then count, then base).

42

Private/data members go at the bottom (and data members get a suffix-underscore; thanks for addressing that part already).

Where does it say that private data members go at the bottom? If it's not documented anywhere, I'll go off of what style we currently use. Doing a quick audit of the first three types that come to mind, I see that basic_string, shared_ptr (and all of its helper classes), and map all put their data members at the top. After I continued to look, the only class I could find that didn't do this is vector, but even its base/helper classes put their private members at the top.

I find these comments about formatting (here and elsewhere) counter productive. I try not to comment on formatting unless it's really egregious. Until we create some formatting rules (which I think would be a great idea, because then contributors would know how to format their code, and you wouldn't have to waste time in reviews asking for changes), let's not comment about formatting unless it makes the code harder to understand.

141–144

At some point, yes. But we don't have all_t yet and this is not functionally different than what it will be.

tcanens added inline comments.Jun 22 2021, 10:18 AM
libcxx/include/__ranges/drop_view.h
37

You need the size of the underlying view to figure out how much to drop in constant time.

If you don't know that, then you have to advance the iterator one step at a time until you either reach the end of the range or N steps, and that's linear.

cjdb added inline comments.Jun 22 2021, 10:24 AM
libcxx/include/__ranges/drop_view.h
49

Why are we not just = defaulting this constructor?

133

is there a reason why you went for no indentation in the first place?

It's the style I adopted back in 2016 when working on cmcstl2; libc++ didn't have any established precedent for requires-clauses, so I paved a way forward. I also find it kind of arbitrary to indent it? We don't indent in the middle of a code block unless we open some sort of grouping tokens (usually parens or braces).
It also swallows up valuable horizontal width, which can impact readability.

Is there an established way of formatting those in the community?

  • cmcstl2 and cjdb-ranges line it up
  • Microsoft/STL and libstdc++ indent

All four use same-line requires-clauses for short requirements, which I think we should adopt in libc++.

I had not realized that the WP was indenting requires-clauses, but I think it might make sense to try to follow that.

Sure, if you want to rescind your offer from D99691, I'll play ball. I would like to know why you think it makes sense to follow the standard wording, but we can follow up with that offline.

zoecarver marked 3 inline comments as done.

Update based on review.

libcxx/include/__ranges/drop_view.h
37

Aha, that makes sense. Thanks for explaining! :)

libcxx/test/std/ranges/range.adaptors/range.drop/begin.pass.cpp
13

Good point. Fixing.

ldionne accepted this revision.Jun 22 2021, 12:02 PM

LGTM pending CI and applying the comments you noted when we spoke just now.

This is awesome! Let's move to transform_view now!

libcxx/include/__ranges/drop_view.h
42

@zoecarver is right that we sometimes have private data members at the top, and sometimes at the bottom. I think either way's fine.

Regarding formatting comments, I think what's hurting is not that we have them during reviews, but that not everybody agrees on how to format things. That creates back-and-forth and arguing over those details, and that is what's harmful. Taking 2 seconds to reformat something that isn't formatted properly isn't the issue IMO.

This revision is now accepted and ready to land.Jun 22 2021, 12:02 PM

Update based on the last few review comments.

When the CI is green I'll land it.

tcanens added inline comments.Jun 22 2021, 1:27 PM
libcxx/include/__ranges/drop_view.h
107

For the random-access-and-sized case, begin should not call ranges::next - that can be linear for sized-but-not-sized-sentinel ranges. It should just return ranges::begin(__base_) + std::min(__count_, ranges::distance(__base_)). Ditto below.

zoecarver updated this revision to Diff 353809.Jun 22 2021, 3:41 PM

Remove shadowing for GCC.

zoecarver updated this revision to Diff 353996.Jun 23 2021, 8:47 AM

Fix memset warning for GCC.

zoecarver added inline comments.Jun 23 2021, 8:51 AM
libcxx/include/__ranges/drop_view.h
107

I think it's OK to use next because we can ensure that next will always use something equivalent to ranges::begin(__base_) + std::min(__count_, ranges::distance(__base_)) (even if it's technically permitted to do something slower by the standard). I'd rather not add a special case here.

tcanens added inline comments.Jun 23 2021, 8:59 AM
libcxx/include/__ranges/drop_view.h
107

I think it's OK to use next because we can ensure that next will always use something equivalent to ranges::begin(__base_) + std::min(__count_, ranges::distance(__base_)) (even if it's technically permitted to do something slower by the standard).

The point is that you can't. For a sized-but-not-sized-sentinel range, the size information is only known from the range itself. Once you decompose the range into an iterator and a sentinel for ranges::next, that information is gone.

This revision was landed with ongoing or failed builds.Jun 23 2021, 10:11 AM
This revision was automatically updated to reflect the committed changes.
zoecarver added inline comments.Jun 23 2021, 10:16 AM
libcxx/include/__ranges/drop_view.h
107

I see what you're getting at. So we'd need to change the condition to be sized_sentinel_for (not sized_range) so that it matches what ranges::advance does (or, better yet, do what you suggested and take advantage of the sized range inside of this function).