- Overview
- Header
- Get MetaMappable interface
- Implemented built-in meta types
- MetaMappable constructor
- MetaMappable member functions
- Non-member utility functions
MetaMappable
is a meta interface to get and set elements in associative containers.
#include "metapp/interfaces/metamappable.h"
We can call MetaType::getMetaMappable()
to get the MetaMappable
interface.
If the type doesn't implement the interface, nullptr
is returned.
const metapp::MetaType * metaType = metapp::getMetaType<std::vector<int> >();
const metapp::MetaMappable * metaMappable = metaType->getMetaMappable();
std::map
(tkStdMap)
std::multimap
(tkStdMultimap)
std::unordered_map
(tkStdUnorderedMap)
std::unordered_multimap
(tkStdUnorderedMultimap)
MetaMappable(
const MetaType * (*getValueType)(const Variant & mappable),
Variant (*get)(const Variant & mappable, const Variant & key),
void (*set)(const Variant & mappable, const Variant & key, const Variant & value),
void (*forEach)(const Variant & mappable, const Callback & callback)
);
All arguments are function pointers. All pointers must point to valid function.
The meaning of each functions are same as the member functions listed below.
The first parameter in all of the member functions is const Variant & mappable
.
It's the Variant which meta type implements MetaMappable
, and hold the proper data such as std::vector
.
The member functions operate on the data.
We can treat mappable
as the C++ object instance which class implements an interface called MetaMappable
.
Variant mappable
can be value that implements MetaMappable
, or reference that refers to value that implements MetaMappable
.
const MetaType * getValueType(const Variant & mappable);
Returns the meta type of the value type. The returned meta type is a type of std::pair
, the up type at 0 is the key type,
the up type at 1 is the value type. Example,
metapp::Variant v{ std::unordered_map<std::string, int>() };
const metapp::MetaMappable * metaMappable = metapp::getNonReferenceMetaType(v)->getMetaMappable();
const metapp::MetaType * valueType = metaMappable->getValueType(v);
ASSERT(valueType->getTypeKind() == metapp::tkStdPair);
ASSERT(valueType->getUpType(0)->equal(metapp::getMetaType<std::string>()));
ASSERT(valueType->getUpType(1)->equal(metapp::getMetaType<int>()));
Variant get(const Variant & mappable, const Variant & key);
Returns a reference to the mapped value of the element with key
.
If no such element exists, an empty Variant (Variant::isEmpty() is true) is returned.
key
is casted to the key type in the container.
void set(const Variant & mappable, const Variant & key, const Variant & value);
Set the mapped value of the element with key
with value
.
key
is casted to the key type in the container.
value
is casted to the value type in the container.
void forEach(const Variant & mappable, const Callback & callback);
using Callback = std::function<bool (const Variant & key, const Variant & value)>;
When forEach
is invoked, callback
is called for every element in mappable
,and the references to the key and value
pare passed as the arguments of the callback
. If callback
returns true, forEach
will continue on next element,
until there is no more elements. If callback
returns false, forEach
will stop the loop and return.
Note: this function is different with MetaIterable::forEach
. MetaIterable::forEach
only passes one argument to the callback,
for std::map
or other associate containers, the argument is a std::pair
of the key and value. To decompose the key and value,
the callback needs to get MetaIndexable
from the std::pair
and uses MetaIndexable
to get the key and value.
MetaMappable::forEach
passes the key and value to the callback directly, it may have better performance than MetaIterable::forEach
.
Below free functions are shortcut functions to use the member functions in MetaMappable
.
Usually you should prefer the utility functions to calling MetaMappable
member function directly.
However, if you need to call functions on a single MetaMappable
more than one times in a high performance application,
you may store mappable.getMetaType()->getMetaMappable()
to a local variable, then use the variable to call the member functions.
This is because getMetaMappable()
has slightly performance overhead (the overhead is neglect most time).
inline const MetaType * mappableGetValueType(const Variant & mappable)
{
return mappable.getMetaType()->getMetaMappable()->getValueType(mappable);
}
inline Variant mappableGet(const Variant & mappable, const Variant & key)
{
return mappable.getMetaType()->getMetaMappable()->get(mappable, key);
}
inline void mappableSet(const Variant & mappable, const Variant & key, const Variant & value)
{
mappable.getMetaType()->getMetaMappable()->set(mappable, key, value);
}
inline void mappableForEach(const Variant & mappable, const MetaMappable::Callback & callback)
{
getNonReferenceMetaType(mappable)->getMetaMappable()->forEach(mappable, callback);
}