Initial commit

Dependencies:   FastPWM

Committer:
lypinator
Date:
Wed Sep 16 01:11:49 2020 +0000
Revision:
0:bb348c97df44
Added PWM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lypinator 0:bb348c97df44 1 /* Copyright (c) 2017 ARM Limited
lypinator 0:bb348c97df44 2 *
lypinator 0:bb348c97df44 3 * Licensed under the Apache License, Version 2.0 (the "License");
lypinator 0:bb348c97df44 4 * you may not use this file except in compliance with the License.
lypinator 0:bb348c97df44 5 * You may obtain a copy of the License at
lypinator 0:bb348c97df44 6 *
lypinator 0:bb348c97df44 7 * http://www.apache.org/licenses/LICENSE-2.0
lypinator 0:bb348c97df44 8 *
lypinator 0:bb348c97df44 9 * Unless required by applicable law or agreed to in writing, software
lypinator 0:bb348c97df44 10 * distributed under the License is distributed on an "AS IS" BASIS,
lypinator 0:bb348c97df44 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lypinator 0:bb348c97df44 12 * See the License for the specific language governing permissions and
lypinator 0:bb348c97df44 13 * limitations under the License.
lypinator 0:bb348c97df44 14 */
lypinator 0:bb348c97df44 15
lypinator 0:bb348c97df44 16 #ifndef MBED_NONCOPYABLE_H_
lypinator 0:bb348c97df44 17 #define MBED_NONCOPYABLE_H_
lypinator 0:bb348c97df44 18
lypinator 0:bb348c97df44 19 #if (!defined(MBED_DEBUG) && (MBED_CONF_PLATFORM_FORCE_NON_COPYABLE_ERROR == 0))
lypinator 0:bb348c97df44 20 #include "mbed_toolchain.h"
lypinator 0:bb348c97df44 21 #include "mbed_debug.h"
lypinator 0:bb348c97df44 22 #endif
lypinator 0:bb348c97df44 23
lypinator 0:bb348c97df44 24 namespace mbed {
lypinator 0:bb348c97df44 25
lypinator 0:bb348c97df44 26 /**
lypinator 0:bb348c97df44 27 * Inheriting from this class autogeneration of copy construction and copy
lypinator 0:bb348c97df44 28 * assignment operations.
lypinator 0:bb348c97df44 29 *
lypinator 0:bb348c97df44 30 * Classes which are not value type should inherit privately from this class
lypinator 0:bb348c97df44 31 * to avoid generation of invalid copy constructor or copy assignment operator
lypinator 0:bb348c97df44 32 * which can lead to unnoticeable programming errors.
lypinator 0:bb348c97df44 33 *
lypinator 0:bb348c97df44 34 * As an example consider the following signature:
lypinator 0:bb348c97df44 35 *
lypinator 0:bb348c97df44 36 * @code
lypinator 0:bb348c97df44 37 * class Resource;
lypinator 0:bb348c97df44 38 *
lypinator 0:bb348c97df44 39 * class Foo {
lypinator 0:bb348c97df44 40 * public:
lypinator 0:bb348c97df44 41 * Foo() : _resource(new Resource()) { }
lypinator 0:bb348c97df44 42 * ~Foo() { delete _resource; }
lypinator 0:bb348c97df44 43 * private:
lypinator 0:bb348c97df44 44 * Resource* _resource;
lypinator 0:bb348c97df44 45 * }
lypinator 0:bb348c97df44 46 *
lypinator 0:bb348c97df44 47 * Foo get_foo();
lypinator 0:bb348c97df44 48 *
lypinator 0:bb348c97df44 49 * Foo foo = get_foo();
lypinator 0:bb348c97df44 50 * @endcode
lypinator 0:bb348c97df44 51 *
lypinator 0:bb348c97df44 52 * There is a bug in this function, it returns a temporary value which will be
lypinator 0:bb348c97df44 53 * byte copied into foo then destroyed. Unfortunately, internally the Foo class
lypinator 0:bb348c97df44 54 * manage a pointer to a Resource object. This pointer will be released when the
lypinator 0:bb348c97df44 55 * temporary is destroyed and foo will manage a pointer to an already released
lypinator 0:bb348c97df44 56 * Resource.
lypinator 0:bb348c97df44 57 *
lypinator 0:bb348c97df44 58 * Two issues has to be fixed in the example above:
lypinator 0:bb348c97df44 59 * - Function signature has to be changed to reflect the fact that Foo
lypinator 0:bb348c97df44 60 * instances cannot be copied. In that case accessor should return a
lypinator 0:bb348c97df44 61 * reference to give access to objects already existing and managed.
lypinator 0:bb348c97df44 62 * Generator on the other hand should return a pointer to the created object.
lypinator 0:bb348c97df44 63 *
lypinator 0:bb348c97df44 64 * @code
lypinator 0:bb348c97df44 65 * // return a reference to an already managed Foo instance
lypinator 0:bb348c97df44 66 * Foo& get_foo();
lypinator 0:bb348c97df44 67 * Foo& foo = get_foo();
lypinator 0:bb348c97df44 68 *
lypinator 0:bb348c97df44 69 * // create a new Foo instance
lypinator 0:bb348c97df44 70 * Foo* make_foo();
lypinator 0:bb348c97df44 71 * Foo* m = make_foo();
lypinator 0:bb348c97df44 72 * @endcode
lypinator 0:bb348c97df44 73 *
lypinator 0:bb348c97df44 74 * - Copy constructor and copy assignment operator has to be made private
lypinator 0:bb348c97df44 75 * in the Foo class. It prevents unwanted copy of Foo objects. This can be
lypinator 0:bb348c97df44 76 * done by declaring copy constructor and copy assignment in the private
lypinator 0:bb348c97df44 77 * section of the Foo class.
lypinator 0:bb348c97df44 78 *
lypinator 0:bb348c97df44 79 * @code
lypinator 0:bb348c97df44 80 * class Foo {
lypinator 0:bb348c97df44 81 * public:
lypinator 0:bb348c97df44 82 * Foo() : _resource(new Resource()) { }
lypinator 0:bb348c97df44 83 * ~Foo() { delete _resource; }
lypinator 0:bb348c97df44 84 * private:
lypinator 0:bb348c97df44 85 * // disallow copy operations
lypinator 0:bb348c97df44 86 * Foo(const Foo&);
lypinator 0:bb348c97df44 87 * Foo& operator=(const Foo&);
lypinator 0:bb348c97df44 88 * // data members
lypinator 0:bb348c97df44 89 * Resource* _resource;
lypinator 0:bb348c97df44 90 * }
lypinator 0:bb348c97df44 91 * @endcode
lypinator 0:bb348c97df44 92 *
lypinator 0:bb348c97df44 93 * Another solution is to inherit privately from the NonCopyable class.
lypinator 0:bb348c97df44 94 * It reduces the boiler plate needed to avoid copy operations but more
lypinator 0:bb348c97df44 95 * importantly it clarifies the programmer intent and the object semantic.
lypinator 0:bb348c97df44 96 *
lypinator 0:bb348c97df44 97 * class Foo : private NonCopyable<Foo> {
lypinator 0:bb348c97df44 98 * public:
lypinator 0:bb348c97df44 99 * Foo() : _resource(new Resource()) { }
lypinator 0:bb348c97df44 100 * ~Foo() { delete _resource; }
lypinator 0:bb348c97df44 101 * private:
lypinator 0:bb348c97df44 102 * Resource* _resource;
lypinator 0:bb348c97df44 103 * }
lypinator 0:bb348c97df44 104 *
lypinator 0:bb348c97df44 105 * @tparam T The type that should be made non copyable. It prevent cases where
lypinator 0:bb348c97df44 106 * the empty base optimization cannot be applied and therefore ensure that the
lypinator 0:bb348c97df44 107 * cost of this semantic sugar is null.
lypinator 0:bb348c97df44 108 *
lypinator 0:bb348c97df44 109 * As an example, the empty base optimization is prohibited if one of the empty
lypinator 0:bb348c97df44 110 * base class is also a base type of the first non static data member:
lypinator 0:bb348c97df44 111 *
lypinator 0:bb348c97df44 112 * @code
lypinator 0:bb348c97df44 113 * struct A { };
lypinator 0:bb348c97df44 114 * struct B : A {
lypinator 0:bb348c97df44 115 * int foo;
lypinator 0:bb348c97df44 116 * };
lypinator 0:bb348c97df44 117 * // thanks to empty base optimization, sizeof(B) == sizeof(int)
lypinator 0:bb348c97df44 118 *
lypinator 0:bb348c97df44 119 * struct C : A {
lypinator 0:bb348c97df44 120 * B b;
lypinator 0:bb348c97df44 121 * };
lypinator 0:bb348c97df44 122 *
lypinator 0:bb348c97df44 123 * // empty base optimization cannot be applied here because A from C and A from
lypinator 0:bb348c97df44 124 * // B shall have a different address. In that case, with the alignment
lypinator 0:bb348c97df44 125 * // sizeof(C) == 2* sizeof(int)
lypinator 0:bb348c97df44 126 * @endcode
lypinator 0:bb348c97df44 127 *
lypinator 0:bb348c97df44 128 * The solution to that problem is to templatize the empty class to makes it
lypinator 0:bb348c97df44 129 * unique to the type it is applied to:
lypinator 0:bb348c97df44 130 *
lypinator 0:bb348c97df44 131 * @code
lypinator 0:bb348c97df44 132 * template<typename T>
lypinator 0:bb348c97df44 133 * struct A<T> { };
lypinator 0:bb348c97df44 134 * struct B : A<B> {
lypinator 0:bb348c97df44 135 * int foo;
lypinator 0:bb348c97df44 136 * };
lypinator 0:bb348c97df44 137 * struct C : A<C> {
lypinator 0:bb348c97df44 138 * B b;
lypinator 0:bb348c97df44 139 * };
lypinator 0:bb348c97df44 140 *
lypinator 0:bb348c97df44 141 * // empty base optimization can be applied B and C does not refer to the same
lypinator 0:bb348c97df44 142 * // kind of A. sizeof(C) == sizeof(B) == sizeof(int).
lypinator 0:bb348c97df44 143 * @endcode
lypinator 0:bb348c97df44 144 *
lypinator 0:bb348c97df44 145 * @note Compile time errors are disabled if the develop or the release profile
lypinator 0:bb348c97df44 146 * is used. To override this behavior and force compile time errors in all profile
lypinator 0:bb348c97df44 147 * set the configuration parameter "platform.force-non-copyable-error" to true.
lypinator 0:bb348c97df44 148 */
lypinator 0:bb348c97df44 149 template<typename T>
lypinator 0:bb348c97df44 150 class NonCopyable {
lypinator 0:bb348c97df44 151 protected:
lypinator 0:bb348c97df44 152 /**
lypinator 0:bb348c97df44 153 * Disallow construction of NonCopyable objects from outside of its hierarchy.
lypinator 0:bb348c97df44 154 */
lypinator 0:bb348c97df44 155 NonCopyable() { }
lypinator 0:bb348c97df44 156 /**
lypinator 0:bb348c97df44 157 * Disallow destruction of NonCopyable objects from outside of its hierarchy.
lypinator 0:bb348c97df44 158 */
lypinator 0:bb348c97df44 159 ~NonCopyable() { }
lypinator 0:bb348c97df44 160
lypinator 0:bb348c97df44 161 #if (!defined(MBED_DEBUG) && (MBED_CONF_PLATFORM_FORCE_NON_COPYABLE_ERROR == 0))
lypinator 0:bb348c97df44 162 /**
lypinator 0:bb348c97df44 163 * NonCopyable copy constructor.
lypinator 0:bb348c97df44 164 *
lypinator 0:bb348c97df44 165 * A compile time warning is issued when this function is used and a runtime
lypinator 0:bb348c97df44 166 * warning is printed when the copy construction of the non copyable happens.
lypinator 0:bb348c97df44 167 *
lypinator 0:bb348c97df44 168 * If you see this warning, your code is probably doing something unspecified.
lypinator 0:bb348c97df44 169 * Copy of non copyable resources can lead to resource leak and random error.
lypinator 0:bb348c97df44 170 */
lypinator 0:bb348c97df44 171 MBED_DEPRECATED("Invalid copy construction of a NonCopyable resource.")
lypinator 0:bb348c97df44 172 NonCopyable(const NonCopyable &)
lypinator 0:bb348c97df44 173 {
lypinator 0:bb348c97df44 174 debug("Invalid copy construction of a NonCopyable resource: %s\r\n", MBED_PRETTY_FUNCTION);
lypinator 0:bb348c97df44 175 }
lypinator 0:bb348c97df44 176
lypinator 0:bb348c97df44 177 /**
lypinator 0:bb348c97df44 178 * NonCopyable copy assignment operator.
lypinator 0:bb348c97df44 179 *
lypinator 0:bb348c97df44 180 * A compile time warning is issued when this function is used and a runtime
lypinator 0:bb348c97df44 181 * warning is printed when the copy construction of the non copyable happens.
lypinator 0:bb348c97df44 182 *
lypinator 0:bb348c97df44 183 * If you see this warning, your code is probably doing something unspecified.
lypinator 0:bb348c97df44 184 * Copy of non copyable resources can lead to resource leak and random error.
lypinator 0:bb348c97df44 185 */
lypinator 0:bb348c97df44 186 MBED_DEPRECATED("Invalid copy assignment of a NonCopyable resource.")
lypinator 0:bb348c97df44 187 NonCopyable &operator=(const NonCopyable &)
lypinator 0:bb348c97df44 188 {
lypinator 0:bb348c97df44 189 debug("Invalid copy assignment of a NonCopyable resource: %s\r\n", MBED_PRETTY_FUNCTION);
lypinator 0:bb348c97df44 190 return *this;
lypinator 0:bb348c97df44 191 }
lypinator 0:bb348c97df44 192
lypinator 0:bb348c97df44 193 #else
lypinator 0:bb348c97df44 194 private:
lypinator 0:bb348c97df44 195 /**
lypinator 0:bb348c97df44 196 * Declare copy constructor as private, any attempt to copy construct
lypinator 0:bb348c97df44 197 * a NonCopyable will fail at compile time.
lypinator 0:bb348c97df44 198 */
lypinator 0:bb348c97df44 199 NonCopyable(const NonCopyable &);
lypinator 0:bb348c97df44 200
lypinator 0:bb348c97df44 201 /**
lypinator 0:bb348c97df44 202 * Declare copy assignment operator as private, any attempt to copy assign
lypinator 0:bb348c97df44 203 * a NonCopyable will fail at compile time.
lypinator 0:bb348c97df44 204 */
lypinator 0:bb348c97df44 205 NonCopyable &operator=(const NonCopyable &);
lypinator 0:bb348c97df44 206 #endif
lypinator 0:bb348c97df44 207 };
lypinator 0:bb348c97df44 208
lypinator 0:bb348c97df44 209 } // namespace mbed
lypinator 0:bb348c97df44 210
lypinator 0:bb348c97df44 211 #endif /* MBED_NONCOPYABLE_H_ */