Reorganize the constructors of non-owning PlaneAdapter

This commit is contained in:
mniip 2023-05-04 19:38:46 +02:00
parent 03e7826080
commit 65cf8021c9
3 changed files with 47 additions and 26 deletions

View File

@ -1,7 +1,10 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <functional>
#include <limits> #include <limits>
#include <type_traits>
#include <utility>
#include "common/Vec2.h" #include "common/Vec2.h"
@ -54,6 +57,24 @@ struct yExtent: extentStorage<Extent>
using extentStorage<Extent>::extentStorage; using extentStorage<Extent>::extentStorage;
}; };
template<typename T>
struct baseStorage
{
using type = T;
};
template<typename T>
struct baseStorage<T &>
{
using type = std::reference_wrapper<T>;
};
template<typename T>
struct baseStorage<T &&>
{
using type = std::reference_wrapper<T>;
};
// A class that contains some container T and lets you index into it as if it // A class that contains some container T and lets you index into it as if it
// were a 2D array of size Width x Height, in row-major order. // were a 2D array of size Width x Height, in row-major order.
template<typename T, size_t Width = DynamicExtent, size_t Height = DynamicExtent> template<typename T, size_t Width = DynamicExtent, size_t Height = DynamicExtent>
@ -73,8 +94,18 @@ class PlaneAdapter: xExtent<Width>, yExtent<Height>
return yExtent<Height>::getExtent(); return yExtent<Height>::getExtent();
} }
std::remove_reference_t<T> &getBase()
{
return Base;
}
std::remove_reference_t<T> const &getBase() const
{
return Base;
}
public: public:
T Base; typename baseStorage<T>::type Base;
PlaneAdapter(): PlaneAdapter():
xExtent<Width>(0), xExtent<Width>(0),
@ -82,18 +113,6 @@ public:
Base() Base()
{} {}
PlaneAdapter(PlaneAdapter const &) = default;
PlaneAdapter(PlaneAdapter &&) = default;
// PlaneAdapter<T> can be constructed from (Vec2, T &&)
// PlaneAdapter<T &> can be constructed from (Vec2, T &)
PlaneAdapter(Vec2<int> size, T &&base):
xExtent<Width>(size.X),
yExtent<Height>(size.Y),
Base(std::forward<T>(base))
{}
template<typename... Args> template<typename... Args>
PlaneAdapter(Vec2<int> size, Args&&... args): PlaneAdapter(Vec2<int> size, Args&&... args):
xExtent<Width>(size.X), xExtent<Width>(size.X),
@ -101,9 +120,12 @@ public:
Base(getWidth() * getHeight(), std::forward<Args>(args)...) Base(getWidth() * getHeight(), std::forward<Args>(args)...)
{} {}
PlaneAdapter &operator=(PlaneAdapter const &) = default; template<typename... Args>
PlaneAdapter(Vec2<int> size, std::in_place_t, Args&&... args):
PlaneAdapter &operator=(PlaneAdapter &&) = default; xExtent<Width>(size.X),
yExtent<Height>(size.Y),
Base(std::forward<Args>(args)...)
{}
Vec2<int> Size() const Vec2<int> Size() const
{ {
@ -118,31 +140,31 @@ public:
iterator RowIterator(Vec2<int> p) iterator RowIterator(Vec2<int> p)
{ {
return std::begin(Base) + (p.X + p.Y * getWidth()); return std::begin(getBase()) + (p.X + p.Y * getWidth());
} }
const_iterator RowIterator(Vec2<int> p) const const_iterator RowIterator(Vec2<int> p) const
{ {
return std::begin(Base) + (p.X + p.Y * getWidth()); return std::begin(getBase()) + (p.X + p.Y * getWidth());
} }
value_type *data() value_type *data()
{ {
return std::data(Base); return std::data(getBase());
} }
value_type const *data() const value_type const *data() const
{ {
return std::data(Base); return std::data(getBase());
} }
value_type &operator[](Vec2<int> p) value_type &operator[](Vec2<int> p)
{ {
return Base[p.X + p.Y * getWidth()]; return getBase()[p.X + p.Y * getWidth()];
} }
value_type const &operator[](Vec2<int> p) const value_type const &operator[](Vec2<int> p) const
{ {
return Base[p.X + p.Y * getWidth()]; return getBase()[p.X + p.Y * getWidth()];
} }
}; };

View File

@ -36,15 +36,15 @@ void VideoBuffer::Crop(Rect<int> rect)
if (rect == Size().OriginRect()) if (rect == Size().OriginRect())
return; return;
PlaneAdapter<std::vector<pixel> &> newVideo(rect.Size(), video.Base); PlaneAdapter<std::vector<pixel> &> newVideo(rect.Size(), std::in_place, video.Base);
for (auto y = 0; y < newVideo.Size().Y; y++) for (auto y = 0; y < newVideo.Size().Y; y++)
std::copy_n( std::copy_n(
video.RowIterator(rect.TopLeft + Vec2(0, y)), video.RowIterator(rect.TopLeft + Vec2(0, y)),
newVideo.Size().X, newVideo.Size().X,
newVideo.RowIterator(Vec2(0, y)) newVideo.RowIterator(Vec2(0, y))
); );
newVideo.Base.resize(newVideo.Size().X * newVideo.Size().Y); video.Base.resize(newVideo.Size().X * newVideo.Size().Y);
newVideo.Base.shrink_to_fit(); video.Base.shrink_to_fit();
video.SetSize(newVideo.Size()); video.SetSize(newVideo.Size());
} }

View File

@ -22,7 +22,6 @@ class VideoBuffer: public RasterDrawMethods<VideoBuffer>
friend struct RasterDrawMethods<VideoBuffer>; friend struct RasterDrawMethods<VideoBuffer>;
public: public:
VideoBuffer(VideoBuffer const &) = default;
VideoBuffer(pixel const *data, Vec2<int> size); VideoBuffer(pixel const *data, Vec2<int> size);
VideoBuffer(pixel const *data, Vec2<int> size, size_t rowStride); VideoBuffer(pixel const *data, Vec2<int> size, size_t rowStride);
VideoBuffer(Vec2<int> size); VideoBuffer(Vec2<int> size);