• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

celerity / celerity-runtime / 9725185072

29 Jun 2024 03:31PM UTC coverage: 94.627% (-0.05%) from 94.676%
9725185072

Pull #258

github

fknorr
[IDAG] do not report execution time from complete_event
Pull Request #258: [IDAG] Add new threading facilities

3083 of 3439 branches covered (89.65%)

Branch coverage included in aggregate %.

84 of 92 new or added lines in 5 files covered. (91.3%)

2 existing lines in 1 file now uncovered.

7132 of 7356 relevant lines covered (96.95%)

207082.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.74
/include/utils.h
1
#pragma once
2

3
#include <cassert>
4
#include <cstdint>
5
#include <functional>
6
#include <string>
7
#include <tuple>
8
#include <type_traits>
9
#include <typeinfo>
10

11
#include <fmt/format.h>
12

13
#include "types.h"
14

15

16
namespace celerity::detail::utils {
17

18
/// Like std::move, but move-constructs the result so it does not reference the argument after returning.
19
template <typename T>
20
T take(T& from) {
450✔
21
        return std::move(from);
450✔
22
}
23

24
template <typename T, typename P>
25
bool isa(const P* p) {
78,669✔
26
        return dynamic_cast<const T*>(p) != nullptr;
78,669!
27
}
28

29
template <typename T, typename P>
30
auto as(P* p) {
17,633✔
31
        assert(isa<T>(p));
17,633✔
32
        return static_cast<std::conditional_t<std::is_const_v<P>, const T*, T*>>(p);
17,633✔
33
}
34

35
template <typename BitMaskT>
36
constexpr inline uint32_t popcount(const BitMaskT bit_mask) noexcept {
37
        static_assert(std::is_integral_v<BitMaskT> && std::is_unsigned_v<BitMaskT>, "popcount argument needs to be an unsigned integer type.");
38

39
        uint32_t counter = 0;
40
        for(auto b = bit_mask; b; b >>= 1) {
41
                counter += b & 1;
42
        }
43
        return counter;
44
}
45

46
// Implementation from Boost.ContainerHash, licensed under the Boost Software License, Version 1.0.
47
inline void hash_combine(std::size_t& seed, std::size_t value) { seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); }
43,814✔
48

49
struct pair_hash {
50
        template <typename U, typename V>
51
        std::size_t operator()(const std::pair<U, V>& p) const {
11,228✔
52
                std::size_t seed = 0;
11,228✔
53
                hash_combine(seed, std::hash<U>{}(p.first));
11,228✔
54
                hash_combine(seed, std::hash<V>{}(p.second));
11,228✔
55
                return seed;
11,228✔
56
        }
57
};
58

59
} // namespace celerity::detail::utils
60

61
namespace celerity::detail::utils_detail {
62

63
template <typename... Without, typename... ToKeep, typename T, typename... Ts>
64
constexpr auto tuple_without_impl(const std::tuple<ToKeep...>& to_keep, const std::tuple<T, Ts...>& to_check) {
14✔
65
        if constexpr((std::is_same_v<T, Without> || ...)) {
66
                if constexpr(sizeof...(Ts) == 0) {
67
                        return to_keep;
6✔
68
                } else {
69
                        return tuple_without_impl<Without...>(to_keep, std::tuple{std::get<Ts>(to_check)...});
70
                }
71
        } else {
72
                if constexpr(sizeof...(Ts) == 0) {
73
                        return std::tuple_cat(to_keep, to_check);
5✔
74
                } else {
75
                        return tuple_without_impl<Without...>(std::tuple_cat(to_keep, std::tuple{std::get<T>(to_check)}), std::tuple{std::get<Ts>(to_check)...});
3✔
76
                }
77
        }
78
}
79

80
template <typename Tuple, typename Callback>
81
constexpr void tuple_for_each_pair_impl(const Tuple&, Callback&&, std::index_sequence<>) {}
5,574✔
82

83
template <typename Tuple, size_t I1, size_t I2, size_t... Is, typename Callback>
84
constexpr void tuple_for_each_pair_impl(const Tuple& tuple, const Callback& cb, std::index_sequence<I1, I2, Is...>) {
10,436✔
85
        cb(std::get<I1>(tuple), std::get<I2>(tuple));
10,436✔
86
        tuple_for_each_pair_impl(tuple, cb, std::index_sequence<Is...>{});
10,436✔
87
}
10,436✔
88

89
} // namespace celerity::detail::utils_detail
90

