diff --git a/README.md b/README.md index 0c755a54..d8ad365d 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ Using [Boost.Asio](https://www.boost.org/doc/libs/1_84_0/doc/html/boost_asio.htm ```cmake # Make sure CMAKE_PREFIX_PATH contains /desired/installation/directory -find_package(asio-grpc) +find_package(asio-grpc CONFIG REQUIRED) find_package(Boost) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc Boost::headers) ``` @@ -123,7 +123,7 @@ Or using [standalone Asio](https://github.com/chriskohlhoff/asio): ```cmake # Make sure CMAKE_PREFIX_PATH contains /desired/installation/directory -find_package(asio-grpc) +find_package(asio-grpc CONFIG REQUIRED) find_package(asio) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-standalone-asio asio::asio) ``` @@ -132,7 +132,7 @@ Or using [libunifex](https://github.com/facebookexperimental/libunifex): ```cmake # Make sure CMAKE_PREFIX_PATH contains /desired/installation/directory -find_package(asio-grpc) +find_package(asio-grpc CONFIG REQUIRED) find_package(unifex) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-unifex unifex::unifex) ``` @@ -141,7 +141,7 @@ Or using [stdexec](https://github.com/NVIDIA/stdexec): ```cmake # Make sure CMAKE_PREFIX_PATH contains /desired/installation/directory -find_package(asio-grpc) +find_package(asio-grpc CONFIG REQUIRED) find_package(stdexec) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-stdexec STDEXEC::stdexec) ``` diff --git a/src/agrpc/server_rpc_ptr.hpp b/src/agrpc/server_rpc_ptr.hpp index c5473733..ed4a68c8 100644 --- a/src/agrpc/server_rpc_ptr.hpp +++ b/src/agrpc/server_rpc_ptr.hpp @@ -40,7 +40,7 @@ class ServerRPCPtr /** * @brief Default constructor * - * The only valid operations after construction are move-assignment and destruction. + * The only valid operations after construction are move-assignment, operator bool, swap and destruction. */ ServerRPCPtr() = default; @@ -83,6 +83,13 @@ class ServerRPCPtr */ const ServerRPCT* operator->() const noexcept { return &server_rpc_->rpc_; } + /** + * @brief Checks whether this pointer owns a ServerRPC + * + * @since 3.1.0 + */ + explicit operator bool() const noexcept { return server_rpc_ != nullptr; } + /** * @brief Get client's initial request message */ @@ -93,6 +100,17 @@ class ServerRPCPtr */ decltype(auto) request() const noexcept { return (server_rpc_->request_); } + /** + * @brief Swap contents of two ServerRPCPtr + * + * @since 3.1.0 + */ + friend void swap(ServerRPCPtr& lhs, ServerRPCPtr& rhs) noexcept + { + std::swap(lhs.server_rpc_, rhs.server_rpc_); + std::swap(lhs.deleter_, rhs.deleter_); + } + private: using Pointer = detail::ServerRPCWithRequest*; using Deleter = void (*)(Pointer) noexcept; diff --git a/test/src/test_server_rpc_17.cpp b/test/src/test_server_rpc_17.cpp index cda39f0c..967152af 100644 --- a/test/src/test_server_rpc_17.cpp +++ b/test/src/test_server_rpc_17.cpp @@ -609,13 +609,19 @@ TEST_CASE_TEMPLATE("ServerRPCPtr automatic cancellation on destruction", RPC, te }); } -TEST_CASE_FIXTURE(ServerRPCTest, "ServerRPCPtr move-assignment") +TEST_CASE_FIXTURE(ServerRPCTest, "ServerRPCPtr move-assignment/swap") { ServerRPC::Ptr ptr; register_callback_and_perform_requests( [&](ServerRPC::Ptr pointer) { - ptr = std::move(pointer); + SUBCASE("move") { ptr = std::move(pointer); } + SUBCASE("swap") + { + using std::swap; + swap(ptr, pointer); + CHECK_FALSE(pointer); + } auto& rpc = *ptr; rpc.finish({}, test::create_already_exists_status(), [ptr = std::move(ptr)](bool ok)