100.00% Lines (36/36) 100.00% Functions (2/2)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2023 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_BUFFER_COPY_HPP 10   #ifndef BOOST_CAPY_BUFFERS_BUFFER_COPY_HPP
11   #define BOOST_CAPY_BUFFERS_BUFFER_COPY_HPP 11   #define BOOST_CAPY_BUFFERS_BUFFER_COPY_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 <cstring> 15   #include <cstring>
16   #include <utility> 16   #include <utility>
17   17  
18   namespace boost { 18   namespace boost {
19   namespace capy { 19   namespace capy {
20   20  
21 - /** Copy the contents of a buffer sequence into another buffer sequence. 21 + namespace detail {
22 - 22 + struct buffer_copy_fn
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   { 23   {
41   template< 24   template<
42   MutableBufferSequence MB, 25   MutableBufferSequence MB,
43   ConstBufferSequence CB> 26   ConstBufferSequence CB>
44   std::size_t 27   std::size_t
HITCBC 45   12256 operator()( 28   12256 operator()(
46   MB const& dest, 29   MB const& dest,
47   CB const& src, 30   CB const& src,
48   std::size_t at_most = std::size_t(-1)) const noexcept 31   std::size_t at_most = std::size_t(-1)) const noexcept
49   { 32   {
HITCBC 50   12256 std::size_t total = 0; 33   12256 std::size_t total = 0;
HITCBC 51   12256 std::size_t pos0 = 0; 34   12256 std::size_t pos0 = 0;
HITCBC 52   12256 std::size_t pos1 = 0; 35   12256 std::size_t pos1 = 0;
HITCBC 53   12256 auto const end0 = end(src); 36   12256 auto const end0 = end(src);
HITCBC 54   12256 auto const end1 = end(dest); 37   12256 auto const end1 = end(dest);
HITCBC 55   12256 auto it0 = begin(src); 38   12256 auto it0 = begin(src);
HITCBC 56   12256 auto it1 = begin(dest); 39   12256 auto it1 = begin(dest);
HITCBC 57   12256 while( 40   12256 while(
HITCBC 58   38002 total < at_most && 41   38002 total < at_most &&
HITCBC 59   54380 it0 != end0 && 42   54380 it0 != end0 &&
HITCBC 60   9402 it1 != end1) 43   9402 it1 != end1)
61   { 44   {
HITCBC 62   19805 const_buffer b0 = *it0; 45   19805 const_buffer b0 = *it0;
HITCBC 63   19805 mutable_buffer b1 = *it1; 46   19805 mutable_buffer b1 = *it1;
HITCBC 64   19805 b0 += pos0; 47   19805 b0 += pos0;
HITCBC 65   19805 b1 += pos1; 48   19805 b1 += pos1;
66   std::size_t const amount = 49   std::size_t const amount =
HITCBC 67   59415 [&] 50   59415 [&]
68   { 51   {
HITCBC 69   19805 std::size_t n = b0.size(); 52   19805 std::size_t n = b0.size();
HITCBC 70   19805 if( n > b1.size()) 53   19805 if( n > b1.size())
HITCBC 71   5750 n = b1.size(); 54   5750 n = b1.size();
HITCBC 72   19805 if( n > at_most - total) 55   19805 if( n > at_most - total)
HITCBC 73   4902 n = at_most - total; 56   4902 n = at_most - total;
HITCBC 74   19805 if(n != 0) 57   19805 if(n != 0)
HITCBC 75   18953 std::memcpy( 58   18953 std::memcpy(
76   b1.data(), 59   b1.data(),
77   b0.data(), 60   b0.data(),
78   n); 61   n);
HITCBC 79   19805 return n; 62   19805 return n;
HITCBC 80   19805 }(); 63   19805 }();
HITCBC 81   19805 total += amount; 64   19805 total += amount;
HITCBC 82   19805 if(amount == b1.size()) 65   19805 if(amount == b1.size())
83   { 66   {
HITCBC 84   7301 ++it1; 67   7301 ++it1;
HITCBC 85   7301 pos1 = 0; 68   7301 pos1 = 0;
86   } 69   }
87   else 70   else
88   { 71   {
HITCBC 89   12504 pos1 += amount; 72   12504 pos1 += amount;
90   } 73   }
HITCBC 91   19805 if(amount == b0.size()) 74   19805 if(amount == b0.size())
92   { 75   {
HITCBC 93   10569 ++it0; 76   10569 ++it0;
HITCBC 94   10569 pos0 = 0; 77   10569 pos0 = 0;
95   } 78   }
96   else 79   else
97   { 80   {
HITCBC 98   9236 pos0 += amount; 81   9236 pos0 += amount;
99   } 82   }
100   } 83   }
HITCBC 101   12256 return total; 84   12256 return total;
102   } 85   }
103 - } buffer_copy {}; 86 + };
  87 + } // detail
  88 +
  89 + /** Copy the contents of a buffer sequence into another buffer sequence.
  90 +
  91 + This function copies bytes from the constant buffer sequence `src` into
  92 + the mutable buffer sequence `dest`, stopping when any limit is reached.
  93 +
  94 + @par Constraints
  95 + @code
  96 + MutableBufferSequence<decltype(dest)> &&
  97 + ConstBufferSequence<decltype(src)>
  98 + @endcode
  99 +
  100 + @return The number of bytes copied, equal to
  101 + `std::min(size(dest), size(src), at_most)`.
  102 +
  103 + @param dest The destination buffer sequence.
  104 + @param src The source buffer sequence.
  105 + @param at_most The maximum bytes to copy. Default copies all available.
  106 + */
  107 + constexpr detail::buffer_copy_fn buffer_copy {};
104   108  
105   } // capy 109   } // capy
106   } // boost 110   } // boost
107   111  
108   #endif 112   #endif