ATLAS Offline Software
Loading...
Searching...
No Matches
CxxUtils Namespace Reference

Namespaces

namespace  detail
namespace  fpcompare
namespace  fpcompare_fn
namespace  vecDetail

Classes

class  ArrayIterator
 Iterator class for Array<N>. More...
class  WritableArray
 Read-write multidimensional array. More...
class  ArrayIteratorChooser
 Helper for defining iterators over Array's. More...
class  ArrayIteratorChooser< 1 >
 Helper for defining iterators over Array's, specialized for N == 1. More...
class  Array
 Read-only multidimensional array. More...
class  Array< 0 >
 Read-only multidimensional array, specialized for N=0. More...
class  WritableArray< 0 >
class  WritableArrayData
class  ArrayScanner
 Helper class for converting strings to Array's. More...
class  BitPacker
 Pack a set of values bitwise into a stream. More...
class  BitPacker8
 Pack a set of values bitwise into a stream. More...
class  BitPacker16
 Pack a set of values bitwise into a stream. More...
class  BitUnpacker
 Helper to unpack a set of values bitwise from a stream. More...
class  BitUnpacker8
 Helper to unpack a set of values bitwise from a stream. More...
class  BitUnpacker16
 Helper to unpack a set of values bitwise from a stream. More...
union  CachedPointer
 Cached pointer with atomic update. More...
class  CachedUniquePtrT
 Cached pointer with atomic update. More...
class  CachedValue
 Cached value with atomic update. More...
class  ExcBadClassName
 Recursively separate out template arguments in a C++ class name. More...
class  ExcMissingVariable
 Exception to signal a missing variable. More...
class  Rules
 A set of transformation rules to use with ClassName. More...
class  reference
 A reference to one bit in a set. More...
class  const_iterator
 Iterator over all 1 bits in the set. More...
class  Impl
 Implementation object. More...
class  ConcurrentPtrSet
 A set of pointers, allowing concurrent, lockless queries. More...
class  IRangeMapPayloadDeleter
 Helper to delete payload objects for ConcurrentRangeMap. More...
struct  DeletePayload
 Map from range to payload object, allowing concurrent, lockless reads. More...
class  ConcurrentStrMap
 Hash map from strings allowing concurrent, lockless reads. More...
class  ConcurrentStrToValMap
 Hash map from strings to arbitrary objects allowing concurrent, lockless reads. More...
class  iterator
 Iterator class. More...
class  FloatCompressor
 Class implementing a lossy float compression. More...
class  FloatPacker
 Pack/unpack floating-point data from/to a given number of bits. More...
class  iterator_range
 Simple range from a pair of iterators. More...
class  LockedPointer
 A pointer together with a movable lock. More...
class  CMurmurHash2A
class  PackedArray
 An array of unsigned values of some bit size, packed tightly. More...
class  pointer_list_base
 A fast way to store a variable-sized collection of pointers. More...
class  pointer_list
 A fast way to store a variable-sized collection of pointers. More...
class  range_with_at
 Add at() methods to a range class. More...
class  range_with_conv
 Add to a range class conversions to containers. More...
class  RefCountedPtr
 Simple smart pointer for Gaudi-style refcounted objects. More...
class  releasing_iterator
 Adapter to retrieve elements from a unique_ptr iterator via release(). More...
class  reverse_wrapper
 Adapter for a container-like class to be used in a range-for so as to iterate in the reverse direction. More...
class  Ring
 A very simple ring buffer. More...
class  SimpleUpdater
 Simple (non-deleting) Updater implementation. More...
struct  sincos
 Helper to simultaneously calculate sin and cos of the same angle. More...
class  span
 Simplified version of the C++20 std::span. More...
struct  vec_fb
class  CRCTable
 Precomputed tables and constants for the CRC calculation. More...
class  RedirStderr
struct  extrace_init
class  Arrayrep
 Representation class for Array's. More...

Concepts

concept  FromArrayrep
 Concept testing whether a type may be used with FromArrayrep.
concept  InputRangeOverT
 Concept for an input range over a given type.
concept  Numeric

Typedefs

template<class T, size_t Alignment = 1>
using aligned_vector = std::vector<T, boost::alignment::aligned_allocator<T, Alignment> >
 A std::vector with extra alignment.
template<class T>
using vec_aligned_vector = aligned_vector<T, 64>
 A std::vector with alignment sufficient for any vector instructions on this platform.
template<class T>
using CachedUniquePtr = CachedUniquePtrT<const T>
typedef std::map< std::string, ClassNamematch_t
 Map used to hold variable assignments from matching.
using const_iterator_value = std::pair<const key_type, mapped_type>
 Value structure for iterators.
using const_iterator_range = CxxUtils::iterator_range<const_iterator>
 A range defined by two iterators.
using payload_unique_ptr = std::unique_ptr<T, DeletePayload>
 unique_ptr holding a payload object.
using const_iterator = const value_type*
using Updater_t = UPDATER<Impl>
using IPayloadDeleter = CxxUtils::IRangeMapPayloadDeleter<T, typename Updater_t::Context_t>
using iterator_value = std::pair<const key_type, mapped_type&>
using iterator_range = CxxUtils::iterator_range<iterator>
template<class KEY, class COMPARE = std::less<KEY>, class KEYCONTAINER = void>
using flat_set = boost::container::flat_set<KEY, COMPARE, KEYCONTANER>
template<class T, size_t N>
using inplace_vector = boost::container::small_vector<T, N>
template<std::ranges::input_range SPAN, class XFORM>
using transform_view_with_at
 Helper to add at() methods to a transform_view.
template<typename T, size_t N>
using vec = typename vecDetail::vec_typedef<T,N>::type
 Define a nice alias for the vectorized type.
template<class VEC>
using vec_type_t = typename vecDetail::vec_type<VEC>::type
 Define a nice alias for the element type of a vectorized type.
template<class VEC>
using vec_mask_type_t = typename vecDetail::vec_mask_type<VEC>::type
 Define a nice alias for the mask type for a vectorized type.
template<typename T, size_t N>
using ivec = vec_fb<typename boost::int_t<sizeof(T) * 8>::exact, N>
typedef float Arrayelt
 The type of an element of an Array.

Enumerations

enum  CacheState : unsigned char { INVALID = 0 , UPDATING = 1 , VALID = 2 }
 State of the cached value; see below. More...
enum class  EmplaceResult { SUCCESS , OVERLAP , DUPLICATE , EXTENDED }
 Results returned from emplace(). More...
