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