From e97bcb4c566fe6e22db64059d56b79e1162be8fa Mon Sep 17 00:00:00 2001 From: Emil Dotchevski Date: Sat, 31 Aug 2013 23:24:40 +0000 Subject: [PATCH] N3757 [SVN r85538] --- include/boost/exception/N3757.hpp | 46 ++++++++++++++++++ include/boost/exception/exception.hpp | 6 +++ test/Jamfile.v2 | 3 +- test/N3757_test.cpp | 67 +++++++++++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 include/boost/exception/N3757.hpp create mode 100644 test/N3757_test.cpp diff --git a/include/boost/exception/N3757.hpp b/include/boost/exception/N3757.hpp new file mode 100644 index 0000000..23b0606 --- /dev/null +++ b/include/boost/exception/N3757.hpp @@ -0,0 +1,46 @@ +//Copyright (c) 2006-2013 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef UUID_9011016A11A711E3B46CD9FA6088709B +#define UUID_9011016A11A711E3B46CD9FA6088709B +#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma GCC system_header +#endif +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(push,1) +#endif + +#include +#include + +namespace +boost + { + //Here we're using the boost::error_info machinery to store the info in the exception + //object. Within the context of N3757, this is strictly an implementation detail. + + template + inline + void + exception:: + set( typename Tag::type const & v ) + { + exception_detail::set_info(*this,error_info(v)); + } + + template + inline + typename Tag::type const * + exception:: + get() const + { + return get_error_info >(*this); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif +#endif diff --git a/include/boost/exception/exception.hpp b/include/boost/exception/exception.hpp index 31d4317..d762cf8 100644 --- a/include/boost/exception/exception.hpp +++ b/include/boost/exception/exception.hpp @@ -207,6 +207,12 @@ boost class exception { + // + public: + template void set( typename Tag::type const & ); + template typename Tag::type const * get() const; + // + protected: exception(): diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 6195a70..d2dfcd6 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost Exception Library test Jamfile # -# Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. +# Copyright (c) 2006-2013 Emil Dotchevski and Reverge Studios, Inc. # # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -42,6 +42,7 @@ run no_exceptions_test.cpp : : : off ; run errinfos_test.cpp ; run exception_ptr_test.cpp/BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR ../../thread/src/tss_null.cpp /boost/exception /boost//thread : : : multi : non_intrusive_exception_ptr_test ; run exception_ptr_test.cpp ../../thread/src/tss_null.cpp /boost//thread : : : multi ; +run N3757_test.cpp ; compile-fail exception_fail.cpp ; compile-fail throw_exception_fail.cpp ; diff --git a/test/N3757_test.cpp b/test/N3757_test.cpp new file mode 100644 index 0000000..caa93ba --- /dev/null +++ b/test/N3757_test.cpp @@ -0,0 +1,67 @@ +//Copyright (c) 2006-2013 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +//This file tests the N3757 syntax for adding error info to std::exception, which is +//different from the syntax used by Boost Exception. + +#include +#include +#include +#include + +struct tag1 { typedef int type; }; +struct tag2 { typedef std::string type; }; +struct tag3 { typedef int type; }; + +struct my_error_code { int ec; my_error_code(int ec):ec(ec){ } }; +struct tag_error_code { typedef my_error_code type; }; + +bool my_error_code_to_string_called=false; + +std::ostream & +operator<<( std::ostream & s, my_error_code const & x ) +{ + my_error_code_to_string_called=true; + return s << "my_error_code(" << x.ec << ')'; +} + +struct my_exception: virtual std::exception, virtual boost::exception { }; + +int +main() + { + try + { + throw my_exception(); + } + catch( + boost::exception & e ) + { + e.set(42); + e.set("42"); + e.set(42); //Implicit conversion + try + { + throw; + } + catch( + my_exception & e ) + { + BOOST_TEST(e.get() && *e.get()==42); + BOOST_TEST(e.get() && *e.get()=="42"); + BOOST_TEST(!e.get()); + BOOST_TEST(e.get() && e.get()->ec==42); + + //Below we're verifying that an error code wrapped in a user-defined type + //invokes the correct op<< to convert the error code to string. + //Note that N3757 diagnostic_information uses different syntax, it is a + //member of of std::exception. + std::string di=boost::diagnostic_information(e); + BOOST_TEST(!di.empty()); + BOOST_TEST(my_error_code_to_string_called); + } + } + return boost::report_errors(); + }