| 
10 | 10 | //  | 
11 | 11 | //===----------------------------------------------------------------------===//  | 
12 | 12 | 
 
  | 
 | 13 | +#include "CommonTestUtils.h"  | 
 | 14 | + | 
13 | 15 | #include "orc-rt/SPSWrapperFunction.h"  | 
14 | 16 | #include "orc-rt/WrapperFunction.h"  | 
15 | 17 | #include "orc-rt/move_only_function.h"  | 
@@ -218,3 +220,80 @@ TEST(SPSWrapperFunctionUtilsTest, TestFunctionReturningExpectedFailureCase) {  | 
218 | 220 | 
 
  | 
219 | 221 |   EXPECT_EQ(ErrMsg, "N is not a multiple of 2");  | 
220 | 222 | }  | 
 | 223 | + | 
 | 224 | +template <size_t N> struct SPSOpCounter {};  | 
 | 225 | + | 
 | 226 | +namespace orc_rt {  | 
 | 227 | +template <size_t N>  | 
 | 228 | +class SPSSerializationTraits<SPSOpCounter<N>, OpCounter<N>> {  | 
 | 229 | +public:  | 
 | 230 | +  static size_t size(const OpCounter<N> &O) { return 0; }  | 
 | 231 | +  static bool serialize(SPSOutputBuffer &OB, const OpCounter<N> &O) {  | 
 | 232 | +    return true;  | 
 | 233 | +  }  | 
 | 234 | +  static bool deserialize(SPSInputBuffer &OB, OpCounter<N> &O) { return true; }  | 
 | 235 | +};  | 
 | 236 | +} // namespace orc_rt  | 
 | 237 | + | 
 | 238 | +static void  | 
 | 239 | +handle_with_reference_types_sps_wrapper(orc_rt_SessionRef Session,  | 
 | 240 | +                                        void *CallCtx,  | 
 | 241 | +                                        orc_rt_WrapperFunctionReturn Return,  | 
 | 242 | +                                        orc_rt_WrapperFunctionBuffer ArgBytes) {  | 
 | 243 | +  SPSWrapperFunction<void(  | 
 | 244 | +      SPSOpCounter<0>, SPSOpCounter<1>, SPSOpCounter<2>,  | 
 | 245 | +      SPSOpCounter<3>)>::handle(Session, CallCtx, Return, ArgBytes,  | 
 | 246 | +                                [](move_only_function<void()> Return,  | 
 | 247 | +                                   OpCounter<0>, OpCounter<1> &,  | 
 | 248 | +                                   const OpCounter<2> &,  | 
 | 249 | +                                   OpCounter<3> &&) { Return(); });  | 
 | 250 | +}  | 
 | 251 | + | 
 | 252 | +TEST(SPSWrapperFunctionUtilsTest, TestHandlerWithReferences) {  | 
 | 253 | +  // Test that we can handle by-value, by-ref, by-const-ref, and by-rvalue-ref  | 
 | 254 | +  // arguments, and that we generate the expected number of moves.  | 
 | 255 | +  OpCounter<0>::reset();  | 
 | 256 | +  OpCounter<1>::reset();  | 
 | 257 | +  OpCounter<2>::reset();  | 
 | 258 | +  OpCounter<3>::reset();  | 
 | 259 | + | 
 | 260 | +  bool DidRun = false;  | 
 | 261 | +  SPSWrapperFunction<void(SPSOpCounter<0>, SPSOpCounter<1>, SPSOpCounter<2>,  | 
 | 262 | +                          SPSOpCounter<3>)>::  | 
 | 263 | +      call(  | 
 | 264 | +          DirectCaller(nullptr, handle_with_reference_types_sps_wrapper),  | 
 | 265 | +          [&](Error R) {  | 
 | 266 | +            cantFail(std::move(R));  | 
 | 267 | +            DidRun = true;  | 
 | 268 | +          },  | 
 | 269 | +          OpCounter<0>(), OpCounter<1>(), OpCounter<2>(), OpCounter<3>());  | 
 | 270 | + | 
 | 271 | +  EXPECT_TRUE(DidRun);  | 
 | 272 | + | 
 | 273 | +  // We expect two default constructions for each parameter: one for the  | 
 | 274 | +  // argument to call, and one for the object to deserialize into.  | 
 | 275 | +  EXPECT_EQ(OpCounter<0>::defaultConstructions(), 2U);  | 
 | 276 | +  EXPECT_EQ(OpCounter<1>::defaultConstructions(), 2U);  | 
 | 277 | +  EXPECT_EQ(OpCounter<2>::defaultConstructions(), 2U);  | 
 | 278 | +  EXPECT_EQ(OpCounter<3>::defaultConstructions(), 2U);  | 
 | 279 | + | 
 | 280 | +  // Pass-by-value: we expect two moves (one for SPS transparent conversion,  | 
 | 281 | +  // one to copy the value to the parameter), and no copies.  | 
 | 282 | +  EXPECT_EQ(OpCounter<0>::moves(), 2U);  | 
 | 283 | +  EXPECT_EQ(OpCounter<0>::copies(), 0U);  | 
 | 284 | + | 
 | 285 | +  // Pass-by-lvalue-reference: we expect one move (for SPS transparent  | 
 | 286 | +  // conversion), no copies.  | 
 | 287 | +  EXPECT_EQ(OpCounter<1>::moves(), 1U);  | 
 | 288 | +  EXPECT_EQ(OpCounter<1>::copies(), 0U);  | 
 | 289 | + | 
 | 290 | +  // Pass-by-const-lvalue-reference: we expect one move (for SPS transparent  | 
 | 291 | +  // conversion), no copies.  | 
 | 292 | +  EXPECT_EQ(OpCounter<2>::moves(), 1U);  | 
 | 293 | +  EXPECT_EQ(OpCounter<2>::copies(), 0U);  | 
 | 294 | + | 
 | 295 | +  // Pass-by-rvalue-reference: we expect one move (for SPS transparent  | 
 | 296 | +  // conversion), no copies.  | 
 | 297 | +  EXPECT_EQ(OpCounter<3>::moves(), 1U);  | 
 | 298 | +  EXPECT_EQ(OpCounter<3>::copies(), 0U);  | 
 | 299 | +}  | 
0 commit comments