File indexing completed on 2025-09-15 09:06:15
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Types.hh"
0011
0012 namespace celeritas
0013 {
0014 namespace detail
0015 {
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 class LogicStack
0040 {
0041 public:
0042
0043
0044 using value_type = bool;
0045 using size_type = celeritas::size_type;
0046
0047
0048 public:
0049
0050 CELER_FORCEINLINE_FUNCTION LogicStack() {}
0051
0052
0053 static CELER_CONSTEXPR_FUNCTION size_type max_stack_depth()
0054 {
0055 return sizeof(size_type) * 8;
0056 }
0057
0058
0059
0060
0061 CELER_FORCEINLINE_FUNCTION size_type size() const { return size_; }
0062
0063
0064 CELER_FORCEINLINE_FUNCTION bool empty() const;
0065
0066
0067 CELER_FORCEINLINE_FUNCTION value_type top() const;
0068
0069
0070 CELER_FORCEINLINE_FUNCTION value_type operator[](size_type index) const;
0071
0072
0073
0074
0075 CELER_FORCEINLINE_FUNCTION void push(value_type v);
0076
0077
0078 CELER_FORCEINLINE_FUNCTION value_type pop();
0079
0080
0081 CELER_FORCEINLINE_FUNCTION void apply_not();
0082
0083
0084 CELER_FORCEINLINE_FUNCTION void apply_and();
0085
0086
0087 CELER_FORCEINLINE_FUNCTION void apply_or();
0088
0089 private:
0090
0091 static CELER_CONSTEXPR_FUNCTION size_type lsb(size_type val)
0092 {
0093 return val & size_type(1);
0094 }
0095
0096
0097 static CELER_CONSTEXPR_FUNCTION size_type shr(size_type val)
0098 {
0099 return val >> size_type(1);
0100 }
0101
0102
0103 static CELER_CONSTEXPR_FUNCTION size_type shl(size_type val)
0104 {
0105 return val << size_type(1);
0106 }
0107
0108 private:
0109
0110
0111 size_type data_{0};
0112 size_type size_{0};
0113 };
0114
0115
0116
0117
0118
0119 CELER_FUNCTION bool LogicStack::empty() const
0120 {
0121 return size_ == size_type(0);
0122 }
0123
0124
0125
0126
0127
0128 CELER_FUNCTION auto LogicStack::top() const -> value_type
0129 {
0130 CELER_EXPECT(!empty());
0131 return LogicStack::lsb(data_);
0132 }
0133
0134
0135
0136
0137
0138 CELER_FUNCTION auto LogicStack::operator[](size_type index) const -> value_type
0139 {
0140 CELER_EXPECT(index < size());
0141 size_type shift = size() - index - size_type(1);
0142 return LogicStack::lsb(data_ >> shift);
0143 }
0144
0145
0146
0147
0148
0149 CELER_FUNCTION void LogicStack::push(value_type v)
0150 {
0151 CELER_EXPECT(size() != max_stack_depth());
0152
0153 data_ = LogicStack::shl(data_) | LogicStack::lsb(v);
0154
0155 ++size_;
0156 }
0157
0158
0159
0160
0161
0162 CELER_FUNCTION auto LogicStack::pop() -> value_type
0163 {
0164 CELER_EXPECT(!empty());
0165
0166 value_type result = LogicStack::lsb(data_);
0167
0168 data_ = LogicStack::shr(data_);
0169
0170 --size_;
0171 return result;
0172 }
0173
0174
0175
0176
0177
0178 CELER_FUNCTION void LogicStack::apply_not()
0179 {
0180 CELER_EXPECT(!empty());
0181 data_ ^= size_type(1);
0182 }
0183
0184
0185
0186
0187
0188 CELER_FUNCTION void LogicStack::apply_and()
0189 {
0190 CELER_EXPECT(size() >= size_type(2));
0191 size_type temp = LogicStack::lsb(data_);
0192 data_ = LogicStack::shr(data_) & (temp | ~size_type(1));
0193 --size_;
0194 }
0195
0196
0197
0198
0199
0200 CELER_FUNCTION void LogicStack::apply_or()
0201 {
0202 CELER_EXPECT(size() >= size_type(2));
0203 data_ = LogicStack::shr(data_) | LogicStack::lsb(data_);
0204 --size_;
0205 }
0206
0207
0208 }
0209 }