1 /*
2  *  Copyright (c) 2021, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes helper functions to convert between public OT C structs and corresponding core C++ classes.
32  */
33 
34 #ifndef AS_CORE_TYPE_HPP_
35 #define AS_CORE_TYPE_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/debug.hpp"
40 
41 namespace ot {
42 
43 /**
44  * Relates a given public OT type to its corresponding core C++ class/type.
45  *
46  * @tparam FromType  The public OT type.
47  *
48  * Specializations of this template struct are provided for different `FromType` which include a member type definition
49  * named `Type` to provide the corresponding core class/type related to `FromType.
50  *
51  * For example, `CoreType<otIp6Address>::Type` is defined as `Ip6::Address`.
52  */
53 template <typename FromType> struct CoreType;
54 
55 /**
56  * Converts a pointer to public OT type (C struct) to the corresponding core C++ type reference.
57  *
58  * @tparam Type   The public OT type to convert.
59  *
60  * @param[in] aObject   A pointer to the object to convert.
61  *
62  * @returns A reference of the corresponding C++ type matching @p aObject.
63  */
AsCoreType(Type * aObject)64 template <typename Type> typename CoreType<Type>::Type &AsCoreType(Type *aObject)
65 {
66     AssertPointerIsNotNull(aObject);
67 
68     return *static_cast<typename CoreType<Type>::Type *>(aObject);
69 }
70 
71 /**
72  * Converts a const pointer to public OT type (C struct) to the corresponding core C++ type reference.
73  *
74  * @tparam Type   The public OT type to convert.
75  *
76  * @param[in] aObject   A const pointer to the object to convert.
77  *
78  * @returns A const reference of the corresponding C++ type matching @p aObject.
79  */
AsCoreType(const Type * aObject)80 template <typename Type> const typename CoreType<Type>::Type &AsCoreType(const Type *aObject)
81 {
82     AssertPointerIsNotNull(aObject);
83 
84     return *static_cast<const typename CoreType<Type>::Type *>(aObject);
85 }
86 
87 /**
88  * Converts a pointer to public OT type (C struct) to the corresponding core C++ type pointer.
89  *
90  * @tparam Type   The public OT type to convert.
91  *
92  * @param[in] aObject   A pointer to the object to convert.
93  *
94  * @returns A pointer of the corresponding C++ type matching @p aObject.
95  */
AsCoreTypePtr(Type * aObject)96 template <typename Type> typename CoreType<Type>::Type *AsCoreTypePtr(Type *aObject)
97 {
98     return static_cast<typename CoreType<Type>::Type *>(aObject);
99 }
100 
101 /**
102  * Converts a const pointer to public OT type (C struct) to the corresponding core C++ type pointer.
103  *
104  * @tparam Type   The public OT type to convert.
105  *
106  * @param[in] aObject   A pointer to the object to convert.
107  *
108  * @returns A const pointer of the corresponding C++ type matching @p aObject.
109  */
AsCoreTypePtr(const Type * aObject)110 template <typename Type> const typename CoreType<Type>::Type *AsCoreTypePtr(const Type *aObject)
111 {
112     return static_cast<const typename CoreType<Type>::Type *>(aObject);
113 }
114 
115 /**
116  * Maps two enumeration types.
117  *
118  * @tparam FromEnumType  The enum type.
119  *
120  * Specializations of this template struct are provided which include a member type definition named `Type` to provide
121  * the related `enum` type mapped with `FromEnumType`.
122  *
123  * For example, `MappedEnum<otMacFilterAddressMode>::Type` is defined as `Mac::Filter::Mode`.
124  */
125 template <typename FromEnumType> struct MappedEnum;
126 
127 /**
128  * Convert an enumeration type value to a related enumeration type value.
129  *
130  * @param[in] aValue   The enumeration value to convert
131  *
132  * @returns The matching enumeration value.
133  */
MapEnum(EnumType aValue)134 template <typename EnumType> const typename MappedEnum<EnumType>::Type MapEnum(EnumType aValue)
135 {
136     return static_cast<typename MappedEnum<EnumType>::Type>(aValue);
137 }
138 
139 // Helper macro to define specialization of `CoreType` struct relating `BaseType` with `SubType`.
140 #define DefineCoreType(BaseType, SubType) \
141     template <> struct CoreType<BaseType> \
142     {                                     \
143         using Type = SubType;             \
144     }
145 
146 // Helper macro to map two related enumeration types.
147 #define DefineMapEnum(FirstEnumType, SecondEnumType) \
148     template <> struct MappedEnum<FirstEnumType>     \
149     {                                                \
150         using Type = SecondEnumType;                 \
151     };                                               \
152                                                      \
153     template <> struct MappedEnum<SecondEnumType>    \
154     {                                                \
155         using Type = FirstEnumType;                  \
156     }
157 
158 } // namespace ot
159 
160 #endif // AS_CORE_TYPE_HPP_
161