Skip to content

Instantly share code, notes, and snippets.

@BillyONeal
Created June 12, 2018 01:44
Show Gist options
  • Save BillyONeal/9fc77c6f3a5c06e39fec9d46f54ec939 to your computer and use it in GitHub Desktop.
Save BillyONeal/9fc77c6f3a5c06e39fec9d46f54ec939 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <utility>
#include <execution>
#include <algorithm>
struct fuel {
fuel() = delete;
explicit fuel(int) {};
fuel(const fuel&) = delete;
fuel& operator=(const fuel&) = delete;
};
struct enriched_fuel {
enriched_fuel() = delete;
explicit enriched_fuel(int) {};
enriched_fuel(const enriched_fuel&) = delete;
enriched_fuel& operator=(const enriched_fuel&) = delete;
};
struct radioactive_waste {
bool empty = false;
radioactive_waste() = delete;
explicit radioactive_waste(int) {}
radioactive_waste(const radioactive_waste&) = delete;
radioactive_waste& operator=(const radioactive_waste&) = delete;
~radioactive_waste() {
assert(empty);
}
void magic() {
empty = true;
}
};
struct radioactive_waste_container {
bool empty = false;
radioactive_waste_container() = delete;
explicit radioactive_waste_container(int) {}
/* implicit */ radioactive_waste_container(radioactive_waste&& waste) {
waste.magic();
}
radioactive_waste_container(const radioactive_waste_container&) = delete;
radioactive_waste_container(radioactive_waste_container&& o) {
o.magic();
}
radioactive_waste_container& operator=(const radioactive_waste_container&) = delete;
// I think my implementation has a bug and it should work without this thing being
// MoveAssignable, and only assignable from radioactive_waste&&...
// This is because I call the serial transform_reduce inside the parallel one but
// I should probably make a version that writes to an init&
radioactive_waste_container& operator=(radioactive_waste_container&& cont) {
assert(empty);
empty = std::exchange(cont.empty, true);
return *this;
}
~radioactive_waste_container() {
assert(empty);
}
void magic() {
empty = true;
}
};
const auto enrich = [](const fuel&) { return enriched_fuel(42); };
struct fission {
radioactive_waste operator()(radioactive_waste_container&& lhs,
radioactive_waste_container&& rhs) {
lhs.magic();
rhs.magic();
return radioactive_waste(42);
}
radioactive_waste operator()(radioactive_waste_container&& lhs,
const enriched_fuel&) {
lhs.magic();
return radioactive_waste(42);
}
radioactive_waste operator()(const enriched_fuel&,
radioactive_waste_container&& rhs) {
rhs.magic();
return radioactive_waste(42);
}
radioactive_waste operator()(const enriched_fuel&, const enriched_fuel&) {
return radioactive_waste(42);
}
};
int main() {
fuel in[10] = {fuel{42}, fuel{42}, fuel{42}, fuel{42}, fuel{42}, fuel{42}, fuel{42}, fuel{42}, fuel{42}, fuel{42}};
{
radioactive_waste_container out(std::transform_reduce(std::begin(in), std::end(in),
radioactive_waste_container(42), fission{}, enrich));
out.magic();
}
{
radioactive_waste_container out(std::transform_reduce(std::execution::par, std::begin(in), std::end(in),
radioactive_waste_container(42), fission{}, enrich));
out.magic();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment