Apache Ignite C++ Client
Loading...
Searching...
No Matches
ignite_result.h
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
20#include "ignite_error.h"
21
22#include <functional>
23#include <future>
24#include <optional>
25#include <string>
26#include <variant>
27
28namespace ignite {
29
33template<typename T>
34class ignite_result {
35public:
36 // Default
37 ignite_result() = default;
38
44 ignite_result(T &&value) // NOLINT(google-explicit-constructor)
45 : m_value(std::move(value)) {}
46
52 ignite_result(ignite_error &&error) // NOLINT(google-explicit-constructor)
53 : m_value(std::move(error)) {}
54
60 [[nodiscard]] bool has_value() const noexcept { return !has_error(); }
61
67 [[nodiscard]] bool has_error() const noexcept { return std::holds_alternative<ignite_error>(m_value); }
68
74 [[nodiscard]] T &&value() && {
75 if (!has_value())
76 throw ignite_error("No value is present in result");
77
78 return std::get<T>(std::move(m_value));
79 }
80
86 [[nodiscard]] const T &value() const & {
87 if (!has_value())
88 throw ignite_error("No value is present in result");
89
90 return std::get<T>(m_value);
91 }
92
98 [[nodiscard]] T &value() & {
99 if (!has_value())
100 throw ignite_error("No value is present in result");
101
102 return std::get<T>(m_value);
103 }
104
110 [[nodiscard]] ignite_error &&error() && {
111 if (!has_error())
112 throw ignite_error("No error is present in result");
113
114 return std::move(std::get<ignite_error>(m_value));
115 }
116
122 [[nodiscard]] const ignite_error &error() const & {
123 if (!has_error())
124 throw ignite_error("No error is present in result");
125
126 return std::get<ignite_error>(m_value);
127 }
128
134 [[nodiscard]] ignite_error &error() & {
135 if (!has_error())
136 throw ignite_error("No error is present in result");
137
138 return std::get<ignite_error>(m_value);
139 }
140
147 explicit operator bool() const noexcept { return !has_error(); }
148
149private:
151 std::variant<ignite_error, T> m_value;
152};
153
157template<>
158class ignite_result<void> {
159public:
164 : m_error(std::nullopt) {}
165
171 ignite_result(ignite_error &&error) // NOLINT(google-explicit-constructor)
172 : m_error(std::move(error)) {}
173
179 [[nodiscard]] bool has_error() const noexcept { return m_error.has_value(); }
180
186 [[nodiscard]] ignite_error &&error() {
187 if (!has_error())
188 throw ignite_error("No error is present in result");
189
190 return std::move(m_error.value());
191 }
192
198 [[nodiscard]] const ignite_error &error() const {
199 if (!has_error())
200 throw ignite_error("No error is present in result");
201
202 return m_error.value();
203 }
204
211 explicit operator bool() const noexcept { return !has_error(); }
212
213private:
215 std::optional<ignite_error> m_error;
216};
217
218template<typename T>
219using ignite_callback = std::function<void(ignite_result<T> &&)>;
220
227template<typename T>
228ignite_result<T> result_of_operation(const std::function<T()> &operation) noexcept {
229 try {
230 if constexpr (std::is_same_v<decltype(operation()), void>) {
231 operation();
232 return {};
233 } else {
234 return {operation()};
235 }
236 } catch (const ignite_error &err) {
237 return {ignite_error(err)};
238 } catch (const std::exception &err) {
239 std::string msg("Standard library exception is thrown: ");
240 msg += err.what();
241 return {ignite_error(error::code::INTERNAL, msg, std::current_exception())};
242 } catch (...) {
243 return {ignite_error(error::code::INTERNAL, "Unknown error is encountered",
244 std::current_exception())};
245 }
246}
247
254template<typename T>
255void result_set_promise(std::promise<T> &pr, ignite_result<T> &&res) {
256 if (!res) {
257 pr.set_exception(std::make_exception_ptr(std::move(res).error()));
258 } else {
259 if constexpr (std::is_same_v<T, void>) {
260 pr.set_value();
261 } else {
262 pr.set_value(std::move(res).value());
263 }
264 }
265}
266
273template<typename T>
274std::function<void(ignite_result<T>)> result_promise_setter(std::shared_ptr<std::promise<T>> pr) {
275 return [pr = std::move(pr)](ignite_result<T> &&res) mutable { result_set_promise<T>(*pr, std::move(res)); };
276}
277
284template<typename T>
285T sync(std::function<void(ignite_callback<T>)> func) {
286 auto promise = std::make_shared<std::promise<T>>();
287 func(result_promise_setter(promise));
288 return promise->get_future().get();
289}
290
291} // namespace ignite
Definition ignite_error.h:35
const ignite_error & error() const
Definition ignite_result.h:198
ignite_result(ignite_error &&error)
Definition ignite_result.h:171
ignite_error && error()
Definition ignite_result.h:186
bool has_error() const noexcept
Definition ignite_result.h:179
ignite_result()
Definition ignite_result.h:163
Definition ignite_result.h:34
ignite_result(T &&value)
Definition ignite_result.h:44
ignite_error && error() &&
Definition ignite_result.h:110
bool has_value() const noexcept
Definition ignite_result.h:60
const ignite_error & error() const &
Definition ignite_result.h:122
bool has_error() const noexcept
Definition ignite_result.h:67
T && value() &&
Definition ignite_result.h:74
ignite_result(ignite_error &&error)
Definition ignite_result.h:52
const T & value() const &
Definition ignite_result.h:86
T & value() &
Definition ignite_result.h:98
ignite_error & error() &
Definition ignite_result.h:134