File indexing completed on 2025-09-16 09:03:18
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/cont/Span.hh"
0011 #include "corecel/data/LdgIterator.hh"
0012 #include "orange/OrangeTypes.hh"
0013
0014 namespace celeritas
0015 {
0016 namespace detail
0017 {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 class InfixEvaluator
0030 {
0031 public:
0032
0033
0034 using SpanConstLogic = LdgSpan<logic_int const>;
0035
0036
0037 public:
0038
0039 explicit CELER_FORCEINLINE_FUNCTION InfixEvaluator(SpanConstLogic logic);
0040
0041
0042 template<class F>
0043 inline CELER_FUNCTION bool operator()(F&& eval_sense) const;
0044
0045 private:
0046
0047 inline CELER_FUNCTION size_type short_circuit(size_type i) const;
0048
0049
0050
0051 SpanConstLogic logic_;
0052 };
0053
0054
0055
0056
0057
0058 CELER_FUNCTION InfixEvaluator::InfixEvaluator(SpanConstLogic logic)
0059 : logic_(logic)
0060 {
0061 CELER_EXPECT(!logic_.empty());
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 template<class F>
0073 CELER_FUNCTION bool InfixEvaluator::operator()(F&& eval_sense) const
0074 {
0075 bool result{true};
0076
0077 int par_depth{0};
0078 size_type i{0};
0079 while (i < logic_.size())
0080 {
0081 if (logic_int const lgc{logic_[i]}; !logic::is_operator_token(lgc))
0082 {
0083 result = static_cast<bool>(eval_sense(FaceId{lgc}));
0084 }
0085 else if ((lgc == logic::lor && result)
0086 || (lgc == logic::land && !result))
0087 {
0088 if (par_depth == 0)
0089 {
0090 break;
0091 }
0092 --par_depth;
0093 i = this->short_circuit(i);
0094 }
0095 else if (lgc == logic::ltrue)
0096 {
0097 result = true;
0098 }
0099 else if (lgc == logic::lopen)
0100 {
0101 ++par_depth;
0102 }
0103 else if (lgc == logic::lclose)
0104 {
0105 CELER_ASSERT(par_depth > 0);
0106 --par_depth;
0107 }
0108 else if (lgc == logic::lnot)
0109 {
0110
0111 CELER_ASSUME(i + 1 < logic_.size());
0112 CELER_EXPECT(!logic::is_operator_token(logic_[i + 1]));
0113 result = !static_cast<bool>(eval_sense(FaceId{logic_[++i]}));
0114 }
0115 ++i;
0116 }
0117 return result;
0118 }
0119
0120
0121
0122
0123
0124 CELER_FUNCTION size_type InfixEvaluator::short_circuit(size_type i) const
0125 {
0126 int par_depth{1};
0127 while (par_depth > 0)
0128 {
0129 CELER_ASSUME(i + 1 < logic_.size());
0130 if (logic_int lgc = logic_[++i]; lgc == logic::lopen)
0131 {
0132 ++par_depth;
0133 }
0134 else if (lgc == logic::lclose)
0135 {
0136 --par_depth;
0137 }
0138 }
0139 return i;
0140 }
0141
0142
0143 }
0144 }