Donald Meyers / Mbed OS evan
Committer:
djmeyers
Date:
Sat Mar 18 22:37:16 2017 +0000
Revision:
0:06ee5f8a484a
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
djmeyers 0:06ee5f8a484a 1 /*
djmeyers 0:06ee5f8a484a 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
djmeyers 0:06ee5f8a484a 3 * SPDX-License-Identifier: Apache-2.0
djmeyers 0:06ee5f8a484a 4 * Licensed under the Apache License, Version 2.0 (the License); you may
djmeyers 0:06ee5f8a484a 5 * not use this file except in compliance with the License.
djmeyers 0:06ee5f8a484a 6 * You may obtain a copy of the License at
djmeyers 0:06ee5f8a484a 7 *
djmeyers 0:06ee5f8a484a 8 * http://www.apache.org/licenses/LICENSE-2.0
djmeyers 0:06ee5f8a484a 9 *
djmeyers 0:06ee5f8a484a 10 * Unless required by applicable law or agreed to in writing, software
djmeyers 0:06ee5f8a484a 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
djmeyers 0:06ee5f8a484a 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
djmeyers 0:06ee5f8a484a 13 * See the License for the specific language governing permissions and
djmeyers 0:06ee5f8a484a 14 * limitations under the License.
djmeyers 0:06ee5f8a484a 15 */
djmeyers 0:06ee5f8a484a 16 #ifndef SMART_POINTER_H
djmeyers 0:06ee5f8a484a 17 #define SMART_POINTER_H
djmeyers 0:06ee5f8a484a 18
djmeyers 0:06ee5f8a484a 19 class ReferenceCount
djmeyers 0:06ee5f8a484a 20 {
djmeyers 0:06ee5f8a484a 21 private:
djmeyers 0:06ee5f8a484a 22
djmeyers 0:06ee5f8a484a 23 int _count; // Reference count
djmeyers 0:06ee5f8a484a 24
djmeyers 0:06ee5f8a484a 25 public:
djmeyers 0:06ee5f8a484a 26
djmeyers 0:06ee5f8a484a 27 void add_ref()
djmeyers 0:06ee5f8a484a 28 {
djmeyers 0:06ee5f8a484a 29 // Increment the reference count
djmeyers 0:06ee5f8a484a 30 _count++;
djmeyers 0:06ee5f8a484a 31 }
djmeyers 0:06ee5f8a484a 32
djmeyers 0:06ee5f8a484a 33 int release()
djmeyers 0:06ee5f8a484a 34 {
djmeyers 0:06ee5f8a484a 35 // Decrement the reference count and
djmeyers 0:06ee5f8a484a 36 // return the reference count.
djmeyers 0:06ee5f8a484a 37 return --_count;
djmeyers 0:06ee5f8a484a 38 }
djmeyers 0:06ee5f8a484a 39 };
djmeyers 0:06ee5f8a484a 40
djmeyers 0:06ee5f8a484a 41 template < typename T > class SmartPointer
djmeyers 0:06ee5f8a484a 42 {
djmeyers 0:06ee5f8a484a 43 private:
djmeyers 0:06ee5f8a484a 44
djmeyers 0:06ee5f8a484a 45 T *_data; // Generic pointer to be stored
djmeyers 0:06ee5f8a484a 46 ReferenceCount *_reference; // Reference count
djmeyers 0:06ee5f8a484a 47
djmeyers 0:06ee5f8a484a 48
djmeyers 0:06ee5f8a484a 49 public:
djmeyers 0:06ee5f8a484a 50
djmeyers 0:06ee5f8a484a 51 SmartPointer()
djmeyers 0:06ee5f8a484a 52 : _data(0), _reference(0)
djmeyers 0:06ee5f8a484a 53 {
djmeyers 0:06ee5f8a484a 54 // Create a new reference
djmeyers 0:06ee5f8a484a 55 _reference = new ReferenceCount();
djmeyers 0:06ee5f8a484a 56 // Increment the reference count
djmeyers 0:06ee5f8a484a 57 _reference->add_ref();
djmeyers 0:06ee5f8a484a 58 }
djmeyers 0:06ee5f8a484a 59
djmeyers 0:06ee5f8a484a 60 SmartPointer(T* value)
djmeyers 0:06ee5f8a484a 61 : _data(value), _reference(0)
djmeyers 0:06ee5f8a484a 62 {
djmeyers 0:06ee5f8a484a 63 // Create a new reference
djmeyers 0:06ee5f8a484a 64 _reference = new ReferenceCount();
djmeyers 0:06ee5f8a484a 65 // Increment the reference count
djmeyers 0:06ee5f8a484a 66 _reference->add_ref();
djmeyers 0:06ee5f8a484a 67 }
djmeyers 0:06ee5f8a484a 68
djmeyers 0:06ee5f8a484a 69 SmartPointer(const SmartPointer<T>& smart_pointer)
djmeyers 0:06ee5f8a484a 70 : _data(smart_pointer._data), reference(smart_pointer._reference)
djmeyers 0:06ee5f8a484a 71 {
djmeyers 0:06ee5f8a484a 72 // Copy constructor
djmeyers 0:06ee5f8a484a 73 // Copy the data and reference pointer
djmeyers 0:06ee5f8a484a 74 // and increment the reference count
djmeyers 0:06ee5f8a484a 75 _reference->add_ref();
djmeyers 0:06ee5f8a484a 76 }
djmeyers 0:06ee5f8a484a 77
djmeyers 0:06ee5f8a484a 78 ~SmartPointer()
djmeyers 0:06ee5f8a484a 79 {
djmeyers 0:06ee5f8a484a 80 if(_reference->release() == 0) {
djmeyers 0:06ee5f8a484a 81 delete _data;
djmeyers 0:06ee5f8a484a 82 delete _reference;
djmeyers 0:06ee5f8a484a 83 }
djmeyers 0:06ee5f8a484a 84 }
djmeyers 0:06ee5f8a484a 85
djmeyers 0:06ee5f8a484a 86 T& operator* ()
djmeyers 0:06ee5f8a484a 87 {
djmeyers 0:06ee5f8a484a 88 return *_data;
djmeyers 0:06ee5f8a484a 89 }
djmeyers 0:06ee5f8a484a 90
djmeyers 0:06ee5f8a484a 91 T* operator-> ()
djmeyers 0:06ee5f8a484a 92 {
djmeyers 0:06ee5f8a484a 93 return _data;
djmeyers 0:06ee5f8a484a 94 }
djmeyers 0:06ee5f8a484a 95
djmeyers 0:06ee5f8a484a 96 SmartPointer<T>& operator = (const SmartPointer<T>& smart_pointer)
djmeyers 0:06ee5f8a484a 97 {
djmeyers 0:06ee5f8a484a 98 // Assignment operator
djmeyers 0:06ee5f8a484a 99 if (this != &SmartPointer) { // Avoid self assignment
djmeyers 0:06ee5f8a484a 100 // Decrement the old reference count
djmeyers 0:06ee5f8a484a 101 // if reference become zero delete the old data
djmeyers 0:06ee5f8a484a 102 if(_reference->release() == 0) {
djmeyers 0:06ee5f8a484a 103 delete _data;
djmeyers 0:06ee5f8a484a 104 delete _reference;
djmeyers 0:06ee5f8a484a 105 }
djmeyers 0:06ee5f8a484a 106
djmeyers 0:06ee5f8a484a 107 // Copy the data and reference pointer
djmeyers 0:06ee5f8a484a 108 // and increment the reference count
djmeyers 0:06ee5f8a484a 109 _data = SmartPointer._data;
djmeyers 0:06ee5f8a484a 110 _reference = SmartPointer._reference;
djmeyers 0:06ee5f8a484a 111 _reference->add_ref();
djmeyers 0:06ee5f8a484a 112 }
djmeyers 0:06ee5f8a484a 113 return *this;
djmeyers 0:06ee5f8a484a 114 }
djmeyers 0:06ee5f8a484a 115
djmeyers 0:06ee5f8a484a 116 };
djmeyers 0:06ee5f8a484a 117
djmeyers 0:06ee5f8a484a 118 #endif // SMART_POINTER_H