I am looking at using std::variant
to store basic types such as float, int, float2, float2, bool2, bool4, etc. which is rather trivial, but I would also ideally like to construct variant objects holding a pointer to a typed array. I came up with this solution, which compiles and run without crashing (which doesn't mean a bug isn't in there)):
#include <variant>
#include <vector>
#include <iostream>
#include <algorithm>
struct float3
{
float x, y, z;
float3() : x(0), y(0), z(0) {}
float3(const float& r) : x(r), y(r), z(r) {}
};
int main()
{
typedef std::variant<float, float3, float3*> Variant;
std::vector<float3> v(3);
std::generate(v.begin(), v.end(), [n=0] () mutable { return ++n; });
Variant var(&v[0]);
if (float3** ptr = std::get_if<float3*>(&var)) {
std::cout << "this is a float3*: " << (*ptr)[0].x << std::endl;
}
else {
std::cout << "didn't recognize type\n";
}
return 0;
};
However, by doing so, I lose some additional data that I'd like to store alongside this particular variant type such as the size of the array (in a number of bytes for example). Would it best to write my own custom Variant class and create a constructor like this:
class Variant
{
public:
enum Type
{
...
FLOAT,
FLOAT2,
FLOAT3,
...
};
Variant(std::shared_ptr<void*>& ptr, Type type, size_t size, size_t stride, ...) :
type(Type),
data(new Data(ptr, size, stride, ...))
{}
std::shared_ptr<Data> data;
};
With class Data
class Data
{
public:
Data(const std::shared_ptr<void*>& ptr, size_t nb, size_t stride, ...) :
ptr(ptr), nbytes(nb), stride(stride) ... {}
std::shared_ptr<void*> ptr;
size_t nbytes;
size_t stride;
...
}
Or can I still somehow make it work with std::variant? Any suggestions would be greatly appreciated.