Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71284 - trunk/libs/math/example
From: pbristow_at_[hidden]
Date: 2011-04-15 10:42:53


Author: pbristow
Date: 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
New Revision: 71284
URL: http://svn.boost.org/trac/boost/changeset/71284

Log:
Added new nonfinite facets examples.
Added:
   trunk/libs/math/example/lexical_cast_native.cpp (contents, props changed)
   trunk/libs/math/example/lexical_cast_nonfinite_facets.cpp (contents, props changed)
   trunk/libs/math/example/nonfinite_facet_simple.cpp (contents, props changed)
   trunk/libs/math/example/nonfinite_facet_sstream.cpp (contents, props changed)
   trunk/libs/math/example/nonfinite_legacy.cpp (contents, props changed)
   trunk/libs/math/example/nonfinite_loopback_ok.cpp (contents, props changed)
   trunk/libs/math/example/nonfinite_num_facet.cpp (contents, props changed)
   trunk/libs/math/example/nonfinite_num_facet_serialization.cpp (contents, props changed)
   trunk/libs/math/example/nonfinite_serialization_archives.cpp (contents, props changed)
   trunk/libs/math/example/test_nonfinite_loopback.cpp (contents, props changed)

Added: trunk/libs/math/example/lexical_cast_native.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/lexical_cast_native.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,121 @@
+/** lexical_cast_nonfinite_facets.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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 very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' with lexical cast
+* to obtain C99 representation of infinity and NaN.
+* This example is from the original Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A very simple example of using lexical cast with
+non_finite_num facet for C99 standard output of infinity and NaN.
+
+\detail This example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allows lexical_cast output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <boost/lexical_cast.hpp>
+using boost::lexical_cast;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <locale>
+using std::locale;
+
+#include <boost/assert.hpp>
+
+int main ()
+{
+ std::cout << "lexical_cast example (NOT using finite_num_facet)." << std::endl;
+
+ // Some tests that are expected to fail on some platforms.
+ // (But these tests are expected to pass using non_finite num_put and num_get facets).
+
+ // Use the current 'native' default locale.
+ std::locale default_locale (std::locale::classic ()); // Note the currrent (default C) locale.
+
+ // Create plus and minus infinity.
+ double plus_infinity = +std::numeric_limits<double>::infinity();
+ double minus_infinity = -std::numeric_limits<double>::infinity();
+
+ // and create a NaN (NotANumber).
+ double NaN = +std::numeric_limits<double>::quiet_NaN ();
+
+ // Output the nonfinite values using the current (default C) locale.
+ // The default representations differ from system to system,
+ // for example, using Microsoft compilers, 1.#INF, -1.#INF, and 1.#QNAN.
+ cout << "Using default locale" << endl;
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+
+ // Checks below are expected to fail on some platforms!
+
+ // Now try some 'round-tripping', 'reading' "inf"
+ double x = boost::lexical_cast<double>("inf");
+ // and check we get a floating-point infinity.
+ BOOST_ASSERT(x == std::numeric_limits<double>::infinity());
+
+ // Check we can convert the other way from floating-point infinity,
+ string s = boost::lexical_cast<string>(numeric_limits<double>::infinity());
+ // to a C99 string representation as "inf".
+ BOOST_ASSERT(s == "inf");
+
+ // Finally try full 'round-tripping' (in both directions):
+ BOOST_ASSERT(lexical_cast<double>(lexical_cast<string>(numeric_limits<double>::infinity()))
+ == numeric_limits<double>::infinity());
+ BOOST_ASSERT(lexical_cast<string>(lexical_cast<double>("inf")) == "inf");
+
+ return 0;
+} // int main()
+
+/*
+
+Output:
+
+from MSVC 10, fails (as expected)
+
+ lexical_cast_native.vcxproj -> J:\Cpp\fp_facet\fp_facet\Debug\lexical_cast_native.exe
+ lexical_cast example (NOT using finite_num_facet).
+ Using default locale
+ +std::numeric_limits<double>::infinity() = 1.#INF
+ -std::numeric_limits<double>::infinity() = -1.#INF
+ +std::numeric_limits<double>::quiet_NaN () = 1.#QNAN
+C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(183,5): error MSB3073: The command ""J:\Cpp\fp_facet\fp_facet\Debug\lexical_cast_native.exe"
+C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(183,5): error MSB3073: :VCEnd" exited with code 3.
+
+
+*/
\ No newline at end of file

