Compute Library
 22.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,
44  "Derived is not a specialization of Base");
45  if(ptr == nullptr)
46  {
47  return nullptr;
48  }
49  return new Derived(*static_cast<const Derived *>(ptr));
50 }
51 } // namespace
52 
53 /** A deep-copying unique pointer that also supports polymorphic cloning behavior
54  *
55  * @note The == operator compares the dereferenced value instead of the pointer itself.
56  *
57  * @tparam Base Base type
58  */
59 template <typename Base>
61 {
62 public:
63  using CopyFunc = std::function<Base *(const Base *)>;
64 
65  deep_unique_ptr(std::nullptr_t val = nullptr) noexcept
66  : _val{ val },
67  _copy{}
68  {
69  }
70  template <typename Derived, typename CopyFuncDerived>
71  deep_unique_ptr(Derived *value, const CopyFuncDerived &copy) noexcept
72  : _val{ value },
73  _copy{ std::move(copy) }
74  {
75  static_assert(std::is_base_of<Base, Derived>::value,
76  "Derived is not a specialization of Base");
77  static_assert(
78  std::is_constructible<CopyFunc, CopyFuncDerived>::value,
79  "CopyFuncDerived is not valid for a copy functor");
80  }
81 
83  : deep_unique_ptr(ptr.clone())
84  {
85  }
87  {
88  deep_unique_ptr<Base> tmp(ptr);
89  swap(*this, tmp);
90  return *this;
91  }
92 
93  deep_unique_ptr(deep_unique_ptr<Base> &&ptr) = default;
95  ~deep_unique_ptr() = default;
96  friend void swap(deep_unique_ptr &ptr0, deep_unique_ptr<Base> &ptr1) noexcept
97  {
98  using std::swap;
99  swap(ptr0._val, ptr1._val);
100  swap(ptr0._copy, ptr1._copy);
101  }
102  Base &operator*() noexcept
103  {
104  return *_val;
105  }
106 
107  const Base &operator*() const noexcept
108  {
109  return *_val;
110  }
111 
112  Base *operator->() noexcept
113  {
114  return _val.operator->();
115  }
116 
117  const Base *operator->() const noexcept
118  {
119  return _val.operator->();
120  }
121 
122  Base *get() noexcept
123  {
124  return _val.get();
125  }
126  const Base *get() const noexcept
127  {
128  return _val.get();
129  }
130 
131  explicit operator bool() const noexcept
132  {
133  return static_cast<bool>(_val);
134  }
135 
136  bool operator==(const deep_unique_ptr<Base> &rhs) const
137  {
138  if(rhs.get() == nullptr && _val == nullptr)
139  {
140  return true;
141  }
142  else if(rhs.get() == nullptr || _val == nullptr)
143  {
144  return false;
145  }
146  else
147  {
148  return (*_val == *rhs);
149  }
150  }
151 
152 private:
153  deep_unique_ptr clone() const
154  {
155  return { _copy(_val.get()), CopyFunc(_copy) };
156  }
157  std::unique_ptr<Base> _val{ nullptr };
158  CopyFunc _copy{};
159 };
160 
161 /** Utility function to create a polymorphic deep-copying unique pointer
162  *
163  * @tparam Base
164  * @tparam Derived
165  * @tparam CopyFunc
166  * @param temp
167  * @param copy
168  * @return deep_unique_ptr<Base>
169  */
170 template <typename Base, typename Derived, typename CopyFunc>
172 {
173  return
174  {
175  new Derived(std::move(temp)),
176  CopyFunc{ std::move(copy) }
177  };
178 }
179 
180 template <typename Base, typename Derived>
182 {
183  static_assert(std::is_base_of<Base, Derived>::value,
184  "Derived is not a specialization of Base");
185 
186  return make_deep_unique<Base, Derived>(
187  std::move(temp), default_polymorphic_copy<Base, Derived>);
188 }
189 
190 template <typename Base, typename Derived, typename... Args>
192 {
193  static_assert(std::is_constructible<Derived, Args...>::value,
194  "Cannot instantiate Derived from arguments");
195 
196  return make_deep_unique<Base, Derived>(
197  std::move(Derived{ std::forward<Args>(args)... }));
198 }
199 
200 } // namespace memory
201 } // namespace utils
202 } // namespace arm_compute
203 #endif // ARM_COMPUTE_MISC_ITERABLE_H
deep_unique_ptr(Derived *value, const CopyFuncDerived &copy) noexcept
Definition: DeepCopy.h:71
deep_unique_ptr< Base > make_deep_unique(Derived &&temp, CopyFunc copy)
Utility function to create a polymorphic deep-copying unique pointer.
Definition: DeepCopy.h:171
deep_unique_ptr & operator=(const deep_unique_ptr< Base > &ptr)
Definition: DeepCopy.h:86
friend void swap(deep_unique_ptr &ptr0, deep_unique_ptr< Base > &ptr1) noexcept
Definition: DeepCopy.h:96
SimpleTensor< T > copy(const SimpleTensor< T > &src, const TensorShape &output_shape)
Definition: Copy.cpp:37
Copyright (c) 2017-2022 Arm Limited.
deep_unique_ptr(const deep_unique_ptr< Base > &ptr)
Definition: DeepCopy.h:82
const Base * operator->() const noexcept
Definition: DeepCopy.h:117
std::function< Base *(const Base *)> CopyFunc
Definition: DeepCopy.h:63
bool operator==(const deep_unique_ptr< Base > &rhs) const
Definition: DeepCopy.h:136
const Base & operator*() const noexcept
Definition: DeepCopy.h:107
deep_unique_ptr(std::nullptr_t val=nullptr) noexcept
Definition: DeepCopy.h:65
A deep-copying unique pointer that also supports polymorphic cloning behavior.
Definition: DeepCopy.h:60
void swap(Window &lhs, Window &rhs)
Definition: Window.inl:304