RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
CroppedArray1DRef.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/Array1DRef.h"
25#include "adt/Invariant.h"
26#include <type_traits>
27
28namespace rawspeed {
29
30template <class T> class CroppedArray1DRef final {
32 int offset;
34
35 friend CroppedArray1DRef<const T>; // We need to be able to convert to const
36 // version.
37
38 // Only allow construction from `Array1DRef<T>::getCrop()`.
40 int numElts) const;
41
43
44public:
45 void establishClassInvariants() const noexcept;
46
47 using value_type = T;
48 using cvless_value_type = std::remove_cv_t<value_type>;
49
51
52 // Can not cast away constness.
53 template <typename T2>
54 requires(std::is_const_v<T2> && !std::is_const_v<T>)
56
57 // Can not change type.
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>>)
62
63 // Conversion from CroppedArray1DRef<T> to CroppedArray1DRef<const T>.
64 template <typename T2>
65 requires(!std::is_const_v<T2> && std::is_const_v<T> &&
66 std::is_same_v<std::remove_const_t<T>, std::remove_const_t<T2>>)
67 CroppedArray1DRef( // NOLINT(google-explicit-constructor)
68 CroppedArray1DRef<T2> RHS)
69 : CroppedArray1DRef(RHS.base, RHS.offset, RHS.numElts) {}
70
71 [[nodiscard]] Array1DRef<T> getAsArray1DRef() const {
72 return {begin(), size()};
73 }
74
75 [[nodiscard]] CroppedArray1DRef<T> getCrop(int offset, int numElts) const;
76 [[nodiscard]] CroppedArray1DRef<T> getBlock(int size, int index) const;
77
78 [[nodiscard]] T* begin() const;
79 [[nodiscard]] T* end() const;
80
81 [[nodiscard]] int RAWSPEED_READONLY size() const;
82
83 [[nodiscard]] T* addressOf(int eltIdx) const;
84 [[nodiscard]] T& operator()(int eltIdx) const;
85};
86
87// CTAD deduction guide
88template <typename T>
90 int numElts) -> CroppedArray1DRef<T>;
91
92template <class T>
93__attribute__((always_inline)) inline void
96 invariant(offset >= 0);
97 invariant(numElts >= 0);
98 invariant(offset <= base.size());
99 invariant(numElts <= base.size());
100 invariant(offset + numElts <= base.size());
101}
102
103template <class T>
105 const int offset_,
106 const int numElts_)
107 : base(base_), offset(offset_), numElts(numElts_) {
108 establishClassInvariants();
109}
110
111template <class T>
112[[nodiscard]] inline CroppedArray1DRef<T>
113CroppedArray1DRef<T>::getCrop(int additionalOffset, int size) const {
115 invariant(additionalOffset >= 0);
116 invariant(size >= 0);
117 invariant(additionalOffset <= numElts);
119 invariant(additionalOffset + size <= numElts);
120 return base.getCrop(offset + additionalOffset, size);
121}
122
123template <class T>
124[[nodiscard]] inline CroppedArray1DRef<T>
127 invariant(index >= 0);
128 invariant(size >= 0);
129 invariant(index <= numElts);
131 const int additionalOffset = size * index;
132 invariant(additionalOffset <= numElts);
133 invariant(additionalOffset + size <= numElts);
134 return getCrop(additionalOffset, size);
135}
136
137template <class T> inline T* CroppedArray1DRef<T>::begin() const {
139 return addressOf(/*eltIdx=*/0);
140}
141template <class T> inline T* CroppedArray1DRef<T>::end() const {
143 return addressOf(/*eltIdx=*/numElts);
144}
145
146template <class T> inline int CroppedArray1DRef<T>::size() const {
148 return numElts;
149}
150
151template <class T>
152inline T* CroppedArray1DRef<T>::addressOf(const int eltIdx) const {
154 invariant(eltIdx >= 0);
155 invariant(eltIdx <= numElts);
156 return base.addressOf(offset + eltIdx);
157}
158
159template <class T>
160inline T& CroppedArray1DRef<T>::operator()(const int eltIdx) const {
162 invariant(eltIdx >= 0);
163 invariant(eltIdx < numElts);
164 return *addressOf(eltIdx);
165}
166
167} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
CroppedArray1DRef< T > getCrop(int offset, int numElts) const
Definition Array1DRef.h:110
CroppedArray1DRef< T > getCrop(int offset, int numElts) const
int RAWSPEED_READONLY size() const
std::remove_cv_t< value_type > cvless_value_type
Array1DRef< T > getAsArray1DRef() const
T & operator()(int eltIdx) const
T * addressOf(int eltIdx) const
CroppedArray1DRef(Array1DRef< T > base, int offset, int numElts)
friend CroppedArray1DRef< T > Array1DRef(int offset, int numElts) const
CroppedArray1DRef< T > getBlock(int size, int index) const
void establishClassInvariants() const noexcept
CroppedArray1DRef(Array1DRef< T > base, int offset, int numElts) -> CroppedArray1DRef< T >
throw T(buf.data())
__attribute__((noinline)) __attribute__((visibility("default"))) JPEGStuffedByteStreamGenerator