Added: trunk/libs/math/example/lexical_cast_nonfinite_facets.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/lexical_cast_nonfinite_facets.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,127 @@
+/** lexical_cast_nonfinite_facets.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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 very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' with lexical cast
+* to obtain C99 representation of infinity and NaN.
+* This example is from the original Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A very simple example of using lexical cast with
+non_finite_num facet for C99 standard output of infinity and NaN.
+
+\detail This example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allows lexical_cast output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+
+See also lexical_cast_native.cpp which is expected to fail on many systems,
+but might succeed if the default locale num_put and num_get facets
+comply with C99 nonfinite input and output specification.
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <boost/lexical_cast.hpp>
+using boost::lexical_cast;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <locale>
+using std::locale;
+
+#include <boost/assert.hpp>
+
+int main ()
+{
+ std::cout << "finite_num_facet with lexical_cast example." << std::endl;
+
+ // Example of using non_finite num_put and num_get facets with lexical_cast.
+ locale old_locale;
+ locale tmp_locale(old_locale, new nonfinite_num_put<char>);
+ // Create a new temporary output locale, and add the output nonfinite_num_put facet.
+
+ locale new_locale(tmp_locale, new nonfinite_num_get<char>);
+ // Create a new output locale (from the tmp locale), and add the input nonfinite_num_get facet.
+
+ // Note that is necessary to do add get and put facets in two steps.
+
+ locale::global(new_locale); // Newly constructed streams
+ // (including those streams inside lexical_cast)
+ // now use new_locale with nonfinite facets.
+
+ // Output using the new locale.
+ cout << "Using C99_out_locale " << endl;
+ cout.imbue(new_locale);
+ // Necessary because cout already constructed using default C locale,
+ // and default facets for nonfinites.
+
+ // Create plus and minus infinity.
+ double plus_infinity = +std::numeric_limits<double>::infinity();
+ double minus_infinity = -std::numeric_limits<double>::infinity();
+
+ // and create a NaN (NotANumber)
+ double NaN = +std::numeric_limits<double>::quiet_NaN ();
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+
+ // Now try some 'round-tripping', 'reading' "inf"
+ double x = boost::lexical_cast<double>("inf");
+ // and check we get a floating-point infinity.
+ BOOST_ASSERT(x == std::numeric_limits<double>::infinity());
+
+ // Check we can convert the other way from floating-point infinity,
+ string s = boost::lexical_cast<string>(numeric_limits<double>::infinity());
+ // to a C99 string representation as "inf".
+ BOOST_ASSERT(s == "inf");
+
+ // Finally try full 'round-tripping' (in both directions):
+ BOOST_ASSERT(lexical_cast<double>(lexical_cast<string>(numeric_limits<double>::infinity()))
+ == numeric_limits<double>::infinity());
+ BOOST_ASSERT(lexical_cast<string>(lexical_cast<double>("inf")) == "inf");
+
+ return 0;
+} // int main()
+
+/*
+
+Output:
+
+ finite_num_facet with lexical_cast example.
+ Using C99_out_locale
+ +std::numeric_limits<double>::infinity() = inf
+ -std::numeric_limits<double>::infinity() = -inf
+ +std::numeric_limits<double>::quiet_NaN () = nan
+
+
+*/
\ No newline at end of file

