CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
utils.hh
Go to the documentation of this file.
1// Copyright Microsoft and CHERIoT Contributors.
2// SPDX-License-Identifier: MIT
3
4/**
5 * \file
6 * \brief Miscellaneous utility functions and classes.
7 */
8
9#pragma once
10
11#include <cdefs.h>
12#include <limits>
13#include <stddef.h>
14#include <stdint.h>
15#include <type_traits>
16
17namespace utils
18{
19 constexpr size_t bytes2bits(size_t in)
20 {
21 return in * __CHAR_BIT__;
22 }
23
24 template<size_t N>
25 constexpr size_t log2()
26 {
27 static_assert(N > 0 && (N & (N - 1)) == 0);
28
29 return 1U + log2<(N >> 1)>();
30 }
31 template<>
32 constexpr size_t log2<1U>()
33 {
34 return 0;
35 }
36
37 template<typename T, size_t N>
38 constexpr size_t array_size(T (&a)[N])
39 {
40 return N;
41 }
42
43 /**
44 * \brief Utility class to delete copy and move contructors.
45 *
46 * Inherit from this if want to prevent your class from being accidentally
47 * copied. This is especially useful for classes used for MMIO as they
48 * must be instantiated at a specific address so copying is a bad idea.
49 *
50 * The default no-argument constructor and destructor is provided.
51 */
52 class NoCopyNoMove
53 {
54 public:
55 NoCopyNoMove() = default;
56 NoCopyNoMove(const NoCopyNoMove &) = delete;
57 NoCopyNoMove &operator=(const NoCopyNoMove &) = delete;
58 NoCopyNoMove(NoCopyNoMove &&) = delete;
59 NoCopyNoMove &operator=(NoCopyNoMove &&) = delete;
60 ~NoCopyNoMove() = default;
61 };
62
63 /**
64 * A helper class modelled on `std::optional` that represents an optional
65 * `T&`. This is stored as a pointer with `nullptr` representing the
66 * not-present version.
67 *
68 * Unlike `std::optional`, this intentionally omits the APIs that make it
69 * possible to access the value without checking that it is present.
70 *
71 * This is intended to be used as an alternative to using bare pointers to
72 * represent `T& | None`.
73 */
74 template<typename T>
76 {
77 /// The pointer to the real value
78 T *pointer;
79
80 public:
81 /**
82 * Construct the optional wrapper from a real value.
83 */
84 __always_inline OptionalReference(T &value) : pointer(&value) {}
85
86 /**
87 * Construct the optional wrapper from not-present value.
88 */
89 OptionalReference(std::nullptr_t) : pointer(nullptr) {}
90
91 /**
92 * Returns a copy of the wrapped value if present or the provided
93 * default value if not.
94 */
95 T value_or(T defaultValue)
96 {
97 if (pointer == nullptr)
98 {
99 return defaultValue;
100 }
101 return *pointer;
102 }
103
104 /**
105 * Returns a reference to the wrapped value if present or the provided
106 * default value if not.
107 */
108 T &value_or(T &defaultValue)
109 {
110 if (pointer == nullptr)
111 {
112 return defaultValue;
113 }
114 return *pointer;
115 }
116
117 /**
118 * If this object holds a value then apply `f` to it and return the
119 * result, otherwise return the result of converting nullptr to the
120 * return type of `f`.
121 */
122 __always_inline auto and_then(auto &&f)
123 {
124 using Result = decltype(f(std::declval<T &>()));
125 if constexpr (std::is_same_v<void, Result>)
126 {
127 if (pointer != nullptr)
128 {
129 f(*pointer);
130 }
131 return;
132 }
133 else
134 {
135 if (pointer != nullptr)
136 {
137 return f(*pointer);
138 }
139 return Result{nullptr};
140 }
141 }
142 };
143
144} // namespace utils
OptionalReference(T &value)
Construct the optional wrapper from a real value.
Definition utils.hh:84
T & value_or(T &defaultValue)
Returns a reference to the wrapped value if present or the provided default value if not.
Definition utils.hh:108
T value_or(T defaultValue)
Returns a copy of the wrapped value if present or the provided default value if not.
Definition utils.hh:95
OptionalReference(std::nullptr_t)
Construct the optional wrapper from not-present value.
Definition utils.hh:89
auto and_then(auto &&f)
If this object holds a value then apply f to it and return the result, otherwise return the result of...
Definition utils.hh:122