8#include <absl/container/flat_hash_map.h>
9#include <absl/container/flat_hash_set.h>
10#include <absl/container/node_hash_map.h>
11#include <absl/container/node_hash_set.h>
21template<
class This,
class T>
inline T&
lazy_init(
const This* self, std::unique_ptr<T>& ptr) {
22 return *(ptr ? ptr : ptr = std::make_unique<T>(*self));
26template<
class D,
class S>
inline D
bitcast(
const S& src) {
28 auto s =
reinterpret_cast<const void*
>(&src);
29 auto d =
reinterpret_cast<void*
>(&dst);
31 if constexpr (
sizeof(D) ==
sizeof(S)) std::memcpy(d, s,
sizeof(D));
32 if constexpr (
sizeof(D) <
sizeof(S)) std::memcpy(d, s,
sizeof(D));
33 if constexpr (
sizeof(D) >
sizeof(S)) {
34 std::memset(d, 0,
sizeof(D));
35 std::memcpy(d, s,
sizeof(S));
41 static_assert(std::is_integral<T>(),
"get_sign only supported for signed and unsigned integer types");
42 if constexpr (std::is_signed<T>())
45 return val >> (T(
sizeof(val)) * T(8) - T(1));
50 auto mod = offset % align;
51 if (mod != 0) offset += align - mod;
58template<
class I,
class T,
class Cmp> I
binary_find(I begin, I end, T val, Cmp cmp) {
59 auto i = std::lower_bound(begin, end, val, cmp);
60 return (i != end && !(cmp(val, *i))) ? i : end;
64inline std::string_view
subview(std::string_view s,
size_t i,
size_t n = std::string_view::npos) {
65 n = std::min(n, s.size());
66 return {s.data() + i, n - i};
70inline void find_and_replace(std::string& str, std::string_view what, std::string_view repl) {
71 for (
size_t pos = str.find(what); pos != std::string::npos; pos = str.find(what, pos + repl.size()))
72 str.replace(pos, what.size(), repl);
78template<
class S>
auto pop(S& s) ->
decltype(s.top(),
typename S::value_type()) {
84template<
class Q>
auto pop(Q& q) ->
decltype(q.front(),
typename Q::value_type()) {
93template<
class C,
class K>
auto lookup(
const C& container,
const K& key) {
94 auto i = container.find(key);
95 if constexpr (std::is_pointer_v<typename C::mapped_type>)
96 return i != container.end() ? i->second :
nullptr;
98 return i != container.end() ? &i->second :
nullptr;
102template<
class C,
class... Args>
auto assert_emplace(C& container, Args&&... args) {
103 auto [i, ins] = container.emplace(std::forward<Args&&>(args)...);
111 using T =
typename std::remove_reference_t<Set>::value_type;
114 if (done_.emplace(val).second) {
121 bool empty()
const {
return stack_.empty(); }
122 const T&
top() {
return stack_.top(); }
131 std::stack<T> stack_;
136 using T =
typename std::remove_reference_t<Set>::value_type;
143 if (done_.emplace(val).second) {
150 bool empty()
const {
return queue_.empty(); }
161 std::queue<T> queue_;
169 bool operator()(T a, T b)
const {
return a->gid() == b->gid(); }
173 bool operator()(T a, T b)
const {
return a->gid() < b->gid(); }
179template<
class K,
class V>
using GIDMap = absl::flat_hash_map<K, V, GIDHash<K>,
GIDEq<K>>;
typename std::remove_reference_t< Set >::value_type T
typename std::remove_reference_t< Set >::value_type T
auto pop(S &s) -> decltype(s.top(), typename S::value_type())
D bitcast(const S &src)
A bitcast from src of type S to D.
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
auto lookup(const C &container, const K &key)
Yields pointer to element (or the element itself if it is already a pointer), if found and nullptr ot...
u64 pad(u64 offset, u64 align)
absl::flat_hash_set< K, GIDHash< K >, GIDEq< K > > GIDSet
T & lazy_init(const This *self, std::unique_ptr< T > &ptr)
hash_t murmur3(hash_t h, uint32_t key)
void find_and_replace(std::string &str, std::string_view what, std::string_view repl)
Replaces all occurrences of what with repl.
absl::node_hash_set< K, GIDHash< K >, GIDEq< K > > GIDNodeSet
absl::flat_hash_map< K, V, GIDHash< K >, GIDEq< K > > GIDMap
absl::node_hash_map< K, V, GIDHash< K >, GIDEq< K > > GIDNodeMap
I binary_find(I begin, I end, T val, Cmp cmp)
std::string_view subview(std::string_view s, size_t i, size_t n=std::string_view::npos)
Like std::string::substr, but works on std::string_view instead.
bool operator()(T a, T b) const
size_t operator()(T p) const
bool operator()(T a, T b) const