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  */
54 template <typename FromType> struct CoreType;
55 
56 /**
57  * Converts a pointer to public OT type (C struct) to the corresponding core C++ type reference.
58  *
59  * @tparam Type   The public OT type to convert.
60  *
61  * @param[in] aObject   A pointer to the object to convert.
62  *
63  * @returns A reference of the corresponding C++ type matching @p aObject.
64  *
65  */
AsCoreType(Type * aObject)66 template <typename Type> typename CoreType<Type>::Type &AsCoreType(Type *aObject)
67 {
68     AssertPointerIsNotNull(aObject);
69 
70     return *static_cast<typename CoreType<Type>::Type *>(aObject);
71 }
72 
73 /**
74  * Converts a const pointer to public OT type (C struct) to the corresponding core C++ type reference.
75  *
76  * @tparam Type   The public OT type to convert.
77  *
78  * @param[in] aObject   A const pointer to the object to convert.
79  *
80  * @returns A const reference of the corresponding C++ type matching @p aObject.
81  *
82  */
AsCoreType(const Type * aObject)83 template <typename Type> const typename CoreType<Type>::Type &AsCoreType(const Type *aObject)
84 {
85     AssertPointerIsNotNull(aObject);
86 
87     return *static_cast<const typename CoreType<Type>::Type *>(aObject);
88 }
89 
90 /**
91  * Converts a pointer to public OT type (C struct) to the corresponding core C++ type pointer.
92  *
93  * @tparam Type   The public OT type to convert.
94  *
95  * @param[in] aObject   A pointer to the object to convert.
96  *
97  * @returns A pointer of the corresponding C++ type matching @p aObject.
98  *
99  */
AsCoreTypePtr(Type * aObject)100 template <typename Type> typename CoreType<Type>::Type *AsCoreTypePtr(Type *aObject)
101 {
102     return static_cast<typename CoreType<Type>::Type *>(aObject);
103 }
104 
105 /**
106  * Converts a const pointer to public OT type (C struct) to the corresponding core C++ type pointer.
107  *
108  * @tparam Type   The public OT type to convert.
109  *
110  * @param[in] aObject   A pointer to the object to convert.
111  *
112  * @returns A const pointer of the corresponding C++ type matching @p aObject.
113  *
114  */
AsCoreTypePtr(const Type * aObject)115 template <typename Type> const typename CoreType<Type>::Type *AsCoreTypePtr(const Type *aObject)
116 {
117     return static_cast<const typename CoreType<Type>::Type *>(aObject);
118 }
119 
120 /**
121  * Maps two enumeration types.
122  *
123  * @tparam FromEnumType  The enum type.
124  *
125  * Specializations of this template struct are provided which include a member type definition named `Type` to provide
126  * the related `enum` type mapped with `FromEnumType`.
127  *
128  * For example, `MappedEnum<otMacFilterAddressMode>::Type` is defined as `Mac::Filter::Mode`.
129  *
130  */
131 template <typename FromEnumType> struct MappedEnum;
132 
133 /**
134  * Convert an enumeration type value to a related enumeration type value.
135  *
136  * @param[in] aValue   The enumeration value to convert
137  *
138  * @returns The matching enumeration value.
139  *
140  */
MapEnum(EnumType aValue)141 template <typename EnumType> const typename MappedEnum<EnumType>::Type MapEnum(EnumType aValue)
142 {
143     return static_cast<typename MappedEnum<EnumType>::Type>(aValue);
144 }
145 
146 // Helper macro to define specialization of `CoreType` struct relating `BaseType` with `SubType`.
147 #define DefineCoreType(BaseType, SubType) \
148     template <> struct CoreType<BaseType> \
149     {                                     \
150         using Type = SubType;             \
151     }
152 
153 // Helper macro to map two related enumeration types.
154 #define DefineMapEnum(FirstEnumType, SecondEnumType) \
155     template <> struct MappedEnum<FirstEnumType>     \
156     {                                                \
157         using Type = SecondEnumType;                 \
158     };                                               \
159                                                      \
160     template <> struct MappedEnum<SecondEnumType>    \
161     {                                                \
162         using Type = FirstEnumType;                  \
163     }
164 
165 } // namespace ot
166 
167 #endif // AS_CORE_TYPE_HPP_
168