GCC Code Coverage Report


Directory: ./
File: libs/capy/src_zlib/stream_cast.hpp
Date: 2025-12-15 05:33:30
Exec Total Coverage
Lines: 0 5 0.0%
Functions: 0 2 0.0%
Branches: 0 0 -%

Line Branch Exec Source
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 // Copyright (c) 2025 Mohammad Nejati
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/capy
9 //
10
11 #ifndef SRC_CAPY_ZLIB_STREAM_CAST_HPP
12 #define SRC_CAPY_ZLIB_STREAM_CAST_HPP
13
14 #include <boost/capy/zlib/stream.hpp>
15
16 #include <cstddef>
17
18 #include <zlib.h>
19
20 namespace boost {
21 namespace capy {
22 namespace zlib {
23
24 //------------------------------------------------
25
26 #define SAME_FIELD(T1,T2,M) \
27 offsetof(T1,M)==offsetof(T2,M) && \
28 sizeof(decltype(T1::M)) == sizeof(decltype(T2::M))
29
30 template<class T1, class T2>
31 constexpr
32 bool
33 is_layout_identical()
34 {
35 return
36 sizeof(T1) == sizeof(T2) &&
37 SAME_FIELD(T1, T2, next_in) &&
38 SAME_FIELD(T1, T2, avail_in) &&
39 SAME_FIELD(T1, T2, total_in) &&
40 SAME_FIELD(T1, T2, next_out) &&
41 SAME_FIELD(T1, T2, avail_out) &&
42 SAME_FIELD(T1, T2, total_out) &&
43 SAME_FIELD(T1, T2, msg) &&
44 SAME_FIELD(T1, T2, state) &&
45 SAME_FIELD(T1, T2, zalloc) &&
46 SAME_FIELD(T1, T2, zfree) &&
47 SAME_FIELD(T1, T2, opaque) &&
48 SAME_FIELD(T1, T2, data_type) &&
49 SAME_FIELD(T1, T2, adler) &&
50 SAME_FIELD(T1, T2, reserved)
51 ;
52 }
53
54 //------------------------------------------------
55
56 template<bool isLayoutIdentical =
57 is_layout_identical<stream, z_stream_s>()>
58 struct stream_cast_impl
59 {
60 explicit
61 stream_cast_impl(
62 stream& st)
63 : pzs_(reinterpret_cast<z_stream_s*>(&st))
64 , st_(st)
65 {
66 zs_.next_in = st_.next_in;
67 zs_.avail_in = st_.avail_in;
68 zs_.total_in = st_.total_in;
69 zs_.next_out = st_.next_out;
70 zs_.avail_out = st_.avail_out;
71 zs_.total_out = st_.total_out;
72 zs_.msg = nullptr;
73 zs_.state = reinterpret_cast<
74 internal_state*>(st_.state);
75 zs_.zalloc = st_.zalloc;
76 zs_.zfree = st_.zfree;
77 zs_.opaque = st_.opaque;
78 zs_.data_type = st_.data_type;
79 zs_.adler = st_.adler;
80 zs_.reserved = st_.reserved;
81 }
82
83 ~stream_cast_impl()
84 {
85 st_.next_in = zs_.next_in;
86 st_.avail_in = zs_.avail_in;
87 st_.total_in = zs_.total_in;
88 st_.next_out = zs_.next_out;
89 st_.avail_out = zs_.avail_out;
90 st_.total_out = zs_.total_out;
91 st_.msg = zs_.msg;
92 st_.state = zs_.state;
93 st_.zalloc = zs_.zalloc;
94 st_.zfree = zs_.zfree;
95 st_.opaque = zs_.opaque;
96 st_.data_type = zs_.data_type;
97 st_.adler = zs_.adler;
98 st_.reserved = zs_.reserved;
99 }
100
101 z_stream_s*
102 get() noexcept
103 {
104 return pzs_;
105 }
106
107 private:
108 z_stream_s* pzs_ = nullptr;
109 stream& st_;
110 z_stream_s zs_;
111 };
112
113 //------------------------------------------------
114
115 template<>
116 struct stream_cast_impl<true>
117 {
118 explicit
119 stream_cast_impl(
120 stream& st)
121 // VFALCO A pinch of undefined behavior here
122 : pzs_(reinterpret_cast<z_stream_s*>(&st))
123 {
124
125 }
126
127 z_stream_s*
128 get() noexcept
129 {
130 return pzs_;
131 }
132
133 private:
134 z_stream_s* pzs_;
135 };
136
137 //------------------------------------------------
138
139 using stream_cast = stream_cast_impl<>;
140
141 } // zlib
142 } // capy
143 } // boost
144
145 #endif
146