libuav original
Dependents: UAVCAN UAVCAN_Subscriber
bitset.hpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #ifndef UAVCAN_UTIL_BITSET_HPP_INCLUDED 00006 #define UAVCAN_UTIL_BITSET_HPP_INCLUDED 00007 00008 #include <cassert> 00009 #include <cstddef> 00010 #include <cstring> 00011 #include <uavcan/build_config.hpp> 00012 00013 namespace uavcan 00014 { 00015 /** 00016 * STL-like bitset 00017 */ 00018 template <std::size_t NumBits> 00019 class UAVCAN_EXPORT BitSet 00020 { 00021 enum { NumBytes = (NumBits + 7) / 8 }; 00022 00023 static std::size_t getByteNum(std::size_t bit_num) { return bit_num / 8; } 00024 00025 static std::size_t getBitNum(const std::size_t bit_num) { return bit_num % 8; } 00026 00027 static void validatePos(std::size_t& inout_pos) 00028 { 00029 if (inout_pos >= NumBits) 00030 { 00031 UAVCAN_ASSERT(0); 00032 inout_pos = NumBits - 1; 00033 } 00034 } 00035 00036 char data_[NumBytes]; 00037 00038 public: 00039 class Reference 00040 { 00041 friend class BitSet; 00042 00043 BitSet* const parent_; 00044 const std::size_t bitpos_; 00045 00046 Reference(BitSet* arg_parent, std::size_t arg_bitpos) 00047 : parent_(arg_parent) 00048 , bitpos_(arg_bitpos) 00049 { } 00050 00051 public: 00052 Reference& operator=(bool x) 00053 { 00054 parent_->set(bitpos_, x); 00055 return *this; 00056 } 00057 00058 Reference& operator=(const Reference& x) 00059 { 00060 parent_->set(bitpos_, x); 00061 return *this; 00062 } 00063 00064 bool operator~() const 00065 { 00066 return !parent_->test(bitpos_); 00067 } 00068 00069 operator bool() const 00070 { 00071 return parent_->test(bitpos_); 00072 } 00073 }; 00074 00075 BitSet() 00076 : data_() 00077 { 00078 reset(); 00079 } 00080 00081 BitSet<NumBits>& reset() 00082 { 00083 std::memset(data_, 0, NumBytes); 00084 return *this; 00085 } 00086 00087 BitSet<NumBits>& set() 00088 { 00089 std::memset(data_, 0xFF, NumBytes); 00090 return *this; 00091 } 00092 00093 BitSet<NumBits>& set(std::size_t pos, bool val = true) 00094 { 00095 validatePos(pos); 00096 if (val) 00097 { 00098 data_[getByteNum(pos)] = char(data_[getByteNum(pos)] | (1 << getBitNum(pos))); 00099 } 00100 else 00101 { 00102 data_[getByteNum(pos)] = char(data_[getByteNum(pos)] & ~(1 << getBitNum(pos))); 00103 } 00104 return *this; 00105 } 00106 00107 bool test(std::size_t pos) const 00108 { 00109 return (data_[getByteNum(pos)] & (1 << getBitNum(pos))) != 0; 00110 } 00111 00112 bool any() const 00113 { 00114 for (std::size_t i = 0; i < NumBits; ++i) 00115 { 00116 if (test(i)) 00117 { 00118 return true; 00119 } 00120 } 00121 return false; 00122 } 00123 00124 std::size_t count() const 00125 { 00126 std::size_t retval = 0; 00127 for (std::size_t i = 0; i < NumBits; ++i) 00128 { 00129 retval += test(i) ? 1U : 0U; 00130 } 00131 return retval; 00132 } 00133 00134 std::size_t size() const { return NumBits; } 00135 00136 bool operator[](std::size_t pos) const 00137 { 00138 return test(pos); 00139 } 00140 00141 Reference operator[](std::size_t pos) 00142 { 00143 validatePos(pos); 00144 return Reference(this, pos); 00145 } 00146 00147 BitSet<NumBits>& operator=(const BitSet<NumBits> & rhs) 00148 { 00149 if (&rhs == this) 00150 { 00151 return *this; 00152 } 00153 for (std::size_t i = 0; i < NumBytes; ++i) 00154 { 00155 data_[i] = rhs.data_[i]; 00156 } 00157 return *this; 00158 } 00159 00160 bool operator!=(const BitSet<NumBits>& rhs) const { return !operator==(rhs); } 00161 bool operator==(const BitSet<NumBits>& rhs) const 00162 { 00163 for (std::size_t i = 0; i < NumBits; ++i) 00164 { 00165 if (test(i) != rhs.test(i)) 00166 { 00167 return false; 00168 } 00169 } 00170 return true; 00171 } 00172 }; 00173 00174 template <> class BitSet<0>; ///< Invalid instantiation 00175 00176 00177 template <typename Stream, std::size_t NumBits> 00178 Stream& operator<<(Stream& s, const BitSet<NumBits>& x) 00179 { 00180 for (std::size_t i = NumBits; i > 0; --i) 00181 { 00182 s << (x.test(i-1) ? "1" : "0"); 00183 } 00184 return s; 00185 } 00186 00187 } 00188 00189 #endif // UAVCAN_UTIL_BITSET_HPP_INCLUDED
Generated on Tue Jul 12 2022 17:17:30 by 1.7.2