From 6abd15b2d81bdef3830accf4ffdae1682ba483b3 Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Thu, 1 Nov 2018 15:12:19 -0700 Subject: [PATCH] white space formatting --- example/capture_result.cpp | 14 +- include/boost/leaf/common.hpp | 87 ++- include/boost/leaf/detail/optional.hpp | 236 +++---- include/boost/leaf/detail/print.hpp | 126 ++-- include/boost/leaf/detail/throw_exception.hpp | 65 +- include/boost/leaf/error.hpp | 388 ++++++----- include/boost/leaf/error_capture.hpp | 548 +++++++-------- include/boost/leaf/exception.hpp | 66 +- include/boost/leaf/exception_capture.hpp | 225 +++--- include/boost/leaf/expect.hpp | 434 ++++++------ include/boost/leaf/preload.hpp | 273 ++++---- include/boost/leaf/result.hpp | 638 +++++++++--------- test/basic_test.cpp | 117 ++-- test/defer_test.1.cpp | 45 +- test/defer_test.2.cpp | 43 +- test/defer_test.3.cpp | 35 +- test/defer_test.4.cpp | 43 +- test/defer_test.5.cpp | 43 +- test/diagnostic_output_test.cpp | 102 ++- test/error_capture_test.cpp | 118 ++-- test/error_test.cpp | 59 +- test/exception_capture_test.cpp | 70 +- test/exception_test.cpp | 99 ++- test/expect_test.1.cpp | 27 +- test/expect_test.2.cpp | 46 +- test/expect_test.3.cpp | 46 +- test/multiple_errors_test.cpp | 47 +- test/optional_test.cpp | 178 ++--- test/preload_test.1.cpp | 43 +- test/preload_test.2.cpp | 32 +- test/preload_test.3.cpp | 43 +- test/preload_test.4.cpp | 43 +- test/print_test.cpp | 82 ++- test/result_capture_test.cpp | 49 +- test/result_test.1.cpp | 65 +- test/result_test.2.cpp | 219 +++--- test/result_test.3.cpp | 38 +- test/result_void_capture_test.cpp | 42 +- 38 files changed, 2432 insertions(+), 2442 deletions(-) diff --git a/example/capture_result.cpp b/example/capture_result.cpp index 151a710..7ad4917 100644 --- a/example/capture_result.cpp +++ b/example/capture_result.cpp @@ -47,13 +47,13 @@ std::vector>> launch_async_tasks( int thre { std::vector>> fut; std::generate_n( std::inserter(fut,fut.end()), thread_count, [ ] - { + { return std::async( std::launch::async, [ ] - { - leaf::expect exp; - return capture(exp,task((rand()%4)!=0)); - } ); + { + leaf::expect exp; + return capture(exp,task((rand()%4)!=0)); } ); + } ); return fut; } @@ -83,9 +83,9 @@ int main() //Failure! Handle error, print failure info. bool matched = handle_error( exp, r, leaf::match( [ ] ( std::string const & v1, int v2, std::thread::id tid ) - { + { std::cerr << "Error in thread " << tid << "! failure_info1: " << v1 << ", failure_info2: " << v2 << std::endl; - } ) ); + } ) ); assert(matched); } } diff --git a/include/boost/leaf/common.hpp b/include/boost/leaf/common.hpp index 08fd620..1268bb7 100644 --- a/include/boost/leaf/common.hpp +++ b/include/boost/leaf/common.hpp @@ -15,56 +15,49 @@ #define LEAF_SOURCE_LOCATION ::boost::leaf::e_source_location{::boost::leaf::e_source_location::loc(__FILE__,__LINE__,__FUNCTION__)} -namespace -boost +namespace boost { namespace leaf { + + struct e_source_location { - namespace - leaf + struct loc { - struct - e_source_location + char const * const file; + int const line; + char const * const function; + + loc( char const * file, int line, char const * function ) noexcept: + file(file), + line(line), + function(function) { - struct - loc - { - char const * const file; - int const line; - char const * const function; - loc( char const * file, int line, char const * function ) noexcept: - file(file), - line(line), - function(function) - { - assert(file!=0); - assert(line>0); - assert(function!=0); - } - }; - loc value; - friend - std::ostream & - operator<<( std::ostream & os, e_source_location const & x ) - { - return os << "At " << x.value.file << '(' << x.value.line << ") in function " << x.value.function << std::endl; - } - }; - //////////////////////////////////////// - struct e_api_function { char const * value; }; - struct e_file_name { std::string value; }; - //////////////////////////////////////// - struct - e_errno - { - int value; - friend - std::ostream & - operator<<( std::ostream & os, e_errno const & err ) - { - using namespace std; - return os << type() << " = " << err.value << ", \"" << std::strerror(err.value) << '"'; - } - }; + assert(file!=0); + assert(line>0); + assert(function!=0); + } + }; + + loc value; + + friend std::ostream & operator<<( std::ostream & os, e_source_location const & x ) + { + return os << "At " << x.value.file << '(' << x.value.line << ") in function " << x.value.function << std::endl; } - } + }; + + struct e_api_function { char const * value; }; + + struct e_file_name { std::string value; }; + + struct e_errno + { + int value; + + friend std::ostream & operator<<( std::ostream & os, e_errno const & err ) { + using namespace std; + return os << type() << " = " << err.value << ", \"" << std::strerror(err.value) << '"'; + } + }; + +} } #endif diff --git a/include/boost/leaf/detail/optional.hpp b/include/boost/leaf/detail/optional.hpp index 09486b2..a2b295e 100644 --- a/include/boost/leaf/detail/optional.hpp +++ b/include/boost/leaf/detail/optional.hpp @@ -11,126 +11,128 @@ #include #include -namespace -boost +namespace boost { namespace leaf { + + namespace leaf_detail { - namespace - leaf + template + class optional { - namespace - leaf_detail + union { T value_; }; + bool has_value_; + + public: + + typedef T value_type; + optional() noexcept: + has_value_(false) { - template - class - optional - { - union { T value_; }; - bool has_value_; - public: - typedef T value_type; - optional() noexcept: - has_value_(false) - { - } - optional( optional const & x ): - has_value_(false) - { - (void) (*this = x); - } - optional( optional && x ) noexcept: - has_value_(false) - { - (void) (*this = std::move(x)); - } - optional( T const & v ): - has_value_(false) - { - put(v); - } - optional( T && v ) noexcept: - has_value_(false) - { - put(std::move(v)); - } - optional & - operator=( optional const & x ) - { - reset(); - if( x.has_value() ) - put(x.value()); - return *this; - } - optional & - operator=( optional && x ) noexcept - { - reset(); - if( x.has_value() ) - put(std::move(x).value()); - return *this; - } - ~optional() noexcept - { - reset(); - } - void - reset() noexcept - { - if( has_value() ) - { - value_.~T(); - has_value_=false; - } - } - T & - put( T const & v ) - { - reset(); - (void) new(&value_) T(v); - has_value_=true; - return value_; - } - T & - put( T && v ) noexcept - { - reset(); - (void) new(&value_) T(std::move(v)); - has_value_=true; - return value_; - } - bool - has_value() const noexcept - { - return has_value_; - } - T const & - value() const & noexcept - { - assert(has_value()); - return value_; - } - T & - value() & noexcept - { - assert(has_value()); - return value_; - } - T const && - value() const && noexcept - { - assert(has_value()); - return value_; - } - T - value() && noexcept - { - assert(has_value()); - T tmp(std::move(value_)); - reset(); - return tmp; - } - }; } - } - } + + optional( optional const & x ): + has_value_(false) + { + (void) (*this = x); + } + + optional( optional && x ) noexcept: + has_value_(false) + { + (void) (*this = std::move(x)); + } + + optional( T const & v ): + has_value_(false) + { + put(v); + } + + optional( T && v ) noexcept: + has_value_(false) + { + put(std::move(v)); + } + + optional & operator=( optional const & x ) + { + reset(); + if( x.has_value() ) + put(x.value()); + return *this; + } + + optional & operator=( optional && x ) noexcept + { + reset(); + if( x.has_value() ) + put(std::move(x).value()); + return *this; + } + + ~optional() noexcept + { + reset(); + } + + void reset() noexcept + { + if( has_value() ) + { + value_.~T(); + has_value_=false; + } + } + + T & put( T const & v ) + { + reset(); + (void) new(&value_) T(v); + has_value_=true; + return value_; + } + + T & put( T && v ) noexcept + { + reset(); + (void) new(&value_) T(std::move(v)); + has_value_=true; + return value_; + } + + bool has_value() const noexcept + { + return has_value_; + } + + T const & value() const & noexcept + { + assert(has_value()); + return value_; + } + + T & value() & noexcept + { + assert(has_value()); + return value_; + } + + T const && value() const && noexcept + { + assert(has_value()); + return value_; + } + + T value() && noexcept + { + assert(has_value()); + T tmp(std::move(value_)); + reset(); + return tmp; + } + }; + + } //leaf_detail + +} } #endif diff --git a/include/boost/leaf/detail/print.hpp b/include/boost/leaf/detail/print.hpp index fb94a25..3eeb110 100644 --- a/include/boost/leaf/detail/print.hpp +++ b/include/boost/leaf/detail/print.hpp @@ -9,78 +9,68 @@ #include -namespace -boost +namespace boost { namespace leaf { + + template + char const * type() noexcept { - namespace - leaf - { - template - char const * - type() noexcept - { #ifdef __FUNCSIG__ - return __FUNCSIG__; + return __FUNCSIG__; #else - return __PRETTY_FUNCTION__; + return __PRETTY_FUNCTION__; #endif - } - namespace - leaf_detail - { - template - struct - is_printable - { - static constexpr bool value=false; - }; - template - struct - is_printable()<(), void())> - { - static constexpr bool value=true; - }; - //////////////////////////////////////// - template ::value,bool ValuePrintable=is_printable::value> - struct diagnostic; - template - struct - diagnostic - { - static - bool - print( std::ostream & os, Wrapper const & x ) - { - os << x; - return true; - } - }; - template - struct - diagnostic - { - static - bool - print( std::ostream & os, Wrapper const & x ) - { - os << type() << " = " << x.value; - return true; - } - }; - template - struct - diagnostic - { - static - bool - print( std::ostream & os, Wrapper const & ) - { - os << type() << " = N/A"; - return true; - } - }; - } - } } + namespace leaf_detail + { + template + struct is_printable + { + static constexpr bool value=false; + }; + + template + struct is_printable()<(), void())> + { + static constexpr bool value=true; + }; + + //////////////////////////////////////// + + template ::value,bool ValuePrintable=is_printable::value> + struct diagnostic; + + template + struct diagnostic + { + static bool print( std::ostream & os, Wrapper const & x ) + { + os << x; + return true; + } + }; + + template + struct diagnostic + { + static bool print( std::ostream & os, Wrapper const & x ) + { + os << type() << " = " << x.value; + return true; + } + }; + + template + struct diagnostic + { + static bool print( std::ostream & os, Wrapper const & ) + { + os << type() << " = N/A"; + return true; + } + }; + } //leaf_detail + +} } + #endif diff --git a/include/boost/leaf/detail/throw_exception.hpp b/include/boost/leaf/detail/throw_exception.hpp index d41c6cd..e0bed37 100644 --- a/include/boost/leaf/detail/throw_exception.hpp +++ b/include/boost/leaf/detail/throw_exception.hpp @@ -12,46 +12,39 @@ #define LEAF_THROW(e) ::boost::leaf::throw_exception(e,LEAF_SOURCE_LOCATION) -namespace -boost +namespace boost { namespace leaf { + + namespace leaf_detail { - namespace - leaf + inline void enforce_std_exception( std::exception const & ) { } + + template + class exception: + public Ex, + public error { - namespace - leaf_detail + public: + exception( Ex && ex, error && e ) noexcept: + Ex(std::move(ex)), + error(std::move(e)) { - inline void enforce_std_exception( std::exception const & ) { } - template - class - exception: - public Ex, - public error - { - public: - exception( Ex && ex, error && e ) noexcept: - Ex(std::move(ex)), - error(std::move(e)) - { - enforce_std_exception(*this); - } - }; + enforce_std_exception(*this); } - template - [[noreturn]] - void - throw_exception( Ex && ex, E && ... e ) - { - throw leaf_detail::exception(std::move(ex),error(std::move(e)...)); - } - template - [[noreturn]] - void - throw_exception( Ex && ex, error const & err, E && ... e ) - { - throw leaf_detail::exception(std::move(ex),err.propagate(std::move(e)...)); - } - } + }; + } //leaf_detail + + template + [[noreturn]] void throw_exception( Ex && ex, E && ... e ) + { + throw leaf_detail::exception(std::move(ex),error(std::move(e)...)); } + template + [[noreturn]] void throw_exception( Ex && ex, error const & err, E && ... e ) + { + throw leaf_detail::exception(std::move(ex),err.propagate(std::move(e)...)); + } + +} } + #endif diff --git a/include/boost/leaf/error.hpp b/include/boost/leaf/error.hpp index b026fac..a9a28dc 100644 --- a/include/boost/leaf/error.hpp +++ b/include/boost/leaf/error.hpp @@ -13,205 +13,201 @@ #include #include -namespace -boost +namespace boost { namespace leaf { + + class error { - namespace - leaf + unsigned id_; + + explicit error( unsigned id ) noexcept: + id_(id) { - class - error - { - unsigned id_; - explicit - error( unsigned id ) noexcept: - id_(id) - { - } - class - id_factory - { - id_factory( id_factory const & ) = delete; - id_factory & operator=( id_factory const & ) = delete; - static - unsigned - new_error_id() noexcept - { - static std::atomic c; - return ++c; - } - unsigned next_id_; - id_factory() noexcept: - next_id_(new_error_id()) - { - } - public: - static - id_factory & - tl_instance() noexcept - { - static thread_local id_factory s; - return s; - } - unsigned - peek() noexcept - { - return next_id_; - } - unsigned - get() noexcept - { - unsigned id = next_id_; - next_id_ = new_error_id(); - return id; - } - }; - public: - error() noexcept: - id_(id_factory::tl_instance().get()) - { - } - template - explicit - error( E && ... e ) noexcept: - id_(id_factory::tl_instance().get()) - { - propagate(std::forward(e)...); - } - friend - bool - operator==( error const & e1, error const & e2 ) noexcept - { - return e1.id_==e2.id_; - } - friend - bool - operator!=( error const & e1, error const & e2 ) noexcept - { - return e1.id_!=e2.id_; - } - friend - std::ostream & - operator<<( std::ostream & os, error const & e ) - { - char buf[sizeof(e.id_)*CHAR_BIT/4+1]; - int nw = std::sprintf(buf,"%X",e.id_); - assert(nw>=0); - assert(nw - error propagate( E && ... ) const noexcept; - }; - //////////////////////////////////////// - namespace - leaf_detail - { - template - struct - error_info - { - E v; - error e; - }; - template - class - slot: - optional> - { - slot( slot const & ) = delete; - slot & operator=( slot const & ) = delete; - typedef optional> base; - slot * prev_; - public: - typedef decltype(E::value) value_type; - slot() noexcept; - ~slot() noexcept; - using base::put; - using base::has_value; - using base::value; - using base::reset; - }; - template - slot * & - tl_slot_ptr() noexcept - { - static thread_local slot * s; - return s; - } - template - slot:: - slot() noexcept - { - slot * & p = tl_slot_ptr(); - prev_ = p; - p = this; - } - template - slot:: - ~slot() noexcept - { - if( prev_ ) - { - optional> & p = *prev_; - p = std::move(*this); - } - tl_slot_ptr() = prev_; - } - template - E * - put_slot( E && v, error const & e ) noexcept - { - if( leaf_detail::slot * p = leaf_detail::tl_slot_ptr() ) - return &p->put(leaf_detail::error_info{std::forward(v),e}).v; - else - return 0; - } - } - template - error - error:: - propagate( E && ... e ) const noexcept - { - { using _ = void const * [ ]; (void) _ { 0, leaf_detail::put_slot(std::forward(e),*this)... }; } - return *this; - } - //////////////////////////////////////// - namespace - leaf_detail - { - template - struct - match_fn - { - F f; - }; - template - struct - match_no_fn - { - }; - } - template - leaf_detail::match_fn - match( F && f ) noexcept - { - return leaf_detail::match_fn { std::move(f) }; - } - template - leaf_detail::match_no_fn - match() noexcept - { - return leaf_detail::match_no_fn { }; - } } + + class id_factory + { + id_factory( id_factory const & ) = delete; + id_factory & operator=( id_factory const & ) = delete; + + static unsigned new_error_id() noexcept + { + static std::atomic c; + return ++c; + } + + unsigned next_id_; + + id_factory() noexcept: + next_id_(new_error_id()) + { + } + + public: + + static id_factory & tl_instance() noexcept + { + static thread_local id_factory s; + return s; + } + + unsigned peek() noexcept + { + return next_id_; + } + + unsigned get() noexcept + { + unsigned id = next_id_; + next_id_ = new_error_id(); + return id; + } + }; + + public: + + error() noexcept: + id_(id_factory::tl_instance().get()) + { + } + + template + explicit error( E && ... e ) noexcept: + id_(id_factory::tl_instance().get()) + { + propagate(std::forward(e)...); + } + + friend bool operator==( error const & e1, error const & e2 ) noexcept + { + return e1.id_==e2.id_; + } + + friend bool operator!=( error const & e1, error const & e2 ) noexcept + { + return e1.id_!=e2.id_; + } + + friend std::ostream & operator<<( std::ostream & os, error const & e ) + { + char buf[sizeof(e.id_)*CHAR_BIT/4+1]; + int nw = std::sprintf(buf,"%X",e.id_); + assert(nw>=0); + assert(nw + error propagate( E && ... ) const noexcept; + + }; + + //////////////////////////////////////// + + namespace leaf_detail + { + + template + struct error_info + { + E v; + error e; + }; + + template + class slot: + optional> + { + slot( slot const & ) = delete; + slot & operator=( slot const & ) = delete; + typedef optional> base; + slot * prev_; + public: + typedef decltype(E::value) value_type; + slot() noexcept; + ~slot() noexcept; + using base::put; + using base::has_value; + using base::value; + using base::reset; + }; + + template + slot * & tl_slot_ptr() noexcept + { + static thread_local slot * s; + return s; + } + + template + slot::slot() noexcept + { + slot * & p = tl_slot_ptr(); + prev_ = p; + p = this; + } + + template + slot::~slot() noexcept + { + if( prev_ ) + { + optional> & p = *prev_; + p = std::move(*this); + } + tl_slot_ptr() = prev_; + } + + template + E * put_slot( E && v, error const & e ) noexcept + { + if( leaf_detail::slot * p = leaf_detail::tl_slot_ptr() ) + return &p->put(leaf_detail::error_info{std::forward(v),e}).v; + else + return 0; + } + } //leaf_detail + + template + error error:: propagate( E && ... e ) const noexcept + { + { using _ = void const * [ ]; (void) _ { 0, leaf_detail::put_slot(std::forward(e),*this)... }; } + return *this; } + //////////////////////////////////////// + + namespace leaf_detail + { + template + struct match_fn + { + F f; + }; + + template + struct match_no_fn + { + }; + } //leaf_detail + + template + leaf_detail::match_fn match( F && f ) noexcept + { + return leaf_detail::match_fn { std::move(f) }; + } + + template + leaf_detail::match_no_fn match() noexcept + { + return leaf_detail::match_no_fn { }; + } + +} } + #endif diff --git a/include/boost/leaf/error_capture.hpp b/include/boost/leaf/error_capture.hpp index 8b4ebd0..4f8e45b 100644 --- a/include/boost/leaf/error_capture.hpp +++ b/include/boost/leaf/error_capture.hpp @@ -11,294 +11,304 @@ #include #include -namespace -boost +namespace boost { namespace leaf { + + class error_capture; + + template + bool handle_error( error_capture const &, M && ... ) noexcept; + + template + decltype(P::value) const * peek( error_capture const & ) noexcept; + + void diagnostic_output( std::ostream &, error_capture const & ); + + namespace leaf_detail { - namespace - leaf + template + struct all_available; + + template + struct all_available { - class error_capture; + static bool check( error_capture const & cap ) noexcept + { + return peek(cap) && all_available::check(cap); + } + }; + template <> + struct all_available<> + { + static bool check( error_capture const & ) noexcept { return true; } + }; + + //////////////////////////////////////// + + template + struct tuple_for_each_capture + { + static void const * dynamic_bind( Tuple const & tup, char const * (*type_id)() ) noexcept + { + assert(type_id!=0); + typedef typename std::tuple_element::type ith_type; + if( &type == type_id ) + return &std::get(tup); + return tuple_for_each_capture::dynamic_bind(tup,type_id); + } + + static void print( std::ostream & os, Tuple const & tup ) + { + typedef typename std::tuple_element::type ith_type; + tuple_for_each_capture::print(os,tup); + auto & opt = std::get(tup); + if( opt.has_value() && diagnostic::print(os,opt.value()) ) + os << std::endl; + } + + static void unload( error const & e, Tuple && tup ) noexcept + { + tuple_for_each_capture::unload(e,std::move(tup)); + auto && opt = std::get(std::move(tup)); + if( opt.has_value() ) + (void) e.propagate(std::move(opt).value()); + } + }; + + template + struct tuple_for_each_capture<0,Tuple> + { + static void const * dynamic_bind( Tuple const &, char const * (*)() ) noexcept { return 0; } + static void print( std::ostream &, Tuple const & ) { } + static void unload( error const &, Tuple && ) noexcept { } + }; + + } //leaf_detail + + //////////////////////////////////////// + + class error_capture + { template - bool handle_error( error_capture const &, M && ... ) noexcept; + friend bool leaf::handle_error( error_capture const &, M && ... ) noexcept; template - decltype(P::value) const * peek( error_capture const & ) noexcept; + friend decltype(P::value) const * leaf::peek( error_capture const & ) noexcept; + + friend void leaf::diagnostic_output( std::ostream &, error_capture const & ); - void diagnostic_output( std::ostream &, error_capture const & ); //////////////////////////////////////// - namespace - leaf_detail + + class dynamic_store + { + mutable std::atomic refcount_; + + virtual void const * bind_( char const * (*)() ) const noexcept = 0; + + protected: + + dynamic_store() noexcept: + refcount_(0) { - template - struct all_available; - template - struct - all_available - { - static - bool - check( error_capture const & cap ) noexcept - { - return peek(cap) && all_available::check(cap); - } - }; - template <> - struct - all_available<> - { - static bool check( error_capture const & ) noexcept { return true; } - }; - //////////////////////////////////////// - template - struct - tuple_for_each_capture - { - static - void const * - dynamic_bind( Tuple const & tup, char const * (*type_id)() ) noexcept - { - assert(type_id!=0); - typedef typename std::tuple_element::type ith_type; - if( &type == type_id ) - return &std::get(tup); - return tuple_for_each_capture::dynamic_bind(tup,type_id); - } - static - void - print( std::ostream & os, Tuple const & tup ) - { - typedef typename std::tuple_element::type ith_type; - tuple_for_each_capture::print(os,tup); - auto & opt = std::get(tup); - if( opt.has_value() && diagnostic::print(os,opt.value()) ) - os << std::endl; - } - static - void - unload( error const & e, Tuple && tup ) noexcept - { - tuple_for_each_capture::unload(e,std::move(tup)); - auto && opt = std::get(std::move(tup)); - if( opt.has_value() ) - (void) e.propagate(std::move(opt).value()); - } - }; - template - struct - tuple_for_each_capture<0,Tuple> - { - static void const * dynamic_bind( Tuple const &, char const * (*)() ) noexcept { return 0; } - static void print( std::ostream &, Tuple const & ) { } - static void unload( error const &, Tuple && ) noexcept { } - }; } + + public: + + virtual ~dynamic_store() noexcept + { + } + + void addref() const noexcept + { + ++refcount_; + } + + void release() const noexcept + { + if( !--refcount_ ) + delete this; + } + + template + leaf_detail::optional const * bind() const noexcept + { + if( void const * p = bind_(&type) ) + return static_cast const *>(p); + else + return 0; + } + + virtual void diagnostic_output( std::ostream & ) const = 0; + virtual void unload( error const & ) noexcept = 0; + }; + //////////////////////////////////////// - class - error_capture + + template + class dynamic_store_impl: + public dynamic_store + { + std::tuple...> s_; + public: + + explicit dynamic_store_impl( std::tuple...> && s ) noexcept: + s_(std::move(s)) { - template - friend bool leaf::handle_error( error_capture const &, M && ... ) noexcept; + } - template - friend decltype(P::value) const * leaf::peek( error_capture const & ) noexcept; + void const * bind_( char const * (*type_id)() ) const noexcept + { + using namespace leaf_detail; + assert(type_id!=0); + return tuple_for_each_capture...>>::dynamic_bind(s_,type_id); + } - friend void leaf::diagnostic_output( std::ostream &, error_capture const & ); + void diagnostic_output( std::ostream & os ) const + { + leaf_detail::tuple_for_each_capture::print(os,s_); + } + + void unload( error const & e ) noexcept + { + leaf_detail::tuple_for_each_capture::unload(e,std::move(s_)); + } + }; - class - dynamic_store - { - mutable std::atomic refcount_; - virtual void const * bind_( char const * (*)() ) const noexcept = 0; - protected: - dynamic_store() noexcept: - refcount_(0) - { - } - public: - virtual - ~dynamic_store() noexcept - { - } - void - addref() const noexcept - { - ++refcount_; - } - void - release() const noexcept - { - if( !--refcount_ ) - delete this; - } - template - leaf_detail::optional const * - bind() const noexcept - { - if( void const * p = bind_(&type) ) - return static_cast const *>(p); - else - return 0; - } - virtual void diagnostic_output( std::ostream & ) const = 0; - virtual void unload( error const & ) noexcept = 0; - }; - template - class - dynamic_store_impl: - public dynamic_store - { - std::tuple...> s_; - public: - explicit - dynamic_store_impl( std::tuple...> && s ) noexcept: - s_(std::move(s)) - { - } - void const * - bind_( char const * (*type_id)() ) const noexcept - { - using namespace leaf_detail; - assert(type_id!=0); - return tuple_for_each_capture...>>::dynamic_bind(s_,type_id); - } - void - diagnostic_output( std::ostream & os ) const - { - leaf_detail::tuple_for_each_capture::print(os,s_); - } - void - unload( error const & e ) noexcept - { - leaf_detail::tuple_for_each_capture::unload(e,std::move(s_)); - } - }; - void - free() noexcept - { - if( s_ ) - { - s_->release(); - s_=0; - } - } - template - int - unwrap( leaf_detail::match_fn const & m, bool & matched ) const - { - if( !matched && (matched=leaf_detail::all_available::check(*this)) ) - (void) m.f( *peek(*this)... ); - return 42; - } - template - int - unwrap( leaf_detail::match_no_fn const & m, bool & matched ) const noexcept - { - if( !matched ) - matched = leaf_detail::all_available::check(*this); - return 42; - } - dynamic_store * s_; - error e_; - protected: - void - set_error( error const & e ) - { - e_ = e; - } - public: - error_capture() noexcept: - s_(0) - { - } - template - error_capture( error const & e, std::tuple...> && s ) noexcept: - s_(new dynamic_store_impl(std::move(s))), - e_(e) - { - s_->addref(); - } - ~error_capture() noexcept - { - free(); - } - error_capture( error_capture const & x ) noexcept: - s_(x.s_), - e_(x.e_) - { - if( s_ ) - s_->addref(); - } - error_capture( error_capture && x ) noexcept: - s_(x.s_), - e_(std::move(x.e_)) - { - x.s_ = 0; - } - error_capture & - operator=( error_capture const & x ) noexcept - { - s_ = x.s_; - s_->addref(); - e_ = x.e_; - return *this; - } - error_capture & - operator=( error_capture && x ) noexcept - { - s_ = x.s_; - x.s_ = 0; - e_ = x.e_; - return *this; - } - explicit - operator bool() const noexcept - { - return s_!=0; - } - error - unload() noexcept - { - if( s_ ) - { - s_->unload(e_); - free(); - } - return e_; - } - }; //////////////////////////////////////// - template - bool - handle_error( error_capture const & e, M && ... m ) noexcept + + void free() noexcept + { + if( s_ ) { - if( e ) - { - bool matched = false; - { using _ = int[ ]; (void) _ { 42, e.unwrap(m,matched)... }; } - if( matched ) - return true; - } - return false; - } - template - decltype(P::value) const * - peek( error_capture const & e ) noexcept - { - if( e ) - if( auto * opt = e.s_->bind

() ) - if( opt->has_value() ) - return &opt->value().value; - return 0; - } - inline - void - diagnostic_output( std::ostream & os, error_capture const & e ) - { - if( e ) - e.s_->diagnostic_output(os); + s_->release(); + s_=0; } } + + template + int unwrap( leaf_detail::match_fn const & m, bool & matched ) const + { + if( !matched && (matched=leaf_detail::all_available::check(*this)) ) + (void) m.f( *peek(*this)... ); + return 42; + } + + template + int unwrap( leaf_detail::match_no_fn const & m, bool & matched ) const noexcept + { + if( !matched ) + matched = leaf_detail::all_available::check(*this); + return 42; + } + + dynamic_store * s_; + error e_; + + protected: + + void set_error( error const & e ) + { + e_ = e; + } + + public: + + error_capture() noexcept: + s_(0) + { + } + + template + error_capture( error const & e, std::tuple...> && s ) noexcept: + s_(new dynamic_store_impl(std::move(s))), + e_(e) + { + s_->addref(); + } + + ~error_capture() noexcept + { + free(); + } + + error_capture( error_capture const & x ) noexcept: + s_(x.s_), + e_(x.e_) + { + if( s_ ) + s_->addref(); + } + + error_capture( error_capture && x ) noexcept: + s_(x.s_), + e_(std::move(x.e_)) + { + x.s_ = 0; + } + + error_capture & operator=( error_capture const & x ) noexcept + { + s_ = x.s_; + s_->addref(); + e_ = x.e_; + return *this; + } + + error_capture & operator=( error_capture && x ) noexcept + { + s_ = x.s_; + x.s_ = 0; + e_ = x.e_; + return *this; + } + + explicit operator bool() const noexcept + { + return s_!=0; + } + + error unload() noexcept + { + if( s_ ) + { + s_->unload(e_); + free(); + } + return e_; + } + }; + + //////////////////////////////////////// + + template + bool handle_error( error_capture const & e, M && ... m ) noexcept + { + if( e ) + { + bool matched = false; + { using _ = int[ ]; (void) _ { 42, e.unwrap(m,matched)... }; } + if( matched ) + return true; + } + return false; } + template + decltype(P::value) const * peek( error_capture const & e ) noexcept + { + if( e ) + if( auto * opt = e.s_->bind

