diff --git a/thirdparty/yasio/compiler/feature_test.hpp b/thirdparty/yasio/compiler/feature_test.hpp index 8b41da2096..549df61f52 100644 --- a/thirdparty/yasio/compiler/feature_test.hpp +++ b/thirdparty/yasio/compiler/feature_test.hpp @@ -33,7 +33,7 @@ SOFTWARE. // https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019 #if defined(_MSC_VER) # if _MSC_VER < 1900 -# define noexcept +# define noexcept throw() # define YASIO__HAS_FULL_CXX11 0 # else # define YASIO__HAS_FULL_CXX11 1 diff --git a/thirdparty/yasio/detail/byte_buffer.hpp b/thirdparty/yasio/detail/byte_buffer.hpp index 0238c77911..0d0b94d519 100644 --- a/thirdparty/yasio/detail/byte_buffer.hpp +++ b/thirdparty/yasio/detail/byte_buffer.hpp @@ -24,24 +24,22 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -/* The byte_buffer concepts +The byte_buffer concepts: a. The memory model is similar to to std::vector, std::string - b. use c realloc/free to manage memory - c. implemented operations: - - resize(without fill) - - resize_fit - - attach/detach(stl not support) - - stl likes: insert, reserve, front, begin, end, push_back and etc. + b. Use c realloc to manage memory + c. Implemented operations: resize(without fill), resize_fit, attach/detach(stl not support) */ -#pragma once +#ifndef YASIO__BYTE_BUFFER_HPP +#define YASIO__BYTE_BUFFER_HPP #include #include #include #include #include #include +#include +#include "yasio/compiler/feature_test.hpp" namespace yasio { @@ -64,48 +62,46 @@ public: memset(&rhs, 0, sizeof(rhs)); } basic_byte_buffer(const std::vector<_Elem>& rhs) { assign(rhs.data(), rhs.data() + rhs.size()); } - ~basic_byte_buffer() { _Tidy(); } + ~basic_byte_buffer() { shrink_to_fit(0); } basic_byte_buffer& operator=(const basic_byte_buffer& rhs) { return assign(rhs.begin(), rhs.end()); } basic_byte_buffer& operator=(basic_byte_buffer&& rhs) noexcept { return this->swap(rhs); } basic_byte_buffer& assign(const void* first, const void* last) { - ptrdiff_t count = (const _Elem*)last - (const _Elem*)first; - if (count > 0) - memcpy(resize(count), first, count); - else - clear(); + clear(); + insert(this->end(), first, last); return *this; } basic_byte_buffer& swap(basic_byte_buffer& rhs) noexcept { - std::swap(_Myfirst, rhs._Myfirst); - std::swap(_Mylast, rhs._Mylast); - std::swap(_Myend, rhs._Myend); + char _Tmp[sizeof(rhs)]; + memcpy(_Tmp, &rhs, sizeof(rhs)); + memcpy(&rhs, this, sizeof(rhs)); + memcpy(this, _Tmp, sizeof(_Tmp)); return *this; } void insert(_Elem* where, const void* first, const void* last) { - ptrdiff_t count = (const _Elem*)last - (const _Elem*)first; + auto count = (const _Elem*)last - (const _Elem*)first; if (count > 0) { - auto insertion_pos = where - this->begin(); - auto cur_size = this->size(); - resize(cur_size + count); - if (insertion_pos >= static_cast(cur_size)) - memcpy(this->begin() + cur_size, first, count); + auto insertion_pos = where - _Myfirst; + auto old_size = _Mylast - _Myfirst; + resize(old_size + count); + if (insertion_pos >= old_size) + memcpy(_Myfirst + old_size, first, count); else if (insertion_pos >= 0) { - where = this->begin() + insertion_pos; + where = _Myfirst + insertion_pos; auto move_to = where + count; - memmove(move_to, where, this->end() - move_to); + memmove(move_to, where, _Mylast - move_to); memcpy(where, first, count); } } } void push_back(_Elem v) { - auto cur_size = this->size(); - resize(cur_size + 1)[cur_size] = v; + resize(this->size() + 1); + *(_Mylast - 1) = v; } _Elem& front() { @@ -114,51 +110,63 @@ public: else throw std::out_of_range("byte_buffer: out of range!"); } + _Elem& back() + { + if (!this->empty()) + return *(_Mylast - 1); + else + throw std::out_of_range("byte_buffer: out of range!"); + } _Elem* begin() noexcept { return _Myfirst; } _Elem* end() noexcept { return _Mylast; } const _Elem* begin() const noexcept { return _Myfirst; } const _Elem* end() const noexcept { return _Mylast; } pointer data() noexcept { return _Myfirst; } const_pointer data() const noexcept { return _Myfirst; } + size_t capacity() const noexcept { return _Myend - _Myfirst; } + size_t size() const noexcept { return _Mylast - _Myfirst; } + void clear() noexcept { _Mylast = _Myfirst; } + void shrink_to_fit() { shrink_to_fit(this->size()); } + bool empty() const noexcept { return _Mylast == _Myfirst; } + void resize(size_t new_size, _Elem val) + { + auto old_size = this->size(); + resize(new_size); + if (old_size < new_size) + memset(_Myfirst + old_size, val, new_size - old_size); + } + void resize(size_t new_size) + { + if (this->capacity() < new_size) + _Reallocate_exactly(new_size * 3 / 2); + _Mylast = _Myfirst + new_size; + } + void resize_fit(size_t new_size) + { + if (this->capacity() < new_size) + _Reallocate_exactly(new_size); + _Mylast = _Myfirst + new_size; + } + void shrink_to_fit(size_t new_size) + { + if (this->capacity() != new_size) + _Reallocate_exactly(new_size); + _Mylast = _Myfirst + new_size; + } void reserve(size_t new_cap) { if (this->capacity() < new_cap) { auto cur_size = this->size(); - _Reset_cap(new_cap); + _Reallocate_exactly(new_cap); _Mylast = _Myfirst + cur_size; } } - _Elem* resize(size_t new_size, _Elem val) - { - auto cur_size = this->size(); - auto ptr = resize(new_size); - if (cur_size < new_size) - memset(ptr + cur_size, val, new_size - cur_size); - return ptr; - } - _Elem* resize(size_t new_size) - { - _Ensure_cap(new_size * 3 / 2); - _Mylast = _Myfirst + new_size; - return _Myfirst; - } - _Elem* resize_fit(size_t new_size) - { - _Ensure_cap(new_size); - _Mylast = _Myfirst + new_size; - return _Myfirst; - } - size_t capacity() const noexcept { return _Myend - _Myfirst; } - size_t size() const noexcept { return _Mylast - _Myfirst; } - void clear() noexcept { _Mylast = _Myfirst; } - bool empty() const noexcept { return _Mylast == _Myfirst; } - void shrink_to_fit() { _Reset_cap(this->size()); } void attach(void* ptr, size_t len) noexcept { if (ptr) { - _Tidy(); + shrink_to_fit(0); _Myfirst = (_Elem*)ptr; _Myend = _Mylast = _Myfirst + len; } @@ -173,41 +181,16 @@ public: } private: - void _Tidy() + void _Reallocate_exactly(size_t new_cap) { - clear(); - shrink_to_fit(); - } - void _Ensure_cap(size_t new_cap) - { - if (this->capacity() < new_cap) - _Reset_cap(new_cap); - } - void _Reset_cap(size_t new_cap) - { - if (new_cap > 0) - { - auto new_blk = (_Elem*)realloc(_Myfirst, new_cap); - if (new_blk) - { - _Myfirst = new_blk; - _Myend = _Myfirst + new_cap; - } - else - throw std::bad_alloc{}; - } + auto new_block = (_Elem*)realloc(_Myfirst, new_cap); + if (new_block || 0 == new_cap) + _Myfirst = new_block; else - { - if (_Myfirst != nullptr) - { - free(_Myfirst); - _Myfirst = nullptr; - } - _Myend = _Myfirst; - } + throw std::bad_alloc{}; + _Myend = _Myfirst + new_cap; } -private: _Elem* _Myfirst = nullptr; _Elem* _Mylast = nullptr; _Elem* _Myend = nullptr; @@ -215,3 +198,4 @@ private: using sbyte_buffer = basic_byte_buffer; using byte_buffer = basic_byte_buffer; } // namespace yasio +#endif