DPC++ Runtime
Runtime libraries for oneAPI DPC++
test_proxy.hpp
Go to the documentation of this file.
1 //==-------------- test_proxy.hpp - DPC++ Explicit SIMD API ----------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // Test proxy to differentiate move and copy constructor calls
9 //===----------------------------------------------------------------------===//
10 
11 #pragma once
12 
14 
15 // The test proxy if solely for the test purposes, so it's off by default, with
16 // no any code generated. It is enabled only if the __ESIMD_ENABLE_TEST_PROXY
17 // macro is defined.
18 // It's expected for the proxy class to be available in device code, so that it
19 // could be incorporated into the ESIMD API classes. Though there is no reason
20 // to limit it to the __SYCL_DEVICE_ONLY__.
21 #ifndef __ESIMD_ENABLE_TEST_PROXY
22 
23 // No code generation by default
24 #define __ESIMD_DECLARE_TEST_PROXY
25 #define __ESIMD_DECLARE_TEST_PROXY_ACCESS
26 #define __esimd_move_test_proxy(other)
27 
28 #else
29 
30 // Declare the class attribute
31 //
32 // We are using non static data member initialization approach to force
33 // the value required. Initialization will take place even if no
34 // default/copy/move constructor of the test_proxy class was explcitly
35 // called by any of the user-defined constructors of the proxy target
36 #define __ESIMD_DECLARE_TEST_PROXY \
37  esimd::detail::test::test_proxy M_testProxy = \
38  esimd::detail::test::test_proxy();
39 
40 // Declare the getter to access the proxy from the tests
41 #define __ESIMD_DECLARE_TEST_PROXY_ACCESS \
42  const auto &get_test_proxy() const { return M_testProxy; }
43 
44 // Test proxy will be handled in a proper way by default/implicit move
45 // constructors and move operators.
46 // Still the user-defined constructors or move operators should explicitly state
47 // what to do with each of class atributes, so a proper wrapper required
48 //
49 // We are using a simple do-while trick to make sure no code breakage could
50 // possibly occur in case macro becomes multistatement (PRE10-C in SEI CERT C)
51 #define __esimd_move_test_proxy(other) \
52  do { \
53  M_testProxy = std::move(other.M_testProxy); \
54  } while (false)
55 
56 namespace sycl {
57 inline namespace _V1 {
58 namespace ext::intel::esimd::detail::test {
59 
60 // The test_proxy class.
61 // Being intended solely for the test purposes, it is enabled only if the
62 // __ESIMD_ENABLE_TEST_PROXY macro is defined, which is off by default.
63 //
64 // This is a helper class for tests to differentiate between the copy
65 // constructor/assignment and the move constructor/assignment calls,
66 // as the copy constructor works as the default fallback for every case with
67 // move constructor disabled or not provided
68 //
69 // It is expected for the class with the test proxy (the class under test) to:
70 // - provide the get_test_proxy() method
71 // - properly handle moving the test_proxy member in user-defined move
72 // constructors and user-defined assignment operators
73 //
74 // Therefore the following expression is expected to return `true` only if the
75 // move constructor or move operator was called for the instance of the class
76 // under test:
77 // instance.get_test_proxy().was_move_destination()
78 //
79 class test_proxy {
80  // Define the default value to use for every constructor
81  bool M_move_destination = false;
82 
83 public:
84  test_proxy() { __esimd_dbg_print(test_proxy()); }
85 
86  test_proxy(const test_proxy &) {
87  __esimd_dbg_print(test_proxy(const test_proxy &other));
88  }
89  test_proxy(test_proxy &&) {
90  __esimd_dbg_print(test_proxy(test_proxy && other));
91  M_move_destination = true;
92  }
93  test_proxy &operator=(const test_proxy &) {
94  __esimd_dbg_print(test_proxy::operator=(const test_proxy &other));
95  return *this;
96  }
97  test_proxy &operator=(test_proxy &&) {
98  __esimd_dbg_print(test_proxy::operator=(test_proxy &&other));
99  M_move_destination = true;
100  return *this;
101  }
102  bool was_move_destination() const { return M_move_destination; }
103 };
104 
105 } // namespace ext::intel::esimd::detail::test
106 } // namespace _V1
107 } // namespace sycl
108 
109 #endif // __ESIMD_ENABLE_TEST_PROXY
110 
#define __esimd_dbg_print(a)
Definition: types.hpp:24
PropertyListT int access::address_space multi_ptr & operator=(multi_ptr &&)=default
Definition: access.hpp:18