SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
Public Member Functions | Protected Attributes | List of all members
smtk::common::RuntimeTypeContainer Class Reference

A container that can hold objects by their exact compile-time type as well as a commonly-inherited, run-time type. More...

#include <RuntimeTypeContainer.h>

Inheritance diagram for smtk::common::RuntimeTypeContainer:
[legend]
Collaboration diagram for smtk::common::RuntimeTypeContainer:
[legend]

Public Member Functions

 RuntimeTypeContainer ()=default
 Construct an empty RuntimeTypeContainer.
 
 RuntimeTypeContainer (const RuntimeTypeContainer &)
 Construct a RuntimeTypeContainer whose contents are copied from an existing RuntimeTypeContainer.
 
 RuntimeTypeContainer (RuntimeTypeContainer &&)=default
 Move the contents of one TypeContainer into a new TypeContainer.
 
RuntimeTypeContaineroperator= (const RuntimeTypeContainer &)
 Copy the contents of an existing TypeContainer into this one.
 
RuntimeTypeContaineroperator= (RuntimeTypeContainer &&)=default
 Move the contents of an existing TypeContainer into this one.
 
template<typename Arg , typename... Args, typename std::enable_if<!std::is_base_of< TypeContainer, Arg >::value, int >::type = 0>
 RuntimeTypeContainer (const Arg &arg, const Args &... args)
 Construct a RuntimeTypeContainer instance from any number of elements. More...
 
bool containsRuntime (smtk::string::Token declaredType) const
 Check if a Type is present in the TypeContainer.
 
template<typename RuntimeType , typename ActualType >
bool insertRuntime (smtk::string::Token declaredType, const ActualType &value)
 Insert a runtime RuntimeType instance into the TypeContainer. More...
 
template<typename RuntimeType , typename ActualType >
bool insertOrAssignRuntime (smtk::string::Token declaredType, const ActualType &value)
 Insert a Type instance into the RuntimeTypeContainer if it does not exist already or replace it if it does.
 
template<typename RuntimeType , typename... Args>
bool emplaceRuntime (smtk::string::Token declaredType, Args &&... args)
 Emplace a RuntimeType instance into the TypeContainer.
 
template<typename RuntimeType >
const RuntimeType & getRuntime (smtk::string::Token declaredType) const
 Access a Type instance, and throw if it is not in the TypeContainer.
 
template<typename RuntimeType >
std::enable_if< std::is_default_constructible< RuntimeType >::value, RuntimeType & >::type getRuntime (smtk::string::Token declaredType) noexcept
 For default-constructible types, access a RuntimeType instance, creating one if it is not in the RuntimeTypeContainer.
 
template<typename RuntimeType >
std::enable_if<!std::is_default_constructible< RuntimeType >::value, RuntimeType & >::type getRuntime (smtk::string::Token declaredType)
 For non-default-constructible types, access a Type instance; throw if it is not in the TypeContainer.
 
template<typename Type >
bool erase ()
 Remove a specific type of object from the container. More...
 
bool eraseRuntime (smtk::string::Token declaredType)
 Remove a specific type of object from the container.
 
void clear () noexcept
 Erase all objects held by the container.
 
std::unordered_set< smtk::string::TokenruntimeBaseTypes () const
 Report the base classes used to insert runtime objects.
 
std::unordered_set< smtk::string::TokenruntimeTypeNames (smtk::string::Token baseType) const
 Report the declared type-names of objects inserted using the given base type.
 
template<typename RuntimeType >
std::unordered_set< smtk::string::TokenruntimeTypeNames () const
 Report the declared type-names of objects inserted using the given base type.
 
- Public Member Functions inherited from smtk::common::TypeContainer
 TypeContainer ()=default
 Construct an empty TypeContainer.
 
 TypeContainer (const TypeContainer &)
 Construct a TypeContainer whose contents are copied from an existing TypeContainer.
 
 TypeContainer (TypeContainer &&)=default
 Move the contents of one TypeContainer into a new TypeContainer.
 
TypeContaineroperator= (const TypeContainer &)
 Copy the contents of an existing TypeContainer into this one.
 
TypeContaineroperator= (TypeContainer &&)=default
 Move the contents of an existing TypeContainer into this one.
 
template<typename Arg , typename... Args, typename std::enable_if<!std::is_base_of< TypeContainer, Arg >::value, int >::type = 0>
 TypeContainer (const Arg &arg, const Args &... args)
 Construct a TypeContainer instance from any number of elements. More...
 
template<typename Type >
KeyType keyId () const
 Return the ID used to index a given Type.
 
template<typename Type >
bool contains () const
 Check if a Type is present in the TypeContainer.
 
template<typename Type >
bool insert (const Type &value)
 Insert a Type instance into the TypeContainer. More...
 
template<typename Type >
bool insertOrAssign (const Type &value)
 Insert a Type instance into the TypeContainer if it does not exist already or replace it if it does.
 
template<typename Type >
bool insert_or_assign (const Type &value)
 Insert a Type instance into the TypeContainer if it does not exist already or replace it if it does.
 
template<typename Type , typename... Args>
bool emplace (Args &&... args)
 Emplace a Type instance into the TypeContainer.
 
template<typename Type >
const Type & get () const
 Access a Type instance, and throw if it is not in the TypeContainer.
 
template<typename Type >
std::enable_if< std::is_default_constructible< Type >::value, Type & >::type get () noexcept
 For default-constructible types, access a Type instance, creating one if it is not in the TypeContainer.
 