enum  { CacheLineSize = 64 }
 While it is possible to determine cache line size at run time (e.g. More...

Functions

template<unsigned int N>
std::ostream & operator<< (std::ostream &s, const Array< N > &a)
template<class T>
void fromArrayrep (const CaloRec::Arrayrep &rep, T &x)
 Helper to convert from an @x Arrayrep to a scalar type.
template<unsigned int N>
void fromArrayrep (const CaloRec::Arrayrep &rep, CxxUtils::Array< N > &x)
 Helper to convert from an @x Arrayrep to an Array.
template<class T>
const T * as_const_ptr (const T *p)
 Helper for getting a const version of a pointer.
template<class T>
atomic_bounded_decrement (std::atomic< T > *a, T bound=0, T decr=1, std::memory_order memorder=std::memory_order_seq_cst)
 Atomically decrement a value with a lower bound.
template<class T>
atomic_fetch_max (std::atomic< T > *a, T v, std::memory_order memorder=std::memory_order_seq_cst)
 Atomically calculate maximum.
template<class T>
atomic_fetch_min (std::atomic< T > *a, T v, std::memory_order memorder=std::memory_order_seq_cst)
 Atomically calculate minimum.
std::string base64_encode (const unsigned char *, unsigned int)
std::vector< unsigned char > base64_decode (const std::string &)
template<class E>
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set (E &lhs, E rhs)
 Convenience function to set bits in a class enum bitmask.
template<class E>
constexpr std::enable_if_t< is_bitmask_v< E >, E & > reset (E &lhs, E rhs)
 Convenience function to clear bits in a class enum bitmask.
template<class E>
constexpr std::enable_if_t< is_bitmask_v< E >, bool > test (E lhs, E rhs)
 Convenience function to test bits in a class enum bitmask.
template<std::integral T>
constexpr T byteswap (T value) noexcept
 Reverse the bytes in n.
 ClassName ()
 Default constructor.
 ClassName (const char *name)
 Parse a class name into component parts.
 ClassName (const std::string &name)
 Parse a class name into component parts.
 ClassName (const std::string &name, std::string::size_type &pos)
 Parse a class name into component parts.
void swap (ClassName &other)
 Swap this expression with another one.
bool isConst () const
 Get the const flag for this expression.
void setConst ()
 Set the const flag for this expression.
const std::string & name () const
 Return the root name of the expression.
std::string qualifiedName () const
 Return the namespace-qualified name of the expression.
std::string fullName () const
 Return the full name of the expression.
size_t ntargs () const
 Return number of template arguments.
const ClassNametarg (size_t i) const
 Return one template argument.
bool operator== (const ClassName &other) const
 Test two expressions for equality.
bool operator!= (const ClassName &other) const
 Test two expressions for inequality.
bool match (const ClassName &pattern, match_t &matches) const
 Match this expression against a pattern.
void subst (const match_t &matches)
 Substitute variables into this expression.
ClassName substCopy (const match_t &matches) const
 Return a copy of this expression with variables substituted.
void applyRules (const Rules &rules)
 Apply a set of transformation rules to this object.
static std::string applyRules (const std::string &name, const Rules &rules)
 Apply a set of transformation rules a class name.
void parse (const std::string &name, std::string::size_type &pos)
 Parse a string into a ClassName.
std::string parsePrimary (const std::string &name, std::string::size_type &pos)
 Parse a primary part of the class name.
void parseNamespace (const std::string &name, std::string::size_type &pos)
 Parse a namespace qualification.
void parseTemplateArgs (const std::string &name, std::string::size_type &pos)
 Parse the template part of a name.
void skipSpaces (const std::string &name, std::string::size_type &pos)
 Skip past spaces in a string.
bool match1 (const ClassName &pattern, bool topLevel, match_t &matches) const
 Match this expression against a pattern.
bool applyRules1 (const Rules &rules)
 Apply a set of transformation rules to this object.
template<typename T>
bool close_to_zero (T value, T eps=std::numeric_limits< T >::epsilon())
 ConcurrentMap (Updater_t &&updater, size_type capacity=64, const Context_t &ctx=Updater_t::defaultContext())
 Hash map from integers/pointers allowing concurrent, lockless reads.
 ConcurrentMap (const ConcurrentMap &other, Updater_t &&updater, size_t capacity=64, const Context_t &ctx=Updater_t::defaultContext())
 Constructor from another map.
template<class InputIterator>
 ConcurrentMap (InputIterator f, InputIterator l, Updater_t &&updater, size_type capacity=64, const Context_t &ctx=Updater_t::defaultContext())
 Constructor from a range.
 ConcurrentMap (const ConcurrentMap &other)=delete
 Copy / move / assign not supported.
 ConcurrentMap (ConcurrentMap &&other)=delete
ConcurrentMapoperator= (const ConcurrentMap &other)=delete
ConcurrentMapoperator= (ConcurrentMap &&other)=delete
 ~ConcurrentMap ()=default
 Destructor.
size_t erased () const
 The number of erased elements in the current table.
const_iterator_range range () const
 Return an iterator range covering the entire map.
const_iterator cbegin () const
 Iterator at the start of the map.
const_iterator cend () const
 Iterator at the end of the map.
bool contains (key_type key) const
 Test if a key is in the container.
size_type count (key_type key) const
 Return the number of times a given key is in the container.
const_iterator find (key_type key) const
 Look up an element in the map.
mapped_type at (key_type key) const
 Look up an element in the map.
std::pair< const_iterator, const_iteratorequal_range (key_type key) const
 Return a range of iterators with entries matching key.
Lock_t lock ()
 Take a lock on the container.
std::pair< const_iterator, bool > emplace (key_type key, mapped_type val, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map.
std::pair< const_iterator, bool > emplace (const Lock_t &lock, key_type key, mapped_type val, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map, with external locking.
std::pair< const_iterator, bool > insert_or_assign (key_type key, mapped_type val, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map, or overwrite an existing one.
std::pair< const_iterator, bool > insert_or_assign (const Lock_t &lock, key_type key, mapped_type val, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map, or overwrite an existing one, with external locking.
template<class PAIR>
std::pair< const_iterator, bool > insert (const PAIR &p)
 Add an element to the map.
template<class InputIterator>
void insert (InputIterator first, InputIterator last)
 Insert a range of elements to the map.
bool erase (key_type key)
 Erase an entry from the table.
bool erase (const Lock_t &lock, key_type key)
 Erase an entry from the table, with external locking.
void reserve (size_type capacity, const Context_t &ctx=Updater_t::defaultContext())
 Increase the table capacity.
void rehash (size_type capacity)
 Increase the table capacity.
void clear (size_t capacity, const Context_t &ctx=Updater_t::defaultContext())
 Erase the table and change the capacity.
void clear (const Context_t &ctx=Updater_t::defaultContext())
 Erase the table (don't change the capacity).
void forceClear ()
 Erase the table in-place.
void quiescent (const Context_t &ctx)
 Called when this thread is no longer referencing anything from this container.
void swap (ConcurrentMap &other)
 Swap this container with another.
Updater_tupdater ()
 Access the Updater instance.
static key_type keyAsKey (val_t val)
 Convert an underlying key value to this type's key value.
static val_t keyAsVal (key_type k)
 Convert this type's key value to an underlying key value.
static mapped_type mappedAsMapped (val_t val)
 Convert an underlying mapped value to this type's mapped value.
static val_t mappedAsVal (mapped_type val)
 Convert this type's mapped value to an underlying mapped value.
Impl_t::const_iterator get (key_type key) const
 Do a lookup in the table.
std::pair< const_iterator, bool > put (key_type key, mapped_type val, bool overwrite=true, const Context_t &ctx=Updater_t::defaultContext())
 Insert / overwrite an entry in the table.
std::pair< const_iterator, bool > put (const Lock_t &lock, key_type key, mapped_type val, bool overwrite=true, const Context_t &ctx=Updater_t::defaultContext())
 Insert / overwrite an entry in the table, with external locking.
 ConcurrentRangeMap (Updater_t &&updater, std::shared_ptr< IPayloadDeleter > payloadDeleter, size_t capacity=16, const COMPARE &compare=COMPARE())
 Constructor.
 ~ConcurrentRangeMap ()
 Destructor.
IPayloadDeleterdeleter ()
 Return a reference to the payload deleter object.
const_iterator find (const key_query_type &key) const
 Search for the first item less than or equal to KEY.
EmplaceResult emplace (const RANGE &range, payload_unique_ptr ptr, bool tryExtend=false, const typename Updater_t::Context_t &ctx=Updater_t::defaultContext())
 Add a new element to the map.
void erase (const key_query_type &key, const typename Updater_t::Context_t &ctx=Updater_t::defaultContext())
 Erase the first item less than or equal to KEY.
int extendLastRange (const RANGE &newRange, const typename Updater_t::Context_t &ctx=Updater_t::defaultContext())
 Extend the range of the last entry of the map.
void updateRanges (std::function< void(RANGE &)> rangeUpdater, const typename Updater_t::Context_t &ctx=Updater_t::defaultContext())
 Update all range objects.
size_t trim (const std::vector< key_query_type > &keys, bool trimall=false)
 Remove unused entries from the front of the list.
size_t nInserts () const
 Return the number times an item was inserted into the map.
size_t maxSize () const
 Return the maximum size of the map.
void quiescent (const typename Updater_t::Context_t &ctx=Updater_t::defaultContext())
 Called when this thread is no longer referencing anything from this container.
const_iterator getBegin (const_iterator &last) const
 Return the begin/last pointers.
void updatePointers (value_type *new_begin, value_type *new_end)
 Consistently update both the begin and last pointers.
bool anyInRange (const key_type &r, const std::vector< key_query_type > &keys) const
 Test to see if any keys within keys match r.
void installImpl (std::unique_ptr< Impl > new_impl, value_type *new_begin, value_type *new_end, const typename Updater_t::Context_t &ctx)
 Install a new implementation instance and make it visible.
int extendImpl (lock_t &lock, const RANGE &extendedRange, const typename Updater_t::Context_t &ctx)
 Extend the range of the last entry of the map.
 ConcurrentToValMap (Updater_t &&updater, size_type capacity=64, const Context_t &ctx=Updater_t::defaultContext())
 Hash map from pointers/integers to arbitrary objects allowing concurrent, lockless reads.
 ConcurrentToValMap (const ConcurrentToValMap &other, Updater_t &&updater, size_t capacity=64, const Context_t &ctx=Updater_t::defaultContext())
 Constructor from another map.
template<class InputIterator>
 ConcurrentToValMap (InputIterator f, InputIterator l, Updater_t &&updater, size_type capacity=64, const Context_t &ctx=Updater_t::defaultContext())
 Constructor from a range.
 ConcurrentToValMap (const ConcurrentToValMap &other)=delete
 Copy / move / assign not supported.
 ConcurrentToValMap (ConcurrentToValMap &&other)=delete
ConcurrentToValMapoperator= (const ConcurrentToValMap &other)=delete
ConcurrentToValMapoperator= (ConcurrentToValMap &&other)=delete
 ~ConcurrentToValMap ()
 Destructor.
std::pair< const_iterator, bool > emplace (key_type key, const mapped_type &val, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map.
std::pair< const_iterator, bool > emplace (key_type key, mapped_type &&val, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map.
std::pair< const_iterator, bool > emplace (key_type key, std::unique_ptr< mapped_type > val, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map.
template<class PAIR>
std::pair< const_iterator, bool > insert (const PAIR &p, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map.
template<class PAIR>
std::pair< const_iterator, bool > insert (PAIR &&p, const Context_t &ctx=Updater_t::defaultContext())
 Add an element to the map.
template<class InputIterator>
void insert (InputIterator first, InputIterator last, const Context_t &ctx=Updater_t::defaultContext())
 Insert a range of elements to the map.
void swap (ConcurrentToValMap &other)
 Swap this container with another.
static key_type keyAsKey (val_t val)
 Convert an underlying key value to this type's key value.
static val_t keyAsVal (key_type k)
 Convert this type's key value to an underlying key value.
static mapped_type * mappedAsMapped (val_t val)
 Convert an underlying mapped value a pointer to this type's mapped value.
static val_t mappedAsVal (mapped_type *val)
 Convert this type's mapped value to an underlying mapped value.
std::pair< const_iterator, bool > put (const key_type key, std::unique_ptr< mapped_type > val, const Context_t &ctx=Updater_t::defaultContext())
 Insert an entry in the table.
template<class InputIterator, class OutputIterator, class InputTag, class OutputTag>
OutputIterator copy_bounded1 (InputIterator begi, InputIterator endi, OutputIterator bego, OutputIterator endo, const InputTag &, const OutputTag &)
 Copy a range with bounds restriction; generic version.
template<class InputIterator, class OutputIterator>
OutputIterator copy_bounded1 (InputIterator begi, InputIterator endi, OutputIterator bego, OutputIterator endo, const std::random_access_iterator_tag &, const std::random_access_iterator_tag &)
 Copy a range with bounds restriction; random_access_iterator version.
template<std::input_iterator InputIterator, std::output_iterator< typename std::iterator_traits< InputIterator >::value_type > OutputIterator>
OutputIterator copy_bounded (InputIterator begi, InputIterator endi, OutputIterator bego, OutputIterator endo)
 Copy a range with bounds restriction.
template<class InputRange, class OutputRange>
auto copy_bounded (const InputRange &input, OutputRange &output) -> decltype(std::begin(output))
 Copy a range with bounds restriction.
template<class InputRange, class OutputRange>
auto copy_bounded (const InputRange &input, OutputRange &&output) -> decltype(std::begin(output))
 Copy a range with bounds restriction.
void deleteCRCTable (CxxUtils::CRCTable *table)
 Delete a CRCTable object.
std::unique_ptr< CRCTablemakeCRCTable (uint64_t p, uint64_t initial=0xffffffffffffffff)
 Initialize CRC tables and constants.
uint64_t crc64_bytewise (const CRCTable &table, const char *data, size_t data_len)
 Find the CRC-64 of a string, using a byte-by-byte algorithm.
uint64_t crc64_bytewise (const char *data, size_t data_len)
 Find the CRC-64 of a string, using a byte-by-byte algorithm, with the default CRC.
uint64_t crc64_bytewise (const std::string &s)
 Find the CRC-64 of a string, using a byte-by-byte algorithm, with the default CRC.
uint64_t crc64 (const CRCTable &table, const char *data, size_t data_len)
 Find the CRC-64 of a string,.
uint64_t crc64 (const char *data, size_t data_len)
 Find the CRC-64 of a string, with the default CRC.
uint64_t crc64 (const std::string &s)
 Find the CRC-64 of a string, using the default polynomial.
uint64_t crc64addint (uint64_t crc, uint64_t x)
 Extend a previously-calculated CRC to include an int.
std::string crc64format (uint64_t crc)
 Format a CRC-64 as a string.
std::string crc64digest (const std::string &str)
 Return a CRC-64 digest of a string.
void exctrace (const std::exception &e, IOFD fd=IOFD_INVALID)
 Print out information for the last exception.
uint16_t le16toh (uint16_t x)
uint32_t le32toh (uint32_t x)
uint64_t le64toh (uint64_t x)
uint16_t get_unaligned16 (const uint8_t *ATH_RESTRICT &p)
 Read a 2-byte little-endian value from a possibly unaligned pointer.
uint32_t get_unaligned32 (const uint8_t *ATH_RESTRICT &p)
 Read a 4-byte little-endian value from a possibly unaligned pointer.
uint64_t get_unaligned64 (const uint8_t *ATH_RESTRICT &p)
 Read an 8-byte little-endian value from a possibly unaligned pointer.
float get_unaligned_float (const uint8_t *ATH_RESTRICT &p)
 Read a little-endian float value from a possibly unaligned pointer.
double get_unaligned_double (const uint8_t *ATH_RESTRICT &p)
 Read a little-endian double value from a possibly unaligned pointer.
template<class T>
get_unaligned (const uint8_t *ATH_RESTRICT &p)
 Define templated versions of the above functions.
template<>
uint8_t get_unaligned< uint8_t > (const uint8_t *ATH_RESTRICT &p)
template<>
uint16_t get_unaligned< uint16_t > (const uint8_t *ATH_RESTRICT &p)
template<>
uint32_t get_unaligned< uint32_t > (const uint8_t *ATH_RESTRICT &p)
template<>
uint64_t get_unaligned< uint64_t > (const uint8_t *ATH_RESTRICT &p)
template<>
float get_unaligned< float > (const uint8_t *ATH_RESTRICT &p)
template<>
double get_unaligned< double > (const uint8_t *ATH_RESTRICT &p)
template<>
int8_t get_unaligned< int8_t > (const uint8_t *ATH_RESTRICT &p)
template<>
int16_t get_unaligned< int16_t > (const uint8_t *ATH_RESTRICT &p)
template<>
int32_t get_unaligned< int32_t > (const uint8_t *ATH_RESTRICT &p)
template<>
int64_t get_unaligned< int64_t > (const uint8_t *ATH_RESTRICT &p)
void hexdump (std::ostream &s, const void *addr, size_t n, size_t offset=0)
 Make a hex dump of memory.
void safeHexdump (std::ostream &s, const void *addr, size_t n, size_t offset=0)
 Make a hex dump of memory, protected against bad reads.
template<class RANGE, class FUNC>
auto min_transformed_element (RANGE &&r, FUNC &&f)
 Find the minimum transformed element in a range.
template<class RANGE, class FUNC>
auto max_transformed_element (RANGE &&r, FUNC &&f)
 Find the maximum transformed element in a range.
uint32_t MurmurHash2 (const void *key, int len, uint32_t seed)
uint64_t MurmurHash64A (const void *key, int len, uint64_t seed)
uint64_t MurmurHash64B (const void *key, int len, uint64_t seed)
uint32_t MurmurHash2A (const void *key, int len, uint32_t seed)
uint32_t MurmurHashNeutral2 (const void *key, int len, uint32_t seed)
uint32_t MurmurHashAligned2 (const void *key, int len, uint32_t seed)
std::string normalizeFunctionName (const std::string &fname)
 Normalize a pretty-printed C++ function name.
template<class T>
constexpr T ones (unsigned int n)
 Return a bit mask with the lower n bits set.
template<typename T>
wrapToPi (T phi)
 Wrap angle in radians to [-pi, pi].
template<typename T>
deltaPhi (T phiA, T phiB)
 Return difference phiA - phiB in range [-pi, pi].
template<typename T>
phiMean (T phiA, T phiB)
 Calculate average of two angles.
template<typename T>
phiBisect (T phiA, T phiB)
 Bisect (average) the angle spanned by phiA and phiB.
void prefetchOne (const void *address)
 Generic prefetch method.
template<size_t N>
void prefetchN (const void *ptr)
 Prefetch an N-byte block of memory.
template<typename T>
void prefetchObj (const T *ptr)
 Generic prefetch of the object of specific types (sizes).
template<typename Iter>
void prefetchNext (Iter iter, Iter endIter)
 Prefetch next object in sequence.
template<typename Iter>
void prefetchTwo (Iter iter, Iter endIter)
 Prefetch two objects.
template<class T>
auto begin (range_with_at< T > &s)
template<class T>
auto begin (const range_with_at< T > &s)
template<class T>
auto end (range_with_at< T > &s)
template<class T>
auto end (const range_with_at< T > &s)
template<class T>
auto begin (range_with_conv< T > &s)
template<class T>
auto begin (const range_with_conv< T > &s)
template<class T>
auto end (range_with_conv< T > &s)
template<class T>
auto end (const range_with_conv< T > &s)
template<class CONT, class RANGE>
CONT to (RANGE &&r)
template<class T>
auto make_reverse_wrapper (T &r)
 Make a reverse_wrapper for a given container-like object.
uint16_t htole16 (uint16_t x)
uint32_t htole32 (uint32_t x)
uint64_t htole64 (uint64_t x)
void set_unaligned16 (uint8_t *ATH_RESTRICT &p, uint16_t val)
 Write a 2-byte little-endian value to a possibly unaligned pointer.
void set_unaligned32 (uint8_t *ATH_RESTRICT &p, uint32_t val)
 Write a 4-byte little-endian value to a possibly unaligned pointer.
void set_unaligned64 (uint8_t *ATH_RESTRICT &p, uint64_t val)
 Write an 8-byte little-endian value to a possibly unaligned pointer.
void set_unaligned_float (uint8_t *ATH_RESTRICT &p, float val)
 Write a little-endian float value to a possibly unaligned pointer.
void set_unaligned_double (uint8_t *ATH_RESTRICT &p, double val)
 Write a little-endian double value to a possibly unaligned pointer.
template<class T>
void set_unaligned (uint8_t *ATH_RESTRICT &p, T val)
 Define templated versions of the above functions.
template<>
void set_unaligned< uint8_t > (uint8_t *ATH_RESTRICT &p, uint8_t val)
template<>
void set_unaligned< uint16_t > (uint8_t *ATH_RESTRICT &p, uint16_t val)
template<>
void set_unaligned< uint32_t > (uint8_t *ATH_RESTRICT &p, uint32_t val)
template<>
void set_unaligned< uint64_t > (uint8_t *ATH_RESTRICT &p, uint64_t val)
template<>
void set_unaligned< float > (uint8_t *ATH_RESTRICT &p, float f)
template<>
void set_unaligned< double > (uint8_t *ATH_RESTRICT &p, double f)
template<>
void set_unaligned< int8_t > (uint8_t *ATH_RESTRICT &p, int8_t val)
template<>
void set_unaligned< int16_t > (uint8_t *ATH_RESTRICT &p, int16_t val)
template<>
void set_unaligned< int32_t > (uint8_t *ATH_RESTRICT &p, int32_t val)
template<>
void set_unaligned< int64_t > (uint8_t *ATH_RESTRICT &p, int64_t val)
template<class T>
 span (T *ptr, std::size_t sz) -> span< T >
 A couple needed deduction guides.
template<class T>
 span (T *beg, T *end) -> span< T >
template<detail::IsContiguousContainer CONTAINER>
auto make_span (CONTAINER &c)
 Helper to make a span from a container.
template<class T>
auto begin (span< T > &s)
template<class T>
auto begin (const span< T > &s)
template<class T>
auto end (span< T > &s)
template<class T>
auto end (const span< T > &s)
std::string strformat (const char *fmt,...)
 return a std::string according to a format fmt and varargs
int atoi (std::string_view str)
 Helper functions to unpack numbers decoded in string into integers and doubles The strings are required to contain only digits, a floating point dot, the signs +- or a whitespace Exceptions are thrown otherwise.
double atof (std::string_view str)
 Converts a string into a double / float.
std::string_view trimWhiteSpaces (std::string_view str) noexcept
 Removes all trailing and starting whitespaces from a string.
std::vector< std::string > tokenize (std::string_view the_str, std::string_view delimiters)
 Splits the string into smaller substrings.
std::vector< std::string > tokenize (std::string_view the_str, char delimiter)
std::vector< double > tokenizeDouble (std::string_view the_str, std::string_view delimiter)
std::vector< int > tokenizeInt (std::string_view str, std::string_view delimiter)
template<Numeric dType, bool silenceEmpty = true>
void convertToNumber (std::string_view str, dType &number)
template<typename T = std::string, typename X = std::string_view>
std::vector< T > tokenize (std::string_view str, X delimiters)
void throw_out_of_range (const std::string &what, size_t index, size_t size, const void *obj)
 Throw an out_of_range exception.
void throw_out_of_range (const char *what, size_t index, size_t size, const void *obj)
 Throw an out_of_range exception.
void ubsan_suppress (void(*func)())
 Helper for suppressing ubsan warnings.
template<class VEC>
ATH_ALWAYS_INLINE constexpr size_t vec_size ()
 Return the number of elements in a vectorized type.
template<class VEC>
ATH_ALWAYS_INLINE constexpr size_t vec_size (const VEC &)
 Return the number of elements in a vectorized type.
template<typename VEC, typename T>
ATH_ALWAYS_INLINE void vbroadcast (VEC &v, T x)
 Copy a scalar to each element of a vectorized type.
template<typename VEC>
ATH_ALWAYS_INLINE void vload (VEC &dst, vec_type_t< VEC > const *src)
template<typename VEC>
ATH_ALWAYS_INLINE void vstore (vec_type_t< VEC > *dst, const VEC &src)
template<typename VEC>
ATH_ALWAYS_INLINE void vselect (VEC &dst, const VEC &a, const VEC &b, const vec_mask_type_t< VEC > &mask)
template<typename VEC>
ATH_ALWAYS_INLINE void vmin (VEC &dst, const VEC &a, const VEC &b)
template<typename VEC>
ATH_ALWAYS_INLINE void vmax (VEC &dst, const VEC &a, const VEC &b)
template<typename VEC>
ATH_ALWAYS_INLINE bool vany (const VEC &mask)
template<typename VEC>
ATH_ALWAYS_INLINE bool vnone (const VEC &mask)
template<typename VEC>
ATH_ALWAYS_INLINE bool vall (const VEC &mask)
template<typename VEC1, typename VEC2>
ATH_ALWAYS_INLINE void vconvert (VEC1 &dst, const VEC2 &src)
 performs dst is the result of a static cast of each element of src
template<size_t... Indices, typename VEC, typename VEC1>
ATH_ALWAYS_INLINE void vpermute (VEC1 &dst, const VEC &src)
 vpermute function.
template<size_t... Indices, typename VEC, typename VEC1>
ATH_ALWAYS_INLINE void vpermute2 (VEC1 &dst, const VEC &src1, const VEC &src2)
 vpermute2 function.
template<typename T, size_t N>
ivec< T, N > operator! (const vec_fb< T, N > &a)
 Negation.
template<typename T, size_t N>
ivec< T, N > operator&& (const vec_fb< T, N > &a, const vec_fb< T, N > &b)
 V1 && V2.
template<typename T, size_t N, class U>
ivec< T, N > operator&& (U a, const vec_fb< T, N > &b)
 S && V.
template<typename T, size_t N, class U>
ivec< T, N > operator&& (const vec_fb< T, N > &a, U b)
 V && S.
template<typename T, size_t N>
ivec< T, N > operator|| (const vec_fb< T, N > &a, const vec_fb< T, N > &b)
 V1 || V2.
void * xmalloc (size_t size)
 Trapping version of malloc.
static bool is_base64 (unsigned char c)
Constructors, destructors, assignment.

Variable-sized bitset allowing (mostly) concurrent access.

This class represents a set of bits. One can think of such an object as either like a std::bitset or like a std::set<unsigned>. This class provides basically the union of the two interfaces. In a few cases, the same method has different semantics in the two interfaces, most notably size(). We follow here the semantics that we would get from std::set<unsigned>. (Rationale: The motivation for this class is to replace the existing use of unordered_set<unsigned> for auxid_set_t. Supplying the same interface makes this easier to drop in as a replacement. However, in some cases, the set operations as provided by a bitset-like interface can be much more efficient, so we'd want to provide those as well.)

The size of the bitset is specified at runtime, to the constructor. Most operations do not change the size. However, the insert() methods, as well as operator=, may be used to grow the size of the set.

Most methods can execute completely concurrently. However, the methods which can change the size of the container, insert() and operator=, are not compatible with other concurrent writes. (Concurrent reads are ok, though.)

Some methods can operate on the entire set (e.g., clear()). Such methods may run concurrently with others, but they will not necessarily be atomic: other threads may be able to see the operation partially completed.

An iterator is provided that iterates over all bits that are set (like iterating over a set<unsigned>).

When the container is expanded, the internal representation needs to be reallocated. The old object is not, however, deleted immediately, as other threads may still be referencing it. If if some point you know that no threads can be referencing old versions any more, you can clean them up by calling emptyGarbage (otherwise, all versions will be deleted when the set object is destroyed).

Some notes on motivation:

The use case that motivated this class was auxid_set_t, which tells which auxiliary variables are available for a given container. This is logically a relatively sparse set of relatively small integers. (Maximum value is ~2000, with a set having ~100 entries.)

This had been implemented as a std::unordered_set<size_t>, but this was not entirely satisfactory. First, in some cases, there was a significant overhead in inserting and deleting items from the set. Second, unordered_set does not allow concurrent reading and writing. This meant that we ended up maintaining thread-local copies of each set, which adds extra overhead and complexity.

The threading issue suggests that we would like to use a container that allows readers to run currently with at least one writer. The fact that the maximum value to be stored in these sets is not too large suggests that a bitmap might be a good representation, as long as the time required to iterate over the set doesn't blow up due to the sparseness of the map.

To study this, a reconstruction job was instrumented to dump out all unique auxid_set_t values. This corpus was then used to run a set of timing tests for different set implementations. This test is built into the ConcurrentBitset unit test, and the corpus is available in the CxxUtils package. Run like:

.../ConcurrentBitset_test.exe --perf .../CxxUtils/share/auxids.uniq

Set implementations that have been tested so far include:

  • std::set
  • std::unordered_set
  • concurrent_unordered_set, from TBB
  • ck_hs, from ConcurrencyKit
  • ck_bitmap, from ConcurrencyKit
  • ConcurrentBitset

Representative results (times in seconds; lower is better):

|--------------------------+------+------+---------+--------|
| | fill | copy | iterate | lookup |
|--------------------------+------+------+---------+--------|
| set | 0.92 | 0.66 | 10.95 | 0.53 |
| unordered_set | 1.63 | 0.93 | 6.56 | 0.50 |
| concurrent_unordered_set | 1.79 | 1.70 | 9.55 | 1.20 |
| ck_hs | 0.78 | 0.83 | 18.92 | 0.88 |
| ck_bitmap | 0.13 | 0.21 | 5.52 | 0.05 |
| ConcurrentBitset | 0.31 | 0.06 | 4.48 | 0.08 |
|--------------------------+------+------+---------+--------|
ConcurrentBitset(bit_t nbits=0)
Constructor.
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition bitmask.h:232
void fill(H5::Group &out_file, size_t iterations)

For this workload, the bitmaps are the clear winner.

Implementation notes:

The implementation here is inspired by ck_bitmap from ConcurrencyKit (http://concurrencykit.org/), though the code is all new. ck_bitmap itself isn't suitable because it doesn't allow for the set to grow, and also because it's a pure C interface, while we want something with a C++ style interface (and in particular something which supports interfaces close to unordered_set<size_t> in order to ease migration).

The bitset is stored as an array of std::atomic<Block_t> objects, where Block_t is the largest unsigned type for which atomic is lockless. This is stored in a separate implementation object in order to allow the container to grow. The implementation object has a fixed-size header followed by the variable-size array of blocks.

To speed up iteration for the typical case of a sparse set, we maintain a `high-water' mark, m_hwm, which is the index of the highest block that might have a bit set. m_hwm can only increase unless the set is cleared. */ class ConcurrentBitset { private: Forward declaration of implementation class. class Impl;

/ Internal type used to hold the bitset data. / The bitset is an array of std::atomic<Block_t>. / This type should generally be the largest unsigned type for which / std::atomic is lockless. typedef unsigned long Block_t;

/ Size, in bits, of Block_t. static const size_t BLOCKSIZE = sizeof(Block_t) * CHAR_BIT;

/ Mask to select out the bit offset within one Block_t. static const size_t MASK = BLOCKSIZE-1;

static_assert (std::atomic<Block_t>::is_always_lock_free);

public: / A bit number. typedef size_t bit_t;


/**

 ConcurrentBitset (bit_t nbits=0)
 Constructor.
 ConcurrentBitset (const ConcurrentBitset &other)
 Copy constructor.
 ConcurrentBitset (std::initializer_list< bit_t > l, bit_t nbits=0)
 Constructor from an initializer list.
 ConcurrentBitset (ConcurrentBitset &&other)
 Move constructor.
 ~ConcurrentBitset ()
 Destructor.
ConcurrentBitsetoperator= (const ConcurrentBitset &other)
 Assignment.
ConcurrentBitsetoperator= (ConcurrentBitset &&other)
 Move.
void emptyGarbage ()
 Clean up old versions of the set.
Size, bit testing
bit_t capacity () const
 The number of bits that this container can hold.
bit_t count () const
 Count the number of 1 bits in the set.
bit_t size () const
 Count the number of 1 bits in the set.
bool test (bit_t bit) const
 Test to see if a bit is set.
size_t count (bit_t bit) const
 Test to see if a bit is set.
bool empty () const
 Return true if there are no 1 bits in the set.
bool none () const
 Return true if there are no 1 bits in the set.
bool all () const
 Return true if all bits in the set are 1.
bool any () const
 Return true if there are any 1 bits in the set.
Single-bit manipulation.
ConcurrentBitsetset (bit_t bit)
 Turn on one bit.
ConcurrentBitsetreset (bit_t bit)
 Turn off one bit.
ConcurrentBitseterase (bit_t bit)
 Turn off one bit.
ConcurrentBitsetflip (bit_t bit)
 Flip the value of one bit.
ConcurrentBitsetset (bit_t bit, bool val)
 Set the value of one bit.
Set operations.
ConcurrentBitsetclear ()
 Clear all bits in the set.
ConcurrentBitsetreset ()
 Clear all bits in the set.
ConcurrentBitsetset ()
 Turn on all bits in the set.
ConcurrentBitsetflip ()
 Flip the state of all bits in the set.
ConcurrentBitsetoperator&= (const ConcurrentBitset &other)
 AND this set with another set.
ConcurrentBitsetoperator|= (const ConcurrentBitset &other)
 OR this set with another set.
ConcurrentBitsetoperator^= (const ConcurrentBitset &other)
 XOR this set with another set.
ConcurrentBitsetoperator-= (const ConcurrentBitset &other)
 Subtract another set from this set.
ConcurrentBitset operator~ () const
 Return a new set that is the complement of this set.
Comparison.
bool operator== (const ConcurrentBitset &other) const
 Test two sets for equality.
bool operator!= (const ConcurrentBitset &other) const
 Test two sets for inequality.
Insert.
ConcurrentBitsetinsert (bit_t bit, bit_t new_nbits=0)
 Set a bit to 1.
template<class ITERATOR, typename = typename std::enable_if< std::is_base_of< typename std::forward_iterator_tag, typename std::iterator_traits<ITERATOR>::iterator_category >::value>>
ConcurrentBitsetinsert (ITERATOR beg, ITERATOR end, bit_t new_nbits=0)
 Set several bits to 1.
ConcurrentBitsetinsert (std::initializer_list< bit_t > l, bit_t new_nbits=0)
 Set several bits to 1.
ConcurrentBitsetinsert (const ConcurrentBitset &other)
 Turn on bits listed in another set.
Array-like element access.
bool operator[] (bit_t bit) const
 Return the value of one bit.
Iterator operations.
const_iterator begin () const
 Return a begin iterator.
const_iterator end () const
 Return an end iterator.
const_iterator find (bit_t bit) const
 If bit bit is set, return an iterator pointing to it.

Variables

bool m_const
 Is this expression const?
std::vector< ClassNamem_namespace
 The containing namespace. This vector is always either 0 or 1 elements long; this is a way of getting something sort of like a pointer but with completely automatic management.
std::string m_name
 The primary name part of this expression.
std::vector< ClassNamem_targs
 The template arguments for this name.
Updater_t m_updater
 Updater object. This maintains ownership of the current implementation class and the older versions.
COMPARE m_compare
 Comparison object.
std::shared_ptr< IPayloadDeleterm_payloadDeleter
 Payload deleter object. Important: do not discard an object while it's still reachable from the m_begin / m_last range — update the pointers first. Otherwise, the object may be deleted while another thread is still referencing it: thread 1: Discard object. Sets grace mask for both slots. thread 2: Call quiescent(). Clears grace mask for 2. Retrieve the discarded object. thread 1: Adjust pointers. Call quiescent. The discarded object may be deleted at this point while thread 2 is still reading it.
std::atomic< value_type * > m_begin
 Pointers to the first and last elements of the container. m_last is not the usual end pointer; it points at the last element in the container. If the container is empty, then m_last will be null. If these are to both be updated together, it should be done in this order. First, m_begin should be set to null. This marks that there's an update in progress. Then m_last should be set, followed by m_begin. To read both pointers, we first fetch m_last. Then fetch m_begin. Then check that both m_begin is non-null and the previous value we fetched for last matches what's now in m_last. If either condition fails, then re-fetch both pointers.
std::atomic< value_type * > m_last
size_t m_nInserts
 Some basic statistics.
size_t m_maxSize
constexpr size_t dynamic_extent = static_cast<size_t>(-1)
 Used to specify a subrange of indefinite size in subspan().
template<class T, class U>
constexpr bool valid_span_type_v = std::is_convertible_v<U(*)[], T(*)[]>
 Is U* a valid type to use to initialize a span<T>?
static const std::string base64_chars
const CRCTable defaultCRCTable (0xad93d23594c935a9)
static const unsigned int NMANTISSA = 23
 Total number of total mantissa bits.
static extrace_init initer

Implementation.

typedef std::mutex mutex_t
 Mutex used for synchronization when switching to a new implementation object.
typedef std::lock_guard< mutex_tlock_t
std::atomic< Impl * > m_impl
 The current implementation object.
std::vector< Impl * > m_garbage
 Old implementation objects, pending deletion.
mutex_t m_mutex
 Mutex protecting the container.
static bit_t nBlocks (bit_t nbits)
 Find number of blocks needed to hold a given number of bits.
ImplnewImpl (bit_t nbits)
 Create a new, uninitialized implementation object.
void expand (bit_t new_nbits)
 Expand the container.
void expandOol (bit_t new_nbits)
 Expand the container: out-of-line portion.

Typedef Documentation

◆ aligned_vector

template<class T, size_t Alignment = 1>
using CxxUtils::aligned_vector = std::vector<T, boost::alignment::aligned_allocator<T, Alignment> >

A std::vector with extra alignment.

The alignment for the payload will be at least either that required by T or Alignment, whichever is greater.

Definition at line 39 of file aligned_vector.h.

◆ Arrayelt

typedef float CaloRec::Arrayelt

The type of an element of an Array.

Definition at line 26 of file Control/CxxUtils/CxxUtils/Arrayrep.h.

◆ CachedUniquePtr

template<class T>
using CxxUtils::CachedUniquePtr = CachedUniquePtrT<const T>

Definition at line 114 of file CachedUniquePtr.h.

◆ const_iterator

using CxxUtils::const_iterator = const value_type*

Definition at line 288 of file ConcurrentRangeMap.h.

◆ const_iterator_range

◆ const_iterator_value

typedef std::pair< const key_type, const mapped_type & > CxxUtils::const_iterator_value = std::pair<const key_type, mapped_type>

Value structure for iterators.

Value structures for iterators.

For a map from K to V, a STL-style iterator should dereference to a std::pair<const K, V>. However, we don't actually store an object like that anywhere. In order to be able to have STL-like iterators, we instead use a pair where the second element is a const reference to the mapped value. We will return this by value when we deference an iterator. (The compiler should be able to optimize out the redundant packing and unpacking of fields.)

Definition at line 236 of file ConcurrentMap.h.

◆ flat_set

template<class KEY, class COMPARE = std::less<KEY>, class KEYCONTAINER = void>
using CxxUtils::flat_set = boost::container::flat_set<KEY, COMPARE, KEYCONTANER>

Definition at line 40 of file flat_set.h.

◆ inplace_vector

template<class T, size_t N>
using CxxUtils::inplace_vector = boost::container::small_vector<T, N>

Definition at line 39 of file inplace_vector.h.

◆ IPayloadDeleter

using CxxUtils::IPayloadDeleter = CxxUtils::IRangeMapPayloadDeleter<T, typename Updater_t::Context_t>

Definition at line 336 of file ConcurrentRangeMap.h.

◆ iterator_range

using CxxUtils::iterator_range = CxxUtils::iterator_range<iterator>

Definition at line 400 of file ConcurrentToValMap.h.

◆ iterator_value

using CxxUtils::iterator_value = std::pair<const key_type, mapped_type&>

Definition at line 237 of file ConcurrentToValMap.h.

◆ ivec

template<typename T, size_t N>
using CxxUtils::ivec = vec_fb<typename boost::int_t<sizeof(T) * 8>::exact, N>

Definition at line 53 of file vec_fb.h.

◆ lock_t

typedef std::lock_guard< mutex_t > CxxUtils::lock_t
private

Definition at line 1063 of file ConcurrentBitset.h.

◆ match_t

typedef std::map<std::string, ClassName> CxxUtils::match_t

Map used to hold variable assignments from matching.

Definition at line 200 of file CxxUtils/CxxUtils/ClassName.h.

◆ mutex_t

typedef std::mutex CxxUtils::mutex_t
private

Mutex used for synchronization when switching to a new implementation object.

Type of the mutex for this container.

Definition at line 1062 of file ConcurrentBitset.h.

◆ payload_unique_ptr

using CxxUtils::payload_unique_ptr = std::unique_ptr<T, DeletePayload>

unique_ptr holding a payload object.

One may initialize an instance of this in one of two ways. First, from another std::unique_ptr:

payload_unique_ptr p = std::unique_ptr<U> (...);
std::unique_ptr< T, DeletePayload > payload_unique_ptr
unique_ptr holding a payload object.

where U* must be convertible to T*. In this case, the pointer will be deleted as a U*. Second, one can supply an explicit deletion function:

T* tp = ...;
payload_unique_ptr p (tp, delfcn);

Definition at line 286 of file ConcurrentRangeMap.h.

◆ transform_view_with_at

template<std::ranges::input_range SPAN, class XFORM>
using CxxUtils::transform_view_with_at
Initial value:

Helper to add at() methods to a transform_view.

Definition at line 58 of file range_with_at.h.

◆ Updater_t

using CxxUtils::Updater_t = UPDATER<Impl>

Definition at line 335 of file ConcurrentRangeMap.h.

◆ vec

template<typename T, size_t N>
using CxxUtils::vec = typename vecDetail::vec_typedef<T,N>::type

Define a nice alias for the vectorized type.

Definition at line 207 of file vec.h.

◆ vec_aligned_vector

template<class T>
using CxxUtils::vec_aligned_vector = aligned_vector<T, 64>

A std::vector with alignment sufficient for any vector instructions on this platform.

For now, just hard code 64, which is sufficient for a 512-bit vector, the largest supported by any x86 processors. We may want to make this platform-dependent in the future.

Definition at line 51 of file aligned_vector.h.

◆ vec_mask_type_t

template<class VEC>
using CxxUtils::vec_mask_type_t = typename vecDetail::vec_mask_type<VEC>::type

Define a nice alias for the mask type for a vectorized type.

Definition at line 219 of file vec.h.

◆ vec_type_t

template<class VEC>
using CxxUtils::vec_type_t = typename vecDetail::vec_type<VEC>::type

Define a nice alias for the element type of a vectorized type.

Definition at line 213 of file vec.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

While it is possible to determine cache line size at run time (e.g.

using sysconf(_SC_LEVEL1_DCACHE_LINESIZE) on Linux or sysctlbyname("hw.cachelinesize", ...) on Apple systems) that approach creates more problems: the location that stores cache line size will probably be out of cache when one needs to know it. This is why we use a compile time constant for cache line size. Cache line size is 64 for the current generation of Intel/AMD CPUs.

If an object spans multiple cache lines then prefetching whole object should be done by prefetching at least one address from each of the cache lines that object occupies. How many lines are needed depends on three things: object size, cache line size, and object starting address. If CacheLineSize is lower than the actual line size then more prefetches than necessary will be generated (2, 4, or more per cache line if cache line size is power of 2). This may be somewhat wasteful so this number may need to be adjusted in the far future when all CPUs have wider cache lines.

Enumerator
CacheLineSize 

Definition at line 59 of file prefetch.h.

59{ CacheLineSize = 64 };
@ CacheLineSize
Definition prefetch.h:59

◆ CacheState

enum CxxUtils::CacheState : unsigned char

State of the cached value; see below.

Enumerator
INVALID 
UPDATING 
VALID 

Definition at line 27 of file CachedValue.h.

27 : unsigned char {
28 INVALID = 0,
29 UPDATING = 1,
30 VALID = 2
31};

◆ EmplaceResult

enum class CxxUtils::EmplaceResult
strong

Results returned from emplace().

Enumerator
SUCCESS 

All ok.

OVERLAP 

New object was added, but overlaps with an existing range.

DUPLICATE 

New object duplicates an existing range, and was not added.

EXTENDED 

Definition at line 383 of file ConcurrentRangeMap.h.

384 {
386 SUCCESS,
387
389 OVERLAP,
390
392 DUPLICATE,
393
394 // Existing range was extended to match the new range; new object
395 // was deleted.
397 };

Function Documentation

◆ all()

bool CxxUtils::all ( ) const

Return true if all bits in the set are 1.

◆ any()

bool CxxUtils::any ( ) const

Return true if there are any 1 bits in the set.

◆ anyInRange()

bool CxxUtils::anyInRange ( const key_type & r,
const std::vector< key_query_type > & keys ) const
private

Test to see if any keys within keys match r.

r Range to test. @break keys List of keys to test. MUST be sorted.

◆ applyRules() [1/2]

void ClassName< T >::applyRules ( const Rules & rules)

Apply a set of transformation rules to this object.

Parameters
rulesThe set of rules to apply.

Recursively walk this expression, trying to apply the transformation rules in rules. If any matches are found, this expression is modified in-place and the walk is repeated. This function terminates when no further matches are found.

Warning: An infinite loop is possible if the replacement for a pattern can always be matched by another pattern.

Definition at line 410 of file CxxUtils/Root/ClassName.cxx.

411{
412 while (applyRules1 (rules))
413 ;
414}
bool applyRules1(const Rules &rules)
Apply a set of transformation rules to this object.

◆ applyRules() [2/2]

std::string CxxUtils::applyRules ( const std::string & name,
const Rules & rules )
static

Apply a set of transformation rules a class name.

param The name of the class to transform.

Parameters
rulesThe set of rules to apply.

This is just shorthand for

cn.applyRules (rules);
return cn.fullName();
const std::string & name() const
Return the root name of the expression.
ClassName()
Default constructor.

◆ applyRules1()

bool ClassName< T >::applyRules1 ( const Rules & rules)
private

Apply a set of transformation rules to this object.

Parameters
rulesThe set of rules to apply.

Recursively walk this expression, trying to apply the transformation rules in rules. If any matches are found, this expression is modified in-place.

Returns true if any matches were found.

Definition at line 674 of file CxxUtils/Root/ClassName.cxx.

675{
676 bool ret = rules.applyTo (*this);
677
678 if (m_namespace.size() > 0)
679 ret |= m_namespace[0].applyRules1 (rules);
680
681 for (size_t i = 0; i < m_targs.size(); i++)
682 ret |= m_targs[i].applyRules1 (rules);
683
684 return ret;
685}
bool applyTo(ClassName &cn) const
Add a new transformation rule.
std::vector< ClassName > m_targs
The template arguments for this name.
std::vector< ClassName > m_namespace
The containing namespace. This vector is always either 0 or 1 elements long; this is a way of getting...

◆ as_const_ptr()

template<class T>
const T * CxxUtils::as_const_ptr ( const T * p)
inline

Helper for getting a const version of a pointer.

Parameters
pPointer to convert.

Given T* p, as_const_ptr(p) will return p as a const T*.

This is similar in spirit to std::as_const (which doesn't really do what you might expect for pointers).

Definition at line 32 of file as_const_ptr.h.

33{
34 return p;
35}

◆ at()

mapped_type & CxxUtils::at ( key_type key) const

Look up an element in the map.

Parameters
keyThe element to find.

Returns the value associated with the key. Throws std::out_of_range if the key does not exist in the map.

Parameters
keyThe element to find.

Returns the value associated with the key. Throws std::out_of_range if the key does not exist in the map.

This returns a non-const reference to the mapped object. The mapped object must be thread-safe itself in order to safely make any changes to it.

◆ atof()

double CxxUtils::atof ( std::string_view str)

Converts a string into a double / float.

Definition at line 46 of file Control/CxxUtils/Root/StringUtils.cxx.

46 {
47 double result{std::numeric_limits<double>::max()};
48 convertToNumber(str, result);
49 return result;
50 }
void convertToNumber(std::string_view str, dType &number)

◆ atoi()

int CxxUtils::atoi ( std::string_view str)

Helper functions to unpack numbers decoded in string into integers and doubles The strings are required to contain only digits, a floating point dot, the signs +- or a whitespace Exceptions are thrown otherwise.

Converts a string into an integer

Definition at line 40 of file Control/CxxUtils/Root/StringUtils.cxx.

40 {
41 int result{std::numeric_limits<int>::max()};
42 convertToNumber(str, result);
43 return result;
44 }

◆ atomic_bounded_decrement()

template<class T>
T CxxUtils::atomic_bounded_decrement ( std::atomic< T > * a,
T bound = 0,
T decr = 1,
std::memory_order memorder = std::memory_order_seq_cst )
inline

Atomically decrement a value with a lower bound.

Parameters
aPointer to the atomic value.
boundLower bound for a.
decrThe amount by which to decrement.
memorderMemory ordering.

Atomically decrement A by DECR, provided the result is not less than BOUND. I.e., the atomic equivalent of:

if (a >= bound + decr) a -= decr;
static Double_t a

Returns in any case the original value of the atomic variable.

Definition at line 41 of file atomic_bounded_decrement.h.

43{
44 T orig = a->load (memorder);
45 // Be careful with the comparison here --- it needs to work for
46 // unsigned values, so we don't want to subtract decr from orig.
47 while (orig >= bound + decr &&
48 !a->compare_exchange_strong (orig, orig - decr, memorder)) {
49 CxxUtils::stall();
50 }
51 return orig;
52}

◆ atomic_fetch_max()

template<class T>
T CxxUtils::atomic_fetch_max ( std::atomic< T > * a,
T v,
std::memory_order memorder = std::memory_order_seq_cst )
inline

Atomically calculate maximum.

Parameters
aPointer to the atomic value.
vThe other value.
memorderMemory ordering.

Computes max(*a, v) and stores it in *a. Returns the original value of *a.

Definition at line 42 of file atomic_fetch_minmax.h.

44{
45 T orig = a->load (memorder);
46 while (v > orig && !a->compare_exchange_strong (orig, v, memorder)) {
47 CxxUtils::stall();
48 }
49 return orig;
50}

◆ atomic_fetch_min()

template<class T>
T CxxUtils::atomic_fetch_min ( std::atomic< T > * a,
T v,
std::memory_order memorder = std::memory_order_seq_cst )
inline

Atomically calculate minimum.

Parameters
aPointer to the atomic value.
vThe other value.
memorderMemory ordering.

Computes min(*a, v) and stores it in *a. Returns the original value of *a.

Definition at line 63 of file atomic_fetch_minmax.h.

65{
66 T orig = a->load (memorder);
67 while (v < orig && !a->compare_exchange_strong (orig, v, memorder)) {
68 CxxUtils::stall();
69 }
70 return orig;
71}

◆ base64_decode()

std::vector< unsigned char > CxxUtils::base64_decode ( const std::string & encoded_string)

Definition at line 97 of file base64.cxx.

97 {
98 int in_len = encoded_string.size();
99 int i = 0;
100 int j = 0;
101 int in_ = 0;
102 unsigned char char_array_4[4], char_array_3[3];
103 std::vector<unsigned char> ret;
104
105 while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
106 char_array_4[i++] = encoded_string[in_]; in_++;
107 if (i ==4) {
108 for (i = 0; i <4; i++)
109 char_array_4[i] = base64_chars.find(char_array_4[i]);
110
111 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
112 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
113 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
114
115 for (i = 0; (i < 3); i++)
116 ret.push_back(char_array_3[i]);
117 i = 0;
118 }
119 }
120
121 if (i) {
122 for (j = i; j <4; j++)
123 char_array_4[j] = 0;
124
125 for (j = 0; j <4; j++)
126 char_array_4[j] = base64_chars.find(char_array_4[j]);
127
128 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
129 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
130 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
131
132 for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]);
133 }
134
135 return ret;
136}
static bool is_base64(unsigned char c)
Definition base64.cxx:51
static const std::string base64_chars
Definition base64.cxx:45
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)

◆ base64_encode()

std::string CxxUtils::base64_encode ( const unsigned char * bytes_to_encode,
unsigned int in_len )

Definition at line 55 of file base64.cxx.

55 {
56 std::string ret;
57 int i = 0;
58 int j = 0;
59 unsigned char char_array_3[3];
60 unsigned char char_array_4[4];
61
62 while (in_len--) {
63 char_array_3[i++] = *(bytes_to_encode++);
64 if (i == 3) {
65 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
66 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
67 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
68 char_array_4[3] = char_array_3[2] & 0x3f;
69
70 for(i = 0; (i <4) ; i++)
71 ret += base64_chars[char_array_4[i]];
72 i = 0;
73 }
74 }
75
76 if (i)
77 {
78 for(j = i; j < 3; j++)
79 char_array_3[j] = '\0';
80
81 char_array_4[0] = ( char_array_3[0] & 0xfc) >> 2;
82 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
83 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
84
85 for (j = 0; (j < i + 1); j++)
86 ret += base64_chars[char_array_4[j]];
87
88 while((i++ < 3))
89 ret += '=';
90
91 }
92
93 return ret;
94
95}

◆ begin() [1/7]

iterator CxxUtils::begin ( ) const

Return a begin iterator.

Iterator at the start of the map.

The mapped objects must themselves be thread-safe in order to make any changes to them through the returned iterators.

◆ begin() [2/7]

template<class T>
auto CxxUtils::begin ( const range_with_at< T > & s)

Definition at line 67 of file range_with_at.h.

67{ return s.begin(); }

◆ begin() [3/7]

template<class T>
auto CxxUtils::begin ( const range_with_conv< T > & s)

Definition at line 61 of file range_with_conv.h.

61{ return s.begin(); }

◆ begin() [4/7]

template<class T>
auto CxxUtils::begin ( const span< T > & s)

Definition at line 330 of file span.h.

330{ return s.begin(); }

◆ begin() [5/7]

template<class T>
auto CxxUtils::begin ( range_with_at< T > & s)

Definition at line 65 of file range_with_at.h.

65{ return s.begin(); }

◆ begin() [6/7]

template<class T>
auto CxxUtils::begin ( range_with_conv< T > & s)

Definition at line 59 of file range_with_conv.h.

59{ return s.begin(); }

◆ begin() [7/7]

template<class T>
auto CxxUtils::begin ( span< T > & s)

Definition at line 328 of file span.h.

328{ return s.begin(); }

◆ byteswap()

template<std::integral T>
T CxxUtils::byteswap ( T value)
constexprnoexcept

Reverse the bytes in n.

Copied from the example implementation given in https://en.cppreference.com/w/cpp/numeric/byteswap

Definition at line 42 of file byteswap.h.

43{
44 static_assert(std::has_unique_object_representations_v<T>,
45 "T may not have padding bits");
46 auto value_representation = std::bit_cast<std::array<std::byte, sizeof(T)>>(value);
47 std::ranges::reverse(value_representation);
48 return std::bit_cast<T>(value_representation);
49}

◆ capacity()

size_t CxxUtils::capacity ( ) const

The number of bits that this container can hold.

Return the current capacity of the map.

Return the current size (capacity) of the hash table.

◆ cbegin()

const_iterator CxxUtils::cbegin ( ) const

Iterator at the start of the map.

◆ cend()

const_iterator CxxUtils::cend ( ) const

Iterator at the end of the map.

◆ ClassName() [1/4]

ClassName< T >::ClassName ( )

Default constructor.

Needed for STL compatibility.

Definition at line 138 of file CxxUtils/Root/ClassName.cxx.

139 : m_const(false)
140{
141}
bool m_const
Is this expression const?

◆ ClassName() [2/4]

ClassName< T >::ClassName ( const char * name)

Parse a class name into component parts.

Parameters
nameThe name to parse.

Raises a BadClassName exception if the name isn't completely parsed.

Parameters
nameThe name to parse.

Raises a ExcBadClassName exception if the name isn't completely parsed.

Definition at line 150 of file CxxUtils/Root/ClassName.cxx.

151 : m_const(false)
152{
153 std::string sname = name;
154 std::string::size_type pos = 0;
155 parse (sname, pos);
156 skipSpaces (sname, pos);
157 if (pos != sname.size())
158 throw ExcBadClassName (sname);
159}
Recursively separate out template arguments in a C++ class name.
void skipSpaces(const std::string &name, std::string::size_type &pos)
Skip past spaces in a string.
void parse(const std::string &name, std::string::size_type &pos)
Parse a string into a ClassName.

◆ ClassName() [3/4]

ClassName< T >::ClassName ( const std::string & name)

Parse a class name into component parts.

Parameters
nameThe name to parse.

Raises a BadClassName exception if the name isn't completely parsed.

Parameters
nameThe name to parse.

Raises a ExcBadClassName exception if the name isn't completely parsed.

Definition at line 168 of file CxxUtils/Root/ClassName.cxx.

169 : m_const(false)
170{
171 std::string::size_type pos = 0;
172 parse (name, pos);
173 skipSpaces (name, pos);
174 if (pos != name.size())
175 throw ExcBadClassName (name);
176}

◆ ClassName() [4/4]

ClassName< T >::ClassName ( const std::string & name,
std::string::size_type & pos )

Parse a class name into component parts.

Parameters
nameString containing the name to parse.
posPosition in the string at which parsing should start.

pos is updated to point to past the point where parsing stopped.

Definition at line 186 of file CxxUtils/Root/ClassName.cxx.

187 : m_const (false)
188{
189 parse (name, pos);
190}

◆ clear() [1/3]

void CxxUtils::clear ( )

Clear all bits in the set.

Remove all entries in the container.

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

Mostly for testing — should not normally be used.

◆ clear() [2/3]

void CxxUtils::clear ( const Context_t & ctx = Updater_t::defaultContext())

Erase the table (don't change the capacity).

Parameters
ctxExecution context.

◆ clear() [3/3]

void CxxUtils::clear ( size_t capacity,
const Context_t & ctx = Updater_t::defaultContext() )

Erase the table and change the capacity.

Parameters
capacityThe new table capacity.
ctxExecution context.

◆ close_to_zero()

template<typename T>
bool CxxUtils::close_to_zero ( T value,
T eps = std::numeric_limits<T>::epsilon() )
Examples
/build/atnight/localbuilds/nightlies/main--Doxygen/athena/Control/CxxUtils/CxxUtils/close_to_zero.h.

Definition at line 48 of file close_to_zero.h.

48 {
49 if constexpr (std::is_integral_v<T>) {
50 // For integers, only exact zero is invalid
51 return value == 0;
52 } else if constexpr (std::is_floating_point_v<T>) {
53 return std::abs(value) < eps;
54 } else {
55 static_assert(std::is_arithmetic_v<T>, "close_to_zero: Only arithmetic types supported");
56 return false;
57 }
58 }

◆ ConcurrentBitset() [1/4]

CxxUtils::ConcurrentBitset ( bit_t nbits = 0)

Constructor.

Parameters
nbitsInitial number of bits to allocate for the map.

◆ ConcurrentBitset() [2/4]

CxxUtils::ConcurrentBitset ( ConcurrentBitset && other)

Move constructor.

Parameters
otherContainer to move.

No concurrent access may be in progress on other. After this returns, other can only be deleted.

◆ ConcurrentBitset() [3/4]

CxxUtils::ConcurrentBitset ( const ConcurrentBitset & other)

Copy constructor.

Parameters
otherContainer to copy.

The copy is not atomic. If a non-atomic update is simultaneously made to other, then the copy may have this update only partially completed.

◆ ConcurrentBitset() [4/4]

CxxUtils::ConcurrentBitset ( std::initializer_list< bit_t > l,
bit_t nbits = 0 )

Constructor from an initializer list.

Parameters
Listof values to set.
nbitsNumber of bits to allocate for the map. If 0, then set the size based on the maximum value in the list.

This allows setting specific bits in the set, like

ConcurrentBitset bs { 1, 5, 10};

◆ ConcurrentMap() [1/5]

CxxUtils::ConcurrentMap ( ConcurrentMap && other)
delete

◆ ConcurrentMap() [2/5]

CxxUtils::ConcurrentMap ( const ConcurrentMap & other)
delete

Copy / move / assign not supported.

◆ ConcurrentMap() [3/5]

CxxUtils::ConcurrentMap ( const ConcurrentMap & other,
Updater_t && updater,
size_t capacity = 64,
const Context_t & ctx = Updater_t::defaultContext() )

Constructor from another map.

Parameters
updaterObject used to manage memory (see comments at the start of the class).
capacityThe initial table capacity of the new table. (Will be rounded up to a power of two.)
ctxExecution context.

(Not really a copy constructor since we need to pass updater.)

◆ ConcurrentMap() [4/5]

template<class InputIterator>
CxxUtils::ConcurrentMap ( InputIterator f,
InputIterator l,
Updater_t && updater,
size_type capacity = 64,
const Context_t & ctx = Updater_t::defaultContext() )

Constructor from a range.

Parameters
fStart iterator for the range.
lEnd iterator for the range.
updaterObject used to manage memory (see comments at the start of the class).
capacityThe initial table capacity of the new table. (Will be rounded up to a power of two.)
ctxExecution context.

Constructor from a range of pairs.

◆ ConcurrentMap() [5/5]

CxxUtils::ConcurrentMap ( Updater_t && updater,
size_type capacity = 64,
const Context_t & ctx = Updater_t::defaultContext() )

Hash map from integers/pointers allowing concurrent, lockless reads.

This class implements a hash map. Both the key and mapped types may be pointers or any numeric type that can fit in a uintptr_t. (However, using floating types for the key is not recommended.) It allows for concurrent access from many threads. Reads can proceed without taking out a lock, while writes are serialized with each other. Thus, this is appropriate for maps which are read-mostly.

This is based on ConcurrentHashmapImpl.

Besides the mapped key and value types, this class is templated on an UPDATER class, which is used to manage the underlying memory. See IsUpdater.h for details. (AthenaKernel/RCUUpdater is a concrete version that should work in the context of Athena.)

The operations used for calculating the hash of the keys and comparing keys can be customized with the HASHER and MATCHER template arguments (though the defaults should usually be fine).

One value of the key must be reserved as a null value, which no real keys may take. By default this is `0', but it may be customized with the NULLVAL template argument. The map may optionally support erasures (via tombstones). To allow this, a second reserved key value must be identified and specified by the TOMBSTONE template argument. Note that the type of the NULLPTR and TOMBSTONE template arguments is a uintptr_t, not KEY.

This mostly supports the interface of std::unordered_map, with a few differences / omissions:

  • Dereferencing the iterator returns a structure by value, not a reference.
  • No try_emplace.
  • No insert methods with hints.
  • No operator==.
  • Nothing dealing with the bucket/node interface or merge().

Performance: This is the result from running the test with –perf on my machine, with gcc 13.0.0

ConcurrentMap lookup: 0.843s wall, 0.840s user + 0.000s system = 0.840s CPU (99.6%) iterate: 0.551s wall, 0.540s user + 0.000s system = 0.540s CPU (97.9%) UnorderedMap lookup: 1.890s wall, 1.870s user + 0.000s system = 1.870s CPU (99.0%) iterate: 0.966s wall, 0.970s user + 0.000s system = 0.970s CPU (100.4%) concurrent_unordered_map lookup: 3.718s wall, 3.690s user + 0.010s system = 3.700s CPU (99.5%) iterate: 5.719s wall, 5.690s user + 0.000s system = 5.690s CPU (99.5%) ck_ht lookup: 1.471s wall, 1.460s user + 0.000s system = 1.460s CPU (99.2%) iterate: 1.519s wall, 1.500s user + 0.000s system = 1.500s CPU (98.7%)

The timing for the lookup test of UnorderedMap is probably overly-optimistic, since the test doesn't do any locking in that case. */ template <class KEY, class VALUE, template <class> class UPDATER, class HASHER = std::hash<KEY>, class MATCHER = std::equal_to<KEY>, detail::ConcurrentHashmapVal_t NULLVAL = 0, detail::ConcurrentHashmapVal_t TOMBSTONE = NULLVAL> requires (detail::IsConcurrentHashmapPayload<KEY> && detail::IsConcurrentHashmapPayload<VALUE> && detail::IsUpdater<UPDATER> && detail::IsHash<HASHER, KEY> && detail::IsBinaryPredicate<MATCHER, KEY>) class ConcurrentMap { private: / Representation type in the underlying map. using val_t = CxxUtils::detail::ConcurrentHashmapVal_t;

Translate between the Hasher/Matcher provided (which take KEY arguments) and what we need to give to the underlying implementation (which takes a uintptr_t). struct Hasher { size_t operator() (val_t k) const { return m_h (keyAsKey (k)); } HASHER m_h; }; struct Matcher { bool operator() (val_t a, val_t b) const { return m_m (keyAsKey (a), keyAsKey (b)); } MATCHER m_m; };

/ The underlying uint->uint hash table. using Impl_t = typename detail::ConcurrentHashmapImpl<UPDATER, Hasher, Matcher, NULLVAL, TOMBSTONE>;

public: / Standard STL types. using key_type = KEY; using mapped_type = VALUE; using size_type = size_t; / Updater object. using Updater_t = typename Impl_t::Updater_t; / Context type. using Context_t = typename Updater_t::Context_t; / Type for external locking. using Lock_t = typename Impl_t::Lock_t;

/ Ensure that the underlying map can store our types. static_assert( sizeof(typename Impl_t::val_t) >= sizeof(key_type) ); static_assert( sizeof(typename Impl_t::val_t) >= sizeof(mapped_type) );

/**

Constructor.

Parameters
updaterObject used to manage memory (see comments at the start of the class).
capacityThe initial table capacity. (Will be rounded up to a power of two.)
ctxExecution context.

◆ ConcurrentRangeMap()

CxxUtils::ConcurrentRangeMap ( Updater_t && updater,
std::shared_ptr< IPayloadDeleter > payloadDeleter,
size_t capacity = 16,
const COMPARE & compare = COMPARE() )

Constructor.

Parameters
updaterObject used to manage memory (see comments at the start of the class).
payloadDeleterObject for deleting payload objects. This is owned via a shared_ptr.
capacityInitial capacity of the map.
compareComparison object.

◆ ConcurrentToValMap() [1/5]

CxxUtils::ConcurrentToValMap ( ConcurrentToValMap && other)
delete

◆ ConcurrentToValMap() [2/5]

CxxUtils::ConcurrentToValMap ( const ConcurrentToValMap & other)
delete

Copy / move / assign not supported.

◆ ConcurrentToValMap() [3/5]

CxxUtils::ConcurrentToValMap ( const ConcurrentToValMap & other,
Updater_t && updater,
size_t capacity = 64,
const Context_t & ctx = Updater_t::defaultContext() )

Constructor from another map.

Parameters
updaterObject used to manage memory (see comments at the start of the class).
capacityThe initial table capacity of the new table. (Will be rounded up to a power of two.)
ctxExecution context.

(Not really a copy constructor since we need to pass updater.)

◆ ConcurrentToValMap() [4/5]

template<class InputIterator>
CxxUtils::ConcurrentToValMap ( InputIterator f,
InputIterator l,
Updater_t && updater,
size_type capacity = 64,
const Context_t & ctx = Updater_t::defaultContext() )

Constructor from a range.

Parameters
fStart iterator for the range.
lEnd iterator for the range.
updaterObject used to manage memory (see comments at the start of the class).
capacityThe initial table capacity of the new table. (Will be rounded up to a power of two.)
ctxExecution context.

Constructor from a range of pairs.

◆ ConcurrentToValMap() [5/5]

CxxUtils::ConcurrentToValMap ( Updater_t && updater,
size_type capacity = 64,
const Context_t & ctx = Updater_t::defaultContext() )

Hash map from pointers/integers to arbitrary objects allowing concurrent, lockless reads.

This class implements a hash map, using keys that may be pointers or any integer type that can fit in an uintptr_t. The mapped type is arbitrary. It allows for concurrent access from many threads. Reads can proceed without taking out a lock, while writes are serialized with each other. Thus, this is appropriate for maps which are read-mostly.

This class includes non-const references that can be used to obtain non-const references to the mapped objects. Howeer, the mapped objects must themselves the thread-safe in order to safely modify them in a multithreaded context.

This is based on ConcurrentHashmapImpl.

Besides the key and mapped value types, this class is templated on an UPDATER class, which is used to manage the underlying memory. See IsUpdater.h for details. (AthenaKernel/RCUUpdater is a concrete version that should work in the context of Athena.)

The operations used for calculating the hash of the keys and comparing keys can be customized with the HASHER and MATCHER template arguments (though the defaults should usually be fine).

One value of the key must be reserved as a null value, which no real keys may take. By default this is `0', but it may be customized with the NULLVAL template argument. Note that the type of the NULLPTR template argument is a uintptr_t, not KEY.

This mostly supports the interface of std::unordered_map, with a few differences / omissions:

  • Dereferencing the iterator returns a structure by value, not a reference.
  • No try_emplace.
  • No insert methods with hints.
  • No clear / erase / overwrite. Those could be implemented if needed (but would require some extra complexity in the memory management).
  • No operator==.
  • Nothing dealing with the bucket/node interface or merge().

The mapped value can be given as any of:

  • A value or const reference. In that case, it needs to be copy-constructable.
  • A rvalue-reference. In that case, it needs to be movable.
  • A unique_ptr to an instance.

I.e., any of these should work:

*

const Payload p (1);
map.emplace (1, p); // By value / const reference
map.emplace (2, Payload (2)); // By rvalue-reference.
// Could also move() an instance.
map.emplace (3, std::make_unique<Payload> (3)); // By unique_ptr.
STL class.
ConcurrentToValMap(Updater_t &&updater, size_type capacity=64, const Context_t &ctx=Updater_t::defaultContext())
Hash map from pointers/integers to arbitrary objects allowing concurrent, lockless reads.

*/ template <class KEY, class VALUE, template <class> class UPDATER, class HASHER = std::hash<KEY>, class MATCHER = std::equal_to<KEY>, detail::ConcurrentHashmapVal_t NULLVAL = 0> requires (detail::IsConcurrentHashmapPayload<KEY> && detail::IsUpdater<UPDATER> && detail::IsHash<HASHER, KEY> && detail::IsBinaryPredicate<MATCHER, KEY>) class ConcurrentToValMap { private: / Representation type in the underlying map. using val_t = CxxUtils::detail::ConcurrentHashmapVal_t;

Translate between the Hasher/Matcher provided (which take KEY arguments) and what we need to give to the underlying implementation (which takes a uintptr_t). struct Hasher { size_t operator() (val_t k) const { return m_h (keyAsKey (k)); } HASHER m_h; }; struct Matcher { bool operator() (val_t a, val_t b) const { return m_m (keyAsKey (a), keyAsKey (b)); } MATCHER m_m; };

/ The underlying uint->uint hash table. using Impl_t = typename detail::ConcurrentHashmapImpl<UPDATER, Hasher, Matcher, NULLVAL>;

public: / Standard STL types. using key_type = KEY; using mapped_type = VALUE; using size_type = size_t; / Updater object. using Updater_t = typename Impl_t::Updater_t; / Context type. using Context_t = typename Updater_t::Context_t;

/**

Constructor.

Parameters
updaterObject used to manage memory (see comments at the start of the class).
capacityThe initial table capacity. (Will be rounded up to a power of two.)
ctxExecution context.

◆ contains()

bool CxxUtils::contains ( key_type key) const

Test if a key is in the container.

Parameters
keyThe key to test.

◆ convertToNumber()

template<Numeric dType, bool silenceEmpty = true>
void CxxUtils::convertToNumber ( std::string_view str,
dType & number )

Definition at line 20 of file StringUtilsTemplates.h.

20 {
22 if constexpr(silenceEmpty){
23 if (str.empty()) {
24 number = 0;
25 return;
26 }
27 }
28 auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), number);
29
30 if (ec != std::errc{}) {
31 throw std::runtime_error("CxxUtils::convertToNumber() - Invalid numeric string: " + std::string(str));
32 }
33 }
std::string_view trimWhiteSpaces(std::string_view str) noexcept
Removes all trailing and starting whitespaces from a string.
void * ptr(T *p)
Definition SGImplSvc.cxx:74
std::string number(const double &d, const std::string &s)
Definition utils.cxx:186

◆ copy_bounded() [1/3]

template<class InputRange, class OutputRange>
auto CxxUtils::copy_bounded ( const InputRange & input,
OutputRange && output ) -> decltype(std::begin(output))
inline

Copy a range with bounds restriction.

Parameters
inputInput range
outputOutput range

copy_bounded written in terms of iterator ranges.

We have this as a distinct overload in order to be able to pass a CxxUtils::span temporary as the second argument.

Definition at line 121 of file copy_bounded.h.

123{
124 return copy_bounded
125 (std::begin(input), std::end(input),
126 std::begin(output), std::end(output));
127}
OutputIterator copy_bounded(InputIterator begi, InputIterator endi, OutputIterator bego, OutputIterator endo)
Copy a range with bounds restriction.

◆ copy_bounded() [2/3]

template<class InputRange, class OutputRange>
auto CxxUtils::copy_bounded ( const InputRange & input,
OutputRange & output ) -> decltype(std::begin(output))
inline

Copy a range with bounds restriction.

Parameters
inputInput range
outputOutput range

copy_bounded written in terms of iterator ranges.

Definition at line 99 of file copy_bounded.h.

101{
102 return copy_bounded
103 (std::begin(input), std::end(input),
104 std::begin(output), std::end(output));
105}

◆ copy_bounded() [3/3]

template<std::input_iterator InputIterator, std::output_iterator< typename std::iterator_traits< InputIterator >::value_type > OutputIterator>
OutputIterator CxxUtils::copy_bounded ( InputIterator begi,
InputIterator endi,
OutputIterator bego,
OutputIterator endo )
inline

Copy a range with bounds restriction.

Parameters
begiStart of input range.
endiEnd of input range.
begoStart of output range.
endoEnd of output range.

Like std::copy(begi, endi, bego), except that it will not copy more than std::distance(bego, endo) elements.

Copies exactly n = std::min (std::distance(begi,endi), std::distance(bego,endo)) elements. Returns bego + n.

Definition at line 79 of file copy_bounded.h.

81{
82 return copy_bounded1
83 (begi, endi, bego, endo,
84 typename std::iterator_traits<InputIterator>::iterator_category(),
85 typename std::iterator_traits<OutputIterator>::iterator_category());
86}
OutputIterator copy_bounded1(InputIterator begi, InputIterator endi, OutputIterator bego, OutputIterator endo, const InputTag &, const OutputTag &)
Copy a range with bounds restriction; generic version.

◆ copy_bounded1() [1/2]

template<class InputIterator, class OutputIterator, class InputTag, class OutputTag>
OutputIterator CxxUtils::copy_bounded1 ( InputIterator begi,
InputIterator endi,
OutputIterator bego,
OutputIterator endo,
const InputTag & ,
const OutputTag &  )
inline

Copy a range with bounds restriction; generic version.

Definition at line 31 of file copy_bounded.h.

35{
36 while (begi != endi && bego != endo) {
37 *bego = *begi;
38 ++begi;
39 ++bego;
40 }
41 return bego;
42}

◆ copy_bounded1() [2/2]

template<class InputIterator, class OutputIterator>
OutputIterator CxxUtils::copy_bounded1 ( InputIterator begi,
InputIterator endi,
OutputIterator bego,
OutputIterator endo,
const std::random_access_iterator_tag & ,
const std::random_access_iterator_tag &  )
inline

Copy a range with bounds restriction; random_access_iterator version.

Definition at line 51 of file copy_bounded.h.

55{
56 size_t n = std::min (endi-begi, endo-bego);
57 return std::copy (begi, begi+n, bego);
58}

◆ count() [1/3]

bit_t CxxUtils::count ( ) const

Count the number of 1 bits in the set.

◆ count() [2/3]

size_t CxxUtils::count ( bit_t bit) const

Test to see if a bit is set.

Parameters
bitNumber of the bit to test.
Returns
1 if the bit is set; 0 otherwise.

Returns 0 if bit is beyond the end of the set.

◆ count() [3/3]

size_type CxxUtils::count ( key_type key) const

Return the number of times a given key is in the container.

Parameters
keyThe key to test.

Returns either 0 or 1, depending on whether or not the key is in the map.

◆ crc64() [1/3]

uint64_t CxxUtils::crc64 ( const char * data,
size_t data_len )

Find the CRC-64 of a string, with the default CRC.

Parameters
dataPointer to the string to hash.
data_lenLength of the string to hash, in bytes.

Definition at line 709 of file crc64.cxx.

711{
712 return crc64 (defaultCRCTable, data, data_len);
713}
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
uint64_t crc64(const CRCTable &table, const char *data, size_t data_len)
Find the CRC-64 of a string,.
Definition crc64.cxx:696
const CRCTable defaultCRCTable(0xad93d23594c935a9)

◆ crc64() [2/3]

uint64_t CxxUtils::crc64 ( const CRCTable & table,
const char * data,
size_t data_len )

Find the CRC-64 of a string,.

Parameters
tablePrecomputed CRC tables and constants.
dataPointer to the string to hash.
data_lenLength of the string to hash, in bytes.

This is the default implementation, used on platforms without pclmul.

Definition at line 696 of file crc64.cxx.

699{
700 return crc64_bytewise (table, data, data_len);
701}
uint64_t crc64_bytewise(const CRCTable &table, const char *data, size_t data_len)
Find the CRC-64 of a string, using a byte-by-byte algorithm.
Definition crc64.cxx:560

◆ crc64() [3/3]

uint64_t CxxUtils::crc64 ( const std::string & s)

Find the CRC-64 of a string, using the default polynomial.

Parameters
strThe string to hash.

Definition at line 720 of file crc64.cxx.

721{
722 return crc64 (defaultCRCTable, s.data(), s.size());
723}

◆ crc64_bytewise() [1/3]

uint64_t CxxUtils::crc64_bytewise ( const char * data,
size_t data_len )

Find the CRC-64 of a string, using a byte-by-byte algorithm, with the default CRC.

Parameters
tablePrecomputed CRC tables and constants.
dataPointer to the string to hash.
data_lenLength of the string to hash, in bytes.

Definition at line 580 of file crc64.cxx.

582{
583 return crc64_bytewise (defaultCRCTable, data, data_len);
584}

◆ crc64_bytewise() [2/3]

uint64_t CxxUtils::crc64_bytewise ( const CRCTable & table,
const char * data,
size_t data_len )

Find the CRC-64 of a string, using a byte-by-byte algorithm.

Parameters
tablePrecomputed CRC tables and constants.
dataPointer to the string to hash.
data_lenLength of the string to hash, in bytes.

Definition at line 560 of file crc64.cxx.

563{
564 uint64_t crc = table.m_initial;
565 const char* seq = data;
566 const char* end = seq + data_len;
567 while (seq < end)
568 crc = table.m_table[(crc ^ *seq++) & 0xff] ^ (crc >> 8);
569 return crc;
570}
const_iterator end() const
Return an end iterator.

◆ crc64_bytewise() [3/3]

uint64_t CxxUtils::crc64_bytewise ( const std::string & s)

Find the CRC-64 of a string, using a byte-by-byte algorithm, with the default CRC.

Parameters
tablePrecomputed CRC tables and constants.
sString to hash.

Definition at line 593 of file crc64.cxx.

594{
595 return crc64_bytewise (defaultCRCTable, s.data(), s.size());
596}

◆ crc64addint()

uint64_t CxxUtils::crc64addint ( uint64_t crc,
uint64_t x )

Extend a previously-calculated CRC to include an int.

Parameters
crcThe previously-calculated CRC.
xThe integer to add.
Returns
The new CRC.

Definition at line 732 of file crc64.cxx.

733{
734 while (x > 0) {
735 crc = defaultCRCTable.m_table[(crc ^ x) & 0xff] ^ (crc >> 8);
736 x >>= 8;
737 }
738 return crc;
739}
#define x

◆ crc64digest()

std::string CxxUtils::crc64digest ( const std::string & str)

Return a CRC-64 digest of a string.

Parameters
strThe string to hash.
Returns
The CRC-64 digest of the string. This is the hash code, expressed as hex as a string.

Definition at line 761 of file crc64.cxx.

762{
763 return crc64format (crc64 (str));
764}
std::string crc64format(uint64_t crc)
Format a CRC-64 as a string.
Definition crc64.cxx:746

◆ crc64format()

std::string CxxUtils::crc64format ( uint64_t crc)

Format a CRC-64 as a string.

Parameters
crcThe CRC to format.

Definition at line 746 of file crc64.cxx.

747{
748 char buf[64];
749 sprintf (buf, "%08X%08X",
750 (unsigned)((crc>>32)&0xffffffff), (unsigned)(crc&0xffffffff));
751 return buf;
752}

◆ deleteCRCTable()

void CxxUtils::deleteCRCTable ( CxxUtils::CRCTable * table)

Delete a CRCTable object.

Delete a CRC table object.

Definition at line 535 of file crc64.cxx.

536{
537 delete table;
538}

◆ deleter()

const IPayloadDeleter & CxxUtils::deleter ( )

Return a reference to the payload deleter object.

◆ deltaPhi()

template<typename T>
T CxxUtils::deltaPhi ( T phiA,
T phiB )
inline

Return difference phiA - phiB in range [-pi, pi].

Definition at line 42 of file phihelper.h.

43 {
44 static_assert(std::is_floating_point<T>::value);
45 return wrapToPi(phiA - phiB);
46 }
T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
Definition phihelper.h:24

◆ emplace() [1/6]

std::pair< const_iterator, bool > CxxUtils::emplace ( const Lock_t & lock,
key_type key,
mapped_type val,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map, with external locking.

Parameters
lockThe lock object returned from lock().
keyThe key of the new item to add.
valThe value of the new item to add.
ctxExecution context.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ emplace() [2/6]

EmplaceResult CxxUtils::emplace ( const RANGE & range,
payload_unique_ptr ptr,
bool tryExtend = false,
const typename Updater_t::Context_t & ctx = Updater_t::defaultContext() )

Add a new element to the map.

Parameters
rangeValidity range for this element.
ptrPayload for this element.
tryExtendIf true, then allow an existing range to be extended (see below).
ctxExecution context.

Returns SUCCESS if the new element was successfully inserted. Returns DUPLICATE if the range compared equal to an existing one. In that case, no new element is inserted (and ptr gets deleted). Returns EXTEND if the range of the last element was extended to range. This happens if tryExtend is true, range is equal to the range of the last element (according to m_compare), and the range can be extended according to extendRange. (This will generally mean that the start time of range matches the last range, and end time of range is after the end time of the last range.) In this case, again no new element is inserted and ptr is deleted. Returns OVERLAP if the range of the new element overlaps an existing element (the new element is still inserted).

◆ emplace() [3/6]

std::pair< const_iterator, bool > CxxUtils::emplace ( key_type key,
const mapped_type & val,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map.

Parameters
keyThe key of the new item to add.
valThe value of the new item to add.
ctxExecution context.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ emplace() [4/6]

std::pair< const_iterator, bool > CxxUtils::emplace ( key_type key,
mapped_type && val,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map.

Parameters
keyThe key of the new item to add.
valThe value of the new item to add.
ctxExecution context.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ emplace() [5/6]

std::pair< const_iterator, bool > CxxUtils::emplace ( key_type key,
mapped_type val,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map.

Parameters
keyThe key of the new item to add.
valThe value of the new item to add.
ctxExecution context.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ emplace() [6/6]

std::pair< const_iterator, bool > CxxUtils::emplace ( key_type key,
std::unique_ptr< mapped_type > val,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map.

Parameters
keyThe key of the new item to add.
valThe value of the new item to add.
ctxExecution context.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ empty()

bool CxxUtils::empty ( ) const

Return true if there are no 1 bits in the set.

Test if the map is empty.

Test if the map is currently empty.

◆ emptyGarbage()

void CxxUtils::ConcurrentBitset::emptyGarbage ( )

Clean up old versions of the set.

The insert and assignment operations may need to grow the set. The original version of the set is not deleted immediately, since other threads may still be accessing it. Call this when no other threads can be accessing old versions in order to clean them up.

Definition at line 153 of file ConcurrentBitset.cxx.

154{
156 for (Impl* p : m_garbage) {
157 free (p);
158 }
159 m_garbage.clear();
160}
Implementation object.
mutex_t m_mutex
Mutex protecting the container.
std::lock_guard< mutex_t > lock_t
Lock_t lock()
Take a lock on the container.
std::vector< Impl * > m_garbage
Old implementation objects, pending deletion.

◆ end() [1/7]

iterator CxxUtils::end ( ) const

Return an end iterator.

Iterator at the end of the map.

The mapped objects must themselves be thread-safe in order to make any changes to them through the returned iterators.

◆ end() [2/7]

template<class T>
auto CxxUtils::end ( const range_with_at< T > & s)

Definition at line 71 of file range_with_at.h.

71{ return s.end(); }

◆ end() [3/7]

template<class T>
auto CxxUtils::end ( const range_with_conv< T > & s)

Definition at line 65 of file range_with_conv.h.

65{ return s.end(); }

◆ end() [4/7]

template<class T>
auto CxxUtils::end ( const span< T > & s)

Definition at line 334 of file span.h.

334{ return s.end(); }

◆ end() [5/7]

template<class T>
auto CxxUtils::end ( range_with_at< T > & s)

Definition at line 69 of file range_with_at.h.

69{ return s.end(); }

◆ end() [6/7]

template<class T>
auto CxxUtils::end ( range_with_conv< T > & s)

Definition at line 63 of file range_with_conv.h.

63{ return s.end(); }

◆ end() [7/7]

template<class T>
auto CxxUtils::end ( span< T > & s)

Definition at line 332 of file span.h.

332{ return s.end(); }

◆ equal_range()

std::pair< iterator, iterator > CxxUtils::equal_range ( key_type key) const

Return a range of iterators with entries matching key.

Parameters
keyThe element to find.

As keys are unique in this container, this is either a single-element range, or both iterators are equal to end().

Parameters
keyThe element to find.

As keys are unique in this container, this is either a single-element range, or both iterators are equal to end().

The mapped objects must themselves be thread-safe in order to make any changes to them through the returned iterators.

◆ erase() [1/4]

ConcurrentBitset & CxxUtils::erase ( bit_t bit)

Turn off one bit.

Parameters
bitThe bit to turn off.

Does nothing if bit beyond the end of the set.

◆ erase() [2/4]

void CxxUtils::erase ( const key_query_type & key,
const typename Updater_t::Context_t & ctx = Updater_t::defaultContext() )

Erase the first item less than or equal to KEY.

Parameters
keyThe key to search erase.
ctxExecution context.

◆ erase() [3/4]

bool CxxUtils::erase ( const Lock_t & lock,
key_type key )

Erase an entry from the table, with external locking.

Parameters
lockThe lock object returned from lock().
keyThe key to erase.

Mark the corresponding entry as deleted. Return true on success, false on failure (key not found).

The tombstone value must be different from the null value.

This may cause the key type returned by an iterator to change asynchronously to the tombstone value.

◆ erase() [4/4]

bool CxxUtils::erase ( key_type key)

Erase an entry from the table.

Parameters
keyThe key to erase.

Mark the corresponding entry as deleted. Return true on success, false on failure (key not found).

The tombstone value must be different from the null value.

This may cause the key type returned by an iterator to change asynchronously to the tombstone value.

◆ erased()

size_t CxxUtils::erased ( ) const

The number of erased elements in the current table.

◆ exctrace()

void CxxUtils::exctrace ( const std::exception & e,
IOFD fd = IOFD_INVALID )

Print out information for the last exception.

Prints the supplied exception, plus the backtrace from the last exception, if available.

Parameters
eThe exception to print.
fdThe file descriptor to which to write.

Definition at line 59 of file exctrace.cxx.

60{
61 if (fd == IOFD_INVALID)
62 fd = Athena::DebugAids::stacktraceFd();
63
64 typedef int (*get_last_trace_fn) (int max_depth, void* trace[]);
65 get_last_trace_fn get_last_trace = (get_last_trace_fn) dlsym (RTLD_DEFAULT, "exctrace_get_last_trace");
66
67
68 MYWRITELIT(fd, "Exception: ");
69 MYWRITE(fd, e.what(), strlen (e.what()));
70
71 if (get_last_trace) {
72 void* trace[100];
73 int depth = get_last_trace (std::end(trace)-std::begin(trace), trace);
74
75 MYWRITELIT(fd, "\n");
76 // Index 0 is __cxa_throw. Skip it.
77 for (int i = 1; i < depth; ++i) {
78 unsigned long ip =
79 reinterpret_cast<unsigned long> (trace[i]);
80 // A function that throws may have the call to __cxa_throw
81 // as the last instruction in the function. In that case, the IP
82 // we see here will be one beyond the end of the function,
83 // and we'll report the wrong function. So move back the IP
84 // slightly for the function that threw.
85 if (i == 1) --ip;
86
87 // It's true that stacktraceLine is not really thread-safe.
88 // However, if we're here, things are going south fast anyway,
89 // so we'll just cross our fingers and try to shovel out as much
90 // information as we can.
91 [[maybe_unused]]
92 bool dum ATLAS_THREAD_SAFE = stacktraceLine (fd, ip);
93 }
94 }
95 else
96 MYWRITELIT(fd, " (no backtrace available).\n");
97}
#define IOFD_INVALID
Invalid channel descriptor constant.
Definition SealCommon.h:20
#define MYWRITE(fd, data, n)
#define ATLAS_THREAD_SAFE
#define MYWRITELIT(fd, str)
Definition exctrace.cxx:35
std::string depth
tag string for intendation
Definition fastadd.cxx:46

◆ expand()

void CxxUtils::expand ( bit_t new_nbits)
private

Expand the container.

Parameters
new_nbitsThe desired new size of the container.

◆ expandOol()

void CxxUtils::ConcurrentBitset::expandOol ( bit_t new_nbits)
private

Expand the container: out-of-line portion.

Parameters
new_nbitsThe desired new size of the container.

Definition at line 167 of file ConcurrentBitset.cxx.

168{
169 // Need to take out the lock.
171 // Check the size again while we're holding the lock.
172 bit_t nbits = (*m_impl).nbits();
173 if (new_nbits > nbits) {
174 // We need to expand. Allocate a new implementation and initialize it,
175 // copying from the existing implementation.
176 Impl* i = new (new_nbits) Impl (*m_impl, new_nbits);
177
178 // Remember that we need to delete the old object.
179 m_garbage.push_back (m_impl);
180
181 // Publish the new one.
182 m_impl = i;
183 }
184}
std::atomic< Impl * > m_impl
The current implementation object.

◆ extendImpl()

int CxxUtils::extendImpl ( lock_t & lock,
const RANGE & extendedRange,
const typename Updater_t::Context_t & ctx )
private

Extend the range of the last entry of the map.

Parameters
Lockobject.
extendedRangeNew range to use for the last entry.
ctxExecution context.

Implementation of extendLastRange; see there for details. Must be called with the lock held.

◆ extendLastRange()

int CxxUtils::extendLastRange ( const RANGE & newRange,
const typename Updater_t::Context_t & ctx = Updater_t::defaultContext() )

Extend the range of the last entry of the map.

Parameters
newRangeNew range to use for the last entry.
ctxExecution context.

The range of the last entry in the map is updated to newRange. Does nothing if the map is empty. This will make a new version of implementation data.

The semantics of what it means to extend a range are given by the extendRange method of the COMPARE object (see above).

Returns -1 if there was an error; 1 if the last range was extended; and 0 if nothing was changed.

◆ find() [1/3]

const_iterator CxxUtils::find ( bit_t bit) const

If bit bit is set, return an iterator pointing to it.

Otherwise, return an end iterator.

Parameters
bitBit number to test.

◆ find() [2/3]

const_iterator CxxUtils::find ( const key_query_type & key) const

Search for the first item less than or equal to KEY.

Parameters
keyThe key to search for.
Returns
The value, or nullptr if not found.

◆ find() [3/3]

iterator CxxUtils::find ( key_type key) const

Look up an element in the map.

Parameters
keyThe element to find.

Returns either an iterator referencing the found element or end().

Parameters
keyThe element to find.

Returns either an iterator referencing the found element or end().

The mapped object must itself be thread-safe in order to make any changes to it through the returned iterator.

◆ flip() [1/2]

ConcurrentBitset & CxxUtils::flip ( )

Flip the state of all bits in the set.

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

◆ flip() [2/2]

ConcurrentBitset & CxxUtils::flip ( bit_t bit)

Flip the value of one bit.

Parameters
bitThe bit to turn flip.

Does nothing if bit beyond the end of the set.

◆ forceClear()

void CxxUtils::forceClear ( )

Erase the table in-place.

This method avoids allocating a new version of the table. However, it is not safe to use concurrently — no other threads may be accessing the container at the same time, either for read or write.

◆ fromArrayrep() [1/2]

template<unsigned int N>
void CxxUtils::fromArrayrep ( const CaloRec::Arrayrep & rep,
CxxUtils::Array< N > & x )

Helper to convert from an @x Arrayrep to an Array.

Parameters
repRepresentation object to convert.
x[out]Result of the conversion.

◆ fromArrayrep() [2/2]

template<class T>
void CxxUtils::fromArrayrep ( const CaloRec::Arrayrep & rep,
T & x )

Helper to convert from an @x Arrayrep to a scalar type.

Parameters
repRepresentation object to convert.
x[out]Result of the conversion.

◆ fullName()

std::string CxxUtils::fullName ( ) const

Return the full name of the expression.

◆ get()

Impl_t::const_iterator CxxUtils::get ( key_type key) const
private

Do a lookup in the table.

Parameters
keyThe key to look up.

Returns an iterator of the underlying map pointing at the found entry or end();

◆ get_unaligned()

template<class T>
T CxxUtils::get_unaligned ( const uint8_t *ATH_RESTRICT & p)

Define templated versions of the above functions.

◆ get_unaligned16()

uint16_t CxxUtils::get_unaligned16 ( const uint8_t *ATH_RESTRICT & p)
inline

Read a 2-byte little-endian value from a possibly unaligned pointer.

Parameters
pPointer from which to read. Advanced to the next value.

Reads a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 63 of file get_unaligned.h.

64{
65 uint16_t ret;
66 memcpy (&ret, p, sizeof(ret));
67 p += sizeof(ret);
68 return le16toh (ret);
69}
uint16_t le16toh(uint16_t x)

◆ get_unaligned32()

uint32_t CxxUtils::get_unaligned32 ( const uint8_t *ATH_RESTRICT & p)
inline

Read a 4-byte little-endian value from a possibly unaligned pointer.

Parameters
pPointer from which to read. Advanced to the next value.

Reads a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 83 of file get_unaligned.h.

84{
85 uint32_t ret;
86 memcpy (&ret, p, sizeof(ret));
87 p += sizeof(ret);
88 return le32toh (ret);
89}
uint32_t le32toh(uint32_t x)

◆ get_unaligned64()

uint64_t CxxUtils::get_unaligned64 ( const uint8_t *ATH_RESTRICT & p)
inline

Read an 8-byte little-endian value from a possibly unaligned pointer.

Parameters
pPointer from which to read. Advanced to the next value.

Reads a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 103 of file get_unaligned.h.

104{
105 uint64_t ret;
106 memcpy (&ret, p, sizeof(ret));
107 p += sizeof(ret);
108 return le64toh (ret);
109}
uint64_t le64toh(uint64_t x)

◆ get_unaligned< double >()

template<>
double CxxUtils::get_unaligned< double > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 195 of file get_unaligned.h.

196{
197 return get_unaligned_double (p);
198}
double get_unaligned_double(const uint8_t *ATH_RESTRICT &p)
Read a little-endian double value from a possibly unaligned pointer.

◆ get_unaligned< float >()

template<>
float CxxUtils::get_unaligned< float > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 187 of file get_unaligned.h.

188{
189 return get_unaligned_float (p);
190}
float get_unaligned_float(const uint8_t *ATH_RESTRICT &p)
Read a little-endian float value from a possibly unaligned pointer.

◆ get_unaligned< int16_t >()

template<>
int16_t CxxUtils::get_unaligned< int16_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 211 of file get_unaligned.h.

212{
213 return get_unaligned<uint16_t> (p);
214}
uint16_t get_unaligned< uint16_t >(const uint8_t *ATH_RESTRICT &p)

◆ get_unaligned< int32_t >()

template<>
int32_t CxxUtils::get_unaligned< int32_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 219 of file get_unaligned.h.

220{
221 return get_unaligned<uint32_t> (p);
222}
uint32_t get_unaligned< uint32_t >(const uint8_t *ATH_RESTRICT &p)

◆ get_unaligned< int64_t >()

template<>
int64_t CxxUtils::get_unaligned< int64_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 227 of file get_unaligned.h.

228{
229 return get_unaligned<uint64_t> (p);
230}
uint64_t get_unaligned< uint64_t >(const uint8_t *ATH_RESTRICT &p)

◆ get_unaligned< int8_t >()

template<>
int8_t CxxUtils::get_unaligned< int8_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 203 of file get_unaligned.h.

204{
205 return get_unaligned<uint8_t> (p);
206}
uint8_t get_unaligned< uint8_t >(const uint8_t *ATH_RESTRICT &p)

◆ get_unaligned< uint16_t >()

template<>
uint16_t CxxUtils::get_unaligned< uint16_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 163 of file get_unaligned.h.

164{
165 return get_unaligned16 (p);
166}
uint16_t get_unaligned16(const uint8_t *ATH_RESTRICT &p)
Read a 2-byte little-endian value from a possibly unaligned pointer.

◆ get_unaligned< uint32_t >()

template<>
uint32_t CxxUtils::get_unaligned< uint32_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 171 of file get_unaligned.h.

172{
173 return get_unaligned32 (p);
174}
uint32_t get_unaligned32(const uint8_t *ATH_RESTRICT &p)
Read a 4-byte little-endian value from a possibly unaligned pointer.

◆ get_unaligned< uint64_t >()

template<>
uint64_t CxxUtils::get_unaligned< uint64_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 179 of file get_unaligned.h.

180{
181 return get_unaligned64 (p);
182}
uint64_t get_unaligned64(const uint8_t *ATH_RESTRICT &p)
Read an 8-byte little-endian value from a possibly unaligned pointer.

◆ get_unaligned< uint8_t >()

template<>
uint8_t CxxUtils::get_unaligned< uint8_t > ( const uint8_t *ATH_RESTRICT & p)
inline

Definition at line 155 of file get_unaligned.h.

156{
157 return *p++;
158}

◆ get_unaligned_double()

double CxxUtils::get_unaligned_double ( const uint8_t *ATH_RESTRICT & p)
inline

Read a little-endian double value from a possibly unaligned pointer.

Parameters
pPointer from which to read. Advanced to the next value.

Reads a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 140 of file get_unaligned.h.

141{
142 return std::bit_cast<double> (get_unaligned64 (p));
143}

◆ get_unaligned_float()

float CxxUtils::get_unaligned_float ( const uint8_t *ATH_RESTRICT & p)
inline

Read a little-endian float value from a possibly unaligned pointer.

Parameters
pPointer from which to read. Advanced to the next value.

Reads a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 123 of file get_unaligned.h.

124{
125 return std::bit_cast<float> (get_unaligned32 (p));
126}

◆ getBegin()

const_iterator CxxUtils::getBegin ( const_iterator & last) const
private

Return the begin/last pointers.

Parameters
[in,out]lastCurrent value of last.

Retrieve consistent values of the begin and last pointers. The last pointer should have already been fetched, and may be updated. Usage should be like this:

if (!last) return; // Container empty.
if (!last) return; // Container empty.
const_iterator getBegin(const_iterator &last) const
Return the begin/last pointers.
const_iterator begin() const
Return a begin iterator.
std::atomic< value_type * > m_last
Iterator over all 1 bits in the set.

◆ hexdump()

void CxxUtils::hexdump ( std::ostream & s,
const void * addr,
size_t n,
size_t offset = 0 )

Make a hex dump of memory.

Parameters
sStream to which to write the output.
addrAddress at which to start dumping.
nNumber of byte to dump.
offsetOffset by which to shift the printed address (mostly for testing).

Definition at line 37 of file hexdump.cxx.

38{
39 const char* ptr = reinterpret_cast<const char*> (addr);
40 size_t ipos = 0;
41
42 boost::io::ios_all_saver saver (s);
43 std::hex (s);
44 s.fill ('0');
45
46 char cbuf[width + 1] = {0};
47 union {
48 uint32_t u32;
49 unsigned char uc[4];
50 } bbuf;
51
52 while (n-- > 0) {
53 if ((ipos % width) == 0) {
54 s << std::setw(16) << reinterpret_cast<uintptr_t>(ptr + ipos) - offset << " ";
55 }
56 if ((ipos % 4) == 0) {
57 s << " ";
58 }
59 bbuf.uc[ipos % 4] = ptr[ipos];
60 cbuf[ipos % width] = std::isgraph (ptr[ipos]) ? ptr[ipos] : '.';
61
62 ++ipos;
63 if ((ipos % 4) == 0) {
64 s << std::setw(8) << static_cast<unsigned int>(bbuf.u32);
65 }
66 if ((ipos % width) == 0) {
67 s << " " << cbuf << "\n";
68 }
69 }
70
71 if ((ipos % width) > 0) {
72 unsigned ntrail = (ipos % 4);
73 if (ntrail > 0) {
74 for (unsigned i = ntrail; i < 4; i++) {
75 bbuf.uc[i] = 0;
76 }
77 s << std::setw(2*ntrail) << static_cast<unsigned int>(bbuf.u32);
78 }
79 while ((ipos % width) != 0) {
80 if ((ipos % 4) == 0) {
81 s << " ";
82 }
83 s << " ";
84 cbuf[ipos % width] = ' ';
85 ++ipos;
86 }
87 s << " " << cbuf << "\n";
88 }
89}
const double width

◆ htole16()

uint16_t CxxUtils::htole16 ( uint16_t x)
inline

Definition at line 42 of file set_unaligned.h.

42{ return x; }

◆ htole32()

uint32_t CxxUtils::htole32 ( uint32_t x)
inline

Definition at line 43 of file set_unaligned.h.

43{ return x; }

◆ htole64()

uint64_t CxxUtils::htole64 ( uint64_t x)
inline

Definition at line 44 of file set_unaligned.h.

44{ return x; }

◆ insert() [1/9]

ConcurrentBitset & CxxUtils::insert ( bit_t bit,
bit_t new_nbits = 0 )

Set a bit to 1.

Expand the set if needed.

Parameters
bitNumber of the bit to set.
new_nbitsHint for new size of set, if it needs to be expanded.

If bit is past the end of the container, then the container will be expanded as needed.

This operation is incompatible with any other simultaneous writes to the same set (reads are ok).

◆ insert() [2/9]

ConcurrentBitset & CxxUtils::insert ( const ConcurrentBitset & other)

Turn on bits listed in another set.

Parameters
otherSet of bits to turn on.

This is the same as operator|=, except that if the size of other is larger than this set, then this set will be expanded to match other.

This operation is incompatible with any other simultaneous writes to the same set (reads are ok).

◆ insert() [3/9]

template<class PAIR>
std::pair< const_iterator, bool > CxxUtils::insert ( const PAIR & p)

Add an element to the map.

Parameters
pThe item to add. Should be a pair where first is the key and second is the integer value.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

For external locking, use emplace().

◆ insert() [4/9]

template<class PAIR>
std::pair< const_iterator, bool > CxxUtils::insert ( const PAIR & p,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map.

Parameters
pThe item to add. Should be a pair where first is the string key and second is the integer value.
ctxExecution context.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ insert() [5/9]

template<class InputIterator>
void CxxUtils::insert ( InputIterator first,
InputIterator last )

Insert a range of elements to the map.

Parameters
firstStart of the range.
lastEnd of the range.

The range should be a sequence of pairs where first is the string key and second is the integer value.

◆ insert() [6/9]

template<class InputIterator>
void CxxUtils::insert ( InputIterator first,
InputIterator last,
const Context_t & ctx = Updater_t::defaultContext() )

Insert a range of elements to the map.

Parameters
firstStart of the range.
lastEnd of the range.
ctxExecution context.

The range should be a sequence of pairs where first is the string key and second is the integer value.

◆ insert() [7/9]

template<class ITERATOR, typename = typename std::enable_if< std::is_base_of< typename std::forward_iterator_tag, typename std::iterator_traits<ITERATOR>::iterator_category >::value>>
ConcurrentBitset & CxxUtils::insert ( ITERATOR beg,
ITERATOR end,
bit_t new_nbits = 0 )

Set several bits to 1.

Expand the set if needed.

Parameters
begStart of range of bits to set.
endEnd of range of bits to set.
new_nbitsHint for new size of set, if it needs to be expanded.

The iteration range should be over something convertible to bit_t. If any bit is past the end of the container, then the container will be expanded as needed.

This operation is incompatible with any other simultaneous writes to the same set (reads are ok).

Example:

std::vector<bit_t> bits { 4, 10, 12};
bs.insert (bits.begin(), bits.end());

◆ insert() [8/9]

template<class PAIR>
std::pair< const_iterator, bool > CxxUtils::insert ( PAIR && p,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map.

Parameters
pThe item to add. Should be a pair where first is the string key and second is the integer value.
ctxExecution context.

This will not overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ insert() [9/9]

ConcurrentBitset & CxxUtils::insert ( std::initializer_list< bit_t > l,
bit_t new_nbits = 0 )

Set several bits to 1.

Expand the set if needed.

Parameters
lList of bits to set.
new_nbitsHint for new size of set, if it needs to be expanded.

If any bit is past the end of the container, then the container will be expanded as needed.

This operation is incompatible with any other simultaneous writes to the same set (reads are ok).

Example:

std::vector<bit_t> bits { 4, 10, 12};
bs.insert ({4, 10, 12});

◆ insert_or_assign() [1/2]

std::pair< const_iterator, bool > CxxUtils::insert_or_assign ( const Lock_t & lock,
key_type key,
mapped_type val,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map, or overwrite an existing one, with external locking.

Parameters
lockThe lock object returned from lock().
keyThe key of the new item to add.
valThe value of the new item to add.
ctxExecution context.

This will overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ insert_or_assign() [2/2]

std::pair< const_iterator, bool > CxxUtils::insert_or_assign ( key_type key,
mapped_type val,
const Context_t & ctx = Updater_t::defaultContext() )

Add an element to the map, or overwrite an existing one.

Parameters
keyThe key of the new item to add.
valThe value of the new item to add.
ctxExecution context.

This will overwrite an existing entry. The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ installImpl()

void CxxUtils::installImpl ( std::unique_ptr< Impl > new_impl,
value_type * new_begin,
value_type * new_end,
const typename Updater_t::Context_t & ctx )
private

Install a new implementation instance and make it visible.

Parameters
new_implThe new instance.
new_beginBegin pointer for the new instance.
new_endEnd pointer for the new instance. (Usual STL meaning of end. If the instance is empty, then new_end should match new_begin.)
ctxExecution context.

◆ is_base64()

bool CxxUtils::is_base64 ( unsigned char c)
inlinestatic

Definition at line 51 of file base64.cxx.

51 {
52 return (isalnum(c) || (c == '+') || (c == '/'));
53}

◆ isConst()

bool CxxUtils::isConst ( ) const

Get the const flag for this expression.

◆ keyAsKey() [1/2]

key_type CxxUtils::keyAsKey ( val_t val)
staticprivate

Convert an underlying key value to this type's key value.

Parameters
valThe underlying key value.

◆ keyAsKey() [2/2]

key_type CxxUtils::keyAsKey ( val_t val)
staticprivate

Convert an underlying key value to this type's key value.

Parameters
valThe underlying key value.

◆ keyAsVal() [1/2]

val_t CxxUtils::keyAsVal ( key_type k)
staticprivate

Convert this type's key value to an underlying key value.

Parameters
kThe key.

◆ keyAsVal() [2/2]

val_t CxxUtils::keyAsVal ( key_type k)
staticprivate

Convert this type's key value to an underlying key value.

Parameters
kThe key.

◆ le16toh()

uint16_t CxxUtils::le16toh ( uint16_t x)
inline

Definition at line 42 of file get_unaligned.h.

42{ return x; }

◆ le32toh()

uint32_t CxxUtils::le32toh ( uint32_t x)
inline

Definition at line 43 of file get_unaligned.h.

43{ return x; }

◆ le64toh()

uint64_t CxxUtils::le64toh ( uint64_t x)
inline

Definition at line 44 of file get_unaligned.h.

44{ return x; }

◆ lock()

Lock_t CxxUtils::lock ( )

Take a lock on the container.

Take a lock on the container. The lock can then be passed to insertion methods, allowing to factor out the locking inside loops. The lock will be released when the lock object is destroyed.

◆ make_reverse_wrapper()

template<class T>
auto CxxUtils::make_reverse_wrapper ( T & r)

Make a reverse_wrapper for a given container-like object.

Definition at line 46 of file reverse_wrapper.h.

46{ return reverse_wrapper(r); }
Adapter for a container-like class to be used in a range-for so as to iterate in the reverse directio...
int r
Definition globals.cxx:22

◆ make_span()

template<detail::IsContiguousContainer CONTAINER>
auto CxxUtils::make_span ( CONTAINER & c)

Helper to make a span from a container.

Parameters
cThe container for which to make a span. It must have contiguous iterators.

Definition at line 319 of file span.h.

320{
321 return CxxUtils::span (c.data(), c.size());
322}
span(T *ptr, std::size_t sz) -> span< T >
A couple needed deduction guides.

◆ makeCRCTable()

std::unique_ptr< CRCTable > CxxUtils::makeCRCTable ( uint64_t p,
uint64_t initial = 0xffffffffffffffff )

Initialize CRC tables and constants.

Parameters
pPolynomial for the CRC. A 1 in the 2^64 bit is implied.
initialInitial CRC value.

Definition at line 547 of file crc64.cxx.

549{
550 return std::make_unique<CRCTable> (p, initial);
551}

◆ mappedAsMapped() [1/2]

mapped_type CxxUtils::mappedAsMapped ( val_t val)
staticprivate

Convert an underlying mapped value to this type's mapped value.

Parameters
valThe underlying mapped value.

◆ mappedAsMapped() [2/2]

mapped_type * CxxUtils::mappedAsMapped ( val_t val)
staticprivate

Convert an underlying mapped value a pointer to this type's mapped value.

Parameters
valThe underlying mapped value.

◆ mappedAsVal() [1/2]

val_t CxxUtils::mappedAsVal ( mapped_type * val)
staticprivate

Convert this type's mapped value to an underlying mapped value.

Parameters
valThe mapped value.

◆ mappedAsVal() [2/2]

val_t CxxUtils::mappedAsVal ( mapped_type val)
staticprivate

Convert this type's mapped value to an underlying mapped value.

Parameters
valThe mapped value.

◆ match()

bool CxxUtils::match ( const ClassName & pattern,
match_t & matches ) const

Match this expression against a pattern.

Parameters
patternThe pattern to match.
[out]matchesDictionary of pattern substitutions.

Return true if pattern matches the current expression. pattern may contain dummy variables of the form $T. On a successful return, the map matches contains the variable assignments needed for the match.

◆ match1()

bool ClassName< T >::match1 ( const ClassName & pattern,
bool topLevel,
match_t & matches ) const
private

Match this expression against a pattern.

Parameters
patternThe pattern to match.
topLevelTrue if this is the outermost level of matching.
[out]matchesDictionary of pattern substitutions.

Return true if pattern matches the current expression. pattern may contain dummy variables of the form $T. On a successful return, the map matches contains the variable assignments needed for the match.

Definition at line 603 of file CxxUtils/Root/ClassName.cxx.

606{
607 if (pattern.m_name[0] == '$') {
608 std::string var = pattern.m_name.substr (1, std::string::npos);
609 match_t::iterator it = matches.find (var);
610 if (it != matches.end()) {
611 if (pattern.m_const && !it->second.m_const) {
612 ClassName cn (it->second);
613 cn.setConst();
614 return *this == cn;
615 }
616 return *this == it->second;
617 }
618
619 matches[var] = *this;
620 if (pattern.m_const) {
621 if (m_const)
622 matches[var].m_const = false;
623 else
624 return false;
625 }
626 return true;
627 }
628
629 // Require that const qualifiers match.
630 // However, if this is the top level, we allow a pattern with no explicit
631 // const to match something that is const. Otherwise, we'd need to repeat
632 // all patterns for the const case.
633 if (topLevel) {
634 if (pattern.m_const && !m_const)
635 return false;
636 }
637 else if (m_const != pattern.m_const) {
638 return false;
639 }
640
641 if (m_name != pattern.m_name)
642 return false;
643
644 if (m_namespace.size() != pattern.m_namespace.size())
645 return false;
646
647 if (m_targs.size() != pattern.m_targs.size())
648 return false;
649
650 if (m_namespace.size() > 0) {
651 if (!m_namespace[0].match1 (pattern.m_namespace[0], false, matches))
652 return false;
653 }
654
655 for (size_t i = 0; i < m_targs.size(); i++) {
656 if (!m_targs[i].match1 (pattern.m_targs[i], false, matches))
657 return false;
658 }
659
660 return true;
661}
bool match1(const ClassName &pattern, bool topLevel, match_t &matches) const
Match this expression against a pattern.
std::string m_name
The primary name part of this expression.

◆ max_transformed_element()

template<class RANGE, class FUNC>
auto CxxUtils::max_transformed_element ( RANGE && r,
FUNC && f )
inline

Find the maximum transformed element in a range.

Parameters
rInput range.
fTransform function.

Evaluates f(x) for each x in r and finds the maximum. Returns a pair (fmax, itmax), where fmax is this maximum value, and itmax is an iterator pointing at the corresponding element in r. If more than one element has the same maximum value, the iterator of the first will be returned.

Precondition: Range r is not empty.

Definition at line 82 of file minmax_transformed_element.h.

83{
84 if (std::ranges::empty (r)) std::abort();
85 auto it = std::ranges::begin(r);
86 auto itmax = it;
87 auto val = f(*it);
88 for (++it; it != std::ranges::end(r); ++it) {
89 auto val2 = f(*it);
90 if (val2 > val) {
91 val = val2;
92 itmax = it;
93 }
94 }
95 return std::make_pair (val, itmax);
96}

◆ maxSize()

size_t CxxUtils::maxSize ( ) const

Return the maximum size of the map.

◆ min_transformed_element()

template<class RANGE, class FUNC>
auto CxxUtils::min_transformed_element ( RANGE && r,
FUNC && f )
inline

Find the minimum transformed element in a range.

Parameters
rInput range.
fTransform function.

Evaluates f(x) for each x in r and finds the minimum. Returns a pair (fmin, itmin), where fmin is this minimum value, and itmin is an iterator pointing at the corresponding element in r. If more than one element has the same minimum value, the iterator of the first will be returned.

Precondition: Range r is not empty.

Definition at line 50 of file minmax_transformed_element.h.

51{
52 if (std::ranges::empty (r)) std::abort();
53 auto it = std::ranges::begin(r);
54 auto itmin = it;
55 auto val = f(*it);
56 for (++it; it != std::ranges::end(r); ++it) {
57 auto val2 = f(*it);
58 if (val2 < val) {
59 val = val2;
60 itmin = it;
61 }
62 }
63 return std::make_pair (val, itmin);
64}

◆ MurmurHash2()

uint32_t CxxUtils::MurmurHash2 ( const void * key,
int len,
uint32_t seed )

Definition at line 42 of file MurmurHash2.cxx.

43{
44 // 'm' and 'r' are mixing constants generated offline.
45 // They're not really 'magic', they just happen to work well.
46
47 const uint32_t m = 0x5bd1e995;
48 const int r = 24;
49
50 // Initialize the hash to a 'random' value
51
52 uint32_t h = seed ^ len;
53
54 // Mix 4 bytes at a time into the hash
55
56 const unsigned char * data = (const unsigned char *)key;
57
58 while(len >= 4)
59 {
60 uint32_t k = *reinterpret_cast<const uint32_t*>(data);
61
62 k *= m;
63 k ^= k >> r;
64 k *= m;
65
66 h *= m;
67 h ^= k;
68
69 data += 4;
70 len -= 4;
71 }
72
73 // Handle the last few bytes of the input array
74
75 switch(len)
76 {
77 case 3: h ^= data[2] << 16;
78 // FALLTHROUGH
79 case 2: h ^= data[1] << 8;
80 // FALLTHROUGH
81 case 1: h ^= data[0];
82 h *= m;
83 };
84
85 // Do a few final mixes of the hash to ensure the last few
86 // bytes are well-incorporated.
87
88 h ^= h >> 13;
89 h *= m;
90 h ^= h >> 15;
91
92 return h;
93}
Header file for AthHistogramAlgorithm.

◆ MurmurHash2A()

uint32_t CxxUtils::MurmurHash2A ( const void * key,
int len,
uint32_t seed )

Definition at line 220 of file MurmurHash2.cxx.

221{
222 const uint32_t M = 0x5bd1e995;
223 const int R = 24;
224 uint32_t l = len;
225
226 const unsigned char * data = (const unsigned char *)key;
227
228 uint32_t h = seed;
229
230 while(len >= 4)
231 {
232 uint32_t k = *reinterpret_cast<const uint32_t*>(data);
233
235
236 data += 4;
237 len -= 4;
238 }
239
240 uint32_t t = 0;
241
242 switch(len)
243 {
244 case 3: t ^= data[2] << 16;
245 // FALLTHROUGH
246 case 2: t ^= data[1] << 8;
247 // FALLTHROUGH
248 case 1: t ^= data[0];
249 };
250
251 MurmurHash_mmix(h,t);
252 MurmurHash_mmix(h,l);
253
254 h ^= h >> 13;
255 h *= M;
256 h ^= h >> 15;
257
258 return h;
259}
#define MurmurHash_mmix(h, k)
Definition MurmurHash2.h:29

◆ MurmurHash64A()

uint64_t CxxUtils::MurmurHash64A ( const void * key,
int len,
uint64_t seed )

Definition at line 103 of file MurmurHash2.cxx.

104{
105 const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995);
106 const int r = 47;
107
108 uint64_t h = seed ^ (len * m);
109
110 const uint64_t * data = (const uint64_t *)key;
111 const uint64_t * end = data + (len/8);
112
113 while(data != end)
114 {
115 uint64_t k = *data++;
116
117 k *= m;
118 k ^= k >> r;
119 k *= m;
120
121 h ^= k;
122 h *= m;
123 }
124
125 const unsigned char * data2 = reinterpret_cast<const unsigned char*>(data);
126
127 switch(len & 7)
128 {
129 case 7: h ^= uint64_t(data2[6]) << 48;
130 // FALLTHROUGH
131 case 6: h ^= uint64_t(data2[5]) << 40;
132 // FALLTHROUGH
133 case 5: h ^= uint64_t(data2[4]) << 32;
134 // FALLTHROUGH
135 case 4: h ^= uint64_t(data2[3]) << 24;
136 // FALLTHROUGH
137 case 3: h ^= uint64_t(data2[2]) << 16;
138 // FALLTHROUGH
139 case 2: h ^= uint64_t(data2[1]) << 8;
140 // FALLTHROUGH
141 case 1: h ^= uint64_t(data2[0]);
142 h *= m;
143 };
144
145 h ^= h >> r;
146 h *= m;
147 h ^= h >> r;
148
149 return h;
150}
#define BIG_CONSTANT(x)

◆ MurmurHash64B()

uint64_t CxxUtils::MurmurHash64B ( const void * key,
int len,
uint64_t seed )

Definition at line 155 of file MurmurHash2.cxx.

156{
157 const uint32_t m = 0x5bd1e995;
158 const int r = 24;
159
160 uint32_t h1 = uint32_t(seed) ^ len;
161 uint32_t h2 = uint32_t(seed >> 32);
162
163 const uint32_t * data = (const uint32_t *)key;
164
165 while(len >= 8)
166 {
167 uint32_t k1 = *data++;
168 k1 *= m; k1 ^= k1 >> r; k1 *= m;
169 h1 *= m; h1 ^= k1;
170 len -= 4;
171
172 uint32_t k2 = *data++;
173 k2 *= m; k2 ^= k2 >> r; k2 *= m;
174 h2 *= m; h2 ^= k2;
175 len -= 4;
176 }
177
178 if(len >= 4)
179 {
180 uint32_t k1 = *data++;
181 k1 *= m; k1 ^= k1 >> r; k1 *= m;
182 h1 *= m; h1 ^= k1;
183 len -= 4;
184 }
185
186 switch(len)
187 {
188 case 3: h2 ^= (reinterpret_cast<unsigned const char*>(data))[2] << 16;
189 // FALLTHROUGH
190 case 2: h2 ^= (reinterpret_cast<unsigned const char*>(data))[1] << 8;
191 // FALLTHROUGH
192 case 1: h2 ^= (reinterpret_cast<unsigned const char*>(data))[0];
193 h2 *= m;
194 };
195
196 h1 ^= h2 >> 18; h1 *= m;
197 h2 ^= h1 >> 22; h2 *= m;
198 h1 ^= h2 >> 17; h1 *= m;
199 h2 ^= h1 >> 19; h2 *= m;
200
201 uint64_t h = h1;
202
203 h = (h << 32) | h2;
204
205 return h;
206}

◆ MurmurHashAligned2()

uint32_t CxxUtils::MurmurHashAligned2 ( const void * key,
int len,
uint32_t seed )

Definition at line 324 of file MurmurHash2.cxx.

325{
326 const uint32_t m = 0x5bd1e995;
327 const int r = 24;
328
329 const unsigned char * data = (const unsigned char *)key;
330
331 uint32_t h = seed ^ len;
332
333 int align = (uint64_t)data & 3;
334
335 if(align && (len >= 4))
336 {
337 // Pre-load the temp registers
338
339 uint32_t t = 0, d = 0;
340
341 switch(align)
342 {
343 case 1: t |= data[2] << 16;
344 // FALLTHROUGH
345 case 2: t |= data[1] << 8;
346 // FALLTHROUGH
347 case 3: t |= data[0];
348 }
349
350 t <<= (8 * align);
351
352 data += 4-align;
353 len -= 4-align;
354
355 int sl = 8 * (4-align);
356 int sr = 8 * align;
357
358 // Mix
359
360 while(len >= 4)
361 {
362 d = *reinterpret_cast<const uint32_t *>(data);
363 t = (t >> sr) | (d << sl);
364
365 uint32_t k = t;
366
367 MIX(h,k,m);
368
369 t = d;
370
371 data += 4;
372 len -= 4;
373 }
374
375 // Handle leftover data in temp registers
376
377 d = 0;
378
379 if(len >= align)
380 {
381 switch(align)
382 {
383 case 3: d |= data[2] << 16;
384 // FALLTHROUGH
385 case 2: d |= data[1] << 8;
386 // FALLTHROUGH
387 case 1: d |= data[0];
388 }
389
390 uint32_t k = (t >> sr) | (d << sl);
391 MIX(h,k,m);
392
393 // At this point, we know that len < 4 and align > 0.
394 data += align;
395 len -= align;
396 // So here, we must have 0 >= len < 3.
397
398 //----------
399 // Handle tail bytes
400
401 switch(len)
402 {
403 // can't happen --- see above.
404 //case 3: h ^= data[2] << 16;
405 // FALLTHROUGH
406 case 2: h ^= data[1] << 8;
407 // FALLTHROUGH
408 case 1: h ^= data[0];
409 h *= m;
410 };
411 }
412 else
413 {
414 switch(len)
415 {
416 // len cannot be 3, because align is at most 3.
417 //case 3: d |= data[2] << 16;
418 // FALLTHROUGH
419 case 2: d |= data[1] << 8;
420 // FALLTHROUGH
421 case 1: d |= data[0];
422 // FALLTHROUGH
423 case 0: h ^= (t >> sr) | (d << sl);
424 h *= m;
425 }
426 }
427
428 h ^= h >> 13;
429 h *= m;
430 h ^= h >> 15;
431
432 return h;
433 }
434 else
435 {
436 while(len >= 4)
437 {
438 uint32_t k = *reinterpret_cast<const uint32_t *>(data);
439
440 MIX(h,k,m);
441
442 data += 4;
443 len -= 4;
444 }
445
446 //----------
447 // Handle tail bytes
448
449 switch(len)
450 {
451 case 3: h ^= data[2] << 16;
452 // FALLTHROUGH
453 case 2: h ^= data[1] << 8;
454 // FALLTHROUGH
455 case 1: h ^= data[0];
456 h *= m;
457 };
458
459 h ^= h >> 13;
460 h *= m;
461 h ^= h >> 15;
462
463 return h;
464 }
465}
#define MIX(h, k, m)
setEventNumber uint32_t

◆ MurmurHashNeutral2()

uint32_t CxxUtils::MurmurHashNeutral2 ( const void * key,
int len,
uint32_t seed )

Definition at line 267 of file MurmurHash2.cxx.

268{
269 const uint32_t m = 0x5bd1e995;
270 const int r = 24;
271
272 uint32_t h = seed ^ len;
273
274 const unsigned char * data = (const unsigned char *)key;
275
276 while(len >= 4)
277 {
278 uint32_t k;
279
280 k = data[0];
281 k |= data[1] << 8;
282 k |= data[2] << 16;
283 k |= data[3] << 24;
284
285 k *= m;
286 k ^= k >> r;
287 k *= m;
288
289 h *= m;
290 h ^= k;
291
292 data += 4;
293 len -= 4;
294 }
295
296 switch(len)
297 {
298 case 3: h ^= data[2] << 16;
299 // FALLTHROUGH
300 case 2: h ^= data[1] << 8;
301 // FALLTHROUGH
302 case 1: h ^= data[0];
303 h *= m;
304 };
305
306 h ^= h >> 13;
307 h *= m;
308 h ^= h >> 15;
309
310 return h;
311}

◆ name()

const std::string & CxxUtils::name ( ) const

Return the root name of the expression.

In A::B<C>, the root name is B.

◆ nBlocks()

bit_t CxxUtils::nBlocks ( bit_t nbits)
staticprivate

Find number of blocks needed to hold a given number of bits.

Parameters
nbitsThe number of bits.

◆ newImpl()

Impl * CxxUtils::newImpl ( bit_t nbits)
private

Create a new, uninitialized implementation object.

Parameters
nbitsNumber of bits to allocate.

This will allocate memory for the Impl object, but will does not run the constructor.

◆ nInserts()

size_t CxxUtils::nInserts ( ) const

Return the number times an item was inserted into the map.

◆ none()

bool CxxUtils::none ( ) const

Return true if there are no 1 bits in the set.

◆ normalizeFunctionName()

std::string CxxUtils::normalizeFunctionName ( const std::string & fname)

Normalize a pretty-printed C++ function name.

Clean `allocator' template arguments from the function f.

Parameters
fnameThe name to normalize.

A C++ compiler can provide a complete printable name of the current function, though for example PRETTY_FUNCTION. This is useful to include in diagnostic messages. However, the exact string generated by different compilers may differ slightly. This can then cause issues if one is trying to compare the output of tests to an expected reference.

This function tries to normalize the function name strings so that they are the same, at least between gcc and clang.

Parameters
fName of the function to clean. */ std::string clean_allocator (std::string f) { std::string::size_type ipos = 0; while ((ipos = f.find (", std::allocator", ipos)) != std::string::npos) { const char* p = f.c_str() + ipos + 16; while (isspace (*p)) ++p; if (*p == '<') { ++p; int nest = 1; while (nest > 0 && *p) { if (*p == '<') ++nest; else if (*p == '>') –nest; ++p; } if (nest == 0) { if (ipos > 0 && f[ipos-1] != '>') { while (isspace (*p)) ++p; } f.erase (ipos, p-f.c_str()-ipos); p = f.c_str() + ipos; } } ipos = p - f.c_str(); } return f; }

std::string munge_string_name (const std::string& str_in) { std::string s = str_in;

std::string::size_type ipos = 0; while ((ipos = s.find ("std::basic_string<", ipos)) != std::string::npos) { std::string::size_type beg = ipos; ipos += 18; int inest = 1; while (inest > 0 && ipos < s.size()) { if (s[ipos] == '<') ++inest; else if (s[ipos] == '>') –inest; ++ipos; } s.replace (beg, ipos-beg, "std::string"); ipos = beg+11; }

for (size_t i = 0; i < s.size(); i++) { if ((i == 0 || (s[i-1] != ':' && !isalnum(s[i-1]))) && strncmp (s.c_str()+i, "string", 6) == 0 && !isalnum(s[i+6])) { s.replace (i, 6, "std::string"); } } return s; }

std::string munge_punct (const std::string& str_in) { std::string s = str_in; for (size_t i = 0; i < s.size()-1; i++) { if (s[i] == ' ' && (s[i+1] == '*' || s[i+1] == '&')) s.erase (i, 1); } return s; }

std::string do_replace (std::string s, const std::string& pat, const std::string& rep) { std::string::size_type ipos = 0; while ((ipos = s.find (pat, ipos)) != std::string::npos) s.replace (ipos, pat.size(), rep); return s; }

std::string munge_names (const std::string& str_in) { std::string s = do_replace (str_in, "SG::DataProxyStorageData::pointer", "void*"); s = do_replace (s, "DPSD::pointer", "void*"); s = do_replace (s, "SG::auxid_t", "unsigned long"); s = do_replace (s, "auxid_t", "unsigned long"); s = do_replace (s, "void* ", "void*"); s = do_replace (s, "CLID", "unsigned int");

if (s.compare (0, 8, "virtual ") == 0) s.erase (0, 8); return s; }

/**

Normalize a pretty-printed C++ function name.

Parameters
fnameThe name to normalize.

A C++ compiler can provide a complete printable name of the current function, though for example PRETTY_FUNCTION. This is useful to include in diagnostic messages. However, the exact string generated by different compilers may differ slightly. This can then cause issues if one is trying to compare the output of tests to an expected reference.

This function tries to normalize the function name strings so that they are the same, at least between gcc and clang.

Definition at line 135 of file normalizeFunctionName.cxx.

136{
137 return munge_names (munge_punct (munge_string_name (clean_allocator (fname))));
138}

◆ ntargs()

size_t ClassName< T >::ntargs ( ) const

Return number of template arguments.

Definition at line 275 of file CxxUtils/Root/ClassName.cxx.

276{
277 return m_targs.size();
278}

◆ ones()

template<class T>
T CxxUtils::ones ( unsigned int n)
inlineconstexpr

Return a bit mask with the lower n bits set.

Definition at line 25 of file ones.h.

26{
27 if (n >= sizeof(T) * 8)
28 return ~static_cast<T>(0);
29 // cppcheck-suppress shiftTooManyBits
30 return (static_cast<T>(1) << n) - 1;
31}

◆ operator!()

template<typename T, size_t N>
ivec< T, N > CxxUtils::operator! ( const vec_fb< T, N > & a)
inline

Negation.

Definition at line 158 of file vec_fb.h.

159{
160 ivec<T, N> c;
161 for (size_t i = 0; i < N; ++i)
162 c.m_arr[i] = a.m_arr[i] == 0;
163 return c;
164}
vec_fb< typename boost::int_t< sizeof(T) *8 >::exact, N > ivec
Definition vec_fb.h:53

◆ operator!=() [1/2]

bool CxxUtils::operator!= ( const ClassName & other) const

Test two expressions for inequality.

◆ operator!=() [2/2]

bool CxxUtils::operator!= ( const ConcurrentBitset & other) const

Test two sets for inequality.

Parameters
otherThe other set to test.

◆ operator&&() [1/3]

template<typename T, size_t N>
ivec< T, N > CxxUtils::operator&& ( const vec_fb< T, N > & a,
const vec_fb< T, N > & b )
inline

V1 && V2.

Definition at line 169 of file vec_fb.h.

170{
171 ivec<T, N> c;
172 for (size_t i = 0; i < N; ++i)
173 c.m_arr[i] = (a.m_arr[i] != 0) & (b.m_arr[i] != 0);
174 return c;
175}

◆ operator&&() [2/3]

template<typename T, size_t N, class U>
ivec< T, N > CxxUtils::operator&& ( const vec_fb< T, N > & a,
U b )
inline

V && S.

Definition at line 191 of file vec_fb.h.

192{
193 ivec<T, N> c;
194 for (size_t i = 0; i < N; ++i)
195 c.m_arr[i] = (a.m_arr[i] != 0) & (b ? -1 : 0);
196 return c;
197}

◆ operator&&() [3/3]

template<typename T, size_t N, class U>
ivec< T, N > CxxUtils::operator&& ( U a,
const vec_fb< T, N > & b )
inline

S && V.

Definition at line 180 of file vec_fb.h.

181{
182 ivec<T, N> c;
183 for (size_t i = 0; i < N; ++i)
184 c.m_arr[i] = a ? b.m_arr[i] != 0 : 0;
185 return c;
186}

◆ operator&=()

ConcurrentBitset & CxxUtils::operator&= ( const ConcurrentBitset & other)

AND this set with another set.

Parameters
otherThe other set.

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

◆ operator-=()

ConcurrentBitset & CxxUtils::operator-= ( const ConcurrentBitset & other)

Subtract another set from this set.

Parameters
otherThe other set.

This is the same as (*this) &= ~other;

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

◆ operator<<()

template<unsigned int N>
std::ostream & CxxUtils::operator<< ( std::ostream & s,
const Array< N > & a )

◆ operator=() [1/6]

ConcurrentBitset & CxxUtils::operator= ( ConcurrentBitset && other)

Move.

Parameters
otherBitset from which to move.

No concurrent access may be in progress on other. After this returns, other can only be deleted.

◆ operator=() [2/6]

ConcurrentMap & CxxUtils::operator= ( ConcurrentMap && other)
delete

◆ operator=() [3/6]

ConcurrentToValMap & CxxUtils::operator= ( ConcurrentToValMap && other)
delete

◆ operator=() [4/6]

ConcurrentBitset & CxxUtils::operator= ( const ConcurrentBitset & other)

Assignment.

Parameters
otherBitset from which to assign.

The copy is not atomic. If a non-atomic update is simultaneously made to other, then the copy may have this update only partially completed.

◆ operator=() [5/6]

ConcurrentMap & CxxUtils::operator= ( const ConcurrentMap & other)
delete

◆ operator=() [6/6]

ConcurrentToValMap & CxxUtils::operator= ( const ConcurrentToValMap & other)
delete

◆ operator==() [1/2]

bool CxxUtils::operator== ( const ClassName & other) const

Test two expressions for equality.

◆ operator==() [2/2]

bool CxxUtils::operator== ( const ConcurrentBitset & other) const

Test two sets for equality.

Parameters
otherThe other set to test.

◆ operator[]()

reference CxxUtils::operator[] ( bit_t bit) const

Return the value of one bit.

Return a reference to one bit.

Parameters
bitThe number of the bit to test.
bitThe number of the bit to reference.

The reference will be invalidated by calls to insert() or operator=. Effects are undefined if bit is past the end of the set.

◆ operator^=()

ConcurrentBitset & CxxUtils::operator^= ( const ConcurrentBitset & other)

XOR this set with another set.

Parameters
otherThe other set.

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

◆ operator|=()

ConcurrentBitset & CxxUtils::operator|= ( const ConcurrentBitset & other)

OR this set with another set.

Parameters
otherThe other set.

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

◆ operator||()

template<typename T, size_t N>
ivec< T, N > CxxUtils::operator|| ( const vec_fb< T, N > & a,
const vec_fb< T, N > & b )
inline

V1 || V2.

Definition at line 202 of file vec_fb.h.

203{
204 ivec<T, N> c;
205 for (size_t i = 0; i < N; ++i)
206 c.m_arr[i] = (a.m_arr[i] != 0) | (b.m_arr[i] != 0);
207 return c;
208}

◆ operator~()

ConcurrentBitset CxxUtils::operator~ ( ) const

Return a new set that is the complement of this set.

◆ parse()

void CxxUtils::parse ( const std::string & name,
std::string::size_type & pos )
private

Parse a string into a ClassName.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

On return, pos will be updated to point just past the last character consumed.

◆ parseNamespace()

void ClassName< T >::parseNamespace ( const std::string & name,
std::string::size_type & pos )
private

Parse a namespace qualification.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

When this is called, the namespace part has already been parsed, and the next two characters in name are ::. This reads in the remainder of the string as a ClassName, and then moves it inside the namespace given by the current object.

On return, pos will be updated to point just past the last character consumed.

Definition at line 522 of file CxxUtils/Root/ClassName.cxx.

524{
525 assert (pos+1 < name.size() && name[pos] == ':' && name[pos+1] == ':');
526 pos += 2;
527 skipSpaces (name, pos);
528
529 ClassName ns (name, pos);
530 ns.swap (*this);
531 if (ns.isConst()) {
532 this->setConst();
533 ns.m_const = false;
534 }
535 ClassName* p = this;
536 while (p->m_namespace.size() > 0)
537 p = &p->m_namespace[0];
538 p->m_namespace.push_back (std::move(ns));
539}
An interface for getting the name of a class as a string.
void setConst()
Set the const flag for this expression.

◆ parsePrimary()

std::string ClassName< T >::parsePrimary ( const std::string & name,
std::string::size_type & pos )
private

Parse a primary part of the class name.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

The primary part of the class name is a string without namespace and template delimiters.

On return, pos will be updated to point just past the last character consumed.

Definition at line 488 of file CxxUtils/Root/ClassName.cxx.

489{
490 skipSpaces (name, pos);
491 std::string out;
492 size_t nest = 0;
493 while (pos < name.size()) {
494 char c = name[pos];
495 if (c == '(')
496 ++nest;
497 else if (c == ')' && nest > 0)
498 --nest;
499 else if (nest == 0 && (c == '<' || c == '>' || c == ',' || c == ':'))
500 break;
501
502 out += c;
503 ++pos;
504 }
505 return out;
506}

◆ parseTemplateArgs()

void ClassName< T >::parseTemplateArgs ( const std::string & name,
std::string::size_type & pos )
private

Parse the template part of a name.

Parameters
nameThe string containing the name.
posPosition in the string to start parsing.

When this is called, the qualified name part of the name has already been parsed, and the next character in name is ::. This reads in template arguments from name.

On return, pos will be updated to point just past the last character consumed.

Definition at line 554 of file CxxUtils/Root/ClassName.cxx.

556{
557 assert (pos < name.size() && name[pos] == '<');
558 ++pos;
559 while (true) {
560 skipSpaces (name, pos);
561 m_targs.emplace_back (name, pos);
562 skipSpaces (name, pos);
563 if (pos == name.size()) break;
564 if (name[pos] == '>') {
565 ++pos;
566 break;
567 }
568 else if (name[pos] == ',')
569 ++pos;
570 else
571 break;
572 }
573}

◆ phiBisect()

template<typename T>
T CxxUtils::phiBisect ( T phiA,
T phiB )
inline

Bisect (average) the angle spanned by phiA and phiB.

The average is calculated by rotating phiA half-way counter-clockwise onto phiB. Note that his method is not symmetric in its arguments. Typical use-cases are to determine the centre of a region in the detector.

The returned value is within the range [-pi, pi].

Definition at line 77 of file phihelper.h.

78 {
79 static_assert(std::is_floating_point<T>::value);
80 T phi = 0.5 * (phiA + phiB);
81 if (phiA > phiB) phi += M_PI;
82 return wrapToPi(phi);
83 }
#define M_PI
Scalar phi() const
phi method

◆ phiMean()

template<typename T>
T CxxUtils::phiMean ( T phiA,
T phiB )
inline

Calculate average of two angles.

The average is calculated as the angle of the sum of the two unit vectors with angles phiA and phiB. As such it always returns the angle in the narrower of the two complimentary regions spanned by phiA and phiB. If the vector sum is zero, return the angle within [-pi/2, pi/2]. This method is symmetric in its arguments except if |mean| equals pi.

The returned value is within the range [-pi, pi].

Definition at line 60 of file phihelper.h.

61 {
62 static_assert(std::is_floating_point<T>::value);
63 const T diff = wrapToPi(phiA - phiB);
64 return wrapToPi(phiB + 0.5 * diff);
65 }
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631

◆ prefetchN()

template<size_t N>
void CxxUtils::prefetchN ( const void * ptr)
inline

Prefetch an N-byte block of memory.

Parameters
[in]ptrStarting address of the block.

Definition at line 85 of file prefetch.h.

86{
87 const char* pp = reinterpret_cast<const char*> (ptr);
88
89 // The compiler will unroll this loop for small N.
90 for (size_t i = 0; i < N; i += CacheLineSize)
91 prefetchOne (pp + i);
92
93 // Issue a prefetch for the last byte as well, in case it crosses
94 // cache lines.
95 prefetchOne (pp + N - 1);
96}
void prefetchOne(const void *address)
Generic prefetch method.
Definition prefetch.h:73

◆ prefetchNext()

template<typename Iter>
void CxxUtils::prefetchNext ( Iter iter,
Iter endIter )
inline

Prefetch next object in sequence.

Parameters
iterCurrent iteration position.
endIterEnd of the sequence.

Iter is a ForwardIterator over pointers.

Prefetches next object in a collection of pointers. Accepts two iterators: the first iterator is the current iteration position, and the second iterator is the end iterator for the whole sequence. The first iterator must not be equal to the end iterator (this is not checked). This increments the iterator and, if not equal to the end, prefetches the complete object referenced by the pointer.

Definition at line 130 of file prefetch.h.

131{
132 if (++iter != endIter)
133 prefetchObj(*iter);
134}
void prefetchObj(const T *ptr)
Generic prefetch of the object of specific types (sizes).
Definition prefetch.h:108

◆ prefetchObj()

template<typename T>
void CxxUtils::prefetchObj ( const T * ptr)
inline

Generic prefetch of the object of specific types (sizes).

Parameters
[in]addressmemory location to prefetch

This method will prefetch as many cache lines as needed to store the object of the specified type in memory. Type is specified as a template argument.

Definition at line 108 of file prefetch.h.

109{
111}
void prefetchN(const void *ptr)
Prefetch an N-byte block of memory.
Definition prefetch.h:85

◆ prefetchOne()

void CxxUtils::prefetchOne ( const void * address)
inline

Generic prefetch method.

Parameters
[in]addressmemory location to prefetch

This is generic method that does not have any extra behavior. It only prefetches the whole cache line which contains the specified memory location. It does not incur any additional overhead and may be the most efficient method for small objects which have a high chance of being on just a single cache line.

Definition at line 73 of file prefetch.h.

74{
76}
#define CXXUTILS_PREFETCH_ADDRESS(ADDR)
Definition prefetch.h:32

◆ prefetchTwo()

template<typename Iter>
void CxxUtils::prefetchTwo ( Iter iter,
Iter endIter )
inline

Prefetch two objects.

Parameters
iterCurrent iteration position.
endIterEnd of the sequence.

Iter is a ForwardIterator over pointers.

Prefetches the current and next objects in a collection of pointers. Accepts two iterators: the first iterator is the current iteration position, and the second is the end iterator for the whole sequence. If the first iterator is not equal to end the iterator, the object to which it points is prefetched. Then the iterator is incremented and, if not equal to the end iterator, the next objects is also prefetched.

Definition at line 154 of file prefetch.h.

155{
156 if (iter != endIter) {
157 prefetchObj(*iter);
158 if (++iter != endIter) {
159 prefetchObj(*iter);
160 }
161 }
162}

◆ put() [1/3]

std::pair< const_iterator, bool > CxxUtils::put ( const key_type key,
std::unique_ptr< mapped_type > val,
const Context_t & ctx = Updater_t::defaultContext() )
private

Insert an entry in the table.

Parameters
keyThe key of the new item to add.
valThe new mapped value to add.
ctxExecution context.

The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ put() [2/3]

std::pair< const_iterator, bool > CxxUtils::put ( const Lock_t & lock,
key_type key,
mapped_type val,
bool overwrite = true,
const Context_t & ctx = Updater_t::defaultContext() )
private

Insert / overwrite an entry in the table, with external locking.

Parameters
lockThe lock object returned from lock().
keyThe key of the new item to add.
valThe value of the new item to add.
overwriteIf true, allow overwriting an existing entry.
ctxExecution context.

The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ put() [3/3]

std::pair< const_iterator, bool > CxxUtils::put ( key_type key,
mapped_type val,
bool overwrite = true,
const Context_t & ctx = Updater_t::defaultContext() )
private

Insert / overwrite an entry in the table.

Parameters
keyThe key of the new item to add.
valThe value of the new item to add.
overwriteIf true, allow overwriting an existing entry.
ctxExecution context.

The first element in the returned pair is an iterator referencing the added item. The second is a flag that is true if a new element was added.

◆ qualifiedName()

std::string ClassName< T >::qualifiedName ( ) const

Return the namespace-qualified name of the expression.

Return the root name of the expression.

In A::B<C>, this is A::B.

In A::B<C>, the root name is B.

Definition at line 240 of file CxxUtils/Root/ClassName.cxx.

241{
242 std::string nsname;
243 if (m_namespace.size() > 0)
244 nsname = m_namespace[0].fullName() + "::";
245 return nsname + m_name;
246}

◆ quiescent() [1/2]

void CxxUtils::quiescent ( const Context_t & ctx)

Called when this thread is no longer referencing anything from this container.

Parameters
ctxExecution context.

◆ quiescent() [2/2]

void CxxUtils::quiescent ( const typename Updater_t::Context_t & ctx = Updater_t::defaultContext())

Called when this thread is no longer referencing anything from this container.

Parameters
ctxExecution context.

◆ range()

iterator_range CxxUtils::range ( ) const

Return an iterator range covering the entire map.

Return a range that can be used to iterate over the container.

The mapped objects must themselves be thread-safe in order to make any changes to them through the returned iterators.

◆ rehash()

void CxxUtils::rehash ( size_type capacity)

Increase the table capacity.

Parameters
capacityThe new table capacity.

No action will be taken if capacity is smaller than the current capacity.

◆ reserve()

void CxxUtils::reserve ( size_type capacity,
const Context_t & ctx = Updater_t::defaultContext() )

Increase the table capacity.

Parameters
capacityThe new table capacity.
ctxExecution context.

No action will be taken if capacity is smaller than the current capacity.

◆ reset() [1/3]

ConcurrentBitset & CxxUtils::reset ( )

Clear all bits in the set.

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

◆ reset() [2/3]

ConcurrentBitset & CxxUtils::reset ( bit_t bit)

Turn off one bit.

Parameters
bitThe bit to turn off.

Does nothing if bit beyond the end of the set.

◆ reset() [3/3]

template<class E>
std::enable_if_t< is_bitmask_v< E >, E & > CxxUtils::reset ( E & lhs,
E rhs )
constexpr

Convenience function to clear bits in a class enum bitmask.

Parameters
lhsTarget bitmask.
rhsBits to clear.

Same as lhs &= ~rhs.
This function is enabled only for enumerators that have used the ATH_BITMASK macro.

Definition at line 251 of file bitmask.h.

252{
253 lhs &= ~rhs;
254 return lhs;
255}

◆ safeHexdump()

void CxxUtils::safeHexdump ( std::ostream & s,
const void * addr,
size_t n,
size_t offset = 0 )

Make a hex dump of memory, protected against bad reads.

Parameters
sStream to which to write the output.
addrAddress at which to start dumping.
nNumber of byte to dump.
offsetOffset by which to shift the printed address (mostly for testing).

This function will skip dumping memory pages that are not readable. It may also start dumping slightly before the requested address, in order to start with an alignment of 16.

Definition at line 104 of file hexdump.cxx.

105{
106 const char* ptr = reinterpret_cast<const char*> (addr);
107
108 // Adjust to start at width-byte boundary.
109 size_t nadj = reinterpret_cast<uintptr_t>(ptr) % width;
110 if (nadj > 0) {
111 ptr -= nadj;
112 n += nadj;
113 }
114
115 long pagesize_ret = sysconf (_SC_PAGESIZE);
116 if (pagesize_ret < 0 || pagesize_ret >= 1024*1024*1024) {
117 std::abort();
118 }
119 size_t pagesize = pagesize_ret;
120
121
122 procmaps m;
123
124 // Print page by page.
125 while (n > 0) {
126 uintptr_t iptr = reinterpret_cast<uintptr_t>(ptr);
127 size_t thispage = ((iptr + pagesize) & ~(pagesize-1)) - iptr;
128 if (thispage > n) {
129 thispage = n;
130 }
131 const procmaps::Entry* ent = m.getEntry (ptr);
132 if (ent && ent->readable) {
133 hexdump (s, ptr, thispage, offset);
134 }
135 else {
136 boost::io::ios_all_saver saver (s);
137 std::hex (s);
138 s.fill ('0');
139 s << std::setw(16) << reinterpret_cast<uintptr_t>(ptr) - offset
140 << " --- is not readable\n";
141 if (ent) {
142 thispage = std::max (ent->endAddress - iptr, thispage);
143 }
144 }
145 ptr += thispage;
146 n -= thispage;
147 }
148}
void hexdump(std::ostream &s, const void *addr, size_t n, size_t offset=0)
Make a hex dump of memory.
Definition hexdump.cxx:37
unsigned long endAddress
Definition procmaps.h:23

◆ set() [1/4]

ConcurrentBitset & CxxUtils::set ( )

Turn on all bits in the set.

This operation is not necessarily atomic; a simultaneous read may be able to see the operation partially done.

◆ set() [2/4]

ConcurrentBitset & CxxUtils::set ( bit_t bit)

Turn on one bit.

Parameters
bitThe bit to turn on.

Does nothing if bit beyond the end of the set.

◆ set() [3/4]

ConcurrentBitset & CxxUtils::set ( bit_t bit,
bool val )

Set the value of one bit.

Parameters
bitThe bit to turn set.
valThe value to which to set it.

Does nothing if bit beyond the end of the set.

◆ set() [4/4]

template<class E>
std::enable_if_t< is_bitmask_v< E >, E & > CxxUtils::set ( E & lhs,
E rhs )
constexpr

Convenience function to set bits in a class enum bitmask.

Parameters
lhsTarget bitmask.
rhsBits to set.

Same as lhs |= rhs.
This function is enabled only for enumerators that have used the ATH_BITMASK macro.

Definition at line 232 of file bitmask.h.

233{
234 lhs |= rhs;
235 return lhs;
236}

◆ set_unaligned()

template<class T>
void CxxUtils::set_unaligned ( uint8_t *ATH_RESTRICT & p,
T val )

Define templated versions of the above functions.

◆ set_unaligned16()

void CxxUtils::set_unaligned16 ( uint8_t *ATH_RESTRICT & p,
uint16_t val )
inline

Write a 2-byte little-endian value to a possibly unaligned pointer.

Parameters
pPointer to which to write. Advanced to the next value.
valValue to write.

Writes a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 64 of file set_unaligned.h.

65{
66 uint16_t tmp = htole16 (val);
67 memcpy (p, &tmp, sizeof(tmp));
68 p += sizeof(tmp);
69}
uint16_t htole16(uint16_t x)

◆ set_unaligned32()

void CxxUtils::set_unaligned32 ( uint8_t *ATH_RESTRICT & p,
uint32_t val )
inline

Write a 4-byte little-endian value to a possibly unaligned pointer.

Parameters
pPointer to which to write. Advanced to the next value.
valValue to write.

Writes a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 84 of file set_unaligned.h.

85{
86 uint32_t tmp = htole32 (val);
87 memcpy (p, &tmp, sizeof(tmp));
88 p += sizeof(tmp);
89}
uint32_t htole32(uint32_t x)

◆ set_unaligned64()

void CxxUtils::set_unaligned64 ( uint8_t *ATH_RESTRICT & p,
uint64_t val )
inline

Write an 8-byte little-endian value to a possibly unaligned pointer.

Parameters
pPointer to which to write. Advanced to the next value.
valValue to write.

Writes a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 104 of file set_unaligned.h.

105{
106 uint64_t tmp = htole64 (val);
107 memcpy (p, &tmp, sizeof(tmp));
108 p += sizeof(tmp);
109}
uint64_t htole64(uint64_t x)

◆ set_unaligned< double >()

template<>
void CxxUtils::set_unaligned< double > ( uint8_t *ATH_RESTRICT & p,
double f )
inline

Definition at line 197 of file set_unaligned.h.

198{
200}
void set_unaligned_double(uint8_t *ATH_RESTRICT &p, double val)
Write a little-endian double value to a possibly unaligned pointer.

◆ set_unaligned< float >()

template<>
void CxxUtils::set_unaligned< float > ( uint8_t *ATH_RESTRICT & p,
float f )
inline

Definition at line 189 of file set_unaligned.h.

190{
191 set_unaligned_float (p, f);
192}
void set_unaligned_float(uint8_t *ATH_RESTRICT &p, float val)
Write a little-endian float value to a possibly unaligned pointer.

◆ set_unaligned< int16_t >()

template<>
void CxxUtils::set_unaligned< int16_t > ( uint8_t *ATH_RESTRICT & p,
int16_t val )
inline

Definition at line 213 of file set_unaligned.h.

214{
215 set_unaligned<uint16_t> (p, std::bit_cast<uint16_t> (val));
216}
void set_unaligned< uint16_t >(uint8_t *ATH_RESTRICT &p, uint16_t val)

◆ set_unaligned< int32_t >()

template<>
void CxxUtils::set_unaligned< int32_t > ( uint8_t *ATH_RESTRICT & p,
int32_t val )
inline

Definition at line 221 of file set_unaligned.h.

222{
223 set_unaligned<uint32_t> (p, std::bit_cast<uint32_t> (val));
224}
void set_unaligned< uint32_t >(uint8_t *ATH_RESTRICT &p, uint32_t val)

◆ set_unaligned< int64_t >()

template<>
void CxxUtils::set_unaligned< int64_t > ( uint8_t *ATH_RESTRICT & p,
int64_t val )
inline

Definition at line 229 of file set_unaligned.h.

230{
231 set_unaligned<uint64_t> (p, std::bit_cast<uint64_t> (val));
232}
void set_unaligned< uint64_t >(uint8_t *ATH_RESTRICT &p, uint64_t val)

◆ set_unaligned< int8_t >()

template<>
void CxxUtils::set_unaligned< int8_t > ( uint8_t *ATH_RESTRICT & p,
int8_t val )
inline

Definition at line 205 of file set_unaligned.h.

206{
207 set_unaligned<uint8_t> (p, std::bit_cast<uint8_t> (val));
208}
void set_unaligned< uint8_t >(uint8_t *ATH_RESTRICT &p, uint8_t val)

◆ set_unaligned< uint16_t >()

template<>
void CxxUtils::set_unaligned< uint16_t > ( uint8_t *ATH_RESTRICT & p,
uint16_t val )
inline

Definition at line 165 of file set_unaligned.h.

166{
167 set_unaligned16 (p, val);
168}
void set_unaligned16(uint8_t *ATH_RESTRICT &p, uint16_t val)
Write a 2-byte little-endian value to a possibly unaligned pointer.

◆ set_unaligned< uint32_t >()

template<>
void CxxUtils::set_unaligned< uint32_t > ( uint8_t *ATH_RESTRICT & p,
uint32_t val )
inline

Definition at line 173 of file set_unaligned.h.

174{
175 set_unaligned32 (p, val);
176}
void set_unaligned32(uint8_t *ATH_RESTRICT &p, uint32_t val)
Write a 4-byte little-endian value to a possibly unaligned pointer.

◆ set_unaligned< uint64_t >()

template<>
void CxxUtils::set_unaligned< uint64_t > ( uint8_t *ATH_RESTRICT & p,
uint64_t val )
inline

Definition at line 181 of file set_unaligned.h.

182{
183 set_unaligned64 (p, val);
184}
void set_unaligned64(uint8_t *ATH_RESTRICT &p, uint64_t val)
Write an 8-byte little-endian value to a possibly unaligned pointer.

◆ set_unaligned< uint8_t >()

template<>
void CxxUtils::set_unaligned< uint8_t > ( uint8_t *ATH_RESTRICT & p,
uint8_t val )
inline

Definition at line 157 of file set_unaligned.h.

158{
159 *p++ = val;
160}

◆ set_unaligned_double()

void CxxUtils::set_unaligned_double ( uint8_t *ATH_RESTRICT & p,
double val )
inline

Write a little-endian double value to a possibly unaligned pointer.

Parameters
pPointer to which to write. Advanced to the next value.
valValue to write.

Writes a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 142 of file set_unaligned.h.

143{
144 set_unaligned64 (p, std::bit_cast<uint64_t> (val));
145}

◆ set_unaligned_float()

void CxxUtils::set_unaligned_float ( uint8_t *ATH_RESTRICT & p,
float val )
inline

Write a little-endian float value to a possibly unaligned pointer.

Parameters
pPointer to which to write. Advanced to the next value.
valValue to write.

Writes a little-endian value, regardless of the host byte ordering, and advances the pointer. Should not rely on undefined behavior, regardless of the alignment of p.

If used in a loop, you'll get better code with a restricted pointer.

Definition at line 124 of file set_unaligned.h.

125{
126 set_unaligned32 (p, std::bit_cast<uint32_t> (val));
127}

◆ setConst()

void CxxUtils::setConst ( )

Set the const flag for this expression.

◆ size()

size_type CxxUtils::size ( ) const

Count the number of 1 bits in the set.

Return the current number of elements in the map.

Return the number of items currently in the map.

Note: If you regard this like a std::bitset, you would expect this to return the number of bits that the set can hold, while if you regard this like a set<bit_t>, then you would expect this to return the number of 1 bits. We follow the latter here.

◆ skipSpaces()

void ClassName< T >::skipSpaces ( const std::string & name,
std::string::size_type & pos )
private

Skip past spaces in a string.

Parameters
nameThe string containing the name.
posPosition in the string to start skipping.

On return, pos will be updated to point just past the last character consumed.

Definition at line 584 of file CxxUtils/Root/ClassName.cxx.

586{
587 while (pos < name.size() && name[pos] == ' ')
588 ++pos;
589}

◆ span() [1/2]

template<class T>
CxxUtils::span ( T * beg,
T * end ) -> span< T >

◆ span() [2/2]

template<class T>
CxxUtils::span ( T * ptr,
std::size_t sz ) -> span< T >

A couple needed deduction guides.

◆ strformat()

std::string CxxUtils::strformat ( const char * fmt,
... )

return a std::string according to a format fmt and varargs

Definition at line 49 of file StrFormat.cxx.

50{
51 char *buf = NULL;
52 int nbytes = -1;
53
54 va_list ap;
55 va_start(ap, fmt); /* Initialize the va_list */
56
57 nbytes = vasprintf(&buf, fmt, ap);
58 va_end(ap); /* Cleanup the va_list */
59
60 if (nbytes < 0) {
61 /*buf is undefined when allocation failed
62 * see: http://linux.die.net/man/3/asprintf
63 */
64 // free(buf);
65 throw std::runtime_error("problem while calling vasprintf");
66 }
67
68 CharLiberator guard(buf);
69
70 // help compiler to apply RVO
71 return std::string(buf);
72}
const char *const fmt

◆ subst()

void ClassName< T >::subst ( const match_t & matches)

Substitute variables into this expression.

Parameters
Thedictionary of variables to substitute.

If this expression contains variables like $T, they are replaced with the corresponding values from matches. If a variable is present in the expression but is not in matches, ExcMissingVariable is thrown.

The substitutions are made in-place.

Definition at line 357 of file CxxUtils/Root/ClassName.cxx.

358{
359 if (m_name[0] == '$') {
360 std::string var = m_name.substr (1, std::string::npos);
361 match_t::const_iterator it = matches.find (var);
362 if (it != matches.end()) {
363 bool const_save = m_const;
364 *this = it->second;
365 m_const |= const_save;
366 }
367 else {
368 throw ExcMissingVariable (var);
369 }
370 }
371
372 for (ClassName& c : m_namespace)
373 c.subst (matches);
374 for (ClassName& c : m_targs)
375 c.subst (matches);
376}

◆ substCopy()

ClassName ClassName< T >::substCopy ( const match_t & matches) const

Return a copy of this expression with variables substituted.

Parameters
Thedictionary of variables to substitute.

If this expression contains variables like $T, they are replaced with the corresponding values from matches. If a variable is present in the expression but is not in matches, ExcMissingVariable is thrown.

The substitutions are made in a copy of the expression, which is returned.

Definition at line 390 of file CxxUtils/Root/ClassName.cxx.

391{
392 ClassName cn (*this);
393 cn.subst (matches);
394 return cn;
395}

◆ swap() [1/3]

void CxxUtils::swap ( ClassName & other)

Swap this expression with another one.

Parameters
otherThe other expression with which to swap.

◆ swap() [2/3]

void CxxUtils::swap ( ConcurrentMap & other)

Swap this container with another.

Parameters
otherThe container with which to swap.

This will also call swap on the Updater object; hence, the Updater object must also support swap. The Hasher and Matcher instances are NOT swapped.

This operation is NOT thread-safe. No other threads may be accessing either container during this operation.

◆ swap() [3/3]

void CxxUtils::swap ( ConcurrentToValMap & other)

Swap this container with another.

Parameters
otherThe container with which to swap.

This will also call swap on the Updater object; hence, the Updater object must also support swap.

This operation is NOT thread-safe. No other threads may be accessing either container during this operation.

◆ targ()

const ClassName & ClassName< T >::targ ( size_t i) const

Return one template argument.

Parameters
iIndex of the argument to return.

Definition at line 285 of file CxxUtils/Root/ClassName.cxx.

286{
287 return m_targs.at (i);
288}

◆ test() [1/2]

bool CxxUtils::test ( bit_t bit) const

Test to see if a bit is set.

Parameters
bitNumber of the bit to test.
Returns
true if the bit is set; false otherwise.

Returns false if bit is beyond the end of the set.

◆ test() [2/2]

template<class E>
std::enable_if_t< is_bitmask_v< E >, bool > CxxUtils::test ( E lhs,
E rhs )
constexpr

Convenience function to test bits in a class enum bitmask.

Parameters
lhsTarget bitmask.
rhsBits to test.

Same as (lhs & rhs) != 0. This function is enabled only for enumerators that have used the ATH_BITMASK macro.

Definition at line 270 of file bitmask.h.

271{
272 typedef std::underlying_type_t<E>underlying;
273 return static_cast<underlying> (lhs & rhs) != 0;
274}

◆ throw_out_of_range() [1/2]

void CxxUtils::throw_out_of_range ( const char * what,
size_t index,
size_t size,
const void * obj )

Throw an out_of_range exception.

Parameters
whatDescription of the error.
indexThe index that was out of range.
sizeThe size of the container.
objPointer to the container (or other relevant object).

Definition at line 43 of file throw_out_of_range.cxx.

45{
46 throw_out_of_range (std::string(what), index, size, obj);
47}
bit_t size() const
Count the number of 1 bits in the set.
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 index.py:1

◆ throw_out_of_range() [2/2]

void CxxUtils::throw_out_of_range ( const std::string & what,
size_t index,
size_t size,
const void * obj )

Throw an out_of_range exception.

Parameters
whatDescription of the error.
indexThe index that was out of range.
sizeThe size of the container.
objPointer to the container (or other relevant object).

Definition at line 27 of file throw_out_of_range.cxx.

29{
30 throw std::out_of_range (std::format
31 ("CxxUtils::throw_out_of_range {} requested index {} >= {} for object at {}",
32 what, index, size, obj));
33};

◆ to()

template<class CONT, class RANGE>
CONT CxxUtils::to ( RANGE && r)

Definition at line 39 of file ranges.h.

40{
41 return CONT (std::ranges::begin (r), std::ranges::end (r));
42}

◆ tokenize() [1/3]

template<typename T = std::string, typename X = std::string_view>
std::vector< T > CxxUtils::tokenize ( std::string_view str,
X delimiters )

Definition at line 37 of file StringUtilsTemplates.h.

37 {
38 std::vector<T> tokens;
39 size_t lastPos = str.find_first_not_of(delimiters, 0);
40 size_t pos = str.find_first_of(delimiters, lastPos);
41
42 while (lastPos != std::string_view::npos) {
43 std::string_view token = str.substr(lastPos, pos - lastPos);
44
45 if constexpr (std::is_same_v<T, std::string_view>) {
46 tokens.push_back(token);
47 } else if constexpr (std::is_same_v<T, std::string>) {
48 tokens.emplace_back(token);
49 } else {
50 // This handles the int/double cases via your existing convertToNumber
51 T value;
52 convertToNumber(token, value);
53 tokens.push_back(value);
54 }
55
56 lastPos = str.find_first_not_of(delimiters, pos);
57 pos = str.find_first_of(delimiters, lastPos);
58 }
59 return tokens;
60 }
unsigned long long T

◆ tokenize() [2/3]

std::vector< std::string > CxxUtils::tokenize ( std::string_view the_str,
char delimiter )

Definition at line 18 of file Control/CxxUtils/Root/StringUtils.cxx.

19 {
21 }
static const std::string delimiter("/")
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.

◆ tokenize() [3/3]

std::vector< std::string > CxxUtils::tokenize ( std::string_view the_str,
std::string_view delimiters )

Splits the string into smaller substrings.

Definition at line 12 of file Control/CxxUtils/Root/StringUtils.cxx.

13 {
14
16 }

◆ tokenizeDouble()

std::vector< double > CxxUtils::tokenizeDouble ( std::string_view the_str,
std::string_view delimiter )

Definition at line 23 of file Control/CxxUtils/Root/StringUtils.cxx.

23 {
24 return tokenize<double, std::string_view>(str, delimiters);
25 }

◆ tokenizeInt()

std::vector< int > CxxUtils::tokenizeInt ( std::string_view str,
std::string_view delimiter )

Definition at line 36 of file Control/CxxUtils/Root/StringUtils.cxx.

36 {
37 return tokenize<int, std::string_view>(str, delimiters);
38 }

◆ trim()

size_t CxxUtils::trim ( const std::vector< key_query_type > & keys,
bool trimall = false )

Remove unused entries from the front of the list.

Parameters
keysList of keys that may still be in use. (Must be sorted.)
trimallIf true, then allow removing all elements in the container. Otherwise, stop when there's one left.

We examine the objects in the container, starting with the earliest one. If none of the keys in keys match the range for this object, then it is removed from the container. We stop when we either find an object with a range matching a key in keys or (if trimall is false) when there is only one object left.

The list keys MUST be sorted.

Removed objects are queued for deletion once all slots have been marked as quiescent.

Returns the number of objects that were removed.

◆ trimWhiteSpaces()

std::string_view CxxUtils::trimWhiteSpaces ( std::string_view str)
noexcept

Removes all trailing and starting whitespaces from a string.

Definition at line 27 of file Control/CxxUtils/Root/StringUtils.cxx.

27 {
28 auto is_not_space = [](unsigned char c) { return !std::isspace(c); };
29
30 auto start = std::find_if(str.begin(), str.end(), is_not_space);
31 auto end = std::find_if(str.rbegin(), str.rend(), is_not_space).base();
32
33 return (start < end) ? std::string_view(start, end) : std::string_view{};
34 }
STL namespace.

◆ ubsan_suppress()

void CxxUtils::ubsan_suppress ( void(* func )())

Helper for suppressing ubsan warnings.

Parameters
funcFunction to call (may be a lambda).

If ubsan is running, temporarily redirect stderr to /dev/null. Then call func.

For example, we sometimes get a bogus ubsan warning from cling initialization. This can be suppressed by adding something like:

CxxUtils::ubsan_suppress ([]() { TInterpreter::Instance(); });
void ubsan_suppress(void(*func)())
Helper for suppressing ubsan warnings.

Definition at line 69 of file ubsan_suppress.cxx.

70{
71 if (dlsym (RTLD_DEFAULT, "__ubsan_handle_add_overflow") != NULL)
72 {
73 RedirStderr redir;
74 func();
75 }
76 else {
77 func();
78 }
79}

◆ updatePointers()

void CxxUtils::updatePointers ( value_type * new_begin,
value_type * new_end )
private

Consistently update both the begin and last pointers.

Parameters
beginNew begin pointer.
endNew end pointer.

◆ updater()

Updater_t & CxxUtils::updater ( )

Access the Updater instance.

◆ updateRanges()

void CxxUtils::updateRanges ( std::function< void(RANGE &)> rangeUpdater,
const typename Updater_t::Context_t & ctx = Updater_t::defaultContext() )

Update all range objects.

Parameters
rangeUpdaterFunctional to call on each range object.
ctxExecution context.

This will iterate through the list of entries and call rangeUpdater on the RANGE part of each. Be careful: rangeUpdater must not change any part of the range which might affect the sorting of entries.

◆ vall()

template<typename VEC>
ATH_ALWAYS_INLINE bool CxxUtils::vall ( const VEC & mask)

Definition at line 402 of file vec.h.

402 {
403 static_assert(std::is_integral<vec_type_t<VEC>>::value,
404 "vec elements must be of integral type. Aka vec must be "
405 "compatible with a mask");
406 VEC alltrue;
407#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
408 // fallback compares to 0 when false
409 // and 1 when is true
410 vbroadcast(alltrue, vec_type_t<VEC>{1});
411 return std::memcmp(mask.m_arr, alltrue.m_arr, sizeof(VEC)) == 0;
412#else
413 // For the gnu vector extensions
414 // Vectors are compared element-wise producing 0 when comparison is false
415 // and -1 (constant of the appropriate type where all bits are set) otherwise.
416 vbroadcast(alltrue, vec_type_t<VEC>{-1});
417 return std::memcmp(&mask, &alltrue, sizeof(VEC)) == 0;
418#endif
419}
typename vecDetail::vec_type< VEC >::type vec_type_t
Define a nice alias for the element type of a vectorized type.
Definition vec.h:213
ATH_ALWAYS_INLINE void vbroadcast(VEC &v, T x)
Copy a scalar to each element of a vectorized type.
Definition vec.h:251

◆ vany()

template<typename VEC>
ATH_ALWAYS_INLINE bool CxxUtils::vany ( const VEC & mask)

Definition at line 362 of file vec.h.

362 {
363 static_assert(std::is_integral<vec_type_t<VEC>>::value,
364 "vec elements must be of integral type. Aka vec must be "
365 "compatible with a mask");
366 VEC zero;
368#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
369 return std::memcmp(mask.m_arr, zero.m_arr, sizeof(VEC)) != 0;
370#else
371 return std::memcmp(&mask, &zero, sizeof(VEC)) != 0;
372#endif
373}
void zero(TH2 *h)
zero the contents of a 2d histogram

◆ vbroadcast()

template<typename VEC, typename T>
ATH_ALWAYS_INLINE void CxxUtils::vbroadcast ( VEC & v,
T x )

Copy a scalar to each element of a vectorized type.

Definition at line 251 of file vec.h.

252{
253#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
254 constexpr size_t N = CxxUtils::vec_size<VEC>();
255 for (size_t i = 0; i < N; ++i) {
256 v[i] = x;
257 }
258#else
259 // using - to avoid sign conversions.
260 v = x - VEC{ 0 };
261#endif
262}
ATH_ALWAYS_INLINE constexpr size_t vec_size()
Return the number of elements in a vectorized type.
Definition vec.h:227

◆ vconvert()

template<typename VEC1, typename VEC2>
ATH_ALWAYS_INLINE void CxxUtils::vconvert ( VEC1 & dst,
const VEC2 & src )

performs dst is the result of a static cast of each element of src

Definition at line 428 of file vec.h.

429{
430 static_assert((vec_size<VEC1>() == vec_size<VEC2>()),
431 "vconvert dst and src have different number of elements");
432
433#if !HAVE_CONVERT_VECTOR || WANT_VECTOR_FALLBACK
434 typedef vec_type_t<VEC1> ELT;
435 constexpr size_t N = vec_size<VEC1>();
436 for (size_t i = 0; i < N; ++i) {
437 dst[i] = static_cast<ELT>(src[i]);
438 }
439#else
440 dst = __builtin_convertvector(src, VEC1);
441#endif
442}

◆ vec_size() [1/2]

template<class VEC>
ATH_ALWAYS_INLINE constexpr size_t CxxUtils::vec_size ( )
constexpr

Return the number of elements in a vectorized type.

Definition at line 227 of file vec.h.

228{
229 typedef vec_type_t<VEC> ELT;
230 return sizeof(VEC) / sizeof(ELT);
231}

◆ vec_size() [2/2]

template<class VEC>
ATH_ALWAYS_INLINE constexpr size_t CxxUtils::vec_size ( const VEC & )
constexpr

Return the number of elements in a vectorized type.

Definition at line 239 of file vec.h.

240{
241 typedef vec_type_t<VEC> ELT;
242 return sizeof(VEC) / sizeof(ELT);
243}

◆ vload()

template<typename VEC>
ATH_ALWAYS_INLINE void CxxUtils::vload ( VEC & dst,
vec_type_t< VEC > const * src )

Definition at line 272 of file vec.h.

273{
274
275#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
276 std::memcpy(dst.m_arr, src, sizeof(VEC));
277#else
278 std::memcpy(&dst, src, sizeof(VEC));
279#endif
280}

◆ vmax()

template<typename VEC>
ATH_ALWAYS_INLINE void CxxUtils::vmax ( VEC & dst,
const VEC & a,
const VEC & b )

Definition at line 343 of file vec.h.

344{
345#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
346 constexpr size_t N = vec_size<VEC>();
347 for (size_t i = 0; i < N; ++i) {
348 dst[i] = a[i] > b[i] ? a[i] : b[i];
349 }
350#else
351 dst = a > b ? a : b;
352#endif
353}

◆ vmin()

template<typename VEC>
ATH_ALWAYS_INLINE void CxxUtils::vmin ( VEC & dst,
const VEC & a,
const VEC & b )

Definition at line 324 of file vec.h.

325{
326#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
327 constexpr size_t N = vec_size<VEC>();
328 for (size_t i = 0; i < N; ++i) {
329 dst[i] = a[i] < b[i] ? a[i] : b[i];
330 }
331#else
332 dst = a < b ? a : b;
333#endif
334}

◆ vnone()

template<typename VEC>
ATH_ALWAYS_INLINE bool CxxUtils::vnone ( const VEC & mask)

Definition at line 382 of file vec.h.

382 {
383 static_assert(std::is_integral<vec_type_t<VEC>>::value,
384 "vec elements must be of integral type. Aka vec must be "
385 "compatible with a mask");
386 VEC zero;
388#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
389 return std::memcmp(mask.m_arr, zero.m_arr, sizeof(VEC)) == 0;
390#else
391 return std::memcmp(&mask, &zero, sizeof(VEC)) == 0;
392#endif
393}

◆ vpermute()

template<size_t... Indices, typename VEC, typename VEC1>
ATH_ALWAYS_INLINE void CxxUtils::vpermute ( VEC1 & dst,
const VEC & src )

vpermute function.

move any element of a vector src into any or multiple position inside dst.

Definition at line 451 of file vec.h.

452{
453
454 static_assert((sizeof...(Indices) == vec_size<VEC1>()),
455 "vpermute number of indices different than return vector size");
456 static_assert(std::is_same<vec_type_t<VEC>, vec_type_t<VEC1>>::value,
457 "vpermute type of input and output vector elements differ");
459 Indices >= 0 && Indices < vec_size<VEC>())...>::value,
460 "vpermute value of a mask index is outside the allowed range");
461
462#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
463 dst = VEC1{ src[Indices]... };
464#else
465 dst = __builtin_shufflevector(src, src, Indices...);
466#endif
467}
std::is_same< bool_pack< bs..., true >, bool_pack< true, bs... > > all_true
Definition vec.h:198

◆ vpermute2()

template<size_t... Indices, typename VEC, typename VEC1>
ATH_ALWAYS_INLINE void CxxUtils::vpermute2 ( VEC1 & dst,
const VEC & src1,
const VEC & src2 )

vpermute2 function.

move any element of the vectors src1, src2 into any or multiple position inside dst.

Definition at line 476 of file vec.h.

477{
478 static_assert(
479 (sizeof...(Indices) == vec_size<VEC1>()),
480 "vpermute2 number of indices different than return vector size");
481 static_assert(std::is_same<vec_type_t<VEC>, vec_type_t<VEC1>>::value,
482 "vpermute2 type of input and output vector elements differ");
483 constexpr size_t N = vec_size<VEC>();
485 Indices >= 0 && Indices < 2 * N)...>::value,
486 "vpermute2 value of a mask index is outside the allowed range");
487
488#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
489 VEC1 tmp;
490 size_t pos{0};
491 for (auto index: { Indices... }) {
492 if (index < N) {
493 tmp[pos] = src1[index];
494 } else {
495 tmp[pos] = src2[index - N];
496 }
497 ++pos;
498 }
499 dst = tmp;
500#else
501 dst = __builtin_shufflevector(src1, src2, Indices...);
502#endif
503}
str index
Definition DeMoScan.py:362

◆ vselect()

template<typename VEC>
ATH_ALWAYS_INLINE void CxxUtils::vselect ( VEC & dst,
const VEC & a,
const VEC & b,
const vec_mask_type_t< VEC > & mask )

Definition at line 306 of file vec.h.

306 {
307#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
308 constexpr size_t N = vec_size<VEC>();
309 for (size_t i = 0; i < N; ++i) {
310 dst[i] = mask[i] ? a[i] : b[i];
311 }
312#else
313 dst = mask ? a : b;
314#endif
315}

◆ vstore()

template<typename VEC>
ATH_ALWAYS_INLINE void CxxUtils::vstore ( vec_type_t< VEC > * dst,
const VEC & src )

Definition at line 290 of file vec.h.

291{
292#if !HAVE_VECTOR_SIZE_ATTRIBUTE || WANT_VECTOR_FALLBACK
293 std::memcpy(dst, src.m_arr, sizeof(VEC));
294#else
295 std::memcpy(dst, &src, sizeof(VEC));
296#endif
297}

◆ wrapToPi()

template<typename T>
T CxxUtils::wrapToPi ( T phi)
inline

Wrap angle in radians to [-pi, pi].

Odd positive (negative) multiples of pi map to (-)pi.

Definition at line 24 of file phihelper.h.

25 {
26 static_assert(std::is_floating_point<T>::value);
27
28 constexpr auto PI = static_cast<T>(M_PI);
29 // For large values this is faster:
30 if (phi < -100 || phi > 100) {
31 return std::remainder(phi, 2 * PI);
32 }
33 while (phi > PI) phi -= 2 * PI;
34 while (phi < -PI) phi += 2 * PI;
35 return phi;
36 }
const float PI

◆ xmalloc()

void * CxxUtils::xmalloc ( size_t size)

Trapping version of malloc.

Parameters
sizeNumber of bytes to allocate.

Calls malloc. Throws a std::bad_alloc exception on failure.

If you're writing new code, you probably don't want to use this! Use make_unique/new or STL containers instead. This is intended for compatiblilty with existing code requiring malloc/free.

Definition at line 31 of file xmalloc.cxx.

32{
33 void* p = malloc (size);
34 if (!p) throw std::bad_alloc();
35 return p;
36}

◆ ~ConcurrentBitset()

CxxUtils::ConcurrentBitset::~ConcurrentBitset ( )

Destructor.

Definition at line 99 of file ConcurrentBitset.cxx.

100{
101 delete m_impl;
102 emptyGarbage();
103}
void emptyGarbage()
Clean up old versions of the set.

◆ ~ConcurrentMap()

CxxUtils::~ConcurrentMap ( )
default

Destructor.

◆ ~ConcurrentRangeMap()

CxxUtils::~ConcurrentRangeMap ( )

Destructor.

Clean up any remaining payload objects.

◆ ~ConcurrentToValMap()

CxxUtils::~ConcurrentToValMap ( )

Destructor.

Variable Documentation

◆ base64_chars

const std::string CxxUtils::base64_chars
static
Initial value:
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/"

Definition at line 45 of file base64.cxx.

◆ defaultCRCTable

const CRCTable CxxUtils::defaultCRCTable(0xad93d23594c935a9) ( 0xad93d23594c935a9 )

◆ dynamic_extent

size_t CxxUtils::dynamic_extent = static_cast<size_t>(-1)
inlineconstexpr

Used to specify a subrange of indefinite size in subspan().

Definition at line 29 of file span.h.

◆ initer

extrace_init CxxUtils::initer
static

Definition at line 90 of file exctrace_collector.cxx.

◆ m_begin

std::atomic<value_type*> CxxUtils::m_begin
private

Pointers to the first and last elements of the container. m_last is not the usual end pointer; it points at the last element in the container. If the container is empty, then m_last will be null. If these are to both be updated together, it should be done in this order. First, m_begin should be set to null. This marks that there's an update in progress. Then m_last should be set, followed by m_begin. To read both pointers, we first fetch m_last. Then fetch m_begin. Then check that both m_begin is non-null and the previous value we fetched for last matches what's now in m_last. If either condition fails, then re-fetch both pointers.

Definition at line 654 of file ConcurrentRangeMap.h.

◆ m_compare

COMPARE CxxUtils::m_compare
private

Comparison object.

Definition at line 625 of file ConcurrentRangeMap.h.

◆ m_const

bool CxxUtils::m_const
private

Is this expression const?

Definition at line 477 of file CxxUtils/CxxUtils/ClassName.h.

◆ m_garbage

std::vector<Impl*> CxxUtils::m_garbage
private

Old implementation objects, pending deletion.

Definition at line 1059 of file ConcurrentBitset.h.

◆ m_impl

Impl_t CxxUtils::m_impl
private

The current implementation object.

Current version of the implementation class.

The underlying hash table.

Definition at line 1056 of file ConcurrentBitset.h.

◆ m_last

std::atomic<value_type*> CxxUtils::m_last
private

Definition at line 655 of file ConcurrentRangeMap.h.

◆ m_maxSize

size_t CxxUtils::m_maxSize
private

Definition at line 659 of file ConcurrentRangeMap.h.

◆ m_mutex

mutex_t CxxUtils::m_mutex
private

Mutex protecting the container.

Definition at line 1064 of file ConcurrentBitset.h.

◆ m_name

std::string CxxUtils::m_name
private

The primary name part of this expression.

Definition at line 486 of file CxxUtils/CxxUtils/ClassName.h.

◆ m_namespace

std::vector<ClassName> CxxUtils::m_namespace
private

The containing namespace. This vector is always either 0 or 1 elements long; this is a way of getting something sort of like a pointer but with completely automatic management.

Definition at line 483 of file CxxUtils/CxxUtils/ClassName.h.

◆ m_nInserts

size_t CxxUtils::m_nInserts
private

Some basic statistics.

Definition at line 658 of file ConcurrentRangeMap.h.

◆ m_payloadDeleter

std::shared_ptr<IPayloadDeleter> CxxUtils::m_payloadDeleter
private

Payload deleter object. Important: do not discard an object while it's still reachable from the m_begin / m_last range — update the pointers first. Otherwise, the object may be deleted while another thread is still referencing it: thread 1: Discard object. Sets grace mask for both slots. thread 2: Call quiescent(). Clears grace mask for 2. Retrieve the discarded object. thread 1: Adjust pointers. Call quiescent. The discarded object may be deleted at this point while thread 2 is still reading it.

Definition at line 638 of file ConcurrentRangeMap.h.

◆ m_targs

std::vector<ClassName> CxxUtils::m_targs
private

The template arguments for this name.

Definition at line 489 of file CxxUtils/CxxUtils/ClassName.h.

◆ m_updater

Updater_t CxxUtils::m_updater
private

Updater object. This maintains ownership of the current implementation class and the older versions.

Definition at line 622 of file ConcurrentRangeMap.h.

◆ NMANTISSA

const unsigned int CxxUtils::NMANTISSA = 23
static

Total number of total mantissa bits.

Definition at line 16 of file FloatCompressor.cxx.

◆ valid_span_type_v

template<class T, class U>
bool CxxUtils::valid_span_type_v = std::is_convertible_v<U(*)[], T(*)[]>
inlineconstexpr

Is U* a valid type to use to initialize a span<T>?

No more than const-conversion. Same logic as used in libstdc++.

Definition at line 36 of file span.h.