Skip to content

Commit b8afbd4

Browse files
Add support for non-copyable types in ApiResponse (#1343)
Add missing move constructors to the slicing and extending ApiResponse class, it is required to support non-copyable response types. Relates-To: OLPEDGE-2753 Signed-off-by: Mykhailo Kuchma <[email protected]>
1 parent e66a5c6 commit b8afbd4

File tree

2 files changed

+67
-10
lines changed

2 files changed

+67
-10
lines changed

olp-cpp-sdk-core/include/olp/core/client/ApiResponse.h

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,39 @@ class ApiResponse : public ResponseExtension<Payload> {
8686
*
8787
* @param other The `ApiResponse` instance.
8888
*/
89-
template <typename P = Payload, typename = typename std::enable_if<
90-
!std::is_same<P, void>::value>::type>
91-
ApiResponse(const ApiResponse<Result, Error, void>& other) // NOLINT
89+
template <
90+
typename P = Payload, typename R = Result,
91+
typename = typename std::enable_if<!std::is_same<P, void>::value>::type,
92+
typename =
93+
typename std::enable_if<std::is_copy_constructible<R>::value>::type>
94+
ApiResponse(const ApiResponse<R, Error, void>& other) // NOLINT
9295
: ResponseExtension<P>(),
9396
result_(other.GetResult()),
9497
error_(other.GetError()),
9598
success_(other.IsSuccessful()) {}
9699

100+
/**
101+
* @brief Creates the `ApiResponse` instance from a similar response type
102+
* without payload. The payload is default initialized.
103+
*
104+
* @note Enabled only for the use cases when the input response type has no
105+
* payload.
106+
*
107+
* Used for moving the successfully executed request.
108+
*
109+
* @param other The `ApiResponse` instance.
110+
*/
111+
template <
112+
typename P = Payload, typename R = Result,
113+
typename = typename std::enable_if<!std::is_same<P, void>::value>::type,
114+
typename =
115+
typename std::enable_if<std::is_move_constructible<R>::value>::type>
116+
ApiResponse(ApiResponse<R, Error, void>&& other) // NOLINT
117+
: ResponseExtension<P>(),
118+
result_(other.MoveResult()),
119+
error_(other.GetError()),
120+
success_(other.IsSuccessful()) {}
121+
97122
/**
98123
* @brief Creates the `ApiResponse` instance from a similar response type
99124
* without payload, and a separate payload.
@@ -126,14 +151,38 @@ class ApiResponse : public ResponseExtension<Payload> {
126151
* @param other The `ApiResponse` instance.
127152
*/
128153
template <
129-
typename U, typename P = Payload,
130-
typename = typename std::enable_if<std::is_same<P, void>::value>::type>
131-
ApiResponse(const ApiResponse<Result, Error, U>& other)
154+
typename U, typename P = Payload, typename R = Result,
155+
typename = typename std::enable_if<std::is_same<P, void>::value>::type,
156+
typename =
157+
typename std::enable_if<std::is_copy_constructible<R>::value>::type>
158+
ApiResponse(const ApiResponse<R, Error, U>& other)
132159
: ResponseExtension<P>(),
133160
result_(other.GetResult()),
134161
error_(other.GetError()),
135162
success_(other.IsSuccessful()) {}
136163

164+
/**
165+
* @brief Creates the `ApiResponse` instance from a similar request with a
166+
* payload.
167+
*
168+
* @note Enabled only for the use cases when the input with a payload is
169+
* sliced to the response without payload.
170+
*
171+
* Used for moving the successfully executed request.
172+
*
173+
* @param other The `ApiResponse` instance.
174+
*/
175+
template <
176+
typename U, typename P = Payload, typename R = Result,
177+
typename = typename std::enable_if<std::is_same<P, void>::value>::type,
178+
typename =
179+
typename std::enable_if<std::is_move_constructible<R>::value>::type>
180+
ApiResponse(ApiResponse<R, Error, U>&& other)
181+
: ResponseExtension<P>(),
182+
result_(other.MoveResult()),
183+
error_(other.GetError()),
184+
success_(other.IsSuccessful()) {}
185+
137186
/**
138187
* @brief Creates the `ApiResponse` instance.
139188
*

olp-cpp-sdk-core/tests/client/ApiResponseTest.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,20 @@ TEST(ApiResponseTest, ResponseExtention) {
117117
}
118118

119119
TEST(ApiResponseTest, ResultWithoutCopyCtor) {
120-
using ProvateResponse = ApiResponse<PrivateClass, ErrorType, PayloadT>;
120+
using PrivateResponse = ApiResponse<PrivateClass, ErrorType>;
121+
using ExtendedPrivateResponse =
122+
ApiResponse<PrivateClass, ErrorType, PayloadT>;
121123
// move constructed
122-
ProvateResponse response_1(PrivateClass(1));
124+
ExtendedPrivateResponse response_1(PrivateClass(1));
123125
// move asigned
124-
ProvateResponse response_2 = PrivateClass(1);
126+
ExtendedPrivateResponse response_2 = PrivateClass(1);
125127
// response can be moved
126-
ProvateResponse response_3 = std::move(response_2);
128+
ExtendedPrivateResponse response_3 = std::move(response_2);
129+
// no payload
130+
PrivateResponse response_4(PrivateClass(1));
131+
// extended
132+
ExtendedPrivateResponse response_5(std::move(response_4));
133+
// sliced
134+
PrivateResponse response_6(std::move(response_5));
127135
}
128136
} // namespace

0 commit comments

Comments
 (0)