diff options
author | gregoire-astruc <gregoire.astruc@gmail.com> | 2015-02-24 13:14:46 +0100 |
---|---|---|
committer | Wouter van Oortmerssen <wvo@google.com> | 2015-03-11 17:27:38 -0700 |
commit | a360958be3f998b66e12a2d3db0ea17a05a37757 (patch) | |
tree | d7d50c9a8c490e45977341d185028fb457f9e900 /include | |
parent | 432f3f26a40dbc51691c6d461d8a137c5e6c9f2e (diff) | |
download | flatbuffers-a360958be3f998b66e12a2d3db0ea17a05a37757.tar.gz flatbuffers-a360958be3f998b66e12a2d3db0ea17a05a37757.tar.bz2 flatbuffers-a360958be3f998b66e12a2d3db0ea17a05a37757.zip |
Implementation of a buffer release strategy.
* Tests for Release feature.
* Check vector_downward.buf_ before passing to deallocator.
* Assertions.
* Shared test between unique_ptr and GetBufferPointer()
* Unnecessary using directives.
* Reallocate vector if released on clear operation.
* Use allocator attribute.
* Renamed `Release()` to `ReleaseBufferPointer()`
* For consistency with `GetBufferPointer()`
* Updated documentation for ReleaseBuffer.
Change-Id: I108527778e56ae5127abf9e5b1be6b445ad75cb7
Diffstat (limited to 'include')
-rw-r--r-- | include/flatbuffers/flatbuffers.h | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index d6b6e9a7..148d43e0 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -26,6 +26,8 @@ #include <type_traits> #include <vector> #include <algorithm> +#include <functional> +#include <memory> #if __cplusplus <= 199711L && \ (!defined(_MSC_VER) || _MSC_VER < 1600) && \ @@ -84,6 +86,10 @@ typedef uint16_t voffset_t; typedef uintmax_t largest_scalar_t; +// Pointer to relinquished memory. +typedef std::unique_ptr<uint8_t, std::function<void(uint8_t * /* unused */)>> + unique_ptr_t; + // Wrapper for uoffset_t to allow safe template specialization. template<typename T> struct Offset { uoffset_t o; @@ -358,9 +364,33 @@ class vector_downward { assert((initial_size & (sizeof(largest_scalar_t) - 1)) == 0); } - ~vector_downward() { allocator_.deallocate(buf_); } + ~vector_downward() { + if (buf_) + allocator_.deallocate(buf_); + } + + void clear() { + if (buf_ == nullptr) + buf_ = allocator_.allocate(reserved_); + + cur_ = buf_ + reserved_; + } + + // Relinquish the pointer to the caller. + unique_ptr_t release() { + // Actually deallocate from the start of the allocated memory. + std::function<void(uint8_t *)> deleter( + std::bind(&simple_allocator::deallocate, allocator_, buf_)); - void clear() { cur_ = buf_ + reserved_; } + // Point to the desired offset. + unique_ptr_t retval(data(), deleter); + + // Don't deallocate when this instance is destroyed. + buf_ = nullptr; + cur_ = nullptr; + + return retval; + } size_t growth_policy(size_t bytes) { return (bytes / 2) & ~(sizeof(largest_scalar_t) - 1); @@ -385,10 +415,14 @@ class vector_downward { } uoffset_t size() const { + assert(cur_ != nullptr && buf_ != nullptr); return static_cast<uoffset_t>(reserved_ - (cur_ - buf_)); } - uint8_t *data() const { return cur_; } + uint8_t *data() const { + assert(cur_ != nullptr); + return cur_; + } uint8_t *data_at(size_t offset) { return buf_ + reserved_ - offset; } @@ -463,6 +497,10 @@ class FlatBufferBuilder FLATBUFFERS_FINAL_CLASS { // Get the serialized buffer (after you call Finish()). uint8_t *GetBufferPointer() const { return buf_.data(); } + // Get the released pointer to the serialized buffer. + // Don't attempt to use this FlatBufferBuilder afterwards! + unique_ptr_t ReleaseBufferPointer() { return buf_.release(); } + void ForceDefaults(bool fd) { force_defaults_ = fd; } void Pad(size_t num_bytes) { buf_.fill(num_bytes); } |