16#include <absl/container/flat_hash_map.h>
17#include <absl/container/flat_hash_set.h>
18#include <absl/container/node_hash_map.h>
19#include <absl/container/node_hash_set.h>
30template<
class D,
class S>
32 requires(std::is_trivially_copyable_v<S> && std::is_trivially_copyable_v<D>)
34 if constexpr (
sizeof(D) ==
sizeof(S)) {
35 return std::bit_cast<D>(src);
38 constexpr std::size_t n = (
sizeof(D) <
sizeof(S)) ?
sizeof(D) :
sizeof(S);
39 std::memcpy(&dst, &src, n);
44constexpr std::uint64_t
pad(std::uint64_t offset, std::uint64_t align)
noexcept {
47 auto mod = offset % align;
48 if (mod) offset += align - mod;
55template<
class I,
class T,
class L>
56constexpr I
binary_find(I begin, I end, T val, L lt)
noexcept {
57 static_assert(std::random_access_iterator<I>);
59 if (std::distance(begin, end) < 16)
60 for (i = begin; i != end && lt(*i, val); ++i) {}
62 i = std::lower_bound(begin, end, val, lt);
63 return (i != end && !lt(val, *i)) ? i : end;
67constexpr std::string_view
subview(std::string_view s,
size_t i,
size_t n = std::string_view::npos)
noexcept {
68 n = std::min(n, s.size());
69 return {s.data() + i, n - i};
73inline void find_and_replace(std::string& str, std::string_view what, std::string_view repl) {
74 for (
size_t pos = str.find(what); pos != std::string::npos; pos = str.find(what, pos + repl.size()))
75 str.replace(pos, what.size(), repl);
82auto pop(S& s) ->
decltype(s.top(),
typename S::value_type()) {
89auto pop(Q& q) ->
decltype(q.front(),
typename Q::value_type()) {
98template<
class C,
class K>
99auto lookup(
const C& container,
const K& key) {
100 auto i = container.find(key);
101 if constexpr (std::is_pointer_v<typename C::mapped_type>)
102 return i != container.end() ? i->second :
nullptr;
104 return i != container.end() ? &i->second :
nullptr;
108template<
class C,
class K>
110 auto i = container.find(key);
111 assert(i != container.end());
116template<
class C,
class... Args>
118 auto [i, ins] = container.emplace(std::forward<Args>(args)...);
127 using T =
typename std::remove_reference_t<Set>::value_type;
134 if (done_.emplace(val).second) {
141 bool empty()
const {
return queue_.empty(); }
152 std::queue<T> queue_;
162 constexpr bool operator()(T a, T b)
const noexcept {
return a->gid() < b->gid(); }
168template<
class K,
class V>
using GIDMap = absl::flat_hash_map<K, V, GIDHash<K>>;
169template<
class K>
using GIDSet = absl::flat_hash_set<K, GIDHash<K>>;
170template<
class K,
class V>
using GIDNodeMap = absl::node_hash_map<K, V, GIDHash<K>>;
171template<
class K>
using GIDNodeSet = absl::node_hash_set<K, GIDHash<K>>;
typename std::remove_reference_t< Set >::value_type T
auto pop(S &s) -> decltype(s.top(), typename S::value_type())
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...
constexpr I binary_find(I begin, I end, T val, L lt) noexcept
absl::flat_hash_map< K, V, GIDHash< K > > GIDMap
constexpr std::uint64_t pad(std::uint64_t offset, std::uint64_t align) noexcept
constexpr std::string_view subview(std::string_view s, size_t i, size_t n=std::string_view::npos) noexcept
Like std::string::substr, but works on std::string_view instead.
void find_and_replace(std::string &str, std::string_view what, std::string_view repl)
Replaces all occurrences of what with repl.
constexpr size_t hash(size_t h) noexcept
absl::node_hash_set< K, GIDHash< K > > GIDNodeSet
absl::node_hash_map< K, V, GIDHash< K > > GIDNodeMap
absl::flat_hash_set< K, GIDHash< K > > GIDSet
auto assert_lookup(C &container, const K &key)
Looks up key in container, asserts that it exists, and returns the mapped value.
constexpr D bitcast_resize(const S &src) noexcept
A bitcast from src of type S to D, supporting different sizes.
constexpr size_t operator()(T p) const noexcept
constexpr bool operator()(T a, T b) const noexcept