test test test

Dependencies:   mbed

Committer:
mohamedmoawya
Date:
Mon May 25 19:06:11 2020 +0000
Revision:
0:e4c5e6ec922e
snake game tteest

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mohamedmoawya 0:e4c5e6ec922e 1 /* Copyright (c) 2017 ARM Limited
mohamedmoawya 0:e4c5e6ec922e 2 *
mohamedmoawya 0:e4c5e6ec922e 3 * Licensed under the Apache License, Version 2.0 (the "License");
mohamedmoawya 0:e4c5e6ec922e 4 * you may not use this file except in compliance with the License.
mohamedmoawya 0:e4c5e6ec922e 5 * You may obtain a copy of the License at
mohamedmoawya 0:e4c5e6ec922e 6 *
mohamedmoawya 0:e4c5e6ec922e 7 * http://www.apache.org/licenses/LICENSE-2.0
mohamedmoawya 0:e4c5e6ec922e 8 *
mohamedmoawya 0:e4c5e6ec922e 9 * Unless required by applicable law or agreed to in writing, software
mohamedmoawya 0:e4c5e6ec922e 10 * distributed under the License is distributed on an "AS IS" BASIS,
mohamedmoawya 0:e4c5e6ec922e 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mohamedmoawya 0:e4c5e6ec922e 12 * See the License for the specific language governing permissions and
mohamedmoawya 0:e4c5e6ec922e 13 * limitations under the License.
mohamedmoawya 0:e4c5e6ec922e 14 */
mohamedmoawya 0:e4c5e6ec922e 15
mohamedmoawya 0:e4c5e6ec922e 16 #ifndef MBED_NONCOPYABLE_H_
mohamedmoawya 0:e4c5e6ec922e 17 #define MBED_NONCOPYABLE_H_
mohamedmoawya 0:e4c5e6ec922e 18
mohamedmoawya 0:e4c5e6ec922e 19 #if (!defined(MBED_DEBUG) && (MBED_CONF_PLATFORM_FORCE_NON_COPYABLE_ERROR == 0))
mohamedmoawya 0:e4c5e6ec922e 20 #include "mbed_toolchain.h"
mohamedmoawya 0:e4c5e6ec922e 21 #include "mbed_debug.h"
mohamedmoawya 0:e4c5e6ec922e 22 #endif
mohamedmoawya 0:e4c5e6ec922e 23
mohamedmoawya 0:e4c5e6ec922e 24 namespace mbed {
mohamedmoawya 0:e4c5e6ec922e 25
mohamedmoawya 0:e4c5e6ec922e 26 /** \addtogroup platform */
mohamedmoawya 0:e4c5e6ec922e 27 /** @{*/
mohamedmoawya 0:e4c5e6ec922e 28 /**
mohamedmoawya 0:e4c5e6ec922e 29 * \defgroup platform_NonCopyable NonCopyable class
mohamedmoawya 0:e4c5e6ec922e 30 * @{
mohamedmoawya 0:e4c5e6ec922e 31 */
mohamedmoawya 0:e4c5e6ec922e 32
mohamedmoawya 0:e4c5e6ec922e 33 /**
mohamedmoawya 0:e4c5e6ec922e 34 * Prevents generation of copy constructor and copy assignment operator in
mohamedmoawya 0:e4c5e6ec922e 35 * derived classes.
mohamedmoawya 0:e4c5e6ec922e 36 *
mohamedmoawya 0:e4c5e6ec922e 37 * @par Usage
mohamedmoawya 0:e4c5e6ec922e 38 *
mohamedmoawya 0:e4c5e6ec922e 39 * To prevent generation of copy constructor and copy assignment operator,
mohamedmoawya 0:e4c5e6ec922e 40 * inherit privately from the NonCopyable class.
mohamedmoawya 0:e4c5e6ec922e 41 *
mohamedmoawya 0:e4c5e6ec922e 42 * @code
mohamedmoawya 0:e4c5e6ec922e 43 * class Resource : NonCopyable<Resource> { };
mohamedmoawya 0:e4c5e6ec922e 44 *
mohamedmoawya 0:e4c5e6ec922e 45 * Resource r;
mohamedmoawya 0:e4c5e6ec922e 46 * // generates compile time error:
mohamedmoawya 0:e4c5e6ec922e 47 * Resource r2 = r;
mohamedmoawya 0:e4c5e6ec922e 48 * @endcode
mohamedmoawya 0:e4c5e6ec922e 49 *
mohamedmoawya 0:e4c5e6ec922e 50 * @par Background information
mohamedmoawya 0:e4c5e6ec922e 51 *
mohamedmoawya 0:e4c5e6ec922e 52 * Instances of polymorphic classes are not meant to be copied. The
mohamedmoawya 0:e4c5e6ec922e 53 * C++ standards generate a default copy constructor and copy assignment
mohamedmoawya 0:e4c5e6ec922e 54 * function if these functions have not been defined in the class.
mohamedmoawya 0:e4c5e6ec922e 55 *
mohamedmoawya 0:e4c5e6ec922e 56 * Consider the following example:
mohamedmoawya 0:e4c5e6ec922e 57 *
mohamedmoawya 0:e4c5e6ec922e 58 * @code
mohamedmoawya 0:e4c5e6ec922e 59 * // base class representing a connection
mohamedmoawya 0:e4c5e6ec922e 60 * struct Connection {
mohamedmoawya 0:e4c5e6ec922e 61 * Connection();
mohamedmoawya 0:e4c5e6ec922e 62 * virtual ~Connection();
mohamedmoawya 0:e4c5e6ec922e 63 * virtual void open() = 0;
mohamedmoawya 0:e4c5e6ec922e 64 * }
mohamedmoawya 0:e4c5e6ec922e 65 *
mohamedmoawya 0:e4c5e6ec922e 66 * class SerialConnection : public Connection {
mohamedmoawya 0:e4c5e6ec922e 67 * public:
mohamedmoawya 0:e4c5e6ec922e 68 * SerialConnection(Serial*);
mohamedmoawya 0:e4c5e6ec922e 69 *
mohamedmoawya 0:e4c5e6ec922e 70 * private:
mohamedmoawya 0:e4c5e6ec922e 71 * Serial* _serial;
mohamedmoawya 0:e4c5e6ec922e 72 * };
mohamedmoawya 0:e4c5e6ec922e 73 *
mohamedmoawya 0:e4c5e6ec922e 74 * Connection& get_connection() {
mohamedmoawya 0:e4c5e6ec922e 75 * static SerialConnection serial_connection;
mohamedmoawya 0:e4c5e6ec922e 76 * return serial_connection;
mohamedmoawya 0:e4c5e6ec922e 77 * }
mohamedmoawya 0:e4c5e6ec922e 78 *
mohamedmoawya 0:e4c5e6ec922e 79 * Connection connection = get_connection();
mohamedmoawya 0:e4c5e6ec922e 80 * @endcode
mohamedmoawya 0:e4c5e6ec922e 81 *
mohamedmoawya 0:e4c5e6ec922e 82 * There is a subtle bug in this code, the function get_connection returns a
mohamedmoawya 0:e4c5e6ec922e 83 * reference to a Connection which is captured by value instead of reference.
mohamedmoawya 0:e4c5e6ec922e 84 *
mohamedmoawya 0:e4c5e6ec922e 85 * When `get_connection` returns a reference to serial_connection it is copied into
mohamedmoawya 0:e4c5e6ec922e 86 * the local variable connection. The vtable and others members defined in Connection
mohamedmoawya 0:e4c5e6ec922e 87 * are copied, but members defined in SerialConnection are left apart. This can cause
mohamedmoawya 0:e4c5e6ec922e 88 * severe crashes or bugs if the virtual functions captured use members not present
mohamedmoawya 0:e4c5e6ec922e 89 * in the base declaration.
mohamedmoawya 0:e4c5e6ec922e 90 *
mohamedmoawya 0:e4c5e6ec922e 91 * To solve that problem, the copy constructor and assignment operator have to
mohamedmoawya 0:e4c5e6ec922e 92 * be declared (but don't need to be defined) in the private section of the
mohamedmoawya 0:e4c5e6ec922e 93 * Connection class:
mohamedmoawya 0:e4c5e6ec922e 94 *
mohamedmoawya 0:e4c5e6ec922e 95 * @code
mohamedmoawya 0:e4c5e6ec922e 96 * struct Connection {
mohamedmoawya 0:e4c5e6ec922e 97 * private:
mohamedmoawya 0:e4c5e6ec922e 98 * Connection(const Connection&);
mohamedmoawya 0:e4c5e6ec922e 99 * Connection& operator=(const Connection&);
mohamedmoawya 0:e4c5e6ec922e 100 * }
mohamedmoawya 0:e4c5e6ec922e 101 * @endcode
mohamedmoawya 0:e4c5e6ec922e 102 *
mohamedmoawya 0:e4c5e6ec922e 103 * Although manually declaring private copy constructor and assignment functions
mohamedmoawya 0:e4c5e6ec922e 104 * works, it is not ideal. These declarations are usually easy to forget,
mohamedmoawya 0:e4c5e6ec922e 105 * not immediately visible, and may be obscure to uninformed programmers.
mohamedmoawya 0:e4c5e6ec922e 106 *
mohamedmoawya 0:e4c5e6ec922e 107 * Using the NonCopyable class reduces the boilerplate required and expresses
mohamedmoawya 0:e4c5e6ec922e 108 * the intent because class inheritance appears right after the class name
mohamedmoawya 0:e4c5e6ec922e 109 * declaration.
mohamedmoawya 0:e4c5e6ec922e 110 *
mohamedmoawya 0:e4c5e6ec922e 111 * @code
mohamedmoawya 0:e4c5e6ec922e 112 * struct Connection : private NonCopyable<Connection> {
mohamedmoawya 0:e4c5e6ec922e 113 * // regular declarations
mohamedmoawya 0:e4c5e6ec922e 114 * }
mohamedmoawya 0:e4c5e6ec922e 115 * @endcode
mohamedmoawya 0:e4c5e6ec922e 116 *
mohamedmoawya 0:e4c5e6ec922e 117 *
mohamedmoawya 0:e4c5e6ec922e 118 * @par Implementation details
mohamedmoawya 0:e4c5e6ec922e 119 *
mohamedmoawya 0:e4c5e6ec922e 120 * Using a template type prevents cases where the empty base optimization cannot
mohamedmoawya 0:e4c5e6ec922e 121 * be applied and therefore ensures that the cost of the NonCopyable semantic
mohamedmoawya 0:e4c5e6ec922e 122 * sugar is null.
mohamedmoawya 0:e4c5e6ec922e 123 *
mohamedmoawya 0:e4c5e6ec922e 124 * As an example, the empty base optimization is prohibited if one of the empty
mohamedmoawya 0:e4c5e6ec922e 125 * base classes is also a base type of the first nonstatic data member:
mohamedmoawya 0:e4c5e6ec922e 126 *
mohamedmoawya 0:e4c5e6ec922e 127 * @code
mohamedmoawya 0:e4c5e6ec922e 128 * struct A { };
mohamedmoawya 0:e4c5e6ec922e 129 * struct B : A {
mohamedmoawya 0:e4c5e6ec922e 130 * int foo;
mohamedmoawya 0:e4c5e6ec922e 131 * };
mohamedmoawya 0:e4c5e6ec922e 132 * // thanks to empty base optimization, sizeof(B) == sizeof(int)
mohamedmoawya 0:e4c5e6ec922e 133 *
mohamedmoawya 0:e4c5e6ec922e 134 * struct C : A {
mohamedmoawya 0:e4c5e6ec922e 135 * B b;
mohamedmoawya 0:e4c5e6ec922e 136 * };
mohamedmoawya 0:e4c5e6ec922e 137 *
mohamedmoawya 0:e4c5e6ec922e 138 * // empty base optimization cannot be applied here because A from C and A from
mohamedmoawya 0:e4c5e6ec922e 139 * // B have a different address. In that case, with the alignment
mohamedmoawya 0:e4c5e6ec922e 140 * // sizeof(C) == 2* sizeof(int)
mohamedmoawya 0:e4c5e6ec922e 141 * @endcode
mohamedmoawya 0:e4c5e6ec922e 142 *
mohamedmoawya 0:e4c5e6ec922e 143 * The solution to that problem is to templatize the empty class to make it
mohamedmoawya 0:e4c5e6ec922e 144 * unique to the type it is applied to:
mohamedmoawya 0:e4c5e6ec922e 145 *
mohamedmoawya 0:e4c5e6ec922e 146 * @code
mohamedmoawya 0:e4c5e6ec922e 147 * template<typename T>
mohamedmoawya 0:e4c5e6ec922e 148 * struct A<T> { };
mohamedmoawya 0:e4c5e6ec922e 149 * struct B : A<B> {
mohamedmoawya 0:e4c5e6ec922e 150 * int foo;
mohamedmoawya 0:e4c5e6ec922e 151 * };
mohamedmoawya 0:e4c5e6ec922e 152 * struct C : A<C> {
mohamedmoawya 0:e4c5e6ec922e 153 * B b;
mohamedmoawya 0:e4c5e6ec922e 154 * };
mohamedmoawya 0:e4c5e6ec922e 155 *
mohamedmoawya 0:e4c5e6ec922e 156 * // empty base optimization can be applied B and C does not refer to the same
mohamedmoawya 0:e4c5e6ec922e 157 * // kind of A. sizeof(C) == sizeof(B) == sizeof(int).
mohamedmoawya 0:e4c5e6ec922e 158 * @endcode
mohamedmoawya 0:e4c5e6ec922e 159 *
mohamedmoawya 0:e4c5e6ec922e 160 * @tparam T The type that should be made noncopyable.
mohamedmoawya 0:e4c5e6ec922e 161 *
mohamedmoawya 0:e4c5e6ec922e 162 * @note Compile time errors are disabled if you use the develop or release profile.
mohamedmoawya 0:e4c5e6ec922e 163 * To override this behavior and force compile time errors in all profiles,
mohamedmoawya 0:e4c5e6ec922e 164 * set the configuration parameter "platform.force-non-copyable-error" to true.
mohamedmoawya 0:e4c5e6ec922e 165 */
mohamedmoawya 0:e4c5e6ec922e 166 template<typename T>
mohamedmoawya 0:e4c5e6ec922e 167 class NonCopyable {
mohamedmoawya 0:e4c5e6ec922e 168 #ifndef DOXYGEN_ONLY
mohamedmoawya 0:e4c5e6ec922e 169 protected:
mohamedmoawya 0:e4c5e6ec922e 170 /**
mohamedmoawya 0:e4c5e6ec922e 171 * Disallow construction of NonCopyable objects from outside of its hierarchy.
mohamedmoawya 0:e4c5e6ec922e 172 */
mohamedmoawya 0:e4c5e6ec922e 173 NonCopyable() { }
mohamedmoawya 0:e4c5e6ec922e 174 /**
mohamedmoawya 0:e4c5e6ec922e 175 * Disallow destruction of NonCopyable objects from outside of its hierarchy.
mohamedmoawya 0:e4c5e6ec922e 176 */
mohamedmoawya 0:e4c5e6ec922e 177 ~NonCopyable() { }
mohamedmoawya 0:e4c5e6ec922e 178
mohamedmoawya 0:e4c5e6ec922e 179 #if (!defined(MBED_DEBUG) && (MBED_CONF_PLATFORM_FORCE_NON_COPYABLE_ERROR == 0))
mohamedmoawya 0:e4c5e6ec922e 180 /**
mohamedmoawya 0:e4c5e6ec922e 181 * NonCopyable copy constructor.
mohamedmoawya 0:e4c5e6ec922e 182 *
mohamedmoawya 0:e4c5e6ec922e 183 * A compile time warning is issued when this function is used, and a runtime
mohamedmoawya 0:e4c5e6ec922e 184 * warning is printed when the copy construction of the noncopyable happens.
mohamedmoawya 0:e4c5e6ec922e 185 *
mohamedmoawya 0:e4c5e6ec922e 186 * If you see this warning, your code is probably doing something unspecified.
mohamedmoawya 0:e4c5e6ec922e 187 * Copying of noncopyable resources can lead to resource leak and random error.
mohamedmoawya 0:e4c5e6ec922e 188 */
mohamedmoawya 0:e4c5e6ec922e 189 MBED_DEPRECATED("Invalid copy construction of a NonCopyable resource.")
mohamedmoawya 0:e4c5e6ec922e 190 NonCopyable(const NonCopyable &)
mohamedmoawya 0:e4c5e6ec922e 191 {
mohamedmoawya 0:e4c5e6ec922e 192 debug("Invalid copy construction of a NonCopyable resource: %s\r\n", MBED_PRETTY_FUNCTION);
mohamedmoawya 0:e4c5e6ec922e 193 }
mohamedmoawya 0:e4c5e6ec922e 194
mohamedmoawya 0:e4c5e6ec922e 195 /**
mohamedmoawya 0:e4c5e6ec922e 196 * NonCopyable copy assignment operator.
mohamedmoawya 0:e4c5e6ec922e 197 *
mohamedmoawya 0:e4c5e6ec922e 198 * A compile time warning is issued when this function is used, and a runtime
mohamedmoawya 0:e4c5e6ec922e 199 * warning is printed when the copy construction of the noncopyable happens.
mohamedmoawya 0:e4c5e6ec922e 200 *
mohamedmoawya 0:e4c5e6ec922e 201 * If you see this warning, your code is probably doing something unspecified.
mohamedmoawya 0:e4c5e6ec922e 202 * Copying of noncopyable resources can lead to resource leak and random error.
mohamedmoawya 0:e4c5e6ec922e 203 */
mohamedmoawya 0:e4c5e6ec922e 204 MBED_DEPRECATED("Invalid copy assignment of a NonCopyable resource.")
mohamedmoawya 0:e4c5e6ec922e 205 NonCopyable &operator=(const NonCopyable &)
mohamedmoawya 0:e4c5e6ec922e 206 {
mohamedmoawya 0:e4c5e6ec922e 207 debug("Invalid copy assignment of a NonCopyable resource: %s\r\n", MBED_PRETTY_FUNCTION);
mohamedmoawya 0:e4c5e6ec922e 208 return *this;
mohamedmoawya 0:e4c5e6ec922e 209 }
mohamedmoawya 0:e4c5e6ec922e 210
mohamedmoawya 0:e4c5e6ec922e 211 #else
mohamedmoawya 0:e4c5e6ec922e 212 private:
mohamedmoawya 0:e4c5e6ec922e 213 /**
mohamedmoawya 0:e4c5e6ec922e 214 * Declare copy constructor as private. Any attempt to copy construct
mohamedmoawya 0:e4c5e6ec922e 215 * a NonCopyable will fail at compile time.
mohamedmoawya 0:e4c5e6ec922e 216 */
mohamedmoawya 0:e4c5e6ec922e 217 NonCopyable(const NonCopyable &);
mohamedmoawya 0:e4c5e6ec922e 218
mohamedmoawya 0:e4c5e6ec922e 219 /**
mohamedmoawya 0:e4c5e6ec922e 220 * Declare copy assignment operator as private. Any attempt to copy assign
mohamedmoawya 0:e4c5e6ec922e 221 * a NonCopyable will fail at compile time.
mohamedmoawya 0:e4c5e6ec922e 222 */
mohamedmoawya 0:e4c5e6ec922e 223 NonCopyable &operator=(const NonCopyable &);
mohamedmoawya 0:e4c5e6ec922e 224 #endif
mohamedmoawya 0:e4c5e6ec922e 225 #endif
mohamedmoawya 0:e4c5e6ec922e 226 };
mohamedmoawya 0:e4c5e6ec922e 227
mohamedmoawya 0:e4c5e6ec922e 228 /**@}*/
mohamedmoawya 0:e4c5e6ec922e 229
mohamedmoawya 0:e4c5e6ec922e 230 /**@}*/
mohamedmoawya 0:e4c5e6ec922e 231
mohamedmoawya 0:e4c5e6ec922e 232 } // namespace mbed
mohamedmoawya 0:e4c5e6ec922e 233
mohamedmoawya 0:e4c5e6ec922e 234 #endif /* MBED_NONCOPYABLE_H_ */