/src/libjxl/lib/jxl/base/span.h
Line | Count | Source |
1 | | // Copyright (c) the JPEG XL Project Authors. All rights reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style |
4 | | // license that can be found in the LICENSE file. |
5 | | |
6 | | #ifndef LIB_JXL_BASE_SPAN_H_ |
7 | | #define LIB_JXL_BASE_SPAN_H_ |
8 | | |
9 | | // Span (array view) is a non-owning container that provides cheap "cut" |
10 | | // operations and could be used as "ArrayLike" data source for PaddedBytes. |
11 | | |
12 | | #include <cstddef> |
13 | | #include <cstdint> |
14 | | #include <type_traits> |
15 | | #include <vector> |
16 | | |
17 | | #include "lib/jxl/base/status.h" |
18 | | |
19 | | namespace jxl { |
20 | | |
21 | | template <typename T> |
22 | | class Span { |
23 | | public: |
24 | 465k | constexpr Span() noexcept : Span(nullptr, 0) {}jxl::Span<jxl::QuantizedSpline const>::Span() Line | Count | Source | 24 | 130k | constexpr Span() noexcept : Span(nullptr, 0) {} |
jxl::Span<jxl::Spline::Point const>::Span() Line | Count | Source | 24 | 130k | constexpr Span() noexcept : Span(nullptr, 0) {} |
jxl::Span<unsigned char const>::Span() Line | Count | Source | 24 | 204k | constexpr Span() noexcept : Span(nullptr, 0) {} |
|
25 | | |
26 | | constexpr Span(T* array, size_t length) noexcept |
27 | 1.96M | : ptr_(array), len_(length) {}jxl::Span<unsigned char const>::Span(unsigned char const*, unsigned long) Line | Count | Source | 27 | 1.44M | : ptr_(array), len_(length) {} |
jxl::Span<jxl::QuantizedSpline const>::Span(jxl::QuantizedSpline const*, unsigned long) Line | Count | Source | 27 | 133k | : ptr_(array), len_(length) {} |
jxl::Span<jxl::Spline::Point const>::Span(jxl::Spline::Point const*, unsigned long) Line | Count | Source | 27 | 133k | : ptr_(array), len_(length) {} |
jxl::Span<float>::Span(float*, unsigned long) Line | Count | Source | 27 | 185k | : ptr_(array), len_(length) {} |
jxl::Span<unsigned char>::Span(unsigned char*, unsigned long) Line | Count | Source | 27 | 60.7k | : ptr_(array), len_(length) {} |
Unexecuted instantiation: jxl::Span<hwy::float16_t>::Span(hwy::float16_t*, unsigned long) |
28 | | |
29 | | template <size_t N> |
30 | 0 | explicit constexpr Span(T (&a)[N]) noexcept : Span(a, N) {} |
31 | | |
32 | | template <typename U> |
33 | | constexpr Span(U* array, size_t length) noexcept |
34 | 7.62k | : ptr_(reinterpret_cast<T*>(array)), len_(length) { |
35 | 7.62k | static_assert(sizeof(U) == sizeof(T), "Incompatible type of source."); |
36 | 7.62k | } |
37 | | |
38 | | template <typename ArrayLike> |
39 | | explicit constexpr Span(const ArrayLike& other) noexcept |
40 | 967k | : Span(reinterpret_cast<T*>(other.data()), other.size()) { |
41 | 967k | static_assert(sizeof(*other.data()) == sizeof(T), |
42 | 967k | "Incompatible type of source."); |
43 | 967k | } jxl::Span<unsigned char const>::Span<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&) Line | Count | Source | 40 | 961k | : Span(reinterpret_cast<T*>(other.data()), other.size()) { | 41 | 961k | static_assert(sizeof(*other.data()) == sizeof(T), | 42 | 961k | "Incompatible type of source."); | 43 | 961k | } |
jxl::Span<unsigned char const>::Span<jxl::PaddedBytes>(jxl::PaddedBytes const&) Line | Count | Source | 40 | 334 | : Span(reinterpret_cast<T*>(other.data()), other.size()) { | 41 | 334 | static_assert(sizeof(*other.data()) == sizeof(T), | 42 | 334 | "Incompatible type of source."); | 43 | 334 | } |
jxl::Span<jxl::QuantizedSpline const>::Span<std::__1::vector<jxl::QuantizedSpline, std::__1::allocator<jxl::QuantizedSpline> > >(std::__1::vector<jxl::QuantizedSpline, std::__1::allocator<jxl::QuantizedSpline> > const&) Line | Count | Source | 40 | 3.03k | : Span(reinterpret_cast<T*>(other.data()), other.size()) { | 41 | 3.03k | static_assert(sizeof(*other.data()) == sizeof(T), | 42 | 3.03k | "Incompatible type of source."); | 43 | 3.03k | } |
jxl::Span<jxl::Spline::Point const>::Span<std::__1::vector<jxl::Spline::Point, std::__1::allocator<jxl::Spline::Point> > >(std::__1::vector<jxl::Spline::Point, std::__1::allocator<jxl::Spline::Point> > const&) Line | Count | Source | 40 | 3.03k | : Span(reinterpret_cast<T*>(other.data()), other.size()) { | 41 | 3.03k | static_assert(sizeof(*other.data()) == sizeof(T), | 42 | 3.03k | "Incompatible type of source."); | 43 | 3.03k | } |
|
44 | | |
45 | | using NCT = typename std::remove_const<T>::type; |
46 | | |
47 | 16.4M | constexpr T* data() const noexcept { return ptr_; }jxl::Span<unsigned char const>::data() const Line | Count | Source | 47 | 2.88M | constexpr T* data() const noexcept { return ptr_; } |
jxl::Span<jxl::Spline::Point const>::data() const Line | Count | Source | 47 | 7.95k | constexpr T* data() const noexcept { return ptr_; } |
jxl::Span<jxl::QuantizedSpline const>::data() const Line | Count | Source | 47 | 7.95k | constexpr T* data() const noexcept { return ptr_; } |
jxl::Span<float>::data() const Line | Count | Source | 47 | 743k | constexpr T* data() const noexcept { return ptr_; } |
Unexecuted instantiation: jxl::Span<hwy::float16_t>::data() const jxl::Span<unsigned char>::data() const Line | Count | Source | 47 | 12.8M | constexpr T* data() const noexcept { return ptr_; } |
|
48 | | |
49 | 2.12M | constexpr size_t size() const noexcept { return len_; }jxl::Span<unsigned char const>::size() const Line | Count | Source | 49 | 1.36M | constexpr size_t size() const noexcept { return len_; } |
jxl::Span<jxl::QuantizedSpline const>::size() const Line | Count | Source | 49 | 13.5k | constexpr size_t size() const noexcept { return len_; } |
Unexecuted instantiation: jxl::Span<jxl::Spline::Point const>::size() const jxl::Span<float>::size() const Line | Count | Source | 49 | 743k | constexpr size_t size() const noexcept { return len_; } |
|
50 | | |
51 | 20.6k | constexpr bool empty() const noexcept { return len_ == 0; }jxl::Span<jxl::QuantizedSpline const>::empty() const Line | Count | Source | 51 | 19.4k | constexpr bool empty() const noexcept { return len_ == 0; } |
jxl::Span<unsigned char const>::empty() const Line | Count | Source | 51 | 1.12k | constexpr bool empty() const noexcept { return len_ == 0; } |
|
52 | | |
53 | 1.69M | constexpr T* begin() const noexcept { return data(); }jxl::Span<unsigned char const>::begin() const Line | Count | Source | 53 | 954k | constexpr T* begin() const noexcept { return data(); } |
Unexecuted instantiation: jxl::Span<jxl::QuantizedSpline const>::begin() const jxl::Span<float>::begin() const Line | Count | Source | 53 | 743k | constexpr T* begin() const noexcept { return data(); } |
|
54 | | |
55 | 954k | constexpr T* end() const noexcept { return data() + size(); }jxl::Span<unsigned char const>::end() const Line | Count | Source | 55 | 954k | constexpr T* end() const noexcept { return data() + size(); } |
Unexecuted instantiation: jxl::Span<jxl::QuantizedSpline const>::end() const |
56 | | |
57 | 12.8M | constexpr T& operator[](size_t i) const noexcept { |
58 | 12.8M | JXL_DASSERT(i < len_); |
59 | | // MSVC 2015 accepts this as constexpr, but not ptr_[i] |
60 | 12.8M | return *(data() + i); |
61 | 12.8M | } jxl::Span<jxl::Spline::Point const>::operator[](unsigned long) const Line | Count | Source | 57 | 7.95k | constexpr T& operator[](size_t i) const noexcept { | 58 | 7.95k | JXL_DASSERT(i < len_); | 59 | | // MSVC 2015 accepts this as constexpr, but not ptr_[i] | 60 | 7.95k | return *(data() + i); | 61 | 7.95k | } |
Unexecuted instantiation: jxl::Span<unsigned char const>::operator[](unsigned long) const Unexecuted instantiation: jxl::Span<hwy::float16_t>::operator[](unsigned long) const jxl::Span<unsigned char>::operator[](unsigned long) const Line | Count | Source | 57 | 12.8M | constexpr T& operator[](size_t i) const noexcept { | 58 | 12.8M | JXL_DASSERT(i < len_); | 59 | | // MSVC 2015 accepts this as constexpr, but not ptr_[i] | 60 | 12.8M | return *(data() + i); | 61 | 12.8M | } |
jxl::Span<jxl::QuantizedSpline const>::operator[](unsigned long) const Line | Count | Source | 57 | 7.95k | constexpr T& operator[](size_t i) const noexcept { | 58 | 7.95k | JXL_DASSERT(i < len_); | 59 | | // MSVC 2015 accepts this as constexpr, but not ptr_[i] | 60 | 7.95k | return *(data() + i); | 61 | 7.95k | } |
|
62 | | |
63 | 557k | Status remove_prefix(size_t n) noexcept { |
64 | 557k | JXL_ENSURE(size() >= n); |
65 | 557k | ptr_ += n; |
66 | 557k | len_ -= n; |
67 | 557k | return true; |
68 | 557k | } jxl::Span<float>::remove_prefix(unsigned long) Line | Count | Source | 63 | 557k | Status remove_prefix(size_t n) noexcept { | 64 | 557k | JXL_ENSURE(size() >= n); | 65 | 557k | ptr_ += n; | 66 | 557k | len_ -= n; | 67 | 557k | return true; | 68 | 557k | } |
Unexecuted instantiation: jxl::Span<unsigned char const>::remove_prefix(unsigned long) |
69 | | |
70 | | // Bounds-checked replacement for `Span<T>(span.data() + offset, count)`. |
71 | | // |
72 | | // Returns an error rather than aborting: callers derive `offset` and `count` |
73 | | // from untrusted input, so an out-of-range request is ordinary rejection of a |
74 | | // malformed file, not a programmer error. (JXL_ENSURE would be wrong here -- |
75 | | // it aborts in debug and fuzzer builds.) |
76 | | // |
77 | | // `len_ - offset` is only evaluated once `offset <= len_` is known to hold, |
78 | | // so a caller passing an underflowed `count` is rejected rather than |
79 | | // wrapping. |
80 | | StatusOr<Span<T>> subspan(size_t offset, size_t count) const { |
81 | | if (offset > len_ || count > len_ - offset) { |
82 | | return JXL_FAILURE("Span::subspan out of range"); |
83 | | } |
84 | | return Span<T>(ptr_ + offset, count); |
85 | | } |
86 | | |
87 | | // Bounds-checked suffix starting at `offset`. |
88 | | StatusOr<Span<T>> subspan(size_t offset) const { |
89 | | if (offset > len_) return JXL_FAILURE("Span::subspan out of range"); |
90 | | return Span<T>(ptr_ + offset, len_ - offset); |
91 | | } |
92 | | |
93 | 954k | void AppendTo(std::vector<NCT>& dst) const { |
94 | 954k | dst.insert(dst.end(), begin(), end()); |
95 | 954k | } |
96 | | |
97 | | std::vector<NCT> Copy() const { return std::vector<NCT>(begin(), end()); } |
98 | | |
99 | | private: |
100 | | T* ptr_; |
101 | | size_t len_; |
102 | | }; |
103 | | |
104 | | using Bytes = Span<const uint8_t>; |
105 | | |
106 | | } // namespace jxl |
107 | | |
108 | | #endif // LIB_JXL_BASE_SPAN_H_ |