EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

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