FE 0.16.1
Fast, Effecient FrontEnds
Loading...
Searching...
No Matches
container.h
Go to the documentation of this file.
1#pragma once
2
3#include <type_traits>
4#include <utility>
5
6#include "fe/assert.h"
7
8namespace fe {
9
10/// Something which behaves like `std::stack` or `std::priority_queue`.
11template<class C>
12concept Stacklike = requires(C c) {
13 c.top();
14 c.pop();
15};
16
17/// Something which behaves like `std::queue`.
18template<class C>
19concept Queuelike = requires(C c) {
20 c.front();
21 c.pop();
22};
23
24/// @name Helpers for Containers
25///@{
26template<Stacklike S>
27[[nodiscard]] typename S::value_type pop(S& s) {
28 // std::priority_queue::top is const, but pop_heap moves the top out of the heap before it compares anything.
29 auto val = std::move(const_cast<typename S::value_type&>(s.top()));
30 s.pop();
31 return val;
32}
33
34template<Queuelike Q>
35[[nodiscard]] typename Q::value_type pop(Q& q) {
36 auto val = std::move(q.front());
37 q.pop();
38 return val;
39}
40
41/// Yields a pointer to the value mapped to @p key (or the value itself if it is a pointer) or `nullptr` if not found.
42/// Constness of @p container carries over to the result.
43/// @warning If the mapped value is **not** already a pointer, this lookup will simply take its address.
44/// This means that, e.g., a rehash of an `ankerl::unordered_dense::map` will invalidate this pointer.
45[[nodiscard]] auto lookup(auto& container, const auto& key) {
46 auto i = container.find(key);
47 if constexpr (std::is_pointer_v<typename std::remove_cvref_t<decltype(container)>::mapped_type>)
48 return i != container.end() ? i->second : nullptr;
49 else
50 return i != container.end() ? &i->second : nullptr;
51}
52
53/// Looks up @p key in @p container, asserts that it exists, and returns a reference to the mapped value.
54[[nodiscard]] decltype(auto) assert_lookup(auto& container, const auto& key) {
55 auto i = container.find(key);
56 assert(i != container.end());
57 return (i->second);
58}
59
60/// Invokes `emplace` on @p container, asserts that insertion actually happened, and returns the iterator.
61auto assert_emplace(auto& container, auto&&... args) {
62 auto [i, ins] = container.emplace(std::forward<decltype(args)>(args)...);
63 assert_unused(ins);
64 return i;
65}
66///@}
67
68} // namespace fe
#define assert_unused(x)
Definition assert.h:27
Something which behaves like std::queue.
Definition container.h:19
Something which behaves like std::stack or std::priority_queue.
Definition container.h:12
Definition algo.h:17
S::value_type pop(S &s)
Definition container.h:27
auto assert_emplace(auto &container, auto &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
Definition container.h:61
decltype(auto) assert_lookup(auto &container, const auto &key)
Looks up key in container, asserts that it exists, and returns a reference to the mapped value.
Definition container.h:54
auto lookup(auto &container, const auto &key)
Yields a pointer to the value mapped to key (or the value itself if it is a pointer) or nullptr if no...
Definition container.h:45