summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorgregoire-astruc <gregoire.astruc@gmail.com>2015-02-24 13:14:46 +0100
committerWouter van Oortmerssen <wvo@google.com>2015-03-11 17:27:38 -0700
commita360958be3f998b66e12a2d3db0ea17a05a37757 (patch)
treed7d50c9a8c490e45977341d185028fb457f9e900 /include
parent432f3f26a40dbc51691c6d461d8a137c5e6c9f2e (diff)
downloadflatbuffers-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.h44
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); }