Skip to content

Commit e29b762

Browse files
Modernizing, modified comments
1 parent b061058 commit e29b762

File tree

1 file changed

+69
-56
lines changed

1 file changed

+69
-56
lines changed

include/buffer/shared_buffer.hpp

Lines changed: 69 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,56 @@
22
*
33
* ## Overview
44
*
5+
* The @c shared_buffer classes provide byte buffers with internal reference counting.
6+
* These classes can be used within asynchronous IO / networking applications where the
7+
* lifetime of the buffer must be kept alive until a requested IO operation completes.
8+
*
9+
* For example, a network write is started asynchronously, which means a write request
10+
* is started, and the write completion will happen at a later time. The byte buffer
11+
* must be kept alive until the completion notification. Meanwhile multiple other
12+
* write requests can happen simultaneously (even on the same thread). For reads, a
13+
* read request can be started, and the byte buffer used for incoming data will be
14+
* kept alive until a read request completes - i.e. data arrives.
15+
*
16+
* In networking applications, this allows multiple sockets to be performing reads
17+
* and writes under one thread (or multiple threads, such as in a thread pool).
18+
* In particular, it eliminates the (sometimes inefficient) design of "one thread
19+
* per socket".
20+
*
21+
* The Connective C++ Chops Net IP library is an asynchronous networking library (using
22+
* Asio underneath) and it uses @c shared_buffer classes for buffer lifetime management.
23+
*
24+
* There are two concrete classes, @c mutable_shared_buffer and @c const_shared_buffer.
25+
* @c mutable_shared_buffer is a reference counted modifiable buffer class with
26+
* convenience methods for appending data. @c const_shared_buffer is a reference counted
27+
* non-modifiable buffer class. Once the object is constructed, it cannot be modified.
28+
*
29+
* A @c const_shared_buffer can be efficiently constructed (no buffer copies) from a
30+
* @c mutable shared_buffer. This allows the use case of serializing data into a
31+
* @c mutable_shared_buffer then constructing a @c const_shared_buffer for writing to
32+
* the network.
33+
*
34+
* Besides the data buffer lifetime management, these utility classes eliminate data
35+
* copies and (obviously) do not have to be used only in networking use cases.
36+
*
537
* ### Additional Details
638
*
7-
* There are two concrete classes:
8-
- `mutable_shared_buffer`, a reference counted modifiable buffer class with convenience methods for appending data.
9-
- `const_shared_buffer`, a reference counted non-modifiable buffer class. Once the object is constructed, it cannot be modified. This class is used by the Chops Net IP library for asynchronous send buffer processing.
10-
11-
Internally all data is stored in a `std::vector` of `std::byte`. There are ordering methods so that shared buffer objects can be stored in sequential or associative containers.
12-
13-
Efficient moving of data (versus copying) is enabled in multiple ways, including:
14-
- Allowing a `const_shared_buffer` to be move constructed from a `mutable_shared_buffer`.
15-
- Allowing a `std::vector` of `std::byte` to be moved into either shared buffer type.
16-
17-
The implementation is adapted from Chris Kohlhoff's reference counted buffer examples (see [References](references.md)).
18-
* The @c mutable_shared_buffer and @c const_shared_buffer classes provide byte
19-
* buffer classes with internal reference counting. These classes are used within
20-
* the Chops Net IP library to manage data buffer lifetimes. The @c mutable_shared_buffer
21-
* class can be used to construct a data buffer, and then a @c const_shared_buffer can
22-
* be move constructed from the @c mutable_shared_buffer for use with the asynchronous
23-
* library functions (whether Chops Net IP or C++ Networking TS or Asio). A
24-
* @c mutable_shared_buffer can also be constructed by moving a @c std::vector of
25-
* @c std:;bytes into it.
39+
* Internally all data is stored in a @c std::vector of @c std::byte. There are
40+
* convenience templated constructors so that the @c shared_buffer objects can
41+
* be constructed from traditional byte buffers, such as @c char @c *.
2642
*
27-
* Besides the data buffer lifetime management, these utility classes eliminate data
28-
* buffer copies.
43+
* There are ordering methods so that shared buffer objects can be stored in
44+
* sequential or associative containers.
45+
*
46+
* Efficient moving of data (versus copying) is enabled in multiple ways, including
47+
* allowing a @c const_shared_buffer to be move constructed from a
48+
* @c mutable_shared_buffer, and allowing a @c std::vector of @c std::byte to be moved
49+
* into either @c shared_buffer type.
2950
*
30-
* This code is based on and modified from Chris Kohlhoff's Asio example code. It has
31-
* been significantly modified by adding a @c mutable_shared_buffer class as well as
32-
* adding convenience methods to the @c const_shared_buffer class.
51+
* The implementation is adapted from Chris Kohlhoff's reference counted buffer
52+
* examples in the Asio library. It has been significantly modified by adding a
53+
* @c mutable_shared_buffer class as well as adding convenience methods to the
54+
* @c const_shared_buffer class.
3355
*
3456
* It is likely that this shared buffer design and code will change as the C++
3557
* Networking TS buffer features are expanded, changed, or better understood. Currently
@@ -67,7 +89,7 @@ class const_shared_buffer;
6789

