[/ Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) ] [section:span span] [simplesect Authors] * Glen Fernandes [endsimplesect] [section Overview] This header provides class template `span`, which is a view over a sequence of objects. It implements the C++20 standard library `std::span` facility. This implementation supports C++11 and higher. In addition to referencing the sequence of objects, the span knows the count of objects. There are two kinds of spans: * Dynamic size (`span` or `span`) * Static size (`span`) Dynamic size spans have a count that can be a value known at run time. Static size spans have a count that must be known at compile time. [endsect] [section Examples] The following snippet shows a function to compute a SHA1 hash whose parameters and return type use spans. ``` auto sha1(boost::span input, boost::span ouput) { SHA_CTX context; SHA1_Init(&context); SHA1_Update(&context, input.data(), input.size()); SHA1_Final(output.data(), &context); return output; } ``` [endsect] [section Reference] ``` namespace boost { constexpr std::size_t dynamic_extent = -1; template class span { public: typedef T element_type; typedef std::remove_cv_t value_type; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T* iterator; typedef const T* const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; static constexpr std::size_t extent = E; constexpr span() noexcept; explicit(E != dynamic_extent) template constexpr span(I* f, size_type c); explicit(E != dynamic_extent) template constexpr span(I* f, L* l); template constexpr span(type_identity_t (&a)[N]); template constexpr span(std::array& a) noexcept; template constexpr span(const std::array& a) noexcept; explicit(E != dynamic_extent) template constexpr span(R&& r); explicit(E != dynamic_extent && N == dynamic_extent) template constexpr span(const span& s) noexcept; template constexpr span first() const; template constexpr span last() const; template constexpr span subspan() const; constexpr span first(size_type c) const; constexpr span last(size_type c) const; constexpr span subspan(size_type o, size_type c = dynamic_extent) const; constexpr size_type size() const noexcept; constexpr size_type size_bytes() const noexcept; constexpr bool empty() const noexcept; constexpr reference operator[](size_type i) const; constexpr reference front() const; constexpr reference back() const; constexpr pointer data() const noexcept; constexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; constexpr reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; }; template span(I*, L) -> span; template span(T(&)[N]) -> span; template span(std::array&) -> span; template span(const std::array&) -> span; template span(R&&) -> span > >; template span as_bytes(span s) noexcept; template span as_writable_bytes(span s) noexcept; } /* boost */ ``` [section Constructors] [variablelist [[`constexpr span() noexcept;`] [[variablelist [[Constraints][`E == dynamic_extent || E == 0` is `true`.]] [[Postconditions][`size() == 0 && data() == nullptr`.]]]]] [[`explicit(E != dynamic_extent) template constexpr span(I* f, size_type c);`] [[variablelist [[Constraints] [`is_convertible_v` is `true`.]] [[Preconditions] [[itemized_list [`[f, f + c)` is a valid range.] [If `E` is not equal to `dynamic_extent`, then `c` is equal to `E`.]]]] [[Effects][Constructs a `span` with data `f` and size `c`.]] [[Throws][Nothing.]]]]] [[`explicit(E != dynamic_extent) template constexpr span(I* f, L* l);`] [[variablelist [[Constraints] [`is_convertible_v` is `true`.]] [[Preconditions] [[itemized_list [If `E` is not equal to `dynamic_extent`, then `l - f` is equal to `E`.] [`[f, l)` is a valid range.]]]] [[Effects][Constructs a `span` with data `f` and size `l - f`.]] [[Throws][Nothing.]]]]] [[`template constexpr span(type_identity_t (&a)[N]);`] [[variablelist [[Constraints][`E == dynamic_extent || E == N` is `true`.]] [[Effects][Constructs a `span` that is a view over the supplied array.]] [[Postconditions][`size() == N && data() == &a[0]` is `true`.]]]]] [[`template constexpr span(std::array& a) noexcept;`] [[variablelist [[Constraints] [[itemized_list [`E == dynamic_extent || E == N` is `true`, and] [`U(*)[]` is convertible to `T(*)[]`.]]]] [[Effects][Constructs a `span` that is a view over the supplied array.]] [[Postconditions][`size() == N && data() == a.data()` is `true`.]]]]] [[`template constexpr span(const std::array& a) noexcept;`] [[variablelist [[Constraints] [[itemized_list [`E == dynamic_extent || E == N` is `true`, and] [`U(*)[]` is convertible to `T(*)[]`.]]]] [[Effects][Constructs a `span` that is a view over the supplied array.]] [[Postconditions][`size() == N && data() == a.data()` is `true`.]]]]] [[`explicit(E != dynamic_extent) template constexpr span(R&& r);`] [[variablelist [[Constraints] [[itemized_list [`is_lvalue_reference_v || is_const_v` is `true`] [`remove_cvref_t` is not a specialization of `span`,] [`remove_cvref_t` is not a specialization of `array`,] [`is_array_v>` is `false`,] [`data(r)` is well-formed and `is_convertible_v >(*)[], T(*)[]>` is `true`, and] [`r.size()` is well-formed and `is_convertible_v().size()), size_t>` is `true`.]]]] [[Effects][Constructs a `span` with data `data(r)` and size `r.size()`.]] [[Throws][What and when data(r) and r.size() throw.]]]]] [[`explicit(E != dynamic_extent && N == dynamic_extent) template constexpr span(const span& s) noexcept;`] [[variablelist [[Constraints] [[itemized_list [`E == dynamic_extent || N == dynamic_extent || E == N` is `true`, and] [`is_convertible_v` is `true`.]]]] [[Preconditions] [If `E` is not equal to `dynamic_extent`, then `s.size()` is equal to `E`.]] [[Effects] [Constructs a `span` that is a view over the range `[s.data(), s.data() + s.size())`.]] [[Postconditions][`size() == s.size() && data() == s.data()`.]]]]]] [endsect] [section Subviews] [variablelist [[`template constexpr span first() const;`] [[variablelist [[Mandates][`C <= E` is `true`.]] [[Preconditions][`C <= size()` is `true`.]] [[Effects] [Equivalent to `return R{data(), C};` where `R` is the return type.]]]]] [[`template constexpr span last() const;`] [[variablelist [[Mandates][`C <= E` is `true`.]] [[Preconditions][`C <= size()` is `true`.]] [[Effects] [Equivalent to `return R{data() + (size() - C), C};` where `R` is the return type.]]]]] [[`template constexpr span subspan() const;`] [[variablelist [[Mandates][`O <= E && (C == dynamic_extent || C <= E - O)` is `true`.]] [[Preconditions] [`O <= size() && (C == dynamic_extent || C <= size() - O)` is `true`.]] [[Effects] [Equivalent to `return span(data() + O, C != dynamic_extent ? C : size() - O);`.]] [[Remarks] [The second template argument of the returned span type is: `C != dynamic_extent ? C : (E != dynamic_extent ? E - O : dynamic_extent)`]]]]] [[`constexpr span first(size_type c) const;`] [[variablelist [[Preconditions][`c <= size()` is `true`.]] [[Effects][Equivalent to: `return {data(), c};`]]]]] [[`constexpr span last(size_type c) const;`] [[variablelist [[Preconditions][`c <= size()` is `true`.]] [[Effects][Equivalent to: `return {data() + (size() - c), c};`]]]]] [[`constexpr span subspan(size_type o, size_type c = dynamic_extent) const;`] [[variablelist [[Preconditions] [`o <= size() && (c == dynamic_extent || o + c <= size())` is `true`.]] [[Effects] [Equivalent to: `return {data() + o, c == dynamic_extent ? size() - o : c};`]]]]]] [endsect] [section Observers] [variablelist [[`constexpr size_type size() const noexcept;`] [[variablelist [[Returns][The number of elements in the span.]]]]] [[`constexpr size_type size_bytes() const noexcept;`] [[variablelist [[Effects][Equivalent to: `return size() * sizeof(T);`]]]]] [[`constexpr bool empty() const noexcept;`] [[variablelist [[Effects][Equivalent to: `return size() == 0;`]]]]]] [endsect] [section Element access] [variablelist [[`constexpr reference operator[](size_type i) const;`] [[variablelist [[Preconditions][`i < size()` is `true`.]] [[Effects][Equivalent to: `return *(data() + i);`]]]]] [[`constexpr reference front() const;`] [[variablelist [[Preconditions][`empty()` is `false`.]] [[Effects][Equivalent to: `return *data();`]]]]] [[`constexpr reference back() const;`] [[variablelist [[Preconditions][`empty()` is `false`.]] [[Effects][Equivalent to: `return *(data() + (size() - 1);`]]]]] [[`constexpr pointer data() const noexcept;`] [[variablelist [[Returns][A pointer to the first element in the span.]]]]]] [endsect] [section Iterator support] [variablelist [[`constexpr iterator begin() const noexcept;`] [[variablelist [[Returns][A constant iterator referring to the first element in the span. If `empty()`, then it returns the same value as `cend()`.]]]]] [[`constexpr iterator end() const noexcept;`] [[variablelist [[Returns][A constant iterator which is the past-the-end value.]]]]] [[`constexpr reverse_iterator rbegin() const noexcept;`] [[variablelist [[Effects][Equivalent to: `return reverse_iterator(end());`]]]]] [[`constexpr reverse_iterator rend() const noexcept;`] [[variablelist [[Effects][Equivalent to: `return reverse_iterator(begin());`]]]]] [[`constexpr const_iterator cbegin() const noexcept;`] [[variablelist [[Returns] [A constant iterator referring to the first element in the span. If `empty()`, then it returns the same value as `cend()`.]]]]] [[`constexpr const_iterator cend() const noexcept;`] [[variablelist [[Returns][A constant iterator which is the past-the-end value.]]]]] [[`constexpr const_reverse_iterator crbegin() const noexcept;`] [[variablelist [[Effects][Equivalent to: `return const_reverse_iterator(cend());`]]]]] [[`constexpr const_reverse_iterator crend() const noexcept;`] [[variablelist [[Effects] [Equivalent to: `return const_reverse_iterator(cbegin());`]]]]]] [endsect] [section Views of object representation] [variablelist [[`template span as_bytes(span s) noexcept;`] [[variablelist [[Effects] [Equivalent to: `return {reinterpret_cast(s.data()), s.size_bytes()};`.]]]]] [[`template span as_writable_bytes(span s) noexcept;`] [[variablelist [[Constraints][`is_const_v` is `false`.]] [[Effects] [Equivalent to: `return R{reinterpret_cast(s.data()), s.size_bytes()};` where `R` is the return type.]]]]]] [endsect] [endsect] [endsect]