From 4b3e5b3e1ac84752bcc621dbcbd802fbe7c0c464 Mon Sep 17 00:00:00 2001 From: gabime Date: Thu, 20 Mar 2014 04:00:26 +0200 Subject: [PATCH] fast_buf --- include/c11log/details/fast_buf.h | 103 ++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 include/c11log/details/fast_buf.h diff --git a/include/c11log/details/fast_buf.h b/include/c11log/details/fast_buf.h new file mode 100644 index 00000000..8b4a49d2 --- /dev/null +++ b/include/c11log/details/fast_buf.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include +#include +#include + +// Fast buffer +// stores its contents on the stack when possible, in vector otherwise +// NOTE: User should be remember that returned buffer might be on the stack!! + +namespace c11log +{ +namespace details +{ + +template +class fast_buf +{ +public: + fast_buf():_stack_size(0) {} + ~fast_buf() {}; + + fast_buf(const bufpair_t& buf_to_copy):fast_buf() + { + append(buf_to_copy); + } + + fast_buf(const fast_buf& other) + { + _stack_size = other._stack_size; + if(!other._v.empty()) + _v = other._v; + else if(_stack_size) + std::copy(other._stack_buf.begin(), other._stack_buf.begin()+_stack_size, _stack_buf.begin()); + } + + fast_buf(fast_buf&& other) + { + _stack_size = other._stack_size; + if(!other._v.empty()) + _v = other._v; + else if(_stack_size) + std::copy(other._stack_buf.begin(), other._stack_buf.begin()+_stack_size, _stack_buf.begin()); + other.clear(); + } + + fast_buf& operator=(const fast_buf& other) = delete; + fast_buf& operator=(fast_buf&& other) = delete; + + void append(const char* buf, std::size_t size) + { + //If we are aleady using _v, forget about the stack + if(!_v.empty()) + { + _v.insert(_v.end(), buf, buf+ size); + } + //Try use the stack + else + { + if(_stack_size+size <= STACK_SIZE) + { + std::memcpy(&_stack_buf[_stack_size], buf, size); + _stack_size+=size; + } + //Not enough stack space. Copy all to _v + else + { + _v.reserve(_stack_size+size); + if(_stack_size) + _v.insert(_v.end(), _stack_buf.begin(), _stack_buf.begin() +_stack_size); + _v.insert(_v.end(), buf, buf+size); + } + } + } + + void append(const bufpair_t &buf) + { + append(buf.first, buf.second); + } + + void clear() + { + _stack_size = 0; + _v.clear(); + } + + bufpair_t get() + { + if(!_v.empty()) + return bufpair_t(_v.data(), _v.size()); + else + return bufpair_t(_stack_buf.data(), _stack_size); + } + +private: + std::vector _v; + std::array _stack_buf; + std::size_t _stack_size; +}; + +} +} //namespace c11log { namespace details {