I'd like to make only my implementation dependent on another header.
hdr:
// FDS.h
#include "MyMath.h"
union FancyDataStructure() {
FancyDataStructure(): state(MyIdentityMat4), fanciful(0.31337) {}
struct { MyMat4 state; float fanciful; };
struct {
MyVec4 c0;
MyVec4 c1;
MyVec4 c2;
MyVec4 c3;
float fancy;
};
}
// please pretend this has a good reason for existing
struct MyMat48() {
MyMat48() {}
MyMat48(const MyMat4& l, const MyMat4& r): left(l), right(r) {}
FancyDataStructure left;
FancyDataStructure right;
};
impl:
// FDS.cpp
#include "FDS.h"
#include "include/FlakyLib.hpp"
void init(MyMat48& instance, const FlakyLibrary::mat4& with) {
instance.left.c2 = MyVec4(
with.FlakyMat4Subscript(3),
with.FlakyMat4Subscript(1),
with.FlakyMat4Subscript(0),
with.FlakyMat4Subscript(2),
);
instance.right.fancy = with.FlakyMat4Determinant();
// This performs a crazy swizzle which demonstrates use of FlakyLib methods
}
extern std::vector<MyMat48> moreExternalState;
void doSomethingComplicatedAndFlaky() {
FlakyLibrary::mat4& m = FlakyLibrary::Oracle::Query();
MyMat48 newItem;
init(newItem, m);
moreExternalState.push_back(newItem);
}
So this should work and I can use MyMat48
in blissful ignorance in, and without linking Flaky into, whatever other compilation unit I am using FDS.h from. It achieves the goal of defining this Mat48 structure in a way that does not infect its type definition with a dependency, and yet takes advantage of functionality provided by said dependency.
But it would be Really Nice™ if I could make this less painful to construct. In particular, what feel like gymnastics involving just assigning values.
If I could have implemented init
as a "private ctor" of MyMat48
somehow, the code would be more expressive. In particular the 4 lines in the body of the last function really does perform a task I would want to squeeze into a single line.
I think I am missing some silver bullet here. I am really hoping that rvalue references could be used here. Somehow. Perhaps it wouldn't reduce the verbosity, but maybe it can make it more clear what is happening? I also question what really goes on with the temporary object, and how to ensure things (that should be) are moved and not copied.
Maybe I could design init
better...