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
#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

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,
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<char>, 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 <stddef.h>
#include <stdint.h>
#include <string.h>
#include <memory>
#include <vector>
#include <exception>
#include <type_traits>
#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<ptrdiff_t>(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<char>;
using byte_buffer = basic_byte_buffer<uint8_t>;
} // namespace yasio
#endif