DocWire SDK
DocWire SDK: Award-winning modern data processing in C++20. SourceForge Community Choice & Microsoft support. AI-driven processing. Supports nearly 100 data formats, including email boxes and OCR. Boost efficiency in text extraction, web data extraction, data mining, document analysis. Offline processing possible for security and confidentiality
checked.h
1 /*********************************************************************************************************************************************/
2 /* DocWire SDK: Award-winning modern data processing in C++20. SourceForge Community Choice & Microsoft support. AI-driven processing. */
3 /* Supports nearly 100 data formats, including email boxes and OCR. Boost efficiency in text extraction, web data extraction, data mining, */
4 /* document analysis. Offline processing possible for security and confidentiality */
5 /* */
6 /* Copyright (c) SILVERCODERS Ltd, http://silvercoders.com */
7 /* Project homepage: https://github.com/docwire/docwire */
8 /* */
9 /* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-DocWire-Commercial */
10 /*********************************************************************************************************************************************/
11 
12 #ifndef DOCWIRE_CHECKED_H
13 #define DOCWIRE_CHECKED_H
14 
15 #include "safety_policy.h"
16 #include "enforce.h"
17 #include <utility>
18 #include <type_traits>
19 
20 namespace docwire
21 {
22 
37 template <typename Dereferenceable, safety_policy safety_level = default_safety_level>
38 class checked
39 {
40 public:
44  checked() = default;
49  checked(const Dereferenceable& value) : m_value(value) {}
53  checked(Dereferenceable&& value) noexcept(std::is_nothrow_move_constructible_v<Dereferenceable>) : m_value(std::move(value)) {}
54 
58  template <typename... Args,
59  typename = std::enable_if_t<
60  std::is_constructible_v<Dereferenceable, Args...> &&
61  (sizeof...(Args) > 1 ||
62  (sizeof...(Args) == 1 &&
63  ((!std::is_same_v<std::decay_t<Args>, checked> &&
64  !std::is_same_v<std::decay_t<Args>, Dereferenceable>) && ...)))
65  >>
66  checked(Args&&... args)
67  : m_value(std::forward<Args>(args)...) {}
68 
69  checked& operator=(const Dereferenceable& value) { m_value = value; return *this; }
70  checked& operator=(Dereferenceable&& value) noexcept(std::is_nothrow_move_assignable_v<Dereferenceable>) { m_value = std::move(value); return *this; }
71 
73  const auto& operator*() const
74  {
75  enforce<safety_level>(static_cast<bool>(m_value), "Attempted to dereference a null/empty value");
76  return *m_value;
77  }
78 
80  auto& operator*()
81  {
82  enforce<safety_level>(static_cast<bool>(m_value), "Attempted to dereference a null/empty value");
83  return *m_value;
84  }
85 
87  auto operator->() const
88  {
89  enforce<safety_level>(static_cast<bool>(m_value), "Attempted to dereference a null/empty value");
90  return &this->operator*();
91  }
92 
93  // Forwarded methods
95  explicit operator bool() const noexcept { return static_cast<bool>(m_value); }
97  auto get() const requires requires(const Dereferenceable& v) { v.get(); } { return m_value.get(); }
98 
100  bool has_value() const noexcept(noexcept(std::declval<const Dereferenceable&>().has_value()))
101  requires requires(const Dereferenceable& v) { v.has_value(); }
102  {
103  return m_value.has_value();
104  }
105 
107  constexpr decltype(auto) value() const
108  noexcept(noexcept(std::declval<const Dereferenceable&>().value()))
109  requires requires(const Dereferenceable& v) { v.value(); }
110  {
111  return m_value.value();
112  }
113 
115  constexpr decltype(auto) value()
116  noexcept(noexcept(std::declval<Dereferenceable&>().value()))
117  requires requires(Dereferenceable& v) { v.value(); }
118  {
119  return m_value.value();
120  }
121 
123  template <typename U>
124  constexpr auto value_or(U&& default_value) const
125  noexcept(noexcept(std::declval<const Dereferenceable&>().value_or(std::forward<U>(default_value))))
126  requires requires(const Dereferenceable& v) { v.value_or(std::forward<U>(default_value)); }
127  {
128  return m_value.value_or(std::forward<U>(default_value));
129  }
130 
132  template<typename... Args>
133  void reset(Args&&... args) noexcept(noexcept(std::declval<Dereferenceable&>().reset(std::forward<Args>(args)...))) requires requires(Dereferenceable& v, Args&&... a) { v.reset(std::forward<Args>(a)...); }
134  {
135  m_value.reset(std::forward<Args>(args)...);
136  }
137 
139  template<class... Args>
140  auto& emplace(Args&&... args) requires requires(Dereferenceable& v, Args&&... a) { v.emplace(std::forward<Args>(a)...); }
141  {
142  return m_value.emplace(std::forward<Args>(args)...);
143  }
144 
146  constexpr const Dereferenceable& unwrap() const & noexcept { return m_value; }
147  constexpr Dereferenceable& unwrap() & noexcept { return m_value; }
148  constexpr Dereferenceable&& unwrap() && noexcept { return std::move(m_value); }
149 
150  explicit constexpr operator const Dereferenceable&() const & noexcept { return m_value; }
151  explicit constexpr operator Dereferenceable&() & noexcept { return m_value; }
152  explicit constexpr operator Dereferenceable&&() && noexcept { return std::move(m_value); }
153 
155  template <typename U>
156  friend constexpr bool operator==(const checked& lhs, const U& rhs)
157  requires (!std::is_same_v<std::decay_t<U>, checked>) &&
158  requires { std::declval<const Dereferenceable&>() == rhs; }
159  {
160  return lhs.m_value == rhs;
161  }
162 
164  friend constexpr bool operator==(const checked& lhs, const checked& rhs)
165  requires requires { std::declval<const Dereferenceable&>() == std::declval<const Dereferenceable&>(); }
166  {
167  return lhs.m_value == rhs.m_value;
168  }
169 
170 private:
171  Dereferenceable m_value;
172 };
173 
174 } // namespace docwire
175 
176 #endif // DOCWIRE_CHECKED_H
A generic wrapper for dereferenceable types (like pointers and optionals) that provides checked acces...
Definition: checked.h:39
checked()=default
Default constructor.
constexpr auto value_or(U &&default_value) const noexcept(noexcept(std::declval< const Dereferenceable & >().value_or(std::forward< U >(default_value)))) requires requires(const Dereferenceable &v)
Returns the contained value or a default value if empty.
Definition: checked.h:124
bool has_value() const noexcept(noexcept(std::declval< const Dereferenceable & >().has_value())) requires requires(const Dereferenceable &v)
Checks if the underlying object has a value.
Definition: checked.h:100
auto get() const requires requires(const Dereferenceable &v)
Returns the raw underlying pointer/value without checks.
Definition: checked.h:97
checked(Dereferenceable &&value) noexcept(std::is_nothrow_move_constructible_v< Dereferenceable >)
Move-constructs from a value.
Definition: checked.h:53
auto & emplace(Args &&... args) requires requires(Dereferenceable &v
Constructs the underlying value in-place.
constexpr friend bool operator==(const checked &lhs, const checked &rhs) requires requires
Compares the underlying values of two checked wrappers.
Definition: checked.h:164
constexpr decltype(auto) value() const noexcept(noexcept(std::declval< const Dereferenceable & >().value())) requires requires(const Dereferenceable &v)
Returns the value, potentially throwing if empty (forwarding underlying behavior).
Definition: checked.h:107
void reset(Args &&... args) noexcept(noexcept(std::declval< Dereferenceable & >().reset(std::forward< Args >(args)...))) requires requires(Dereferenceable &v
Resets the underlying value.
constexpr friend bool operator==(const checked &lhs, const U &rhs) requires(!std
Compares the underlying value with another value.
Definition: checked.h:156
auto operator->() const
Returns a pointer to the underlying value, checking for validity in strict mode.
Definition: checked.h:87
checked(Args &&... args)
Forwards arguments to construct the underlying object in-place.
Definition: checked.h:66
const auto & operator*() const
Returns a reference to the underlying value, checking for validity in strict mode.
Definition: checked.h:73
auto & operator*()
Returns a reference to the underlying value, checking for validity in strict mode.
Definition: checked.h:80
constexpr const Dereferenceable & unwrap() const &noexcept
Unwraps the checked wrapper to return the underlying object.
Definition: checked.h:146
checked(const Dereferenceable &value)
Constructs from a value. Implicit conversion is allowed to support seamless wrapping of null-like typ...
Definition: checked.h:49
The main namespace for the DocWire SDK.
Definition: ai_elements.h:19
requires(!string_method_equipped< T >) struct stringifier< T >
Specialization for types that are streamable to std::ostream.