Skip to content

Commit

Permalink
Merge branch 'add_auto_conversion_from_wrapper'
Browse files Browse the repository at this point in the history
closed #48
  • Loading branch information
acki-m committed Mar 29, 2017
2 parents cf52aa5 + cdf63a9 commit 8dbbf79
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 21 deletions.
7 changes: 6 additions & 1 deletion src/rttr/detail/variant/variant_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,12 @@ RTTR_INLINE bool variant::convert(T& value) const

const type source_type = get_type();
const type target_type = type::get<T>();
if (target_type == source_type)
if (source_type.is_wrapper() && !target_type.is_wrapper())
{
variant var = extract_wrapped_value();
return var.convert<T>(value);
}
else if (target_type == source_type)
{
value = const_cast<variant&>(*this).get_value<T>();
ok = true;
Expand Down
9 changes: 8 additions & 1 deletion src/rttr/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ bool variant::can_convert(const type& target_type) const
if (!is_valid())
return false;

const type source_type = get_type();
type source_type = get_type();
source_type = (source_type.is_wrapper() && !target_type.is_wrapper()) ? source_type.get_wrapped_type() : source_type;

if (source_type == target_type)
return true;
Expand Down Expand Up @@ -261,6 +262,12 @@ bool variant::convert(const type& target_type, variant& target_var) const
target_var = *this;
return true; // the current variant is already the target type, we don't need to do anything
}
else if (source_type.is_wrapper() && !target_type.is_wrapper())
{
variant var = extract_wrapped_value();
ok = var.convert(target_type);
target_var = var;
}
else if ((source_is_arithmetic && target_is_arithmetic) ||
(source_is_arithmetic && target_type == string_type) ||
(source_type == string_type && target_is_arithmetic) ||
Expand Down
40 changes: 40 additions & 0 deletions src/unit_tests/variant/variant_conv_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,3 +631,43 @@ TEST_CASE("variant test - convert to nullptr", "[variant]")
}

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

TEST_CASE("variant test - convert from wrapped value", "[variant]")
{
SECTION("Invalid conversion")
{
int obj = 42;
variant var = std::ref(obj);

CHECK(var.can_convert(type::get<int>()) == true);

bool ok = false;
int val = var.convert<int>(&ok);
CHECK(ok == true);
CHECK(val == obj);

CHECK(var.convert(type::get<int>()) == true);

int val_2;
CHECK(var.convert<int>(val_2) == true);
CHECK(val_2 == obj);
}

SECTION("invalid conversion")
{
int obj = 42;
int* obj_ptr = &obj;
variant var = std::ref(obj_ptr);

// cannot convert from int* to int automatically
CHECK(var.can_convert(type::get<int>()) == false);

bool ok = false;
int val = var.convert<int>(&ok);
CHECK(ok == false);

CHECK(var.convert(type::get<int>()) == false);
}
}

/////////////////////////////////////////////////////////////////////////////////////////
Original file line number Diff line number Diff line change
Expand Up @@ -257,26 +257,26 @@ TEST_CASE("variant_associative_view::iterator operations", "[variant_associative
REQUIRE(itr != view.end());

itr++;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 2);
CHECK(itr.get_key().to_int() == 2);
itr--;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 1);
CHECK(itr.get_key().to_int() == 1);
++itr;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 2);
CHECK(itr.get_key().to_int() == 2);
--itr;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 1);
CHECK(itr.get_key().to_int() == 1);

itr = view.begin();
itr += 2;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 3);
CHECK(itr.get_key().to_int() == 3);
itr += 1;
itr -= 3;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 1);
CHECK(itr.get_key().to_int() == 1);

itr = view.begin();
itr = itr + 3;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 4);
CHECK(itr.get_key().to_int() == 4);
itr = itr - 3;
CHECK(itr.get_key().extract_wrapped_value().to_int() == 1);
CHECK(itr.get_key().to_int() == 1);
}

/////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -294,7 +294,7 @@ TEST_CASE("variant_associative_view::insert", "[variant_associative_view]")
auto ret = view.insert(1);
CHECK(ret.first != view.end());

CHECK(ret.first.get_key().extract_wrapped_value().to_int() == 1);
CHECK(ret.first.get_key().to_int() == 1);
CHECK(ret.first.get_value().is_valid() == false);
CHECK(ret.second == true);

Expand Down Expand Up @@ -342,8 +342,8 @@ TEST_CASE("variant_associative_view::insert", "[variant_associative_view]")

REQUIRE(ret.first != view.end());

CHECK(ret.first.get_key().extract_wrapped_value().to_int() == 1);
CHECK(ret.first.get_value().extract_wrapped_value().to_string() == "one");
CHECK(ret.first.get_key().to_int() == 1);
CHECK(ret.first.get_value().to_string() == "one");
CHECK(ret.second == true);

ret = view.insert(std::make_pair(std::string("one"), 1));
Expand Down Expand Up @@ -388,8 +388,8 @@ TEST_CASE("variant_associative_view::find", "[variant_associative_view]")
auto itr = view.find(1);

CHECK(itr != view.end());
CHECK(itr.get_key().extract_wrapped_value() == 1);
CHECK(itr.get_value().extract_wrapped_value() == "one");
CHECK(itr.get_key().to_int() == 1);
CHECK(itr.get_value().to_string() == "one");

// negative test
itr = view.find(4);
Expand Down Expand Up @@ -422,7 +422,7 @@ TEST_CASE("variant_associative_view::equal_range", "[variant_associative_view]")

for (auto itr = range.first; itr != range.second; ++itr)
{
CHECK(itr.get_key().extract_wrapped_value().to_int() == 3);
CHECK(itr.get_key().to_int() == 3);
}

// invalid equal_range search
Expand Down Expand Up @@ -456,11 +456,11 @@ TEST_CASE("variant_associative_view::equal_range", "[variant_associative_view]")
REQUIRE(count == 3);

auto itr = range.first;
CHECK(itr.get_value().extract_wrapped_value().to_string() == "B");
CHECK(itr.get_value().to_string() == "B");
++itr;
CHECK(itr.get_value().extract_wrapped_value().to_string() == "C");
CHECK(itr.get_value().to_string() == "C");
++itr;
CHECK(itr.get_value().extract_wrapped_value().to_string() == "D");
CHECK(itr.get_value().to_string() == "D");

++itr;
CHECK(itr == range.second);
Expand Down Expand Up @@ -593,13 +593,13 @@ TEST_CASE("variant_associative_view::begin/end", "[variant_associative_view]")
int i = 0;
for (auto& item : view)
{
CHECK(item.first.extract_wrapped_value().to_int() == ++i);
CHECK(item.first.to_int() == ++i);
}

auto itr_begin = view.begin();
if (itr_begin != view.end())
{
CHECK(itr_begin.get_key().extract_wrapped_value() == 1);
CHECK(itr_begin.get_key().to_int() == 1);
}
}

Expand Down

0 comments on commit 8dbbf79

Please sign in to comment.