Added: trunk/libs/math/example/nonfinite_facet_simple.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/nonfinite_facet_simple.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,234 @@
+/** nonfinite_num_facet.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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 very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' to obtain C99
+* representation of infinity and NaN.
+* (from the original
+* Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A very simple example of using non_finite_num facet for
+C99 standard output of infinity and NaN.
+
+\detail This example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allow output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+This is particularly useful when used with Boost.Seralization so that non-finite NaNs and infinity
+values in text and xml archives can be handled correctly and portably.
+
+*/
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <limits>
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+// from Johan Rade Floating Point Utilities.
+
+int main ()
+{
+ std::cout << "Nonfinite_num_facet very simple example." << std::endl;
+
+ std::locale default_locale (std::locale::classic ()); // Note the currrent (default C) locale.
+
+ // Create plus and minus infinity.
+ double plus_infinity = +std::numeric_limits<double>::infinity();
+ double minus_infinity = -std::numeric_limits<double>::infinity();
+
+ // and create a NaN (NotANumber)
+ double NaN = +std::numeric_limits<double>::quiet_NaN ();
+
+ // Output the nonfinite values using the current (default C) locale.
+ // The default representations differ from system to system,
+ // for example, using Microsoft compilers, 1.#INF, -1.#INF, and 1.#QNAN.
+ cout << "Using C locale" << endl;
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+
+ // Create a new output locale, and add the nonfinite_num_put facet
+ std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>);
+ // and imbue the cout stream with the new locale.
+ cout.imbue (C99_out_locale);
+
+ // Output using the new locale
+ cout << "Using C99_out_locale " << endl;
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+
+
+ // Create a string with the expected C99 representation of plus infinity.
+ std::string inf = "inf";
+ { // Try to read an infinity value using the default C locale.
+ // Create an input stream which will provide "inf"
+ std::istringstream iss (inf);
+
+ // Create a double ready to take the input,
+ double infinity;
+ // and read "inf" from the stringstream:
+ iss >> infinity;
+
+ // This will not work on all platforms!
+ if (! iss)
+ { // Reading infinity went wrong!
+ std::cerr << "C locale input format error!" << std::endl;
+ }
+ } // Using default C locale.
+
+ { // Now retry using C99 facets.
+ // Create a new input locale and add the nonfinite_num_get facet.
+ std::locale C99_in_locale (default_locale, new boost::math::nonfinite_num_get<char>);
+ // imbue the stream with the C99 input locale.
+ // Create an input stream which will provide "inf"
+ std::istringstream iss (inf);
+ iss.imbue (C99_in_locale);
+
+ // Create a double ready to take the input,
+ double infinity;
+ // and read from the stringstream:
+ iss >> infinity;
+
+ if (! iss)
+ { // Reading infinity went wrong!
+ std::cout << "C99 input format error!" << std::endl;
+ }
+ // Expect to get an infinity, which will display still using the C99 locale as "inf"
+ cout << "infinity in C99 representation is " << infinity << endl;
+
+ // To check, we can switch back to the default C locale.
+ cout.imbue (default_locale);
+ cout << "infinity in default C representation is " << infinity << endl;
+ } // using C99 locale.
+
+ {
+ // A 'loop-back example, output to a stringstream, and reading it back in.
+ // Create C99 input and output locales.
+ std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>);
+ std::locale C99_in_locale (default_locale, new boost::math::nonfinite_num_get<char>);
+
+ std::ostringstream oss;
+ oss.imbue(C99_out_locale);
+ oss << plus_infinity;
+
+ std::istringstream iss(oss.str()); // So stream contains "inf".
+ iss.imbue (C99_in_locale);
+
+ std::string s;
+
+ iss >> s;
+
+ cout.imbue(C99_out_locale);
+ if (oss.str() != s)
+ {
+ cout << plus_infinity << " != " << s << " loopback failed!" << endl;
+ }
+ else
+ {
+ cout << plus_infinity << " == " << s << " as expected." << endl;
+ }
+ }
+
+
+ // Example varying the width and position of the nonfinite representations.
+ // With the nonfinite_num_put and _get facets, the width of the output is constant.
+
+ #ifdef BOOST_NO_NUMERIC_LIMITS_LOWEST
+ std::streamsize max_digits10 = 2 + numeric_limits<double>::digits * 30103UL / 100000UL;
+ cout << "BOOST_NO_NUMERIC_LIMITS_LOWEST is defined." << endl;
+#else
+ // Can use new C++0X max_digits10 (the maximum potentially significant digits).
+ std::streamsize max_digits10 = std::numeric_limits<double>::max_digits10;
+#endif
+ cout << "std::numeric_limits<double>::max_digits10 is " << max_digits10 << endl;
+ cout.precision(max_digits10);
+
+ double pi = 3.141592653589793238462643383279502884197169399375105820974944;
+ // Expect 17 (probably) decimal digits (regardless of locale).
+ // cout has the default locale.
+ cout << "pi = " << pi << endl; // pi = 3.1415926535897931
+ cout.imbue (C99_out_locale); // Use cout with the C99 locale
+ // (expect the same output for a double).
+ cout << "pi = " << pi << endl; // pi = 3.1415926535897931
+
+ cout << "infinity in C99 representation is " << plus_infinity << endl;
+
+ //int width = 2; // Check effect if width too small is OK.
+ // (There was a disturbed layout on older MSVC?).
+ int width = 20;
+
+ // Similarly if we can switch back to the default C locale.
+ cout.imbue (default_locale);
+ cout << "infinity in default C representation is " << plus_infinity << endl;
+ cout << "infinity in default C representation (setw(" << width << ") is " << setw(width) << plus_infinity <<'|' << endl;
+ cout << "infinity in default C representation (setw(" << width << ") is " << left << setw(width) << plus_infinity <<'|' << endl;
+ cout << "infinity in default C representation (setw(" << width << ") is " << internal << setw(width) << plus_infinity <<'|' << endl;
+
+ cout.imbue (C99_out_locale);
+ cout << "infinity in C99 representation (setw(" << width << ") is " << right << setw(width) << plus_infinity <<'|'<< endl;
+ cout << "infinity in C99 representation (setw(" << width << ") is " << left << setw(width) << plus_infinity <<'|'<< endl;
+ cout << "infinity in C99 representation (setw(" << width << ") is " << internal << setw(width) << plus_infinity <<'|'<< endl;
+
+ return 0;
+} // int main()
+
+// end of test_nonfinite_num_facets.cpp
+
+/*
+
+Output:
+
+simple_nonfinite_facet.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\nonfinite_facet_simple.exe
+ Nonfinite_num_facet very simple example.
+ Using C locale
+ +std::numeric_limits<double>::infinity() = 1.#INF
+ -std::numeric_limits<double>::infinity() = -1.#INF
+ +std::numeric_limits<double>::quiet_NaN () = 1.#QNAN
+ Using C99_out_locale
+ +std::numeric_limits<double>::infinity() = inf
+ -std::numeric_limits<double>::infinity() = -inf
+ +std::numeric_limits<double>::quiet_NaN () = nan
+ infinity in C99 representation is inf
+ infinity in default C representation is 1.#INF
+ 3
+ 3
+ inf == inf as expected.
+ std::numeric_limits<double>::max_digits10 is 17
+ pi = 3.1415926535897931
+ C locale input format error!
+ pi = 3.1415926535897931
+ infinity in C99 representation is inf
+ infinity in default C representation is 1.#INF
+ infinity in default C representation (setw(20) is 1.#INF|
+ infinity in default C representation (setw(20) is 1.#INF |
+ infinity in default C representation (setw(20) is 1.#INF|
+ infinity in C99 representation (setw(20) is inf|
+ infinity in C99 representation (setw(20) is inf |
+ infinity in C99 representation (setw(20) is inf|
+
+*/
\ No newline at end of file

