Flow 1.0.2
Flow project: Full implementation reference.
blob.hpp
Go to the documentation of this file.
1/* Flow
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19#pragma once
20
22
23namespace flow::util
24{
25
26/**
27 * Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Logger,
28 * enabling easier logging albeit with a small perf trade-off. Most users will use the concrete types
29 * #Blob/#Sharing_blob which alias to Blob_with_log_context.
30 *
31 * @see Basic_blob. It supplies the core behavior of Blob_with_log_context. Note that while some APIs are shadowed in
32 * this (non-polymorphic) sub-class and thus documented inside the `class { braces }`, a significant number
33 * are simply inherited: namely the ones that do not log. Typically one would look at Basic_blob
34 * documentation and simply mentally remove any `Logger* logger_ptr` argument from the prototype, knowing
35 * the logging will occur with the log context established at Blob_with_log_context construction.
36 *
37 * In a vague sense Blob_with_log_context is to `Basic_blob<>` what `string` is to `basic_string`, in that it is a
38 * commonly used concrete type rather than a template. However, unlike that analogy, it also adds behavior and data.
39 * Basic_blob accomplishes (optional) logging by means of the user supplying (if desired) a non-null `Logger*`
40 * to each API they want to log. Blob_with_log_context, instead, takes a `Logger*` in any non-move/copy ctor and
41 * uses it for all subsequent logging. Basic_blob uses a little less memory and is a little bit faster, while
42 * Blob_with_log_context (#Blob, #Sharing_blob) is more convenient.
43 *
44 * It is possible, though somewhat exotic, to use any shadowed APIs (that take the `Logger* logger_ptr` optional
45 * arg) from Basic_blob (via cast of `this` to `Basic_blob*` perhaps).
46 *
47 * Lastly, reminder: Basic_blob, and hence Blob_with_log_context, log at TRACE log level or more verbose. If in any
48 * case there is no interest in logging at such a verbose level (checked against log::Logger::should_log() of course)
49 * then using #Blob_sans_log_context or #Sharing_blob_sans_log_context is straightforwardly superior.
50 *
51 * ### Historic note ###
52 * Originally `Blob` was the only class in the hierarchy and (1) could not be used with custom allocators (and was not
53 * SHM-friendly) unlike Basic_blob; and (2) stored a log context from construction unlike Basic_blob.
54 * Then when those 2 changes became required by some use cases, Basic_blob took the vast majority of what used to
55 * be `Blob` and added those 2 changes. Meanwhile `Blob` was rewritten in terms of Basic_blob in a way that
56 * exactly preserved its behavior (so that no call-site changes for Blob-using code were needed).
57 * Lastly, when `S_SHARING_ALLOWED` template param was added to Basic_blob, `Blob` became a template
58 * Blob_with_log_context, while #Blob aliased to `Blob_with_log_context<false>` thus staying functionally
59 * exactly the same as before, minus the share() feature. (`Sharing_blob` was added, aliasing to
60 * `Blob_with_log_context<true>`, being exactly idetical to `Blob` before; the rename was possible due to
61 * no production code using the sharing feature yet.)
62 *
63 * @internal
64 * ### Impl notes ###
65 * It is quite straightforward; we derive from Basic_blob, with `Allocator` set to the default `std::allocator`
66 * (heap alloc) and keep all of its behaviors except shadowing all APIs that take a `Logger*` having the shadows
67 * no longer take that but pass-through the ctor-supplied `Logger*` to the shadowee. As typical we use log::Log_context
68 * to store the necessary context including said `Logger*`. In some cases, also, a Basic_blob API is constrained
69 * (dtor, assignment) to not be able to even take a `Logger*` and therefore cannot log at all; we shadow such APIs
70 * as well and enable logging by judiciously calling something functionally equivalent to the shadowed thing.
71 * (See for example ~Blob_with_log_context() and the assignment operators.)
72 * @endinternal
73 *
74 * @tparam S_SHARING_ALLOWED
75 * See Basic_blob.
76 */
77template<bool S_SHARING_ALLOWED>
79 public log::Log_context,
80 public Basic_blob<std::allocator<uint8_t>, S_SHARING_ALLOWED>
81{
82public:
83 // Types.
84
85 /// Short-hand for our main base.
86 using Base = Basic_blob<std::allocator<uint8_t>, S_SHARING_ALLOWED>;
87
88 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
89 using value_type = typename Base::value_type;
90 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
91 using size_type = typename Base::size_type;
92 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
94 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
95 using Iterator = typename Base::Iterator;
96 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
98 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
100 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
101 using pointer = typename Base::pointer;
102 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
104 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
105 using reference = typename Base::reference;
106 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
108 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
109 using iterator = typename Base::iterator;
110 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
112
113 // Constants.
114
115 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
116 static constexpr auto S_SHARING = Base::S_SHARING;
117
118 /// Short-hand for base member (needed because base access to a template must be qualified otherwise).
119 static constexpr auto S_UNCHANGED = Base::S_UNCHANGED;
120
121 // Constructors/destructor.
122
123 /**
124 * On top of the similar 2-arg Basic_blob ctor, memorizes the given log::Logger for all future logging
125 * in `*this`. (Except, technically, one can subsequently override this by using super-class APIs which take
126 * `Logger*`.)
127 *
128 * @param logger_ptr
129 * The Logger implementation to use subsequently.
130 */
131 Blob_with_log_context(log::Logger* logger_ptr = 0);
132
133 /**
134 * On top of the similar 3-arg Basic_blob ctor, memorizes the given log::Logger for all future logging
135 * in `*this`. (Except, technically, one can subsequently override this by using super-class APIs which take
136 * `Logger*`.)
137 *
138 * @param logger_ptr
139 * The Logger implementation to use subsequently.
140 * @param size
141 * See super-class API.
142 */
143 explicit Blob_with_log_context(log::Logger* logger_ptr, size_type size);
144
145 /**
146 * On top of the similar Basic_blob move ctor, moves the source object's log::Logger for all future logging
147 * in `*this`. (Except, technically, one can subsequently override this by using super-class APIs which take
148 * `Logger*`.)
149 *
150 * @param moved_src
151 * See super-class API.
152 */
154
155 /**
156 * On top of the similar Basic_blob copy ctor, copies the source object's log::Logger for all future logging
157 * in `*this`. (Except, technically, one can subsequently override this by using super-class APIs which take
158 * `Logger*`.)
159 *
160 * @param src
161 * See super-class API.
162 */
163 explicit Blob_with_log_context(const Blob_with_log_context& src);
164
165 /// On top of the similar Basic_blob dtor, adds some possible TRACE-logging.
167
168 // Methods.
169
170 /**
171 * On top of the similar Basic_blob method, logs using the stored log context.
172 *
173 * @note We do not shadow Basic_blob::assign() (move overload), as it would've been identical to the present
174 * operator. In Blob_with_log_context, unlike Basic_blob, there is no need for an extra `logger_ptr` optional
175 * arg.
176 *
177 * @param moved_src
178 * See super-class API.
179 * @return See super-class API.
180 */
182
183 /**
184 * On top of the similar Basic_blob method, logs using the stored log context.
185 *
186 * @note We do not shadow Basic_blob::assign() (copy overload), as it would've been identical to the present
187 * operator. In Blob_with_log_context, unlike Basic_blob, there is no need for an extra `logger_ptr` optional
188 * arg.
189 *
190 * @param src
191 * See super-class API.
192 * @return See super-class API.
193 */
195
196 /**
197 * On top of the similar Basic_blob method, logs using the stored log context.
198 *
199 * @param other
200 * See super-class API.
201 */
202 void swap(Blob_with_log_context& other);
203
204 /**
205 * On top of the similar Basic_blob method, logs using the stored log context and copies it to the returned
206 * object as well.
207 *
208 * @param other
209 * See super-class API.
210 * @return See super-class API.
211 */
213
214 /**
215 * On top of the similar Basic_blob method, logs using the stored log context and copies it to the returned
216 * object as well.
217 *
218 * @param size
219 * See super-class API.
220 * @return See super-class API.
221 */
223
224 /**
225 * On top of the similar Basic_blob method, logs using the stored log context and copies it to the returned
226 * object as well.
227 *
228 * @param size
229 * See super-class API.
230 * @return See super-class API.
231 */
233
234 /**
235 * On top of the similar Basic_blob method, logs using the stored log context and copies it to the emitted
236 * objects as well.
237 *
238 * @tparam Emit_blob_func
239 * See super-class API. However in this version the arg type in the signature is `Blob_with_log_context&&`.
240 * @param size
241 * See super-class API.
242 * @param headless_pool
243 * See super-class API.
244 * @param emit_blob_func
245 * See `Emit_blob_func`.
246 */
247 template<typename Emit_blob_func>
248 void share_after_split_equally(size_type size, bool headless_pool, Emit_blob_func&& emit_blob_func);
249
250 /**
251 * On top of the similar Basic_blob method, logs using the stored log context and copies it to the emitted
252 * objects as well.
253 *
254 * @tparam Blob_container
255 * See super-class API. However in this version the container element type must be Blob_with_log_context.
256 * @param size
257 * See super-class API.
258 * @param headless_pool
259 * See super-class API.
260 * @param out_blobs
261 * See super-class API.
262 */
263 template<typename Blob_container>
264 void share_after_split_equally_emit_seq(size_type size, bool headless_pool, Blob_container* out_blobs);
265
266 /**
267 * On top of the similar Basic_blob method, logs using the stored log context and copes it to the emitted
268 * objects as well.
269 *
270 * @tparam Blob_ptr_container
271 * See super-class API. However in this version the container element pointer's type must be
272 * Blob_with_log_context.
273 * @param size
274 * See super-class API.
275 * @param headless_pool
276 * See super-class API.
277 * @param out_blobs
278 * See super-class API.
279 */
280 template<typename Blob_ptr_container>
281 void share_after_split_equally_emit_ptr_seq(size_type size, bool headless_pool, Blob_ptr_container* out_blobs);
282
283 /**
284 * On top of the similar Basic_blob method, logs using the stored log context.
285 *
286 * @param src
287 * See super-class API.
288 * @return See super-class API.
289 */
290 size_type assign_copy(const boost::asio::const_buffer& src);
291
292 /**
293 * On top of the similar Basic_blob method, logs using the stored log context.
294 *
295 * @param dest
296 * See super-class API.
297 * @param src
298 * See super-class API.
299 * @return See super-class API.
300 */
301 Iterator emplace_copy(Const_iterator dest, const boost::asio::const_buffer& src);
302
303 /**
304 * On top of the similar Basic_blob method, logs using the stored log context.
305 *
306 * @param src
307 * See super-class API.
308 * @param dest
309 * See super-class API.
310 * @return See super-class API.
311 */
312 Const_iterator sub_copy(Const_iterator src, const boost::asio::mutable_buffer& dest) const;
313
314 /**
315 * On top of the similar Basic_blob method, logs using the stored log context.
316 *
317 * @param capacity
318 * See super-class API.
319 */
321
322 /// On top of the similar Basic_blob method, logs using the stored log context.
323 void make_zero();
324
325 /**
326 * On top of the similar Basic_blob method, logs using the stored log context.
327 *
328 * @param size
329 * See super-class API.
330 * @param start_or_unchanged
331 * See super-class API.
332 */
333 void resize(size_type size, size_type start_or_unchanged = S_UNCHANGED);
334
335 // private: There are no added data per se, but there is the added base, log::Log_context, which stores some stuff.
336}; // class Blob_with_log_context
337
338// Free functions: in *_fwd.hpp.
339
340// Template implementations.
341
342template<bool S_SHARING_ALLOWED>
344 log::Log_context(logger_ptr, Base::S_LOG_COMPONENT)
345 // And default-ct Base().
346{
347 // Nothing else.
348}
349
350template<bool S_SHARING_ALLOWED>
352 log::Log_context(logger_ptr, Base::S_LOG_COMPONENT),
353 Base(size, get_logger())
354{
355 // Nothing else.
356}
357
358template<bool S_SHARING_ALLOWED>
360 log::Log_context(static_cast<log::Log_context&&>(std::move(moved_src))),
361 Base(std::move(moved_src), get_logger())
362{
363 // Nothing else.
364}
365
366template<bool S_SHARING_ALLOWED>
368 log::Log_context(static_cast<const log::Log_context&>(src)),
369 Base(src, get_logger())
370{
371 // Nothing else.
372}
373
374template<bool S_SHARING_ALLOWED>
376{
377 /* ~Basic_blob() doesn't log at all -- no way to give a Logger* to it -- but a way to get some potentially
378 * useful logging is to make_zero(). It is redundant (which is why ~Basic_blob() does not bother) but in some
379 * cases usefully logs. */
380 make_zero();
381}
382
383template<bool S_SHARING_ALLOWED>
386{
387 using log::Log_context;
388
389 Log_context::operator=(static_cast<const Log_context&>(src));
390 Base::assign(src, get_logger()); // Yay! We can leverage this to make operator=() log which Basic_blob can't do.
391 return *this;
392}
393
394template<bool S_SHARING_ALLOWED>
397{
398 using log::Log_context;
399
400 Log_context::operator=(static_cast<Log_context&&>(std::move(moved_src)));
401 Base::assign(std::move(moved_src), get_logger()); // Same comment as in copy-assignment above.
402 return *this;
403}
404
405template<bool S_SHARING_ALLOWED>
407{
408 using log::Log_context;
409 using std::swap;
410
411 if (this != &other)
412 {
413 swap(*static_cast<Log_context*>(this), static_cast<Log_context&>(other));
414 Base::swap(other, get_logger()); // Might as well keep this inside the `if` as a micro-optimization.
415 }
416}
417
418template<bool S_SHARING_ALLOWED>
420{
421 return blob1.swap(blob2);
422}
423
424template<bool S_SHARING_ALLOWED>
426{
427 Blob_with_log_context blob(get_logger());
428 static_cast<Base&>(blob) = Base::share(get_logger());
429 return blob;
430}
431
432template<bool S_SHARING_ALLOWED>
435{
436 Blob_with_log_context blob(get_logger());
437 static_cast<Base&>(blob) = Base::share_after_split_left(lt_size, get_logger());
438 return blob;
439}
440
441template<bool S_SHARING_ALLOWED>
444{
445 Blob_with_log_context blob(get_logger());
446 static_cast<Base&>(blob) = Base::share_after_split_right(rt_size, get_logger());
447 return blob;
448}
449
450template<bool S_SHARING_ALLOWED>
451template<typename Emit_blob_func>
453 Emit_blob_func&& emit_blob_func)
454{
455 Base::share_after_split_equally_impl(size, headless_pool, std::move(emit_blob_func), get_logger(),
456 [this](size_type lt_size, [[maybe_unused]] log::Logger* logger_ptr)
458 {
459 assert(logger_ptr == get_logger());
460 return share_after_split_left(lt_size);
461 });
462}
463
464template<bool S_SHARING_ALLOWED>
465template<typename Blob_container>
467 Blob_container* out_blobs_ptr)
468{
469 // Almost copy-pasted from Basic_blob::<same method>(). It's short, though, so it seems fine. @todo Revisit.
470
471 assert(out_blobs_ptr);
472 share_after_split_equally(size, headless_pool, [&](Blob_with_log_context&& blob_moved)
473 {
474 out_blobs_ptr->push_back(std::move(blob_moved));
475 });
476}
477
478template<bool S_SHARING_ALLOWED>
479template<typename Blob_ptr_container>
481 bool headless_pool,
482 Blob_ptr_container* out_blobs_ptr)
483{
484 // Almost copy-pasted from Basic_blob::<same method>(). It's short, though, so it seems fine. @todo Revisit.
485
486 // By documented requirements this should be, like, <...>_ptr<Blob_with_log_context>.
487 using Ptr = typename Blob_ptr_container::value_type;
488
489 assert(out_blobs_ptr);
490
491 share_after_split_equally(size, headless_pool, [&](Blob_with_log_context&& blob_moved)
492 {
493 out_blobs_ptr->push_back(Ptr(new Blob_with_log_context(std::move(blob_moved))));
494 });
495}
496
497template<bool S_SHARING_ALLOWED>
499{
500 Base::reserve(new_capacity, get_logger());
501}
502
503template<bool S_SHARING_ALLOWED>
505{
506 Base::resize(new_size, new_start_or_unchanged, get_logger());
507}
508
509template<bool S_SHARING_ALLOWED>
511{
512 Base::make_zero(get_logger());
513}
514
515template<bool S_SHARING_ALLOWED>
517 Blob_with_log_context<S_SHARING_ALLOWED>::assign_copy(const boost::asio::const_buffer& src)
518{
519 return Base::assign_copy(src, get_logger());
520}
521
522template<bool S_SHARING_ALLOWED>
525{
526 return Base::emplace_copy(dest, src, get_logger());
527}
528
529template<bool S_SHARING_ALLOWED>
531 Blob_with_log_context<S_SHARING_ALLOWED>::sub_copy(Const_iterator src, const boost::asio::mutable_buffer& dest) const
532{
533 return Base::sub_copy(src, dest, get_logger());
534}
535
536} // namespace flow::util
Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...
Definition: log.hpp:1619
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
Definition: log.hpp:1291
A hand-optimized and API-tweaked replacement for vector<uint8_t>, i.e., buffer of bytes inside an all...
Definition: basic_blob.hpp:247
value_type const * Const_iterator
Type for iterator pointing into an immutable structure of this type.
Definition: basic_blob.hpp:264
Const_iterator const_iterator
For container compliance (hence the irregular capitalization): Const_iterator type.
Definition: basic_blob.hpp:282
std::ptrdiff_t difference_type
Type for difference of size_types.
Definition: basic_blob.hpp:258
static constexpr bool S_SHARING
Value of template parameter S_SHARING_ALLOWED (for generic programming).
Definition: basic_blob.hpp:287
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.
Definition: basic_blob.hpp:276
static constexpr size_type S_UNCHANGED
Special value indicating an unchanged size_type value; such as in resize().
Definition: basic_blob.hpp:290
const value_type & const_reference
For container compliance (hence the irregular capitalization): reference to const element.
Definition: basic_blob.hpp:278
size_type size() const
Returns number of elements stored, namely end() - begin().
value_type * Iterator
Type for iterator pointing into a mutable structure of this type.
Definition: basic_blob.hpp:261
Const_iterator const_pointer
For container compliance (hence the irregular capitalization): pointer to const element.
Definition: basic_blob.hpp:274
Iterator pointer
For container compliance (hence the irregular capitalization): pointer to element.
Definition: basic_blob.hpp:272
std::allocator< uint8_t > Allocator_raw
Short-hand for the allocator type specified at compile-time. Its element type is our value_type.
Definition: basic_blob.hpp:267
Iterator iterator
For container compliance (hence the irregular capitalization): Iterator type.
Definition: basic_blob.hpp:280
uint8_t value_type
Short-hand for values, which in this case are unsigned bytes.
Definition: basic_blob.hpp:252
std::size_t size_type
Type for index into blob or length of blob or sub-blob.
Definition: basic_blob.hpp:255
Basic_blob that works in regular heap (and is itself placed in heap or stack) and memorizes a log::Lo...
Definition: blob.hpp:81
Blob_with_log_context share() const
On top of the similar Basic_blob method, logs using the stored log context and copies it to the retur...
Definition: blob.hpp:425
void make_zero()
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:510
typename Base::const_iterator const_iterator
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:111
void reserve(size_type capacity)
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:498
size_type assign_copy(const boost::asio::const_buffer &src)
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:517
typename Base::Allocator_raw Allocator_raw
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:99
void share_after_split_equally(size_type size, bool headless_pool, Emit_blob_func &&emit_blob_func)
On top of the similar Basic_blob method, logs using the stored log context and copies it to the emitt...
Definition: blob.hpp:452
void swap(Blob_with_log_context &other)
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:406
Blob_with_log_context & operator=(Blob_with_log_context &&moved_src)
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:396
Blob_with_log_context(log::Logger *logger_ptr=0)
On top of the similar 2-arg Basic_blob ctor, memorizes the given log::Logger for all future logging i...
Definition: blob.hpp:343
typename Base::difference_type difference_type
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:93
typename Base::iterator iterator
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:109
typename Base::const_pointer const_pointer
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:103
static constexpr auto S_SHARING
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:116
void share_after_split_equally_emit_seq(size_type size, bool headless_pool, Blob_container *out_blobs)
On top of the similar Basic_blob method, logs using the stored log context and copies it to the emitt...
Definition: blob.hpp:466
typename Base::pointer pointer
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:101
Iterator emplace_copy(Const_iterator dest, const boost::asio::const_buffer &src)
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:524
typename Base::Iterator Iterator
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:95
typename Base::const_reference const_reference
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:107
Blob_with_log_context share_after_split_left(size_type size)
On top of the similar Basic_blob method, logs using the stored log context and copies it to the retur...
Definition: blob.hpp:434
static constexpr auto S_UNCHANGED
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:119
void resize(size_type size, size_type start_or_unchanged=S_UNCHANGED)
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:504
typename Base::value_type value_type
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:89
void share_after_split_equally_emit_ptr_seq(size_type size, bool headless_pool, Blob_ptr_container *out_blobs)
On top of the similar Basic_blob method, logs using the stored log context and copes it to the emitte...
Definition: blob.hpp:480
typename Base::Const_iterator Const_iterator
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:97
typename Base::size_type size_type
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:91
Const_iterator sub_copy(Const_iterator src, const boost::asio::mutable_buffer &dest) const
On top of the similar Basic_blob method, logs using the stored log context.
Definition: blob.hpp:531
typename Base::reference reference
Short-hand for base member (needed because base access to a template must be qualified otherwise).
Definition: blob.hpp:105
Blob_with_log_context share_after_split_right(size_type size)
On top of the similar Basic_blob method, logs using the stored log context and copies it to the retur...
Definition: blob.hpp:443
~Blob_with_log_context()
On top of the similar Basic_blob dtor, adds some possible TRACE-logging.
Definition: blob.hpp:375
Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module...
Definition: basic_blob.hpp:29
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).
void swap(Blob_with_log_context< S_SHARING_ALLOWED > &blob1, Blob_with_log_context< S_SHARING_ALLOWED > &blob2)
On top of the similar Basic_blob related function, logs using the stored log context of blob1.
Definition: blob.hpp:419