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

celerity / celerity-runtime / 12009876465

25 Nov 2024 12:19PM UTC coverage: 94.911%. Remained the same
12009876465

push

github

fknorr
[RM] fixup includes

3189 of 3626 branches covered (87.95%)

Branch coverage included in aggregate %.

7049 of 7161 relevant lines covered (98.44%)

1541661.11 hits per line

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

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

3
#include "types.h"
4

5
#include <algorithm>
6
#include <cassert>
7
#include <concepts>
8
#include <cstddef>
9
#include <cstdint>
10
#include <functional>
11
#include <string>
12
#include <string_view>
13
#include <tuple>
14
#include <type_traits>
15
#include <typeinfo>
16
#include <utility>
17

18
#include <fmt/format.h>
19

20

21
#define CELERITY_DETAIL_UTILS_CAT_2(a, b) a##b
22
#define CELERITY_DETAIL_UTILS_CAT(a, b) CELERITY_DETAIL_UTILS_CAT_2(a, b)
23

24

25
namespace celerity::detail::utils {
26

27
/// Like std::move, but move-constructs the result so it does not reference the argument after returning.
28
template <typename T>
29
T take(T& from) {
752✔
30
        return std::move(from);
752✔
31
}
32

33
template <typename T, typename P>
34
bool isa(const P* p) {
85,811✔
35
        return dynamic_cast<const T*>(p) != nullptr;
85,811!
36
}
37

38
template <typename T, typename P>
39
auto as(P* p) {
15,988✔
40
        assert(isa<T>(p));
15,988✔
41
        return static_cast<std::conditional_t<std::is_const_v<P>, const T*, T*>>(p);
15,988✔
42
}
43

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

48
        uint32_t counter = 0;
49
        for(auto b = bit_mask; b; b >>= 1) {
50
                counter += b & 1;
51
        }
52
        return counter;
53
}
54

55
// Implementation from Boost.ContainerHash, licensed under the Boost Software License, Version 1.0.
56
inline void hash_combine(std::size_t& seed, std::size_t value) { seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); }
67,826✔
57

58
struct pair_hash {
59
        template <typename U, typename V>
60
        std::size_t operator()(const std::pair<U, V>& p) const {
18,331✔
61
                std::size_t seed = 0;
18,331✔
62
                hash_combine(seed, std::hash<U>{}(p.first));
18,331✔
63
                hash_combine(seed, std::hash<V>{}(p.second));
18,331✔
64
                return seed;
18,331✔
65
        }
66
};
67

68
} // namespace celerity::detail::utils
69

70
namespace celerity::detail::utils_detail {
71

72
template <typename... Without, typename... ToKeep, typename T, typename... Ts>
73
constexpr auto tuple_without_impl(const std::tuple<ToKeep...>& to_keep, const std::tuple<T, Ts...>& to_check) {
74
        if constexpr((std::is_same_v<T, Without> || ...)) {
75
                if constexpr(sizeof...(Ts) == 0) {
76
                        return to_keep;
77
                } else {
78
                        return tuple_without_impl<Without...>(to_keep, std::tuple{std::get<Ts>(to_check)...});
79
                }
80
        } else {
81
                if constexpr(sizeof...(Ts) == 0) {
82
                        return std::tuple_cat(to_keep, to_check);
83
                } else {
84
                        return tuple_without_impl<Without...>(std::tuple_cat(to_keep, std::tuple{std::get<T>(to_check)}), std::tuple{std::get<Ts>(to_check)...});
85
                }
86
        }
87
}
88

89
template <typename Container, typename Key, typename Enable = void>
90
struct has_member_find : std::false_type {};
91

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

95
template <typename Container, typename Key>
96
inline constexpr bool has_member_find_v = has_member_find<Container, Key>::value;
97

98
} // namespace celerity::detail::utils_detail
99