91
namespace celerity::detail::utils {
92

93
/// See `utils::type_switch_t`.
94
template <typename Lookup, typename... KVs>
95
struct type_switch {};
96

97
/// `switch` equivalent of `std::conditional_t`. Use as `utils::type_switch_t<lookup-type, key-type-1(result-type-1), key-type-2(result-type-2), ...>`
98
template <typename Lookup, typename... KVs>
99
using type_switch_t = typename type_switch<Lookup, KVs...>::type;
100

101
template <typename MatchingKey, typename Value, typename... KVs>
102
struct type_switch<MatchingKey, MatchingKey(Value), KVs...> {
103
        using type = Value;
104
};
105

106
template <typename NonMatching, typename Key, typename Value, typename... KVs>
107
struct type_switch<NonMatching, Key(Value), KVs...> {
108
        using type = type_switch_t<NonMatching, KVs...>;
109
};
110

111
template <typename... Without, typename... Ts>
112
constexpr auto tuple_without(const std::tuple<Ts...>& tuple) {
18✔
113
        if constexpr(sizeof...(Ts) > 0) {
114
                return utils_detail::tuple_without_impl<Without...>({}, tuple);
11✔
115
        } else {
116
                return tuple;
7✔
117
        }
118
}
119

120
template <typename Tuple, typename Callback>
121
constexpr void tuple_for_each_pair(const Tuple& tuple, const Callback& cb) {
5,574✔
122
        static_assert(std::tuple_size_v<Tuple> % 2 == 0, "an even number of entries is required");
123
        utils_detail::tuple_for_each_pair_impl(tuple, cb, std::make_index_sequence<std::tuple_size_v<Tuple>>{});
5,574✔
124
}
5,574✔
125

126
/// Fiddles out the base name of a (possibly templated) struct or class from a full (possibly mangled) type name.
127
/// The input parameter should be `typeid(Struct*)`, i.e. a _pointer_ to the desired struct type.
128
std::string get_simplified_type_name_from_pointer(const std::type_info& pointer_type_info);
129

130
/// Fiddles out the base name of a (possibly templated) struct or class from a full (possibly mangled) type name.
131
template <typename Struct>
132
std::string get_simplified_type_name() {
1,705✔
133
        // Using a pointer will also make this function work types that have no definitions, which commonly happens for kernel name type.
134
        return get_simplified_type_name_from_pointer(typeid(Struct*));
1,705✔
135
}
136

137
/// Escapes "<", ">", and "&" with their corresponding HTML escape sequences
138
std::string escape_for_dot_label(std::string str);
139

140
/// Print the buffer id as either 'B1' or 'B1 "name"' (if `name` is non-empty)
141
std::string make_buffer_debug_label(const buffer_id bid, const std::string& name = "");
142

143
[[noreturn]] void unreachable();
144

145
enum class panic_solution {
146
        log_and_abort,     ///< default
147
        throw_logic_error, ///< enabled in unit tests to detect and recover from panics
148
};
149

150
/// Globally and atomically sets the behavior of `utils::panic()`.
151
void set_panic_solution(panic_solution solution);
152

153
/// Either throws or aborts with a message, depending on the global `panic_solution` setting.
154
[[noreturn]] void panic(const std::string& msg);
155

156
/// Either throws or aborts with a message, depending on the global `panic_solution` setting.
157
template <typename... FmtParams>
UNCOV
158
[[noreturn]] void panic(fmt::format_string<FmtParams...> fmt_string, FmtParams&&... fmt_args) {
×
159
        // TODO also receive a std::source_location with C++20.
UNCOV
160
        panic(fmt::format(fmt_string, std::forward<FmtParams>(fmt_args)...));
×
161
}
162

163
/// Ignores, logs, or panics on an error depending on the `error_policy`.
164
void report_error(const error_policy policy, const std::string& msg);
165

166
/// Ignores, logs, or panics on an error depending on the `error_policy`.
167
template <typename... FmtParams, std::enable_if_t<sizeof...(FmtParams) >= 1, int> = 0>
168
void report_error(const error_policy policy, const fmt::format_string<FmtParams...> fmt_string, FmtParams&&... fmt_args) {
31✔
169
        // TODO also receive a std::source_location with C++20.
170
        if(policy != error_policy::ignore) { report_error(policy, fmt::format(fmt_string, std::forward<FmtParams>(fmt_args)...)); }
79!
171
}
14✔
172

173
} // namespace celerity::detail::utils
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc