LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
util::LazyVector< T, A > Class Template Reference

A contiguous data container expanded on write. More...

#include "LazyVector.h"

Public Types

STL vector types
using allocator_type = typename Data_t::allocator_type
 
using value_type = typename Data_t::value_type
 
using size_type = typename Data_t::size_type
 
using difference_type = typename Data_t::difference_type
 
using reference = typename Data_t::reference
 
using const_reference = typename Data_t::const_reference
 
using pointer = typename Data_t::pointer
 
using const_pointer = typename Data_t::const_pointer
 

Public Member Functions

 LazyVector ()=default
 
 LazyVector (allocator_type const &a)
 Constructor: like default, but using the specified allocator. More...
 
 LazyVector (size_type n)
 Constructor: a lazy vector with a specified maximum size. More...
 
 LazyVector (size_type n, value_type const &defValue)
 Constructor: a lazy vector with a specified maximum size. More...
 
reference at (size_type pos)
 Returns a reference to the specified element, throws an exception if not present. More...
 
Container information

— END Constructors -------------------------------------------——

size_type size () const noexcept
 Returns the size of the vector. More...
 
bool empty () const noexcept
 Returns whether the vector is empty. More...
 
size_type data_size () const noexcept
 Returns the size of data actually stored. More...
 
bool has_index (size_type pos) const noexcept
 Returns whether the specified position is within the vector. More...
 
bool data_empty () const noexcept
 Returns whether no data is actually stored. More...
 
value_type const & data_defvalue () const
 
size_type data_begin_index () const
 
size_type data_end_index () const
 
bool data_has_index (size_type pos) const
 Returns the internal storage index for the specified position. More...
 
const_pointer data_address (size_type pos) const
 Returns a constant pointer to the specified element. More...
 
Access to data elements

There are important differences between the access methods of LazyVector and the ones of STL vector.

The constant versions of the access methods differ from the corresponding STL vector ones in that they return a copy of the element rather than a reference to it. This happens because the element could not have current storage, and we can't create it because the method is constant.

Also, the non-constant versions of the access methods always ensure storage for the accessed element. If such behaviour needs to be avoided (e.g. for performance reasons), use the methods explicitly named constant: const_at() and const_get(), explicitly constant versions of at() and operator[] respectively. To preserve the naming scheme, a method get() is also provided which is equivalent to the non-constant version of operator[].

value_type at (size_type pos) const
 Returns a reference to the specified element, throws an exception if not present. More...
 
value_type const_at (size_type pos) const
 Returns a reference to the specified element, throws an exception if not present. More...
 
value_type operator[] (size_type pos) const
 Returns a copy of the specified element. More...
 
value_type const_get (size_type pos) const
 Returns a copy of the specified element. More...
 
reference operator[] (size_type pos)
 Returns a reference to the specified element. More...
 
reference get (size_type pos)
 Returns a reference to the specified element. More...
 
Container operations
void resize (size_type newSize)
 Changes the nominal size of the container. More...
 
void reserve (size_type n)
 Allocates enough memory in storage to store n elements. More...
 
void clear ()
 Removes all stored data and sets the nominal size to 0. More...
 
void shrink_to_fit ()
 Reduces memory usage to the amount needed by the elements with storage. More...
 
void data_prepare (size_type startIndex, size_type endIndex)
 Prepares the vector to store elements in the specified range. More...
 
void data_prepare (size_type n)
 Prepares the vector to store n elements from 0. More...
 
void data_init (size_type startIndex, size_type endIndex)
 Allocates the specified range and stores default values for it. More...
 
void data_init (size_type n)
 Allocates and initializes n elements starting from index 0. More...
 

Private Types

using Data_t = std::vector< T, A >
 Actual data storage type. More...
 

Private Member Functions

size_type index_of (size_type pos) const
 Returns the internal storage index for the specified position. More...
 
void expand (size_type pos)
 Expands the storage to include the specified position. More...
 
void init (size_type pos, size_type n=1U)
 Makes the first data allocation. More...
 
void expand_front (size_type pos)
 Expands the storage to include the specified position behind it. More...
 
void expand_back (size_type pos)
 Expands the storage to include the specified position ahead of it. More...
 
void fix_size ()
 Makes sure the nominal size is large enough to include all stored data. More...
 
void data_clear ()
 Erases all stored data from the container; nominal size is not changed. More...
 
void check_range (size_type pos) const
 Throws std::out_of_range if pos is not contained in the vector. More...
 
Data_tstorage ()
 Returns the data storage. More...
 
Data_t const & storage () const
 Returns the data storage. More...
 

Static Private Member Functions

static value_type const & defaultValueType ()
 Returns the class default value (used when user does not specify any). More...
 

Private Attributes

Data_t fData
 Actual data storage. More...
 
size_type fNominalSize = 0U
 Alleged data size. More...
 
size_type fFirstIndex = fData.max_size()
 First element currently stored. More...
 
value_type fDefValue = defaultValueType()
 Default value. More...
 

Static Private Attributes

static value_type const fDefaultDefaultValue {}
 Default-initialised value of type value_type used as default fallback. More...
 

Detailed Description

template<typename T, typename A = typename std::vector<T>::allocator_type>
class util::LazyVector< T, A >

A contiguous data container expanded on write.

Template Parameters
Ttype of contained data
Aallocator for the data (default: STL vector's default allocator)

This container class represents a number of data elements contiguously allocated in memory. It mimics the behaviour and interface of STL vector, but the actual data allocation is lazy, that is it happens only when writing to an element is requested. The internal allocation is always contiguous, including as little data as it can accommodate elements from the first to the last index written at any point.

The interface is also a partial replica of STL vector, with the addition of members specific to this class, whose names start with data_. Among the relevant features missing from this object there is iterators.

For some internal resizing operations, a default value is used to construct the new values. This default value can be specified in some constructors, Otherwise, a value equivalent to 0 (i.e. value_type(0)) is used for arithmetic value types, and the default-constructed value is used for all other types.

Example of usage:

// start with a lazy vector of nominal size 6 elements and no actual data:
// add a value `-4.0` at the previous-to-last element `4`:
// the vector will look like: { ... [4] -4.0 ... }
// (nominal size: 6, 1 stored datum)
v[4] = -4.0;
// add a value `-2.0` at the third element:
// the vector will look like: { ... [2] -2.0, [3] def, [4] -4.0 ... }
// (nominal size still 6, 3 stored data, the default value "def" is 0.0)
v[2] = -2.0;
// we want to set element #6 to -6.0: we need to expand the vector first.
v.resize(7U); // barely enough for element #6
// the vector will look like: { ... [2] -2.0, [3] def, [4] -4.0 [5] def [6] -6.0 }
// (nominal size 7, 5 stored data, the default value "def" is 0.0)
v[6] = -6.0;
Note
Special care needs to be used when accessing a non-const LazyVector, since every access will create storage for the specified element (like in STL map operator[]). For this reason, the special methods const_at(size_type) and const_get(size_type) are provided, which never create storage.

Definition at line 77 of file LazyVector.h.

Member Typedef Documentation

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::allocator_type = typename Data_t::allocator_type

Definition at line 86 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::const_pointer = typename Data_t::const_pointer

Definition at line 93 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::const_reference = typename Data_t::const_reference

Definition at line 91 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::Data_t = std::vector<T, A>
private

Actual data storage type.

Definition at line 79 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::difference_type = typename Data_t::difference_type

Definition at line 89 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::pointer = typename Data_t::pointer

Definition at line 92 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::reference = typename Data_t::reference

Definition at line 90 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::size_type = typename Data_t::size_type

Definition at line 88 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
using util::LazyVector< T, A >::value_type = typename Data_t::value_type

Definition at line 87 of file LazyVector.h.

Constructor & Destructor Documentation

template<typename T, typename A = typename std::vector<T>::allocator_type>
util::LazyVector< T, A >::LazyVector ( )
default

— BEGIN Constructors ----------------------------------------------— Default constructor: an empty vector.

template<typename T , typename A >
util::LazyVector< T, A >::LazyVector ( allocator_type const &  a)

Constructor: like default, but using the specified allocator.

Definition at line 469 of file LazyVector.h.

469  : fData(a)
470 {}
Data_t fData
Actual data storage.
Definition: LazyVector.h:415
template<typename T , typename A >
util::LazyVector< T, A >::LazyVector ( size_type  n)

Constructor: a lazy vector with a specified maximum size.

Parameters
nthe initial maximum size of the vector
Note
This constructor is essentially different from the one of STL vector with the same signature.

The vector is set to a nominal size of n, with no stored data.

The default value of vector elements is the default-constructed T value, as returned by defaultValueType().

Definition at line 474 of file LazyVector.h.

475 {}
static value_type const & defaultValueType()
Returns the class default value (used when user does not specify any).
Definition: LazyVector.h:455
LazyVector()=default
Char_t n[5]
template<typename T , typename A >
util::LazyVector< T, A >::LazyVector ( size_type  n,
value_type const &  defValue 
)

Constructor: a lazy vector with a specified maximum size.

Parameters
nthe initial maximum size of the vector
defValuevalue to be used when resizing
Note
This constructor is essentially different from the one of STL vector with the same signature.

The vector is set to a nominal size of n, with no stored data. A default value defValue is registered, so that it can be used when actual storage is needed for elements whose value is not explicitly specified by the user:

v[0] = 0;
v[2] = -2;
std::cout << "Default element [1]: " << v.at(1) << std::endl;

will print something like: "Default element [1]: 5".

Definition at line 479 of file LazyVector.h.

480  : fNominalSize(n), fDefValue(defValue)
481 {}
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:417
Char_t n[5]
value_type fDefValue
Default value.
Definition: LazyVector.h:419

Member Function Documentation

template<typename T , typename A >
util::LazyVector< T, A >::value_type util::LazyVector< T, A >::at ( size_type  pos) const

Returns a reference to the specified element, throws an exception if not present.

Parameters
posposition to be accessed
Returns
a copy of the value of requested element
Exceptions
std::out_of_rangeif the container is too small to contain pos

Returns a copy of the specified element. If the requested element is beyond the size of the container, an exception std::out_of_range is thrown.

Note
This method differs from the corresponding STL vector in that it returns a copy of the element rather than a reference to it. This happens because the element could not have current storage, and we can't create it because the method is constant.

Definition at line 500 of file LazyVector.h.

References util::LazyVector< T, A >::check_range(), util::LazyVector< T, A >::data_defvalue(), util::LazyVector< T, A >::data_has_index(), util::LazyVector< T, A >::index_of(), and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< TF1 >::const_at(), and util::LazyVector< TF1 >::data_has_index().

501 {
502  /*
503  * Behaviour summary:
504  * * if `pos` is out of vector range, throw an exception
505  * * if element at `pos` has no storage, return a copy of the default value
506  * * otherwise, return a copy of the element at `pos`
507  */
508  check_range(pos); // verify that `pos` is valid, throw otherwise
509  return data_has_index(pos) ? storage()[index_of(pos)] : data_defvalue();
510 } // util::LazyVector<T,A>::at() const
void check_range(size_type pos) const
Throws std::out_of_range if pos is not contained in the vector.
Definition: LazyVector.h:680
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:431
value_type const & data_defvalue() const
Definition: LazyVector.h:165
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
bool data_has_index(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:176
template<typename T , typename A >
util::LazyVector< T, A >::reference util::LazyVector< T, A >::at ( size_type  pos)

Returns a reference to the specified element, throws an exception if not present.

Parameters
posposition to be accessed
Returns
the reference to the requested element
Exceptions
std::out_of_rangeif the container is too small to contain pos
See also
data_defvalue()

Returns a reference to the specified element. If the element is not stored yet, it's created with the default value, and returned. If the requested element is beyond the size of the container, an exception std::out_of_range is thrown.

Definition at line 485 of file LazyVector.h.

References util::LazyVector< T, A >::check_range(), util::LazyVector< T, A >::expand(), util::LazyVector< T, A >::index_of(), and util::LazyVector< T, A >::storage().

486 {
487  /*
488  * Behaviour summary:
489  * * if `pos` is out of vector range, throw an exception
490  * * if element at `pos` has no storage, create storage for it
491  * * return a reference to the element at `pos`
492  */
493  check_range(pos); // verify that `pos` is valid, throw otherwise
494  expand(pos);
495  return storage()[index_of(pos)]; // we already know it's valid
496 }
void check_range(size_type pos) const
Throws std::out_of_range if pos is not contained in the vector.
Definition: LazyVector.h:680
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:431
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
void expand(size_type pos)
Expands the storage to include the specified position.
Definition: LazyVector.h:623
template<typename T , typename A >
void util::LazyVector< T, A >::check_range ( size_type  pos) const
private

Throws std::out_of_range if pos is not contained in the vector.

Definition at line 680 of file LazyVector.h.

References util::LazyVector< T, A >::has_index(), util::LazyVector< T, A >::size(), and util::to_string().

Referenced by util::LazyVector< T, A >::at(), and util::LazyVector< TF1 >::index_of().

681 {
682  if (has_index(pos)) return;
683  throw std::out_of_range("Index " + std::to_string(pos) +
684  " is out of LazyVector range (size: " + std::to_string(size()) + ")");
685 } // util::LazyVector<T,A>::check_range()
bool has_index(size_type pos) const noexcept
Returns whether the specified position is within the vector.
Definition: LazyVector.h:158
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:149
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
template<typename T , typename A >
void util::LazyVector< T, A >::clear ( )

Removes all stored data and sets the nominal size to 0.

Definition at line 587 of file LazyVector.h.

References util::LazyVector< T, A >::data_clear(), and util::LazyVector< T, A >::fNominalSize.

Referenced by phot::PhotonLibrary::CreateEmptyLibrary(), phot::PhotonLibrary::LoadLibraryFromFile(), and util::LazyVector< TF1 >::reserve().

588 {
589  data_clear();
590  fNominalSize = 0U;
591 } // util::LazyVector<T,A>::clear()
void data_clear()
Erases all stored data from the container; nominal size is not changed.
Definition: LazyVector.h:672
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:417
template<typename T, typename A = typename std::vector<T>::allocator_type>
value_type util::LazyVector< T, A >::const_at ( size_type  pos) const
inline

Returns a reference to the specified element, throws an exception if not present.

Parameters
posposition to be accessed
Returns
a copy of the value of requested element
Exceptions
std::out_of_rangeif the container is too small to contain pos

Returns a copy of the specified element. If the requested element is beyond the size of the container, an exception std::out_of_range is thrown.

Note
This method differs from the corresponding STL vector in that it returns a copy of the element rather than a reference to it. This happens because the element could not have current storage, and we can't create it because the method is constant.

Definition at line 237 of file LazyVector.h.

237 { return at(pos); }
value_type at(size_type pos) const
Returns a reference to the specified element, throws an exception if not present. ...
Definition: LazyVector.h:500
template<typename T, typename A = typename std::vector<T>::allocator_type>
value_type util::LazyVector< T, A >::const_get ( size_type  pos) const
inline

Returns a copy of the specified element.

Parameters
posposition to be accessed
Returns
a copy of the specified element
See also
at(size_type) const

Returns a copy of the specified element. If the requested element is beyond the size of the container, the result is undefined.

Note
See at(value_type) const for an explanation of why a value is returned rather than a reference.

Definition at line 270 of file LazyVector.h.

270 { return this->operator[](pos); }
value_type operator[](size_type pos) const
Returns a copy of the specified element.
Definition: LazyVector.h:532
template<typename T , typename A >
util::LazyVector< T, A >::const_pointer util::LazyVector< T, A >::data_address ( size_type  pos) const

Returns a constant pointer to the specified element.

Parameters
posposition of the element
Returns
pointer to storage for specified element, nullptr if not stored

If pos represents an element that has storage, the pointer to that element is returned. If instead pos represents a valid element with no storage (default value), nullptr is returned. If pos does not represent a valid element, the result is undefined.

Definition at line 549 of file LazyVector.h.

References util::LazyVector< T, A >::data_begin_index(), util::LazyVector< T, A >::data_size(), util::LazyVector< T, A >::index_of(), and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< TF1 >::data_has_index(), phot::PhotonLibrary::GetCounts(), phot::PhotonLibrary::GetReflCounts(), phot::PhotonLibrary::GetReflT0s(), phot::PhotonLibrary::GetTimingPars(), phot::PhotonLibrary::GetTimingTF1s(), and phot::PhotonLibrary::uncheckedAccessTimingTF1().

551 {
552  /*
553  * Behaviour summary:
554  * * if `pos` is out of vector range, behaviour is undefined
555  * * if element at `pos` has no storage, return nullptr
556  * * otherwise, return the pointer to the specified element
557  */
558  // this implementation will return nullptr if `pos` is out of range;
559  // this is not a requirement, and may change at any time.
560  if (pos < data_begin_index()) return nullptr;
561  auto const index = index_of(pos);
562  return (index < data_size()) ? storage().data() + index : nullptr;
563 } // util::LazyVector<T,A>::data_address()
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:431
size_type data_begin_index() const
Definition: LazyVector.h:169
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type data_size() const noexcept
Returns the size of data actually stored.
Definition: LazyVector.h:155
template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::data_begin_index ( ) const
inline
template<typename T , typename A >
void util::LazyVector< T, A >::data_clear ( )
private

Erases all stored data from the container; nominal size is not changed.

Definition at line 672 of file LazyVector.h.

References util::LazyVector< T, A >::fFirstIndex, and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< T, A >::clear(), util::LazyVector< T, A >::data_init(), util::LazyVector< T, A >::data_prepare(), util::LazyVector< TF1 >::index_of(), and util::LazyVector< T, A >::resize().

673 {
674  storage().clear();
675  fFirstIndex = storage().max_size();
676 } // util::LazyVector<T,A>::data_clear()
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:418
template<typename T, typename A = typename std::vector<T>::allocator_type>
value_type const& util::LazyVector< T, A >::data_defvalue ( ) const
inline
template<typename T, typename A = typename std::vector<T>::allocator_type>
bool util::LazyVector< T, A >::data_empty ( ) const
inlinenoexcept

Returns whether no data is actually stored.

Definition at line 161 of file LazyVector.h.

Referenced by util::LazyVector< T, A >::expand(), and util::LazyVector< T, A >::init().

161 { return fData.empty(); }
Data_t fData
Actual data storage.
Definition: LazyVector.h:415
template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::data_end_index ( ) const
inline

Index after the last data element in the storage (undefined if data_empty()).

Definition at line 173 of file LazyVector.h.

Referenced by util::LazyVector< TF1 >::data_has_index(), util::LazyVector< T, A >::expand(), util::LazyVector< T, A >::expand_back(), util::LazyVector< T, A >::fix_size(), and util::LazyVector< T, A >::resize().

173 { return data_begin_index() + data_size(); }
size_type data_begin_index() const
Definition: LazyVector.h:169
size_type data_size() const noexcept
Returns the size of data actually stored.
Definition: LazyVector.h:155
template<typename T, typename A = typename std::vector<T>::allocator_type>
bool util::LazyVector< T, A >::data_has_index ( size_type  pos) const
inline

Returns the internal storage index for the specified position.

Definition at line 176 of file LazyVector.h.

Referenced by util::LazyVector< T, A >::at(), and util::LazyVector< T, A >::operator[]().

177  {
178  return (pos >= data_begin_index()) && (pos < data_end_index());
179  }
size_type data_begin_index() const
Definition: LazyVector.h:169
size_type data_end_index() const
Definition: LazyVector.h:173
template<typename T , typename A >
void util::LazyVector< T, A >::data_init ( size_type  startIndex,
size_type  endIndex 
)

Allocates the specified range and stores default values for it.

Parameters
startIndexindex of the first element to be initialized
endIndexindex after the last element to be initialized

Each element in the range from startIndex to endIndex is stored and the default value is assigned to it.

Old data is lost.

Note
The nominal size of the vector is not changed, therefore the specified range might be not honored. If used in combination with resize(), resize() should be called first.

Definition at line 609 of file LazyVector.h.

References util::LazyVector< T, A >::data_clear(), util::LazyVector< T, A >::data_defvalue(), e, util::LazyVector< T, A >::fFirstIndex, util::LazyVector< T, A >::size(), and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< TF1 >::data_prepare(), and phot::PhotonLibrary::LoadLibraryFromFile().

610 {
611  // we do not go beyond the declared size of the vector:
612  size_type const e = std::min(endIndex, size());
613  if (startIndex >= e) return;
614 
615  data_clear(); // remove the old data
616  storage().resize(e - startIndex, data_defvalue());
617  fFirstIndex = startIndex;
618 
619 } // util::LazyVector<T,A>::data_init(size_type, size_type)
void data_clear()
Erases all stored data from the container; nominal size is not changed.
Definition: LazyVector.h:672
value_type const & data_defvalue() const
Definition: LazyVector.h:165
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:149
typename Data_t::size_type size_type
Definition: LazyVector.h:88
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:418
Float_t e
Definition: plot.C:35
template<typename T, typename A = typename std::vector<T>::allocator_type>
void util::LazyVector< T, A >::data_init ( size_type  n)
inline

Allocates and initializes n elements starting from index 0.

Parameters
nnumber of elements to be initialized

Each element in the range from 0 to n is stored and the default value is assigned to it. This is semantically similar to std::vector::resize(n, data_defvalue(), except that this method does not change the nominal size of the vector.

Old data is lost.

Note
The nominal size of the vector is not changed, therefore the specified range might be not honored. If used in combination with resize(), resize() should be called first.

Definition at line 409 of file LazyVector.h.

Referenced by util::LazyVector< TF1 >::data_init().

409 { data_init(0U, n); }
void data_init(size_type startIndex, size_type endIndex)
Allocates the specified range and stores default values for it.
Definition: LazyVector.h:609
Char_t n[5]
template<typename T , typename A >
void util::LazyVector< T, A >::data_prepare ( size_type  startIndex,
size_type  endIndex 
)

Prepares the vector to store elements in the specified range.

Parameters
startIndexindex of the first element to be stored
endIndexindex after the last element to be stored
See also
data_prepare(size_type)

This method sets the lower index to startIndex, and allocates enough storage to store the whole requested range. The elements are not initialized or constructed, but Following access to elements in the specified range will not cause memory reallocation, and that holds until an access outside that range happens, after which all bets are off.

Old data is lost.

Note
The nominal size of the vector is not changed, therefore the specified range might be not honored. If used in combination with resize(), resize() should be called first.

Definition at line 595 of file LazyVector.h.

References util::LazyVector< T, A >::data_clear(), e, util::LazyVector< T, A >::fFirstIndex, util::LazyVector< T, A >::size(), and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< TF1 >::shrink_to_fit().

596 {
597  // we do not go beyond the declared size of the vector:
598  size_type const e = std::min(endIndex, size());
599  if (startIndex >= e) return;
600 
601  data_clear(); // remove the old data
602  storage().reserve(e - startIndex);
603  fFirstIndex = startIndex;
604 
605 } // util::LazyVector<T,A>::data_prepare(size_type, size_type)
void data_clear()
Erases all stored data from the container; nominal size is not changed.
Definition: LazyVector.h:672
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:149
typename Data_t::size_type size_type
Definition: LazyVector.h:88
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:418
Float_t e
Definition: plot.C:35
template<typename T, typename A = typename std::vector<T>::allocator_type>
void util::LazyVector< T, A >::data_prepare ( size_type  n)
inline

Prepares the vector to store n elements from 0.

Parameters
nnumber of elements to prepare storage for
See also
data_prepare(size_type, size_type)

This method reserves storage for n elements starting with the element #0.

Old data is lost.

See data_prepare(size_type, size_type) for more information.

Definition at line 376 of file LazyVector.h.

Referenced by util::LazyVector< TF1 >::data_prepare().

376 { data_prepare(0U, n); }
void data_prepare(size_type startIndex, size_type endIndex)
Prepares the vector to store elements in the specified range.
Definition: LazyVector.h:595
Char_t n[5]
template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::data_size ( ) const
inlinenoexcept

Returns the size of data actually stored.

Definition at line 155 of file LazyVector.h.

Referenced by util::LazyVector< T, A >::data_address(), util::LazyVector< TF1 >::data_end_index(), and util::LazyVector< T, A >::operator[]().

155 { return fData.size(); }
Data_t fData
Actual data storage.
Definition: LazyVector.h:415
template<typename T, typename A = typename std::vector<T>::allocator_type>
static value_type const& util::LazyVector< T, A >::defaultValueType ( )
inlinestaticprivate

Returns the class default value (used when user does not specify any).

Definition at line 455 of file LazyVector.h.

455 { return fDefaultDefaultValue; }
static value_type const fDefaultDefaultValue
Default-initialised value of type value_type used as default fallback.
Definition: LazyVector.h:422
template<typename T, typename A = typename std::vector<T>::allocator_type>
bool util::LazyVector< T, A >::empty ( ) const
inlinenoexcept

Returns whether the vector is empty.

Definition at line 152 of file LazyVector.h.

152 { return fNominalSize == 0U; }
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:417
template<typename T , typename A >
void util::LazyVector< T, A >::expand ( size_type  pos)
private

Expands the storage to include the specified position.

Definition at line 623 of file LazyVector.h.

References util::LazyVector< T, A >::data_begin_index(), util::LazyVector< T, A >::data_empty(), util::LazyVector< T, A >::data_end_index(), util::LazyVector< T, A >::expand_back(), util::LazyVector< T, A >::expand_front(), and util::LazyVector< T, A >::init().

Referenced by util::LazyVector< T, A >::at(), util::LazyVector< TF1 >::index_of(), and util::LazyVector< T, A >::operator[]().

624 {
625  // this is just a dispatcher
626  if (data_empty())
627  init(pos);
628  else if (pos < data_begin_index())
629  expand_front(pos);
630  else if (pos >= data_end_index())
631  expand_back(pos);
632 }
void expand_front(size_type pos)
Expands the storage to include the specified position behind it.
Definition: LazyVector.h:646
bool data_empty() const noexcept
Returns whether no data is actually stored.
Definition: LazyVector.h:161
size_type data_begin_index() const
Definition: LazyVector.h:169
void expand_back(size_type pos)
Expands the storage to include the specified position ahead of it.
Definition: LazyVector.h:655
void init(size_type pos, size_type n=1U)
Makes the first data allocation.
Definition: LazyVector.h:636
size_type data_end_index() const
Definition: LazyVector.h:173
template<typename T , typename A >
void util::LazyVector< T, A >::expand_back ( size_type  pos)
private

Expands the storage to include the specified position ahead of it.

Definition at line 655 of file LazyVector.h.

References util::LazyVector< T, A >::data_begin_index(), util::LazyVector< T, A >::data_defvalue(), util::LazyVector< T, A >::data_end_index(), util::LazyVector< T, A >::fix_size(), and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< T, A >::expand(), and util::LazyVector< TF1 >::index_of().

656 {
657  assert(pos >= data_end_index());
658  storage().resize(pos + 1U - data_begin_index(), data_defvalue());
659  fix_size();
660 }
value_type const & data_defvalue() const
Definition: LazyVector.h:165
void fix_size()
Makes sure the nominal size is large enough to include all stored data.
Definition: LazyVector.h:664
size_type data_begin_index() const
Definition: LazyVector.h:169
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type data_end_index() const
Definition: LazyVector.h:173
template<typename T , typename A >
void util::LazyVector< T, A >::expand_front ( size_type  pos)
private

Expands the storage to include the specified position behind it.

Definition at line 646 of file LazyVector.h.

References util::begin(), util::LazyVector< T, A >::data_begin_index(), util::LazyVector< T, A >::data_defvalue(), util::LazyVector< T, A >::fFirstIndex, and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< T, A >::expand(), and util::LazyVector< TF1 >::index_of().

647 {
648  assert(pos < data_begin_index());
649  storage().insert(storage().begin(), data_begin_index() - pos, data_defvalue());
650  fFirstIndex = pos;
651 }
value_type const & data_defvalue() const
Definition: LazyVector.h:165
size_type data_begin_index() const
Definition: LazyVector.h:169
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:418
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
template<typename T , typename A >
void util::LazyVector< T, A >::fix_size ( )
private

Makes sure the nominal size is large enough to include all stored data.

Definition at line 664 of file LazyVector.h.

References util::LazyVector< T, A >::data_end_index(), and util::LazyVector< T, A >::fNominalSize.

Referenced by util::LazyVector< T, A >::expand_back(), util::LazyVector< TF1 >::index_of(), and util::LazyVector< T, A >::init().

665 {
666  auto const min_size = data_end_index();
667  if (fNominalSize < min_size) fNominalSize = min_size;
668 }
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:417
size_type data_end_index() const
Definition: LazyVector.h:173
template<typename T, typename A = typename std::vector<T>::allocator_type>
reference util::LazyVector< T, A >::get ( size_type  pos)
inline

Returns a reference to the specified element.

Parameters
posposition to be accessed
Returns
a reference to the specified element
See also
data_defvalue()

Returns a reference to the specified element. If that element is not stored, it is allocated first; all missing elements, including the required one, are initialised by copying into them the default value stored at construction. Like for STL vector, this method does not expand the vector: if pos is beyond the vector size, the result is undefined.

Definition at line 288 of file LazyVector.h.

288 { return this->operator[](pos); }
value_type operator[](size_type pos) const
Returns a copy of the specified element.
Definition: LazyVector.h:532
template<typename T, typename A = typename std::vector<T>::allocator_type>
bool util::LazyVector< T, A >::has_index ( size_type  pos) const
inlinenoexcept

Returns whether the specified position is within the vector.

Definition at line 158 of file LazyVector.h.

Referenced by util::LazyVector< T, A >::check_range(), and util::LazyVector< T, A >::operator[]().

158 { return pos < size(); }
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:149
template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::index_of ( size_type  pos) const
inlineprivate

Returns the internal storage index for the specified position.

Definition at line 431 of file LazyVector.h.

Referenced by util::LazyVector< T, A >::at(), util::LazyVector< T, A >::data_address(), util::LazyVector< T, A >::operator[](), and util::LazyVector< T, A >::resize().

431 { return pos - fFirstIndex; }
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:418
template<typename T , typename A >
void util::LazyVector< T, A >::init ( size_type  pos,
size_type  n = 1U 
)
private

Makes the first data allocation.

Definition at line 636 of file LazyVector.h.

References util::LazyVector< T, A >::data_defvalue(), util::LazyVector< T, A >::data_empty(), util::LazyVector< T, A >::fFirstIndex, util::LazyVector< T, A >::fix_size(), and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< T, A >::expand(), and util::LazyVector< TF1 >::index_of().

637 {
638  assert(data_empty());
639  storage().assign(n, data_defvalue());
640  fFirstIndex = pos;
641  fix_size();
642 }
value_type const & data_defvalue() const
Definition: LazyVector.h:165
void fix_size()
Makes sure the nominal size is large enough to include all stored data.
Definition: LazyVector.h:664
bool data_empty() const noexcept
Returns whether no data is actually stored.
Definition: LazyVector.h:161
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:418
Char_t n[5]
template<typename T , typename A >
util::LazyVector< T, A >::value_type util::LazyVector< T, A >::operator[] ( size_type  pos) const

Returns a copy of the specified element.

Parameters
posposition to be accessed
Returns
a copy of the specified element
See also
at(size_type) const

Returns a copy of the specified element. If the requested element is beyond the size of the container, the result is undefined.

Note
See at(value_type) const for an explanation of why a value is returned rather than a reference.

Definition at line 532 of file LazyVector.h.

References util::LazyVector< T, A >::data_begin_index(), util::LazyVector< T, A >::data_defvalue(), util::LazyVector< T, A >::data_size(), util::LazyVector< T, A >::index_of(), and util::LazyVector< T, A >::storage().

Referenced by util::LazyVector< TF1 >::const_at(), util::LazyVector< TF1 >::const_get(), and util::LazyVector< TF1 >::get().

533 {
534  /*
535  * Behaviour summary:
536  * * if `pos` is out of vector range, behaviour is undefined
537  * * if element at `pos` has no storage, return a copy of the default value
538  * * otherwise, return a copy of the element at `pos`
539  */
540  // this implementation will return a default value if `pos` is out of range;
541  // this is not a requirement, and may change at any time.
542  if (pos < data_begin_index()) return data_defvalue();
543  auto const index = index_of(pos);
544  return (index < data_size()) ? storage()[index] : data_defvalue();
545 } // util::LazyVector<T,A>::operator[] () const
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:431
value_type const & data_defvalue() const
Definition: LazyVector.h:165
size_type data_begin_index() const
Definition: LazyVector.h:169
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type data_size() const noexcept
Returns the size of data actually stored.
Definition: LazyVector.h:155
template<typename T , typename A >
util::LazyVector< T, A >::reference util::LazyVector< T, A >::operator[] ( size_type  pos)

Returns a reference to the specified element.

Parameters
posposition to be accessed
Returns
a reference to the specified element
See also
data_defvalue()

Returns a reference to the specified element. If that element is not stored, it is allocated first; all missing elements, including the required one, are initialised by copying into them the default value stored at construction. Like for STL vector, this method does not expand the vector: if pos is beyond the vector size, the result is undefined.

Definition at line 514 of file LazyVector.h.

References util::LazyVector< T, A >::data_has_index(), util::LazyVector< T, A >::expand(), util::LazyVector< T, A >::has_index(), util::LazyVector< T, A >::index_of(), and util::LazyVector< T, A >::storage().

515 {
516  /*
517  * Behaviour summary:
518  * * if `pos` is out of vector range, behaviour is undefined
519  * * if element at `pos` has no storage, create storage for it
520  * * return a reference to the element at `pos`
521  */
522  // to have the common case where the requested position has storage be handled
523  // the fastest, we "enforce" the order by nesting (optimiser has last word)
524  if (!data_has_index(pos)) {
525  if (has_index(pos)) expand(pos);
526  }
527  return storage()[index_of(pos)];
528 } // util::LazyVector<T,A>::operator[]()
bool has_index(size_type pos) const noexcept
Returns whether the specified position is within the vector.
Definition: LazyVector.h:158
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:431
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
void expand(size_type pos)
Expands the storage to include the specified position.
Definition: LazyVector.h:623
bool data_has_index(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:176
template<typename T, typename A = typename std::vector<T>::allocator_type>
void util::LazyVector< T, A >::reserve ( size_type  n)
inline

Allocates enough memory in storage to store n elements.

Parameters
nnumber of elements to have storage for
See also
data_prepare()

Storage allocation is resized to be able to host at least n elements (it is not reduced). Note that the use of reserve() for LazyVector is more subtle than for a STL vector. The common use of reserve() is to avoid reallocations when extending the vector. In this case, after a call to reserve(n) the reallocation is avoided only as long as only the elements from data_begin_index() to data_begin_index() + n (excluded) are written.

Note that data_prepare() has a similar purpose and might be more effective.

Definition at line 335 of file LazyVector.h.

335 { storage().reserve(n); }
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
Char_t n[5]
template<typename T , typename A >
void util::LazyVector< T, A >::resize ( size_type  newSize)

Changes the nominal size of the container.

Parameters
newSizenew container size

The nominal size of the vector is set to newSize. Even when newSize is larger than the current nominal size, no additional data is stored. If the new nominal size is smaller, actual data may be released (i.e. erased) so that no stored data is beyond the new nominal size.

Note
It is not possible to specify a filling value: the "default" value specified on construction is always used.

Definition at line 567 of file LazyVector.h.

References util::begin(), util::LazyVector< T, A >::data_begin_index(), util::LazyVector< T, A >::data_clear(), util::LazyVector< T, A >::data_end_index(), util::end(), util::LazyVector< T, A >::fNominalSize, util::LazyVector< T, A >::index_of(), and util::LazyVector< T, A >::storage().

Referenced by phot::PhotonLibrary::CreateEmptyLibrary(), util::LazyVector< TF1 >::get(), and phot::PhotonLibrary::LoadLibraryFromFile().

568 {
569  /*
570  * Behaviour summary:
571  * * when extending, do not change storage
572  * * when shrinking, cut the excess storage
573  */
574  fNominalSize = newSize;
575  // delete any excess data
576  if (data_end_index() > newSize) {
578  data_clear(); // no data is left
579  else {
580  storage().erase(storage().begin() + index_of(fNominalSize), storage().end());
581  }
582  }
583 } // util::LazyVector<T,A>::resize()
void data_clear()
Erases all stored data from the container; nominal size is not changed.
Definition: LazyVector.h:672
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:431
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
size_type data_begin_index() const
Definition: LazyVector.h:169
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:417
size_type data_end_index() const
Definition: LazyVector.h:173
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
template<typename T, typename A = typename std::vector<T>::allocator_type>
void util::LazyVector< T, A >::shrink_to_fit ( )
inline

Reduces memory usage to the amount needed by the elements with storage.

Definition at line 341 of file LazyVector.h.

341 { storage().shrink_to_fit(); }
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:426
template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::size ( ) const
inlinenoexcept
template<typename T, typename A = typename std::vector<T>::allocator_type>
Data_t const& util::LazyVector< T, A >::storage ( ) const
inlineprivate

Returns the data storage.

Definition at line 427 of file LazyVector.h.

427 { return fData; }
Data_t fData
Actual data storage.
Definition: LazyVector.h:415

Member Data Documentation

template<typename T, typename A = typename std::vector<T>::allocator_type>
Data_t util::LazyVector< T, A >::fData
private
template<typename T, typename A = typename std::vector<T>::allocator_type>
util::LazyVector< T, A >::value_type const util::LazyVector< T, A >::fDefaultDefaultValue {}
staticprivate

Default-initialised value of type value_type used as default fallback.

Definition at line 422 of file LazyVector.h.

Referenced by util::LazyVector< TF1 >::defaultValueType().

template<typename T, typename A = typename std::vector<T>::allocator_type>
value_type util::LazyVector< T, A >::fDefValue = defaultValueType()
private

Default value.

Definition at line 419 of file LazyVector.h.

Referenced by util::LazyVector< TF1 >::data_defvalue().

template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::fFirstIndex = fData.max_size()
private
template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::fNominalSize = 0U
private

The documentation for this class was generated from the following file: