GCC Code Coverage Report


Directory: gridformat/
File: gridformat/common/variant.hpp
Date: 2024-11-20 14:41:59
Exec Total Coverage
Lines: 19 20 95.0%
Functions: 27 29 93.1%
Branches: 3 6 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 Helper functions for variants
7 */
8 #ifndef GRIDFORMAT_COMMON_VARIANT_HPP_
9 #define GRIDFORMAT_COMMON_VARIANT_HPP_
10
11 #include <variant>
12 #include <utility>
13 #include <concepts>
14 #include <type_traits>
15
16 #include <gridformat/common/callable_overload_set.hpp>
17 #include <gridformat/common/exceptions.hpp>
18 #include <gridformat/common/type_traits.hpp>
19
20 namespace GridFormat::Variant {
21
22 #ifndef DOXYGEN
23 namespace Detail {
24
25 template<typename R, typename... Removes, typename... Callables, typename Callback>
26 172508 auto append_without_overloads(Overload<Callables...>&& base, Callback cb) {
27 172508 auto cur_overloads = Overload{std::move(base), [cb=cb] (const R& r) { cb(r); } };
28 if constexpr (sizeof...(Removes) > 0)
29 2 return append_without_overloads<Removes...>(std::move(cur_overloads), cb);
30 else
31 172506 return cur_overloads;
32 }
33
34 template<typename... Removes, typename TargetVariant, typename Callback>
35 172506 auto without_overload_set(TargetVariant& t, Callback cb) {
36 258759 auto base_overload = Overload{[&] (const auto& v) { t = v; }};
37 if constexpr (sizeof...(Removes) == 0)
38 return base_overload;
39 else
40 172506 return append_without_overloads<Removes...>(std::move(base_overload), cb);
41 }
42
43 } // namespace Detail
44 #endif // DOXYGEN
45
46
47 //! \addtogroup Common
48 //! \{
49
50 template<typename T, typename... Ts>
51 470240 constexpr bool is(const std::variant<Ts...>& v) {
52
1/2
✓ Branch 1 taken 235120 times.
✗ Branch 2 not taken.
940480 return std::visit(Overload{
53 103595 [] (const T&) { return true; },
54 131525 [] (const auto&) { return false; }
55 940480 }, v);
56 }
57
58 template<typename... Removes, typename... Ts>
59 172458 constexpr auto without(const std::variant<Ts...>& v) {
60 const auto throw_callback = [] (const auto&) { throw ValueError("Cannot remove type currently held by a variant"); };
61 172458 ReducedVariant<std::variant<Ts...>, Removes...> result;
62
1/2
✓ Branch 2 taken 86205 times.
✗ Branch 3 not taken.
172458 std::visit(Detail::without_overload_set<Removes...>(result, throw_callback), v);
63 289661 return result;
64 }
65
66 template<typename Remove, typename... Ts, typename Replacement>
67 requires(!std::same_as<Remove, std::remove_cvref_t<Replacement>> &&
68 std::assignable_from<ReducedVariant<std::variant<Ts...>, Remove>&, Replacement>)
69 constexpr auto replace(const std::variant<Ts...>& v, Replacement&& replacement) {
70 ReducedVariant<std::variant<Ts...>, Remove> result;
71 const auto replace_callback = [&] (const Remove&) { result = std::forward<Replacement>(replacement); };
72 std::visit(Detail::without_overload_set<Remove>(result, replace_callback), v);
73 return result;
74 }
75
76 template<typename T>
77 constexpr T unwrap(const std::variant<T>& v) {
78 return std::visit([] (const T& value) { return value; }, v);
79 }
80
81 template<typename To, typename... Ts>
82 requires(std::conjunction_v<std::is_assignable<To, const Ts&>...>)
83 28844 constexpr void unwrap_to(To& to, const std::variant<Ts...>& v) {
84
1/2
✓ Branch 1 taken 14423 times.
✗ Branch 2 not taken.
43269 std::visit([&] (const auto& value) { to = value; }, v);
85 28844 }
86
87 //! \} group Common
88
89 } // end namespace GridFormat::Variant
90
91 #endif // GRIDFORMAT_COMMON_VARIANT_HPP_
92