ATLAS Offline Software
PackedArray.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
12 #include "CxxUtils/PackedArray.h"
13 #include <stdexcept>
14 #include <climits>
15 #include <cassert>
16 
17 
18 namespace {
19 
20 
22 const int nper = sizeof (unsigned int) * CHAR_BIT;
23 
24 
29 inline
31 {
32  return (1<<sz) - 1;
33 }
34 
35 
36 } // anonymous namespace
37 
38 
39 namespace CxxUtils {
40 
41 
47 inline
49 {
50  return (n * m_bitsize + nper-1) / nper;
51 }
52 
53 
58 inline
60 {
61  return (n * m_bitsize) / nper;
62 }
63 
64 
69 inline
71 {
72  return (n * m_bitsize) % nper;
73 }
74 
75 
82 inline
84 {
85  // Get the bits from the first entry.
86  value_type v = m_vec[ndx] >> off;
87 
88  // If the packed entry wraps between two base entries, collect the bits
89  // from the next base entry.
90  if (m_bitsize > nper - off) {
91  int bits = m_bitsize - (nper - off);
92  // cppcheck-suppress shiftTooManyBits; false positive
93  // m_bitsize <= nper
94  v |= ((m_vec[ndx+1] & mask(bits)) << (nper - off));
95  }
96 
97  // Mask down to the proper number of bits.
98  return v & m_mask;
99 }
100 
101 
109 inline
111 {
112  // Set the bits in the first entry.
113  m_vec[ndx] = (m_vec[ndx] & ~(m_mask<<off)) | ((v&m_mask) << off);
114 
115  // If the packed entry wraps between two base entries, set the bits
116  // in the next entry.
117  if (m_bitsize > nper - off) {
118  value_type mask2 = mask (m_bitsize - (nper - off));
119  m_vec[ndx+1] = (m_vec[ndx+1] & ~mask2) | ((v >> (nper - off)) & mask2);
120  }
121 }
122 
123 
129 {
130  if (n >= m_size) {
131  throw std::out_of_range ("PackedArray");
132  }
133 }
134 
135 
144  const allocator_type& allocator/*=allocator_type()*/)
145  : m_bitsize (bitsize),
146  m_size (0),
147  m_mask (mask (bitsize)),
148  m_vec (allocator)
149 {
150  assert (m_bitsize > 0 && m_bitsize <= nper);
151 }
152 
153 
164  size_type n,
165  value_type val /*= 0*/,
166  const allocator_type& allocator/*=allocator_type()*/)
167  : m_bitsize (bitsize),
168  m_size (n),
169  m_mask (mask (bitsize)),
170  m_vec (nbase(n), 0, allocator)
171 {
172  assert (m_bitsize > 0 && m_bitsize <= nper);
173  if (val != 0) {
174  for (size_type i = 0; i < n; i++)
175  set (i, val);
176  }
177 }
178 
179 
186 {
187  m_size = n;
188  m_vec.clear();
189  m_vec.resize (nbase(n));
190  if (u != 0) {
191  for (size_type i = 0; i < n; i++)
192  set (i, u);
193  }
194 }
195 
196 
201 {
202  return m_vec.get_allocator();
203 }
204 
205 
210 {
211  return m_size;
212 }
213 
214 
219 {
220  return m_vec.max_size();
221 }
222 
223 
229 {
230  return m_vec.capacity() * nper / m_bitsize;
231 }
232 
233 
240 {
241  m_vec.resize (nbase (sz));
242  if (sz > m_size) {
243  // Making the container bigger. Need to fill the remaining values.
244  if (c != 0) {
245  // Set them to something non-zero.
246  for (size_t i = m_size; i < sz; i++)
247  set (i, c);
248  }
249  else {
250  // Filling the new entries with 0.
251  // New elements in the base vector will have been set to 0.
252  // However, we also need to zero out any remaining packed elements
253  // (or piece thereof) in the last base element that was occupied
254  // before the resize.
255  int off = tooff (m_size);
256  // Don't need to do anything if packed entries exactly fit
257  // in the allocated base size.
258  if (off != 0) {
259  size_t ndx = tondx (m_size);
260  m_vec[ndx] &= mask (off);
261  }
262  }
263  }
264  m_size = sz;
265 }
266 
267 
271 bool PackedArray::empty() const
272 {
273  return m_size == 0;
274 }
275 
276 
283 {
284  m_vec.reserve (nbase (n));
285 }
286 
287 
293 {
294  return doget (tondx (n), tooff (n));
295 }
296 
297 
304 {
305  return doset (tondx (n), tooff (n), val);
306 }
307 
308 
318 {
319  return doget (tondx (n), tooff (n));
320 }
321 
322 
332 {
333  return proxy (*this, n);
334 }
335 
336 
346 {
347  range_check (n);
348  return doget (tondx (n), tooff (n));
349 }
350 
351 
361 {
362  range_check (n);
363  return proxy (*this, n);
364 }
365 
366 
375 {
376  return doget (0, 0);
377 }
378 
379 
388 {
389  return doget (tondx (m_size-1), tooff (m_size-1));
390 }
391 
392 
401 {
402  return proxy (*this, 0);
403 }
404 
405 
414 {
415  return proxy (*this, m_size-1);
416 }
417 
418 
424 {
425  ++m_size;
426  size_t nb = nbase (m_size);
427  if (nb != m_vec.size())
428  m_vec.resize (nb);
429  doset (tondx (m_size-1), tooff (m_size-1), x);
430 }
431 
432 
437 {
438  --m_size;
439  size_t nb = nbase (m_size);
440  if (nb != m_vec.size())
441  m_vec.resize (nb);
442 }
443 
444 
450 {
451  std::swap (m_bitsize, other.m_bitsize);
452  std::swap (m_size, other.m_size);
453  std::swap (m_mask, other.m_mask);
454  std::swap (m_vec, other.m_vec);
455 }
456 
457 
462 {
463  m_size = 0;
464  m_vec.clear();
465 }
466 
467 
474 void PackedArray::set_bitsize (int bitsize)
475 {
476  assert (m_size == 0);
477  assert (bitsize > 0 && bitsize <= nper);
478  m_bitsize = bitsize;
479  m_mask = mask (bitsize);
480 }
481 
482 
487 {
488  return m_bitsize;
489 }
490 
491 
492 } // namespace CxxUtils
CxxUtils::PackedArray::operator[]
value_type operator[](size_type n) const
Access an element, as an rvalue.
Definition: PackedArray.cxx:317
CxxUtils::PackedArray::m_vec
basetype m_vec
Underlying vector holding the data.
Definition: PackedArray.h:285
CxxUtils::PackedArray::assign
void assign(size_type n, value_type u)
Set the container to multiple copies of the same value.
Definition: PackedArray.cxx:185
fitman.sz
sz
Definition: fitman.py:527
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:392
CxxUtils::PackedArray::push_back
void push_back(value_type x)
Add an element to the end of the collection.
Definition: PackedArray.cxx:423
CxxUtils::PackedArray::back
value_type back() const
Access the last element in the collection as an rvalue.
Definition: PackedArray.cxx:387
CxxUtils::PackedArray::nbase
size_t nbase(size_type n) const
Calculate the number of entries in the base vector needed to hold entries with the current bitsize.
Definition: PackedArray.cxx:48
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
CxxUtils::PackedArray::swap
void swap(PackedArray &other)
Swap this collection with another.
Definition: PackedArray.cxx:449
CxxUtils::PackedArray::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
Definition: PackedArray.cxx:282
CxxUtils::PackedArray::m_size
size_type m_size
The current number of entries in the container.
Definition: PackedArray.h:279
CxxUtils::PackedArray::size
size_type size() const
Returns the number of elements in the collection.
Definition: PackedArray.cxx:209
CxxUtils::PackedArray::tooff
int tooff(size_type n) const
Find the bit offset of entry within its entry in the base vector.
Definition: PackedArray.cxx:70
x
#define x
CxxUtils::PackedArray::bitsize
int bitsize() const
Return the bitsize of the container.
Definition: PackedArray.cxx:486
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
CxxUtils::PackedArray::at
value_type at(size_type n) const
Access an element, as an rvalue.
Definition: PackedArray.cxx:345
CxxUtils::PackedArray::empty
bool empty() const
Returns true if the collection is empty.
Definition: PackedArray.cxx:271
CxxUtils::PackedArray
An array of unsigned values of some bit size, packed tightly.
Definition: PackedArray.h:42
CxxUtils::PackedArray::doget
value_type doget(size_type ndx, int off) const
Return the entry at base index ndx/offset off.
Definition: PackedArray.cxx:83
CxxUtils::PackedArray::get_allocator
allocator_type get_allocator() const
Returns the allocator of the underlying vector.
Definition: PackedArray.cxx:200
CxxUtils::PackedArray::PackedArray
PackedArray(int bitsize=8, const allocator_type &allocator=allocator_type())
Constructor.
Definition: PackedArray.cxx:143
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:731
CxxUtils
Definition: aligned_vector.h:29
CxxUtils::PackedArray::range_check
void range_check(size_type n) const
Check that n is in range and throw out_of_range if not.
Definition: PackedArray.cxx:128
CxxUtils::PackedArray::resize
void resize(size_type sz, value_type c=0)
Resizes the collection to the specified number of elements.
Definition: PackedArray.cxx:239
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
CxxUtils::PackedArray::front
value_type front() const
Access the first element in the collection as an rvalue.
Definition: PackedArray.cxx:374
CxxUtils::PackedArray::allocator_type
basetype::allocator_type allocator_type
Definition: PackedArray.h:51
CxxUtils::PackedArray::m_bitsize
int m_bitsize
The current bitsize of the container.
Definition: PackedArray.h:276
CxxUtils::PackedArray::get
value_type get(size_type n) const
Return the entry at index n.
Definition: PackedArray.cxx:292
CxxUtils::PackedArray::m_mask
value_type m_mask
Mask with m_bitsize bits set.
Definition: PackedArray.h:282
CxxUtils::PackedArray::proxy
proxy class for representing an lvalue to an element of PackedArray.
Definition: PackedArray.h:58
python.PyAthena.v
v
Definition: PyAthena.py:154
CxxUtils::PackedArray::tondx
size_t tondx(size_type n) const
Find the index in the base vector where entry starts.
Definition: PackedArray.cxx:59
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
CxxUtils::PackedArray::set_bitsize
void set_bitsize(int bitsize)
Change the bitsize of the container.
Definition: PackedArray.cxx:474
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
CxxUtils::PackedArray::set
void set(size_type n, value_type val)
Set the entry at index n.
Definition: PackedArray.cxx:303
PackedArray.h
An array of unsigned values of some bit size, packed tightly.
CxxUtils::PackedArray::pop_back
void pop_back()
Remove the last element from the collection.
Definition: PackedArray.cxx:436
CxxUtils::PackedArray::value_type
unsigned int value_type
Definition: PackedArray.h:50
CxxUtils::PackedArray::doset
void doset(size_type ndx, int off, value_type v)
Set the entry at base index ndx/offset off to v.
Definition: PackedArray.cxx:110
hotSpotInTAG.nb
nb
Definition: hotSpotInTAG.py:164
value_type
Definition: EDM_MasterSearch.h:11
CxxUtils::PackedArray::clear
void clear()
Erase all the elements in the collection.
Definition: PackedArray.cxx:461
python.compressB64.c
def c
Definition: compressB64.py:93
CxxUtils::PackedArray::capacity
size_type capacity() const
Returns the total number of elements that the collection can hold before needing to allocate more mem...
Definition: PackedArray.cxx:228
CxxUtils::PackedArray::max_size
size_type max_size() const
Returns the size() of the largest possible collection.
Definition: PackedArray.cxx:218
CxxUtils::PackedArray::size_type
size_t size_type
Definition: PackedArray.h:49