2 #ifndef UVCC_BUFFER__HPP     3 #define UVCC_BUFFER__HPP     5 #include "uvcc/debug.hpp"     6 #include "uvcc/utility.hpp"    11 #include <type_traits>           13 #include <initializer_list>      34   friend class udp_send;
    40   using sink_cb_t = std::function< 
void(
buffer&) >;
    54     std::size_t buf_count;
    58     static void* operator 
new(std::size_t _size, 
const std::initializer_list< std::size_t > &_len_values)
    60       auto extra_buf_count = _len_values.size();
    61       if (extra_buf_count > 0)  --extra_buf_count;
    62       std::size_t total_buf_len = 0;
    63       for (
auto len : _len_values)  total_buf_len += len;
    64       return ::operator 
new(_size + extra_buf_count*
sizeof(uv_t) + alignment_padding(extra_buf_count) + total_buf_len);
    66     static void operator 
delete(
void *_ptr, 
const std::initializer_list< std::size_t >&)  { ::operator 
delete(_ptr); }
    67     static void operator 
delete(
void *_ptr)  { ::operator 
delete(_ptr); }
    70     instance(
const std::initializer_list< std::size_t > &_len_values) : buf_count(_len_values.size())
    75         uv_buf_struct.base = 
nullptr;
    76         uv_buf_struct.len = 0;
    80         uv_t *buf = &uv_buf_struct;
    81         std::size_t total_buf_len = 0;
    82         for (
auto len : _len_values)  total_buf_len += ((buf++)->len = len);
    83         if (total_buf_len == 0)
    86           for (
decltype(buf_count) i = 0; i < buf_count; ++i)  { buf[i].base = 
nullptr; buf[i].len = 0; }
    90           uv_buf_struct.base = 
reinterpret_cast< 
char* >(buf) + alignment_padding(buf_count - 1);
    92           for (
decltype(buf_count) i = 1; i < buf_count; ++i)  buf[i].base = &buf[i-1].base[buf[i-1].len];
    98     ~instance() = 
default;
   100     instance(
const instance&) = 
delete;
   101     instance& operator =(
const instance&) = 
delete;
   103     instance(instance&&) = 
delete;
   104     instance& operator =(instance&&) = 
delete;
   107     static std::size_t alignment_padding(
const std::size_t _extra_buf_count) 
noexcept   109       const std::size_t base_size = 
sizeof(instance) + _extra_buf_count*
sizeof(uv_t);
   110       const std::size_t proper_size = (base_size + 
alignof(std::max_align_t) - 1) & ~(
alignof(std::max_align_t) - 1);
   111       return proper_size - base_size;
   116       auto &sink_cb = sink_cb_storage.value();
   120         buffer b(&uv_buf_struct, adopt_ref);
   126           if (refs.dec() == 0)  
delete this;
   134     static uv_t* create(
const std::initializer_list< std::size_t > &_len_values)
   135     { 
return &(
new(_len_values) instance(_len_values))->uv_buf_struct; }
   136     static uv_t* create()  { 
return create({}); }
   138     constexpr static instance* from(uv_t *_uv_buf) 
noexcept   140       static_assert(std::is_standard_layout< instance >::value, 
"not a standard layout type");
   141       return reinterpret_cast< instance* >(
reinterpret_cast< 
char* >(_uv_buf) - offsetof(instance, uv_buf_struct));
   146       static uv_t* from(
decltype(uv_t::base) _base) 
noexcept   148         return reinterpret_cast< uv_t* >(
reinterpret_cast< 
char* >(_base) - alignment_padding(0) - 
sizeof(uv_t));
   152     void ref()  { refs.inc(); }
   153     void unref() 
noexcept  { 
if (refs.dec() == 0)  destroy(); }
   156   friend typename buffer::instance* debug::instance<>(buffer&) 
noexcept;
   163   explicit buffer(uv_t *_uv_buf)
   165     if (_uv_buf)  instance::from(_uv_buf)->ref();
   169   explicit buffer(uv_t *_uv_buf, 
const adopt_ref_t) : uv_buf(_uv_buf)  {}
   172   ~buffer()  { 
if (uv_buf)  instance::from(uv_buf)->unref(); }
   201   buffer(
const buffer &_that) : buffer(_that.uv_buf)  {}
   206       if (_that.uv_buf)  instance::from(_that.uv_buf)->ref();
   208       uv_buf = _that.uv_buf;
   209       if (t)  instance::from(t)->unref();
   214   buffer(
buffer &&_that) 
noexcept : uv_buf(_that.uv_buf)  { _that.uv_buf = 
nullptr; }
   220       uv_buf = _that.uv_buf;
   221       _that.uv_buf = 
nullptr;
   222       if (t)  instance::from(t)->unref();
   228   void swap(
buffer &_that) 
noexcept  { std::swap(uv_buf, _that.uv_buf); }
   230   long nrefs() 
const noexcept  { 
return instance::from(uv_buf)->refs.get_value(); }
   232   sink_cb_t& sink_cb() 
const noexcept  { 
return instance::from(uv_buf)->sink_cb_storage.value(); }
   235   std::size_t 
count() 
const noexcept  { 
return instance::from(uv_buf)->buf_count; }
   266 using on_buffer_alloc_t = std::function< 
buffer(
handle _handle, std::size_t _suggested_size) >;
   276 template<> 
inline void swap(
uv::
buffer &_this, 
uv::
buffer &_that) 
noexcept  { _this.swap(_that); }
 Namespace for all uvcc definitions. 
 
operator bool() const noexcept
Equivalent to (base() != nullptr). 
 
A wrapper providing the feature of being a standard layout type for the given type _T_...
 
buffer(const std::initializer_list< std::size_t > &_len_values)
Create an array of initialized uv_buf_t buffer describing structures. 
 
std::size_t count() const noexcept
The number of the uv_buf_t structures in the array. 
 
decltype(uv_t::len) & len(const std::size_t _i=0) const noexcept
The .len field of the _i-th buffer structure. 
 
uv_t & operator[](const std::size_t _i) const noexcept
Access to the _i-th uv_buf_t buffer structure in the array. 
 
The base class for the libuv handles. 
 
long nrefs() const noexcept
The current number of existing references to the same buffer as this variable refers to...
 
A reference counter with atomic increment/decrement. 
 
decltype(uv_t::base) & base(const std::size_t _i=0) const noexcept
The .base field of the _i-th buffer structure. 
 
buffer()
Create a single uv_buf_t null-initialized buffer structure.