Skip to content

Commit

Permalink
Merge branch 'adjust_variant_class'
Browse files Browse the repository at this point in the history
  • Loading branch information
acki-m committed Dec 8, 2016
2 parents 3881a31 + 64dd258 commit 47e5c11
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 46 deletions.
63 changes: 20 additions & 43 deletions src/examples/json_serialization/json_serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,35 +104,27 @@ void write_atomic_types_to_json(const type& t, const variant& var, PrettyWriter<

/////////////////////////////////////////////////////////////////////////////////////////

static void write_array(const variant_array_view& a,
const std::vector<std::size_t>& size_indices,
std::vector<std::size_t>& indices, PrettyWriter<StringBuffer>& writer)
static void write_array(const variant_array_view& a, PrettyWriter<StringBuffer>& writer)
{
writer.StartArray();
for (int i = 0; i < a.get_size_variadic(size_indices); i++)
for (int i = 0; i < a.get_size(); ++i)
{
if (!size_indices.empty())
indices[size_indices.size()] = i;
else
indices[0] = i;

if (size_indices.size() + 1 < a.get_rank())
variant var = a.get_value_as_ref(i);
if (var.is_array())
{
std::vector<std::size_t> new_size_indices = size_indices;
new_size_indices.push_back(i);
write_array(a, new_size_indices, indices, writer);
write_array(var.create_array_view(), writer);
}
else
{
variant value = a.get_value_variadic(indices);
type value_type = value.get_type();
variant wrapped_var = var.extract_wrapped_value();
type value_type = wrapped_var.get_type();
if (value_type.is_arithmetic() || value_type == type::get<std::string>() || value_type.is_enumeration())
{
write_atomic_types_to_json(value_type, value, writer);
write_atomic_types_to_json(value_type, wrapped_var, writer);
}
else // object
{
to_json_recursively(value, writer);
to_json_recursively(wrapped_var, writer);
}
}
}
Expand All @@ -141,15 +133,6 @@ static void write_array(const variant_array_view& a,

/////////////////////////////////////////////////////////////////////////////////////////

static void write_array(const variant_array_view& a, PrettyWriter<StringBuffer>& writer)
{
std::vector<std::size_t> indices(a.get_rank(), 0);
std::vector<std::size_t> size_indices;
write_array(a, size_indices, indices, writer);
}

/////////////////////////////////////////////////////////////////////////////////////////

void to_json_recursively(const instance& obj2, PrettyWriter<StringBuffer>& writer)
{
writer.StartObject();
Expand Down Expand Up @@ -238,34 +221,30 @@ variant extract_basic_types(Value& json_value)

/////////////////////////////////////////////////////////////////////////////////////////

void write_array_recursively(variant_array_view& var_array, Value& json_array_value,
const std::vector<std::size_t>& size_indices,
std::vector<std::size_t>& indices)
void write_array_recursively(variant_array_view& var_array, Value& json_array_value)
{
var_array.set_size_variadic(json_array_value.Size(), size_indices);
const auto rank = size_indices.size();
const type array_type = var_array.get_rank_type(rank + 1);
var_array.set_size(json_array_value.Size());
for (SizeType i = 0; i < json_array_value.Size(); ++i)
{
auto& json_index_value = json_array_value[i];
indices[rank] = i;
if (json_index_value.IsArray())
{
std::vector<std::size_t> new_size_indices = size_indices;
new_size_indices.push_back(i);
write_array_recursively(var_array, json_index_value, new_size_indices, indices);
auto sub_array_view = var_array.get_value_as_ref(i).create_array_view();
write_array_recursively(sub_array_view, json_index_value);
}
else if (json_index_value.IsObject())
{
variant var_tmp = var_array.get_value_variadic(indices);
fromjson_recursively(var_tmp, json_index_value);
var_array.set_value_variadic(indices, var_tmp);
variant var_tmp = var_array.get_value_as_ref(i);
variant wrapped_var = var_tmp.extract_wrapped_value();
fromjson_recursively(wrapped_var, json_index_value);
var_array.set_value(i, wrapped_var);
}
else
{
const type array_type = var_array.get_rank_type(i);
variant extracted_value = extract_basic_types(json_index_value);
if (extracted_value.convert(array_type))
var_array.set_value_variadic(indices, extracted_value);
var_array.set_value(i, extracted_value);
}
}
}
Expand All @@ -292,9 +271,7 @@ void fromjson_recursively(instance obj2, Value& json_object)
{
variant var = prop.get_value(obj);
auto array_view = var.create_array_view();
std::vector<std::size_t> indices(array_view.get_rank(), 0);
std::vector<std::size_t> size_indices;
write_array_recursively(array_view, json_value, size_indices, indices);
write_array_recursively(array_view, json_value);

prop.set_value(obj, var);
break;
Expand Down
4 changes: 3 additions & 1 deletion src/examples/json_serialization/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
#include <string>
#include <vector>
#include <array>

#include <iostream>

#include <rttr/registration>

#include "json_serialize.h"

using namespace rttr;
Expand Down Expand Up @@ -142,6 +143,7 @@ int main(int argc, char** argv)
std::cout << "\n############################################\n" << std::endl;

std::cout << "Circle c_2:\n" << io::to_json(c_2) << std::endl;

return 0;
}

5 changes: 5 additions & 0 deletions src/rttr/detail/array/array_accessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ struct array_accessor

/////////////////////////////////////////////////////////////////////////////////////////

static variant get_value_as_ref(Array_Type& array, std::size_t index_1);
static variant get_value_as_ref(const Array_Type& array, std::size_t index_1);

/////////////////////////////////////////////////////////////////////////////////////////

template<typename... Indices>
static bool set_value(const Array_Type&, argument&, Indices... indices);
static bool set_value(const Array_Type&, argument&, const std::vector<std::size_t>&);
Expand Down
71 changes: 71 additions & 0 deletions src/rttr/detail/array/array_accessor_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,20 @@ struct array_accessor_impl<Array_Type, std::true_type>

/////////////////////////////////////////////////////////////////////////////////////////

static variant get_value_as_ref(Array_Type& obj, std::size_t index_1)
{
return variant(std::ref(array_mapper<Array_Type>::get_value(obj, index_1)));
}

/////////////////////////////////////////////////////////////////////////////////////////

static variant get_value_as_ref(const Array_Type& obj, std::size_t index_1)
{
return variant(std::cref(array_mapper<Array_Type>::get_value(obj, index_1)));
}

/////////////////////////////////////////////////////////////////////////////////////////

template<typename... Indices>
static bool set_value(Array_Type& obj, argument& arg, Indices... indices)
{
Expand Down Expand Up @@ -402,6 +416,20 @@ struct array_accessor_impl<Array_Type, std::false_type>

/////////////////////////////////////////////////////////////////////////////////////////

static variant get_value_as_ref(Array_Type& obj, std::size_t index_1)
{
return variant();
}

/////////////////////////////////////////////////////////////////////////////////////////

static variant get_value_as_ref(const Array_Type& obj, std::size_t index_1)
{
return variant();
}

/////////////////////////////////////////////////////////////////////////////////////////

template<typename... Indices>
static bool set_value(Array_Type& obj, argument& arg, Indices... indices)
{
Expand Down Expand Up @@ -696,6 +724,49 @@ variant array_accessor<Array_Type>::get_value(const Array_Type& array, const std
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

template<typename Array_Type>
variant array_accessor<Array_Type>::get_value_as_ref(Array_Type& array, std::size_t index)
{
const bool is_rank_in_range = std::integral_constant<bool, (1 <= rank<Array_Type>::value) >::value;
const bool is_returning_by_reference = std::is_reference<decltype(array_mapper<Array_Type>::get_value(array, index))>::value;

#if RTTR_COMPILER == RTTR_COMPILER_MSVC && RTTR_COMP_VER <= 1800
// the compiler has a bug:
// int foo[2];
// auto bar = std::ref(foo);
// does not compile..., so we disable the compilation for this
using cond = typename std::integral_constant<bool, is_rank_in_range && is_returning_by_reference && !std::is_array<Array_Type>::value>::type;
#else
using cond = typename std::integral_constant<bool, is_rank_in_range && is_returning_by_reference>::type;
#endif

return array_accessor_impl<Array_Type, cond>::get_value_as_ref(array, index);
}

/////////////////////////////////////////////////////////////////////////////////////////

template<typename Array_Type>
variant array_accessor<Array_Type>::get_value_as_ref(const Array_Type& array, std::size_t index)
{
const bool is_rank_in_range = std::integral_constant<bool, (1 <= rank<Array_Type>::value) >::value;
const bool is_returning_by_reference = std::is_reference<decltype(array_mapper<Array_Type>::get_value(array, index))>::value;

#if RTTR_COMPILER == RTTR_COMPILER_MSVC && RTTR_COMP_VER <= 1800
// the compiler has a bug:
// int foo[2];
// auto bar = std::ref(foo);
// does not compile..., so we disable the compilation for this
using cond = typename std::integral_constant<bool, is_rank_in_range && is_returning_by_reference && !std::is_array<Array_Type>::value>::type;
#else
using cond = typename std::integral_constant<bool, is_rank_in_range && is_returning_by_reference>::type;
#endif

return array_accessor_impl<Array_Type, cond>::get_value_as_ref(array, index);
}

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////

template<typename Array_Type>
template<typename... Indices>
bool array_accessor<Array_Type>::set_value(const Array_Type&, argument&, Indices... indices) { return false; }
Expand Down
7 changes: 7 additions & 0 deletions src/rttr/detail/array/array_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ class array_wrapper : public array_wrapper_base

/////////////////////////////////////////////////////////////////////////////////////////

variant get_value_as_ref(std::size_t index_1) const
{
return array_accessor<Array_Type>::get_value_as_ref(*m_address_data, index_1);
}

/////////////////////////////////////////////////////////////////////////////////////////

bool insert_value(std::size_t index_1, argument& arg)
{
return array_accessor<Array_Type>::insert_value(*m_address_data, arg, index_1);
Expand Down
2 changes: 2 additions & 0 deletions src/rttr/detail/array/array_wrapper_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class RTTR_API array_wrapper_base
virtual variant get_value(std::size_t index_1, std::size_t index_2, std::size_t index_3) const { return variant(); }
virtual variant get_value_variadic(const std::vector<std::size_t>& index_list) const { return variant(); }

virtual variant get_value_as_ref(std::size_t index_1) const { return variant(); }

virtual bool insert_value(std::size_t index_1, argument& arg) { return false; }
virtual bool insert_value(std::size_t index_1, std::size_t index_2, argument& arg) { return false; }
virtual bool insert_value(std::size_t index_1, std::size_t index_2, std::size_t index_3, argument& arg) { return false; }
Expand Down
10 changes: 10 additions & 0 deletions src/rttr/detail/misc/misc_type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,17 @@ namespace detail

template<typename T1, typename T2>
using is_same_nullptr = typename is_same_nullptr_impl<T1, T2>::type;
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// workaround, because MSVC 2013 can't handle deleted copy-ctors very well; specialize for further types here
template<typename T>
struct is_copy_constructible : std::is_copy_constructible<T>{};

template<typename T>
struct is_copy_constructible<std::unique_ptr<T>> : std::false_type {};

/////////////////////////////////////////////////////////////////////////////////////////
} // end namespace detail
} // end namespace rttr

Expand Down
42 changes: 41 additions & 1 deletion src/rttr/detail/variant/variant_data_policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ enum class variant_policy_operation : uint8_t
DESTROY,
CLONE,
SWAP,
EXTRACT_WRAPPED_VALUE,
GET_VALUE,
GET_TYPE,
GET_PTR,
Expand Down Expand Up @@ -176,6 +177,35 @@ static RTTR_INLINE is_nullptr(T& to)
return false;
}

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
#if RTTR_COMPILER == RTTR_COMPILER_MSVC && RTTR_COMP_VER <= 1800
// MSVC 2013 has not a full working "std::is_copy_constructible", thats why
// this workaround is used here
template<typename T>
using is_copyable = ::rttr::detail::is_copy_constructible<T>;
#else
template<typename T>
using is_copyable = std::is_copy_constructible<T>;
#endif

template<typename T, typename Tp = decay_except_array_t<wrapper_mapper_t<T>> >
enable_if_t<is_copyable<Tp>::value &&
is_wrapper<T>::value, variant> get_wrapped_value(T& value)
{
using raw_wrapper_type = remove_cv_t<remove_reference_t<T>>;
return variant(wrapper_mapper<raw_wrapper_type>::get(value));
}

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T, typename Tp = decay_except_array_t<wrapper_mapper_t<T>>>
enable_if_t<!is_copyable<Tp>::value ||
!is_wrapper<T>::value, variant> get_wrapped_value(T& value)
{
return variant();
}

/////////////////////////////////////////////////////////////////////////////////////////

/*!
Expand Down Expand Up @@ -207,6 +237,11 @@ struct variant_data_base_policy
Tp::swap(const_cast<T&>(Tp::get_value(src_data)), arg.get_value<variant_data>());
break;
}
case variant_policy_operation::EXTRACT_WRAPPED_VALUE:
{
arg.get_value<variant>() = get_wrapped_value(Tp::get_value(src_data));
break;
}
case variant_policy_operation::GET_VALUE:
{
arg.get_value<const void*>() = &Tp::get_value(src_data);
Expand Down Expand Up @@ -244,7 +279,7 @@ struct variant_data_base_policy
}
case variant_policy_operation::IS_ARRAY:
{
return ::rttr::detail::is_array<typename raw_type<T>::type>::value;
return can_create_array_container<T>::value;
}
case variant_policy_operation::TO_ARRAY:
{
Expand Down Expand Up @@ -662,6 +697,7 @@ struct RTTR_API variant_data_policy_void
case variant_policy_operation::DESTROY:
case variant_policy_operation::CLONE:
case variant_policy_operation::SWAP:
case variant_policy_operation::EXTRACT_WRAPPED_VALUE:
{
break;
}
Expand Down Expand Up @@ -794,6 +830,10 @@ struct RTTR_API variant_data_policy_nullptr_t
swap(get_value(src_data), arg.get_value<variant_data>());
break;
}
case variant_policy_operation::EXTRACT_WRAPPED_VALUE:
{
break;
}
case variant_policy_operation::GET_VALUE:
{
arg.get_value<const void*>() = &get_value(src_data);
Expand Down
11 changes: 11 additions & 0 deletions src/rttr/detail/variant/variant_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ RTTR_INLINE const T& variant::get_value() const

/////////////////////////////////////////////////////////////////////////////////////////

template<typename T>
RTTR_INLINE const T& variant::get_wrapped_value() const
{
detail::data_address_container result{detail::get_invalid_type(), detail::get_invalid_type(), nullptr, nullptr};
m_policy(detail::variant_policy_operation::GET_ADDRESS_CONTAINER, m_data, result);
using nonRef = detail::remove_cv_t<T>;
return *reinterpret_cast<const nonRef*>(result.m_data_address_wrapped_type);
}

/////////////////////////////////////////////////////////////////////////////////////////

RTTR_INLINE void* variant::get_ptr() const
{
void* value;
Expand Down
9 changes: 9 additions & 0 deletions src/rttr/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ type variant::get_type() const

/////////////////////////////////////////////////////////////////////////////////////////

variant variant::extract_wrapped_value() const
{
variant var;
m_policy(detail::variant_policy_operation::EXTRACT_WRAPPED_VALUE, m_data, var);
return var;
}

/////////////////////////////////////////////////////////////////////////////////////////

variant_array_view variant::create_array_view() const
{
variant_array_view result;
Expand Down
Loading

0 comments on commit 47e5c11

Please # to comment.