mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

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