Dictionary Trait
Exposing and using dictionary functionality of a type.
The DictionaryTrait trait is used to expose the dictionary functionality of a type. In this example, we will write a function which takes a type and an instance of that type, and prints its entries:
#include <cubos/core/reflection/traits/dictionary.hpp> #include <cubos/core/reflection/type.hpp> using cubos::core::reflection::DictionaryTrait; using cubos::core::reflection::Type; void printDictionary(const Type& type, const void* instance) { const auto& dictionaryTrait = type.get<DictionaryTrait>();
Through the trait, we can access the size of the dictionary and its key and value types:
auto dictionaryView = dictionaryTrait.view(instance); CUBOS_INFO("Dictionary with {} entries of key type {} and value type {}", dictionaryView.length(), dictionaryTrait.keyType().name(), dictionaryTrait.valueType().name());
We can also iterate over the entries of a dictionary and access them:
if (!dictionaryTrait.keyType().is<int32_t>() || !dictionaryTrait.valueType().is<int32_t>()) { CUBOS_INFO("This function does not support printing dictionary with key and value types other than int32_t"); return; } for (auto [key, value] : dictionaryView) { CUBOS_INFO("{} -> {}", *static_cast<const int32_t*>(key), *static_cast<const int32_t*>(value)); } }
In this example, we're only supporting dictionaris which map int32_t
s, but we could for example implement a printing function which supports all primitive types.
To make calling our function easier, we can add a convenience typed wrapper:
template <typename T> void printDictionary(const T& dictionary) { using cubos::core::reflection::reflect; printDictionary(reflect<T>(), &dictionary); }
Using this function is now as simple as:
#include <cubos/core/reflection/external/map.hpp> #include <cubos/core/reflection/external/primitives.hpp> int main() { std::map<int32_t, int32_t> map = { {1, 2}, {2, 4}, {3, 6}, {4, 8}, }; printDictionary(map); // Dictionary with 4 entries of key type int32_t and value type int32_t // 1 -> 2 // 2 -> 4 // 3 -> 6 // 4 -> 8 }
Its important to note that both the includes above are necessary, as we're reflecting the type std::map<int32_t, int32_t>
, which also means reflecting int32_t
.
Executing the sample should output:
// Dictionary with 4 entries of key type int32_t and value type int32_t // 1 -> 2 // 2 -> 4 // 3 -> 6 // 4 -> 8