forked from boostorg/system
Merge branch 'develop'
This commit is contained in:
@ -60,8 +60,7 @@
|
|||||||
<a href="#Class-error_condition-constructors">Class <code>error_condition</code> constructors</a><br>
|
<a href="#Class-error_condition-constructors">Class <code>error_condition</code> constructors</a><br>
|
||||||
<a href="#Class-error_condition-modifiers">Class <code>error_condition</code> modifiers</a><br>
|
<a href="#Class-error_condition-modifiers">Class <code>error_condition</code> modifiers</a><br>
|
||||||
<a href="#Class-error_condition-observers">Class <code>error_condition</code> observers</a><br>
|
<a href="#Class-error_condition-observers">Class <code>error_condition</code> observers</a><br>
|
||||||
<a href="#throws-object"><code>throws</code> object</a><br>
|
<a href="#Function-boost-throws">Function <code>boost::throws()</code></a><br>
|
||||||
<a href="#Semantics-of-throws">Semantics of <code>throws</code> object</a><br>
|
|
||||||
<a href="#Non-member-functions">Non-member functions</a><br>
|
<a href="#Non-member-functions">Non-member functions</a><br>
|
||||||
<a href="#Header-system_error">Header <boost/system/system_error.hpp></a><br>
|
<a href="#Header-system_error">Header <boost/system/system_error.hpp></a><br>
|
||||||
<a href="#Class-system_error">Class <code>system_error</code></a><br>
|
<a href="#Class-system_error">Class <code>system_error</code></a><br>
|
||||||
@ -316,8 +315,12 @@ fixed by globally adding () to these names to turn them into function calls.</p>
|
|||||||
operator<<( basic_ostream<charT,traits>& os, const error_code & ec );
|
operator<<( basic_ostream<charT,traits>& os, const error_code & ec );
|
||||||
|
|
||||||
size_t hash_value( const error_code & ec );
|
size_t hash_value( const error_code & ec );
|
||||||
}
|
|
||||||
}</pre>
|
} // namespace system
|
||||||
|
|
||||||
|
system::error_code & throws();
|
||||||
|
|
||||||
|
} // namespace boost</pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p>The value of each<code> errc_t</code> constant shall be the same as the
|
<p>The value of each<code> errc_t</code> constant shall be the same as the
|
||||||
value of the <code><cerrno></code> macro shown in the above synopsis.</p>
|
value of the <code><cerrno></code> macro shown in the above synopsis.</p>
|
||||||
@ -644,36 +647,6 @@ observers</a></h3>
|
|||||||
<code>int</code>) that can occur with <code>bool</code> are not allowed,
|
<code>int</code>) that can occur with <code>bool</code> are not allowed,
|
||||||
eliminating some sources of user error. One possible implementation choice for
|
eliminating some sources of user error. One possible implementation choice for
|
||||||
this type is pointer to member. <i>--end note</i> <i>]</i></p>
|
this type is pointer to member. <i>--end note</i> <i>]</i></p>
|
||||||
</blockquote>
|
|
||||||
<h2><a name="throws-object"><code>throws</code> object</a></h2>
|
|
||||||
<pre>extern error_code throws;</pre>
|
|
||||||
<p>The predefined <code>error_code</code> object <code>throws</code> is supplied
|
|
||||||
for use as a "throw on error" tag.</p>
|
|
||||||
<h2><a name="Semantics-of-throws">Semantics of <code>throws</code></a> object</h2>
|
|
||||||
<p>Functions that specify an argument in the form <code>error_code& ec=throws</code>,
|
|
||||||
with appropriate namespace qualifiers, have the following error handling
|
|
||||||
semantics:</p>
|
|
||||||
<blockquote>
|
|
||||||
<p><i>Postconditions:</i></p>
|
|
||||||
<blockquote>
|
|
||||||
<p>If <code>&ec != &throws</code> and an error occurred:</p>
|
|
||||||
<ul>
|
|
||||||
<li> <code>ec.value()</code> returns the implementation specific error
|
|
||||||
number for the particular error that occurred.</li>
|
|
||||||
<li><code>ec.category()</code> returns the <code>
|
|
||||||
<a href="#Class-error_category">error_category</a></code> for <code>ec.value()</code>.</li>
|
|
||||||
</ul>
|
|
||||||
<p>if <code>&ec != &throws</code> and an error did not occur, <code>ec.clear()</code>.</p>
|
|
||||||
</blockquote>
|
|
||||||
<p><i>Throws:</i></p>
|
|
||||||
<blockquote>
|
|
||||||
<p>If an error occurs and <code>&ec == &throws</code>, throws an exception of type
|
|
||||||
<code><a href="#Class-system_error">system_error</a></code> or of a type
|
|
||||||
derived from <code><a href="#Class-system_error">system_error</a></code>. The
|
|
||||||
exception's <code>code()</code> member function returns a reference to an
|
|
||||||
<code>error_code</code> object with the behavior specified in <i>
|
|
||||||
Postconditions</i>.</p>
|
|
||||||
</blockquote>
|
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<h2><a name="Non-member-functions">Non-member functions</a></h2>
|
<h2><a name="Non-member-functions">Non-member functions</a></h2>
|
||||||
<pre>bool operator==( const error_code & lhs, const error_code & rhs ) noexcept;</pre>
|
<pre>bool operator==( const error_code & lhs, const error_code & rhs ) noexcept;</pre>
|
||||||
@ -736,6 +709,37 @@ bool operator!=( const error_condition & condition, const error_code & c
|
|||||||
<p><i>Returns: </i> A hash value representing <code>ec</code>.</p>
|
<p><i>Returns: </i> A hash value representing <code>ec</code>.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
<h2><a name="Function-boost-throws">Function <code>boost::throws()</code></a></h2>
|
||||||
|
|
||||||
|
<pre>system::error_code& throws();</pre>
|
||||||
|
<blockquote>
|
||||||
|
<p><i>Returns:</i> A <code>system::error_code</code> reference
|
||||||
|
for use in some user-defined function signature as a "throw on error" tag.</p>
|
||||||
|
<p><i>Remark:</i> The only valid use for the returned reference is to test its
|
||||||
|
address for equality or inequality to the address of the reference returned by
|
||||||
|
another call to throws(). The returned reference itself has been poisoned so
|
||||||
|
that an attempt to dereference it will fail.</p>
|
||||||
|
<p>[<i>Example: </i>Example of a function that uses the <code>throws()</code> idiom:</p>
|
||||||
|
<blockquote>
|
||||||
|
<pre>int divide(int dividend, int divisor,
|
||||||
|
boost::system::error_code& ec = boost::throws())
|
||||||
|
{
|
||||||
|
if (divisor == 0) // is there an error?
|
||||||
|
{
|
||||||
|
if (&ec == &boost::throws()) // throw on error
|
||||||
|
throw "oops!"; // whatever exception you prefer
|
||||||
|
ec = error_code(EDOM, generic_category()); // report error via error_code
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (&ec != &boost::throws()) // error reporting via error_code
|
||||||
|
ec.clear();
|
||||||
|
return dividend / divisor;
|
||||||
|
}</pre>
|
||||||
|
</blockquote>
|
||||||
|
<p>— <i>end Example</i>]</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
<h2><a name="Header-system_error">Header <boost/system/system_error.hpp></a></h2>
|
<h2><a name="Header-system_error">Header <boost/system/system_error.hpp></a></h2>
|
||||||
|
|
||||||
<h3><a name="Class-system_error">Class <code>
|
<h3><a name="Class-system_error">Class <code>
|
||||||
@ -818,7 +822,7 @@ application program interfaces.</p>
|
|||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%B %d, %Y" startspan -->January 06, 2014<!--webbot bot="Timestamp" endspan i-checksum="31400" --> </font>
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%B %d, %Y" startspan -->September 07, 2017<!--webbot bot="Timestamp" endspan i-checksum="38006" --> </font>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p><EFBFBD> Copyright Beman Dawes, 2006, 2007, 2008, 2013</p>
|
<p><EFBFBD> Copyright Beman Dawes, 2006, 2007, 2008, 2013</p>
|
||||||
|
@ -542,8 +542,9 @@ namespace boost
|
|||||||
// "throws" function in namespace boost rather than namespace boost::system.
|
// "throws" function in namespace boost rather than namespace boost::system.
|
||||||
|
|
||||||
} // namespace system
|
} // namespace system
|
||||||
|
|
||||||
namespace detail { inline system::error_code * throws() { return 0; } }
|
namespace detail
|
||||||
|
{
|
||||||
// Misuse of the error_code object is turned into a noisy failure by
|
// Misuse of the error_code object is turned into a noisy failure by
|
||||||
// poisoning the reference. This particular implementation doesn't
|
// poisoning the reference. This particular implementation doesn't
|
||||||
// produce warnings or errors from popular compilers, is very efficient
|
// produce warnings or errors from popular compilers, is very efficient
|
||||||
@ -551,8 +552,17 @@ namespace boost
|
|||||||
// from order of initialization problems. In practice, it also seems
|
// from order of initialization problems. In practice, it also seems
|
||||||
// cause user function error handling implementation errors to be detected
|
// cause user function error handling implementation errors to be detected
|
||||||
// very early in the development cycle.
|
// very early in the development cycle.
|
||||||
|
inline system::error_code* throws()
|
||||||
|
{
|
||||||
|
// See github.com/boostorg/system/pull/12 by visigoth for why the return
|
||||||
|
// is poisoned with (1) rather than (0). A test, test_throws_usage(), has
|
||||||
|
// been added to error_code_test.cpp, and as visigoth mentioned it fails
|
||||||
|
// on clang for release builds with a return of 0 but works fine with (1).
|
||||||
|
return reinterpret_cast<system::error_code*>(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline system::error_code & throws()
|
inline system::error_code& throws()
|
||||||
{ return *detail::throws(); }
|
{ return *detail::throws(); }
|
||||||
|
|
||||||
namespace system
|
namespace system
|
||||||
|
@ -56,6 +56,53 @@ namespace
|
|||||||
ss >> s;
|
ss >> s;
|
||||||
BOOST_TEST( s == expected );
|
BOOST_TEST( s == expected );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// throws_function_test ------------------------------------------------------------//
|
||||||
|
|
||||||
|
// usage example
|
||||||
|
|
||||||
|
int divide(int dividend, int divisor, boost::system::error_code& ec = boost::throws())
|
||||||
|
{
|
||||||
|
if (divisor == 0) // is there an error?
|
||||||
|
{
|
||||||
|
if (&ec == &boost::throws()) // throw on error
|
||||||
|
throw "oops!"; // whatever exception you prefer
|
||||||
|
ec = error_code(EDOM, generic_category()); // report error via error_code
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (&ec != &boost::throws()) // error reporting via error_code
|
||||||
|
ec.clear();
|
||||||
|
return dividend / divisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// test usage example
|
||||||
|
|
||||||
|
void test_throws_usage()
|
||||||
|
{
|
||||||
|
std::cout << "Test throws() example and usage...\n";
|
||||||
|
error_code ec;
|
||||||
|
|
||||||
|
// no error tests
|
||||||
|
BOOST_TEST_EQ((divide(10, 2)), 5); // no error, report via exception
|
||||||
|
ec = make_error_code(errc::argument_out_of_domain);
|
||||||
|
BOOST_TEST_EQ((divide(10, 5, ec)), 2); // no error, report via error_code
|
||||||
|
BOOST_TEST(!ec);
|
||||||
|
|
||||||
|
ec = make_error_code(errc::argument_out_of_domain);
|
||||||
|
BOOST_TEST_EQ((divide(10, 0, ec)), 0); // error, report via error_code
|
||||||
|
BOOST_TEST(ec);
|
||||||
|
|
||||||
|
bool exception_thrown = false;
|
||||||
|
try
|
||||||
|
{ divide(10, 0); } // error, report via exception
|
||||||
|
catch (...)
|
||||||
|
{ exception_thrown = true; }
|
||||||
|
BOOST_TEST(exception_thrown);
|
||||||
|
|
||||||
|
//error_code should_fail(boost::throws()); // should fail at runtime
|
||||||
|
//boost::throws() = ec; // should fail at runtime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// main ------------------------------------------------------------------------------//
|
// main ------------------------------------------------------------------------------//
|
||||||
@ -202,6 +249,8 @@ int main( int, char ** )
|
|||||||
BOOST_TEST( econd.message() != "" );
|
BOOST_TEST( econd.message() != "" );
|
||||||
BOOST_TEST( econd.message().substr( 0, 13) != "Unknown error" );
|
BOOST_TEST( econd.message().substr( 0, 13) != "Unknown error" );
|
||||||
|
|
||||||
|
test_throws_usage();
|
||||||
|
|
||||||
#ifdef BOOST_WINDOWS_API
|
#ifdef BOOST_WINDOWS_API
|
||||||
std::cout << "Windows tests...\n";
|
std::cout << "Windows tests...\n";
|
||||||
// these tests probe the Windows errc decoder
|
// these tests probe the Windows errc decoder
|
||||||
|
Reference in New Issue
Block a user