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_COPY_HPP
11 : #define BOOST_CAPY_BUFFERS_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 : This function copies no more than `at_most` bytes from the constant buffer
24 : sequence denoted by `src` into the mutable buffer sequence denoted by `dest`.
25 :
26 : @par Constraints
27 : @code
28 : mutable_buffer_sequence<decltype(dest)> &&
29 : const_buffer_sequence<decltype(src)>
30 : @endcode
31 :
32 : @return The number of bytes actually copied, which will be exactly equal to
33 : `std::min( size(dest), size(src), at_most )`.
34 :
35 : @param dest The destination buffer sequence
36 :
37 : @param src The source buffer sequence
38 : */
39 : constexpr struct copy_mrdocs_workaround_t
40 : {
41 : template<
42 : mutable_buffer_sequence MutableBufferSequence,
43 : const_buffer_sequence ConstBufferSequence>
44 : std::size_t
45 600020 : operator()(
46 : MutableBufferSequence const& dest,
47 : ConstBufferSequence const& src,
48 : std::size_t at_most = std::size_t(-1)) const noexcept
49 : {
50 600020 : std::size_t total = 0;
51 600020 : std::size_t pos0 = 0;
52 600020 : std::size_t pos1 = 0;
53 600020 : auto const end0 = end(src);
54 600020 : auto const end1 = end(dest);
55 600020 : auto it0 = begin(src);
56 600020 : auto it1 = begin(dest);
57 600020 : while(
58 1619783 : total < at_most &&
59 2939445 : it0 != end0 &&
60 : it1 != end1)
61 : {
62 1026225 : const_buffer b0 = *it0;
63 1026225 : mutable_buffer b1 = *it1;
64 1026225 : b0 += pos0;
65 1026225 : b1 += pos1;
66 : std::size_t const amount =
67 3078675 : [&]
68 : {
69 1026225 : std::size_t n = b0.size();
70 1026225 : if( n > b1.size())
71 23653 : n = b1.size();
72 1026225 : if( n > at_most - total)
73 4878 : n = at_most - total;
74 1026225 : if(n != 0)
75 772086 : std::memcpy(
76 : b1.data(),
77 : b0.data(),
78 : n);
79 1026225 : return n;
80 1026225 : }();
81 1026225 : total += amount;
82 1026225 : if(amount == b1.size())
83 : {
84 32092 : ++it1;
85 32092 : pos1 = 0;
86 : }
87 : else
88 : {
89 994133 : pos1 += amount;
90 : }
91 1026225 : if(amount == b0.size())
92 : {
93 999110 : ++it0;
94 999110 : pos0 = 0;
95 : }
96 : else
97 : {
98 27115 : pos0 += amount;
99 : }
100 : }
101 600020 : return total;
102 : }
103 : } copy {};
104 :
105 : } // capy
106 : } // boost
107 :
108 : #endif
|