Removal of support for FLATBUFFERS_CPP98_STL (#6918)

* Removal of support for FLATBUFFERS_CPP98_STL

For context, see https://github.com/google/flatbuffers/issues/6704

* Also removed vector_data
This commit is contained in:
Wouter van Oortmerssen
2021-11-12 14:01:11 -08:00
committed by GitHub
parent 3fab0c6ee4
commit 6748c373be
29 changed files with 119 additions and 545 deletions

View File

@@ -26,14 +26,6 @@
#include <memory>
#include <limits>
#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
#define FLATBUFFERS_CPP98_STL
#endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
#if defined(FLATBUFFERS_CPP98_STL)
#include <cctype>
#endif // defined(FLATBUFFERS_CPP98_STL)
// Detect C++17 compatible compiler.
// __cplusplus >= 201703L - a compiler has support of 'static inline' variables.
#if defined(FLATBUFFERS_USE_STD_OPTIONAL) \
@@ -55,7 +47,7 @@
#endif
#else
// Disable non-trivial ctors if FLATBUFFERS_SPAN_MINIMAL defined.
#if !defined(FLATBUFFERS_TEMPLATES_ALIASES) || defined(FLATBUFFERS_CPP98_STL)
#if !defined(FLATBUFFERS_TEMPLATES_ALIASES)
#define FLATBUFFERS_SPAN_MINIMAL
#else
// Enable implicit construction of a span<T,N> from a std::array<T,N>.
@@ -63,139 +55,32 @@
#endif
#endif // defined(FLATBUFFERS_USE_STD_SPAN)
// This header provides backwards compatibility for C++98 STLs like stlport.
// This header provides backwards compatibility for older versions of the STL.
namespace flatbuffers {
// Retrieve ::back() from a string in a way that is compatible with pre C++11
// STLs (e.g stlport).
inline char& string_back(std::string &value) {
return value[value.length() - 1];
}
inline char string_back(const std::string &value) {
return value[value.length() - 1];
}
// Helper method that retrieves ::data() from a vector in a way that is
// compatible with pre C++11 STLs (e.g stlport).
template <typename T> inline T *vector_data(std::vector<T> &vector) {
// In some debug environments, operator[] does bounds checking, so &vector[0]
// can't be used.
return vector.empty() ? nullptr : &vector[0];
}
template <typename T> inline const T *vector_data(
const std::vector<T> &vector) {
return vector.empty() ? nullptr : &vector[0];
}
template <typename T, typename V>
inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
#if defined(FLATBUFFERS_CPP98_STL)
vector->push_back(data);
#else
vector->emplace_back(std::forward<V>(data));
#endif // defined(FLATBUFFERS_CPP98_STL)
}
#ifndef FLATBUFFERS_CPP98_STL
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
template <typename T>
using numeric_limits = std::numeric_limits<T>;
#else
template <typename T> class numeric_limits :
public std::numeric_limits<T> {};
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
template <typename T>
using numeric_limits = std::numeric_limits<T>;
#else
template <typename T> class numeric_limits :
public std::numeric_limits<T> {
public:
// Android NDK fix.
static T lowest() {
return std::numeric_limits<T>::min();
}
};
template <> class numeric_limits<float> :
public std::numeric_limits<float> {
public:
static float lowest() { return -FLT_MAX; }
};
template <> class numeric_limits<double> :
public std::numeric_limits<double> {
public:
static double lowest() { return -DBL_MAX; }
};
template <> class numeric_limits<unsigned long long> {
public:
static unsigned long long min() { return 0ULL; }
static unsigned long long max() { return ~0ULL; }
static unsigned long long lowest() {
return numeric_limits<unsigned long long>::min();
}
};
template <> class numeric_limits<long long> {
public:
static long long min() {
return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1));
}
static long long max() {
return static_cast<long long>(
(1ULL << ((sizeof(long long) << 3) - 1)) - 1);
}
static long long lowest() {
return numeric_limits<long long>::min();
}
};
#endif // FLATBUFFERS_CPP98_STL
public std::numeric_limits<T> {};
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
#ifndef FLATBUFFERS_CPP98_STL
template <typename T> using is_scalar = std::is_scalar<T>;
template <typename T, typename U> using is_same = std::is_same<T,U>;
template <typename T> using is_floating_point = std::is_floating_point<T>;
template <typename T> using is_unsigned = std::is_unsigned<T>;
template <typename T> using is_enum = std::is_enum<T>;
template <typename T> using make_unsigned = std::make_unsigned<T>;
template<bool B, class T, class F>
using conditional = std::conditional<B, T, F>;
template<class T, T v>
using integral_constant = std::integral_constant<T, v>;
template <bool B>
using bool_constant = integral_constant<bool, B>;
using true_type = std::true_type;
using false_type = std::false_type;
#else
// Map C++ TR1 templates defined by stlport.
template <typename T> using is_scalar = std::tr1::is_scalar<T>;
template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
template <typename T> using is_floating_point =
std::tr1::is_floating_point<T>;
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
template <typename T> using is_enum = std::tr1::is_enum<T>;
// Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
template<typename T> struct make_unsigned {
static_assert(is_unsigned<T>::value, "Specialization not implemented!");
using type = T;
};
template<> struct make_unsigned<char> { using type = unsigned char; };
template<> struct make_unsigned<short> { using type = unsigned short; };
template<> struct make_unsigned<int> { using type = unsigned int; };
template<> struct make_unsigned<long> { using type = unsigned long; };
template<>
struct make_unsigned<long long> { using type = unsigned long long; };
template<bool B, class T, class F>
using conditional = std::tr1::conditional<B, T, F>;
template<class T, T v>
using integral_constant = std::tr1::integral_constant<T, v>;
template <bool B>
using bool_constant = integral_constant<bool, B>;
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
#endif // !FLATBUFFERS_CPP98_STL
template <typename T> using is_scalar = std::is_scalar<T>;
template <typename T, typename U> using is_same = std::is_same<T,U>;
template <typename T> using is_floating_point = std::is_floating_point<T>;
template <typename T> using is_unsigned = std::is_unsigned<T>;
template <typename T> using is_enum = std::is_enum<T>;
template <typename T> using make_unsigned = std::make_unsigned<T>;
template<bool B, class T, class F>
using conditional = std::conditional<B, T, F>;
template<class T, T v>
using integral_constant = std::integral_constant<T, v>;
template <bool B>
using bool_constant = integral_constant<bool, B>;
using true_type = std::true_type;
using false_type = std::false_type;
#else
// MSVC 2010 doesn't support C++11 aliases.
template <typename T> struct is_scalar : public std::is_scalar<T> {};
@@ -215,124 +100,33 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
typedef bool_constant<false> false_type;
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#ifndef FLATBUFFERS_CPP98_STL
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
template <class T> using unique_ptr = std::unique_ptr<T>;
#else
// MSVC 2010 doesn't support C++11 aliases.
// We're manually "aliasing" the class here as we want to bring unique_ptr
// into the flatbuffers namespace. We have unique_ptr in the flatbuffers
// namespace we have a completely independent implementation (see below)
// for C++98 STL implementations.
template <class T> class unique_ptr : public std::unique_ptr<T> {
public:
unique_ptr() {}
explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
unique_ptr(unique_ptr&& u) { *this = std::move(u); }
unique_ptr& operator=(std::unique_ptr<T>&& u) {
std::unique_ptr<T>::reset(u.release());
return *this;
}
unique_ptr& operator=(unique_ptr&& u) {
std::unique_ptr<T>::reset(u.release());
return *this;
}
unique_ptr& operator=(T* p) {
return std::unique_ptr<T>::operator=(p);
}
};
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#if defined(FLATBUFFERS_TEMPLATES_ALIASES)
template <class T> using unique_ptr = std::unique_ptr<T>;
#else
// Very limited implementation of unique_ptr.
// This is provided simply to allow the C++ code generated from the default
// settings to function in C++98 environments with no modifications.
template <class T> class unique_ptr {
public:
typedef T element_type;
unique_ptr() : ptr_(nullptr) {}
explicit unique_ptr(T* p) : ptr_(p) {}
unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); }
unique_ptr(const unique_ptr& u) : ptr_(nullptr) {
reset(const_cast<unique_ptr*>(&u)->release());
}
~unique_ptr() { reset(); }
unique_ptr& operator=(const unique_ptr& u) {
reset(const_cast<unique_ptr*>(&u)->release());
// MSVC 2010 doesn't support C++11 aliases.
// We're manually "aliasing" the class here as we want to bring unique_ptr
// into the flatbuffers namespace. We have unique_ptr in the flatbuffers
// namespace we have a completely independent implementation (see below)
// for C++98 STL implementations.
template <class T> class unique_ptr : public std::unique_ptr<T> {
public:
unique_ptr() {}
explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
unique_ptr(unique_ptr&& u) { *this = std::move(u); }
unique_ptr& operator=(std::unique_ptr<T>&& u) {
std::unique_ptr<T>::reset(u.release());
return *this;
}
unique_ptr& operator=(unique_ptr&& u) {
reset(u.release());
std::unique_ptr<T>::reset(u.release());
return *this;
}
unique_ptr& operator=(T* p) {
reset(p);
return *this;
return std::unique_ptr<T>::operator=(p);
}
const T& operator*() const { return *ptr_; }
T* operator->() const { return ptr_; }
T* get() const noexcept { return ptr_; }
explicit operator bool() const { return ptr_ != nullptr; }
// modifiers
T* release() {
T* value = ptr_;
ptr_ = nullptr;
return value;
}
void reset(T* p = nullptr) {
T* value = ptr_;
ptr_ = p;
if (value) delete value;
}
void swap(unique_ptr& u) {
T* temp_ptr = ptr_;
ptr_ = u.ptr_;
u.ptr_ = temp_ptr;
}
private:
T* ptr_;
};
template <class T> bool operator==(const unique_ptr<T>& x,
const unique_ptr<T>& y) {
return x.get() == y.get();
}
template <class T, class D> bool operator==(const unique_ptr<T>& x,
const D* y) {
return static_cast<D*>(x.get()) == y;
}
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
return reinterpret_cast<intptr_t>(x.get()) == y;
}
template <class T> bool operator!=(const unique_ptr<T>& x, decltype(nullptr)) {
return !!x;
}
template <class T> bool operator!=(decltype(nullptr), const unique_ptr<T>& x) {
return !!x;
}
template <class T> bool operator==(const unique_ptr<T>& x, decltype(nullptr)) {
return !x;
}
template <class T> bool operator==(decltype(nullptr), const unique_ptr<T>& x) {
return !x;
}
#endif // !FLATBUFFERS_CPP98_STL
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#ifdef FLATBUFFERS_USE_STD_OPTIONAL
template<class T>