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.
|
---|