Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
maybe.h
Go to the documentation of this file.
1
10
11/*
12Copyright (c) 2026 MrXie1109
13
14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal
16in the Software without restriction, including without limitation the rights
17to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18copies of the Software, and to permit persons to whom the Software is
19furnished to do so, subject to the following conditions:
20
21The above copyright notice and this permission notice shall be included in all
22copies or substantial portions of the Software.
23
24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30SOFTWARE.
31*/
32
33#pragma once
34#include <iostream>
35#include <memory>
36#include <utility>
37
38#include "../core/csexc.h"
39
40namespace console {
45 struct nothing_t {};
46
47 static constexpr nothing_t nothing;
48
56 template <class T>
57 class Maybe {
58 std::unique_ptr<T> ptr;
59
60 public:
62 Maybe() : ptr(nullptr) {}
63
69 template <class First,
70 class... Rest,
71 class = typename std::enable_if<
72 sizeof...(Rest) != 0
73 || !std::is_same<typename std::decay<First>::type,
74 Maybe>::value>::type>
75 Maybe(First &&first, Rest &&...args) :
76 ptr(new T(
77 std::forward<First>(first), std::forward<Rest>(args)...)) {}
78
84 Maybe(const Maybe &other) :
85 ptr(other.ptr ? new T(other.value()) : nullptr) {}
86
91 Maybe(Maybe &&other) : ptr(std::move(other.ptr)) {}
92
97 Maybe(decltype(nothing)) : ptr(nullptr) {}
98
104 T &value() {
105 if (ptr) return *ptr;
106 throw TypeError("Nothing");
107 }
108
114 const T &value() const {
115 if (ptr) return *ptr;
116 throw TypeError("Nothing");
117 }
118
124 const Maybe &operator=(const T &value) {
125 ptr.reset(new T(value));
126 return *this;
127 }
128
134 const Maybe &operator=(T &&value) {
135 ptr.reset(new T(std::move(value)));
136 return *this;
137 }
138
144 Maybe &operator=(const Maybe &other) {
145 if (this != &other)
146 ptr.reset(other.ptr ? new T(*other.ptr) : nullptr);
147 return *this;
148 }
149
155 Maybe &operator=(Maybe &&other) noexcept {
156 if (this != &other) ptr = std::move(other.ptr);
157 return *this;
158 }
159
165 const Maybe &operator=(decltype(nothing)) {
166 ptr = nullptr;
167 return *this;
168 }
169
173 void reset() { ptr.reset(); }
174
180 template <class... Args>
181 void reset(Args &&...args) {
182 ptr.reset(new T(std::forward<Args>(args)...));
183 }
184
191 friend std::ostream &operator<<(std::ostream &os, const Maybe &maybe) {
192 if (maybe.ptr) return os << maybe.value();
193 return os << "(nothing)";
194 }
195
204 friend std::istream &operator>>(std::istream &is, Maybe &maybe) {
205 T tmp;
206 if (is >> tmp)
207 maybe.reset(std::move(tmp));
208 else {
209 maybe = nothing;
210 is.clear();
211 }
212 return is;
213 }
214
219 explicit operator bool() const noexcept { return bool(ptr); }
220
225 bool has_value() const noexcept { return bool(ptr); }
226
228 T &operator*() { return *ptr; }
229
231 const T &operator*() const { return *ptr; }
232
234 T *operator->() { return ptr.get(); }
235
237 const T *operator->() const { return ptr.get(); }
238
245 template <class U>
246 T value_or(U &&default_value) const {
247 return ptr ? *ptr : T(std::forward<U>(default_value));
248 }
249
254 void swap(Maybe &other) noexcept { ptr.swap(other.ptr); }
255 };
256}
可选值容器,可包含一个值或为空。
Definition maybe.h:57
const Maybe & operator=(T &&value)
从 T 值赋值(移动)。
Definition maybe.h:134
friend std::ostream & operator<<(std::ostream &os, const Maybe &maybe)
输出 Maybe 到流。若包含值则输出值,否则输出 "(nothing)"。
Definition maybe.h:191
Maybe & operator=(Maybe &&other) noexcept
移动赋值。
Definition maybe.h:155
Maybe & operator=(const Maybe &other)
拷贝赋值。
Definition maybe.h:144
const T & operator*() const
解引用获取值(常量),前置条件:has_value() 为 true。
Definition maybe.h:231
bool has_value() const noexcept
检查 Maybe 是否包含值。
Definition maybe.h:225
T * operator->()
成员访问运算符(非常量),前置条件:has_value() 为 true。
Definition maybe.h:234
const T * operator->() const
成员访问运算符(常量),前置条件:has_value() 为 true。
Definition maybe.h:237
T & operator*()
解引用获取值(非常量),前置条件:has_value() 为 true。
Definition maybe.h:228
Maybe(First &&first, Rest &&...args)
从参数包直接构造一个包含值的 Maybe。
Definition maybe.h:75
friend std::istream & operator>>(std::istream &is, Maybe &maybe)
从流读取一个值到 Maybe。
Definition maybe.h:204
T value_or(U &&default_value) const
返回当前值,若为空则返回提供的默认值。
Definition maybe.h:246
void swap(Maybe &other) noexcept
交换两个 Maybe 的内容。
Definition maybe.h:254
const T & value() const
获取内部值的引用(常量)。
Definition maybe.h:114
std::unique_ptr< T > ptr
实际存储的指针,为空表示 nothing。
Definition maybe.h:58
T & value()
获取内部值的引用(非常量)。
Definition maybe.h:104
const Maybe & operator=(const T &value)
从 T 值赋值(拷贝)。
Definition maybe.h:124
Maybe(Maybe &&other)
移动构造,转移所有权。
Definition maybe.h:91
void reset(Args &&...args)
重置为新的值(从参数包构造)。
Definition maybe.h:181
Maybe(decltype(nothing))
从 nothing 标记构造空 Maybe。
Definition maybe.h:97
Maybe()
默认构造一个空 Maybe。
Definition maybe.h:62
const Maybe & operator=(decltype(nothing))
赋值为空(nothing)。
Definition maybe.h:165
Maybe(const Maybe &other)
拷贝构造,深拷贝内部值。
Definition maybe.h:84
void reset()
清空 Maybe,使其为空。
Definition maybe.h:173
TypeError(const std::string &msg)
构造 TypeError。
Definition csexc.h:102
定义 console 库使用的自定义异常类层次结构。
本库所有组件所在的顶层命名空间。
@ T
Definition kb.h:99
static constexpr nothing_t nothing
Definition maybe.h:47
空状态标记对象,用于显式构造空的 Maybe。
Definition maybe.h:45