Added: trunk/libs/math/example/nonfinite_facet_sstream.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/nonfinite_facet_sstream.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,132 @@
+// nonfinite_facet_sstream.cpp
+
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Examples of nonfinite with output and input facets and stringstreams.
+
+\detail Contruct a new locale with the nonfinite_num_put and nonfinite_num_get
+facets and imbue istringstream, ostringstream and stringstreams,
+showing output and input (and loopback for the stringstream).
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_put;
+using boost::math::nonfinite_num_get;
+
+using boost::math::legacy;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+#include <locale>
+using std::locale;
+
+#include <sstream>
+ using std::stringstream;
+ using std::istringstream;
+ using std::ostringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <assert.h>
+
+int main()
+{
+//[nonfinite_facets_sstream_1
+ locale old_locale;
+ locale tmp_locale(old_locale, new nonfinite_num_put<char>);
+ locale new_locale(tmp_locale, new nonfinite_num_get<char>);
+//] [/nonfinite_facets_sstream_1]
+
+ // Note that to add two facets, nonfinite_num_put and nonfinite_num_get,
+ // you have to add one at a time, using a temporary locale.
+
+ {
+ ostringstream oss;
+ oss.imbue(new_locale);
+ double inf = numeric_limits<double>::infinity();
+ oss << inf; // Write out.
+ cout << "infinity output was " << oss.str() << endl;
+ assert(oss.str() == "inf");
+ }
+ {
+ istringstream iss;
+ iss.str("inf");
+ iss.imbue(new_locale);
+ double inf;
+ iss >> inf; // Read from "inf"
+ cout << "Infinity input was " << iss.str() << endl;
+ assert(inf == numeric_limits<double>::infinity());
+ }
+
+ {
+//[nonfinite_facets_sstream_2
+ stringstream ss;
+ ss.imbue(new_locale);
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Write out.
+ assert(ss.str() == "inf");
+ double r;
+ ss >> r; // Read back in.
+ assert(inf == r); // Confirms that the double values really are identical.
+
+ cout << "infinity output was " << ss.str() << endl;
+ cout << "infinity input was " << r << endl;
+ // But the string representation of r displayed will be the native type
+ // because, when it was constructed, cout had NOT been imbued
+ // with the new locale containing the nonfinite_numput facet.
+ // So the cout output will be "1.#INF on MS platforms
+ // and may be "inf" or other string representation on other platforms.
+
+//] [/nonfinite_facets_sstream_2]
+ }
+
+ {
+ stringstream ss;
+ ss.imbue(new_locale);
+
+ double nan = numeric_limits<double>::quiet_NaN();
+ ss << nan; // Write out.
+ assert(ss.str() == "nan");
+
+ double v;
+ ss >> v; // Read back in.
+
+ cout << "NaN output was " << ss.str() << endl;
+ cout << "NaN input was " << v << endl;
+
+ // assert(nan == v); // Always fails because NaN == NaN fails!
+ // assert(nan == numeric_limits<double>::quiet_NaN()); asserts!
+
+ // And the string representation will be the native type
+ // because cout has NOT been imbued with a locale containing
+ // the nonfinite_numput facet.
+ // So the output will be "1.#QNAN on MS platforms
+ // and may be "nan" or other string representation on other platforms.
+ }
+
+} // int main()
+
+
+/*
+//[nonfinite_facet_sstream_output
+
+ infinity output was inf
+ Infinity input was inf
+ infinity output was inf
+ infinity input was 1.#INF
+ NaN output was nan
+ NaN input was 1.#QNAN
+
+//] [nonfinite_facet_sstream_output]
+*/
+

Added: trunk/libs/math/example/nonfinite_legacy.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/nonfinite_legacy.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,91 @@
+// nonfinite_legacy.cpp
+
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Basic tests of nonfinite loopback with output and input facet.
+
+\detail Basic loopback test outputs using the so-called 'legacy' facets,
+"1.#INF" and "1.#QNAN".
+
+and reads back in using nonfinite input 'legacy' facet, and
+(if possible) checks if loopback OK.
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_put;
+using boost::math::nonfinite_num_get;
+
+using boost::math::legacy;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+#include <locale>
+using std::locale;
+
+#include <sstream>
+ using std::stringstream;
+#include <limits>
+using std::numeric_limits;
+
+#include <assert.h>
+
+int main()
+{
+
+ locale old_locale;
+ locale tmp_locale(old_locale, new nonfinite_num_put<char>(legacy));
+ locale new_locale(tmp_locale, new nonfinite_num_get<char>(legacy));
+ // Note that to add two facets, nonfinite_num_put and nonfinite_num_get,
+ // you have to add one at a time, using a temporary locale.
+
+ {
+ stringstream ss;
+ ss.imbue(new_locale);
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Write out.
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "infinity output was " << inf << endl;
+ cout << "infinity input was " << r << endl;
+
+ assert(inf == r);
+ }
+ {
+ stringstream ss;
+ ss.imbue(new_locale);
+
+ double nan = numeric_limits<double>::quiet_NaN();
+ ss << nan; // Write out.
+ double v;
+ ss >> v; // Read back in.
+
+ cout << "NaN output was " << nan << endl;
+ cout << "NaN input was " << v << endl;
+
+ // assert(nan == v); // Always fails because NaN == NaN fails!
+ // assert(nan == numeric_limits<double>::quiet_NaN()); asserts!
+ }
+
+} // int main()
+
+/*
+
+Output:
+
+ infinity output was 1.#INF
+ infinity input was 1.#INF
+ NaN output was 1.#QNAN
+ NaN input was 1.#QNAN
+
+*/
+

