Selaa lähdekoodia

* Check the base classes of a variant and return the matching object if a base class matches

master
bergmann 5 vuotta sitten
vanhempi
commit
73267ee7c1
6 muutettua tiedostoa jossa 88 lisäystä ja 2 poistoa
  1. +10
    -0
      include/cpprtti/misc/variant.h
  2. +54
    -2
      include/cpprtti/misc/variant.inl
  3. +5
    -0
      include/cpprtti/types/class_type.h
  4. +3
    -0
      include/cpprtti/types/class_type.inl
  5. +10
    -0
      include/cpprtti/types/member/member_variable.h
  6. +6
    -0
      include/cpprtti/types/member/member_variable.inl

+ 10
- 0
include/cpprtti/misc/variant.h Näytä tiedosto

@@ -109,6 +109,11 @@ namespace cpprtti
template<typename T_to>
inline variant to() const;

/**
* @brief Convert this variant to another type.
*/
inline variant to(cpprtti::type_id id) const;

/**
* @brief Convert this variant to another type.
*/
@@ -129,6 +134,11 @@ namespace cpprtti
* @brief Check if the variant has a value assigned, if not throw an exception.
*/
inline void check_impl() const;

/**
* @brief Check if the passed type id is supported by the type stored in this variant.
*/
inline bool check_type(const cpprtti::type& t, type_id id) const;
};

constexpr decltype(auto) make_variant = cppmp::generic_predicate<__impl::variant_builder> { };


+ 54
- 2
include/cpprtti/misc/variant.inl Näytä tiedosto

@@ -8,6 +8,8 @@
#include <cppmp/core/conditionals.h>
#include <cppmp/misc/generic_predicate.h>

#include <cpprtti/types/class_type.h>

#include "variant.h"
#include "exception.h"
#include "../registry.h"
@@ -303,7 +305,7 @@ namespace cpprtti
{
check_impl();

if (_impl->type.id() != get_type_id<cppmp::decay_t<T>>())
if (!check_type(_impl->type, get_type_id<cppmp::decay_t<T>>()))
{
throw exception(
error_code::variant_type_mismatch,
@@ -326,7 +328,36 @@ namespace cpprtti
variant variant::to() const
{
using to_type = cppmp::decay_t<T_to>;
return to(get_type_id<to_type>());
auto * t = type().registry().find<to_type>();
if (!t)
{
throw exception(
error_code::variant_is_empty,
cppcore::string_builder()
<< "No known conversion from type '"
<< type().name()
<< "' to type '"
<< get_type_name<to_type>()
<< "'!");
}
return to(*t);
}

variant variant::to(cpprtti::type_id id) const
{
auto t = type().registry().find(id);
if (!t)
{
throw exception(
error_code::variant_is_empty,
cppcore::string_builder()
<< "No known conversion from type '"
<< type().name()
<< "' to type id '"
<< id
<< "'!");
}
return to(*t);
}

variant variant::to(const cpprtti::type& t) const
@@ -372,4 +403,25 @@ namespace cpprtti
}
}

bool variant::check_type(const cpprtti::type& t, type_id id) const
{
if (t.id() == id)
return true;

if (t.rtti_type() == cpprtti::rtti_type::class_type)
{
auto* _ct = dynamic_cast<const cpprtti::class_type*>(&t);
assert(_ct);
auto& ct = *_ct;

for (auto& kvp : ct.base_classes())
{
if (check_type(*kvp, id))
return true;
}
}

return false;
}

}

+ 5
- 0
include/cpprtti/types/class_type.h Näytä tiedosto

@@ -31,6 +31,11 @@ namespace cpprtti
type_id p_id,
const std::string& p_name);

/**
* @brief Get the vector of base classes.
*/
inline const class_type_vector& base_classes() const;

/**
* @brief Get a map of all registered members.
*/


+ 3
- 0
include/cpprtti/types/class_type.inl Näytä tiedosto

@@ -16,6 +16,9 @@ namespace cpprtti
: type(p_registry, p_id, p_name, rtti_type_t::class_type)
{ }

const class_type::class_type_vector& class_type::base_classes() const
{ return _base_classes; }

const member& class_type::member(
const std::string& p_name) const
{


+ 10
- 0
include/cpprtti/types/member/member_variable.h Näytä tiedosto

@@ -54,12 +54,22 @@ namespace cpprtti
template<typename T_object>
inline variant get(T_object& obj) const;

/**
* @brief Get the current value of the member.
*/
inline variant get(const variant& obj) const;

/**
* @brief Set the new value of the member.
*/
template<typename T_object, typename T_value>
inline void set(T_object& obj, const T_value& value) const;

/**
* @brief Set the new value of the member.
*/
inline void set(const variant& obj, const variant& value) const;

protected:
/**
* @brief Get the current value of the member.


+ 6
- 0
include/cpprtti/types/member/member_variable.inl Näytä tiedosto

@@ -47,6 +47,9 @@ namespace cpprtti
return get_impl(make_variant(_owner.registry(), obj));
}

variant member_variable::get(const variant& obj) const
{ return get_impl(obj); }

template<typename T_object, typename T_value>
inline void member_variable::set(T_object& obj, const T_value& value) const
{
@@ -64,6 +67,9 @@ namespace cpprtti
return set_impl(make_variant(_owner.registry(), obj), make_variant(_owner.registry(), value));
}

void member_variable::set(const variant& obj, const variant& value) const
{ return set_impl(obj, value); }

namespace __impl
{



Ladataan…
Peruuta
Tallenna