GCC Code Coverage Report


Directory: gridformat/
File: gridformat/common/reserved_vector.hpp
Date: 2024-11-20 14:41:59
Exec Total Coverage
Lines: 32 32 100.0%
Functions: 68 72 94.4%
Branches: 7 14 50.0%

Line Branch Exec Source
1 // SPDX-FileCopyrightText: 2022-2023 Dennis Gläser <dennis.glaeser@iws.uni-stuttgart.de>
2 // SPDX-License-Identifier: MIT
3 /*!
4 * \file
5 * \ingroup Common
6 * \brief Vector with preallocated memory.
7 */
8 #ifndef GRIDFORMAT_COMMON_RESERVED_VECTOR_HPP_
9 #define GRIDFORMAT_COMMON_RESERVED_VECTOR_HPP_
10
11 #include <bit>
12 #include <array>
13 #include <vector>
14 #include <utility>
15 #include <memory_resource>
16 #include <algorithm>
17 #include <iterator>
18
19 namespace GridFormat {
20
21 template<typename T, std::size_t N>
22 class ReservedVector {
23 using Vector = std::pmr::vector<T>;
24
25 public:
26 using value_type = T;
27
28 8848803 ReservedVector() = default;
29
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 ReservedVector(std::size_t n, const T& r) : ReservedVector() { _elements.resize(n, r); }
30
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 ReservedVector(std::initializer_list<T>&& initList) : ReservedVector() { _copy_back(initList); }
31
32 // We need both template and non-template variant, because if only the template is present, the
33 // compiler tries to use the default copy ctor (which is deleted). Same for move ctor & assignments.
34 template<std::size_t M>
35
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 ReservedVector(const ReservedVector<T, M>& other) : ReservedVector() { _copy_back(other); }
36
1/2
✓ Branch 2 taken 1184713 times.
✗ Branch 3 not taken.
1188318 ReservedVector(const ReservedVector& other) : ReservedVector() { _copy_back(other); }
37
38 template<std::size_t M>
39
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
4 ReservedVector(ReservedVector<T, M>&& other) : ReservedVector() { _move_back(std::move(other)); }
40
1/2
✓ Branch 3 taken 198158 times.
✗ Branch 4 not taken.
198158 ReservedVector(ReservedVector&& other) : ReservedVector() { _move_back(std::move(other)); }
41
42 ReservedVector& operator=(const ReservedVector& other) {
43 _elements = Vector{typename Vector::allocator_type{&_resource}};
44 _copy_back(other);
45 return *this;
46 }
47
48 template<std::size_t M>
49 ReservedVector& operator=(const ReservedVector<T, M>& other) {
50 _elements = Vector{typename Vector::allocator_type{&_resource}};
51 _copy_back(other);
52 return *this;
53 }
54
55 35628 ReservedVector& operator=(ReservedVector&& other) {
56
1/2
✓ Branch 3 taken 35628 times.
✗ Branch 4 not taken.
35628 _elements = Vector{typename Vector::allocator_type{&_resource}};
57 35628 _move_back(std::move(other));
58 35628 return *this;
59 }
60
61 template<std::size_t M>
62 ReservedVector& operator=(ReservedVector<T, M>&& other) {
63 _elements = Vector{typename Vector::allocator_type{&_resource}};
64 _move_back(std::move(other));
65 return *this;
66 }
67
68 void clear() { _elements.clear(); }
69 7186991 std::size_t size() const { return _elements.size(); }
70 2463736 void reserve(std::size_t n) { _elements.reserve(n); }
71 void resize(std::size_t n) { _elements.resize(n); }
72 104038 void resize(std::size_t n, const T& value) { _elements.resize(n, value); }
73
74 1085413 void push_back(const T& element) { _elements.push_back(element); }
75 1462757 void push_back(T&& element) { _elements.push_back(std::move(element)); }
76
77 273506 decltype(auto) begin() { return _elements.begin(); }
78 3844263 decltype(auto) begin() const { return _elements.begin(); }
79
80 260544 decltype(auto) end() { return _elements.end(); }
81 3494727 decltype(auto) end() const { return _elements.end(); }
82
83 2137077 decltype(auto) operator[](std::size_t i) { return _elements[i]; }
84 6443451 decltype(auto) operator[](std::size_t i) const { return _elements[i]; }
85
86 2 decltype(auto) at(std::size_t i) { return _elements.at(i); }
87 4535713 decltype(auto) at(std::size_t i) const { return _elements.at(i); }
88
89 private:
90 template<std::ranges::sized_range R>
91 1188336 void _copy_back(const R& other) {
92 1188336 _elements.reserve(std::ranges::size(other));
93 1188336 std::ranges::copy(other, std::back_inserter(_elements));
94 1188336 }
95
96 template<std::ranges::sized_range R> requires(!std::is_lvalue_reference_v<R>)
97 233792 void _move_back(R&& other) {
98 233792 _elements.reserve(std::ranges::size(other));
99 233792 std::ranges::move(std::move(other), std::back_inserter(_elements));
100 233792 }
101
102 std::array<std::byte, N*sizeof(T)> _buffer;
103 std::pmr::monotonic_buffer_resource _resource{_buffer.data(), _buffer.size()};
104 Vector _elements{typename Vector::allocator_type{&_resource}};
105 };
106
107 } // namespace GridFormat
108
109 #endif // GRIDFORMAT_COMMON_RESERVED_VECTOR_HPP_
110