Skip to content

Commit 93e375b

Browse files
authored
Updated ClonedPtr
1 parent 55aef03 commit 93e375b

19 files changed

+700
-256
lines changed

include/helib/CModulus.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <helib/NumbTh.h>
2121
#include <helib/PAlgebra.h>
2222
#include <helib/bluestein.h>
23-
#include <helib/clonedPtr.h>
23+
#include <helib/ClonedPtr.h>
2424

2525
namespace helib {
2626

@@ -61,17 +61,17 @@ class Cmodulus
6161
long rInv;
6262

6363
// tables for forward FFT
64-
copied_ptr<NTL::zz_pX> powers;
64+
CopiedPtr<NTL::zz_pX> powers;
6565
NTL::Vec<NTL::mulmod_precon_t> powers_aux;
66-
copied_ptr<NTL::fftRep> Rb;
66+
CopiedPtr<NTL::fftRep> Rb;
6767

6868
// tables for backward FFT
69-
copied_ptr<NTL::zz_pX> ipowers;
69+
CopiedPtr<NTL::zz_pX> ipowers;
7070
NTL::Vec<NTL::mulmod_precon_t> ipowers_aux;
71-
copied_ptr<NTL::fftRep> iRb;
71+
CopiedPtr<NTL::fftRep> iRb;
7272

7373
// PhimX modulo q, for faster division w/ remainder
74-
copied_ptr<zz_pXModulus1> phimx;
74+
CopiedPtr<zz_pXModulus1> phimx;
7575

7676
// Allocate memory and compute roots
7777
void privateInit(const PAlgebra&, long rt);

include/helib/ClonedPtr.h

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
/* Copyright (C) 2012-2020 IBM Corp.
2+
* This program is Licensed under the Apache License, Version 2.0
3+
* (the "License"); you may not use this file except in compliance
4+
* with the License. You may obtain a copy of the License at
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
* Unless required by applicable law or agreed to in writing, software
7+
* distributed under the License is distributed on an "AS IS" BASIS,
8+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
* See the License for the specific language governing permissions and
10+
* limitations under the License. See accompanying LICENSE file.
11+
*/
12+
#ifndef HELIB_CLONEDPTR_H
13+
#define HELIB_CLONEDPTR_H
14+
15+
#include <utility> // std::swap
16+
/**
17+
* @file ClonedPtr.h
18+
* @brief Implementation of smart pointer `ClonedPtr` with "cloning" semantics.
19+
* The API should be familiar to those that use the standard library smart
20+
* pointers (unique_ptr and shared_ptr).
21+
*
22+
* Two "cloning" policies are provided; one for "deep cloning" (default) and the
23+
* other "shallow cloning". For an object to be managed by `ClonedPtr`, a class
24+
* needs a "clone" method for deep cloning that creates a raw pointer to a copy
25+
* of the object or a copy constructor for shallow cloning. An alias
26+
* `CopiedPtr` is provided for convenience which is a `ClonedPtr` with shallow
27+
* clone policy.
28+
**/
29+
30+
namespace helib {
31+
32+
/**
33+
* @brief Clone any type of pointer.
34+
* @param ptr Pointer to be cloned. That is the object that it points to is
35+
*`cloned`.
36+
* @return A new pointer object that points to a freshly cloned object.
37+
* @note Requires that the object being cloned has a `clone` method.
38+
**/
39+
template <typename PTR>
40+
PTR clonePtr(PTR& ptr)
41+
{
42+
static_assert(std::is_pointer<decltype(ptr->clone())>::value,
43+
"`clone` method must return raw pointer.");
44+
45+
return PTR(ptr->clone());
46+
}
47+
48+
/**
49+
* @struct DeepCopy
50+
* @brief Deep copy an object by using its clone method.
51+
* @tparam T The type of object to be cloned.
52+
**/
53+
template <typename T>
54+
struct DeepCopy
55+
{
56+
/**
57+
* @brief Apply the cloning policy.
58+
* @param ptr The pointer to apply clone policy.
59+
* @return The pointer to apply clone policy.
60+
**/
61+
static T* apply(const T* ptr)
62+
{
63+
static_assert(std::is_pointer<decltype(ptr->clone())>::value,
64+
"`clone` method must return raw pointer.");
65+
66+
return ptr->clone();
67+
}
68+
};
69+
70+
/**
71+
* @struct ShallowCopy
72+
* @brief Shallow copy an object by using its copy constructor.
73+
* @tparam T The type of object to be cloned.
74+
**/
75+
template <typename T>
76+
struct ShallowCopy
77+
{
78+
/**
79+
* @brief Apply the cloning policy.
80+
* @param ptr The pointer to apply clone policy.
81+
* @return The pointer to apply clone policy.
82+
**/
83+
static T* apply(const T* ptr)
84+
{
85+
static_assert(std::is_copy_constructible<T>::value,
86+
"Must be copy constructable.");
87+
88+
return new T(*ptr);
89+
}
90+
};
91+
92+
/**
93+
* @class ClonedPtr
94+
* @brief A smart pointer that `clones` the object it holds when it is copied.
95+
* @tparam T The type of object managed by the pointer.
96+
* @tparam Cloner A policy of how to clone the object pointed to, either `deep`
97+
* or `shallow`. The default is `deep`.
98+
**/
99+
template <typename T, typename Cloner = DeepCopy<T>>
100+
class ClonedPtr
101+
{
102+
public:
103+
/**
104+
* @brief The type of the managed object.
105+
**/
106+
using value_type = T;
107+
108+
/**
109+
* @brief Explicit constructor to create new `ClonedPtr` object.
110+
* @param p The raw pointer to the object that `ClonedPtr` will manage.
111+
**/
112+
explicit ClonedPtr(T* p = nullptr) : ptr(p) {}
113+
114+
/**
115+
* @brief Special constructor to create new `ClonedPtr` object promoting a
116+
* nullptr.
117+
**/
118+
ClonedPtr(std::nullptr_t) : ptr(nullptr) {}
119+
120+
/**
121+
* @brief The destructor deletes the managed object.
122+
**/
123+
~ClonedPtr()
124+
{
125+
if (ptr != nullptr)
126+
delete ptr;
127+
}
128+
129+
/**
130+
* @brief Copy construct by cloning the managed object based on the
131+
* cloning policy.
132+
* @param other The `ClonedPtr` object to be cloned.
133+
**/
134+
ClonedPtr(const ClonedPtr& other) : ptr(copy(other.ptr)) {}
135+
136+
/**
137+
* @brief Move construct by taking ownership of the managed object by the
138+
* `ClonedPtr` object being `moved` and setting its pointer to `nullptr`.
139+
* @param other The `ClonedPtr` object to be moved.
140+
**/
141+
ClonedPtr(ClonedPtr&& other) noexcept : ptr{std::exchange(other.ptr, nullptr)}
142+
{}
143+
144+
/**
145+
* @brief Copy assign by cloning the managed object based on the
146+
* cloning policy.
147+
* @param other The `ClonedPtr` object to be cloned.
148+
* @return Reference to `*this`.
149+
**/
150+
ClonedPtr& operator=(const ClonedPtr& other)
151+
{
152+
if (this != &other) {
153+
delete ptr;
154+
ptr = copy(other.ptr);
155+
}
156+
return *this;
157+
}
158+
159+
/**
160+
* @brief Move construct by taking ownership of the managed object by the
161+
* `ClonedPtr` object being `moved` and setting its pointer to `nullptr`.
162+
* @param other The `ClonedPtr` object to be moved.
163+
* @return Reference to `*this`.
164+
**/
165+
ClonedPtr& operator=(ClonedPtr&& other) noexcept
166+
{
167+
if (this != &other) {
168+
delete ptr;
169+
ptr = std::exchange(other.ptr, nullptr);
170+
}
171+
return *this;
172+
}
173+
174+
/**
175+
* @brief Reset method deletes the object that it currently managed and
176+
* manages the object given by a raw pointer.
177+
* @param p The raw pointer to replace the raw pointer currently managed by
178+
* the `ClonedPtr` object. The default is `nullptr`.
179+
**/
180+
void reset(T* p = nullptr)
181+
{
182+
if (ptr != p) {
183+
if (ptr != nullptr)
184+
delete ptr;
185+
ptr = p;
186+
}
187+
}
188+
189+
/**
190+
* @brief Release the ownership of the currently managed object by
191+
* returning the pointer and setting the held pointer to nullptr.
192+
* @return the pointer currently held by the `ClonedPtr` object.
193+
**/
194+
T* release() noexcept
195+
{
196+
T* ptr_to_release = ptr;
197+
ptr = nullptr;
198+
return ptr_to_release;
199+
}
200+
201+
/**
202+
* @brief convert `ClonedPtr` to `bool`, `false` if there is a managed object
203+
* is else converts to `true`.
204+
**/
205+
explicit operator bool() const noexcept { return ptr != nullptr; }
206+
207+
/**
208+
* @brief Dereference the smart pointer.
209+
* @return `const` reference to manged object.
210+
**/
211+
const T& operator*() const { return *ptr; }
212+
213+
/**
214+
* @brief Dereference the smart pointer.
215+
* @return Reference to managed object.
216+
**/
217+
T& operator*() { return *ptr; }
218+
219+
/**
220+
* @brief Struct dereference to access members of the managed object.
221+
* @return The `const` raw pointer to the managed object.
222+
**/
223+
const T* operator->() const { return ptr; }
224+
225+
/**
226+
* @brief Struct dereference to access members of the managed object.
227+
* @return The raw pointer to the managed object.
228+
**/
229+
T* operator->() { return ptr; }
230+
231+
/**
232+
* @brief Get the pointer managed by `ClonedPtr` object.
233+
* @return The `const` raw pointer to the managed object.
234+
**/
235+
const T* get() const { return ptr; }
236+
237+
/**
238+
* @brief Get the pointer managed by `ClonedPtr` object.
239+
* @return The raw pointer to the managed object.
240+
**/
241+
T* get() { return ptr; }
242+
243+
/**
244+
* @brief Equal to another `ClonedPtr` object.
245+
* @param other `ClonedPtr` object to compare to.
246+
* @return `true` if this `ClonedPtr` manages the same object as `other`
247+
* else `false`.
248+
**/
249+
bool operator==(const ClonedPtr& other) const { return ptr == other.ptr; }
250+
251+
/**
252+
* @brief Not equal to another `ClonedPtr` object.
253+
* @param other `ClonedPtr` object to compare to.
254+
* @return `true` if this `ClonedPtr` does not manage the same object as
255+
* `other` else `false`.
256+
**/
257+
bool operator!=(const ClonedPtr& other) const { return ptr != other.ptr; }
258+
259+
/**
260+
* @brief Less than another `ClonedPtr` object.
261+
* @param other `ClonedPtr` object to compare to.
262+
* @return `true` if the address of the managed object is less than that of
263+
* the object managed by `other` else `false`.
264+
**/
265+
bool operator<(const ClonedPtr& other) const { return ptr < other.ptr; }
266+
267+
/**
268+
* @brief Greater than another `ClonedPtr` object.
269+
* @param other `ClonedPtr` object to compare to.
270+
* @return `true` if the address of the managed object is greater than that of
271+
* the object managed by `other` else `false`.
272+
**/
273+
bool operator>(const ClonedPtr& other) const { return ptr > other.ptr; }
274+
275+
/**
276+
* @brief Less than or equal to another `ClonedPtr` object.
277+
* @param other `ClonedPtr` object to compare to.
278+
* @return `true` if the address of the managed object is less than or equal
279+
* to that of the object managed by `other` else `false`.
280+
**/
281+
bool operator<=(const ClonedPtr& other) const { return ptr <= other.ptr; }
282+
283+
/**
284+
* @brief Greater than or equal to another `ClonedPtr` object.
285+
* @param other `ClonedPtr` object to compare to.
286+
* @return `true` if the address of the managed object is greater than or
287+
*equal to that of the object managed by `other` else `false`.
288+
**/
289+
bool operator>=(const ClonedPtr& other) const { return ptr >= other.ptr; }
290+
291+
/**
292+
* @brief Swap the managed objects of the this `ClonedPtr` object and
293+
* another.
294+
* @param other `ClonedPtr` object to swap managed object with.
295+
**/
296+
void swap(ClonedPtr& other) { std::swap(ptr, other.ptr); }
297+
298+
private:
299+
// Copy function applies cloning policy.
300+
T* copy(T* p) { return (p ? Cloner::apply(p) : nullptr); }
301+
302+
// The raw pointer to the managed object.
303+
T* ptr = nullptr;
304+
};
305+
306+
/**
307+
* @brief `CopiedPtr` is an alias to `ClonedPtr` but with the cloning policy
308+
* set to `shallow` copy.
309+
* @tparam T Type of the object pointed to by `CopiedPtr`.
310+
**/
311+
template <typename T>
312+
using CopiedPtr = ClonedPtr<T, ShallowCopy<T>>;
313+
314+
/**
315+
* @brief Construct an object of type `T` based on arguments passed and point
316+
* to it with a `ClonedPtr` object.
317+
* @param args The arguments to be forwarded to create an object that will be
318+
* pointed to by `ClonedPtr`.
319+
* @tparam T The type of object that will be constructed and pointed to by the
320+
* `ClonedPtr` object.
321+
* @tparam Args Packed type for arguments to construct a `ClonedPtr`.
322+
* @return A `ClonedPtr` object pointing to the newly constructed object.
323+
**/
324+
template <typename T, typename... Args>
325+
ClonedPtr<T> makeClonedPtr(Args&&... args)
326+
{
327+
return ClonedPtr<T>(new T(std::forward<Args>(args)...));
328+
}
329+
330+
} // namespace helib
331+
332+
#endif // HELIB_CLONEDPTR_H

0 commit comments

Comments
 (0)