Created
April 26, 2017 20:32
-
-
Save matpen/729dd1892597990388a5b7635acd40f3 to your computer and use it in GitHub Desktop.
RTTR Associative container mapper for QHash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef RTTRQHASH_H | |
#define RTTRQHASH_H | |
#include <QHash> | |
#include <rttr/type.h> | |
#include <new> | |
namespace rttr | |
{ | |
template<typename K, typename T, typename...Args> | |
struct associative_container_mapper<QHash<K, T>, Args...> : detail::associative_container_base<QHash<K, T>, Args...> | |
{ | |
using Itr = typename QHash<K, T>::iterator; | |
static Itr& get_iterator(detail::iterator_data& data) | |
{ | |
//extract the iterator from data | |
return *reinterpret_cast<Itr*&>(data); | |
} | |
static const Itr& get_iterator(const detail::iterator_data& data) | |
{ | |
//extract the iterator from data | |
return *reinterpret_cast<Itr* const &>(data); | |
} | |
static void create(detail::iterator_data& itr_tgt, const Itr& itr_src) | |
{ | |
//save the iterator | |
new(&itr_tgt) Itr(itr_src); | |
} | |
static void create(detail::iterator_data& itr_tgt, const detail::iterator_data& itr_src) | |
{ | |
//save the iterator | |
new(&itr_tgt) Itr(get_iterator(itr_src)); | |
} | |
static void destroy(detail::iterator_data& itr) | |
{ | |
//destroy the iterator | |
reinterpret_cast<Itr*&>(itr)->~iterator(); | |
} | |
static void advance(detail::iterator_data& itr, std::ptrdiff_t idx) | |
{ | |
//advance the iterator | |
get_iterator(itr) += idx; | |
} | |
static bool equal(const detail::iterator_data& lhs_itr, const detail::iterator_data& rhs_itr) RTTR_NOEXCEPT | |
{ | |
//check if the given iterators are equal | |
auto& lhs = get_iterator(lhs_itr); | |
auto& rhs = get_iterator(rhs_itr); | |
return lhs == rhs; | |
} | |
static variant get_key(const detail::iterator_data& itr) | |
{ | |
//return the key | |
auto& it = get_iterator(itr); | |
return variant(std::ref(it.key())); | |
} | |
static variant get_value(const detail::iterator_data& itr) | |
{ | |
//return the value | |
auto& it = get_iterator(itr); | |
return variant(std::ref(it.value())); | |
} | |
static void find(void* container, detail::iterator_data& itr, argument& key) | |
{ | |
//returns an iterator pointing to the item with the key | |
Itr it = reinterpret_cast<QHash<K, T>*>(container)->find(key.get_value<K>()); | |
new(&itr) Itr(it); | |
} | |
static void equal_range(void* container, argument& key, detail::iterator_data& itr_begin, detail::iterator_data& itr_end) | |
{ | |
//return a pair of iterators delimiting the range of values stored under "key" | |
QPair<Itr, Itr> iterators = reinterpret_cast<QHash<K, T>*>(container)->equal_range(key.get_value<K>()); | |
new(&itr_begin) Itr(iterators.first); | |
new(&itr_end) Itr(iterators.second); | |
} | |
static std::size_t erase(void* container, argument& key) | |
{ | |
//remove the key from the container | |
return reinterpret_cast<QHash<K, T>*>(container)->remove(key.get_value<K>()); | |
} | |
static void clear(void* container) | |
{ | |
//clear the container | |
reinterpret_cast<QHash<K, T>*>(container)->clear(); | |
} | |
static bool insert_key(void* /*container*/, argument& /*key*/, detail::iterator_data& /*itr*/) | |
{ | |
//not a key-only container | |
return false; | |
} | |
static bool insert_key_value(void* container, argument& key, argument& value, detail::iterator_data& itr) | |
{ | |
//check the types | |
if (key.get_type() != type::get<K>() || value.get_type() != type::get<T>()) | |
return false; | |
//insert the value into the container | |
Itr it = reinterpret_cast<QHash<K, T>*>(container)->insert(key.get_value<K>(), value.get_value<T>()); | |
new(&itr) Itr(it); | |
return true; | |
} | |
}; | |
} | |
#endif // RTTRQHASH_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment