Update yasio

This commit is contained in:
halx99 2021-12-11 13:02:56 +08:00
parent e2f13576ae
commit 09b122ee3f
2 changed files with 71 additions and 87 deletions

View File

@ -33,7 +33,7 @@ SOFTWARE.
// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019 // https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019
#if defined(_MSC_VER) #if defined(_MSC_VER)
# if _MSC_VER < 1900 # if _MSC_VER < 1900
# define noexcept # define noexcept throw()
# define YASIO__HAS_FULL_CXX11 0 # define YASIO__HAS_FULL_CXX11 0
# else # else
# define YASIO__HAS_FULL_CXX11 1 # define YASIO__HAS_FULL_CXX11 1

View File

@ -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, 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/
/* The byte_buffer concepts The byte_buffer concepts:
a. The memory model is similar to to std::vector<char>, std::string a. The memory model is similar to to std::vector<char>, std::string
b. use c realloc/free to manage memory b. Use c realloc to manage memory
c. implemented operations: c. Implemented operations: resize(without fill), resize_fit, attach/detach(stl not support)
- resize(without fill)
- resize_fit
- attach/detach(stl not support)
- stl likes: insert, reserve, front, begin, end, push_back and etc.
*/ */
#pragma once #ifndef YASIO__BYTE_BUFFER_HPP
#define YASIO__BYTE_BUFFER_HPP
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <exception> #include <exception>
#include <type_traits>
#include "yasio/compiler/feature_test.hpp"
namespace yasio namespace yasio
{ {
@ -64,48 +62,46 @@ public:
memset(&rhs, 0, sizeof(rhs)); memset(&rhs, 0, sizeof(rhs));
} }
basic_byte_buffer(const std::vector<_Elem>& rhs) { assign(rhs.data(), rhs.data() + rhs.size()); } 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=(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& operator=(basic_byte_buffer&& rhs) noexcept { return this->swap(rhs); }
basic_byte_buffer& assign(const void* first, const void* last) basic_byte_buffer& assign(const void* first, const void* last)
{ {
ptrdiff_t count = (const _Elem*)last - (const _Elem*)first; clear();
if (count > 0) insert(this->end(), first, last);
memcpy(resize(count), first, count);
else
clear();
return *this; return *this;
} }
basic_byte_buffer& swap(basic_byte_buffer& rhs) noexcept basic_byte_buffer& swap(basic_byte_buffer& rhs) noexcept
{ {
std::swap(_Myfirst, rhs._Myfirst); char _Tmp[sizeof(rhs)];
std::swap(_Mylast, rhs._Mylast); memcpy(_Tmp, &rhs, sizeof(rhs));
std::swap(_Myend, rhs._Myend); memcpy(&rhs, this, sizeof(rhs));
memcpy(this, _Tmp, sizeof(_Tmp));
return *this; return *this;
} }
void insert(_Elem* where, const void* first, const void* last) 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) if (count > 0)
{ {
auto insertion_pos = where - this->begin(); auto insertion_pos = where - _Myfirst;
auto cur_size = this->size(); auto old_size = _Mylast - _Myfirst;
resize(cur_size + count); resize(old_size + count);
if (insertion_pos >= static_cast<ptrdiff_t>(cur_size)) if (insertion_pos >= old_size)
memcpy(this->begin() + cur_size, first, count); memcpy(_Myfirst + old_size, first, count);
else if (insertion_pos >= 0) else if (insertion_pos >= 0)
{ {
where = this->begin() + insertion_pos; where = _Myfirst + insertion_pos;
auto move_to = where + count; auto move_to = where + count;
memmove(move_to, where, this->end() - move_to); memmove(move_to, where, _Mylast - move_to);
memcpy(where, first, count); memcpy(where, first, count);
} }
} }
} }
void push_back(_Elem v) void push_back(_Elem v)
{ {
auto cur_size = this->size(); resize(this->size() + 1);
resize(cur_size + 1)[cur_size] = v; *(_Mylast - 1) = v;
} }
_Elem& front() _Elem& front()
{ {
@ -114,51 +110,63 @@ public:
else else
throw std::out_of_range("byte_buffer: out of range!"); 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* begin() noexcept { return _Myfirst; }
_Elem* end() noexcept { return _Mylast; } _Elem* end() noexcept { return _Mylast; }
const _Elem* begin() const noexcept { return _Myfirst; } const _Elem* begin() const noexcept { return _Myfirst; }
const _Elem* end() const noexcept { return _Mylast; } const _Elem* end() const noexcept { return _Mylast; }
pointer data() noexcept { return _Myfirst; } pointer data() noexcept { return _Myfirst; }
const_pointer data() const 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) void reserve(size_t new_cap)
{ {
if (this->capacity() < new_cap) if (this->capacity() < new_cap)
{ {
auto cur_size = this->size(); auto cur_size = this->size();
_Reset_cap(new_cap); _Reallocate_exactly(new_cap);
_Mylast = _Myfirst + cur_size; _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 void attach(void* ptr, size_t len) noexcept
{ {
if (ptr) if (ptr)
{ {
_Tidy(); shrink_to_fit(0);
_Myfirst = (_Elem*)ptr; _Myfirst = (_Elem*)ptr;
_Myend = _Mylast = _Myfirst + len; _Myend = _Mylast = _Myfirst + len;
} }
@ -173,41 +181,16 @@ public:
} }
private: private:
void _Tidy() void _Reallocate_exactly(size_t new_cap)
{ {
clear(); auto new_block = (_Elem*)realloc(_Myfirst, new_cap);
shrink_to_fit(); if (new_block || 0 == new_cap)
} _Myfirst = new_block;
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{};
}
else else
{ throw std::bad_alloc{};
if (_Myfirst != nullptr) _Myend = _Myfirst + new_cap;
{
free(_Myfirst);
_Myfirst = nullptr;
}
_Myend = _Myfirst;
}
} }
private:
_Elem* _Myfirst = nullptr; _Elem* _Myfirst = nullptr;
_Elem* _Mylast = nullptr; _Elem* _Mylast = nullptr;
_Elem* _Myend = nullptr; _Elem* _Myend = nullptr;
@ -215,3 +198,4 @@ private:
using sbyte_buffer = basic_byte_buffer<char>; using sbyte_buffer = basic_byte_buffer<char>;
using byte_buffer = basic_byte_buffer<uint8_t>; using byte_buffer = basic_byte_buffer<uint8_t>;
} // namespace yasio } // namespace yasio
#endif