GCC Code Coverage Report


Directory: ./
File: libs/capy/include/boost/capy/any_bufref.hpp
Date: 2026-01-19 05:31:50
Exec Total Coverage
Lines: 18 18 100.0%
Functions: 8 8 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot 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_ANY_BUFREF_HPP
11 #define BOOST_CAPY_ANY_BUFREF_HPP
12
13 #include <boost/capy/detail/config.hpp>
14 #include <boost/capy/buffers.hpp>
15
16 #include <cstddef>
17
18 namespace boost {
19 namespace capy {
20
21 /** A type-erased buffer sequence I/O parameter.
22
23 This class provides a type-erased interface for iterating
24 over buffer sequences without knowing the concrete type.
25 It allows asynchronous operations to efficiently type-erase
26 the buffer sequence parameter, avoiding the need to
27 templatize the implementation.
28
29 @par Example
30 The following shows the minimal form of an awaitable, templated on the
31 buffer sequence type, with only an `await_suspend` method. The example
32 demonstrates that you can construct an `any_bufref` in the parameter
33 list when calling a virtual interface; there is no need to create a
34 separate variable if not desired.
35
36 @code
37 template<class Buffers>
38 struct awaitable
39 {
40 Buffers b;
41
42 void await_suspend( std::coroutine_handle<> )
43 {
44 my_virtual_engine_submit( any_bufref( b ) );
45 }
46 };
47
48 // Example virtual interface accepting any_bufref
49 void my_virtual_engine_submit( any_bufref p )
50 {
51 capy::mutable_buffer temp[8];
52 std::size_t n = p.copy_to( temp, 8 );
53 // ... handle the buffers ...
54 }
55 @endcode
56 */
57 class any_bufref
58 {
59 public:
60 /** Construct from a const buffer sequence.
61
62 @param bs The buffer sequence to adapt.
63 */
64 template<ConstBufferSequence BS>
65 explicit
66 18 any_bufref(BS const& bs) noexcept
67 18 : bs_(&bs)
68 18 , fn_(&copy_impl<BS>)
69 {
70 18 }
71
72 /** Fill an array with buffers from the sequence.
73
74 @param dest Pointer to array of mutable buffer descriptors.
75 @param n Maximum number of buffers to copy.
76
77 @return The number of buffers actually copied.
78 */
79 std::size_t
80 9 copy_to(
81 mutable_buffer* dest,
82 std::size_t n) const noexcept
83 {
84 9 return fn_(bs_, dest, n);
85 }
86
87 private:
88 template<ConstBufferSequence BS>
89 static std::size_t
90 9 copy_impl(
91 void const* p,
92 mutable_buffer* dest,
93 std::size_t n)
94 {
95 9 auto const& bs = *static_cast<BS const*>(p);
96 9 auto it = begin(bs);
97 9 auto const end_it = end(bs);
98
99 9 std::size_t i = 0;
100 if constexpr (MutableBufferSequence<BS>)
101 {
102 5 for(; it != end_it && i < n; ++it, ++i)
103 3 dest[i] = *it;
104 }
105 else
106 {
107 22 for(; it != end_it && i < n; ++it, ++i)
108 {
109 15 auto const& buf = *it;
110 30 dest[i] = mutable_buffer(
111 const_cast<char*>(
112 15 static_cast<char const*>(buf.data())),
113 buf.size());
114 }
115 }
116 9 return i;
117 }
118
119 using fn_t = std::size_t(*)(void const*,
120 mutable_buffer*, std::size_t);
121
122 void const* bs_;
123 fn_t fn_;
124 };
125
126 } // namespace capy
127 } // namespace boost
128
129 #endif
130