ldionne added inline comments.
================ Comment at: include/span:217 + using pointer = _Tp *; + using const_pointer = const _Tp *; // not in standard + using reference = _Tp &; ---------------- mclow.lists wrote: > ldionne wrote: > > Why are we providing them if they are not in the standard? > Because (a) they're useful (see the definition of `const_iterator` below, and > (b) I (and STL, who wrote the final version of the `span` paper, believe that > not having them was just an oversight. > I sent you a LWG issue email. ================ Comment at: include/span:254 + constexpr span(const _Container& __c, + const enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) + : __data{_VSTD::data(__c)} ---------------- mclow.lists wrote: > ldionne wrote: > > For both of these `Container` constructors, the paper expresses the SFINAE > > conditions based on `Container`, not on `Container` in one case and > > `Container const` in the other, which is what you're doing. > > > > This is actually a bug in the paper, because this will make code like this > > compile: > > > > ``` > > std::vector<int> const v; > > std::span<int, 10> s(v); > > ``` > > > > Instead, this should be a compiler error because we're clearly not > > const-correct here, initializing a `span`-over-non-const from a const > > `vector`. Example: https://wandbox.org/permlink/kYCui3o0LEGRQ67x > > > > This happens because we're discarding the constness of the `_Container` > > template parameter if we stick 100% to the wording of the paper. Should > > this be a DR? > Yes, this should be an LWG issue. Ugh, actually, I am wrong! The paper is fine and you implemented the paper correctly. The paper says ``` Remarks: These constructors shall not participate in overload resolution unless: — `Container` is not a specialization of span, — `Container` is not a specialization of array, — `is_array_v<Container>` is `false`, — `data(cont)` and `size(cont)` are both well-formed, and — `remove_pointer_t<decltype(data(cont))>(*)[]` is convertible to `ElementType(*)[]`. ``` since `cont` has the right constness, the paper properly describes what should happen. My mistake. ================ Comment at: include/span:275 + +// ~span() noexcept = default; + ---------------- mclow.lists wrote: > ldionne wrote: > > Why is this commented out? > This is commented out because of a clang bug > https://bugs.llvm.org/show_bug.cgi?id=38143, where copy constructor will > become non-constexpr. Once this fixed, we can un-comment this line (though > it should make no difference if it is present or not). > What! Thanks. ================ Comment at: include/span:351 + { + pointer __p = __data; + __data = __other.__data; ---------------- mclow.lists wrote: > ldionne wrote: > > Just curious -- why not use `_VSTD::swap(__data, __other.__data)`? This > > would avoid any potential for a stupid logic error to sneak up. > Not to have to include `<utility>`? (It may get included anyway) `<array>` already includes `<utility>`. Your choice, I don't mind. ================ Comment at: include/span:356-359 + _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept + { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } + + _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writeable_bytes() const noexcept ---------------- mclow.lists wrote: > ldionne wrote: > > It looks like neither `as_bytes` nor `as_writeable_bytes` is marked `const` > > in the paper. Why are we deviating? > In N4762, they're marked as non-member functions that take `span<whatever>` > by value. This implementation just turns around and calls a member function > (with an unpronounceable name) to do the work. The standard never mentions > `__as_bytes` or `__as_writeable_bytes`. > > > > > I completely missed the leading underscores on those methods, along with the non-member functions. Thanks, this is not an issue. ================ Comment at: include/span:531 + operator==(const span<_Tp1, _Extent1>& __lhs, const span<_Tp2, _Extent2>& __rhs) + { return equal(__lhs.begin(), __lhs.end(), __rhs.begin(), __rhs.end()); } + ---------------- mclow.lists wrote: > ldionne wrote: > > It's kind of crazy those are not constrained in any way, but that's what > > the paper says. I would expect some constraint based on whether we can > > compare `_Tp1` and _Tp2`. > In my prototype implementation, they were constrained. But LEWG decided not > to go there (which is the same approach taken in https://wg21.link/P0805 ). > There needs to be another paper written about constraining container > comparisons. > > It also applies to homogenous comparisons. Consider `vector<complex<double>>` > Two of them can't be compared (less than, etc), because `complex<double>` > doesn't have a `operator<` Thanks for the information. https://reviews.llvm.org/D49338 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits