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

celerity / celerity-runtime / 10216674169

02 Aug 2024 01:45PM UTC coverage: 94.951% (+2.1%) from 92.884%
10216674169

push

github

fknorr
Remove experimental::user_benchmarker

user_benchmarker has been obsolete ever since we moved away from
structured logging as a the profiler (CPAT) interface.

2978 of 3372 branches covered (88.32%)

Branch coverage included in aggregate %.

6557 of 6670 relevant lines covered (98.31%)

1534446.4 hits per line

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

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

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

12
#include <fmt/format.h>
13

14
#include "types.h"
15

16

17
namespace celerity::detail::utils {
18

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

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

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

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

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

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

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

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

62
namespace celerity::detail::utils_detail {
63

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

81
template <typename Container, typename Key, typename Enable = void>
82
struct has_member_find : std::false_type {};
83

84
template <typename Container, typename Key>
85
struct has_member_find<Container, Key, std::void_t<decltype(std::declval<const Container&>().find(std::declval<const Key&>()))>> : std::true_type {};
86

87
template <typename Container, typename Key>
88
inline constexpr bool has_member_find_v = has_member_find<Container, Key>::value;
89

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

92
namespace celerity::detail::utils {
93

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

98
/// `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), ...>`
99
template <typename Lookup, typename... KVs>
100
using type_switch_t = typename type_switch<Lookup, KVs...>::type;
101

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

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

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

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

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

132
/// Escapes "<", ">", and "&" with their corresponding HTML escape sequences
133
std::string escape_for_dot_label(std::string str);
134

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

138
std::string make_task_debug_label(const task_type tt, const task_id tid, const std::string& debug_name, bool title_case = false);
139

140
[[noreturn]] void unreachable();
141

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

147
/// Globally and atomically sets the behavior of `utils::panic()`.
148
void set_panic_solution(panic_solution solution);
149

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

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

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

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

170
template <typename Container>
171
Container set_intersection(const Container& lhs, const Container& rhs) {
280✔
172
        using std::begin, std::end;
173
        assert(std::is_sorted(begin(lhs), end(lhs)));
280✔
174
        assert(std::is_sorted(begin(rhs), end(rhs)));
280✔
175
        Container intersection;
280✔
176
        std::set_intersection(begin(lhs), end(lhs), begin(rhs), end(rhs), std::back_inserter(intersection));
560✔
177
        return intersection;
280✔
178
}
×
179

180
template <typename Container, typename Key>
181
bool contains(const Container& container, const Key& key) {
1,284✔
182
        using std::begin, std::end;
183
        if constexpr(utils_detail::has_member_find_v<Container, Key>) {
184
                return container.find(key) != end(container);
790✔
185
        } else {
186
                return std::find(begin(container), end(container), key) != end(container);
2,667✔
187
        }
188
}
189

190
template <typename Container, typename Predicate>
191
void erase_if(Container& container, const Predicate& predicate) {
6,657,731✔
192
        using std::begin, std::end;
193
        container.erase(std::remove_if(begin(container), end(container), predicate), end(container));
19,973,193✔
194
}
6,657,731✔
195

196
} // 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