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 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 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 217 template<typename T> T ReadScalar(const void *p) { 218 return EndianScalar(*reinterpret_cast<const T *>(p)); 219 } 220 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). 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