#include #include #include #include #if __cplusplus >= 201402L #define HAS_CPP14_SUPPORT #endif using namespace mapbox::util; template using Either = mapbox::util::variant; struct Response { }; struct Error { }; void test_lambda_overloads() { Either 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 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 singleton; apply_visitor(make_visitor([](int) {}), singleton); } void test_lambda_overloads_sfinae() #ifdef HAS_CPP14_SUPPORT { variant> 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{4, 5, 6}; apply_visitor(visitor, var); } #else { } #endif void test_match_singleton() { variant singleton = 5; singleton.match([](int) {}); auto lambda = [](int) {}; singleton.match(lambda); } void test_match_overloads() { Either rv; rv = Response{}; rv.match([](Response) { std::cout << "Response\n"; }, // [](Error) { std::cout << "Error\n"; }); // } void test_match_overloads_capture() { Either 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; } struct MovableOnly { MovableOnly() = default; MovableOnly(MovableOnly&&) = default; MovableOnly& operator=(MovableOnly&&) = default; }; struct MovableCopyable { MovableCopyable() = default; MovableCopyable(MovableCopyable&&) = default; MovableCopyable& operator=(MovableCopyable&&) = default; MovableCopyable(const MovableCopyable&) = default; MovableCopyable& operator=(const MovableCopyable&) = default; }; void test_match_overloads_init_capture() #ifdef HAS_CPP14_SUPPORT { Either rv; rv = Error{}; rv.match([p = MovableOnly{}](auto&&) {}); { auto lambda = [p = MovableCopyable{}](auto&&) {}; rv.match(lambda); rv.match([p = MovableOnly{}](Response) { std::cout << "Response\n"; }, [p = MovableOnly{}](Error) { std::cout << "Error\n"; }); } { auto lambda = [](Error) { std::cout << "Error\n"; }; rv.match([p = MovableOnly{}](Response) { std::cout << "Response\n"; }, lambda); rv.match(lambda, [p = MovableOnly{}](Response) { std::cout << "Response\n"; }); } } #else { } #endif // See #140 void test_match_overloads_otherwise() #ifdef HAS_CPP14_SUPPORT { struct Center { }; struct Indent { }; struct Justify { }; struct None { }; using Properties = mapbox::util::variant; Properties props = Justify{}; props.match([&](Center) { std::cout << "Center\n"; }, // [&](Indent) { std::cout << "Indent\n"; }, // [&](auto&&) { std::cout << "Otherwise\n"; }); // } #else { } #endif 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(); test_match_overloads_init_capture(); test_match_overloads_otherwise(); } #undef HAS_CPP14_SUPPORT