GCC Code Coverage Report


Directory: gridformat/
File: gridformat/decorators/reader_polylines_subdivider.hpp
Date: 2025-03-26 17:08:15
Exec Total Coverage
Lines: 52 75 69.3%
Functions: 10 27 37.0%
Branches: 50 162 30.9%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2025 Dennis Gläser <dennis.a.glaeser@gmail.com>
2 // SPDX-License-Identifier: MIT
3 /*!
4 * \file
5 * \ingroup Adapters
6 * \copydoc GridFormat::ReaderAdapters::PolylinesSubdivider
7 */
8 #ifndef GRIDFORMAT_DECORATORS_READER_SUBDIVIDE_POLYLINES_ADAPTER_HPP_
9 #define GRIDFORMAT_DECORATORS_READER_SUBDIVIDE_POLYLINES_ADAPTER_HPP_
10
11 #include <concepts>
12 #include <algorithm>
13 #include <iterator>
14 #include <memory>
15
16 #include <gridformat/common/exceptions.hpp>
17 #include <gridformat/common/buffer_field.hpp>
18 #include <gridformat/grid/reader.hpp>
19
20 namespace GridFormat::ReaderDecorators {
21
22 /*!
23 * \ingroup Adapters
24 * \brief Adapter for readers that subdivides polyline cells into collections of segments.
25 * \note The adapter takes ownership over the reader provided upon construction.
26 */
27 class PolylinesSubdivider : public GridReader {
28 public:
29 template<std::derived_from<GridReader> Reader>
30 requires(not std::is_lvalue_reference_v<Reader>)
31 2 explicit PolylinesSubdivider(Reader&& reader)
32
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 : _reader{std::make_unique<std::remove_cvref_t<Reader>>(std::move(reader))}
33 2 {}
34
35 template<std::derived_from<GridReader> Reader>
36 explicit PolylinesSubdivider(std::unique_ptr<Reader>&& reader)
37 : _reader{std::move(reader)}
38 {}
39
40 private:
41 2 void _open(const std::string& filename, typename GridReader::FieldNames& fields) override {
42 2 _reader->open(filename);
43
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 std::ranges::copy(point_field_names(*_reader), std::back_inserter(fields.point_fields));
44
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 std::ranges::copy(cell_field_names(*_reader), std::back_inserter(fields.cell_fields));
45
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 std::ranges::copy(meta_data_field_names(*_reader), std::back_inserter(fields.meta_data_fields));
46 2 }
47
48 void _close() override {
49 _reader->close();
50 }
51
52 std::string _name() const override {
53 return "PolyLineReaderAdapter<" + _reader->name() + ">";
54 }
55
56 14 std::size_t _number_of_cells() const override {
57 14 std::size_t result = 0;
58
1/2
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
14 _reader->visit_cells([&] (CellType ct, const std::vector<std::size_t>& corners) {
59
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
140 result += ct == CellType::polyline ? corners.size() - 1 : 1;
60 140 });
61 14 return result;
62 }
63
64 2 std::size_t _number_of_points() const override {
65 2 return _reader->number_of_points();
66 }
67
68 std::size_t _number_of_pieces() const override {
69 return _reader->number_of_pieces();
70 }
71
72 bool _is_sequence() const override {
73 return _reader->is_sequence();
74 }
75
76 FieldPtr _points() const override {
77 return _reader->points();
78 }
79
80 void _visit_cells(const typename GridReader::CellVisitor& visitor) const override {
81 _reader->visit_cells([&] (CellType ct, const std::vector<std::size_t>& corners) {
82 if (ct == CellType::polyline) {
83 std::vector<std::size_t> sub_segment_corners(2);
84 for (std::size_t i = 0; i < corners.size() - 1; ++i) {
85 sub_segment_corners[0] = corners[i];
86 sub_segment_corners[1] = corners[i + 1];
87 visitor(CellType::segment, sub_segment_corners);
88 }
89 } else {
90 visitor(ct, corners);
91 }
92 });
93 }
94
95 12 FieldPtr _cell_field(std::string_view name) const override {
96
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 FieldPtr raw_field = _reader->cell_field(name);
97
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 const auto raw_layout = raw_field->layout();
98
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 const auto raw_data = raw_field->serialized();
99
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 auto adapted_layout = raw_layout.dimension() > 1
100
4/10
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✓ Branch 8 taken 4 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
20 ? MDLayout{_number_of_cells()}.with_sub_layout(raw_layout.sub_layout(1))
101
9/14
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 4 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 8 times.
✓ Branch 18 taken 4 times.
20 : MDLayout{_number_of_cells()};
102
103
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
36 return raw_field->precision().visit([&] <typename T> (const Precision<T>&) -> FieldPtr {
104
4/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
24 const std::size_t number_of_components = raw_layout.dimension() > 1 ? raw_layout.number_of_entries(1) : 1;
105
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 const std::span raw_buffer = raw_data.template as_span_of<T>();
106
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 std::vector<T> adapted_buffer(adapted_layout.number_of_entries());
107
108 24 std::size_t raw_index = 0;
109 24 std::size_t adapted_index = 0;
110 384 const auto copy = [&] () {
111
2/24
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✓ Branch 53 taken 90 times.
✗ Branch 54 not taken.
✓ Branch 58 taken 90 times.
✗ Branch 59 not taken.
360 std::copy_n(
112 180 raw_buffer.begin() + raw_index*number_of_components,
113 number_of_components,
114 360 adapted_buffer.begin() + adapted_index*number_of_components
115 );
116 };
117
118
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
264 _reader->visit_cells([&] (CellType ct, const std::vector<std::size_t>& corners) {
119
4/24
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 30 times.
✓ Branch 21 taken 30 times.
✓ Branch 22 taken 30 times.
✓ Branch 23 taken 30 times.
120 if (ct == CellType::polyline) {
120
4/24
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 31 taken 60 times.
✓ Branch 32 taken 30 times.
✓ Branch 34 taken 60 times.
✓ Branch 35 taken 30 times.
180 for (std::size_t i = 0; i < corners.size() - 1; ++i) {
121 120 copy();
122 120 adapted_index++;
123 }
124 } else {
125 60 copy();
126 60 adapted_index++;
127 }
128 120 raw_index++;
129 });
130
131
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
48 return make_field_ptr(BufferField{
132 24 std::move(adapted_buffer),
133 24 std::move(adapted_layout)
134
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
48 });
135
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
48 });
136 12 }
137
138 12 FieldPtr _point_field(std::string_view name) const override {
139 12 return _reader->point_field(name);
140 }
141
142 6 FieldPtr _meta_data_field(std::string_view name) const override {
143 6 return _reader->meta_data_field(name);
144 }
145
146 std::unique_ptr<GridReader> _reader;
147 };
148
149 } // namespace GridFormat::ReaderDecorators
150
151 #endif // GRIDFORMAT_DECORATORS_READER_SUBDIVIDE_POLYLINES_ADAPTER_HPP_
152