• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *    Copyright (c) 2017, 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 utility macros for coding.
32  */
33 #ifndef OTBR_COMMON_CODE_UTILS_HPP_
34 #define OTBR_COMMON_CODE_UTILS_HPP_
35 
36 #ifndef OTBR_LOG_TAG
37 #define OTBR_LOG_TAG "UTILS"
38 #endif
39 
40 #include <assert.h>
41 #include <memory>
42 #include <stdlib.h>
43 
44 #include "common/logging.hpp"
45 
46 /**
47  *  This aligns the pointer to @p aAlignType.
48  *
49  *  @param[in] aMem        A pointer to arbitrary memory.
50  *  @param[in] aAlignType  The type to align with and convert the pointer to this type.
51  *
52  *  @returns A pointer to aligned memory.
53  *
54  */
55 #define OTBR_ALIGNED(aMem, aAlignType) \
56     reinterpret_cast<aAlignType>(      \
57         ((reinterpret_cast<unsigned long>(aMem) + sizeof(aAlignType) - 1) / sizeof(aAlignType)) * sizeof(aAlignType))
58 
59 #ifndef CONTAINING_RECORD
60 #define BASE 0x1
61 #define myoffsetof(s, m) (((size_t) & (((s *)BASE)->m)) - BASE)
62 #define CONTAINING_RECORD(address, type, field) ((type *)((uint8_t *)(address)-myoffsetof(type, field)))
63 #endif /* CONTAINING_RECORD */
64 
65 /**
66  *  This checks for the specified status, which is expected to
67  *  commonly be successful, and branches to the local label 'exit' if
68  *  the status is unsuccessful.
69  *
70  *  @param[in] aStatus  A scalar status to be evaluated against zero (0).
71  *
72  */
73 #define SuccessOrExit(aStatus) \
74     do                         \
75     {                          \
76         if ((aStatus) != 0)    \
77         {                      \
78             goto exit;         \
79         }                      \
80     } while (false)
81 
82 /**
83  * This macro verifies a given error status to be successful (compared against value zero (0)), otherwise, it emits a
84  * given error messages and exits the program.
85  *
86  * @param[in] aStatus   A scalar error status to be evaluated against zero (0).
87  * @param[in] aMessage  A message (text string) to print on failure.
88  *
89  */
90 #define SuccessOrDie(aStatus, aMessage)                                      \
91     do                                                                       \
92     {                                                                        \
93         if ((aStatus) != 0)                                                  \
94         {                                                                    \
95             otbrLogEmerg("FAILED %s:%d - %s", __FILE__, __LINE__, aMessage); \
96             exit(-1);                                                        \
97         }                                                                    \
98     } while (false)
99 
100 /**
101  *  This checks for the specified condition, which is expected to
102  *  commonly be true, and both executes @a ... and branches to the
103  *  local label 'exit' if the condition is false.
104  *
105  *  @param[in] aCondition  A Boolean expression to be evaluated.
106  *  @param[in] ...         An expression or block to execute when the
107  *                         assertion fails.
108  *
109  */
110 #define VerifyOrExit(aCondition, ...) \
111     do                                \
112     {                                 \
113         if (!(aCondition))            \
114         {                             \
115             __VA_ARGS__;              \
116             goto exit;                \
117         }                             \
118     } while (false)
119 
120 /**
121  * This macro checks for the specified condition, which is expected to commonly be true,
122  * and both prints the message and terminates the program if the condition is false.
123  *
124  * @param[in] aCondition  The condition to verify
125  * @param[in] aMessage    A message (text string) to print on failure.
126  *
127  */
128 #define VerifyOrDie(aCondition, aMessage)                                    \
129     do                                                                       \
130     {                                                                        \
131         if (!(aCondition))                                                   \
132         {                                                                    \
133             otbrLogEmerg("FAILED %s:%d - %s", __FILE__, __LINE__, aMessage); \
134             exit(-1);                                                        \
135         }                                                                    \
136     } while (false)
137 
138 /**
139  *  This unconditionally executes @a ... and branches to the local
140  *  label 'exit'.
141  *
142  *  @note The use of this interface implies neither success nor
143  *        failure for the overall exit status of the enclosing
144  *        function body.
145  *
146  *  @param[in] ...  An optional expression or block to execute
147  *                  when the assertion fails.
148  *
149  */
150 #define ExitNow(...) \
151     do               \
152     {                \
153         __VA_ARGS__; \
154         goto exit;   \
155     } while (false)
156 
157 #define OTBR_NOOP
158 #define OTBR_UNUSED_VARIABLE(variable) ((void)(variable))
159 
MakeUnique(Args &&...args)160 template <typename T, typename... Args> std::unique_ptr<T> MakeUnique(Args &&... args)
161 {
162     return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
163 }
164 
165 /**
166  * This class makes any class that derives from it non-copyable. It is intended to be used as a private base class.
167  *
168  */
169 class NonCopyable
170 {
171 public:
172     NonCopyable(const NonCopyable &) = delete;
173     NonCopyable &operator=(const NonCopyable &) = delete;
174 
175 protected:
176     NonCopyable(void) = default;
177 };
178 
179 template <typename T> class Optional
180 {
181 public:
182     constexpr Optional(void) = default;
183 
Optional(T aValue)184     Optional(T aValue) { SetValue(aValue); }
185 
~Optional(void)186     ~Optional(void) { ClearValue(); }
187 
Optional(const Optional & aOther)188     Optional(const Optional &aOther) { AssignFrom(aOther); }
189 
operator =(const Optional & aOther)190     Optional &operator=(const Optional &aOther) { AssignFrom(aOther); }
191 
operator ->(void) const192     constexpr const T *operator->(void)const { return &GetValue(); }
193 
operator *(void) const194     constexpr const T &operator*(void)const { return GetValue(); }
195 
HasValue(void) const196     constexpr bool HasValue(void) const { return mHasValue; }
197 
198 private:
GetValue(void) const199     T &GetValue(void) const
200     {
201         assert(mHasValue);
202         return *const_cast<T *>(reinterpret_cast<const T *>(&mStorage));
203     }
204 
ClearValue(void)205     void ClearValue(void)
206     {
207         if (mHasValue)
208         {
209             GetValue().~T();
210             mHasValue = false;
211         }
212     }
213 
SetValue(const T & aValue)214     void SetValue(const T &aValue)
215     {
216         ClearValue();
217         new (&mStorage) T(aValue);
218         mHasValue = true;
219     }
220 
AssignFrom(const Optional & aOther)221     void AssignFrom(const Optional &aOther)
222     {
223         ClearValue();
224         if (aOther.mHasValue)
225         {
226             SetValue(aOther.GetValue());
227         }
228     }
229 
230     alignas(T) unsigned char mStorage[sizeof(T)];
231     bool mHasValue = false;
232 };
233 
234 #endif // OTBR_COMMON_CODE_UTILS_HPP_
235