diff --git a/include/async_promise.hpp b/include/async_promise.hpp index 0ace7bf..b00532f 100644 --- a/include/async_promise.hpp +++ b/include/async_promise.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -234,23 +235,29 @@ auto apply(Func&& func, Tuple&& tuple) -> decltype(apply(std::forward(func return apply(std::forward(func), std::forward(tuple), Seq{}); } + +template +struct is_invocable : + std::is_constructible, std::reference_wrapper::type>> +{}; + #else using std::apply; +using std::is_invocable; #endif template -class task +struct task { - public: - task() = default; - task(const task&) = default; - task(task&&) = default; - task& operator=(const task&) = default; - task& operator=(task&&) = default; - virtual ~task() = default; - - virtual Result run() = 0; + task() = default; + task(const task&) = default; + task(task&&) = default; + task& operator=(const task&) = default; + task& operator=(task&&) = default; + virtual ~task() = default; + + virtual Result run() = 0; }; @@ -258,64 +265,140 @@ template using task_ptr = std::shared_ptr>; -class promise_helper +struct promise_helper { - public: - static void resolve(std::promise& promise) + static void resolve(std::promise& promise) + { + try { - try - { - promise.set_value(); - } - catch(...) - {} + promise.set_value(); } + catch(...) + {} + } - template - static void resolve(std::promise& promise, Value&& val) + template + static void resolve(std::promise& promise, Value&& val) + { + try { - try - { - promise.set_value(std::forward(val)); - } - catch(...) - {} + promise.set_value(std::forward(val)); } + catch(...) + {} + } - template - static void reject(std::promise& promise, std::exception_ptr err) + template + static void reject(std::promise& promise, std::exception_ptr err) + { + try { - try - { - promise.set_exception(std::move(err)); - } - catch(...) - {} + promise.set_exception(std::move(err)); + } + catch(...) + {} + } +}; + + +struct vector_helper +{ + template + static void reserve(T&, std::size_t) + {} + + template + static void reserve(std::vector& v, std::size_t n) + { + v.reserve(n); + } +}; + + +template +struct class_method_call_helper +{ + template + T call(Method&& method, Class* obj, Tuple&& tpl) + { + using tuple_t = typename std::decay::type; + using impl_t = impl::value, std::tuple_size::value>; + return impl_t::call(std::forward(method), obj, std::forward(tpl)); + } + + template + struct impl + { + static T call(Method&& method, Class* obj, Tuple&& tpl) + { + using impl_t = impl; + return impl_t::call(std::forward(method), obj, std::forward(tpl)); } + }; + + template + struct impl + { + static T call(Method&& method, Class* obj, Tuple&& tpl) + { + return (obj->*method)(std::get(std::forward(tpl))...); + } + }; }; -class vector_helper +template +class initial_class_task final : public task, public class_method_call_helper { public: - template - static void reserve(T&, std::size_t) + template + explicit initial_class_task(Method_&& method, Class* obj, Args_&&... args) + : m_method{std::forward(method)} + , m_obj{obj} + , m_args{std::forward(args)...} {} - template - static void reserve(std::vector& v, std::size_t n) + Result run() final { - v.reserve(n); + return this->call(m_method, m_obj, m_args); } + + private: + Method m_method; + Class* const m_obj; + std::tuple m_args; +}; + + +template +class initial_class_task final : public task, public class_method_call_helper +{ + public: + template + explicit initial_class_task(Method_&& method, Class* obj, Args_&&... args) + : m_method{std::forward(method)} + , m_obj{obj} + , m_args{std::forward(args)...} + {} + + void run() final + { + this->call(m_method, m_obj, m_args); + } + + private: + Method m_method; + Class* const m_obj; + std::tuple m_args; }; template -class initial_task final : public task +class initial_func_task final : public task { public: template - explicit initial_task(Func_&& func, Args_&&... args) + explicit initial_func_task(Func_&& func, Args_&&... args) : m_func{std::forward(func)} , m_args{std::forward(args)...} {} @@ -332,11 +415,11 @@ class initial_task final : public task template -class initial_task final : public task +class initial_func_task final : public task { public: template - explicit initial_task(Func_&& func, Args_&&... args) + explicit initial_func_task(Func_&& func, Args_&&... args) : m_func{std::forward(func)} , m_args{std::forward(args)...} {} @@ -365,12 +448,57 @@ class next_task : public task }; +template +class then_class_task final : public next_task +{ + public: + template + then_class_task(task_ptr parent, Method_&& method, Class* obj) + : next_task{std::move(parent)} + , m_method{std::forward(method)} + , m_obj{obj} + {} + + Result run() final + { + return (m_obj->*m_method)(this->m_parent->run()); + } + + private: + Method m_method; + Class* const m_obj; +}; + + +template +class then_class_task_void final : public next_task +{ +public: + template + then_class_task_void(task_ptr parent, Method_&& method, Class* obj) + : next_task{std::move(parent)} + , m_method{std::forward(method)} + , m_obj{obj} + {} + + Result run() final + { + this->m_parent->run(); + return (m_obj->*m_method)(); + } + +private: + Method m_method; + Class* const m_obj; +}; + + template -class then_task final : public next_task +class then_func_task final : public next_task { public: template - then_task(task_ptr parent, T&& func) + then_func_task(task_ptr parent, T&& func) : next_task{std::move(parent)} , m_func{std::forward(func)} {} @@ -386,11 +514,11 @@ class then_task final : public next_task template -class then_task_void final : public next_task +class then_func_task_void final : public next_task { public: template - then_task_void(task_ptr parent, T&& func) + then_func_task_void(task_ptr parent, T&& func) : next_task{std::move(parent)} , m_func{std::forward(func)} {} @@ -1598,12 +1726,27 @@ class promise virtual ~promise() = default; + /** + * @brief Constructor to create a promise object with an initial class method. + * @param method - Method for call. + * @param obj - Object containing the required method. + * @param args - Optional function arguments. + */ + template, + typename = typename std::enable_if::value>::type> + explicit promise(Method&& method, Class* obj, Args&&... args) + : m_task{std::make_shared(std::forward(method), obj, std::forward(args)...)} + {}; + + /** * @brief Constructor to create a promise object with an initial function. * @param func - Initial function. * @param args - Optional function arguments. */ - template> + template> explicit promise(Func&& func, Args&&... args) : m_task{std::make_shared(std::forward(func), std::forward(args)...)} {}; @@ -1620,30 +1763,59 @@ class promise {}; + /** + * @brief Add a class method to be called if the previous function was resolved. + * @param method - Method that not receives any result of the previous call. + * @param obj - Object containing the required method. + * @return Promise object. + */ + template::type> + promise then(Method&& method, Class* obj) const + { + using task = internal::then_class_task_void; + return promise{std::make_shared(m_task, std::forward(method), obj)}; + } + + + /** + * @brief Add a class method to be called if the previous function was resolved. + * @param method - Method that receives the result of the previous call. + * @param obj - Object containing the required method. + * @return Promise object. + */ + template::type> + promise then(Method&& method, Class* obj) const + { + using task = internal::then_class_task; + return promise{std::make_shared(m_task, std::forward(method), obj)}; + } + + /** * @brief Add a function to be called if the previous function was resolved. - * @param func - Function that receives the result of the previous function. + * @param func - Function that not receives any result of the previous call. * @return Promise object. */ - template::type, - typename = typename std::enable_if::value>::type> + template::type> promise then(Func&& func) const { - using task = internal::then_task; + using task = internal::then_func_task_void; return promise{std::make_shared(m_task, std::forward(func))}; } /** * @brief Add a function to be called if the previous function was resolved. - * @param func - Function that not receives any result of the previous function. + * @param func - Function that receives the result of the previous call. * @return Promise object. */ - template::type> + template::type, + typename = typename std::enable_if::value>::type> promise then(Func&& func) const { - using task = internal::then_task_void; + using task = internal::then_func_task; return promise{std::make_shared(m_task, std::forward(func))}; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e734d2..0e1292f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,17 +36,20 @@ include(Catch) set(HEADERS src/common.h - src/funcs.h + src/test_funcs.h + src/test_struct.h ) set(SOURCES src/all_settled.cpp src/all.cpp src/any.cpp + src/class_initial.cpp + src/class_then.cpp src/fail.cpp src/finally.cpp - src/funcs.cpp - src/initial.cpp + src/func_initial.cpp + src/func_then.cpp src/make_all_settled.cpp src/make_all.cpp src/make_any.cpp @@ -56,7 +59,8 @@ set(SOURCES src/race.cpp src/settled.cpp src/smoke.cpp - src/then.cpp + src/test_funcs.cpp + src/test_struct.cpp ) set(TARGET async_promise_tests) diff --git a/tests/src/class_initial.cpp b/tests/src/class_initial.cpp new file mode 100644 index 0000000..4ff3e00 --- /dev/null +++ b/tests/src/class_initial.cpp @@ -0,0 +1,104 @@ +/****************************************************************************** +** +** Copyright (C) 2023 Ivan Pinezhaninov +** +** This file is part of the async_promise project - which can be found at +** https://github.com/IvanPinezhaninov/async_promise/. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +** OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +** THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +******************************************************************************/ + +// async_promise +#include + +// catch2 +#include +#include + +// local +#include "test_struct.h" + +static constexpr auto str = "Hello World!"; + + +TEST_CASE("Class initial void void", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::void_void, &test}.run(); + + REQUIRE_NOTHROW(future.get()); +} + + +TEST_CASE("Class initial error void void", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::error_void_void, &test}.run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class initial void string", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::void_string, &test, str}.run(); + + REQUIRE_NOTHROW(future.get()); +} + + +TEST_CASE("Class initial error void string", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::error_void_string, &test, str}.run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class initial string void", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::string_void, &test}.run(); + + std::string res; + REQUIRE_NOTHROW(res = future.get()); + REQUIRE(res == str); +} + + +TEST_CASE("Class initial error string void", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::error_string_void, &test}.run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class initial string string", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::string_string, &test, str}.run(); + + std::string res; + REQUIRE_NOTHROW(res = future.get()); + REQUIRE(res == str); +} + + +TEST_CASE("Class initial error string string", "[initial]") +{ + test_struct test; + auto future = async::promise{&test_struct::error_string_string, &test, str}.run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} diff --git a/tests/src/class_then.cpp b/tests/src/class_then.cpp new file mode 100644 index 0000000..37da3bc --- /dev/null +++ b/tests/src/class_then.cpp @@ -0,0 +1,142 @@ +/****************************************************************************** +** +** Copyright (C) 2023 Ivan Pinezhaninov +** +** This file is part of the async_promise project - which can be found at +** https://github.com/IvanPinezhaninov/async_promise/. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +** OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +** THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +******************************************************************************/ + +// async_promise +#include + +// catch2 +#include +#include + +// local +#include "test_struct.h" + +static constexpr auto str = "Hello World!"; + + +TEST_CASE("Class then void void", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise().then(&test_struct::void_void, &test).run(); + + REQUIRE_NOTHROW(future.get()); +} + + +TEST_CASE("Class then error void void", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise().then(&test_struct::error_void_void, &test).run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class then void void ignore arg", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::void_void, &test).run(); + + REQUIRE_NOTHROW(future.get()); +} + + +TEST_CASE("Class then error void void ignore arg", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::error_void_void, &test).run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class then void string", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::void_string, &test).run(); + + REQUIRE_NOTHROW(future.get()); +} + + +TEST_CASE("Class then error void string", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::error_void_string, &test).run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class then string void", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise().then(&test_struct::string_void, &test).run(); + + std::string res; + REQUIRE_NOTHROW(res = future.get()); + REQUIRE(res == str); +} + + +TEST_CASE("Class then error string void", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise().then(&test_struct::error_string_void, &test).run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class then string void ignore arg", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::string_void, &test).run(); + + std::string res; + REQUIRE_NOTHROW(res = future.get()); + REQUIRE(res == str); +} + + +TEST_CASE("Class then error string void ignore arg", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::error_string_void, &test).run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} + + +TEST_CASE("Class then string string", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::string_string, &test).run(); + + std::string res; + REQUIRE_NOTHROW(res = future.get()); + REQUIRE(res == str); +} + + +TEST_CASE("Class then error string string", "[then]") +{ + test_struct test; + auto future = async::make_resolved_promise(str).then(&test_struct::error_string_string, &test).run(); + + REQUIRE_THROWS_MATCHES(future.get(), std::runtime_error, Catch::Matchers::Message(str)); +} diff --git a/tests/src/fail.cpp b/tests/src/fail.cpp index fe8c6bd..c9a1ed1 100644 --- a/tests/src/fail.cpp +++ b/tests/src/fail.cpp @@ -22,7 +22,7 @@ #include // local -#include "funcs.h" +#include "test_funcs.h" static constexpr auto str = "Hello World!"; diff --git a/tests/src/finally.cpp b/tests/src/finally.cpp index 4256cb2..7363761 100644 --- a/tests/src/finally.cpp +++ b/tests/src/finally.cpp @@ -22,7 +22,7 @@ #include // local -#include "funcs.h" +#include "test_funcs.h" static constexpr auto str = "Hello World!"; diff --git a/tests/src/initial.cpp b/tests/src/func_initial.cpp similarity index 83% rename from tests/src/initial.cpp rename to tests/src/func_initial.cpp index 4a6204c..3a5b585 100644 --- a/tests/src/initial.cpp +++ b/tests/src/func_initial.cpp @@ -23,12 +23,12 @@ #include // local -#include "funcs.h" +#include "test_funcs.h" static constexpr auto str = "Hello World!"; -TEST_CASE("Initial void void", "[initial]") +TEST_CASE("Func initial void void", "[initial]") { auto future = async::promise{void_void}.run(); @@ -36,7 +36,7 @@ TEST_CASE("Initial void void", "[initial]") } -TEST_CASE("Initial error void void", "[initial]") +TEST_CASE("Func initial error void void", "[initial]") { auto future = async::promise{error_void_void}.run(); @@ -44,7 +44,7 @@ TEST_CASE("Initial error void void", "[initial]") } -TEST_CASE("Initial void string", "[initial]") +TEST_CASE("Func initial void string", "[initial]") { auto future = async::promise{void_string, str}.run(); @@ -52,7 +52,7 @@ TEST_CASE("Initial void string", "[initial]") } -TEST_CASE("Initial error void string", "[initial]") +TEST_CASE("Func initial error void string", "[initial]") { auto future = async::promise{error_void_string, str}.run(); @@ -60,7 +60,7 @@ TEST_CASE("Initial error void string", "[initial]") } -TEST_CASE("Initial string void", "[initial]") +TEST_CASE("Func initial string void", "[initial]") { auto future = async::promise{string_void}.run(); @@ -70,7 +70,7 @@ TEST_CASE("Initial string void", "[initial]") } -TEST_CASE("Initial error string void", "[initial]") +TEST_CASE("Func initial error string void", "[initial]") { auto future = async::promise{error_string_void}.run(); @@ -78,7 +78,7 @@ TEST_CASE("Initial error string void", "[initial]") } -TEST_CASE("Initial string string", "[initial]") +TEST_CASE("Func initial string string", "[initial]") { auto future = async::promise{string_string, str}.run(); @@ -88,7 +88,7 @@ TEST_CASE("Initial string string", "[initial]") } -TEST_CASE("Initial error string string", "[initial]") +TEST_CASE("Func initial error string string", "[initial]") { auto future = async::promise{error_string_string, str}.run(); diff --git a/tests/src/then.cpp b/tests/src/func_then.cpp similarity index 82% rename from tests/src/then.cpp rename to tests/src/func_then.cpp index b830b99..dd26b16 100644 --- a/tests/src/then.cpp +++ b/tests/src/func_then.cpp @@ -23,12 +23,12 @@ #include // local -#include "funcs.h" +#include "test_funcs.h" static constexpr auto str = "Hello World!"; -TEST_CASE("Then void void", "[then]") +TEST_CASE("Func then void void", "[then]") { auto future = async::make_resolved_promise().then(void_void).run(); @@ -36,7 +36,7 @@ TEST_CASE("Then void void", "[then]") } -TEST_CASE("Then error void void", "[then]") +TEST_CASE("Func then error void void", "[then]") { auto future = async::make_resolved_promise().then(error_void_void).run(); @@ -44,7 +44,7 @@ TEST_CASE("Then error void void", "[then]") } -TEST_CASE("Then void void ignore arg", "[then]") +TEST_CASE("Func then void void ignore arg", "[then]") { auto future = async::make_resolved_promise(str).then(void_void).run(); @@ -52,7 +52,7 @@ TEST_CASE("Then void void ignore arg", "[then]") } -TEST_CASE("Then error void void ignore arg", "[then]") +TEST_CASE("Func then error void void ignore arg", "[then]") { auto future = async::make_resolved_promise(str).then(error_void_void).run(); @@ -60,7 +60,7 @@ TEST_CASE("Then error void void ignore arg", "[then]") } -TEST_CASE("Then void string", "[then]") +TEST_CASE("Func then void string", "[then]") { auto future = async::make_resolved_promise(str).then(void_string).run(); @@ -68,7 +68,7 @@ TEST_CASE("Then void string", "[then]") } -TEST_CASE("Then error void string", "[then]") +TEST_CASE("Func then error void string", "[then]") { auto future = async::make_resolved_promise(str).then(error_void_string).run(); @@ -76,7 +76,7 @@ TEST_CASE("Then error void string", "[then]") } -TEST_CASE("Then string void", "[then]") +TEST_CASE("Func then string void", "[then]") { auto future = async::make_resolved_promise().then(string_void).run(); @@ -86,7 +86,7 @@ TEST_CASE("Then string void", "[then]") } -TEST_CASE("Then error string void", "[then]") +TEST_CASE("Func then error string void", "[then]") { auto future = async::make_resolved_promise().then(error_string_void).run(); @@ -94,7 +94,7 @@ TEST_CASE("Then error string void", "[then]") } -TEST_CASE("Then string void ignore arg", "[then]") +TEST_CASE("Func then string void ignore arg", "[then]") { auto future = async::make_resolved_promise(str).then(string_void).run(); @@ -104,7 +104,7 @@ TEST_CASE("Then string void ignore arg", "[then]") } -TEST_CASE("Then error string void ignore arg", "[then]") +TEST_CASE("Func then error string void ignore arg", "[then]") { auto future = async::make_resolved_promise(str).then(error_string_void).run(); @@ -112,7 +112,7 @@ TEST_CASE("Then error string void ignore arg", "[then]") } -TEST_CASE("Then string string", "[then]") +TEST_CASE("Func then string string", "[then]") { auto future = async::make_resolved_promise(str).then(string_string).run(); @@ -122,7 +122,7 @@ TEST_CASE("Then string string", "[then]") } -TEST_CASE("Then error string string", "[then]") +TEST_CASE("Func then error string string", "[then]") { auto future = async::make_resolved_promise(str).then(error_string_string).run(); diff --git a/tests/src/funcs.cpp b/tests/src/test_funcs.cpp similarity index 97% rename from tests/src/funcs.cpp rename to tests/src/test_funcs.cpp index f13dfea..8fb2306 100644 --- a/tests/src/funcs.cpp +++ b/tests/src/test_funcs.cpp @@ -2,7 +2,7 @@ #include // local -#include "funcs.h" +#include "test_funcs.h" static constexpr auto str = "Hello World!"; diff --git a/tests/src/funcs.h b/tests/src/test_funcs.h similarity index 95% rename from tests/src/funcs.h rename to tests/src/test_funcs.h index a038401..656629b 100644 --- a/tests/src/funcs.h +++ b/tests/src/test_funcs.h @@ -15,8 +15,8 @@ ** ******************************************************************************/ -#ifndef FUNCS_H -#define FUNCS_H +#ifndef TEST_FUNCS_H +#define TEST_FUNCS_H // stl #include @@ -42,4 +42,4 @@ std::string error_string_string(std::string str); std::string string_exception(std::exception_ptr e); -#endif // FUNCS_H +#endif // TEST_FUNCS_H diff --git a/tests/src/test_struct.cpp b/tests/src/test_struct.cpp new file mode 100644 index 0000000..64b9038 --- /dev/null +++ b/tests/src/test_struct.cpp @@ -0,0 +1,72 @@ +// stl +#include + +// local +#include "test_struct.h" + +static constexpr auto str = "Hello World!"; + + +void test_struct::void_void() +{} + + +void test_struct::error_void_void() +{ + throw std::runtime_error{str}; +} + + +void test_struct::void_string(std::string str) +{} + + +void test_struct::error_void_string(std::string str) +{ + throw std::runtime_error{str}; +} + + +void test_struct::void_exception(std::exception_ptr e) +{} + + +std::string test_struct::string_void() +{ + return str; +} + + +std::string test_struct::error_string_void() +{ + throw std::runtime_error{str}; +} + + +std::string test_struct::string_string(std::string str) +{ + return str; +} + + +std::string test_struct::error_string_string(std::string str) +{ + throw std::runtime_error{str}; +} + + +std::string test_struct::string_exception(std::exception_ptr e) +{ + try + { + std::rethrow_exception(e); + } + catch(const std::exception& e) + { + return e.what(); + } + catch(...) + { + return str; + } +} diff --git a/tests/src/test_struct.h b/tests/src/test_struct.h new file mode 100644 index 0000000..3a3833d --- /dev/null +++ b/tests/src/test_struct.h @@ -0,0 +1,48 @@ +/****************************************************************************** +** +** Copyright (C) 2023 Ivan Pinezhaninov +** +** This file is part of the async_promise - which can be found at +** https://github.com/IvanPinezhaninov/async_promise/. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +** OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +** THE USE OR OTHER DEALINGS IN THE SOFTWARE. +** +******************************************************************************/ + +#ifndef TEST_STRUCT_H +#define TEST_STRUCT_H + +// stl +#include + + +struct test_struct final +{ + void void_void(); + + void error_void_void(); + + void void_string(std::string str); + + void error_void_string(std::string str); + + void void_exception(std::exception_ptr e); + + std::string string_void(); + + std::string error_string_void(); + + std::string string_string(std::string str); + + std::string error_string_string(std::string str); + + std::string string_exception(std::exception_ptr e); +}; + +#endif // TEST_STRUCT_H