Attempting to publish a tree

Dependencies:   BLE_API mbed-dev-bin nRF51822

Fork of microbit-dal by Lancaster University

Committer:
cefn
Date:
Wed Jun 01 17:43:26 2016 +0000
Revision:
18:ce4dd8fcdf4f
Parent:
1:8aa5cdb4ab67
Attempting to publish a tree

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 #ifndef MICROBIT_MANAGED_TYPE_H
Jonathan Austin 1:8aa5cdb4ab67 27 #define MICROBIT_MANAGED_TYPE_H
Jonathan Austin 1:8aa5cdb4ab67 28
Jonathan Austin 1:8aa5cdb4ab67 29 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 30
Jonathan Austin 1:8aa5cdb4ab67 31 /**
Jonathan Austin 1:8aa5cdb4ab67 32 * Class definition for a Generic Managed Type.
Jonathan Austin 1:8aa5cdb4ab67 33 *
Jonathan Austin 1:8aa5cdb4ab67 34 * Represents a reference counted object.
Jonathan Austin 1:8aa5cdb4ab67 35 *
Jonathan Austin 1:8aa5cdb4ab67 36 * @note When the destructor is called, delete is called on the object - implicitly calling the given objects destructor.
Jonathan Austin 1:8aa5cdb4ab67 37 */
Jonathan Austin 1:8aa5cdb4ab67 38 template <class T>
Jonathan Austin 1:8aa5cdb4ab67 39 class ManagedType
Jonathan Austin 1:8aa5cdb4ab67 40 {
Jonathan Austin 1:8aa5cdb4ab67 41 protected:
Jonathan Austin 1:8aa5cdb4ab67 42
Jonathan Austin 1:8aa5cdb4ab67 43 int *ref;
Jonathan Austin 1:8aa5cdb4ab67 44
Jonathan Austin 1:8aa5cdb4ab67 45 public:
Jonathan Austin 1:8aa5cdb4ab67 46
Jonathan Austin 1:8aa5cdb4ab67 47 T *object;
Jonathan Austin 1:8aa5cdb4ab67 48
Jonathan Austin 1:8aa5cdb4ab67 49 /**
Jonathan Austin 1:8aa5cdb4ab67 50 * Constructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 51 *
Jonathan Austin 1:8aa5cdb4ab67 52 * @param object the object that you would like to be ref counted - of class T
Jonathan Austin 1:8aa5cdb4ab67 53 *
Jonathan Austin 1:8aa5cdb4ab67 54 * @code
Jonathan Austin 1:8aa5cdb4ab67 55 * T object = new T();
Jonathan Austin 1:8aa5cdb4ab67 56 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 57 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 58 */
Jonathan Austin 1:8aa5cdb4ab67 59 ManagedType(T* object);
Jonathan Austin 1:8aa5cdb4ab67 60
Jonathan Austin 1:8aa5cdb4ab67 61 /**
Jonathan Austin 1:8aa5cdb4ab67 62 * Default constructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 63 */
Jonathan Austin 1:8aa5cdb4ab67 64 ManagedType();
Jonathan Austin 1:8aa5cdb4ab67 65
Jonathan Austin 1:8aa5cdb4ab67 66 /**
Jonathan Austin 1:8aa5cdb4ab67 67 * Copy constructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 68 *
Jonathan Austin 1:8aa5cdb4ab67 69 * @param t another managed type instance of class type T.
Jonathan Austin 1:8aa5cdb4ab67 70 *
Jonathan Austin 1:8aa5cdb4ab67 71 * @code
Jonathan Austin 1:8aa5cdb4ab67 72 * T* object = new T();
Jonathan Austin 1:8aa5cdb4ab67 73 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 74 * ManagedType<T> mt1(mt);
Jonathan Austin 1:8aa5cdb4ab67 75 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 76 */
Jonathan Austin 1:8aa5cdb4ab67 77 ManagedType(const ManagedType<T> &t);
Jonathan Austin 1:8aa5cdb4ab67 78
Jonathan Austin 1:8aa5cdb4ab67 79 /**
Jonathan Austin 1:8aa5cdb4ab67 80 * Destructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 81 */
Jonathan Austin 1:8aa5cdb4ab67 82 ~ManagedType();
Jonathan Austin 1:8aa5cdb4ab67 83
Jonathan Austin 1:8aa5cdb4ab67 84 /**
Jonathan Austin 1:8aa5cdb4ab67 85 * Copy-assign member function for the managed type, given a class space.
Jonathan Austin 1:8aa5cdb4ab67 86 *
Jonathan Austin 1:8aa5cdb4ab67 87 * @code
Jonathan Austin 1:8aa5cdb4ab67 88 * T* object = new T();
Jonathan Austin 1:8aa5cdb4ab67 89 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 90 * ManagedType<T> mt1 = mt;
Jonathan Austin 1:8aa5cdb4ab67 91 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 92 */
Jonathan Austin 1:8aa5cdb4ab67 93 ManagedType<T>& operator = (const ManagedType<T>&i);
Jonathan Austin 1:8aa5cdb4ab67 94
Jonathan Austin 1:8aa5cdb4ab67 95 /**
Jonathan Austin 1:8aa5cdb4ab67 96 * Returns the references to this ManagedType.
Jonathan Austin 1:8aa5cdb4ab67 97 *
Jonathan Austin 1:8aa5cdb4ab67 98 * @code
Jonathan Austin 1:8aa5cdb4ab67 99 * T* object = new T();
Jonathan Austin 1:8aa5cdb4ab67 100 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 101 * ManagedType<T> mt1(mt);
Jonathan Austin 1:8aa5cdb4ab67 102 *
Jonathan Austin 1:8aa5cdb4ab67 103 * mt.getReferences // this will be 2!
Jonathan Austin 1:8aa5cdb4ab67 104 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 105 */
Jonathan Austin 1:8aa5cdb4ab67 106 int getReferences();
Jonathan Austin 1:8aa5cdb4ab67 107
Jonathan Austin 1:8aa5cdb4ab67 108 /**
Jonathan Austin 1:8aa5cdb4ab67 109 * De-reference operator overload. This makes modifying ref-counted POD
Jonathan Austin 1:8aa5cdb4ab67 110 * easier.
Jonathan Austin 1:8aa5cdb4ab67 111 *
Jonathan Austin 1:8aa5cdb4ab67 112 * @code
Jonathan Austin 1:8aa5cdb4ab67 113 * ManagedType<int> x = 0;
Jonathan Austin 1:8aa5cdb4ab67 114 * *x = 1; // mutates the ref-counted integer
Jonathan Austin 1:8aa5cdb4ab67 115 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 116 */
Jonathan Austin 1:8aa5cdb4ab67 117 T& operator*() {
Jonathan Austin 1:8aa5cdb4ab67 118 return *object;
Jonathan Austin 1:8aa5cdb4ab67 119 }
Jonathan Austin 1:8aa5cdb4ab67 120
Jonathan Austin 1:8aa5cdb4ab67 121 /**
Jonathan Austin 1:8aa5cdb4ab67 122 * Method call operator overload. This forwards the call to the underlying
Jonathan Austin 1:8aa5cdb4ab67 123 * object.
Jonathan Austin 1:8aa5cdb4ab67 124 *
Jonathan Austin 1:8aa5cdb4ab67 125 * @code
Jonathan Austin 1:8aa5cdb4ab67 126 * ManagedType<T> x = new T();
Jonathan Austin 1:8aa5cdb4ab67 127 * x->m(); // resolves to T::m
Jonathan Austin 1:8aa5cdb4ab67 128 */
Jonathan Austin 1:8aa5cdb4ab67 129 T* operator->() {
Jonathan Austin 1:8aa5cdb4ab67 130 if (object == NULL)
Jonathan Austin 1:8aa5cdb4ab67 131 microbit_panic(MICROBIT_NULL_DEREFERENCE);
Jonathan Austin 1:8aa5cdb4ab67 132 return object;
Jonathan Austin 1:8aa5cdb4ab67 133 }
Jonathan Austin 1:8aa5cdb4ab67 134
Jonathan Austin 1:8aa5cdb4ab67 135 /**
Jonathan Austin 1:8aa5cdb4ab67 136 * Shorthand for `x.operator->()`
Jonathan Austin 1:8aa5cdb4ab67 137 */
Jonathan Austin 1:8aa5cdb4ab67 138 T* get() {
Jonathan Austin 1:8aa5cdb4ab67 139 return object;
Jonathan Austin 1:8aa5cdb4ab67 140 }
Jonathan Austin 1:8aa5cdb4ab67 141
Jonathan Austin 1:8aa5cdb4ab67 142 /**
Jonathan Austin 1:8aa5cdb4ab67 143 * A simple inequality overload to compare two ManagedType instances.
Jonathan Austin 1:8aa5cdb4ab67 144 */
Jonathan Austin 1:8aa5cdb4ab67 145 bool operator!=(const ManagedType<T>& x) {
Jonathan Austin 1:8aa5cdb4ab67 146 return !(this == x);
Jonathan Austin 1:8aa5cdb4ab67 147 }
Jonathan Austin 1:8aa5cdb4ab67 148
Jonathan Austin 1:8aa5cdb4ab67 149 /**
Jonathan Austin 1:8aa5cdb4ab67 150 * A simple equality overload to compare two ManagedType instances.
Jonathan Austin 1:8aa5cdb4ab67 151 */
Jonathan Austin 1:8aa5cdb4ab67 152 bool operator==(const ManagedType<T>& x) {
Jonathan Austin 1:8aa5cdb4ab67 153 return this->object == x.object;
Jonathan Austin 1:8aa5cdb4ab67 154 }
Jonathan Austin 1:8aa5cdb4ab67 155 };
Jonathan Austin 1:8aa5cdb4ab67 156
Jonathan Austin 1:8aa5cdb4ab67 157 /**
Jonathan Austin 1:8aa5cdb4ab67 158 * Constructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 159 *
Jonathan Austin 1:8aa5cdb4ab67 160 * @param object the object that you would like to be ref counted - of class T
Jonathan Austin 1:8aa5cdb4ab67 161 *
Jonathan Austin 1:8aa5cdb4ab67 162 * @code
Jonathan Austin 1:8aa5cdb4ab67 163 * T object = new T();
Jonathan Austin 1:8aa5cdb4ab67 164 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 165 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 166 */
Jonathan Austin 1:8aa5cdb4ab67 167 template<typename T>
Jonathan Austin 1:8aa5cdb4ab67 168 ManagedType<T>::ManagedType(T* object)
Jonathan Austin 1:8aa5cdb4ab67 169 {
Jonathan Austin 1:8aa5cdb4ab67 170 this->object = object;
Jonathan Austin 1:8aa5cdb4ab67 171 ref = (int *)malloc(sizeof(int));
Jonathan Austin 1:8aa5cdb4ab67 172 *ref = 1;
Jonathan Austin 1:8aa5cdb4ab67 173 }
Jonathan Austin 1:8aa5cdb4ab67 174
Jonathan Austin 1:8aa5cdb4ab67 175 /**
Jonathan Austin 1:8aa5cdb4ab67 176 * Default constructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 177 */
Jonathan Austin 1:8aa5cdb4ab67 178 template<typename T>
Jonathan Austin 1:8aa5cdb4ab67 179 ManagedType<T>::ManagedType()
Jonathan Austin 1:8aa5cdb4ab67 180 {
Jonathan Austin 1:8aa5cdb4ab67 181 this->object = NULL;
Jonathan Austin 1:8aa5cdb4ab67 182 ref = (int *)malloc(sizeof(int));
Jonathan Austin 1:8aa5cdb4ab67 183 *ref = 0;
Jonathan Austin 1:8aa5cdb4ab67 184 }
Jonathan Austin 1:8aa5cdb4ab67 185
Jonathan Austin 1:8aa5cdb4ab67 186 /**
Jonathan Austin 1:8aa5cdb4ab67 187 * Copy constructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 188 *
Jonathan Austin 1:8aa5cdb4ab67 189 * @param t another managed type instance of class type T.
Jonathan Austin 1:8aa5cdb4ab67 190 *
Jonathan Austin 1:8aa5cdb4ab67 191 * @code
Jonathan Austin 1:8aa5cdb4ab67 192 * T* object = new T();
Jonathan Austin 1:8aa5cdb4ab67 193 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 194 * ManagedType<T> mt1(mt);
Jonathan Austin 1:8aa5cdb4ab67 195 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 196 */
Jonathan Austin 1:8aa5cdb4ab67 197 template<typename T>
Jonathan Austin 1:8aa5cdb4ab67 198 ManagedType<T>::ManagedType(const ManagedType<T> &t)
Jonathan Austin 1:8aa5cdb4ab67 199 {
Jonathan Austin 1:8aa5cdb4ab67 200 this->object = t.object;
Jonathan Austin 1:8aa5cdb4ab67 201 this->ref = t.ref;
Jonathan Austin 1:8aa5cdb4ab67 202 (*ref)++;
Jonathan Austin 1:8aa5cdb4ab67 203 }
Jonathan Austin 1:8aa5cdb4ab67 204
Jonathan Austin 1:8aa5cdb4ab67 205 /**
Jonathan Austin 1:8aa5cdb4ab67 206 * Destructor for the managed type, given a class space T.
Jonathan Austin 1:8aa5cdb4ab67 207 */
Jonathan Austin 1:8aa5cdb4ab67 208 template<typename T>
Jonathan Austin 1:8aa5cdb4ab67 209 ManagedType<T>::~ManagedType()
Jonathan Austin 1:8aa5cdb4ab67 210 {
Jonathan Austin 1:8aa5cdb4ab67 211 // Special case - we were created using a default constructor, and never assigned a value.
Jonathan Austin 1:8aa5cdb4ab67 212 if (*ref == 0)
Jonathan Austin 1:8aa5cdb4ab67 213 {
Jonathan Austin 1:8aa5cdb4ab67 214 // Simply destroy our reference counter and we're done.
Jonathan Austin 1:8aa5cdb4ab67 215 free(ref);
Jonathan Austin 1:8aa5cdb4ab67 216 }
Jonathan Austin 1:8aa5cdb4ab67 217
Jonathan Austin 1:8aa5cdb4ab67 218 // Normal case - we have a valid piece of data.
Jonathan Austin 1:8aa5cdb4ab67 219 // Decrement our reference counter and free all allocated memory if we're deleting the last reference.
Jonathan Austin 1:8aa5cdb4ab67 220 else if (--(*ref) == 0)
Jonathan Austin 1:8aa5cdb4ab67 221 {
Jonathan Austin 1:8aa5cdb4ab67 222 delete object;
Jonathan Austin 1:8aa5cdb4ab67 223 free(ref);
Jonathan Austin 1:8aa5cdb4ab67 224 }
Jonathan Austin 1:8aa5cdb4ab67 225 }
Jonathan Austin 1:8aa5cdb4ab67 226
Jonathan Austin 1:8aa5cdb4ab67 227 /**
Jonathan Austin 1:8aa5cdb4ab67 228 * Copy-assign member function for the managed type, given a class space.
Jonathan Austin 1:8aa5cdb4ab67 229 *
Jonathan Austin 1:8aa5cdb4ab67 230 * @code
Jonathan Austin 1:8aa5cdb4ab67 231 * T* object = new T();
Jonathan Austin 1:8aa5cdb4ab67 232 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 233 * ManagedType<T> mt1 = mt;
Jonathan Austin 1:8aa5cdb4ab67 234 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 235 */
Jonathan Austin 1:8aa5cdb4ab67 236 template<typename T>
Jonathan Austin 1:8aa5cdb4ab67 237 ManagedType<T>& ManagedType<T>::operator = (const ManagedType<T>&t)
Jonathan Austin 1:8aa5cdb4ab67 238 {
Jonathan Austin 1:8aa5cdb4ab67 239 if (this == &t)
Jonathan Austin 1:8aa5cdb4ab67 240 return *this;
Jonathan Austin 1:8aa5cdb4ab67 241
Jonathan Austin 1:8aa5cdb4ab67 242 // Special case - we were created using a default constructor, and never assigned a value.
Jonathan Austin 1:8aa5cdb4ab67 243 if (*ref == 0)
Jonathan Austin 1:8aa5cdb4ab67 244 {
Jonathan Austin 1:8aa5cdb4ab67 245 // Simply destroy our reference counter, as we're about to adopt another.
Jonathan Austin 1:8aa5cdb4ab67 246 free(ref);
Jonathan Austin 1:8aa5cdb4ab67 247 }
Jonathan Austin 1:8aa5cdb4ab67 248
Jonathan Austin 1:8aa5cdb4ab67 249 else if (--(*ref) == 0)
Jonathan Austin 1:8aa5cdb4ab67 250 {
Jonathan Austin 1:8aa5cdb4ab67 251 delete object;
Jonathan Austin 1:8aa5cdb4ab67 252 free(ref);
Jonathan Austin 1:8aa5cdb4ab67 253 }
Jonathan Austin 1:8aa5cdb4ab67 254
Jonathan Austin 1:8aa5cdb4ab67 255 object = t.object;
Jonathan Austin 1:8aa5cdb4ab67 256 ref = t.ref;
Jonathan Austin 1:8aa5cdb4ab67 257
Jonathan Austin 1:8aa5cdb4ab67 258 (*ref)++;
Jonathan Austin 1:8aa5cdb4ab67 259
Jonathan Austin 1:8aa5cdb4ab67 260 return *this;
Jonathan Austin 1:8aa5cdb4ab67 261 }
Jonathan Austin 1:8aa5cdb4ab67 262
Jonathan Austin 1:8aa5cdb4ab67 263 /**
Jonathan Austin 1:8aa5cdb4ab67 264 * Returns the references to this ManagedType.
Jonathan Austin 1:8aa5cdb4ab67 265 *
Jonathan Austin 1:8aa5cdb4ab67 266 * @code
Jonathan Austin 1:8aa5cdb4ab67 267 * T* object = new T();
Jonathan Austin 1:8aa5cdb4ab67 268 * ManagedType<T> mt(t);
Jonathan Austin 1:8aa5cdb4ab67 269 * ManagedType<T> mt1(mt);
Jonathan Austin 1:8aa5cdb4ab67 270 *
Jonathan Austin 1:8aa5cdb4ab67 271 * mt.getReferences // this will be 2!
Jonathan Austin 1:8aa5cdb4ab67 272 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 273 */
Jonathan Austin 1:8aa5cdb4ab67 274 template<typename T>
Jonathan Austin 1:8aa5cdb4ab67 275 int ManagedType<T>::getReferences()
Jonathan Austin 1:8aa5cdb4ab67 276 {
Jonathan Austin 1:8aa5cdb4ab67 277 return (*ref);
Jonathan Austin 1:8aa5cdb4ab67 278 }
Jonathan Austin 1:8aa5cdb4ab67 279 #endif