() ) + if( opt->has_value() ) + return &opt->value().value; + return 0; + } + + inline void diagnostic_output( std::ostream & os, error_capture const & e ) + { + if( e ) + e.s_->diagnostic_output(os); + } + +} } + #endif diff --git a/include/boost/leaf/exception.hpp b/include/boost/leaf/exception.hpp index 1677e0d..c8cb949 100644 --- a/include/boost/leaf/exception.hpp +++ b/include/boost/leaf/exception.hpp @@ -10,43 +10,37 @@ #include #include -namespace -boost +namespace boost { namespace leaf { + + inline error get_error( std::exception const & ex ) noexcept { - namespace - leaf - { - inline - error - get_error( std::exception const & ex ) noexcept - { - if( auto e = dynamic_cast(&ex) ) - return *e; - else - return error::peek_next_error(); - } - template - decltype(P::value) const * - peek( expect const & exp, std::exception const & ex ) noexcept - { - return peek

(exp,get_error(ex)); - } - template - void - handle_exception( expect & exp, std::exception const & ex, M && ... m ) - { - if( handle_error(exp,get_error(ex),m...) ) - (void) error(); - else - throw; - } - template - void - diagnostic_output( std::ostream & os, expect const & exp, std::exception const & ex ) - { - diagnostic_output(os,exp,get_error(ex)); - } - } + if( auto e = dynamic_cast(&ex) ) + return *e; + else + return error::peek_next_error(); } + template + decltype(P::value) const * peek( expect const & exp, std::exception const & ex ) noexcept + { + return peek

(exp,get_error(ex)); + } + + template + void handle_exception( expect & exp, std::exception const & ex, M && ... m ) + { + if( handle_error(exp,get_error(ex),m...) ) + (void) error(); + else + throw; + } + + template + void diagnostic_output( std::ostream & os, expect const & exp, std::exception const & ex ) + { + diagnostic_output(os,exp,get_error(ex)); + } + +} } + #endif diff --git a/include/boost/leaf/exception_capture.hpp b/include/boost/leaf/exception_capture.hpp index b0dac2f..be60857 100644 --- a/include/boost/leaf/exception_capture.hpp +++ b/include/boost/leaf/exception_capture.hpp @@ -11,137 +11,136 @@ #include #include -namespace -boost +namespace boost { namespace leaf { + + namespace leaf_detail { - namespace - leaf + class captured_exception: + public std::exception, + error_capture { - namespace - leaf_detail + std::exception_ptr ex_; + bool has_error_; + + public: + + captured_exception( std::exception_ptr && ex, error_capture && cap, bool has_error ) noexcept: + error_capture(std::move(cap)), + ex_(std::move(ex)), + has_error_(has_error) { - class - captured_exception: - public std::exception, - error_capture - { - std::exception_ptr ex_; - bool has_error_; - public: - captured_exception( std::exception_ptr && ex, error_capture && cap, bool has_error ) noexcept: - error_capture(std::move(cap)), - ex_(std::move(ex)), - has_error_(has_error) - { - assert(ex_); - } - [[noreturn]] - void - rethrow_original_exception() - { - if( !has_error_ ) - { - set_error(error::peek_next_error()); - has_error_ = true; - } - unload(); - std::rethrow_exception(ex_); - } - friend - void - diagnostic_output( std::ostream & os, captured_exception const & ce ) - { - diagnostic_output(os,static_cast(ce)); - } - }; - template - class - exception_trap - { - F f_; - public: - explicit - exception_trap( F && f ) noexcept: - f_(std::move(f)) - { - } - template - decltype(std::declval()(std::declval()...)) - operator()( A && ... a ) - { - expect exp; - try - { - return f_(std::forward(a)...); - } - catch( error const & e ) - { - throw captured_exception(std::current_exception(),capture(exp,e),true); - } - catch(...) - { - throw captured_exception(std::current_exception(),capture(exp,error()),false); - } - } - }; + assert(ex_); } - template - leaf_detail::exception_trap - capture_exception( F && f ) noexcept + + [[noreturn]] void rethrow_original_exception() { - return leaf_detail::exception_trap(std::move(f)); - } - template - decltype(std::declval().get()) - get( Future && f ) - { - try + if( !has_error_ ) { - return std::forward(f).get(); - } - catch( leaf_detail::captured_exception & ex ) - { - ex.rethrow_original_exception(); + set_error(error::peek_next_error()); + has_error_ = true; } + unload(); + std::rethrow_exception(ex_); } + + friend void diagnostic_output( std::ostream & os, captured_exception const & ce ) + { + diagnostic_output(os,static_cast(ce)); + } + }; + //////////////////////////////////////// - template - void - current_exception_diagnostic_print( std::ostream & os, expect const & exp ) + + template + class exception_trap + { + F f_; + + public: + + explicit exception_trap( F && f ) noexcept: + f_(std::move(f)) { - os << "Current Exception Diagnostic Information:" << std::endl; - try + } + + template + decltype(std::declval()(std::declval()...)) operator()( A && ... a ) + { + expect exp; + try { - throw; + return f_(std::forward(a)...); } - catch( std::exception const & ex ) + catch( error const & e ) { - os << - "Exception dynamic type: " << typeid(ex).name() << std::endl << - "std::exception::what(): " << ex.what() << std::endl; + throw captured_exception(std::current_exception(),capture(exp,e),true); } - catch( ... ) + catch(...) { - os << "Unknown exception type (not a std::exception)" << std::endl; - } - try - { - throw; - } - catch( leaf_detail::captured_exception const & e ) - { - diagnostic_output(os,e); - } - catch( error const & e ) - { - diagnostic_output(os,exp,e); - } - catch( ... ) - { - diagnostic_output(os,exp); + throw captured_exception(std::current_exception(),capture(exp,error()),false); } } + }; + } //leaf_detail + + template + leaf_detail::exception_trap capture_exception( F && f ) noexcept + { + return leaf_detail::exception_trap(std::move(f)); + } + + template + decltype(std::declval().get()) get( Future && f ) + { + try + { + return std::forward(f).get(); + } + catch( leaf_detail::captured_exception & ex ) + { + ex.rethrow_original_exception(); } } + //////////////////////////////////////// + + template + void current_exception_diagnostic_print( std::ostream & os, expect const & exp ) + { + os << "Current Exception Diagnostic Information:" << std::endl; + try + { + throw; + } + catch( std::exception const & ex ) + { + os << + "Exception dynamic type: " << typeid(ex).name() << std::endl << + "std::exception::what(): " << ex.what() << std::endl; + } + catch( ... ) + { + os << "Unknown exception type (not a std::exception)" << std::endl; + } + + try + { + throw; + } + catch( leaf_detail::captured_exception const & e ) + { + diagnostic_output(os,e); + } + catch( error const & e ) + { + diagnostic_output(os,exp,e); + } + catch( ... ) + { + diagnostic_output(os,exp); + } + } + +} } + #endif diff --git a/include/boost/leaf/expect.hpp b/include/boost/leaf/expect.hpp index e465d47..5593668 100644 --- a/include/boost/leaf/expect.hpp +++ b/include/boost/leaf/expect.hpp @@ -11,246 +11,244 @@ #include #include -namespace -boost +namespace boost { namespace leaf { + + class error_capture; + + namespace leaf_detail { - namespace - leaf - { - namespace - leaf_detail + template + struct type_index; + + template + struct type_index + { + static const int value = 0; + }; + + template + struct type_index + { + static const int value = 1 + type_index::value; + }; + + template + struct tuple_type_index; + + template + struct tuple_type_index> + { + static const int value = type_index::value; + }; + + //////////////////////////////////////// + + template + struct slots_subset; + + template + struct slots_subset + { + static bool have_values( SlotsTuple const & tup, error const & e ) noexcept { - template - struct type_index; - template - struct - type_index + auto & sl = std::get::value>(tup); + return sl.has_value() && sl.value().e==e && slots_subset::have_values(tup,e); + } + }; + + template + struct slots_subset + { + static bool have_values( SlotsTuple const &, error const & ) noexcept { return true; } + }; + + //////////////////////////////////////// + + template + struct tuple_for_each_expect + { + static void print( std::ostream & os, Tuple const & tup ) + { + tuple_for_each_expect::print(os,tup); + auto & opt = std::get(tup); + if( opt.has_value() ) { - static const int value = 0; - }; - template - struct - type_index - { - static const int value = 1 + type_index::value; - }; - template - struct tuple_type_index; - template - struct - tuple_type_index> - { - static const int value = type_index::value; - }; - //////////////////////////////////////// - template - struct slots_subset; - template - struct - slots_subset - { - static - bool - have_values( SlotsTuple const & tup, error const & e ) noexcept - { - auto & sl = std::get::value>(tup); - return sl.has_value() && sl.value().e==e && slots_subset::have_values(tup,e); - } - }; - template - struct - slots_subset - { - static bool have_values( SlotsTuple const &, error const & ) noexcept { return true; } - }; - //////////////////////////////////////// - template - struct - tuple_for_each_expect - { - static - void - print( std::ostream & os, Tuple const & tup ) - { - tuple_for_each_expect::print(os,tup); - auto & opt = std::get(tup); - if( opt.has_value() ) - { - auto & x = opt.value(); - if( diagnostic::print(os,x.v) ) - os << "(0x" << x.e << ')' << std::endl; - } - } - static - void - print( std::ostream & os, Tuple const & tup, error const & e ) - { - tuple_for_each_expect::print(os,tup,e); - auto & opt = std::get(tup); - if( opt.has_value() ) - { - auto & x = opt.value(); - if( x.e==e && diagnostic::print(os,x.v) ) - os << std::endl; - } - } - static - void - clear( Tuple & tup ) noexcept - { - tuple_for_each_expect::clear(tup); - std::get(tup).reset(); - } - }; - template - struct - tuple_for_each_expect<0,Tuple> - { - static void print( std::ostream &, Tuple const & ) noexcept { } - static void print( std::ostream &, Tuple const &, error const & ) noexcept { } - static void clear( Tuple & ) noexcept { } - }; - //////////////////////////////////////// - template - optional - convert_optional( slot && x, error const & e ) noexcept - { - if( x.has_value() && x.value().e==e ) - return optional(std::move(x).value().v); - else - return optional(); + auto & x = opt.value(); + if( diagnostic::print(os,x.v) ) + os << "(0x" << x.e << ')' << std::endl; } } - class error_capture; + + static void print( std::ostream & os, Tuple const & tup, error const & e ) + { + tuple_for_each_expect::print(os,tup,e); + auto & opt = std::get(tup); + if( opt.has_value() ) + { + auto & x = opt.value(); + if( x.e==e && diagnostic::print(os,x.v) ) + os << std::endl; + } + } + + static void clear( Tuple & tup ) noexcept + { + tuple_for_each_expect::clear(tup); + std::get(tup).reset(); + } + }; + + template + struct tuple_for_each_expect<0,Tuple> + { + static void print( std::ostream &, Tuple const & ) noexcept { } + static void print( std::ostream &, Tuple const &, error const & ) noexcept { } + static void clear( Tuple & ) noexcept { } + }; + + //////////////////////////////////////// + + template + optional convert_optional( slot && x, error const & e ) noexcept + { + if( x.has_value() && x.value().e==e ) + return optional(std::move(x).value().v); + else + return optional(); + } template - struct - dependent_type - { + struct dependent_type + { typedef leaf::error_capture error_capture; - }; + }; - template - class expect; + } //leaf_detail - template - bool handle_error( expect &, error const &, M && ... ) noexcept; + template + class expect; - template - decltype(P::value) const * peek( expect const &, error const & ) noexcept; + template + bool handle_error( expect &, error const &, M && ... ) noexcept; - template - void diagnostic_output( std::ostream &, expect const & ); + template + decltype(P::value) const * peek( expect const &, error const & ) noexcept; - template - void diagnostic_output( std::ostream &, expect const &, error const & ); + template + void diagnostic_output( std::ostream &, expect const & ); - template - class - expect - { - friend class error; + template + void diagnostic_output( std::ostream &, expect const &, error const & ); - template - friend bool leaf::handle_error( expect &, error const &, M && ... ) noexcept; + template + class expect + { + friend class error; - template - friend decltype(P::value) const * leaf::peek( expect const &, error const & ) noexcept; + template + friend bool leaf::handle_error( expect &, error const &, M && ... ) noexcept; - template - friend void leaf::diagnostic_output( std::ostream &, expect const & ); + template + friend decltype(P::value) const * leaf::peek( expect const &, error const & ) noexcept; - template - friend void leaf::diagnostic_output( std::ostream &, expect const &, error const & ); + template + friend void leaf::diagnostic_output( std::ostream &, expect const & ); - expect( expect const & ) = delete; - expect & operator=( expect const & ) = delete; + template + friend void leaf::diagnostic_output( std::ostream &, expect const &, error const & ); - std::tuple...> s_; + expect( expect const & ) = delete; + expect & operator=( expect const & ) = delete; - template - int - unwrap( leaf_detail::match_fn const & m, error const & e, bool & matched ) const - { - using namespace leaf_detail; - if( !matched && (matched=slots_subset...>::have_values(s_,e)) ) - (void) m.f( *leaf::peek(*this,e)... ); - return 42; - } - template - int - unwrap( leaf_detail::match_no_fn const & m, error const & e, bool & matched ) const noexcept - { - using namespace leaf_detail; - if( !matched ) - matched = slots_subset...>::have_values(s_,e); - return 42; - } - bool propagate_; - public: - expect() noexcept: - propagate_(true) - { - } - ~expect() noexcept - { - if( !propagate_ ) - leaf_detail::tuple_for_each_expect::clear(s_); - } - friend - typename dependent_type::error_capture - capture( expect & exp, error const & e ) - { - using namespace leaf_detail; - typename dependent_type::error_capture cap( - e, - std::make_tuple( - convert_optional( - std::move(std::get,decltype(exp.s_)>::value>(exp.s_)),e)...)); - return cap; - } - void - propagate() noexcept - { - propagate_ = true; - } - }; - template - bool - handle_error( expect & exp, error const & e, M && ... m ) noexcept - { - bool matched = false; - { using _ = int[ ]; (void) _ { 42, exp.unwrap(m,e,matched)... }; } - if( matched ) - exp.propagate_ = false; - return matched; - } - template - decltype(P::value) const * - peek( expect const & exp, error const & e ) noexcept - { - auto & opt = std::get::value>(exp.s_); - if( opt.has_value() ) - { - auto & x = opt.value(); - if( x.e==e ) - return &x.v.value; - } - return 0; - } - template - void - diagnostic_output( std::ostream & os, expect const & exp ) - { - leaf_detail::tuple_for_each_expect::print(os,exp.s_); - } - template - void - diagnostic_output( std::ostream & os, expect const & exp, error const & e ) - { - leaf_detail::tuple_for_each_expect::print(os,exp.s_,e); - } + std::tuple...> s_; + + template + int unwrap( leaf_detail::match_fn const & m, error const & e, bool & matched ) const + { + using namespace leaf_detail; + if( !matched && (matched=slots_subset...>::have_values(s_,e)) ) + (void) m.f( *leaf::peek(*this,e)... ); + return 42; } + + template + int unwrap( leaf_detail::match_no_fn const & m, error const & e, bool & matched ) const noexcept + { + using namespace leaf_detail; + if( !matched ) + matched = slots_subset...>::have_values(s_,e); + return 42; + } + + bool propagate_; + + public: + + expect() noexcept: + propagate_(true) + { + } + + ~expect() noexcept + { + if( !propagate_ ) + leaf_detail::tuple_for_each_expect::clear(s_); + } + + friend typename leaf_detail::dependent_type::error_capture capture( expect & exp, error const & e ) + { + using namespace leaf_detail; + typename leaf_detail::dependent_type::error_capture cap( + e, + std::make_tuple( + convert_optional( + std::move(std::get,decltype(exp.s_)>::value>(exp.s_)),e)...)); + return cap; + } + + void propagate() noexcept + { + propagate_ = true; + } + }; + + //////////////////////////////////////// + + template + bool handle_error( expect & exp, error const & e, M && ... m ) noexcept + { + bool matched = false; + { using _ = int[ ]; (void) _ { 42, exp.unwrap(m,e,matched)... }; } + if( matched ) + exp.propagate_ = false; + return matched; } + template + decltype(P::value) const * peek( expect const & exp, error const & e ) noexcept + { + auto & opt = std::get::value>(exp.s_); + if( opt.has_value() ) + { + auto & x = opt.value(); + if( x.e==e ) + return &x.v.value; + } + return 0; + } + + template + void diagnostic_output( std::ostream & os, expect const & exp ) + { + leaf_detail::tuple_for_each_expect::print(os,exp.s_); + } + + template + void diagnostic_output( std::ostream & os, expect const & exp, error const & e ) + { + leaf_detail::tuple_for_each_expect::print(os,exp.s_,e); + } + +} } + #endif diff --git a/include/boost/leaf/preload.hpp b/include/boost/leaf/preload.hpp index 9e967b8..4d8df4b 100644 --- a/include/boost/leaf/preload.hpp +++ b/include/boost/leaf/preload.hpp @@ -9,156 +9,155 @@ #include -namespace -boost +namespace boost { namespace leaf { + + namespace leaf_detail { - namespace - leaf + template + struct tuple_for_each_preload { - namespace - leaf_detail + static void trigger( Tuple & tup, error e ) noexcept { - template - struct - tuple_for_each_preload - { - static - void - trigger( Tuple & tup, error e ) noexcept - { - tuple_for_each_preload::trigger(tup,e); - std::get(tup).trigger(e); - } - }; - template - struct - tuple_for_each_preload<0,Tuple> - { - static void trigger( Tuple const &, error ) noexcept { } - }; + tuple_for_each_preload::trigger(tup,e); + std::get(tup).trigger(e); } - //////////////////////////////////////// - namespace - leaf_detail + }; + + template + struct tuple_for_each_preload<0,Tuple> + { + static void trigger( Tuple const &, error ) noexcept { } + }; + } //leaf_detail + + //////////////////////////////////////// + + namespace leaf_detail + { + template + class preloaded_item + { + slot * s_; + E v_; + public: + explicit preloaded_item( E && v ) noexcept: + s_(tl_slot_ptr()), + v_(std::forward(v)) { - template - class - preloaded_item - { - slot * s_; - E v_; - public: - explicit - preloaded_item( E && v ) noexcept: - s_(tl_slot_ptr()), - v_(std::forward(v)) - { - } - void - trigger( error e ) noexcept - { - if( s_ && (!s_->has_value() || s_->value().e!=e) ) - s_->put( leaf_detail::error_info{std::move(v_),e} ); - } - }; - template - class - preloaded - { - preloaded & operator=( preloaded const & ) = delete; - std::tuple...> p_; - error e_; - bool moved_; - public: - explicit - preloaded( E && ... e ) noexcept: - p_(preloaded_item(std::forward(e))...), - e_(error::peek_next_error()), - moved_(false) - { - } - preloaded( preloaded && x ) noexcept: - p_(std::move(x.p_)), - e_(std::move(x.e_)), - moved_(false) - { - x.moved_ = true; - } - ~preloaded() noexcept - { - if( !moved_ && (e_!=error::peek_next_error() || std::uncaught_exception()) ) - leaf_detail::tuple_for_each_preload::trigger(p_,e_); - } - }; } + + void trigger( error e ) noexcept + { + if( s_ && (!s_->has_value() || s_->value().e!=e) ) + s_->put( leaf_detail::error_info{std::move(v_),e} ); + } + }; + template - leaf_detail::preloaded - preload( E && ... e ) noexcept + class preloaded + { + preloaded & operator=( preloaded const & ) = delete; + + std::tuple...> p_; + error e_; + bool moved_; + + public: + + explicit preloaded( E && ... e ) noexcept: + p_(preloaded_item(std::forward(e))...), + e_(error::peek_next_error()), + moved_(false) { - return leaf_detail::preloaded(std::forward(e)...); } - //////////////////////////////////////// - namespace - leaf_detail + + preloaded( preloaded && x ) noexcept: + p_(std::move(x.p_)), + e_(std::move(x.e_)), + moved_(false) { - template - class - deferred_item - { - typedef decltype(std::declval()()) E; - slot * s_; - F f_; - public: - explicit - deferred_item( F && f ) noexcept: - s_(tl_slot_ptr()), - f_(std::forward(f)) - { - } - void - trigger( error e ) noexcept - { - if( s_ && (!s_->has_value() || s_->value().e!=e) ) - s_->put( leaf_detail::error_info{f_(),e} ); - } - }; - template - class - deferred - { - deferred & operator=( deferred const & ) = delete; - std::tuple...> d_; - error e_; - bool moved_; - public: - explicit - deferred( F && ... f ) noexcept: - d_(deferred_item(std::forward(f))...), - e_(error::peek_next_error()), - moved_(false) - { - } - deferred( deferred && x ) noexcept: - d_(std::move(x.d_)), - e_(std::move(x.e_)), - moved_(false) - { - x.moved_ = true; - } - ~deferred() noexcept - { - if( !moved_ && (e_!=error::peek_next_error() || std::uncaught_exception()) ) - leaf_detail::tuple_for_each_preload::trigger(d_,e_); - } - }; + x.moved_ = true; } - template - leaf_detail::deferred - defer( F && ... f ) noexcept + + ~preloaded() noexcept { - return leaf_detail::deferred(std::forward(f)...); + if( !moved_ && (e_!=error::peek_next_error() || std::uncaught_exception()) ) + leaf_detail::tuple_for_each_preload::trigger(p_,e_); } - } + }; + } //leaf_detail + + template + leaf_detail::preloaded preload( E && ... e ) noexcept + { + return leaf_detail::preloaded(std::forward(e)...); } + //////////////////////////////////////// + + namespace leaf_detail + { + template + class deferred_item + { + typedef decltype(std::declval()()) E; + slot * s_; + F f_; + + public: + + explicit deferred_item( F && f ) noexcept: + s_(tl_slot_ptr()), + f_(std::forward(f)) + { + } + + void trigger( error e ) noexcept + { + if( s_ && (!s_->has_value() || s_->value().e!=e) ) + s_->put( leaf_detail::error_info{f_(),e} ); + } + }; + + template + class deferred + { + deferred & operator=( deferred const & ) = delete; + std::tuple...> d_; + error e_; + bool moved_; + + public: + + explicit deferred( F && ... f ) noexcept: + d_(deferred_item(std::forward(f))...), + e_(error::peek_next_error()), + moved_(false) + { + } + + deferred( deferred && x ) noexcept: + d_(std::move(x.d_)), + e_(std::move(x.e_)), + moved_(false) + { + x.moved_ = true; + } + + ~deferred() noexcept + { + if( !moved_ && (e_!=error::peek_next_error() || std::uncaught_exception()) ) + leaf_detail::tuple_for_each_preload::trigger(d_,e_); + } + }; + } //leaf_detail + + template + leaf_detail::deferred defer( F && ... f ) noexcept + { + return leaf_detail::deferred(std::forward(f)...); + } + +} } + #endif diff --git a/include/boost/leaf/result.hpp b/include/boost/leaf/result.hpp index 4892efe..df81213 100644 --- a/include/boost/leaf/result.hpp +++ b/include/boost/leaf/result.hpp @@ -13,345 +13,347 @@ #define LEAF_AUTO(v,r) auto _r_##v = r; if( !_r_##v ) return _r_##v.error(); auto & v = *_r_##v #define LEAF_CHECK(r) {auto _r_##v = r; if( !_r_##v ) return _r_##v.error();} -namespace -boost - { - namespace - leaf - { - class bad_result: public std::exception { }; +namespace boost { namespace leaf { - template - class result; + class bad_result: public std::exception { }; + + template + class result; + + template + class expect; + + template + bool handle_error( expect &, result &, M && ... ) noexcept; + + template + decltype(P::value) const * peek( expect const &, result const & ) noexcept; + + template + void diagnostic_output( std::ostream &, expect const &, result const & ); + + //////////////////////////////////////// + + template + class result + { + + template + friend bool leaf::handle_error( expect &, result &, M && ... ) noexcept; + + template + friend decltype(P::value) const * leaf::peek( expect const &, result const & ) noexcept; + + template + friend void leaf::diagnostic_output( std::ostream &, expect const &, result const & ); + + union + { + T value_; + error err_; + error_capture cap_; + }; + + enum class variant + { + value, + err, + cap + }; + + variant which_; + + void destroy() noexcept + { + switch( which_ ) + { + case variant:: value: + value_.~T(); + break; + case variant::err: + err_.~error(); + break; + default: + assert(which_==variant::cap); + cap_.~error_capture(); + } + which_= (variant)-1; + } + + void copy_from( result const & x ) + { + switch( x.which_ ) + { + case variant::value: + (void) new(&value_) T(x.value_); + break; + case variant::err: + (void) new(&err_) leaf::error(x.err_); + break; + default: + assert(x.which_==variant::cap); + (void) new(&cap_) error_capture(x.cap_); + }; + which_ = x.which_; + } + + void move_from( result && x ) noexcept + { + switch( x.which_ ) + { + case variant:: value: + (void) new(&value_) T(std::move(x.value_)); + break; + case variant::err: + (void) new(&err_) leaf::error(std::move(x.err_)); + break; + default: + assert(x.which_==variant::cap); + (void) new(&cap_) error_capture(std::move(x.cap_)); + }; + which_ = x.which_; + } + + public: + + ~result() noexcept + { + destroy(); + } + + result( result const & x ) + { + copy_from(x); + } + + result( result && x ) noexcept + { + move_from(std::move(x)); + } + + result() noexcept: + value_(T()), + which_(variant::value) + { + } + + result( T const & v ): + value_(v), + which_(variant::value) + { + } + + result( T && v ) noexcept: + value_(std::move(v)), + which_(variant::value) + { + } + + result( leaf::error const & e ) noexcept: + err_(e), + which_(variant::err) + { + } + + result( leaf::error_capture const & cap ) noexcept: + cap_(cap), + which_(variant::cap) + { + } + + result( leaf::error_capture && cap ) noexcept: + cap_(std::move(cap)), + which_(variant::cap) + { + } + + result & operator=( result const & x ) + { + destroy(); + copy_from(x); + return *this; + } + + result & operator=( result && x ) noexcept + { + destroy(); + move_from(std::move(x)); + return *this; + } + + explicit operator bool() const noexcept + { + return which_==variant::value; + } + + T const & value() const + { + if( which_==variant::value ) + return value_; + else + LEAF_THROW(bad_result()); + } + + T & value() + { + if( which_==variant::value ) + return value_; + else + LEAF_THROW(bad_result()); + } + + T const & operator*() const + { + return value(); + } + + T & operator*() + { + return value(); + } template - class expect; + leaf::error error( E && ... e ) noexcept + { + switch( which_ ) + { + case variant::value: + return leaf::error(std::forward(e)...); + case variant::cap: + { + error_capture cap = cap_; + destroy(); + (void) new(&err_) leaf::error(cap.unload()); + which_ = variant::err; + } + default: + assert(which_==variant::err); + return err_.propagate(std::forward(e)...); + } + } + template + friend result capture( expect & exp, result const & r ) + { + if( r.which_==variant::err ) + return capture(exp,r.err_); + else + return r; + } + }; + + //////////////////////////////////////// + + template <> + class result: + result + { template - bool handle_error( expect &, result &, M && ... ) noexcept; + friend bool leaf::handle_error( expect &, result &, M && ... ) noexcept; template - decltype(P::value) const * peek( expect const &, result const & ) noexcept; + friend decltype(P::value) const * leaf::peek( expect const &, result const & ) noexcept; template - void diagnostic_output( std::ostream &, expect const &, result const & ); - //////////////////////////////////////// - template - class - result - { - template - friend bool leaf::handle_error( expect &, result &, M && ... ) noexcept; + friend void leaf::diagnostic_output( std::ostream &, expect const &, result const & ); - template - friend decltype(P::value) const * leaf::peek( expect const &, result const & ) noexcept; + typedef result base; - template - friend void leaf::diagnostic_output( std::ostream &, expect const &, result const & ); + result( result && rb ): + base(std::move(rb)) + { + } - union - { - T value_; - error err_; - error_capture cap_; - }; - enum class - variant - { - value, - err, - cap - }; - variant which_; - void - destroy() noexcept - { - switch( which_ ) - { - case variant:: - value: - value_.~T(); - break; - case variant:: - err: - err_.~error(); - break; - default: - assert(which_==variant::cap); - cap_.~error_capture(); - } - which_= (variant)-1; - } - void - copy_from( result const & x ) - { - switch( x.which_ ) - { - case variant:: - value: - (void) new(&value_) T(x.value_); - break; - case variant:: - err: - (void) new(&err_) leaf::error(x.err_); - break; - default: - assert(x.which_==variant::cap); - (void) new(&cap_) error_capture(x.cap_); - }; - which_ = x.which_; - } - void - move_from( result && x ) noexcept - { - switch( x.which_ ) - { - case variant:: - value: - (void) new(&value_) T(std::move(x.value_)); - break; - case variant:: - err: - (void) new(&err_) leaf::error(std::move(x.err_)); - break; - default: - assert(x.which_==variant::cap); - (void) new(&cap_) error_capture(std::move(x.cap_)); - }; - which_ = x.which_; - } + public: - public: + ~result() noexcept + { + } - ~result() noexcept - { - destroy(); - } - result( result const & x ) - { - copy_from(x); - } - result( result && x ) noexcept - { - move_from(std::move(x)); - } - result() noexcept: - value_(T()), - which_(variant::value) - { - } - result( T const & v ): - value_(v), - which_(variant::value) - { - } - result( T && v ) noexcept: - value_(std::move(v)), - which_(variant::value) - { - } - result( leaf::error const & e ) noexcept: - err_(e), - which_(variant::err) - { - } - result( leaf::error_capture const & cap ) noexcept: - cap_(cap), - which_(variant::cap) - { - } - result( leaf::error_capture && cap ) noexcept: - cap_(std::move(cap)), - which_(variant::cap) - { - } - result & - operator=( result const & x ) - { - destroy(); - copy_from(x); - return *this; - } - result & - operator=( result && x ) noexcept - { - destroy(); - move_from(std::move(x)); - return *this; - } - explicit - operator bool() const noexcept - { - return which_==variant::value; - } - T const & - value() const - { - if( which_==variant::value ) - return value_; - else - LEAF_THROW(bad_result()); - } - T & - value() - { - if( which_==variant::value ) - return value_; - else - LEAF_THROW(bad_result()); - } - T const & - operator*() const - { - return value(); - } - T & - operator*() - { - return value(); - } - template - leaf::error - error( E && ... e ) noexcept - { - switch( which_ ) - { - case variant:: - value: - return leaf::error(std::forward(e)...); - case variant:: - cap: - { - error_capture cap = cap_; - destroy(); - (void) new(&err_) leaf::error(cap.unload()); - which_ = variant::err; - } - default: - assert(which_==variant::err); - return err_.propagate(std::forward(e)...); - } - } - template - friend - result - capture( expect & exp, result const & r ) - { - if( r.which_==variant::err ) - return capture(exp,r.err_); - else - return r; - } - }; - //////////////////////////////////////// - template <> - class - result: - result - { - template - friend bool leaf::handle_error( expect &, result &, M && ... ) noexcept; + result() noexcept + { + } - template - friend decltype(P::value) const * leaf::peek( expect const &, result const & ) noexcept; + result( leaf::error const & e ) noexcept: + base(e) + { + } - template - friend void leaf::diagnostic_output( std::ostream &, expect const &, result const & ); + result( leaf::error_capture const & cap ) noexcept: + base(cap) + { + } - typedef result base; + result( leaf::error_capture && cap ) noexcept: + base(std::move(cap)) + { + } - result( result && rb ): - base(std::move(rb)) - { - } + using base::operator bool; + using base::error; - public: + template + friend result capture( expect & exp, result const & r ) + { + return capture(exp,static_cast const &>(r)); + } - ~result() noexcept - { - } - result() noexcept - { - } - result( leaf::error const & e ) noexcept: - base(e) - { - } - result( leaf::error_capture const & cap ) noexcept: - base(cap) - { - } - result( leaf::error_capture && cap ) noexcept: - base(std::move(cap)) - { - } - using base::operator bool; - using base::error; - template - friend - result - capture( expect & exp, result const & r ) - { - return capture(exp,static_cast const &>(r)); - } - template - friend - bool - handle_error( expect & exp, result & r, M && ... m ) noexcept - { - result & rb = r; - return handle_error(exp,rb,m...); - } - template - friend - void - diagnostic_output( std::ostream & os, expect const & exp, result const & r ) - { - result const & rb = r; - diagnostic_output(os,exp,rb); - } - }; - //////////////////////////////////////// - template - bool - handle_error( expect & exp, result & r, M && ... m ) noexcept - { - assert(!r); - if( r.which_==result::variant::err ) - return handle_error(exp,r.err_,m...); - else - { - assert(r.which_==result::variant::cap); - return handle_error(r.cap_,m...); - } - } - template - decltype(P::value) const * - peek( expect const & exp, result const & r ) noexcept - { - assert(!r); - if( r.which_==result::variant::err ) - return peek

