From ce06820e8060798d2da521355f79798cd8167369 Mon Sep 17 00:00:00 2001 From: Ribulous Barnulous Date: Sat, 21 Mar 2015 09:21:47 -0400 Subject: [PATCH 1/2] added support for error_info r-value references --- include/boost/exception/detail/error_info_impl.hpp | 8 ++++ include/boost/exception/info.hpp | 36 ++++++++++++++++++ test/error_info_test.cpp | 43 ++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/include/boost/exception/detail/error_info_impl.hpp b/include/boost/exception/detail/error_info_impl.hpp index 12e601b5..e7426c8c 100644 --- a/include/boost/exception/detail/error_info_impl.hpp +++ b/include/boost/exception/detail/error_info_impl.hpp @@ -12,6 +12,7 @@ #pragma warning(push,1) #endif +#include #include namespace @@ -46,6 +47,13 @@ boost typedef T value_type; error_info( value_type const & value ); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + error_info( value_type && value); + error_info( error_info const & ) = default; + error_info( error_info && ) = default; + error_info& operator=( error_info const & ) = default; + error_info& operator=( error_info && ) = default; +#endif ~error_info() throw(); value_type const & diff --git a/include/boost/exception/info.hpp b/include/boost/exception/info.hpp index 762a950f..68490ec4 100644 --- a/include/boost/exception/info.hpp +++ b/include/boost/exception/info.hpp @@ -46,6 +46,16 @@ boost { } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + inline + error_info:: + error_info( value_type && value ): + value_(std::move(value)) + { + } +#endif + template inline error_info:: @@ -175,6 +185,22 @@ boost return x; } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + inline + E const & + set_info( E const & x, error_info && v ) + { + typedef error_info error_info_tag_t; + shared_ptr p( new error_info_tag_t(std::move(v)) ); + exception_detail::error_info_container * c=x.data_.get(); + if( !c ) + x.data_.adopt(c=new exception_detail::error_info_container_impl); + c->set(p,BOOST_EXCEPTION_STATIC_TYPEID(error_info_tag_t)); + return x; + } +#endif + template struct derives_boost_exception @@ -190,6 +216,16 @@ boost { return exception_detail::set_info(x,v); } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + inline + typename enable_if,E const &>::type + operator<<( E const & x, error_info && v ) + { + return exception_detail::set_info(x,std::move(v)); + } +#endif } #if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) diff --git a/test/error_info_test.cpp b/test/error_info_test.cpp index f3dda1a9..26496263 100644 --- a/test/error_info_test.cpp +++ b/test/error_info_test.cpp @@ -11,6 +11,9 @@ struct throws_on_copy; struct non_printable { }; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +struct move_only; +#endif struct user_data @@ -43,6 +46,9 @@ typedef boost::error_info test_4; typedef boost::error_info test_5; typedef boost::error_info test_6; typedef boost::error_info test_7; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +typedef boost::error_info test_8; +#endif struct test_exception: @@ -63,6 +69,17 @@ throws_on_copy } }; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +struct +move_only + { + move_only() = default; + move_only( move_only const & ) = delete; + move_only( move_only && ) = default; + }; +#endif + + void basic_test() { @@ -133,6 +150,14 @@ throw_test_2() throw test_exception() << test_6(non_printable()); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +void +throw_test_3() + { + throw test_exception() << test_8(move_only()); + } +#endif + void throw_catch_add_file_name( char const * name ) { @@ -224,6 +249,24 @@ test_basic_throw_catch() { BOOST_TEST(false); } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + try + { + throw_test_3(); + BOOST_ASSERT(false); + } + catch( + boost::exception & x ) + { + BOOST_TEST(boost::get_error_info(x)); + } + catch( + ... ) + { + BOOST_TEST(false); + } +#endif } void From a544388628f5c9b4da5efe926390aa7ef6b73606 Mon Sep 17 00:00:00 2001 From: Ribulous Barnulous Date: Sun, 22 Mar 2015 09:24:26 -0400 Subject: [PATCH 2/2] removed defaulted constructors and assignment operators to support more compilers; added missing header files --- include/boost/exception/detail/error_info_impl.hpp | 13 ++++--- include/boost/exception/info.hpp | 42 +++++++++++++++++++++- test/error_info_test.cpp | 9 +++-- 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/include/boost/exception/detail/error_info_impl.hpp b/include/boost/exception/detail/error_info_impl.hpp index e7426c8c..ab916794 100644 --- a/include/boost/exception/detail/error_info_impl.hpp +++ b/include/boost/exception/detail/error_info_impl.hpp @@ -14,6 +14,7 @@ #include #include +#include namespace boost @@ -48,11 +49,13 @@ boost error_info( value_type const & value ); #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - error_info( value_type && value); - error_info( error_info const & ) = default; - error_info( error_info && ) = default; - error_info& operator=( error_info const & ) = default; - error_info& operator=( error_info && ) = default; + error_info( value_type && value ); + error_info( error_info const & ); + error_info( error_info && other ) + BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(value_type(std::move(other.value_)))); + error_info& operator=( error_info const & other ); + error_info& operator=( error_info && other ) + BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(other.value_ = std::move(other.value_))); #endif ~error_info() throw(); diff --git a/include/boost/exception/info.hpp b/include/boost/exception/info.hpp index 68490ec4..255354f4 100644 --- a/include/boost/exception/info.hpp +++ b/include/boost/exception/info.hpp @@ -16,8 +16,10 @@ #include #include #include +#include #include #include +#include namespace boost @@ -54,6 +56,44 @@ boost value_(std::move(value)) { } + + template + inline + error_info:: + error_info( error_info const & other ): + value_(other.value_) + { + } + + template + inline + error_info:: + error_info( error_info && other ) + BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(value_type(std::move(other.value_)))) + : value_(std::move(other.value_)) + { + } + + template + inline + error_info& + error_info:: + operator=( error_info const & other ) + { + value_ = other.value_; + return *this; + } + + template + inline + error_info& + error_info:: + operator=( error_info && other ) + BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(other.value_ = std::move(other.value_))) + { + value_ = std::move(other.value_); + return *this; + } #endif template @@ -192,7 +232,7 @@ boost set_info( E const & x, error_info && v ) { typedef error_info error_info_tag_t; - shared_ptr p( new error_info_tag_t(std::move(v)) ); + shared_ptr p = boost::make_shared(std::move(v)); exception_detail::error_info_container * c=x.data_.get(); if( !c ) x.data_.adopt(c=new exception_detail::error_info_container_impl); diff --git a/test/error_info_test.cpp b/test/error_info_test.cpp index 26496263..96cf4ffb 100644 --- a/test/error_info_test.cpp +++ b/test/error_info_test.cpp @@ -73,9 +73,11 @@ throws_on_copy struct move_only { - move_only() = default; + move_only(int x) : x_(x) {} + move_only( move_only && other ) : x_(other.x_) {} + int x_; + private: move_only( move_only const & ) = delete; - move_only( move_only && ) = default; }; #endif @@ -154,7 +156,7 @@ throw_test_2() void throw_test_3() { - throw test_exception() << test_8(move_only()); + throw test_exception() << test_8(move_only(7)); } #endif @@ -260,6 +262,7 @@ test_basic_throw_catch() boost::exception & x ) { BOOST_TEST(boost::get_error_info(x)); + BOOST_TEST(boost::get_error_info(x)->x_ == 7); } catch( ... )