Added: trunk/libs/math/example/nonfinite_loopback_ok.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/nonfinite_loopback_ok.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,70 @@
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Basic tests of nonfinite loopback.
+
+\detail Basic loopback test outputs using nonfinite facets
+(output and input) and reads back in, and checks if loopback OK.
+
+Expected to work portably on all platforms.
+
+*/
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4702)
+#endif
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include <locale>
+using std::locale;
+
+#include <sstream>
+ using std::stringstream;
+#include <limits>
+using std::numeric_limits;
+
+#include <assert.h>
+
+int main()
+{
+ locale old_locale; // Current global locale.
+ // Create tmp_locale and store the output nonfinite_num_put facet in it.
+ locale tmp_locale(old_locale, new nonfinite_num_put<char>);
+ // Create new_locale and store the input nonfinite_num_get facet in it.
+ locale new_locale(tmp_locale, new nonfinite_num_get<char>);
+ // Seems necessary to add one facet at a time, hence need a tmp_locale.
+
+ stringstream ss; // Both input and output.
+ ss.imbue(new_locale);
+
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Write out.
+ double r;
+ ss >> r; // Read back in.
+
+ assert(inf == r); // OK MSVC <= 10.0!
+
+} // int main()
+
+/*
+
+Output:
+
+ nonfinite_loopback_ok.vcxproj -> J:\Cpp\fp_facet\fp_facet\Debug\nonfinite_loopback_ok.exe
+
+
+*/
+

