File indexing completed on 2023-03-17 10:50:29
0001 #ifndef DataFormats_L1TrackTrigger_TTBV_h
0002 #define DataFormats_L1TrackTrigger_TTBV_h
0003
0004 #include <bitset>
0005 #include <array>
0006 #include <string>
0007 #include <algorithm>
0008 #include <cmath>
0009 #include <utility>
0010 #include <vector>
0011 #include <iostream>
0012
0013
0014
0015
0016
0017
0018
0019
0020 class TTBV {
0021 public:
0022 static constexpr int S_ = 64;
0023
0024 private:
0025 bool twos_;
0026 int size_;
0027 std::bitset<S_> bs_;
0028
0029 public:
0030
0031 TTBV() : twos_(false), size_(0), bs_() {}
0032
0033
0034 TTBV(const double d) : twos_(false), size_(S_) {
0035 int index(0);
0036 const char* c = reinterpret_cast<const char*>(&d);
0037 for (int iByte = 0; iByte < (int)sizeof(d); iByte++) {
0038 const std::bitset<std::numeric_limits<unsigned char>::digits> byte(*(c + iByte));
0039 for (int bit = 0; bit < std::numeric_limits<unsigned char>::digits; bit++)
0040 bs_[index++] = byte[bit];
0041 }
0042 }
0043
0044
0045 TTBV(unsigned long long int value, int size) : twos_(false), size_(size), bs_(value) {}
0046
0047
0048 TTBV(int value, int size, bool twos = false)
0049 : twos_(twos), size_(size), bs_((!twos || value >= 0) ? value : value + iMax()) {}
0050
0051
0052 TTBV(double value, double base, int size, bool twos = false) : TTBV((int)std::floor(value / base), size, twos) {}
0053
0054
0055 TTBV(const std::string& str, bool twos = false) : twos_(twos), size_(str.size()), bs_(str) {}
0056
0057
0058 TTBV(const std::bitset<S_>& bs, bool twos = false) : twos_(twos), size_(S_), bs_(bs) {}
0059
0060
0061 TTBV(const TTBV& ttBV, int begin, int end = 0, bool twos = false) : twos_(twos), size_(begin - end), bs_(ttBV.bs_) {
0062 bs_ <<= S_ - begin;
0063 bs_ >>= S_ - begin + end;
0064 }
0065
0066
0067 bool twos() const { return twos_; }
0068
0069 int size() const { return size_; }
0070
0071 const std::bitset<S_>& bs() const { return bs_; }
0072
0073
0074 bool operator[](int pos) const { return bs_[pos]; }
0075 std::bitset<S_>::reference operator[](int pos) { return bs_[pos]; }
0076
0077
0078 bool msb() const { return bs_[size_ - 1]; }
0079
0080
0081 std::bitset<S_>::reference msb() { return bs_[size_ - 1]; }
0082
0083
0084
0085 bool all() const { return bs_.all(); }
0086 bool any() const { return bs_.any(); }
0087 bool none() const { return bs_.none(); }
0088 int count() const { return bs_.count(); }
0089
0090
0091 bool operator==(const TTBV& rhs) const { return bs_ == rhs.bs_; }
0092
0093
0094 bool operator!=(const TTBV& rhs) const { return bs_ != rhs.bs_; }
0095
0096
0097 TTBV& operator&=(const TTBV& rhs) {
0098 const int m(std::max(size_, rhs.size()));
0099 this->resize(m);
0100 TTBV bv(rhs);
0101 bv.resize(m);
0102 bs_ &= bv.bs_;
0103 return *this;
0104 }
0105
0106
0107 TTBV& operator|=(const TTBV& rhs) {
0108 const int m(std::max(size_, rhs.size()));
0109 this->resize(m);
0110 TTBV bv(rhs);
0111 bv.resize(m);
0112 bs_ |= bv.bs_;
0113 return *this;
0114 }
0115
0116
0117 TTBV& operator^=(const TTBV& rhs) {
0118 const int m(std::max(size_, rhs.size()));
0119 this->resize(m);
0120 TTBV bv(rhs);
0121 bv.resize(m);
0122 bs_ ^= bv.bs_;
0123 return *this;
0124 }
0125
0126
0127 TTBV operator~() const {
0128 TTBV bv(*this);
0129 return bv.flip();
0130 }
0131
0132
0133 TTBV& operator>>=(int pos) {
0134 bs_ >>= pos;
0135 size_ -= pos;
0136 return *this;
0137 }
0138
0139
0140 TTBV& operator<<=(int pos) {
0141 bs_ <<= S_ - size_ + pos;
0142 bs_ >>= S_ - size_ + pos;
0143 size_ -= pos;
0144 return *this;
0145 }
0146
0147
0148 TTBV operator<<(int pos) const {
0149 TTBV bv(*this);
0150 return bv <<= pos;
0151 }
0152
0153
0154 TTBV operator>>(int pos) const {
0155 TTBV bv(*this);
0156 return bv >>= pos;
0157 }
0158
0159
0160 TTBV& operator+=(const TTBV& rhs) {
0161 bs_ <<= rhs.size();
0162 bs_ |= rhs.bs_;
0163 size_ += rhs.size();
0164 return *this;
0165 }
0166
0167
0168 TTBV operator+(const TTBV& rhs) const {
0169 TTBV lhs(*this);
0170 return lhs += rhs;
0171 }
0172
0173
0174 TTBV& operator++() {
0175 bs_ = std::bitset<S_>(bs_.to_ullong() + 1);
0176 this->resize(size_);
0177 return *this;
0178 }
0179
0180
0181 TTBV& reset() {
0182 bs_.reset();
0183 return *this;
0184 }
0185
0186
0187 TTBV& set() {
0188 for (int n = 0; n < size_; n++)
0189 bs_.set(n);
0190 return *this;
0191 }
0192
0193
0194 TTBV& flip() {
0195 for (int n = 0; n < size_; n++)
0196 bs_.flip(n);
0197 return *this;
0198 }
0199
0200
0201 TTBV& reset(int pos) {
0202 bs_.reset(pos);
0203 return *this;
0204 }
0205
0206
0207 TTBV& set(int pos) {
0208 bs_.set(pos);
0209 return *this;
0210 }
0211
0212
0213 TTBV& set(std::vector<int> vpos) {
0214 for (int pos : vpos)
0215 bs_.set(pos);
0216 return *this;
0217 }
0218
0219
0220 TTBV& flip(int pos) {
0221 bs_.flip(pos);
0222 return *this;
0223 }
0224
0225
0226 TTBV& abs() {
0227 if (twos_) {
0228 twos_ = false;
0229 if (this->msb())
0230 this->flip();
0231 size_--;
0232 }
0233 return *this;
0234 }
0235
0236
0237 TTBV& resize(int size) {
0238 bool msb = this->msb();
0239 if (size > size_) {
0240 if (twos_)
0241 for (int n = size_; n < size; n++)
0242 bs_.set(n, msb);
0243 size_ = size;
0244 } else if (size < size_ && size > 0) {
0245 this->operator<<=(size - size_);
0246 if (twos_)
0247 this->msb() = msb;
0248 }
0249 return *this;
0250 }
0251
0252
0253 std::string str() const { return bs_.to_string().substr(S_ - size_, S_); }
0254
0255
0256 std::string str(int start, int end = 0) const { return this->str().substr(size_ - start, size_ - end); }
0257
0258
0259 int val() const { return (twos_ && this->msb()) ? (int)bs_.to_ullong() - iMax() : bs_.to_ullong(); }
0260
0261
0262 int val(bool twos) const { return (twos && this->msb()) ? (int)bs_.to_ullong() - iMax() : bs_.to_ullong(); }
0263
0264
0265 int val(int start, int end = 0, bool twos = false) const { return TTBV(*this, start, end).val(twos); }
0266
0267
0268 double val(double base) const { return (this->val() + .5) * base; }
0269
0270
0271 double val(double base, int start, int end = 0, bool twos = false) const {
0272 return (this->val(start, end, twos) + .5) * base;
0273 }
0274
0275
0276 double extract(double base, int size, bool twos = false) {
0277 double val = this->val(base, size, 0, twos);
0278 this->operator>>=(size);
0279 return val;
0280 }
0281
0282
0283 int extract(int size, bool twos = false) {
0284 double val = this->val(size, 0, twos);
0285 this->operator>>=(size);
0286 return val;
0287 }
0288
0289
0290 TTBV slice(int size, bool twos = false) {
0291 TTBV ttBV(*this, size, 0, twos);
0292 this->operator>>=(size);
0293 return ttBV;
0294 }
0295
0296
0297 int count(int begin, int end, bool b = true) const {
0298 int c(0);
0299 for (int i = begin; i < end; i++)
0300 if (bs_[i] == b)
0301 c++;
0302 return c;
0303 }
0304
0305
0306 int plEncode(bool b = true) const {
0307 for (int e = 0; e < size_; e++)
0308 if (bs_[e] == b)
0309 return e;
0310 return size_;
0311 }
0312
0313
0314 int pmEncode(bool b = true) const {
0315 for (int e = size_ - 1; e > -1; e--)
0316 if (bs_[e] == b)
0317 return e;
0318 return size_;
0319 }
0320
0321
0322 int encode(int n, bool b = true) const {
0323 int sum(0);
0324 for (int e = 0; e < size_; e++) {
0325 if (bs_[e] == b) {
0326 sum++;
0327 if (sum == n)
0328 return e;
0329 }
0330 }
0331 return size_;
0332 }
0333
0334 std::vector<int> ids(bool b = true, bool singed = false) const {
0335 std::vector<int> v;
0336 v.reserve(bs_.count());
0337 for (int i = 0; i < size_; i++)
0338 if (bs_[i] == b)
0339 v.push_back(singed ? i + size_ / 2 : i);
0340 return v;
0341 }
0342
0343 friend std::ostream& operator<<(std::ostream& os, const TTBV& ttBV) { return os << ttBV.str(); }
0344
0345 private:
0346
0347 constexpr std::array<unsigned long long int, S_> powersOfTwo() const {
0348 std::array<unsigned long long int, S_> lut = {};
0349 for (int i = 0; i < S_; i++)
0350 lut[i] = std::pow(2, i);
0351 return lut;
0352 }
0353
0354
0355 unsigned long long int iMax() const {
0356 static const std::array<unsigned long long int, S_> lut = powersOfTwo();
0357 return lut[size_];
0358 }
0359 };
0360
0361 #endif