Line data Source code
1 : //
2 : // Copyright (c) 2025 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/capy
8 : //
9 :
10 : #include <boost/capy/buffers/buffer_array.hpp>
11 :
12 : namespace boost {
13 : namespace capy {
14 : namespace detail {
15 :
16 : namespace {
17 :
18 : template<class Buffer>
19 : void
20 1024 : do_remove_prefix(
21 : Buffer* arr,
22 : std::size_t* count,
23 : std::size_t* total_size,
24 : std::size_t n) noexcept
25 : {
26 1024 : if(n >= *total_size)
27 : {
28 276 : while(*count > 0)
29 180 : arr[--(*count)].~Buffer();
30 96 : *total_size = 0;
31 96 : return;
32 : }
33 :
34 928 : std::size_t i = 0;
35 1348 : while(i < *count && n > 0)
36 : {
37 1260 : auto& b = arr[i];
38 1260 : if(n < b.size())
39 : {
40 840 : b += n;
41 840 : *total_size -= n;
42 840 : break;
43 : }
44 420 : n -= b.size();
45 420 : *total_size -= b.size();
46 420 : b.~Buffer();
47 420 : ++i;
48 : }
49 :
50 : // Compact: move remaining buffers to front
51 928 : if(i > 0)
52 : {
53 420 : std::size_t j = 0;
54 840 : while(i < *count)
55 : {
56 420 : arr[j] = arr[i];
57 420 : arr[i].~Buffer();
58 420 : ++i;
59 420 : ++j;
60 : }
61 420 : *count = j;
62 : }
63 : }
64 :
65 : template<class Buffer>
66 : void
67 1056 : do_keep_prefix(
68 : Buffer* arr,
69 : std::size_t* count,
70 : std::size_t* total_size,
71 : std::size_t n) noexcept
72 : {
73 1056 : if(n >= *total_size)
74 64 : return;
75 :
76 992 : if(n == 0)
77 : {
78 276 : while(*count > 0)
79 180 : arr[--(*count)].~Buffer();
80 96 : *total_size = 0;
81 96 : return;
82 : }
83 :
84 896 : std::size_t remaining = n;
85 896 : std::size_t i = 0;
86 1316 : while(i < *count && remaining > 0)
87 : {
88 1260 : auto& b = arr[i];
89 1260 : if(remaining < b.size())
90 : {
91 840 : b = Buffer(b.data(), remaining);
92 840 : ++i;
93 840 : break;
94 : }
95 420 : remaining -= b.size();
96 420 : ++i;
97 : }
98 :
99 : // Destruct elements beyond the new count
100 1316 : while(*count > i)
101 420 : arr[--(*count)].~Buffer();
102 :
103 896 : *total_size = n;
104 : }
105 :
106 : } // anonymous namespace
107 :
108 : void
109 512 : buffer_array_remove_prefix(
110 : const_buffer* arr,
111 : std::size_t* count,
112 : std::size_t* total_size,
113 : std::size_t n) noexcept
114 : {
115 512 : do_remove_prefix(arr, count, total_size, n);
116 512 : }
117 :
118 : void
119 512 : buffer_array_remove_prefix(
120 : mutable_buffer* arr,
121 : std::size_t* count,
122 : std::size_t* total_size,
123 : std::size_t n) noexcept
124 : {
125 512 : do_remove_prefix(arr, count, total_size, n);
126 512 : }
127 :
128 : void
129 528 : buffer_array_keep_prefix(
130 : const_buffer* arr,
131 : std::size_t* count,
132 : std::size_t* total_size,
133 : std::size_t n) noexcept
134 : {
135 528 : do_keep_prefix(arr, count, total_size, n);
136 528 : }
137 :
138 : void
139 528 : buffer_array_keep_prefix(
140 : mutable_buffer* arr,
141 : std::size_t* count,
142 : std::size_t* total_size,
143 : std::size_t n) noexcept
144 : {
145 528 : do_keep_prefix(arr, count, total_size, n);
146 528 : }
147 :
148 : } // namespace detail
149 : } // namespace capy
150 : } // namespace boost
|