FE 0.13.1
Header-only C++ frontend library
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 auto val = std::move(s.top());
29 s.pop();
30 return val;
31}
32
33template<Queuelike Q>
34[[nodiscard]] typename Q::value_type pop(Q& q) {
35 auto val = std::move(q.front());
36 q.pop();
37 return val;
38}
39
40/// Yields pointer to element (or the element itself if it is already a pointer), if found and `nullptr` otherwise.
41/// Constness of @p container carries over to the result.
42/// @warning If the element is **not** already a pointer, this lookup will simply take the address of this element.
43/// This means that, e.g., a rehash of an `absl::flat_hash_map` will invalidate this pointer.
44template<class C, class K>
45[[nodiscard]] auto lookup(C& container, const K& key) {
46 auto i = container.find(key);
47 if constexpr (std::is_pointer_v<typename C::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.
54template<class C, class K>
55[[nodiscard]] decltype(auto) assert_lookup(C& container, const K& key) {
56 auto i = container.find(key);
57 assert(i != container.end());
58 return (i->second);
59}
60
61/// Invokes `emplace` on @p container, asserts that insertion actually happened, and returns the iterator.
62template<class C, class... Args>
63auto assert_emplace(C& container, Args&&... args) {
64 auto [i, ins] = container.emplace(std::forward<Args>(args)...);
65 assert_unused(ins);
66 return i;
67}
68///@}
69
70} // namespace fe
#define assert_unused(x)
Definition assert.h:50
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
auto lookup(C &container, const K &key)
Yields pointer to element (or the element itself if it is already a pointer), if found and nullptr ot...
Definition container.h:45
S::value_type pop(S &s)
Definition container.h:27
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
Definition container.h:63
decltype(auto) assert_lookup(C &container, const K &key)
Looks up key in container, asserts that it exists, and returns a reference to the mapped value.
Definition container.h:55