Embedded Template Library 1.0
Loading...
Searching...
No Matches
message.h
1/******************************************************************************
2The MIT License(MIT)
3
4Embedded Template Library.
5https://github.com/ETLCPP/etl
6https://www.etlcpp.com
7
8Copyright(c) 2017 John Wellbelove
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files(the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions :
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27******************************************************************************/
28
29#ifndef ETL_MESSAGE_INCLUDED
30#define ETL_MESSAGE_INCLUDED
31
32#include "platform.h"
33#include "error_handler.h"
34#include "exception.h"
35#include "message_types.h"
36#include "static_assert.h"
37#include "type_traits.h"
38
39namespace etl
40{
41 //***************************************************************************
42 class message_exception : public etl::exception
43 {
44 public:
45
46 message_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
47 : exception(reason_, file_name_, line_number_)
48 {
49 }
50 };
51
52 //***************************************************************************
53 class unhandled_message_exception : public etl::message_exception
54 {
55 public:
56
57 unhandled_message_exception(string_type file_name_, numeric_type line_number_)
58 : message_exception(ETL_ERROR_TEXT("message:unknown", ETL_MESSAGE_FILE_ID"A"), file_name_, line_number_)
59 {
60 }
61 };
62
64 {
65 };
66
67#if ETL_HAS_VIRTUAL_MESSAGES
68 //***************************************************************************
71 //***************************************************************************
73 {
74 public:
75
76 //***********************************
77 virtual ~imessage() ETL_NOEXCEPT {}
78
79 //***********************************
80 ETL_NODISCARD
81 virtual etl::message_id_t get_message_id() const ETL_NOEXCEPT = 0;
82 };
83
84 //***************************************************************************
87 //***************************************************************************
88 template <etl::message_id_t ID_, typename TBase = etl::imessage>
89 class message
90 : public TBase
91 , public etl::message_tag
92 {
93 public:
94
95 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TBase>::value), "TBase is not derived from etl::imessage");
96
97 typedef TBase base_type;
98
99 //***********************************
100 ETL_NODISCARD
101 virtual etl::message_id_t get_message_id() const ETL_NOEXCEPT ETL_OVERRIDE
102 {
103 return ID;
104 }
105
106 //***********************************
107 static ETL_CONSTANT etl::message_id_t ID = ID_;
108 };
109
110#else
111
112 //***************************************************************************
115 //***************************************************************************
116 class imessage
117 {
118 public:
119
120 //***********************************
121 ETL_NODISCARD
122 etl::message_id_t get_message_id() const ETL_NOEXCEPT
123 {
124 return id;
125 }
126
127 protected:
128
129 //***********************************
130 imessage(etl::message_id_t id_) ETL_NOEXCEPT
131 : id(id_)
132 {
133 }
134
135 //***********************************
136 imessage(const imessage& other) ETL_NOEXCEPT
137 : id(other.id)
138 {
139 }
140
141 //***********************************
142 imessage& operator=(const imessage& rhs) ETL_NOEXCEPT
143 {
144 id = rhs.id;
145 return *this;
146 }
147
148 //***********************************
150
151 private:
152
153 imessage() ETL_DELETE;
154 };
155
156 //***************************************************************************
159 //***************************************************************************
160 template <etl::message_id_t ID_, typename TBase = etl::imessage>
161 class message
162 : public TBase
163 , public etl::message_tag
164 {
165 public:
166
167 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TBase>::value), "TBase is not derived from etl::imessage");
168
169 typedef TBase base_type;
170
171 //***********************************
172 message() ETL_NOEXCEPT
173 : TBase(ID)
174 {
175 }
176
177 //***********************************
178 message(const message&) ETL_NOEXCEPT
179 : TBase(ID)
180 {
181 }
182
183 //***********************************
184 message& operator=(const message&) ETL_NOEXCEPT
185 {
186 return *this;
187 }
188
189 //***********************************
190 static ETL_CONSTANT etl::message_id_t ID = ID_;
191 };
192#endif
193
194 //***************************************************************************
196 //***************************************************************************
197 template <etl::message_id_t ID_, typename TBase>
199
200 //***************************************************************************
202 //***************************************************************************
203 template <typename T>
204 struct is_imessage : public etl::bool_constant< etl::is_same<etl::imessage, typename etl::remove_cvref<T>::type>::value>
205 {
206 };
207
208 //***************************************************************************
210 //***************************************************************************
211 template <typename T>
212 struct is_message : public etl::bool_constant< etl::is_base_of< etl::imessage, typename etl::remove_cvref<T>::type>::value>
213 {
214 };
215
216 //***************************************************************************
218 //***************************************************************************
219 template <typename T>
220 struct is_message_type : public etl::bool_constant< etl::is_base_of< etl::message_tag, typename etl::remove_cvref<T>::type>::value>
221 {
222 };
223
224 //***************************************************************************
226 //***************************************************************************
227 template <typename T>
228 struct is_message_base : public etl::bool_constant<etl::is_message<T>::value && !etl::is_message_type<T>::value>
229 {
230 };
231
232 //***************************************************************************
234 //***************************************************************************
235 template <typename T>
236 struct is_user_message_base : public etl::bool_constant<etl::is_message_base<T>::value && !etl::is_imessage<T>::value>
237 {
238 };
239
240#if ETL_USING_CPP17
241 //***************************************************************************
243 //***************************************************************************
244 template <typename T>
245 inline constexpr bool is_imessage_v = is_imessage<T>::value;
246
247 //***************************************************************************
249 //***************************************************************************
250 template <typename T>
251 inline constexpr bool is_message_v = is_message<T>::value;
252
253 //***************************************************************************
255 //***************************************************************************
256 template <typename T>
257 inline constexpr bool is_message_type_v = is_message_type<T>::value;
258
259 //***************************************************************************
261 //***************************************************************************
262 template <typename T>
263 inline constexpr bool is_message_base_v = is_message_base<T>::value;
264
265 //***************************************************************************
267 //***************************************************************************
268 template <typename T>
269 inline constexpr bool is_user_message_base_v = is_user_message_base<T>::value;
270#endif
271
272 //***************************************************************************
274 //***************************************************************************
275 template <typename T>
277 {
278 private:
279
280 ETL_STATIC_ASSERT(etl::is_message<T>::value, "T is not an ETL message");
281
282 typedef char yes;
283 struct no
284 {
285 char value[2];
286 };
287
288 template <typename U>
289 static yes test(char (*)[sizeof(&U::ID)]);
290
291 template <typename>
292 static no test(...);
293
294 public:
295
296 static const bool value = sizeof(test<typename etl::remove_cv<T>::type>(0)) == sizeof(yes);
297 };
298
299 template <typename T>
300 const bool has_message_id<T>::value;
301
302#if ETL_USING_CPP17
303 template <typename T>
304 inline constexpr bool has_message_id_v = has_message_id<T>::value;
305#endif
306
307#if ETL_USING_CPP11
308 namespace private_message
309 {
310 template <typename TMsg1, typename TMsg2, bool HasIDs>
311 struct compare_message_id_less_impl;
312
313 //**********************************************
314 // Compare the message ID of two messages.
315 // \tparam TMsg1 The first message type.
316 // \tparam TMsg2 The second message type.
317 // Only selected if both TMsg1 or TMsg2 don't have an ID.
318 //**********************************************
319 template <typename TMsg1, typename TMsg2>
320 struct compare_message_id_less_impl<TMsg1, TMsg2, false>
321 {
322 ETL_STATIC_ASSERT(etl::has_message_id<TMsg1>::value, "TMsg1 does not have an ID");
323 ETL_STATIC_ASSERT(etl::has_message_id<TMsg2>::value, "TMsg2 does not have an ID");
324 ETL_STATIC_ASSERT(etl::is_message_type<TMsg1>::value, "TMsg1 is not derived from etl::message<>");
325 ETL_STATIC_ASSERT(etl::is_message_type<TMsg2>::value, "TMsg2 is not derived from etl::message<>");
326 };
327
328 //**********************************************
329 // Compare the message ID of two messages.
330 // \tparam TMsg1 The first message type.
331 // \tparam TMsg2 The second message type.
332 // value is true if TMsg1::ID < TMsg2::ID.
333 // Only selected if both TMsg1 and TMsg2 have an ID.
334 //***********************************************
335 template <typename TMsg1, typename TMsg2>
336 struct compare_message_id_less_impl<TMsg1, TMsg2, true> : etl::bool_constant < TMsg1::ID< TMsg2::ID>
337 {
338 ETL_STATIC_ASSERT(etl::is_message_type<TMsg1>::value, "TMsg1 is not derived from etl::message<>");
339 ETL_STATIC_ASSERT(etl::is_message_type<TMsg2>::value, "TMsg2 is not derived from etl::message<>");
340 };
341 } // namespace private_message
342
343 //**********************************************
348 //**********************************************
349 template <typename TMsg1, typename TMsg2>
350 struct compare_message_id_less
351 : public private_message::compare_message_id_less_impl< TMsg1, TMsg2, has_message_id<TMsg1>::value && has_message_id<TMsg2>::value>
352 {
353 };
354#else
355 //**********************************************
360 //**********************************************
361 template <typename TMsg1, typename TMsg2>
362 struct compare_message_id_less : etl::bool_constant < TMsg1::ID< TMsg2::ID>
363 {
364 ETL_STATIC_ASSERT(etl::is_message_type<TMsg1>::value, "TMsg1 is not derived from etl::message<>");
365 ETL_STATIC_ASSERT(etl::is_message_type<TMsg2>::value, "TMsg2 is not derived from etl::message<>");
366 };
367#endif
368
369#if ETL_USING_CPP17
370 template <typename TMsg1, typename TMsg2>
371 inline constexpr bool compare_message_id_less_v = compare_message_id_less<TMsg1, TMsg2>::value;
372#endif
373} // namespace etl
374
375#endif
Definition message.h:73
Definition message.h:43
Definition message.h:64
Definition message.h:92
static ETL_CONSTANT etl::message_id_t ID
The message's static ID.
Definition message.h:107
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
Definition exception.h:59
Definition absolute.h:40
uint_least8_t message_id_t
Allow alternative type for message id.
Definition message_types.h:40
Definition type_traits.h:97
Detects presence of a static ID member.
Definition message.h:277
Is T an etl::imessage?
Definition message.h:205
Is T a base of etl::message<T>.
Definition message.h:229
Is T an etl::message<> or derived from etl::message<>.
Definition message.h:221
Is T ultimately derived from etl::imessage?
Definition message.h:213
Is T a user defined base of etl::message<T> and not an etl::imessage.
Definition message.h:237