Eddystone test using modified DAL

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit-eddystone

Fork of microbit-dal by Lancaster University

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ManagedType.h Source File

ManagedType.h

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 #ifndef MICROBIT_MANAGED_TYPE_H
00027 #define MICROBIT_MANAGED_TYPE_H
00028 
00029 #include "MicroBitConfig.h"
00030 
00031 /**
00032   * Class definition for a Generic Managed Type.
00033   *
00034   * Represents a reference counted object.
00035   *
00036   * @note When the destructor is called, delete is called on the object - implicitly calling the given objects destructor.
00037   */
00038 template <class T>
00039 class ManagedType
00040 {
00041 protected:
00042 
00043     int *ref;
00044 
00045 public:
00046 
00047     T *object;
00048 
00049     /**
00050       * Constructor for the managed type, given a class space T.
00051       *
00052       * @param object the object that you would like to be ref counted - of class T
00053       *
00054       * @code
00055       * T object = new T();
00056       * ManagedType<T> mt(t);
00057       * @endcode
00058       */
00059     ManagedType(T* object);
00060 
00061     /**
00062       * Default constructor for the managed type, given a class space T.
00063       */
00064     ManagedType();
00065 
00066     /**
00067       * Copy constructor for the managed type, given a class space T.
00068       *
00069       * @param t another managed type instance of class type T.
00070       *
00071       * @code
00072       * T* object = new T();
00073       * ManagedType<T> mt(t);
00074       * ManagedType<T> mt1(mt);
00075       * @endcode
00076       */
00077     ManagedType(const ManagedType<T> &t);
00078 
00079     /**
00080       * Destructor for the managed type, given a class space T.
00081       */
00082     ~ManagedType();
00083 
00084     /**
00085       * Copy-assign member function for the managed type, given a class space.
00086       *
00087       * @code
00088       * T* object = new T();
00089       * ManagedType<T> mt(t);
00090       * ManagedType<T> mt1 = mt;
00091       * @endcode
00092       */
00093     ManagedType<T>& operator = (const ManagedType<T>&i);
00094 
00095     /**
00096       * Returns the references to this ManagedType.
00097       *
00098       * @code
00099       * T* object = new T();
00100       * ManagedType<T> mt(t);
00101       * ManagedType<T> mt1(mt);
00102       *
00103       * mt.getReferences // this will be 2!
00104       * @endcode
00105       */
00106     int getReferences();
00107 
00108     /**
00109       * De-reference operator overload. This makes modifying ref-counted POD
00110       * easier.
00111       *
00112       * @code
00113       * ManagedType<int> x = 0;
00114       * *x = 1; // mutates the ref-counted integer
00115       * @endcode
00116       */
00117     T& operator*() {
00118         return *object;
00119     }
00120 
00121     /**
00122       * Method call operator overload. This forwards the call to the underlying
00123       * object.
00124       *
00125       * @code
00126       * ManagedType<T> x = new T();
00127       * x->m(); // resolves to T::m
00128       */
00129     T* operator->() {
00130         if (object == NULL)
00131             microbit_panic(MICROBIT_NULL_DEREFERENCE);
00132         return object;
00133     }
00134 
00135     /**
00136       * Shorthand for `x.operator->()`
00137       */
00138     T* get() {
00139         return object;
00140     }
00141 
00142     /**
00143       * A simple inequality overload to compare two ManagedType instances.
00144       */
00145     bool operator!=(const ManagedType<T>& x) {
00146         return !(this == x);
00147     }
00148 
00149     /**
00150       * A simple equality overload to compare two ManagedType instances.
00151       */
00152     bool operator==(const ManagedType<T>& x) {
00153         return this->object == x.object;
00154     }
00155 };
00156 
00157 /**
00158   * Constructor for the managed type, given a class space T.
00159   *
00160   * @param object the object that you would like to be ref counted - of class T
00161   *
00162   * @code
00163   * T object = new T();
00164   * ManagedType<T> mt(t);
00165   * @endcode
00166   */
00167 template<typename T>
00168 ManagedType<T>::ManagedType(T* object)
00169 {
00170     this->object = object;
00171     ref = (int *)malloc(sizeof(int));
00172     *ref = 1;
00173 }
00174 
00175 /**
00176   * Default constructor for the managed type, given a class space T.
00177   */
00178 template<typename T>
00179 ManagedType<T>::ManagedType()
00180 {
00181     this->object = NULL;
00182     ref = (int *)malloc(sizeof(int));
00183     *ref = 0;
00184 }
00185 
00186 /**
00187   * Copy constructor for the managed type, given a class space T.
00188   *
00189   * @param t another managed type instance of class type T.
00190   *
00191   * @code
00192   * T* object = new T();
00193   * ManagedType<T> mt(t);
00194   * ManagedType<T> mt1(mt);
00195   * @endcode
00196   */
00197 template<typename T>
00198 ManagedType<T>::ManagedType(const ManagedType<T> &t)
00199 {
00200     this->object = t.object;
00201     this->ref = t.ref;
00202     (*ref)++;
00203 }
00204 
00205 /**
00206   * Destructor for the managed type, given a class space T.
00207   */
00208 template<typename T>
00209 ManagedType<T>::~ManagedType()
00210 {
00211     // Special case - we were created using a default constructor, and never assigned a value.
00212     if (*ref == 0)
00213     {
00214         // Simply destroy our reference counter and we're done.
00215         free(ref);
00216     }
00217 
00218     // Normal case - we have a valid piece of data.
00219     // Decrement our reference counter and free all allocated memory if we're deleting the last reference.
00220     else if (--(*ref) == 0)
00221     {
00222         delete object;
00223         free(ref);
00224     }
00225 }
00226 
00227 /**
00228   * Copy-assign member function for the managed type, given a class space.
00229   *
00230   * @code
00231   * T* object = new T();
00232   * ManagedType<T> mt(t);
00233   * ManagedType<T> mt1 = mt;
00234   * @endcode
00235   */
00236 template<typename T>
00237 ManagedType<T>& ManagedType<T>::operator = (const ManagedType<T>&t)
00238 {
00239     if (this == &t)
00240         return *this;
00241 
00242     // Special case - we were created using a default constructor, and never assigned a value.
00243     if (*ref == 0)
00244     {
00245         // Simply destroy our reference counter, as we're about to adopt another.
00246         free(ref);
00247     }
00248 
00249     else if (--(*ref) == 0)
00250     {
00251         delete object;
00252         free(ref);
00253     }
00254 
00255     object = t.object;
00256     ref = t.ref;
00257 
00258     (*ref)++;
00259 
00260     return *this;
00261 }
00262 
00263 /**
00264   * Returns the references to this ManagedType.
00265   *
00266   * @code
00267   * T* object = new T();
00268   * ManagedType<T> mt(t);
00269   * ManagedType<T> mt1(mt);
00270   *
00271   * mt.getReferences // this will be 2!
00272   * @endcode
00273   */
00274 template<typename T>
00275 int ManagedType<T>::getReferences()
00276 {
00277     return (*ref);
00278 }
00279 #endif