98.85% Lines (86/87)
100.00% Functions (16/16)
| TLA | Baseline | Branch | ||||||
|---|---|---|---|---|---|---|---|---|
| Line | Hits | Code | Line | Hits | Code | |||
| 1 | // | 1 | // | |||||
| 2 | // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) | 2 | // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) | |||||
| 3 | // | 3 | // | |||||
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |||||
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||||
| 6 | // | 6 | // | |||||
| 7 | // Official repository: https://github.com/cppalliance/capy | 7 | // Official repository: https://github.com/cppalliance/capy | |||||
| 8 | // | 8 | // | |||||
| 9 | 9 | |||||||
| 10 | #ifndef BOOST_CAPY_DETAIL_BUFFER_ARRAY_HPP | 10 | #ifndef BOOST_CAPY_DETAIL_BUFFER_ARRAY_HPP | |||||
| 11 | #define BOOST_CAPY_DETAIL_BUFFER_ARRAY_HPP | 11 | #define BOOST_CAPY_DETAIL_BUFFER_ARRAY_HPP | |||||
| 12 | 12 | |||||||
| 13 | #include <boost/capy/detail/config.hpp> | 13 | #include <boost/capy/detail/config.hpp> | |||||
| 14 | #include <boost/capy/detail/except.hpp> | 14 | #include <boost/capy/detail/except.hpp> | |||||
| 15 | #include <boost/capy/buffers.hpp> | 15 | #include <boost/capy/buffers.hpp> | |||||
| 16 | 16 | |||||||
| 17 | #include <cstddef> | 17 | #include <cstddef> | |||||
| 18 | #include <new> | 18 | #include <new> | |||||
| 19 | #include <span> | 19 | #include <span> | |||||
| 20 | #include <utility> | 20 | #include <utility> | |||||
| 21 | 21 | |||||||
| 22 | namespace boost { | 22 | namespace boost { | |||||
| 23 | namespace capy { | 23 | namespace capy { | |||||
| 24 | namespace detail { | 24 | namespace detail { | |||||
| 25 | 25 | |||||||
| 26 | /** A buffer sequence holding up to N buffers. | 26 | /** A buffer sequence holding up to N buffers. | |||||
| 27 | 27 | |||||||
| 28 | This class template stores a fixed-capacity array of buffer | 28 | This class template stores a fixed-capacity array of buffer | |||||
| 29 | descriptors, where the actual count can vary from 0 to N. | 29 | descriptors, where the actual count can vary from 0 to N. | |||||
| 30 | It provides efficient storage for small buffer sequences | 30 | It provides efficient storage for small buffer sequences | |||||
| 31 | without dynamic allocation. | 31 | without dynamic allocation. | |||||
| 32 | 32 | |||||||
| 33 | @par Example | 33 | @par Example | |||||
| 34 | @code | 34 | @code | |||||
| 35 | void process(ConstBufferSequence auto const& buffers) | 35 | void process(ConstBufferSequence auto const& buffers) | |||||
| 36 | { | 36 | { | |||||
| 37 | detail::const_buffer_array<4> bufs(buffers); | 37 | detail::const_buffer_array<4> bufs(buffers); | |||||
| 38 | // use bufs.begin(), bufs.end(), bufs.to_span() | 38 | // use bufs.begin(), bufs.end(), bufs.to_span() | |||||
| 39 | } | 39 | } | |||||
| 40 | @endcode | 40 | @endcode | |||||
| 41 | 41 | |||||||
| 42 | @tparam N Maximum number of buffers the array can hold. | 42 | @tparam N Maximum number of buffers the array can hold. | |||||
| 43 | @tparam IsConst If true, holds const_buffer; otherwise mutable_buffer. | 43 | @tparam IsConst If true, holds const_buffer; otherwise mutable_buffer. | |||||
| 44 | */ | 44 | */ | |||||
| 45 | template<std::size_t N, bool IsConst> | 45 | template<std::size_t N, bool IsConst> | |||||
| 46 | class buffer_array | 46 | class buffer_array | |||||
| 47 | { | 47 | { | |||||
| 48 | public: | 48 | public: | |||||
| 49 | /** The type of buffer stored in the array. | 49 | /** The type of buffer stored in the array. | |||||
| 50 | */ | 50 | */ | |||||
| 51 | using value_type = std::conditional_t<IsConst, const_buffer, mutable_buffer>; | 51 | using value_type = std::conditional_t<IsConst, const_buffer, mutable_buffer>; | |||||
| 52 | 52 | |||||||
| 53 | private: | 53 | private: | |||||
| 54 | std::size_t n_ = 0; | 54 | std::size_t n_ = 0; | |||||
| 55 | std::size_t size_ = 0; | 55 | std::size_t size_ = 0; | |||||
| 56 | union { | 56 | union { | |||||
| 57 | int dummy_; | 57 | int dummy_; | |||||
| 58 | value_type arr_[N]; | 58 | value_type arr_[N]; | |||||
| 59 | }; | 59 | }; | |||||
| 60 | 60 | |||||||
| 61 | public: | 61 | public: | |||||
| 62 | /** Construct a default instance. | 62 | /** Construct a default instance. | |||||
| 63 | 63 | |||||||
| 64 | Constructs an empty buffer array. | 64 | Constructs an empty buffer array. | |||||
| 65 | */ | 65 | */ | |||||
| HITCBC | 66 | 6 | buffer_array() noexcept | 66 | 6 | buffer_array() noexcept | ||
| HITCBC | 67 | 6 | : dummy_(0) | 67 | 6 | : dummy_(0) | ||
| 68 | { | 68 | { | |||||
| HITCBC | 69 | 6 | } | 69 | 6 | } | ||
| 70 | 70 | |||||||
| 71 | /** Construct a copy. | 71 | /** Construct a copy. | |||||
| 72 | */ | 72 | */ | |||||
| HITCBC | 73 | 292 | buffer_array(buffer_array const& other) noexcept | 73 | 292 | buffer_array(buffer_array const& other) noexcept | ||
| HITCBC | 74 | 292 | : n_(other.n_) | 74 | 292 | : n_(other.n_) | ||
| HITCBC | 75 | 292 | , size_(other.size_) | 75 | 292 | , size_(other.size_) | ||
| 76 | { | 76 | { | |||||
| HITCBC | 77 | 811 | for(std::size_t i = 0; i < n_; ++i) | 77 | 811 | for(std::size_t i = 0; i < n_; ++i) | ||
| HITCBC | 78 | 519 | ::new(&arr_[i]) value_type(other.arr_[i]); | 78 | 519 | ::new(&arr_[i]) value_type(other.arr_[i]); | ||
| HITCBC | 79 | 292 | } | 79 | 292 | } | ||
| 80 | 80 | |||||||
| 81 | /** Construct from a single buffer. | 81 | /** Construct from a single buffer. | |||||
| 82 | 82 | |||||||
| 83 | @param b The buffer to store. | 83 | @param b The buffer to store. | |||||
| 84 | */ | 84 | */ | |||||
| HITCBC | 85 | 130 | buffer_array(value_type const& b) noexcept | 85 | 130 | buffer_array(value_type const& b) noexcept | ||
| HITCBC | 86 | 130 | : dummy_(0) | 86 | 130 | : dummy_(0) | ||
| 87 | { | 87 | { | |||||
| HITCBC | 88 | 130 | if(b.size() != 0) | 88 | 130 | if(b.size() != 0) | ||
| 89 | { | 89 | { | |||||
| HITCBC | 90 | 122 | ::new(&arr_[0]) value_type(b); | 90 | 122 | ::new(&arr_[0]) value_type(b); | ||
| HITCBC | 91 | 122 | n_ = 1; | 91 | 122 | n_ = 1; | ||
| HITCBC | 92 | 122 | size_ = b.size(); | 92 | 122 | size_ = b.size(); | ||
| 93 | } | 93 | } | |||||
| HITCBC | 94 | 130 | } | 94 | 130 | } | ||
| 95 | 95 | |||||||
| 96 | /** Construct from a buffer sequence. | 96 | /** Construct from a buffer sequence. | |||||
| 97 | 97 | |||||||
| 98 | Copies up to N buffer descriptors from the source | 98 | Copies up to N buffer descriptors from the source | |||||
| 99 | sequence into the internal array. If the sequence | 99 | sequence into the internal array. If the sequence | |||||
| 100 | contains more than N non-empty buffers, excess | 100 | contains more than N non-empty buffers, excess | |||||
| 101 | buffers are silently ignored. | 101 | buffers are silently ignored. | |||||
| 102 | 102 | |||||||
| 103 | @param bs The buffer sequence to copy from. | 103 | @param bs The buffer sequence to copy from. | |||||
| 104 | */ | 104 | */ | |||||
| 105 | template<class BS> | 105 | template<class BS> | |||||
| 106 | requires (IsConst ? ConstBufferSequence<BS> : MutableBufferSequence<BS>) | 106 | requires (IsConst ? ConstBufferSequence<BS> : MutableBufferSequence<BS>) | |||||
| 107 | && (!std::same_as<std::remove_cvref_t<BS>, buffer_array>) | 107 | && (!std::same_as<std::remove_cvref_t<BS>, buffer_array>) | |||||
| 108 | && (!std::same_as<std::remove_cvref_t<BS>, value_type>) | 108 | && (!std::same_as<std::remove_cvref_t<BS>, value_type>) | |||||
| HITCBC | 109 | 185 | buffer_array(BS const& bs) noexcept | 109 | 185 | buffer_array(BS const& bs) noexcept | ||
| HITCBC | 110 | 185 | : dummy_(0) | 110 | 185 | : dummy_(0) | ||
| 111 | { | 111 | { | |||||
| HITCBC | 112 | 185 | auto it = capy::begin(bs); | 112 | 185 | auto it = capy::begin(bs); | ||
| HITCBC | 113 | 185 | auto const last = capy::end(bs); | 113 | 185 | auto const last = capy::end(bs); | ||
| HITCBC | 114 | 618 | while(it != last && n_ < N) | 114 | 618 | while(it != last && n_ < N) | ||
| 115 | { | 115 | { | |||||
| HITCBC | 116 | 433 | value_type b(*it); | 116 | 433 | value_type b(*it); | ||
| HITCBC | 117 | 433 | if(b.size() != 0) | 117 | 433 | if(b.size() != 0) | ||
| 118 | { | 118 | { | |||||
| HITCBC | 119 | 427 | ::new(&arr_[n_++]) value_type(b); | 119 | 427 | ::new(&arr_[n_++]) value_type(b); | ||
| HITCBC | 120 | 427 | size_ += b.size(); | 120 | 427 | size_ += b.size(); | ||
| 121 | } | 121 | } | |||||
| HITCBC | 122 | 433 | ++it; | 122 | 433 | ++it; | ||
| 123 | } | 123 | } | |||||
| HITCBC | 124 | 185 | } | 124 | 185 | } | ||
| 125 | 125 | |||||||
| 126 | /** Construct from a buffer sequence with overflow checking. | 126 | /** Construct from a buffer sequence with overflow checking. | |||||
| 127 | 127 | |||||||
| 128 | Copies buffer descriptors from the source sequence | 128 | Copies buffer descriptors from the source sequence | |||||
| 129 | into the internal array. | 129 | into the internal array. | |||||
| 130 | 130 | |||||||
| 131 | @param bs The buffer sequence to copy from. | 131 | @param bs The buffer sequence to copy from. | |||||
| 132 | 132 | |||||||
| 133 | @throws std::length_error if the sequence contains | 133 | @throws std::length_error if the sequence contains | |||||
| 134 | more than N non-empty buffers. | 134 | more than N non-empty buffers. | |||||
| 135 | */ | 135 | */ | |||||
| 136 | template<class BS> | 136 | template<class BS> | |||||
| 137 | requires (IsConst ? ConstBufferSequence<BS> : MutableBufferSequence<BS>) | 137 | requires (IsConst ? ConstBufferSequence<BS> : MutableBufferSequence<BS>) | |||||
| HITCBC | 138 | 4 | buffer_array(std::in_place_t, BS const& bs) | 138 | 4 | buffer_array(std::in_place_t, BS const& bs) | ||
| HITCBC | 139 | 4 | : dummy_(0) | 139 | 4 | : dummy_(0) | ||
| 140 | { | 140 | { | |||||
| HITCBC | 141 | 4 | auto it = capy::begin(bs); | 141 | 4 | auto it = capy::begin(bs); | ||
| HITCBC | 142 | 4 | auto const last = capy::end(bs); | 142 | 4 | auto const last = capy::end(bs); | ||
| HITCBC | 143 | 14 | while(it != last) | 143 | 14 | while(it != last) | ||
| 144 | { | 144 | { | |||||
| HITCBC | 145 | 12 | value_type b(*it); | 145 | 12 | value_type b(*it); | ||
| HITCBC | 146 | 12 | if(b.size() != 0) | 146 | 12 | if(b.size() != 0) | ||
| 147 | { | 147 | { | |||||
| HITCBC | 148 | 12 | if(n_ >= N) | 148 | 12 | if(n_ >= N) | ||
| HITCBC | 149 | 2 | detail::throw_length_error(); | 149 | 2 | detail::throw_length_error(); | ||
| HITCBC | 150 | 10 | ::new(&arr_[n_++]) value_type(b); | 150 | 10 | ::new(&arr_[n_++]) value_type(b); | ||
| HITCBC | 151 | 10 | size_ += b.size(); | 151 | 10 | size_ += b.size(); | ||
| 152 | } | 152 | } | |||||
| HITCBC | 153 | 10 | ++it; | 153 | 10 | ++it; | ||
| 154 | } | 154 | } | |||||
| HITCBC | 155 | 2 | } | 155 | 2 | } | ||
| 156 | 156 | |||||||
| 157 | /** Construct from an iterator range. | 157 | /** Construct from an iterator range. | |||||
| 158 | 158 | |||||||
| 159 | Copies up to N non-empty buffer descriptors from the | 159 | Copies up to N non-empty buffer descriptors from the | |||||
| 160 | range `[first, last)`. If the range contains more than | 160 | range `[first, last)`. If the range contains more than | |||||
| 161 | N non-empty buffers, excess buffers are silently ignored. | 161 | N non-empty buffers, excess buffers are silently ignored. | |||||
| 162 | 162 | |||||||
| 163 | @param first Iterator to the first buffer descriptor. | 163 | @param first Iterator to the first buffer descriptor. | |||||
| 164 | @param last Iterator past the last buffer descriptor. | 164 | @param last Iterator past the last buffer descriptor. | |||||
| 165 | */ | 165 | */ | |||||
| 166 | template<class Iterator> | 166 | template<class Iterator> | |||||
| HITCBC | 167 | 8 | buffer_array(Iterator first, Iterator last) noexcept | 167 | 8 | buffer_array(Iterator first, Iterator last) noexcept | ||
| HITCBC | 168 | 8 | : dummy_(0) | 168 | 8 | : dummy_(0) | ||
| 169 | { | 169 | { | |||||
| HITCBC | 170 | 26 | while(first != last && n_ < N) | 170 | 26 | while(first != last && n_ < N) | ||
| 171 | { | 171 | { | |||||
| HITCBC | 172 | 18 | value_type b(*first); | 172 | 18 | value_type b(*first); | ||
| HITCBC | 173 | 18 | if(b.size() != 0) | 173 | 18 | if(b.size() != 0) | ||
| 174 | { | 174 | { | |||||
| HITCBC | 175 | 14 | ::new(&arr_[n_++]) value_type(b); | 175 | 14 | ::new(&arr_[n_++]) value_type(b); | ||
| HITCBC | 176 | 14 | size_ += b.size(); | 176 | 14 | size_ += b.size(); | ||
| 177 | } | 177 | } | |||||
| HITCBC | 178 | 18 | ++first; | 178 | 18 | ++first; | ||
| 179 | } | 179 | } | |||||
| HITCBC | 180 | 8 | } | 180 | 8 | } | ||
| 181 | 181 | |||||||
| 182 | /** Construct from an iterator range with overflow checking. | 182 | /** Construct from an iterator range with overflow checking. | |||||
| 183 | 183 | |||||||
| 184 | Copies all non-empty buffer descriptors from the range | 184 | Copies all non-empty buffer descriptors from the range | |||||
| 185 | `[first, last)` into the internal array. | 185 | `[first, last)` into the internal array. | |||||
| 186 | 186 | |||||||
| 187 | @param first Iterator to the first buffer descriptor. | 187 | @param first Iterator to the first buffer descriptor. | |||||
| 188 | @param last Iterator past the last buffer descriptor. | 188 | @param last Iterator past the last buffer descriptor. | |||||
| 189 | 189 | |||||||
| 190 | @throws std::length_error if the range contains more | 190 | @throws std::length_error if the range contains more | |||||
| 191 | than N non-empty buffers. | 191 | than N non-empty buffers. | |||||
| 192 | */ | 192 | */ | |||||
| 193 | template<class Iterator> | 193 | template<class Iterator> | |||||
| HITCBC | 194 | 4 | buffer_array(std::in_place_t, Iterator first, Iterator last) | 194 | 4 | buffer_array(std::in_place_t, Iterator first, Iterator last) | ||
| HITCBC | 195 | 4 | : dummy_(0) | 195 | 4 | : dummy_(0) | ||
| 196 | { | 196 | { | |||||
| HITCBC | 197 | 14 | while(first != last) | 197 | 14 | while(first != last) | ||
| 198 | { | 198 | { | |||||
| HITCBC | 199 | 12 | value_type b(*first); | 199 | 12 | value_type b(*first); | ||
| HITCBC | 200 | 12 | if(b.size() != 0) | 200 | 12 | if(b.size() != 0) | ||
| 201 | { | 201 | { | |||||
| HITCBC | 202 | 12 | if(n_ >= N) | 202 | 12 | if(n_ >= N) | ||
| HITCBC | 203 | 2 | detail::throw_length_error(); | 203 | 2 | detail::throw_length_error(); | ||
| HITCBC | 204 | 10 | ::new(&arr_[n_++]) value_type(b); | 204 | 10 | ::new(&arr_[n_++]) value_type(b); | ||
| HITCBC | 205 | 10 | size_ += b.size(); | 205 | 10 | size_ += b.size(); | ||
| 206 | } | 206 | } | |||||
| HITCBC | 207 | 10 | ++first; | 207 | 10 | ++first; | ||
| 208 | } | 208 | } | |||||
| HITCBC | 209 | 2 | } | 209 | 2 | } | ||
| 210 | 210 | |||||||
| 211 | /** Destructor. | 211 | /** Destructor. | |||||
| 212 | */ | 212 | */ | |||||
| HITCBC | 213 | 625 | ~buffer_array() | 213 | 625 | ~buffer_array() | ||
| 214 | { | 214 | { | |||||
| HITCBC | 215 | 1725 | while(n_--) | 215 | 1725 | while(n_--) | ||
| HITCBC | 216 | 1100 | arr_[n_].~value_type(); | 216 | 1100 | arr_[n_].~value_type(); | ||
| HITCBC | 217 | 625 | } | 217 | 625 | } | ||
| 218 | 218 | |||||||
| 219 | /** Assign by copying. | 219 | /** Assign by copying. | |||||
| 220 | */ | 220 | */ | |||||
| 221 | buffer_array& | 221 | buffer_array& | |||||
| HITCBC | 222 | 4 | operator=(buffer_array const& other) noexcept | 222 | 4 | operator=(buffer_array const& other) noexcept | ||
| 223 | { | 223 | { | |||||
| HITCBC | 224 | 4 | if(this != &other) | 224 | 4 | if(this != &other) | ||
| 225 | { | 225 | { | |||||
| HITCBC | 226 | 4 | while(n_--) | 226 | 4 | while(n_--) | ||
| MISUBC | 227 | ✗ | arr_[n_].~value_type(); | 227 | ✗ | arr_[n_].~value_type(); | ||
| HITCBC | 228 | 4 | n_ = other.n_; | 228 | 4 | n_ = other.n_; | ||
| HITCBC | 229 | 4 | size_ = other.size_; | 229 | 4 | size_ = other.size_; | ||
| HITCBC | 230 | 10 | for(std::size_t i = 0; i < n_; ++i) | 230 | 10 | for(std::size_t i = 0; i < n_; ++i) | ||
| HITCBC | 231 | 6 | ::new(&arr_[i]) value_type(other.arr_[i]); | 231 | 6 | ::new(&arr_[i]) value_type(other.arr_[i]); | ||
| 232 | } | 232 | } | |||||
| HITCBC | 233 | 4 | return *this; | 233 | 4 | return *this; | ||
| 234 | } | 234 | } | |||||
| 235 | 235 | |||||||
| 236 | /** Return an iterator to the beginning. | 236 | /** Return an iterator to the beginning. | |||||
| 237 | */ | 237 | */ | |||||
| 238 | value_type* | 238 | value_type* | |||||
| HITCBC | 239 | 130 | begin() noexcept | 239 | 130 | begin() noexcept | ||
| 240 | { | 240 | { | |||||
| HITCBC | 241 | 130 | return arr_; | 241 | 130 | return arr_; | ||
| 242 | } | 242 | } | |||||
| 243 | 243 | |||||||
| 244 | /** Return an iterator to the beginning. | 244 | /** Return an iterator to the beginning. | |||||
| 245 | */ | 245 | */ | |||||
| 246 | value_type const* | 246 | value_type const* | |||||
| HITCBC | 247 | 2441 | begin() const noexcept | 247 | 2441 | begin() const noexcept | ||
| 248 | { | 248 | { | |||||
| HITCBC | 249 | 2441 | return arr_; | 249 | 2441 | return arr_; | ||
| 250 | } | 250 | } | |||||
| 251 | 251 | |||||||
| 252 | /** Return an iterator to the end. | 252 | /** Return an iterator to the end. | |||||
| 253 | */ | 253 | */ | |||||
| 254 | value_type* | 254 | value_type* | |||||
| HITCBC | 255 | 129 | end() noexcept | 255 | 129 | end() noexcept | ||
| 256 | { | 256 | { | |||||
| HITCBC | 257 | 129 | return arr_ + n_; | 257 | 129 | return arr_ + n_; | ||
| 258 | } | 258 | } | |||||
| 259 | 259 | |||||||
| 260 | /** Return an iterator to the end. | 260 | /** Return an iterator to the end. | |||||
| 261 | */ | 261 | */ | |||||
| 262 | value_type const* | 262 | value_type const* | |||||
| HITCBC | 263 | 2441 | end() const noexcept | 263 | 2441 | end() const noexcept | ||
| 264 | { | 264 | { | |||||
| HITCBC | 265 | 2441 | return arr_ + n_; | 265 | 2441 | return arr_ + n_; | ||
| 266 | } | 266 | } | |||||
| 267 | 267 | |||||||
| 268 | /** Return a span of the buffers. | 268 | /** Return a span of the buffers. | |||||
| 269 | */ | 269 | */ | |||||
| 270 | std::span<value_type> | 270 | std::span<value_type> | |||||
| HITCBC | 271 | 379 | to_span() noexcept | 271 | 379 | to_span() noexcept | ||
| 272 | { | 272 | { | |||||
| HITCBC | 273 | 379 | return { arr_, n_ }; | 273 | 379 | return { arr_, n_ }; | ||
| 274 | } | 274 | } | |||||
| 275 | 275 | |||||||
| 276 | /** Return a span of the buffers. | 276 | /** Return a span of the buffers. | |||||
| 277 | */ | 277 | */ | |||||
| 278 | std::span<value_type const> | 278 | std::span<value_type const> | |||||
| HITCBC | 279 | 175 | to_span() const noexcept | 279 | 175 | to_span() const noexcept | ||
| 280 | { | 280 | { | |||||
| HITCBC | 281 | 175 | return { arr_, n_ }; | 281 | 175 | return { arr_, n_ }; | ||
| 282 | } | 282 | } | |||||
| 283 | 283 | |||||||
| 284 | /** Conversion to mutable span. | 284 | /** Conversion to mutable span. | |||||
| 285 | */ | 285 | */ | |||||
| HITCBC | 286 | 1 | operator std::span<value_type>() noexcept | 286 | 1 | operator std::span<value_type>() noexcept | ||
| 287 | { | 287 | { | |||||
| HITCBC | 288 | 1 | return { arr_, n_ }; | 288 | 1 | return { arr_, n_ }; | ||
| 289 | } | 289 | } | |||||
| 290 | 290 | |||||||
| 291 | /** Conversion to const span. | 291 | /** Conversion to const span. | |||||
| 292 | */ | 292 | */ | |||||
| 293 | operator std::span<value_type const>() const noexcept | 293 | operator std::span<value_type const>() const noexcept | |||||
| 294 | { | 294 | { | |||||
| 295 | return { arr_, n_ }; | 295 | return { arr_, n_ }; | |||||
| 296 | } | 296 | } | |||||
| 297 | 297 | |||||||
| 298 | /** Return the total byte count in O(1). | 298 | /** Return the total byte count in O(1). | |||||
| 299 | */ | 299 | */ | |||||
| 300 | std::size_t | 300 | std::size_t | |||||
| 301 | byte_size() const noexcept | 301 | byte_size() const noexcept | |||||
| 302 | { | 302 | { | |||||
| 303 | return size_; | 303 | return size_; | |||||
| 304 | } | 304 | } | |||||
| 305 | }; | 305 | }; | |||||
| 306 | 306 | |||||||
| 307 | /** Alias for buffer_array holding const_buffer. | 307 | /** Alias for buffer_array holding const_buffer. | |||||
| 308 | 308 | |||||||
| 309 | @tparam N Maximum number of buffers. | 309 | @tparam N Maximum number of buffers. | |||||
| 310 | */ | 310 | */ | |||||
| 311 | template<std::size_t N> | 311 | template<std::size_t N> | |||||
| 312 | using const_buffer_array = buffer_array<N, true>; | 312 | using const_buffer_array = buffer_array<N, true>; | |||||
| 313 | 313 | |||||||
| 314 | /** Alias for buffer_array holding mutable_buffer. | 314 | /** Alias for buffer_array holding mutable_buffer. | |||||
| 315 | 315 | |||||||
| 316 | @tparam N Maximum number of buffers. | 316 | @tparam N Maximum number of buffers. | |||||
| 317 | */ | 317 | */ | |||||
| 318 | template<std::size_t N> | 318 | template<std::size_t N> | |||||
| 319 | using mutable_buffer_array = buffer_array<N, false>; | 319 | using mutable_buffer_array = buffer_array<N, false>; | |||||
| 320 | 320 | |||||||
| 321 | } // namespace detail | 321 | } // namespace detail | |||||
| 322 | } // namespace capy | 322 | } // namespace capy | |||||
| 323 | } // namespace boost | 323 | } // namespace boost | |||||
| 324 | 324 | |||||||
| 325 | #endif | 325 | #endif | |||||