17#ifndef FLATBUFFERS_STL_EMULATION_H_
18#define FLATBUFFERS_STL_EMULATION_H_
29#ifndef FLATBUFFERS_USE_STD_OPTIONAL
32 #if (defined(__cplusplus) && __cplusplus >= 201703L) \
33 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
34 #define FLATBUFFERS_USE_STD_OPTIONAL 1
36 #define FLATBUFFERS_USE_STD_OPTIONAL 0
40#if FLATBUFFERS_USE_STD_OPTIONAL
44#ifndef FLATBUFFERS_USE_STD_SPAN
48 #if defined(__cplusplus) && __cplusplus >= 202002L
49 #define FLATBUFFERS_USE_STD_SPAN 1
53#if defined(FLATBUFFERS_USE_STD_SPAN)
58 #if !defined(FLATBUFFERS_TEMPLATES_ALIASES)
59 #define FLATBUFFERS_SPAN_MINIMAL
69#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
71 using numeric_limits = std::numeric_limits<T>;
74 public std::numeric_limits<T> {};
77#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
78 template <
typename T>
using is_scalar = std::is_scalar<T>;
79 template <
typename T,
typename U>
using is_same = std::is_same<T,U>;
81 template <
typename T>
using is_unsigned = std::is_unsigned<T>;
82 template <
typename T>
using is_enum = std::is_enum<T>;
83 template <
typename T>
using make_unsigned = std::make_unsigned<T>;
84 template<
bool B,
class T,
class F>
86 template<
class T, T v>
94 template <
typename T>
struct is_scalar :
public std::is_scalar<T> {};
95 template <
typename T,
typename U>
struct is_same :
public std::is_same<T,U> {};
97 public std::is_floating_point<T> {};
98 template <
typename T>
struct is_unsigned :
public std::is_unsigned<T> {};
99 template <
typename T>
struct is_enum :
public std::is_enum<T> {};
100 template <
typename T>
struct make_unsigned :
public std::make_unsigned<T> {};
101 template<
bool B,
class T,
class F>
103 template<
class T, T v>
111#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
112 template <
class T>
using unique_ptr = std::unique_ptr<T>;
119 template <
class T>
class unique_ptr :
public std::unique_ptr<T> {
126 std::unique_ptr<T>::reset(u.release());
130 std::unique_ptr<T>::reset(u.release());
134 return std::unique_ptr<T>::operator=(
p);
139#if FLATBUFFERS_USE_STD_OPTIONAL
141using Optional = std::optional<T>;
142using nullopt_t = std::nullopt_t;
143inline constexpr nullopt_t nullopt = std::nullopt;
155#if defined(FLATBUFFERS_CONSTEXPR_DEFINED)
157 template <
class>
struct nullopt_holder {
158 static constexpr nullopt_t
instance_ = nullopt_t(0);
160 template<
class Dummy>
170 template<
class Dummy>
187 FLATBUFFERS_CONSTEXPR_CPP11
Optional() FLATBUFFERS_NOEXCEPT
188 : value_(), has_value_(false) {}
191 : value_(), has_value_(
false) {}
193 FLATBUFFERS_CONSTEXPR_CPP11
Optional(T val) FLATBUFFERS_NOEXCEPT
194 : value_(val), has_value_(
true) {}
196 FLATBUFFERS_CONSTEXPR_CPP11
Optional(
const Optional &other) FLATBUFFERS_NOEXCEPT
197 : value_(other.value_), has_value_(other.has_value_) {}
199 FLATBUFFERS_CONSTEXPR_CPP14 Optional &
operator=(
const Optional &other) FLATBUFFERS_NOEXCEPT {
200 value_ = other.value_;
201 has_value_ = other.has_value_;
211 FLATBUFFERS_CONSTEXPR_CPP14 Optional &
operator=(T val) FLATBUFFERS_NOEXCEPT {
221 void swap(Optional &other) FLATBUFFERS_NOEXCEPT {
222 std::swap(value_, other.value_);
223 std::swap(has_value_, other.has_value_);
226 FLATBUFFERS_CONSTEXPR_CPP11 FLATBUFFERS_EXPLICIT_CPP11
operator bool() const FLATBUFFERS_NOEXCEPT {
230 FLATBUFFERS_CONSTEXPR_CPP11
bool has_value() const FLATBUFFERS_NOEXCEPT {
234 FLATBUFFERS_CONSTEXPR_CPP11
const T&
operator*() const FLATBUFFERS_NOEXCEPT {
243 T
value_or(T default_value)
const FLATBUFFERS_NOEXCEPT {
244 return has_value() ? value_ : default_value;
261template<
class T,
class U>
262FLATBUFFERS_CONSTEXPR_CPP11
bool operator==(
const Optional<T>& lhs,
const U& rhs) FLATBUFFERS_NOEXCEPT {
263 return static_cast<bool>(lhs) && (*lhs == rhs);
266template<
class T,
class U>
267FLATBUFFERS_CONSTEXPR_CPP11
bool operator==(
const T& lhs,
const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
268 return static_cast<bool>(rhs) && (lhs == *rhs);
271template<
class T,
class U>
272FLATBUFFERS_CONSTEXPR_CPP11
bool operator==(
const Optional<T>& lhs,
const Optional<U>& rhs) FLATBUFFERS_NOEXCEPT {
273 return static_cast<bool>(lhs) !=
static_cast<bool>(rhs)
275 : !
static_cast<bool>(lhs) ?
false : (*lhs == *rhs);
281#if defined(FLATBUFFERS_USE_STD_SPAN)
282 inline constexpr std::size_t
dynamic_extent = std::dynamic_extent;
283 template<
class T, std::
size_t Extent = std::dynamic_extent>
284 using span = std::span<T, Extent>;
291#if !defined(FLATBUFFERS_SPAN_MINIMAL)
298 template<
class To, std::
size_t Extent,
class From, std::
size_t N>
299 struct is_span_convertible {
301 typename std::conditional<std::is_convertible<From (*)[], To (*)[]>::value
307 struct SpanIterator {
309 using iterator_category = std::forward_iterator_tag;
310 using difference_type = std::ptrdiff_t;
311 using value_type =
typename std::remove_cv<T>::type;
312 using reference = T&;
317 using _Unchecked_type = pointer;
320 SpanIterator(pointer ptr) : ptr_(ptr) {}
321 reference
operator*()
const {
return *ptr_; }
322 pointer operator->() {
return ptr_; }
323 SpanIterator& operator++() { ptr_++;
return *
this; }
324 SpanIterator operator++(
int) {
auto tmp = *
this; ++(*this);
return tmp; }
326 friend bool operator== (
const SpanIterator& lhs,
const SpanIterator& rhs) {
return lhs.ptr_ == rhs.ptr_; }
327 friend bool operator!= (
const SpanIterator& lhs,
const SpanIterator& rhs) {
return lhs.ptr_ != rhs.ptr_; }
338template<
class T, std::
size_t Extent = dynamic_extent>
339class span FLATBUFFERS_FINAL_CLASS {
356 FLATBUFFERS_CONSTEXPR_CPP11
362 FLATBUFFERS_CONSTEXPR_CPP11
bool empty() const FLATBUFFERS_NOEXCEPT {
367 FLATBUFFERS_CONSTEXPR_CPP11
pointer data() const FLATBUFFERS_NOEXCEPT {
371 #if !defined(FLATBUFFERS_SPAN_MINIMAL)
372 using Iterator = internal::SpanIterator<T>;
374 Iterator
begin()
const {
return Iterator(data()); }
375 Iterator end()
const {
return Iterator(data() +
size()); }
384 FLATBUFFERS_CONSTEXPR_CPP11
span(
const span &other) FLATBUFFERS_NOEXCEPT
385 : data_(other.data_), count_(other.count_) {}
387 FLATBUFFERS_CONSTEXPR_CPP14 span &
operator=(
const span &other)
388 FLATBUFFERS_NOEXCEPT {
390 count_ = other.count_;
400 FLATBUFFERS_CONSTEXPR_CPP11
402 : data_ (Extent == dynamic_extent ? first : (Extent == count ? first : nullptr)),
403 count_(Extent ==
dynamic_extent ? count : (Extent == count ? Extent : 0)) {
409 #if defined(FLATBUFFERS_SPAN_MINIMAL)
410 FLATBUFFERS_CONSTEXPR_CPP11
span() FLATBUFFERS_NOEXCEPT : data_(
nullptr),
412 static_assert(extent == 0 || extent ==
dynamic_extent,
"invalid span");
420 template<std::size_t N = 0,
421 typename internal::is_span_convertible<element_type, Extent, element_type, (N - N)>
::type = 0>
422 FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT : data_(
nullptr),
424 static_assert(extent == 0 || extent ==
dynamic_extent,
"invalid span");
433 template<std::size_t N,
434 typename internal::is_span_convertible<element_type, Extent, element_type, N>::type = 0>
435 FLATBUFFERS_CONSTEXPR_CPP11 span(element_type (&arr)[N]) FLATBUFFERS_NOEXCEPT
436 : data_(arr), count_(N) {}
438 template<
class U, std::size_t N,
439 typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
440 FLATBUFFERS_CONSTEXPR_CPP11 span(std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
441 : data_(
arr.data()), count_(N) {}
448 template<
class U, std::size_t N,
449 typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
450 FLATBUFFERS_CONSTEXPR_CPP11 span(
const std::array<U, N> &arr) FLATBUFFERS_NOEXCEPT
451 : data_(
arr.data()), count_(N) {}
458 template<
class U, std::size_t N,
459 typename internal::is_span_convertible<element_type, Extent, U, N>::type = 0>
460 FLATBUFFERS_CONSTEXPR_CPP11 span(
const flatbuffers::span<U, N> &s) FLATBUFFERS_NOEXCEPT
461 : span(
s.data(),
s.size()) {
473#if !defined(FLATBUFFERS_SPAN_MINIMAL)
474template<
class ElementType, std::
size_t Extent>
475FLATBUFFERS_CONSTEXPR_CPP11
476flatbuffers::span<ElementType, Extent>
make_span(ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
477 return span<ElementType, Extent>(arr);
480template<
class ElementType, std::
size_t Extent>
481FLATBUFFERS_CONSTEXPR_CPP11
482flatbuffers::span<const ElementType, Extent>
make_span(
const ElementType(&arr)[Extent]) FLATBUFFERS_NOEXCEPT {
483 return span<const ElementType, Extent>(arr);
486template<
class ElementType, std::
size_t Extent>
487FLATBUFFERS_CONSTEXPR_CPP11
488flatbuffers::span<ElementType, Extent>
make_span(std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
489 return span<ElementType, Extent>(arr);
492template<
class ElementType, std::
size_t Extent>
493FLATBUFFERS_CONSTEXPR_CPP11
494flatbuffers::span<const ElementType, Extent>
make_span(
const std::array<ElementType, Extent> &arr) FLATBUFFERS_NOEXCEPT {
495 return span<const ElementType, Extent>(arr);
498template<
class ElementType, std::
size_t Extent>
499FLATBUFFERS_CONSTEXPR_CPP11
500flatbuffers::span<ElementType, dynamic_extent>
make_span(ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
501 return span<ElementType, dynamic_extent>(first, count);
504template<
class ElementType, std::
size_t Extent>
505FLATBUFFERS_CONSTEXPR_CPP11
506flatbuffers::span<const ElementType, dynamic_extent>
make_span(
const ElementType *first, std::size_t count) FLATBUFFERS_NOEXCEPT {
507 return span<const ElementType, dynamic_extent>(first, count);
nest::Expr operator*(const nest::Expr &, const nest::Expr &)
#define FLATBUFFERS_ASSERT
void reset() FLATBUFFERS_NOEXCEPT
T value_or(T default_value) const FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP14 Optional & operator=(T val) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 pointer data() const FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 Optional(const Optional &other) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 Optional(T val) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 Optional(nullopt_t) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 span() FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 Optional() FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 span(const span &other) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 size_type size_bytes() const FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP14 span & operator=(const span &other) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 bool has_value() const FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 reference operator[](size_type idx) const
FLATBUFFERS_CONSTEXPR_CPP11 const T & operator*() const FLATBUFFERS_NOEXCEPT
void swap(Optional &other) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 size_type size() const FLATBUFFERS_NOEXCEPT
const T & const_reference
FLATBUFFERS_CONSTEXPR_CPP14 Optional & operator=(const Optional &other) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 bool empty() const FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP11 span(pointer first, size_type count) FLATBUFFERS_NOEXCEPT
FLATBUFFERS_CONSTEXPR_CPP14 Optional & operator=(nullopt_t) FLATBUFFERS_NOEXCEPT
unique_ptr & operator=(std::unique_ptr< T > &&u)
unique_ptr(std::unique_ptr< T > &&u)
unique_ptr & operator=(unique_ptr &&u)
unique_ptr(unique_ptr &&u)
unique_ptr & operator=(T *p)
bool_constant< false > false_type
bool_constant< true > true_type
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span< U, N > make_span(Array< U, N > &arr) FLATBUFFERS_NOEXCEPT
bool operator==(const Array< T, length > &lhs, const Array< T, length > &rhs) noexcept
FLATBUFFERS_CONSTEXPR std::size_t dynamic_extent
static const nullopt_t instance_
FLATBUFFERS_CONSTEXPR_CPP11 nullopt_t(int)