Line data Source code
1 : //
2 : // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/buffers
8 : //
9 :
10 : #ifndef BOOST_BUFFERS_MUTABLE_BUFFER_HPP
11 : #define BOOST_BUFFERS_MUTABLE_BUFFER_HPP
12 :
13 : #include <boost/buffers/detail/config.hpp>
14 : #include <boost/buffers/tag_invoke.hpp>
15 : #include <cstddef>
16 : #include <type_traits>
17 :
18 : namespace boost {
19 : namespace buffers {
20 :
21 : /** Holds a buffer that can be modified.
22 : */
23 : class mutable_buffer
24 : {
25 : unsigned char* p_ = nullptr;
26 : std::size_t n_ = 0;
27 :
28 : public:
29 : using value_type = mutable_buffer;
30 : using const_iterator =
31 : value_type const*;
32 :
33 : /** Constructor.
34 : */
35 545 : mutable_buffer() = default;
36 :
37 : /** Constructor.
38 : */
39 : mutable_buffer(
40 : mutable_buffer const&) = default;
41 :
42 : /** Constructor.
43 : */
44 641015 : mutable_buffer(
45 : void* data,
46 : std::size_t size) noexcept
47 641015 : : p_(static_cast<
48 : unsigned char*>(data))
49 641015 : , n_(size)
50 : {
51 641015 : }
52 :
53 : /** Assignment.
54 : */
55 : mutable_buffer& operator=(
56 : mutable_buffer const&) = default;
57 :
58 : // conversion to boost::asio::mutable_buffer
59 : template<
60 : class T
61 : , class = typename std::enable_if<
62 : std::is_constructible<T,
63 : void*, std::size_t>::value
64 : && ! std::is_same<T, mutable_buffer>::value
65 : //&& ! std::is_same<T, const_buffer>::value
66 : >::type
67 : >
68 4 : operator T() const noexcept
69 : {
70 4 : return T{ data(), size() };
71 : }
72 :
73 : void*
74 813742 : data() const noexcept
75 : {
76 813742 : return p_;
77 : }
78 :
79 : std::size_t
80 1695793 : size() const noexcept
81 : {
82 1695793 : return n_;
83 : }
84 :
85 : const_iterator
86 : begin() const noexcept
87 : {
88 : return this;
89 : }
90 :
91 : const_iterator
92 : end() const noexcept
93 : {
94 : return this + 1;
95 : }
96 :
97 : /** Remove a prefix from the buffer.
98 : */
99 : mutable_buffer&
100 827333 : operator+=(std::size_t n) noexcept
101 : {
102 827333 : if(n >= n_)
103 : {
104 23303 : p_ = p_ + n_;
105 23303 : n_ = 0;
106 23303 : return *this;
107 : }
108 804030 : p_ = p_ + n;
109 804030 : n_ -= n;
110 804030 : return *this;
111 : }
112 :
113 : /** Return the buffer with a prefix removed.
114 : */
115 : friend
116 : mutable_buffer
117 827298 : operator+(
118 : mutable_buffer b,
119 : std::size_t n) noexcept
120 : {
121 827298 : return b += n;
122 : }
123 :
124 : /** Return the buffer with a prefix removed.
125 : */
126 : friend
127 : mutable_buffer
128 1 : operator+(
129 : std::size_t n,
130 : mutable_buffer b) noexcept
131 : {
132 1 : return b += n;
133 : }
134 :
135 : friend
136 : mutable_buffer
137 733 : tag_invoke(
138 : prefix_tag const&,
139 : mutable_buffer const& b,
140 : std::size_t n) noexcept
141 : {
142 733 : if(n < b.size())
143 409 : return { b.p_, n };
144 324 : return b;
145 : }
146 :
147 : friend
148 : mutable_buffer
149 733 : tag_invoke(
150 : suffix_tag const&,
151 : mutable_buffer const& b,
152 : std::size_t n) noexcept
153 : {
154 733 : if(n < b.size())
155 287 : return { b.p_ + b.n_ - n, n };
156 446 : return b;
157 : }
158 : };
159 :
160 : } // buffers
161 : } // boost
162 :
163 : #endif
|