1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/capy
7  
// Official repository: https://github.com/cppalliance/capy
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_CAPY_BUFFERS_SPAN_HPP
10  
#ifndef BOOST_CAPY_BUFFERS_SPAN_HPP
11  
#define BOOST_CAPY_BUFFERS_SPAN_HPP
11  
#define BOOST_CAPY_BUFFERS_SPAN_HPP
12  

12  

13  
#include <boost/capy/detail/config.hpp>
13  
#include <boost/capy/detail/config.hpp>
14  
#include <boost/capy/buffers.hpp>
14  
#include <boost/capy/buffers.hpp>
15  
#include <span>
15  
#include <span>
16  

16  

17  
namespace boost {
17  
namespace boost {
18  
namespace capy {
18  
namespace capy {
19  

19  

20  
/** Remove bytes from the beginning of a span of const buffers.
20  
/** Remove bytes from the beginning of a span of const buffers.
21  

21  

22  
    Modifies the span and its buffer contents in-place to
22  
    Modifies the span and its buffer contents in-place to
23  
    remove the first `n` bytes.
23  
    remove the first `n` bytes.
24  

24  

25  
    @param bs The span to modify.
25  
    @param bs The span to modify.
26  
    @param n The number of bytes to remove.
26  
    @param n The number of bytes to remove.
27  
*/
27  
*/
28  
inline
28  
inline
29  
void
29  
void
30  
remove_span_prefix(
30  
remove_span_prefix(
31  
    std::span<const_buffer>& bs,
31  
    std::span<const_buffer>& bs,
32  
    std::size_t n) noexcept
32  
    std::size_t n) noexcept
33  
{
33  
{
34  
    while(bs.size() > 0)
34  
    while(bs.size() > 0)
35  
    {
35  
    {
36  
        if(n < bs.front().size())
36  
        if(n < bs.front().size())
37  
        {
37  
        {
38  
            bs.front() += n;
38  
            bs.front() += n;
39  
            return;
39  
            return;
40  
        }
40  
        }
41  
        n -= bs.front().size();
41  
        n -= bs.front().size();
42  
        bs = bs.subspan(1);
42  
        bs = bs.subspan(1);
43  
    }
43  
    }
44  
}
44  
}
45  

45  

46  
/** Remove bytes from the beginning of a span of mutable buffers.
46  
/** Remove bytes from the beginning of a span of mutable buffers.
47  

47  

48  
    Modifies the span and its buffer contents in-place to
48  
    Modifies the span and its buffer contents in-place to
49  
    remove the first `n` bytes.
49  
    remove the first `n` bytes.
50  

50  

51  
    @param bs The span to modify.
51  
    @param bs The span to modify.
52  
    @param n The number of bytes to remove.
52  
    @param n The number of bytes to remove.
53  
*/
53  
*/
54  
inline
54  
inline
55  
void
55  
void
56  
remove_span_prefix(
56  
remove_span_prefix(
57  
    std::span<mutable_buffer>& bs,
57  
    std::span<mutable_buffer>& bs,
58  
    std::size_t n) noexcept
58  
    std::size_t n) noexcept
59  
{
59  
{
60  
    while(bs.size() > 0)
60  
    while(bs.size() > 0)
61  
    {
61  
    {
62  
        if(n < bs.front().size())
62  
        if(n < bs.front().size())
63  
        {
63  
        {
64  
            bs.front() += n;
64  
            bs.front() += n;
65  
            return;
65  
            return;
66  
        }
66  
        }
67  
        n -= bs.front().size();
67  
        n -= bs.front().size();
68  
        bs = bs.subspan(1);
68  
        bs = bs.subspan(1);
69  
    }
69  
    }
70  
}
70  
}
71  

71  

72  
/** Remove bytes from the end of a span of const buffers.
72  
/** Remove bytes from the end of a span of const buffers.
73  

73  

74  
    Modifies the span and its buffer contents in-place to
74  
    Modifies the span and its buffer contents in-place to
75  
    remove the last `n` bytes.
75  
    remove the last `n` bytes.
76  

76  

77  
    @param bs The span to modify.
77  
    @param bs The span to modify.
78  
    @param n The number of bytes to remove.
78  
    @param n The number of bytes to remove.
79  
*/
79  
*/
80  
inline
80  
inline
81  
void
81  
void
82  
remove_span_suffix(
82  
remove_span_suffix(
83  
    std::span<const_buffer>& bs,
83  
    std::span<const_buffer>& bs,
84  
    std::size_t n) noexcept
84  
    std::size_t n) noexcept
85  
{
85  
{
86  
    while(bs.size() > 0)
86  
    while(bs.size() > 0)
87  
    {
87  
    {
88  
        if(n < bs.back().size())
88  
        if(n < bs.back().size())
89  
        {
89  
        {
90  
            auto& b = bs.back();
90  
            auto& b = bs.back();
91  
            b = const_buffer(b.data(), b.size() - n);
91  
            b = const_buffer(b.data(), b.size() - n);
92  
            return;
92  
            return;
93  
        }
93  
        }
94  
        n -= bs.back().size();
94  
        n -= bs.back().size();
95  
        bs = bs.subspan(0, bs.size() - 1);
95  
        bs = bs.subspan(0, bs.size() - 1);
96  
    }
96  
    }
97  
}
97  
}
98  

98  

99  
/** Remove bytes from the end of a span of mutable buffers.
99  
/** Remove bytes from the end of a span of mutable buffers.
100  

100  

101  
    Modifies the span and its buffer contents in-place to
101  
    Modifies the span and its buffer contents in-place to
102  
    remove the last `n` bytes.
102  
    remove the last `n` bytes.
103  

103  

104  
    @param bs The span to modify.
104  
    @param bs The span to modify.
105  
    @param n The number of bytes to remove.
105  
    @param n The number of bytes to remove.
106  
*/
106  
*/
107  
inline
107  
inline
108  
void
108  
void
109  
remove_span_suffix(
109  
remove_span_suffix(
110  
    std::span<mutable_buffer>& bs,
110  
    std::span<mutable_buffer>& bs,
111  
    std::size_t n) noexcept
111  
    std::size_t n) noexcept
112  
{
112  
{
113  
    while(bs.size() > 0)
113  
    while(bs.size() > 0)
114  
    {
114  
    {
115  
        if(n < bs.back().size())
115  
        if(n < bs.back().size())
116  
        {
116  
        {
117  
            auto& b = bs.back();
117  
            auto& b = bs.back();
118  
            b = mutable_buffer(b.data(), b.size() - n);
118  
            b = mutable_buffer(b.data(), b.size() - n);
119  
            return;
119  
            return;
120  
        }
120  
        }
121  
        n -= bs.back().size();
121  
        n -= bs.back().size();
122  
        bs = bs.subspan(0, bs.size() - 1);
122  
        bs = bs.subspan(0, bs.size() - 1);
123  
    }
123  
    }
124  
}
124  
}
125  

125  

126  
/** Keep only the first bytes of a span of const buffers.
126  
/** Keep only the first bytes of a span of const buffers.
127  

127  

128  
    Modifies the span and its buffer contents in-place to
128  
    Modifies the span and its buffer contents in-place to
129  
    keep only the first `n` bytes.
129  
    keep only the first `n` bytes.
130  

130  

131  
    @param bs The span to modify.
131  
    @param bs The span to modify.
132  
    @param n The number of bytes to keep.
132  
    @param n The number of bytes to keep.
133  
*/
133  
*/
134  
inline
134  
inline
135  
void
135  
void
136  
keep_span_prefix(
136  
keep_span_prefix(
137  
    std::span<const_buffer>& bs,
137  
    std::span<const_buffer>& bs,
138  
    std::size_t n) noexcept
138  
    std::size_t n) noexcept
139  
{
139  
{
140  
    auto total = buffer_size(bs);
140  
    auto total = buffer_size(bs);
141  
    if(n < total)
141  
    if(n < total)
142  
        remove_span_suffix(bs, total - n);
142  
        remove_span_suffix(bs, total - n);
143  
}
143  
}
144  

144  

145  
/** Keep only the first bytes of a span of mutable buffers.
145  
/** Keep only the first bytes of a span of mutable buffers.
146  

146  

147  
    Modifies the span and its buffer contents in-place to
147  
    Modifies the span and its buffer contents in-place to
148  
    keep only the first `n` bytes.
148  
    keep only the first `n` bytes.
149  

149  

150  
    @param bs The span to modify.
150  
    @param bs The span to modify.
151  
    @param n The number of bytes to keep.
151  
    @param n The number of bytes to keep.
152  
*/
152  
*/
153  
inline
153  
inline
154  
void
154  
void
155  
keep_span_prefix(
155  
keep_span_prefix(
156  
    std::span<mutable_buffer>& bs,
156  
    std::span<mutable_buffer>& bs,
157  
    std::size_t n) noexcept
157  
    std::size_t n) noexcept
158  
{
158  
{
159  
    auto total = buffer_size(bs);
159  
    auto total = buffer_size(bs);
160  
    if(n < total)
160  
    if(n < total)
161  
        remove_span_suffix(bs, total - n);
161  
        remove_span_suffix(bs, total - n);
162  
}
162  
}
163  

163  

164  
/** Keep only the last bytes of a span of const buffers.
164  
/** Keep only the last bytes of a span of const buffers.
165  

165  

166  
    Modifies the span and its buffer contents in-place to
166  
    Modifies the span and its buffer contents in-place to
167  
    keep only the last `n` bytes.
167  
    keep only the last `n` bytes.
168  

168  

169  
    @param bs The span to modify.
169  
    @param bs The span to modify.
170  
    @param n The number of bytes to keep.
170  
    @param n The number of bytes to keep.
171  
*/
171  
*/
172  
inline
172  
inline
173  
void
173  
void
174  
keep_span_suffix(
174  
keep_span_suffix(
175  
    std::span<const_buffer>& bs,
175  
    std::span<const_buffer>& bs,
176  
    std::size_t n) noexcept
176  
    std::size_t n) noexcept
177  
{
177  
{
178  
    auto total = buffer_size(bs);
178  
    auto total = buffer_size(bs);
179  
    if(n < total)
179  
    if(n < total)
180  
        remove_span_prefix(bs, total - n);
180  
        remove_span_prefix(bs, total - n);
181  
}
181  
}
182  

182  

183  
/** Keep only the last bytes of a span of mutable buffers.
183  
/** Keep only the last bytes of a span of mutable buffers.
184  

184  

185  
    Modifies the span and its buffer contents in-place to
185  
    Modifies the span and its buffer contents in-place to
186  
    keep only the last `n` bytes.
186  
    keep only the last `n` bytes.
187  

187  

188  
    @param bs The span to modify.
188  
    @param bs The span to modify.
189  
    @param n The number of bytes to keep.
189  
    @param n The number of bytes to keep.
190  
*/
190  
*/
191  
inline
191  
inline
192  
void
192  
void
193  
keep_span_suffix(
193  
keep_span_suffix(
194  
    std::span<mutable_buffer>& bs,
194  
    std::span<mutable_buffer>& bs,
195  
    std::size_t n) noexcept
195  
    std::size_t n) noexcept
196  
{
196  
{
197  
    auto total = buffer_size(bs);
197  
    auto total = buffer_size(bs);
198  
    if(n < total)
198  
    if(n < total)
199  
        remove_span_prefix(bs, total - n);
199  
        remove_span_prefix(bs, total - n);
200  
}
200  
}
201  

201  

202  
} // capy
202  
} // capy
203  
} // boost
203  
} // boost
204  

204  

205  
#endif
205  
#endif