/
Plane.vxx
125 lines (111 loc) · 4.38 KB
/
Plane.vxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#pragma once
#include "RemappingFunctions.vxx"
template<typename PixelType>
struct CanvasProxy {
field(Height, 0uz);
field(Width, 0uz);
field(Stride, 0z);
field(Data, static_cast<PixelType*>(nullptr));
public:
auto operator[](auto y) const {
return Data + y * Stride;
}
};
template<typename PixelType>
struct Plane : CanvasProxy<PixelType> {
private:
using EmptyType = struct {};
struct ExistentialTypeForRemappingFunction {
using QuantificationBound = auto(std::ptrdiff_t, std::ptrdiff_t, std::size_t, std::size_t)->std::array<std::ptrdiff_t, 2>;
public:
field(HostedFunction, std::function<QuantificationBound>{});
public:
auto& operator=(AnyBut<ExistentialTypeForRemappingFunction> auto&& RemappingFunction) {
if constexpr (requires { { RemappingFunction(0z, 0z, 0uz, 0uz) }->std::same_as<std::array<std::ptrdiff_t, 2>>; })
HostedFunction = Forward(RemappingFunction);
else
HostedFunction = [RemappingFunction = Forward(RemappingFunction)](auto y, auto x, auto Height, auto Width) {
if constexpr (requires { { RemappingFunction(y, Height) }->std::same_as<std::ptrdiff_t>; })
return std::array{ RemappingFunction(y, Height), RemappingFunction(x, Width) };
else
static_assert(sizeof(RemappingFunction) == -1, "Plane: specified remapping function has an incompatible signature.");
};
return *this;
}
auto operator()(auto y, auto x, auto Height, auto Width) const {
return HostedFunction(y, x, Height, Width);
}
};
public:
static constexpr auto Readonly = std::is_const_v<PixelType>;
static inline auto DefaultRemappingFunction = [] {
if constexpr (auto PolymorphicRemappingFunction = ExistentialTypeForRemappingFunction{}; Readonly)
return PolymorphicRemappingFunction = RemappingFunctions::Reflect;
else
return EmptyType{};
}();
public:
[[no_unique_address]]
field(OutOfBoundsRemapping, DefaultRemappingFunction);
private:
struct RemappedAccess {
field(TargetPlane, static_cast<const Plane*>(nullptr));
field(yAbsolute, 0z);
field(xOffset, 0z);
public:
auto operator[](std::integral auto x) const {
if (auto xAbsolute = x + xOffset; xAbsolute < 0 || yAbsolute < 0 || xAbsolute >= TargetPlane->Width || yAbsolute >= TargetPlane->Height) {
auto [yRemapped, xRemapped] = TargetPlane->OutOfBoundsRemapping(yAbsolute, xAbsolute, TargetPlane->Height, TargetPlane->Width);
return TargetPlane->DirectAccess()[yRemapped][xRemapped];
}
else [[likely]]
return TargetPlane->DirectAccess()[yAbsolute][xAbsolute];
}
};
private:
struct OffsetView {
field(TargetPlane, static_cast<const Plane*>(nullptr));
field(yOffset, 0z);
field(xOffset, 0z);
public:
auto operator[](std::integral auto y) const {
return RemappedAccess{ .TargetPlane = TargetPlane, .yAbsolute = y + yOffset, .xOffset = xOffset };
}
auto QueryCoordinates() const {
return std::array{ yOffset, xOffset };
}
auto View(std::integral auto y, std::integral auto x) const {
return OffsetView{ .TargetPlane = TargetPlane, .yOffset = yOffset + y, .xOffset = xOffset + x };
}
public:
explicit operator auto() const {
auto StringRepresentation = std::ostringstream{};
StringRepresentation << "Resolution: " << TargetPlane->Width << " × " << TargetPlane->Height << "\n";
StringRepresentation << "Absolute Coordinates of the Origin: { y = " << yOffset << ", x = " << xOffset << " }\n";
StringRepresentation << "Sample Type: " << (std::integral<PixelType> ? "Int" : "Float") << "\n";
StringRepresentation << "Bytes Per Sample: " << sizeof(PixelType);
return StringRepresentation.str();
}
};
public:
auto operator[](std::integral auto y) const {
if constexpr (Readonly)
return RemappedAccess{ .TargetPlane = this, .yAbsolute = y };
else
return CanvasProxy<PixelType>::operator[](y);
}
auto View(std::integral auto y, std::integral auto x) const requires Readonly {
return OffsetView{ .TargetPlane = this, .yOffset = y, .xOffset = x };
}
auto& DirectAccess() const requires Readonly {
return static_cast<const CanvasProxy<PixelType>&>(*this);
}
public:
explicit operator auto() const {
auto StringRepresentation = std::ostringstream{};
StringRepresentation << "Resolution: " << this->Width << " × " << this->Height << "\n";
StringRepresentation << "Sample Type: " << (std::integral<PixelType> ? "Int" : "Float") << "\n";
StringRepresentation << "Bytes Per Sample: " << sizeof(PixelType);
return StringRepresentation.str();
}
};