]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /** nonfinite_serialization_archives.cpp |
2 | * | |
3 | * Copyright (c) 2011 Paul A. Bristow | |
4 | * | |
5 | * Distributed under the Boost Software License, Version 1.0. | |
6 | * (See accompanying file LICENSE_1_0.txt | |
7 | * or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 | * | |
9 | * This very simple program illustrates how to use the | |
10 | * `boost/math/nonfinite_num_facets.hpp' to obtain C99 | |
11 | * representation of infinity and NaN. | |
12 | * From the original Floating Point Utilities contribution by Johan Rade. | |
13 | * Floating Point Utility library has been accepted into Boost, | |
14 | * but the utilities are incorporated into Boost.Math library. | |
15 | * | |
16 | \file | |
17 | ||
18 | \brief A simple example of using non_finite_num facet for | |
19 | C99 standard output of infinity and NaN in serialization archives. | |
20 | ||
21 | \detail This example shows how to create a C99 non-finite locale, | |
22 | and imbue input and output streams with the non_finite_num put and get facets. | |
23 | This allow output and input of infinity and NaN in a Standard portable way, | |
24 | This permits 'loop-back' of output back into input (and portably across different system too). | |
25 | This is particularly useful when used with Boost.Seralization so that non-finite NaNs and infinity | |
26 | values in text and xml archives can be handled correctly and portably. | |
27 | ||
28 | */ | |
29 | ||
30 | ||
31 | #ifdef _MSC_VER | |
32 | # pragma warning(disable : 4127) // conditional expression is constant. | |
33 | #endif | |
34 | ||
35 | ||
36 | #include <boost/archive/text_oarchive.hpp> | |
37 | using boost::archive::text_oarchive; | |
38 | #include <boost/archive/codecvt_null.hpp> | |
39 | using boost::archive::codecvt_null; | |
40 | using boost::archive::no_codecvt; | |
41 | ||
42 | #include <boost/math/special_functions/nonfinite_num_facets.hpp> | |
43 | using boost::math::nonfinite_num_get; | |
44 | using boost::math::nonfinite_num_put; | |
45 | ||
46 | #include <iostream> | |
47 | using std::cout; | |
48 | using std::endl; | |
49 | using std::cerr; | |
50 | ||
51 | #include <iomanip> | |
52 | using std::setw; | |
53 | using std::left; | |
54 | using std::right; | |
55 | using std::internal; | |
56 | ||
57 | #include <string> | |
58 | using std::string; | |
59 | ||
60 | #include <sstream> | |
61 | using std::istringstream; | |
62 | ||
63 | #include <fstream> | |
64 | using std::ofstream; | |
65 | ||
66 | #include <limits> | |
67 | using std::numeric_limits; | |
68 | ||
69 | #include <locale> | |
70 | using std::locale; | |
71 | ||
72 | ||
73 | /* | |
74 | Use with serialization archives. | |
75 | ||
76 | It is important that the same locale is used | |
77 | when an archive is saved and when it is loaded. | |
78 | Otherwise, loading the archive may fail. | |
79 | ||
80 | By default, archives are saved and loaded with a classic C locale with a | |
81 | `boost::archive::codecvt_null` facet added. | |
82 | Normally you do not have to worry about that. | |
83 | The constructors for the archive classes, as a side-effect, | |
84 | imbue the stream with such a locale. | |
85 | ||
86 | However, if you want to use the facets `nonfinite_num_put` and `nonfinite_num_get` | |
87 | with archives,`then you have to manage the locale manually. | |
88 | ||
89 | That is done by calling the archive constructor with the flag `boost::archive::no_codecvt`. | |
90 | Then the archive constructor will not imbue the stream with a new locale. | |
91 | ||
92 | The following code shows how to use `nonfinite_num_put` with a `text_oarchive`: | |
93 | ||
94 | */ | |
95 | ||
96 | int main() | |
97 | { | |
98 | ||
99 | if((std::numeric_limits<double>::has_infinity == false) || (std::numeric_limits<double>::infinity() == 0)) | |
100 | { | |
101 | std::cout << "Infinity not supported on this platform." << std::endl; | |
102 | return 0; | |
103 | } | |
104 | ||
105 | if((std::numeric_limits<double>::has_quiet_NaN == false) || (std::numeric_limits<double>::quiet_NaN() == 0)) | |
106 | { | |
107 | std::cout << "NaN not supported on this platform." << std::endl; | |
108 | return 0; | |
109 | } | |
110 | ||
111 | locale default_locale(locale::classic(), new boost::archive::codecvt_null<char>); | |
112 | // codecvt_null so the archive constructor will not imbue the stream with a new locale. | |
113 | ||
114 | locale my_locale(default_locale, new nonfinite_num_put<char>); | |
115 | // Add nonfinite_num_put facet to locale. | |
116 | ||
117 | ofstream ofs("test.txt"); | |
118 | ofs.imbue(my_locale); | |
119 | ||
120 | boost::archive::text_oarchive oa(ofs, no_codecvt); | |
121 | ||
122 | double x = numeric_limits<double>::infinity(); | |
123 | oa & x; | |
124 | ||
125 | ||
126 | } // int main() | |
127 | ||
128 | ||
129 | /* The same method works with nonfinite_num_get and text_iarchive. | |
130 | ||
131 | If you use the trap_infinity and trap_nan flags with a serialization archive, | |
132 | then you must set the exception mask of the stream. | |
133 | Serialization archives do not check the stream state. | |
134 | ||
135 | ||
136 | */ |