dl
dl_vector2.h
浏览该文件的文档.
1
15#pragma once
16
17#include <cstddef>
18#include <vector>
19#include <cassert>
20#include <span>
21
22#include "dl_type.h"
24#include "math/dl_math.h"
25
26namespace dl
27{
29template<typename T, typename Index = unsigned>
31{
32public:
34 using PointU = Size;
39 _w{ 0 }
40 {}
41
46 {
47 _init(size);
48 }
49
53 Vector2(const Size& size, const T* p)
54 {
55 _init(size);
56
57 for (size_t i = 0; i < _data.size(); ++i)
58 {
59 _data[i] = *(p + i);
60 }
61 }
62
65 Vector2(const Vector2& b)
66 {
67 this->operator=(b);
68 }
69
74 void Resize(const Size& size)
75 {
76 Vector2 temp{ *this };
77
78 _init(size);
79 Fill({});
80
81 CopyCross(temp);
82 }
83
85 {
86 if (this == &b)
87 return *this;
88
89 _data = b._data;
90 _w = b._w;
91 _rebuild_ptr_line((Index)b._ptrLine.size());
92 return *this;
93 }
94
98 std::span<T> operator[](Index j)
99 {
100 assert(j < _ptrLine.size());
101 return { _ptrLine[j], _w };
102 }
103
106 const std::span<T> operator[](Index j) const
107 {
108 assert(j < _ptrLine.size());
109 return { _ptrLine[j], _w };
110 }
111
116 /*T& operator[](std::size_t j, std::size_t i)
117 {
118 assert(j < _ptrLine.size());
119 assert(i < _w);
120 return _ptrLine[j][i];
121 }*/
122
123 const T& Get(Index j, Index i) const
124 {
125 assert(j < _ptrLine.size());
126 assert(i < _w);
127 return _ptrLine[j][i];
128 }
129 const T& Get(const PointU& xy) const
130 {
131 return Get(xy[1], xy[0]);
132 }
133 T& GetRef(Index j, Index i)
134 {
135 assert(j < _ptrLine.size());
136 assert(i < _w);
137 return _ptrLine[j][i];
138 }
139 T& GetRef(const PointU& xy)
140 {
141 return GetRef(xy[1], xy[0]);
142 }
143
146 T* GetPointer(Index j, Index i)
147 {
148 if (j >= _ptrLine.size()
149 || i >= _w)
150 return nullptr;
151 return &_ptrLine[j][i];
152 }
153 T* GetPointer(const PointU& xy)
154 {
155 return GetPointer(xy[1], xy[0]);
156 }
157 T* GetPointerOffset(const PointU& xy, const Point& offset)
158 {
159 Point xy_out = toPoint(xy) + offset;
160 if (xy_out[0] < 0 || xy_out[1] < 0)
161 return nullptr;
162 return GetPointer((Index)xy_out[1], (Index)xy_out[0]);
163 }
164
165 void Set(Index j, Index i, const T& v)
166 {
167 assert(j < _ptrLine.size());
168 assert(i < _w);
169 _ptrLine[j][i] = v;
170 }
171
175 void Fill(const T& v)
176 {
177 for (auto& iter : _data)
178 iter = v;
179 }
180 void Clear()
181 {
182 _data.clear();
183 _w = 0;
184 _ptrLine.clear();
185 }
186
190 void CopyCross(const Vector2& b)
191 {
192 Index i_max = (std::min)(_w, b._w);
193 Index j_max = (Index)(std::min)(_ptrLine.size(), b._ptrLine.size());
194 for(Index j = 0; j < j_max; ++j)
195 for (Index i = 0; i < i_max; ++i)
196 {
197 GetRef(j, i) = b.Get(j, i);
198 }
199 }
200
204 void PushBack(std::vector<T>& vec)
205 {
206 assert(vec.size() == _w);
207 _data.insert(_data.end(), vec.begin(), vec.end());
208 _rebuild_ptr_line((Index)_ptrLine.size() + 1);
209 }
210
211
212 bool IsEmpty() const { return _data.empty(); }
213
214 const std::byte* GetBuffer() const
215 {
216 return (const std::byte*)_data.data();
217 }
218
220 {
221 return _data.data();
222 }
223
224 const T* GetData() const
225 {
226 return _data.data();
227 }
228
229 Index GetWidth() const
230 {
231 return _w;
232 }
233
234 Index GetHeight() const
235 {
236 return (Index)_ptrLine.size();
237 }
238
239 Size GetSize() const
240 {
241 return { GetWidth(), GetHeight() };
242 }
243
244 // 由于标准库 size与 length等价,不使用length命名
245 Index GetSizeMul() const
246 {
247 return GetWidth() * GetHeight();
248 }
249
251 {
252 return (Index)(_data.size() * sizeof(T));
253 }
254
255 auto begin()
256 {
257 return _data.begin();
258 }
259 auto end()
260 {
261 return _data.end();
262 }
263 void reserve(size_t i)
264 {
265 _data.reserve(i);
266 }
267 void emplace_back(T&& t)
268 {
269 _data.emplace_back(t);
270 }
271 size_t size() const
272 {
273 return _data.size();
274 }
275 // 顺时针旋转90度
277 {
278 Vector2 ret;
279 ret.Resize({ v.GetHeight(), v.GetWidth() });
280
281 for (Index j = 0; j < v.GetHeight(); ++j)
282 {
283 for (Index i = 0; i < v.GetWidth(); ++i)
284 {
285 ret[i][v.GetHeight() - j - 1] = v[j][i];
286 }
287 }
288 return ret;
289 }
290private:
291 std::vector<T> _data;
292 Index _w;// 宽
293 std::vector<T*> _ptrLine; // 行指针
294
295 void _init(const Size& size)
296 {
297 _w = size[0];
298 _data.resize(Accumulate::Mul(size));
299 _rebuild_ptr_line(size[1]);
300 }
301 // 重建行指针
302 void _rebuild_ptr_line(Index h)
303 {
304 _ptrLine.resize(h);
305 for (Index i = 0; i < _ptrLine.size(); ++i)
306 _ptrLine[i] = _data.data() + i * _w;
307 }
308};
309
310
311}
const std::byte * GetBuffer() const
Array< Index, 2 > Size
void emplace_back(T &&t)
void Resize(const Size &size)
调整为指定大小
Index GetHeight() const
void CopyCross(const Vector2 &b)
从b拷贝重复的面积
const T * GetData() const
void PushBack(std::vector< T > &vec)
插入行
Index GetSizeMul() const
T * GetPointerOffset(const PointU &xy, const Point &offset)
T * GetPointer(Index j, Index i)
返回元素地址,失败返回空
Vector2(const Size &size, const T *p)
以指定大小构造,并传入指针赋值初始化
Index GetWidth() const
T & GetRef(Index j, Index i)
const std::span< T > operator[](Index j) const
返回第j行
Vector2()
空构造
const T & Get(Index j, Index i) const
返回第j行 第i个
T & GetRef(const PointU &xy)
void reserve(size_t i)
static Vector2 RotateRightAngle1(const Vector2 &v)
Size GetSize() const
T * GetPointer(const PointU &xy)
Vector2(const Size &size)
以指定大小构造
Vector2(const Vector2 &b)
复制构造 todo
bool IsEmpty() const
const T & Get(const PointU &xy) const
std::span< T > operator[](Index j)
返回第j行
Vector2 & operator=(const Vector2 &b)
void Set(Index j, Index i, const T &v)
数学相关的通用算法
通用类型
constexpr auto Mul(const C &container)
求积product
constexpr Array< Point::value_type, N > toPoint(const Array< T, N > &a)
转换到Point,已知长度
PointU Size
Point2 Point