1#ifndef FLATBUFFERS_BASE_H_
2#define FLATBUFFERS_BASE_H_
3
4// clang-format off
5#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
6 defined(_MSC_VER) && defined(_DEBUG)
7 #define _CRTDBG_MAP_ALLOC
8#endif
9
10#include <assert.h>
11
12#if !defined(FLATBUFFERS_ASSERT)
13#define FLATBUFFERS_ASSERT assert
14#endif
15
16#ifndef ARDUINO
17#include <cstdint>
18#endif
19
20#include <cstddef>
21#include <cstdlib>
22#include <cstring>
23
24#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
25 defined(_MSC_VER) && defined(_DEBUG)
26 #include <crtdbg.h>
27 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
28 #define new DEBUG_NEW
29#endif
30
31#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H)
32 #include <utility.h>
33#else
34 #include <utility>
35#endif
36
37#include <string>
38#include <type_traits>
39#include <vector>
40#include <set>
41#include <algorithm>
42#include <iterator>
43#include <memory>
44
45#ifdef _STLPORT_VERSION
46 #define FLATBUFFERS_CPP98_STL
47#endif
48#ifndef FLATBUFFERS_CPP98_STL
49 #include <functional>
50#endif
51
52#include "flatbuffers/stl_emulation.h"
53
54/// @cond FLATBUFFERS_INTERNAL
55#if __cplusplus <= 199711L && \
56 (!defined(_MSC_VER) || _MSC_VER < 1600) && \
57 (!defined(__GNUC__) || \
58 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400))
59 #error A C++11 compatible compiler with support for the auto typing is \
60 required for FlatBuffers.
61 #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
62#endif
63
64#if !defined(__clang__) && \
65 defined(__GNUC__) && \
66 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
67 // Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr
68 // and constexpr keywords. Note the __clang__ check is needed, because clang
69 // presents itself as an older GNUC compiler.
70 #ifndef nullptr_t
71 const class nullptr_t {
72 public:
73 template<class T> inline operator T*() const { return 0; }
74 private:
75 void operator&() const;
76 } nullptr = {};
77 #endif
78 #ifndef constexpr
79 #define constexpr const
80 #endif
81#endif
82
83// The wire format uses a little endian encoding (since that's efficient for
84// the common platforms).
85#if defined(__s390x__)
86 #define FLATBUFFERS_LITTLEENDIAN 0
87#endif // __s390x__
88#if !defined(FLATBUFFERS_LITTLEENDIAN)
89 #if defined(__GNUC__) || defined(__clang__)
90 #ifdef __BIG_ENDIAN__
91 #define FLATBUFFERS_LITTLEENDIAN 0
92 #else
93 #define FLATBUFFERS_LITTLEENDIAN 1
94 #endif // __BIG_ENDIAN__
95 #elif defined(_MSC_VER)
96 #if defined(_M_PPC)
97 #define FLATBUFFERS_LITTLEENDIAN 0
98 #else
99 #define FLATBUFFERS_LITTLEENDIAN 1
100 #endif
101 #else
102 #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN.
103 #endif
104#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
105
106#define FLATBUFFERS_VERSION_MAJOR 1
107#define FLATBUFFERS_VERSION_MINOR 9
108#define FLATBUFFERS_VERSION_REVISION 0
109#define FLATBUFFERS_STRING_EXPAND(X) #X
110#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
111
112#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
113 (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407))
114 #define FLATBUFFERS_FINAL_CLASS final
115 #define FLATBUFFERS_OVERRIDE override
116#else
117 #define FLATBUFFERS_FINAL_CLASS
118 #define FLATBUFFERS_OVERRIDE
119#endif
120
121#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
122 (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406))
123 #define FLATBUFFERS_CONSTEXPR constexpr
124#else
125 #define FLATBUFFERS_CONSTEXPR
126#endif
127
128#if (defined(__cplusplus) && __cplusplus >= 201402L) || \
129 (defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
130 #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR
131#else
132 #define FLATBUFFERS_CONSTEXPR_CPP14
133#endif
134
135#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || \
136 defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026
137 #define FLATBUFFERS_NOEXCEPT noexcept
138#else
139 #define FLATBUFFERS_NOEXCEPT
140#endif
141
142// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
143// private, so be sure to put it at the end or reset access mode explicitly.
144#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
145 (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404))
146 #define FLATBUFFERS_DELETE_FUNC(func) func = delete;
147#else
148 #define FLATBUFFERS_DELETE_FUNC(func) private: func;
149#endif
150
151#if defined(_MSC_VER)
152 #pragma warning(push)
153 #pragma warning(disable: 4127) // C4127: conditional expression is constant
154#endif
155
156#ifndef FLATBUFFERS_HAS_STRING_VIEW
157 // Only provide flatbuffers::string_view if __has_include can be used
158 // to detect a header that provides an implementation
159 #if defined(__has_include)
160 // Check for std::string_view (in c++17)
161 #if __has_include(<string_view>) && (__cplusplus >= 201606 || _HAS_CXX17)
162 #include <string_view>
163 namespace flatbuffers {
164 typedef std::string_view string_view;
165 }
166 #define FLATBUFFERS_HAS_STRING_VIEW 1
167 // Check for std::experimental::string_view (in c++14, compiler-dependent)
168 #elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411)
169 #include <experimental/string_view>
170 namespace flatbuffers {
171 typedef std::experimental::string_view string_view;
172 }
173 #define FLATBUFFERS_HAS_STRING_VIEW 1
174 #endif
175 #endif // __has_include
176#endif // !FLATBUFFERS_HAS_STRING_VIEW
177
178/// @endcond
179
180/// @file
181namespace flatbuffers {
182
183/// @cond FLATBUFFERS_INTERNAL
184// Our default offset / size type, 32bit on purpose on 64bit systems.
185// Also, using a consistent offset type maintains compatibility of serialized
186// offset values between 32bit and 64bit systems.
187typedef uint32_t uoffset_t;
188
189// Signed offsets for references that can go in both directions.
190typedef int32_t soffset_t;
191
192// Offset/index used in v-tables, can be changed to uint8_t in
193// format forks to save a bit of space if desired.
194typedef uint16_t voffset_t;
195
196typedef uintmax_t largest_scalar_t;
197
198// In 32bits, this evaluates to 2GB - 1
199#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
200
201// We support aligning the contents of buffers up to this size.
202#define FLATBUFFERS_MAX_ALIGNMENT 16
203
204template<typename T> T EndianSwap(T t) {
205 #if defined(_MSC_VER)
206 #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
207 #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
208 #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
209 #else
210 #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
211 // __builtin_bswap16 was missing prior to GCC 4.8.
212 #define FLATBUFFERS_BYTESWAP16(x) \
213 static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
214 #else
215 #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
216 #endif
217 #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
218 #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
219 #endif
220 if (sizeof(T) == 1) { // Compile-time if-then's.
221 return t;
222 } else if (sizeof(T) == 2) {
223 union { T t; uint16_t i; } u;
224 u.t = t;
225 u.i = FLATBUFFERS_BYTESWAP16(u.i);
226 return u.t;
227 } else if (sizeof(T) == 4) {
228 union { T t; uint32_t i; } u;
229 u.t = t;
230 u.i = FLATBUFFERS_BYTESWAP32(u.i);
231 return u.t;
232 } else if (sizeof(T) == 8) {
233 union { T t; uint64_t i; } u;
234 u.t = t;
235 u.i = FLATBUFFERS_BYTESWAP64(u.i);
236 return u.t;
237 } else {
238 FLATBUFFERS_ASSERT(0);
239 }
240}
241
242
243template<typename T> T EndianScalar(T t) {
244 #if FLATBUFFERS_LITTLEENDIAN
245 return t;
246 #else
247 return EndianSwap(t);
248 #endif
249}
250
251template<typename T> T ReadScalar(const void *p) {
252 return EndianScalar(*reinterpret_cast<const T *>(p));
253}
254
255template<typename T> void WriteScalar(void *p, T t) {
256 *reinterpret_cast<T *>(p) = EndianScalar(t);
257}
258
259// Computes how many bytes you'd have to pad to be able to write an
260// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
261// memory).
262inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
263 return ((~buf_size) + 1) & (scalar_size - 1);
264}
265
266} // namespace flatbuffers
267#endif // FLATBUFFERS_BASE_H_
268