Skip to content

Commit 8e9d06e

Browse files
committed
optional
Signed-off-by: turuslan <[email protected]>
1 parent 34c487a commit 8e9d06e

File tree

9 files changed

+167
-88
lines changed

9 files changed

+167
-88
lines changed

example/snp_chat/main.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ struct ChatController : ConnectionsController {
107107
fmt::println("#{} > {}", i_msg, msg);
108108
}
109109

110-
Coro<void> broadcast(std::optional<size_t> i_read,
110+
Coro<void> broadcast(qtils::Optional<size_t> i_read,
111111
size_t i_msg,
112112
std::string msg) {
113113
for (auto &[i_write, writer] : writers) {
@@ -152,7 +152,7 @@ struct ChatController : ConnectionsController {
152152
struct Input {
153153
Input(IoContextPtr io_context_ptr) : fd_{*io_context_ptr, STDIN_FILENO} {}
154154

155-
Coro<std::optional<std::string>> read() {
155+
Coro<qtils::Optional<std::string>> read() {
156156
auto [ec, n] = co_await boost::asio::async_read_until(
157157
fd_, buf_, "\n", boost::asio::as_tuple(boost::asio::use_awaitable));
158158
if (ec) {
@@ -175,7 +175,7 @@ struct Input {
175175
CoroOutcome<void> co_main(IoContextPtr io_context_ptr, size_t arg_i) {
176176
fmt::println("#{} (self)", arg_i);
177177

178-
std::optional<Port> listen_port;
178+
qtils::Optional<Port> listen_port;
179179
GenesisHash genesis;
180180
ConnectionsConfig config{genesis, keys.at(arg_i)};
181181
auto is_server = arg_i == 0;
@@ -189,7 +189,7 @@ CoroOutcome<void> co_main(IoContextPtr io_context_ptr, size_t arg_i) {
189189
Input input{io_context_ptr};
190190
while (true) {
191191
auto msg = co_await input.read();
192-
if (not msg) {
192+
if (not msg.has_value()) {
193193
break;
194194
}
195195
msg->resize(std::min(msg->size(), ChatController::kMaxMsg));
@@ -216,10 +216,9 @@ CoroOutcome<void> co_main(IoContextPtr io_context_ptr, size_t arg_i) {
216216
[chat](ConnectionInfo info, StreamPtr stream) -> CoroOutcome<void> {
217217
co_return co_await chat->add(info, stream);
218218
});
219-
std::optional<CoroHandler<void>> work_guard;
220-
co_await coroHandler<void>([&](CoroHandler<void> &&handler) {
221-
work_guard.emplace(std::move(handler));
222-
});
219+
qtils::Optional<CoroHandler<void>> work_guard;
220+
co_await coroHandler<void>(
221+
[&](CoroHandler<void> &&handler) { work_guard = std::move(handler); });
223222
}
224223
co_return outcome::success();
225224
}

src/TODO_qtils/from_span.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <optional>
1111
#include <stdexcept>
1212

13+
#include <TODO_qtils/optional.hpp>
1314
#include <qtils/bytes.hpp>
1415

1516
namespace qtils {
@@ -22,7 +23,7 @@ namespace qtils {
2223
}
2324

2425
template <typename T>
25-
std::optional<T> fromSpan(BytesIn span) {
26+
Optional<T> fromSpan(BytesIn span) {
2627
T out;
2728
if (not fromSpan(out, span)) {
2829
return std::nullopt;

src/TODO_qtils/optional.hpp

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright Quadrivium LLC
3+
* All Rights Reserved
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <optional>
10+
11+
namespace qtils {
12+
/**
13+
* `std::optional` wrapper.
14+
* Becomes `std::nullopt` when moved from.
15+
* `std::nullopt` throws on access to value.
16+
* Requires to write `.has_value()`.
17+
* Can be move assigned for move only types.
18+
*/
19+
template <typename T>
20+
class Optional {
21+
public:
22+
Optional() : value_{std::nullopt} {}
23+
24+
Optional(const std::nullopt_t &) : value_{std::nullopt} {}
25+
26+
Optional(const T &value) : value_{value} {}
27+
void operator=(const T &value) {
28+
value_.emplace(value);
29+
}
30+
31+
Optional(T &&value) : value_{std::move(value)} {}
32+
void operator=(T &&value) {
33+
value_.emplace(std::move(value));
34+
}
35+
36+
Optional(const Optional<T> &other) : value_{other.value_} {}
37+
void operator=(const Optional<T> &other) {
38+
value_ = other.value_;
39+
}
40+
41+
Optional(Optional<T> &&other)
42+
: value_{std::exchange(other.value_, std::nullopt)} {}
43+
void operator=(Optional<T> &&other) {
44+
if (other.value_.has_value()) {
45+
value_.emplace(std::exchange(other.value_, std::nullopt).value());
46+
} else {
47+
value_.reset();
48+
}
49+
}
50+
51+
bool has_value() const {
52+
return value_.has_value();
53+
}
54+
55+
T &operator*() {
56+
return value_.value();
57+
}
58+
const T &operator*() const {
59+
return value_.value();
60+
}
61+
T *operator->() {
62+
return &value_.value();
63+
}
64+
const T *operator->() const {
65+
return &value_.value();
66+
}
67+
68+
Optional<T> take() {
69+
return std::exchange(*this, Optional<T>{});
70+
}
71+
72+
bool operator==(const T &value) const {
73+
return value_ == value;
74+
}
75+
76+
private:
77+
std::optional<T> value_;
78+
};
79+
} // namespace qtils

src/crypto/ed25519.hpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,12 @@ namespace jam::crypto::ed25519 {
4747
}
4848

4949
inline Public get_public(const KeyPair &keypair) {
50-
return qtils::fromSpan<Public>(
51-
std::span{keypair}.subspan(ED25519_SECRET_KEY_LENGTH))
52-
.value();
50+
return *qtils::fromSpan<Public>(
51+
std::span{keypair}.subspan(ED25519_SECRET_KEY_LENGTH));
5352
}
5453

5554
inline Public get_secret(const KeyPair &keypair) {
56-
return qtils::fromSpan<Secret>(
57-
std::span{keypair}.first(ED25519_SECRET_KEY_LENGTH))
58-
.value();
55+
return *qtils::fromSpan<Secret>(
56+
std::span{keypair}.first(ED25519_SECRET_KEY_LENGTH));
5957
}
6058
} // namespace jam::crypto::ed25519

src/snp/connections/config.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ namespace jam::snp {
1515
// https://github.com/zdave-parity/jam-np/blob/5d374b53578cdd93646e3ee19e2b19ea132317b8/simple.md?plain=1#L30-L35
1616
GenesisHash genesis;
1717
crypto::ed25519::KeyPair keypair;
18-
std::optional<Port> listen_port;
18+
qtils::Optional<Port> listen_port;
1919
};
2020
} // namespace jam::snp

src/snp/connections/connections.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ namespace jam::snp {
4545
certificate,
4646
std::nullopt,
4747
self));
48-
if (self->config_.listen_port) {
48+
if (self->config_.listen_port.has_value()) {
4949
BOOST_OUTCOME_CO_TRY(self->server_,
5050
lsquic::Engine::make(self->io_context_ptr_,
5151
self->connection_id_counter_,

src/snp/connections/connections.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ namespace jam::snp {
8181
Key key_;
8282
std::weak_ptr<ConnectionsController> controller_;
8383
std::shared_ptr<lsquic::Engine> client_;
84-
std::optional<std::shared_ptr<lsquic::Engine>> server_;
84+
qtils::Optional<std::shared_ptr<lsquic::Engine>> server_;
8585
std::unordered_map<Key,
8686
std::variant<Connecting, Connected>,
8787
qtils::BytesStdHash>

0 commit comments

Comments
 (0)