Compute Library
 23.11
DeepCopy.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #ifndef ARM_COMPUTE_MISC_ITERABLE_H
26 #define ARM_COMPUTE_MISC_ITERABLE_H
27 namespace arm_compute
28 {
29 namespace utils
30 {
31 namespace memory
32 {
33 namespace
34 {
35 /** Default polymorphic deep copy function, used by deep_unique_ptr
36  *
37  * @param ptr Potentially polymorphic object to be deep copied
38  * @return template <typename Base, typename Derived>*
39  */
40 template <typename Base, typename Derived>
41 Base *default_polymorphic_copy(const Base *ptr)
42 {
43  static_assert(std::is_base_of<Base, Derived>::value, "Derived is not a specialization of Base");
44  if (ptr == nullptr)
45  {
46  return nullptr;
47  }
48  return new Derived(*static_cast<const Derived *>(ptr));
49 }
50 } // namespace
51 
52 /** A deep-copying unique pointer that also supports polymorphic cloning behavior
53  *
54  * @note The == operator compares the dereferenced value instead of the pointer itself.
55  *
56  * @tparam Base Base type
57  */
58 template <typename Base>
60 {
61 public:
62  using CopyFunc = std::function<Base *(const Base *)>;
63 
64  deep_unique_ptr(std::nullptr_t val = nullptr) noexcept : _val{val}, _copy{}
65  {
66  }
67  template <typename Derived, typename CopyFuncDerived>
68  deep_unique_ptr(Derived *value, const CopyFuncDerived &copy) noexcept : _val{value}, _copy{std::move(copy)}
69  {
70  static_assert(std::is_base_of<Base, Derived>::value, "Derived is not a specialization of Base");
71  static_assert(std::is_constructible<CopyFunc, CopyFuncDerived>::value,
72  "CopyFuncDerived is not valid for a copy functor");
73  }
74 
76  {
77  }
79  {
80  deep_unique_ptr<Base> tmp(ptr);
81  swap(*this, tmp);
82  return *this;
83  }
84 
85  deep_unique_ptr(deep_unique_ptr<Base> &&ptr) = default;
87  ~deep_unique_ptr() = default;
88  friend void swap(deep_unique_ptr &ptr0, deep_unique_ptr<Base> &ptr1) noexcept
89  {
90  using std::swap;
91  swap(ptr0._val, ptr1._val);
92  swap(ptr0._copy, ptr1._copy);
93  }
94  Base &operator*() noexcept
95  {
96  return *_val;
97  }
98 
99  const Base &operator*() const noexcept
100  {
101  return *_val;
102  }
103 
104  Base *operator->() noexcept
105  {
106  return _val.operator->();
107  }
108 
109  const Base *operator->() const noexcept
110  {
111  return _val.operator->();
112  }
113 
114  Base *get() noexcept
115  {
116  return _val.get();
117  }
118  const Base *get() const noexcept
119  {
120  return _val.get();
121  }
122 
123  explicit operator bool() const noexcept
124  {
125  return static_cast<bool>(_val);
126  }
127 
128  bool operator==(const deep_unique_ptr<Base> &rhs) const
129  {
130  if (rhs.get() == nullptr && _val == nullptr)
131  {
132  return true;
133  }
134  else if (rhs.get() == nullptr || _val == nullptr)
135  {
136  return false;
137  }
138  else
139  {
140  return (*_val == *rhs);
141  }
142  }
143 
144 private:
145  deep_unique_ptr clone() const
146  {
147  return {_copy(_val.get()), CopyFunc(_copy)};
148  }
149  std::unique_ptr<Base> _val{nullptr};
150  CopyFunc _copy{};
151 };
152 
153 /** Utility function to create a polymorphic deep-copying unique pointer
154  *
155  * @tparam Base
156  * @tparam Derived
157  * @tparam CopyFunc
158  * @param temp
159  * @param copy
160  * @return deep_unique_ptr<Base>
161  */
162 template <typename Base, typename Derived, typename CopyFunc>
163 deep_unique_ptr<Base> make_deep_unique(Derived &&temp, CopyFunc copy)
164 {
165  return {new Derived(std::move(temp)), CopyFunc{std::move(copy)}};
166 }
167 
168 template <typename Base, typename Derived>
170 {
171  static_assert(std::is_base_of<Base, Derived>::value, "Derived is not a specialization of Base");
172 
173  return make_deep_unique<Base, Derived>(std::move(temp), default_polymorphic_copy<Base, Derived>);
174 }
175 
176 template <typename Base, typename Derived, typename... Args>
178 {
179  static_assert(std::is_constructible<Derived, Args...>::value, "Cannot instantiate Derived from arguments");
180 
181  return make_deep_unique<Base, Derived>(std::move(Derived{std::forward<Args>(args)...}));
182 }
183 
184 } // namespace memory
185 } // namespace utils
186 } // namespace arm_compute
187 #endif // ARM_COMPUTE_MISC_ITERABLE_H
GemmTuner.args
args
Definition: GemmTuner.py:679
arm_compute::utils::memory::deep_unique_ptr::operator*
const Base & operator*() const noexcept
Definition: DeepCopy.h:99
arm_compute::utils::memory::deep_unique_ptr::operator==
bool operator==(const deep_unique_ptr< Base > &rhs) const
Definition: DeepCopy.h:128
arm_compute::utils::memory::deep_unique_ptr::CopyFunc
std::function< Base *(const Base *)> CopyFunc
Definition: DeepCopy.h:62
arm_compute::utils::memory::deep_unique_ptr
A deep-copying unique pointer that also supports polymorphic cloning behavior.
Definition: DeepCopy.h:59
arm_compute::utils::memory::deep_unique_ptr::get
const Base * get() const noexcept
Definition: DeepCopy.h:118
arm_compute::utils::memory::deep_unique_ptr::deep_unique_ptr
deep_unique_ptr(Derived *value, const CopyFuncDerived &copy) noexcept
Definition: DeepCopy.h:68
arm_compute::utils::memory::deep_unique_ptr::deep_unique_ptr
deep_unique_ptr(std::nullptr_t val=nullptr) noexcept
Definition: DeepCopy.h:64
arm_compute::utils::memory::make_deep_unique
deep_unique_ptr< Base > make_deep_unique(Derived &&temp, CopyFunc copy)
Utility function to create a polymorphic deep-copying unique pointer.
Definition: DeepCopy.h:163
arm_compute::utils::memory::deep_unique_ptr::operator=
deep_unique_ptr & operator=(const deep_unique_ptr< Base > &ptr)
Definition: DeepCopy.h:78
arm_compute::utils::memory::deep_unique_ptr::operator*
Base & operator*() noexcept
Definition: DeepCopy.h:94
arm_compute::test::validation::reference::copy
SimpleTensor< T > copy(const SimpleTensor< T > &src, const TensorShape &output_shape)
Definition: Copy.cpp:37
arm_compute::utils::memory::deep_unique_ptr::get
Base * get() noexcept
Definition: DeepCopy.h:114
arm_compute::utils::memory::deep_unique_ptr::operator->
const Base * operator->() const noexcept
Definition: DeepCopy.h:109
arm_compute::swap
void swap(Window &lhs, Window &rhs)
Definition: Window.inl:318
arm_compute
Copyright (c) 2017-2023 Arm Limited.
Definition: introduction.dox:24
arm_compute::utils::memory::deep_unique_ptr::deep_unique_ptr
deep_unique_ptr(const deep_unique_ptr< Base > &ptr)
Definition: DeepCopy.h:75
arm_compute::utils::memory::deep_unique_ptr::swap
friend void swap(deep_unique_ptr &ptr0, deep_unique_ptr< Base > &ptr1) noexcept
Definition: DeepCopy.h:88
arm_compute::utils::memory::deep_unique_ptr::~deep_unique_ptr
~deep_unique_ptr()=default
arm_compute::utils::memory::deep_unique_ptr::operator->
Base * operator->() noexcept
Definition: DeepCopy.h:104