23#include <boost/interprocess/smart_ptr/shared_ptr.hpp> 
   24#include <boost/move/make_unique.hpp> 
  245template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
  268  static_assert(std::is_same_v<typename Allocator_raw::value_type, value_type>,
 
  269                "Allocator template param must be of form A<V> where V is our value_type.");
 
  330  static constexpr bool S_IS_VANILLA_ALLOC = std::is_same_v<Allocator_raw, std::allocator<value_type>>;
 
  643  template<
typename Emit_blob_func>
 
  662  template<
typename Blob_container>
 
  683  template<
typename Blob_ptr_container>
 
 1137  template<
typename Emit_blob_func, 
typename Share_after_split_left_func>
 
 1139                                      Emit_blob_func&& emit_blob_func,
 
 1141                                      Share_after_split_left_func&& share_after_split_left_func);
 
 1176    using Pointer_raw = 
typename std::allocator_traits<Allocator_raw>::pointer;
 
 1321                                                        boost::shared_ptr<value_type[]>,
 
 1322                                                        boost::movelib::unique_ptr<value_type[]>>,
 
 1324                                                        boost::interprocess::shared_ptr
 
 1326                                                        boost::movelib::unique_ptr<value_type, Deleter_raw>>>;
 
 1424template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1426  m_alloc_raw(alloc_raw) 
 
 1431template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1440template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1443  m_alloc_raw(std::allocator_traits<
Allocator_raw>::select_on_container_copy_construction(src.m_alloc_raw))
 
 1453template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1456  m_alloc_raw(std::move(moved_src.m_alloc_raw))
 
 1463template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1466template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1473    if constexpr(S_SHARING)
 
 1479    if constexpr(std::allocator_traits<Allocator_raw>::propagate_on_container_copy_assignment::value)
 
 1546template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1552template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1556  if (
this != &moved_src)
 
 1559    if constexpr(std::allocator_traits<Allocator_raw>::propagate_on_container_move_assignment::value)
 
 1561      m_alloc_raw = std::move(moved_src.m_alloc_raw);
 
 1588    make_zero(logger_ptr); 
 
 1591    swap_impl(moved_src, logger_ptr);
 
 1598template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1601  return assign(std::move(moved_src));
 
 1604template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1615                                      "swapping <=> Blob [" << &other << 
"] (internal buffer sized " 
 1625#pragma GCC diagnostic push 
 1626#pragma GCC diagnostic ignored "-Wpragmas"  
 1627#pragma GCC diagnostic ignored "-Wunknown-warning-option"  
 1628#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 
 1634#pragma GCC diagnostic pop 
 1641template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1647  if constexpr(std::allocator_traits<Allocator_raw>::propagate_on_container_swap::value)
 
 1662  swap_impl(other, logger_ptr);
 
 1665template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1669  return blob1.
swap(blob2, logger_ptr);
 
 1672template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1675  static_assert(S_SHARING,
 
 1676                "Do not invoke (and thus instantiate) share() or derived methods unless you set the S_SHARING_ALLOWED " 
 1677                  "template parameter to true.  Sharing will be enabled at a small perf cost; see class doc header.");
 
 1682  Basic_blob sharing_blob{m_alloc_raw, logger_ptr}; 
 
 1683  assert(!sharing_blob.m_buf_ptr);
 
 1684  sharing_blob.m_buf_ptr = m_buf_ptr;
 
 1686  sharing_blob.m_capacity = m_capacity;
 
 1687  sharing_blob.m_start = m_start;
 
 1688  sharing_blob.m_size = m_size;
 
 1694      (
"Blob [" << 
this << 
"] shared with new Blob [" << &sharing_blob << 
"]; ref-count incremented.");
 
 1697  return sharing_blob;
 
 1700template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1704  if (lt_size > size())
 
 1713                                    "[" << lt_size << 
"] values into that one and leaving the remaining " 
 1714                                    "[" << (size() - lt_size) << 
"] in this one.");
 
 1717  auto sharing_blob = share(logger_ptr); 
 
 1718  sharing_blob.resize(lt_size); 
 
 1719  start_past_prefix_inc(lt_size);
 
 1721  return sharing_blob;
 
 1724template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1728  if (rt_size > size())
 
 1733  const auto lt_size = size() - rt_size;
 
 1738                                    "the last [" << rt_size << 
