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
#include <cstdint>
#include <functional>
#include <limits>
#include <type_traits>
#include <utility>
#include "common/Vec2.h"
@ -54,6 +57,24 @@ struct yExtent: extentStorage<Extent>
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
// were a 2D array of size Width x Height, in row-major order.
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();
}
std::remove_reference_t<T> &getBase()
{
return Base;
}
std::remove_reference_t<T> const &getBase() const
{
return Base;
}
public:
T Base;
typename baseStorage<T>::type Base;
PlaneAdapter():
xExtent<Width>(0),
@ -82,18 +113,6 @@ public:
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>
PlaneAdapter(Vec2<int> size, Args&&... args):
xExtent<Width>(size.X),
@ -101,9 +120,12 @@ public:
Base(getWidth() * getHeight(), std::forward<Args>(args)...)
{}
PlaneAdapter &operator=(PlaneAdapter const &) = default;
PlaneAdapter &operator=(PlaneAdapter &&) = default;
template<typename... Args>
PlaneAdapter(Vec2<int> size, std::in_place_t, Args&&... args):
xExtent<Width>(size.X),
yExtent<Height>(size.Y),
Base(std::forward<Args>(args)...)
{}
Vec2<int> Size() const
{
@ -118,31 +140,31 @@ public:
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
{
return std::begin(Base) + (p.X + p.Y * getWidth());
return std::begin(getBase()) + (p.X + p.Y * getWidth());
}
value_type *data()
{
return std::data(Base);
return std::data(getBase());
}
value_type const *data() const
{
return std::data(Base);
return std::data(getBase());
}
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
{
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())
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++)
std::copy_n(
video.RowIterator(rect.TopLeft + Vec2(0, y)),
newVideo.Size().X,
newVideo.RowIterator(Vec2(0, y))
);
newVideo.Base.resize(newVideo.Size().X * newVideo.Size().Y);
newVideo.Base.shrink_to_fit();
video.Base.resize(newVideo.Size().X * newVideo.Size().Y);
video.Base.shrink_to_fit();
video.SetSize(newVideo.Size());
}

View File

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