userver: userver/utils/checked_pointer.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 <stdexcept>
7
8#include <userver/utils/assert.hpp>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace utils {
13
14/// @ingroup userver_universal userver_containers
15///
16/// @brief Utility template for returning a pointer to an object that
17/// is owned by someone else; throws std::runtime_error if nullptr is stored
18///
19/// Useful for returning cache search result.
20template <typename T>
22 public:
23 /* implicit */ constexpr CheckedPtr(std::nullptr_t) noexcept
24 : ptr_{nullptr} {}
25 explicit constexpr CheckedPtr(T* ptr) noexcept : ptr_{ptr} {}
26
27 explicit constexpr operator bool() const noexcept {
28#ifndef NDEBUG
29 checked_ = true;
30#endif
31 return ptr_;
32 }
33
34 T* Get() const& {
35 CheckPointer();
36 return ptr_;
37 }
38
39 T* Get() && { RvalueDisabled(); }
40
41 T* operator->() const& { return Get(); }
42 T* operator->() && { RvalueDisabled(); }
43
44 T& operator*() const& { return *Get(); }
45 T& operator*() && { RvalueDisabled(); }
46
47 private:
48 [[noreturn]] void RvalueDisabled() {
49 static_assert(
50 !sizeof(T),
51 "Don't use temporary CheckedPtr, check it first, then dereference");
52 std::abort();
53 }
54 void CheckPointer() const {
55#ifndef NDEBUG
56 UASSERT_MSG(checked_,
57 "CheckedPtr contents were not checked before dereferencing");
58#endif
59 if (!ptr_) throw std::runtime_error{"Empty checked_pointer"};
60 }
61#ifndef NDEBUG
62 mutable bool checked_{false};
63#endif
64 T* ptr_;
65};
66
67template <typename T>
68class CheckedPtr<T&> {
69 static_assert(!sizeof(T), "Don't use CheckedPointer for references");
70};
71
72template <typename T>
73constexpr CheckedPtr<T> MakeCheckedPtr(T* ptr) noexcept {
74 return CheckedPtr<T>{ptr};
75}
76
77} // namespace utils
78
79USERVER_NAMESPACE_END