Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/container/span"

From cppreference.com
< cpp‎ | containerRedirect page
m (Member constant: +C++20)
m (Redirected page to enwiki:Rust (programming language))
Line 1: Line 1:
{{cpp/title|span}}
+
#REDIRECT [[enwiki:Rust_(programming_language)]]
{{cpp/container/span/navbar}}
+
{{dcl begin}}
+
{{dcl header|span}}
+
{{dcl|since=c++20|1=
+
template<
+
    class T,
+
    std::size_t Extent = std::dynamic_extent
+
> class span;
+
}}
+
{{dcl end}}
+
 
+
The class template {{tt|span}} describes an object that can refer to a contiguous sequence of objects with the first element of the sequence at position zero. A {{tt|span}} can either have a ''static'' extent, in which case the number of elements in the sequence is known at compile-time and encoded in the type, or a ''dynamic'' extent.
+
 
+
If a {{tt|span}} has ''dynamic'' extent, a typical implementation holds two members: a pointer to {{tt|T}} and a size.
+
A {{tt|span}} with ''static'' extent may have only one member: a pointer to {{tt|T}}.
+
 
+
{{rrev|since=c++23|
+
Every specialization of {{tt|std::span}} is a {{named req|TriviallyCopyable}} type.
+
}}
+
 
+
===Template parameters===
+
{{par begin}}
+
{{par|T|element type; must be a complete object type that is not an abstract class type}}
+
{{par|Extent|the number of elements in the sequence, or {{tt|std::dynamic_extent}} if dynamic}}
+
{{par end}}
+
 
+
===Member types===
+
{{dsc begin}}
+
{{dsc hitem|Member type|Definition}}
+
{{dsc|{{tt|element_type}}|{{tt|T}}}}
+
{{dsc|{{tt|value_type}}|{{co|std::remove_cv_t<T>}}}}
+
{{dsc|{{tt|size_type}}|{{lc|std::size_t}}}}
+
{{dsc|{{tt|difference_type}}|{{lc|std::ptrdiff_t}}}}
+
{{dsc|{{tt|pointer}}|{{co|T*}}}}
+
{{dsc|{{tt|const_pointer}}|{{co|const T*}}}}
+
{{dsc|{{tt|reference}}|{{co|T&}}}}
+
{{dsc|{{tt|const_reference}}|{{co|const T&}}}}
+
{{dsc|{{tt|iterator}}|implementation-defined {{named req|RandomAccessIterator}}, {{named req|ConstexprIterator}}, and {{lconcept|contiguous_iterator}} whose {{tt|value_type}} is {{tt|value_type}}}}
+
{{dsc|{{tt|reverse_iterator}}|{{co|std::reverse_iterator<iterator>}}}}
+
{{dsc end}}
+
 
+
{{petty|Note: {{tt|iterator}} is a mutable iterator if {{tt|T}} is not const-qualified.}}
+
 
+
All requirements on the iterator types of a {{named req|Container}} apply to the {{tt|iterator}} type of {{tt|span}} as well.
+
 
+
===Member constant===
+
{{ddcl|since=c++20|1=
+
static constexpr std::size_t extent = Extent;
+
}}
+
 
+
===Member functions===
+
{{dsc begin}}
+
{{dsc inc|cpp/container/span/dsc constructor}}
+
{{dsc inc|cpp/container/span/dsc operator{{=}}}}
+
 
+
{{dsc h2|Iterators}}
+
{{dsc inc|cpp/container/dsc begin|span}}
+
{{dsc inc|cpp/container/dsc end|span}}
+
{{dsc inc|cpp/container/dsc rbegin|span}}
+
{{dsc inc|cpp/container/dsc rend|span}}
+
 
+
{{dsc h2|Element access}}
+
{{dsc inc|cpp/container/dsc front|span}}
+
{{dsc inc|cpp/container/dsc back|span}}
+
{{dsc inc|cpp/container/span/dsc operator_at}}
+
{{dsc inc|cpp/container/span/dsc data}}
+
 
+
{{dsc h2|Observers}}
+
{{dsc inc|cpp/container/span/dsc size}}
+
{{dsc inc|cpp/container/span/dsc size_bytes}}
+
{{dsc inc|cpp/container/span/dsc empty}}
+
 
+
{{dsc h2|Subviews}}
+
{{dsc inc|cpp/container/span/dsc first}}
+
{{dsc inc|cpp/container/span/dsc last}}
+
{{dsc inc|cpp/container/span/dsc subspan}}
+
{{dsc end}}
+
 
+
===Non-member functions===
+
{{dsc begin}}
+
{{dsc inc|cpp/container/span/dsc as_bytes}}
+
{{dsc end}}
+
 
+
===Non-member constant===
+
{{dsc begin}}
+
{{dsc inc|cpp/container/span/dsc dynamic_extent}}
+
{{dsc end}}
+
 