6890
/**
6991
* @brief A mutable (modifiable) byte buffer class with convenience methods, internally
70-
* reference-counted for efficient copying.
92+
* reference-counted for efficient copying and lifetime management.
7193
*
7294
* This class provides ownership, copying, and lifetime management for byte oriented
7395
* buffers. In particular, it is designed to be used in conjunction with the
@@ -76,7 +98,7 @@ class const_shared_buffer;
7698
* a reference counted buffer can be passed among multiple layers of software without
7799
* any one layer "owning" the buffer.
78100
*
79-
* A std::byte pointer returned by the @c data method may be invalidated if the
101+
* A @c std::byte pointer returned by the @c data method may be invalidated if the
80102
* @c mutable_shared_buffer is modified in any way (this follows the usual constraints
81103
* on @c std::vector iterator invalidation).
82104
*
@@ -130,6 +152,9 @@ class mutable_shared_buffer {
130152
mutable_shared_buffer(size_type(0)) {
131153
*m_data = std::move(bv);
132154
}
155+
// Add constrained templated constructor for std::vector of any valid byte type,
156+
// specially char *; will need to use reinterpret_cast constructor of
157+
// std::shared_ptr
133158
/**
134159
* @brief Construct a @c mutable_shared_buffer with an initial size, contents
135160
* set to zero.
@@ -156,6 +181,7 @@ class mutable_shared_buffer {
156181
mutable_shared_buffer(const std::byte* buf, size_type sz) :
157182
m_data(std::make_shared<byte_vec>(buf, buf+sz)) { }
158183

184+
// Add std::span constructors, maybe remove above constructor and add example
159185
/**
160186
* @brief Construct by copying bytes from an arbitrary pointer.
161187
*
@@ -348,7 +374,7 @@ class mutable_shared_buffer {
348374
* @return @c true if @c size() same for each, and each byte compares @c true.
349375
*/
350376
bool operator== (const mutable_shared_buffer& rhs) noexcept {
351-
return *m_data == *(rhs.m_data);
377+
return *m_data == *rhs.m_data;
352378
}
353379

354380
/**
@@ -362,7 +388,7 @@ class mutable_shared_buffer {
362388
*
363389
*/
364390
auto operator<=>(const mutable_shared_buffer& rhs) noexcept {
365-
return *m_data <=> *(rhs.m_data);
391+
return *m_data <=> *rhs.m_data;
366392
}
367393

368394
}; // end mutable_shared_buffer class
@@ -402,9 +428,6 @@ class const_shared_buffer {
402428

403429
private:
404430

405-
friend bool operator==(const const_shared_buffer&, const const_shared_buffer&) noexcept;
406-
friend bool operator<(const const_shared_buffer&, const const_shared_buffer&) noexcept;
407-
408431
friend bool operator==(const mutable_shared_buffer&, const const_shared_buffer&) noexcept;
409432
friend bool operator==(const const_shared_buffer&, const mutable_shared_buffer&) noexcept;
410433

@@ -527,9 +550,6 @@ class const_shared_buffer {
527550
*/
528551
bool empty() const noexcept { return (*m_data).empty(); }
529552

530-
}; // end const_shared_buffer class
531-
532-
// non-member functions
533553
/**
534554
* @brief Compare two @c const_shared_buffer objects for internal buffer
535555
* byte-by-byte equality.
@@ -540,33 +560,26 @@ class const_shared_buffer {
540560
* @return @c true if @c size() same for each, and each byte compares @c true.
541561
*
542562
*/
543-
inline bool operator== (const const_shared_buffer& lhs, const const_shared_buffer& rhs) noexcept {
544-
return *(lhs.m_data) == *(rhs.m_data);
545-
}
546-
547-
/**
548-
* @brief Compare two @c const_shared_buffer objects for inequality.
549-
*
550-
* @return Opposite of @c operator==.
551-
*
552-
*/
553-
inline bool operator!= (const const_shared_buffer& lhs, const const_shared_buffer& rhs) noexcept {
554-
return !(lhs == rhs);
555-
}
556-
563+
bool operator== (const const_shared_buffer& rhs) noexcept {
564+
return *m_data == *rhs.m_data;
565+
}
557566
/**
558567
* @brief Compare two @c const_shared_buffer objects for internal buffer
559-
* byte-by-byte less-than ordering.
568+
* byte-by-byte spaceship operator ordering.
560569
*
561-
* Internally this invokes the @c std::vector @c operator< on @c std::byte
570+
* Internally this invokes the @c std::vector @c <=> on @c std::byte
562571
* elements.
563572
*
564-
* @return @c true if internal buffer of left is less than internal buffer of right.
573+
* @return Spaceship operator comparison result.
565574
*
566575
*/
567-
inline bool operator< (const const_shared_buffer& lhs, const const_shared_buffer& rhs) noexcept {
568-
return *(lhs.m_data) < *(rhs.m_data);
569-
}
576+
bool operator<=> (const const_shared_buffer& lhs, const const_shared_buffer& rhs) noexcept {
577+
return *m_data <=> *rhs.m_data;
578+
}
579+
580+
}; // end const_shared_buffer class
581+
582+
// non-member functions
570583

571584
/**
572585
* @brief Compare a @c const_shared_buffer object with a @c mutable_shared_buffer for
@@ -575,7 +588,7 @@ inline bool operator< (const const_shared_buffer& lhs, const const_shared_buffer
575588
* @return @c true if @c size() same for each, and each byte compares @c true.
576589
*/
577590
inline bool operator== (const const_shared_buffer& lhs, const mutable_shared_buffer& rhs) noexcept {
578-
return *(lhs.m_data) == *(rhs.m_data);
591+
return *lhs.m_data == *rhs.m_data;
579592
}
580593

581594
/**
@@ -585,7 +598,7 @@ inline bool operator== (const const_shared_buffer& lhs, const mutable_shared_buf
585598
* @return @c true if @c size() same for each, and each byte compares @c true.
586599
*/
587600
inline bool operator== (const mutable_shared_buffer& lhs, const const_shared_buffer& rhs) noexcept {
588-
return *(lhs.m_data) == *(rhs.m_data);
601+
return *lhs.m_data == *rhs.m_data;
589602
}
590603

591604
} // end namespace

0 commit comments

Comments
 (0)