Added: trunk/libs/math/example/nonfinite_num_facet.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/nonfinite_num_facet.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,255 @@
+/** nonfinite_num_facet.cpp
+ *
+ * Copyright (c) 2011 Francois Mauger
+ * Copyright (c) 2011 Paul A. Bristow
+ *
+ * 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 simple program illustrates how to use the
+ * `boost/math/nonfinite_num_facets.hpp' material from the original
+ * Floating Point Utilities by Johan Rade.
+
+ *
+\file
+
+\brief A fairly simple example of using non_finite_num facet for
+C99 standard output of infinity and NaN.
+
+\detail This program illustrates how to use the
+ `boost/math/nonfinite_num_facets.hpp' material from the original
+ Floating Point Utilities contribution by Johan Rade.
+ Floating Point Utility library has been accepted into Boost,
+ but the utilities have been/will be incorporated into Boost.Math library.
+
+ Based on an example from Francois Mauger.
+
+ double and float variables are assigned ordinary finite values (pi),
+ and nonfinite like infinity and NaN.
+
+ These values are then output and read back in, and then redisplayed.
+
+*/
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+//#include <sstream>
+#include <limits> // numeric_limits
+
+#include <boost/cstdint.hpp>
+
+// from Johan Rade Floating Point Utilities :
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+
+static const char sep = ',';
+
+/* A class with a float and a double */
+struct foo
+{
+ foo () : fvalue (3.1415927F), dvalue (3.1415926535897931)
+ {
+ }
+ // Set both the values to -infinity :
+ void minus_infinity ()
+ {
+ fvalue = -std::numeric_limits<float>::infinity ();
+ dvalue = -std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // Set the values to +infinity :
+ void plus_infinity ()
+ {
+ fvalue = +std::numeric_limits<float>::infinity ();
+ dvalue = +std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // Set the values to NaN :
+ void nan ()
+ {
+ fvalue = +std::numeric_limits<float>::quiet_NaN ();
+ dvalue = +std::numeric_limits<double>::quiet_NaN ();
+ return;
+ }
+ // Print a foo:
+ void print (std::ostream & a_out, const std::string & a_title)
+ {
+ if (a_title.empty ()) a_out << "foo";
+ else a_out << a_title;
+ a_out << " : " << std::endl;
+ a_out << "|-- " << "fvalue = ";
+ // Use max_digits10 to obtain
+ // all potentially significant decimal digits for the floating-point type.
+ a_out.precision (std::numeric_limits<float>::max_digits10);
+ a_out << fvalue << std::endl;
+ a_out << "`-- " << "dvalue = ";
+ a_out.precision (std::numeric_limits<double>::max_digits10);
+ a_out << dvalue << std::endl;
+ return;
+ }
+
+ // I/O operators for a foo structure of a float and a double :
+ friend std::ostream & operator<< (std::ostream & a_out, const foo & a_foo);
+ friend std::istream & operator>> (std::istream & a_in, foo & a_foo);
+
+ // Attributes :
+ float fvalue; // Single precision floating number.
+ double dvalue; // Double precision floating number.
+};
+
+std::ostream & operator<< (std::ostream & a_out, const foo & a_foo)
+{ // Output bracketed FPs, for example "(3.1415927,3.1415926535897931)"
+ a_out.precision (std::numeric_limits<float>::max_digits10);
+ a_out << "(" << a_foo.fvalue << sep ;
+ a_out.precision (std::numeric_limits<double>::max_digits10);
+ a_out << a_foo.dvalue << ")";
+ return a_out;
+}
+
+std::istream & operator>> (std::istream & a_in, foo & a_foo)
+{ // Input bracketed FPs, into a foo structure,
+ // for example from "(3.1415927,3.1415926535897931)"
+ char c = 0;
+ a_in.get (c);
+ if (c != '(')
+ {
+ std::cerr << "ERROR: operator>> No ( " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ float f;
+ a_in >> std::ws >> f;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != sep)
+ {
+ std::cerr << "ERROR: operator>> c='" << c << "'" << std::endl;
+ std::cerr << "ERROR: operator>> No '" << sep << "'" << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ double d;
+ a_in >> std::ws >> d;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != ')')
+ {
+ std::cerr << "ERROR: operator>> No ) " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ a_foo.fvalue = f;
+ a_foo.dvalue = d;
+ return a_in;
+} // std::istream & operator>> (std::istream & a_in, foo & a_foo)
+
+int main ()
+{
+ std::cout << "nonfinite_num_facet simple example." << std::endl;
+
+ std::locale the_default_locale (std::locale::classic ());
+
+ {
+ std::cout << "Write to a string buffer (using default locale) :" << std::endl;
+ foo f0; // pi
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+
+ f0.print (std::cout, "f0"); // pi
+ f1.print (std::cout, "f1"); // +inf
+ f2.print (std::cout, "f2"); // -inf
+ f3.print (std::cout, "f3"); // NaN
+
+ std::ostringstream oss;
+ std::locale C99_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ oss.imbue (C99_out_locale);
+ oss.precision (15);
+ oss << f0 << f1 << f2 << f3;
+ std::cout << "Output in C99 format is: \"" << oss.str () << "\"" << std::endl;
+ std::cout << "Output done." << std::endl;
+ }
+
+ {
+ std::string the_string = "(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)"; // C99 format
+ // Must have correct separator!
+ std::cout << "Read C99 format from a string buffer containing \"" << the_string << "\""<< std::endl;
+
+ std::locale C99_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ std::istringstream iss (the_string);
+ iss.imbue (C99_in_locale);
+
+ foo f0, f1, f2, f3;
+ iss >> f0 >> f1 >> f2 >> f3;
+ if (! iss)
+ {
+ std::cout << "Input Format error !" << std::endl;
+ }
+ else
+ {
+ std::cout << "Input OK." << std::endl;
+ cout << "Display in default locale format " << endl;
+ f0.print (std::cout, "f0");
+ f1.print (std::cout, "f1");
+ f2.print (std::cout, "f2");
+ f3.print (std::cout, "f3");
+ }
+ std::cout << "Input done." << std::endl;
+ }
+
+ std::cout << "End nonfinite_num_facet.cpp" << std::endl;
+ return 0;
+} // int main()
+
+ // end of test_nonfinite_num_facets.cpp
+
+/*
+
+Output:
+
+ nonfinite_num_facet.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\nonfinite_num_facet.exe
+ nonfinite_num_facet simple example.
+ Write to a string buffer (using default locale) :
+ f0 :
+ |-- fvalue = 3.1415927
+ `-- dvalue = 3.1415926535897931
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Output in C99 format is: "(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)"
+ Output done.
+ Read C99 format from a string buffer containing "(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)"
+ Display in default locale format
+ f0 :
+ |-- fvalue = 3.1415927
+ `-- dvalue = 3.1415926535897931
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Input done.
+ End nonfinite_num_facet.cpp
+ Input OK.
+
+*/
\ No newline at end of file

Added: trunk/libs/math/example/nonfinite_num_facet_serialization.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/nonfinite_num_facet_serialization.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,302 @@
+/** nonfinite_num_facet_serialization.cpp
+ *
+ * Copyright (c) 2011 Francois Mauger
+ * Copyright (c) 2011 Paul A. Bristow
+ *
+ * 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 sample program illustrates how to use the
+ * `boost/math/nonfinite_num_facets.hpp' material from the original
+ * Floating Point Utilities contribution by Johan Rade. Here it is
+ * shown how non finite floating number can be serialized and
+ * deserialized from I/O streams and/or Boost text/XML archives. It
+ * produces two archives stored in `test.txt' and `test.xml' files.
+ *
+ * Tested with Boost 1.44, gcc 4.4.1, Linux/i686 (32bits)
+ *
+ */
+
+
+#ifdef _MSC_VER
+# pragma warning(push)
+
+# pragma warning(disable : 4224) // formal parameter 'version' was previously defined as a type
+# pragma warning(disable : 4100) // unreferenced formal parameter
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <limits>
+
+#include <boost/cstdint.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/xml_oarchive.hpp>
+#include <boost/archive/xml_iarchive.hpp>
+#include <boost/archive/codecvt_null.hpp>
+
+// from Johan Rade Floating Point Utilities :
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+
+/* A class with a float and a double */
+struct foo
+{
+ foo () : fvalue (3.141593F), dvalue (3.14159265358979) {}
+ // set the values at -infinity :
+ void minus_infinity ()
+ {
+ fvalue = -std::numeric_limits<float>::infinity ();
+ dvalue = -std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // set the values at +infinity :
+ void plus_infinity ()
+ {
+ fvalue = +std::numeric_limits<float>::infinity ();
+ dvalue = +std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // set the values at NaN :
+ void nan ()
+ {
+ fvalue = +std::numeric_limits<float>::quiet_NaN ();
+ dvalue = +std::numeric_limits<double>::quiet_NaN ();
+ return;
+ }
+ // print :
+ void print (std::ostream & a_out, const std::string & a_title)
+ {
+ if (a_title.empty ()) a_out << "foo";
+ else a_out << a_title;
+ a_out << " : " << std::endl;
+ a_out << "|-- " << "fvalue = ";
+ a_out.precision (7);
+ a_out << fvalue << std::endl;
+ a_out << "`-- " << "dvalue = ";
+ a_out.precision (15);
+ a_out << dvalue << std::endl;
+ return;
+ }
+
+ // I/O operators :
+ friend std::ostream & operator<< (std::ostream & a_out, const foo & a_foo);
+ friend std::istream & operator>> (std::istream & a_in, foo & a_foo);
+
+ // Boost serialization :
+ template <class Archive>
+ void serialize (Archive & ar, int version)
+ {
+ ar & BOOST_SERIALIZATION_NVP (fvalue);
+ ar & BOOST_SERIALIZATION_NVP (dvalue);
+ return;
+ }
+
+ // Attributes :
+ float fvalue; // single precision floating number
+ double dvalue; // double precision floating number
+};
+
+std::ostream & operator<< (std::ostream & a_out, const foo & a_foo)
+{
+ a_out << "(" << a_foo.fvalue << ";" << a_foo.dvalue << ")";
+ return a_out;
+}
+
+std::istream & operator>> (std::istream & a_in, foo & a_foo)
+{
+ char c = 0;
+ a_in.get (c);
+ if (c != '(')
+ {
+ std::cerr << "ERROR: operator>> No ( " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ float f;
+ a_in >> std::ws >> f;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != ';')
+ {
+ std::cerr << "ERROR: operator>> c='" << c << "'" << std::endl;
+ std::cerr << "ERROR: operator>> No ; " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ double d;
+ a_in >> std::ws >> d;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != ')')
+ {
+ std::cerr << "ERROR: operator>> No ) " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ a_foo.fvalue = f;
+ a_foo.dvalue = d;
+ return a_in;
+}
+
+int main (void)
+{
+ std::clog << "Hello Booster !" << std::endl
+ << "This is the `test_nonfinite_num_facets_1.cpp' sample program !" << std::endl;
+
+ std::locale the_default_locale (std::locale::classic (),
+ new boost::archive::codecvt_null<char>);
+
+ {
+ std::clog << "Write to some string buffer..." << std::endl;
+ foo f0;
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::ostringstream oss;
+ std::locale the_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ oss.imbue (the_out_locale);
+ oss.precision (15);
+ oss << f0 << f1 << f2 << f3;
+ std::clog << "Output is: `" << oss.str () << "'" << std::endl;
+ std::clog << "Done." << std::endl;
+ }
+
+ {
+ std::clog << "Read from to some string buffer..." << std::endl;
+ std::string the_string = "(3.14159;3.14159)(-inf;-inf)(inf;inf)(nan;nan)";
+ std::clog << "Input is: `" << the_string << "'" << std::endl;
+
+ std::locale the_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ std::istringstream iss (the_string);
+ iss.imbue (the_in_locale);
+
+ foo f0, f1, f2, f3;
+ iss >> f0 >> f1 >> f2 >> f3;
+ if (! iss)
+ {
+ std::cerr << "Format error !" << std::endl;
+ }
+ else
+ {
+ std::cerr << "Success !" << std::endl;
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+ }
+ std::clog << "Done." << std::endl;
+ }
+
+ {
+ std::clog << "Serialize (boost text archive)..." << std::endl;
+ foo f0;
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::locale the_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ std::ofstream fout ("test.txt");
+ fout.imbue (the_out_locale);
+ boost::archive::text_oarchive toar (fout, boost::archive::no_codecvt);
+
+ toar & f0;
+ toar & f1;
+ toar & f2;
+ toar & f3;
+ std::clog << "Done." << std::endl;
+ }
+
+ {
+ std::clog << "Deserialize (boost text archive)..." << std::endl;
+ std::locale the_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ std::ifstream fin ("test.txt");
+ fin.imbue (the_in_locale);
+ boost::archive::text_iarchive tiar (fin, boost::archive::no_codecvt);
+ foo f0, f1, f2, f3;
+
+ tiar & f0;
+ tiar & f1;
+ tiar & f2;
+ tiar & f3;
+
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::clog << "Done." << std::endl;
+ }
+
+ {
+ std::clog << "Serialize (boost XML archive)..." << std::endl;
+ foo f0;
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::locale the_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ std::ofstream fout ("test.xml");
+ fout.imbue (the_out_locale);
+ boost::archive::xml_oarchive xoar (fout, boost::archive::no_codecvt);
+
+ xoar & BOOST_SERIALIZATION_NVP (f0);
+ xoar & BOOST_SERIALIZATION_NVP (f1);
+ xoar & BOOST_SERIALIZATION_NVP (f2);
+ xoar & BOOST_SERIALIZATION_NVP (f3);
+ std::clog << "Done." << std::endl;
+ }
+
+ {
+ std::clog << "Deserialize (boost XML archive)..." << std::endl;
+ std::locale the_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ std::ifstream fin ("test.xml");
+ fin.imbue (the_in_locale);
+ boost::archive::xml_iarchive xiar (fin, boost::archive::no_codecvt);
+ foo f0, f1, f2, f3;
+
+ xiar & BOOST_SERIALIZATION_NVP (f0);
+ xiar & BOOST_SERIALIZATION_NVP (f1);
+ xiar & BOOST_SERIALIZATION_NVP (f2);
+ xiar & BOOST_SERIALIZATION_NVP (f3);
+
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::clog << "Done." << std::endl;
+ }
+
+ std::clog << "Bye ! " << std::endl;
+ return 0;
+}
+
+ /* end of test_nonfinite_num_facets_1.cpp */

Added: trunk/libs/math/example/nonfinite_serialization_archives.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/nonfinite_serialization_archives.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,126 @@
+/** nonfinite_serialization_archives.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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 very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' to obtain C99
+* representation of infinity and NaN.
+* From the original Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A simple example of using non_finite_num facet for
+C99 standard output of infinity and NaN in serialization archives.
+
+\detail This example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allow output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+This is particularly useful when used with Boost.Seralization so that non-finite NaNs and infinity
+values in text and xml archives can be handled correctly and portably.
+
+*/
+
+
+#ifdef MSC_VER
+# pragma warning (disable :4224)
+#endif
+
+#include <boost/archive/text_oarchive.hpp>
+using boost::archive::text_oarchive;
+#include <boost/archive/codecvt_null.hpp>
+using boost::archive::codecvt_null;
+using boost::archive::no_codecvt;
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <fstream>
+using std::ofstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <locale>
+using std::locale;
+
+
+/*
+Use with serialization archives.
+
+It is important that the same locale is used
+when an archive is saved and when it is loaded.
+Otherwise, loading the archive may fail.
+
+By default, archives are saved and loaded with a classic C locale with a
+`boost::archive::codecvt_null` facet added.
+Normally you do not have to worry about that.
+The constructors for the archive classes, as a side-effect,
+imbue the stream with such a locale.
+
+However, if you want to use the facets `nonfinite_num_put` and `nonfinite_num_get`
+with archives,`then you have to manage the locale manually.
+
+That is done by calling the archive constructor with the flag `boost::archive::no_codecvt`.
+Then the archive constructor will not imbue the stream with a new locale.
+
+The following code shows how to use `nonfinite_num_put` with a `text_oarchive`:
+
+*/
+
+int main()
+{
+
+ locale default_locale(locale::classic(), new boost::archive::codecvt_null<char>);
+ // codecvt_null so the archive constructor will not imbue the stream with a new locale.
+
+ locale my_locale(default_locale, new nonfinite_num_put<char>);
+ // Add nonfinite_num_put facet to locale.
+
+ ofstream ofs("test.txt");
+ ofs.imbue(my_locale);
+
+ boost::archive::text_oarchive oa(ofs, no_codecvt);
+
+ double x = numeric_limits<double>::infinity();
+ oa & x;
+
+
+} // int main()
+
+
+/* The same method works with nonfinite_num_get and text_iarchive.
+
+If you use the trap_infinity and trap_nan flags with a serialization archive,
+then you must set the exception mask of the stream.
+Serialization archives do not check the stream state.
+
+
+u
+
+
+*/
\ No newline at end of file

Added: trunk/libs/math/example/test_nonfinite_loopback.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/math/example/test_nonfinite_loopback.cpp 2011-04-15 10:42:50 EDT (Fri, 15 Apr 2011)
@@ -0,0 +1,97 @@
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Basic tests of native nonfinite loopback.
+
+\detail Basic loopback test outputs using the platforms built-in facets
+and reads back in, and checks if loopback OK.
+
+Using MSVC this doesn't work OK:
+input produces just "1" instead of "1.#QNAN", 1.#SNAN" or 1.#IND"!
+
+*/
+
+#include <iostream>
+using std::cout;
+using std::endl;
+#include <locale>
+using std::locale;
+#include <string>
+using std::string;
+#include <sstream>
+ using std::stringstream;
+#include <limits>
+using std::numeric_limits;
+
+int main()
+{
+ locale default_locale; // Current global locale.
+ // Try to use the default locale first.
+ // On MSVC this doesn't work.
+
+ { // Try infinity.
+ stringstream ss; // Both input and output.
+ ss.imbue(default_locale); // Redundant, of course.
+ string infs;
+ if(numeric_limits<double>::has_infinity)
+ { // Make sure infinity is specialised for type double.
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Output infinity.
+ infs = ss.str(); //
+ }
+ else
+ { // Need to provide a suitable string for infinity.
+ infs = "1.#INF"; // Might suit MSVC?
+ ss << infs;
+ }
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "infinity output was " << infs << endl; // "1.#INF"
+ cout << "infinity input was " << r << endl; // "1"
+ }
+
+ { // Try Quiet NaN
+ stringstream ss; // Both input and output.
+ ss.imbue(default_locale); // Redundant, of course.
+ string infs;
+ if(numeric_limits<double>::has_quiet_NaN)
+ { // Make sure quiet NaN is specialised for type double.
+ double qnan = numeric_limits<double>::quiet_NaN();
+ ss << qnan; // Output quiet_NaN.
+ infs = ss.str(); //
+ }
+ else
+ { // Need to provide a suitable string for quiet_NAN.
+ infs = "1.#QNAN";
+ ss << infs;
+ }
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "quiet_NaN output was " << infs << endl; // "1.#QNAN"
+ cout << "quiet_NaN input was " << r << endl; // "1#"
+ }
+
+
+} // int main()
+
+/*
+
+Output (MSVC Version 10.0):
+
+
+ infinity output was 1.#INF
+ infinity input was 1
+ quiet_NaN output was 1.#QNAN
+ quiet_NaN input was 1
+
+
+*/
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk