1 | #ifndef FLATBUFFERS_BASE_H_ |
2 | #define FLATBUFFERS_BASE_H_ |
3 | |
4 | // clang-format off |
5 | |
6 | // If activate should be declared and included first. |
7 | #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ |
8 | defined(_MSC_VER) && defined(_DEBUG) |
9 | // The _CRTDBG_MAP_ALLOC inside <crtdbg.h> will replace |
10 | // calloc/free (etc) to its debug version using #define directives. |
11 | #define _CRTDBG_MAP_ALLOC |
12 | #include <stdlib.h> |
13 | #include <crtdbg.h> |
14 | // Replace operator new by trace-enabled version. |
15 | #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) |
16 | #define new DEBUG_NEW |
17 | #endif |
18 | |
19 | #if !defined(FLATBUFFERS_ASSERT) |
20 | #include <assert.h> |
21 | #define FLATBUFFERS_ASSERT assert |
22 | #elif defined(FLATBUFFERS_ASSERT_INCLUDE) |
23 | // Include file with forward declaration |
24 | #include FLATBUFFERS_ASSERT_INCLUDE |
25 | #endif |
26 | |
27 | #ifndef ARDUINO |
28 | #include <cstdint> |
29 | #endif |
30 | |
31 | #include <cstddef> |
32 | #include <cstdlib> |
33 | #include <cstring> |
34 | |
35 | #if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) |
36 | #include <utility.h> |
37 | #else |
38 | #include <utility> |
39 | #endif |
40 | |
41 | #include <string> |
42 | #include <type_traits> |
43 | #include <vector> |
44 | #include <set> |
45 | #include <algorithm> |
46 | #include <iterator> |
47 | #include <memory> |
48 | |
49 | #if defined(__unix__) && !defined(FLATBUFFERS_LOCALE_INDEPENDENT) |
50 | #include <unistd.h> |
51 | #endif |
52 | |
53 | #ifdef __ANDROID__ |
54 | #include <android/api-level.h> |
55 | #endif |
56 | |
57 | #if defined(__ICCARM__) |
58 | #include <intrinsics.h> |
59 | #endif |
60 | |
61 | // Note the __clang__ check is needed, because clang presents itself |
62 | // as an older GNUC compiler (4.2). |
63 | // Clang 3.3 and later implement all of the ISO C++ 2011 standard. |
64 | // Clang 3.4 and later implement all of the ISO C++ 2014 standard. |
65 | // http://clang.llvm.org/cxx_status.html |
66 | |
67 | // Note the MSVC value '__cplusplus' may be incorrect: |
68 | // The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L, |
69 | // indicating (erroneously!) that the compiler conformed to the C++98 Standard. |
70 | // This value should be correct starting from MSVC2017-15.7-Preview-3. |
71 | // The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set. |
72 | // Workaround (for details see MSDN): |
73 | // Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility. |
74 | // The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch. |
75 | |
76 | #if defined(__GNUC__) && !defined(__clang__) |
77 | #define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) |
78 | #else |
79 | #define FLATBUFFERS_GCC 0 |
80 | #endif |
81 | |
82 | #if defined(__clang__) |
83 | #define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) |
84 | #else |
85 | #define FLATBUFFERS_CLANG 0 |
86 | #endif |
87 | |
88 | /// @cond FLATBUFFERS_INTERNAL |
89 | #if __cplusplus <= 199711L && \ |
90 | (!defined(_MSC_VER) || _MSC_VER < 1600) && \ |
91 | (!defined(__GNUC__) || \ |
92 | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) |
93 | #error A C++11 compatible compiler with support for the auto typing is \ |
94 | required for FlatBuffers. |
95 | #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ |
96 | #endif |
97 | |
98 | #if !defined(__clang__) && \ |
99 | defined(__GNUC__) && \ |
100 | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) |
101 | // Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr |
102 | // and constexpr keywords. Note the __clang__ check is needed, because clang |
103 | // presents itself as an older GNUC compiler. |
104 | #ifndef nullptr_t |
105 | const class nullptr_t { |
106 | public: |
107 | template<class T> inline operator T*() const { return 0; } |
108 | private: |
109 | void operator&() const; |
110 | } nullptr = {}; |
111 | #endif |
112 | #ifndef constexpr |
113 | #define constexpr const |
114 | #endif |
115 | #endif |
116 | |
117 | // The wire format uses a little endian encoding (since that's efficient for |
118 | // the common platforms). |
119 | #if defined(__s390x__) |
120 | #define FLATBUFFERS_LITTLEENDIAN 0 |
121 | #endif // __s390x__ |
122 | #if !defined(FLATBUFFERS_LITTLEENDIAN) |
123 | #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) |
124 | #if (defined(__BIG_ENDIAN__) || \ |
125 | (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) |
126 | #define FLATBUFFERS_LITTLEENDIAN 0 |
127 | #else |
128 | #define FLATBUFFERS_LITTLEENDIAN 1 |
129 | #endif // __BIG_ENDIAN__ |
130 | #elif defined(_MSC_VER) |
131 | #if defined(_M_PPC) |
132 | #define FLATBUFFERS_LITTLEENDIAN 0 |
133 | #else |
134 | #define FLATBUFFERS_LITTLEENDIAN 1 |
135 | #endif |
136 | #else |
137 | #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN. |
138 | #endif |
139 | #endif // !defined(FLATBUFFERS_LITTLEENDIAN) |
140 | |
141 | #define FLATBUFFERS_VERSION_MAJOR 2 |
142 | #define FLATBUFFERS_VERSION_MINOR 0 |
143 | #define FLATBUFFERS_VERSION_REVISION 6 |
144 | #define FLATBUFFERS_STRING_EXPAND(X) #X |
145 | #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) |
146 | namespace flatbuffers { |
147 | // Returns version as string "MAJOR.MINOR.REVISION". |
148 | const char* FLATBUFFERS_VERSION(); |
149 | } |
150 | |
151 | #if (!defined(_MSC_VER) || _MSC_VER > 1600) && \ |
152 | (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \ |
153 | defined(__clang__) |
154 | #define FLATBUFFERS_FINAL_CLASS final |
155 | #define FLATBUFFERS_OVERRIDE override |
156 | #define FLATBUFFERS_EXPLICIT_CPP11 explicit |
157 | #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t |
158 | #else |
159 | #define FLATBUFFERS_FINAL_CLASS |
160 | #define FLATBUFFERS_OVERRIDE |
161 | #define FLATBUFFERS_EXPLICIT_CPP11 |
162 | #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE |
163 | #endif |
164 | |
165 | #if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ |
166 | (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ |
167 | (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) |
168 | #define FLATBUFFERS_CONSTEXPR constexpr |
169 | #define FLATBUFFERS_CONSTEXPR_CPP11 constexpr |
170 | #define FLATBUFFERS_CONSTEXPR_DEFINED |
171 | #else |
172 | #define FLATBUFFERS_CONSTEXPR const |
173 | #define FLATBUFFERS_CONSTEXPR_CPP11 |
174 | #endif |
175 | |
176 | #if (defined(__cplusplus) && __cplusplus >= 201402L) || \ |
177 | (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) |
178 | #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR_CPP11 |
179 | #else |
180 | #define FLATBUFFERS_CONSTEXPR_CPP14 |
181 | #endif |
182 | |
183 | #if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ |
184 | (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \ |
185 | defined(__clang__) |
186 | #define FLATBUFFERS_NOEXCEPT noexcept |
187 | #else |
188 | #define FLATBUFFERS_NOEXCEPT |
189 | #endif |
190 | |
191 | // NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to |
192 | // private, so be sure to put it at the end or reset access mode explicitly. |
193 | #if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ |
194 | (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ |
195 | defined(__clang__) |
196 | #define FLATBUFFERS_DELETE_FUNC(func) func = delete |
197 | #else |
198 | #define FLATBUFFERS_DELETE_FUNC(func) private: func |
199 | #endif |
200 | |
201 | #if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ |
202 | (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ |
203 | defined(__clang__) |
204 | #define FLATBUFFERS_DEFAULT_DECLARATION |
205 | #endif |
206 | |
207 | // Check if we can use template aliases |
208 | // Not possible if Microsoft Compiler before 2012 |
209 | // Possible is the language feature __cpp_alias_templates is defined well |
210 | // Or possible if the C++ std is C+11 or newer |
211 | #if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \ |
212 | || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \ |
213 | || (defined(__cplusplus) && __cplusplus >= 201103L) |
214 | #define FLATBUFFERS_TEMPLATES_ALIASES |
215 | #endif |
216 | |
217 | #ifndef FLATBUFFERS_HAS_STRING_VIEW |
218 | // Only provide flatbuffers::string_view if __has_include can be used |
219 | // to detect a header that provides an implementation |
220 | #if defined(__has_include) |
221 | // Check for std::string_view (in c++17) |
222 | #if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17)) |
223 | #include <string_view> |
224 | namespace flatbuffers { |
225 | typedef std::string_view string_view; |
226 | } |
227 | #define FLATBUFFERS_HAS_STRING_VIEW 1 |
228 | // Check for std::experimental::string_view (in c++14, compiler-dependent) |
229 | #elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411) |
230 | #include <experimental/string_view> |
231 | namespace flatbuffers { |
232 | typedef std::experimental::string_view string_view; |
233 | } |
234 | #define FLATBUFFERS_HAS_STRING_VIEW 1 |
235 | // Check for absl::string_view |
236 | #elif __has_include("absl/strings/string_view.h") |
237 | #include "absl/strings/string_view.h" |
238 | namespace flatbuffers { |
239 | typedef absl::string_view string_view; |
240 | } |
241 | #define FLATBUFFERS_HAS_STRING_VIEW 1 |
242 | #endif |
243 | #endif // __has_include |
244 | #endif // !FLATBUFFERS_HAS_STRING_VIEW |
245 | |
246 | #ifndef FLATBUFFERS_GENERAL_HEAP_ALLOC_OK |
247 | // Allow heap allocations to be used |
248 | #define FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 1 |
249 | #endif // !FLATBUFFERS_GENERAL_HEAP_ALLOC_OK |
250 | |
251 | #ifndef FLATBUFFERS_HAS_NEW_STRTOD |
252 | // Modern (C++11) strtod and strtof functions are available for use. |
253 | // 1) nan/inf strings as argument of strtod; |
254 | // 2) hex-float as argument of strtod/strtof. |
255 | #if (defined(_MSC_VER) && _MSC_VER >= 1900) || \ |
256 | (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ |
257 | (defined(__clang__)) |
258 | #define FLATBUFFERS_HAS_NEW_STRTOD 1 |
259 | #endif |
260 | #endif // !FLATBUFFERS_HAS_NEW_STRTOD |
261 | |
262 | #ifndef FLATBUFFERS_LOCALE_INDEPENDENT |
263 | // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, strtoull_l}. |
264 | #if ((defined(_MSC_VER) && _MSC_VER >= 1800) || \ |
265 | (defined(_XOPEN_VERSION) && (_XOPEN_VERSION>=700)) && (!defined(__ANDROID_API__) || (defined(__ANDROID_API__) && (__ANDROID_API__>=21)))) |
266 | #define FLATBUFFERS_LOCALE_INDEPENDENT 1 |
267 | #else |
268 | #define FLATBUFFERS_LOCALE_INDEPENDENT 0 |
269 | #endif |
270 | #endif // !FLATBUFFERS_LOCALE_INDEPENDENT |
271 | |
272 | // Suppress Undefined Behavior Sanitizer (recoverable only). Usage: |
273 | // - __supress_ubsan__("undefined") |
274 | // - __supress_ubsan__("signed-integer-overflow") |
275 | #if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) |
276 | #define __supress_ubsan__(type) __attribute__((no_sanitize(type))) |
277 | #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) |
278 | #define __supress_ubsan__(type) __attribute__((no_sanitize_undefined)) |
279 | #else |
280 | #define __supress_ubsan__(type) |
281 | #endif |
282 | |
283 | // This is constexpr function used for checking compile-time constants. |
284 | // Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`. |
285 | template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { |
286 | return !!t; |
287 | } |
288 | |
289 | // Enable C++ attribute [[]] if std:c++17 or higher. |
290 | #if ((__cplusplus >= 201703L) \ |
291 | || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))) |
292 | // All attributes unknown to an implementation are ignored without causing an error. |
293 | #define FLATBUFFERS_ATTRIBUTE(attr) attr |
294 | |
295 | #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]] |
296 | #else |
297 | #define FLATBUFFERS_ATTRIBUTE(attr) |
298 | |
299 | #if FLATBUFFERS_CLANG >= 30800 |
300 | #define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]] |
301 | #elif FLATBUFFERS_GCC >= 70300 |
302 | #define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]] |
303 | #else |
304 | #define FLATBUFFERS_FALLTHROUGH() |
305 | #endif |
306 | #endif |
307 | |
308 | /// @endcond |
309 | |
310 | /// @file |
311 | namespace flatbuffers { |
312 | |
313 | /// @cond FLATBUFFERS_INTERNAL |
314 | // Our default offset / size type, 32bit on purpose on 64bit systems. |
315 | // Also, using a consistent offset type maintains compatibility of serialized |
316 | // offset values between 32bit and 64bit systems. |
317 | typedef uint32_t uoffset_t; |
318 | |
319 | // Signed offsets for references that can go in both directions. |
320 | typedef int32_t soffset_t; |
321 | |
322 | // Offset/index used in v-tables, can be changed to uint8_t in |
323 | // format forks to save a bit of space if desired. |
324 | typedef uint16_t voffset_t; |
325 | |
326 | typedef uintmax_t largest_scalar_t; |
327 | |
328 | // In 32bits, this evaluates to 2GB - 1 |
329 | #define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) |
330 | |
331 | // We support aligning the contents of buffers up to this size. |
332 | #define FLATBUFFERS_MAX_ALIGNMENT 16 |
333 | |
334 | /// @brief The length of a FlatBuffer file header. |
335 | static const size_t kFileIdentifierLength = 4; |
336 | |
337 | inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) { |
338 | return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) && |
339 | (align & (align - 1)) == 0; // must be power of 2 |
340 | } |
341 | |
342 | #if defined(_MSC_VER) |
343 | #pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized |
344 | #pragma warning(push) |
345 | #pragma warning(disable: 4127) // C4127: conditional expression is constant |
346 | #endif |
347 | |
348 | template<typename T> T EndianSwap(T t) { |
349 | #if defined(_MSC_VER) |
350 | #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort |
351 | #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong |
352 | #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 |
353 | #elif defined(__ICCARM__) |
354 | #define FLATBUFFERS_BYTESWAP16 __REV16 |
355 | #define FLATBUFFERS_BYTESWAP32 __REV |
356 | #define FLATBUFFERS_BYTESWAP64(x) \ |
357 | ((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U) |
358 | #else |
359 | #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) |
360 | // __builtin_bswap16 was missing prior to GCC 4.8. |
361 | #define FLATBUFFERS_BYTESWAP16(x) \ |
362 | static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16)) |
363 | #else |
364 | #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 |
365 | #endif |
366 | #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 |
367 | #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 |
368 | #endif |
369 | if (sizeof(T) == 1) { // Compile-time if-then's. |
370 | return t; |
371 | } else if (sizeof(T) == 2) { |
372 | union { T t; uint16_t i; } u = { t }; |
373 | u.i = FLATBUFFERS_BYTESWAP16(u.i); |
374 | return u.t; |
375 | } else if (sizeof(T) == 4) { |
376 | union { T t; uint32_t i; } u = { t }; |
377 | u.i = FLATBUFFERS_BYTESWAP32(u.i); |
378 | return u.t; |
379 | } else if (sizeof(T) == 8) { |
380 | union { T t; uint64_t i; } u = { t }; |
381 | u.i = FLATBUFFERS_BYTESWAP64(u.i); |
382 | return u.t; |
383 | } else { |
384 | FLATBUFFERS_ASSERT(0); |
385 | return t; |
386 | } |
387 | } |
388 | |
389 | #if defined(_MSC_VER) |
390 | #pragma warning(pop) |
391 | #endif |
392 | |
393 | |
394 | template<typename T> T EndianScalar(T t) { |
395 | #if FLATBUFFERS_LITTLEENDIAN |
396 | return t; |
397 | #else |
398 | return EndianSwap(t); |
399 | #endif |
400 | } |
401 | |
402 | template<typename T> |
403 | // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. |
404 | __supress_ubsan__("alignment" ) |
405 | T ReadScalar(const void *p) { |
406 | return EndianScalar(*reinterpret_cast<const T *>(p)); |
407 | } |
408 | |
409 | // See https://github.com/google/flatbuffers/issues/5950 |
410 | |
411 | #if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) |
412 | #pragma GCC diagnostic push |
413 | #pragma GCC diagnostic ignored "-Wstringop-overflow" |
414 | #endif |
415 | |
416 | template<typename T> |
417 | // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. |
418 | __supress_ubsan__("alignment" ) |
419 | void WriteScalar(void *p, T t) { |
420 | *reinterpret_cast<T *>(p) = EndianScalar(t); |
421 | } |
422 | |
423 | template<typename T> struct Offset; |
424 | template<typename T> __supress_ubsan__("alignment" ) void WriteScalar(void *p, Offset<T> t) { |
425 | *reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o); |
426 | } |
427 | |
428 | #if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) |
429 | #pragma GCC diagnostic pop |
430 | #endif |
431 | |
432 | // Computes how many bytes you'd have to pad to be able to write an |
433 | // "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in |
434 | // memory). |
435 | __supress_ubsan__("unsigned-integer-overflow" ) |
436 | inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { |
437 | return ((~buf_size) + 1) & (scalar_size - 1); |
438 | } |
439 | |
440 | // Generic 'operator==' with conditional specialisations. |
441 | // T e - new value of a scalar field. |
442 | // T def - default of scalar (is known at compile-time). |
443 | template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; } |
444 | |
445 | #if defined(FLATBUFFERS_NAN_DEFAULTS) && \ |
446 | defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) |
447 | // Like `operator==(e, def)` with weak NaN if T=(float|double). |
448 | template<typename T> inline bool IsFloatTheSameAs(T e, T def) { |
449 | return (e == def) || ((def != def) && (e != e)); |
450 | } |
451 | template<> inline bool IsTheSameAs<float>(float e, float def) { |
452 | return IsFloatTheSameAs(e, def); |
453 | } |
454 | template<> inline bool IsTheSameAs<double>(double e, double def) { |
455 | return IsFloatTheSameAs(e, def); |
456 | } |
457 | #endif |
458 | |
459 | // Check 'v' is out of closed range [low; high]. |
460 | // Workaround for GCC warning [-Werror=type-limits]: |
461 | // comparison is always true due to limited range of data type. |
462 | template<typename T> |
463 | inline bool IsOutRange(const T &v, const T &low, const T &high) { |
464 | return (v < low) || (high < v); |
465 | } |
466 | |
467 | // Check 'v' is in closed range [low; high]. |
468 | template<typename T> |
469 | inline bool IsInRange(const T &v, const T &low, const T &high) { |
470 | return !IsOutRange(v, low, high); |
471 | } |
472 | |
473 | } // namespace flatbuffers |
474 | #endif // FLATBUFFERS_BASE_H_ |
475 | |