3CA67MIKCW5GPY5JCDR47ELVGGBOUNYV7SCA3XOMUXXOKDGWIBWQC
2WYS7YX7HXX2MAGIAJ63JFAP74O5Q26MQCT6KPLSEEXKT27PKOJAC
Q4BI3KHPY7G275UHURXZ23GQTMCI7OQAVQOFK7XR62KFH7SFHRQQC
FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC
722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC
BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC
KG47IF4CPCUT3BHS34WDRHTH5HYMBTY4OSTB3X7APR2E5ZJ32IYQC
BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC
T3TZRPPAIA24I3YL3JFB4XEAYCWU3HJAJUCF7NNIFMP4I5X4SM5QC
KN5Z747NMDBSXQHVGLLYQKCOW5423HDAYDCMIR6RTZZMICMCPN3AC
LHPZHX4FMRYBM7NI22QTP3VZDBYFRSNTY3L6BEEFPPF5KWCFFIHQC
KOOPA77MHDMNHAKH7YXUD2POVQCT3R2HHDHEFBW3G7MVM7QJQVYAC
JN2TPHENEBIY2OE5FRCQ2E6QCL6FPVHJHUCP4UODD6DITRVV2LIQC
3I2VE3RJ4E4WZZSUGJKOMHP2FKOAZA6SLVMVYE3B54SZCYXGIU4QC
GKKJ75HX2ERLVBZVE2CUB6T3J2SUT7R3UKEKTEYNOG43ZKX6X5MQC
struct valid_t {
bool valid_int, valid_outer, valid_ghosts;
constexpr valid_t() : valid_t(false) {}
explicit constexpr valid_t(bool b)
: valid_int(b), valid_outer(b), valid_ghosts(b) {}
friend constexpr valid_t operator~(const valid_t &x) {
valid_t r;
r.valid_int = !x.valid_int;
r.valid_outer = !x.valid_outer;
r.valid_ghosts = !x.valid_ghosts;
return r;
}
friend constexpr valid_t operator&(const valid_t &x, const valid_t &y) {
valid_t r;
r.valid_int = x.valid_int && y.valid_int;
r.valid_outer = x.valid_outer && y.valid_outer;
r.valid_ghosts = x.valid_ghosts && y.valid_ghosts;
return r;
}
friend constexpr valid_t operator|(const valid_t &x, const valid_t &y) {
valid_t r;
r.valid_int = x.valid_int || y.valid_int;
r.valid_outer = x.valid_outer || y.valid_outer;
r.valid_ghosts = x.valid_ghosts || y.valid_ghosts;
return r;
}
valid_t &operator&=(const valid_t &x) { return *this = *this & x; }
valid_t &operator|=(const valid_t &x) { return *this = *this | x; }
constexpr bool valid_all() const {
return valid_int && valid_outer && valid_ghosts;
}
constexpr bool valid_any() const {
return valid_int || valid_outer || valid_ghosts;
}
friend bool operator==(const valid_t &x, const valid_t &y) {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) ==
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
friend bool operator<(const valid_t &x, const valid_t &y) {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) <
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
friend ostream &operator<<(ostream &os, const valid_t v) {
auto str = [](bool v) { return v ? "VAL" : "INV"; };
return os << "[int:" << str(v.valid_int) << ",outer:" << str(v.valid_outer)
<< ",ghosts:" << str(v.valid_ghosts) << "]";
}
operator string() const {
ostringstream buf;
buf << *this;
return buf.str();
}
};
inline constexpr valid_t make_valid_int() {
valid_t valid;
valid.valid_int = true;
return valid;
}
inline constexpr valid_t make_valid_outer() {
valid_t valid;
valid.valid_outer = true;
return valid;
}
inline constexpr valid_t make_valid_ghosts() {
valid_t valid;
valid.valid_ghosts = true;
return valid;
}
inline constexpr valid_t make_valid_all() { return ~valid_t(); }
} // namespace CarpetX
namespace std {
using namespace CarpetX;
template <> struct equal_to<valid_t> {
constexpr bool operator()(const valid_t &x, const valid_t &y) const {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) ==
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
};
template <> struct less<valid_t> {
constexpr bool operator()(const valid_t &x, const valid_t &y) const {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) <
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
};
} // namespace std
namespace CarpetX {
class why_valid_t {
valid_t valid;
function<string()> why_int, why_outer, why_ghosts;
public:
// The constructor that doesn't give a reason should never be called
why_valid_t() = delete;
why_valid_t(const function<string()> &why) : why_valid_t(false, why) {}
why_valid_t(bool b, const function<string()> &why)
: why_valid_t(valid_t(b), why) {}
why_valid_t(const valid_t &val, const function<string()> &why)
: valid(val), why_int(why), why_outer(why), why_ghosts(why) {}
const valid_t &get() const { return valid; }
void set(const valid_t &val, const function<string()> &why) {
auto old_valid = valid;
valid = val;
auto new_valid = valid;
if (new_valid.valid_int != old_valid.valid_int)
why_int = why;
if (new_valid.valid_outer != old_valid.valid_outer)
why_outer = why;
if (new_valid.valid_ghosts != old_valid.valid_ghosts)
why_ghosts = why;
}
void set_int(bool b, const function<string()> &why) {
auto val = valid;
val.valid_int = b;
set(val, why);
}
void set_outer(bool b, const function<string()> &why) {
auto val = valid;
val.valid_outer = b;
set(val, why);
}
void set_ghosts(bool b, const function<string()> &why) {
auto val = valid;
val.valid_ghosts = b;
set(val, why);
}
void set_and(const valid_t &val, const function<string()> &why) {
set(valid & val, why);
}
void set_or(const valid_t &val, const function<string()> &why) {
set(valid | val, why);
}
friend ostream &operator<<(ostream &os, const why_valid_t why) {
return os << why.valid << ","
<< "why{int:" << why.why_int() << ","
<< "outer:" << why.why_outer() << ","
<< "ghosts:" << why.why_ghosts() << "}";
}
operator string() const {
ostringstream buf;
buf << *this;
return buf.str();
}
};
#ifndef VALID_HXX
#define VALID_HXX
#include <functional>
#include <iostream>
#include <sstream>
#include <tuple>
namespace CarpetX {
using namespace std;
struct valid_t {
bool valid_int, valid_outer, valid_ghosts;
constexpr valid_t() : valid_t(false) {}
explicit constexpr valid_t(bool b)
: valid_int(b), valid_outer(b), valid_ghosts(b) {}
friend constexpr valid_t operator~(const valid_t &x) {
valid_t r;
r.valid_int = !x.valid_int;
r.valid_outer = !x.valid_outer;
r.valid_ghosts = !x.valid_ghosts;
return r;
}
friend constexpr valid_t operator&(const valid_t &x, const valid_t &y) {
valid_t r;
r.valid_int = x.valid_int && y.valid_int;
r.valid_outer = x.valid_outer && y.valid_outer;
r.valid_ghosts = x.valid_ghosts && y.valid_ghosts;
return r;
}
friend constexpr valid_t operator|(const valid_t &x, const valid_t &y) {
valid_t r;
r.valid_int = x.valid_int || y.valid_int;
r.valid_outer = x.valid_outer || y.valid_outer;
r.valid_ghosts = x.valid_ghosts || y.valid_ghosts;
return r;
}
valid_t &operator&=(const valid_t &x) { return *this = *this & x; }
valid_t &operator|=(const valid_t &x) { return *this = *this | x; }
constexpr bool valid_all() const {
return valid_int && valid_outer && valid_ghosts;
}
constexpr bool valid_any() const {
return valid_int || valid_outer || valid_ghosts;
}
friend bool operator==(const valid_t &x, const valid_t &y) {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) ==
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
friend bool operator<(const valid_t &x, const valid_t &y) {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) <
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
friend ostream &operator<<(ostream &os, const valid_t v) {
auto str = [](bool v) { return v ? "VAL" : "INV"; };
return os << "[int:" << str(v.valid_int) << ",outer:" << str(v.valid_outer)
<< ",ghosts:" << str(v.valid_ghosts) << "]";
}
operator string() const {
ostringstream buf;
buf << *this;
return buf.str();
}
};
inline constexpr valid_t make_valid_int() {
valid_t valid;
valid.valid_int = true;
return valid;
}
inline constexpr valid_t make_valid_outer() {
valid_t valid;
valid.valid_outer = true;
return valid;
}
inline constexpr valid_t make_valid_ghosts() {
valid_t valid;
valid.valid_ghosts = true;
return valid;
}
inline constexpr valid_t make_valid_all() { return ~valid_t(); }
} // namespace CarpetX
namespace std {
using namespace CarpetX;
template <> struct equal_to<valid_t> {
constexpr bool operator()(const valid_t &x, const valid_t &y) const {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) ==
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
};
template <> struct less<valid_t> {
constexpr bool operator()(const valid_t &x, const valid_t &y) const {
return make_tuple(x.valid_int, x.valid_outer, x.valid_ghosts) <
make_tuple(y.valid_int, y.valid_outer, y.valid_ghosts);
}
};
} // namespace std
namespace CarpetX {
class why_valid_t {
valid_t valid;
function<string()> why_int, why_outer, why_ghosts;
public:
// The constructor that doesn't give a reason should never be called
why_valid_t() = delete;
why_valid_t(const function<string()> &why) : why_valid_t(false, why) {}
why_valid_t(bool b, const function<string()> &why)
: why_valid_t(valid_t(b), why) {}
why_valid_t(const valid_t &val, const function<string()> &why)
: valid(val), why_int(why), why_outer(why), why_ghosts(why) {}
const valid_t &get() const { return valid; }
void set(const valid_t &val, const function<string()> &why) {
auto old_valid = valid;
valid = val;
auto new_valid = valid;
if (new_valid.valid_int != old_valid.valid_int)
why_int = why;
if (new_valid.valid_outer != old_valid.valid_outer)
why_outer = why;
if (new_valid.valid_ghosts != old_valid.valid_ghosts)
why_ghosts = why;
}
void set_int(bool b, const function<string()> &why) {
auto val = valid;
val.valid_int = b;
set(val, why);
}
void set_outer(bool b, const function<string()> &why) {
auto val = valid;
val.valid_outer = b;
set(val, why);
}
void set_ghosts(bool b, const function<string()> &why) {
auto val = valid;
val.valid_ghosts = b;
set(val, why);
}
void set_and(const valid_t &val, const function<string()> &why) {
set(valid & val, why);
}
void set_or(const valid_t &val, const function<string()> &why) {
set(valid | val, why);
}
friend ostream &operator<<(ostream &os, const why_valid_t why) {
return os << why.valid << ","
<< "why{int:" << why.why_int() << ","
<< "outer:" << why.why_outer() << ","
<< "ghosts:" << why.why_ghosts() << "}";
}
operator string() const {
ostringstream buf;
buf << *this;
return buf.str();
}
};
} // namespace CarpetX
#endif // #ifndef VALID_HXX