Created
June 12, 2018 01:44
-
-
Save BillyONeal/9fc77c6f3a5c06e39fec9d46f54ec939 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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