1 // Copyright (c) 2006 Johan Rade 2 // Copyright (c) 2011 Paul A. Bristow - filename changes for boost-trunk. 3 4 // Distributed under the Boost Software License, Version 1.0. 5 // (See accompanying file LICENSE_1_0.txt 6 // or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 //#ifdef _MSC_VER 9 //# pragma warning(disable : 4511 4512 4702) 10 //#endif 11 12 #define BOOST_TEST_MAIN 13 14 #include <limits> 15 #include <locale> 16 #include <sstream> 17 18 #include <boost/archive/text_iarchive.hpp> 19 #include <boost/archive/text_oarchive.hpp> 20 #include <boost/archive/text_wiarchive.hpp> 21 #include <boost/archive/text_woarchive.hpp> 22 #include <boost/archive/codecvt_null.hpp> 23 #include <boost/test/unit_test.hpp> 24 #include <boost/math/special_functions/nonfinite_num_facets.hpp> 25 #include <boost/math/special_functions/sign.hpp> 26 #include <boost/math/special_functions/fpclassify.hpp> 27 28 #include "almost_equal.ipp" 29 30 namespace { 31 32 // The anonymous namespace resolves ambiguities on platforms 33 // with fpclassify etc functions at global scope. 34 35 using namespace boost::archive; 36 37 using namespace boost::math; 38 using boost::math::signbit; 39 using boost::math::changesign; 40 using (boost::math::isnan)(; 41 42 //------------------------------------------------------------------------------ 43 44 void archive_basic_test(); 45 void archive_put_trap_test(); 46 void archive_get_trap_test(); 47 48 BOOST_AUTO_TEST_CASE(archive_test) 49 { 50 archive_basic_test(); 51 archive_put_trap_test(); 52 archive_get_trap_test(); 53 } 54 55 //------------------------------------------------------------------------------ 56 57 template<class CharType, class OArchiveType, class IArchiveType, class ValType> 58 void archive_basic_test_impl(); 59 60 void archive_basic_test() 61 { 62 archive_basic_test_impl<char, text_oarchive, text_iarchive, float>(); 63 archive_basic_test_impl<char, text_oarchive, text_iarchive, double>(); 64 archive_basic_test_impl< 65 char, text_oarchive, text_iarchive, long double>(); 66 archive_basic_test_impl< 67 wchar_t, text_woarchive, text_wiarchive, float>(); 68 archive_basic_test_impl< 69 wchar_t, text_woarchive, text_wiarchive, double>(); 70 archive_basic_test_impl< 71 wchar_t, text_woarchive, text_wiarchive, long double>(); 72 } 73 74 template<class CharType, class OArchiveType, class IArchiveType, class ValType> 75 void archive_basic_test_impl() 76 { 77 if((std::numeric_limits<ValType>::has_infinity == 0) || (std::numeric_limits<ValType>::infinity() == 0)) 78 return; 79 std::locale default_locale(std::locale::classic(), 80 new boost::archive::codecvt_null<CharType>); 81 std::locale tmp_locale(default_locale, new nonfinite_num_put<CharType>); 82 std::locale my_locale(tmp_locale, new nonfinite_num_get<CharType>); 83 84 std::basic_stringstream<CharType> ss; 85 ss.imbue(my_locale); 86 87 ValType a1 = static_cast<ValType>(0); 88 ValType a2 = static_cast<ValType>(2307.35); 89 ValType a3 = std::numeric_limits<ValType>::infinity(); 90 BOOST_CHECK((boost::math::isinf)(a3)); 91 ValType a4 = std::numeric_limits<ValType>::quiet_NaN(); 92 BOOST_CHECK(((boost::math::isnan)()(a4)); 93 ValType a5 = std::numeric_limits<ValType>::signaling_NaN(); 94 BOOST_CHECK(((boost::math::isnan)()(a5)); 95 ValType a6 = (changesign)(static_cast<ValType>(0)); 96 ValType a7 = static_cast<ValType>(-57.13); 97 ValType a8 = -std::numeric_limits<ValType>::infinity(); 98 BOOST_CHECK((boost::math::isinf)(a8)); 99 ValType a9 = -std::numeric_limits<ValType>::quiet_NaN(); 100 BOOST_CHECK(((boost::math::isnan)()(a9)); 101 ValType a10 = -std::numeric_limits<ValType>::signaling_NaN(); 102 BOOST_CHECK(((boost::math::isnan)()(a10)); 103 104 { 105 OArchiveType oa(ss, no_codecvt); 106 oa & a1 & a2 & a3 & a4 & a5 & a6 & a7 & a8 & a9 & a10; 107 } 108 109 ValType b1, b2, b3, b4, b5, b6, b7, b8, b9, b10; 110 111 { 112 IArchiveType ia(ss, no_codecvt); 113 ia & b1 & b2 & b3 & b4 & b5 & b6 & b7 & b8 & b9 & b10; 114 } 115 116 BOOST_CHECK(a1 == b1); 117 BOOST_CHECK(almost_equal(a2, b2)); 118 BOOST_CHECK(a3 == b3); 119 BOOST_CHECK((isnan)(b4)); 120 BOOST_CHECK(!(signbit)(b4)); 121 BOOST_CHECK((isnan)(b5)); 122 BOOST_CHECK(!(signbit)(b5)); 123 BOOST_CHECK(a6 == b6); 124 BOOST_CHECK(almost_equal(a7, b7)); 125 BOOST_CHECK(a8 == b8); 126 BOOST_CHECK((isnan)(b9)); 127 BOOST_CHECK((signbit)(b9)); 128 BOOST_CHECK((isnan)(b10)); 129 BOOST_CHECK((signbit)(b10)); 130 } 131 132 //------------------------------------------------------------------------------ 133 134 template<class CharType, class OArchiveType, class IArchiveType, class ValType> 135 void archive_put_trap_test_impl(); 136 137 void archive_put_trap_test() 138 { 139 archive_put_trap_test_impl<char, text_oarchive, text_iarchive, float>(); 140 archive_put_trap_test_impl<char, text_oarchive, text_iarchive, double>(); 141 archive_put_trap_test_impl< 142 char, text_oarchive, text_iarchive, long double>(); 143 archive_put_trap_test_impl< 144 wchar_t, text_woarchive, text_wiarchive, float>(); 145 archive_put_trap_test_impl< 146 wchar_t, text_woarchive, text_wiarchive, double>(); 147 archive_put_trap_test_impl< 148 wchar_t, text_woarchive, text_wiarchive, long double>(); 149 } 150 151 template<class CharType, class OArchiveType, class IArchiveType, class ValType> 152 void archive_put_trap_test_impl() 153 { 154 if((std::numeric_limits<ValType>::has_infinity == 0) || (std::numeric_limits<ValType>::infinity() == 0)) 155 return; 156 157 std::locale default_locale(std::locale::classic(), 158 new boost::archive::codecvt_null<CharType>); 159 std::locale new_locale(default_locale, 160 new nonfinite_num_put<CharType>(trap_infinity)); 161 162 std::basic_stringstream<CharType> ss; 163 ss.exceptions(std::ios_base::failbit | std::ios_base::badbit); 164 ss.imbue(new_locale); 165 166 ValType a = std::numeric_limits<ValType>::infinity(); 167 168 OArchiveType oa(ss, no_codecvt); 169 170 try { 171 oa & a; 172 } 173 catch(std::exception&) { 174 ss.clear(); 175 return; 176 } 177 178 BOOST_CHECK(false); 179 } 180 181 //------------------------------------------------------------------------------ 182 183 template<class CharType, class OArchiveType, class IArchiveType, class ValType> 184 void archive_get_trap_test_impl(); 185 186 void archive_get_trap_test() 187 { 188 archive_get_trap_test_impl<char, text_oarchive, text_iarchive, float>(); 189 archive_get_trap_test_impl<char, text_oarchive, text_iarchive, double>(); 190 archive_get_trap_test_impl< 191 char, text_oarchive, text_iarchive, long double>(); 192 archive_get_trap_test_impl< 193 wchar_t, text_woarchive, text_wiarchive, float>(); 194 archive_get_trap_test_impl< 195 wchar_t, text_woarchive, text_wiarchive, double>(); 196 archive_get_trap_test_impl< 197 wchar_t, text_woarchive, text_wiarchive, long double>(); 198 } 199 200 template<class CharType, class OArchiveType, class IArchiveType, class ValType> 201 void archive_get_trap_test_impl() 202 { 203 if((std::numeric_limits<ValType>::has_infinity == 0) || (std::numeric_limits<ValType>::infinity() == 0)) 204 return; 205 206 std::locale default_locale(std::locale::classic(), 207 new boost::archive::codecvt_null<CharType>); 208 std::locale tmp_locale(default_locale, new nonfinite_num_put<CharType>); 209 std::locale my_locale(tmp_locale, 210 new nonfinite_num_get<CharType>(trap_nan)); 211 212 std::basic_stringstream<CharType> ss; 213 ss.exceptions(std::ios_base::failbit); 214 ss.imbue(my_locale); 215 216 ValType a = -std::numeric_limits<ValType>::quiet_NaN(); 217 218 { 219 OArchiveType oa(ss, no_codecvt); 220 oa & a; 221 } 222 223 ValType b; 224 { 225 IArchiveType ia(ss, no_codecvt); 226 try { 227 ia & b; 228 } 229 catch(std::exception&) { 230 return; 231 } 232 } 233 234 BOOST_CHECK(false); 235 } 236 237 //------------------------------------------------------------------------------ 238 239 } // anonymous namespace 240