Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
SafeEnum.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017-2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef BLE_SAFE_ENUM_H_ 00018 #define BLE_SAFE_ENUM_H_ 00019 00020 #include <stddef.h> 00021 #include <stdint.h> 00022 00023 namespace ble { 00024 00025 /** 00026 * Helper class used to define safe enumerations. 00027 * 00028 * C++ 98 enums expose different security holes: 00029 * - Scope The scope of the enum is the scope defining it. In other words, 00030 * enumerator defined at namespace scope are in the same scope that other 00031 * enumerator defined in that namespace even if they belong to a different 00032 * enumeration. 00033 * As a result it is really easy to collide names between two different 00034 * enumerators. At the end, the programmer has to protect its declaration 00035 * with long prefixing. 00036 * - Unsafe comparison: enumerators really just are named integer and can be 00037 * implicitly converted to integer. As a result it is possible to compare 00038 * value of different enum type. 00039 * - Layout: The layout type of enumerations is implementation defined. 00040 * 00041 * This template class expose a framework to overcome those issues: 00042 * 00043 * First enum has to be defined in a structure which inherit from this class. 00044 * The target type is the name of the structure containing the enumeration 00045 * while LayoutType is the inner type used to stored the enum. 00046 * 00047 * Comparison operator are provided so it is not possible to compare a SafeEnum 00048 * of a type to another SafeEnum of a different type. 00049 * 00050 * Implicit conversion to integer is not defined, users have to either use the 00051 * value function which return the integer value stored in an EnumType. Client 00052 * class can also define their own conversion operation. 00053 * 00054 * @tparam Target structure containing the enumeration definition. 00055 * @tparam LayoutType Inner type used to store enumeration value. 00056 * 00057 * @code 00058 00059 struct color_t : SafeEnum<color_t> { 00060 enum type { 00061 RED, 00062 GREEN, 00063 BLACK 00064 }; 00065 00066 color_t(type) : SafeEnum<color_t>(type) { } 00067 }; 00068 00069 // use an uint8_t to store the enumeration value 00070 struct shape_t : SafeEnum<shape_t, uint8_t> { 00071 enum type { 00072 RECTANGLE, 00073 CIRCLE, 00074 TRIANGLE 00075 }; 00076 00077 shape_t(type) : SafeEnum<shape_t>(type) { } 00078 }; 00079 00080 // shape enumerator is in the shape_t scope. 00081 shape_t shape = shape_t::RECTANGLE; 00082 00083 shape_t shape = color_t::RED; // Compilation error 00084 00085 if (shape == shape_t::CIRCLE) { 00086 } 00087 00088 // compilation error 00089 if (shape == color_t::RED) { 00090 00091 } 00092 00093 void sink(shape_t); (1) 00094 void sink(color_t); (2) 00095 00096 sink(shape); // use overload (1) 00097 sink(color); // use overload (2) 00098 00099 // explicit access to the value is mandatory when a SafeEnum value is used 00100 // as the condition in a switch statement 00101 switch(shape.value()) { 00102 case shape_t::RECTANGLE: 00103 break; 00104 } 00105 00106 * @endcode 00107 */ 00108 template<typename Target, typename LayoutType = unsigned int> 00109 struct SafeEnum { 00110 00111 /** 00112 * Construction of an enumeration value. 00113 */ 00114 SafeEnum(LayoutType value) : _value(value) { } 00115 00116 /** 00117 * Equal to operator for SafeEnum instances. 00118 * 00119 * @param lhs left hand side of the comparison 00120 * @param rhs right hand side of the comparison 00121 * 00122 * @return true if the inner value of lhs and rhs are equal and false 00123 * otherwise. 00124 */ 00125 friend bool operator==(SafeEnum lhs, SafeEnum rhs) { 00126 return lhs._value == rhs._value; 00127 } 00128 00129 /** 00130 * Not equal to operator for SafeEnum instances. 00131 * 00132 * @param lhs left hand side of the comparison 00133 * @param rhs right hand side of the comparison 00134 * 00135 * @return true if the inner value of lhs and rhs are not equal and false 00136 * otherwise. 00137 */ 00138 friend bool operator!=(SafeEnum lhs, SafeEnum rhs) { 00139 return !(lhs == rhs); 00140 } 00141 00142 /** 00143 * Explicit access to the inner value of the SafeEnum instance. 00144 */ 00145 LayoutType value() const { 00146 return _value; 00147 } 00148 00149 private: 00150 LayoutType _value; 00151 }; 00152 00153 } // namespace ble 00154 00155 #endif /* BLE_SAFE_ENUM_H_ */
Generated on Sun Jul 17 2022 08:25:29 by 1.7.2