Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
Diff: features/FEATURE_BLE/ble/SafeEnum.h
- Revision:
- 0:5b88d5760320
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/features/FEATURE_BLE/ble/SafeEnum.h Tue Dec 17 23:23:45 2019 +0000
@@ -0,0 +1,220 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2017-2017 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BLE_SAFE_ENUM_H_
+#define BLE_SAFE_ENUM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace ble {
+
+/**
+ * Helper class used to define safe enumerations.
+ *
+ * C++ 98 enums expose different security holes:
+ * - Scope The scope of the enum is the scope defining it. In other words,
+ * enumerator defined at namespace scope are in the same scope that other
+ * enumerator defined in that namespace even if they belong to a different
+ * enumeration.
+ * As a result it is really easy to collide names between two different
+ * enumerators. At the end, the programmer has to protect its declaration
+ * with long prefixing.
+ * - Unsafe comparison: enumerators really just are named integer and can be
+ * implicitly converted to integer. As a result it is possible to compare
+ * value of different enum type.
+ * - Layout: The layout type of enumerations is implementation defined.
+ *
+ * This template class expose a framework to overcome those issues:
+ *
+ * First enum has to be defined in a structure which inherit from this class.
+ * The target type is the name of the structure containing the enumeration
+ * while LayoutType is the inner type used to stored the enum.
+ *
+ * Comparison operator are provided so it is not possible to compare a SafeEnum
+ * of a type to another SafeEnum of a different type.
+ *
+ * Implicit conversion to integer is not defined, users have to either use the
+ * value function which return the integer value stored in an EnumType. Client
+ * class can also define their own conversion operation.
+ *
+ * @tparam Target structure containing the enumeration definition.
+ * @tparam LayoutType Inner type used to store enumeration value.
+ *
+ * @code
+
+ struct color_t : SafeEnum<color_t> {
+ enum type {
+ RED,
+ GREEN,
+ BLACK
+ };
+
+ color_t(type) : SafeEnum<color_t>(type) { }
+ };
+
+ // use an uint8_t to store the enumeration value
+ struct shape_t : SafeEnum<shape_t, uint8_t> {
+ enum type {
+ RECTANGLE,
+ CIRCLE,
+ TRIANGLE
+ };
+
+ shape_t(type) : SafeEnum<shape_t>(type) { }
+ };
+
+ // shape enumerator is in the shape_t scope.
+ shape_t shape = shape_t::RECTANGLE;
+
+ shape_t shape = color_t::RED; // Compilation error
+
+ if (shape == shape_t::CIRCLE) {
+ }
+
+ // compilation error
+ if (shape == color_t::RED) {
+
+ }
+
+ void sink(shape_t); (1)
+ void sink(color_t); (2)
+
+ sink(shape); // use overload (1)
+ sink(color); // use overload (2)
+
+ // explicit access to the value is mandatory when a SafeEnum value is used
+ // as the condition in a switch statement
+ switch(shape.value()) {
+ case shape_t::RECTANGLE:
+ break;
+ }
+
+ * @endcode
+ */
+template<typename Target, typename LayoutType = unsigned int>
+struct SafeEnum {
+ /**
+ * Type of the representation.
+ */
+ typedef LayoutType representation_t;
+
+protected:
+ /**
+ * Construction of an enumeration value.
+ */
+ explicit SafeEnum(LayoutType value) : _value(value) { }
+
+public:
+ /**
+ * Equal to operator for Target instances.
+ *
+ * @param lhs left hand side of the comparison
+ * @param rhs right hand side of the comparison
+ *
+ * @return true if the inner value of lhs and rhs are equal and false
+ * otherwise.
+ */
+ friend bool operator==(Target lhs, Target rhs) {
+ return lhs._value == rhs._value;
+ }
+
+ /**
+ * Not equal to operator for Target instances.
+ *
+ * @param lhs left hand side of the comparison
+ * @param rhs right hand side of the comparison
+ *
+ * @return true if the inner value of lhs and rhs are not equal and false
+ * otherwise.
+ */
+ friend bool operator!=(Target lhs, Target rhs) {
+ return !(lhs == rhs);
+ }
+
+ /**
+ * Less than operator for Target instances.
+ *
+ * @param lhs left hand side of the comparison
+ * @param rhs right hand side of the comparison
+ *
+ * @return true if the inner value of lhs is less than rhs and false otherwise.
+ */
+ friend bool operator<(Target lhs, Target rhs) {
+ return lhs.value() < rhs.value();
+ }
+
+ /**
+ * Less than or equal to operator for Target instances.
+ *
+ * @param lhs left hand side of the comparison
+ * @param rhs right hand side of the comparison
+ *
+ * @return true if the inner value of lhs is less than or equal to rhs and
+ * false otherwise.
+ */
+ friend bool operator<=(Target lhs, Target rhs) {
+ return lhs.value() < rhs.value() || lhs == rhs;
+ }
+
+ /**
+ * Greater than operator for Target instances.
+ *
+ * @param lhs left hand side of the comparison
+ * @param rhs right hand side of the comparison
+ *
+ * @return true if the inner value of lhs is greater than rhs; false
+ * otherwise.
+ */
+ friend bool operator>(Target lhs, Target rhs) {
+ return !(lhs <= rhs);
+ }
+
+ /**
+ * Greater than or equal to operator for Target instances.
+ *
+ * @param lhs left hand side of the comparison
+ * @param rhs right hand side of the comparison
+ *
+ * @return true if the inner value of lhs is greater than or equal to rhs;
+ * false otherwise.
+ */
+ friend bool operator>=(Target lhs, Target rhs) {
+ return !(lhs < rhs);
+ }
+
+ /**
+ * Explicit access to the inner value of the SafeEnum instance.
+ */
+ LayoutType value() const {
+ return _value;
+ }
+
+ /**
+ * Return a pointer to the inner storage.
+ */
+ const LayoutType* storage() const
+ {
+ return &_value;
+ }
+
+private:
+ LayoutType _value;
+};
+
+} // namespace ble
+
+#endif /* BLE_SAFE_ENUM_H_ */