Skip to content

Instantly share code, notes, and snippets.

@rampion
Created April 3, 2018 02:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rampion/aef893e6ef5e25b0bb56a40911136433 to your computer and use it in GitHub Desktop.
Save rampion/aef893e6ef5e25b0bb56a40911136433 to your computer and use it in GitHub Desktop.
#include <memory>
#include <iostream>
// TODO compare w/ operator::new
namespace plan {
template <typename A, typename B>
struct Apply {
using Target = typename A::Target;
A const a;
B const b;
Apply(A const && a, B const && b) : a{a}, b{b} {};
template<typename ... Args>
Target* build(char* buf, Args ... args) const {
return a.build(buf, b.build(buf + a.size()), args...);
}
size_t size() const {
return a.size() + b.size();
}
Apply<A,B>&& operator()() {
return std::move(*this);
}
template<typename U, typename ... Vs>
auto operator()(U const && u, Vs const && ... vs) {
return Apply<Apply<A,B>,U>{std::move(*this), std::move(u)}( std::move(vs) ... );
}
};
template<typename T>
struct Lift {
using Target = T;
Lift() {}
template<typename ... Args>
Target* build(char* buf, Args ... args) const {
return new (buf) T{args...};
}
size_t size() const {
return sizeof(T);
}
Lift<T>&& operator()() {
return std::move(*this);
}
template<typename U, typename ... Vs>
auto operator()(U const && u, Vs const && ... vs) {
return Apply<Lift<T>,U>{std::move(*this), std::move(u)}( std::move(vs) ... );
}
};
template<typename T>
struct Array {
size_t const length;
Array(size_t length) : length{length} {}
T* build(char* buf) const {
return new (buf) T[length]{};
}
void destroy(char* buf) const {
((T[length]) buf).~T();
}
size_t size() const {
return sizeof(T[length]);
}
};
template <typename P>
auto heap_allocate(P plan) {
return plan.build(new char[plan.size()]);
}
}
class V4 {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
int* const x;
float* const y;
int* const z;
#pragma clang diagnostic pop
public:
V4(int* x, float* y, int* z) : x{x}, y{y}, z{z} {}
static auto Plan(size_t n, size_t m) {
return plan::Lift<V4>{}(
plan::Array<int>{n},
plan::Array<float>{n},
plan::Array<int>{m}
);
}
};
template
struct plan::Lift<V4>;
int main(int argc, char** argv) {
if (argc != 3
|| *argv[1] == '\0' || strspn(argv[1], "0123456789") < strlen(argv[1])
|| *argv[1] == '\0' || strspn(argv[2], "0123456789") < strlen(argv[2])
) {
std::cout << "Usage " << argv[0] << " <n> <m>\n";
return -1;
}
size_t n = atoi(argv[1]),
m = atoi(argv[2]);
auto v4 = std::unique_ptr<V4>{plan::heap_allocate(
V4::Plan(n,m)
)};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment