NEML2 2.0.0
Loading...
Searching...
No Matches
Storage< I, T > Class Template Reference

Detailed Description

template<typename I, typename T>
class neml2::Storage< I, T >

Storage container that stores a vector of unique pointers of T, but represents most of the public facing accessors (iterators, operator[]).

That is, these accessors dereference the underlying storage. More importantly, if data is not properly initialized using set_pointer(), this dereferencing will either lead to an assertion or a nullptr dereference.

#include <Storage.h>

Classes

struct  DereferenceIterator
 

Public Types

using values_type = typename std::map<I, std::unique_ptr<T>>
 
using iterator = DereferenceIterator<typename values_type::iterator>
 
using const_iterator = DereferenceIterator<typename values_type::const_iterator>
 

Public Member Functions

 Storage ()=default
 
std::size_t size () const
 
bool empty () const
 
bool has_key (const I &i) const
 
T * set_pointer (const I &i, std::unique_ptr< T > &&ptr)
 
Iterators

Begin and end iterators to the underlying data.

Note that dereferencing these iterators may lead to an assertion or the dereference of a nullptr whether or not the underlying data is initialized.

iterator begin ()
 
iterator end ()
 
const_iterator begin () const
 
const_iterator end () const
 
T & operator[] (const I &i) const
 
T & operator[] (const I &i)
 
const T * query_value (const I &i) const
 
T * query_value (const I &i)
 

Member Typedef Documentation

◆ const_iterator

template<typename I , typename T >
using const_iterator = DereferenceIterator<typename values_type::const_iterator>

◆ iterator

template<typename I , typename T >
using iterator = DereferenceIterator<typename values_type::iterator>

◆ values_type

template<typename I , typename T >
using values_type = typename std::map<I, std::unique_ptr<T>>

Constructor & Destructor Documentation

◆ Storage()

template<typename I , typename T >
Storage ( )
default

Member Function Documentation

◆ begin() [1/2]

template<typename I , typename T >
iterator begin ( )
inline

◆ begin() [2/2]

template<typename I , typename T >
const_iterator begin ( ) const
inline

◆ empty()

template<typename I , typename T >
bool empty ( ) const
inline
Returns
Whether or not the underlying storage is empty.

◆ end() [1/2]

template<typename I , typename T >
iterator end ( )
inline

◆ end() [2/2]

template<typename I , typename T >
const_iterator end ( ) const
inline

◆ has_key()

template<typename I , typename T >
bool has_key ( const I & i) const
inline
Returns
whether or not the underlying object at index i is initialized

◆ operator[]() [1/2]

template<typename I , typename T >
T & operator[] ( const I & i)
inline

◆ operator[]() [2/2]

template<typename I , typename T >
T & operator[] ( const I & i) const
inline
Returns
A reference to the underlying data at index i.

Note that the underlying data may not necessarily be initialized, in which case this will throw an assertion error.

You can check whether or not the underlying data is intialized with has_key(i).

◆ query_value() [1/2]

template<typename I , typename T >
T * query_value ( const I & i)
inline

◆ query_value() [2/2]

template<typename I , typename T >
const T * query_value ( const I & i) const
inline
Returns
A pointer to the underlying data at index i

The pointer will be nullptr if !has_key(i), that is, if the unique_ptr at index i is not initialized

◆ set_pointer()

template<typename I , typename T >
T * set_pointer ( const I & i,
std::unique_ptr< T > && ptr )
inline

Sets the underlying unique_ptr at index i to ptr.

This can be used to construct objects in the storage, i.e., set_pointer(0, std::make_unique<T>(...));

This is the only method that allows for the modification of ownership in the underlying vector. Protect it wisely.

◆ size()

template<typename I , typename T >
std::size_t size ( ) const
inline
Returns
The size of the underlying storage.

Note that this is not necessarily the size of constructed objects, as underlying objects could be uninitialized