Skip to content

Commit 94f01cc

Browse files
committed
Array2DRef: store Array1DRef internally, not a pointer
1 parent f374c42 commit 94f01cc

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed

src/librawspeed/adt/Array2DRef.h

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#pragma once
2323

2424
#include "adt/Array1DRef.h"
25+
#include "adt/CroppedArray1DRef.h" // IWYU pragma: keep
2526
#include "adt/Invariant.h"
2627
#include "adt/Optional.h"
2728
#include <cstddef>
@@ -31,7 +32,7 @@
3132
namespace rawspeed {
3233

3334
template <class T> class Array2DRef final {
34-
T* _data;
35+
Array1DRef<T> data;
3536
int _pitch;
3637

3738
friend Array2DRef<const T>; // We need to be able to convert to const version.
@@ -40,6 +41,8 @@ template <class T> class Array2DRef final {
4041
friend Array2DRef<std::byte>;
4142
friend Array2DRef<const std::byte>;
4243

44+
Array2DRef(Array1DRef<T> data, int width, int height, int pitch);
45+
4346
public:
4447
void establishClassInvariants() const noexcept;
4548

@@ -51,7 +54,9 @@ template <class T> class Array2DRef final {
5154

5255
Array2DRef() = delete;
5356

54-
Array2DRef(T* data, int width, int height, int pitch = 0);
57+
Array2DRef(T* data, int width, int height, int pitch);
58+
59+
Array2DRef(T* data, int width, int height);
5560

5661
// Can not cast away constness.
5762
template <typename T2>
@@ -70,7 +75,7 @@ template <class T> class Array2DRef final {
7075
requires(!std::is_const_v<T2> && std::is_const_v<T> &&
7176
std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T2>>)
7277
Array2DRef(Array2DRef<T2> RHS) // NOLINT google-explicit-constructor
73-
: _data(RHS._data), _pitch(RHS._pitch), width(RHS.width),
78+
: data(RHS.data), _pitch(RHS._pitch), width(RHS.width),
7479
height(RHS.height) {}
7580

7681
// Const-preserving conversion from Array2DRef<T> to Array2DRef<std::byte>.
@@ -80,7 +85,7 @@ template <class T> class Array2DRef final {
8085
std::remove_const_t<T2>>) &&
8186
std::is_same_v<std::remove_const_t<T>, std::byte>)
8287
Array2DRef(Array2DRef<T2> RHS) // NOLINT google-explicit-constructor
83-
: _data(reinterpret_cast<T*>(RHS._data)), _pitch(sizeof(T2) * RHS._pitch),
88+
: data(RHS.data), _pitch(sizeof(T2) * RHS._pitch),
8489
width(sizeof(T2) * RHS.width), height(RHS.height) {}
8590

8691
template <typename AllocatorType =
@@ -102,26 +107,47 @@ template <class T> class Array2DRef final {
102107

103108
// CTAD deduction guide
104109
template <typename T>
105-
explicit Array2DRef(T* data, int width, int height, int pitch = 0)
110+
explicit Array2DRef(Array1DRef<T> data, int width, int height, int pitch)
106111
-> Array2DRef<T>;
107112

113+
// CTAD deduction guide
114+
template <typename T>
115+
explicit Array2DRef(T* data, int width, int height, int pitch) -> Array2DRef<T>;
116+
117+
// CTAD deduction guide
118+
template <typename T>
119+
explicit Array2DRef(T* data, int width, int height) -> Array2DRef<T>;
120+
108121
template <class T>
109122
inline void Array2DRef<T>::establishClassInvariants() const noexcept {
110-
invariant(_data);
123+
data.establishClassInvariants();
111124
invariant(width >= 0);
112125
invariant(height >= 0);
113126
invariant(_pitch >= 0);
114127
invariant(_pitch >= width);
115128
invariant((width == 0) == (height == 0));
116129
invariant((_pitch == 0) == (width == 0));
117130
invariant((_pitch == 0) == (height == 0));
131+
invariant(data.size() == _pitch * height);
132+
}
133+
134+
template <class T>
135+
Array2DRef<T>::Array2DRef(Array1DRef<T> data_, const int width_,
136+
const int height_, const int pitch_)
137+
: data(data_), _pitch(pitch_), width(width_), height(height_) {
138+
establishClassInvariants();
139+
}
140+
141+
template <class T>
142+
Array2DRef<T>::Array2DRef(T* data_, const int width_, const int height_,
143+
const int pitch_)
144+
: Array2DRef({data_, pitch_ * height_}, width_, height_, pitch_) {
145+
establishClassInvariants();
118146
}
119147

120148
template <class T>
121-
Array2DRef<T>::Array2DRef(T* data, const int width_, const int height_,
122-
const int pitch_ /* = 0 */)
123-
: _data(data), _pitch(pitch_ == 0 ? width_ : pitch_), width(width_),
124-
height(height_) {
149+
Array2DRef<T>::Array2DRef(T* data_, const int width_, const int height_)
150+
: Array2DRef(data_, width_, height_, /*pitch=*/width_) {
125151
establishClassInvariants();
126152
}
127153

@@ -130,7 +156,7 @@ template <class T>
130156
Array2DRef<T>::getAsArray1DRef() const {
131157
establishClassInvariants();
132158
if (height == 1 || _pitch == width)
133-
return {{_data, width * height}};
159+
return data.getCrop(/*offset=*/0, width * height).getAsArray1DRef();
134160
return std::nullopt;
135161
}
136162

@@ -139,12 +165,7 @@ inline Array1DRef<T> Array2DRef<T>::operator[](const int row) const {
139165
establishClassInvariants();
140166
invariant(row >= 0);
141167
invariant(row < height);
142-
#pragma GCC diagnostic push
143-
#pragma GCC diagnostic ignored "-Wpragmas"
144-
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
145-
#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
146-
return Array1DRef<T>(&_data[row * _pitch], width);
147-
#pragma GCC diagnostic pop
168+
return data.getCrop(row * _pitch, width).getAsArray1DRef();
148169
}
149170

150171
template <class T>

0 commit comments

Comments
 (0)