(exp,r.err_); - else - { - assert(r.which_==result::variant::cap); - return peek

(r.cap_); - } - } - template - void - diagnostic_output( std::ostream & os, expect const & exp, result const & r ) - { - assert(!r); - if( r.which_==result::variant::err ) - return diagnostic_output(os,exp,r.err_); - else - { - assert(r.which_==result::variant::cap); - return diagnostic_output(os,r.cap_); - } - } + template + friend bool handle_error( expect & exp, result & r, M && ... m ) noexcept + { + result & rb = r; + return handle_error(exp,rb,m...); + } + + template + friend void diagnostic_output( std::ostream & os, expect const & exp, result const & r ) + { + result const & rb = r; + diagnostic_output(os,exp,rb); + } + }; + + //////////////////////////////////////// + + template + bool handle_error( expect & exp, result & r, M && ... m ) noexcept + { + assert(!r); + if( r.which_==result::variant::err ) + return handle_error(exp,r.err_,m...); + else + { + assert(r.which_==result::variant::cap); + return handle_error(r.cap_,m...); } } + template + decltype(P::value) const * peek( expect const & exp, result const & r ) noexcept + { + assert(!r); + if( r.which_==result::variant::err ) + return peek

(exp,r.err_); + else + { + assert(r.which_==result::variant::cap); + return peek

(r.cap_); + } + } + + template + void diagnostic_output( std::ostream & os, expect const & exp, result const & r ) + { + assert(!r); + if( r.which_==result::variant::err ) + return diagnostic_output(os,exp,r.err_); + else + { + assert(r.which_==result::variant::cap); + return diagnostic_output(os,r.cap_); + } + } + +} } + #endif diff --git a/test/basic_test.cpp b/test/basic_test.cpp index 7d9129f..6e1167a 100644 --- a/test/basic_test.cpp +++ b/test/basic_test.cpp @@ -10,110 +10,123 @@ namespace leaf = boost::leaf; template -struct -info - { +struct info +{ int value; - }; -leaf::error -f1() - { +}; + +leaf::error f1() +{ return leaf::error( info<1>{1} ); - } -leaf::error -f2() - { +} + +leaf::error f2() +{ return f1().propagate( info<2>{2} ); - } -leaf::error -f3() - { +} + +leaf::error f3() +{ return f2().propagate( info<3>{3} ); - } -leaf::error -f4() - { +} + +leaf::error f4() +{ return f3().propagate(); - } -int -main() - { +} + +int main() +{ leaf::expect,info<2>,info<4>> exp0; leaf::error e0 = f4(); - { + { int const * p = leaf::peek>(exp0,e0); BOOST_TEST(p && *p==1); - } - { + } + + { int const * p = leaf::peek>(exp0,e0); BOOST_TEST(p && *p==2); - } + } + BOOST_TEST(!leaf::peek>(exp0,e0)); leaf::expect,info<2>,info<4>> exp; leaf::error e1 = f4(); - { + + { int const * p = leaf::peek>(exp0,e0); BOOST_TEST(p && *p==1); - } - { + } + + { int const * p = leaf::peek>(exp0,e0); BOOST_TEST(p && *p==2); - } + } + BOOST_TEST(!leaf::peek>(exp0,e0)); BOOST_TEST(!leaf::peek>(exp,e0)); BOOST_TEST(!leaf::peek>(exp,e0)); BOOST_TEST(!leaf::peek>(exp,e0)); - { + + { int const * p = leaf::peek>(exp,e1); BOOST_TEST(p && *p==1); - } - { + } + + { int const * p = leaf::peek>(exp,e1); BOOST_TEST(p && *p==2); - } + } + BOOST_TEST(!leaf::peek>(exp,e1)); BOOST_TEST( !handle_error(exp,e1,leaf::match,info<2>,info<4>>()) ); leaf::error e2 = f4(); - { + + { int const * p = leaf::peek>(exp,e2); BOOST_TEST(p && *p==1); - } - { + } + + { int const * p = leaf::peek>(exp,e2); BOOST_TEST(p && *p==2); - } + } + BOOST_TEST(!leaf::peek>(exp,e2)); - { + + { int c1=0, c2=0, c3=0; BOOST_TEST( handle_error( exp, e2, leaf::match,info<2>,info<4>>( [&c1]( int, int, int ) - { + { ++c1; - } ), + } ), leaf::match,info<2>,info<4>>( [&c2]( int, int, int ) - { + { ++c2; - } ), + } ), leaf::match,info<1>>( [&c3]( int i2,int i1 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); ++c3; - } ) ) ); + } ) ) ); BOOST_TEST(c1==0); BOOST_TEST(c2==0); BOOST_TEST(c3==1); - } - { + } + + { int c=0; BOOST_TEST( handle_error( exp0, e0, leaf::match,info<1>>( [&c]( int i2,int i1 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); ++c; - } ) ) ); + } ) ) ); BOOST_TEST(c==1); - } - return boost::report_errors(); } + + return boost::report_errors(); +} diff --git a/test/defer_test.1.cpp b/test/defer_test.1.cpp index f16118c..ee433a2 100644 --- a/test/defer_test.1.cpp +++ b/test/defer_test.1.cpp @@ -12,40 +12,39 @@ namespace leaf = boost::leaf; int global; -int -get_global() noexcept - { +int get_global() noexcept +{ return global; - } -struct -info - { +} + +struct info +{ int value; - }; -leaf::error -g() - { +}; + +leaf::error g() +{ global = 0; auto propagate = leaf::defer( [ ] { return info{get_global()}; } ); global = 42; return leaf::error(); - } -leaf::error -f() - { +} + +leaf::error f() +{ return g(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; int c=0; BOOST_TEST( handle_error( exp, f(), leaf::match( [&c]( int i42 ) - { + { BOOST_TEST(i42==42); ++c; - } ) ) ); - BOOST_TEST(c==1); + } ) ) ); return boost::report_errors(); - } + BOOST_TEST(c==1); +} diff --git a/test/defer_test.2.cpp b/test/defer_test.2.cpp index 9338d28..beceefb 100644 --- a/test/defer_test.2.cpp +++ b/test/defer_test.2.cpp @@ -11,43 +11,42 @@ namespace leaf = boost::leaf; template -struct -info - { +struct info +{ int value; - }; -leaf::error -f0() - { +}; + +leaf::error f0() +{ auto propagate = leaf::defer( [ ] { return info<0>{0}; } ); return leaf::error( info<2>{2} ); - } -leaf::error -f1() - { +} + +leaf::error f1() +{ auto propagate = leaf::defer( [ ] { return info<0>{-1}; }, [ ] { return info<1>{1}; }, [ ] { return info<2>{-1}; } ); return f0(); - } -leaf::error -f2() - { +} + +leaf::error f2() +{ return f1().propagate( info<4>{4} ); - } -int -main() - { +} + +int main() +{ leaf::expect,info<1>,info<2>,info<3>,info<4>> exp; leaf::error e = f2(); BOOST_TEST(!leaf::peek>(exp,e)); int c=0; BOOST_TEST( handle_error( exp, e, leaf::match,info<2>,info<4>>( [&c]( int i1, int i2, int i4 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); BOOST_TEST(i4==4); ++c; - } ) ) ); + } ) ) ); BOOST_TEST(c==1); return boost::report_errors(); - } +} diff --git a/test/defer_test.3.cpp b/test/defer_test.3.cpp index 4590da0..cc6ad9c 100644 --- a/test/defer_test.3.cpp +++ b/test/defer_test.3.cpp @@ -13,36 +13,35 @@ namespace leaf = boost::leaf; struct info { int value; }; -leaf::result -g1() - { +leaf::result g1() +{ auto propagate = leaf::defer( [ ] { return info{1}; } ); return { }; - } -leaf::result -g2() - { +} + +leaf::result g2() +{ return leaf::error(); - } -leaf::result -f() - { +} + +leaf::result f() +{ auto propagate = leaf::defer( [ ] { return info{2}; } ); LEAF_CHECK(g1()); return g2(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; leaf::result r = f(); int c=0; BOOST_TEST( handle_error( exp, r, leaf::match( [&c]( int x ) - { + { BOOST_TEST(x==2); ++c; - } ) ) ); + } ) ) ); BOOST_TEST(c==1); return boost::report_errors(); - } +} diff --git a/test/defer_test.4.cpp b/test/defer_test.4.cpp index eba5a8c..63951bc 100644 --- a/test/defer_test.4.cpp +++ b/test/defer_test.4.cpp @@ -15,41 +15,40 @@ struct my_error: std::exception { }; struct info { int value; }; -void -g1() - { +void g1() +{ auto propagate = leaf::defer( [ ] { return info{1}; } ); - } -void -g2() - { +} + +void g2() +{ throw my_error(); - } -void -f() - { +} + +void f() +{ auto propagate = leaf::defer( [ ] { return info{2}; } ); g1(); g2(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; try - { + { f(); - } + } catch( my_error & e ) - { + { int c=0; handle_exception( exp, e, leaf::match( [&c]( int x ) - { + { BOOST_TEST(x==2); ++c; - } ) ); + } ) ); BOOST_TEST(c==1); - } - return boost::report_errors(); } + return boost::report_errors(); +} diff --git a/test/defer_test.5.cpp b/test/defer_test.5.cpp index 74e439b..83c7158 100644 --- a/test/defer_test.5.cpp +++ b/test/defer_test.5.cpp @@ -15,41 +15,40 @@ struct my_error: std::exception { }; struct info { int value; }; -void -g1() - { +void g1() +{ auto propagate = leaf::defer( [ ] { return info{1}; } ); - } -void -g2() - { +} + +void g2() +{ leaf::throw_exception(my_error()); - } -void -f() - { +} + +void f() +{ auto propagate = leaf::defer( [ ] { return info{2}; } ); g1(); g2(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; try - { + { f(); - } + } catch( my_error & e ) - { + { int c=0; handle_exception( exp, e, leaf::match( [&c]( int x ) - { + { BOOST_TEST(x==2); ++c; - } ) ); + } ) ); BOOST_TEST(c==1); - } - return boost::report_errors(); } + return boost::report_errors(); +} diff --git a/test/diagnostic_output_test.cpp b/test/diagnostic_output_test.cpp index 3d9f474..b17365c 100644 --- a/test/diagnostic_output_test.cpp +++ b/test/diagnostic_output_test.cpp @@ -12,67 +12,60 @@ namespace leaf = boost::leaf; -struct -my_error: +struct my_error: virtual std::exception +{ + char const * what() const noexcept { - char const * - what() const noexcept - { return "my_error"; - } - }; + } +}; -struct -printable_payload +struct printable_payload +{ + friend std::ostream & operator<<( std::ostream & os, printable_payload const & x ) { - friend - std::ostream & - operator<<( std::ostream & os, printable_payload const & x ) - { return os << "printed printable_payload"; - } - }; -struct -non_printable_payload - { - }; -struct -printable_info_printable_payload - { + } +}; + +struct non_printable_payload +{ +}; + +struct printable_info_printable_payload +{ printable_payload value; - friend - std::ostream & - operator<<( std::ostream & os, printable_info_printable_payload const & x ) - { + + friend std::ostream & operator<<( std::ostream & os, printable_info_printable_payload const & x ) + { return os << "*** printable_info_printable_payload " << x.value << " ***"; - } - }; -struct -printable_info_non_printable_payload - { + } +}; + +struct printable_info_non_printable_payload +{ non_printable_payload value; - friend - std::ostream & - operator<<( std::ostream & os, printable_info_non_printable_payload const & x ) - { + + friend std::ostream & operator<<( std::ostream & os, printable_info_non_printable_payload const & x ) + { return os << "*** printable_info_non_printable_payload ***"; - } - }; -struct -non_printable_info_printable_payload - { + } +}; + +struct non_printable_info_printable_payload +{ printable_payload value; - }; -struct -non_printable_info_non_printable_payload - { +}; + +struct non_printable_info_non_printable_payload +{ non_printable_payload value; - }; -int -main() +}; + +int main() +{ { - { leaf::expect < printable_info_printable_payload, @@ -83,7 +76,7 @@ main() leaf::e_source_location > exp; try - { + { leaf::throw_exception( my_error(), LEAF_SOURCE_LOCATION, @@ -92,10 +85,9 @@ main() non_printable_info_printable_payload(), non_printable_info_non_printable_payload(), leaf::e_errno{ENOENT} ); - } - catch( - my_error & e ) - { + } + catch( my_error & e ) + { std::ostringstream st; current_exception_diagnostic_print(st,exp); std::string s = st.str(); @@ -107,7 +99,7 @@ main() BOOST_TEST(s.find(") in function")!=s.npos); std::cout << s; handle_exception( exp, e, leaf::match<>() ); - } } - return boost::report_errors(); } + return boost::report_errors(); +} diff --git a/test/error_capture_test.cpp b/test/error_capture_test.cpp index ce4a0db..0cbee97 100644 --- a/test/error_capture_test.cpp +++ b/test/error_capture_test.cpp @@ -11,111 +11,123 @@ namespace leaf = boost::leaf; template -struct -info - { +struct info +{ int value; - }; -leaf::error -f1() - { +}; + +leaf::error f1() +{ return leaf::error( info<1>{1} ); - } -leaf::error -f2() - { +} + +leaf::error f2() +{ return f1().propagate( info<2>{2} ); - } -leaf::error -f3() - { +} + +leaf::error f3() +{ return f2().propagate( info<3>{3} ); - } -leaf::error -f4() - { +} + +leaf::error f4() +{ return f3().propagate(); - } -leaf::error_capture -make_capture() - { +} + +leaf::error_capture make_capture() +{ leaf::expect,info<2>,info<4>> exp; return capture(exp,f4()); - } -int -main() - { +} + +int main() +{ leaf::error_capture e1 = make_capture(); BOOST_TEST(e1); - { + + { int const * p = leaf::peek>(e1); BOOST_TEST(p && *p==1); - } - { + } + + { int const * p = leaf::peek>(e1); BOOST_TEST(p && *p==2); - } + } + BOOST_TEST(!leaf::peek>(e1)); leaf::expect,info<2>,info<4>> exp; leaf::error e2 = f4(); - { + + { int const * p = leaf::peek>(e1); BOOST_TEST(p && *p==1); - } - { + } + + { int const * p = leaf::peek>(e1); BOOST_TEST(p && *p==2); - } + } + BOOST_TEST(!leaf::peek>(e1)); - { + + { int const * p = leaf::peek>(exp,e2); BOOST_TEST(p && *p==1); - } - { + } + + { int const * p = leaf::peek>(exp,e2); BOOST_TEST(p && *p==2); - } + } + BOOST_TEST(!leaf::peek>(exp,e2)); - { + + { int c1=0, c2=0; BOOST_TEST( handle_error( exp, e2, leaf::match,info<2>,info<4>>( [&c1]( int, int, int ) - { + { ++c1; - } ), + } ), leaf::match,info<1>>( [&c2]( int i2,int i1 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); ++c2; - } ) ) ); + } ) ) ); BOOST_TEST(c1==0); BOOST_TEST(c2==1); - } - { + } + + { int c1=0, c2=0, c3=0; BOOST_TEST( handle_error( e1, leaf::match,info<2>,info<3>>( [&c1]( int, int, int ) - { + { ++c1; - } ), + } ), leaf::match,info<2>,info<4>>( [&c2]( int, int, int ) - { + { ++c2; - } ), + } ), leaf::match,info<1>>( [&c3]( int i2,int i1 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); ++c3; - } ) ) ); + } ) ) ); BOOST_TEST(c1==0); BOOST_TEST(c2==0); BOOST_TEST(c3==1); - } + } + BOOST_TEST( handle_error( e1, leaf::match,info<2>,info<3>>(), leaf::match,info<2>,info<4>>(), leaf::match,info<1>>() ) ); + return boost::report_errors(); } diff --git a/test/error_test.cpp b/test/error_test.cpp index 3b297f7..20fa622 100644 --- a/test/error_test.cpp +++ b/test/error_test.cpp @@ -10,59 +10,58 @@ namespace leaf = boost::leaf; template -struct -info - { +struct info +{ int value; - }; -leaf::error -f1() - { +}; + +leaf::error f1() +{ return leaf::error( info<1>{1} ); - } -leaf::error -f2() - { +} + +leaf::error f2() +{ leaf::expect> exp; return f1().propagate( info<2>{2} ); - } -leaf::error -f3() - { +} + +leaf::error f3() +{ leaf::expect,info<3>> exp; return f2().propagate( info<4>{4} ); - } -leaf::error -f4() - { +} + +leaf::error f4() +{ leaf::expect,info<2>,info<3>,info<4>> exp; - { + { leaf::error e = f3(); BOOST_TEST( handle_error( exp, e, leaf::match,info<2>,info<3>,info<4>>(), leaf::match,info<2>,info<4>>() ) ); - } + } leaf::error e = f3(); int c1=0, c2=0; BOOST_TEST( handle_error( exp, e, leaf::match,info<2>,info<3>,info<4>>( [&c1]( int, int, int, int ) - { + { ++c1; - } ), + } ), leaf::match,info<2>,info<4>>( [&c2]( int i1, int i2, int i4 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); BOOST_TEST(i4==4); ++c2; - } ) ) ); + } ) ) ); BOOST_TEST(c1==0); BOOST_TEST(c2==1); return leaf::error(); - } -int -main() - { +} + +int main() +{ leaf::expect,info<3>,info<4>> exp; leaf::error e=f4(); BOOST_TEST(!leaf::peek>(exp,e)); @@ -73,4 +72,4 @@ main() BOOST_TEST(leaf::leaf_detail::tl_slot_ptr>()!=0); BOOST_TEST(leaf::leaf_detail::tl_slot_ptr>()!=0); return boost::report_errors(); - } +} diff --git a/test/exception_capture_test.cpp b/test/exception_capture_test.cpp index 3302837..b75078f 100644 --- a/test/exception_capture_test.cpp +++ b/test/exception_capture_test.cpp @@ -19,82 +19,82 @@ struct my_error: std::exception { }; template struct info { int value; }; -struct -fut_info - { +struct fut_info +{ int a; int b; int result; std::future fut; - }; +}; + template -std::vector -launch_tasks( int task_count, F && f ) - { +std::vector launch_tasks( int task_count, F && f ) +{ assert(task_count>0); std::vector fut; std::generate_n( std::inserter(fut,fut.end()), task_count, [&f] - { + { int const a = rand(); int const b = rand(); int const res = (rand()%10) - 5; return fut_info { a, b, res, std::async( std::launch::async, [f,a,b,res] { - auto wrapper = leaf::capture_exception,info<2>,info<3>>(std::move(f)); - return wrapper( a, b, res ); + auto wrapper = leaf::capture_exception,info<2>,info<3>>(std::move(f)); + return wrapper( a, b, res ); } ) }; - } ); + } ); return fut; - } +} + template -void -test( int task_count, F && f ) noexcept - { +void test( int task_count, F && f ) noexcept +{ std::vector fut = launch_tasks( task_count, std::forward(f) ); for( auto & f : fut ) - { + { using namespace leaf::leaf_detail; f.fut.wait(); leaf::expect,info<2>,info<4>> exp; try - { + { int r = leaf::get(f.fut); BOOST_TEST(r>=0); BOOST_TEST(r==f.result); - } - catch( - my_error const & e ) - { + } + catch( my_error const & e ) + { int c=0; handle_exception( exp, e, leaf::match,info<2>>( [&f,&c]( int x1, int x2 ) { - BOOST_TEST(x1==f.a); - BOOST_TEST(x2==f.b); - ++c; + BOOST_TEST(x1==f.a); + BOOST_TEST(x2==f.b); + ++c; } ) ); BOOST_TEST(c==1); - } } } -int -main() - { +} + +int main() +{ test( 42, [ ]( int a, int b, int res ) - { + { if( res>=0 ) return res; else leaf::throw_exception( my_error(), info<1>{a}, info<2>{b}, info<3>{}) ; - } ); + } ); + test( 42, [ ]( int a, int b, int res ) - { + { if( res>=0 ) return res; else - { + { auto propagate = leaf::preload( info<1>{a}, info<2>{b}, info<3>{} ); throw my_error(); - } - } ); + } + } ); + return boost::report_errors(); - } +} diff --git a/test/exception_test.cpp b/test/exception_test.cpp index b3b7861..16e3c6d 100644 --- a/test/exception_test.cpp +++ b/test/exception_test.cpp @@ -17,82 +17,79 @@ struct my_error: std::exception { }; std::function thrower; template -struct -info - { +struct info +{ int value; - }; -void -f1() - { +}; + +void f1() +{ thrower(); - } -void -f2() - { +} + +void f2() +{ leaf::expect> exp; try - { + { f1(); BOOST_TEST(false); - } + } catch( std::exception const & ex ) - { + { leaf::get_error(ex).propagate( info<2>{2} ); throw; - } } -void -f3() - { +} + +void f3() +{ leaf::expect,info<3>> exp; auto propagate = leaf::preload( info<4>{4} ); f2(); - } -void -f4() - { +} + +void f4() +{ leaf::expect,info<2>,info<3>,info<4>> exp; try - { + { f3(); BOOST_TEST(false); - } - catch( - my_error const & e ) - { + } + catch( my_error const & e ) + { int c1=0, c2=0; handle_exception( exp, e, leaf::match,info<2>,info<3>,info<4>>( [&c1]( int, int, int, int ) - { + { ++c1; - } ), + } ), leaf::match,info<2>,info<4>>( [&c2]( int i1, int i2, int i4 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); BOOST_TEST(i4==4); ++c2; - } ) + } ) ); BOOST_TEST(c1==0); BOOST_TEST(c2==1); - } - throw my_error(); } -void -test( std::function const & f ) - { + throw my_error(); +} + +void test( std::function const & f ) +{ thrower = f; leaf::expect,info<3>,info<4>> exp; try - { + { f4(); BOOST_TEST(false); - } - catch( - my_error const & e ) - { + } + catch( my_error const & e ) + { BOOST_TEST(!leaf::peek>(exp,e)); BOOST_TEST(!leaf::peek>(exp,e)); BOOST_TEST(!leaf::peek>(exp,e)); @@ -100,19 +97,21 @@ test( std::function const & f ) BOOST_TEST(leaf::leaf_detail::tl_slot_ptr>()!=0); BOOST_TEST(leaf::leaf_detail::tl_slot_ptr>()!=0); BOOST_TEST(leaf::leaf_detail::tl_slot_ptr>()!=0); - } } -int -main() +} + +int main() +{ + test( [ ] { - test( [ ] - { leaf::throw_exception( my_error(), info<1>{1} ); - } ); + } ); + test( [ ] - { + { auto propagate = leaf::preload(info<1>{1}); throw my_error(); - } ); + } ); + return boost::report_errors(); - } +} diff --git a/test/expect_test.1.cpp b/test/expect_test.1.cpp index 97c3952..00b9202 100644 --- a/test/expect_test.1.cpp +++ b/test/expect_test.1.cpp @@ -11,27 +11,26 @@ namespace leaf = boost::leaf; struct info { int value; }; -leaf::error -g() - { +leaf::error g() +{ leaf::expect exp; return leaf::error(); - } -leaf::error -f() - { +} + +leaf::error f() +{ return g(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; int c=0; BOOST_TEST( !handle_error( exp, f(), leaf::match( [&c]( int i ) - { + { ++c; - } ) ) ); + } ) ) ); BOOST_TEST(c==0); return boost::report_errors(); - } +} diff --git a/test/expect_test.2.cpp b/test/expect_test.2.cpp index 3b56b12..e4cca6f 100644 --- a/test/expect_test.2.cpp +++ b/test/expect_test.2.cpp @@ -14,42 +14,42 @@ struct info { int value; }; struct my_error: std::exception { }; -void -g() - { +void g() +{ leaf::expect exp; throw my_error(); - } -void -f() - { +} + +void f() +{ return g(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; try - { + { f(); BOOST_TEST(false); - } + } catch( my_error & e ) - { + { int c=0; try - { + { handle_exception( exp, e, leaf::match( [&c]( int i ) - { + { ++c; - } ) ); + } ) ); BOOST_TEST(false); - } - catch( my_error & ) - { - } - BOOST_TEST(c==0); } - return boost::report_errors(); + catch( my_error & ) + { + } + BOOST_TEST(c==0); } + + return boost::report_errors(); +} diff --git a/test/expect_test.3.cpp b/test/expect_test.3.cpp index 79c25d6..bc1859d 100644 --- a/test/expect_test.3.cpp +++ b/test/expect_test.3.cpp @@ -14,42 +14,42 @@ struct info { int value; }; struct my_error: std::exception { }; -void -g() - { +void g() +{ leaf::expect exp; leaf::throw_exception(my_error()); - } -void -f() - { +} + +void f() +{ return g(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; try - { + { f(); BOOST_TEST(false); - } + } catch( my_error & e ) - { + { int c=0; try - { + { handle_exception( exp, e, leaf::match( [&c]( int i ) - { + { ++c; - } ) ); + } ) ); BOOST_TEST(false); - } - catch( my_error & ) - { - } - BOOST_TEST(c==0); } - return boost::report_errors(); + catch( my_error & ) + { + } + BOOST_TEST(c==0); } + + return boost::report_errors(); +} diff --git a/test/multiple_errors_test.cpp b/test/multiple_errors_test.cpp index 8fd8e72..aaf9a0b 100644 --- a/test/multiple_errors_test.cpp +++ b/test/multiple_errors_test.cpp @@ -10,54 +10,53 @@ namespace leaf = boost::leaf; template -struct -info - { +struct info +{ int value; - }; -leaf::error -f12() - { +}; + +leaf::error f12() +{ return leaf::error( info<1>{1}, info<2>{2} ); - } -leaf::error -f34() - { +} + +leaf::error f34() +{ return leaf::error( info<3>{3}, info<4>{4} ); - } -int -main() - { +} + +int main() +{ leaf::expect,info<2>,info<3>,info<4>> exp; leaf::error e1=f12(); leaf::error e2=f34(); int e1c1=0, e1c2=0; BOOST_TEST( handle_error( exp, e1, leaf::match,info<4>>( [&e1c1]( int, int ) - { + { ++e1c1; - } ), + } ), leaf::match,info<2>>( [&e1c2]( int i1, int i2 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); ++e1c2; - } ) ) ); + } ) ) ); BOOST_TEST(e1c1==0); BOOST_TEST(e1c2==1); int e2c1=0, e2c2=0; BOOST_TEST( handle_error( exp, e2, leaf::match,info<2>>( [&e2c1]( int, int ) - { + { ++e2c1; - } ), + } ), leaf::match,info<4>>( [&e2c2]( int i3, int i4 ) - { + { BOOST_TEST(i3==3); BOOST_TEST(i4==4); ++e2c2; - } ) ) ); + } ) ) ); BOOST_TEST(e2c1==0); BOOST_TEST(e2c2==1); return boost::report_errors(); - } +} diff --git a/test/optional_test.cpp b/test/optional_test.cpp index 13b3006..112aed2 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -13,74 +13,81 @@ struct error { }; int object_count=0; int value_count=0; -class -my_info - { +class my_info +{ my_info & operator=( my_info const & ) = delete; - public: + +public: + int value; - explicit - my_info( int value ): + + explicit my_info( int value ): value(value) - { + { BOOST_TEST(++object_count>0); BOOST_TEST(++value_count>0); - } + } + my_info( my_info const & x ): value(x.value) - { + { BOOST_TEST(++object_count>0); BOOST_TEST(++value_count>0); - } + } + my_info( my_info && x ): value(x.value) - { + { x.value=-1; BOOST_TEST(++object_count>0); - } + } ~my_info() - { + { BOOST_TEST(--object_count>=0); if( value!=-1 ) BOOST_TEST(--value_count>=0); - } - }; + } +}; -class -throws_on_copy - { +class throws_on_copy +{ throws_on_copy & operator=( throws_on_copy const & )=delete; - public: - int value; - throws_on_copy() - { - BOOST_TEST(++object_count>0); - } - throws_on_copy( throws_on_copy const & ) - { - throw error(); - } - throws_on_copy( throws_on_copy && ) - { - BOOST_TEST(++object_count>0); - } - ~throws_on_copy() - { - BOOST_TEST(--object_count>=0); - } - }; -void -run_tests() +public: + + int value; + + throws_on_copy() { + BOOST_TEST(++object_count>0); + } + + throws_on_copy( throws_on_copy const & ) + { + throw error(); + } + + throws_on_copy( throws_on_copy && ) + { + BOOST_TEST(++object_count>0); + } + + ~throws_on_copy() + { + BOOST_TEST(--object_count>=0); + } +}; + +void run_tests() +{ using leaf::leaf_detail::optional; - { + { optional x; BOOST_TEST(!x.has_value()); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { my_info a(42); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -89,24 +96,24 @@ run_tests() BOOST_TEST(value_count==2); BOOST_TEST(x.has_value()); BOOST_TEST(x.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { throws_on_copy a; BOOST_TEST(object_count==1); try - { + { optional x(a); BOOST_TEST(false); - } - catch( error & ) - { - } } + catch( error & ) + { + } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { my_info a(42); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -115,10 +122,10 @@ run_tests() BOOST_TEST(value_count==1); BOOST_TEST(x.has_value()); BOOST_TEST(x.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -131,10 +138,10 @@ run_tests() BOOST_TEST(x.value().value==42); BOOST_TEST(y.has_value()); BOOST_TEST(y.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -146,10 +153,10 @@ run_tests() BOOST_TEST(!x.has_value()); BOOST_TEST(y.has_value()); BOOST_TEST(y.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -163,10 +170,10 @@ run_tests() BOOST_TEST(x.value().value==42); BOOST_TEST(y.has_value()); BOOST_TEST(y.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -182,28 +189,28 @@ run_tests() BOOST_TEST(x.value().value==42); BOOST_TEST(y.has_value()); BOOST_TEST(y.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x((throws_on_copy())); BOOST_TEST(object_count==1); BOOST_TEST(x.has_value()); optional y; try - { + { (void) (y=x); - } + } catch( error & ) - { - } + { + } BOOST_TEST(object_count==1); BOOST_TEST(x.has_value()); BOOST_TEST(!y.has_value()); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -216,10 +223,10 @@ run_tests() BOOST_TEST(!x.has_value()); BOOST_TEST(y.has_value()); BOOST_TEST(y.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -234,10 +241,10 @@ run_tests() BOOST_TEST(!x.has_value()); BOOST_TEST(y.has_value()); BOOST_TEST(y.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x; my_info a(42); x.put(a); @@ -245,10 +252,10 @@ run_tests() BOOST_TEST(value_count==2); BOOST_TEST(x.has_value()); BOOST_TEST(x.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(43)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -258,20 +265,20 @@ run_tests() BOOST_TEST(value_count==2); BOOST_TEST(x.has_value()); BOOST_TEST(x.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x; x.put(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); BOOST_TEST(x.has_value()); BOOST_TEST(x.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(43)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -280,10 +287,10 @@ run_tests() BOOST_TEST(value_count==1); BOOST_TEST(x.has_value()); BOOST_TEST(x.value().value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); @@ -292,24 +299,23 @@ run_tests() BOOST_TEST(value_count==1); BOOST_TEST(!x.has_value()); BOOST_TEST(a.value==42); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - { + { optional x(my_info(42)); BOOST_TEST(object_count==1); BOOST_TEST(value_count==1); BOOST_TEST(x.has_value()); x.reset(); BOOST_TEST(!x.has_value()); - } + } BOOST_TEST(!object_count); BOOST_TEST(!value_count); - } +} -int -main() - { +int main() +{ run_tests(); return boost::report_errors(); - } +} diff --git a/test/preload_test.1.cpp b/test/preload_test.1.cpp index 9468895..187c5a8 100644 --- a/test/preload_test.1.cpp +++ b/test/preload_test.1.cpp @@ -11,43 +11,42 @@ namespace leaf = boost::leaf; template -struct -info - { +struct info +{ int value; - }; -leaf::error -f0() - { +}; + +leaf::error f0() +{ auto propagate = leaf::preload( info<0>{0} ); return leaf::error( info<2>{2} ); - } -leaf::error -f1() - { +} + +leaf::error f1() +{ auto propagate = leaf::preload( info<0>{-1}, info<1>{1}, info<2>{-1} ); return f0(); - } -leaf::error -f2() - { +} + +leaf::error f2() +{ return f1().propagate( info<4>{4} ); - } -int -main() - { +} + +int main() +{ leaf::expect,info<1>,info<2>,info<3>,info<4>> exp; leaf::error e = f2(); BOOST_TEST(!leaf::peek>(exp,e)); int c=0; BOOST_TEST( handle_error( exp, e, leaf::match,info<2>,info<4>>( [&c]( int i1, int i2, int i4 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); BOOST_TEST(i4==4); ++c; - } ) ) ); + } ) ) ); BOOST_TEST(c==1); return boost::report_errors(); - } +} diff --git a/test/preload_test.2.cpp b/test/preload_test.2.cpp index b3156e2..c86ae33 100644 --- a/test/preload_test.2.cpp +++ b/test/preload_test.2.cpp @@ -13,36 +13,36 @@ namespace leaf = boost::leaf; struct info { int value; }; -leaf::result -g1() - { +leaf::result g1() +{ auto propagate = leaf::preload( info{1} ); return { }; - } -leaf::result -g2() - { +} + +leaf::result g2() +{ return leaf::error(); - } -leaf::result -f() - { +} + +leaf::result f() +{ auto propagate = leaf::preload( info{2} ); LEAF_CHECK(g1()); return g2(); - } +} + int main() - { +{ leaf::expect exp; leaf::result r = f(); int c=0; BOOST_TEST( handle_error( exp, r, leaf::match( [&c]( int x ) - { + { BOOST_TEST(x==2); ++c; - } ) ) ); + } ) ) ); BOOST_TEST(c==1); return boost::report_errors(); - } +} diff --git a/test/preload_test.3.cpp b/test/preload_test.3.cpp index 59ffad1..12fb206 100644 --- a/test/preload_test.3.cpp +++ b/test/preload_test.3.cpp @@ -15,41 +15,40 @@ struct my_error: std::exception { }; struct info { int value; }; -void -g1() - { +void g1() +{ auto propagate = leaf::preload( info{1} ); - } -void -g2() - { +} + +void g2() +{ throw my_error(); - } -void -f() - { +} + +void f() +{ auto propagate = leaf::preload( info{2} ); g1(); g2(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; try - { + { f(); - } + } catch( my_error & e ) - { + { int c=0; handle_exception( exp, e, leaf::match( [&c]( int x ) - { + { BOOST_TEST(x==2); ++c; - } ) ); + } ) ); BOOST_TEST(c==1); - } - return boost::report_errors(); } + return boost::report_errors(); +} diff --git a/test/preload_test.4.cpp b/test/preload_test.4.cpp index 5f2f62e..986febb 100644 --- a/test/preload_test.4.cpp +++ b/test/preload_test.4.cpp @@ -15,41 +15,40 @@ struct my_error: std::exception { }; struct info { int value; }; -void -g1() - { +void g1() +{ auto propagate = leaf::preload( info{1} ); - } -void -g2() - { +} + +void g2() +{ leaf::throw_exception(my_error()); - } -void -f() - { +} + +void f() +{ auto propagate = leaf::preload( info{2} ); g1(); g2(); - } -int -main() - { +} + +int main() +{ leaf::expect exp; try - { + { f(); - } + } catch( my_error & e ) - { + { int c=0; handle_exception( exp, e, leaf::match( [&c]( int x ) - { + { BOOST_TEST(x==2); ++c; - } ) ); + } ) ); BOOST_TEST(c==1); - } - return boost::report_errors(); } + return boost::report_errors(); +} diff --git a/test/print_test.cpp b/test/print_test.cpp index 08a1d2e..93846b4 100644 --- a/test/print_test.cpp +++ b/test/print_test.cpp @@ -10,84 +10,82 @@ namespace leaf = boost::leaf; -struct -c1 - { +struct c1 +{ int value; - friend - std::ostream & - operator<<( std::ostream & os, c1 const & ) - { + + friend std::ostream & operator<<( std::ostream & os, c1 const & ) + { return os << "c1"; - } - }; -struct -c2 - { - int value; - }; -std::ostream & -operator<<( std::ostream & os, c2 const & ) - { - return os << "c2"; } -struct -c3 - { +}; + +struct c2 +{ int value; - }; -struct -c4 - { +}; + +std::ostream & operator<<( std::ostream & os, c2 const & ) +{ + return os << "c2"; +} + +struct c3 +{ + int value; +}; + +struct c4 +{ struct unprintable { }; unprintable value;; - }; +}; + template -bool -check( T const & x, char const * sub ) - { +bool check( T const & x, char const * sub ) +{ using namespace leaf::leaf_detail; std::ostringstream s; diagnostic::print(s,x); std::string q = s.str(); return q.find(sub)!=q.npos; - } -int -main() - { +} + +int main() +{ BOOST_TEST(check(c1{42},"c1")); - { + { c1 x; c1 & y = x; BOOST_TEST(check(x,"c1")); BOOST_TEST(check(y,"c1")); - } + } BOOST_TEST(check(c2{42},"c2")); - { + { c2 x = {42}; c2 & y = x; BOOST_TEST(check(x,"c2")); BOOST_TEST(check(y,"c2")); - } + } BOOST_TEST(check(c3{42},"c3")); BOOST_TEST(check(c3{42},"42")); - { + { c3 x = {42}; c3 & y = x; BOOST_TEST(check(x,"c3")); BOOST_TEST(check(x,"42")); BOOST_TEST(check(y,"c3")); BOOST_TEST(check(y,"42")); - } + } BOOST_TEST(check(c4(),"c4")); BOOST_TEST(check(c4(),"N/A")); - { + { c4 x; c4 & y = x; BOOST_TEST(check(x,"c4")); BOOST_TEST(check(x,"N/A")); BOOST_TEST(check(y,"c4")); BOOST_TEST(check(y,"N/A")); - } - return boost::report_errors(); } + return boost::report_errors(); +} diff --git a/test/result_capture_test.cpp b/test/result_capture_test.cpp index ec432c9..e8d21ef 100644 --- a/test/result_capture_test.cpp +++ b/test/result_capture_test.cpp @@ -16,64 +16,63 @@ namespace leaf = boost::leaf; template struct info { int value; }; -struct -fut_info - { +struct fut_info +{ int a; int b; int result; std::future> fut; - }; +}; + template -std::vector -launch_tasks( int task_count, F f ) - { +std::vector launch_tasks( int task_count, F f ) +{ assert(task_count>0); std::vector fut; std::generate_n( std::inserter(fut,fut.end()), task_count, [f] - { + { int const a = rand(); int const b = rand(); int const res = (rand()%10) - 5; return fut_info { a, b, res, std::async( std::launch::async, [f,a,b,res] { - leaf::expect,info<2>,info<3>> exp; - return capture(exp,f(a,b,res)); + leaf::expect,info<2>,info<3>> exp; + return capture(exp,f(a,b,res)); } ) }; - } ); + } ); return fut; - } -int -main() - { +} + +int main() +{ std::vector fut = launch_tasks( 42, [ ]( int a, int b, int res ) noexcept -> leaf::result - { + { if( res>=0 ) return res; else return leaf::error(info<1>{a},info<2>{b},info<3>{}); - } ); + } ); for( auto & f : fut ) - { + { using namespace leaf::leaf_detail; f.fut.wait(); leaf::expect,info<2>,info<4>> exp; if( leaf::result r = f.fut.get() ) - { + { BOOST_TEST(*r>=0); BOOST_TEST(*r==f.result); - } + } else - { + { int c=0; BOOST_TEST( handle_error( exp, r, leaf::match,info<2>>( [&f,&c]( int x1, int x2 ) - { + { BOOST_TEST(x1==f.a); BOOST_TEST(x2==f.b); ++c; - } ) ) ); + } ) ) ); BOOST_TEST(c==1); - } } - return boost::report_errors(); } + return boost::report_errors(); +} diff --git a/test/result_test.1.cpp b/test/result_test.1.cpp index 5cd80f0..72364fd 100644 --- a/test/result_test.1.cpp +++ b/test/result_test.1.cpp @@ -11,69 +11,68 @@ namespace leaf = boost::leaf; -struct -my_value - { - }; +struct my_value +{ +}; + template -struct -info - { +struct info +{ int value; - }; -leaf::result -f1( bool success ) - { +}; + +leaf::result f1( bool success ) +{ if( success ) return { }; else return leaf::error( info<1>{1} ); - } -leaf::result -f2( bool success ) - { +} + +leaf::result f2( bool success ) +{ leaf::expect> exp; if( leaf::result r=f1(success) ) return r; else return r.error( info<2>{2} ); - } -leaf::result -f3( bool success ) - { +} + +leaf::result f3( bool success ) +{ leaf::expect,info<3>> exp; auto propagate = leaf::preload( info<4>{4} ); return f2(success); - } -leaf::result -f4( bool success ) - { +} + +leaf::result f4( bool success ) +{ leaf::expect,info<2>,info<3>,info<4>> exp; if( leaf::result r = f3( success ) ) return r; else - { + { int c1=0, c2=0; BOOST_TEST( handle_error( exp, r, leaf::match,info<2>,info<3>,info<4>>( [&c1]( int, int, int, int ) - { + { ++c1; - } ), + } ), leaf::match,info<2>,info<4>>( [&c2]( int i1, int i2, int i4 ) - { + { BOOST_TEST(i1==1); BOOST_TEST(i2==2); BOOST_TEST(i4==4); ++c2; - } ) ) ); + } ) ) ); BOOST_TEST(c1==0); BOOST_TEST(c2==1); return leaf::error(); - } } -int -main() - { +} + +int main() +{ leaf::expect,info<3>,info<4>> exp; BOOST_TEST(f4(true)); leaf::result r=f4(false); @@ -87,4 +86,4 @@ main() BOOST_TEST(leaf::leaf_detail::tl_slot_ptr>()!=0); BOOST_TEST(leaf::leaf_detail::tl_slot_ptr>()!=0); return boost::report_errors(); - } +} diff --git a/test/result_test.2.cpp b/test/result_test.2.cpp index 06ecc18..5b1d079 100644 --- a/test/result_test.2.cpp +++ b/test/result_test.2.cpp @@ -11,57 +11,62 @@ namespace leaf = boost::leaf; -struct -val - { +struct val +{ static int count; + val() - { + { ++count; - } + } + val( val const & ) - { + { ++count; - } + } + val( val && ) - { + { ++count; - } + } + ~val() - { + { --count; - } - }; + } +}; int val::count = 0; -struct -err - { +struct err +{ static int count; + err() - { + { ++count; - } + } + err( err const & ) - { + { ++count; - } + } + err( err && ) - { + { ++count; - } + } + ~err() - { + { --count; - } - }; + } +}; int err::count = 0; struct e_err { err value; }; -int -main() - { - { //value default-copy +int main() +{ + { //value default-copy leaf::expect exp; leaf::result r1; BOOST_TEST(r1); @@ -71,10 +76,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move-copy + { //value move-copy leaf::expect exp; leaf::result r1 = val(); BOOST_TEST(r1); @@ -84,10 +89,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value copy-copy + { //value copy-copy leaf::expect exp; val v; leaf::result r1 = v; @@ -98,11 +103,11 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==3); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value default-move + { //value default-move leaf::expect exp; leaf::result r1; BOOST_TEST(r1); @@ -112,10 +117,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move-move + { //value move-move leaf::expect exp; leaf::result r1 = val(); BOOST_TEST(r1); @@ -125,10 +130,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move-move + { //value move-move leaf::expect exp; val v; leaf::result r1 = v; @@ -139,11 +144,11 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==3); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value default-assign copy + { //value default-assign copy leaf::expect exp; leaf::result r1; BOOST_TEST(r1); @@ -153,10 +158,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move-assign copy + { //value move-assign copy leaf::expect exp; leaf::result r1 = val(); BOOST_TEST(r1); @@ -166,10 +171,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move-assign copy + { //value move-assign copy leaf::expect exp; val v; leaf::result r1 = v; @@ -180,11 +185,11 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==3); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value default-assign move + { //value default-assign move leaf::expect exp; leaf::result r1; BOOST_TEST(r1); @@ -194,10 +199,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move-assign move + { //value move-assign move leaf::expect exp; leaf::result r1 = val(); BOOST_TEST(r1); @@ -207,10 +212,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move-assign move + { //value move-assign move leaf::expect exp; val v; leaf::result r1 = v; @@ -221,11 +226,11 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==3); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value default - capture - copy + { //value default - capture - copy leaf::expect exp; leaf::result r1 = capture(exp,leaf::result()); BOOST_TEST(r1); @@ -235,10 +240,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move - capture - copy + { //value move - capture - copy leaf::expect exp; leaf::result r1 = capture(exp,leaf::result(val())); BOOST_TEST(r1); @@ -248,10 +253,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value copy - capture - copy + { //value copy - capture - copy leaf::expect exp; val v; leaf::result r1 = capture(exp,leaf::result(v)); @@ -262,11 +267,11 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==3); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value default - capture - move + { //value default - capture - move leaf::expect exp; leaf::result r1 = capture(exp,leaf::result()); BOOST_TEST(r1); @@ -276,10 +281,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move - capture - move + { //value move - capture - move leaf::expect exp; leaf::result r1 = capture(exp,leaf::result(val())); BOOST_TEST(r1); @@ -289,10 +294,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move - capture - move + { //value move - capture - move leaf::expect exp; val v; leaf::result r1 = capture(exp,leaf::result(v)); @@ -303,11 +308,11 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==3); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value default - capture - assign copy + { //value default - capture - assign copy leaf::expect exp; leaf::result r1 = capture(exp,leaf::result()); BOOST_TEST(r1); @@ -317,10 +322,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move - capture - assign copy + { //value move - capture - assign copy leaf::expect exp; leaf::result r1 = capture(exp,leaf::result(val())); BOOST_TEST(r1); @@ -330,10 +335,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move - capture - assign copy + { //value move - capture - assign copy leaf::expect exp; val v; leaf::result r1 = capture(exp,leaf::result(v)); @@ -344,11 +349,11 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==3); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value default - capture - assign move + { //value default - capture - assign move leaf::expect exp; leaf::result r1 = capture(exp,leaf::result()); BOOST_TEST(r1); @@ -358,10 +363,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move - capture - assign move + { //value move - capture - assign move leaf::expect exp; leaf::result r1 = capture(exp,leaf::result(val())); BOOST_TEST(r1); @@ -371,10 +376,10 @@ main() BOOST_TEST(r2); BOOST_TEST(err::count==0); BOOST_TEST(val::count==2); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //value move - capture - assign move + { //value move - capture - assign move leaf::expect exp; val v; leaf::result r1 = capture(exp,leaf::result(v)); @@ -389,7 +394,7 @@ main() BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - copy + { //error move - copy leaf::expect exp; leaf::result r1 = leaf::error( e_err { } ); BOOST_TEST(!r1); @@ -400,10 +405,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - copy + { //error copy - copy leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = e; @@ -415,11 +420,11 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - move + { //error move - move leaf::expect exp; leaf::result r1 = leaf::error( e_err { } ); BOOST_TEST(!r1); @@ -430,10 +435,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - move + { //error copy - move leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = e; @@ -445,11 +450,11 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - assign copy + { //error move - assign copy leaf::expect exp; leaf::result r1 = leaf::error( e_err { } ); BOOST_TEST(!r1); @@ -460,10 +465,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - assign copy + { //error copy - assign copy leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = e; @@ -475,11 +480,11 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - assign move + { //error move - assign move leaf::expect exp; leaf::result r1 = leaf::error( e_err { } ); BOOST_TEST(!r1); @@ -490,10 +495,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - assign move + { //error copy - assign move leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = e; @@ -505,11 +510,11 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - capture - copy + { //error move - capture - copy leaf::expect exp; leaf::result r1 = capture( exp, leaf::result( leaf::error( e_err { } ) ) ); BOOST_TEST(!r1); @@ -520,10 +525,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - capture - copy + { //error copy - capture - copy leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = capture( exp, leaf::result(e) ); @@ -535,11 +540,11 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - capture - move + { //error move - capture - move leaf::expect exp; leaf::result r1 = capture( exp, leaf::result( leaf::error( e_err { } ) ) ); BOOST_TEST(!r1); @@ -550,10 +555,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - capture - move + { //error copy - capture - move leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = capture( exp, leaf::result(e) ); @@ -565,11 +570,11 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - capture - assign copy + { //error move - capture - assign copy leaf::expect exp; leaf::result r1 = capture( exp, leaf::result( leaf::error( e_err { } ) ) ); BOOST_TEST(!r1); @@ -580,10 +585,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - capture - assign copy + { //error copy - capture - assign copy leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = capture( exp, leaf::result(e) ); @@ -595,11 +600,11 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error move - capture - assign move + { //error move - capture - assign move leaf::expect exp; leaf::result r1 = capture( exp, leaf::result( leaf::error( e_err { } ) ) ); BOOST_TEST(!r1); @@ -610,10 +615,10 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); - { //error copy - capture - assign move + { //error copy - capture - assign move leaf::expect exp; leaf::error e( e_err{ } ); leaf::result r1 = capture( exp, leaf::result(e) ); @@ -625,9 +630,9 @@ main() BOOST_TEST(handle_error(exp,r2,leaf::match<>())); BOOST_TEST(err::count==1); BOOST_TEST(val::count==0); - } + } BOOST_TEST(err::count==0); BOOST_TEST(val::count==0); return boost::report_errors(); - } +} diff --git a/test/result_test.3.cpp b/test/result_test.3.cpp index fb21c27..dae7e77 100644 --- a/test/result_test.3.cpp +++ b/test/result_test.3.cpp @@ -11,42 +11,44 @@ namespace leaf = boost::leaf; -struct -err - { +struct err +{ static int count; + err() - { + { ++count; - } + } + err( err const & ) - { + { ++count; - } + } + err( err && ) - { + { ++count; - } + } + ~err() - { + { --count; - } - }; + } +}; int err::count = 0; struct e_err1 { err value; }; struct e_err2 { err value; }; -int -main() - { +int main() +{ leaf::result r0; - { + { leaf::expect exp; leaf::result r1 = leaf::error( e_err1{ } ); BOOST_TEST(!r1); r0 = capture(exp,r1); BOOST_TEST(err::count==1); - } + } BOOST_TEST(err::count==1); BOOST_TEST(!r0); leaf::expect exp; @@ -54,4 +56,4 @@ main() BOOST_TEST(err::count==2); BOOST_TEST(handle_error(exp,r2,leaf::match())); return boost::report_errors(); - } +} diff --git a/test/result_void_capture_test.cpp b/test/result_void_capture_test.cpp index fdb8e20..b10679f 100644 --- a/test/result_void_capture_test.cpp +++ b/test/result_void_capture_test.cpp @@ -16,22 +16,21 @@ namespace leaf = boost::leaf; template struct info { int value; }; -struct -fut_info - { +struct fut_info +{ int a; int b; int result; std::future> fut; - }; +}; + template -std::vector -launch_tasks( int task_count, F f ) - { +std::vector launch_tasks( int task_count, F f ) +{ assert(task_count>0); std::vector fut; std::generate_n( std::inserter(fut,fut.end()), task_count, [f] - { + { int const a = rand(); int const b = rand(); int const res = (rand()%10) - 5; @@ -40,29 +39,30 @@ launch_tasks( int task_count, F f ) leaf::expect,info<2>,info<3>> exp; return capture(exp,f(a,b,res)); } ) }; - } ); + } ); return fut; - } -int -main() - { +} + +int main() +{ std::vector fut = launch_tasks( 42, [ ]( int a, int b, int res ) noexcept -> leaf::result - { + { if( res>=0 ) return { }; else return leaf::error(info<1>{a},info<2>{b},info<3>{}); - } ); + } ); + for( auto & f : fut ) - { + { using namespace leaf::leaf_detail; f.fut.wait(); leaf::expect,info<2>,info<4>> exp; if( leaf::result r = f.fut.get() ) - { - } + { + } else - { + { int c=0; BOOST_TEST( handle_error( exp, r, leaf::match,info<2>>( [&f,&c]( int x1, int x2 ) { @@ -71,7 +71,7 @@ main() ++c; } ) ) ); BOOST_TEST(c==1); - } } - return boost::report_errors(); } + return boost::report_errors(); +}