Skip to content

Commit

Permalink
Merge branch 'daniel-j-h-lambda-visitor'
Browse files Browse the repository at this point in the history
  • Loading branch information
artemp committed Nov 14, 2016
2 parents a5a79a5 + 4d462f2 commit 9a115c5
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ LDFLAGS := $(LDFLAGS)

ALL_HEADERS = $(shell find include/mapbox/ '(' -name '*.hpp' ')')

all: out/bench-variant out/unique_ptr_test out/unique_ptr_test out/recursive_wrapper_test out/binary_visitor_test
all: out/bench-variant out/unique_ptr_test out/unique_ptr_test out/recursive_wrapper_test out/binary_visitor_test out/lambda_overload_test

mason_packages:
git submodule update --init .mason
Expand Down Expand Up @@ -47,6 +47,10 @@ out/binary_visitor_test: Makefile mason_packages test/binary_visitor_test.cpp
mkdir -p ./out
$(CXX) -o out/binary_visitor_test test/binary_visitor_test.cpp -I./include -Itest/include $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)

out/lambda_overload_test: Makefile mason_packages test/lambda_overload_test.cpp
mkdir -p ./out
$(CXX) -o out/lambda_overload_test test/lambda_overload_test.cpp -I./include -Itest/include $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)

bench: out/bench-variant out/unique_ptr_test out/unique_ptr_test out/recursive_wrapper_test out/binary_visitor_test
./out/bench-variant 100000
./out/unique_ptr_test 100000
Expand Down
36 changes: 36 additions & 0 deletions include/mapbox/variant_visitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef MAPBOX_UTIL_VARIANT_VISITOR_HPP
#define MAPBOX_UTIL_VARIANT_VISITOR_HPP

namespace mapbox {
namespace util {

template <typename... Fns>
struct visitor;

template <typename Fn>
struct visitor<Fn> : Fn
{
using Fn::operator();

visitor(Fn fn) : Fn(fn) {}
};

template <typename Fn, typename... Fns>
struct visitor<Fn, Fns...> : Fn, visitor<Fns...>
{
using Fn::operator();
using visitor<Fns...>::operator();

visitor(Fn fn, Fns... fns) : Fn(fn), visitor<Fns...>(fns...) {}
};

template <typename... Fns>
visitor<Fns...> make_visitor(Fns... fns)
{
return visitor<Fns...>(fns...);
}

} // namespace util
} // namespace mapbox

#endif // MAPBOX_UTIL_VARIANT_VISITOR_HPP
92 changes: 92 additions & 0 deletions test/lambda_overload_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#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);
}

#ifdef HAS_CPP14_SUPPORT
void test_lambda_overloads_sfinae()
{
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);
}
#endif

int main()
{
test_lambda_overloads();
test_singleton_variant();
test_lambda_overloads_capture();

#ifdef HAS_CPP14_SUPPORT
test_lambda_overloads_sfinae();
#endif
}

#undef HAS_CPP14_SUPPORT

0 comments on commit 9a115c5

Please sign in to comment.