Skip to content

Commit

Permalink
Merge pull request #114 from mapbox/strict-conversions
Browse files Browse the repository at this point in the history
Strict conversions
  • Loading branch information
artemp committed Jul 26, 2016
2 parents c511b2f + 075d963 commit 388376a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
19 changes: 18 additions & 1 deletion include/mapbox/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,30 @@ struct convertible_type<T>
static constexpr std::size_t index = invalid_value;
};


template <typename T, typename... Types>
struct count_convertibles;

template <typename T, typename First, typename... Types>
struct count_convertibles<T, First, Types...>
{
static constexpr std::size_t value = (std::is_convertible<T, First>::value ? 1 : 0) + count_convertibles<T,Types...>::value;
};

template <typename T>
struct count_convertibles<T>
{
static constexpr std::size_t value = 0;
};

template <typename T, typename... Types>
struct value_traits
{
using value_type = typename std::remove_const<typename std::remove_reference<T>::type>::type;
static constexpr std::size_t direct_index = direct_type<value_type, Types...>::index;
static constexpr bool is_direct = direct_index != invalid_value;
static constexpr std::size_t index = is_direct ? direct_index : convertible_type<value_type, Types...>::index;
static constexpr std::size_t index = is_direct ? direct_index : count_convertibles<value_type, Types...>::value == 1
? convertible_type<value_type, Types...>::index : invalid_value;
static constexpr bool is_valid = index != invalid_value;
static constexpr std::size_t tindex = is_valid ? sizeof...(Types)-index : 0;
using target_type = typename std::tuple_element<tindex, std::tuple<void, Types...>>::type;
Expand Down
10 changes: 8 additions & 2 deletions test/t/issue21.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#include "catch.hpp"

#include <mapbox/variant.hpp>
Expand All @@ -11,6 +10,12 @@ static int count;
struct t1
{
int value;

t1(t1 const& rhs)
: value(rhs.value)
{
++count;
}
t1(int v) : value(v)
{
++count;
Expand All @@ -37,7 +42,8 @@ TEST_CASE("set() works cleanly even if the constructor throws ", "[variant]")

count = 0;
{
variant_type v{42};
t1 obj{42};
variant_type v = obj;
REQUIRE(v.is<t1>());
REQUIRE(v.get<t1>().value == 42);
REQUIRE_THROWS({
Expand Down
2 changes: 1 addition & 1 deletion test/t/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ TEST_CASE("implicit conversion", "[variant][implicit conversion]")
TEST_CASE("implicit conversion to first type in variant type list", "[variant][implicit conversion]")
{
using variant_type = mapbox::util::variant<long, char>;
variant_type var = 5.0; // converted to long
variant_type var = 5l; // converted to long
REQUIRE(var.get<long>() == 5);
REQUIRE_THROWS_AS({
var.get<char>();
Expand Down

0 comments on commit 388376a

Please sign in to comment.