diff options
-rw-r--r-- | include/flatbuffers/flatbuffers.h | 55 | ||||
-rw-r--r-- | include/flatbuffers/reflection.h | 2 | ||||
-rw-r--r-- | tests/test.cpp | 4 |
3 files changed, 42 insertions, 19 deletions
diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index 5ea32ca9..8cab3cd3 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -24,13 +24,20 @@ #include <cstdlib> #include <cstring> #include <string> +#include <utility> #include <type_traits> #include <vector> #include <set> #include <algorithm> -#include <functional> #include <memory> +#ifdef _STLPORT_VERSION + #define FLATBUFFERS_CPP98_STL +#endif +#ifndef FLATBUFFERS_CPP98_STL + #include <functional> +#endif + /// @cond FLATBUFFERS_INTERNAL #if __cplusplus <= 199711L && \ (!defined(_MSC_VER) || _MSC_VER < 1600) && \ @@ -123,9 +130,11 @@ typedef uintmax_t largest_scalar_t; // In 32bits, this evaluates to 2GB - 1 #define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1) +#ifndef FLATBUFFERS_CPP98_STL // Pointer to relinquished memory. typedef std::unique_ptr<uint8_t, std::function<void(uint8_t * /* unused */)>> unique_ptr_t; +#endif // Wrapper for uoffset_t to allow safe template specialization. template<typename T> struct Offset { @@ -234,23 +243,19 @@ template<typename T> struct IndirectHelper<const T *> { // An STL compatible iterator implementation for Vector below, effectively // calling Get() for every element. -template<typename T, bool bConst> -struct VectorIterator : public - std::iterator < std::input_iterator_tag, - typename std::conditional < bConst, - const typename IndirectHelper<T>::return_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; +template<typename T, typename IT> +struct VectorIterator + : public std::iterator<std::input_iterator_tag, IT, uoffset_t> { + + typedef std::iterator<std::input_iterator_tag, IT, uoffset_t> super_type; public: VectorIterator(const uint8_t *data, uoffset_t i) : data_(data + IndirectHelper<T>::element_stride * i) {}; VectorIterator(const VectorIterator &other) : data_(other.data_) {} + #ifndef FLATBUFFERS_CPP98_STL VectorIterator(VectorIterator &&other) : data_(std::move(other.data_)) {} + #endif VectorIterator &operator=(const VectorIterator &other) { data_ = other.data_; @@ -301,8 +306,10 @@ private: // Vector::data() assumes the vector elements start after the length field. template<typename T> class Vector { public: - typedef VectorIterator<T, false> iterator; - typedef VectorIterator<T, true> const_iterator; + typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type> + iterator; + typedef VectorIterator<T, typename IndirectHelper<T>::return_type> + const_iterator; uoffset_t size() const { return EndianScalar(length_); } @@ -471,6 +478,7 @@ class vector_downward { cur_ = buf_ + reserved_; } + #ifndef FLATBUFFERS_CPP98_STL // Relinquish the pointer to the caller. unique_ptr_t release() { // Actually deallocate from the start of the allocated memory. @@ -486,6 +494,7 @@ class vector_downward { return retval; } + #endif size_t growth_policy(size_t bytes) { return (bytes / 2) & ~(sizeof(largest_scalar_t) - 1); @@ -562,6 +571,10 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) { inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { 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 /// @addtogroup flatbuffers_cpp_api @@ -627,6 +640,7 @@ FLATBUFFERS_FINAL_CLASS /// @return Returns a `uint8_t` pointer to the unfinished buffer. uint8_t *GetCurrentBufferPointer() const { return buf_.data(); } + #ifndef FLATBUFFERS_CPP98_STL /// @brief Get the released pointer to the serialized buffer. /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! /// @return The `unique_ptr` returned has a special allocator that knows how @@ -637,6 +651,7 @@ FLATBUFFERS_FINAL_CLASS Finished(); return buf_.release(); } + #endif /// @cond FLATBUFFERS_INTERNAL void Finished() const { @@ -674,11 +689,13 @@ FLATBUFFERS_FINAL_CLASS void PopBytes(size_t amount) { buf_.pop(amount); } template<typename T> void AssertScalarT() { + #ifndef FLATBUFFERS_CPP98_STL // The code assumes power of 2 sizes and endian-swap-ability. static_assert(std::is_scalar<T>::value // The Offset<T> type is essentially a scalar but fails is_scalar. || sizeof(T) == sizeof(Offset<void>), "T must be a scalar type"); + #endif } // Write a single aligned scalar to the buffer @@ -981,7 +998,7 @@ FLATBUFFERS_FINAL_CLASS /// @return Returns a typed `Offset` into the serialized data indicating /// where the vector is stored. 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 @@ -995,6 +1012,7 @@ FLATBUFFERS_FINAL_CLASS return Offset<Vector<uint8_t>>(EndVector(v.size())); } + #ifndef FLATBUFFERS_CPP98_STL /// @brief Serialize values returned by a function into a FlatBuffer `vector`. /// This is a convenience function that takes care of iteration for you. /// @tparam T The data type of the `std::vector` elements. @@ -1006,8 +1024,9 @@ FLATBUFFERS_FINAL_CLASS const std::function<T (size_t i)> &f) { std::vector<T> elems(vector_size); 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`. /// This is a convenience function for a common case. @@ -1019,7 +1038,7 @@ FLATBUFFERS_FINAL_CLASS const std::vector<std::string> &v) { std::vector<Offset<String>> offsets(v.size()); 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`. @@ -1044,7 +1063,7 @@ FLATBUFFERS_FINAL_CLASS /// where the vector is stored. template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs( const std::vector<T> &v) { - return CreateVectorOfStructs(v.data(), v.size()); + return CreateVectorOfStructs(data(v), v.size()); } /// @cond FLATBUFFERS_INTERNAL diff --git a/include/flatbuffers/reflection.h b/include/flatbuffers/reflection.h index 87091438..ae331ce2 100644 --- a/include/flatbuffers/reflection.h +++ b/include/flatbuffers/reflection.h @@ -370,6 +370,7 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize, uoffset_t elem_size, std::vector<uint8_t> *flatbuf, const reflection::Object *root_table = nullptr); +#ifndef FLATBUFFERS_CPP98_STL template <typename T> void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val, const Vector<T> *vec, std::vector<uint8_t> *flatbuf, @@ -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 // FlatBuffer. This can be used when any of the above methods are not diff --git a/tests/test.cpp b/tests/test.cpp index 11aea177..37ed4c11 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -25,7 +25,9 @@ #include "namespace_test/namespace_test1_generated.h" #include "namespace_test/namespace_test2_generated.h" -#include <random> +#ifndef FLATBUFFERS_CPP98_STL + #include <random> +#endif using namespace MyGame::Example; |