Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | List of all members
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
 
value_type operator[] (size_type pos) const
 Returns a copy of the specified element. More...
 
value_type const_get (size_type pos) const
 
reference operator[] (size_type pos)
 Returns a reference to the specified element. More...
 
reference get (size_type pos)
 
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
 

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 78 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 88 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 95 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 93 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 80 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 91 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 94 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 92 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 90 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 89 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 489 of file LazyVector.h.

490  : fData(a)
491  {}
const double a
Data_t fData
Actual data storage.
Definition: LazyVector.h:430
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 496 of file LazyVector.h.

498  {}
static value_type const & defaultValueType()
Returns the class default value (used when user does not specify any).
Definition: LazyVector.h:471
LazyVector()=default
std::void_t< T > n
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 503 of file LazyVector.h.

504  : fNominalSize(n)
505  , fDefValue(defValue)
506  {}
std::void_t< T > n
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:432
value_type fDefValue
Default value.
Definition: LazyVector.h:434

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 529 of file LazyVector.h.

530 {
531  /*
532  * Behaviour summary:
533  * * if `pos` is out of vector range, throw an exception
534  * * if element at `pos` has no storage, return a copy of the default value
535  * * otherwise, return a copy of the element at `pos`
536  */
537  check_range(pos); // verify that `pos` is valid, throw otherwise
539 } // 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:717
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:446
value_type const & data_defvalue() const
Definition: LazyVector.h:172
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
bool data_has_index(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:184
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 512 of file LazyVector.h.

513 {
514  /*
515  * Behaviour summary:
516  * * if `pos` is out of vector range, throw an exception
517  * * if element at `pos` has no storage, create storage for it
518  * * return a reference to the element at `pos`
519  */
520  check_range(pos); // verify that `pos` is valid, throw otherwise
521  expand(pos);
522  return storage()[index_of(pos)]; // we already know it's valid
523 }
void check_range(size_type pos) const
Throws std::out_of_range if pos is not contained in the vector.
Definition: LazyVector.h:717
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:446
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
void expand(size_type pos)
Expands the storage to include the specified position.
Definition: LazyVector.h:662
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 717 of file LazyVector.h.

717  {
718  if (has_index(pos)) return;
719  throw std::out_of_range(
720  "Index " + std::to_string(pos) + " is out of LazyVector range (size: "
721  + std::to_string(size()) + ")"
722  );
723 } // 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:165
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:156
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
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 622 of file LazyVector.h.

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

Definition at line 245 of file LazyVector.h.

245 { 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:529
template<typename T, typename A = typename std::vector<T>::allocator_type>
value_type util::LazyVector< T, A >::const_get ( size_type  pos) const
inline

Definition at line 278 of file LazyVector.h.

278 { return this->operator[](pos); }
value_type operator[](size_type pos) const
Returns a copy of the specified element.
Definition: LazyVector.h:565
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 584 of file LazyVector.h.

585 {
586  /*
587  * Behaviour summary:
588  * * if `pos` is out of vector range, behaviour is undefined
589  * * if element at `pos` has no storage, return nullptr
590  * * otherwise, return the pointer to the specified element
591  */
592  // this implementation will return nullptr if `pos` is out of range;
593  // this is not a requirement, and may change at any time.
594  if (pos < data_begin_index()) return nullptr;
595  auto const index = index_of(pos);
596  return (index < data_size())? storage().data() + index: nullptr;
597 } // 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:446
size_type data_begin_index() const
Definition: LazyVector.h:176
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type data_size() const noexcept
Returns the size of data actually stored.
Definition: LazyVector.h:162
template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::data_begin_index ( ) const
inline

Index of the first data element in the storage (undefined if data_empty()).

Definition at line 176 of file LazyVector.h.

176 { return fFirstIndex; }
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:433
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 709 of file LazyVector.h.

709  {
710  storage().clear();
711  fFirstIndex = storage().max_size();
712 } // util::LazyVector<T,A>::data_clear()
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:433
template<typename T, typename A = typename std::vector<T>::allocator_type>
value_type const& util::LazyVector< T, A >::data_defvalue ( ) const
inline

Returns the default value.

See also
LazyVector(size_type, value_type const&)

Definition at line 172 of file LazyVector.h.

172 { return fDefValue; }
value_type fDefValue
Default value.
Definition: LazyVector.h:434
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 168 of file LazyVector.h.

168 { return fData.empty(); }
Data_t fData
Actual data storage.
Definition: LazyVector.h:430
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 180 of file LazyVector.h.

181  { return data_begin_index() + data_size(); }
size_type data_begin_index() const
Definition: LazyVector.h:176
size_type data_size() const noexcept
Returns the size of data actually stored.
Definition: LazyVector.h:162
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 184 of file LazyVector.h.

185  { return (pos >= data_begin_index()) && (pos < data_end_index()); }
size_type data_begin_index() const
Definition: LazyVector.h:176
size_type data_end_index() const
Definition: LazyVector.h:180
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 647 of file LazyVector.h.

648 {
649  // we do not go beyond the declared size of the vector:
650  size_type const e = std::min(endIndex, size());
651  if (startIndex >= e) return;
652 
653  data_clear(); // remove the old data
654  storage().resize(e - startIndex, data_defvalue());
655  fFirstIndex = startIndex;
656 
657 } // 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:709
value_type const & data_defvalue() const
Definition: LazyVector.h:172
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:156
const double e
typename Data_t::size_type size_type
Definition: LazyVector.h:90
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:433
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
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 422 of file LazyVector.h.

422 { 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:647
std::void_t< T > n
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 631 of file LazyVector.h.

632 {
633  // we do not go beyond the declared size of the vector:
634  size_type const e = std::min(endIndex, size());
635  if (startIndex >= e) return;
636 
637  data_clear(); // remove the old data
638  storage().reserve(e - startIndex);
639  fFirstIndex = startIndex;
640 
641 } // 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:709
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:156
const double e
typename Data_t::size_type size_type
Definition: LazyVector.h:90
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:433
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
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 389 of file LazyVector.h.

389 { 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:631
std::void_t< T > n
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 162 of file LazyVector.h.

162 { return fData.size(); }
Data_t fData
Actual data storage.
Definition: LazyVector.h:430
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 471 of file LazyVector.h.

471 { return fDefaultDefaultValue; }
static value_type const fDefaultDefaultValue
Default-initialised value of type value_type used as default fallback.
Definition: LazyVector.h:437
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 159 of file LazyVector.h.

159 { return fNominalSize == 0U; }
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:432
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 662 of file LazyVector.h.

662  {
663  // this is just a dispatcher
664  if (data_empty()) init(pos);
665  else if (pos < data_begin_index()) expand_front(pos);
666  else if (pos >= data_end_index()) expand_back(pos);
667 }
void expand_front(size_type pos)
Expands the storage to include the specified position behind it.
Definition: LazyVector.h:682
bool data_empty() const noexcept
Returns whether no data is actually stored.
Definition: LazyVector.h:168
size_type data_begin_index() const
Definition: LazyVector.h:176
void expand_back(size_type pos)
Expands the storage to include the specified position ahead of it.
Definition: LazyVector.h:692
void init(size_type pos, size_type n=1U)
Makes the first data allocation.
Definition: LazyVector.h:672
size_type data_end_index() const
Definition: LazyVector.h:180
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 692 of file LazyVector.h.

692  {
693  assert(pos >= data_end_index());
694  storage().resize(pos + 1U - data_begin_index(), data_defvalue());
695  fix_size();
696 }
value_type const & data_defvalue() const
Definition: LazyVector.h:172
void fix_size()
Makes sure the nominal size is large enough to include all stored data.
Definition: LazyVector.h:701
size_type data_begin_index() const
Definition: LazyVector.h:176
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type data_end_index() const
Definition: LazyVector.h:180
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 682 of file LazyVector.h.

682  {
683  assert(pos < data_begin_index());
684  storage().insert
686  fFirstIndex = pos;
687 }
value_type const & data_defvalue() const
Definition: LazyVector.h:172
size_type data_begin_index() const
Definition: LazyVector.h:176
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:433
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
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 701 of file LazyVector.h.

701  {
702  auto const min_size = data_end_index();
703  if (fNominalSize < min_size) fNominalSize = min_size;
704 }
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:432
size_type data_end_index() const
Definition: LazyVector.h:180
template<typename T, typename A = typename std::vector<T>::allocator_type>
reference util::LazyVector< T, A >::get ( size_type  pos)
inline

Definition at line 296 of file LazyVector.h.

296 { return this->operator[](pos); }
value_type operator[](size_type pos) const
Returns a copy of the specified element.
Definition: LazyVector.h:565
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 165 of file LazyVector.h.

165 { return pos < size(); }
size_type size() const noexcept
Returns the size of the vector.
Definition: LazyVector.h:156
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 446 of file LazyVector.h.

446 { return pos - fFirstIndex; }
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:433
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 672 of file LazyVector.h.

672  {
673  assert(data_empty());
674  storage().assign(n, data_defvalue());
675  fFirstIndex = pos;
676  fix_size();
677 }
value_type const & data_defvalue() const
Definition: LazyVector.h:172
void fix_size()
Makes sure the nominal size is large enough to include all stored data.
Definition: LazyVector.h:701
bool data_empty() const noexcept
Returns whether no data is actually stored.
Definition: LazyVector.h:168
std::void_t< T > n
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type fFirstIndex
First element currently stored.
Definition: LazyVector.h:433
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 565 of file LazyVector.h.

566 {
567  /*
568  * Behaviour summary:
569  * * if `pos` is out of vector range, behaviour is undefined
570  * * if element at `pos` has no storage, return a copy of the default value
571  * * otherwise, return a copy of the element at `pos`
572  */
573  // this implementation will return a default value if `pos` is out of range;
574  // this is not a requirement, and may change at any time.
575  if (pos < data_begin_index()) return data_defvalue();
576  auto const index = index_of(pos);
577  return (index < data_size())? storage()[index]: data_defvalue();
578 } // 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:446
value_type const & data_defvalue() const
Definition: LazyVector.h:172
size_type data_begin_index() const
Definition: LazyVector.h:176
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type data_size() const noexcept
Returns the size of data actually stored.
Definition: LazyVector.h:162
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 545 of file LazyVector.h.

546 {
547  /*
548  * Behaviour summary:
549  * * if `pos` is out of vector range, behaviour is undefined
550  * * if element at `pos` has no storage, create storage for it
551  * * return a reference to the element at `pos`
552  */
553  // to have the common case where the requested position has storage be handled
554  // the fastest, we "enforce" the order by nesting (optimiser has last word)
555  if (!data_has_index(pos)) {
556  if (has_index(pos)) expand(pos);
557  }
558  return storage()[index_of(pos)];
559 } // 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:165
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:446
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
void expand(size_type pos)
Expands the storage to include the specified position.
Definition: LazyVector.h:662
bool data_has_index(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:184
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 348 of file LazyVector.h.

348 { storage().reserve(n); }
std::void_t< T > n
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
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 602 of file LazyVector.h.

602  {
603  /*
604  * Behaviour summary:
605  * * when extending, do not change storage
606  * * when shrinking, cut the excess storage
607  */
608  fNominalSize = newSize;
609  // delete any excess data
610  if (data_end_index() > newSize) {
611  if (fNominalSize <= data_begin_index()) data_clear(); // no data is left
612  else {
613  storage().erase
615  }
616  }
617 } // util::LazyVector<T,A>::resize()
void data_clear()
Erases all stored data from the container; nominal size is not changed.
Definition: LazyVector.h:709
size_type index_of(size_type pos) const
Returns the internal storage index for the specified position.
Definition: LazyVector.h:446
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:176
Data_t & storage()
Returns the data storage.
Definition: LazyVector.h:441
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:432
size_type data_end_index() const
Definition: LazyVector.h:180
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
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 354 of file LazyVector.h.

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

Returns the size of the vector.

Definition at line 156 of file LazyVector.h.

156 { return fNominalSize; }
size_type fNominalSize
Alleged data size.
Definition: LazyVector.h:432
template<typename T, typename A = typename std::vector<T>::allocator_type>
Data_t& util::LazyVector< T, A >::storage ( )
inlineprivate

Returns the data storage.

Definition at line 441 of file LazyVector.h.

441 { return fData; }
Data_t fData
Actual data storage.
Definition: LazyVector.h:430
template<typename T, typename A = typename std::vector<T>::allocator_type>
Data_t const& util::LazyVector< T, A >::storage ( ) const
inlineprivate

Definition at line 442 of file LazyVector.h.

442 { return fData; }
Data_t fData
Actual data storage.
Definition: LazyVector.h:430

Member Data Documentation

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

Actual data storage.

Definition at line 430 of file LazyVector.h.

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 437 of file LazyVector.h.

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 434 of file LazyVector.h.

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

First element currently stored.

Definition at line 433 of file LazyVector.h.

template<typename T, typename A = typename std::vector<T>::allocator_type>
size_type util::LazyVector< T, A >::fNominalSize = 0U
private

Alleged data size.

Definition at line 432 of file LazyVector.h.


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