-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds a type-erased response adapter to the public API #201
Open
anarthal
wants to merge
15
commits into
boostorg:develop
Choose a base branch
from
anarthal:feature/type-erased-response
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
d182276
Added any_adapter
anarthal a8c4f75
Move any_adapter
anarthal 1957cc7
Merge branch 'develop' into feature/type-erased-response
anarthal 2592957
Fixed compl handler signatures
anarthal 3098fca
Immediate executor fix
anarthal 6c6bcd0
casts to any_adapter
anarthal 6e7c42b
get_impl is now private
anarthal 0f56460
reference docs (1)
anarthal 299e7ca
Reference docs (2)
anarthal 42d1250
reference fixes
anarthal b5e90ea
Fixed async_initiate signature
anarthal 585988b
Test for connection::async_exec
anarthal 90a07a1
test_any_adapter
anarthal 63aad80
Added test to Jamfile
anarthal 3adac15
Missing include
anarthal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* Copyright (c) 2018-2023 Marcelo Zimbres Silva ([email protected]) | ||
* | ||
* Distributed under the Boost Software License, Version 1.0. (See | ||
* accompanying file LICENSE.txt) | ||
*/ | ||
|
||
#ifndef BOOST_REDIS_ANY_ADAPTER_HPP | ||
#define BOOST_REDIS_ANY_ADAPTER_HPP | ||
|
||
|
||
#include <boost/redis/resp3/node.hpp> | ||
#include <boost/redis/adapter/adapt.hpp> | ||
#include <boost/system/error_code.hpp> | ||
#include <cstddef> | ||
#include <functional> | ||
#include <string_view> | ||
#include <type_traits> | ||
|
||
namespace boost::redis { | ||
|
||
namespace detail { | ||
|
||
// Forward decl | ||
template <class Executor> | ||
class connection_base; | ||
|
||
} | ||
|
||
/** @brief A type-erased reference to a response. | ||
* @ingroup high-level-api | ||
* | ||
* A type-erased response adapter. It can be executed using @ref connection::async_exec. | ||
* Using this type instead of raw response references enables separate compilation. | ||
* | ||
* Given a response object `resp` that can be passed to `async_exec`, the following two | ||
* statements have the same effect: | ||
* ``` | ||
* co_await conn.async_exec(req, resp); | ||
* co_await conn.async_exec(req, any_response(resp)); | ||
* ``` | ||
*/ | ||
class any_adapter | ||
{ | ||
using fn_type = std::function<void(std::size_t, resp3::basic_node<std::string_view> const&, system::error_code&)>; | ||
|
||
struct impl_t { | ||
fn_type adapt_fn; | ||
std::size_t supported_response_size; | ||
} impl_; | ||
|
||
template <class T> | ||
static auto create_impl(T& resp) -> impl_t | ||
{ | ||
using namespace boost::redis::adapter; | ||
auto adapter = boost_redis_adapt(resp); | ||
std::size_t size = adapter.get_supported_response_size(); | ||
return { std::move(adapter), size }; | ||
} | ||
|
||
template <class Executor> | ||
friend class detail::connection_base; | ||
|
||
public: | ||
/** | ||
* @brief Constructor. | ||
* | ||
* Creates a type-erased response adapter from `resp` by calling | ||
* `boost_redis_adapt`. `T` must be a valid Redis response type. | ||
* Any type passed to @ref connection::async_exec qualifies. | ||
* | ||
* This object stores a reference to `resp`, which must be kept alive | ||
* while `*this` is being used. | ||
*/ | ||
template <class T, class = std::enable_if_t<!std::is_same_v<T, any_adapter>>> | ||
explicit any_adapter(T& resp) : impl_(create_impl(resp)) {} | ||
}; | ||
|
||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,6 +49,7 @@ local tests = | |
test_low_level | ||
test_request | ||
test_run | ||
test_any_adapter | ||
; | ||
|
||
# Build and run the tests | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* Copyright (c) 2018-2022 Marcelo Zimbres Silva ([email protected]) | ||
* | ||
* Distributed under the Boost Software License, Version 1.0. (See | ||
* accompanying file LICENSE.txt) | ||
*/ | ||
|
||
#include <boost/redis/ignore.hpp> | ||
#include <boost/redis/response.hpp> | ||
#include <boost/redis/adapter/any_adapter.hpp> | ||
#include <string> | ||
#define BOOST_TEST_MODULE any_adapter | ||
#include <boost/test/included/unit_test.hpp> | ||
|
||
using boost::redis::generic_response; | ||
using boost::redis::response; | ||
using boost::redis::ignore; | ||
using boost::redis::any_adapter; | ||
|
||
BOOST_AUTO_TEST_CASE(any_adapter_response_types) | ||
{ | ||
// any_adapter can be used with any supported responses | ||
response<int> r1; | ||
response<int, std::string> r2; | ||
generic_response r3; | ||
|
||
BOOST_CHECK_NO_THROW(any_adapter{r1}); | ||
BOOST_CHECK_NO_THROW(any_adapter{r2}); | ||
BOOST_CHECK_NO_THROW(any_adapter{r3}); | ||
BOOST_CHECK_NO_THROW(any_adapter{ignore}); | ||
} | ||
|
||
BOOST_AUTO_TEST_CASE(any_adapter_copy_move) | ||
{ | ||
// any_adapter can be copied/moved | ||
response<int, std::string> r; | ||
any_adapter ad1 {r}; | ||
|
||
// copy constructor | ||
any_adapter ad2 {ad1}; | ||
|
||
// move constructor | ||
any_adapter ad3 {std::move(ad2)}; | ||
|
||
// copy assignment | ||
BOOST_CHECK_NO_THROW(ad2 = ad1); | ||
|
||
// move assignment | ||
BOOST_CHECK_NO_THROW(ad2 = std::move(ad1)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there should be no
friend
class here, the class should defineand forward the call directly to
impl_
. Once you do that you can also remove this typedef and replace it withany_adapter
AFAICS.In a later issue we will have to think about how this relates to the receiver adapter or whether we need another any adapter class. This will be needed to type erase the receive operation too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense only if
any_adapter
is a public class - otherwise I can remove it (together with the Doxygen docs). See my question above.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, let us keep it public.