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>>;
642 template<
typename Emit_blob_func>
661 template<
typename Blob_container>
682 template<
typename Blob_ptr_container>
1136 template<
typename Emit_blob_func,
typename Share_after_split_left_func>
1138 Emit_blob_func&& emit_blob_func,
1140 Share_after_split_left_func&& share_after_split_left_func);
1175 using Pointer_raw =
typename std::allocator_traits<Allocator_raw>::pointer;
1320 boost::shared_ptr<value_type[]>,
1321 boost::movelib::unique_ptr<value_type[]>>,
1323 boost::interprocess::shared_ptr
1325 boost::movelib::unique_ptr<value_type, Deleter_raw>>>;
1423template<
typename Allocator,
bool S_SHARING_ALLOWED>
1425 m_alloc_raw(alloc_raw)
1430template<
typename Allocator,
bool S_SHARING_ALLOWED>
1439template<
typename Allocator,
bool S_SHARING_ALLOWED>
1442 m_alloc_raw(std::allocator_traits<
Allocator_raw>::select_on_container_copy_construction(src.m_alloc_raw))
1452template<
typename Allocator,
bool S_SHARING_ALLOWED>
1455 m_alloc_raw(std::move(moved_src.m_alloc_raw))
1462template<
typename Allocator,
bool S_SHARING_ALLOWED>
1465template<
typename Allocator,
bool S_SHARING_ALLOWED>
1472 if constexpr(S_SHARING)
1478 if constexpr(std::allocator_traits<Allocator_raw>::propagate_on_container_copy_assignment::value)
1545template<
typename Allocator,
bool S_SHARING_ALLOWED>
1551template<
typename Allocator,
bool S_SHARING_ALLOWED>
1555 if (
this != &moved_src)
1558 if constexpr(std::allocator_traits<Allocator_raw>::propagate_on_container_move_assignment::value)
1560 m_alloc_raw = std::move(moved_src.m_alloc_raw);
1587 make_zero(logger_ptr);
1590 swap_impl(moved_src, logger_ptr);
1597template<
typename Allocator,
bool S_SHARING_ALLOWED>
1600 return assign(std::move(moved_src));
1603template<
typename Allocator,
bool S_SHARING_ALLOWED>
1614 "swapping <=> Blob [" << &other <<
"] (internal buffer sized "
1624#pragma GCC diagnostic push
1625#pragma GCC diagnostic ignored "-Wpragmas"
1626#pragma GCC diagnostic ignored "-Wunknown-warning-option"
1627#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
1633#pragma GCC diagnostic pop
1640template<
typename Allocator,
bool S_SHARING_ALLOWED>
1646 if constexpr(std::allocator_traits<Allocator_raw>::propagate_on_container_swap::value)
1661 swap_impl(other, logger_ptr);
1664template<
typename Allocator,
bool S_SHARING_ALLOWED>
1668 return blob1.
swap(blob2, logger_ptr);
1671template<
typename Allocator,
bool S_SHARING_ALLOWED>
1674 static_assert(S_SHARING,
1675 "Do not invoke (and thus instantiate) share() or derived methods unless you set the S_SHARING_ALLOWED "
1676 "template parameter to true. Sharing will be enabled at a small perf cost; see class doc header.");
1681 Basic_blob sharing_blob(m_alloc_raw, logger_ptr);
1686 sharing_blob.
m_start = m_start;
1687 sharing_blob.
m_size = m_size;
1693 (
"Blob [" <<
this <<
"] shared with new Blob [" << &sharing_blob <<
"]; ref-count incremented.");
1696 return sharing_blob;
1699template<
typename Allocator,
bool S_SHARING_ALLOWED>
1703 if (lt_size > size())
1712 "[" << lt_size <<
"] values into that one and leaving the remaining "
1713 "[" << (size() - lt_size) <<
"] in this one.");
1716 auto sharing_blob = share(logger_ptr);
1717 sharing_blob.resize(lt_size);
1718 start_past_prefix_inc(lt_size);
1720 return sharing_blob;
1723template<
typename Allocator,
bool S_SHARING_ALLOWED>
1727 if (rt_size > size())
1732 const auto lt_size = size() - rt_size;
1737 "the last [" << rt_size <<
"] values into that one and leaving the "
1738 "remaining [" << lt_size <<
"] in this one.");
1741 auto sharing_blob = share(logger_ptr);
1743 sharing_blob.start_past_prefix_inc(lt_size);
1745 return sharing_blob;
1748template<
typename Allocator,
bool S_SHARING_ALLOWED>
1749template<
typename Emit_blob_func,
typename Share_after_split_left_func>
1752 Share_after_split_left_func&& share_after_split_left_func)
1761 "adjacent sharing sub-Blobs of size [" << size <<
"] each "
1762 "(last one possibly smaller).");
1767 emit_blob_func(share_after_split_left_func(size, logger_ptr));
1773 make_zero(logger_ptr);
1777template<
typename Allocator,
bool S_SHARING_ALLOWED>
1778template<
typename Emit_blob_func>
1780 Emit_blob_func&& emit_blob_func,
1783 share_after_split_equally_impl(size, headless_pool, std::move(emit_blob_func), logger_ptr,
1786 return share_after_split_left(lt_size, logger_ptr);
1790template<
typename Allocator,
bool S_SHARING_ALLOWED>
1791template<
typename Blob_container>
1797 assert(out_blobs_ptr);
1798 share_after_split_equally(size, headless_pool, [&](
Basic_blob&& blob_moved)
1800 out_blobs_ptr->push_back(std::move(blob_moved));
1804template<
typename Allocator,
bool S_SHARING_ALLOWED>
1805template<
typename Blob_ptr_container>
1808 Blob_ptr_container* out_blobs_ptr,
1814 using Ptr =
typename Blob_ptr_container::value_type;
1816 assert(out_blobs_ptr);
1818 share_after_split_equally(size, headless_pool, [&](
Basic_blob&& blob_moved)
1820 out_blobs_ptr->push_back(Ptr(
new Basic_blob(std::move(blob_moved))));
1824template<
typename Allocator,
bool S_SHARING_ALLOWED>
1828 static_assert(S_SHARING_ALLOWED,
1829 "blobs_sharing() would only make sense on `Basic_blob`s with S_SHARING_ALLOWED=true. "
1830 "Even if we were to allow this to instantiate (compile) it would always return false.");
1832 return ((!blob1.
zero()) && (!blob2.
zero()))
1833 && ((&blob1 == &blob2)
1840template<
typename Allocator,
bool S_SHARING_ALLOWED>
1843 return zero() ? 0 : m_size;
1846template<
typename Allocator,
bool S_SHARING_ALLOWED>
1849 return zero() ? 0 : m_start;
1852template<
typename Allocator,
bool S_SHARING_ALLOWED>
1858template<
typename Allocator,
bool S_SHARING_ALLOWED>
1861 return zero() ? 0 : m_capacity;
1864template<
typename Allocator,
bool S_SHARING_ALLOWED>
1870template<
typename Allocator,
bool S_SHARING_ALLOWED>
1873 using boost::make_shared_noinit;
1874 using boost::shared_ptr;
1875 using std::numeric_limits;
1879 assert(zero() || ((new_capacity <= m_capacity) && (m_capacity > 0)));
1885 if (zero() && (new_capacity != 0))
1891 "allocating internal buffer sized [" << new_capacity <<
"].");
1894 if (new_capacity <=
size_type(numeric_limits<std::ptrdiff_t>::max()))
1901 if constexpr(S_IS_VANILLA_ALLOC)
1914 if constexpr(S_SHARING)
1920 m_buf_ptr.reset(
new value_type[new_capacity],
1922 [logger_ptr, original_blob =
this, new_capacity]
1926 FLOW_LOG_TRACE(
"Deallocating internal buffer sized [" << new_capacity <<
"] originally allocated by "
1927 "Blob [" << original_blob <<
"]; note that Blob may now be gone and furthermore another "
1928 "Blob might live at that address now. A message immediately preceding this one should "
1929 "indicate the last Blob to give up ownership of the internal buffer.");
1938 m_buf_ptr = make_shared_noinit<value_type[]>(new_capacity);
1943 m_buf_ptr = boost::movelib::make_unique_definit<value_type[]>(new_capacity);
1952 if constexpr(S_SHARING)
1954 m_buf_ptr.reset(m_alloc_raw.allocate(new_capacity),
2002 m_buf_ptr.get_deleter() =
Deleter_raw(m_alloc_raw, new_capacity);
2003 m_buf_ptr.reset(m_alloc_raw.allocate(new_capacity));
2009 assert(
false &&
"Enormous or corrupt new_capacity?!");
2036 m_capacity = new_capacity;
2046 assert(capacity() >= new_capacity);
2049template<
typename Allocator,
bool S_SHARING_ALLOWED>
2053 auto& new_start = new_start_or_unchanged;
2054 if (new_start == S_UNCHANGED)
2056 new_start = start();
2059 const size_type min_capacity = new_start + new_size;
2062 assert(min_capacity >= new_size);
2063 assert(min_capacity >= new_start);
2070 reserve(min_capacity, logger_ptr);
2071 assert(capacity() >= min_capacity);
2076 m_start = new_start;
2080 assert(size() == new_size);
2081 assert(start() == new_start);
2084template<
typename Allocator,
bool S_SHARING_ALLOWED>
2087 resize(((start() + size()) > prefix_size)
2088 ? (start() + size() - prefix_size)
2094template<
typename Allocator,
bool S_SHARING_ALLOWED>
2097 assert((prefix_size_inc >= 0) || (start() >=
size_type(-prefix_size_inc)));
2098 start_past_prefix(start() + prefix_size_inc);
2101template<
typename Allocator,
bool S_SHARING_ALLOWED>
2109template<
typename Allocator,
bool S_SHARING_ALLOWED>
2119 if constexpr(S_SHARING_ALLOWED)
2122 "[" << capacity() <<
"]; deallocation will immediately follow if no sharing "
2123 "`Blob`s remain; else ref-count merely decremented.");
2128 "[" << capacity() <<
"].");
2136template<
typename Allocator,
bool S_SHARING_ALLOWED>
2149 emplace_copy(const_begin(), src, logger_ptr);
2156template<
typename Allocator,
bool S_SHARING_ALLOWED>
2165 assert(valid_iterator(dest));
2167 const Iterator dest_it = iterator_sans_const(dest);
2178 "memory area [" <<
static_cast<const void*
>(src_data) <<
"] sized "
2179 "[" << n <<
"] to internal buffer at offset [" << (dest - const_begin()) <<
"].");
2182 assert(derefable_iterator(dest_it));
2186 assert(((dest_it + n) <= src_data) || ((src_data + n) <= dest_it));
2200#pragma GCC diagnostic push
2201#pragma GCC diagnostic ignored "-Wpragmas"
2202#pragma GCC diagnostic ignored "-Wunknown-warning-option"
2203#pragma GCC diagnostic ignored "-Wstringop-overflow"
2204#pragma GCC diagnostic ignored "-Wrestrict"
2210 memcpy(dest_it, src_data, n);
2212#pragma GCC diagnostic pop
2218template<
typename Allocator,
bool S_SHARING_ALLOWED>
2227 assert(valid_iterator(src));
2232 const auto dest_data =
static_cast<Iterator>(dest.data());
2238 "memory area [" <<
static_cast<const void*
>(dest_data) <<
"] sized "
2239 "[" << n <<
"] from internal buffer offset [" << (src - const_begin()) <<
"].");
2242 assert(derefable_iterator(src));
2245 assert(((src + n) <= dest_data) || ((dest_data + n) <= src));
2248#pragma GCC diagnostic push
2249#pragma GCC diagnostic ignored "-Wpragmas"
2250#pragma GCC diagnostic ignored "-Wunknown-warning-option"
2251#pragma GCC diagnostic ignored "-Wstringop-overflow"
2252#pragma GCC diagnostic ignored "-Wrestrict"
2253 memcpy(dest_data, src, n);
2254#pragma GCC diagnostic pop
2260template<
typename Allocator,
bool S_SHARING_ALLOWED>
2266 assert(derefable_iterator(first));
2267 assert(valid_iterator(past_last));
2269 const Iterator dest = iterator_sans_const(first);
2271 if (past_last > first)
2273 const auto n_moved =
size_type(const_end() - past_last);
2278#pragma GCC diagnostic push
2279#pragma GCC diagnostic ignored "-Wpragmas"
2280#pragma GCC diagnostic ignored "-Wunknown-warning-option"
2281#pragma GCC diagnostic ignored "-Wstringop-overflow"
2282#pragma GCC diagnostic ignored "-Wrestrict"
2283 memmove(dest, iterator_sans_const(past_last), n_moved);
2284#pragma GCC diagnostic pop
2288 m_size -= (past_last - first);
2296template<
typename Allocator,
bool S_SHARING_ALLOWED>
2301 return *const_begin();
2304template<
typename Allocator,
bool S_SHARING_ALLOWED>
2309 return const_end()[-1];
2312template<
typename Allocator,
bool S_SHARING_ALLOWED>
2320template<
typename Allocator,
bool S_SHARING_ALLOWED>
2328template<
typename Allocator,
bool S_SHARING_ALLOWED>
2332 return const_front();
2335template<
typename Allocator,
bool S_SHARING_ALLOWED>
2339 return const_back();
2342template<
typename Allocator,
bool S_SHARING_ALLOWED>
2346 return const_cast<Basic_blob*
>(
this)->begin();
2349template<
typename Allocator,
bool S_SHARING_ALLOWED>
2369 const auto raw_or_fancy_buf_ptr = m_buf_ptr.get();
2370 return &(*raw_or_fancy_buf_ptr) + m_start;
2373template<
typename Allocator,
bool S_SHARING_ALLOWED>
2377 return zero() ? const_begin() : (const_begin() + size());
2380template<
typename Allocator,
bool S_SHARING_ALLOWED>
2384 return zero() ? begin() : (begin() + size());
2387template<
typename Allocator,
bool S_SHARING_ALLOWED>
2391 return const_begin();
2394template<
typename Allocator,
bool S_SHARING_ALLOWED>
2398 return const_begin();
2401template<
typename Allocator,
bool S_SHARING_ALLOWED>
2408template<
typename Allocator,
bool S_SHARING_ALLOWED>
2415template<
typename Allocator,
bool S_SHARING_ALLOWED>
2419 return const_begin();
2422template<
typename Allocator,
bool S_SHARING_ALLOWED>
2429template<
typename Allocator,
bool S_SHARING_ALLOWED>
2432 return empty() ? (it == const_end())
2436template<
typename Allocator,
bool S_SHARING_ALLOWED>
2439 return empty() ? false
2443template<
typename Allocator,
bool S_SHARING_ALLOWED>
2450template<
typename Allocator,
bool S_SHARING_ALLOWED>
2453 using boost::asio::const_buffer;
2454 return const_buffer(const_data(), size());
2457template<
typename Allocator,
bool S_SHARING_ALLOWED>
2460 using boost::asio::mutable_buffer;
2461 return mutable_buffer(data(), size());
2464template<
typename Allocator,
bool S_SHARING_ALLOWED>
2471template<
typename Allocator,
bool S_SHARING_ALLOWED>
2475 m_alloc_raw(std::in_place, alloc_raw),
2481template<
typename Allocator,
bool S_SHARING_ALLOWED>
2489template<
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(Basic_blob &&moved_src, log::Logger *logger_ptr=0)
Move constructor, constructing a blob exactly internally equal to pre-call moved_src,...
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....
void resize(size_type size, size_type start_or_unchanged=S_UNCHANGED, log::Logger *logger_ptr=0)
Guarantees post-condition size() == size and start() == start; no values in pre-call range [begin(),...
boost::asio::mutable_buffer mutable_buffer()
Same as const_buffer() but the returned view is mutable.
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...
void reserve(size_type capacity, log::Logger *logger_ptr=0)
Ensures that an internal buffer of at least capacity elements is allocated and owned; disallows growi...
Basic_blob & assign(Basic_blob &&moved_src, log::Logger *logger_ptr=0)
Move assignment.
Iterator emplace_copy(Const_iterator dest, const boost::asio::const_buffer &src, log::Logger *logger_ptr=0)
Copies src buffer directly onto equally sized area within *this at location dest; *this must have suf...
value_type const * Const_iterator
Type for iterator pointing into an immutable structure of this type.
Basic_blob share_after_split_left(size_type size, log::Logger *logger_ptr=0)
Applicable to !zero() blobs, this shifts this->begin() by size to the right without changing end(); a...
size_type assign_copy(const boost::asio::const_buffer &src, log::Logger *logger_ptr=0)
Replaces logical contents with a copy of the given non-overlapping area anywhere in memory.
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.
Iterator erase(Const_iterator first, Const_iterator past_last)
Performs the minimal number of operations to make range [begin(), end()) unchanged except for lacking...
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.
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).
void swap_impl(Basic_blob &other, log::Logger *logger_ptr=0)
The body of swap(), except for the part that swaps (or decides not to swap) m_alloc_raw.
Basic_blob share(log::Logger *logger_ptr=0) const
Applicable to !zero() blobs, this returns an identical Basic_blob that shares (co-owns) *this allocat...
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(size_type size, log::Logger *logger_ptr=0, const Allocator_raw &alloc_raw=Allocator_raw())
Constructs blob with size() and capacity() equal to the given size, and start() == 0.
bool empty() const
Returns size() == 0.
const value_type & const_back() const
Returns reference to immutable last element.
Basic_blob(const Basic_blob &src, log::Logger *logger_ptr=0)
Copy constructor, constructing a blob logically equal to src.
void swap(Basic_blob &other, log::Logger *logger_ptr=0)
Swaps the contents of this structure and other, or no-op if this == &other.
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.
void share_after_split_equally_emit_ptr_seq(size_type size, bool headless_pool, Blob_ptr_container *out_blobs, log::Logger *logger_ptr=0)
share_after_split_equally() wrapper that places Ptr<Basic_blob>s into the given container via push_ba...
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().
Const_iterator sub_copy(Const_iterator src, const boost::asio::mutable_buffer &dest, log::Logger *logger_ptr=0) const
The opposite of emplace_copy() in every way, copying a sub-blob onto a target memory area.
Basic_blob share_after_split_right(size_type size, log::Logger *logger_ptr=0)
Identical to share_after_split_left(), except this->end() shifts by size to the left (instead of this...
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.
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...
static constexpr Flow_log_component S_LOG_COMPONENT
Our flow::log::Component.
Const_iterator cend() const
Synonym of const_end().
void share_after_split_equally(size_type size, bool headless_pool, Emit_blob_func &&emit_blob_func, log::Logger *logger_ptr=0)
Identical to successively performing share_after_split_left(size) until this->empty() == true; the re...
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.
void share_after_split_equally_emit_seq(size_type size, bool headless_pool, Blob_container *out_blobs, log::Logger *logger_ptr=0)
share_after_split_equally() wrapper that places Basic_blobs into the given container via push_back().
Iterator iterator
For container compliance (hence the irregular capitalization): Iterator type.
Basic_blob(const Allocator_raw &alloc_raw=Allocator_raw())
Constructs blob with zero() == true.
~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.
Allocator_raw get_allocator() const
Returns a copy of the internally cached Allocator_raw as set by a constructor or assign() or assignme...
void make_zero(log::Logger *logger_ptr=0)
Guarantees post-condition zero() == true by dropping *this ownership of the allocated internal buffer...
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=0)
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.