lexical_cast.hpp 106 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748
  1. #ifndef BOOST_LEXICAL_CAST_INCLUDED
  2. #define BOOST_LEXICAL_CAST_INCLUDED
  3. // MS compatible compilers support #pragma once
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. // Boost lexical_cast.hpp header -------------------------------------------//
  8. //
  9. // See http://www.boost.org/libs/conversion for documentation.
  10. // See end of this header for rights and permissions.
  11. //
  12. // what: lexical_cast custom keyword cast
  13. // who: contributed by Kevlin Henney,
  14. // enhanced with contributions from Terje Slettebo,
  15. // with additional fixes and suggestions from Gennaro Prota,
  16. // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
  17. // Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
  18. // Cheng Yang, Matthew Bradbury, David W. Birdsall, Pavel Korzh and other Boosters
  19. // when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2013
  20. #include <boost/config.hpp>
  21. #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
  22. #define BOOST_LCAST_NO_WCHAR_T
  23. #endif
  24. #include <climits>
  25. #include <cstddef>
  26. #include <string>
  27. #include <cstring>
  28. #include <cstdio>
  29. #include <typeinfo>
  30. #include <exception>
  31. #include <boost/limits.hpp>
  32. #include <boost/mpl/if.hpp>
  33. #include <boost/throw_exception.hpp>
  34. #include <boost/type_traits/ice.hpp>
  35. #include <boost/type_traits/is_pointer.hpp>
  36. #include <boost/static_assert.hpp>
  37. #include <boost/detail/lcast_precision.hpp>
  38. #include <boost/detail/workaround.hpp>
  39. #ifndef BOOST_NO_STD_LOCALE
  40. # include <locale>
  41. #else
  42. # ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  43. // Getting error at this point means, that your STL library is old/lame/misconfigured.
  44. // If nothing can be done with STL library, define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE,
  45. // but beware: lexical_cast will understand only 'C' locale delimeters and thousands
  46. // separators.
  47. # error "Unable to use <locale> header. Define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE to force "
  48. # error "boost::lexical_cast to use only 'C' locale during conversions."
  49. # endif
  50. #endif
  51. #ifdef BOOST_NO_STRINGSTREAM
  52. #include <strstream>
  53. #else
  54. #include <sstream>
  55. #endif
  56. #ifdef BOOST_NO_TYPEID
  57. #define BOOST_LCAST_THROW_BAD_CAST(S, T) throw_exception(bad_lexical_cast())
  58. #else
  59. #define BOOST_LCAST_THROW_BAD_CAST(Source, Target) \
  60. throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)))
  61. #endif
  62. namespace boost
  63. {
  64. // exception used to indicate runtime lexical_cast failure
  65. class BOOST_SYMBOL_VISIBLE bad_lexical_cast :
  66. // workaround MSVC bug with std::bad_cast when _HAS_EXCEPTIONS == 0
  67. #if defined(BOOST_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
  68. public std::exception
  69. #else
  70. public std::bad_cast
  71. #endif
  72. #if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )
  73. // under bcc32 5.5.1 bad_cast doesn't derive from exception
  74. , public std::exception
  75. #endif
  76. {
  77. public:
  78. bad_lexical_cast() BOOST_NOEXCEPT :
  79. #ifndef BOOST_NO_TYPEID
  80. source(&typeid(void)), target(&typeid(void))
  81. #else
  82. source(0), target(0) // this breaks getters
  83. #endif
  84. {
  85. }
  86. bad_lexical_cast(
  87. const std::type_info &source_type_arg,
  88. const std::type_info &target_type_arg) BOOST_NOEXCEPT :
  89. source(&source_type_arg), target(&target_type_arg)
  90. {
  91. }
  92. const std::type_info &source_type() const
  93. {
  94. return *source;
  95. }
  96. const std::type_info &target_type() const
  97. {
  98. return *target;
  99. }
  100. #ifndef BOOST_NO_CXX11_NOEXCEPT
  101. virtual const char *what() const noexcept
  102. #else
  103. virtual const char *what() const throw()
  104. #endif
  105. {
  106. return "bad lexical cast: "
  107. "source type value could not be interpreted as target";
  108. }
  109. #ifndef BOOST_NO_CXX11_NOEXCEPT
  110. virtual ~bad_lexical_cast() BOOST_NOEXCEPT
  111. #else
  112. virtual ~bad_lexical_cast() throw()
  113. #endif
  114. {}
  115. private:
  116. const std::type_info *source;
  117. const std::type_info *target;
  118. };
  119. namespace detail // widest_char
  120. {
  121. template <typename TargetChar, typename SourceChar>
  122. struct widest_char
  123. {
  124. typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  125. (sizeof(TargetChar) > sizeof(SourceChar))
  126. , TargetChar
  127. , SourceChar >::type type;
  128. };
  129. }
  130. } // namespace boost
  131. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC) && !defined(__PGIC__)
  132. #include <cmath>
  133. #include <istream>
  134. #ifndef BOOST_NO_CXX11_HDR_ARRAY
  135. #include <array>
  136. #endif
  137. #include <boost/array.hpp>
  138. #include <boost/numeric/conversion/cast.hpp>
  139. #include <boost/type_traits/make_unsigned.hpp>
  140. #include <boost/type_traits/is_signed.hpp>
  141. #include <boost/type_traits/is_integral.hpp>
  142. #include <boost/type_traits/is_arithmetic.hpp>
  143. #include <boost/type_traits/remove_pointer.hpp>
  144. #include <boost/type_traits/has_left_shift.hpp>
  145. #include <boost/type_traits/has_right_shift.hpp>
  146. #include <boost/math/special_functions/sign.hpp>
  147. #include <boost/math/special_functions/fpclassify.hpp>
  148. #include <boost/range/iterator_range_core.hpp>
  149. #include <boost/container/container_fwd.hpp>
  150. #include <boost/integer.hpp>
  151. #ifndef BOOST_NO_CWCHAR
  152. # include <cwchar>
  153. #endif
  154. namespace boost {
  155. namespace detail // is_char_or_wchar<...>
  156. {
  157. // returns true, if T is one of the character types
  158. template < typename T >
  159. struct is_char_or_wchar
  160. {
  161. typedef boost::type_traits::ice_or<
  162. boost::is_same< T, char >::value,
  163. #ifndef BOOST_LCAST_NO_WCHAR_T
  164. boost::is_same< T, wchar_t >::value,
  165. #endif
  166. #ifndef BOOST_NO_CXX11_CHAR16_T
  167. boost::is_same< T, char16_t >::value,
  168. #endif
  169. #ifndef BOOST_NO_CXX11_CHAR32_T
  170. boost::is_same< T, char32_t >::value,
  171. #endif
  172. boost::is_same< T, unsigned char >::value,
  173. boost::is_same< T, signed char >::value
  174. > result_type;
  175. BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
  176. };
  177. }
  178. namespace detail // normalize_single_byte_char<Char>
  179. {
  180. // Converts signed/unsigned char to char
  181. template < class Char >
  182. struct normalize_single_byte_char
  183. {
  184. typedef Char type;
  185. };
  186. template <>
  187. struct normalize_single_byte_char< signed char >
  188. {
  189. typedef char type;
  190. };
  191. template <>
  192. struct normalize_single_byte_char< unsigned char >
  193. {
  194. typedef char type;
  195. };
  196. }
  197. namespace detail // deduce_character_type_later<T>
  198. {
  199. // Helper type, meaning that stram character for T must be deduced
  200. // at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
  201. template < class T > struct deduce_character_type_later {};
  202. }
  203. namespace detail // stream_char_common<T>
  204. {
  205. // Selectors to choose stream character type (common for Source and Target)
  206. // Returns one of char, wchar_t, char16_t, char32_t or deduce_character_type_later<T> types
  207. // Executed on Stage 1 (See deduce_source_char<T> and deduce_target_char<T>)
  208. template < typename Type >
  209. struct stream_char_common: public boost::mpl::if_c<
  210. boost::detail::is_char_or_wchar< Type >::value,
  211. Type,
  212. boost::detail::deduce_character_type_later< Type >
  213. > {};
  214. template < typename Char >
  215. struct stream_char_common< Char* >: public boost::mpl::if_c<
  216. boost::detail::is_char_or_wchar< Char >::value,
  217. Char,
  218. boost::detail::deduce_character_type_later< Char* >
  219. > {};
  220. template < typename Char >
  221. struct stream_char_common< const Char* >: public boost::mpl::if_c<
  222. boost::detail::is_char_or_wchar< Char >::value,
  223. Char,
  224. boost::detail::deduce_character_type_later< const Char* >
  225. > {};
  226. template < typename Char >
  227. struct stream_char_common< boost::iterator_range< Char* > >: public boost::mpl::if_c<
  228. boost::detail::is_char_or_wchar< Char >::value,
  229. Char,
  230. boost::detail::deduce_character_type_later< boost::iterator_range< Char* > >
  231. > {};
  232. template < typename Char >
  233. struct stream_char_common< boost::iterator_range< const Char* > >: public boost::mpl::if_c<
  234. boost::detail::is_char_or_wchar< Char >::value,
  235. Char,
  236. boost::detail::deduce_character_type_later< boost::iterator_range< const Char* > >
  237. > {};
  238. template < class Char, class Traits, class Alloc >
  239. struct stream_char_common< std::basic_string< Char, Traits, Alloc > >
  240. {
  241. typedef Char type;
  242. };
  243. template < class Char, class Traits, class Alloc >
  244. struct stream_char_common< boost::container::basic_string< Char, Traits, Alloc > >
  245. {
  246. typedef Char type;
  247. };
  248. template < typename Char, std::size_t N >
  249. struct stream_char_common< boost::array< Char, N > >: public boost::mpl::if_c<
  250. boost::detail::is_char_or_wchar< Char >::value,
  251. Char,
  252. boost::detail::deduce_character_type_later< boost::array< Char, N > >
  253. > {};
  254. template < typename Char, std::size_t N >
  255. struct stream_char_common< boost::array< const Char, N > >: public boost::mpl::if_c<
  256. boost::detail::is_char_or_wchar< Char >::value,
  257. Char,
  258. boost::detail::deduce_character_type_later< boost::array< const Char, N > >
  259. > {};
  260. #ifndef BOOST_NO_CXX11_HDR_ARRAY
  261. template < typename Char, std::size_t N >
  262. struct stream_char_common< std::array<Char, N > >: public boost::mpl::if_c<
  263. boost::detail::is_char_or_wchar< Char >::value,
  264. Char,
  265. boost::detail::deduce_character_type_later< std::array< Char, N > >
  266. > {};
  267. template < typename Char, std::size_t N >
  268. struct stream_char_common< std::array< const Char, N > >: public boost::mpl::if_c<
  269. boost::detail::is_char_or_wchar< Char >::value,
  270. Char,
  271. boost::detail::deduce_character_type_later< std::array< const Char, N > >
  272. > {};
  273. #endif
  274. #ifdef BOOST_HAS_INT128
  275. template <> struct stream_char_common< boost::int128_type >: public boost::mpl::identity< char > {};
  276. template <> struct stream_char_common< boost::uint128_type >: public boost::mpl::identity< char > {};
  277. #endif
  278. #if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
  279. template <>
  280. struct stream_char_common< wchar_t >
  281. {
  282. typedef char type;
  283. };
  284. #endif
  285. }
  286. namespace detail // deduce_source_char_impl<T>
  287. {
  288. // If type T is `deduce_character_type_later` type, then tries to deduce
  289. // character type using boost::has_left_shift<T> metafunction.
  290. // Otherwise supplied type T is a character type, that must be normalized
  291. // using normalize_single_byte_char<Char>.
  292. // Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
  293. template < class Char >
  294. struct deduce_source_char_impl
  295. {
  296. typedef BOOST_DEDUCED_TYPENAME boost::detail::normalize_single_byte_char< Char >::type type;
  297. };
  298. template < class T >
  299. struct deduce_source_char_impl< deduce_character_type_later< T > >
  300. {
  301. typedef boost::has_left_shift< std::basic_ostream< char >, T > result_t;
  302. #if defined(BOOST_LCAST_NO_WCHAR_T)
  303. BOOST_STATIC_ASSERT_MSG((result_t::value),
  304. "Source type is not std::ostream`able and std::wostream`s are not supported by your STL implementation");
  305. typedef char type;
  306. #else
  307. typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  308. result_t::value, char, wchar_t
  309. >::type type;
  310. BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_left_shift< std::basic_ostream< type >, T >::value),
  311. "Source type is neither std::ostream`able nor std::wostream`able");
  312. #endif
  313. };
  314. }
  315. namespace detail // deduce_target_char_impl<T>
  316. {
  317. // If type T is `deduce_character_type_later` type, then tries to deduce
  318. // character type using boost::has_right_shift<T> metafunction.
  319. // Otherwise supplied type T is a character type, that must be normalized
  320. // using normalize_single_byte_char<Char>.
  321. // Executed at Stage 2 (See deduce_source_char<T> and deduce_target_char<T>)
  322. template < class Char >
  323. struct deduce_target_char_impl
  324. {
  325. typedef BOOST_DEDUCED_TYPENAME normalize_single_byte_char< Char >::type type;
  326. };
  327. template < class T >
  328. struct deduce_target_char_impl< deduce_character_type_later<T> >
  329. {
  330. typedef boost::has_right_shift<std::basic_istream<char>, T > result_t;
  331. #if defined(BOOST_LCAST_NO_WCHAR_T)
  332. BOOST_STATIC_ASSERT_MSG((result_t::value),
  333. "Target type is not std::istream`able and std::wistream`s are not supported by your STL implementation");
  334. typedef char type;
  335. #else
  336. typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  337. result_t::value, char, wchar_t
  338. >::type type;
  339. BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value),
  340. "Target type is neither std::istream`able nor std::wistream`able");
  341. #endif
  342. };
  343. }
  344. namespace detail // deduce_target_char<T> and deduce_source_char<T>
  345. {
  346. // We deduce stream character types in two stages.
  347. //
  348. // Stage 1 is common for Target and Source. At Stage 1 we get
  349. // non normalized character type (may contain unsigned/signed char)
  350. // or deduce_character_type_later<T> where T is the original type.
  351. // Stage 1 is executed by stream_char_common<T>
  352. //
  353. // At Stage 2 we normalize character types or try to deduce character
  354. // type using metafunctions.
  355. // Stage 2 is executed by deduce_target_char_impl<T> and
  356. // deduce_source_char_impl<T>
  357. //
  358. // deduce_target_char<T> and deduce_source_char<T> functions combine
  359. // both stages
  360. template < class T >
  361. struct deduce_target_char
  362. {
  363. typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
  364. typedef BOOST_DEDUCED_TYPENAME deduce_target_char_impl< stage1_type >::type stage2_type;
  365. typedef stage2_type type;
  366. };
  367. template < class T >
  368. struct deduce_source_char
  369. {
  370. typedef BOOST_DEDUCED_TYPENAME stream_char_common< T >::type stage1_type;
  371. typedef BOOST_DEDUCED_TYPENAME deduce_source_char_impl< stage1_type >::type stage2_type;
  372. typedef stage2_type type;
  373. };
  374. }
  375. namespace detail // deduce_char_traits template
  376. {
  377. // We are attempting to get char_traits<> from Source or Tagret
  378. // template parameter. Otherwise we'll be using std::char_traits<Char>
  379. template < class Char, class Target, class Source >
  380. struct deduce_char_traits
  381. {
  382. typedef std::char_traits< Char > type;
  383. };
  384. template < class Char, class Traits, class Alloc, class Source >
  385. struct deduce_char_traits< Char
  386. , std::basic_string< Char, Traits, Alloc >
  387. , Source
  388. >
  389. {
  390. typedef Traits type;
  391. };
  392. template < class Char, class Target, class Traits, class Alloc >
  393. struct deduce_char_traits< Char
  394. , Target
  395. , std::basic_string< Char, Traits, Alloc >
  396. >
  397. {
  398. typedef Traits type;
  399. };
  400. template < class Char, class Traits, class Alloc, class Source >
  401. struct deduce_char_traits< Char
  402. , boost::container::basic_string< Char, Traits, Alloc >
  403. , Source
  404. >
  405. {
  406. typedef Traits type;
  407. };
  408. template < class Char, class Target, class Traits, class Alloc >
  409. struct deduce_char_traits< Char
  410. , Target
  411. , boost::container::basic_string< Char, Traits, Alloc >
  412. >
  413. {
  414. typedef Traits type;
  415. };
  416. template < class Char, class Traits, class Alloc1, class Alloc2 >
  417. struct deduce_char_traits< Char
  418. , std::basic_string< Char, Traits, Alloc1 >
  419. , std::basic_string< Char, Traits, Alloc2 >
  420. >
  421. {
  422. typedef Traits type;
  423. };
  424. template<class Char, class Traits, class Alloc1, class Alloc2>
  425. struct deduce_char_traits< Char
  426. , boost::container::basic_string< Char, Traits, Alloc1 >
  427. , boost::container::basic_string< Char, Traits, Alloc2 >
  428. >
  429. {
  430. typedef Traits type;
  431. };
  432. template < class Char, class Traits, class Alloc1, class Alloc2 >
  433. struct deduce_char_traits< Char
  434. , boost::container::basic_string< Char, Traits, Alloc1 >
  435. , std::basic_string< Char, Traits, Alloc2 >
  436. >
  437. {
  438. typedef Traits type;
  439. };
  440. template < class Char, class Traits, class Alloc1, class Alloc2 >
  441. struct deduce_char_traits< Char
  442. , std::basic_string< Char, Traits, Alloc1 >
  443. , boost::container::basic_string< Char, Traits, Alloc2 >
  444. >
  445. {
  446. typedef Traits type;
  447. };
  448. }
  449. namespace detail // array_to_pointer_decay<T>
  450. {
  451. template<class T>
  452. struct array_to_pointer_decay
  453. {
  454. typedef T type;
  455. };
  456. template<class T, std::size_t N>
  457. struct array_to_pointer_decay<T[N]>
  458. {
  459. typedef const T * type;
  460. };
  461. }
  462. namespace detail // is_this_float_conversion_optimized<Float, Char>
  463. {
  464. // this metafunction evaluates to true, if we have optimized comnversion
  465. // from Float type to Char array.
  466. // Must be in sync with lexical_stream_limited_src<Char, ...>::shl_real_type(...)
  467. template <typename Float, typename Char>
  468. struct is_this_float_conversion_optimized
  469. {
  470. typedef boost::type_traits::ice_and<
  471. boost::is_float<Float>::value,
  472. #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
  473. boost::type_traits::ice_or<
  474. boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value,
  475. boost::is_same<Char, wchar_t>::value
  476. >::value
  477. #else
  478. boost::type_traits::ice_eq<sizeof(Char), sizeof(char) >::value
  479. #endif
  480. > result_type;
  481. BOOST_STATIC_CONSTANT(bool, value = (result_type::value) );
  482. };
  483. }
  484. namespace detail // lcast_src_length
  485. {
  486. // Return max. length of string representation of Source;
  487. template< class Source // Source type of lexical_cast.
  488. >
  489. struct lcast_src_length
  490. {
  491. BOOST_STATIC_CONSTANT(std::size_t, value = 1);
  492. // To check coverage, build the test with
  493. // bjam --v2 profile optimization=off
  494. static void check_coverage() {}
  495. };
  496. // Helper for integral types.
  497. // Notes on length calculation:
  498. // Max length for 32bit int with grouping "\1" and thousands_sep ',':
  499. // "-2,1,4,7,4,8,3,6,4,7"
  500. // ^ - is_signed
  501. // ^ - 1 digit not counted by digits10
  502. // ^^^^^^^^^^^^^^^^^^ - digits10 * 2
  503. //
  504. // Constant is_specialized is used instead of constant 1
  505. // to prevent buffer overflow in a rare case when
  506. // <boost/limits.hpp> doesn't add missing specialization for
  507. // numeric_limits<T> for some integral type T.
  508. // When is_specialized is false, the whole expression is 0.
  509. template<class Source>
  510. struct lcast_src_length_integral
  511. {
  512. #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
  513. BOOST_STATIC_CONSTANT(std::size_t, value =
  514. std::numeric_limits<Source>::is_signed +
  515. std::numeric_limits<Source>::is_specialized + /* == 1 */
  516. std::numeric_limits<Source>::digits10 * 2
  517. );
  518. #else
  519. BOOST_STATIC_CONSTANT(std::size_t, value = 156);
  520. BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);
  521. #endif
  522. };
  523. #define BOOST_LCAST_DEF(T) \
  524. template<> struct lcast_src_length<T> \
  525. : lcast_src_length_integral<T> \
  526. { static void check_coverage() {} };
  527. BOOST_LCAST_DEF(short)
  528. BOOST_LCAST_DEF(unsigned short)
  529. BOOST_LCAST_DEF(int)
  530. BOOST_LCAST_DEF(unsigned int)
  531. BOOST_LCAST_DEF(long)
  532. BOOST_LCAST_DEF(unsigned long)
  533. #if defined(BOOST_HAS_LONG_LONG)
  534. BOOST_LCAST_DEF(boost::ulong_long_type)
  535. BOOST_LCAST_DEF(boost::long_long_type )
  536. #elif defined(BOOST_HAS_MS_INT64)
  537. BOOST_LCAST_DEF(unsigned __int64)
  538. BOOST_LCAST_DEF( __int64)
  539. #endif
  540. #ifdef BOOST_HAS_INT128
  541. BOOST_LCAST_DEF(boost::int128_type)
  542. BOOST_LCAST_DEF(boost::uint128_type)
  543. #endif
  544. #undef BOOST_LCAST_DEF
  545. #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
  546. // Helper for floating point types.
  547. // -1.23456789e-123456
  548. // ^ sign
  549. // ^ leading digit
  550. // ^ decimal point
  551. // ^^^^^^^^ lcast_precision<Source>::value
  552. // ^ "e"
  553. // ^ exponent sign
  554. // ^^^^^^ exponent (assumed 6 or less digits)
  555. // sign + leading digit + decimal point + "e" + exponent sign == 5
  556. template<class Source>
  557. struct lcast_src_length_floating
  558. {
  559. BOOST_STATIC_ASSERT(
  560. std::numeric_limits<Source>::max_exponent10 <= 999999L &&
  561. std::numeric_limits<Source>::min_exponent10 >= -999999L
  562. );
  563. BOOST_STATIC_CONSTANT(std::size_t, value =
  564. 5 + lcast_precision<Source>::value + 6
  565. );
  566. };
  567. template<>
  568. struct lcast_src_length<float>
  569. : lcast_src_length_floating<float>
  570. {
  571. static void check_coverage() {}
  572. };
  573. template<>
  574. struct lcast_src_length<double>
  575. : lcast_src_length_floating<double>
  576. {
  577. static void check_coverage() {}
  578. };
  579. template<>
  580. struct lcast_src_length<long double>
  581. : lcast_src_length_floating<long double>
  582. {
  583. static void check_coverage() {}
  584. };
  585. #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
  586. }
  587. namespace detail // lexical_cast_stream_traits<Source, Target>
  588. {
  589. template <class Source, class Target>
  590. struct lexical_cast_stream_traits {
  591. typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
  592. typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<src>::type no_cv_src;
  593. typedef boost::detail::deduce_source_char<no_cv_src> deduce_src_char_metafunc;
  594. typedef BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::type src_char_t;
  595. typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_target_char<Target>::type target_char_t;
  596. typedef BOOST_DEDUCED_TYPENAME boost::detail::widest_char<
  597. target_char_t, src_char_t
  598. >::type char_type;
  599. #if !defined(BOOST_NO_CXX11_CHAR16_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  600. BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char16_t, src_char_t>::value
  601. && !boost::is_same<char16_t, target_char_t>::value),
  602. "Your compiler does not have full support for char16_t" );
  603. #endif
  604. #if !defined(BOOST_NO_CXX11_CHAR32_T) && defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  605. BOOST_STATIC_ASSERT_MSG(( !boost::is_same<char32_t, src_char_t>::value
  606. && !boost::is_same<char32_t, target_char_t>::value),
  607. "Your compiler does not have full support for char32_t" );
  608. #endif
  609. typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_char_traits<
  610. char_type, Target, no_cv_src
  611. >::type traits;
  612. typedef boost::type_traits::ice_and<
  613. boost::is_same<char, src_char_t>::value, // source is not a wide character based type
  614. boost::type_traits::ice_ne<sizeof(char), sizeof(target_char_t) >::value, // target type is based on wide character
  615. boost::type_traits::ice_not<
  616. boost::detail::is_char_or_wchar<no_cv_src>::value // single character widening is optimized
  617. >::value // and does not requires stringbuffer
  618. > is_string_widening_required_t;
  619. typedef boost::type_traits::ice_not< boost::type_traits::ice_or<
  620. boost::is_integral<no_cv_src>::value,
  621. boost::detail::is_this_float_conversion_optimized<no_cv_src, char_type >::value,
  622. boost::detail::is_char_or_wchar<
  623. BOOST_DEDUCED_TYPENAME deduce_src_char_metafunc::stage1_type // if we did not get character type at stage1
  624. >::value // then we have no optimization for that type
  625. >::value > is_source_input_not_optimized_t;
  626. // If we have an optimized conversion for
  627. // Source, we do not need to construct stringbuf.
  628. BOOST_STATIC_CONSTANT(bool, requires_stringbuf =
  629. (boost::type_traits::ice_or<
  630. is_string_widening_required_t::value, is_source_input_not_optimized_t::value
  631. >::value)
  632. );
  633. typedef boost::detail::lcast_src_length<no_cv_src> len_t;
  634. };
  635. }
  636. namespace detail // '0', '+' and '-' constants
  637. {
  638. template < typename Char > struct lcast_char_constants;
  639. template<>
  640. struct lcast_char_constants<char>
  641. {
  642. BOOST_STATIC_CONSTANT(char, zero = '0');
  643. BOOST_STATIC_CONSTANT(char, minus = '-');
  644. BOOST_STATIC_CONSTANT(char, plus = '+');
  645. BOOST_STATIC_CONSTANT(char, lowercase_e = 'e');
  646. BOOST_STATIC_CONSTANT(char, capital_e = 'E');
  647. BOOST_STATIC_CONSTANT(char, c_decimal_separator = '.');
  648. };
  649. #ifndef BOOST_LCAST_NO_WCHAR_T
  650. template<>
  651. struct lcast_char_constants<wchar_t>
  652. {
  653. BOOST_STATIC_CONSTANT(wchar_t, zero = L'0');
  654. BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');
  655. BOOST_STATIC_CONSTANT(wchar_t, plus = L'+');
  656. BOOST_STATIC_CONSTANT(wchar_t, lowercase_e = L'e');
  657. BOOST_STATIC_CONSTANT(wchar_t, capital_e = L'E');
  658. BOOST_STATIC_CONSTANT(wchar_t, c_decimal_separator = L'.');
  659. };
  660. #endif
  661. #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  662. template<>
  663. struct lcast_char_constants<char16_t>
  664. {
  665. BOOST_STATIC_CONSTANT(char16_t, zero = u'0');
  666. BOOST_STATIC_CONSTANT(char16_t, minus = u'-');
  667. BOOST_STATIC_CONSTANT(char16_t, plus = u'+');
  668. BOOST_STATIC_CONSTANT(char16_t, lowercase_e = u'e');
  669. BOOST_STATIC_CONSTANT(char16_t, capital_e = u'E');
  670. BOOST_STATIC_CONSTANT(char16_t, c_decimal_separator = u'.');
  671. };
  672. #endif
  673. #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  674. template<>
  675. struct lcast_char_constants<char32_t>
  676. {
  677. BOOST_STATIC_CONSTANT(char32_t, zero = U'0');
  678. BOOST_STATIC_CONSTANT(char32_t, minus = U'-');
  679. BOOST_STATIC_CONSTANT(char32_t, plus = U'+');
  680. BOOST_STATIC_CONSTANT(char32_t, lowercase_e = U'e');
  681. BOOST_STATIC_CONSTANT(char32_t, capital_e = U'E');
  682. BOOST_STATIC_CONSTANT(char32_t, c_decimal_separator = U'.');
  683. };
  684. #endif
  685. }
  686. namespace detail // lcast_to_unsigned
  687. {
  688. template<class T>
  689. inline
  690. BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value) BOOST_NOEXCEPT
  691. {
  692. typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type result_type;
  693. return static_cast<result_type>(
  694. value < 0 ? 0u - static_cast<result_type>(value) : value
  695. );
  696. }
  697. }
  698. namespace detail // lcast_put_unsigned
  699. {
  700. template<class Traits, class T, class CharT>
  701. CharT* lcast_put_unsigned(const T n_param, CharT* finish)
  702. {
  703. #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
  704. BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
  705. #endif
  706. typedef typename Traits::int_type int_type;
  707. CharT const czero = lcast_char_constants<CharT>::zero;
  708. int_type const zero = Traits::to_int_type(czero);
  709. BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  710. (sizeof(int_type) > sizeof(T))
  711. , int_type
  712. , T
  713. >::type n = n_param;
  714. #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  715. std::locale loc;
  716. if (loc != std::locale::classic()) {
  717. typedef std::numpunct<CharT> numpunct;
  718. numpunct const& np = BOOST_USE_FACET(numpunct, loc);
  719. std::string const grouping = np.grouping();
  720. std::string::size_type const grouping_size = grouping.size();
  721. if ( grouping_size && grouping[0] > 0 )
  722. {
  723. #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
  724. // Check that ulimited group is unreachable:
  725. BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
  726. #endif
  727. CharT thousands_sep = np.thousands_sep();
  728. std::string::size_type group = 0; // current group number
  729. char last_grp_size = grouping[0];
  730. char left = last_grp_size;
  731. do
  732. {
  733. if(left == 0)
  734. {
  735. ++group;
  736. if(group < grouping_size)
  737. {
  738. char const grp_size = grouping[group];
  739. last_grp_size = grp_size <= 0 ? static_cast<char>(CHAR_MAX) : grp_size;
  740. }
  741. left = last_grp_size;
  742. --finish;
  743. Traits::assign(*finish, thousands_sep);
  744. }
  745. --left;
  746. --finish;
  747. int_type const digit = static_cast<int_type>(n % 10U);
  748. Traits::assign(*finish, Traits::to_char_type(zero + digit));
  749. n /= 10;
  750. } while(n);
  751. return finish;
  752. }
  753. }
  754. #endif
  755. {
  756. do
  757. {
  758. --finish;
  759. int_type const digit = static_cast<int_type>(n % 10U);
  760. Traits::assign(*finish, Traits::to_char_type(zero + digit));
  761. n /= 10;
  762. } while(n);
  763. }
  764. return finish;
  765. }
  766. }
  767. namespace detail // lcast_ret_unsigned
  768. {
  769. template<class Traits, class T, class CharT>
  770. inline bool lcast_ret_unsigned(T& value, const CharT* const begin, const CharT* end)
  771. {
  772. #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
  773. BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
  774. // GCC when used with flag -std=c++0x may not have std::numeric_limits
  775. // specializations for __int128 and unsigned __int128 types.
  776. // Try compilation with -std=gnu++0x or -std=gnu++11.
  777. //
  778. // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40856
  779. BOOST_STATIC_ASSERT_MSG(std::numeric_limits<T>::is_specialized,
  780. "std::numeric_limits are not specialized for integral type passed to boost::lexical_cast"
  781. );
  782. #endif
  783. CharT const czero = lcast_char_constants<CharT>::zero;
  784. --end;
  785. value = 0;
  786. if (begin > end || *end < czero || *end >= czero + 10)
  787. return false;
  788. value = static_cast<T>(*end - czero);
  789. --end;
  790. T multiplier = 1;
  791. bool multiplier_overflowed = false;
  792. #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  793. std::locale loc;
  794. if (loc != std::locale::classic()) {
  795. typedef std::numpunct<CharT> numpunct;
  796. numpunct const& np = BOOST_USE_FACET(numpunct, loc);
  797. std::string const& grouping = np.grouping();
  798. std::string::size_type const grouping_size = grouping.size();
  799. /* According to Programming languages - C++
  800. * we MUST check for correct grouping
  801. */
  802. if (grouping_size && grouping[0] > 0)
  803. {
  804. unsigned char current_grouping = 0;
  805. CharT const thousands_sep = np.thousands_sep();
  806. char remained = static_cast<char>(grouping[current_grouping] - 1);
  807. bool shall_we_return = true;
  808. for(;end>=begin; --end)
  809. {
  810. if (remained) {
  811. T const multiplier_10 = static_cast<T>(multiplier * 10);
  812. if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
  813. T const dig_value = static_cast<T>(*end - czero);
  814. T const new_sub_value = static_cast<T>(multiplier_10 * dig_value);
  815. if (*end < czero || *end >= czero + 10
  816. /* detecting overflow */
  817. || (dig_value && new_sub_value / dig_value != multiplier_10)
  818. || static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
  819. || (multiplier_overflowed && dig_value)
  820. )
  821. return false;
  822. value = static_cast<T>(value + new_sub_value);
  823. multiplier = static_cast<T>(multiplier * 10);
  824. --remained;
  825. } else {
  826. if ( !Traits::eq(*end, thousands_sep) ) //|| begin == end ) return false;
  827. {
  828. /*
  829. * According to Programming languages - C++
  830. * Digit grouping is checked. That is, the positions of discarded
  831. * separators is examined for consistency with
  832. * use_facet<numpunct<charT> >(loc ).grouping()
  833. *
  834. * BUT what if there is no separators at all and grouping()
  835. * is not empty? Well, we have no extraced separators, so we
  836. * won`t check them for consistency. This will allow us to
  837. * work with "C" locale from other locales
  838. */
  839. shall_we_return = false;
  840. break;
  841. } else {
  842. if ( begin == end ) return false;
  843. if (current_grouping < grouping_size-1 ) ++current_grouping;
  844. remained = grouping[current_grouping];
  845. }
  846. }
  847. }
  848. if (shall_we_return) return true;
  849. }
  850. }
  851. #endif
  852. {
  853. while ( begin <= end )
  854. {
  855. T const multiplier_10 = static_cast<T>(multiplier * 10);
  856. if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
  857. T const dig_value = static_cast<T>(*end - czero);
  858. T const new_sub_value = static_cast<T>(multiplier_10 * dig_value);
  859. if (*end < czero || *end >= czero + 10
  860. /* detecting overflow */
  861. || (dig_value && new_sub_value / dig_value != multiplier_10)
  862. || static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
  863. || (multiplier_overflowed && dig_value)
  864. )
  865. return false;
  866. value = static_cast<T>(value + new_sub_value);
  867. multiplier = static_cast<T>(multiplier * 10);
  868. --end;
  869. }
  870. }
  871. return true;
  872. }
  873. }
  874. namespace detail
  875. {
  876. template <class CharT>
  877. bool lc_iequal(const CharT* val, const CharT* lcase, const CharT* ucase, unsigned int len) BOOST_NOEXCEPT {
  878. for( unsigned int i=0; i < len; ++i ) {
  879. if ( val[i] != lcase[i] && val[i] != ucase[i] ) return false;
  880. }
  881. return true;
  882. }
  883. /* Returns true and sets the correct value if found NaN or Inf. */
  884. template <class CharT, class T>
  885. inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value
  886. , const CharT* lc_NAN, const CharT* lc_nan
  887. , const CharT* lc_INFINITY, const CharT* lc_infinity
  888. , const CharT opening_brace, const CharT closing_brace) BOOST_NOEXCEPT
  889. {
  890. using namespace std;
  891. if (begin == end) return false;
  892. const CharT minus = lcast_char_constants<CharT>::minus;
  893. const CharT plus = lcast_char_constants<CharT>::plus;
  894. const int inifinity_size = 8;
  895. bool has_minus = false;
  896. /* Parsing +/- */
  897. if( *begin == minus)
  898. {
  899. ++ begin;
  900. has_minus = true;
  901. }
  902. else if( *begin == plus ) ++begin;
  903. if( end-begin < 3 ) return false;
  904. if( lc_iequal(begin, lc_nan, lc_NAN, 3) )
  905. {
  906. begin += 3;
  907. if (end != begin) /* It is 'nan(...)' or some bad input*/
  908. {
  909. if(end-begin<2) return false; // bad input
  910. -- end;
  911. if( *begin != opening_brace || *end != closing_brace) return false; // bad input
  912. }
  913. if( !has_minus ) value = std::numeric_limits<T>::quiet_NaN();
  914. else value = (boost::math::changesign) (std::numeric_limits<T>::quiet_NaN());
  915. return true;
  916. } else
  917. if (( /* 'INF' or 'inf' */
  918. end-begin==3
  919. &&
  920. lc_iequal(begin, lc_infinity, lc_INFINITY, 3)
  921. )
  922. ||
  923. ( /* 'INFINITY' or 'infinity' */
  924. end-begin==inifinity_size
  925. &&
  926. lc_iequal(begin, lc_infinity, lc_INFINITY, inifinity_size)
  927. )
  928. )
  929. {
  930. if( !has_minus ) value = std::numeric_limits<T>::infinity();
  931. else value = (boost::math::changesign) (std::numeric_limits<T>::infinity());
  932. return true;
  933. }
  934. return false;
  935. }
  936. template <class CharT, class T>
  937. bool put_inf_nan_impl(CharT* begin, CharT*& end, const T& value
  938. , const CharT* lc_nan
  939. , const CharT* lc_infinity) BOOST_NOEXCEPT
  940. {
  941. using namespace std;
  942. const CharT minus = lcast_char_constants<CharT>::minus;
  943. if ( (boost::math::isnan)(value) )
  944. {
  945. if ( (boost::math::signbit)(value) )
  946. {
  947. *begin = minus;
  948. ++ begin;
  949. }
  950. memcpy(begin, lc_nan, 3 * sizeof(CharT));
  951. end = begin + 3;
  952. return true;
  953. } else if ( (boost::math::isinf)(value) )
  954. {
  955. if ( (boost::math::signbit)(value) )
  956. {
  957. *begin = minus;
  958. ++ begin;
  959. }
  960. memcpy(begin, lc_infinity, 3 * sizeof(CharT));
  961. end = begin + 3;
  962. return true;
  963. }
  964. return false;
  965. }
  966. #ifndef BOOST_LCAST_NO_WCHAR_T
  967. template <class T>
  968. bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value) BOOST_NOEXCEPT
  969. {
  970. return parse_inf_nan_impl(begin, end, value
  971. , L"NAN", L"nan"
  972. , L"INFINITY", L"infinity"
  973. , L'(', L')');
  974. }
  975. template <class T>
  976. bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value) BOOST_NOEXCEPT
  977. {
  978. return put_inf_nan_impl(begin, end, value, L"nan", L"infinity");
  979. }
  980. #endif
  981. #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  982. template <class T>
  983. bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value) BOOST_NOEXCEPT
  984. {
  985. return parse_inf_nan_impl(begin, end, value
  986. , u"NAN", u"nan"
  987. , u"INFINITY", u"infinity"
  988. , u'(', u')');
  989. }
  990. template <class T>
  991. bool put_inf_nan(char16_t* begin, char16_t*& end, const T& value) BOOST_NOEXCEPT
  992. {
  993. return put_inf_nan_impl(begin, end, value, u"nan", u"infinity");
  994. }
  995. #endif
  996. #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  997. template <class T>
  998. bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value) BOOST_NOEXCEPT
  999. {
  1000. return parse_inf_nan_impl(begin, end, value
  1001. , U"NAN", U"nan"
  1002. , U"INFINITY", U"infinity"
  1003. , U'(', U')');
  1004. }
  1005. template <class T>
  1006. bool put_inf_nan(char32_t* begin, char32_t*& end, const T& value) BOOST_NOEXCEPT
  1007. {
  1008. return put_inf_nan_impl(begin, end, value, U"nan", U"infinity");
  1009. }
  1010. #endif
  1011. template <class CharT, class T>
  1012. bool parse_inf_nan(const CharT* begin, const CharT* end, T& value) BOOST_NOEXCEPT
  1013. {
  1014. return parse_inf_nan_impl(begin, end, value
  1015. , "NAN", "nan"
  1016. , "INFINITY", "infinity"
  1017. , '(', ')');
  1018. }
  1019. template <class CharT, class T>
  1020. bool put_inf_nan(CharT* begin, CharT*& end, const T& value) BOOST_NOEXCEPT
  1021. {
  1022. return put_inf_nan_impl(begin, end, value, "nan", "infinity");
  1023. }
  1024. }
  1025. namespace detail // lcast_ret_float
  1026. {
  1027. // Silence buggy MS warnings like C4244: '+=' : conversion from 'int' to 'unsigned short', possible loss of data
  1028. #if defined(_MSC_VER) && (_MSC_VER == 1400)
  1029. # pragma warning(push)
  1030. # pragma warning(disable:4244)
  1031. #endif
  1032. template <class T>
  1033. struct mantissa_holder_type
  1034. {
  1035. /* Can not be used with this type */
  1036. };
  1037. template <>
  1038. struct mantissa_holder_type<float>
  1039. {
  1040. typedef unsigned int type;
  1041. typedef double wide_result_t;
  1042. };
  1043. template <>
  1044. struct mantissa_holder_type<double>
  1045. {
  1046. #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
  1047. typedef long double wide_result_t;
  1048. #if defined(BOOST_HAS_LONG_LONG)
  1049. typedef boost::ulong_long_type type;
  1050. #elif defined(BOOST_HAS_MS_INT64)
  1051. typedef unsigned __int64 type;
  1052. #endif
  1053. #endif
  1054. };
  1055. template<class Traits, class T, class CharT>
  1056. inline bool lcast_ret_float(T& value, const CharT* begin, const CharT* end)
  1057. {
  1058. #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  1059. std::locale loc;
  1060. typedef std::numpunct<CharT> numpunct;
  1061. numpunct const& np = BOOST_USE_FACET(numpunct, loc);
  1062. std::string const grouping(
  1063. (loc == std::locale::classic())
  1064. ? std::string()
  1065. : np.grouping()
  1066. );
  1067. std::string::size_type const grouping_size = grouping.size();
  1068. CharT const thousands_sep = static_cast<CharT>(grouping_size ? np.thousands_sep() : 0);
  1069. CharT const decimal_point = np.decimal_point();
  1070. bool found_grouping = false;
  1071. std::string::size_type last_grouping_pos = grouping_size - 1;
  1072. #else
  1073. CharT const decimal_point = lcast_char_constants<CharT>::c_decimal_separator;
  1074. #endif
  1075. CharT const czero = lcast_char_constants<CharT>::zero;
  1076. CharT const minus = lcast_char_constants<CharT>::minus;
  1077. CharT const plus = lcast_char_constants<CharT>::plus;
  1078. CharT const capital_e = lcast_char_constants<CharT>::capital_e;
  1079. CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
  1080. value = static_cast<T>(0);
  1081. if (parse_inf_nan(begin, end, value)) return true;
  1082. typedef typename Traits::int_type int_type;
  1083. typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::type mantissa_type;
  1084. typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::wide_result_t wide_result_t;
  1085. int_type const zero = Traits::to_int_type(czero);
  1086. if (begin == end) return false;
  1087. /* Getting the plus/minus sign */
  1088. bool has_minus = false;
  1089. if (Traits::eq(*begin, minus) ) {
  1090. ++ begin;
  1091. has_minus = true;
  1092. if (begin == end) return false;
  1093. } else if (Traits::eq(*begin, plus) ) {
  1094. ++begin;
  1095. if (begin == end) return false;
  1096. }
  1097. bool found_decimal = false;
  1098. bool found_number_before_exp = false;
  1099. int pow_of_10 = 0;
  1100. mantissa_type mantissa=0;
  1101. bool is_mantissa_full = false;
  1102. char length_since_last_delim = 0;
  1103. while ( begin != end )
  1104. {
  1105. if (found_decimal) {
  1106. /* We allow no thousand_separators after decimal point */
  1107. mantissa_type tmp_mantissa = mantissa * 10u;
  1108. if (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) break;
  1109. if ( *begin < czero || *begin >= czero + 10 ) return false;
  1110. if ( is_mantissa_full
  1111. || tmp_mantissa / 10u != mantissa
  1112. || (std::numeric_limits<mantissa_type>::max)()-(*begin - zero) < tmp_mantissa
  1113. ) {
  1114. is_mantissa_full = true;
  1115. ++ begin;
  1116. continue;
  1117. }
  1118. -- pow_of_10;
  1119. mantissa = tmp_mantissa;
  1120. mantissa += *begin - zero;
  1121. found_number_before_exp = true;
  1122. } else {
  1123. if (*begin >= czero && *begin < czero + 10) {
  1124. /* Checking for mantissa overflow. If overflow will
  1125. * occur, them we only increase multiplyer
  1126. */
  1127. mantissa_type tmp_mantissa = mantissa * 10u;
  1128. if( !is_mantissa_full
  1129. && tmp_mantissa / 10u == mantissa
  1130. && (std::numeric_limits<mantissa_type>::max)()-(*begin - zero) >= tmp_mantissa
  1131. )
  1132. {
  1133. mantissa = tmp_mantissa;
  1134. mantissa += *begin - zero;
  1135. } else
  1136. {
  1137. is_mantissa_full = true;
  1138. ++ pow_of_10;
  1139. }
  1140. found_number_before_exp = true;
  1141. ++ length_since_last_delim;
  1142. } else if (Traits::eq(*begin, decimal_point) || Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) {
  1143. #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  1144. /* If ( we need to check grouping
  1145. * and ( grouping missmatches
  1146. * or grouping position is incorrect
  1147. * or we are using the grouping position 0 twice
  1148. * )
  1149. * ) then return error
  1150. */
  1151. if( grouping_size && found_grouping
  1152. && (
  1153. length_since_last_delim != grouping[0]
  1154. || last_grouping_pos>1
  1155. || (last_grouping_pos==0 && grouping_size>1)
  1156. )
  1157. ) return false;
  1158. #endif
  1159. if(Traits::eq(*begin, decimal_point)) {
  1160. ++ begin;
  1161. found_decimal = true;
  1162. if (!found_number_before_exp && begin==end) return false;
  1163. continue;
  1164. }else {
  1165. if (!found_number_before_exp) return false;
  1166. break;
  1167. }
  1168. }
  1169. #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  1170. else if (grouping_size && Traits::eq(*begin, thousands_sep)){
  1171. if(found_grouping)
  1172. {
  1173. /* It is not he first time, when we find thousands separator,
  1174. * so we need to chek, is the distance between two groupings
  1175. * equal to grouping[last_grouping_pos] */
  1176. if (length_since_last_delim != grouping[last_grouping_pos] )
  1177. {
  1178. if (!last_grouping_pos) return false;
  1179. else
  1180. {
  1181. -- last_grouping_pos;
  1182. if (length_since_last_delim != grouping[last_grouping_pos]) return false;
  1183. }
  1184. } else
  1185. /* We are calling the grouping[0] twice, when grouping size is more than 1 */
  1186. if (grouping_size>1u && last_grouping_pos+1<grouping_size) return false;
  1187. } else {
  1188. /* Delimiter at the begining ',000' */
  1189. if (!length_since_last_delim) return false;
  1190. found_grouping = true;
  1191. if (length_since_last_delim > grouping[last_grouping_pos] ) return false;
  1192. }
  1193. length_since_last_delim = 0;
  1194. ++ begin;
  1195. /* Delimiter at the end '100,' */
  1196. if (begin == end) return false;
  1197. continue;
  1198. }
  1199. #endif
  1200. else return false;
  1201. }
  1202. ++begin;
  1203. }
  1204. // Exponent found
  1205. if ( begin != end && (Traits::eq(*begin, lowercase_e) || Traits::eq(*begin, capital_e)) ) {
  1206. ++ begin;
  1207. if ( begin == end ) return false;
  1208. bool exp_has_minus = false;
  1209. if(Traits::eq(*begin, minus)) {
  1210. exp_has_minus = true;
  1211. ++ begin;
  1212. if ( begin == end ) return false;
  1213. } else if (Traits::eq(*begin, plus)) {
  1214. ++ begin;
  1215. if ( begin == end ) return false;
  1216. }
  1217. int exp_pow_of_10 = 0;
  1218. while ( begin != end )
  1219. {
  1220. if ( *begin < czero
  1221. || *begin >= czero + 10
  1222. || exp_pow_of_10 * 10 < exp_pow_of_10) /* Overflows are checked lower more precisely*/
  1223. return false;
  1224. exp_pow_of_10 *= 10;
  1225. exp_pow_of_10 += *begin - zero;
  1226. ++ begin;
  1227. };
  1228. if ( exp_pow_of_10 ) {
  1229. /* Overflows are checked lower */
  1230. if ( exp_has_minus ) {
  1231. pow_of_10 -= exp_pow_of_10;
  1232. } else {
  1233. pow_of_10 += exp_pow_of_10;
  1234. }
  1235. }
  1236. }
  1237. /* We need a more accurate algorithm... We can not use current algorithm
  1238. * with long doubles (and with doubles if sizeof(double)==sizeof(long double)).
  1239. */
  1240. const wide_result_t result = std::pow(static_cast<wide_result_t>(10.0), pow_of_10) * mantissa;
  1241. value = static_cast<T>( has_minus ? (boost::math::changesign)(result) : result);
  1242. if ( (boost::math::isinf)(value) || (boost::math::isnan)(value) ) return false;
  1243. return true;
  1244. }
  1245. // Unsilence buggy MS warnings like C4244: '+=' : conversion from 'int' to 'unsigned short', possible loss of data
  1246. #if defined(_MSC_VER) && (_MSC_VER == 1400)
  1247. # pragma warning(pop)
  1248. #endif
  1249. }
  1250. namespace detail // parser_buf
  1251. {
  1252. //
  1253. // class parser_buf:
  1254. // acts as a stream buffer which wraps around a pair of pointers
  1255. //
  1256. // This class is copied (and slightly changed) from
  1257. // boost/regex/v4/cpp_regex_traits.hpp
  1258. // Thanks John Maddock for it! (previous version had some
  1259. // problems with libc++ and some other STL implementations)
  1260. template <class BufferType, class charT>
  1261. class parser_buf : public BufferType {
  1262. typedef BufferType base_type;
  1263. typedef typename base_type::int_type int_type;
  1264. typedef typename base_type::char_type char_type;
  1265. typedef typename base_type::pos_type pos_type;
  1266. typedef ::std::streamsize streamsize;
  1267. typedef typename base_type::off_type off_type;
  1268. public:
  1269. parser_buf() : base_type() { setbuf(0, 0); }
  1270. const charT* getnext() { return this->gptr(); }
  1271. #ifndef BOOST_NO_USING_TEMPLATE
  1272. using base_type::pptr;
  1273. using base_type::pbase;
  1274. #else
  1275. charT* pptr() const { return base_type::pptr(); }
  1276. charT* pbase() const { return base_type::pbase(); }
  1277. #endif
  1278. base_type* setbuf(char_type* s, streamsize n) {
  1279. this->setg(s, s, s + n);
  1280. return this;
  1281. }
  1282. pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) {
  1283. if(which & ::std::ios_base::out)
  1284. return pos_type(off_type(-1));
  1285. off_type size = static_cast<off_type>(this->egptr() - this->eback());
  1286. charT* g = this->eback();
  1287. if(off_type(sp) <= size)
  1288. {
  1289. this->setg(g, g + off_type(sp), g + size);
  1290. }
  1291. return pos_type(off_type(-1));
  1292. }
  1293. pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) {
  1294. typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
  1295. if(which & ::std::ios_base::out)
  1296. return pos_type(off_type(-1));
  1297. std::ptrdiff_t size = this->egptr() - this->eback();
  1298. std::ptrdiff_t pos = this->gptr() - this->eback();
  1299. charT* g = this->eback();
  1300. switch(static_cast<cast_type>(way))
  1301. {
  1302. case ::std::ios_base::beg:
  1303. if((off < 0) || (off > size))
  1304. return pos_type(off_type(-1));
  1305. else
  1306. this->setg(g, g + off, g + size);
  1307. break;
  1308. case ::std::ios_base::end:
  1309. if((off < 0) || (off > size))
  1310. return pos_type(off_type(-1));
  1311. else
  1312. this->setg(g, g + size - off, g + size);
  1313. break;
  1314. case ::std::ios_base::cur:
  1315. {
  1316. std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
  1317. if((newpos < 0) || (newpos > size))
  1318. return pos_type(off_type(-1));
  1319. else
  1320. this->setg(g, g + newpos, g + size);
  1321. break;
  1322. }
  1323. default: ;
  1324. }
  1325. #ifdef BOOST_MSVC
  1326. #pragma warning(push)
  1327. #pragma warning(disable:4244)
  1328. #endif
  1329. return static_cast<pos_type>(this->gptr() - this->eback());
  1330. #ifdef BOOST_MSVC
  1331. #pragma warning(pop)
  1332. #endif
  1333. }
  1334. private:
  1335. parser_buf& operator=(const parser_buf&);
  1336. parser_buf(const parser_buf&);
  1337. };
  1338. }
  1339. namespace detail
  1340. {
  1341. struct do_not_construct_out_stream_t{};
  1342. }
  1343. namespace detail // optimized stream wrapper
  1344. {
  1345. // String representation of Source has an upper limit.
  1346. template< class CharT // a result of widest_char transformation
  1347. , class Traits // usually char_traits<CharT>
  1348. , bool RequiresStringbuffer
  1349. >
  1350. class lexical_stream_limited_src
  1351. {
  1352. #if defined(BOOST_NO_STRINGSTREAM)
  1353. typedef std::ostrstream out_stream_t;
  1354. #elif defined(BOOST_NO_STD_LOCALE)
  1355. typedef std::ostringstream out_stream_t;
  1356. typedef parser_buf<std::streambuf, char> buffer_t;
  1357. #else
  1358. typedef std::basic_ostringstream<CharT, Traits> out_stream_t;
  1359. typedef parser_buf<std::basic_streambuf<CharT, Traits>, CharT> buffer_t;
  1360. #endif
  1361. typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  1362. RequiresStringbuffer,
  1363. out_stream_t,
  1364. do_not_construct_out_stream_t
  1365. >::type deduced_out_stream_t;
  1366. // A string representation of Source is written to [start, finish).
  1367. CharT* start;
  1368. CharT* finish;
  1369. deduced_out_stream_t out_stream;
  1370. public:
  1371. lexical_stream_limited_src(CharT* sta, CharT* fin) BOOST_NOEXCEPT
  1372. : start(sta)
  1373. , finish(fin)
  1374. {}
  1375. private:
  1376. // Undefined:
  1377. lexical_stream_limited_src(lexical_stream_limited_src const&);
  1378. void operator=(lexical_stream_limited_src const&);
  1379. /************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
  1380. bool shl_char(CharT ch) BOOST_NOEXCEPT
  1381. {
  1382. Traits::assign(*start, ch);
  1383. finish = start + 1;
  1384. return true;
  1385. }
  1386. #ifndef BOOST_LCAST_NO_WCHAR_T
  1387. template <class T>
  1388. bool shl_char(T ch)
  1389. {
  1390. BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) ,
  1391. "boost::lexical_cast does not support narrowing of char types."
  1392. "Use boost::locale instead" );
  1393. #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
  1394. std::locale loc;
  1395. CharT const w = BOOST_USE_FACET(std::ctype<CharT>, loc).widen(ch);
  1396. #else
  1397. CharT const w = static_cast<CharT>(ch);
  1398. #endif
  1399. Traits::assign(*start, w);
  1400. finish = start + 1;
  1401. return true;
  1402. }
  1403. #endif
  1404. bool shl_char_array(CharT const* str) BOOST_NOEXCEPT
  1405. {
  1406. start = const_cast<CharT*>(str);
  1407. finish = start + Traits::length(str);
  1408. return true;
  1409. }
  1410. template <class T>
  1411. bool shl_char_array(T const* str)
  1412. {
  1413. BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
  1414. "boost::lexical_cast does not support narrowing of char types."
  1415. "Use boost::locale instead" );
  1416. return shl_input_streamable(str);
  1417. }
  1418. bool shl_char_array_limited(CharT const* str, std::size_t max_size) BOOST_NOEXCEPT
  1419. {
  1420. start = const_cast<CharT*>(str);
  1421. finish = std::find(start, start + max_size, Traits::to_char_type(0));
  1422. return true;
  1423. }
  1424. template<typename InputStreamable>
  1425. bool shl_input_streamable(InputStreamable& input)
  1426. {
  1427. #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
  1428. // If you have compilation error at this point, than your STL library
  1429. // does not support such conversions. Try updating it.
  1430. BOOST_STATIC_ASSERT((boost::is_same<char, CharT>::value));
  1431. #endif
  1432. #ifndef BOOST_NO_EXCEPTIONS
  1433. out_stream.exceptions(std::ios::badbit);
  1434. try {
  1435. #endif
  1436. bool const result = !(out_stream << input).fail();
  1437. const buffer_t* const p = static_cast<buffer_t*>(
  1438. static_cast<std::basic_streambuf<CharT, Traits>*>(out_stream.rdbuf())
  1439. );
  1440. start = p->pbase();
  1441. finish = p->pptr();
  1442. return result;
  1443. #ifndef BOOST_NO_EXCEPTIONS
  1444. } catch (const ::std::ios_base::failure& /*f*/) {
  1445. return false;
  1446. }
  1447. #endif
  1448. }
  1449. template <class T>
  1450. inline bool shl_signed(T n)
  1451. {
  1452. start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
  1453. if(n < 0)
  1454. {
  1455. --start;
  1456. CharT const minus = lcast_char_constants<CharT>::minus;
  1457. Traits::assign(*start, minus);
  1458. }
  1459. return true;
  1460. }
  1461. template <class T, class SomeCharT>
  1462. bool shl_real_type(const T& val, SomeCharT* begin, SomeCharT*& end)
  1463. {
  1464. if (put_inf_nan(begin, end, val)) return true;
  1465. lcast_set_precision(out_stream, &val);
  1466. return shl_input_streamable(val);
  1467. }
  1468. static bool shl_real_type(float val, char* begin, char*& end)
  1469. { using namespace std;
  1470. if (put_inf_nan(begin, end, val)) return true;
  1471. const double val_as_double = val;
  1472. end = begin +
  1473. #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
  1474. sprintf_s(begin, end-begin,
  1475. #else
  1476. sprintf(begin,
  1477. #endif
  1478. "%.*g", static_cast<int>(boost::detail::lcast_get_precision<float>()), val_as_double);
  1479. return end > begin;
  1480. }
  1481. static bool shl_real_type(double val, char* begin, char*& end)
  1482. { using namespace std;
  1483. if (put_inf_nan(begin, end, val)) return true;
  1484. end = begin +
  1485. #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
  1486. sprintf_s(begin, end-begin,
  1487. #else
  1488. sprintf(begin,
  1489. #endif
  1490. "%.*g", static_cast<int>(boost::detail::lcast_get_precision<double>()), val);
  1491. return end > begin;
  1492. }
  1493. #ifndef __MINGW32__
  1494. static bool shl_real_type(long double val, char* begin, char*& end)
  1495. { using namespace std;
  1496. if (put_inf_nan(begin, end, val)) return true;
  1497. end = begin +
  1498. #if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
  1499. sprintf_s(begin, end-begin,
  1500. #else
  1501. sprintf(begin,
  1502. #endif
  1503. "%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double>()), val );
  1504. return end > begin;
  1505. }
  1506. #endif
  1507. #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_SWPRINTF) && !defined(__MINGW32__)
  1508. static bool shl_real_type(float val, wchar_t* begin, wchar_t*& end)
  1509. { using namespace std;
  1510. if (put_inf_nan(begin, end, val)) return true;
  1511. const double val_as_double = val;
  1512. end = begin + swprintf(begin, end-begin,
  1513. L"%.*g",
  1514. static_cast<int>(boost::detail::lcast_get_precision<float >()),
  1515. val_as_double );
  1516. return end > begin;
  1517. }
  1518. static bool shl_real_type(double val, wchar_t* begin, wchar_t*& end)
  1519. { using namespace std;
  1520. if (put_inf_nan(begin, end, val)) return true;
  1521. end = begin + swprintf(begin, end-begin,
  1522. L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
  1523. return end > begin;
  1524. }
  1525. static bool shl_real_type(long double val, wchar_t* begin, wchar_t*& end)
  1526. { using namespace std;
  1527. if (put_inf_nan(begin, end, val)) return true;
  1528. end = begin + swprintf(begin, end-begin,
  1529. L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
  1530. return end > begin;
  1531. }
  1532. #endif
  1533. /************************************ OPERATORS << ( ... ) ********************************/
  1534. public:
  1535. template<class Alloc>
  1536. bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
  1537. {
  1538. start = const_cast<CharT*>(str.data());
  1539. finish = start + str.length();
  1540. return true;
  1541. }
  1542. template<class Alloc>
  1543. bool operator<<(boost::container::basic_string<CharT,Traits,Alloc> const& str) BOOST_NOEXCEPT
  1544. {
  1545. start = const_cast<CharT*>(str.data());
  1546. finish = start + str.length();
  1547. return true;
  1548. }
  1549. bool operator<<(bool value) BOOST_NOEXCEPT
  1550. {
  1551. CharT const czero = lcast_char_constants<CharT>::zero;
  1552. Traits::assign(*start, Traits::to_char_type(czero + value));
  1553. finish = start + 1;
  1554. return true;
  1555. }
  1556. bool operator<<(const iterator_range<CharT*>& rng) BOOST_NOEXCEPT
  1557. {
  1558. start = rng.begin();
  1559. finish = rng.end();
  1560. return true;
  1561. }
  1562. bool operator<<(const iterator_range<const CharT*>& rng) BOOST_NOEXCEPT
  1563. {
  1564. start = const_cast<CharT*>(rng.begin());
  1565. finish = const_cast<CharT*>(rng.end());
  1566. return true;
  1567. }
  1568. bool operator<<(const iterator_range<const signed char*>& rng) BOOST_NOEXCEPT
  1569. {
  1570. return (*this) << iterator_range<char*>(
  1571. const_cast<char*>(reinterpret_cast<const char*>(rng.begin())),
  1572. const_cast<char*>(reinterpret_cast<const char*>(rng.end()))
  1573. );
  1574. }
  1575. bool operator<<(const iterator_range<const unsigned char*>& rng) BOOST_NOEXCEPT
  1576. {
  1577. return (*this) << iterator_range<char*>(
  1578. const_cast<char*>(reinterpret_cast<const char*>(rng.begin())),
  1579. const_cast<char*>(reinterpret_cast<const char*>(rng.end()))
  1580. );
  1581. }
  1582. bool operator<<(const iterator_range<signed char*>& rng) BOOST_NOEXCEPT
  1583. {
  1584. return (*this) << iterator_range<char*>(
  1585. reinterpret_cast<char*>(rng.begin()),
  1586. reinterpret_cast<char*>(rng.end())
  1587. );
  1588. }
  1589. bool operator<<(const iterator_range<unsigned char*>& rng) BOOST_NOEXCEPT
  1590. {
  1591. return (*this) << iterator_range<char*>(
  1592. reinterpret_cast<char*>(rng.begin()),
  1593. reinterpret_cast<char*>(rng.end())
  1594. );
  1595. }
  1596. bool operator<<(char ch) { return shl_char(ch); }
  1597. bool operator<<(unsigned char ch) { return ((*this) << static_cast<char>(ch)); }
  1598. bool operator<<(signed char ch) { return ((*this) << static_cast<char>(ch)); }
  1599. #if !defined(BOOST_LCAST_NO_WCHAR_T)
  1600. bool operator<<(wchar_t const* str) { return shl_char_array(str); }
  1601. bool operator<<(wchar_t * str) { return shl_char_array(str); }
  1602. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  1603. bool operator<<(wchar_t ch) { return shl_char(ch); }
  1604. #endif
  1605. #endif
  1606. #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  1607. bool operator<<(char16_t ch) { return shl_char(ch); }
  1608. bool operator<<(char16_t * str) { return shl_char_array(str); }
  1609. bool operator<<(char16_t const * str) { return shl_char_array(str); }
  1610. #endif
  1611. #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  1612. bool operator<<(char32_t ch) { return shl_char(ch); }
  1613. bool operator<<(char32_t * str) { return shl_char_array(str); }
  1614. bool operator<<(char32_t const * str) { return shl_char_array(str); }
  1615. #endif
  1616. bool operator<<(unsigned char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
  1617. bool operator<<(unsigned char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
  1618. bool operator<<(signed char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
  1619. bool operator<<(signed char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
  1620. bool operator<<(char const* str) { return shl_char_array(str); }
  1621. bool operator<<(char* str) { return shl_char_array(str); }
  1622. bool operator<<(short n) { return shl_signed(n); }
  1623. bool operator<<(int n) { return shl_signed(n); }
  1624. bool operator<<(long n) { return shl_signed(n); }
  1625. bool operator<<(unsigned short n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
  1626. bool operator<<(unsigned int n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
  1627. bool operator<<(unsigned long n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
  1628. #if defined(BOOST_HAS_LONG_LONG)
  1629. bool operator<<(boost::ulong_long_type n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
  1630. bool operator<<(boost::long_long_type n) { return shl_signed(n); }
  1631. #elif defined(BOOST_HAS_MS_INT64)
  1632. bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
  1633. bool operator<<( __int64 n) { return shl_signed(n); }
  1634. #endif
  1635. #ifdef BOOST_HAS_INT128
  1636. bool operator<<(const boost::uint128_type& n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
  1637. bool operator<<(const boost::int128_type& n) { return shl_signed(n); }
  1638. #endif
  1639. bool operator<<(float val) { return shl_real_type(val, start, finish); }
  1640. bool operator<<(double val) { return shl_real_type(val, start, finish); }
  1641. bool operator<<(long double val) {
  1642. #ifndef __MINGW32__
  1643. return shl_real_type(val, start, finish);
  1644. #else
  1645. return shl_real_type(static_cast<double>(val), start, finish);
  1646. #endif
  1647. }
  1648. template <std::size_t N>
  1649. bool operator<<(boost::array<CharT, N> const& input) BOOST_NOEXCEPT
  1650. { return shl_char_array_limited(input.begin(), N); }
  1651. template <std::size_t N>
  1652. bool operator<<(boost::array<unsigned char, N> const& input) BOOST_NOEXCEPT
  1653. { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
  1654. template <std::size_t N>
  1655. bool operator<<(boost::array<signed char, N> const& input) BOOST_NOEXCEPT
  1656. { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
  1657. template <std::size_t N>
  1658. bool operator<<(boost::array<const CharT, N> const& input) BOOST_NOEXCEPT
  1659. { return shl_char_array_limited(input.begin(), N); }
  1660. template <std::size_t N>
  1661. bool operator<<(boost::array<const unsigned char, N> const& input) BOOST_NOEXCEPT
  1662. { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
  1663. template <std::size_t N>
  1664. bool operator<<(boost::array<const signed char, N> const& input) BOOST_NOEXCEPT
  1665. { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
  1666. #ifndef BOOST_NO_CXX11_HDR_ARRAY
  1667. template <std::size_t N>
  1668. bool operator<<(std::array<CharT, N> const& input) BOOST_NOEXCEPT
  1669. {
  1670. if (input.size()) return shl_char_array_limited(&input[0], N);
  1671. else return true;
  1672. }
  1673. template <std::size_t N>
  1674. bool operator<<(std::array<unsigned char, N> const& input) BOOST_NOEXCEPT
  1675. { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
  1676. template <std::size_t N>
  1677. bool operator<<(std::array<signed char, N> const& input) BOOST_NOEXCEPT
  1678. { return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
  1679. template <std::size_t N>
  1680. bool operator<<(std::array<const CharT, N> const& input) BOOST_NOEXCEPT
  1681. {
  1682. if (input.size()) return shl_char_array_limited(&input[0], N);
  1683. else return true;
  1684. }
  1685. template <std::size_t N>
  1686. bool operator<<(std::array<const unsigned char, N> const& input) BOOST_NOEXCEPT
  1687. { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
  1688. template <std::size_t N>
  1689. bool operator<<(std::array<const signed char, N> const& input) BOOST_NOEXCEPT
  1690. { return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
  1691. #endif
  1692. template <class InStreamable>
  1693. bool operator<<(const InStreamable& input) { return shl_input_streamable(input); }
  1694. /************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
  1695. private:
  1696. template <typename Type>
  1697. bool shr_unsigned(Type& output)
  1698. {
  1699. if (start == finish) return false;
  1700. CharT const minus = lcast_char_constants<CharT>::minus;
  1701. CharT const plus = lcast_char_constants<CharT>::plus;
  1702. bool has_minus = false;
  1703. /* We won`t use `start' any more, so no need in decrementing it after */
  1704. if ( Traits::eq(minus,*start) )
  1705. {
  1706. ++start;
  1707. has_minus = true;
  1708. } else if ( Traits::eq( plus, *start ) )
  1709. {
  1710. ++start;
  1711. }
  1712. bool const succeed = lcast_ret_unsigned<Traits>(output, start, finish);
  1713. if (has_minus) {
  1714. output = static_cast<Type>(0u - output);
  1715. }
  1716. return succeed;
  1717. }
  1718. template <typename Type>
  1719. bool shr_signed(Type& output)
  1720. {
  1721. if (start == finish) return false;
  1722. CharT const minus = lcast_char_constants<CharT>::minus;
  1723. CharT const plus = lcast_char_constants<CharT>::plus;
  1724. typedef BOOST_DEDUCED_TYPENAME make_unsigned<Type>::type utype;
  1725. utype out_tmp =0;
  1726. bool has_minus = false;
  1727. /* We won`t use `start' any more, so no need in decrementing it after */
  1728. if ( Traits::eq(minus,*start) )
  1729. {
  1730. ++start;
  1731. has_minus = true;
  1732. } else if ( Traits::eq(plus, *start) )
  1733. {
  1734. ++start;
  1735. }
  1736. bool succeed = lcast_ret_unsigned<Traits>(out_tmp, start, finish);
  1737. if (has_minus) {
  1738. utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
  1739. succeed = succeed && out_tmp<=comp_val;
  1740. output = static_cast<Type>(0u - out_tmp);
  1741. } else {
  1742. utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
  1743. succeed = succeed && out_tmp<=comp_val;
  1744. output = out_tmp;
  1745. }
  1746. return succeed;
  1747. }
  1748. template<typename InputStreamable>
  1749. bool shr_using_base_class(InputStreamable& output)
  1750. {
  1751. BOOST_STATIC_ASSERT_MSG(
  1752. (!boost::is_pointer<InputStreamable>::value),
  1753. "boost::lexical_cast can not convert to pointers"
  1754. );
  1755. #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_LOCALE)
  1756. BOOST_STATIC_ASSERT_MSG((boost::is_same<char, CharT>::value),
  1757. "boost::lexical_cast can not convert, because your STL library does not "
  1758. "support such conversions. Try updating it."
  1759. );
  1760. #endif
  1761. #if defined(BOOST_NO_STRINGSTREAM)
  1762. std::istrstream stream(start, finish - start);
  1763. #else
  1764. buffer_t buf;
  1765. buf.setbuf(start, finish - start);
  1766. #if defined(BOOST_NO_STD_LOCALE)
  1767. std::istream stream(&buf);
  1768. #else
  1769. std::basic_istream<CharT, Traits> stream(&buf);
  1770. #endif // BOOST_NO_STD_LOCALE
  1771. #endif // BOOST_NO_STRINGSTREAM
  1772. #ifndef BOOST_NO_EXCEPTIONS
  1773. stream.exceptions(std::ios::badbit);
  1774. try {
  1775. #endif
  1776. stream.unsetf(std::ios::skipws);
  1777. lcast_set_precision(stream, static_cast<InputStreamable*>(0));
  1778. return stream >> output &&
  1779. stream.get() ==
  1780. #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
  1781. // GCC 2.9x lacks std::char_traits<>::eof().
  1782. // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
  1783. // configurations, which do provide std::char_traits<>::eof().
  1784. EOF;
  1785. #else
  1786. Traits::eof();
  1787. #endif
  1788. #ifndef BOOST_NO_EXCEPTIONS
  1789. } catch (const ::std::ios_base::failure& /*f*/) {
  1790. return false;
  1791. }
  1792. #endif
  1793. }
  1794. template<class T>
  1795. inline bool shr_xchar(T& output)
  1796. {
  1797. BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ),
  1798. "boost::lexical_cast does not support narrowing of character types."
  1799. "Use boost::locale instead" );
  1800. bool const ok = (finish - start == 1);
  1801. if (ok) {
  1802. CharT out;
  1803. Traits::assign(out, *start);
  1804. output = static_cast<T>(out);
  1805. }
  1806. return ok;
  1807. }
  1808. /************************************ OPERATORS >> ( ... ) ********************************/
  1809. public:
  1810. bool operator>>(unsigned short& output) { return shr_unsigned(output); }
  1811. bool operator>>(unsigned int& output) { return shr_unsigned(output); }
  1812. bool operator>>(unsigned long int& output) { return shr_unsigned(output); }
  1813. bool operator>>(short& output) { return shr_signed(output); }
  1814. bool operator>>(int& output) { return shr_signed(output); }
  1815. bool operator>>(long int& output) { return shr_signed(output); }
  1816. #if defined(BOOST_HAS_LONG_LONG)
  1817. bool operator>>(boost::ulong_long_type& output) { return shr_unsigned(output); }
  1818. bool operator>>(boost::long_long_type& output) { return shr_signed(output); }
  1819. #elif defined(BOOST_HAS_MS_INT64)
  1820. bool operator>>(unsigned __int64& output) { return shr_unsigned(output); }
  1821. bool operator>>(__int64& output) { return shr_signed(output); }
  1822. #endif
  1823. #ifdef BOOST_HAS_INT128
  1824. bool operator>>(boost::uint128_type& output) { return shr_unsigned(output); }
  1825. bool operator>>(boost::int128_type& output) { return shr_signed(output); }
  1826. #endif
  1827. bool operator>>(char& output) { return shr_xchar(output); }
  1828. bool operator>>(unsigned char& output) { return shr_xchar(output); }
  1829. bool operator>>(signed char& output) { return shr_xchar(output); }
  1830. #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
  1831. bool operator>>(wchar_t& output) { return shr_xchar(output); }
  1832. #endif
  1833. #if !defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  1834. bool operator>>(char16_t& output) { return shr_xchar(output); }
  1835. #endif
  1836. #if !defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CXX11_UNICODE_LITERALS)
  1837. bool operator>>(char32_t& output) { return shr_xchar(output); }
  1838. #endif
  1839. template<class Alloc>
  1840. bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
  1841. template<class Alloc>
  1842. bool operator>>(boost::container::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
  1843. private:
  1844. template <std::size_t N, class ArrayT>
  1845. bool shr_std_array(ArrayT& output) BOOST_NOEXCEPT
  1846. {
  1847. using namespace std;
  1848. const std::size_t size = finish - start;
  1849. if (size > N - 1) { // `-1` because we need to store \0 at the end
  1850. return false;
  1851. }
  1852. memcpy(&output[0], start, size * sizeof(CharT));
  1853. output[size] = Traits::to_char_type(0);
  1854. return true;
  1855. }
  1856. public:
  1857. template <std::size_t N>
  1858. bool operator>>(boost::array<CharT, N>& output) BOOST_NOEXCEPT
  1859. {
  1860. return shr_std_array<N>(output);
  1861. }
  1862. template <std::size_t N>
  1863. bool operator>>(boost::array<unsigned char, N>& output)
  1864. {
  1865. return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
  1866. }
  1867. template <std::size_t N>
  1868. bool operator>>(boost::array<signed char, N>& output)
  1869. {
  1870. return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
  1871. }
  1872. #ifndef BOOST_NO_CXX11_HDR_ARRAY
  1873. template <std::size_t N>
  1874. bool operator>>(std::array<CharT, N>& output) BOOST_NOEXCEPT
  1875. {
  1876. return shr_std_array<N>(output);
  1877. }
  1878. template <std::size_t N>
  1879. bool operator>>(std::array<unsigned char, N>& output)
  1880. {
  1881. return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
  1882. }
  1883. template <std::size_t N>
  1884. bool operator>>(std::array<signed char, N>& output)
  1885. {
  1886. return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
  1887. }
  1888. #endif
  1889. /*
  1890. * case "-0" || "0" || "+0" : output = false; return true;
  1891. * case "1" || "+1": output = true; return true;
  1892. * default: return false;
  1893. */
  1894. bool operator>>(bool& output) BOOST_NOEXCEPT
  1895. {
  1896. CharT const zero = lcast_char_constants<CharT>::zero;
  1897. CharT const plus = lcast_char_constants<CharT>::plus;
  1898. CharT const minus = lcast_char_constants<CharT>::minus;
  1899. switch(finish-start)
  1900. {
  1901. case 1:
  1902. output = Traits::eq(start[0], zero+1);
  1903. return output || Traits::eq(start[0], zero );
  1904. case 2:
  1905. if ( Traits::eq( plus, *start) )
  1906. {
  1907. ++start;
  1908. output = Traits::eq(start[0], zero +1);
  1909. return output || Traits::eq(start[0], zero );
  1910. } else
  1911. {
  1912. output = false;
  1913. return Traits::eq( minus, *start)
  1914. && Traits::eq( zero, start[1]);
  1915. }
  1916. default:
  1917. output = false; // Suppress warning about uninitalized variable
  1918. return false;
  1919. }
  1920. }
  1921. bool operator>>(float& output) { return lcast_ret_float<Traits>(output,start,finish); }
  1922. private:
  1923. // Not optimised converter
  1924. template <class T>
  1925. bool float_types_converter_internal(T& output, int /*tag*/) {
  1926. if (parse_inf_nan(start, finish, output)) return true;
  1927. bool return_value = shr_using_base_class(output);
  1928. /* Some compilers and libraries successfully
  1929. * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
  1930. * We are trying to provide a unified behaviour,
  1931. * so we just forbid such conversions (as some
  1932. * of the most popular compilers/libraries do)
  1933. * */
  1934. CharT const minus = lcast_char_constants<CharT>::minus;
  1935. CharT const plus = lcast_char_constants<CharT>::plus;
  1936. CharT const capital_e = lcast_char_constants<CharT>::capital_e;
  1937. CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
  1938. if ( return_value &&
  1939. (
  1940. Traits::eq(*(finish-1), lowercase_e) // 1.0e
  1941. || Traits::eq(*(finish-1), capital_e) // 1.0E
  1942. || Traits::eq(*(finish-1), minus) // 1.0e- or 1.0E-
  1943. || Traits::eq(*(finish-1), plus) // 1.0e+ or 1.0E+
  1944. )
  1945. ) return false;
  1946. return return_value;
  1947. }
  1948. // Optimised converter
  1949. bool float_types_converter_internal(double& output,char /*tag*/) {
  1950. return lcast_ret_float<Traits>(output,start,finish);
  1951. }
  1952. public:
  1953. bool operator>>(double& output)
  1954. {
  1955. /*
  1956. * Some compilers implement long double as double. In that case these types have
  1957. * same size, same precision, same max and min values... And it means,
  1958. * that current implementation of lcast_ret_float cannot be used for type
  1959. * double, because it will give a big precision loss.
  1960. * */
  1961. boost::mpl::if_c<
  1962. #if (defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)
  1963. boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
  1964. #else
  1965. 1,
  1966. #endif
  1967. int,
  1968. char
  1969. >::type tag = 0;
  1970. return float_types_converter_internal(output, tag);
  1971. }
  1972. bool operator>>(long double& output)
  1973. {
  1974. int tag = 0;
  1975. return float_types_converter_internal(output, tag);
  1976. }
  1977. // Generic istream-based algorithm.
  1978. // lcast_streambuf_for_target<InputStreamable>::value is true.
  1979. template<typename InputStreamable>
  1980. bool operator>>(InputStreamable& output) { return shr_using_base_class(output); }
  1981. };
  1982. }
  1983. namespace detail
  1984. {
  1985. template<typename T>
  1986. struct is_stdstring
  1987. {
  1988. BOOST_STATIC_CONSTANT(bool, value = false );
  1989. };
  1990. template<typename CharT, typename Traits, typename Alloc>
  1991. struct is_stdstring< std::basic_string<CharT, Traits, Alloc> >
  1992. {
  1993. BOOST_STATIC_CONSTANT(bool, value = true );
  1994. };
  1995. template<typename CharT, typename Traits, typename Alloc>
  1996. struct is_stdstring< boost::container::basic_string<CharT, Traits, Alloc> >
  1997. {
  1998. BOOST_STATIC_CONSTANT(bool, value = true );
  1999. };
  2000. template<typename Target, typename Source>
  2001. struct is_arithmetic_and_not_xchars
  2002. {
  2003. BOOST_STATIC_CONSTANT(bool, value =
  2004. (
  2005. boost::type_traits::ice_and<
  2006. boost::is_arithmetic<Source>::value,
  2007. boost::is_arithmetic<Target>::value,
  2008. boost::type_traits::ice_not<
  2009. detail::is_char_or_wchar<Target>::value
  2010. >::value,
  2011. boost::type_traits::ice_not<
  2012. detail::is_char_or_wchar<Source>::value
  2013. >::value
  2014. >::value
  2015. )
  2016. );
  2017. };
  2018. /*
  2019. * is_xchar_to_xchar<Target, Source>::value is true, when
  2020. * Target and Souce are the same char types, or when
  2021. * Target and Souce are char types of the same size.
  2022. */
  2023. template<typename Target, typename Source>
  2024. struct is_xchar_to_xchar
  2025. {
  2026. BOOST_STATIC_CONSTANT(bool, value =
  2027. (
  2028. boost::type_traits::ice_or<
  2029. boost::type_traits::ice_and<
  2030. is_same<Source,Target>::value,
  2031. is_char_or_wchar<Target>::value
  2032. >::value,
  2033. boost::type_traits::ice_and<
  2034. boost::type_traits::ice_eq< sizeof(char),sizeof(Target)>::value,
  2035. boost::type_traits::ice_eq< sizeof(char),sizeof(Source)>::value,
  2036. is_char_or_wchar<Target>::value,
  2037. is_char_or_wchar<Source>::value
  2038. >::value
  2039. >::value
  2040. )
  2041. );
  2042. };
  2043. template<typename Target, typename Source>
  2044. struct is_char_array_to_stdstring
  2045. {
  2046. BOOST_STATIC_CONSTANT(bool, value = false );
  2047. };
  2048. template<typename CharT, typename Traits, typename Alloc>
  2049. struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, CharT* >
  2050. {
  2051. BOOST_STATIC_CONSTANT(bool, value = true );
  2052. };
  2053. template<typename CharT, typename Traits, typename Alloc>
  2054. struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, const CharT* >
  2055. {
  2056. BOOST_STATIC_CONSTANT(bool, value = true );
  2057. };
  2058. template<typename CharT, typename Traits, typename Alloc>
  2059. struct is_char_array_to_stdstring< boost::container::basic_string<CharT, Traits, Alloc>, CharT* >
  2060. {
  2061. BOOST_STATIC_CONSTANT(bool, value = true );
  2062. };
  2063. template<typename CharT, typename Traits, typename Alloc>
  2064. struct is_char_array_to_stdstring< boost::container::basic_string<CharT, Traits, Alloc>, const CharT* >
  2065. {
  2066. BOOST_STATIC_CONSTANT(bool, value = true );
  2067. };
  2068. #if (defined _MSC_VER)
  2069. # pragma warning( push )
  2070. # pragma warning( disable : 4701 ) // possible use of ... before initialization
  2071. # pragma warning( disable : 4702 ) // unreachable code
  2072. # pragma warning( disable : 4267 ) // conversion from 'size_t' to 'unsigned int'
  2073. #endif
  2074. template<typename Target, typename Source>
  2075. struct lexical_cast_do_cast
  2076. {
  2077. static inline Target lexical_cast_impl(const Source& arg)
  2078. {
  2079. typedef lexical_cast_stream_traits<Source, Target> stream_trait;
  2080. typedef detail::lexical_stream_limited_src<
  2081. BOOST_DEDUCED_TYPENAME stream_trait::char_type,
  2082. BOOST_DEDUCED_TYPENAME stream_trait::traits,
  2083. stream_trait::requires_stringbuf
  2084. > interpreter_type;
  2085. // Target type must be default constructible
  2086. Target result;
  2087. BOOST_DEDUCED_TYPENAME stream_trait::char_type buf[stream_trait::len_t::value + 1];
  2088. stream_trait::len_t::check_coverage();
  2089. interpreter_type interpreter(buf, buf + stream_trait::len_t::value + 1);
  2090. // Disabling ADL, by directly specifying operators.
  2091. if(!(interpreter.operator <<(arg) && interpreter.operator >>(result)))
  2092. BOOST_LCAST_THROW_BAD_CAST(Source, Target);
  2093. return result;
  2094. }
  2095. };
  2096. #if (defined _MSC_VER)
  2097. # pragma warning( pop )
  2098. #endif
  2099. template <typename Source>
  2100. struct lexical_cast_copy
  2101. {
  2102. static inline const Source& lexical_cast_impl(const Source &arg) BOOST_NOEXCEPT
  2103. {
  2104. return arg;
  2105. }
  2106. };
  2107. template <class Source, class Target >
  2108. struct detect_precision_loss
  2109. {
  2110. typedef boost::numeric::Trunc<Source> Rounder;
  2111. typedef Source source_type ;
  2112. typedef BOOST_DEDUCED_TYPENAME mpl::if_<
  2113. boost::is_arithmetic<Source>, Source, Source const&
  2114. >::type argument_type ;
  2115. static source_type nearbyint ( argument_type s )
  2116. {
  2117. const source_type near_int = Rounder::nearbyint(s);
  2118. if (near_int) {
  2119. const source_type orig_div_round = s / near_int;
  2120. const source_type eps = std::numeric_limits<source_type>::epsilon();
  2121. if ((orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > eps)
  2122. BOOST_LCAST_THROW_BAD_CAST(Source, Target);
  2123. }
  2124. return s ;
  2125. }
  2126. typedef typename Rounder::round_style round_style;
  2127. } ;
  2128. template <class Source, class Target >
  2129. struct nothrow_overflow_handler
  2130. {
  2131. void operator() ( boost::numeric::range_check_result r )
  2132. {
  2133. if (r != boost::numeric::cInRange)
  2134. BOOST_LCAST_THROW_BAD_CAST(Source, Target);
  2135. }
  2136. } ;
  2137. template <typename Target, typename Source>
  2138. struct lexical_cast_dynamic_num_not_ignoring_minus
  2139. {
  2140. static inline Target lexical_cast_impl(const Source &arg)
  2141. {
  2142. return boost::numeric::converter<
  2143. Target,
  2144. Source,
  2145. boost::numeric::conversion_traits<Target,Source>,
  2146. nothrow_overflow_handler<Source, Target>,
  2147. detect_precision_loss<Source, Target>
  2148. >::convert(arg);
  2149. }
  2150. };
  2151. template <typename Target, typename Source>
  2152. struct lexical_cast_dynamic_num_ignoring_minus
  2153. {
  2154. static inline Target lexical_cast_impl(const Source &arg)
  2155. {
  2156. typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if_c<
  2157. boost::is_float<Source>::value,
  2158. boost::mpl::identity<Source>,
  2159. boost::make_unsigned<Source>
  2160. >::type usource_t;
  2161. typedef boost::numeric::converter<
  2162. Target,
  2163. usource_t,
  2164. boost::numeric::conversion_traits<Target,usource_t>,
  2165. nothrow_overflow_handler<usource_t, Target>,
  2166. detect_precision_loss<usource_t, Target>
  2167. > converter_t;
  2168. return (
  2169. arg < 0 ? static_cast<Target>(0u - converter_t::convert(0u - arg)) : converter_t::convert(arg)
  2170. );
  2171. }
  2172. };
  2173. /*
  2174. * lexical_cast_dynamic_num follows the rules:
  2175. * 1) If Source can be converted to Target without precision loss and
  2176. * without overflows, then assign Source to Target and return
  2177. *
  2178. * 2) If Source is less than 0 and Target is an unsigned integer,
  2179. * then negate Source, check the requirements of rule 1) and if
  2180. * successful, assign static_casted Source to Target and return
  2181. *
  2182. * 3) Otherwise throw a bad_lexical_cast exception
  2183. *
  2184. *
  2185. * Rule 2) required because boost::lexical_cast has the behavior of
  2186. * stringstream, which uses the rules of scanf for conversions. And
  2187. * in the C99 standard for unsigned input value minus sign is
  2188. * optional, so if a negative number is read, no errors will arise
  2189. * and the result will be the two's complement.
  2190. */
  2191. template <typename Target, typename Source>
  2192. struct lexical_cast_dynamic_num
  2193. {
  2194. static inline Target lexical_cast_impl(const Source &arg)
  2195. {
  2196. typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  2197. boost::type_traits::ice_and<
  2198. boost::type_traits::ice_or<
  2199. boost::is_signed<Source>::value,
  2200. boost::is_float<Source>::value
  2201. >::value,
  2202. boost::type_traits::ice_not<
  2203. boost::is_same<Source, bool>::value
  2204. >::value,
  2205. boost::type_traits::ice_not<
  2206. boost::is_same<Target, bool>::value
  2207. >::value,
  2208. boost::is_unsigned<Target>::value
  2209. >::value,
  2210. lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
  2211. lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
  2212. >::type caster_type;
  2213. return caster_type::lexical_cast_impl(arg);
  2214. }
  2215. };
  2216. }
  2217. template <typename Target, typename Source>
  2218. inline Target lexical_cast(const Source &arg)
  2219. {
  2220. typedef BOOST_DEDUCED_TYPENAME boost::detail::array_to_pointer_decay<Source>::type src;
  2221. typedef BOOST_DEDUCED_TYPENAME boost::type_traits::ice_or<
  2222. boost::detail::is_xchar_to_xchar<Target, src >::value,
  2223. boost::detail::is_char_array_to_stdstring<Target, src >::value,
  2224. boost::type_traits::ice_and<
  2225. boost::is_same<Target, src >::value,
  2226. boost::detail::is_stdstring<Target >::value
  2227. >::value
  2228. > shall_we_copy_t;
  2229. typedef BOOST_DEDUCED_TYPENAME
  2230. boost::detail::is_arithmetic_and_not_xchars<Target, src > shall_we_copy_with_dynamic_check_t;
  2231. typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  2232. shall_we_copy_t::value,
  2233. boost::detail::lexical_cast_copy<src >,
  2234. BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
  2235. shall_we_copy_with_dynamic_check_t::value,
  2236. boost::detail::lexical_cast_dynamic_num<Target, src >,
  2237. boost::detail::lexical_cast_do_cast<Target, src >
  2238. >::type
  2239. >::type caster_type;
  2240. return caster_type::lexical_cast_impl(arg);
  2241. }
  2242. template <typename Target>
  2243. inline Target lexical_cast(const char* chars, std::size_t count)
  2244. {
  2245. return ::boost::lexical_cast<Target>(
  2246. ::boost::iterator_range<const char*>(chars, chars + count)
  2247. );
  2248. }
  2249. template <typename Target>
  2250. inline Target lexical_cast(const unsigned char* chars, std::size_t count)
  2251. {
  2252. return ::boost::lexical_cast<Target>(
  2253. ::boost::iterator_range<const unsigned char*>(chars, chars + count)
  2254. );
  2255. }
  2256. template <typename Target>
  2257. inline Target lexical_cast(const signed char* chars, std::size_t count)
  2258. {
  2259. return ::boost::lexical_cast<Target>(
  2260. ::boost::iterator_range<const signed char*>(chars, chars + count)
  2261. );
  2262. }
  2263. #ifndef BOOST_LCAST_NO_WCHAR_T
  2264. template <typename Target>
  2265. inline Target lexical_cast(const wchar_t* chars, std::size_t count)
  2266. {
  2267. return ::boost::lexical_cast<Target>(
  2268. ::boost::iterator_range<const wchar_t*>(chars, chars + count)
  2269. );
  2270. }
  2271. #endif
  2272. #ifndef BOOST_NO_CXX11_CHAR16_T
  2273. template <typename Target>
  2274. inline Target lexical_cast(const char16_t* chars, std::size_t count)
  2275. {
  2276. return ::boost::lexical_cast<Target>(
  2277. ::boost::iterator_range<const char16_t*>(chars, chars + count)
  2278. );
  2279. }
  2280. #endif
  2281. #ifndef BOOST_NO_CXX11_CHAR32_T
  2282. template <typename Target>
  2283. inline Target lexical_cast(const char32_t* chars, std::size_t count)
  2284. {
  2285. return ::boost::lexical_cast<Target>(
  2286. ::boost::iterator_range<const char32_t*>(chars, chars + count)
  2287. );
  2288. }
  2289. #endif
  2290. } // namespace boost
  2291. #else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
  2292. namespace boost {
  2293. namespace detail
  2294. {
  2295. // selectors for choosing stream character type
  2296. template<typename Type>
  2297. struct stream_char
  2298. {
  2299. typedef char type;
  2300. };
  2301. #ifndef BOOST_LCAST_NO_WCHAR_T
  2302. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  2303. template<>
  2304. struct stream_char<wchar_t>
  2305. {
  2306. typedef wchar_t type;
  2307. };
  2308. #endif
  2309. template<>
  2310. struct stream_char<wchar_t *>
  2311. {
  2312. typedef wchar_t type;
  2313. };
  2314. template<>
  2315. struct stream_char<const wchar_t *>
  2316. {
  2317. typedef wchar_t type;
  2318. };
  2319. template<>
  2320. struct stream_char<std::wstring>
  2321. {
  2322. typedef wchar_t type;
  2323. };
  2324. #endif
  2325. // stream wrapper for handling lexical conversions
  2326. template<typename Target, typename Source, typename Traits>
  2327. class lexical_stream
  2328. {
  2329. private:
  2330. typedef typename widest_char<
  2331. typename stream_char<Target>::type,
  2332. typename stream_char<Source>::type>::type char_type;
  2333. typedef Traits traits_type;
  2334. public:
  2335. lexical_stream(char_type* = 0, char_type* = 0)
  2336. {
  2337. stream.unsetf(std::ios::skipws);
  2338. lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );
  2339. }
  2340. ~lexical_stream()
  2341. {
  2342. #if defined(BOOST_NO_STRINGSTREAM)
  2343. stream.freeze(false);
  2344. #endif
  2345. }
  2346. bool operator<<(const Source &input)
  2347. {
  2348. return !(stream << input).fail();
  2349. }
  2350. template<typename InputStreamable>
  2351. bool operator>>(InputStreamable &output)
  2352. {
  2353. return !is_pointer<InputStreamable>::value &&
  2354. stream >> output &&
  2355. stream.get() ==
  2356. #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
  2357. // GCC 2.9x lacks std::char_traits<>::eof().
  2358. // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
  2359. // configurations, which do provide std::char_traits<>::eof().
  2360. EOF;
  2361. #else
  2362. traits_type::eof();
  2363. #endif
  2364. }
  2365. bool operator>>(std::string &output)
  2366. {
  2367. #if defined(BOOST_NO_STRINGSTREAM)
  2368. stream << '\0';
  2369. #endif
  2370. stream.str().swap(output);
  2371. return true;
  2372. }
  2373. #ifndef BOOST_LCAST_NO_WCHAR_T
  2374. bool operator>>(std::wstring &output)
  2375. {
  2376. stream.str().swap(output);
  2377. return true;
  2378. }
  2379. #endif
  2380. private:
  2381. #if defined(BOOST_NO_STRINGSTREAM)
  2382. std::strstream stream;
  2383. #elif defined(BOOST_NO_STD_LOCALE)
  2384. std::stringstream stream;
  2385. #else
  2386. std::basic_stringstream<char_type,traits_type> stream;
  2387. #endif
  2388. };
  2389. }
  2390. // call-by-value fallback version (deprecated)
  2391. template<typename Target, typename Source>
  2392. Target lexical_cast(Source arg)
  2393. {
  2394. typedef typename detail::widest_char<
  2395. BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type
  2396. , BOOST_DEDUCED_TYPENAME detail::stream_char<Source>::type
  2397. >::type char_type;
  2398. typedef std::char_traits<char_type> traits;
  2399. detail::lexical_stream<Target, Source, traits> interpreter;
  2400. Target result;
  2401. if(!(interpreter << arg && interpreter >> result))
  2402. BOOST_LCAST_THROW_BAD_CAST(Source, Target);
  2403. return result;
  2404. }
  2405. } // namespace boost
  2406. #endif
  2407. // Copyright Kevlin Henney, 2000-2005.
  2408. // Copyright Alexander Nasonov, 2006-2010.
  2409. // Copyright Antony Polukhin, 2011-2013.
  2410. //
  2411. // Distributed under the Boost Software License, Version 1.0. (See
  2412. // accompanying file LICENSE_1_0.txt or copy at
  2413. // http://www.boost.org/LICENSE_1_0.txt)
  2414. #undef BOOST_LCAST_THROW_BAD_CAST
  2415. #undef BOOST_LCAST_NO_WCHAR_T
  2416. #endif // BOOST_LEXICAL_CAST_INCLUDED