diff --git a/configure.ac b/configure.ac index 338b4a8..8bac554 100644 --- a/configure.ac +++ b/configure.ac @@ -101,11 +101,13 @@ AC_CONFIG_FILES([Makefile src/tools/Makefile src/core/Makefile src/service/Makefile - src/app/Makefile + src/frost/Makefile test/Makefile test/core/Makefile test/p2p/Makefile test/service/Makefile + test/frost/Makefile + test/testlib/Makefile contrib/Makefile]) diff --git a/contrib/catch/catch.hpp b/contrib/catch/catch.hpp index ccd5749..1712c95 100644 --- a/contrib/catch/catch.hpp +++ b/contrib/catch/catch.hpp @@ -10690,6 +10690,31 @@ void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator } #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) + + +template +std::string translateIfNestedException(E &e, std::size_t level) { + try { + std::rethrow_if_nested(e); + return std::string(); + } + catch( std::exception& e1 ) { + return std::string("\n") + std::string(level*2, ' ') + e1.what() + translateIfNestedException(e1, level + 1); + } + catch( std::string& msg ) { + return std::string("\n") + std::string(level*2, ' ') + msg; + } + catch( std::nested_exception& e1 ) { + return std::string("\n") + std::string(level*2, ' ') + "Unknown exception" + translateIfNestedException(e1, level + 1); + } + catch( const char* msg ) { + return std::string("\n") + std::string(level*2, ' ') + msg; + } + catch(...) { + return std::string("\n") + std::string(level*2, ' ') + "Unknown exception"; + } +} + std::string ExceptionTranslatorRegistry::translateActiveException() const { try { #ifdef __OBJC__ @@ -10719,11 +10744,14 @@ std::string ExceptionTranslatorRegistry::translateActiveException() const { std::rethrow_exception(std::current_exception()); } catch( std::exception& ex ) { - return ex.what(); + return std::string(ex.what()) + translateIfNestedException(ex, 1); } catch( std::string& msg ) { return msg; } + catch( std::nested_exception& ex ) { + return "Unknown exception" + translateIfNestedException(ex, 1); + } catch( const char* msg ) { return msg; } diff --git a/contrib/cex/async_result.hpp b/contrib/cex/async_result.hpp new file mode 100644 index 0000000..cceefd0 --- /dev/null +++ b/contrib/cex/async_result.hpp @@ -0,0 +1,359 @@ +#pragma once + +#include +#include +#include + +namespace cex { + +template +class async_result_base +{ +protected: + async_result_base() = default; +public: + virtual ~async_result_base() = default; + virtual void operator()(const RES& res) = 0; + virtual void operator()(RES&& res) = 0; + virtual void on_error() = 0; +}; + +template +class async_result_base +{ +protected: + async_result_base() = default; +public: + virtual ~async_result_base() = default; + virtual void operator()(RES& res) = 0; + virtual void on_error() = 0; +}; + + +template <> +class async_result_base +{ +protected: + async_result_base() = default; +public: + virtual ~async_result_base() = default; + virtual void operator()() = 0; + virtual void on_error() = 0; +}; + +template +class async_result; + +template +class async_result : public async_result_base +{ + SUCCESS_HANDLER m_res; + ERROR_HANDLER m_err; + std::tuple m_args; +public: + async_result(const SUCCESS_HANDLER& res, const ERROR_HANDLER& err, ARGS&&... args) + : m_res(res), m_err(err), m_args(std::forward(args)...) + {} + + async_result(const async_result& other) = default; + ~async_result() override = default; + + async_result& operator=(const async_result& other) = default; + + void operator()(const RES& res) override + { std::apply(m_res, std::tuple_cat(std::make_tuple(res), std::move(m_args))); } + + void operator()(RES&& res) override + { std::apply(m_res, std::tuple_cat(std::make_tuple(std::forward(res)), std::move(m_args))); } + + void on_error() override + { std::apply(m_err, std::move(m_args)); } + + const async_result& forward() const + { return *this; } + + async_result clone() const + { return async_result(*this); } +}; + +template +class async_result : public async_result_base +{ + SUCCESS_HANDLER m_res; + ERROR_HANDLER m_err; + std::tuple m_args; +public: + async_result(const SUCCESS_HANDLER& res, const ERROR_HANDLER& err, ARGS&&... args) + : m_res(res), m_err(err), m_args(std::forward(args)...) + {} + + async_result(const async_result& other) = default; + ~async_result() override = default; + + async_result& operator=(const async_result& other) = default; + + void operator()(RES& res) override + { std::apply(m_res, std::tuple_cat(std::make_tuple(res), std::move(m_args))); } + + void on_error() override + { std::apply(m_err, std::move(m_args)); } + + const async_result& forward() const + { return *this; } + + async_result clone() const + { return async_result(*this); } +}; + +template +class async_result : public async_result_base +{ + SUCCESS_HANDLER m_res; + ERROR_HANDLER m_err; + std::tuple m_args; +public: + async_result(const SUCCESS_HANDLER& res, const ERROR_HANDLER& err, ARGS&&... args) + : m_res(res), m_err(err), m_args(std::forward(args)...) + {} + + async_result(const async_result& other) = default; + ~async_result() override = default; + + async_result& operator=(const async_result& other) = default; + + void operator()() override + { std::apply(m_res, std::move(m_args)); } + + void on_error() override + { std::apply(m_err, std::move(m_args)); } + + const async_result& forward() const + { return *this; } + + async_result clone() const + { return async_result(*this); } +}; + + +template +class async_result : public async_result_base +{ + SUCCESS_HANDLER m_res; + ERROR_HANDLER m_err; + std::tuple m_args; +public: + async_result(SUCCESS_HANDLER&& res, ERROR_HANDLER&& err, ARGS&&... args) + : m_res(std::move(res)), m_err(std::move(err)), m_args(std::forward(args)...) + {} + + async_result(async_result&& other) noexcept = default; + ~async_result() override = default; + + async_result& operator=(async_result&& other) noexcept = default; + + void operator()(const RES& res) override + { std::apply(m_res, std::tuple_cat(std::make_tuple(res), std::move(m_args))); } + + void operator()(RES&& res) override + { std::apply(m_res, std::tuple_cat(std::make_tuple(std::forward(res)), std::move(m_args))); } + + void on_error() override + { std::apply(m_err, std::move(m_args)); } + + async_result&& forward() + { return std::move(*this); } +}; + +template +class async_result : public async_result_base +{ + SUCCESS_HANDLER m_res; + ERROR_HANDLER m_err; + std::tuple m_args; +public: + async_result(SUCCESS_HANDLER&& res, ERROR_HANDLER&& err, ARGS&&... args) + : m_res(std::move(res)), m_err(std::move(err)), m_args(std::forward(args)...) + {} + + async_result(async_result&& other) noexcept = default; + ~async_result() override = default; + + async_result& operator=(async_result&& other) noexcept = default; + + void operator()(RES& res) override + { std::apply(m_res, std::tuple_cat(std::make_tuple(res), std::move(m_args))); } + + void on_error() override + { std::apply(m_err, std::move(m_args)); } + + async_result&& forward() + { return std::move(*this); } +}; + + +template +class async_result : public async_result_base +{ + SUCCESS_HANDLER m_res; + ERROR_HANDLER m_err; + std::tuple m_args; +public: + async_result(SUCCESS_HANDLER&& res, ERROR_HANDLER&& err, ARGS&&... args) + : m_res(std::move(res)), m_err(std::move(err)), m_args(std::forward(args)...) + {} + + async_result(async_result&& other) noexcept = default; + ~async_result() override = default; + + async_result& operator=(async_result&& other) noexcept = default; + + void operator()() override + { std::apply(std::move(m_res), std::move(m_args)); } + + void on_error() override + { std::apply(m_err, std::move(m_args)); } + + async_result&& forward() + { return std::move(*this); } + +}; + + +template +class shared_async_result : public async_result_base +{ + std::shared_ptr> m_handler; +public: + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "google-explicit-constructor" + template + shared_async_result(const async_result& res) + : m_handler(std::make_shared>(res)) + {} + + template + shared_async_result(async_result&& res) + : m_handler(std::make_shared>(move(res))) + {} +#pragma clang diagnostic pop + + shared_async_result(const shared_async_result& other) : m_handler(other.m_handler) {} + shared_async_result(shared_async_result&& other) noexcept : m_handler(std::move(other.m_handler)) {} + + ~shared_async_result() override = default; + + shared_async_result& operator=(const shared_async_result& other) = default; + shared_async_result& operator=(shared_async_result&& other) noexcept = default; + + void operator()(const RES& res) override + { (*m_handler)(res); } + + void operator()(RES&& res) override + { (*m_handler)(std::move(res));; } + + void on_error() override + { m_handler->on_error(); } + + shared_async_result& forward() + { return *this; } +}; + +template +class shared_async_result : public async_result_base +{ + std::shared_ptr> m_handler; +public: + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "google-explicit-constructor" + template + shared_async_result(const async_result& res) + : m_handler(std::make_shared>(res)) + {} + + template + shared_async_result(async_result&& res) + : m_handler(std::make_shared>(move(res))) + {} +#pragma clang diagnostic pop + + shared_async_result(const shared_async_result& other) : m_handler(other.m_handler) {} + shared_async_result(shared_async_result&& other) noexcept : m_handler(std::move(other.m_handler)) {} + + ~shared_async_result() override = default; + + shared_async_result& operator=(const shared_async_result& other) = default; + shared_async_result& operator=(shared_async_result&& other) noexcept = default; + + void operator()(RES& res) override + { (*m_handler)(res); } + + void on_error() override + { m_handler->on_error(); } + + shared_async_result& forward() + { return *this; } +}; + +template <> +class shared_async_result : public async_result_base +{ + std::shared_ptr> m_handler; +public: + +#pragma clang diagnostic push +#pragma ide diagnostic ignored "google-explicit-constructor" + template + shared_async_result(const async_result& res) + : m_handler(std::make_shared>(res)) + {} + + template + shared_async_result(async_result&& res) + : m_handler(std::make_shared>(std::move(res))) + {} +#pragma clang diagnostic pop + + shared_async_result(const shared_async_result& other) : m_handler(other.m_handler) {} + shared_async_result(shared_async_result&& other) noexcept : m_handler(std::move(other.m_handler)) {} + + ~shared_async_result() override = default; + + shared_async_result& operator=(const shared_async_result& other) = default; + shared_async_result& operator=(shared_async_result&& other) noexcept = default; + + void operator()() override + { (*m_handler)(); } + + void on_error() override + { m_handler->on_error(); } + + shared_async_result& forward() + { return *this; } +}; + +template +async_result make_async_result(const SUCCESS_HANDLER& on_success, const ERROR_HANDLER& on_error, ARGS&& ... args) +{ + return async_result(on_success, on_error, std::forward(args)...); +} + +template +async_result make_async_result(const SUCCESS_HANDLER& on_success, const ERROR_HANDLER& on_error, ARGS&& ... args) +{ + return async_result(on_success, on_error, std::forward(args)...); +} + +template +async_result make_async_result(SUCCESS_HANDLER&& on_success, ERROR_HANDLER&& on_error, ARGS&& ... args) +{ + return async_result(std::move(on_success), std::move(on_error), std::forward(args)...); +} + +template +async_result make_async_result(SUCCESS_HANDLER&& on_success, ERROR_HANDLER&& on_error, ARGS&& ... args) +{ + return async_result(std::move(on_success), std::move(on_error), std::forward(args)...); +} +} \ No newline at end of file diff --git a/contrib/cex/fixsizevector.hpp b/contrib/cex/fixsizevector.hpp index 09f7e6e..ba53d6e 100644 --- a/contrib/cex/fixsizevector.hpp +++ b/contrib/cex/fixsizevector.hpp @@ -2,6 +2,9 @@ #include #include +#include + +#include "cex_defs.hpp" namespace cex { @@ -39,16 +42,16 @@ class fixsize_vector : protected std::vector { public: - fixsize_vector() noexcept : base(SIZE) {} - explicit fixsize_vector(const allocator_type& a) noexcept : base(SIZE, a) {} - explicit fixsize_vector(const value_type& v) noexcept : base(SIZE, v) {} - fixsize_vector(const value_type& v, const allocator_type& a) noexcept : base(SIZE, v, a) {} + fixsize_vector() CEXCXX_NOEXCEPT : base(SIZE) {} + explicit fixsize_vector(const allocator_type& a) CEXCXX_NOEXCEPT : base(SIZE, a) {} + explicit fixsize_vector(const value_type& v) CEXCXX_NOEXCEPT : base(SIZE, v) {} + fixsize_vector(const value_type& v, const allocator_type& a) CEXCXX_NOEXCEPT : base(SIZE, v, a) {} fixsize_vector(const fixsize_vector& v) : base(v) {} - fixsize_vector(fixsize_vector&& v) noexcept : base(std::move(v)) {} + fixsize_vector(fixsize_vector&& v) CEXCXX_NOEXCEPT : base(std::move(v)) {} - fixsize_vector(const base& v) : base(check_size(v)) {} - fixsize_vector(base&& v) noexcept : base(check_resize(std::move(v))) {} + explicit fixsize_vector(const base& v) : base(check_size(v)) {} + explicit fixsize_vector(base&& v) CEXCXX_NOEXCEPT : base(check_resize(std::move(v))) {} fixsize_vector(const fixsize_vector& v, const allocator_type& a) : base(v, a) {} fixsize_vector(fixsize_vector&& v, const allocator_type& a) : base(std::move(v), a) {} @@ -59,13 +62,13 @@ class fixsize_vector : protected std::vector { fixsize_vector(I f, I l, const allocator_type& a = allocator_type()) : base(SIZE, a) { assign(f, l); } - ~fixsize_vector() noexcept = default; + ~fixsize_vector() CEXCXX_NOEXCEPT = default; fixsize_vector& operator=(const fixsize_vector& x) { base::operator=(x); return *this; } - fixsize_vector& operator=(fixsize_vector&& x) noexcept { base::operator=(std::move(x)); return *this; } + fixsize_vector& operator=(fixsize_vector&& x) CEXCXX_NOEXCEPT { base::operator=(std::move(x)); return *this; } fixsize_vector& operator=(const base& x) { base::operator=(check_size(x)); return *this; } - fixsize_vector& operator=(base&& x) noexcept { base::operator=(check_resize(std::move(x))); return *this; } + fixsize_vector& operator=(base&& x) CEXCXX_NOEXCEPT { base::operator=(check_resize(std::move(x))); return *this; } fixsize_vector& operator=(std::initializer_list l) { base::operator=(check_size(l)); return *this; } @@ -81,7 +84,8 @@ class fixsize_vector : protected std::vector { void swap(base& x) { base::swap(check_size(x)); } - operator std::vector&(){ return reinterpret_cast&>(*this); } + explicit operator base&(){ return reinterpret_cast(*this); } + explicit operator const base&() const { return reinterpret_cast(*this); } using base::begin; using base::cbegin; @@ -107,24 +111,39 @@ class fixsize_vector : protected std::vector { using base::data; }; -template< class T, size_t SIZE1, size_t SIZE2, class Alloc > -bool operator==(const fixsize_vector& x1, const fixsize_vector& x2) -{ return reinterpret_cast&>(x1) == reinterpret_cast&>(x2); } +template< class T, size_t SIZE1, size_t SIZE2, class A1, class A2 > +CEXCXX20_CONSTEXPR bool operator==(const fixsize_vector& x1, const fixsize_vector& x2) +{ return reinterpret_cast&>(x1) == reinterpret_cast&>(x2); } + +#if __cplusplus >= 202002L + +template< class T, size_t SIZE1, /*size_t SIZE2, */class A1/*, class A2*/ > +constexpr std::strong_ordering operator<=>(const fixsize_vector& x1, const fixsize_vector& x2) +{ return reinterpret_cast&>(x1) <=> reinterpret_cast&>(x2); } + +#else + +template< class T, size_t SIZE1, size_t SIZE2, class A1, class A2 > +bool operator<(const fixsize_vector& x1, const fixsize_vector& x2) +{ return reinterpret_cast&>(x1) < reinterpret_cast&>(x2); } + +#endif -template< class T, size_t SIZE, class Alloc > -bool operator==(const fixsize_vector& x1, const std::vector& x2) -{ return reinterpret_cast&>(x1) == x2; } -template< class T, size_t SIZE, class Alloc > -bool operator==(const std::vector& x1, const fixsize_vector& x2) -{ return x1 == reinterpret_cast&>(x2); } +//template< class T, size_t SIZE, class A1, class A2 > +//bool operator==(const fixsize_vector& x1, const std::vector& x2) +//{ return reinterpret_cast&>(x1) == x2; } +// +//template< class T, size_t SIZE, class A1, class A2 > +//bool operator==(const std::vector& x1, const fixsize_vector& x2) +//{ return x1 == reinterpret_cast&>(x2); } -template -STREAM& operator << (STREAM& s, const fixsize_vector& x) +template +STREAM& operator << (STREAM& s, const fixsize_vector& x) { return s.write(x.data(), SIZE); } -template -STREAM& operator >> (STREAM& s, fixsize_vector& x) +template +STREAM& operator >> (STREAM& s, fixsize_vector& x) { return s.read(x.data(), SIZE); } } diff --git a/contrib/cex/wrapstream.hpp b/contrib/cex/wrapstream.hpp index e9b63de..4d28501 100644 --- a/contrib/cex/wrapstream.hpp +++ b/contrib/cex/wrapstream.hpp @@ -22,7 +22,7 @@ class stream { private: container_type m_container; - iterator m_read_it; + const_iterator m_read_it; public: stream() : m_container(), m_read_it(m_container.begin()) {} explicit stream(container_type&& container) : m_container(std::move(container)), m_read_it(m_container.cbegin()) {} @@ -44,8 +44,7 @@ class stream { return *this; } - - template + template V> stream& write(const V& elements) { auto pos = position(); @@ -55,6 +54,16 @@ class stream { return *this; } + template