include/boost/capy/buffers/buffer_copy.hpp

100.0% Lines (36/36) 100.0% Functions (10/11)
include/boost/capy/buffers/buffer_copy.hpp
Line Hits 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 This function copies bytes from the constant buffer sequence `src` into
24 the mutable buffer sequence `dest`, stopping when any limit is reached.
25
26 @par Constraints
27 @code
28 MutableBufferSequence<decltype(dest)> &&
29 ConstBufferSequence<decltype(src)>
30 @endcode
31
32 @return The number of bytes copied, equal to
33 `std::min(size(dest), size(src), at_most)`.
34
35 @param dest The destination buffer sequence.
36 @param src The source buffer sequence.
37 @param at_most The maximum bytes to copy. Default copies all available.
38 */
39 constexpr struct buffer_copy_mrdocs_workaround_t
40 {
41 template<
42 MutableBufferSequence MB,
43 ConstBufferSequence CB>
44 std::size_t
45 15198 operator()(
46 MB const& dest,
47 CB const& src,
48 std::size_t at_most = std::size_t(-1)) const noexcept
49 {
50 15198 std::size_t total = 0;
51 15198 std::size_t pos0 = 0;
52 15198 std::size_t pos1 = 0;
53 15198 auto const end0 = end(src);
54 15198 auto const end1 = end(dest);
55 15198 auto it0 = begin(src);
56 15198 auto it1 = begin(dest);
57 15198 while(
58 46531 total < at_most &&
59 66892 it0 != end0 &&
60 9334 it1 != end1)
61 {
62 25401 const_buffer b0 = *it0;
63 25401 mutable_buffer b1 = *it1;
64 25401 b0 += pos0;
65 25401 b1 += pos1;
66 std::size_t const amount =
67 76203 [&]
68 {
69 25401 std::size_t n = b0.size();
70 25401 if( n > b1.size())
71 5732 n = b1.size();
72 25401 if( n > at_most - total)
73 4902 n = at_most - total;
74 25401 if(n != 0)
75 23043 std::memcpy(
76 b1.data(),
77 b0.data(),
78 n);
79 25401 return n;
80 25401 }();
81 25401 total += amount;
82 25401 if(amount == b1.size())
83 {
84 7278 ++it1;
85 7278 pos1 = 0;
86 }
87 else
88 {
89 18123 pos1 += amount;
90 }
91 25401 if(amount == b0.size())
92 {
93 16183 ++it0;
94 16183 pos0 = 0;
95 }
96 else
97 {
98 9218 pos0 += amount;
99 }
100 }
101 15198 return total;
102 }
103 } buffer_copy {};
104
105 } // capy
106 } // boost
107
108 #endif
109