Squashed 'third_party/variant/' changes from 24dcab2..3b02ca0
3b02ca0 add which() method returning zero based index of stored T in Types... for boost::variant() compatibility c117592 update unit test to match c64c74775a80474f2012c1a49ab2865e3666107a 36f1e12 add get<T>() overloads for when T is stored in recursive_wrapper<T> also makes get<T>() a compile time error where T is not in Types... (ref #24) 7dfdfa2 clean up coverage files in test directory too [skip ci] 89f8a41 add coverage report git-subtree-dir: third_party/variant git-subtree-split: 3b02ca0e3ab1a36dd6ec9138e7f93eb3176ae5f7
This commit is contained in:
parent
884c998622
commit
76674a3594
2
Makefile
2
Makefile
@ -89,6 +89,8 @@ clean:
|
|||||||
rm -rf *.dSYM
|
rm -rf *.dSYM
|
||||||
rm -f unit.gc*
|
rm -f unit.gc*
|
||||||
rm -f *gcov
|
rm -f *gcov
|
||||||
|
rm -f test/unit.gc*
|
||||||
|
rm -f test/*gcov
|
||||||
|
|
||||||
pgo: out Makefile variant.hpp
|
pgo: out Makefile variant.hpp
|
||||||
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS) -pg -fprofile-generate
|
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS) -pg -fprofile-generate
|
||||||
|
@ -4,6 +4,7 @@ An alternative to `boost::variant` for C++11.
|
|||||||
|
|
||||||
[](https://travis-ci.org/mapbox/variant)
|
[](https://travis-ci.org/mapbox/variant)
|
||||||
[](https://ci.appveyor.com/project/Mapbox/variant)
|
[](https://ci.appveyor.com/project/Mapbox/variant)
|
||||||
|
[](https://coveralls.io/r/mapbox/variant?branch=master)
|
||||||
|
|
||||||
# Why use Mapbox Variant?
|
# Why use Mapbox Variant?
|
||||||
|
|
||||||
|
@ -212,11 +212,22 @@ TEST_CASE( "variant should correctly index types", "[variant]" ) {
|
|||||||
REQUIRE(variant_type(float(0.0)).get_type_index() == 0);
|
REQUIRE(variant_type(float(0.0)).get_type_index() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test internal api
|
||||||
|
TEST_CASE( "variant::which() returns zero based index of stored type", "[variant]" ) {
|
||||||
|
typedef util::variant<bool,std::string,std::uint64_t,std::int64_t,double,float> variant_type;
|
||||||
|
// Index is in reverse order
|
||||||
|
REQUIRE(variant_type(true).which() == 0);
|
||||||
|
REQUIRE(variant_type(std::string("test")).which() == 1);
|
||||||
|
REQUIRE(variant_type(std::uint64_t(0)).which() == 2);
|
||||||
|
REQUIRE(variant_type(std::int64_t(0)).which() == 3);
|
||||||
|
REQUIRE(variant_type(double(0.0)).which() == 4);
|
||||||
|
REQUIRE(variant_type(float(0.0)).which() == 5);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE( "get with type not in variant type list should throw", "[variant]" ) {
|
TEST_CASE( "get with type not in variant type list should throw", "[variant]" ) {
|
||||||
typedef util::variant<int> variant_type;
|
typedef util::variant<int> variant_type;
|
||||||
variant_type var = 5;
|
variant_type var = 5;
|
||||||
REQUIRE(var.get<int>() == 5);
|
REQUIRE(var.get<int>() == 5);
|
||||||
REQUIRE_THROWS(var.get<double>()); // XXX shouldn't this be a compile time error? See https://github.com/mapbox/variant/issues/24
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "get with wrong type (here: double) should throw", "[variant]" ) {
|
TEST_CASE( "get with wrong type (here: double) should throw", "[variant]" ) {
|
||||||
@ -237,7 +248,6 @@ TEST_CASE( "implicit conversion", "[variant][implicit conversion]" ) {
|
|||||||
typedef util::variant<int> variant_type;
|
typedef util::variant<int> variant_type;
|
||||||
variant_type var(5.0); // converted to int
|
variant_type var(5.0); // converted to int
|
||||||
REQUIRE(var.get<int>() == 5);
|
REQUIRE(var.get<int>() == 5);
|
||||||
REQUIRE_THROWS(var.get<double>());
|
|
||||||
var = 6.0; // works for operator=, too
|
var = 6.0; // works for operator=, too
|
||||||
REQUIRE(var.get<int>() == 6);
|
REQUIRE(var.get<int>() == 6);
|
||||||
}
|
}
|
||||||
@ -247,7 +257,6 @@ TEST_CASE( "implicit conversion to first type in variant type list", "[variant][
|
|||||||
variant_type var = 5.0; // converted to long
|
variant_type var = 5.0; // converted to long
|
||||||
REQUIRE(var.get<long>() == 5);
|
REQUIRE(var.get<long>() == 5);
|
||||||
REQUIRE_THROWS(var.get<char>());
|
REQUIRE_THROWS(var.get<char>());
|
||||||
REQUIRE_THROWS(var.get<double>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "implicit conversion to unsigned char", "[variant][implicit conversion]" ) {
|
TEST_CASE( "implicit conversion to unsigned char", "[variant][implicit conversion]" ) {
|
||||||
@ -297,7 +306,6 @@ TEST_CASE( "variant printer", "[visitor][unary visitor][printer]" ) {
|
|||||||
REQUIRE(out.str() == "2.1,123,foo,456,foo");
|
REQUIRE(out.str() == "2.1,123,foo,456,foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char* const argv[])
|
int main (int argc, char* const argv[])
|
||||||
{
|
{
|
||||||
int result = Catch::Session().run(argc, argv);
|
int result = Catch::Session().run(argc, argv);
|
||||||
|
46
variant.hpp
46
variant.hpp
@ -601,7 +601,8 @@ public:
|
|||||||
type_index = detail::direct_type<T, Types...>::index;
|
type_index = detail::direct_type<T, Types...>::index;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
// get<T>()
|
||||||
|
template<typename T, typename std::enable_if<(detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
|
||||||
VARIANT_INLINE T& get()
|
VARIANT_INLINE T& get()
|
||||||
{
|
{
|
||||||
if (type_index == detail::direct_type<T, Types...>::index)
|
if (type_index == detail::direct_type<T, Types...>::index)
|
||||||
@ -610,11 +611,13 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::runtime_error("in get()");
|
throw std::runtime_error("in get<T>()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T, typename std::enable_if<
|
||||||
|
(detail::direct_type<T, Types...>::index != detail::invalid_value)
|
||||||
|
>::type* = nullptr>
|
||||||
VARIANT_INLINE T const& get() const
|
VARIANT_INLINE T const& get() const
|
||||||
{
|
{
|
||||||
if (type_index == detail::direct_type<T, Types...>::index)
|
if (type_index == detail::direct_type<T, Types...>::index)
|
||||||
@ -623,15 +626,50 @@ public:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::runtime_error("in get()");
|
throw std::runtime_error("in get<T>()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get<T>() - T stored as recursive_wrapper<T>
|
||||||
|
template <typename T, typename std::enable_if<
|
||||||
|
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||||
|
>::type* = nullptr>
|
||||||
|
VARIANT_INLINE T& get()
|
||||||
|
{
|
||||||
|
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||||
|
{
|
||||||
|
return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("in get<T>()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T,typename std::enable_if<
|
||||||
|
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||||
|
>::type* = nullptr>
|
||||||
|
VARIANT_INLINE T const& get() const
|
||||||
|
{
|
||||||
|
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||||
|
{
|
||||||
|
return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw std::runtime_error("in get<T>()");
|
||||||
|
}
|
||||||
|
}
|
||||||
VARIANT_INLINE std::size_t get_type_index() const
|
VARIANT_INLINE std::size_t get_type_index() const
|
||||||
{
|
{
|
||||||
return type_index;
|
return type_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VARIANT_INLINE int which() const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<int>(sizeof...(Types) - type_index - 1);
|
||||||
|
}
|
||||||
|
|
||||||
// visitor
|
// visitor
|
||||||
// unary
|
// unary
|
||||||
template <typename F, typename V>
|
template <typename F, typename V>
|
||||||
|
Loading…
Reference in New Issue
Block a user