- 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);
}