Skip to content

Instantly share code, notes, and snippets.

@ktbarrett
Last active November 19, 2019 06:23
Show Gist options
  • Save ktbarrett/0617bf6171406df46e8b560370029059 to your computer and use it in GitHub Desktop.
Save ktbarrett/0617bf6171406df46e8b560370029059 to your computer and use it in GitHub Desktop.
unique_handle and xtransform
struct no_delete {
template <typename T>
void operator() (T*) {}
};
template <typename T>
using unique_handle = std::unique_ptr<T, no_delete>;
template <typename T>
auto get_handle_to(T& a) {
return unique_handle<T>(&a);
}
template <typename I, size_t SZ, typename F>
auto xtransform(unique_handle<std::array<I, SZ>>& in, F&& func)
{
using O = std::result_of_t<F(I&)>;
static_assert((sizeof(O) == sizeof(I)) &&
(alignof(O) == alignof(I)),
"Input and Output Types are Incompatible");
auto out = unique_handle<std::array<O, SZ>>(reinterpret_cast<std::array<O, SZ>*>(in.get()));
std::transform(std::begin(*in), std::end(*in), std::begin(*out), [&func](auto& a){
O r = func(a);
a.~I();
return r;
});
in.release();
return out;
}
template <typename I, size_t SZ, typename I2, typename F>
auto xtransform(unique_handle<std::array<I, SZ>>& in, const unique_handle<std::array<I2, SZ>>& in2, F&& func)
{
using O = std::result_of_t<F(I&, I2&)>;
static_assert((sizeof(O) == sizeof(I)) &&
(alignof(O) == alignof(I)),
"Input and Output Types are Incompatible");
auto out = unique_handle<std::array<O, SZ>>(reinterpret_cast<std::array<O, SZ>*>(in.get()));
std::transform(std::begin(*in), std::end(*in), std::begin(*in2), std::begin(*out), [&func](auto& a, auto& b){
O r = func(a, b);
a.~I();
return r;
});
in.release();
return out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment