Upgrade to mapbox/variant 1.1.4

This commit is contained in:
Daniel Patterson
2016-12-01 15:44:27 -08:00
parent 20c8ac0272
commit 29b3caf529
44 changed files with 936 additions and 286 deletions
+7 -8
View File
@@ -1,4 +1,3 @@
#include <algorithm>
#include <cstdlib>
#include <iostream>
@@ -8,10 +7,10 @@
#include <utility>
#include <vector>
#include <boost/timer/timer.hpp>
#include <boost/variant.hpp>
#include "auto_cpu_timer.hpp"
#include "variant.hpp"
#include <boost/variant.hpp>
#include <mapbox/variant.hpp>
#define TEXT_SHORT "Test"
#define TEXT_LONG "Testing various variant implementations with a longish string ........................................."
@@ -140,12 +139,12 @@ int main(int argc, char** argv)
{
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer t;
auto_cpu_timer t;
run_variant_test(NUM_RUNS);
}
{
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer t;
auto_cpu_timer t;
run_boost_test(NUM_RUNS);
}
}
@@ -158,7 +157,7 @@ int main(int argc, char** argv)
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer timer;
auto_cpu_timer timer;
for (std::size_t i = 0; i < THREADS; ++i)
{
tg.emplace_back(new std::thread(run_variant_test, NUM_RUNS));
@@ -171,7 +170,7 @@ int main(int argc, char** argv)
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer timer;
auto_cpu_timer timer;
for (std::size_t i = 0; i < THREADS; ++i)
{
tg.emplace_back(new std::thread(run_boost_test, NUM_RUNS));
+2 -2
View File
@@ -9,8 +9,8 @@
#include <utility>
#include <vector>
#include "variant.hpp"
#include "variant_io.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
using namespace mapbox;
@@ -1,7 +1,6 @@
// @EXPECTED: First type in variant must be default constructible to allow default construction of variant
#include <variant.hpp>
#include <mapbox/variant.hpp>
// Checks that the first type in a variant must be default constructible to
// make the variant default constructible.
@@ -1,7 +1,6 @@
// @EXPECTED: Template parameter type list of variant can not be empty
#include <variant.hpp>
#include <mapbox/variant.hpp>
// Empty type list should not work.
+1 -2
View File
@@ -1,7 +1,6 @@
// @EXPECTED:
#include <variant.hpp>
#include <mapbox/variant.hpp>
int main()
{
+1 -2
View File
@@ -1,7 +1,6 @@
// @EXPECTED: enable_if
#include <variant.hpp>
#include <mapbox/variant.hpp>
int main()
{
+2 -3
View File
@@ -1,7 +1,6 @@
// @EXPECTED:
// @EXPECTED: invalid type in T in `is<T>()` for this variant
#include <variant.hpp>
#include <mapbox/variant.hpp>
int main()
{
@@ -1,7 +1,6 @@
// @EXPECTED: const int
#include <variant.hpp>
#include <mapbox/variant.hpp>
struct mutating_visitor
{
@@ -1,7 +1,6 @@
// @EXPECTED: Variant can not hold reference types
#include <variant.hpp>
#include <mapbox/variant.hpp>
int main()
{
+158
View File
@@ -0,0 +1,158 @@
#include <cstddef>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
#include <unordered_set>
#include <utility>
#include <mapbox/variant.hpp>
using namespace mapbox::util;
void test_singleton()
{
using V = variant<int>;
V singleton = 5;
if (std::hash<V>{}(singleton) != std::hash<int>{}(5))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
void test_default_hashable()
{
using V = variant<int, double, std::string>;
V var;
// Check int hashes
var = 1;
if (std::hash<V>{}(var) != std::hash<int>{}(1))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
// Check double hashes
var = 23.4;
if (std::hash<V>{}(var) != std::hash<double>{}(23.4))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
// Check string hashes
var = std::string{"Hello, World!"};
if (std::hash<V>{}(var) != std::hash<std::string>{}("Hello, World!"))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
struct Hashable
{
static const constexpr auto const_hash = 5;
};
namespace std {
template <>
struct hash<Hashable>
{
std::size_t operator()(const Hashable&) const noexcept
{
return Hashable::const_hash;
}
};
}
void test_custom_hasher()
{
using V = variant<int, Hashable, double>;
V var;
var = Hashable{};
if (std::hash<V>{}(var) != Hashable::const_hash)
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
void test_hashable_in_container()
{
using V = variant<int, std::string, double>;
// won't compile if V is not Hashable
std::unordered_set<V> vs;
vs.insert(1);
vs.insert(2.3);
vs.insert("4");
}
struct Empty
{
};
struct Node;
using Tree = variant<Empty, recursive_wrapper<Node>>;
struct Node
{
Node(Tree left_, Tree right_) : left(std::move(left_)), right(std::move(right_)) {}
Tree left = Empty{};
Tree right = Empty{};
};
namespace std {
template <>
struct hash<Empty>
{
std::size_t operator()(const Empty&) const noexcept
{
return 3;
}
};
template <>
struct hash<Node>
{
std::size_t operator()(const Node& n) const noexcept
{
return 5 + std::hash<Tree>{}(n.left) + std::hash<Tree>{}(n.right);
}
};
}
void test_recursive_hashable()
{
Tree tree = Node{Node{Empty{}, Empty{}}, Empty{}};
if (std::hash<Tree>{}(tree) != ((5 + (5 + (3 + 3))) + 3))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
int main()
{
test_singleton();
test_default_hashable();
test_custom_hasher();
test_hashable_in_container();
test_recursive_hashable();
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <chrono>
#include <iostream>
struct auto_cpu_timer {
std::chrono::time_point<std::chrono::high_resolution_clock> start;
auto_cpu_timer() : start(std::chrono::high_resolution_clock::now()) {
}
~auto_cpu_timer() {
auto end = std::chrono::high_resolution_clock::now();
std::chrono::microseconds elapsed =
std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cerr << elapsed.count() << "us" << std::endl;
}
};
+127
View File
@@ -0,0 +1,127 @@
#include <iostream>
#include <vector>
#include <mapbox/variant.hpp>
#include <mapbox/variant_visitor.hpp>
#if __cplusplus >= 201402L
#define HAS_CPP14_SUPPORT
#endif
using namespace mapbox::util;
template <typename Left, typename Right>
using Either = mapbox::util::variant<Left, Right>;
struct Response
{
};
struct Error
{
};
void test_lambda_overloads()
{
Either<Error, Response> rv;
rv = Response{};
auto visitor = make_visitor([](Response) { std::cout << "Response\n"; }, //
[](Error) { std::cout << "Error\n"; }); //
apply_visitor(visitor, rv);
}
void test_lambda_overloads_capture()
{
Either<Error, Response> rv;
rv = Error{};
int ok = 0;
int err = 0;
auto visitor = make_visitor([&](Response) { ok += 1; }, //
[&](Error) { err += 1; }); //
apply_visitor(visitor, rv);
std::cout << "Got " << ok << " ok, " << err << " err" << std::endl;
}
void test_singleton_variant()
{
variant<int> singleton;
apply_visitor(make_visitor([](int) {}), singleton);
}
void test_lambda_overloads_sfinae()
#ifdef HAS_CPP14_SUPPORT
{
variant<int, float, std::vector<int>> var;
auto visitor = make_visitor([](auto range) -> decltype(std::begin(range), void()) {
for (auto each : range)
std::cout << each << ' '; },
[](auto x) -> decltype(std::cout << x, void()) {
std::cout << x << std::endl;
});
var = 1;
apply_visitor(visitor, var);
var = 2.f;
apply_visitor(visitor, var);
var = std::vector<int>{4, 5, 6};
apply_visitor(visitor, var);
}
#else
{
}
#endif
void test_match_singleton()
{
variant<int> singleton = 5;
singleton.match([](int) {});
}
void test_match_overloads()
{
Either<Error, Response> rv;
rv = Response{};
rv.match([](Response) { std::cout << "Response\n"; }, //
[](Error) { std::cout << "Error\n"; }); //
}
void test_match_overloads_capture()
{
Either<Error, Response> rv;
rv = Error{};
int ok = 0;
int err = 0;
rv.match([&](Response) { ok += 1; }, //
[&](Error) { err += 1; }); //
std::cout << "Got " << ok << " ok, " << err << " err" << std::endl;
}
int main()
{
test_lambda_overloads();
test_singleton_variant();
test_lambda_overloads_capture();
test_lambda_overloads_sfinae();
test_match_singleton();
test_match_overloads();
test_match_overloads_capture();
}
#undef HAS_CPP14_SUPPORT
+1 -1
View File
@@ -1,4 +1,4 @@
#include "variant.hpp"
#include <mapbox/variant.hpp>
#include <stdexcept>
+3 -3
View File
@@ -5,9 +5,9 @@
#include <typeinfo>
#include <utility>
#include <boost/timer/timer.hpp>
#include "auto_cpu_timer.hpp"
#include "variant.hpp"
#include <mapbox/variant.hpp>
using namespace mapbox;
@@ -111,7 +111,7 @@ int main(int argc, char** argv)
int total = 0;
{
boost::timer::auto_cpu_timer t;
auto_cpu_timer t;
for (std::size_t i = 0; i < NUM_ITER; ++i)
{
total += util::apply_visitor(test::calculator(), result);
+5 -2
View File
@@ -6,7 +6,7 @@
#include <utility>
#include <vector>
#include "variant.hpp"
#include <mapbox/variant.hpp>
using namespace mapbox;
@@ -41,9 +41,12 @@ struct print
void operator()(line_string const& line) const
{
std::cerr << "Line(";
bool first = true;
for (auto const& pt : line)
{
std::cerr << pt.x << " " << pt.y << ",";
if (!first) std::cerr << ",";
std::cerr << pt.x << " " << pt.y;
if (first) first = false;
}
std::cerr << ")" << std::endl;
}
+1 -1
View File
@@ -1,5 +1,5 @@
#include "variant.hpp"
#include <mapbox/variant.hpp>
#define NAME_EXT " i-d"
using variant_type = mapbox::util::variant<int, double>;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "variant.hpp"
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-d"
using variant_type = mapbox::util::variant<bool, int, double>;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "variant.hpp"
#include <mapbox/variant.hpp>
#define NAME_EXT " i-d-b"
using variant_type = mapbox::util::variant<int, double, bool>;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "variant.hpp"
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-d-c"
using variant_type = mapbox::util::variant<bool, int, double, char>;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "variant.hpp"
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-c-d-i"
using variant_type = mapbox::util::variant<bool, int, char, double, int>;
+1 -1
View File
@@ -1,5 +1,5 @@
#include "variant.hpp"
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-i-d-c-u"
using variant_type = mapbox::util::variant<bool, int, int, double, char, short int>;
+1 -1
View File
@@ -3,7 +3,7 @@
#include "catch.hpp"
#include "variant_io.hpp"
#include <mapbox/variant_io.hpp>
struct add_visitor
{
+20
View File
@@ -0,0 +1,20 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
// https://github.com/mapbox/variant/issues/122
struct X
{
template <typename ValueType>
X(const ValueType&) {}
};
TEST_CASE("Correctly choose appropriate constructor", "[variant]")
{
mapbox::util::variant<X, int> a{123};
decltype(a) b(a);
REQUIRE(a.which() == b.which());
}
+10 -4
View File
@@ -1,8 +1,7 @@
#include "catch.hpp"
#include "variant.hpp"
#include "variant_io.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
// https://github.com/mapbox/variant/issues/21
@@ -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;
@@ -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({
+2 -2
View File
@@ -1,8 +1,8 @@
#include "catch.hpp"
#include "variant.hpp"
#include "variant_io.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
#include <string>
+1 -1
View File
@@ -1,7 +1,7 @@
#include "catch.hpp"
#include "optional.hpp"
#include <mapbox/optional.hpp>
struct dummy
{
+1 -1
View File
@@ -1,7 +1,7 @@
#include "catch.hpp"
#include "recursive_wrapper.hpp"
#include <mapbox/recursive_wrapper.hpp>
#include <type_traits>
#include <utility>
+2 -2
View File
@@ -5,8 +5,8 @@
#include "catch.hpp"
#include "variant.hpp"
#include "variant_io.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
struct some_struct
{
+2 -2
View File
@@ -1,8 +1,8 @@
#include "catch.hpp"
#include "variant.hpp"
#include "variant_io.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
#include <string>
+28 -5
View File
@@ -1,7 +1,7 @@
#include "catch.hpp"
#include "variant.hpp"
#include "variant_io.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
#include <algorithm>
#include <cstdint>
@@ -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>();
@@ -543,9 +543,9 @@ TEST_CASE("storing reference wrappers to consts works")
int a = 1;
variant_type v{std::cref(a)};
REQUIRE(v.get<int const>() == 1);
REQUIRE(v.get<int>() == 1); // this works (see #82)
REQUIRE(v.get<int>() == 1);
REQUIRE(mapbox::util::get<int const>(v) == 1);
// REQUIRE(mapbox::util::get<int>(v) == 1); // this doesn't work (see #82)
REQUIRE(mapbox::util::get<int>(v) == 1);
REQUIRE_THROWS_AS({
v.get<double const>();
},
@@ -568,3 +568,26 @@ TEST_CASE("storing reference wrappers to consts works")
},
mapbox::util::bad_variant_access&);
}
TEST_CASE("recursive wrapper")
{
using variant_type = mapbox::util::variant<mapbox::util::recursive_wrapper<int>>;
variant_type v(1);
REQUIRE(v.is<int>());
REQUIRE(v.get<int>() == 1);
}
TEST_CASE("variant : direct_type helper should match T, references (T&) and const references (T const&) to the original type T)")
{
using value = mapbox::util::variant<bool, std::uint64_t>;
std::uint64_t u(1234);
REQUIRE(value(u).is<std::uint64_t>()); // matches T
std::uint64_t& ur(u);
REQUIRE(value(ur).is<std::uint64_t>()); // matches T&
std::uint64_t const& ucr(u);
REQUIRE(value(ucr).is<std::uint64_t>()); // matches T const&
}
+3 -3
View File
@@ -6,9 +6,9 @@
#include <typeinfo>
#include <utility>
#include <boost/timer/timer.hpp>
#include "auto_cpu_timer.hpp"
#include "variant.hpp"
#include <mapbox/variant.hpp>
using namespace mapbox;
@@ -112,7 +112,7 @@ int main(int argc, char** argv)
int total = 0;
{
boost::timer::auto_cpu_timer t;
auto_cpu_timer t;
for (std::size_t i = 0; i < NUM_ITER; ++i)
{
total += util::apply_visitor(test::calculator(), result);