userver: userver/utils/checked_pointer.hpp Source File
Loading...
Searching...
No Matches
checked_pointer.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/checked_pointer.hpp
4/// @brief @copybrief utils::CheckedPtr
5
6#include <cstdlib>
7
8#include <userver/utils/assert.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace utils {
13
14namespace impl {
15[[noreturn]] void ThrowEmptyCheckedPointerException();
16}
17
18/// @ingroup userver_universal userver_containers
19///
20/// @brief Utility template for returning a pointer to an object that
21/// is owned by someone else; throws std::runtime_error if nullptr is stored
22///
23/// Useful for returning cache search result.
24template <typename T>
26public:
27 /* implicit */ constexpr CheckedPtr(std::nullptr_t) noexcept : ptr_{nullptr} {}
28 explicit constexpr CheckedPtr(T* ptr) noexcept : ptr_{ptr} {}
29
30 explicit constexpr operator bool() const noexcept {
31#ifndef NDEBUG
32 checked_ = true;
33#endif
34 return ptr_;
35 }
36
37 T* Get() const& {
38 CheckPointer();
39 return ptr_;
40 }
41
42 T* Get() && { RvalueDisabled(); }
43
44 T* operator->() const& { return Get(); }
45 T* operator->() && { RvalueDisabled(); }
46
47 T& operator*() const& { return *Get(); }
48 T& operator*() && { RvalueDisabled(); }
49
50private:
51 [[noreturn]] void RvalueDisabled() {
52 static_assert(!sizeof(T), "Don't use temporary CheckedPtr, check it first, then dereference");
53 std::abort();
54 }
55 void CheckPointer() const {
56#ifndef NDEBUG
57 UASSERT_MSG(checked_, "CheckedPtr contents were not checked before dereferencing");
58#endif
59 if (!ptr_) {
60 impl::ThrowEmptyCheckedPointerException();
61 }
62 }
63#ifndef NDEBUG
64 mutable bool checked_{false};
65#endif
66 T* ptr_;
67};
68
69template <typename T>
70class CheckedPtr<T&> {
71 static_assert(!sizeof(T), "Don't use CheckedPointer for references");
72};
73
74template <typename T>
75constexpr CheckedPtr<T> MakeCheckedPtr(T* ptr) noexcept {
76 return CheckedPtr<T>{ptr};
77}
78
79} // namespace utils
80
81USERVER_NAMESPACE_END