This is a minimal amount of #ifdef's to make stlport work.

Minimal, in the sense that this will only allow flatbuffers.h +
generated code to work. Everything else (tests, parsing, reflection
etc.) may still not compile with stlport.

Functionality has been reduced, some utility functions are not
available.

Tested: on Linux (no stlport), Android (stlport).

Change-Id: I3f8b6a88258c07d78964dd455fb9f99f65266301
parent 3101e327
...@@ -24,13 +24,20 @@ ...@@ -24,13 +24,20 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <utility>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include <set> #include <set>
#include <algorithm> #include <algorithm>
#include <functional>
#include <memory> #include <memory>
#ifdef _STLPORT_VERSION
#define FLATBUFFERS_CPP98_STL
#endif
#ifndef FLATBUFFERS_CPP98_STL
#include <functional>
#endif
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
#if __cplusplus <= 199711L && \ #if __cplusplus <= 199711L && \
(!defined(_MSC_VER) || _MSC_VER < 1600) && \ (!defined(_MSC_VER) || _MSC_VER < 1600) && \
...@@ -123,9 +130,11 @@ typedef uintmax_t largest_scalar_t; ...@@ -123,9 +130,11 @@ typedef uintmax_t largest_scalar_t;
// In 32bits, this evaluates to 2GB - 1 // In 32bits, this evaluates to 2GB - 1
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1) #define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
#ifndef FLATBUFFERS_CPP98_STL
// Pointer to relinquished memory. // Pointer to relinquished memory.
typedef std::unique_ptr<uint8_t, std::function<void(uint8_t * /* unused */)>> typedef std::unique_ptr<uint8_t, std::function<void(uint8_t * /* unused */)>>
unique_ptr_t; unique_ptr_t;
#endif
// Wrapper for uoffset_t to allow safe template specialization. // Wrapper for uoffset_t to allow safe template specialization.
template<typename T> struct Offset { template<typename T> struct Offset {
...@@ -234,23 +243,19 @@ template<typename T> struct IndirectHelper<const T *> { ...@@ -234,23 +243,19 @@ template<typename T> struct IndirectHelper<const T *> {
// An STL compatible iterator implementation for Vector below, effectively // An STL compatible iterator implementation for Vector below, effectively
// calling Get() for every element. // calling Get() for every element.
template<typename T, bool bConst> template<typename T, typename IT>
struct VectorIterator : public struct VectorIterator
std::iterator < std::input_iterator_tag, : public std::iterator<std::input_iterator_tag, IT, uoffset_t> {
typename std::conditional < bConst,
const typename IndirectHelper<T>::return_type, typedef std::iterator<std::input_iterator_tag, IT, uoffset_t> super_type;
typename IndirectHelper<T>::return_type > ::type, uoffset_t > {
typedef std::iterator<std::input_iterator_tag,
typename std::conditional<bConst,
const typename IndirectHelper<T>::return_type,
typename IndirectHelper<T>::return_type>::type, uoffset_t> super_type;
public: public:
VectorIterator(const uint8_t *data, uoffset_t i) : VectorIterator(const uint8_t *data, uoffset_t i) :
data_(data + IndirectHelper<T>::element_stride * i) {}; data_(data + IndirectHelper<T>::element_stride * i) {};
VectorIterator(const VectorIterator &other) : data_(other.data_) {} VectorIterator(const VectorIterator &other) : data_(other.data_) {}
#ifndef FLATBUFFERS_CPP98_STL
VectorIterator(VectorIterator &&other) : data_(std::move(other.data_)) {} VectorIterator(VectorIterator &&other) : data_(std::move(other.data_)) {}
#endif
VectorIterator &operator=(const VectorIterator &other) { VectorIterator &operator=(const VectorIterator &other) {
data_ = other.data_; data_ = other.data_;
...@@ -301,8 +306,10 @@ private: ...@@ -301,8 +306,10 @@ private:
// Vector::data() assumes the vector elements start after the length field. // Vector::data() assumes the vector elements start after the length field.
template<typename T> class Vector { template<typename T> class Vector {
public: public:
typedef VectorIterator<T, false> iterator; typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type>
typedef VectorIterator<T, true> const_iterator; iterator;
typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
const_iterator;
uoffset_t size() const { return EndianScalar(length_); } uoffset_t size() const { return EndianScalar(length_); }
...@@ -471,6 +478,7 @@ class vector_downward { ...@@ -471,6 +478,7 @@ class vector_downward {
cur_ = buf_ + reserved_; cur_ = buf_ + reserved_;
} }
#ifndef FLATBUFFERS_CPP98_STL
// Relinquish the pointer to the caller. // Relinquish the pointer to the caller.
unique_ptr_t release() { unique_ptr_t release() {
// Actually deallocate from the start of the allocated memory. // Actually deallocate from the start of the allocated memory.
...@@ -486,6 +494,7 @@ class vector_downward { ...@@ -486,6 +494,7 @@ class vector_downward {
return retval; return retval;
} }
#endif
size_t growth_policy(size_t bytes) { size_t growth_policy(size_t bytes) {
return (bytes / 2) & ~(sizeof(largest_scalar_t) - 1); return (bytes / 2) & ~(sizeof(largest_scalar_t) - 1);
...@@ -562,6 +571,10 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) { ...@@ -562,6 +571,10 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
return ((~buf_size) + 1) & (scalar_size - 1); return ((~buf_size) + 1) & (scalar_size - 1);
} }
template <typename T> const T* data(const std::vector<T> &v) {
return v.empty() ? nullptr : &v.front();
}
/// @endcond /// @endcond
/// @addtogroup flatbuffers_cpp_api /// @addtogroup flatbuffers_cpp_api
...@@ -627,6 +640,7 @@ FLATBUFFERS_FINAL_CLASS ...@@ -627,6 +640,7 @@ FLATBUFFERS_FINAL_CLASS
/// @return Returns a `uint8_t` pointer to the unfinished buffer. /// @return Returns a `uint8_t` pointer to the unfinished buffer.
uint8_t *GetCurrentBufferPointer() const { return buf_.data(); } uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }
#ifndef FLATBUFFERS_CPP98_STL
/// @brief Get the released pointer to the serialized buffer. /// @brief Get the released pointer to the serialized buffer.
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
/// @return The `unique_ptr` returned has a special allocator that knows how /// @return The `unique_ptr` returned has a special allocator that knows how
...@@ -637,6 +651,7 @@ FLATBUFFERS_FINAL_CLASS ...@@ -637,6 +651,7 @@ FLATBUFFERS_FINAL_CLASS
Finished(); Finished();
return buf_.release(); return buf_.release();
} }
#endif
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
void Finished() const { void Finished() const {
...@@ -674,11 +689,13 @@ FLATBUFFERS_FINAL_CLASS ...@@ -674,11 +689,13 @@ FLATBUFFERS_FINAL_CLASS
void PopBytes(size_t amount) { buf_.pop(amount); } void PopBytes(size_t amount) { buf_.pop(amount); }
template<typename T> void AssertScalarT() { template<typename T> void AssertScalarT() {
#ifndef FLATBUFFERS_CPP98_STL
// The code assumes power of 2 sizes and endian-swap-ability. // The code assumes power of 2 sizes and endian-swap-ability.
static_assert(std::is_scalar<T>::value static_assert(std::is_scalar<T>::value
// The Offset<T> type is essentially a scalar but fails is_scalar. // The Offset<T> type is essentially a scalar but fails is_scalar.
|| sizeof(T) == sizeof(Offset<void>), || sizeof(T) == sizeof(Offset<void>),
"T must be a scalar type"); "T must be a scalar type");
#endif
} }
// Write a single aligned scalar to the buffer // Write a single aligned scalar to the buffer
...@@ -981,7 +998,7 @@ FLATBUFFERS_FINAL_CLASS ...@@ -981,7 +998,7 @@ FLATBUFFERS_FINAL_CLASS
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
template<typename T> Offset<Vector<T>> CreateVector(const std::vector<T> &v) { template<typename T> Offset<Vector<T>> CreateVector(const std::vector<T> &v) {
return CreateVector(v.data(), v.size()); return CreateVector(data(v), v.size());
} }
// vector<bool> may be implemented using a bit-set, so we can't access it as // vector<bool> may be implemented using a bit-set, so we can't access it as
...@@ -995,6 +1012,7 @@ FLATBUFFERS_FINAL_CLASS ...@@ -995,6 +1012,7 @@ FLATBUFFERS_FINAL_CLASS
return Offset<Vector<uint8_t>>(EndVector(v.size())); return Offset<Vector<uint8_t>>(EndVector(v.size()));
} }
#ifndef FLATBUFFERS_CPP98_STL
/// @brief Serialize values returned by a function into a FlatBuffer `vector`. /// @brief Serialize values returned by a function into a FlatBuffer `vector`.
/// This is a convenience function that takes care of iteration for you. /// This is a convenience function that takes care of iteration for you.
/// @tparam T The data type of the `std::vector` elements. /// @tparam T The data type of the `std::vector` elements.
...@@ -1006,8 +1024,9 @@ FLATBUFFERS_FINAL_CLASS ...@@ -1006,8 +1024,9 @@ FLATBUFFERS_FINAL_CLASS
const std::function<T (size_t i)> &f) { const std::function<T (size_t i)> &f) {
std::vector<T> elems(vector_size); std::vector<T> elems(vector_size);
for (size_t i = 0; i < vector_size; i++) elems[i] = f(i); for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
return CreateVector(elems.data(), elems.size()); return CreateVector(elems);
} }
#endif
/// @brief Serialize a `std::vector<std::string>` into a FlatBuffer `vector`. /// @brief Serialize a `std::vector<std::string>` into a FlatBuffer `vector`.
/// This is a convenience function for a common case. /// This is a convenience function for a common case.
...@@ -1019,7 +1038,7 @@ FLATBUFFERS_FINAL_CLASS ...@@ -1019,7 +1038,7 @@ FLATBUFFERS_FINAL_CLASS
const std::vector<std::string> &v) { const std::vector<std::string> &v) {
std::vector<Offset<String>> offsets(v.size()); std::vector<Offset<String>> offsets(v.size());
for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]); for (size_t i = 0; i < v.size(); i++) offsets[i] = CreateString(v[i]);
return CreateVector(offsets.data(), offsets.size()); return CreateVector(offsets);
} }
/// @brief Serialize an array of structs into a FlatBuffer `vector`. /// @brief Serialize an array of structs into a FlatBuffer `vector`.
...@@ -1044,7 +1063,7 @@ FLATBUFFERS_FINAL_CLASS ...@@ -1044,7 +1063,7 @@ FLATBUFFERS_FINAL_CLASS
/// where the vector is stored. /// where the vector is stored.
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs( template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
const std::vector<T> &v) { const std::vector<T> &v) {
return CreateVectorOfStructs(v.data(), v.size()); return CreateVectorOfStructs(data(v), v.size());
} }
/// @cond FLATBUFFERS_INTERNAL /// @cond FLATBUFFERS_INTERNAL
......
...@@ -370,6 +370,7 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize, ...@@ -370,6 +370,7 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
uoffset_t elem_size, std::vector<uint8_t> *flatbuf, uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
const reflection::Object *root_table = nullptr); const reflection::Object *root_table = nullptr);
#ifndef FLATBUFFERS_CPP98_STL
template <typename T> template <typename T>
void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val, void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
const Vector<T> *vec, std::vector<uint8_t> *flatbuf, const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
...@@ -391,6 +392,7 @@ void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val, ...@@ -391,6 +392,7 @@ void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
} }
} }
} }
#endif
// Adds any new data (in the form of a new FlatBuffer) to an existing // Adds any new data (in the form of a new FlatBuffer) to an existing
// FlatBuffer. This can be used when any of the above methods are not // FlatBuffer. This can be used when any of the above methods are not
......
...@@ -25,7 +25,9 @@ ...@@ -25,7 +25,9 @@
#include "namespace_test/namespace_test1_generated.h" #include "namespace_test/namespace_test1_generated.h"
#include "namespace_test/namespace_test2_generated.h" #include "namespace_test/namespace_test2_generated.h"
#include <random> #ifndef FLATBUFFERS_CPP98_STL
#include <random>
#endif
using namespace MyGame::Example; using namespace MyGame::Example;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment