File indexing completed on 2025-09-17 09:07:50
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <type_traits>
0010
0011 #include "corecel/Assert.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/data/LdgIterator.hh"
0014 #include "orange/OrangeTypes.hh"
0015 #include "orange/SenseUtils.hh"
0016
0017 #include "LogicStack.hh"
0018
0019 namespace celeritas
0020 {
0021 namespace detail
0022 {
0023
0024
0025
0026
0027 class LogicEvaluator
0028 {
0029 public:
0030
0031
0032 using SpanConstLogic = LdgSpan<logic_int const>;
0033 using SpanConstSense = Span<SenseValue const>;
0034
0035
0036 public:
0037
0038 explicit CELER_FORCEINLINE_FUNCTION LogicEvaluator(SpanConstLogic logic);
0039
0040
0041 inline CELER_FUNCTION bool operator()(SpanConstSense values) const;
0042
0043
0044 template<class F, std::enable_if_t<std::is_invocable_v<F, FaceId>, bool> = true>
0045 inline CELER_FUNCTION bool operator()(F&& eval_sense) const;
0046
0047 private:
0048
0049
0050 SpanConstLogic logic_;
0051 };
0052
0053
0054
0055
0056
0057 CELER_FUNCTION LogicEvaluator::LogicEvaluator(SpanConstLogic logic)
0058 : logic_(logic)
0059 {
0060 CELER_EXPECT(!logic_.empty());
0061 }
0062
0063
0064
0065
0066
0067 CELER_FUNCTION bool LogicEvaluator::operator()(SpanConstSense values) const
0068 {
0069 auto calc_sense
0070 = [&](FaceId face_id) -> Sense { return values[face_id.get()]; };
0071 return (*this)(calc_sense);
0072 }
0073
0074
0075
0076
0077
0078 template<class F, std::enable_if_t<std::is_invocable_v<F, FaceId>, bool>>
0079 CELER_FUNCTION bool LogicEvaluator::operator()(F&& eval_sense) const
0080 {
0081 LogicStack stack;
0082
0083 for (logic_int lgc : logic_)
0084 {
0085 if (!logic::is_operator_token(lgc))
0086 {
0087
0088 stack.push(static_cast<bool>(eval_sense(FaceId{lgc})));
0089 continue;
0090 }
0091
0092
0093 switch (lgc)
0094 {
0095
0096 case logic::ltrue: stack.push(true); break;
0097 case logic::lor: stack.apply_or(); break;
0098 case logic::land: stack.apply_and(); break;
0099 case logic::lnot: stack.apply_not(); break;
0100 default: CELER_ASSERT_UNREACHABLE();
0101 }
0102
0103 }
0104 CELER_ENSURE(stack.size() == 1);
0105 return stack.top();
0106 }
0107
0108
0109 }
0110 }