TLA 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/capy
8 : //
9 :
10 : #ifndef BOOST_CAPY_BUFFERS_BUFFER_COPY_HPP
11 : #define BOOST_CAPY_BUFFERS_BUFFER_COPY_HPP
12 :
13 : #include <boost/capy/detail/config.hpp>
14 : #include <boost/capy/buffers.hpp>
15 : #include <cstring>
16 : #include <utility>
17 :
18 : namespace boost {
19 : namespace capy {
20 :
21 : /** Copy the contents of a buffer sequence into another buffer sequence.
22 :
23 : @functionobject
24 : */
25 : constexpr struct
26 : {
27 : /** Copy the contents of a buffer sequence into another buffer sequence.
28 :
29 : Copies bytes from the constant buffer sequence `src` into the
30 : mutable buffer sequence `dest`, stopping when any limit is
31 : reached.
32 :
33 : @param dest The destination buffer sequence.
34 :
35 : @param src The source buffer sequence.
36 :
37 : @param at_most The maximum bytes to copy. Default copies all
38 : available.
39 :
40 : @return The number of bytes copied, equal to
41 : `std::min(size(dest), size(src), at_most)`.
42 : */
43 : template<
44 : MutableBufferSequence MB,
45 : ConstBufferSequence CB>
46 : std::size_t
47 HIT 10957 : operator()(
48 : MB const& dest,
49 : CB const& src,
50 : std::size_t at_most = std::size_t(-1)) const noexcept
51 : {
52 10957 : std::size_t total = 0;
53 10957 : std::size_t pos0 = 0;
54 10957 : std::size_t pos1 = 0;
55 10957 : auto const end0 = end(src);
56 10957 : auto const end1 = end(dest);
57 10957 : auto it0 = begin(src);
58 10957 : auto it1 = begin(dest);
59 10957 : while(
60 35908 : total < at_most &&
61 50466 : it0 != end0 &&
62 9423 : it1 != end1)
63 : {
64 18512 : const_buffer b0 = *it0;
65 18512 : mutable_buffer b1 = *it1;
66 18512 : b0 += pos0;
67 18512 : b1 += pos1;
68 : std::size_t const amount =
69 55536 : [&]
70 : {
71 18512 : std::size_t n = b0.size();
72 18512 : if( n > b1.size())
73 5718 : n = b1.size();
74 18512 : if( n > at_most - total)
75 4902 : n = at_most - total;
76 18512 : if(n != 0)
77 17659 : std::memcpy(
78 : b1.data(),
79 : b0.data(),
80 : n);
81 18512 : return n;
82 18512 : }();
83 18512 : total += amount;
84 18512 : if(amount == b1.size())
85 : {
86 6187 : ++it1;
87 6187 : pos1 = 0;
88 : }
89 : else
90 : {
91 12325 : pos1 += amount;
92 : }
93 18512 : if(amount == b0.size())
94 : {
95 9308 : ++it0;
96 9308 : pos0 = 0;
97 : }
98 : else
99 : {
100 9204 : pos0 += amount;
101 : }
102 : }
103 10957 : return total;
104 : }
105 : } buffer_copy {};
106 :
107 : } // capy
108 : } // boost
109 :
110 : #endif
|