Ticket #6700: boost_1_55_0_lexical_cast_hpp.patch

File boost_1_55_0_lexical_cast_hpp.patch, 8.5 KB (added by Troy Korjuslommi <troykor@…>, 9 years ago)

Patch to add try_lexical_cast function. Patch is against boost_1_55_0 lexical_cast.hpp.

Line 
122a23,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>
202378a2397,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>
482442a2488,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>
702467a2534,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>
1012512a2609,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>
1262735a2856,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>
2232738a2955
224> // Copyright Troy Korjuslommi, 2014.