ATLAS Offline Software
PackedArray.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
12 #include "CxxUtils/PackedArray.h"
14 #include <stdexcept>
15 #include <climits>
16 #include <cassert>
17 
18 
19 namespace {
20 
21 
23 const int nper = sizeof (unsigned int) * CHAR_BIT;
24 
25 
30 inline
32 {
33  return (1<<sz) - 1;
34 }
35 
36 
37 } // anonymous namespace
38 
39 
40 namespace CxxUtils {
41 
42 
48 inline
50 {
51  return (n * m_bitsize + nper-1) / nper;
52 }
53 
54 
59 inline
61 {
62  return (n * m_bitsize) / nper;
63 }
64 
65 
70 inline
72 {
73  return (n * m_bitsize) % nper;
74 }
75 
76 
83 inline
85 {
86  // Get the bits from the first entry.
87  value_type v = m_vec[ndx] >> off;
88 
89  // If the packed entry wraps between two base entries, collect the bits
90  // from the next base entry.
91  if (m_bitsize > nper - off) {
92  int bits = m_bitsize - (nper - off);
93  // cppcheck-suppress shiftTooManyBits; false positive
94  // m_bitsize <= nper
95  v |= ((m_vec[ndx+1] & mask(bits)) << (nper - off));
96  }
97 
98  // Mask down to the proper number of bits.
99  return v & m_mask;
100 }
101 
102 
110 inline
112 {
113  // Set the bits in the first entry.
114  m_vec[ndx] = (m_vec[ndx] & ~(m_mask<<off)) | ((v&m_mask) << off);
115 
116  // If the packed entry wraps between two base entries, set the bits
117  // in the next entry.
118  if (m_bitsize > nper - off) {
119  value_type mask2 = mask (m_bitsize - (nper - off));
120  m_vec[ndx+1] = (m_vec[ndx+1] & ~mask2) | ((v >> (nper - off)) & mask2);
121  }
122 }
123 
124 
130 {
131  if (n >= m_size) {
132  throw_out_of_range (__PRETTY_FUNCTION__, n, m_size, this);
133  }
134 }
135 
136 
145  const allocator_type& allocator/*=allocator_type()*/)
146  : m_bitsize (bitsize),
147  m_size (0),
148  m_mask (mask (bitsize)),
149  m_vec (allocator)
150 {
151  assert (m_bitsize > 0 && m_bitsize <= nper);
152 }
153 
154 
165  size_type n,
166  value_type val /*= 0*/,
167  const allocator_type& allocator/*=allocator_type()*/)
168  : m_bitsize (bitsize),
169  m_size (n),
170  m_mask (mask (bitsize)),
171  m_vec (nbase(n), 0, allocator)
172 {
173  assert (m_bitsize > 0 && m_bitsize <= nper);
174  if (val != 0) {
175  for (size_type i = 0; i < n; i++)
176  set (i, val);
177  }
178 }
179 
180 
187 {
188  m_size = n;
189  m_vec.clear();
190  m_vec.resize (nbase(n));
191  if (u != 0) {
192  for (size_type i = 0; i < n; i++)
193  set (i, u);
194  }
195 }
196 
197 
202 {
203  return m_vec.get_allocator();
204 }
205 
206 
211 {
212  return m_size;
213 }
214 
215 
220 {
221  return m_vec.max_size();
222 }
223 
224 
230 {
231  return m_vec.capacity() * nper / m_bitsize;
232 }
233 
234 
241 {
242  m_vec.resize (nbase (sz));
243  if (sz > m_size) {
244  // Making the container bigger. Need to fill the remaining values.
245  if (c != 0) {
246  // Set them to something non-zero.
247  for (size_t i = m_size; i < sz; i++)
248  set (i, c);
249  }
250  else {
251  // Filling the new entries with 0.
252  // New elements in the base vector will have been set to 0.
253  // However, we also need to zero out any remaining packed elements
254  // (or piece thereof) in the last base element that was occupied
255  // before the resize.
256  int off = tooff (m_size);
257  // Don't need to do anything if packed entries exactly fit
258  // in the allocated base size.
259  if (off != 0) {
260  size_t ndx = tondx (m_size);
261  m_vec[ndx] &= mask (off);
262  }
263  }
264  }
265  m_size = sz;
266 }
267 
268 
272 bool PackedArray::empty() const
273 {
274  return m_size == 0;
275 }
276 
277 
284 {
285  m_vec.reserve (nbase (n));
286 }
287 
288 
294 {
295  return doget (tondx (n), tooff (n));
296 }
297 
298 
305 {
306  return doset (tondx (n), tooff (n), val);
307 }
308 
309 
319 {
320  return doget (tondx (n), tooff (n));
321 }
322 
323 
333 {
334  return proxy (*this, n);
335 }
336 
337 
347 {
348  range_check (n);
349  return doget (tondx (n), tooff (n));
350 }
351 
352 
362 {
363  range_check (n);
364  return proxy (*this, n);
365 }
366 
367 
376 {
377  return doget (0, 0);
378 }
379 
380 
389 {
390  return doget (tondx (m_size-1), tooff (m_size-1));
391 }
392 
393 
402 {
403  return proxy (*this, 0);
404 }
405 
406 
415 {
416  return proxy (*this, m_size-1);
417 }
418 
419 
425 {
426  ++m_size;
427  size_t nb = nbase (m_size);
428  if (nb != m_vec.size())
429  m_vec.resize (nb);
430  doset (tondx (m_size-1), tooff (m_size-1), x);
431 }
432 
433 
438 {
439  --m_size;
440  size_t nb = nbase (m_size);
441  if (nb != m_vec.size())
442  m_vec.resize (nb);
443 }
444 
445 
451 {
452  std::swap (m_bitsize, other.m_bitsize);
453  std::swap (m_size, other.m_size);
454  std::swap (m_mask, other.m_mask);
455  std::swap (m_vec, other.m_vec);
456 }
457 
458 
463 {
464  m_size = 0;
465  m_vec.clear();
466 }
467 
468 
475 void PackedArray::set_bitsize (int bitsize)
476 {
477  assert (m_size == 0);
478  assert (bitsize > 0 && bitsize <= nper);
479  m_bitsize = bitsize;
480  m_mask = mask (bitsize);
481 }
482 
483 
488 {
489  return m_bitsize;
490 }
491 
492 
493 } // namespace CxxUtils
CxxUtils::PackedArray::operator[]
value_type operator[](size_type n) const
Access an element, as an rvalue.
Definition: PackedArray.cxx:318
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:186
fitman.sz
sz
Definition: fitman.py:527
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:407
CxxUtils::PackedArray::push_back
void push_back(value_type x)
Add an element to the end of the collection.
Definition: PackedArray.cxx:424
CxxUtils::PackedArray::back
value_type back() const
Access the last element in the collection as an rvalue.
Definition: PackedArray.cxx:388
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:49
CxxUtils::PackedArray::swap
void swap(PackedArray &other)
Swap this collection with another.
Definition: PackedArray.cxx:450
CxxUtils::PackedArray::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
Definition: PackedArray.cxx:283
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:210
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:71
x
#define x
CxxUtils::PackedArray::bitsize
int bitsize() const
Return the bitsize of the container.
Definition: PackedArray.cxx:487
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:459
CxxUtils::PackedArray::at
value_type at(size_type n) const
Access an element, as an rvalue.
Definition: PackedArray.cxx:346
CxxUtils::PackedArray::empty
bool empty() const
Returns true if the collection is empty.
Definition: PackedArray.cxx:272
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:84
CxxUtils::PackedArray::get_allocator
allocator_type get_allocator() const
Returns the allocator of the underlying vector.
Definition: PackedArray.cxx:201
CxxUtils::PackedArray::PackedArray
PackedArray(int bitsize=8, const allocator_type &allocator=allocator_type())
Constructor.
Definition: PackedArray.cxx:144
CxxUtils::throw_out_of_range
void throw_out_of_range(const std::string &what, size_t index, size_t size, const void *obj)
Throw an out_of_range exception.
Definition: throw_out_of_range.cxx:27
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:727
throw_out_of_range.h
Helpers for throwing out_of_range exceptions.
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:129
CxxUtils::PackedArray::resize
void resize(size_type sz, value_type c=0)
Resizes the collection to the specified number of elements.
Definition: PackedArray.cxx:240
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:375
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:293
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:60
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
CxxUtils::PackedArray::set_bitsize
void set_bitsize(int bitsize)
Change the bitsize of the container.
Definition: PackedArray.cxx:475
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:304
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:437
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:111
hotSpotInTAG.nb
nb
Definition: hotSpotInTAG.py:163
value_type
Definition: EDM_MasterSearch.h:11
CxxUtils::PackedArray::clear
void clear()
Erase all the elements in the collection.
Definition: PackedArray.cxx:462
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:229
CxxUtils::PackedArray::max_size
size_type max_size() const
Returns the size() of the largest possible collection.
Definition: PackedArray.cxx:219
CxxUtils::PackedArray::size_type
size_t size_type
Definition: PackedArray.h:49