+
===Helper templates===
+
{{ddcl|since=c++20|num=1|1=
+
template< class T, std::size_t Extent >
+
inline constexpr bool ranges::enable_borrowed_range<std::span<T, Extent>> = true;
+
}}
+
This specialization of {{lc|ranges::enable_borrowed_range}} makes {{tt|span}} satisfy {{lconcept|borrowed_range}}.
+
 
+
{{ddcl|since=c++20|1=
+
template< class T, std::size_t Extent >
+
inline constexpr bool ranges::enable_view<std::span<T, Extent>> = true;
+
}}
+
This specialization of {{lc|ranges::enable_view}} makes {{tt|span}} satisfy {{lconcept|view}}.
+
 
+
==={{rl|deduction guides|Deduction guides}}{{mark c++20}}===
+
 
+
===Notes===
+
Specializations of {{tt|std::span}} are already trivially copyable types in all existing implementations, even before the formal requirement introduced in C++23.
+
 
+
{{feature test macro|__cpp_lib_span|std=C++20|value=202002L|[[#Top|{{tt|std::span}}]]}}
+
 
+
===Example===
+
{{example
+
|The example uses {{tt|std::span}} to implement some algorithms on contiguous ranges.
+
|code=
+
#include <algorithm>
+
#include <cstddef>
+
#include <iostream>
+
#include <span>
+
 
+
template<class T, std::size_t N>
+
[[nodiscard]]
+
constexpr auto slide(std::span<T,N> s, std::size_t offset, std::size_t width)
+
{
+
    return s.subspan(offset, offset + width <= s.size() ? width : 0U);
+
}
+
 
+
template<class T, std::size_t N, std::size_t M>
+
constexpr bool starts_with(std::span<T,N> data, std::span<T,M> prefix)
+
{
+
    return data.size() >= prefix.size()
+
        && std::equal(prefix.begin(), prefix.end(), data.begin());
+
}
+
 
+
template<class T, std::size_t N, std::size_t M>
+
constexpr bool ends_with(std::span<T,N> data, std::span<T,M> suffix)
+
{
+
    return data.size() >= suffix.size()
+
        && std::equal(data.end() - suffix.size(), data.end(),
+
                      suffix.end() - suffix.size());
+
}
+
 
+
template<class T, std::size_t N, std::size_t M>
+
constexpr bool contains(std::span<T,N> span, std::span<T,M> sub)
+
{
+
    return std::search(span.begin(), span.end(), sub.begin(), sub.end()) != span.end();
+
//  return std::ranges::search(span, sub).begin() != span.end();
+
}
+
 
+
void print(const auto& seq)
+
{
+
    for (const auto& elem : seq)
+
        std::cout << elem << ' ';
+
    std::cout << '\n';
+
}
+
 
+
int main()
+
{
+
    constexpr int a[] {0, 1, 2, 3, 4, 5, 6, 7, 8};
+
    constexpr int b[] {8, 7, 6};
+
 
+
    for (std::size_t offset{}; ; ++offset)
+
    {
+
        static constexpr std::size_t width{6};
+
        auto s = slide(std::span{a}, offset, width);
+
        if (s.empty())
+
            break;
+
        print(s);
+
    }
+
 
+
    static_assert(
+
        starts_with(std::span{a}, std::span{a, 4}) and
+
        starts_with(std::span{a + 1, 4}, std::span{a + 1, 3}) and
+
      ! starts_with(std::span{a}, std::span{b}) and
+
      ! starts_with(std::span{a, 8}, std::span{a + 1, 3}) and
+
        ends_with(std::span{a}, std::span{a + 6, 3}) and
+
      ! ends_with(std::span{a}, std::span{a + 6, 2}) and
+
        contains(std::span{a}, std::span{a + 1, 4}) and
+
      ! contains(std::span{a, 8}, std::span{a, 9})
+
    );
+
}
+
|output=
+
0 1 2 3 4 5
+
1 2 3 4 5 6
+
2 3 4 5 6 7
+
3 4 5 6 7 8
+
}}
+
 
+
===Defect reports===
+
{{dr list begin}}
+
{{dr list item|paper=P2325R3|std=C++20|before={{tt|span}} of non-zero static extents were not {{tt|view}}|after=they are as {{lconcept|default_initializable}} is not required}}
+
{{dr list end}}
+
 
+
===See also===
+
{{dsc begin}}
+
{{dsc inc|cpp/utility/dsc initializer_list}}
+
{{dsc inc|cpp/string/dsc basic_string_view}}
+
{{dsc inc|cpp/container/dsc mdspan}}
+
{{dsc inc|cpp/ranges/dsc subrange}}
+
{{dsc end}}
+
 
+
{{langlinks|de|es|ja|ru|zh}}
+

Revision as of 12:51, 30 July 2023