Embedded Template Library 1.0
Loading...
Searching...
No Matches
endianness.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_ENDIAN_INCLUDED
32#define ETL_ENDIAN_INCLUDED
33
34#include "platform.h"
35#include "enum_type.h"
36#include "binary.h"
37
38#include <stdint.h>
39
40#if ETL_USING_CPP20 && ETL_USING_STL
41 #include <bit>
42#endif
43
47
48// Have we not already defined ETL_ENDIAN_NATIVE?
49#if !defined(ETL_ENDIAN_NATIVE)
50 // Can we use the C++20 definitions?
51 #if ETL_USING_CPP20 && ETL_USING_STL
52 #define ETL_ENDIAN_LITTLE static_cast<int>(std::endian::little)
53 #define ETL_ENDIAN_BIG static_cast<int>(std::endian::big)
54 #define ETL_ENDIAN_NATIVE static_cast<int>(std::endian::native)
55 // Is this the IAR compiler?
56 #elif defined(ETL_COMPILER_IAR) && defined(__LITTLE_ENDIAN__)
57 #define ETL_ENDIAN_LITTLE 0
58 #define ETL_ENDIAN_BIG 1
59 #if __LITTLE_ENDIAN__ == 1
60 #define ETL_ENDIAN_NATIVE ETL_ENDIAN_LITTLE
61 #elif __LITTLE_ENDIAN__ == 0
62 #define ETL_ENDIAN_NATIVE ETL_ENDIAN_BIG
63 #endif
64 // If not can we use the compiler macros?
65 #elif defined(__BYTE_ORDER__)
66 // Test the two versions of the macro we are likely to see.
67 #if defined(__ORDER_LITTLE_ENDIAN__)
68 #define ETL_ENDIAN_LITTLE __ORDER_LITTLE_ENDIAN__
69 #define ETL_ENDIAN_BIG __ORDER_BIG_ENDIAN__
70 #define ETL_ENDIAN_NATIVE __BYTE_ORDER__
71 #elif defined(__LITTLE_ENDIAN__)
72 #define ETL_ENDIAN_LITTLE __LITTLE_ENDIAN__
73 #define ETL_ENDIAN_BIG __BIG_ENDIAN__
74 #define ETL_ENDIAN_NATIVE __BYTE_ORDER__
75 #endif
76 #else
77 // The user needs to define ETL_ENDIAN_NATIVE.
78 #error Unable to determine native endianness at compile time. ETL_ENDIAN_NATIVE must be defined either as 0 for 'little endian' or 1 for 'big endian'.
79 #endif
80#else
81 // Default values for little and big endianness.
82 #define ETL_ENDIAN_LITTLE 0
83 #define ETL_ENDIAN_BIG 1
84#endif
85
86// If true, then the endianness of the platform can be constexpr.
87#if (ETL_USING_CPP11 && defined(ETL_ENDIAN_NATIVE))
88 #define ETL_HAS_CONSTEXPR_ENDIANNESS 1
89#else
90 #define ETL_HAS_CONSTEXPR_ENDIANNESS 0
91#endif
92
93namespace etl
94{
95 //***************************************************************************
98 //***************************************************************************
99 struct endian
100 {
101 enum enum_type
102 {
103 little = ETL_ENDIAN_LITTLE,
104 big = ETL_ENDIAN_BIG,
105 native = ETL_ENDIAN_NATIVE
106 };
107
108 ETL_DECLARE_ENUM_TYPE(endian, int)
109 ETL_ENUM_TYPE(little, "little")
110 ETL_ENUM_TYPE(big, "big")
111 ETL_END_ENUM_TYPE
112 };
113
114 //***************************************************************************
117 //***************************************************************************
119 {
121 {
122 return etl::endian(*this);
123 }
124
125#if ETL_HAS_CONSTEXPR_ENDIANNESS
126 ETL_CONSTEXPR
127#endif
128 operator etl::endian() const
129 {
130 return get();
131 }
132
133#if ETL_HAS_CONSTEXPR_ENDIANNESS
134 static ETL_CONSTEXPR etl::endian value()
135#else
136 static etl::endian value()
137#endif
138 {
139 return get();
140 }
141
142 private:
143
144#if ETL_HAS_CONSTEXPR_ENDIANNESS
145 static ETL_CONSTEXPR etl::endian get()
146 {
147 return etl::endian::native;
148 }
149#else
150 static etl::endian get()
151 {
152 static const uint32_t i = 0xFFFF0000;
153
154 return (*reinterpret_cast<const unsigned char*>(&i) == 0) ? etl::endian::little : etl::endian::big;
155 }
156#endif
157 };
158
159 //***************************************************************************
160 template <typename T>
161 ETL_CONSTEXPR14
163 ntoh(T value)
164 {
165 if (endianness::value() == endian::little)
166 {
167 return etl::reverse_bytes(value);
168 }
169 else
170 {
171 return value;
172 }
173 }
174
175 //***************************************************************************
176 template <typename T>
177 ETL_CONSTEXPR14
179 hton(T value)
180 {
181 if (endianness::value() == endian::little)
182 {
183 return etl::reverse_bytes(value);
184 }
185 else
186 {
187 return value;
188 }
189 }
190}
191
192#endif
ETL_CONSTEXPR14 etl::enable_if< etl::is_integral< T >::value &&etl::is_unsigned< T >::value &&(etl::integral_limits< T >::bits==16U), T >::type reverse_bytes(T value)
Definition binary.h:739
Definition endianness.h:100
Definition endianness.h:119
bitset_ext
Definition absolute.h:38
pair holds two objects of arbitrary type
Definition utility.h:164