• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /** nonfinite_num_facet_trap.cpp
3 *
4 * Copyright (c) 2012 Paul A. Bristow
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt
8 * or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 * This very simple program illustrates how to use the
11 * `boost/math/nonfinite_num_facets.hpp` trapping output of infinity and/or NaNs.
12 *
13 \file
14 
15 \brief A very simple example of using non_finite_num facet for
16 trapping output of infinity and/or NaNs.
17 
18 \note To actually get an exception throw by the iostream library
19 one must enable exceptions.
20   `oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);`
21 \note Which bit is set is implementation dependent, so enable exceptions for both.
22 
23 This is a fairly brutal method of catching nonfinites on output,
24 but may suit some applications.
25 
26 */
27 
28 #ifdef _MSC_VER
29 #   pragma warning(disable : 4127) // conditional expression is constant.
30 // assumes C++ exceptions enabled /EHsc
31 #endif
32 
33 #include <boost/cstdint.hpp>
34 #include <boost/math/special_functions/nonfinite_num_facets.hpp>
35 
36 #include <iostream>
37 #include <iomanip>
38 using std::cout;
39 using std::endl;
40 using std::hex;
41 #include <exception>
42 #include <limits> // numeric_limits
43 using std::numeric_limits;
44 
main()45 int main()
46 {
47   using namespace boost::math;
48 
49   std::cout << "nonfinite_num_facet_trap.cpp" << std::endl;
50 
51   const double inf = +std::numeric_limits<double>::infinity ();
52   const double nan = +std::numeric_limits<double>::quiet_NaN ();
53 
54   { // Output infinity and NaN with default flags (no trapping).
55     std::ostringstream oss;
56     std::locale default_locale (std::locale::classic ());
57     std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>);
58     oss.imbue (C99_out_locale);
59     oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
60     oss << inf <<  ' ' << nan;
61     cout << "oss.rdstate()  = " << hex << oss.rdstate() << endl; // 0
62     cout << "os.str() = " << oss.str() << endl; // os.str() = inf nan
63   }
64 
65   try
66   { // // Output infinity with flags set to trap and catch any infinity.
67     std::ostringstream oss;
68     std::locale default_locale (std::locale::classic ());
69     std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>(trap_infinity));
70     oss.imbue (C99_out_locale);
71     oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
72     // Note that which bit is set is implementation dependent, so enable exceptions for both.
73     oss << inf;
74     cout << "oss.rdstate()  = " << hex << oss.rdstate() << endl;
75     cout << "oss.str() = " << oss.str() << endl;
76   }
77   catch(const std::ios_base::failure& e)
78   { // Expect "Infinity".
79     std::cout << "\n""Message from thrown exception was: " << e.what() << std::endl;
80   }
81 
82   try
83   { // // Output NaN with flags set to catch any NaNs.
84     std::ostringstream oss;
85     std::locale default_locale (std::locale::classic ());
86     std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>(trap_nan));
87     oss.imbue (C99_out_locale);
88     oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
89     // Note that which bit is set is implementation dependent, so enable exceptions for both.
90     oss << nan;
91     cout << "oss.str() = " << oss.str() << endl;
92   }
93   catch(const std::ios_base::failure& e)
94   { // Expect "Infinity".
95     std::cout << "\n""Message from thrown exception was: " << e.what() << std::endl;
96  }
97 
98 
99   return 0; // end of nonfinite_num_facet_trap.cpp
100 } // int main()
101 
102 
103 /*
104 
105 Output:
106 
107   nonfinite_num_facet_trap.cpp
108   oss.rdstate()  = 0
109   os.str() = inf nan
110 
111   Message from thrown exception was: Infinity
112 
113   Message from thrown exception was: NaN
114 
115 */
116