• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2021, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for an owned smart pointer.
32  */
33 
34 #ifndef OWNED_PTR_HPP_
35 #define OWNED_PTR_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/ptr_wrapper.hpp"
40 
41 namespace ot {
42 
43 /**
44  * Represents an owned smart pointer.
45  *
46  * `OwnedPtr` acts as sole owner of the object it manages. An `OwnedPtr` is non-copyable (copy constructor is deleted)
47  * but the ownership can be transferred from one `OwnedPtr` to another using move semantics.
48  *
49  * The `Type` class MUST provide `Free()` method which frees the instance.
50  *
51  * @tparam Type  The pointer type.
52  */
53 template <class Type> class OwnedPtr : public Ptr<Type>
54 {
55     using Ptr<Type>::mPointer;
56 
57 public:
58     /**
59      * This is the default constructor for `OwnedPtr` initializing it as null.
60      */
61     OwnedPtr(void) = default;
62 
63     /**
64      * Initializes the `OwnedPtr` with a given pointer.
65      *
66      * The `OwnedPtr` takes the ownership of the object at @p aPointer.
67      *
68      * @param[in] aPointer  A pointer to object to initialize with.
69      */
OwnedPtr(Type * aPointer)70     explicit OwnedPtr(Type *aPointer)
71         : Ptr<Type>(aPointer)
72     {
73     }
74 
75     /**
76      * Initializes the `OwnedPtr` from another `OwnedPtr` using move semantics.
77      *
78      * The `OwnedPtr` takes over the ownership of the object from @p aOther. After this call, @p aOther will be null.
79      *
80      * @param[in] aOther   An rvalue reference to another `OwnedPtr`.
81      */
OwnedPtr(OwnedPtr && aOther)82     OwnedPtr(OwnedPtr &&aOther)
83     {
84         mPointer        = aOther.mPointer;
85         aOther.mPointer = nullptr;
86     }
87 
88     /**
89      * This is the destructor for `OwnedPtr`.
90      *
91      * Upon destruction, the `OwnedPtr` invokes `Free()` method on its managed object (if any).
92      */
~OwnedPtr(void)93     ~OwnedPtr(void) { Delete(); }
94 
95     /**
96      * Frees the owned object (if any).
97      *
98      * Invokes `Free()` method on the `Type` object owned by `OwnedPtr` (if any). It will also set the
99      * `OwnedPtr` to null.
100      */
Free(void)101     void Free(void)
102     {
103         Delete();
104         mPointer = nullptr;
105     }
106 
107     /**
108      * Frees the current object owned by `OwnedPtr` (if any) and replaces it with a new one.
109      *
110      * The method will `Free()` the current object managed by `OwnedPtr` (if different from @p aPointer) before taking
111      * the ownership of the object at @p aPointer. The method correctly handles a self `Reset()` (i.e., @p aPointer
112      * being the same pointer as the one currently managed by `OwnedPtr`).
113      *
114      * @param[in] aPointer   A pointer to the new object to replace with.
115      */
Reset(Type * aPointer=nullptr)116     void Reset(Type *aPointer = nullptr)
117     {
118         if (mPointer != aPointer)
119         {
120             Delete();
121             mPointer = aPointer;
122         }
123     }
124 
125     /**
126      * Releases the ownership of the current object in `OwnedPtr` (if any).
127      *
128      * After this call, the `OwnedPtr` will be null.
129      *
130      * @returns The pointer to the object owned by `OwnedPtr` or `nullptr` if `OwnedPtr` was null.
131      */
Release(void)132     Type *Release(void)
133     {
134         Type *pointer = mPointer;
135         mPointer      = nullptr;
136         return pointer;
137     }
138 
139     /**
140      * Allows passing of the ownership to another `OwnedPtr` using move semantics.
141      *
142      * @returns An rvalue reference of the pointer to move from.
143      */
PassOwnership(void)144     OwnedPtr &&PassOwnership(void) { return static_cast<OwnedPtr &&>(*this); }
145 
146     /**
147      * Overload the assignment operator `=` to replace the object owned by the `OwnedPtr` with another one
148      * using move semantics.
149      *
150      * The `OwnedPtr` first frees its current owned object (if there is any and it is different from @p aOther) before
151      * taking over the ownership of the object from @p aOther. This method correctly handles a self assignment (i.e.,
152      * assigning the pointer to itself).
153      *
154      * @param[in] aOther   An rvalue reference to an `OwnedPtr` to move from.
155      *
156      * @returns A reference to this `OwnedPtr`.
157      */
operator =(OwnedPtr && aOther)158     OwnedPtr &operator=(OwnedPtr &&aOther)
159     {
160         Reset(aOther.Release());
161         return *this;
162     }
163 
164     OwnedPtr(const OwnedPtr &)            = delete;
165     OwnedPtr(OwnedPtr &)                  = delete;
166     OwnedPtr &operator=(const OwnedPtr &) = delete;
167 
168 private:
Delete(void)169     void Delete(void)
170     {
171         if (mPointer != nullptr)
172         {
173             mPointer->Free();
174         }
175     }
176 };
177 
178 } // namespace ot
179 
180 #endif // OWNED_PTR_HPP_
181