1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This code is made available to you under your choice of the following sets
4  * of licensing terms:
5  */
6 /* This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9  */
10 /* Copyright 2013 Mozilla Contributors
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *     http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  */
24 
25 #ifndef mozilla_pkix_ScopedPtr_h
26 #define mozilla_pkix_ScopedPtr_h
27 
28 namespace mozilla {
29 namespace pkix {
30 
31 // A subset polyfill of std::unique_ptr that does not support move construction
32 // or move assignment. This is used instead of std::unique_ptr because some
33 // important toolchains still don't provide std::unique_ptr, including in
34 // particular Android NDK projects with APP_STL=stlport_static or
35 // ALL_STL=stlport_shared.
36 template <typename T, void (&Destroyer)(T*)>
37 class ScopedPtr final {
38  public:
mValue(value)39   explicit ScopedPtr(T* value = nullptr) : mValue(value) {}
40 
41   ScopedPtr(const ScopedPtr&) = delete;
42 
~ScopedPtr()43   ~ScopedPtr() {
44     if (mValue) {
45       Destroyer(mValue);
46     }
47   }
48 
49   void operator=(const ScopedPtr&) = delete;
50 
51   T& operator*() const { return *mValue; }
52   T* operator->() const { return mValue; }
53 
54   explicit operator bool() const { return mValue; }
55 
get()56   T* get() const { return mValue; }
57 
release()58   T* release() {
59     T* result = mValue;
60     mValue = nullptr;
61     return result;
62   }
63 
64   void reset(T* newValue = nullptr) {
65     // The C++ standard requires std::unique_ptr to destroy the old value
66     // pointed to by mValue, if any, *after* assigning the new value to mValue.
67     T* oldValue = mValue;
68     mValue = newValue;
69     if (oldValue) {
70       Destroyer(oldValue);
71     }
72   }
73 
74  private:
75   T* mValue;
76 };
77 
78 }  // namespace pkix
79 }  // namespace mozilla
80 
81 #endif  // mozilla_pkix_ScopedPtr_h
82