"] values into that one and leaving the " 
 1739                                    "remaining [" << lt_size << 
"] in this one.");
 
 1742  auto sharing_blob = share(logger_ptr); 
 
 1744  sharing_blob.start_past_prefix_inc(lt_size);
 
 1746  return sharing_blob;
 
 1749template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1750template<
typename Emit_blob_func, 
typename Share_after_split_left_func>
 
 1753        Share_after_split_left_func&& share_after_split_left_func)
 
 1762                                    "adjacent sharing sub-Blobs of size [" << size << 
"] each " 
 1763                                    "(last one possibly smaller).");
 
 1768    emit_blob_func(share_after_split_left_func(size, logger_ptr)); 
 
 1774    make_zero(logger_ptr);
 
 1778template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1779template<
typename Emit_blob_func>
 
 1781                                                                         Emit_blob_func&& emit_blob_func,
 
 1784  share_after_split_equally_impl(size, headless_pool, std::move(emit_blob_func), logger_ptr,
 
 1787    return share_after_split_left(lt_size, logger_ptr);
 
 1791template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1792template<
typename Blob_container>
 
 1798  assert(out_blobs_ptr);
 
 1799  share_after_split_equally(size, headless_pool, [&](
Basic_blob&& blob_moved)
 
 1801    out_blobs_ptr->push_back(std::move(blob_moved));
 
 1805template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1806template<
typename Blob_ptr_container>
 
 1809                                                                                      Blob_ptr_container* out_blobs_ptr,
 
 1815  using Ptr = 
typename Blob_ptr_container::value_type;
 
 1817  assert(out_blobs_ptr);
 
 1819  share_after_split_equally(size, headless_pool, [&](
Basic_blob&& blob_moved)
 
 1821    out_blobs_ptr->push_back(Ptr(
new Basic_blob{std::move(blob_moved)}));
 
 1825template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1829  static_assert(S_SHARING_ALLOWED,
 
 1830                "blobs_sharing() would only make sense on `Basic_blob`s with S_SHARING_ALLOWED=true.  " 
 1831                  "Even if we were to allow this to instantiate (compile) it would always return false.");
 
 1833  return ((!blob1.
zero()) && (!blob2.
zero())) 
 
 1834         && ((&blob1 == &blob2) 
 
 1841template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1844  return zero() ? 0 : m_size; 
 
 1847template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1850  return zero() ? 0 : m_start; 
 
 1853template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1859template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1862  return zero() ? 0 : m_capacity; 
 
 1865template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1871template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 1874  using boost::make_shared_noinit;
 
 1875  using boost::shared_ptr;
 
 1876  using std::numeric_limits;
 
 1880  assert(zero() || ((new_capacity <= m_capacity) && (m_capacity > 0)));
 
 1886  if (zero() && (new_capacity != 0))
 
 1892                                      "allocating internal buffer sized [" << new_capacity << 
"].");
 
 1895    if (new_capacity <= 
size_type(numeric_limits<std::ptrdiff_t>::max())) 
 
 1902      if constexpr(S_IS_VANILLA_ALLOC)
 
 1915        if constexpr(S_SHARING)
 
 1921            m_buf_ptr.reset(
new value_type[new_capacity],
 
 1923                            [logger_ptr, original_blob = 
this, new_capacity]
 
 1927              FLOW_LOG_TRACE(
"Deallocating internal buffer sized [" << new_capacity << 
"] originally allocated by " 
 1928                             "Blob [" << original_blob << 
"]; note that Blob may now be gone and furthermore another " 
 1929                             "Blob might live at that address now.  A message immediately preceding this one should " 
 1930                             "indicate the last Blob to give up ownership of the internal buffer.");
 
 1939            m_buf_ptr = make_shared_noinit<value_type[]>(new_capacity);
 
 1944          m_buf_ptr = boost::movelib::make_unique_definit<value_type[]>(new_capacity);
 
 1953        if constexpr(S_SHARING)
 
 1955          m_buf_ptr.reset(m_alloc_raw.allocate(new_capacity), 
 
 2003          m_buf_ptr.get_deleter() = 
Deleter_raw{m_alloc_raw, new_capacity};
 
 2004          m_buf_ptr.reset(m_alloc_raw.allocate(new_capacity));
 
 2010      assert(
false && 
"Enormous or corrupt new_capacity?!");
 
 2037    m_capacity = new_capacity;
 
 2047  assert(capacity() >= new_capacity); 
 
 2050template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2054  auto& new_start = new_start_or_unchanged;
 
 2055  if (new_start == S_UNCHANGED)
 
 2057    new_start = start();
 
 2060  const size_type min_capacity = new_start + new_size;
 
 2063  assert(min_capacity >= new_size);
 
 2064  assert(min_capacity >= new_start);
 
 2071  reserve(min_capacity, logger_ptr);
 
 2072  assert(capacity() >= min_capacity);
 
 2077    m_start = new_start;
 
 2081  assert(size() == new_size);
 
 2082  assert(start() == new_start);
 
 2085template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2088  resize(((start() + size()) > prefix_size)
 
 2089           ? (start() + size() - prefix_size)
 
 2095template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2098  assert((prefix_size_inc >= 0) || (start() >= 
size_type(-prefix_size_inc)));
 
 2099  start_past_prefix(start() + prefix_size_inc);
 
 2102template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2110template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2120      if constexpr(S_SHARING_ALLOWED)
 
 2123                                        "[" << capacity() << 
"]; deallocation will immediately follow if no sharing " 
 2124                                        "`Blob`s remain; else ref-count merely decremented.");
 
 2129                                        "[" << capacity() << 
"].");
 
 2137template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2150  emplace_copy(const_begin(), src, logger_ptr);
 
 2157template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2166  assert(valid_iterator(dest));
 
 2168  const Iterator dest_it = iterator_sans_const(dest);
 
 2179                                      "memory area [" << 
static_cast<const void*
>(src_data) << 
"] sized " 
 2180                                      "[" << n << 
"] to internal buffer at offset [" << (dest - const_begin()) << 
"].");
 
 2183    assert(derefable_iterator(dest_it)); 
 
 2187    assert(((dest_it + n) <= src_data) || ((src_data + n) <= dest_it));
 
 2201#pragma GCC diagnostic push 
 2202#pragma GCC diagnostic ignored "-Wpragmas"  
 2203#pragma GCC diagnostic ignored "-Wunknown-warning-option"  
 2204#pragma GCC diagnostic ignored "-Wstringop-overflow" 
 2205#pragma GCC diagnostic ignored "-Wrestrict"  
 2211    memcpy(dest_it, src_data, n);
 
 2213#pragma GCC diagnostic pop 
 2219template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2228  assert(valid_iterator(src));
 
 2233    const auto dest_data = 
static_cast<Iterator>(dest.data());
 
 2239                                      "memory area [" << 
static_cast<const void*
>(dest_data) << 
"] sized " 
 2240                                      "[" << n << 
"] from internal buffer offset [" << (src - const_begin()) << 
"].");
 
 2243    assert(derefable_iterator(src));
 
 2246    assert(((src + n) <= dest_data) || ((dest_data + n) <= src));
 
 2249#pragma GCC diagnostic push 
 2250#pragma GCC diagnostic ignored "-Wpragmas"  
 2251#pragma GCC diagnostic ignored "-Wunknown-warning-option"  
 2252#pragma GCC diagnostic ignored "-Wstringop-overflow" 
 2253#pragma GCC diagnostic ignored "-Wrestrict" 
 2254    memcpy(dest_data, src, n);
 
 2255#pragma GCC diagnostic pop 
 2261template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2267  assert(derefable_iterator(first)); 
 
 2268  assert(valid_iterator(past_last)); 
 
 2270  const Iterator dest = iterator_sans_const(first);
 
 2272  if (past_last > first) 
 
 2274    const auto n_moved = 
size_type(const_end() - past_last);
 
 2279#pragma GCC diagnostic push 
 2280#pragma GCC diagnostic ignored "-Wpragmas"  
 2281#pragma GCC diagnostic ignored "-Wunknown-warning-option"  
 2282#pragma GCC diagnostic ignored "-Wstringop-overflow" 
 2283#pragma GCC diagnostic ignored "-Wrestrict" 
 2284      memmove(dest, iterator_sans_const(past_last), n_moved); 
 
 2285#pragma GCC diagnostic pop 
 2289    m_size -= (past_last - first);
 
 2297template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2302  return *const_begin();
 
 2305template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2310  return const_end()[-1];
 
 2313template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2321template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2329template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2333  return const_front();
 
 2336template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2340  return const_back();
 
 2343template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2347  return const_cast<Basic_blob*
>(
this)->begin();
 
 2350template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2370  const auto raw_or_fancy_buf_ptr = m_buf_ptr.get();
 
 2371  return &(*raw_or_fancy_buf_ptr) + m_start;
 
 2374template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2378  return zero() ? const_begin() : (const_begin() + size());
 
 2381template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2385  return zero() ? begin() : (begin() + size());
 
 2388template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2392  return const_begin();
 
 2395template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2399  return const_begin();
 
 2402template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2409template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2416template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2420  return const_begin();
 
 2423template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2430template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2433  return empty() ? (it == const_end())
 
 2437template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2440  return empty() ? false
 
 2444template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2451template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2454  return boost::asio::const_buffer{const_data(), size()};
 
 2457template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2460  return boost::asio::mutable_buffer{data(), size()};
 
 2463template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2470template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2474  m_alloc_raw(std::in_place, alloc_raw),
 
 2480template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
 2488template<
typename Allocator, 
bool S_SHARING_ALLOWED>
 
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
virtual bool should_log(Sev sev, const Component &component) const =0
Given attributes of a hypothetical message that would be logged, return true if that message should b...
Internal deleter functor used if and only if S_IS_VANILLA_ALLOC is false and therefore only with Buf_...
Pointer_raw pointer
For boost::interprocess::shared_ptr and unique_ptr compliance (hence the irregular capitalization).
Deleter_raw()
Default ctor: Must never be invoked; suitable only for a null smart-pointer.
size_type m_buf_sz
See ctor and operator()(): the size of the buffer to deallocate.
std::optional< Allocator_raw > m_alloc_raw
See ctor: the allocator that operator()() shall use to deallocate.
void operator()(Pointer_raw to_delete)
Deallocates using Allocator_raw::deallocate(), passing-in the supplied pointer (to value_type) to_del...
typename std::allocator_traits< Allocator_raw >::pointer Pointer_raw
Short-hand for the allocator's pointer type, pointing to Basic_blob::value_type.
A hand-optimized and API-tweaked replacement for vector<uint8_t>, i.e., buffer of bytes inside an all...
Basic_blob share(log::Logger *logger_ptr=nullptr) const
Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...
Basic_blob & operator=(Basic_blob &&moved_src)
Move assignment operator (no logging): equivalent to assign(std::move(moved_src), nullptr).
bool derefable_iterator(Const_iterator it) const
Returns true if and only if the given iterator points to an element within this blob's size() element...
bool zero() const
Returns false if a buffer is allocated and owned; true otherwise.
Const_iterator begin() const
Equivalent to const_begin().
size_type m_capacity
See capacity(); but m_capacity is meaningless (and containing unknown value) if !m_buf_ptr (i....
boost::asio::mutable_buffer mutable_buffer()
Same as const_buffer() but the returned view is mutable.
void share_after_split_equally(size_type size, bool headless_pool, Emit_blob_func &&emit_blob_func, log::Logger *logger_ptr=nullptr)
Identical to successively performing share_after_split_left(size) until this->empty() == true; the re...
void resize(size_type size, size_type start_or_unchanged=S_UNCHANGED, log::Logger *logger_ptr=nullptr)
Guarantees post-condition size() == size and start() == start; no values in pre-call range [begin(),...
std::conditional_t< S_IS_VANILLA_ALLOC, std::conditional_t< S_SHARING, boost::shared_ptr< value_type[]>, boost::movelib::unique_ptr< value_type[]> >, std::conditional_t< S_SHARING, boost::interprocess::shared_ptr< value_type, Allocator_raw, Deleter_raw >, boost::movelib::unique_ptr< value_type, Deleter_raw > > > Buf_ptr
The smart-pointer type used for m_buf_ptr; a custom-allocator-and-SHM-friendly impl and parameterizat...
Basic_blob(const Basic_blob &src, log::Logger *logger_ptr=nullptr)
Copy constructor, constructing a blob logically equal to src.
void swap(Basic_blob &other, log::Logger *logger_ptr=nullptr)
Swaps the contents of this structure and other, or no-op if this == &other.
value_type const * Const_iterator
Type for iterator pointing into an immutable structure of this type.
value_type * data()
Equivalent to begin().
Buf_ptr m_buf_ptr
Pointer to currently allocated buffer of size m_capacity; null if and only if zero() == true.
Basic_blob(Basic_blob &&moved_src, log::Logger *logger_ptr=nullptr)
Move constructor, constructing a blob exactly internally equal to pre-call moved_src,...
Iterator erase(Const_iterator first, Const_iterator past_last)
Performs the minimal number of operations to make range [begin(), end()) unchanged except for lacking...
size_type assign_copy(const boost::asio::const_buffer &src, log::Logger *logger_ptr=nullptr)
Replaces logical contents with a copy of the given non-overlapping area anywhere in memory.
value_type & back()
Returns reference to mutable last element.
Const_iterator const_iterator
For container compliance (hence the irregular capitalization): Const_iterator type.
std::ptrdiff_t difference_type
Type for difference of size_types.
Iterator end()
Returns pointer one past mutable last element; empty() is possible.
Basic_blob(size_type size, log::Logger *logger_ptr=nullptr, const Allocator_raw &alloc_raw=Allocator_raw{})
Constructs blob with size() and capacity() equal to the given size, and start() == 0.
void clear()
Equivalent to resize(0, start()).
size_type start() const
Returns the offset between begin() and the start of the internally allocated buffer.
Const_iterator cbegin() const
Synonym of const_begin().
static constexpr bool S_SHARING
Value of template parameter S_SHARING_ALLOWED (for generic programming).
Basic_blob share_after_split_left(size_type size, log::Logger *logger_ptr=nullptr)
Applicable to !zero() blobs, this shifts this->begin() by size to the right without changing end(); a...
size_type capacity() const
Returns the number of elements in the internally allocated buffer, which is 1 or more; or 0 if no buf...
value_type & reference
For container compliance (hence the irregular capitalization): reference to element.
Basic_blob & operator=(const Basic_blob &src)
Copy assignment operator (no logging): equivalent to assign(src, nullptr).
bool valid_iterator(Const_iterator it) const
Returns true if and only if: this->derefable_iterator(it) || (it == this->const_end()).
value_type const * const_data() const
Equivalent to const_begin().
static constexpr size_type S_UNCHANGED
Special value indicating an unchanged size_type value; such as in resize().
Basic_blob & assign(Basic_blob &&moved_src, log::Logger *logger_ptr=nullptr)
Move assignment.
bool empty() const
Returns size() == 0.
const value_type & const_back() const
Returns reference to immutable last element.
const value_type & const_reference
For container compliance (hence the irregular capitalization): reference to const element.
size_type size() const
Returns number of elements stored, namely end() - begin().
const value_type & const_front() const
Returns reference to immutable first element.
Iterator emplace_copy(Const_iterator dest, const boost::asio::const_buffer &src, log::Logger *logger_ptr=nullptr)
Copies src buffer directly onto equally sized area within *this at location dest; *this must have suf...
void share_after_split_equally_impl(size_type size, bool headless_pool, Emit_blob_func &&emit_blob_func, log::Logger *logger_ptr, Share_after_split_left_func &&share_after_split_left_func)
Impl of share_after_split_equally() but capable of emitting not just *this type (Basic_blob<....
value_type * Iterator
Type for iterator pointing into a mutable structure of this type.
const value_type & front() const
Equivalent to const_front().
Const_iterator end() const
Equivalent to const_end().
void start_past_prefix_inc(difference_type prefix_size_inc)
Like start_past_prefix() but shifts the current prefix position by the given incremental value (posit...
Iterator iterator_sans_const(Const_iterator it)
Returns iterator-to-mutable equivalent to given iterator-to-immutable.
Iterator begin()
Returns pointer to mutable first element; or end() if empty().
void share_after_split_equally_emit_seq(size_type size, bool headless_pool, Blob_container *out_blobs, log::Logger *logger_ptr=nullptr)
share_after_split_equally() wrapper that places Basic_blobs into the given container via push_back().
Const_iterator sub_copy(Const_iterator src, const boost::asio::mutable_buffer &dest, log::Logger *logger_ptr=nullptr) const
The opposite of emplace_copy() in every way, copying a sub-blob onto a target memory area.
void reserve(size_type capacity, log::Logger *logger_ptr=nullptr)
Ensures that an internal buffer of at least capacity elements is allocated and owned; disallows growi...
size_type m_start
See start(); but m_start is meaningless (and containing unknown value) if !m_buf_ptr (i....
Const_iterator const_pointer
For container compliance (hence the irregular capitalization): pointer to const element.
static constexpr bool S_IS_VANILLA_ALLOC
true if Allocator_raw underlying allocator template is simply std::allocator; false otherwise.
Basic_blob(const Allocator_raw &alloc_raw=Allocator_raw{})
Constructs blob with zero() == true.
value_type & front()
Returns reference to mutable first element.
size_type m_size
See size(); but m_size is meaningless (and containing unknown value) if !m_buf_ptr (i....
const value_type & back() const
Equivalent to const_back().
Const_iterator const_begin() const
Returns pointer to immutable first element; or end() if empty().
Allocator_raw m_alloc_raw
See get_allocator(): copy of the allocator supplied by the user (though, if Allocator_raw is stateles...
void share_after_split_equally_emit_ptr_seq(size_type size, bool headless_pool, Blob_ptr_container *out_blobs, log::Logger *logger_ptr=nullptr)
share_after_split_equally() wrapper that places Ptr<Basic_blob>s into the given container via push_ba...
void make_zero(log::Logger *logger_ptr=nullptr)
Guarantees post-condition zero() == true by dropping *this ownership of the allocated internal buffer...
static constexpr Flow_log_component S_LOG_COMPONENT
Our flow::log::Component.
Const_iterator cend() const
Synonym of const_end().
void swap_impl(Basic_blob &other, log::Logger *logger_ptr)
The body of swap(), except for the part that swaps (or decides not to swap) m_alloc_raw.
Iterator pointer
For container compliance (hence the irregular capitalization): pointer to element.
Allocator Allocator_raw
Short-hand for the allocator type specified at compile-time. Its element type is our value_type.
Const_iterator const_end() const
Returns pointer one past immutable last element; empty() is possible.
Iterator iterator
For container compliance (hence the irregular capitalization): Iterator type.
~Basic_blob()
Destructor that drops *this ownership of the allocated internal buffer if any, as by make_zero(); if ...
uint8_t value_type
Short-hand for values, which in this case are unsigned bytes.
Basic_blob share_after_split_right(size_type size, log::Logger *logger_ptr=nullptr)
Identical to share_after_split_left(), except this->end() shifts by size to the left (instead of this...
Allocator_raw get_allocator() const
Returns a copy of the internally cached Allocator_raw as set by a constructor or assign() or assignme...
void start_past_prefix(size_type prefix_size)
Restructures blob to consist of an internally allocated buffer and a [begin(), end) range starting at...
std::size_t size_type
Type for index into blob or length of blob or sub-blob.
boost::asio::const_buffer const_buffer() const
Convenience accessor returning an immutable boost.asio buffer "view" into the entirety of the blob.
Basic_blob & assign(const Basic_blob &src, log::Logger *logger_ptr=nullptr)
Copy assignment: assuming (this != &src) && (!blobs_sharing(*this, src)), makes *this logically equal...
#define FLOW_LOG_TRACE_WITHOUT_CHECKING(ARG_stream_fragment)
Logs a TRACE message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...
#define FLOW_LOG_SET_CONTEXT(ARG_logger_ptr, ARG_component_payload)
For the rest of the block within which this macro is instantiated, causes all FLOW_LOG_....
#define FLOW_LOG_TRACE(ARG_stream_fragment)
Logs a TRACE message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...
@ S_TRACE
Message indicates any condition that may occur with great frequency (thus verbose if logged).
Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module...
bool in_closed_open_range(T const &min_val, T const &val, T const &max_val)
Returns true if and only if the given value is within the given range, given as a [low,...
void swap(Basic_blob< Allocator, S_SHARING_ALLOWED > &blob1, Basic_blob< Allocator, S_SHARING_ALLOWED > &blob2, log::Logger *logger_ptr)
Equivalent to blob1.swap(blob2).
bool in_closed_range(T const &min_val, T const &val, T const &max_val)
Returns true if and only if the given value is within the given range, inclusive.
bool blobs_sharing(const Basic_blob< Allocator, S_SHARING_ALLOWED > &blob1, const Basic_blob< Allocator, S_SHARING_ALLOWED > &blob2)
Returns true if and only if both given objects are not zero() == true, and they either co-own a commo...
Flow_log_component
The flow::log::Component payload enumeration comprising various log components used by Flow's own int...
unsigned char uint8_t
Byte. Best way to represent a byte of binary data. This is 8 bits on all modern systems.