File indexing completed on 2026-11-13 10:48:05
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <iostream>
0010 #include <ostream>
0011 #include <variant>
0012 #include <vector>
0013
0014 namespace celeritas
0015 {
0016 namespace orangeinp
0017 {
0018 namespace detail
0019 {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 class NodeReplacer
0030 {
0031 public:
0032 enum NodeRepl
0033 {
0034 unvisited,
0035 unknown,
0036 known_false,
0037 known_true
0038 };
0039
0040
0041
0042 using VecRepl = std::vector<NodeRepl>;
0043
0044
0045 public:
0046
0047 inline NodeReplacer(VecRepl* state, NodeId n);
0048
0049
0050 inline bool operator()(Aliased const& n);
0051 inline bool operator()(Negated const& n);
0052 inline bool operator()(Joined const& n);
0053
0054
0055 inline bool operator()(True const&);
0056 inline bool operator()(False const&);
0057
0058
0059 inline bool operator()(Surface const&) { return {}; }
0060
0061 private:
0062 VecRepl* state_;
0063 NodeRepl repl_;
0064
0065
0066 inline bool update(NodeId n, NodeRepl repl);
0067 };
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 NodeReplacer::NodeReplacer(VecRepl* state, NodeId n) : state_{state}
0078 {
0079 CELER_EXPECT(state_);
0080 repl_ = (*state_)[n.unchecked_get()];
0081 }
0082
0083
0084
0085
0086
0087 bool NodeReplacer::operator()(True const&)
0088 {
0089 CELER_ASSERT(repl_ == NodeRepl::known_true);
0090 return false;
0091 }
0092
0093
0094
0095
0096
0097 bool NodeReplacer::operator()(False const&)
0098 {
0099 CELER_ASSERT(repl_ == NodeRepl::known_false);
0100 return false;
0101 }
0102
0103
0104
0105
0106
0107
0108
0109 bool NodeReplacer::operator()(Aliased const& n)
0110 {
0111 return this->update(n.node, repl_);
0112 }
0113
0114
0115
0116
0117
0118
0119
0120 bool NodeReplacer::operator()(Negated const& n)
0121 {
0122 NodeRepl repl = [r = repl_] {
0123 switch (r)
0124 {
0125 case NodeRepl::known_false:
0126 return NodeRepl::known_true;
0127 case NodeRepl::known_true:
0128 return NodeRepl::known_false;
0129 default:
0130 return r;
0131 }
0132 }();
0133
0134 return this->update(n.node, repl);
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144 bool NodeReplacer::operator()(Joined const& n)
0145 {
0146 NodeRepl repl = repl_;
0147 if ((repl == NodeRepl::known_true && n.op == op_or)
0148 || (repl == NodeRepl::known_false && n.op == op_and))
0149 {
0150
0151
0152 repl = NodeRepl::unknown;
0153 }
0154
0155 bool updated{false};
0156 for (NodeId d : n.nodes)
0157 {
0158
0159
0160 bool daughter_updated = this->update(d, repl);
0161 updated = updated || daughter_updated;
0162 }
0163 return updated;
0164 }
0165
0166
0167
0168
0169
0170 bool NodeReplacer::update(NodeId n, NodeRepl repl)
0171 {
0172 CELER_EXPECT(n < state_->size());
0173 NodeRepl& dest = (*state_)[n.unchecked_get()];
0174 CELER_VALIDATE(
0175 !(dest == NodeRepl::known_true && repl == NodeRepl::known_false)
0176 && !(dest == NodeRepl::known_false && repl == NodeRepl::known_true),
0177 << "encountered logical contradiction in CSG operation");
0178 if (dest < repl)
0179 {
0180 dest = repl;
0181 return true;
0182 }
0183 return false;
0184 }
0185
0186
0187 }
0188 }
0189 }