@@ -74,6 +74,14 @@ concept LegalDataConversion =
7474 std::is_convertible_v<std::remove_reference_t <From> (*)[],
7575 std::remove_reference_t <To> (*)[]>;
7676
77+ // Akin to `std::constructible_from<span, T>`, but meant to be used in a
78+ // type-deducing context where we don't know what args would be deduced;
79+ // `std::constructible_from` can't be directly used in such a case since the
80+ // type parameters must be fully-specified (e.g. `span<int>`), requiring us to
81+ // have that knowledge already.
82+ template <typename T>
83+ concept SpanConstructibleFrom = requires (const T& t) { span (t); };
84+
7785template <typename T, typename It>
7886concept CompatibleIter = std::contiguous_iterator<It> &&
7987 LegalDataConversion<std::iter_reference_t <It>, T>;
@@ -1488,42 +1496,20 @@ auto as_writable_chars(span<T, X, InternalPtrType> s) noexcept {
14881496 span<char , N>(reinterpret_cast <char *>(s.data ()), s.size_bytes ()));
14891497}
14901498
1491- // Type-deducing helper for constructing a span.
1492- //
1493- // # Safety
1494- // The contiguous iterator `it` must point to the first element of at least
1495- // `size` many elements or Undefined Behaviour may result as the span may give
1496- // access beyond the bounds of the collection pointed to by `it`.
1497- template <int &... ExplicitArgumentBarrier, typename It>
1498- UNSAFE_BUFFER_USAGE constexpr auto make_span (
1499- It it,
1500- StrictNumeric<size_t > size) noexcept {
1501- using T = std::remove_reference_t <std::iter_reference_t <It>>;
1502- // SAFETY: The caller guarantees that `it` is the first of at least `size`
1503- // many elements.
1504- return UNSAFE_BUFFERS (span<T>(it, size));
1505- }
1506-
15071499// Type-deducing helper for constructing a span.
15081500// Deprecated: Use CTAD (i.e. use `span()` directly without template arguments).
15091501// TODO(crbug.com/341907909): Remove.
15101502//
1511- // # Checks
1512- // The function CHECKs that `it <= end` and will terminate otherwise.
1513- //
1514- // # Safety
1515- // The contiguous iterator `it` and its end sentinel `end` must be for the same
1516- // allocation or Undefined Behaviour may result as the span may give access
1517- // beyond the bounds of the collection pointed to by `it`.
1518- template <int &... ExplicitArgumentBarrier,
1519- typename It,
1520- typename End,
1521- typename = std::enable_if_t <!std::is_convertible_v<End, size_t >>>
1522- UNSAFE_BUFFER_USAGE constexpr auto make_span (It it, End end) noexcept {
1523- using T = std::remove_reference_t <std::iter_reference_t <It>>;
1524- // SAFETY: The caller guarantees that `it` and `end` are iterators of the
1525- // same allocation.
1526- return UNSAFE_BUFFERS (span<T>(it, end));
1503+ // SAFETY: `it` must point to the first of a (possibly-empty) series of
1504+ // contiguous valid elements. If `end_or_size` is a size, the series must
1505+ // contain at least that many valid elements; if it is an iterator or sentinel,
1506+ // it must refer to the same allocation, and all elements in the range [it,
1507+ // end_or_size) must be valid. Otherwise, the span will allow access to invalid
1508+ // elements, resulting in UB.
1509+ template <int &... ExplicitArgumentBarrier, typename It, typename EndOrSize>
1510+ requires (std::contiguous_iterator<It>)
1511+ UNSAFE_BUFFER_USAGE constexpr auto make_span(It it, EndOrSize end_or_size) {
1512+ return UNSAFE_BUFFERS (span (it, end_or_size));
15271513}
15281514
15291515// make_span utility function that deduces both the span's value_type and extent
@@ -1533,6 +1519,7 @@ UNSAFE_BUFFER_USAGE constexpr auto make_span(It it, End end) noexcept {
15331519// Deprecated: Use CTAD (i.e. use `span()` directly without template arguments).
15341520// TODO(crbug.com/341907909): Remove.
15351521template <int &... ExplicitArgumentBarrier, typename Container>
1522+ requires (internal::SpanConstructibleFrom<Container>)
15361523constexpr auto make_span(Container&& container) noexcept {
15371524 return span (std::forward<Container>(container));
15381525}
@@ -1664,9 +1651,9 @@ constexpr span<const uint8_t, N> byte_span_with_nul_from_cstring(
16641651// or vector-like objects holding other scalar types, prior to passing them
16651652// into an API that requires byte spans.
16661653template <int &... ExplicitArgumentBarrier, typename Spannable>
1667- requires requires ( const Spannable& arg) { make_span (arg); }
1654+ requires (internal::SpanConstructibleFrom< Spannable>)
16681655constexpr auto as_byte_span(const Spannable& arg) {
1669- return as_bytes (make_span (arg));
1656+ return as_bytes (span (arg));
16701657}
16711658
16721659template <int &... ExplicitArgumentBarrier, typename T, size_t N>
@@ -1681,26 +1668,20 @@ constexpr span<const uint8_t, N * sizeof(T)> as_byte_span(
16811668// or vector-like objects holding other scalar types, prior to passing them
16821669// into an API that requires mutable byte spans.
16831670template <int &... ExplicitArgumentBarrier, typename Spannable>
1684- requires requires (Spannable&& arg) {
1685- make_span (arg);
1686- requires !std::is_const_v<typename decltype (make_span (arg))::element_type>;
1687- }
1671+ requires (internal::SpanConstructibleFrom<Spannable> &&
1672+ !std::is_const_v<typename decltype (span(
1673+ std::declval<Spannable>()))::element_type>)
16881674constexpr auto as_writable_byte_span(Spannable&& arg) {
1689- return as_writable_bytes (make_span (std::forward<Spannable>(arg)));
1675+ return as_writable_bytes (span (std::forward<Spannable>(arg)));
16901676}
16911677
16921678// This overload for arrays preserves the compile-time size N of the array in
16931679// the span type signature span<uint8_t, N>.
16941680template <int &... ExplicitArgumentBarrier, typename T, size_t N>
1681+ requires (!std::is_const_v<T>)
16951682constexpr span<uint8_t, N * sizeof(T)> as_writable_byte_span(
16961683 T (&arr LIFETIME_BOUND)[N]) {
1697- return as_writable_bytes (make_span (arr));
1698- }
1699-
1700- template <int &... ExplicitArgumentBarrier, typename T, size_t N>
1701- constexpr span<uint8_t , N * sizeof (T)> as_writable_byte_span(
1702- T (&&arr LIFETIME_BOUND)[N]) {
1703- return as_writable_bytes (make_span (arr));
1684+ return as_writable_bytes (span (arr));
17041685}
17051686
17061687namespace internal {
0 commit comments