RTC auf true

Committer:
kevman
Date:
Wed Nov 28 15:10:15 2018 +0000
Revision:
0:38ceb79fef03
RTC modified

Who changed what in which revision?

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