RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
Array1DRef.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2023 Roman Lebedev
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#pragma once
22
23#include "rawspeedconfig.h"
24#include "adt/Invariant.h"
25#include <cstddef>
26#include <type_traits>
27
28namespace rawspeed {
29
30template <class T> class CroppedArray1DRef;
31
32template <class T> class Array1DRef final {
35
36 friend Array1DRef<const T>; // We need to be able to convert to const version.
37
38 // We need to be able to convert to std::byte.
41
42public:
43 void establishClassInvariants() const noexcept;
44
45 using value_type = T;
46 using cvless_value_type = std::remove_cv_t<value_type>;
47
48 Array1DRef() = delete;
49
51
52 // Can not cast away constness.
53 template <typename T2>
54 requires(std::is_const_v<T2> && !std::is_const_v<T>)
55 Array1DRef(Array1DRef<T2> RHS) = delete;
56
57 // Can not change type to non-byte.
58 template <typename T2>
59 requires(!(std::is_const_v<T2> && !std::is_const_v<T>) &&
60 !std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T2>> &&
61 !std::is_same_v<std::remove_const_t<T>, std::byte>)
62 Array1DRef(Array1DRef<T2> RHS) = delete;
63
64 // Conversion from Array1DRef<T> to Array1DRef<const T>.
65 template <typename T2>
66 requires(!std::is_const_v<T2> && std::is_const_v<T> &&
67 std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T2>>)
68 Array1DRef(Array1DRef<T2> RHS) // NOLINT(google-explicit-constructor)
69 : Array1DRef(RHS.data, RHS.numElts) {}
70
71 // Const-preserving conversion from Array1DRef<T> to Array1DRef<std::byte>.
72 template <typename T2>
73 requires(
74 !(std::is_const_v<T2> && !std::is_const_v<T>) &&
75 !(std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T2>>) &&
76 std::is_same_v<std::remove_const_t<T>, std::byte>)
77 Array1DRef(Array1DRef<T2> RHS) // NOLINT(google-explicit-constructor)
78 : Array1DRef(reinterpret_cast<T*>(RHS.data), sizeof(T2) * RHS.numElts) {}
79
80 [[nodiscard]] CroppedArray1DRef<T> getCrop(int offset, int numElts) const;
81 [[nodiscard]] CroppedArray1DRef<T> getBlock(int numElts, int index) const;
82
83 [[nodiscard]] int RAWSPEED_READONLY size() const;
84
85 [[nodiscard]] T* addressOf(int eltIdx) const;
86 [[nodiscard]] T& operator()(int eltIdx) const;
87
88 [[nodiscard]] T* begin() const;
89 [[nodiscard]] T* end() const;
90};
91
92// CTAD deduction guide
93template <typename T> Array1DRef(T* data_, int numElts_) -> Array1DRef<T>;
94
95template <class T>
96__attribute__((always_inline)) inline void
98 invariant(data);
99 invariant(numElts >= 0);
100}
101
102template <class T>
103inline Array1DRef<T>::Array1DRef(T* data_, const int numElts_)
104 : data(data_), numElts(numElts_) {
105 establishClassInvariants();
106}
107
108template <class T>
109[[nodiscard]] inline CroppedArray1DRef<T>
110Array1DRef<T>::getCrop(int offset, int size) const {
112 invariant(offset >= 0);
113 invariant(size >= 0);
114 invariant(offset <= numElts);
116 invariant(offset + size <= numElts);
117 return {*this, offset, size};
118}
119
120template <class T>
121[[nodiscard]] inline CroppedArray1DRef<T>
122Array1DRef<T>::getBlock(int size, int index) const {
124 invariant(index >= 0);
125 invariant(size >= 0);
126 invariant(index <= numElts);
128 return getCrop(size * index, size);
129}
130
131template <class T>
132__attribute__((always_inline)) inline T*
133Array1DRef<T>::addressOf(const int eltIdx) const {
134 establishClassInvariants();
135 invariant(eltIdx >= 0);
136 invariant(eltIdx <= numElts);
137#pragma GCC diagnostic push
138#pragma GCC diagnostic ignored "-Wpragmas"
139#pragma GCC diagnostic ignored "-Wunknown-warning-option"
140#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
141 return data + eltIdx;
142#pragma GCC diagnostic pop
143}
144
145template <class T>
146__attribute__((always_inline)) inline T&
147Array1DRef<T>::operator()(const int eltIdx) const {
148 establishClassInvariants();
149 invariant(eltIdx >= 0);
150 invariant(eltIdx < numElts);
151 return *addressOf(eltIdx);
152}
153
154template <class T> inline int Array1DRef<T>::size() const {
155 establishClassInvariants();
156 return numElts;
157}
158
159template <class T> inline T* Array1DRef<T>::begin() const {
160 establishClassInvariants();
161 return addressOf(/*eltIdx=*/0);
162}
163template <class T> inline T* Array1DRef<T>::end() const {
164 establishClassInvariants();
165 return addressOf(/*eltIdx=*/numElts);
166}
167
168} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
bool RAWSPEED_READNONE __attribute__((visibility("default"))) benchmarkDryRun()
Definition Common.cpp:35
T * addressOf(int eltIdx) const
CroppedArray1DRef< T > getCrop(int offset, int numElts) const
Definition Array1DRef.h:110
CroppedArray1DRef< T > getBlock(int numElts, int index) const
Definition Array1DRef.h:122
T * end() const
T * begin() const
T & operator()(int eltIdx) const
Array1DRef()=delete
int RAWSPEED_READONLY size() const
void establishClassInvariants() const noexcept
std::remove_cv_t< value_type > cvless_value_type
Definition Array1DRef.h:46
T * addressOf(int eltIdx) const
CroppedArray1DRef< T > getCrop(int offset, int numElts) const
Definition Array1DRef.h:110
Array1DRef(Array1DRef< T2 > RHS)
Definition Array1DRef.h:77
T & operator()(int eltIdx) const
int RAWSPEED_READONLY size() const
throw T(buf.data())
__attribute__((noinline)) __attribute__((visibility("default"))) JPEGStuffedByteStreamGenerator
Array1DRef(T *data_, int numElts_) -> Array1DRef< T >