In addition, boost::diagnostic_information can be used to compose an automatic (if not user-friendly) message that contains all of the error_info objects added to a boost::exception. This is useful for inclusion in logs and other diagnostic objects.
diff --git a/doc/source/boost-exception.reno b/doc/source/boost-exception.reno
index c85fe07..594879b 100644
--- a/doc/source/boost-exception.reno
+++ b/doc/source/boost-exception.reno
@@ -320,6 +320,128 @@
reno_context
+
+
+
+
+ 7
+ 2
+ (:include include:)
(:auto also explicit="
+ 1
+
+ 0
+
+ 12
+
+ reno_context
+
+
+
+
+ 2
+
+ 1
+
+ 0
+
+ 13
+
+ reno_context
+
+
+
+
+ 2
+
+ 1
+
+ 0
+
+ -8
+
+
+ 2
+ ":)
+
+
+
+
+ 0
+
+ 14
+
+ reno_context
+
-
-
- 0
-
- 14
+ 16reno_context
@@ -462,27 +546,27 @@
1
- D9B8E6AA12A4F33953B1A961FA590C5A3840234B6531CA8C04AC985AD5800835
- 2432554768
- 702
- 408
+ 7116AEECEA666794E31DC99390ADEC1BA6AF74B2398067A0739767B4B76FA97A
+ 4128134227
+ 307
+ 3020
- ../../example/enable_error_info.cpp
+ ../../example/logging.cpp00
- integrating boost exception in existing exception class hierarchies
+ diagnostic information
- tutorial_enable_error_info
+ tutorial_diagnostic_information
@@ -497,7 +581,33 @@
0
- 15
+ -12
+
+
+
+ 1
+ 2
+ (:include include:)
(:auto also:)
+
+
+
+
+ 0
+
+ -13
+
+
+
+ 1
+ 2
+ (:include include:)
(:auto also:)
+
+
+
+
+ 0
+
+ 17reno_context
@@ -540,7 +650,7 @@
0
- 16
+ 18reno_context
@@ -549,63 +659,47 @@
- 0
+ 2
+ 9748FFBBC9F02FEB97E0BA1E6280C51FFF5D7F217F0F12EE8ED29F6BE5CCCE44
+ 2533933282
+ 8724
+ 615
+ E23085202D084CBB50F289988A6A592F06D923B77D0AB25D7A98A7188DF5BE3B
+ 1414247481
+ 766
+ 7388
- 1
+ 0
+ ../../../../boost/exception_ptr.hpp
+ 0
+ 0
- Motivation
+ current_exception
- motivation
+
- 7
+ 12
- (:include include:)
(:auto also explicit="
- 1
-
- 0
-
- -13
-
-
- 2
-
- 1
-
- 0
-
- -14
-
-
- 2
-
- 1
-
- 0
-
- -8
-
-
- 2
- ":)
+ (:include include:)
(:auto also:)
0
- 17
+ 19reno_context
@@ -658,7 +752,7 @@
0
- 18
+ 20reno_context
@@ -707,7 +801,7 @@
0
- 19
+ 21reno_context
@@ -752,52 +846,7 @@
0
- 20
-
- reno_context
-
-
-
-
-
-
- 1
- 7116AEECEA666794E31DC99390ADEC1BA6AF74B2398067A0739767B4B76FA97A
- 4128134227
- 307
- 302
-
-
-
-
-
- 0
- ../../example/logging.cpp
- 0
- 0
-
-
-
-
- diagnostic information
-
-
- tutorial_diagnostic_information
-
-
-
-
-
- 1
- 2
- (:include include:)
(:auto also:)
-
-
-
-
- 0
-
- 21
+ 22reno_context
@@ -846,7 +895,7 @@
0
- 22
+ 23reno_context
@@ -885,55 +934,6 @@
0
-
-
- 0
-
- 23
-
- reno_context
-
-
-
-
-
-
- 2
- 9748FFBBC9F02FEB97E0BA1E6280C51FFF5D7F217F0F12EE8ED29F6BE5CCCE44
- 2533933282
- 8724
- 615
- E23085202D084CBB50F289988A6A592F06D923B77D0AB25D7A98A7188DF5BE3B
- 1414247481
- 766
- 7388
-
-
-
-
-
- 0
- ../../../../boost/exception_ptr.hpp
- 0
- 0
-
-
-
-
- current_exception
-
-
-
-
-
-
-
-
- 1
- 2
- (:include include:)
(:auto also:)
-
- 0
@@ -1217,6 +1217,49 @@
reno_context
+
+
+
+
+
+ 1
+ F4C951B28F7DE500973AA3DFAA99F2BADA6EDAFA2B406C30BEF3B7FBE6FD57D7
+ 2263754923
+ 982
+ 306
+
+
+
+
+
+ 0
+ ../../example/error_info_2.cpp
+ 0
+ 0
+
+
+
+
+ adding of arbitrary data to active exception objects
+
+
+ adding_data_later
+
+
+
+
+
+ 0
+
+
+
+
+ 0
+
+ 31
+
+ reno_context
+
@@ -1262,7 +1305,7 @@
0
- 31
+ 32reno_context
@@ -1311,7 +1354,7 @@
0
- 32
+ 33reno_context
@@ -1349,7 +1392,7 @@
0
- 33
+ 34reno_context
@@ -1387,7 +1430,7 @@
0
- 34
+ 35reno_context
@@ -1436,7 +1479,7 @@
0
- 35
+ 36reno_context
@@ -1485,7 +1528,7 @@
0
- 36
+ 37reno_context
@@ -1523,7 +1566,7 @@
0
- 37
+ 38reno_context
@@ -1572,7 +1615,7 @@
0
- 38
+ 39reno_context
@@ -1621,7 +1664,50 @@
0
- 39
+ 40
+
+ reno_context
+
+
+
+
+
+
+ 1
+ D10E536B909EFFF78FB09E6242AEC7C74ACDD75AE7DF32B45870422B752E5D8E
+ 1903336130
+ 557
+ 382
+
+
+
+
+
+ 0
+ ../../example/error_info_1.cpp
+ 0
+ 0
+
+
+
+
+ adding of arbitrary data at the point of the throw
+
+
+ adding_data_at_throw
+
+
+
+
+
+ 0
+
+
+
+
+ 0
+
+ 41reno_context
@@ -1659,7 +1745,7 @@
0
- 40
+ 42reno_context
@@ -1702,50 +1788,7 @@
0
- 41
-
- reno_context
-
-
-
-
-
-
- 1
- F4C951B28F7DE500973AA3DFAA99F2BADA6EDAFA2B406C30BEF3B7FBE6FD57D7
- 2263754923
- 982
- 306
-
-
-
-
-
- 0
- ../../example/error_info_2.cpp
- 0
- 0
-
-
-
-
- adding of arbitrary data to active exception objects
-
-
- adding_data_later
-
-
-
-
-
- 0
-
-
-
-
- 0
-
- 42
+ 43reno_context
@@ -1790,7 +1833,7 @@
0
- 43
+ 44reno_context
@@ -1829,49 +1872,6 @@
0
-
-
- 0
-
- 44
-
- reno_context
-
-
-
-
-
-
- 1
- D10E536B909EFFF78FB09E6242AEC7C74ACDD75AE7DF32B45870422B752E5D8E
- 1903336130
- 557
- 382
-
-
-
-
-
- 0
- ../../example/error_info_1.cpp
- 0
- 0
-
-
-
-
- adding of arbitrary data at the point of the throw
-
-
- adding_data_at_throw
-
-
-
-
-
- 0
-
- 0
@@ -2669,28 +2669,6 @@
0
-
-
- 0
-
- -12
-
-
-
- 0
-
-
-
-
- 0
-
- -13
-
-
-
- 0
-
- 0
@@ -2724,6 +2702,28 @@
0
+
+
+ 0
+
+ -12
+
+
+
+ 0
+
+
+
+
+ 0
+
+ -13
+
+
+
+ 0
+
+ 0
@@ -2951,6 +2951,17 @@
-37
+
+ 0
+
+
+
+
+ 0
+
+ -38
+
+ 72
@@ -2959,7 +2970,7 @@
0
- -37
+ -382
@@ -2988,7 +2999,7 @@
0
- -38
+ -39
@@ -2999,7 +3010,7 @@
0
- -38
+ -392
@@ -3033,17 +3044,6 @@
decl pre_indent="4":)
};@]
-
-
- 0
-
- -39
-
-
-
- 0
-
- 0
@@ -3366,28 +3366,6 @@
0
-
-
- 0
-
- -12
-
-
-
- 0
-
-
-
-
- 0
-
- -13
-
-
-
- 0
-
- 0
@@ -3421,6 +3399,28 @@
0
+
+
+ 0
+
+ -12
+
+
+
+ 0
+
+
+
+
+ 0
+
+ -13
+
+
+
+ 0
+
+ 0
@@ -3513,7 +3513,7 @@
0
- -37
+ -382
@@ -3522,7 +3522,7 @@
0
- -38
+ -392
@@ -3531,7 +3531,7 @@
0
- -38
+ -392
@@ -3540,7 +3540,7 @@
0
- -38
+ -392
@@ -3549,7 +3549,7 @@
0
- -38
+ -392
@@ -3571,7 +3571,7 @@
0
- -31
+ -322
@@ -3604,7 +3604,7 @@
0
- -18
+ -202
@@ -3772,6 +3772,17 @@
-42
+
+ 0
+
+
+
+
+ 0
+
+ -43
+
+ 52
@@ -3780,7 +3791,7 @@
0
- -21
+ -222
@@ -3796,17 +3807,6 @@
decl:)@]
-
-
- 0
-
- -43
-
-
-
- 0
-
- 0
@@ -3899,7 +3899,7 @@
0
- -42
+ -432
@@ -3986,7 +3986,7 @@
0
- -11
+ -142
@@ -4019,7 +4019,7 @@
0
- -38
+ -392
@@ -4052,7 +4052,7 @@
0
- -38
+ -392
@@ -4083,7 +4083,7 @@
0
- -30
+ -312
@@ -4092,7 +4092,7 @@
0
- -12
+ -152
@@ -4110,7 +4110,7 @@
0
- -23
+ -182
@@ -4119,7 +4119,7 @@
0
- -35
+ -362
@@ -4141,7 +4141,7 @@
0
- -19
+ -212
@@ -4150,7 +4150,7 @@
0
- -34
+ -352
@@ -4219,7 +4219,7 @@
0
- -12
+ -152
@@ -4312,7 +4312,7 @@
0
- -38
+ -392
@@ -4343,7 +4343,7 @@
0
- -38
+ -392
@@ -4352,7 +4352,7 @@
0
- -38
+ -392
@@ -4366,50 +4366,6 @@
-11
-
- 3
- 2
- [@template <class T>
---unspecified--- (:link
- 1
-
- 0
-
- -11
-
-
- 2
- :)( T const & x );@]
-
-
-
-
- 0
-
- -12
-
-
-
- 3
- 2
- [@typedef ---unspecified--- (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :);@]
-
-
-
-
- 0
-
- -13
-
- 0
@@ -4422,7 +4378,18 @@
- 0
+ 3
+ 2
+ [@template <class T>
---unspecified--- (:link
+ 1
+
+ 0
+
+ -14
+
+
+ 2
+ :)( T const & x );@]
@@ -4433,7 +4400,18 @@
- 0
+ 3
+ 2
+ [@typedef ---unspecified--- (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :);@]
@@ -4447,6 +4425,28 @@
0
+
+
+ 0
+
+ -12
+
+
+
+ 0
+
+
+
+
+ 0
+
+ -13
+
+
+
+ 0
+
+ 0
@@ -4465,6 +4465,48 @@
-18
+
+ 5
+ 2
+ [@(:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :)();@]
+
+
+
+
+ 0
+
+ -19
+
+
+
+ 0
+
+
+
+
+ 0
+
+ -20
+
+ 32
@@ -4473,7 +4515,7 @@
0
- -18
+ -202
@@ -4484,7 +4526,7 @@
0
- -19
+ -21
@@ -4504,7 +4546,7 @@
0
- -19
+ -212
@@ -4513,7 +4555,7 @@
0
- -34
+ -352
@@ -4522,7 +4564,7 @@
0
- -11
+ -142
@@ -4558,7 +4600,7 @@
0
- -19
+ -212
@@ -4567,7 +4609,7 @@
0
- -34
+ -352
@@ -4578,18 +4620,7 @@
0
- -20
-
-
-
- 0
-
-
-
-
- 0
-
- -21
+ -22
@@ -4600,24 +4631,13 @@
0
- -21
+ -222:)( E const & e );@]
-
-
- 0
-
- -22
-
-
-
- 0
-
- 0
@@ -4626,27 +4646,7 @@
- 5
- 2
- [@(:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :)();@]
+ 0
@@ -4755,6 +4755,17 @@
-30
+
+ 0
+
+
+
+
+ 0
+
+ -31
+
+ 52
@@ -4763,7 +4774,7 @@
0
- -30
+ -312
@@ -4772,7 +4783,7 @@
0
- -37
+ -382
@@ -4783,7 +4794,7 @@
0
- -31
+ -32
@@ -4803,24 +4814,13 @@
0
- -31
+ -322:)( E const & x );@]
-
-
- 0
-
- -32
-
-
-
- 0
-
- 0
@@ -4840,27 +4840,7 @@
- 5
- 2
- [@#ifdef BOOST_NO_EXCEPTIONS
void (:link
- 1
-
- 0
-
- -34
-
-
- 2
- :)( std::exception const & e ); // user defined
#else
template <class E>
void (:link
- 1
-
- 0
-
- -34
-
-
- 2
- :)( E const & e );
#endif@]
+ 0
@@ -4873,7 +4853,7 @@
52
- [@void (:link
+ [@#ifdef BOOST_NO_EXCEPTIONS
void (:link 10
@@ -4882,16 +4862,16 @@
2
- :)( (:link
+ :)( std::exception const & e ); // user defined
#else
template <class E>
void (:link 10
- -12
+ -352
- :) const & ep );
+ :)( E const & e );
#endif@]
@@ -4902,7 +4882,27 @@
- 0
+ 5
+ 2
+ [@void (:link
+ 1
+
+ 0
+
+ -36
+
+
+ 2
+ :)( (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) const & ep );
@@ -4913,18 +4913,7 @@
- 3
- 2
- [@class (:link
- 1
-
- 0
-
- -37
-
-
- 2
- :);@]
+ 0
@@ -4937,7 +4926,7 @@
32
- [@template <class Tag,class T>
class (:link
+ [@class (:link 10
@@ -4957,7 +4946,18 @@
- 0
+ 3
+ 2
+ [@template <class Tag,class T>
class (:link
+ 1
+
+ 0
+
+ -39
+
+
+ 2
+ :);@]
@@ -5048,7 +5048,7 @@
0
- -37
+ -382
@@ -5280,7 +5280,7 @@
0
- -18
+ -202
@@ -5289,7 +5289,7 @@
0
- -23
+ -182
@@ -5311,7 +5311,7 @@
0
- -37
+ -382
@@ -5320,7 +5320,7 @@
0
- -37
+ -382
@@ -5329,7 +5329,7 @@
0
- -44
+ -402
@@ -5338,7 +5338,7 @@
0
- -41
+ -302
@@ -5347,7 +5347,7 @@
0
- -22
+ -232
@@ -5369,7 +5369,7 @@
0
- -38
+ -392
@@ -5391,7 +5391,7 @@
0
- -37
+ -382
@@ -5400,7 +5400,7 @@
0
- -38
+ -392
@@ -5436,7 +5436,7 @@
0
- -38
+ -392
@@ -5445,7 +5445,7 @@
0
- -37
+ -382
@@ -5463,7 +5463,7 @@
0
- -37
+ -382
@@ -5472,7 +5472,7 @@
0
- -37
+ -382
@@ -5490,7 +5490,7 @@
0
- -36
+ -372
@@ -5499,7 +5499,7 @@
0
- -37
+ -382
@@ -5508,7 +5508,7 @@
0
- -11
+ -142
@@ -5517,7 +5517,7 @@
0
- -37
+ -382
@@ -5526,7 +5526,7 @@
0
- -37
+ -382
@@ -5535,7 +5535,7 @@
0
- -37
+ -382
@@ -5544,7 +5544,7 @@
0
- -34
+ -352
@@ -5553,7 +5553,7 @@
0
- -37
+ -382
@@ -5562,7 +5562,7 @@
0
- -34
+ -352
@@ -5571,7 +5571,7 @@
0
- -37
+ -382
@@ -5580,7 +5580,7 @@
0
- -12
+ -152
@@ -5589,7 +5589,7 @@
0
- -18
+ -202
@@ -5598,7 +5598,7 @@
0
- -34
+ -352
@@ -5607,7 +5607,7 @@
0
- -19
+ -212
@@ -5616,7 +5616,7 @@
0
- -21
+ -222
@@ -5625,7 +5625,7 @@
0
- -21
+ -222
@@ -5634,7 +5634,7 @@
0
- -19
+ -212
@@ -5656,7 +5656,7 @@
0
- -37
+ -382
@@ -5665,7 +5665,7 @@
0
- -37
+ -382
@@ -5674,7 +5674,7 @@
0
- -38
+ -392
@@ -5696,7 +5696,7 @@
0
- -37
+ -382
@@ -5705,7 +5705,7 @@
0
- -37
+ -382
@@ -5719,467 +5719,6 @@
-11
-
- 5
- 2
- (:auto !!!:)
(:include synopsis:)
!!!!Requirements:
T must be a class with an accessible no-throw copy constructor as per (15.5.1).
!!!!Returns:
* If T derives from boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :), the returned object is of type T and is a copy of x.
* Otherwise, the returned object is of an unspecified type that derives publicly from both T and boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :). The T sub-object is initialized from x by the T copy constructor.
!!!!Throws:
Nothing.
-
-
-
-
- 0
-
- -12
-
-
-
- 17
- 2
- (:auto !!!:)
(:include synopsis:)
The (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) type can be used to refer to a copy of an exception object. It is Default Constructible, Copy Constructible, Assignable and Equality Comparable; (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :)'s operations do not throw.
Two instances of (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) are equivalent and compare equal if and only if they refer to the same exception.
The default constructor of (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) produces the null value of the type. The null value is equivalent only to itself.
!!!!Thread safety
* It is legal for multiple threads to hold (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) references to the same exception object.
* It is illegal for multiple threads to modify the same (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) object concurrently.
* While calling (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) makes a copy of the current exception object, it is still possible for the two copies to share internal state. Therefore, in general it is not safe to call (:link
- 1
-
- 0
-
- -35
-
-
- 2
- :) concurrently to throw the same exception object into multiple threads.
-
-
-
-
- 0
-
- -13
-
-
-
- 7
- 2
- (:auto !!!:)
Deriving from boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) effectively decouples the semantics of a failure from the information that is relevant to each individual instance of reporting a failure with a given semantic.
In other words: with boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :), what data a given exception object transports depends primarily on the context in which failures are reported (not on its type.) Since exception types need no members, it becomes very natural to throw exceptions that derive from more than one type to indicate multiple appropriate semantics:
[@struct exception_base: virtual std::exception, virtual boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) { };
struct io_error: virtual exception_base { };
struct file_error: virtual io_error { };
struct read_error: virtual io_error { };
struct file_read_error: virtual file_error, virtual read_error { };@]
Using this approach, exception types become a simple tagging system for categorizing errors and selecting failures in exception handlers.
-
-
-
-
- 0
-
- -14
-
-
-
- 27
- 2
- (:auto !!:)
Some exception hierarchies can not be modified to make boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) a base type. In this case, the (:link
- 1
-
- 0
-
- -11
-
-
- 2
- :) function template can be used to make exception objects derive from boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) anyway. Here is an example:
[@#include <(:link
- 1
-
- 0
-
- -50
-
-
- 2
- :)>
#include <stdexcept>
typedef boost::(:link
- 1
-
- 0
-
- -38
-
-
- 2
- :)<struct tag_std_range_min,size_t> std_range_min;
typedef boost::(:link
- 1
-
- 0
-
- -38
-
-
- 2
- :)<struct tag_std_range_max,size_t> std_range_max;
typedef boost::(:link
- 1
-
- 0
-
- -38
-
-
- 2
- :)<struct tag_std_range_index,size_t> std_range_index;
template <class T>
class
my_container
{
public:
size_t size() const;
T const &
operator[]( size_t i ) const
{
if( i > size() )
throw boost::(:link
- 1
-
- 0
-
- -11
-
-
- 2
- :)(std::range_error("Index out of range")) <<
std_range_min(0) <<
std_range_max(size()) <<
std_range_index(i);
//....
}
};
@]
The call to (:link
- 1
-
- 0
-
- -11
-
-
- 2
- :)<T> gets us an object of ''unspecified type'' which is guaranteed to derive from both boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) and T. This makes it possible to use (:link
- 1
-
- 0
-
- -9
-
-
- 2
- mod="/":) to store additional information in the exception object. The exception can be intercepted as T &, so existing exception handling will not break. It can also be intercepted as boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) &, so that (:link
- 1
-
- 0
-
- -6
-
-
- 2
- |more information can be added to the exception at a later time:).
-
-
-
-
- 0
-
- -15
-
-
-
- 37
- 2
- (:auto !!!:)
When you catch an exception, you can call (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) to get an (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) object:
[@#include <(:link
- 1
-
- 0
-
- -57
-
-
- 2
- :)>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
void do_work(); //throws cloning-enabled boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :)s
void
worker_thread( boost::(:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) & error )
{
try
{
do_work();
error = boost::(:link
- 1
-
- 0
-
- -12
-
-
- 2
- :)();
}
catch(
... )
{
error = boost::(:link
- 1
-
- 0
-
- -23
-
-
- 2
- :)();
}
}@]
In the above example, note that (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) captures the original type of the exception object. The exception can be thrown again using the (:link
- 1
-
- 0
-
- -35
-
-
- 2
- :) function:
[@// ...continued
void
work()
{
boost::(:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) error;
boost::(:link http://www.boost.org/doc/html/boost/thread.html|thread:) t( boost::(:link http://www.boost.org/libs/bind/bind.html|bind:)(worker_thread,boost::(:link http://www.boost.org/doc/html/ref.html|ref:)(error)) );
t.(:link http://www.boost.org/doc/html/boost/thread.html|join:)();
if( error )
boost::(:link
- 1
-
- 0
-
- -35
-
-
- 2
- :)(error);
}@]
Note that (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) could fail to copy the original exception object in the following cases:
* if there is not enough memory, in which case the returned (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) points to an instance of std::bad_alloc, or
* if (:link
- 1
-
- 0
-
- -18
-
-
- 2
- :) was not used in the throw-expression passed to the original throw statement and the current implementation does not have the necessary compiler-specific support to copy the exception automatically, in which case the returned (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) points to an instance of (:link
- 1
-
- 0
-
- -30
-
-
- 2
- :).
Regardless, the use of (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) and (:link
- 1
-
- 0
-
- -35
-
-
- 2
- :) in the above examples is well-formed.
-
-
-
-
- 0
-
- -16
-
- 332
@@ -6188,7 +5727,7 @@
0
- -37
+ -382
@@ -6197,7 +5736,7 @@
0
- -37
+ -382
@@ -6206,7 +5745,7 @@
0
- -38
+ -392
@@ -6224,7 +5763,7 @@
0
- -37
+ -382
@@ -6233,7 +5772,7 @@
0
- -38
+ -392
@@ -6242,7 +5781,7 @@
0
- -37
+ -382
@@ -6260,7 +5799,7 @@
0
- -37
+ -382
@@ -6278,25 +5817,25 @@
0
- -37
+ -382
- :):
[@catch( io_error & e )
{
std::cerr << "I/O Error!\n";
if( shared_ptr<std::string const> fn=(:link
+ :):
[@catch( io_error & e )
{
std::cerr << "I/O Error!\n";
if( std::string const * fn=(:link 10
- -31
+ -322
- :)<file_name>(e) )
std::cerr << "File name: " << *fn << "\n";
if( shared_ptr<int const> c=(:link
+ :)<file_name>(e) )
std::cerr << "File name: " << *fn << "\n";
if( int const * c=(:link 10
- -31
+ -322
@@ -6305,7 +5844,7 @@
0
- -21
+ -222
@@ -6314,7 +5853,7 @@
0
- -38
+ -392
@@ -6323,7 +5862,7 @@
0
- -37
+ -382
@@ -6334,40 +5873,98 @@
0
- -17
+ -14
- 19
+ 52
- (:auto !!:)
Boost Exception responds to the following configuration macros:
'''BOOST_NO_RTTI'''\\
'''BOOST_NO_TYPEID'''
The first macro prevents Boost Exception from using dynamic_cast and dynamic typeid. If the second macro is also defined, Boost Exception does not use static typeid either. There are no observable degrading effects on the library functionality, except for the following:
->By default, the (:link
+ (:auto !!!:)
(:include synopsis:)
!!!!Requirements:
T must be a class with an accessible no-throw copy constructor as per (15.5.1).
!!!!Returns:
* If T derives from boost::(:link 10
- -31
+ -382
- :) function template can be called with any exception type. If BOOST_NO_RTTI is defined, (:link
+ :), the returned object is of type T and is a copy of x.
* Otherwise, the returned object is of an unspecified type that derives publicly from both T and boost::(:link 10
- -31
+ -382
- :) can be used only with objects of type boost::(:link
+ :). The T sub-object is initialized from x by the T copy constructor.
!!!!Throws:
Nothing.
+
+
+
+
+ 0
+
+ -15
+
+
+
+ 17
+ 2
+ (:auto !!!:)
(:include synopsis:)
The (:link 10
- -37
+ -152
- :).
!!!!Note:
The library needs RTTI functionality. Disabling the language RTTI support enables an internal RTTI system, which may have more or less overhead depending on the platform.
'''BOOST_EXCEPTION_DISABLE'''
By default, (:link
+ :) type can be used to refer to a copy of an exception object. It is Default Constructible, Copy Constructible, Assignable and Equality Comparable; (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :)'s operations do not throw.
Two instances of (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) are equivalent and compare equal if and only if they refer to the same exception.
The default constructor of (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) produces the null value of the type. The null value is equivalent only to itself.
!!!!Thread safety
* It is legal for multiple threads to hold (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) references to the same exception object.
* It is illegal for multiple threads to modify the same (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) object concurrently.
* While calling (:link 10
@@ -6376,202 +5973,23 @@
2
- :) and (:link
+ :) makes a copy of the current exception object, it is still possible for the two copies to share internal state. Therefore, in general it is not safe to call (:link 10
- -11
+ -362
- :) are integrated directly in the (:link
- 1
-
- 0
-
- -34
-
-
- 2
- :) function. Defining BOOST_EXCEPTION_DISABLE disables this integration.
Note that on some non-conformant compilers, for example MSVC 7.0 and older, as well as BCC, BOOST_EXCEPTION_DISABLE is implicitly defined in (:link
- 1
-
- 0
-
- -58
-
-
- 2
- :).
'''BOOST_NO_EXCEPTIONS'''
This macro disables exception handling in Boost, forwarding all exceptions to a user-defined non-template version of boost::
- 1
-
- 0
-
- -34
-
-
- 2
- . However, unless BOOST_EXCEPTION_DISABLE is also defined, users can still examine the exception object for any data added at the point of the throw, or use boost::
- 1
-
- 0
-
- -21
-
-
- 2
- (of course under BOOST_NO_EXCEPTIONS, the user-defined boost::throw_exception is not allowed to return to the caller.)
+ :) concurrently to throw the same exception object into multiple threads.
0
- -18
-
-
-
- 21
- 2
- (:auto !!!:)
(:include synopsis:)
!!!!Requirements:
T must be a class with an accessible no-throw copy constructor.
!!!!Returns:
An object of ''unspecified'' type which derives publicly from T. That is, the returned object can be intercepted by a catch(T &).
!!!!Description:
This function is designed to be used directly in a throw-expression to enable the (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) support in Boost Exception. For example:
[@class
my_exception:
public std::exception
{
};
....
throw boost::(:link
- 1
-
- 0
-
- -18
-
-
- 2
- :)(my_exception());@]
Unless (:link
- 1
-
- 0
-
- -18
-
-
- 2
- :) is called at the time an exception object is used in a throw-expression, an attempt to copy it using (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) may return an (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) which refers to an instance of (:link
- 1
-
- 0
-
- -30
-
-
- 2
- :). See (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) for details.
!!!!Note:
Instead of using the throw keyword directly, it is preferable to call boost::(:link
- 1
-
- 0
-
- -34
-
-
- 2
- :). This is guaranteed to throw an exception that derives from boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) and supports the (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) functionality.
-
-
-
-
- 0
-
- -19
-
-
-
- 7
- 2
- (:auto !!!:)
(:include synopsis:)
This macro takes an exception object, records BOOST_CURRENT_FUNCTION, __FILE__ and __LINE__ in it, and forwards it to
- 1
-
- 0
-
- -34
-
-
- 2
- . To recover this information at the catch site, use
- 1
-
- 0
-
- -31
-
-
- 2
- ; the information is also included in the message returned by
- 1
-
- 0
-
- -21
-
-
- 2
- .
-
-
-
-
- 0
-
- -20
+ -16
@@ -6582,7 +6000,7 @@
0
- -21
+ -222
@@ -6591,7 +6009,7 @@
0
- -37
+ -382
@@ -6600,7 +6018,7 @@
0
- -37
+ -382
@@ -6627,7 +6045,7 @@
0
- -37
+ -382
@@ -6636,7 +6054,7 @@
0
- -37
+ -382
@@ -6645,7 +6063,7 @@
0
- -21
+ -222
@@ -6654,13 +6072,694 @@
0
- -43
+ -442:)
+
+
+ 0
+
+ -12
+
+
+
+ 7
+ 2
+ (:auto !!!:)
Deriving from boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) effectively decouples the semantics of a failure from the information that is relevant to each individual instance of reporting a failure with a given semantic.
In other words: with boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :), what data a given exception object transports depends primarily on the context in which failures are reported (not on its type.) Since exception types need no members, it becomes very natural to throw exceptions that derive from more than one type to indicate multiple appropriate semantics:
[@struct exception_base: virtual std::exception, virtual boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) { };
struct io_error: virtual exception_base { };
struct file_error: virtual io_error { };
struct read_error: virtual io_error { };
struct file_read_error: virtual file_error, virtual read_error { };@]
Using this approach, exception types become a simple tagging system for categorizing errors and selecting failures in exception handlers.
+
+
+
+
+ 0
+
+ -13
+
+
+
+ 27
+ 2
+ (:auto !!:)
Some exception hierarchies can not be modified to make boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) a base type. In this case, the (:link
+ 1
+
+ 0
+
+ -14
+
+
+ 2
+ :) function template can be used to make exception objects derive from boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) anyway. Here is an example:
[@#include <(:link
+ 1
+
+ 0
+
+ -50
+
+
+ 2
+ :)>
#include <stdexcept>
typedef boost::(:link
+ 1
+
+ 0
+
+ -39
+
+
+ 2
+ :)<struct tag_std_range_min,size_t> std_range_min;
typedef boost::(:link
+ 1
+
+ 0
+
+ -39
+
+
+ 2
+ :)<struct tag_std_range_max,size_t> std_range_max;
typedef boost::(:link
+ 1
+
+ 0
+
+ -39
+
+
+ 2
+ :)<struct tag_std_range_index,size_t> std_range_index;
template <class T>
class
my_container
{
public:
size_t size() const;
T const &
operator[]( size_t i ) const
{
if( i > size() )
throw boost::(:link
+ 1
+
+ 0
+
+ -14
+
+
+ 2
+ :)(std::range_error("Index out of range")) <<
std_range_min(0) <<
std_range_max(size()) <<
std_range_index(i);
//....
}
};
@]
The call to (:link
+ 1
+
+ 0
+
+ -14
+
+
+ 2
+ :)<T> gets us an object of ''unspecified type'' which is guaranteed to derive from both boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) and T. This makes it possible to use (:link
+ 1
+
+ 0
+
+ -9
+
+
+ 2
+ mod="/":) to store additional information in the exception object. The exception can be intercepted as T &, so existing exception handling will not break. It can also be intercepted as boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) &, so that (:link
+ 1
+
+ 0
+
+ -6
+
+
+ 2
+ |more information can be added to the exception at a later time:).
+
+
+
+
+ 0
+
+ -17
+
+
+
+ 37
+ 2
+ (:auto !!!:)
When you catch an exception, you can call (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) to get an (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) object:
[@#include <(:link
+ 1
+
+ 0
+
+ -57
+
+
+ 2
+ :)>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
void do_work(); //throws cloning-enabled boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :)s
void
worker_thread( boost::(:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) & error )
{
try
{
do_work();
error = boost::(:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :)();
}
catch(
... )
{
error = boost::(:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :)();
}
}@]
In the above example, note that (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) captures the original type of the exception object. The exception can be thrown again using the (:link
+ 1
+
+ 0
+
+ -36
+
+
+ 2
+ :) function:
[@// ...continued
void
work()
{
boost::(:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) error;
boost::(:link http://www.boost.org/doc/html/boost/thread.html|thread:) t( boost::(:link http://www.boost.org/libs/bind/bind.html|bind:)(worker_thread,boost::(:link http://www.boost.org/doc/html/ref.html|ref:)(error)) );
t.(:link http://www.boost.org/doc/html/boost/thread.html|join:)();
if( error )
boost::(:link
+ 1
+
+ 0
+
+ -36
+
+
+ 2
+ :)(error);
}@]
Note that (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) could fail to copy the original exception object in the following cases:
* if there is not enough memory, in which case the returned (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) points to an instance of std::bad_alloc, or
* if (:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :) was not used in the throw-expression passed to the original throw statement and the current implementation does not have the necessary compiler-specific support to copy the exception automatically, in which case the returned (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) points to an instance of (:link
+ 1
+
+ 0
+
+ -31
+
+
+ 2
+ :).
Regardless, the use of (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) and (:link
+ 1
+
+ 0
+
+ -36
+
+
+ 2
+ :) in the above examples is well-formed.
+
+
+
+
+ 0
+
+ -18
+
+
+
+ 29
+ 2
+ (:auto !!!:)
(:include synopsis:)
!!!!Requirements:
The (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) function must not be called outside of a catch block.
!!!!Returns:
* An (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) that refers to the currently handled exception or a copy of the currently handled exception.
* If the function needs to allocate memory and the attempt fails, it returns an (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) that refers to an instance of std::bad_alloc.
!!!!Throws:
Nothing.
!!!!Notes:
* It is unspecified whether the return values of two successive calls to (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) refer to the same exception object.
* Correct implementation of (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) may require compiler support, unless (:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :) was used at the time the currently handled exception object was passed to throw. If (:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :) was not used, and if the compiler does not provide the necessary support, then (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) may return an (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) that refers to an instance of (:link
+ 1
+
+ 0
+
+ -31
+
+
+ 2
+ :). In this case, if the original exception object derives from boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :), then the boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) sub-object of the (:link
+ 1
+
+ 0
+
+ -31
+
+
+ 2
+ :) object is initialized by the boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) copy constructor.
+
+
+
+
+ 0
+
+ -19
+
+
+
+ 19
+ 2
+ (:auto !!:)
Boost Exception responds to the following configuration macros:
'''BOOST_NO_RTTI'''\\
'''BOOST_NO_TYPEID'''
The first macro prevents Boost Exception from using dynamic_cast and dynamic typeid. If the second macro is also defined, Boost Exception does not use static typeid either. There are no observable degrading effects on the library functionality, except for the following:
->By default, the (:link
+ 1
+
+ 0
+
+ -32
+
+
+ 2
+ :) function template can be called with any exception type. If BOOST_NO_RTTI is defined, (:link
+ 1
+
+ 0
+
+ -32
+
+
+ 2
+ :) can be used only with objects of type boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :).
!!!!Note:
The library needs RTTI functionality. Disabling the language RTTI support enables an internal RTTI system, which may have more or less overhead depending on the platform.
'''BOOST_EXCEPTION_DISABLE'''
By default, (:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :) and (:link
+ 1
+
+ 0
+
+ -14
+
+
+ 2
+ :) are integrated directly in the (:link
+ 1
+
+ 0
+
+ -35
+
+
+ 2
+ :) function. Defining BOOST_EXCEPTION_DISABLE disables this integration.
Note that on some non-conformant compilers, for example MSVC 7.0 and older, as well as BCC, BOOST_EXCEPTION_DISABLE is implicitly defined in (:link
+ 1
+
+ 0
+
+ -58
+
+
+ 2
+ :).
'''BOOST_NO_EXCEPTIONS'''
This macro disables exception handling in Boost, forwarding all exceptions to a user-defined non-template version of boost::
+ 1
+
+ 0
+
+ -35
+
+
+ 2
+ . However, unless BOOST_EXCEPTION_DISABLE is also defined, users can still examine the exception object for any data added at the point of the throw, or use boost::
+ 1
+
+ 0
+
+ -22
+
+
+ 2
+ (of course under BOOST_NO_EXCEPTIONS, the user-defined boost::throw_exception is not allowed to return to the caller.)
+
+
+
+
+ 0
+
+ -20
+
+
+
+ 21
+ 2
+ (:auto !!!:)
(:include synopsis:)
!!!!Requirements:
T must be a class with an accessible no-throw copy constructor.
!!!!Returns:
An object of ''unspecified'' type which derives publicly from T. That is, the returned object can be intercepted by a catch(T &).
!!!!Description:
This function is designed to be used directly in a throw-expression to enable the (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) support in Boost Exception. For example:
[@class
my_exception:
public std::exception
{
};
....
throw boost::(:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :)(my_exception());@]
Unless (:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :) is called at the time an exception object is used in a throw-expression, an attempt to copy it using (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) may return an (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) which refers to an instance of (:link
+ 1
+
+ 0
+
+ -31
+
+
+ 2
+ :). See (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :) for details.
!!!!Note:
Instead of using the throw keyword directly, it is preferable to call boost::(:link
+ 1
+
+ 0
+
+ -35
+
+
+ 2
+ :). This is guaranteed to throw an exception that derives from boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) and supports the (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) functionality.
+
+ 0
@@ -6668,6 +6767,46 @@
-21
+
+ 7
+ 2
+ (:auto !!!:)
(:include synopsis:)
This macro takes an exception object, records BOOST_CURRENT_FUNCTION, __FILE__ and __LINE__ in it, and forwards it to
+ 1
+
+ 0
+
+ -35
+
+
+ 2
+ . To recover this information at the catch site, use
+ 1
+
+ 0
+
+ -32
+
+
+ 2
+ ; the information is also included in the message returned by
+ 1
+
+ 0
+
+ -22
+
+
+ 2
+ .
+
+
+
+
+ 0
+
+ -22
+
+ 292
@@ -6676,7 +6815,7 @@
0
- -37
+ -382
@@ -6685,7 +6824,7 @@
0
- -38
+ -392
@@ -6694,7 +6833,7 @@
0
- -37
+ -382
@@ -6712,7 +6851,7 @@
0
- -37
+ -382
@@ -6721,7 +6860,7 @@
0
- -21
+ -222
@@ -6730,7 +6869,7 @@
0
- -38
+ -392
@@ -6739,7 +6878,7 @@
0
- -38
+ -392
@@ -6748,7 +6887,7 @@
0
- -38
+ -392
@@ -6775,7 +6914,7 @@
0
- -21
+ -222
@@ -6784,7 +6923,7 @@
0
- -38
+ -392
@@ -6793,7 +6932,7 @@
0
- -43
+ -442
@@ -6804,7 +6943,7 @@
0
- -22
+ -23
@@ -6824,7 +6963,7 @@
0
- -38
+ -392
@@ -6833,7 +6972,7 @@
0
- -38
+ -392
@@ -6842,7 +6981,7 @@
0
- -38
+ -392
@@ -6851,7 +6990,7 @@
0
- -37
+ -382
@@ -6860,152 +6999,13 @@
0
- -31
+ -322:).
-
-
- 0
-
- -23
-
-
-
- 29
- 2
- (:auto !!!:)
(:include synopsis:)
!!!!Requirements:
The (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) function must not be called outside of a catch block.
!!!!Returns:
* An (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) that refers to the currently handled exception or a copy of the currently handled exception.
* If the function needs to allocate memory and the attempt fails, it returns an (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) that refers to an instance of std::bad_alloc.
!!!!Throws:
Nothing.
!!!!Notes:
* It is unspecified whether the return values of two successive calls to (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) refer to the same exception object.
* Correct implementation of (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) may require compiler support, unless (:link
- 1
-
- 0
-
- -18
-
-
- 2
- :) was used at the time the currently handled exception object was passed to throw. If (:link
- 1
-
- 0
-
- -18
-
-
- 2
- :) was not used, and if the compiler does not provide the necessary support, then (:link
- 1
-
- 0
-
- -23
-
-
- 2
- :) may return an (:link
- 1
-
- 0
-
- -12
-
-
- 2
- :) that refers to an instance of (:link
- 1
-
- 0
-
- -30
-
-
- 2
- :). In this case, if the original exception object derives from boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :), then the boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) sub-object of the (:link
- 1
-
- 0
-
- -30
-
-
- 2
- :) object is initialized by the boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) copy constructor.
-
- 0
@@ -7047,7 +7047,7 @@
0
- -37
+ -382
@@ -7082,7 +7082,7 @@
0
- -37
+ -382
@@ -7091,7 +7091,7 @@
0
- -21
+ -222
@@ -7137,27 +7137,90 @@
- 5
+ 192
- (:auto !!!:)
(:include synopsis:)
This type is used by the (:link
+ (:auto !!!:)
Sometimes the throw site does not have all the information that is needed at the catch site to make sense of what went wrong. Let's say we have an exception type file_read_error, which takes a file name in its constructor. Consider the following function:
[@void
file_read( FILE * f, void * buffer, size_t size )
{
if( size!=fread(buffer,1,size,f) )
throw file_read_error(????);
}@]
How can the file_read function pass a file name to the exception type constructor? All it has is a FILE handle.
Using boost::(:link 10
- -12
+ -382
- :) support in Boost Exception. Please see (:link
+ :) allows us to free the file_read function from the burden of storing the file name in exceptions it throws:
[@#include <(:link 10
- -23
+ -502
- :).
+ :)>
#include <stdio.h>
#include <errno.h>
typedef boost::(:link
+ 1
+
+ 0
+
+ -39
+
+
+ 2
+ :)<struct tag_errno,int> errno_info;
class file_read_error: public boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) { };
void
file_read( FILE * f, void * buffer, size_t size )
{
if( size!=fread(buffer,1,size,f) )
throw file_read_error() << errno_info(errno);
}@]
If file_read detects a failure, it throws an exception which contains the information that is available at the time, namely the errno. Other relevant information, such as the file name, can be added in a context higher up the call stack, where it is known naturally:
[@#include <(:link
+ 1
+
+ 0
+
+ -50
+
+
+ 2
+ :)>
#include <boost/shared_ptr.hpp>
#include <stdio.h>
#include <string>
typedef boost::(:link
+ 1
+
+ 0
+
+ -39
+
+
+ 2
+ :)<struct tag_file_name,std::string> file_name_info;
boost::shared_ptr<FILE> file_open( char const * file_name, char const * mode );
void file_read( FILE * f, void * buffer, size_t size );
void
parse_file( char const * file_name )
{
boost::shared_ptr<FILE> f = file_open(file_name,"rb");
assert(f);
try
{
char buf[1024];
file_read( f.get(), buf, sizeof(buf) );
}
catch(
boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) & e )
{
e << file_name_info(file_name);
throw;
}
}@]
The above function is (almost) exception-neutral -- if an exception is emitted by any function call within the try block, parse_file does not need to do any real work, but it intercepts any boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) object, stores the file name, and re-throws using a throw-expression with no operand (15.1.6). The rationale for catching any boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) object is that the file name is relevant to any failure that occurs in parse_file, ''even if the failure is unrelated to file I/O''.
@@ -7167,6 +7230,37 @@
-31
+
+ 5
+ 2
+ (:auto !!!:)
(:include synopsis:)
This type is used by the (:link
+ 1
+
+ 0
+
+ -15
+
+
+ 2
+ :) support in Boost Exception. Please see (:link
+ 1
+
+ 0
+
+ -18
+
+
+ 2
+ :).
+
+
+
+
+ 0
+
+ -32
+
+ 132
@@ -7175,7 +7269,7 @@
0
- -38
+ -392
@@ -7184,7 +7278,7 @@
0
- -37
+ -382
@@ -7202,7 +7296,7 @@
0
- -31
+ -322
@@ -7211,7 +7305,7 @@
0
- -31
+ -322
@@ -7220,7 +7314,7 @@
0
- -17
+ -192
@@ -7231,7 +7325,7 @@
0
- -32
+ -33
@@ -7242,7 +7336,7 @@
0
- -33
+ -342
@@ -7251,7 +7345,7 @@
0
- -34
+ -352
@@ -7260,7 +7354,7 @@
0
- -16
+ -112
@@ -7275,24 +7369,6 @@
2 mod="w":)
##(:link 1
-
- 0
-
- -14
-
-
- 2
- mod="w":)
##(:link
- 1
-
- 0
-
- -33
-
-
- 2
- mod="w":)
##(:link
- 10
@@ -7305,7 +7381,7 @@
0
- -36
+ -342
@@ -7314,11 +7390,11 @@
0
- -20
+ -122
- mod="w":)
#Documentation
##Class (:link
+ mod="w":)
##(:link 10
@@ -7327,12 +7403,30 @@
2
+ mod="w":)
##(:link
+ 1
+
+ 0
+
+ -16
+
+
+ 2
+ mod="w":)
#Documentation
##Class (:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2:)
##Throwing Exceptions
###(:link 10
- -19
+ -212
@@ -7341,7 +7435,7 @@
0
- -34
+ -352
@@ -7350,7 +7444,7 @@
0
- -38
+ -392
@@ -7377,7 +7471,7 @@
0
- -31
+ -322
@@ -7386,7 +7480,7 @@
0
- -11
+ -142
@@ -7395,7 +7489,16 @@
0
- -12
+ -15
+
+
+ 2
+ :)
###(:link
+ 1
+
+ 0
+
+ -202
@@ -7410,15 +7513,6 @@
2:)
###(:link 1
-
- 0
-
- -23
-
-
- 2
- :)
###(:link
- 10
@@ -7431,7 +7525,7 @@
0
- -35
+ -362
@@ -7440,7 +7534,7 @@
0
- -30
+ -312
@@ -7449,7 +7543,7 @@
0
- -21
+ -222
@@ -7494,7 +7588,7 @@
0
- -39
+ -412
@@ -7521,7 +7615,7 @@
0
- -17
+ -192
@@ -7550,7 +7644,7 @@
0
- -33
+ -34
@@ -7561,7 +7655,7 @@
0
- -18
+ -202
@@ -7570,7 +7664,7 @@
0
- -34
+ -352
@@ -7579,7 +7673,7 @@
0
- -37
+ -382
@@ -7588,7 +7682,7 @@
0
- -40
+ -422
@@ -7597,7 +7691,7 @@
0
- -15
+ -172
@@ -7608,7 +7702,7 @@
0
- -34
+ -35
@@ -7619,7 +7713,7 @@
0
- -34
+ -352
@@ -7628,7 +7722,7 @@
0
- -18
+ -202
@@ -7637,7 +7731,7 @@
0
- -11
+ -142
@@ -7646,7 +7740,7 @@
0
- -34
+ -352
@@ -7655,7 +7749,7 @@
0
- -34
+ -352
@@ -7664,7 +7758,7 @@
0
- -34
+ -352
@@ -7673,7 +7767,7 @@
0
- -31
+ -322
@@ -7682,7 +7776,7 @@
0
- -21
+ -222
@@ -7693,7 +7787,7 @@
0
- -35
+ -36
@@ -7706,7 +7800,7 @@
0
- -36
+ -37
@@ -7717,7 +7811,7 @@
0
- -37
+ -382
@@ -7726,7 +7820,7 @@
0
- -13
+ -122
@@ -7737,7 +7831,7 @@
0
- -37
+ -38
@@ -7748,7 +7842,7 @@
0
- -37
+ -382
@@ -7757,7 +7851,7 @@
0
- -37
+ -382
@@ -7766,7 +7860,7 @@
0
- -38
+ -392
@@ -7784,7 +7878,7 @@
0
- -37
+ -382
@@ -7793,7 +7887,7 @@
0
- -31
+ -322
@@ -7804,7 +7898,7 @@
0
- -38
+ -39
@@ -7815,7 +7909,7 @@
0
- -38
+ -392
@@ -7833,7 +7927,7 @@
0
- -37
+ -382
@@ -7851,7 +7945,7 @@
0
- -38
+ -392
@@ -7869,7 +7963,7 @@
0
- -38
+ -392
@@ -7887,7 +7981,7 @@
0
- -38
+ -392
@@ -7914,7 +8008,7 @@
0
- -37
+ -382
@@ -7932,7 +8026,7 @@
0
- -31
+ -322
@@ -7950,7 +8044,7 @@
0
- -37
+ -382
@@ -7959,7 +8053,7 @@
0
- -37
+ -382
@@ -7968,26 +8062,13 @@
0
- -31
+ -322<errno_info>(x) )
....
}@]
-
-
- 0
-
- -39
-
-
-
- 1
- 2
- (:auto !!:)
(:pagelist fmt="index" tags="type":)
-
- 0
@@ -7995,193 +8076,6 @@
-40
-
- 11
- 2
- (:auto !!!:)
Here is how cloning can be enabled in a throw-expression (15.1):
[@#include <(:link
- 1
-
- 0
-
- -56
-
-
- 2
- :)>
#include <stdio.h>
#include <errno.h>
typedef boost::error_info<struct tag_errno,int> errno_info;
class file_read_error: public boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) { };
void
file_read( FILE * f, void * buffer, size_t size )
{
if( size!=fread(buffer,1,size,f) )
throw boost::(:link
- 1
-
- 0
-
- -18
-
-
- 2
- :)(file_read_error()) <<
errno_info(errno);
}@]
Of course, (:link
- 1
-
- 0
-
- -18
-
-
- 2
- :) may be used with any exception type; there is no requirement that it should derive from boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :).
-
-
-
-
- 0
-
- -41
-
-
-
- 19
- 2
- (:auto !!!:)
Sometimes the throw site does not have all the information that is needed at the catch site to make sense of what went wrong. Let's say we have an exception type file_read_error, which takes a file name in its constructor. Consider the following function:
[@void
file_read( FILE * f, void * buffer, size_t size )
{
if( size!=fread(buffer,1,size,f) )
throw file_read_error(????);
}@]
How can the file_read function pass a file name to the exception type constructor? All it has is a FILE handle.
Using boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) allows us to free the file_read function from the burden of storing the file name in exceptions it throws:
[@#include <(:link
- 1
-
- 0
-
- -50
-
-
- 2
- :)>
#include <stdio.h>
#include <errno.h>
typedef boost::(:link
- 1
-
- 0
-
- -38
-
-
- 2
- :)<struct tag_errno,int> errno_info;
class file_read_error: public boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) { };
void
file_read( FILE * f, void * buffer, size_t size )
{
if( size!=fread(buffer,1,size,f) )
throw file_read_error() << errno_info(errno);
}@]
If file_read detects a failure, it throws an exception which contains the information that is available at the time, namely the errno. Other relevant information, such as the file name, can be added in a context higher up the call stack, where it is known naturally:
[@#include <(:link
- 1
-
- 0
-
- -50
-
-
- 2
- :)>
#include <boost/shared_ptr.hpp>
#include <stdio.h>
#include <string>
typedef boost::(:link
- 1
-
- 0
-
- -38
-
-
- 2
- :)<struct tag_file_name,std::string> file_name_info;
boost::shared_ptr<FILE> file_open( char const * file_name, char const * mode );
void file_read( FILE * f, void * buffer, size_t size );
void
parse_file( char const * file_name )
{
boost::shared_ptr<FILE> f = file_open(file_name,"rb");
assert(f);
try
{
char buf[1024];
file_read( f.get(), buf, sizeof(buf) );
}
catch(
boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) & e )
{
e << file_name_info(file_name);
throw;
}
}@]
The above function is (almost) exception-neutral -- if an exception is emitted by any function call within the try block, parse_file does not need to do any real work, but it intercepts any boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) object, stores the file name, and re-throws using a throw-expression with no operand (15.1.6). The rationale for catching any boost::(:link
- 1
-
- 0
-
- -37
-
-
- 2
- :) object is that the file name is relevant to any failure that occurs in parse_file, ''even if the failure is unrelated to file I/O''.
-
-
-
-
- 0
-
- -42
-
-
-
- 1
- 2
- (:auto !!:)
!!!Synopsis
(:include synopsis:)
-
-
-
-
- 0
-
- -43
-
-
-
- 3
- 2
- !!!!Example:
this is a possible output from the (:link
- 1
-
- 0
-
- -21
-
-
- 2
- :) function, as used in ''libs/exception/example/example_io.cpp:''
[@example_io.cpp(83): Throw in function class boost::shared_ptr<struct _iobuf> __cdecl my_fopen(const char *,const char *)
Dynamic exception type: class boost::exception_detail::clone_impl<class fopen_error>
std::exception::what: example_io error
[struct tag_errno *] = 2, OS says "No such file or directory"
[struct tag_file_name *] = tmp1.txt
[struct tag_function *] = fopen
[struct tag_open_mode *] = rb@]
-
-
-
-
- 0
-
- -44
-
- 172
@@ -8199,7 +8093,7 @@
0
- -38
+ -392
@@ -8208,7 +8102,7 @@
0
- -37
+ -382
@@ -8217,7 +8111,7 @@
0
- -38
+ -392
@@ -8226,7 +8120,7 @@
0
- -37
+ -382
@@ -8244,7 +8138,7 @@
0
- -31
+ -322
@@ -8253,13 +8147,119 @@
0
- -31
+ -322:) function template is instantiated with the typedef from (1), and is passed an exception object of a polymorphic type. If the exception object contains the requested value, err will point to it; otherwise a null pointer is returned.
+
+
+ 0
+
+ -41
+
+
+
+ 1
+ 2
+ (:auto !!:)
(:pagelist fmt="index" tags="type":)
+
+
+
+
+ 0
+
+ -42
+
+
+
+ 11
+ 2
+ (:auto !!!:)
Here is how cloning can be enabled in a throw-expression (15.1):
[@#include <(:link
+ 1
+
+ 0
+
+ -56
+
+
+ 2
+ :)>
#include <stdio.h>
#include <errno.h>
typedef boost::error_info<struct tag_errno,int> errno_info;
class file_read_error: public boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :) { };
void
file_read( FILE * f, void * buffer, size_t size )
{
if( size!=fread(buffer,1,size,f) )
throw boost::(:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :)(file_read_error()) <<
errno_info(errno);
}@]
Of course, (:link
+ 1
+
+ 0
+
+ -20
+
+
+ 2
+ :) may be used with any exception type; there is no requirement that it should derive from boost::(:link
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ :).
+
+
+
+
+ 0
+
+ -43
+
+
+
+ 1
+ 2
+ (:auto !!:)
!!!Synopsis
(:include synopsis:)
+
+
+
+
+ 0
+
+ -44
+
+
+
+ 3
+ 2
+ !!!!Example:
this is a possible output from the (:link
+ 1
+
+ 0
+
+ -22
+
+
+ 2
+ :) function, as used in ''libs/exception/example/example_io.cpp:''
[@example_io.cpp(83): Throw in function class boost::shared_ptr<struct _iobuf> __cdecl my_fopen(const char *,const char *)
Dynamic exception type: class boost::exception_detail::clone_impl<class fopen_error>
std::exception::what: example_io error
[struct tag_errno *] = 2, OS says "No such file or directory"
[struct tag_file_name *] = tmp1.txt
[struct tag_function *] = fopen
[struct tag_open_mode *] = rb@]
+
+ 0
@@ -8275,7 +8275,7 @@
0
- -37
+ -382
@@ -8284,7 +8284,7 @@
0
- -37
+ -382
@@ -8315,7 +8315,7 @@
0
- -38
+ -392
@@ -8324,7 +8324,7 @@
0
- -38
+ -392
@@ -8436,7 +8436,7 @@
0
- -42
+ -432
@@ -8445,7 +8445,7 @@
0
- -42
+ -432
@@ -8596,7 +8596,7 @@
0
- -38
+ -392
@@ -8826,28 +8826,6 @@
0
-
-
- 0
-
- -12
-
-
-
- 0
-
-
-
-
- 0
-
- -13
-
-
-
- 0
-
- 0
@@ -8881,6 +8859,28 @@
0
+
+
+ 0
+
+ -12
+
+
+
+ 0
+
+
+
+
+ 0
+
+ -13
+
+
+
+ 0
+
+ 0
@@ -9505,6 +9505,17 @@
-11
+
+ 0
+
+
+
+
+ 0
+
+ -14
+
+ 32
@@ -9524,7 +9535,7 @@
0
- -12
+ -15
@@ -9542,39 +9553,6 @@
:)>
[@namespace
boost
{
(:include decl pre_indent="4":)
}@]
-
-
- 0
-
- -13
-
-
-
- 0
-
-
-
-
- 0
-
- -14
-
-
-
- 0
-
-
-
-
- 0
-
- -15
-
-
-
- 0
-
- 0
@@ -9586,6 +9564,28 @@
0
+
+
+ 0
+
+ -12
+
+
+
+ 0
+
+
+
+
+ 0
+
+ -13
+
+
+
+ 0
+
+ 0
@@ -9604,6 +9604,39 @@
-18
+
+ 3
+ 2
+ `#include <(:link
+ 1
+
+ 0
+
+ -57
+
+
+ 2
+ :)>
[@namespace
boost
{
(:include decl pre_indent="4":)
}@]
+
+
+
+
+ 0
+
+ -19
+
+
+
+ 0
+
+
+
+
+ 0
+
+ -20
+
+ 32
@@ -9623,7 +9656,7 @@
0
- -19
+ -21
@@ -9645,18 +9678,7 @@
0
- -20
-
-
-
- 0
-
-
-
-
- 0
-
- -21
+ -22
@@ -9667,24 +9689,13 @@
0
- -42
+ -432:)>\\
[@namespace
boost
{
(:include decl pre_indent="4":)
}@]
-
-
- 0
-
- -22
-
-
-
- 0
-
- 0
@@ -9693,18 +9704,7 @@
- 3
- 2
- `#include <(:link
- 1
-
- 0
-
- -57
-
-
- 2
- :)>
[@namespace
boost
{
(:include decl pre_indent="4":)
}@]
+ 0
@@ -9781,7 +9781,7 @@
0
- -42
+ -432
@@ -9808,6 +9808,17 @@
-30
+
+ 0
+
+
+
+
+ 0
+
+ -31
+
+ 32
@@ -9827,7 +9838,7 @@
0
- -31
+ -32
@@ -9836,17 +9847,6 @@
[@namespace
boost
{
(:include decl pre_indent="4":)
}@]
-
-
- 0
-
- -32
-
-
-
- 0
-
- 0
@@ -9865,6 +9865,17 @@
-34
+
+ 0
+
+
+
+
+ 0
+
+ -35
+
+ 32
@@ -9884,7 +9895,7 @@
0
- -35
+ -36
@@ -9906,7 +9917,7 @@
0
- -36
+ -37
@@ -9917,7 +9928,7 @@
0
- -37
+ -38
@@ -9939,7 +9950,7 @@
0
- -38
+ -39
@@ -9957,17 +9968,6 @@
:)>
[@namespace
boost
{
(:include def pre_indent="4":)
}@]
-
-
- 0
-
- -39
-
-
-
- 0
-
- 0
@@ -9998,18 +9998,7 @@
- 3
- 2
- [@#include <string>
namespace
boost
{
(:include
- 1
-
- 0
-
- -37
-
-
- 2
- decl pre_indent="4":)
(:include api pre_indent="4":)
}@]
+ 0
@@ -10020,7 +10009,18 @@
- 0
+ 3
+ 2
+ [@#include <string>
namespace
boost
{
(:include
+ 1
+
+ 0
+
+ -38
+
+
+ 2
+ decl pre_indent="4":)
(:include api pre_indent="4":)
}@]
@@ -10323,12 +10323,6 @@
-11
-
- -12
-
-
- -13
- -14
@@ -10338,6 +10332,12 @@
-16
+
+ -12
+
+
+ -13
+ -17
@@ -10489,7 +10489,7 @@
- -32
+ -33
@@ -10506,7 +10506,7 @@
- -33
+ -34
@@ -10591,7 +10591,7 @@
- -16
+ -11
@@ -10608,7 +10608,7 @@
- -36
+ -37
@@ -10625,7 +10625,7 @@
- -13
+ -12
@@ -10693,7 +10693,7 @@
- -39
+ -41
@@ -10751,7 +10751,7 @@
- -15
+ -17
@@ -10775,7 +10775,7 @@
- -43
+ -44
@@ -10799,7 +10799,7 @@
- -14
+ -13
@@ -10855,7 +10855,7 @@
- -30
+ -31
@@ -10883,7 +10883,7 @@
- -23
+ -18
@@ -10911,7 +10911,7 @@
- -12
+ -15
@@ -10939,7 +10939,7 @@
- -35
+ -36
@@ -10995,7 +10995,7 @@
- -31
+ -32
@@ -11019,7 +11019,7 @@
- -20
+ -16
@@ -11123,7 +11123,7 @@
- -44
+ -40
@@ -11199,7 +11199,7 @@
- -34
+ -35
@@ -11231,7 +11231,7 @@
- -17
+ -19
@@ -11283,7 +11283,7 @@
- -38
+ -39
@@ -11399,7 +11399,7 @@
- -21
+ -22
@@ -11531,7 +11531,7 @@
- -18
+ -20
@@ -11559,7 +11559,7 @@
- -11
+ -14
@@ -11587,7 +11587,7 @@
- -37
+ -38
@@ -11667,7 +11667,7 @@
- -40
+ -42
@@ -11691,7 +11691,7 @@
- -19
+ -21
@@ -11715,7 +11715,7 @@
- -41
+ -30
@@ -11739,7 +11739,7 @@
- -42
+ -43
@@ -11819,7 +11819,7 @@
- -22
+ -23
@@ -11892,7 +11892,7 @@
0
- -11
+ -14error_info free function
@@ -11901,7 +11901,7 @@
0
- -12
+ -15type
@@ -11910,7 +11910,16 @@
0
- -14
+ -16
+
+
+ diagnostic_information tutorial
+
+
+
+ 0
+
+ -13tutorial
@@ -11919,7 +11928,7 @@
0
- -15
+ -17noindex tutorial
@@ -11933,15 +11942,6 @@
exception_ptr free function
-
-
- 0
-
- -19
-
-
- macro
- 0
@@ -11949,7 +11949,7 @@
-20
- diagnostic_information tutorial
+ exception_ptr free function
@@ -11958,7 +11958,7 @@
-21
- diagnostic_information free function
+ macro
@@ -11967,7 +11967,7 @@
-22
- noalso noindex tutorial
+ diagnostic_information free function
@@ -11976,7 +11976,7 @@
-23
- exception_ptr free function
+ noalso noindex tutorial
@@ -12039,7 +12039,7 @@
-30
- exception_ptr type
+ noalso noindex tutorial
@@ -12048,7 +12048,7 @@
-31
- error_info free function
+ exception_ptr type
@@ -12057,7 +12057,7 @@
-32
- noindex
+ error_info free function
@@ -12066,7 +12066,7 @@
-33
- tutorial
+ noindex
@@ -12075,7 +12075,7 @@
-34
- free function
+ tutorial
@@ -12084,7 +12084,7 @@
-35
- exception_ptr free function
+ free function
@@ -12093,7 +12093,7 @@
-36
- tutorial
+ exception_ptr free function
@@ -12102,7 +12102,7 @@
-37
- type
+ tutorial
@@ -12117,16 +12117,16 @@
0
- -40
+ -39
- noindex tutorial
+ type0
- -41
+ -40noalso noindex tutorial
@@ -12138,16 +12138,16 @@
-42
-
+ noindex tutorial0
- -44
+ -43
- noalso noindex tutorial
+