Skip to content

Instantly share code, notes, and snippets.

@matpen
Created April 26, 2017 20:32
Show Gist options
  • Save matpen/729dd1892597990388a5b7635acd40f3 to your computer and use it in GitHub Desktop.
Save matpen/729dd1892597990388a5b7635acd40f3 to your computer and use it in GitHub Desktop.
RTTR Associative container mapper for QHash
#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