17 #ifndef FLATBUFFERS_STL_EMULATION_H_
18 #define FLATBUFFERS_STL_EMULATION_H_
24 #include <type_traits>
29 #if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
30 #define FLATBUFFERS_CPP98_STL
31 #endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
33 #if defined(FLATBUFFERS_CPP98_STL)
35 #endif // defined(FLATBUFFERS_CPP98_STL)
39 #if defined(FLATBUFFERS_USE_STD_OPTIONAL) \
40 || (defined(__cplusplus) && __cplusplus >= 201703L) \
41 || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))
43 #ifndef FLATBUFFERS_USE_STD_OPTIONAL
44 #define FLATBUFFERS_USE_STD_OPTIONAL
46 #endif // defined(FLATBUFFERS_USE_STD_OPTIONAL) ...
49 #if defined(FLATBUFFERS_USE_STD_SPAN)
51 #elif defined(__cpp_lib_span) && defined(__has_include)
52 #if __has_include(<span>)
54 #define FLATBUFFERS_USE_STD_SPAN
58 #if !defined(FLATBUFFERS_TEMPLATES_ALIASES) || defined(FLATBUFFERS_CPP98_STL)
59 #define FLATBUFFERS_SPAN_MINIMAL
64 #endif // defined(FLATBUFFERS_USE_STD_SPAN)
72 return value[value.length() - 1];
76 return value[value.length() - 1];
81 template <
typename T>
inline T *
vector_data(std::vector<T> &vector) {
84 return vector.empty() ? nullptr : &vector[0];
88 const std::vector<T> &vector) {
89 return vector.empty() ? nullptr : &vector[0];
92 template <
typename T,
typename V>
94 #if defined(FLATBUFFERS_CPP98_STL)
95 vector->push_back(
data);
97 vector->emplace_back(std::forward<V>(
data));
98 #endif // defined(FLATBUFFERS_CPP98_STL)
101 #ifndef FLATBUFFERS_CPP98_STL
102 #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
103 template <
typename T>
104 using numeric_limits = std::numeric_limits<T>;
107 public std::numeric_limits<T> {};
108 #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
111 public std::numeric_limits<T> {
115 return std::numeric_limits<T>::min();
119 template <>
class numeric_limits<float> :
120 public std::numeric_limits<float> {
122 static float lowest() {
return -FLT_MAX; }
125 template <>
class numeric_limits<double> :
126 public std::numeric_limits<double> {
128 static double lowest() {
return -DBL_MAX; }
131 template <>
class numeric_limits<unsigned long long> {
133 static unsigned long long min() {
return 0ULL; }
134 static unsigned long long max() {
return ~0ULL; }
135 static unsigned long long lowest() {
136 return numeric_limits<unsigned long long>::min();
140 template <>
class numeric_limits<long long> {
142 static long long min() {
143 return static_cast<long long>(1ULL << ((
sizeof(
long long) << 3) - 1));
145 static long long max() {
146 return static_cast<long long>(
147 (1ULL << ((
sizeof(
long long) << 3) - 1)) - 1);
149 static long long lowest() {
150 return numeric_limits<long long>::min();
153 #endif // FLATBUFFERS_CPP98_STL
155 #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
156 #ifndef FLATBUFFERS_CPP98_STL
157 template <
typename T>
using is_scalar = std::is_scalar<T>;
158 template <
typename T,
typename U>
using is_same = std::is_same<T,U>;
159 template <
typename T>
using is_floating_point = std::is_floating_point<T>;
160 template <
typename T>
using is_unsigned = std::is_unsigned<T>;
161 template <
typename T>
using is_enum = std::is_enum<T>;
162 template <
typename T>
using make_unsigned = std::make_unsigned<T>;
163 template<
bool B,
class T,
class F>
164 using conditional = std::conditional<B, T, F>;
165 template<
class T, T v>
166 using integral_constant = std::integral_constant<T, v>;
168 using bool_constant = integral_constant<bool, B>;
171 template <
typename T>
using is_scalar = std::tr1::is_scalar<T>;
172 template <
typename T,
typename U>
using is_same = std::tr1::is_same<T,U>;
173 template <
typename T>
using is_floating_point =
174 std::tr1::is_floating_point<T>;
175 template <
typename T>
using is_unsigned = std::tr1::is_unsigned<T>;
176 template <
typename T>
using is_enum = std::tr1::is_enum<T>;
178 template<
typename T>
struct make_unsigned {
179 static_assert(is_unsigned<T>::value,
"Specialization not implemented!");
182 template<>
struct make_unsigned<char> {
using type =
unsigned char; };
183 template<>
struct make_unsigned<short> {
using type =
unsigned short; };
184 template<>
struct make_unsigned<int> {
using type =
unsigned int; };
185 template<>
struct make_unsigned<long> {
using type =
unsigned long; };
187 struct make_unsigned<long long> {
using type =
unsigned long long; };
188 template<
bool B,
class T,
class F>
189 using conditional = std::tr1::conditional<B, T, F>;
190 template<
class T, T v>
191 using integral_constant = std::tr1::integral_constant<T, v>;
193 using bool_constant = integral_constant<bool, B>;
194 #endif // !FLATBUFFERS_CPP98_STL
197 template <
typename T>
struct is_scalar :
public std::is_scalar<T> {};
198 template <
typename T,
typename U>
struct is_same :
public std::is_same<T,U> {};
200 public std::is_floating_point<T> {};
201 template <
typename T>
struct is_unsigned :
public std::is_unsigned<T> {};
202 template <
typename T>
struct is_enum :
public std::is_enum<T> {};
203 template <
typename T>
struct make_unsigned :
public std::make_unsigned<T> {};
204 template<
bool B,
class T,
class F>
206 template<
class T, T v>
210 #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
212 #ifndef FLATBUFFERS_CPP98_STL
213 #if defined(FLATBUFFERS_TEMPLATES_ALIASES)
214 template <
class T>
using unique_ptr = std::unique_ptr<T>;
221 template <
class T>
class unique_ptr :
public std::unique_ptr<T> {
228 std::unique_ptr<T>::reset(u.release());
232 std::unique_ptr<T>::reset(u.release());
236 return std::unique_ptr<T>::operator=(p);
239 #endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
244 template <
class T>
class unique_ptr {
246 typedef T element_type;
252 reset(
const_cast<unique_ptr*
>(&u)->release());
257 reset(
const_cast<unique_ptr*
>(&u)->release());
271 const T& operator*()
const {
return *ptr_; }
272 T* operator->()
const {
return ptr_; }
273 T* get() const noexcept {
return ptr_; }
274 explicit operator bool()
const {
return ptr_ !=
nullptr; }
283 void reset(T* p =
nullptr) {
286 if (value)
delete value;
299 template <
class T>
bool operator==(
const unique_ptr<T>& x,
300 const unique_ptr<T>& y) {
301 return x.get() == y.get();
304 template <
class T,
class D>
bool operator==(
const unique_ptr<T>& x,
306 return static_cast<D*
>(x.get()) == y;
309 template <
class T>
bool operator==(
const unique_ptr<T>& x, intptr_t y) {
310 return reinterpret_cast<intptr_t
>(x.get()) == y;
313 template <
class T>
bool operator!=(
const unique_ptr<T>& x, decltype(
nullptr)) {
317 template <
class T>
bool operator!=(decltype(
nullptr),
const unique_ptr<T>& x) {
321 template <
class T>
bool operator==(
const unique_ptr<T>& x, decltype(
nullptr)) {
325 template <
class T>
bool operator==(decltype(
nullptr),
const unique_ptr<T>& x) {
329 #endif // !FLATBUFFERS_CPP98_STL
331 #ifdef FLATBUFFERS_USE_STD_OPTIONAL
334 using nullopt_t = std::nullopt_t;
347 #if defined(FLATBUFFERS_CONSTEXPR_DEFINED)
349 template <
class>
struct nullopt_holder {
350 static constexpr nullopt_t
instance_ = nullopt_t(0);
352 template<
class Dummy>
362 template<
class Dummy>
379 FLATBUFFERS_CONSTEXPR_CPP11
Optional() FLATBUFFERS_NOEXCEPT
380 : value_(), has_value_(false) {}
383 : value_(), has_value_(
false) {}
385 FLATBUFFERS_CONSTEXPR_CPP11
Optional(T val) FLATBUFFERS_NOEXCEPT
386 : value_(val), has_value_(
true) {}
389 : value_(other.value_), has_value_(other.has_value_) {}
392 value_ = other.value_;
393 has_value_ = other.has_value_;
418 FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_EXPLICIT_CPP11
operator bool() const FLATBUFFERS_NOEXCEPT {
422 FLATBUFFERS_CONSTEXPR_CPP11
bool has_value() const FLATBUFFERS_NOEXCEPT {
426 FLATBUFFERS_CONSTEXPR_CPP11
const T&
operator*() const FLATBUFFERS_NOEXCEPT {
435 T
value_or(T default_value)
const FLATBUFFERS_NOEXCEPT {
436 return has_value() ? value_ : default_value;
453 template<
class T,
class U>
454 FLATBUFFERS_CONSTEXPR_CPP11
bool operator==(
const Optional<T>& lhs,
const U& rhs) FLATBUFFERS_NOEXCEPT {
455 return static_cast<bool>(lhs) && (*lhs == rhs);
458 template<
class T,
class U>
459 FLATBUFFERS_CONSTEXPR_CPP11
bool operator==(
const T& lhs,
const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
460 return static_cast<bool>(rhs) && (lhs == *rhs);
463 template<
class T,
class U>
464 FLATBUFFERS_CONSTEXPR_CPP11
bool operator==(
const Optional<T>& lhs,
const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
465 return static_cast<bool>(lhs) !=
static_cast<bool>(rhs)
467 : !
static_cast<bool>(lhs) ?
false : (*lhs == *rhs);
469 #endif // FLATBUFFERS_USE_STD_OPTIONAL
473 #if defined(FLATBUFFERS_USE_STD_SPAN)
475 template<
class T, std::
size_t Extent = std::dynamic_extent>
476 using span = std::span<T, Extent>;
478 #else // !defined(FLATBUFFERS_USE_STD_SPAN)
483 #if !defined(FLATBUFFERS_SPAN_MINIMAL)
490 template<
class E, std::
size_t Extent,
class U, std::
size_t N>
491 struct is_span_convertable {
493 typename std::conditional<std::is_convertible<U (*)[], E (*)[]>::value
499 #endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
504 template<
class T, std::
size_t Extent = dynamic_extent>
505 class span FLATBUFFERS_FINAL_CLASS {
522 FLATBUFFERS_CONSTEXPR_CPP11
528 FLATBUFFERS_CONSTEXPR_CPP11
bool empty() const FLATBUFFERS_NOEXCEPT {
533 FLATBUFFERS_CONSTEXPR_CPP11
pointer data() const FLATBUFFERS_NOEXCEPT {
543 FLATBUFFERS_CONSTEXPR_CPP11
span(
const span &other) FLATBUFFERS_NOEXCEPT
544 : data_(other.data_), count_(other.count_) {}
546 FLATBUFFERS_CONSTEXPR_CPP14 span &
operator=(
const span &other)
547 FLATBUFFERS_NOEXCEPT {
549 count_ = other.count_;
559 FLATBUFFERS_CONSTEXPR_CPP11
568 #if defined(FLATBUFFERS_SPAN_MINIMAL)
569 FLATBUFFERS_CONSTEXPR_CPP11
span() FLATBUFFERS_NOEXCEPT : data_(
nullptr),
571 static_assert(extent == 0 || extent ==
dynamic_extent,
"invalid span");
579 template<std::size_t N = 0,
580 typename internal::is_span_convertable<element_type, Extent, element_type, (N - N)>::type = 0>
581 FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(
nullptr),
583 static_assert(extent == 0 || extent ==
dynamic_extent,
"invalid span");
592 template<std::size_t N,
593 typename internal::is_span_convertable<element_type, Extent, element_type, N>::type = 0>
594 FLATBUFFERS_CONSTEXPR_CPP11 span(element_type (&arr)[N]) FLATBUFFERS_NOEXCEPT
595 : data_(arr), count_(N) {}
597 template<
class U, std::size_t N,
598 typename internal::is_span_convertable<element_type, Extent, U, N>::type = 0>
599 FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
600 : data_(arr.data()), count_(N) {}
607 template<
class U, std::size_t N,
608 typename internal::is_span_convertable<element_type, Extent, U, N>::type = 0>
609 FLATBUFFERS_CONSTEXPR_CPP11 span(
const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
610 : data_(arr.data()), count_(N) {}
617 template<
class U, std::size_t N,
618 typename internal::is_span_convertable<element_type, Extent, U, N>::type = 0>
619 FLATBUFFERS_CONSTEXPR_CPP11 span(
const flatbuffers::span<U, N> &s) FLATBUFFERS_NOEXCEPT
620 : span(s.data(), s.size()) {
623 #endif // !defined(FLATBUFFERS_SPAN_MINIMAL)
631 #if !defined(FLATBUFFERS_SPAN_MINIMAL)
632 template<
class U, std::
size_t N>
633 FLATBUFFERS_CONSTEXPR_CPP11
634 flatbuffers::span<U, N> make_span(U(&arr)[N]) FLATBUFFERS_NOEXCEPT {
635 return span<U, N>(arr);
638 template<
class U, std::
size_t N>
639 FLATBUFFERS_CONSTEXPR_CPP11
640 flatbuffers::span<const U, N> make_span(
const U(&arr)[N]) FLATBUFFERS_NOEXCEPT {
641 return span<const U, N>(arr);
644 template<
class U, std::
size_t N>
645 FLATBUFFERS_CONSTEXPR_CPP11
646 flatbuffers::span<U, N> make_span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
647 return span<U, N>(arr);
650 template<
class U, std::
size_t N>
651 FLATBUFFERS_CONSTEXPR_CPP11
652 flatbuffers::span<const U, N> make_span(
const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
653 return span<const U, N>(arr);
656 template<
class U, std::
size_t N>
657 FLATBUFFERS_CONSTEXPR_CPP11
658 flatbuffers::span<U, dynamic_extent> make_span(U *first, std::size_t
count) FLATBUFFERS_NOEXCEPT {
659 return span<U, dynamic_extent>(first,
count);
662 template<
class U, std::
size_t N>
663 FLATBUFFERS_CONSTEXPR_CPP11
664 flatbuffers::span<const U, dynamic_extent> make_span(
const U *first, std::size_t
count) FLATBUFFERS_NOEXCEPT {
665 return span<const U, dynamic_extent>(first,
count);
669 #endif // defined(FLATBUFFERS_USE_STD_SPAN)
673 #endif // FLATBUFFERS_STL_EMULATION_H_