template<typename Type >
std::enable_if<!std::is_default_constructible< Type >::value, Type & >::type get ()
 For non-default-constructible types, access a Type instance; throw if it is not in the TypeContainer.
 
template<typename Type >
bool erase ()
 Remove a specific type of object from the container.
 
bool empty () const noexcept
 Return true if the container holds no objects and false otherwise.
 
std::size_t size () const noexcept
 Return the nubmer of objects held by the container.
 
void clear () noexcept
 Erase all objects held by the container.
 
std::set< smtk::string::Tokenkeys () const
 Return a set of keys corresponding to the values in the container. More...
 

Protected Attributes

std::unordered_map< smtk::string::Token, std::unordered_set< smtk::string::Token > > m_runtimeObjects
 Map from RuntimeType type-names (i.e., the common base classes used to insert values) to declared types.
 
- Protected Attributes inherited from smtk::common::TypeContainer
std::unordered_map< KeyType, std::unique_ptr< Wrapper > > m_container
 

Additional Inherited Members

- Public Types inherited from smtk::common::TypeContainer
using KeyType = smtk::string::Hash
 
- Protected Member Functions inherited from smtk::common::TypeContainer
template<typename Arg , typename... Args>
std::enable_if<!std::is_base_of< TypeContainer, Arg >::value, bool >::type insertAll (const Arg &arg, const Args &... args)
 
bool insertAll ()
 

Detailed Description

A container that can hold objects by their exact compile-time type as well as a commonly-inherited, run-time type.

This class extends TypeContainer with a runtime API that stores objects of a common type under user-provided "type names" chosen at run time. (These "type names" do not need to name actual types, but they may.)

Insertion and retrieval

For example, consider a TypeContainer used to hold metadata objects. Compile-time objects can be inserted during the build but users may need to add "programmable" metadata objects at run-time. The application can provide a base RuntimeMetadata class with virtual methods and then allow users to "name" instances of this base class as if each represented its own type.

struct MetadataA { const char* name = "Foo"; };
struct MetadataB { const char* name = "Bar"; };
class RuntimeMetadata
{
public:
RuntimeMetadata(const std::string& name) : m_name(name) { }
virtual std::string name() const { return m_name; }
private:
std::string m_name;
};
class Baz : public RuntimeMetadata
{
public:
Baz() : RuntimeMetadata("Baz") { };
};
RuntimeTypeContainer allMetadata(MetadataA(), MetadataB());
allMetadata.emplaceRuntime("Baz", RuntimeMetadata("Baz"));

In this example, there are now two "compile-time" entries in allMetadata plus one "run-time" entry. You can fetch "Foo" and "Bar" by knowing their type at compile time:

auto& foo = allMetadata.get<Foo>();
auto& bar = allMetadata.get<Bar>();

You can fetch "Baz" by knowing either its type or that it inherits RuntimeMetadata:

auto bazDirect = allMetadata.get<Baz>();
auto bazByBase = allMetadata.getRuntime<RuntimeMetadata>("Baz");

Importantly, (1) you can store multiple "run-time" objects sharing the same base class in the type container as long as their declared types are unique and (2) the declared type does not need to match any actual type. However, (3) if fetching by a run-time object's base type, the template parameter must exactly match the type used to insert the object into the TypeContainer.

For example:

class Xyzzy : public Baz { };
allMetadata.emplaceRuntime<RuntimeMetadata>("Xyzzy", Xyzzy());
auto dataBad = allMetadata.getRuntime<Baz>("Xyzzy"); // Will NOT work.
auto dataGood = allMetadata.getRuntime<RuntimeMetadata>("Xyzzy"); // Correct.

Introspection of runtime type-data

It is also important for consumers of a RuntimeTypeContainer to be able to fetch the list of run-time objects and their base types. To this end, you can access a map from run-time storage types to the user-provided "type names."

// Fetch a set of string-tokens naming the base types of runtime objects:
auto runtimeBases = allMetadata.runtimeBaseTypes();
// Return the type-names of objects that "inherit" a given runtime base type:
auto runtimeObjectTypes = allMetadata.runtimeTypeNames("RuntimeMetadata");

Constructor & Destructor Documentation

◆ RuntimeTypeContainer()

template<typename Arg , typename... Args, typename std::enable_if<!std::is_base_of< TypeContainer, Arg >::value, int >::type = 0>
smtk::common::RuntimeTypeContainer::RuntimeTypeContainer ( const Arg &  arg,
const Args &...  args 
)
inline

Construct a RuntimeTypeContainer instance from any number of elements.

Elements are added in the order they appear in the constructor, so subsequent values for the same type will be ignored.

Member Function Documentation

◆ erase()

template<typename Type >
bool smtk::common::RuntimeTypeContainer::erase ( )
inline

Remove a specific type of object from the container.

This is overridden from the base class to ensure m_runtimeObjects is maintained.

◆ insertRuntime()

template<typename RuntimeType , typename ActualType >
bool smtk::common::RuntimeTypeContainer::insertRuntime ( smtk::string::Token  declaredType,
const ActualType &  value 
)
inline

Insert a runtime RuntimeType instance into the TypeContainer.

Note that if the type already exists in the container, the insertion will fail.


The documentation for this class was generated from the following files:
smtk::common::RuntimeTypeContainer::RuntimeTypeContainer
RuntimeTypeContainer()=default
Construct an empty RuntimeTypeContainer.