Home | History | Annotate | Download | only in flatbuffers
      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