BitFieldCoder.h
Go to the documentation of this file.
1 #ifndef BITFIELDCODER_H
2 #define BITFIELDCODER_H
3 
4 #include <vector>
5 #include <map>
6 
7 #include <sstream>
8 #include <string>
9 
10 //Most helpers taken from DD4hep
11 /*
12 https://github.com/AIDASoft/DD4hep
13 */
14 
15 namespace gar {
16  namespace geo {
17 
18  typedef long long long64 ;
19  typedef unsigned long long ulong64 ;
20 
21  class Tokenizer {
22  std::vector< std::string >& _tokens ;
23  char _del ;
24  char _last ;
25 
26  public:
27 
28  Tokenizer( std::vector< std::string >& tokens, char del )
29  : _tokens(tokens), _del(del), _last(del)
30  {
31 
32  }
33 
34  void operator()(const char& c)
35  {
36  if( c != _del )
37  {
38  if( _last == _del ){
39  _tokens.push_back("") ;
40  }
41  _tokens.back() += c ;
42  }
43  _last = c ;
44  }
45 
46  };
47 
48  /// Helper class for BitFieldCoder that corresponds to one field value.
49  class BitFieldValue {
50 
51  public:
52  /// Default constructor
54  /// Copy constructor
56  /// Move constructor
58 
59  /** The standard c'tor.
60  * @param name name of the field
61  * @param offset offset of field
62  * @param signedWidth width of field, negative if field is signed
63  */
64  BitFieldValue( const std::string& name, unsigned offset, int signedWidth ) ;
65  /// Default destructor
66  ~BitFieldValue() = default ;
67 
68  /// Assignment operator
69  BitFieldValue& operator=(const BitFieldValue&) = default ;
70 
71  /// calculate this field's value given an external 64 bit bitmap
72  long64 value(long64 bitfield) const;
73 
74  // assign the given value to the bit field
75  void set(long64& bitfield, long64 value) const ;
76 
77  /** The field's name */
78  const std::string& name() const { return _name ; }
79 
80  /** The field's offset */
81  unsigned offset() const { return _offset ; }
82 
83  /** The field's width */
84  unsigned width() const { return _width ; }
85 
86  /** True if field is interpreted as signed */
87  bool isSigned() const { return _isSigned ; }
88 
89  /** The field's mask */
90  ulong64 mask() const { return _mask ; }
91 
92  /** Minimal value */
93  int minValue() const { return _minVal; }
94 
95  /** Maximal value */
96  int maxValue() const { return _maxVal; }
97 
98  protected:
99 
100  ulong64 _mask {};
101  unsigned _offset {};
102  unsigned _width {};
103  int _minVal {};
104  int _maxVal {};
105  bool _isSigned {};
107 
108  };
109 
110  /// Helper class for decoding and encoding a bit field of 64bits for convenient declaration
111  /** and manipulation of sub fields of various widths.<br>
112  * This is a thread safe re-implementation of the functionality in the deprected BitField64.
113  *
114  * Example:<br>
115  * BitFieldCoder bc("layer:7,system:-3,barrel:3,theta:32:11,phi:11" ) ; <br>
116  * bc.set( field, "layer" , 123 ); <br>
117  * bc.set( field, "system" , -4 ); <br>
118  * bc.set( field, "barrel" , 7 ); <br>
119  * bc.set( field, "theta" , 180 ); <br>
120  * bc.set( field, "phi" , 270 ); <br>
121  * ... <br>
122  * int theta = bc.get( field, "theta" ) ; <br>
123  * ... <br>
124  * unsigned phiIndex = bc.index("phi") ; <br>
125  * int phi = bc.get( field, phiIndex ) ; <br>
126  *
127  * @author F.Gaede, DESY
128  * @date 2017-09
129  */
131 
132  public :
133 
134  typedef std::map<std::string, unsigned int> IndexMap ;
135 
136  /// Default constructor
137  BitFieldCoder() = default ;
138  /// Copy constructor
140  /// Move constructor
142  /// Default destructor
143  ~BitFieldCoder() = default ;
144 
145  /// Assignment operator
146  BitFieldCoder& operator=(const BitFieldCoder&) = default ;
147 
148  /** The c'tor takes an initialization string of the form:<br>
149  * <fieldDesc>[,<fieldDesc>...]<br>
150  * fieldDesc = name:[start]:[-]length<br>
151  * where:<br>
152  * name: The name of the field<br>
153  * start: The start bit of the field. If omitted assumed to start
154  * immediately following previous field, or at the least significant
155  * bit if the first field.<br>
156  * length: The number of bits in the field. If preceeded by '-'
157  * the field is signed, otherwise unsigned.<br>
158  * Bit numbering is from the least significant bit (bit 0) to the most
159  * significant (bit 63). <br>
160  * Example: "layer:7,system:-3,barrel:3,theta:32:11,phi:11"
161  */
162  BitFieldCoder( const std::string& initString ) : _joined(0)
163  {
164  init( initString ) ;
165  }
166 
167  /** return a new 64bit value given as high and low 32bit words.
168  */
169  static long64 toLong(unsigned low_Word, unsigned high_Word ) { return ( ( low_Word & 0xffffffffULL ) | ( ( high_Word & 0xffffffffULL ) << 32 ) ); }
170 
171  /** The low word, bits 0-31
172  */
173  static unsigned lowWord(long64 bitfield) { return unsigned( bitfield & 0xffffFFFFUL ); }
174 
175  /** The high word, bits 32-63
176  */
177  static unsigned highWord(long64 bitfield) { return unsigned( bitfield >> 32); }
178 
179  /** get value of sub-field specified by index
180  */
181  long64 get(long64 bitfield, size_t index) const { return _fields.at(index).value( bitfield ); }
182 
183  /** Access to field through name .
184  */
185  long64 get(long64 bitfield, const std::string& name) const { return _fields.at( index( name ) ).value( bitfield ); }
186 
187  /** set value of sub-field specified by index
188  */
189  void set(long64& bitfield, size_t index, ulong64 value) const { _fields.at(index).set( bitfield , value ); }
190 
191  /** Access to field through name .
192  */
193  void set(long64& bitfield, const std::string& name, ulong64 value) const { _fields.at( index( name ) ).set( bitfield, value ); }
194 
195  /** Highest bit used in fields [0-63]
196  */
197  unsigned highestBit() const ;
198 
199 
200  /** Number of values */
201  size_t size() const { return _fields.size() ; }
202 
203  /** Index for field named 'name'
204  */
205  size_t index( const std::string& name) const ;
206 
207  /** Const Access to field through name .
208  */
209  const BitFieldValue& operator[](const std::string& name) const { return _fields[ index( name ) ] ;}
210 
211  /** Const Access to field through index .
212  */
213  const BitFieldValue& operator[](unsigned index) const { return _fields[ index ] ;}
214 
215  /** Return a valid description string of all fields
216  */
217  std::string fieldDescription() const ;
218 
219  /** Return a string with a comma separated list of the current sub field values
220  */
221  std::string valueString(ulong64 bitfield) const ;
222 
223  const std::vector<BitFieldValue>& fields() const { return _fields;}
224 
225  /** the mask of all the bits used in the description */
226  ulong64 mask() const { return _joined ; }
227 
228  protected:
229 
230  /** Add an additional field to the list
231  */
232  void addField( const std::string& name, unsigned offset, int width );
233 
234  /** Decode the initialization string as described in the constructor.
235  * @see BitFieldCoder( const std::string& initString )
236  */
237  void init( const std::string& initString) ;
238 
239  public:
240 
241  protected:
242  // -------------- data members:--------------
243  std::vector<BitFieldValue> _fields{};
244  IndexMap _map{};
245  long64 _joined{};
246  };
247 
248  } // geo
249  }// gar
250 
251  #endif /*BITFIELDCODER_H*/
size_t size() const
static QCString name
Definition: declinfo.cpp:673
static unsigned highWord(long64 bitfield)
void operator()(const char &c)
Definition: BitFieldCoder.h:34
std::vector< std::string > & _tokens
Definition: BitFieldCoder.h:22
Helper class for BitFieldCoder that corresponds to one field value.
Definition: BitFieldCoder.h:49
std::string string
Definition: nybbler.cc:12
static unsigned lowWord(long64 bitfield)
BitFieldCoder(const std::string &initString)
long long long64
Definition: BitFieldCoder.h:18
init
Definition: train.py:42
const BitFieldValue & operator[](unsigned index) const
const BitFieldValue & operator[](const std::string &name) const
const std::vector< BitFieldValue > & fields() const
ulong64 mask() const
Tokenizer(std::vector< std::string > &tokens, char del)
Definition: BitFieldCoder.h:28
static long64 toLong(unsigned low_Word, unsigned high_Word)
Helper class for decoding and encoding a bit field of 64bits for convenient declaration.
ulong64 mask() const
Definition: BitFieldCoder.h:90
General GArSoft Utilities.
unsigned offset() const
Definition: BitFieldCoder.h:81
unsigned width() const
Definition: BitFieldCoder.h:84
std::map< std::string, unsigned int > IndexMap
bool isSigned() const
Definition: BitFieldCoder.h:87
const std::string & name() const
Definition: BitFieldCoder.h:78
LArSoft geometry interface.
Definition: ChannelGeo.h:16
unsigned long long ulong64
Definition: BitFieldCoder.h:19