100
namespace celerity::detail::utils {
101

102
/// See `utils::type_switch_t`.
103
template <typename Lookup, typename... KVs>
104
struct type_switch {};
105

106
/// `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), ...>`
107
template <typename Lookup, typename... KVs>
108
using type_switch_t = typename type_switch<Lookup, KVs...>::type;
109

110
template <typename MatchingKey, typename Value, typename... KVs>
111
struct type_switch<MatchingKey, MatchingKey(Value), KVs...> {
112
        using type = Value;
113
};
114

115
template <typename NonMatching, typename Key, typename Value, typename... KVs>
116
struct type_switch<NonMatching, Key(Value), KVs...> {
117
        using type = type_switch_t<NonMatching, KVs...>;
118
};
119

120
template <typename... Without, typename... Ts>
121
constexpr auto tuple_without(const std::tuple<Ts...>& tuple) {
122
        if constexpr(sizeof...(Ts) > 0) {
123
                return utils_detail::tuple_without_impl<Without...>({}, tuple);
124
        } else {
125
                return tuple;
126
        }
127
}
128

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

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

140
/// Escapes "<", ">", and "&" with their corresponding HTML escape sequences
141
std::string escape_for_dot_label(std::string str);
142

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

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

148
[[noreturn]] void unreachable();
149

150
enum class panic_solution {
151
        log_and_abort,     ///< default
152
        throw_logic_error, ///< enabled in unit tests to detect and recover from panics
153
};
154

155
/// Globally and atomically sets the behavior of `utils::panic()`.
156
void set_panic_solution(panic_solution solution);
157

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

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

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

171
/// Ignores, logs, or panics on an error depending on the `error_policy`.
172
template <typename... FmtParams, std::enable_if_t<sizeof...(FmtParams) >= 1, int> = 0>
173
void report_error(const error_policy policy, const fmt::format_string<FmtParams...> fmt_string, FmtParams&&... fmt_args) {
34✔
174
        // TODO also receive a std::source_location with C++20.
175
        if(policy != error_policy::ignore) { report_error(policy, fmt::format(fmt_string, std::forward<FmtParams>(fmt_args)...)); }
87!
176
}
15✔
177

178
template <typename Container>
179
Container set_intersection(const Container& lhs, const Container& rhs) {
289✔
180
        using std::begin, std::end;
181
        assert(std::is_sorted(begin(lhs), end(lhs)));
289✔
182
        assert(std::is_sorted(begin(rhs), end(rhs)));
289✔
183
        Container intersection;
289✔
184
        std::set_intersection(begin(lhs), end(lhs), begin(rhs), end(rhs), std::back_inserter(intersection));
578✔
185
        return intersection;
289✔
186
}
×
187

188
template <typename Container, typename Key>
189
bool contains(const Container& container, const Key& key) {
1,313✔
190
        using std::begin, std::end;
191
        if constexpr(utils_detail::has_member_find_v<Container, Key>) {
192
                return container.find(key) != end(container);
802✔
193
        } else {
194
                return std::find(begin(container), end(container), key) != end(container);
2,736✔
195
        }
196
}
197

198
template <typename Container, typename Predicate>
199
void erase_if(Container& container, const Predicate& predicate) {
200
        using std::begin, std::end;
201
        container.erase(std::remove_if(begin(container), end(container), predicate), end(container));
202
}
203

204
/// Replaces all occurrences of `pattern` in `in` with `with`. If `pattern` is empty, returns the input string unchanged.
205
std::string replace_all(const std::string_view& input, const std::string_view& pattern, const std::string_view& replacement);
206

207
template <std::integral Integral>
208
[[nodiscard]] constexpr Integral ceil(const Integral quantity, const Integral granularity) {
502✔
209
        return (quantity + granularity - 1) / granularity * granularity;
502✔
210
}
211

212
template <typename Void>
213
    requires(std::is_void_v<Void>)
214
[[nodiscard]] constexpr Void* offset(Void* const ptr, const size_t offset_bytes) {
2,039✔
215
        using byte_type = std::conditional_t<std::is_const_v<Void>, const std::byte, std::byte>;
216
        return static_cast<byte_type*>(ptr) + offset_bytes;
2,039✔
217
}
218

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