| 1 | 22a23,40
|
|---|
| 2 | > //
|
|---|
| 3 | > // Jan 2014: Added try_lexical_cast, by Troy Korjuslommi.
|
|---|
| 4 | >
|
|---|
| 5 | > /**
|
|---|
| 6 | > * try_lexical_cast: A version which doesn't throw bad_lexical_cast.
|
|---|
| 7 | > * All other exceptions will be thrown as normal.
|
|---|
| 8 | > *
|
|---|
| 9 | > * Getting rid of exceptions thrown in the callbacks nothrow_overflow_handler and detect_precision_loss
|
|---|
| 10 | > * would mean rewriting boost::numeric::converter, which seems excessive, and futile. And it would create
|
|---|
| 11 | > * a dependency on those patches going through for this patch to be accepted. Ergo, I resorted to catching
|
|---|
| 12 | > * these exceptions to provide non throwing behavior.
|
|---|
| 13 | > *
|
|---|
| 14 | > * Dropped the deprecated call-by-value fallback version
|
|---|
| 15 | > * template<typename Target, typename Source>
|
|---|
| 16 | > * bool bool try_lexical_cast(Target& result, Source arg);
|
|---|
| 17 | > */
|
|---|
| 18 | >
|
|---|
| 19 | >
|
|---|
| 20 | 2378a2397,2423
|
|---|
| 21 | >
|
|---|
| 22 | >
|
|---|
| 23 | > static inline bool try_lexical_cast_impl(Target& result, const Source& arg)
|
|---|
| 24 | > {
|
|---|
| 25 | > typedef lexical_cast_stream_traits<Source, Target> stream_trait;
|
|---|
| 26 | >
|
|---|
| 27 | > typedef detail::lexical_stream_limited_src<
|
|---|
| 28 | > BOOST_DEDUCED_TYPENAME stream_trait::char_type,
|
|---|
| 29 | > BOOST_DEDUCED_TYPENAME stream_trait::traits,
|
|---|
| 30 | > stream_trait::requires_stringbuf
|
|---|
| 31 | > > interpreter_type;
|
|---|
| 32 | >
|
|---|
| 33 | > // Target type must be default constructible
|
|---|
| 34 | > // Target result;
|
|---|
| 35 | >
|
|---|
| 36 | > BOOST_DEDUCED_TYPENAME stream_trait::char_type buf[stream_trait::len_t::value + 1];
|
|---|
| 37 | > stream_trait::len_t::check_coverage();
|
|---|
| 38 | >
|
|---|
| 39 | > interpreter_type interpreter(buf, buf + stream_trait::len_t::value + 1);
|
|---|
| 40 | >
|
|---|
| 41 | > // Disabling ADL, by directly specifying operators.
|
|---|
| 42 | > if(!(interpreter.operator <<(arg) && interpreter.operator >>(result)))
|
|---|
| 43 | > return false;
|
|---|
| 44 | >
|
|---|
| 45 | > return true;
|
|---|
| 46 | > }
|
|---|
| 47 | >
|
|---|
| 48 | 2442a2488,2508
|
|---|
| 49 | >
|
|---|
| 50 | > static inline bool try_lexical_cast_impl(Target& result, const Source &arg)
|
|---|
| 51 | > {
|
|---|
| 52 | > try {
|
|---|
| 53 | > result = boost::numeric::converter<
|
|---|
| 54 | > Target,
|
|---|
| 55 | > Source,
|
|---|
| 56 | > boost::numeric::conversion_traits<Target,Source>,
|
|---|
| 57 | > nothrow_overflow_handler<Source, Target>,
|
|---|
| 58 | > detect_precision_loss<Source, Target>
|
|---|
| 59 | > >::convert(arg);
|
|---|
| 60 | > return true;
|
|---|
| 61 | >
|
|---|
| 62 | > } catch (const bad_lexical_cast& ex) {
|
|---|
| 63 | > return false;
|
|---|
| 64 | > }
|
|---|
| 65 | > catch (...) {
|
|---|
| 66 | > throw;
|
|---|
| 67 | > }
|
|---|
| 68 | > }
|
|---|
| 69 | >
|
|---|
| 70 | 2467a2534,2563
|
|---|
| 71 | >
|
|---|
| 72 | > static inline bool try_lexical_cast_impl(Target& result, const Source &arg)
|
|---|
| 73 | > {
|
|---|
| 74 | > typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if_c<
|
|---|
| 75 | > boost::is_float<Source>::value,
|
|---|
| 76 | > boost::mpl::identity<Source>,
|
|---|
| 77 | > boost::make_unsigned<Source>
|
|---|
| 78 | > >::type usource_t;
|
|---|
| 79 | >
|
|---|
| 80 | > typedef boost::numeric::converter<
|
|---|
| 81 | > Target,
|
|---|
| 82 | > usource_t,
|
|---|
| 83 | > boost::numeric::conversion_traits<Target,usource_t>,
|
|---|
| 84 | > nothrow_overflow_handler<usource_t, Target>,
|
|---|
| 85 | > detect_precision_loss<usource_t, Target>
|
|---|
| 86 | > > converter_t;
|
|---|
| 87 | >
|
|---|
| 88 | > try {
|
|---|
| 89 | > result = (
|
|---|
| 90 | > arg < 0 ? static_cast<Target>(0u - converter_t::convert(0u - arg)) : converter_t::convert(arg)
|
|---|
| 91 | > );
|
|---|
| 92 | > return true;
|
|---|
| 93 | > } catch (const bad_lexical_cast& ex) {
|
|---|
| 94 | > return false;
|
|---|
| 95 | > }
|
|---|
| 96 | > catch (...) {
|
|---|
| 97 | > throw;
|
|---|
| 98 | > }
|
|---|
| 99 | > }
|
|---|
| 100 | >
|
|---|
| 101 | 2512a2609,2632
|
|---|
| 102 | >
|
|---|
| 103 | > static inline bool try_lexical_cast_impl(Target& result, const Source &arg)
|
|---|
| 104 | > {
|
|---|
| 105 | > typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
|
|---|
| 106 | > boost::type_traits::ice_and<
|
|---|
| 107 | > boost::type_traits::ice_or<
|
|---|
| 108 | > boost::is_signed<Source>::value,
|
|---|
| 109 | > boost::is_float<Source>::value
|
|---|
| 110 | > >::value,
|
|---|
| 111 | > boost::type_traits::ice_not<
|
|---|
| 112 | > boost::is_same<Source, bool>::value
|
|---|
| 113 | > >::value,
|
|---|
| 114 | > boost::type_traits::ice_not<
|
|---|
| 115 | > boost::is_same<Target, bool>::value
|
|---|
| 116 | > >::value,
|
|---|
| 117 | > boost::is_unsigned<Target>::value
|
|---|
| 118 | > >::value,
|
|---|
| 119 | > lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
|
|---|
| 120 | > lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
|
|---|
| 121 | > >::type caster_type;
|
|---|
| 122 | >
|
|---|
| 123 | > return caster_type::try_lexical_cast_impl(result, arg);
|
|---|
| 124 | > }
|
|---|
| 125 | >
|
|---|
| 126 | 2735a2856,2951
|
|---|
| 127 | >
|
|---|
| 128 | >
|
|---|
| 129 | > #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) && !defined(__PGIC__)
|
|---|
| 130 | >
|
|---|
| 131 | > namespace boost
|
|---|
| 132 | > {
|
|---|
| 133 | >
|
|---|
| 134 | > template <typename Target, typename Source>
|
|---|
| 135 | > inline bool try_lexical_cast(Target& result, const Source &arg)
|
|---|
| 136 | > {
|
|---|
| 137 | > typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
|
|---|
| 138 | >
|
|---|
| 139 | > typedef BOOST_DEDUCED_TYPENAME boost::type_traits::ice_or<
|
|---|
| 140 | > boost::detail::is_xchar_to_xchar<Target, src >::value,
|
|---|
| 141 | > boost::detail::is_char_array_to_stdstring<Target, src >::value,
|
|---|
| 142 | > boost::type_traits::ice_and<
|
|---|
| 143 | > boost::is_same<Target, src >::value,
|
|---|
| 144 | > boost::detail::is_stdstring<Target >::value
|
|---|
| 145 | > >::value
|
|---|
| 146 | > > shall_we_copy_t;
|
|---|
| 147 | >
|
|---|
| 148 | > typedef BOOST_DEDUCED_TYPENAME
|
|---|
| 149 | > boost::detail::is_arithmetic_and_not_xchars<Target, src > shall_we_copy_with_dynamic_check_t;
|
|---|
| 150 | >
|
|---|
| 151 | > typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
|
|---|
| 152 | > shall_we_copy_t::value,
|
|---|
| 153 | > boost::detail::lexical_cast_copy<src >,
|
|---|
| 154 | > BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
|
|---|
| 155 | > shall_we_copy_with_dynamic_check_t::value,
|
|---|
| 156 | > boost::detail::lexical_cast_dynamic_num<Target, src >,
|
|---|
| 157 | > boost::detail::lexical_cast_do_cast<Target, src >
|
|---|
| 158 | > >::type
|
|---|
| 159 | > >::type caster_type;
|
|---|
| 160 | >
|
|---|
| 161 | > return caster_type::try_lexical_cast_impl(result, arg);
|
|---|
| 162 | > }
|
|---|
| 163 | >
|
|---|
| 164 | > template <typename Target>
|
|---|
| 165 | > inline bool try_lexical_cast(Target& result, const char* chars, std::size_t count)
|
|---|
| 166 | > {
|
|---|
| 167 | > return ::boost::try_lexical_cast<Target>(result,
|
|---|
| 168 | > ::boost::iterator_range<const char*>(chars, chars + count)
|
|---|
| 169 | > );
|
|---|
| 170 | > }
|
|---|
| 171 | >
|
|---|
| 172 | >
|
|---|
| 173 | > template <typename Target>
|
|---|
| 174 | > inline bool try_lexical_cast(Target& result, const unsigned char* chars, std::size_t count)
|
|---|
| 175 | > {
|
|---|
| 176 | > return ::boost::try_lexical_cast<Target>(result,
|
|---|
| 177 | > ::boost::iterator_range<const unsigned char*>(chars, chars + count)
|
|---|
| 178 | > );
|
|---|
| 179 | > }
|
|---|
| 180 | >
|
|---|
| 181 | > template <typename Target>
|
|---|
| 182 | > inline bool try_lexical_cast(Target& result, const signed char* chars, std::size_t count)
|
|---|
| 183 | > {
|
|---|
| 184 | > return ::boost::try_lexical_cast<Target>(result,
|
|---|
| 185 | > ::boost::iterator_range<const signed char*>(chars, chars + count)
|
|---|
| 186 | > );
|
|---|
| 187 | > }
|
|---|
| 188 | >
|
|---|
| 189 | > #ifndef BOOST_LCAST_NO_WCHAR_T
|
|---|
| 190 | > template <typename Target>
|
|---|
| 191 | > inline bool try_lexical_cast(Target& result, const wchar_t* chars, std::size_t count)
|
|---|
| 192 | > {
|
|---|
| 193 | > return ::boost::try_lexical_cast<Target>(result,
|
|---|
| 194 | > ::boost::iterator_range<const wchar_t*>(chars, chars + count)
|
|---|
| 195 | > );
|
|---|
| 196 | > }
|
|---|
| 197 | > #endif
|
|---|
| 198 | > #ifndef BOOST_NO_CXX11_CHAR16_T
|
|---|
| 199 | > template <typename Target>
|
|---|
| 200 | > inline bool try_lexical_cast(Target& result, const char16_t* chars, std::size_t count)
|
|---|
| 201 | > {
|
|---|
| 202 | > return ::boost::try_lexical_cast<Target>(result,
|
|---|
| 203 | > ::boost::iterator_range<const char16_t*>(chars, chars + count)
|
|---|
| 204 | > );
|
|---|
| 205 | > }
|
|---|
| 206 | > #endif
|
|---|
| 207 | > #ifndef BOOST_NO_CXX11_CHAR32_T
|
|---|
| 208 | > template <typename Target>
|
|---|
| 209 | > inline bool try_lexical_cast(Target& result, const char32_t* chars, std::size_t count)
|
|---|
| 210 | > {
|
|---|
| 211 | > return ::boost::try_lexical_cast<Target>(result,
|
|---|
| 212 | > ::boost::iterator_range<const char32_t*>(chars, chars + count)
|
|---|
| 213 | > );
|
|---|
| 214 | > }
|
|---|
| 215 | > #endif
|
|---|
| 216 | >
|
|---|
| 217 | > } // namespace boost
|
|---|
| 218 | >
|
|---|
| 219 | > #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|---|
| 220 | >
|
|---|
| 221 | >
|
|---|
| 222 | >
|
|---|
| 223 | 2738a2955
|
|---|
| 224 | > // Copyright Troy Korjuslommi, 2014.
|
|---|