Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SafeEnum.h Source File

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_ */