Skip to content

Commit

Permalink
Add constraint to visit() with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Bronek committed Nov 30, 2023
1 parent fbc9519 commit 021bcfc
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 6 deletions.
16 changes: 14 additions & 2 deletions src/ripple/json/MultivarJson.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,27 @@ struct MultivarJson
auto
visit() &
{
return [self = this](auto... args) {
return [self = this](auto... args) requires requires()
{
visitor(
std::declval<MultivarJson&>(),
std::declval<decltype(args)>()...);
}
{
return visitor(*self, std::forward<decltype(args)>(args)...);
};
}

auto
visit() const&
{
return [self = this](auto... args) {
return [self = this](auto... args) requires requires()
{
visitor(
std::declval<MultivarJson const&>(),
std::declval<decltype(args)>()...);
}
{
return visitor(*self, std::forward<decltype(args)>(args)...);
};
}
Expand Down
93 changes: 89 additions & 4 deletions src/test/json/MultivarJson_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,28 +621,113 @@ struct MultivarJson_test : beast::unit_test::suite
return !requires
{
std::forward<decltype(v)>(v).visit(
1, [](Json::Value&, auto) {});
1, [](Json::Value&&, auto) {});
};
}(std::move(s1)));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit();
std::forward<decltype(v)>(v).visit()(
1, [](Json::Value&&, auto) {});
};
}(std::move(s1)));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit(
1, [](Json::Value const&, auto) {});
1, [](Json::Value const&&, auto) {});
};
}(std::move(std::as_const(s1))));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit();
std::forward<decltype(v)>(v).visit()(
1, [](Json::Value const&&, auto) {});
};
}(std::move(std::as_const(s1))));

// Missing const
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit(
1, [](Json::Value&, auto) {});
};
}(std::as_const(s1)));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit()(
1, [](Json::Value&, auto) {});
};
}(std::as_const(s1)));

// Missing parameter
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit(1, []() {});
};
}(s1));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit()(1, []() {});
};
}(s1));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit(1, [](auto) {});
};
}(s1));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit()(1, [](auto) {});
};
}(s1));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit(1, [](Json::Value&) {});
};
}(s1));
static_assert([](auto&& v) {
return !requires
{
std::forward<decltype(v)>(v).visit()(
1, [](Json::Value&) {});
};
}(s1));

// Sanity checks
static_assert([](auto&& v) {
return requires
{
std::forward<decltype(v)>(v).visit(1, [](auto...) {});
};
}(std::as_const(s1)));
static_assert([](auto&& v) {
return requires
{
std::forward<decltype(v)>(v).visit()(1, [](auto...) {});
};
}(std::as_const(s1)));
static_assert([](auto&& v) {
return requires
{
std::forward<decltype(v)>(v).visit(
1, [](Json::Value&, auto) {});
};
}(s1));
static_assert([](auto&& v) {
return requires
{
std::forward<decltype(v)>(v).visit()(
1, [](Json::Value&, auto) {});
};
}(s1));
}
}
};
Expand Down
55 changes: 55 additions & 0 deletions src/test/protocol/ApiVersion_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,61 @@ struct ApiVersion_test : beast::unit_test::suite
&result);

BEAST_EXPECT(result == productAllVersions);

// Several overloads we want to fail
static_assert([](auto&& v) {
return !requires
{
forAllApiVersions(
std::forward<decltype(v)>(v).visit(), //
[](Json::Value&, auto) {}); // missing const
};
}(std::as_const(s1)));

static_assert([](auto&& v) {
return !requires
{
forAllApiVersions(
std::forward<decltype(v)>(v).visit(), //
[](auto...) {}); // cannot bind rvalues
};
}(std::move(s1)));

static_assert([](auto&& v) {
return !requires
{
forAllApiVersions(
std::forward<decltype(v)>(v).visit(), //
[](auto) {}); // missing parameter
};
}(s1));

static_assert([](auto&& v) {
return !requires
{
forAllApiVersions(
std::forward<decltype(v)>(v).visit(), //
[](Json::Value const&) {}); // missing parameter
};
}(std::as_const(s1)));

// Sanity checks
static_assert([](auto&& v) {
return requires
{
forAllApiVersions(
std::forward<decltype(v)>(v).visit(), //
[](auto ...) {});
};
}(s1));
static_assert([](auto&& v) {
return requires
{
forAllApiVersions(
std::forward<decltype(v)>(v).visit(), //
[](Json::Value const&, auto ...) {});
};
}(std::as_const(s1)));
}
}
};
Expand Down

0 comments on commit 021bcfc

Please sign in to comment.