Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /* mbed Microcontroller Library
marcozecchini 0:9fca2b23d0ba 2 * Copyright (c) 2017-2017 ARM Limited
marcozecchini 0:9fca2b23d0ba 3 *
marcozecchini 0:9fca2b23d0ba 4 * Licensed under the Apache License, Version 2.0 (the "License");
marcozecchini 0:9fca2b23d0ba 5 * you may not use this file except in compliance with the License.
marcozecchini 0:9fca2b23d0ba 6 * You may obtain a copy of the License at
marcozecchini 0:9fca2b23d0ba 7 *
marcozecchini 0:9fca2b23d0ba 8 * http://www.apache.org/licenses/LICENSE-2.0
marcozecchini 0:9fca2b23d0ba 9 *
marcozecchini 0:9fca2b23d0ba 10 * Unless required by applicable law or agreed to in writing, software
marcozecchini 0:9fca2b23d0ba 11 * distributed under the License is distributed on an "AS IS" BASIS,
marcozecchini 0:9fca2b23d0ba 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcozecchini 0:9fca2b23d0ba 13 * See the License for the specific language governing permissions and
marcozecchini 0:9fca2b23d0ba 14 * limitations under the License.
marcozecchini 0:9fca2b23d0ba 15 */
marcozecchini 0:9fca2b23d0ba 16
marcozecchini 0:9fca2b23d0ba 17 #ifndef BLE_SAFE_ENUM_H_
marcozecchini 0:9fca2b23d0ba 18 #define BLE_SAFE_ENUM_H_
marcozecchini 0:9fca2b23d0ba 19
marcozecchini 0:9fca2b23d0ba 20 #include <stddef.h>
marcozecchini 0:9fca2b23d0ba 21 #include <stdint.h>
marcozecchini 0:9fca2b23d0ba 22
marcozecchini 0:9fca2b23d0ba 23 namespace ble {
marcozecchini 0:9fca2b23d0ba 24
marcozecchini 0:9fca2b23d0ba 25 /**
marcozecchini 0:9fca2b23d0ba 26 * Helper class used to define safe enumerations.
marcozecchini 0:9fca2b23d0ba 27 *
marcozecchini 0:9fca2b23d0ba 28 * C++ 98 enums expose different security holes:
marcozecchini 0:9fca2b23d0ba 29 * - Scope The scope of the enum is the scope defining it. In other words,
marcozecchini 0:9fca2b23d0ba 30 * enumerator defined at namespace scope are in the same scope that other
marcozecchini 0:9fca2b23d0ba 31 * enumerator defined in that namespace even if they belong to a different
marcozecchini 0:9fca2b23d0ba 32 * enumeration.
marcozecchini 0:9fca2b23d0ba 33 * As a result it is really easy to collide names between two different
marcozecchini 0:9fca2b23d0ba 34 * enumerators. At the end, the programmer has to protect its declaration
marcozecchini 0:9fca2b23d0ba 35 * with long prefixing.
marcozecchini 0:9fca2b23d0ba 36 * - Unsafe comparison: enumerators really just are named integer and can be
marcozecchini 0:9fca2b23d0ba 37 * implicitly converted to integer. As a result it is possible to compare
marcozecchini 0:9fca2b23d0ba 38 * value of different enum type.
marcozecchini 0:9fca2b23d0ba 39 * - Layout: The layout type of enumerations is implementation defined.
marcozecchini 0:9fca2b23d0ba 40 *
marcozecchini 0:9fca2b23d0ba 41 * This template class expose a framework to overcome those issues:
marcozecchini 0:9fca2b23d0ba 42 *
marcozecchini 0:9fca2b23d0ba 43 * First enum has to be defined in a structure which inherit from this class.
marcozecchini 0:9fca2b23d0ba 44 * The target type is the name of the structure containing the enumeration
marcozecchini 0:9fca2b23d0ba 45 * while LayoutType is the inner type used to stored the enum.
marcozecchini 0:9fca2b23d0ba 46 *
marcozecchini 0:9fca2b23d0ba 47 * Comparison operator are provided so it is not possible to compare a SafeEnum
marcozecchini 0:9fca2b23d0ba 48 * of a type to another SafeEnum of a different type.
marcozecchini 0:9fca2b23d0ba 49 *
marcozecchini 0:9fca2b23d0ba 50 * Implicit conversion to integer is not defined, users have to either use the
marcozecchini 0:9fca2b23d0ba 51 * value function which return the integer value stored in an EnumType. Client
marcozecchini 0:9fca2b23d0ba 52 * class can also define their own conversion operation.
marcozecchini 0:9fca2b23d0ba 53 *
marcozecchini 0:9fca2b23d0ba 54 * @tparam Target structure containing the enumeration definition.
marcozecchini 0:9fca2b23d0ba 55 * @tparam LayoutType Inner type used to store enumeration value.
marcozecchini 0:9fca2b23d0ba 56 *
marcozecchini 0:9fca2b23d0ba 57 * @code
marcozecchini 0:9fca2b23d0ba 58
marcozecchini 0:9fca2b23d0ba 59 struct color_t : SafeEnum<color_t> {
marcozecchini 0:9fca2b23d0ba 60 enum type {
marcozecchini 0:9fca2b23d0ba 61 RED,
marcozecchini 0:9fca2b23d0ba 62 GREEN,
marcozecchini 0:9fca2b23d0ba 63 BLACK
marcozecchini 0:9fca2b23d0ba 64 };
marcozecchini 0:9fca2b23d0ba 65
marcozecchini 0:9fca2b23d0ba 66 color_t(type) : SafeEnum<color_t>(type) { }
marcozecchini 0:9fca2b23d0ba 67 };
marcozecchini 0:9fca2b23d0ba 68
marcozecchini 0:9fca2b23d0ba 69 // use an uint8_t to store the enumeration value
marcozecchini 0:9fca2b23d0ba 70 struct shape_t : SafeEnum<shape_t, uint8_t> {
marcozecchini 0:9fca2b23d0ba 71 enum type {
marcozecchini 0:9fca2b23d0ba 72 RECTANGLE,
marcozecchini 0:9fca2b23d0ba 73 CIRCLE,
marcozecchini 0:9fca2b23d0ba 74 TRIANGLE
marcozecchini 0:9fca2b23d0ba 75 };
marcozecchini 0:9fca2b23d0ba 76
marcozecchini 0:9fca2b23d0ba 77 shape_t(type) : SafeEnum<shape_t>(type) { }
marcozecchini 0:9fca2b23d0ba 78 };
marcozecchini 0:9fca2b23d0ba 79
marcozecchini 0:9fca2b23d0ba 80 // shape enumerator is in the shape_t scope.
marcozecchini 0:9fca2b23d0ba 81 shape_t shape = shape_t::RECTANGLE;
marcozecchini 0:9fca2b23d0ba 82
marcozecchini 0:9fca2b23d0ba 83 shape_t shape = color_t::RED; // Compilation error
marcozecchini 0:9fca2b23d0ba 84
marcozecchini 0:9fca2b23d0ba 85 if (shape == shape_t::CIRCLE) {
marcozecchini 0:9fca2b23d0ba 86 }
marcozecchini 0:9fca2b23d0ba 87
marcozecchini 0:9fca2b23d0ba 88 // compilation error
marcozecchini 0:9fca2b23d0ba 89 if (shape == color_t::RED) {
marcozecchini 0:9fca2b23d0ba 90
marcozecchini 0:9fca2b23d0ba 91 }
marcozecchini 0:9fca2b23d0ba 92
marcozecchini 0:9fca2b23d0ba 93 void sink(shape_t); (1)
marcozecchini 0:9fca2b23d0ba 94 void sink(color_t); (2)
marcozecchini 0:9fca2b23d0ba 95
marcozecchini 0:9fca2b23d0ba 96 sink(shape); // use overload (1)
marcozecchini 0:9fca2b23d0ba 97 sink(color); // use overload (2)
marcozecchini 0:9fca2b23d0ba 98
marcozecchini 0:9fca2b23d0ba 99 // explicit access to the value is mandatory when a SafeEnum value is used
marcozecchini 0:9fca2b23d0ba 100 // as the condition in a switch statement
marcozecchini 0:9fca2b23d0ba 101 switch(shape.value()) {
marcozecchini 0:9fca2b23d0ba 102 case shape_t::RECTANGLE:
marcozecchini 0:9fca2b23d0ba 103 break;
marcozecchini 0:9fca2b23d0ba 104 }
marcozecchini 0:9fca2b23d0ba 105
marcozecchini 0:9fca2b23d0ba 106 * @endcode
marcozecchini 0:9fca2b23d0ba 107 */
marcozecchini 0:9fca2b23d0ba 108 template<typename Target, typename LayoutType = unsigned int>
marcozecchini 0:9fca2b23d0ba 109 struct SafeEnum {
marcozecchini 0:9fca2b23d0ba 110
marcozecchini 0:9fca2b23d0ba 111 /**
marcozecchini 0:9fca2b23d0ba 112 * Construction of an enumeration value.
marcozecchini 0:9fca2b23d0ba 113 */
marcozecchini 0:9fca2b23d0ba 114 SafeEnum(LayoutType value) : _value(value) { }
marcozecchini 0:9fca2b23d0ba 115
marcozecchini 0:9fca2b23d0ba 116 /**
marcozecchini 0:9fca2b23d0ba 117 * Equal to operator for SafeEnum instances.
marcozecchini 0:9fca2b23d0ba 118 *
marcozecchini 0:9fca2b23d0ba 119 * @param lhs left hand side of the comparison
marcozecchini 0:9fca2b23d0ba 120 * @param rhs right hand side of the comparison
marcozecchini 0:9fca2b23d0ba 121 *
marcozecchini 0:9fca2b23d0ba 122 * @return true if the inner value of lhs and rhs are equal and false
marcozecchini 0:9fca2b23d0ba 123 * otherwise.
marcozecchini 0:9fca2b23d0ba 124 */
marcozecchini 0:9fca2b23d0ba 125 friend bool operator==(SafeEnum lhs, SafeEnum rhs) {
marcozecchini 0:9fca2b23d0ba 126 return lhs._value == rhs._value;
marcozecchini 0:9fca2b23d0ba 127 }
marcozecchini 0:9fca2b23d0ba 128
marcozecchini 0:9fca2b23d0ba 129 /**
marcozecchini 0:9fca2b23d0ba 130 * Not equal to operator for SafeEnum instances.
marcozecchini 0:9fca2b23d0ba 131 *
marcozecchini 0:9fca2b23d0ba 132 * @param lhs left hand side of the comparison
marcozecchini 0:9fca2b23d0ba 133 * @param rhs right hand side of the comparison
marcozecchini 0:9fca2b23d0ba 134 *
marcozecchini 0:9fca2b23d0ba 135 * @return true if the inner value of lhs and rhs are not equal and false
marcozecchini 0:9fca2b23d0ba 136 * otherwise.
marcozecchini 0:9fca2b23d0ba 137 */
marcozecchini 0:9fca2b23d0ba 138 friend bool operator!=(SafeEnum lhs, SafeEnum rhs) {
marcozecchini 0:9fca2b23d0ba 139 return !(lhs == rhs);
marcozecchini 0:9fca2b23d0ba 140 }
marcozecchini 0:9fca2b23d0ba 141
marcozecchini 0:9fca2b23d0ba 142 /**
marcozecchini 0:9fca2b23d0ba 143 * Explicit access to the inner value of the SafeEnum instance.
marcozecchini 0:9fca2b23d0ba 144 */
marcozecchini 0:9fca2b23d0ba 145 LayoutType value() const {
marcozecchini 0:9fca2b23d0ba 146 return _value;
marcozecchini 0:9fca2b23d0ba 147 }
marcozecchini 0:9fca2b23d0ba 148
marcozecchini 0:9fca2b23d0ba 149 private:
marcozecchini 0:9fca2b23d0ba 150 LayoutType _value;
marcozecchini 0:9fca2b23d0ba 151 };
marcozecchini 0:9fca2b23d0ba 152
marcozecchini 0:9fca2b23d0ba 153 } // namespace ble
marcozecchini 0:9fca2b23d0ba 154
marcozecchini 0:9fca2b23d0ba 155 #endif /* BLE_SAFE_ENUM_H_ */