passenger 3.0.21 → 3.9.1.beta

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (835) hide show
  1. data/DEVELOPERS.TXT +4 -10
  2. data/NEWS +19 -27
  3. data/Rakefile +20 -19
  4. data/bin/passenger +3 -2
  5. data/bin/passenger-config +35 -5
  6. data/bin/passenger-install-apache2-module +12 -12
  7. data/bin/passenger-install-nginx-module +55 -38
  8. data/bin/passenger-memory-stats +3 -1
  9. data/bin/passenger-status +7 -35
  10. data/build/agents.rb +107 -21
  11. data/build/apache2.rb +11 -46
  12. data/build/basics.rb +61 -9
  13. data/build/common_library.rb +59 -142
  14. data/build/cxx_tests.rb +111 -110
  15. data/build/documentation.rb +33 -0
  16. data/build/misc.rb +30 -12
  17. data/build/nginx.rb +10 -39
  18. data/build/oxt_tests.rb +1 -0
  19. data/build/ruby_extension.rb +1 -5
  20. data/build/test_basics.rb +3 -2
  21. data/dev/copy_boost_headers.rb +2 -1
  22. data/doc/Architectural overview.html +49 -90
  23. data/doc/DebuggingAndStressTesting.txt.md +49 -0
  24. data/doc/Packaging.txt.md +254 -0
  25. data/doc/Security of user switching support.html +35 -66
  26. data/doc/Users guide Apache.html +588 -758
  27. data/doc/Users guide Apache.idmap.txt +253 -136
  28. data/doc/Users guide Apache.txt +154 -109
  29. data/doc/Users guide Nginx.html +544 -660
  30. data/doc/Users guide Nginx.idmap.txt +179 -91
  31. data/doc/Users guide Nginx.txt +192 -118
  32. data/doc/Users guide Standalone.html +65 -48
  33. data/doc/Users guide Standalone.idmap.txt +10 -2
  34. data/doc/Users guide Standalone.txt +4 -0
  35. data/doc/images/glyphicons-halflings-white.png +0 -0
  36. data/doc/images/glyphicons-halflings.png +0 -0
  37. data/doc/images/phusion_banner_small.png +0 -0
  38. data/doc/images/{smart-lv2.png → smart.png} +0 -0
  39. data/doc/images/{smart-lv2.svg → smart.svg} +0 -0
  40. data/doc/templates/bootstrap.min.css +397 -0
  41. data/doc/templates/markdown.html.erb +117 -0
  42. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +2 -1
  43. data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +26 -48
  44. data/doc/users_guide_snippets/passenger_spawn_method.txt +18 -30
  45. data/doc/users_guide_snippets/support_information.txt +30 -0
  46. data/ext/apache2/Bucket.cpp +9 -26
  47. data/ext/apache2/Bucket.h +13 -10
  48. data/ext/apache2/Configuration.cpp +70 -58
  49. data/ext/apache2/Configuration.hpp +19 -47
  50. data/ext/apache2/DirectoryMapper.h +7 -7
  51. data/ext/apache2/Hooks.cpp +150 -313
  52. data/ext/boost/algorithm/string/detail/case_conv.hpp +4 -2
  53. data/ext/boost/algorithm/string/detail/find_format.hpp +20 -20
  54. data/ext/boost/algorithm/string/detail/find_format_all.hpp +23 -23
  55. data/ext/boost/algorithm/string/detail/find_format_store.hpp +2 -2
  56. data/ext/boost/algorithm/string/detail/formatter.hpp +25 -0
  57. data/ext/boost/algorithm/string/formatter.hpp +20 -3
  58. data/ext/boost/assert.hpp +85 -4
  59. data/ext/boost/bind/bind.hpp +1 -1
  60. data/ext/boost/concept/detail/backward_compatibility.hpp +1 -1
  61. data/ext/boost/concept_check.hpp +140 -64
  62. data/ext/boost/config.hpp +1 -1
  63. data/ext/boost/config/auto_link.hpp +8 -6
  64. data/ext/boost/config/compiler/borland.hpp +12 -2
  65. data/ext/boost/config/compiler/clang.hpp +89 -30
  66. data/ext/boost/config/compiler/codegear.hpp +3 -2
  67. data/ext/boost/config/compiler/common_edg.hpp +7 -5
  68. data/ext/boost/config/compiler/cray.hpp +61 -0
  69. data/ext/boost/config/compiler/digitalmars.hpp +9 -1
  70. data/ext/boost/config/compiler/gcc.hpp +33 -24
  71. data/ext/boost/config/compiler/gcc_xml.hpp +4 -0
  72. data/ext/boost/config/compiler/hp_acc.hpp +12 -1
  73. data/ext/boost/config/compiler/intel.hpp +78 -4
  74. data/ext/boost/config/compiler/metrowerks.hpp +4 -1
  75. data/ext/boost/config/compiler/mpw.hpp +4 -1
  76. data/ext/boost/config/compiler/nvcc.hpp +8 -66
  77. data/ext/boost/config/compiler/pathscale.hpp +80 -0
  78. data/ext/boost/config/compiler/pgi.hpp +5 -5
  79. data/ext/boost/config/compiler/sunpro_cc.hpp +4 -1
  80. data/ext/boost/config/compiler/vacpp.hpp +37 -13
  81. data/ext/boost/config/compiler/visualc.hpp +24 -11
  82. data/ext/boost/config/platform/bsd.hpp +1 -1
  83. data/ext/boost/config/platform/cray.hpp +18 -0
  84. data/ext/boost/config/platform/cygwin.hpp +10 -0
  85. data/ext/boost/config/platform/linux.hpp +5 -0
  86. data/ext/boost/config/platform/macos.hpp +5 -4
  87. data/ext/boost/config/platform/symbian.hpp +5 -2
  88. data/ext/boost/config/platform/vms.hpp +25 -0
  89. data/ext/boost/config/platform/win32.hpp +7 -1
  90. data/ext/boost/config/select_compiler_config.hpp +8 -25
  91. data/ext/boost/config/select_platform_config.hpp +8 -1
  92. data/ext/boost/config/select_stdlib_config.hpp +9 -1
  93. data/ext/boost/config/stdlib/dinkumware.hpp +6 -9
  94. data/ext/boost/config/stdlib/libcomo.hpp +1 -4
  95. data/ext/boost/config/stdlib/libcpp.hpp +36 -0
  96. data/ext/boost/config/stdlib/libstdcpp3.hpp +37 -11
  97. data/ext/boost/config/stdlib/modena.hpp +1 -4
  98. data/ext/boost/config/stdlib/msl.hpp +1 -4
  99. data/ext/boost/config/stdlib/roguewave.hpp +9 -6
  100. data/ext/boost/config/stdlib/sgi.hpp +12 -4
  101. data/ext/boost/config/stdlib/stlport.hpp +11 -4
  102. data/ext/boost/config/stdlib/vacpp.hpp +11 -4
  103. data/ext/boost/config/suffix.hpp +71 -6
  104. data/ext/boost/config/warning_disable.hpp +1 -1
  105. data/ext/boost/container/container_fwd.hpp +177 -0
  106. data/ext/boost/cstdint.hpp +17 -12
  107. data/ext/boost/current_function.hpp +2 -1
  108. data/ext/boost/date_time/c_time.hpp +17 -1
  109. data/ext/boost/date_time/compiler_config.hpp +13 -15
  110. data/ext/boost/date_time/date_formatting.hpp +7 -1
  111. data/ext/boost/date_time/filetime_functions.hpp +4 -4
  112. data/ext/boost/date_time/gregorian_calendar.ipp +2 -2
  113. data/ext/boost/date_time/strings_from_facet.hpp +3 -3
  114. data/ext/boost/date_time/time_facet.hpp +101 -101
  115. data/ext/boost/detail/endian.hpp +4 -2
  116. data/ext/boost/detail/fenv.hpp +74 -0
  117. data/ext/boost/detail/sp_typeinfo.hpp +6 -0
  118. data/ext/boost/exception/detail/clone_current_exception.hpp +47 -0
  119. data/ext/boost/exception/detail/exception_ptr.hpp +194 -122
  120. data/ext/boost/exception/detail/type_info.hpp +3 -3
  121. data/ext/boost/exception/diagnostic_information.hpp +37 -21
  122. data/ext/boost/exception/exception.hpp +21 -1
  123. data/ext/boost/exception/info.hpp +0 -1
  124. data/ext/boost/function.hpp +2 -2
  125. data/ext/boost/function/function_base.hpp +15 -9
  126. data/ext/boost/function/function_template.hpp +26 -48
  127. data/ext/boost/integer_fwd.hpp +0 -16
  128. data/ext/boost/integer_traits.hpp +2 -2
  129. data/ext/boost/iterator.hpp +1 -1
  130. data/ext/boost/iterator/iterator_adaptor.hpp +1 -7
  131. data/ext/boost/iterator/iterator_facade.hpp +13 -13
  132. data/ext/boost/iterator/transform_iterator.hpp +5 -20
  133. data/ext/boost/lexical_cast.hpp +1655 -673
  134. data/ext/boost/math/policies/policy.hpp +982 -0
  135. data/ext/boost/math/special_functions/detail/fp_traits.hpp +570 -0
  136. data/ext/boost/math/special_functions/detail/round_fwd.hpp +80 -0
  137. data/ext/boost/math/special_functions/fpclassify.hpp +533 -0
  138. data/ext/boost/math/special_functions/math_fwd.hpp +1070 -0
  139. data/ext/boost/math/special_functions/sign.hpp +145 -0
  140. data/ext/boost/math/tools/config.hpp +321 -0
  141. data/ext/boost/math/tools/promotion.hpp +150 -0
  142. data/ext/boost/math/tools/real_cast.hpp +29 -0
  143. data/ext/boost/math/tools/user.hpp +97 -0
  144. data/ext/boost/move/move.hpp +1222 -0
  145. data/ext/boost/mpl/O1_size.hpp +40 -0
  146. data/ext/boost/mpl/O1_size_fwd.hpp +24 -0
  147. data/ext/boost/mpl/advance.hpp +76 -0
  148. data/ext/boost/mpl/advance_fwd.hpp +28 -0
  149. data/ext/boost/mpl/at.hpp +52 -0
  150. data/ext/boost/mpl/at_fwd.hpp +24 -0
  151. data/ext/boost/mpl/aux_/O1_size_impl.hpp +87 -0
  152. data/ext/boost/mpl/aux_/advance_backward.hpp +128 -0
  153. data/ext/boost/mpl/aux_/advance_forward.hpp +127 -0
  154. data/ext/boost/mpl/aux_/arithmetic_op.hpp +92 -0
  155. data/ext/boost/mpl/aux_/at_impl.hpp +45 -0
  156. data/ext/boost/mpl/aux_/begin_end_impl.hpp +101 -0
  157. data/ext/boost/mpl/aux_/clear_impl.hpp +35 -0
  158. data/ext/boost/mpl/aux_/comparison_op.hpp +83 -0
  159. data/ext/boost/mpl/aux_/config/forwarding.hpp +27 -0
  160. data/ext/boost/mpl/aux_/config/typeof.hpp +38 -0
  161. data/ext/boost/mpl/aux_/contains_impl.hpp +61 -0
  162. data/ext/boost/mpl/aux_/find_if_pred.hpp +31 -0
  163. data/ext/boost/mpl/aux_/fold_impl.hpp +43 -0
  164. data/ext/boost/mpl/aux_/has_begin.hpp +23 -0
  165. data/ext/boost/mpl/aux_/has_size.hpp +23 -0
  166. data/ext/boost/mpl/aux_/has_tag.hpp +23 -0
  167. data/ext/boost/mpl/aux_/inserter_algorithm.hpp +159 -0
  168. data/ext/boost/mpl/aux_/is_msvc_eti_arg.hpp +64 -0
  169. data/ext/boost/mpl/aux_/iter_apply.hpp +47 -0
  170. data/ext/boost/mpl/aux_/iter_fold_if_impl.hpp +210 -0
  171. data/ext/boost/mpl/aux_/iter_fold_impl.hpp +42 -0
  172. data/ext/boost/mpl/aux_/lambda_spec.hpp +49 -0
  173. data/ext/boost/mpl/aux_/largest_int.hpp +63 -0
  174. data/ext/boost/mpl/aux_/msvc_eti_base.hpp +77 -0
  175. data/ext/boost/mpl/aux_/msvc_type.hpp +62 -0
  176. data/ext/boost/mpl/aux_/numeric_cast_utils.hpp +77 -0
  177. data/ext/boost/mpl/aux_/numeric_op.hpp +315 -0
  178. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp +97 -0
  179. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp +97 -0
  180. data/ext/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp +94 -0
  181. data/ext/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp +180 -0
  182. data/ext/boost/mpl/aux_/preprocessed/gcc/greater.hpp +94 -0
  183. data/ext/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp +94 -0
  184. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp +133 -0
  185. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp +180 -0
  186. data/ext/boost/mpl/aux_/preprocessed/gcc/less.hpp +94 -0
  187. data/ext/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp +94 -0
  188. data/ext/boost/mpl/aux_/preprocessed/gcc/list.hpp +323 -0
  189. data/ext/boost/mpl/aux_/preprocessed/gcc/minus.hpp +146 -0
  190. data/ext/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp +94 -0
  191. data/ext/boost/mpl/aux_/preprocessed/gcc/plus.hpp +146 -0
  192. data/ext/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp +231 -0
  193. data/ext/boost/mpl/aux_/preprocessed/gcc/times.hpp +146 -0
  194. data/ext/boost/mpl/aux_/preprocessed/gcc/vector.hpp +323 -0
  195. data/ext/boost/mpl/aux_/preprocessor/default_params.hpp +67 -0
  196. data/ext/boost/mpl/aux_/push_back_impl.hpp +70 -0
  197. data/ext/boost/mpl/aux_/push_front_impl.hpp +71 -0
  198. data/ext/boost/mpl/aux_/reverse_fold_impl.hpp +44 -0
  199. data/ext/boost/mpl/aux_/size_impl.hpp +52 -0
  200. data/ext/boost/mpl/aux_/traits_lambda_spec.hpp +63 -0
  201. data/ext/boost/mpl/back_fwd.hpp +24 -0
  202. data/ext/boost/mpl/back_inserter.hpp +34 -0
  203. data/ext/boost/mpl/begin_end.hpp +57 -0
  204. data/ext/boost/mpl/begin_end_fwd.hpp +27 -0
  205. data/ext/boost/mpl/clear.hpp +39 -0
  206. data/ext/boost/mpl/clear_fwd.hpp +24 -0
  207. data/ext/boost/mpl/comparison.hpp +24 -0
  208. data/ext/boost/mpl/contains.hpp +41 -0
  209. data/ext/boost/mpl/contains_fwd.hpp +25 -0
  210. data/ext/boost/mpl/deref.hpp +41 -0
  211. data/ext/boost/mpl/distance.hpp +78 -0
  212. data/ext/boost/mpl/distance_fwd.hpp +28 -0
  213. data/ext/boost/mpl/empty_fwd.hpp +24 -0
  214. data/ext/boost/mpl/equal_to.hpp +21 -0
  215. data/ext/boost/mpl/find.hpp +38 -0
  216. data/ext/boost/mpl/find_if.hpp +50 -0
  217. data/ext/boost/mpl/fold.hpp +48 -0
  218. data/ext/boost/mpl/front_fwd.hpp +24 -0
  219. data/ext/boost/mpl/front_inserter.hpp +33 -0
  220. data/ext/boost/mpl/greater.hpp +21 -0
  221. data/ext/boost/mpl/greater_equal.hpp +21 -0
  222. data/ext/boost/mpl/inserter.hpp +32 -0
  223. data/ext/boost/mpl/iter_fold.hpp +49 -0
  224. data/ext/boost/mpl/iter_fold_if.hpp +117 -0
  225. data/ext/boost/mpl/iterator_range.hpp +42 -0
  226. data/ext/boost/mpl/iterator_tags.hpp +27 -0
  227. data/ext/boost/mpl/less.hpp +21 -0
  228. data/ext/boost/mpl/less_equal.hpp +21 -0
  229. data/ext/boost/mpl/limits/list.hpp +21 -0
  230. data/ext/boost/mpl/limits/vector.hpp +21 -0
  231. data/ext/boost/mpl/list.hpp +57 -0
  232. data/ext/boost/mpl/list/aux_/O1_size.hpp +33 -0
  233. data/ext/boost/mpl/list/aux_/begin_end.hpp +44 -0
  234. data/ext/boost/mpl/list/aux_/clear.hpp +34 -0
  235. data/ext/boost/mpl/list/aux_/empty.hpp +34 -0
  236. data/ext/boost/mpl/list/aux_/front.hpp +33 -0
  237. data/ext/boost/mpl/list/aux_/include_preprocessed.hpp +35 -0
  238. data/ext/boost/mpl/list/aux_/item.hpp +55 -0
  239. data/ext/boost/mpl/list/aux_/iterator.hpp +76 -0
  240. data/ext/boost/mpl/list/aux_/pop_front.hpp +34 -0
  241. data/ext/boost/mpl/list/aux_/preprocessed/plain/list10.hpp +149 -0
  242. data/ext/boost/mpl/list/aux_/preprocessed/plain/list20.hpp +169 -0
  243. data/ext/boost/mpl/list/aux_/push_back.hpp +36 -0
  244. data/ext/boost/mpl/list/aux_/push_front.hpp +39 -0
  245. data/ext/boost/mpl/list/aux_/size.hpp +33 -0
  246. data/ext/boost/mpl/list/aux_/tag.hpp +24 -0
  247. data/ext/boost/mpl/list/list0.hpp +42 -0
  248. data/ext/boost/mpl/list/list10.hpp +43 -0
  249. data/ext/boost/mpl/list/list20.hpp +43 -0
  250. data/ext/boost/mpl/long.hpp +22 -0
  251. data/ext/boost/mpl/long_fwd.hpp +27 -0
  252. data/ext/boost/mpl/minus.hpp +21 -0
  253. data/ext/boost/mpl/multiplies.hpp +53 -0
  254. data/ext/boost/mpl/negate.hpp +81 -0
  255. data/ext/boost/mpl/not_equal_to.hpp +21 -0
  256. data/ext/boost/mpl/numeric_cast.hpp +41 -0
  257. data/ext/boost/mpl/pair.hpp +70 -0
  258. data/ext/boost/mpl/plus.hpp +21 -0
  259. data/ext/boost/mpl/pop_back_fwd.hpp +24 -0
  260. data/ext/boost/mpl/pop_front_fwd.hpp +24 -0
  261. data/ext/boost/mpl/prior.hpp +19 -0
  262. data/ext/boost/mpl/push_back.hpp +53 -0
  263. data/ext/boost/mpl/push_back_fwd.hpp +24 -0
  264. data/ext/boost/mpl/push_front.hpp +52 -0
  265. data/ext/boost/mpl/push_front_fwd.hpp +24 -0
  266. data/ext/boost/mpl/remove_if.hpp +83 -0
  267. data/ext/boost/mpl/reverse_fold.hpp +50 -0
  268. data/ext/boost/mpl/same_as.hpp +55 -0
  269. data/ext/boost/mpl/sequence_tag.hpp +124 -0
  270. data/ext/boost/mpl/sequence_tag_fwd.hpp +26 -0
  271. data/ext/boost/mpl/size.hpp +42 -0
  272. data/ext/boost/mpl/size_fwd.hpp +24 -0
  273. data/ext/boost/mpl/tag.hpp +52 -0
  274. data/ext/boost/mpl/times.hpp +21 -0
  275. data/ext/boost/mpl/vector.hpp +57 -0
  276. data/ext/boost/mpl/vector/aux_/O1_size.hpp +56 -0
  277. data/ext/boost/mpl/vector/aux_/at.hpp +116 -0
  278. data/ext/boost/mpl/vector/aux_/back.hpp +59 -0
  279. data/ext/boost/mpl/vector/aux_/begin_end.hpp +49 -0
  280. data/ext/boost/mpl/vector/aux_/clear.hpp +55 -0
  281. data/ext/boost/mpl/vector/aux_/empty.hpp +68 -0
  282. data/ext/boost/mpl/vector/aux_/front.hpp +56 -0
  283. data/ext/boost/mpl/vector/aux_/include_preprocessed.hpp +55 -0
  284. data/ext/boost/mpl/vector/aux_/item.hpp +103 -0
  285. data/ext/boost/mpl/vector/aux_/iterator.hpp +130 -0
  286. data/ext/boost/mpl/vector/aux_/pop_back.hpp +40 -0
  287. data/ext/boost/mpl/vector/aux_/pop_front.hpp +40 -0
  288. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp +829 -0
  289. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp +1144 -0
  290. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp +139 -0
  291. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp +159 -0
  292. data/ext/boost/mpl/vector/aux_/push_back.hpp +40 -0
  293. data/ext/boost/mpl/vector/aux_/push_front.hpp +40 -0
  294. data/ext/boost/mpl/vector/aux_/size.hpp +49 -0
  295. data/ext/boost/mpl/vector/aux_/tag.hpp +32 -0
  296. data/ext/boost/mpl/vector/aux_/vector0.hpp +52 -0
  297. data/ext/boost/mpl/vector/vector0.hpp +34 -0
  298. data/ext/boost/mpl/vector/vector10.hpp +45 -0
  299. data/ext/boost/mpl/vector/vector20.hpp +45 -0
  300. data/ext/boost/none.hpp +1 -1
  301. data/ext/boost/numeric/conversion/bounds.hpp +24 -0
  302. data/ext/boost/numeric/conversion/cast.hpp +61 -0
  303. data/ext/boost/numeric/conversion/conversion_traits.hpp +39 -0
  304. data/ext/boost/numeric/conversion/converter.hpp +68 -0
  305. data/ext/boost/numeric/conversion/converter_policies.hpp +186 -0
  306. data/ext/boost/numeric/conversion/detail/bounds.hpp +58 -0
  307. data/ext/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
  308. data/ext/boost/numeric/conversion/detail/converter.hpp +602 -0
  309. data/ext/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
  310. data/ext/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
  311. data/ext/boost/numeric/conversion/detail/meta.hpp +120 -0
  312. data/ext/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
  313. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
  314. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
  315. data/ext/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
  316. data/ext/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
  317. data/ext/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
  318. data/ext/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
  319. data/ext/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
  320. data/ext/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
  321. data/ext/boost/operators.hpp +3 -1
  322. data/ext/boost/optional/optional.hpp +146 -79
  323. data/ext/boost/optional/optional_fwd.hpp +8 -1
  324. data/ext/boost/preprocessor/cat.hpp +2 -2
  325. data/ext/boost/preprocessor/config/config.hpp +39 -4
  326. data/ext/boost/preprocessor/facilities/intercept.hpp +277 -0
  327. data/ext/boost/preprocessor/facilities/overload.hpp +25 -0
  328. data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +3 -3
  329. data/ext/boost/preprocessor/iteration/iterate.hpp +3 -3
  330. data/ext/boost/preprocessor/punctuation/paren.hpp +23 -0
  331. data/ext/boost/preprocessor/repetition/enum_shifted_params.hpp +44 -0
  332. data/ext/boost/preprocessor/seq/cat.hpp +5 -4
  333. data/ext/boost/preprocessor/seq/size.hpp +0 -1
  334. data/ext/boost/preprocessor/tuple/eat.hpp +83 -34
  335. data/ext/boost/preprocessor/tuple/elem.hpp +161 -355
  336. data/ext/boost/preprocessor/tuple/rem.hpp +110 -48
  337. data/ext/boost/preprocessor/tuple/to_list.hpp +90 -36
  338. data/ext/boost/preprocessor/variadic/elem.hpp +94 -0
  339. data/ext/boost/preprocessor/variadic/size.hpp +30 -0
  340. data/ext/boost/range/begin.hpp +17 -6
  341. data/ext/boost/range/concepts.hpp +37 -2
  342. data/ext/boost/range/detail/safe_bool.hpp +72 -0
  343. data/ext/boost/range/end.hpp +14 -9
  344. data/ext/boost/range/iterator_range_core.hpp +120 -12
  345. data/ext/boost/range/size.hpp +21 -5
  346. data/ext/boost/smart_ptr/detail/shared_count.hpp +88 -0
  347. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +3 -0
  348. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +142 -0
  349. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +9 -0
  350. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +10 -2
  351. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +5 -1
  352. data/ext/boost/smart_ptr/detail/spinlock.hpp +4 -1
  353. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +20 -3
  354. data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +4 -0
  355. data/ext/boost/smart_ptr/make_shared.hpp +591 -22
  356. data/ext/boost/smart_ptr/shared_array.hpp +29 -1
  357. data/ext/boost/smart_ptr/shared_ptr.hpp +29 -13
  358. data/ext/boost/smart_ptr/weak_ptr.hpp +24 -12
  359. data/ext/boost/src/pthread/once.cpp +9 -7
  360. data/ext/boost/src/pthread/thread.cpp +32 -28
  361. data/ext/boost/src/pthread/timeconv.inl +4 -5
  362. data/ext/boost/src/tss_null.cpp +5 -1
  363. data/ext/boost/static_assert.hpp +8 -2
  364. data/ext/boost/thread/detail/config.hpp +19 -4
  365. data/ext/boost/thread/detail/move.hpp +11 -5
  366. data/ext/boost/thread/detail/thread.hpp +59 -43
  367. data/ext/boost/thread/exceptions.hpp +9 -9
  368. data/ext/boost/thread/future.hpp +150 -82
  369. data/ext/boost/thread/locks.hpp +101 -60
  370. data/ext/boost/thread/pthread/condition_variable.hpp +79 -32
  371. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +12 -3
  372. data/ext/boost/thread/pthread/mutex.hpp +17 -14
  373. data/ext/boost/thread/pthread/once.hpp +3 -4
  374. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +12 -2
  375. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -19
  376. data/ext/boost/thread/pthread/shared_mutex.hpp +13 -13
  377. data/ext/boost/thread/pthread/thread_data.hpp +40 -12
  378. data/ext/boost/thread/thread_time.hpp +5 -0
  379. data/ext/boost/throw_exception.hpp +1 -1
  380. data/ext/boost/token_functions.hpp +34 -10
  381. data/ext/boost/type_traits/add_rvalue_reference.hpp +66 -0
  382. data/ext/boost/type_traits/alignment_of.hpp +1 -1
  383. data/ext/boost/type_traits/detail/bool_trait_def.hpp +26 -3
  384. data/ext/boost/type_traits/detail/bool_trait_undef.hpp +3 -2
  385. data/ext/boost/type_traits/detail/cv_traits_impl.hpp +1 -1
  386. data/ext/boost/type_traits/detail/size_t_trait_def.hpp +6 -4
  387. data/ext/boost/type_traits/detail/type_trait_def.hpp +8 -2
  388. data/ext/boost/type_traits/function_traits.hpp +1 -1
  389. data/ext/boost/type_traits/has_nothrow_constructor.hpp +53 -0
  390. data/ext/boost/type_traits/has_nothrow_copy.hpp +19 -5
  391. data/ext/boost/type_traits/has_trivial_constructor.hpp +51 -0
  392. data/ext/boost/type_traits/has_trivial_copy.hpp +20 -5
  393. data/ext/boost/type_traits/has_trivial_destructor.hpp +12 -5
  394. data/ext/boost/type_traits/intrinsics.hpp +119 -71
  395. data/ext/boost/type_traits/is_const.hpp +5 -5
  396. data/ext/boost/type_traits/is_convertible.hpp +14 -13
  397. data/ext/boost/type_traits/is_enum.hpp +1 -1
  398. data/ext/boost/type_traits/is_floating_point.hpp +27 -0
  399. data/ext/boost/type_traits/is_function.hpp +3 -3
  400. data/ext/boost/type_traits/is_fundamental.hpp +1 -1
  401. data/ext/boost/type_traits/is_member_function_pointer.hpp +2 -2
  402. data/ext/boost/type_traits/is_member_pointer.hpp +2 -2
  403. data/ext/boost/type_traits/is_pod.hpp +11 -3
  404. data/ext/boost/type_traits/is_pointer.hpp +2 -2
  405. data/ext/boost/type_traits/is_signed.hpp +8 -3
  406. data/ext/boost/type_traits/is_union.hpp +8 -0
  407. data/ext/boost/type_traits/is_unsigned.hpp +9 -4
  408. data/ext/boost/type_traits/is_volatile.hpp +5 -5
  409. data/ext/boost/type_traits/remove_cv.hpp +4 -3
  410. data/ext/boost/type_traits/remove_pointer.hpp +51 -2
  411. data/ext/boost/type_traits/remove_reference.hpp +2 -2
  412. data/ext/boost/type_traits/type_with_alignment.hpp +8 -2
  413. data/ext/boost/utility/declval.hpp +44 -0
  414. data/ext/boost/utility/detail/in_place_factory_prefix.hpp +36 -0
  415. data/ext/boost/utility/detail/in_place_factory_suffix.hpp +23 -0
  416. data/ext/boost/utility/detail/result_of_iterate.hpp +142 -0
  417. data/ext/boost/utility/in_place_factory.hpp +88 -0
  418. data/ext/boost/utility/result_of.hpp +103 -0
  419. data/ext/boost/utility/swap.hpp +55 -0
  420. data/ext/common/AnsiColorConstants.h +36 -0
  421. data/ext/common/ApplicationPool2/Common.h +87 -0
  422. data/ext/common/ApplicationPool2/ComponentInfo.h +53 -0
  423. data/ext/common/ApplicationPool2/Group.h +648 -0
  424. data/ext/common/ApplicationPool2/Implementation.cpp +580 -0
  425. data/ext/common/ApplicationPool2/Options.h +576 -0
  426. data/ext/common/ApplicationPool2/PipeWatcher.h +61 -0
  427. data/ext/common/ApplicationPool2/Pool.h +1181 -0
  428. data/ext/common/ApplicationPool2/Process.h +425 -0
  429. data/ext/common/ApplicationPool2/README.md +96 -0
  430. data/ext/common/ApplicationPool2/Session.h +158 -0
  431. data/ext/common/ApplicationPool2/Socket.h +246 -0
  432. data/ext/common/ApplicationPool2/Spawner.h +2212 -0
  433. data/ext/common/ApplicationPool2/SuperGroup.h +749 -0
  434. data/ext/common/BackgroundEventLoop.cpp +129 -0
  435. data/ext/common/BackgroundEventLoop.h +61 -0
  436. data/ext/common/Constants.h +3 -1
  437. data/ext/common/EventedBufferedInput.h +331 -0
  438. data/ext/common/EventedMessageServer.h +17 -34
  439. data/ext/common/EventedServer.h +2 -2
  440. data/ext/common/Exceptions.h +71 -19
  441. data/ext/common/FileDescriptor.h +8 -6
  442. data/ext/common/HttpConstants.h +167 -0
  443. data/ext/common/IniFile.h +24 -0
  444. data/ext/common/Logging.h +62 -849
  445. data/ext/common/MessageReadersWriters.h +19 -0
  446. data/ext/common/MessageServer.h +11 -14
  447. data/ext/common/MultiLibeio.cpp +198 -0
  448. data/ext/common/MultiLibeio.h +67 -0
  449. data/ext/common/ResourceLocator.h +24 -41
  450. data/ext/common/SafeLibev.h +186 -14
  451. data/ext/common/StaticString.h +23 -3
  452. data/ext/common/UnionStation.h +972 -0
  453. data/ext/common/Utils.cpp +168 -24
  454. data/ext/common/Utils.h +25 -3
  455. data/ext/common/Utils/CachedFileStat.hpp +4 -3
  456. data/ext/common/Utils/FileChangeChecker.h +2 -2
  457. data/ext/common/Utils/HashMap.h +50 -0
  458. data/ext/common/Utils/IOUtils.cpp +229 -68
  459. data/ext/common/Utils/IOUtils.h +134 -3
  460. data/ext/common/Utils/Lock.h +28 -0
  461. data/ext/common/Utils/MemoryBarrier.h +52 -0
  462. data/ext/common/Utils/PriorityQueue.h +54 -0
  463. data/ext/common/Utils/ProcessMetricsCollector.h +9 -11
  464. data/ext/common/Utils/ScopeGuard.h +50 -1
  465. data/ext/common/Utils/SmallVector.h +653 -0
  466. data/ext/common/Utils/StrIntUtils.cpp +26 -2
  467. data/ext/common/Utils/StrIntUtils.h +18 -2
  468. data/ext/common/Utils/StringMap.h +125 -8
  469. data/ext/common/Utils/Template.h +212 -0
  470. data/ext/common/Utils/fib.c +699 -0
  471. data/ext/common/Utils/fib.h +101 -0
  472. data/ext/common/Utils/fibpriv.h +67 -0
  473. data/ext/common/Utils/json-forwards.h +249 -0
  474. data/ext/common/Utils/json.h +1855 -0
  475. data/ext/common/Utils/jsoncpp.cpp +4230 -0
  476. data/ext/common/agents/Base.cpp +1126 -0
  477. data/ext/common/{AgentBase.h → agents/Base.h} +5 -1
  478. data/ext/common/agents/EnvPrinter.c +16 -0
  479. data/ext/common/agents/HelperAgent/AgentOptions.h +81 -0
  480. data/ext/common/{HelperAgent → agents/HelperAgent}/BacktracesServer.h +3 -2
  481. data/ext/common/agents/HelperAgent/FileBackedPipe.h +732 -0
  482. data/ext/common/agents/HelperAgent/Main.cpp +497 -0
  483. data/ext/common/agents/HelperAgent/RequestHandler.cpp +283 -0
  484. data/ext/common/agents/HelperAgent/RequestHandler.h +2139 -0
  485. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +451 -0
  486. data/ext/common/{LoggingAgent → agents/LoggingAgent}/DataStoreId.h +1 -1
  487. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.cpp +1 -1
  488. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.h +0 -0
  489. data/ext/common/{LoggingAgent → agents/LoggingAgent}/LoggingServer.h +18 -16
  490. data/ext/common/{LoggingAgent → agents/LoggingAgent}/Main.cpp +15 -13
  491. data/ext/common/{LoggingAgent → agents/LoggingAgent}/RemoteSender.h +6 -6
  492. data/ext/common/agents/SpawnPreparer.cpp +127 -0
  493. data/ext/common/{Watchdog.cpp → agents/Watchdog/Main.cpp} +63 -25
  494. data/ext/libeio/Changes +72 -0
  495. data/ext/{google/COPYING → libeio/LICENSE} +17 -9
  496. data/ext/libeio/Makefile.am +15 -0
  497. data/ext/libeio/Makefile.in +694 -0
  498. data/ext/libeio/aclocal.m4 +9418 -0
  499. data/ext/libeio/autogen.sh +3 -0
  500. data/ext/libeio/config.guess +1501 -0
  501. data/ext/libeio/config.h.in +136 -0
  502. data/ext/libeio/config.sub +1705 -0
  503. data/ext/libeio/configure +14822 -0
  504. data/ext/libeio/configure.ac +22 -0
  505. data/ext/libeio/demo.c +194 -0
  506. data/ext/libeio/ecb.h +457 -0
  507. data/ext/libeio/eio.c +2816 -0
  508. data/ext/libeio/eio.h +411 -0
  509. data/ext/libeio/install-sh +520 -0
  510. data/ext/libeio/libeio.m4 +211 -0
  511. data/ext/libeio/ltmain.sh +9636 -0
  512. data/ext/libeio/missing +376 -0
  513. data/ext/libeio/xthread.h +166 -0
  514. data/ext/libev/Changes +125 -7
  515. data/ext/libev/Makefile.am +5 -3
  516. data/ext/libev/Makefile.in +209 -120
  517. data/ext/libev/aclocal.m4 +6027 -4619
  518. data/ext/libev/autogen.sh +1 -4
  519. data/ext/libev/config.h.in +11 -7
  520. data/ext/libev/configure +7312 -14993
  521. data/ext/libev/configure.ac +12 -5
  522. data/ext/libev/depcomp +630 -0
  523. data/ext/libev/ev++.h +48 -32
  524. data/ext/libev/ev.c +1173 -391
  525. data/ext/libev/ev.h +315 -181
  526. data/ext/libev/ev_epoll.c +66 -15
  527. data/ext/libev/ev_kqueue.c +20 -18
  528. data/ext/libev/ev_poll.c +27 -23
  529. data/ext/libev/ev_port.c +39 -19
  530. data/ext/libev/ev_select.c +23 -17
  531. data/ext/libev/ev_vars.h +25 -8
  532. data/ext/libev/ev_win32.c +6 -6
  533. data/ext/libev/ev_wrap.h +22 -2
  534. data/ext/libev/event.c +18 -17
  535. data/ext/libev/event.h +16 -4
  536. data/ext/libev/libev.m4 +10 -6
  537. data/ext/libev/ltmain.sh +7353 -5811
  538. data/ext/nginx/Configuration.c +74 -42
  539. data/ext/nginx/Configuration.h +3 -5
  540. data/ext/nginx/ContentHandler.c +26 -83
  541. data/ext/nginx/ContentHandler.h +1 -1
  542. data/ext/nginx/config +13 -9
  543. data/ext/nginx/ngx_http_passenger_module.c +3 -7
  544. data/ext/oxt/detail/backtrace_enabled.hpp +5 -102
  545. data/ext/oxt/detail/context.hpp +90 -0
  546. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -0
  547. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +4 -0
  548. data/ext/oxt/detail/spin_lock_pthreads.hpp +14 -0
  549. data/ext/oxt/detail/tracable_exception_enabled.hpp +2 -2
  550. data/ext/oxt/dynamic_thread_group.hpp +27 -1
  551. data/ext/oxt/implementation.cpp +415 -0
  552. data/ext/oxt/{thread.cpp → initialize.hpp} +13 -6
  553. data/ext/oxt/macros.hpp +32 -1
  554. data/ext/oxt/spin_lock.hpp +6 -11
  555. data/ext/oxt/system_calls.cpp +204 -16
  556. data/ext/oxt/system_calls.hpp +85 -45
  557. data/ext/oxt/thread.hpp +13 -117
  558. data/ext/ruby/passenger_native_support.c +82 -237
  559. data/helper-scripts/backtrace-sanitizer.rb +114 -0
  560. data/helper-scripts/classic-rails-loader.rb +135 -0
  561. data/helper-scripts/classic-rails-preloader.rb +161 -0
  562. data/helper-scripts/node-loader.js +314 -0
  563. data/helper-scripts/rack-loader.rb +104 -0
  564. data/helper-scripts/rack-preloader.rb +132 -0
  565. data/helper-scripts/wsgi-loader.py +231 -0
  566. data/helper-scripts/wsgi-preloader.py +1 -0
  567. data/lib/phusion_passenger.rb +159 -61
  568. data/lib/phusion_passenger/abstract_installer.rb +182 -87
  569. data/lib/phusion_passenger/admin_tools/server_instance.rb +25 -19
  570. data/lib/phusion_passenger/analytics_logger.rb +5 -4
  571. data/lib/phusion_passenger/classic_rails/{request_handler.rb → thread_handler_extension.rb} +4 -40
  572. data/lib/phusion_passenger/classic_rails_extensions/init.rb +5 -3
  573. data/lib/phusion_passenger/common_library.rb +441 -0
  574. data/lib/phusion_passenger/console_text_template.rb +4 -16
  575. data/lib/phusion_passenger/constants.rb +1 -8
  576. data/lib/phusion_passenger/debug_logging.rb +5 -2
  577. data/lib/phusion_passenger/dependencies.rb +51 -13
  578. data/lib/phusion_passenger/loader_shared_helpers.rb +318 -0
  579. data/lib/phusion_passenger/message_channel.rb +3 -47
  580. data/lib/phusion_passenger/message_client.rb +2 -2
  581. data/lib/phusion_passenger/native_support.rb +36 -15
  582. data/lib/phusion_passenger/packaging.rb +8 -11
  583. data/lib/phusion_passenger/platform_info.rb +25 -17
  584. data/lib/phusion_passenger/platform_info/apache.rb +10 -7
  585. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +10 -30
  586. data/lib/phusion_passenger/platform_info/compiler.rb +93 -34
  587. data/lib/phusion_passenger/platform_info/ruby.rb +37 -97
  588. data/lib/phusion_passenger/preloader_shared_helpers.rb +121 -0
  589. data/lib/phusion_passenger/public_api.rb +1 -4
  590. data/lib/phusion_passenger/rack/{request_handler.rb → thread_handler_extension.rb} +14 -63
  591. data/lib/phusion_passenger/rails3_extensions/init.rb +9 -8
  592. data/lib/phusion_passenger/request_handler.rb +500 -0
  593. data/lib/phusion_passenger/request_handler/thread_handler.rb +360 -0
  594. data/lib/phusion_passenger/ruby_core_enhancements.rb +142 -0
  595. data/lib/phusion_passenger/standalone/command.rb +36 -15
  596. data/lib/phusion_passenger/standalone/package_runtime_command.rb +16 -8
  597. data/lib/phusion_passenger/standalone/runtime_installer.rb +169 -72
  598. data/lib/phusion_passenger/standalone/start_command.rb +44 -39
  599. data/lib/phusion_passenger/standalone/utils.rb +5 -5
  600. data/lib/phusion_passenger/utils.rb +35 -914
  601. data/lib/phusion_passenger/utils/ansi_colors.rb +59 -0
  602. data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
  603. data/lib/phusion_passenger/utils/robust_interruption.rb +134 -0
  604. data/lib/phusion_passenger/utils/tee_input.rb +174 -0
  605. data/lib/phusion_passenger/utils/tmpio.rb +33 -0
  606. data/lib/phusion_passenger/utils/unseekable_socket.rb +6 -0
  607. data/resources/mime.types +5 -1
  608. data/{lib/phusion_passenger/templates → resources}/standalone_default_root/index.html +0 -0
  609. data/{lib/phusion_passenger → resources}/templates/apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  610. data/{lib/phusion_passenger → resources}/templates/apache2/config_snippets.txt.erb +0 -0
  611. data/{lib/phusion_passenger → resources}/templates/apache2/deployment_example.txt.erb +0 -0
  612. data/{lib/phusion_passenger → resources}/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -0
  613. data/{lib/phusion_passenger → resources}/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  614. data/{lib/phusion_passenger → resources}/templates/apache2/run_installer_as_root.txt.erb +0 -0
  615. data/{lib/phusion_passenger → resources}/templates/apache2/welcome.txt.erb +0 -0
  616. data/{lib/phusion_passenger → resources}/templates/error_layout.css +6 -0
  617. data/resources/templates/error_layout.html.template +89 -0
  618. data/resources/templates/general_error.html.template +1 -0
  619. data/resources/templates/general_error_with_html.html.template +1 -0
  620. data/{lib/phusion_passenger → resources}/templates/nginx/ask_for_extra_configure_flags.txt.erb +0 -0
  621. data/{lib/phusion_passenger → resources}/templates/nginx/cannot_write_to_dir.txt.erb +0 -0
  622. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets.txt.erb +0 -0
  623. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets_inserted.txt.erb +0 -0
  624. data/{lib/phusion_passenger → resources}/templates/nginx/confirm_extra_configure_flags.txt.erb +0 -0
  625. data/{lib/phusion_passenger → resources}/templates/nginx/deployment_example.txt.erb +0 -0
  626. data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +8 -0
  627. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_downloaded.txt.erb +0 -0
  628. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_extracted.txt.erb +0 -0
  629. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  630. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  631. data/{lib/phusion_passenger → resources}/templates/nginx/query_download_and_install.txt.erb +0 -0
  632. data/{lib/phusion_passenger → resources}/templates/nginx/run_installer_as_root.txt.erb +0 -0
  633. data/{lib/phusion_passenger → resources}/templates/nginx/welcome.txt.erb +0 -0
  634. data/{lib/phusion_passenger → resources}/templates/standalone/cannot_write_to_dir.txt.erb +0 -0
  635. data/{lib/phusion_passenger → resources}/templates/standalone/config.erb +26 -5
  636. data/{lib/phusion_passenger → resources}/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  637. data/{lib/phusion_passenger → resources}/templates/standalone/run_installer_as_root.txt.erb +0 -0
  638. data/{lib/phusion_passenger → resources}/templates/standalone/welcome.txt.erb +0 -0
  639. data/resources/templates/undisclosed_error.html.template +25 -0
  640. data/test/config.json.example +42 -0
  641. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +86 -0
  642. data/test/cxx/ApplicationPool2/OptionsTest.cpp +44 -0
  643. data/test/cxx/ApplicationPool2/PoolTest.cpp +1234 -0
  644. data/test/cxx/ApplicationPool2/ProcessTest.cpp +131 -0
  645. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +229 -0
  646. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +744 -0
  647. data/test/cxx/BufferedIOTest.cpp +7 -7
  648. data/test/cxx/CxxTestMain.cpp +65 -2
  649. data/test/cxx/FileBackedPipeTest.cpp +626 -0
  650. data/test/cxx/FileChangeCheckerTest.cpp +20 -18
  651. data/test/cxx/FilterSupportTest.cpp +5 -5
  652. data/test/cxx/IOUtilsTest.cpp +11 -4
  653. data/test/cxx/MessageReadersWritersTest.cpp +1 -1
  654. data/test/cxx/MessageServerTest.cpp +31 -30
  655. data/test/cxx/RequestHandlerTest.cpp +777 -0
  656. data/test/cxx/ScgiRequestParserTest.cpp +36 -16
  657. data/test/cxx/ServerInstanceDirTest.cpp +1 -1
  658. data/test/cxx/StringMapTest.cpp +61 -0
  659. data/test/cxx/TemplateTest.cpp +118 -0
  660. data/test/cxx/TestSupport.cpp +25 -68
  661. data/test/cxx/TestSupport.h +81 -41
  662. data/test/cxx/{LoggingTest.cpp → UnionStationTest.cpp} +79 -74
  663. data/test/cxx/UtilsTest.cpp +59 -5
  664. data/test/integration_tests/apache2_tests.rb +2 -2
  665. data/test/integration_tests/nginx_tests.rb +1 -1
  666. data/test/integration_tests/spec_helper.rb +7 -5
  667. data/test/oxt/oxt_test_main.cpp +2 -0
  668. data/test/oxt/syscall_interruption_test.cpp +1 -0
  669. data/test/ruby/classic_rails/loader_spec.rb +48 -0
  670. data/test/ruby/classic_rails/preloader_spec.rb +54 -0
  671. data/test/ruby/rack/loader_spec.rb +62 -0
  672. data/test/ruby/rack/preloader_spec.rb +74 -0
  673. data/test/ruby/{abstract_request_handler_spec.rb → request_handler_spec.rb} +31 -68
  674. data/test/ruby/shared/loader_spec.rb +241 -0
  675. data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +141 -182
  676. data/test/ruby/shared/ruby_loader_spec.rb +55 -0
  677. data/test/ruby/spec_helper.rb +8 -53
  678. data/test/ruby/utils/file_system_watcher_spec.rb +9 -1
  679. data/test/ruby/utils_spec.rb +10 -683
  680. data/test/stub/rack/config.ru +28 -3
  681. data/test/stub/rack/start.rb +47 -0
  682. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/Rakefile +0 -0
  683. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/application_controller.rb +0 -2
  684. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_1.rb +0 -0
  685. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_2.rb +0 -0
  686. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/foo_controller.rb +0 -0
  687. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/helpers/application_helper.rb +0 -0
  688. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/boot.rb +0 -0
  689. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/database.yml +3 -3
  690. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environment.rb +5 -2
  691. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/development.rb +0 -0
  692. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/production.rb +0 -0
  693. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/staging.rb +0 -0
  694. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/inflections.rb +0 -0
  695. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/mime_types.rb +0 -0
  696. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/routes.rb +1 -0
  697. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/about +0 -0
  698. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/console +0 -0
  699. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/dbconsole +0 -0
  700. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/destroy +0 -0
  701. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/generate +0 -0
  702. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/benchmarker +0 -0
  703. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/profiler +0 -0
  704. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/request +0 -0
  705. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/plugin +0 -0
  706. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/inspector +0 -0
  707. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/reaper +0 -0
  708. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/spawner +0 -0
  709. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/runner +0 -0
  710. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/server +0 -0
  711. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Gemfile +0 -0
  712. data/test/stub/rails3.0/Gemfile.lock +80 -0
  713. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Rakefile +0 -0
  714. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/controllers/application_controller.rb +0 -0
  715. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/helpers/application_helper.rb +0 -0
  716. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/views/layouts/application.html.erb +0 -0
  717. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config.ru +0 -0
  718. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/application.rb +0 -0
  719. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/boot.rb +0 -0
  720. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/database.yml +0 -0
  721. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environment.rb +0 -0
  722. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/development.rb +0 -0
  723. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/production.rb +0 -0
  724. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/test.rb +0 -0
  725. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/backtrace_silencers.rb +0 -0
  726. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/inflections.rb +0 -0
  727. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/mime_types.rb +0 -0
  728. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/passenger.rb +0 -0
  729. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/secret_token.rb +0 -0
  730. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/session_store.rb +0 -0
  731. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/locales/en.yml +0 -0
  732. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/routes.rb +0 -0
  733. data/test/stub/{rails_apps/3.0/empty → rails3.0}/db/seeds.rb +0 -0
  734. data/test/stub/{rails_apps/3.0/empty → rails3.0}/doc/README_FOR_APP +0 -0
  735. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/404.html +0 -0
  736. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/422.html +0 -0
  737. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/500.html +0 -0
  738. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/favicon.ico +0 -0
  739. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/index.html +0 -0
  740. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/robots.txt +0 -0
  741. data/test/stub/{rails_apps/3.0/empty → rails3.0}/script/rails +0 -0
  742. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/performance/browsing_test.rb +0 -0
  743. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/test_helper.rb +0 -0
  744. data/test/stub/start_error.pl +24 -0
  745. data/test/stub/wsgi/passenger_wsgi.py +71 -3
  746. data/test/support/apache2_controller.rb +2 -2
  747. data/test/support/placebo-preloader.rb +88 -0
  748. data/test/support/test_helper.rb +1 -14
  749. data/test/tut/tut.h +11 -4
  750. metadata +590 -326
  751. data.tar.gz.asc +0 -12
  752. data/PACKAGING.TXT +0 -25
  753. data/build/config.rb +0 -46
  754. data/ext/apache2/HelperAgent.cpp +0 -364
  755. data/ext/boost/call_traits.hpp +0 -24
  756. data/ext/boost/detail/call_traits.hpp +0 -164
  757. data/ext/common/AbstractSpawnManager.h +0 -110
  758. data/ext/common/AgentBase.cpp +0 -432
  759. data/ext/common/ApplicationPool/Client.h +0 -788
  760. data/ext/common/ApplicationPool/Interface.h +0 -295
  761. data/ext/common/ApplicationPool/Pool.h +0 -1327
  762. data/ext/common/ApplicationPool/Server.h +0 -479
  763. data/ext/common/MessageChannel.h +0 -494
  764. data/ext/common/PoolOptions.h +0 -518
  765. data/ext/common/Process.h +0 -253
  766. data/ext/common/Session.h +0 -436
  767. data/ext/common/SpawnManager.h +0 -611
  768. data/ext/google/ChangeLog +0 -167
  769. data/ext/google/dense_hash_map +0 -310
  770. data/ext/google/dense_hash_set +0 -287
  771. data/ext/google/sparse_hash_map +0 -294
  772. data/ext/google/sparse_hash_set +0 -275
  773. data/ext/google/sparsehash/densehashtable.h +0 -1062
  774. data/ext/google/sparsehash/sparseconfig.h +0 -55
  775. data/ext/google/sparsehash/sparsehashtable.h +0 -1015
  776. data/ext/google/sparsetable +0 -1468
  777. data/ext/google/type_traits.h +0 -250
  778. data/ext/nginx/HelperAgent.cpp +0 -1355
  779. data/ext/nginx/ScgiRequestParser.h +0 -375
  780. data/ext/oxt/backtrace.cpp +0 -185
  781. data/ext/oxt/tracable_exception.cpp +0 -89
  782. data/helper-scripts/passenger-spawn-server +0 -106
  783. data/lib/phusion_passenger/abstract_request_handler.rb +0 -766
  784. data/lib/phusion_passenger/abstract_server.rb +0 -372
  785. data/lib/phusion_passenger/abstract_server_collection.rb +0 -335
  786. data/lib/phusion_passenger/app_process.rb +0 -174
  787. data/lib/phusion_passenger/classic_rails/application_spawner.rb +0 -344
  788. data/lib/phusion_passenger/classic_rails/framework_spawner.rb +0 -311
  789. data/lib/phusion_passenger/exceptions.rb +0 -103
  790. data/lib/phusion_passenger/html_template.rb +0 -107
  791. data/lib/phusion_passenger/rack/application_spawner.rb +0 -231
  792. data/lib/phusion_passenger/spawn_manager.rb +0 -359
  793. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +0 -38
  794. data/lib/phusion_passenger/templates/app_init_error.html.erb +0 -64
  795. data/lib/phusion_passenger/templates/database_error.html.erb +0 -66
  796. data/lib/phusion_passenger/templates/error_layout.html.erb +0 -39
  797. data/lib/phusion_passenger/templates/framework_init_error.html.erb +0 -39
  798. data/lib/phusion_passenger/templates/general_error.html.erb +0 -22
  799. data/lib/phusion_passenger/templates/load_error.html.erb +0 -46
  800. data/lib/phusion_passenger/templates/version_not_found.html.erb +0 -34
  801. data/lib/phusion_passenger/utils/rewindable_input.rb +0 -125
  802. data/lib/phusion_passenger/wsgi/application_spawner.rb +0 -108
  803. data/test/config.yml.example +0 -41
  804. data/test/cxx/ApplicationPool_PoolTest.cpp +0 -33
  805. data/test/cxx/ApplicationPool_PoolTestCases.cpp +0 -1029
  806. data/test/cxx/ApplicationPool_ServerTest.cpp +0 -308
  807. data/test/cxx/ApplicationPool_Server_PoolTest.cpp +0 -80
  808. data/test/cxx/MessageChannelTest.cpp +0 -557
  809. data/test/cxx/PoolOptionsTest.cpp +0 -116
  810. data/test/cxx/SpawnManagerTest.cpp +0 -161
  811. data/test/ruby/abstract_server_collection_spec.rb +0 -247
  812. data/test/ruby/abstract_server_spec.rb +0 -61
  813. data/test/ruby/app_process_spec.rb +0 -43
  814. data/test/ruby/classic_rails/application_spawner_spec.rb +0 -89
  815. data/test/ruby/classic_rails/framework_spawner_spec.rb +0 -92
  816. data/test/ruby/rack/application_spawner_spec.rb +0 -116
  817. data/test/ruby/shared/abstract_server_spec.rb +0 -23
  818. data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +0 -38
  819. data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +0 -19
  820. data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +0 -15
  821. data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +0 -27
  822. data/test/ruby/shared/spawners/preloading_spawner_spec.rb +0 -29
  823. data/test/ruby/shared/spawners/reload_all_spec.rb +0 -36
  824. data/test/ruby/shared/spawners/reload_single_spec.rb +0 -52
  825. data/test/ruby/shared/spawners/spawn_server_spec.rb +0 -28
  826. data/test/ruby/shared/spawners/spawner_spec.rb +0 -273
  827. data/test/ruby/shared/utils/pseudo_io_spec.rb +0 -60
  828. data/test/ruby/spawn_manager_spec.rb +0 -134
  829. data/test/ruby/wsgi/application_spawner_spec.rb +0 -50
  830. data/test/stub/message_channel.rb +0 -11
  831. data/test/stub/message_channel_2.rb +0 -12
  832. data/test/stub/message_channel_3.rb +0 -19
  833. data/test/stub/rails_apps/3.0/empty/Gemfile.lock +0 -73
  834. data/test/stub/spawn_server.rb +0 -22
  835. metadata.gz.asc +0 -12
@@ -136,22 +136,6 @@ template < std::size_t Bits >
136
136
  template < >
137
137
  struct low_bits_mask_t< ::std::numeric_limits<unsigned char>::digits >;
138
138
 
139
- #if USHRT_MAX > UCHAR_MAX
140
- template < >
141
- struct low_bits_mask_t< ::std::numeric_limits<unsigned short>::digits >;
142
- #endif
143
-
144
- #if UINT_MAX > USHRT_MAX
145
- template < >
146
- struct low_bits_mask_t< ::std::numeric_limits<unsigned int>::digits >;
147
- #endif
148
-
149
- #if ULONG_MAX > UINT_MAX
150
- template < >
151
- struct low_bits_mask_t< ::std::numeric_limits<unsigned long>::digits >;
152
- #endif
153
-
154
-
155
139
  // From <boost/integer/static_log2.hpp> ------------------------------------//
156
140
 
157
141
  template <static_log2_argument_type Value >
@@ -5,7 +5,7 @@
5
5
  * accompanying file LICENSE_1_0.txt or copy at
6
6
  * http://www.boost.org/LICENSE_1_0.txt)
7
7
  *
8
- * $Id: integer_traits.hpp 58381 2009-12-14 18:14:48Z johnmaddock $
8
+ * $Id: integer_traits.hpp 76784 2012-01-29 21:58:13Z eric_niebler $
9
9
  *
10
10
  * Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers
11
11
  */
@@ -227,7 +227,7 @@ class integer_traits< ::boost::ulong_long_type>
227
227
  template<>
228
228
  class integer_traits< ::boost::long_long_type>
229
229
  : public std::numeric_limits< ::boost::long_long_type>,
230
- public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) - 1)), ~(1LL << (sizeof(::boost::long_long_type) - 1))>
230
+ public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1)), ~(1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1))>
231
231
  { };
232
232
 
233
233
  template<>
@@ -1,4 +1,4 @@
1
- // interator.hpp workarounds for non-conforming standard libraries ---------//
1
+ // iterator.hpp workarounds for non-conforming standard libraries ---------//
2
2
 
3
3
  // (C) Copyright Beman Dawes 2000. Distributed under the Boost
4
4
  // Software License, Version 1.0. (See accompanying file
@@ -24,15 +24,9 @@
24
24
 
25
25
  #ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
26
26
  # include <boost/type_traits/remove_reference.hpp>
27
-
28
- # if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
29
- # include <boost/type_traits/add_reference.hpp>
30
- # endif
31
-
32
- #else
33
- # include <boost/type_traits/add_reference.hpp>
34
27
  #endif
35
28
 
29
+ #include <boost/type_traits/add_reference.hpp>
36
30
  #include <boost/iterator/detail/config_def.hpp>
37
31
 
38
32
  #include <boost/iterator/iterator_traits.hpp>
@@ -105,6 +105,7 @@ namespace boost
105
105
 
106
106
  typedef typename remove_const<ValueParam>::type value_type;
107
107
 
108
+ // Not the real associated pointer type
108
109
  typedef typename mpl::eval_if<
109
110
  boost::detail::iterator_writability_disabled<ValueParam,Reference>
110
111
  , add_pointer<const value_type>
@@ -323,7 +324,7 @@ namespace boost
323
324
 
324
325
  static type make(Reference x)
325
326
  {
326
- return implicit_cast<type>(&x);
327
+ return boost::implicit_cast<type>(&x);
327
328
  }
328
329
  };
329
330
 
@@ -617,6 +618,12 @@ namespace boost
617
618
  Value, CategoryOrTraversal, Reference, Difference
618
619
  > associated_types;
619
620
 
621
+ typedef boost::detail::operator_arrow_result<
622
+ typename associated_types::value_type
623
+ , Reference
624
+ , typename associated_types::pointer
625
+ > pointer_;
626
+
620
627
  protected:
621
628
  // For use by derived classes
622
629
  typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
@@ -626,7 +633,9 @@ namespace boost
626
633
  typedef typename associated_types::value_type value_type;
627
634
  typedef Reference reference;
628
635
  typedef Difference difference_type;
629
- typedef typename associated_types::pointer pointer;
636
+
637
+ typedef typename pointer_::type pointer;
638
+
630
639
  typedef typename associated_types::iterator_category iterator_category;
631
640
 
632
641
  reference operator*() const
@@ -634,18 +643,9 @@ namespace boost
634
643
  return iterator_core_access::dereference(this->derived());
635
644
  }
636
645
 
637
- typename boost::detail::operator_arrow_result<
638
- value_type
639
- , reference
640
- , pointer
641
- >::type
642
- operator->() const
646
+ pointer operator->() const
643
647
  {
644
- return boost::detail::operator_arrow_result<
645
- value_type
646
- , reference
647
- , pointer
648
- >::make(*this->derived());
648
+ return pointer_::make(*this->derived());
649
649
  }
650
650
 
651
651
  typename boost::detail::operator_brackets_result<Derived,Value,reference>::type
@@ -20,6 +20,8 @@
20
20
  #include <boost/type_traits/is_reference.hpp>
21
21
  #include <boost/type_traits/remove_const.hpp>
22
22
  #include <boost/type_traits/remove_reference.hpp>
23
+ #include <boost/utility/result_of.hpp>
24
+
23
25
 
24
26
  #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
25
27
  # include <boost/type_traits/is_base_and_derived.hpp>
@@ -35,33 +37,16 @@ namespace boost
35
37
 
36
38
  namespace detail
37
39
  {
38
-
39
- template <class UnaryFunc>
40
- struct function_object_result
41
- {
42
- typedef typename UnaryFunc::result_type type;
43
- };
44
-
45
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
46
- template <class Return, class Argument>
47
- struct function_object_result<Return(*)(Argument)>
48
- {
49
- typedef Return type;
50
- };
51
- #endif
52
-
53
40
  // Compute the iterator_adaptor instantiation to be used for transform_iterator
54
41
  template <class UnaryFunc, class Iterator, class Reference, class Value>
55
42
  struct transform_iterator_base
56
43
  {
57
44
  private:
58
45
  // By default, dereferencing the iterator yields the same as
59
- // the function. Do we need to adjust the way
60
- // function_object_result is computed for the standard
61
- // proposal (e.g. using Doug's result_of)?
46
+ // the function.
62
47
  typedef typename ia_dflt_help<
63
48
  Reference
64
- , function_object_result<UnaryFunc>
49
+ , result_of<UnaryFunc(typename std::iterator_traits<Iterator>::reference)>
65
50
  >::type reference;
66
51
 
67
52
  // To get the default for Value: remove any reference on the
@@ -113,7 +98,7 @@ namespace boost
113
98
  #endif
114
99
  }
115
100
 
116
- template<
101
+ template <
117
102
  class OtherUnaryFunction
118
103
  , class OtherIterator
119
104
  , class OtherReference
@@ -1,6 +1,12 @@
1
1
  #ifndef BOOST_LEXICAL_CAST_INCLUDED
2
2
  #define BOOST_LEXICAL_CAST_INCLUDED
3
3
 
4
+ // MS compatible compilers support #pragma once
5
+
6
+ #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7
+ # pragma once
8
+ #endif
9
+
4
10
  // Boost lexical_cast.hpp header -------------------------------------------//
5
11
  //
6
12
  // See http://www.boost.org/libs/conversion for documentation.
@@ -11,28 +17,75 @@
11
17
  // enhanced with contributions from Terje Slettebo,
12
18
  // with additional fixes and suggestions from Gennaro Prota,
13
19
  // Beman Dawes, Dave Abrahams, Daryle Walker, Peter Dimov,
14
- // Alexander Nasonov and other Boosters
15
- // when: November 2000, March 2003, June 2005, June 2006
20
+ // Alexander Nasonov, Antony Polukhin, Justin Viiret, Michael Hofmann,
21
+ // Cheng Yang, Matthew Bradbury, David W. Birdsall and other Boosters
22
+ // when: November 2000, March 2003, June 2005, June 2006, March 2011 - 2012
23
+
24
+ #include <boost/config.hpp>
25
+ #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
26
+ #define BOOST_LCAST_NO_WCHAR_T
27
+ #endif
28
+
29
+ #if (defined(__MINGW32__) || defined(__MINGW64__)) && (__GNUC__ == 4) \
30
+ && ((__GNUC_MINOR__ == 4) || (__GNUC_MINOR__ == 5)) && defined(__STRICT_ANSI__) \
31
+ && !defined(BOOST_LCAST_NO_WCHAR_T)
32
+
33
+ // workaround for a mingw bug
34
+ // http://sourceforge.net/tracker/index.php?func=detail&aid=2373234&group_id=2435&atid=102435
35
+ #include <_mingw.h>
36
+ #if (__GNUC_MINOR__ == 4)
37
+ extern "C" {
38
+ _CRTIMP int __cdecl swprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...);
39
+ _CRTIMP int __cdecl vswprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...);
40
+ }
41
+ #endif
42
+ #if (__GNUC_MINOR__ == 5)
43
+ extern "C" {
44
+ _CRTIMP int __cdecl swprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , ...);
45
+ _CRTIMP int __cdecl vswprintf(wchar_t * __restrict__ , const wchar_t * __restrict__ , va_list);
46
+ }
47
+ #endif
48
+ #endif
16
49
 
17
50
  #include <climits>
18
51
  #include <cstddef>
19
52
  #include <istream>
20
53
  #include <string>
54
+ #include <cstring>
55
+ #include <cstdio>
21
56
  #include <typeinfo>
22
57
  #include <exception>
23
- #include <boost/config.hpp>
58
+ #include <cmath>
24
59
  #include <boost/limits.hpp>
25
60
  #include <boost/mpl/if.hpp>
26
61
  #include <boost/throw_exception.hpp>
27
62
  #include <boost/type_traits/is_pointer.hpp>
63
+ #include <boost/type_traits/is_integral.hpp>
64
+ #include <boost/type_traits/is_arithmetic.hpp>
65
+ #include <boost/type_traits/remove_pointer.hpp>
66
+ #include <boost/numeric/conversion/cast.hpp>
67
+ #include <boost/type_traits/ice.hpp>
28
68
  #include <boost/type_traits/make_unsigned.hpp>
29
- #include <boost/call_traits.hpp>
69
+ #include <boost/type_traits/is_signed.hpp>
70
+ #include <boost/math/special_functions/sign.hpp>
71
+ #include <boost/math/special_functions/fpclassify.hpp>
30
72
  #include <boost/static_assert.hpp>
31
73
  #include <boost/detail/lcast_precision.hpp>
32
74
  #include <boost/detail/workaround.hpp>
75
+ #if !defined(__SUNPRO_CC)
76
+ #include <boost/container/container_fwd.hpp>
77
+ #endif // !defined(__SUNPRO_CC)
78
+ #ifndef BOOST_NO_CWCHAR
79
+ # include <cwchar>
80
+ #endif
33
81
 
34
82
  #ifndef BOOST_NO_STD_LOCALE
35
- #include <locale>
83
+ # include <locale>
84
+ #else
85
+ # ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
86
+ # warning "Unable to use <locale> header. boost::lexical_cast will use the 'C' locale."
87
+ # define BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
88
+ # endif
36
89
  #endif
37
90
 
38
91
  #ifdef BOOST_NO_STRINGSTREAM
@@ -41,10 +94,6 @@
41
94
  #include <sstream>
42
95
  #endif
43
96
 
44
- #if defined(BOOST_NO_STRINGSTREAM) || defined(BOOST_NO_STD_WSTRING)
45
- #define BOOST_LCAST_NO_WCHAR_T
46
- #endif
47
-
48
97
  #ifdef BOOST_NO_TYPEID
49
98
  #define BOOST_LCAST_THROW_BAD_CAST(S, T) throw_exception(bad_lexical_cast())
50
99
  #else
@@ -55,7 +104,13 @@
55
104
  namespace boost
56
105
  {
57
106
  // exception used to indicate runtime lexical_cast failure
58
- class bad_lexical_cast : public std::bad_cast
107
+ class bad_lexical_cast :
108
+ // workaround MSVC bug with std::bad_cast when _HAS_EXCEPTIONS == 0
109
+ #if defined(BOOST_MSVC) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
110
+ public std::exception
111
+ #else
112
+ public std::bad_cast
113
+ #endif
59
114
 
60
115
  #if defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, < 0x560 )
61
116
  // under bcc32 5.5.1 bad_cast doesn't derive from exception
@@ -104,60 +159,110 @@ namespace boost
104
159
 
105
160
  namespace detail // selectors for choosing stream character type
106
161
  {
107
- template<typename Type>
108
- struct stream_char
109
- {
110
- typedef char type;
111
- };
162
+ template<typename Type>
163
+ struct stream_char
164
+ {
165
+ typedef char type;
166
+ };
112
167
 
113
168
  #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
114
- template<class CharT, class Traits, class Alloc>
115
- struct stream_char< std::basic_string<CharT,Traits,Alloc> >
116
- {
117
- typedef CharT type;
118
- };
169
+ template<class CharT, class Traits, class Alloc>
170
+ struct stream_char< std::basic_string<CharT,Traits,Alloc> >
171
+ {
172
+ typedef CharT type;
173
+ };
174
+
175
+ #if !defined(__SUNPRO_CC)
176
+ template<class CharT, class Traits, class Alloc>
177
+ struct stream_char< ::boost::container::basic_string<CharT,Traits,Alloc> >
178
+ {
179
+ typedef CharT type;
180
+ };
181
+ #endif // !defined(__SUNPRO_CC)
119
182
  #endif
120
183
 
121
184
  #ifndef BOOST_LCAST_NO_WCHAR_T
122
185
  #ifndef BOOST_NO_INTRINSIC_WCHAR_T
123
- template<>
124
- struct stream_char<wchar_t>
125
- {
126
- typedef wchar_t type;
127
- };
186
+ template<>
187
+ struct stream_char<wchar_t>
188
+ {
189
+ typedef wchar_t type;
190
+ };
128
191
  #endif
129
192
 
130
- template<>
131
- struct stream_char<wchar_t *>
132
- {
133
- typedef wchar_t type;
134
- };
193
+ template<>
194
+ struct stream_char<wchar_t *>
195
+ {
196
+ typedef wchar_t type;
197
+ };
135
198
 
136
- template<>
137
- struct stream_char<const wchar_t *>
138
- {
139
- typedef wchar_t type;
140
- };
199
+ template<>
200
+ struct stream_char<const wchar_t *>
201
+ {
202
+ typedef wchar_t type;
203
+ };
141
204
 
142
205
  #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
143
- template<>
144
- struct stream_char<std::wstring>
145
- {
146
- typedef wchar_t type;
147
- };
206
+ template<>
207
+ struct stream_char<std::wstring>
208
+ {
209
+ typedef wchar_t type;
210
+ };
211
+ #endif
212
+ #endif
213
+
214
+
215
+ #ifndef BOOST_NO_CHAR16_T
216
+
217
+ template<>
218
+ struct stream_char<char16_t>
219
+ {
220
+ typedef char16_t type;
221
+ };
222
+
223
+ template<>
224
+ struct stream_char<char16_t *>
225
+ {
226
+ typedef char16_t type;
227
+ };
228
+
229
+ template<>
230
+ struct stream_char<const char16_t *>
231
+ {
232
+ typedef char16_t type;
233
+ };
234
+
148
235
  #endif
236
+
237
+ #ifndef BOOST_NO_CHAR32_T
238
+
239
+ template<>
240
+ struct stream_char<char32_t>
241
+ {
242
+ typedef char32_t type;
243
+ };
244
+
245
+ template<>
246
+ struct stream_char<char32_t *>
247
+ {
248
+ typedef char32_t type;
249
+ };
250
+
251
+ template<>
252
+ struct stream_char<const char32_t *>
253
+ {
254
+ typedef char32_t type;
255
+ };
256
+
149
257
  #endif
150
258
 
151
259
  template<typename TargetChar, typename SourceChar>
152
260
  struct widest_char
153
261
  {
154
- typedef TargetChar type;
155
- };
156
-
157
- template<>
158
- struct widest_char<char, wchar_t>
159
- {
160
- typedef wchar_t type;
262
+ typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
263
+ (sizeof(TargetChar) > sizeof(SourceChar))
264
+ , TargetChar
265
+ , SourceChar >::type type;
161
266
  };
162
267
  }
163
268
 
@@ -188,140 +293,76 @@ namespace boost
188
293
  typedef Traits type;
189
294
  };
190
295
 
191
- template<class CharT, class Traits, class Alloc1, class Alloc2>
296
+ #if !defined(__SUNPRO_CC)
297
+ template<class CharT, class Traits, class Alloc, class Source>
192
298
  struct deduce_char_traits< CharT
193
- , std::basic_string<CharT,Traits,Alloc1>
194
- , std::basic_string<CharT,Traits,Alloc2>
299
+ , ::boost::container::basic_string<CharT,Traits,Alloc>
300
+ , Source
195
301
  >
196
302
  {
197
303
  typedef Traits type;
198
304
  };
199
- #endif
200
- }
201
-
202
- namespace detail // lcast_src_length
203
- {
204
- // Return max. length of string representation of Source;
205
- // 0 if unlimited (with exceptions for some types, see below).
206
- // Values with limited string representation are placed to
207
- // the buffer locally defined in lexical_cast function.
208
- // 1 is returned for few types such as CharT const* or
209
- // std::basic_string<CharT> that already have an internal
210
- // buffer ready to be reused by lexical_stream_limited_src.
211
- // Each specialization should have a correspondent operator<<
212
- // defined in lexical_stream_limited_src.
213
- template< class CharT // A result of widest_char transformation.
214
- , class Source // Source type of lexical_cast.
215
- >
216
- struct lcast_src_length
217
- {
218
- BOOST_STATIC_CONSTANT(std::size_t, value = 0);
219
- // To check coverage, build the test with
220
- // bjam --v2 profile optimization=off
221
- static void check_coverage() {}
222
- };
223
-
224
- template<>
225
- struct lcast_src_length<char, bool>
226
- {
227
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
228
- static void check_coverage() {}
229
- };
230
-
231
- template<>
232
- struct lcast_src_length<char, char>
233
- {
234
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
235
- static void check_coverage() {}
236
- };
237
-
238
- // No specializations for:
239
- // lcast_src_length<char, signed char>
240
- // lcast_src_length<char, unsigned char>
241
- // lcast_src_length<char, signed char*>
242
- // lcast_src_length<char, unsigned char*>
243
- // lcast_src_length<char, signed char const*>
244
- // lcast_src_length<char, unsigned char const*>
245
-
246
- #ifndef BOOST_LCAST_NO_WCHAR_T
247
- template<>
248
- struct lcast_src_length<wchar_t, bool>
249
- {
250
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
251
- static void check_coverage() {}
252
- };
253
-
254
- template<>
255
- struct lcast_src_length<wchar_t, char>
256
- {
257
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
258
- static void check_coverage() {}
259
- };
260
305
 
261
- #ifndef BOOST_NO_INTRINSIC_WCHAR_T
262
- template<>
263
- struct lcast_src_length<wchar_t, wchar_t>
306
+ template<class CharT, class Target, class Traits, class Alloc>
307
+ struct deduce_char_traits< CharT
308
+ , Target
309
+ , ::boost::container::basic_string<CharT,Traits,Alloc>
310
+ >
264
311
  {
265
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
266
- static void check_coverage() {}
312
+ typedef Traits type;
267
313
  };
268
- #endif
269
- #endif
270
314
 
271
- template<>
272
- struct lcast_src_length<char, char const*>
315
+ template<class CharT, class Traits, class Alloc1, class Alloc2>
316
+ struct deduce_char_traits< CharT
317
+ , std::basic_string<CharT,Traits,Alloc1>
318
+ , std::basic_string<CharT,Traits,Alloc2>
319
+ >
273
320
  {
274
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
275
- static void check_coverage() {}
321
+ typedef Traits type;
276
322
  };
277
323
 
278
- template<>
279
- struct lcast_src_length<char, char*>
324
+ template<class CharT, class Traits, class Alloc1, class Alloc2>
325
+ struct deduce_char_traits< CharT
326
+ , ::boost::container::basic_string<CharT,Traits,Alloc1>
327
+ , ::boost::container::basic_string<CharT,Traits,Alloc2>
328
+ >
280
329
  {
281
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
282
- static void check_coverage() {}
330
+ typedef Traits type;
283
331
  };
284
332
 
285
- #ifndef BOOST_LCAST_NO_WCHAR_T
286
- template<>
287
- struct lcast_src_length<wchar_t, wchar_t const*>
333
+ template<class CharT, class Traits, class Alloc1, class Alloc2>
334
+ struct deduce_char_traits< CharT
335
+ , ::boost::container::basic_string<CharT,Traits,Alloc1>
336
+ , std::basic_string<CharT,Traits,Alloc2>
337
+ >
288
338
  {
289
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
290
- static void check_coverage() {}
339
+ typedef Traits type;
291
340
  };
292
341
 
293
- template<>
294
- struct lcast_src_length<wchar_t, wchar_t*>
342
+ template<class CharT, class Traits, class Alloc1, class Alloc2>
343
+ struct deduce_char_traits< CharT
344
+ , std::basic_string<CharT,Traits,Alloc1>
345
+ , ::boost::container::basic_string<CharT,Traits,Alloc2>
346
+ >
295
347
  {
296
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
297
- static void check_coverage() {}
348
+ typedef Traits type;
298
349
  };
350
+ #endif // !defined(__SUNPRO_CC)
299
351
  #endif
352
+ }
300
353
 
301
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
302
- template<class CharT, class Traits, class Alloc>
303
- struct lcast_src_length< CharT, std::basic_string<CharT,Traits,Alloc> >
304
- {
305
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
306
- static void check_coverage() {}
307
- };
308
- #else
309
- template<>
310
- struct lcast_src_length< char, std::basic_string<char> >
311
- {
312
- BOOST_STATIC_CONSTANT(std::size_t, value = 1);
313
- static void check_coverage() {}
314
- };
315
-
316
- #ifndef BOOST_LCAST_NO_WCHAR_T
317
- template<>
318
- struct lcast_src_length< wchar_t, std::basic_string<wchar_t> >
354
+ namespace detail // lcast_src_length
355
+ {
356
+ // Return max. length of string representation of Source;
357
+ template< class Source // Source type of lexical_cast.
358
+ >
359
+ struct lcast_src_length
319
360
  {
320
361
  BOOST_STATIC_CONSTANT(std::size_t, value = 1);
362
+ // To check coverage, build the test with
363
+ // bjam --v2 profile optimization=off
321
364
  static void check_coverage() {}
322
365
  };
323
- #endif
324
- #endif
325
366
 
326
367
  // Helper for integral types.
327
368
  // Notes on length calculation:
@@ -342,7 +383,7 @@ namespace boost
342
383
  #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
343
384
  BOOST_STATIC_CONSTANT(std::size_t, value =
344
385
  std::numeric_limits<Source>::is_signed +
345
- std::numeric_limits<Source>::is_specialized + // == 1
386
+ std::numeric_limits<Source>::is_specialized + /* == 1 */
346
387
  std::numeric_limits<Source>::digits10 * 2
347
388
  );
348
389
  #else
@@ -350,20 +391,12 @@ namespace boost
350
391
  BOOST_STATIC_ASSERT(sizeof(Source) * CHAR_BIT <= 256);
351
392
  #endif
352
393
  };
353
-
354
- #define BOOST_LCAST_DEF1(CharT, T) \
355
- template<> struct lcast_src_length<CharT, T> \
394
+ // TODO: FIX for char16_t, char32_t, we can ignore CharT
395
+ #define BOOST_LCAST_DEF(T) \
396
+ template<> struct lcast_src_length<T> \
356
397
  : lcast_src_length_integral<T> \
357
398
  { static void check_coverage() {} };
358
399
 
359
- #ifdef BOOST_LCAST_NO_WCHAR_T
360
- #define BOOST_LCAST_DEF(T) BOOST_LCAST_DEF1(char, T)
361
- #else
362
- #define BOOST_LCAST_DEF(T) \
363
- BOOST_LCAST_DEF1(char, T) \
364
- BOOST_LCAST_DEF1(wchar_t, T)
365
- #endif
366
-
367
400
  BOOST_LCAST_DEF(short)
368
401
  BOOST_LCAST_DEF(unsigned short)
369
402
  BOOST_LCAST_DEF(int)
@@ -379,7 +412,6 @@ namespace boost
379
412
  #endif
380
413
 
381
414
  #undef BOOST_LCAST_DEF
382
- #undef BOOST_LCAST_DEF1
383
415
 
384
416
  #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
385
417
  // Helper for floating point types.
@@ -405,53 +437,30 @@ namespace boost
405
437
  };
406
438
 
407
439
  template<>
408
- struct lcast_src_length<char,float>
440
+ struct lcast_src_length<float>
409
441
  : lcast_src_length_floating<float>
410
442
  {
411
443
  static void check_coverage() {}
412
444
  };
413
445
 
414
446
  template<>
415
- struct lcast_src_length<char,double>
447
+ struct lcast_src_length<double>
416
448
  : lcast_src_length_floating<double>
417
449
  {
418
450
  static void check_coverage() {}
419
451
  };
420
452
 
421
453
  template<>
422
- struct lcast_src_length<char,long double>
454
+ struct lcast_src_length<long double>
423
455
  : lcast_src_length_floating<long double>
424
456
  {
425
457
  static void check_coverage() {}
426
458
  };
427
459
 
428
- #ifndef BOOST_LCAST_NO_WCHAR_T
429
- template<>
430
- struct lcast_src_length<wchar_t,float>
431
- : lcast_src_length_floating<float>
432
- {
433
- static void check_coverage() {}
434
- };
435
-
436
- template<>
437
- struct lcast_src_length<wchar_t,double>
438
- : lcast_src_length_floating<double>
439
- {
440
- static void check_coverage() {}
441
- };
442
-
443
- template<>
444
- struct lcast_src_length<wchar_t,long double>
445
- : lcast_src_length_floating<long double>
446
- {
447
- static void check_coverage() {}
448
- };
449
-
450
- #endif // #ifndef BOOST_LCAST_NO_WCHAR_T
451
460
  #endif // #ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION
452
461
  }
453
462
 
454
- namespace detail // '0' and '-' constants
463
+ namespace detail // '0', '+' and '-' constants
455
464
  {
456
465
  template<typename CharT> struct lcast_char_constants;
457
466
 
@@ -460,6 +469,10 @@ namespace boost
460
469
  {
461
470
  BOOST_STATIC_CONSTANT(char, zero = '0');
462
471
  BOOST_STATIC_CONSTANT(char, minus = '-');
472
+ BOOST_STATIC_CONSTANT(char, plus = '+');
473
+ BOOST_STATIC_CONSTANT(char, lowercase_e = 'e');
474
+ BOOST_STATIC_CONSTANT(char, capital_e = 'E');
475
+ BOOST_STATIC_CONSTANT(char, c_decimal_separator = '.');
463
476
  };
464
477
 
465
478
  #ifndef BOOST_LCAST_NO_WCHAR_T
@@ -468,15 +481,38 @@ namespace boost
468
481
  {
469
482
  BOOST_STATIC_CONSTANT(wchar_t, zero = L'0');
470
483
  BOOST_STATIC_CONSTANT(wchar_t, minus = L'-');
484
+ BOOST_STATIC_CONSTANT(wchar_t, plus = L'+');
485
+ BOOST_STATIC_CONSTANT(wchar_t, lowercase_e = L'e');
486
+ BOOST_STATIC_CONSTANT(wchar_t, capital_e = L'E');
487
+ BOOST_STATIC_CONSTANT(wchar_t, c_decimal_separator = L'.');
471
488
  };
472
489
  #endif
473
- }
474
490
 
475
- namespace detail // lexical_streambuf_fake
476
- {
477
- struct lexical_streambuf_fake
478
- {
491
+ #ifndef BOOST_NO_CHAR16_T
492
+ template<>
493
+ struct lcast_char_constants<char16_t>
494
+ {
495
+ BOOST_STATIC_CONSTANT(char16_t, zero = u'0');
496
+ BOOST_STATIC_CONSTANT(char16_t, minus = u'-');
497
+ BOOST_STATIC_CONSTANT(char16_t, plus = u'+');
498
+ BOOST_STATIC_CONSTANT(char16_t, lowercase_e = u'e');
499
+ BOOST_STATIC_CONSTANT(char16_t, capital_e = u'E');
500
+ BOOST_STATIC_CONSTANT(char16_t, c_decimal_separator = u'.');
501
+ };
502
+ #endif
503
+
504
+ #ifndef BOOST_NO_CHAR32_T
505
+ template<>
506
+ struct lcast_char_constants<char32_t>
507
+ {
508
+ BOOST_STATIC_CONSTANT(char32_t, zero = U'0');
509
+ BOOST_STATIC_CONSTANT(char32_t, minus = U'-');
510
+ BOOST_STATIC_CONSTANT(char32_t, plus = U'+');
511
+ BOOST_STATIC_CONSTANT(char32_t, lowercase_e = U'e');
512
+ BOOST_STATIC_CONSTANT(char32_t, capital_e = U'E');
513
+ BOOST_STATIC_CONSTANT(char32_t, c_decimal_separator = U'.');
479
514
  };
515
+ #endif
480
516
  }
481
517
 
482
518
  namespace detail // lcast_to_unsigned
@@ -506,218 +542,826 @@ namespace boost
506
542
  namespace detail // lcast_put_unsigned
507
543
  {
508
544
  template<class Traits, class T, class CharT>
509
- CharT* lcast_put_unsigned(T n, CharT* finish)
545
+ CharT* lcast_put_unsigned(const T n_param, CharT* finish)
510
546
  {
511
547
  #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
512
548
  BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
513
549
  #endif
514
550
 
551
+ typedef typename Traits::int_type int_type;
552
+ CharT const czero = lcast_char_constants<CharT>::zero;
553
+ int_type const zero = Traits::to_int_type(czero);
554
+ BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
555
+ (sizeof(int_type) > sizeof(T))
556
+ , int_type
557
+ , T
558
+ >::type n = n_param;
559
+
515
560
  #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
516
- // TODO: use BOOST_NO_STD_LOCALE
517
561
  std::locale loc;
518
- typedef std::numpunct<CharT> numpunct;
519
- numpunct const& np = BOOST_USE_FACET(numpunct, loc);
520
- std::string const& grouping = np.grouping();
521
- std::string::size_type const grouping_size = grouping.size();
522
- CharT thousands_sep = grouping_size ? np.thousands_sep() : 0;
523
- std::string::size_type group = 0; // current group number
524
- char last_grp_size = grouping[0] <= 0 ? CHAR_MAX : grouping[0];
525
- // a) Since grouping is const, grouping[grouping.size()] returns 0.
526
- // b) It's safe to assume here and below that CHAR_MAX
527
- // is equivalent to unlimited grouping:
562
+ if (loc != std::locale::classic()) {
563
+ typedef std::numpunct<CharT> numpunct;
564
+ numpunct const& np = BOOST_USE_FACET(numpunct, loc);
565
+ std::string const grouping = np.grouping();
566
+ std::string::size_type const grouping_size = grouping.size();
567
+
568
+ if ( grouping_size && grouping[0] > 0 )
569
+ {
570
+
528
571
  #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
529
- BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
572
+ // Check that ulimited group is unreachable:
573
+ BOOST_STATIC_ASSERT(std::numeric_limits<T>::digits10 < CHAR_MAX);
530
574
  #endif
575
+ CharT thousands_sep = np.thousands_sep();
576
+ std::string::size_type group = 0; // current group number
577
+ char last_grp_size = grouping[0];
578
+ char left = last_grp_size;
531
579
 
532
- char left = last_grp_size;
580
+ do
581
+ {
582
+ if(left == 0)
583
+ {
584
+ ++group;
585
+ if(group < grouping_size)
586
+ {
587
+ char const grp_size = grouping[group];
588
+ last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;
589
+ }
590
+
591
+ left = last_grp_size;
592
+ --finish;
593
+ Traits::assign(*finish, thousands_sep);
594
+ }
595
+
596
+ --left;
597
+
598
+ --finish;
599
+ int_type const digit = static_cast<int_type>(n % 10U);
600
+ Traits::assign(*finish, Traits::to_char_type(zero + digit));
601
+ n /= 10;
602
+ } while(n);
603
+ return finish;
604
+ }
605
+ }
533
606
  #endif
534
-
535
- typedef typename Traits::int_type int_type;
536
- CharT const czero = lcast_char_constants<CharT>::zero;
537
- int_type const zero = Traits::to_int_type(czero);
538
-
539
- do
540
607
  {
541
- #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
542
- if(left == 0)
608
+ do
543
609
  {
544
- ++group;
545
- if(group < grouping_size)
546
- {
547
- char const grp_size = grouping[group];
548
- last_grp_size = grp_size <= 0 ? CHAR_MAX : grp_size;
549
- }
550
-
551
- left = last_grp_size;
552
610
  --finish;
553
- Traits::assign(*finish, thousands_sep);
554
- }
555
-
556
- --left;
557
- #endif
558
-
559
- --finish;
560
- int_type const digit = static_cast<int_type>(n % 10U);
561
- Traits::assign(*finish, Traits::to_char_type(zero + digit));
562
- n /= 10;
563
- } while(n);
611
+ int_type const digit = static_cast<int_type>(n % 10U);
612
+ Traits::assign(*finish, Traits::to_char_type(zero + digit));
613
+ n /= 10;
614
+ } while(n);
615
+ }
564
616
 
565
617
  return finish;
566
618
  }
567
619
  }
568
620
 
569
- namespace detail // stream wrapper for handling lexical conversions
621
+ namespace detail // lcast_ret_unsigned
570
622
  {
571
- template<typename Target, typename Source, typename Traits>
572
- class lexical_stream
623
+ template<class Traits, class T, class CharT>
624
+ inline bool lcast_ret_unsigned(T& value, const CharT* const begin, const CharT* end)
573
625
  {
574
- private:
575
- typedef typename widest_char<
576
- typename stream_char<Target>::type,
577
- typename stream_char<Source>::type>::type char_type;
626
+ #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
627
+ BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed);
628
+ #endif
629
+ typedef typename Traits::int_type int_type;
630
+ CharT const czero = lcast_char_constants<CharT>::zero;
631
+ --end;
632
+ value = 0;
578
633
 
579
- typedef Traits traits_type;
634
+ if (begin > end || *end < czero || *end >= czero + 10)
635
+ return false;
636
+ value = *end - czero;
637
+ --end;
638
+ T multiplier = 1;
639
+ bool multiplier_overflowed = false;
580
640
 
581
- public:
582
- lexical_stream(char_type* = 0, char_type* = 0)
583
- {
584
- stream.unsetf(std::ios::skipws);
585
- lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );
641
+ #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
642
+ std::locale loc;
643
+ if (loc != std::locale::classic()) {
644
+ typedef std::numpunct<CharT> numpunct;
645
+ numpunct const& np = BOOST_USE_FACET(numpunct, loc);
646
+ std::string const& grouping = np.grouping();
647
+ std::string::size_type const grouping_size = grouping.size();
648
+
649
+ /* According to Programming languages - C++
650
+ * we MUST check for correct grouping
651
+ */
652
+ if (grouping_size && grouping[0] > 0)
653
+ {
654
+ unsigned char current_grouping = 0;
655
+ CharT const thousands_sep = np.thousands_sep();
656
+ char remained = grouping[current_grouping] - 1;
657
+ bool shall_we_return = true;
658
+
659
+ for(;end>=begin; --end)
660
+ {
661
+ if (remained) {
662
+ T const multiplier_10 = multiplier * 10;
663
+ if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
664
+
665
+ T const dig_value = *end - czero;
666
+ T const new_sub_value = multiplier_10 * dig_value;
667
+
668
+ if (*end < czero || *end >= czero + 10
669
+ /* detecting overflow */
670
+ || (dig_value && new_sub_value / dig_value != multiplier_10)
671
+ || static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
672
+ || (multiplier_overflowed && dig_value)
673
+ )
674
+ return false;
675
+
676
+ value += new_sub_value;
677
+ multiplier *= 10;
678
+ --remained;
679
+ } else {
680
+ if ( !Traits::eq(*end, thousands_sep) ) //|| begin == end ) return false;
681
+ {
682
+ /*
683
+ * According to Programming languages - C++
684
+ * Digit grouping is checked. That is, the positions of discarded
685
+ * separators is examined for consistency with
686
+ * use_facet<numpunct<charT> >(loc ).grouping()
687
+ *
688
+ * BUT what if there is no separators at all and grouping()
689
+ * is not empty? Well, we have no extraced separators, so we
690
+ * won`t check them for consistency. This will allow us to
691
+ * work with "C" locale from other locales
692
+ */
693
+ shall_we_return = false;
694
+ break;
695
+ } else {
696
+ if ( begin == end ) return false;
697
+ if (current_grouping < grouping_size-1 ) ++current_grouping;
698
+ remained = grouping[current_grouping];
699
+ }
700
+ }
701
+ }
702
+
703
+ if (shall_we_return) return true;
704
+ }
586
705
  }
587
- ~lexical_stream()
706
+ #endif
588
707
  {
589
- #if defined(BOOST_NO_STRINGSTREAM)
590
- stream.freeze(false);
591
- #endif
708
+ while ( begin <= end )
709
+ {
710
+ T const multiplier_10 = multiplier * 10;
711
+ if (multiplier_10 / 10 != multiplier) multiplier_overflowed = true;
712
+
713
+ T const dig_value = *end - czero;
714
+ T const new_sub_value = multiplier_10 * dig_value;
715
+
716
+ if (*end < czero || *end >= czero + 10
717
+ /* detecting overflow */
718
+ || (dig_value && new_sub_value / dig_value != multiplier_10)
719
+ || static_cast<T>((std::numeric_limits<T>::max)()-new_sub_value) < value
720
+ || (multiplier_overflowed && dig_value)
721
+ )
722
+ return false;
723
+
724
+ value += new_sub_value;
725
+ multiplier *= 10;
726
+ --end;
727
+ }
592
728
  }
593
- bool operator<<(const Source &input)
729
+ return true;
730
+ }
731
+ }
732
+
733
+ namespace detail
734
+ {
735
+ /* Returns true and sets the correct value if found NaN or Inf. */
736
+ template <class CharT, class T>
737
+ inline bool parse_inf_nan_impl(const CharT* begin, const CharT* end, T& value
738
+ , const CharT* lc_NAN, const CharT* lc_nan
739
+ , const CharT* lc_INFINITY, const CharT* lc_infinity
740
+ , const CharT opening_brace, const CharT closing_brace)
741
+ {
742
+ using namespace std;
743
+ if (begin == end) return false;
744
+ const CharT minus = lcast_char_constants<CharT>::minus;
745
+ const CharT plus = lcast_char_constants<CharT>::plus;
746
+ const int inifinity_size = 8;
747
+
748
+ bool has_minus = false;
749
+ /* Parsing +/- */
750
+ if( *begin == minus)
594
751
  {
595
- return !(stream << input).fail();
752
+ ++ begin;
753
+ has_minus = true;
596
754
  }
597
- template<typename InputStreamable>
598
- bool operator>>(InputStreamable &output)
755
+ else if( *begin == plus ) ++begin;
756
+
757
+ if( end-begin < 3 ) return false;
758
+ if( !memcmp(begin, lc_nan, 3*sizeof(CharT)) || !memcmp(begin, lc_NAN, 3*sizeof(CharT)) )
599
759
  {
600
- return !is_pointer<InputStreamable>::value &&
601
- stream >> output &&
602
- stream.get() ==
603
- #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
604
- // GCC 2.9x lacks std::char_traits<>::eof().
605
- // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
606
- // configurations, which do provide std::char_traits<>::eof().
607
-
608
- EOF;
609
- #else
610
- traits_type::eof();
611
- #endif
760
+ begin += 3;
761
+ if (end != begin) /* It is 'nan(...)' or some bad input*/
762
+ {
763
+ if(end-begin<2) return false; // bad input
764
+ -- end;
765
+ if( *begin != opening_brace || *end != closing_brace) return false; // bad input
766
+ }
767
+
768
+ if( !has_minus ) value = std::numeric_limits<T>::quiet_NaN();
769
+ else value = (boost::math::changesign) (std::numeric_limits<T>::quiet_NaN());
770
+ return true;
771
+ } else
772
+ if (( /* 'INF' or 'inf' */
773
+ end-begin==3
774
+ &&
775
+ (!memcmp(begin, lc_infinity, 3*sizeof(CharT)) || !memcmp(begin, lc_INFINITY, 3*sizeof(CharT)))
776
+ )
777
+ ||
778
+ ( /* 'INFINITY' or 'infinity' */
779
+ end-begin==inifinity_size
780
+ &&
781
+ (!memcmp(begin, lc_infinity, inifinity_size)|| !memcmp(begin, lc_INFINITY, inifinity_size))
782
+ )
783
+ )
784
+ {
785
+ if( !has_minus ) value = std::numeric_limits<T>::infinity();
786
+ else value = (boost::math::changesign) (std::numeric_limits<T>::infinity());
787
+ return true;
612
788
  }
613
789
 
614
- #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
790
+ return false;
791
+ }
615
792
 
616
- bool operator>>(std::string &output)
793
+ #ifndef BOOST_LCAST_NO_WCHAR_T
794
+ template <class T>
795
+ bool parse_inf_nan(const wchar_t* begin, const wchar_t* end, T& value)
796
+ {
797
+ return parse_inf_nan_impl(begin, end, value
798
+ , L"NAN", L"nan"
799
+ , L"INFINITY", L"infinity"
800
+ , L'(', L')');
801
+ }
802
+ #endif
803
+ #ifndef BOOST_NO_CHAR16_T
804
+ template <class T>
805
+ bool parse_inf_nan(const char16_t* begin, const char16_t* end, T& value)
806
+ {
807
+ return parse_inf_nan_impl(begin, end, value
808
+ , u"NAN", u"nan"
809
+ , u"INFINITY", u"infinity"
810
+ , u'(', u')');
811
+ }
812
+ #endif
813
+ #ifndef BOOST_NO_CHAR32_T
814
+ template <class T>
815
+ bool parse_inf_nan(const char32_t* begin, const char32_t* end, T& value)
816
+ {
817
+ return parse_inf_nan_impl(begin, end, value
818
+ , U"NAN", U"nan"
819
+ , U"INFINITY", U"infinity"
820
+ , U'(', U')');
821
+ }
822
+ #endif
823
+
824
+ template <class CharT, class T>
825
+ bool parse_inf_nan(const CharT* begin, const CharT* end, T& value)
826
+ {
827
+ return parse_inf_nan_impl(begin, end, value
828
+ , "NAN", "nan"
829
+ , "INFINITY", "infinity"
830
+ , '(', ')');
831
+ }
832
+ #ifndef BOOST_LCAST_NO_WCHAR_T
833
+ template <class T>
834
+ bool put_inf_nan(wchar_t* begin, wchar_t*& end, const T& value)
835
+ {
836
+ using namespace std;
837
+ if ( (boost::math::isnan)(value) )
617
838
  {
618
- #if defined(BOOST_NO_STRINGSTREAM)
619
- stream << '\0';
620
- #endif
621
- stream.str().swap(output);
839
+ if ( (boost::math::signbit)(value) )
840
+ {
841
+ memcpy(begin,L"-nan", sizeof(L"-nan"));
842
+ end = begin + 4;
843
+ } else
844
+ {
845
+ memcpy(begin,L"nan", sizeof(L"nan"));
846
+ end = begin + 3;
847
+ }
622
848
  return true;
623
- }
624
- #ifndef BOOST_LCAST_NO_WCHAR_T
625
- bool operator>>(std::wstring &output)
849
+ } else if ( (boost::math::isinf)(value) )
626
850
  {
627
- stream.str().swap(output);
851
+ if ( (boost::math::signbit)(value) )
852
+ {
853
+ memcpy(begin,L"-inf", sizeof(L"-inf"));
854
+ end = begin + 4;
855
+ } else
856
+ {
857
+ memcpy(begin,L"inf", sizeof(L"inf"));
858
+ end = begin + 3;
859
+ }
628
860
  return true;
629
861
  }
630
- #endif
631
862
 
632
- #else
633
- bool operator>>(std::basic_string<char_type,traits_type>& output)
863
+ return false;
864
+ }
865
+ #endif
866
+ template <class CharT, class T>
867
+ bool put_inf_nan(CharT* begin, CharT*& end, const T& value)
868
+ {
869
+ using namespace std;
870
+ if ( (boost::math::isnan)(value) )
634
871
  {
635
- stream.str().swap(output);
872
+ if ( (boost::math::signbit)(value) )
873
+ {
874
+ memcpy(begin,"-nan", sizeof("-nan"));
875
+ end = begin + 4;
876
+ } else
877
+ {
878
+ memcpy(begin,"nan", sizeof("nan"));
879
+ end = begin + 3;
880
+ }
881
+ return true;
882
+ } else if ( (boost::math::isinf)(value) )
883
+ {
884
+ if ( (boost::math::signbit)(value) )
885
+ {
886
+ memcpy(begin,"-inf", sizeof("-inf"));
887
+ end = begin + 4;
888
+ } else
889
+ {
890
+ memcpy(begin,"inf", sizeof("inf"));
891
+ end = begin + 3;
892
+ }
636
893
  return true;
637
894
  }
638
895
 
639
- template<class Alloc>
640
- bool operator>>(std::basic_string<char_type,traits_type,Alloc>& out)
896
+ return false;
897
+ }
898
+
899
+ }
900
+
901
+
902
+ namespace detail // lcast_ret_float
903
+ {
904
+ template <class T>
905
+ struct mantissa_holder_type
906
+ {
907
+ /* Can not be used with this type */
908
+ };
909
+
910
+ template <>
911
+ struct mantissa_holder_type<float>
912
+ {
913
+ typedef unsigned int type;
914
+ };
915
+
916
+ template <>
917
+ struct mantissa_holder_type<double>
918
+ {
919
+ #if defined(BOOST_HAS_LONG_LONG)
920
+ typedef boost::ulong_long_type type;
921
+ #elif defined(BOOST_HAS_MS_INT64)
922
+ typedef unsigned __int64 type;
923
+ #endif
924
+ };
925
+
926
+ template<class Traits, class T, class CharT>
927
+ inline bool lcast_ret_float(T& value, const CharT* begin, const CharT* end)
928
+ {
929
+
930
+ #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
931
+ std::locale loc;
932
+ typedef std::numpunct<CharT> numpunct;
933
+ numpunct const& np = BOOST_USE_FACET(numpunct, loc);
934
+ std::string const grouping(
935
+ (loc == std::locale::classic())
936
+ ? std::string()
937
+ : np.grouping()
938
+ );
939
+ std::string::size_type const grouping_size = grouping.size();
940
+ CharT const thousands_sep = grouping_size ? np.thousands_sep() : 0;
941
+ CharT const decimal_point = np.decimal_point();
942
+ bool found_grouping = false;
943
+ std::string::size_type last_grouping_pos = grouping_size - 1;
944
+ #else
945
+ CharT const decimal_point = lcast_char_constants<CharT>::c_decimal_separator;
946
+ #endif
947
+
948
+ CharT const czero = lcast_char_constants<CharT>::zero;
949
+ CharT const minus = lcast_char_constants<CharT>::minus;
950
+ CharT const plus = lcast_char_constants<CharT>::plus;
951
+ CharT const capital_e = lcast_char_constants<CharT>::capital_e;
952
+ CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
953
+
954
+ value = 0.0;
955
+
956
+ if (parse_inf_nan(begin, end, value)) return true;
957
+
958
+ typedef typename Traits::int_type int_type;
959
+ typedef BOOST_DEDUCED_TYPENAME mantissa_holder_type<T>::type mantissa_type;
960
+ int_type const zero = Traits::to_int_type(czero);
961
+ if (begin == end) return false;
962
+
963
+ /* Getting the plus/minus sign */
964
+ bool has_minus = false;
965
+ if ( *begin == minus ) {
966
+ ++ begin;
967
+ has_minus = true;
968
+ if (begin == end) return false;
969
+ } else if ( *begin == plus ) {
970
+ ++begin;
971
+ if (begin == end) return false;
972
+ }
973
+
974
+ bool found_decimal = false;
975
+ bool found_number_before_exp = false;
976
+ int pow_of_10 = 0;
977
+ mantissa_type mantissa=0;
978
+ bool is_mantissa_full = false;
979
+
980
+ char length_since_last_delim = 0;
981
+
982
+ while ( begin != end )
641
983
  {
642
- std::basic_string<char_type,traits_type> str(stream.str());
643
- out.assign(str.begin(), str.end());
644
- return true;
984
+ if (found_decimal) {
985
+ /* We allow no thousand_separators after decimal point */
986
+
987
+ mantissa_type tmp_mantissa = mantissa * 10u;
988
+ if ( *begin == lowercase_e || *begin == capital_e ) break;
989
+ if ( *begin < czero || *begin >= czero + 10 ) return false;
990
+ if ( is_mantissa_full
991
+ || tmp_mantissa / 10u != mantissa
992
+ || (std::numeric_limits<mantissa_type>::max)()-(*begin - zero) < tmp_mantissa
993
+ ) {
994
+ is_mantissa_full = true;
995
+ ++ begin;
996
+ continue;
997
+ }
998
+
999
+ -- pow_of_10;
1000
+ mantissa = tmp_mantissa;
1001
+ mantissa += *begin - zero;
1002
+
1003
+ found_number_before_exp = true;
1004
+ } else {
1005
+
1006
+ if (*begin >= czero && *begin < czero + 10) {
1007
+
1008
+ /* Checking for mantissa overflow. If overflow will
1009
+ * occur, them we only increase multiplyer
1010
+ */
1011
+ mantissa_type tmp_mantissa = mantissa * 10u;
1012
+ if( !is_mantissa_full
1013
+ && tmp_mantissa / 10u == mantissa
1014
+ && (std::numeric_limits<mantissa_type>::max)()-(*begin - zero) >= tmp_mantissa
1015
+ )
1016
+ {
1017
+ mantissa = tmp_mantissa;
1018
+ mantissa += *begin - zero;
1019
+ } else
1020
+ {
1021
+ is_mantissa_full = true;
1022
+ ++ pow_of_10;
1023
+ }
1024
+
1025
+ found_number_before_exp = true;
1026
+ ++ length_since_last_delim;
1027
+ } else if ( *begin == decimal_point || *begin == lowercase_e || *begin == capital_e) {
1028
+ #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
1029
+ /* If ( we need to check grouping
1030
+ * and ( grouping missmatches
1031
+ * or grouping position is incorrect
1032
+ * or we are using the grouping position 0 twice
1033
+ * )
1034
+ * ) then return error
1035
+ */
1036
+ if( grouping_size && found_grouping
1037
+ && (
1038
+ length_since_last_delim != grouping[0]
1039
+ || last_grouping_pos>1
1040
+ || (last_grouping_pos==0 && grouping_size>1)
1041
+ )
1042
+ ) return false;
1043
+ #endif
1044
+
1045
+ if(*begin == decimal_point){
1046
+ ++ begin;
1047
+ found_decimal = true;
1048
+ continue;
1049
+ }else {
1050
+ if (!found_number_before_exp) return false;
1051
+ break;
1052
+ }
1053
+ }
1054
+ #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
1055
+ else if (grouping_size && *begin == thousands_sep){
1056
+ if(found_grouping)
1057
+ {
1058
+ /* It is not he first time, when we find thousands separator,
1059
+ * so we need to chek, is the distance between two groupings
1060
+ * equal to grouping[last_grouping_pos] */
1061
+
1062
+ if (length_since_last_delim != grouping[last_grouping_pos] )
1063
+ {
1064
+ if (!last_grouping_pos) return false;
1065
+ else
1066
+ {
1067
+ -- last_grouping_pos;
1068
+ if (length_since_last_delim != grouping[last_grouping_pos]) return false;
1069
+ }
1070
+ } else
1071
+ /* We are calling the grouping[0] twice, when grouping size is more than 1 */
1072
+ if (grouping_size>1u && last_grouping_pos+1<grouping_size) return false;
1073
+
1074
+ } else {
1075
+ /* Delimiter at the begining ',000' */
1076
+ if (!length_since_last_delim) return false;
1077
+
1078
+ found_grouping = true;
1079
+ if (length_since_last_delim > grouping[last_grouping_pos] ) return false;
1080
+ }
1081
+
1082
+ length_since_last_delim = 0;
1083
+ ++ begin;
1084
+
1085
+ /* Delimiter at the end '100,' */
1086
+ if (begin == end) return false;
1087
+ continue;
1088
+ }
1089
+ #endif
1090
+ else return false;
1091
+ }
1092
+
1093
+ ++begin;
645
1094
  }
1095
+
1096
+ // Exponent found
1097
+ if ( begin != end && ( *begin == lowercase_e || *begin == capital_e ) ) {
1098
+ ++ begin;
1099
+ if ( begin == end ) return false;
1100
+
1101
+ bool exp_has_minus = false;
1102
+ if( *begin == minus ) {
1103
+ exp_has_minus = true;
1104
+ ++ begin;
1105
+ if ( begin == end ) return false;
1106
+ } else if (*begin == plus ) {
1107
+ ++ begin;
1108
+ if ( begin == end ) return false;
1109
+ }
1110
+
1111
+ int exp_pow_of_10 = 0;
1112
+ while ( begin != end )
1113
+ {
1114
+ if ( *begin < czero
1115
+ || *begin >= czero + 10
1116
+ || exp_pow_of_10 * 10 < exp_pow_of_10) /* Overflows are checked lower more precisely*/
1117
+ return false;
1118
+
1119
+ exp_pow_of_10 *= 10;
1120
+ exp_pow_of_10 += *begin - zero;
1121
+ ++ begin;
1122
+ };
1123
+
1124
+ if ( exp_pow_of_10 ) {
1125
+ /* Overflows are checked lower */
1126
+ if ( exp_has_minus ) {
1127
+ pow_of_10 -= exp_pow_of_10;
1128
+ } else {
1129
+ pow_of_10 += exp_pow_of_10;
1130
+ }
1131
+ }
1132
+ }
1133
+
1134
+ /* We need a more accurate algorithm... We can not use current algorithm
1135
+ * with long doubles (and with doubles if sizeof(double)==sizeof(long double)).
1136
+ */
1137
+ long double result = std::pow(10.0L, pow_of_10) * mantissa;
1138
+ value = static_cast<T>( has_minus ? (boost::math::changesign)(result) : result);
1139
+
1140
+ if ( (boost::math::isinf)(value) || (boost::math::isnan)(value) ) return false;
1141
+
1142
+ return true;
1143
+ }
1144
+ }
1145
+
1146
+ namespace detail // stl_buf_unlocker
1147
+ {
1148
+ template< class BufferType, class CharT >
1149
+ class stl_buf_unlocker: public BufferType{
1150
+ public:
1151
+ typedef BufferType base_class;
1152
+ #ifndef BOOST_NO_USING_TEMPLATE
1153
+ using base_class::pptr;
1154
+ using base_class::pbase;
1155
+ using base_class::setg;
1156
+ using base_class::setp;
1157
+ #else
1158
+ CharT* pptr() const { return base_class::pptr(); }
1159
+ CharT* pbase() const { return base_class::pbase(); }
1160
+ void setg(CharT* gbeg, CharT* gnext, CharT* gend){ return base_class::setg(gbeg, gnext, gend); }
1161
+ void setp(CharT* pbeg, CharT* pend) { return setp(pbeg, pend); }
646
1162
  #endif
647
- private:
648
- #if defined(BOOST_NO_STRINGSTREAM)
649
- std::strstream stream;
650
- #elif defined(BOOST_NO_STD_LOCALE)
651
- std::stringstream stream;
652
- #else
653
- std::basic_stringstream<char_type,traits_type> stream;
654
- #endif
655
1163
  };
656
1164
  }
657
1165
 
1166
+ namespace detail
1167
+ {
1168
+ struct do_not_construct_stringbuffer_t{};
1169
+ }
1170
+
658
1171
  namespace detail // optimized stream wrapper
659
1172
  {
660
1173
  // String representation of Source has an upper limit.
661
1174
  template< class CharT // a result of widest_char transformation
662
- , class Base // lexical_streambuf_fake or basic_streambuf<CharT>
663
1175
  , class Traits // usually char_traits<CharT>
1176
+ , bool RequiresStringbuffer
664
1177
  >
665
- class lexical_stream_limited_src : public Base
1178
+ class lexical_stream_limited_src
666
1179
  {
1180
+ typedef stl_buf_unlocker<std::basic_streambuf<CharT, Traits>, CharT > local_streambuffer_t;
1181
+
1182
+ #if defined(BOOST_NO_STRINGSTREAM)
1183
+ typedef stl_buf_unlocker<std::strstream, CharT > local_stringbuffer_t;
1184
+ #elif defined(BOOST_NO_STD_LOCALE)
1185
+ typedef stl_buf_unlocker<std::stringstream, CharT > local_stringbuffer_t;
1186
+ #else
1187
+ typedef stl_buf_unlocker<std::basic_stringbuf<CharT, Traits>, CharT > local_stringbuffer_t;
1188
+ #endif
1189
+ typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
1190
+ RequiresStringbuffer,
1191
+ local_stringbuffer_t,
1192
+ do_not_construct_stringbuffer_t
1193
+ >::type deduced_stringbuffer_t;
1194
+
667
1195
  // A string representation of Source is written to [start, finish).
668
- // Currently, it is assumed that [start, finish) is big enough
669
- // to hold a string representation of any Source value.
670
1196
  CharT* start;
671
1197
  CharT* finish;
1198
+ deduced_stringbuffer_t stringbuffer;
1199
+
1200
+ public:
1201
+ lexical_stream_limited_src(CharT* sta, CharT* fin)
1202
+ : start(sta)
1203
+ , finish(fin)
1204
+ {}
672
1205
 
673
1206
  private:
1207
+ // Undefined:
1208
+ lexical_stream_limited_src(lexical_stream_limited_src const&);
1209
+ void operator=(lexical_stream_limited_src const&);
674
1210
 
675
- static void widen_and_assign(char*p, char ch)
1211
+ /************************************ HELPER FUNCTIONS FOR OPERATORS << ( ... ) ********************************/
1212
+ bool shl_char(CharT ch)
676
1213
  {
677
- Traits::assign(*p, ch);
1214
+ Traits::assign(*start, ch);
1215
+ finish = start + 1;
1216
+ return true;
678
1217
  }
679
1218
 
680
1219
  #ifndef BOOST_LCAST_NO_WCHAR_T
681
- static void widen_and_assign(wchar_t* p, char ch)
1220
+ template <class T>
1221
+ bool shl_char(T ch)
682
1222
  {
683
- // TODO: use BOOST_NO_STD_LOCALE
1223
+ BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)) ,
1224
+ "boost::lexical_cast does not support conversions from whar_t to char types."
1225
+ "Use boost::locale instead" );
1226
+ #ifndef BOOST_LEXICAL_CAST_ASSUME_C_LOCALE
684
1227
  std::locale loc;
685
1228
  wchar_t w = BOOST_USE_FACET(std::ctype<wchar_t>, loc).widen(ch);
686
- Traits::assign(*p, w);
1229
+ #else
1230
+ wchar_t w = ch;
1231
+ #endif
1232
+ Traits::assign(*start, w);
1233
+ finish = start + 1;
1234
+ return true;
687
1235
  }
1236
+ #endif
688
1237
 
689
- static void widen_and_assign(wchar_t* p, wchar_t ch)
1238
+ bool shl_char_array(CharT const* str)
690
1239
  {
691
- Traits::assign(*p, ch);
1240
+ start = const_cast<CharT*>(str);
1241
+ finish = start + Traits::length(str);
1242
+ return true;
692
1243
  }
693
1244
 
694
- static void widen_and_assign(char*, wchar_t ch); // undefined
1245
+ #ifndef BOOST_LCAST_NO_WCHAR_T
1246
+ template <class T>
1247
+ bool shl_char_array(T const* str)
1248
+ {
1249
+ BOOST_STATIC_ASSERT_MSG(( sizeof(T) <= sizeof(CharT)),
1250
+ "boost::lexical_cast does not support conversions from wchar_t to char types."
1251
+ "Use boost::locale instead" );
1252
+ return shl_input_streamable(str);
1253
+ }
695
1254
  #endif
696
1255
 
697
- template<class OutputStreamable>
698
- bool lcast_put(const OutputStreamable& input)
1256
+ template<typename InputStreamable>
1257
+ bool shl_input_streamable(InputStreamable& input)
699
1258
  {
700
- this->setp(start, finish);
701
- std::basic_ostream<CharT> stream(static_cast<Base*>(this));
702
- lcast_set_precision(stream, static_cast<OutputStreamable*>(0));
1259
+ std::basic_ostream<CharT> stream(&stringbuffer);
703
1260
  bool const result = !(stream << input).fail();
704
- finish = this->pptr();
1261
+ start = stringbuffer.pbase();
1262
+ finish = stringbuffer.pptr();
705
1263
  return result;
706
1264
  }
707
1265
 
708
- // Undefined:
709
- lexical_stream_limited_src(lexical_stream_limited_src const&);
710
- void operator=(lexical_stream_limited_src const&);
1266
+ template <class T>
1267
+ inline bool shl_signed(T n)
1268
+ {
1269
+ start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
1270
+ if(n < 0)
1271
+ {
1272
+ --start;
1273
+ CharT const minus = lcast_char_constants<CharT>::minus;
1274
+ Traits::assign(*start, minus);
1275
+ }
1276
+ return true;
1277
+ }
711
1278
 
712
- public:
1279
+ #if (defined _MSC_VER)
1280
+ # pragma warning( push )
1281
+ // C4996: This function or variable may be unsafe. Consider using sprintf_s instead
1282
+ # pragma warning( disable : 4996 )
1283
+ #endif
713
1284
 
714
- lexical_stream_limited_src(CharT* sta, CharT* fin)
715
- : start(sta)
716
- , finish(fin)
717
- {}
1285
+ template <class T>
1286
+ bool shl_float(float val,T* out)
1287
+ { using namespace std;
1288
+ if (put_inf_nan(start,finish,val)) return true;
1289
+ finish = start + sprintf(out,"%.*g", static_cast<int>(boost::detail::lcast_get_precision<float >()), val );
1290
+ return finish > start;
1291
+ }
1292
+
1293
+ template <class T>
1294
+ bool shl_double(double val,T* out)
1295
+ { using namespace std;
1296
+ if (put_inf_nan(start,finish,val)) return true;
1297
+ finish = start + sprintf(out,"%.*lg", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
1298
+ return finish > start;
1299
+ }
1300
+ #ifndef __MINGW32__
1301
+ template <class T>
1302
+ bool shl_long_double(long double val,T* out)
1303
+ { using namespace std;
1304
+ if (put_inf_nan(start,finish,val)) return true;
1305
+ finish = start + sprintf(out,"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
1306
+ return finish > start;
1307
+ }
1308
+ #endif
1309
+
1310
+ #if (defined _MSC_VER)
1311
+ # pragma warning( pop )
1312
+ #endif
1313
+
1314
+
1315
+ #ifndef BOOST_LCAST_NO_WCHAR_T
1316
+ bool shl_float(float val,wchar_t* out)
1317
+ { using namespace std;
1318
+ if (put_inf_nan(start,finish,val)) return true;
1319
+ finish = start + swprintf(out,
1320
+ #if !defined(__MINGW32__) && !defined(UNDER_CE)
1321
+ finish-start,
1322
+ #endif
1323
+ L"%.*g", static_cast<int>(boost::detail::lcast_get_precision<float >()), val );
1324
+
1325
+ return finish > start;
1326
+ }
1327
+
1328
+
1329
+ bool shl_double(double val,wchar_t* out)
1330
+ { using namespace std;
1331
+ if (put_inf_nan(start,finish,val)) return true;
1332
+ /* __MINGW32__ is defined for both mingw.org and for mingw-w64.
1333
+ * For mingw-w64, __MINGW64__ is defined, too, when targetting
1334
+ * 64 bits.
1335
+ *
1336
+ * swprintf realization in MinGW and under WinCE does not conform
1337
+ * to the ISO C
1338
+ * Standard.
1339
+ */
1340
+ finish = start + swprintf(out,
1341
+ #if !defined(__MINGW32__) && !defined(UNDER_CE)
1342
+ finish-start,
1343
+ #endif
1344
+ L"%.*lg", static_cast<int>(boost::detail::lcast_get_precision<double >()), val );
1345
+ return finish > start;
1346
+ }
1347
+
1348
+ #ifndef __MINGW32__
1349
+ bool shl_long_double(long double val,wchar_t* out)
1350
+ { using namespace std;
1351
+ if (put_inf_nan(start,finish,val)) return true;
1352
+ finish = start + swprintf(out,
1353
+ #if !defined(UNDER_CE)
1354
+ finish-start,
1355
+ #endif
1356
+ L"%.*Lg", static_cast<int>(boost::detail::lcast_get_precision<long double >()), val );
1357
+ return finish > start;
1358
+ }
1359
+ #endif
718
1360
 
719
- public: // output
1361
+ #endif
720
1362
 
1363
+ /************************************ OPERATORS << ( ... ) ********************************/
1364
+ public:
721
1365
  template<class Alloc>
722
1366
  bool operator<<(std::basic_string<CharT,Traits,Alloc> const& str)
723
1367
  {
@@ -726,37 +1370,151 @@ namespace boost
726
1370
  return true;
727
1371
  }
728
1372
 
729
- bool operator<<(bool);
730
- bool operator<<(char);
731
- #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
732
- bool operator<<(wchar_t);
733
- #endif
734
- bool operator<<(CharT const*);
735
- bool operator<<(short);
736
- bool operator<<(int);
737
- bool operator<<(long);
738
- bool operator<<(unsigned short);
739
- bool operator<<(unsigned int);
740
- bool operator<<(unsigned long);
1373
+ #if !defined(__SUNPRO_CC)
1374
+ template<class Alloc>
1375
+ bool operator<<(::boost::container::basic_string<CharT,Traits,Alloc> const& str)
1376
+ {
1377
+ start = const_cast<CharT*>(str.data());
1378
+ finish = start + str.length();
1379
+ return true;
1380
+ }
1381
+ #endif // !defined(__SUNPRO_CC)
1382
+ bool operator<<(bool value)
1383
+ {
1384
+ CharT const czero = lcast_char_constants<CharT>::zero;
1385
+ Traits::assign(*start, Traits::to_char_type(czero + value));
1386
+ finish = start + 1;
1387
+ return true;
1388
+ }
1389
+
1390
+ bool operator<<(char ch) { return shl_char(ch); }
1391
+ bool operator<<(unsigned char ch) { return ((*this) << static_cast<char>(ch)); }
1392
+ bool operator<<(signed char ch) { return ((*this) << static_cast<char>(ch)); }
1393
+ #if !defined(BOOST_LCAST_NO_WCHAR_T)
1394
+ bool operator<<(wchar_t const* str) { return shl_char_array(str); }
1395
+ bool operator<<(wchar_t * str) { return shl_char_array(str); }
1396
+ #ifndef BOOST_NO_INTRINSIC_WCHAR_T
1397
+ bool operator<<(wchar_t ch) { return shl_char(ch); }
1398
+ #endif
1399
+ #endif
1400
+ bool operator<<(unsigned char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
1401
+ bool operator<<(unsigned char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
1402
+ bool operator<<(signed char const* ch) { return ((*this) << reinterpret_cast<char const*>(ch)); }
1403
+ bool operator<<(signed char * ch) { return ((*this) << reinterpret_cast<char *>(ch)); }
1404
+ bool operator<<(char const* str) { return shl_char_array(str); }
1405
+ bool operator<<(char* str) { return shl_char_array(str); }
1406
+ bool operator<<(short n) { return shl_signed(n); }
1407
+ bool operator<<(int n) { return shl_signed(n); }
1408
+ bool operator<<(long n) { return shl_signed(n); }
1409
+ bool operator<<(unsigned short n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1410
+ bool operator<<(unsigned int n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1411
+ bool operator<<(unsigned long n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1412
+
741
1413
  #if defined(BOOST_HAS_LONG_LONG)
742
- bool operator<<(boost::ulong_long_type);
743
- bool operator<<(boost::long_long_type );
1414
+ bool operator<<(boost::ulong_long_type n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1415
+ bool operator<<(boost::long_long_type n) { return shl_signed(n); }
744
1416
  #elif defined(BOOST_HAS_MS_INT64)
745
- bool operator<<(unsigned __int64);
746
- bool operator<<( __int64);
1417
+ bool operator<<(unsigned __int64 n) { start = lcast_put_unsigned<Traits>(n, finish); return true; }
1418
+ bool operator<<( __int64 n) { return shl_signed(n); }
747
1419
  #endif
748
- // These three operators use ostream and streambuf.
749
- // lcast_streambuf_for_source<T>::value is true.
750
- bool operator<<(float);
751
- bool operator<<(double);
752
- bool operator<<(long double);
1420
+ bool operator<<(float val) { return shl_float(val,start); }
1421
+ bool operator<<(double val) { return shl_double(val,start); }
1422
+ bool operator<<(long double val) {
1423
+ #ifndef __MINGW32__
1424
+ return shl_long_double(val,start);
1425
+ #else
1426
+ return shl_double(val,start);
1427
+ #endif
1428
+ }
753
1429
 
754
- public: // input
1430
+ template<class InStreamable>
1431
+ bool operator<<(const InStreamable& input) { return shl_input_streamable(input); }
1432
+
1433
+ /************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
1434
+ private:
1435
+
1436
+ template <typename Type>
1437
+ bool shr_unsigned(Type& output)
1438
+ {
1439
+ if (start == finish) return false;
1440
+ CharT const minus = lcast_char_constants<CharT>::minus;
1441
+ CharT const plus = lcast_char_constants<CharT>::plus;
1442
+ bool has_minus = false;
1443
+
1444
+ /* We won`t use `start' any more, so no need in decrementing it after */
1445
+ if ( Traits::eq(minus,*start) )
1446
+ {
1447
+ ++start;
1448
+ has_minus = true;
1449
+ } else if ( Traits::eq( plus, *start ) )
1450
+ {
1451
+ ++start;
1452
+ }
1453
+
1454
+ bool const succeed = lcast_ret_unsigned<Traits>(output, start, finish);
1455
+ #if (defined _MSC_VER)
1456
+ # pragma warning( push )
1457
+ // C4146: unary minus operator applied to unsigned type, result still unsigned
1458
+ # pragma warning( disable : 4146 )
1459
+ #elif defined( __BORLANDC__ )
1460
+ # pragma option push -w-8041
1461
+ #endif
1462
+ if (has_minus) output = static_cast<Type>(-output);
1463
+ #if (defined _MSC_VER)
1464
+ # pragma warning( pop )
1465
+ #elif defined( __BORLANDC__ )
1466
+ # pragma option pop
1467
+ #endif
1468
+ return succeed;
1469
+ }
1470
+
1471
+ template <typename Type>
1472
+ bool shr_signed(Type& output)
1473
+ {
1474
+ if (start == finish) return false;
1475
+ CharT const minus = lcast_char_constants<CharT>::minus;
1476
+ CharT const plus = lcast_char_constants<CharT>::plus;
1477
+ typedef BOOST_DEDUCED_TYPENAME make_unsigned<Type>::type utype;
1478
+ utype out_tmp =0;
1479
+ bool has_minus = false;
1480
+
1481
+ /* We won`t use `start' any more, so no need in decrementing it after */
1482
+ if ( Traits::eq(minus,*start) )
1483
+ {
1484
+ ++start;
1485
+ has_minus = true;
1486
+ } else if ( Traits::eq(plus, *start) )
1487
+ {
1488
+ ++start;
1489
+ }
1490
+
1491
+ bool succeed = lcast_ret_unsigned<Traits>(out_tmp, start, finish);
1492
+ if (has_minus) {
1493
+ #if (defined _MSC_VER)
1494
+ # pragma warning( push )
1495
+ // C4146: unary minus operator applied to unsigned type, result still unsigned
1496
+ # pragma warning( disable : 4146 )
1497
+ #elif defined( __BORLANDC__ )
1498
+ # pragma option push -w-8041
1499
+ #endif
1500
+ utype const comp_val = static_cast<utype>(-(std::numeric_limits<Type>::min)());
1501
+ succeed = succeed && out_tmp<=comp_val;
1502
+ output = -out_tmp;
1503
+ #if (defined _MSC_VER)
1504
+ # pragma warning( pop )
1505
+ #elif defined( __BORLANDC__ )
1506
+ # pragma option pop
1507
+ #endif
1508
+ } else {
1509
+ utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
1510
+ succeed = succeed && out_tmp<=comp_val;
1511
+ output = out_tmp;
1512
+ }
1513
+ return succeed;
1514
+ }
755
1515
 
756
- // Generic istream-based algorithm.
757
- // lcast_streambuf_for_target<InputStreamable>::value is true.
758
1516
  template<typename InputStreamable>
759
- bool operator>>(InputStreamable& output)
1517
+ bool shr_using_base_class(InputStreamable& output)
760
1518
  {
761
1519
  #if (defined _MSC_VER)
762
1520
  # pragma warning( push )
@@ -766,8 +1524,9 @@ namespace boost
766
1524
  if(is_pointer<InputStreamable>::value)
767
1525
  return false;
768
1526
 
769
- this->setg(start, start, finish);
770
- std::basic_istream<CharT> stream(static_cast<Base*>(this));
1527
+ local_streambuffer_t bb;
1528
+ bb.setg(start, start, finish);
1529
+ std::basic_istream<CharT> stream(&bb);
771
1530
  stream.unsetf(std::ios::skipws);
772
1531
  lcast_set_precision(stream, static_cast<InputStreamable*>(0));
773
1532
  #if (defined _MSC_VER)
@@ -786,396 +1545,622 @@ namespace boost
786
1545
  #endif
787
1546
  }
788
1547
 
789
- bool operator>>(CharT&);
790
-
791
- #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
792
- // This #if is in sync with lcast_streambuf_for_target
793
-
794
- bool operator>>(std::string&);
795
-
796
- #ifndef BOOST_LCAST_NO_WCHAR_T
797
- bool operator>>(std::wstring&);
798
- #endif
799
-
800
- #else
801
- template<class Alloc>
802
- bool operator>>(std::basic_string<CharT,Traits,Alloc>& str)
1548
+ template<class T>
1549
+ inline bool shr_xchar(T& output)
803
1550
  {
804
- str.assign(start, finish);
805
- return true;
1551
+ BOOST_STATIC_ASSERT_MSG(( sizeof(CharT) == sizeof(T) ),
1552
+ "boost::lexical_cast does not support conversions from whar_t to char types."
1553
+ "Use boost::locale instead" );
1554
+ bool const ok = (finish - start == 1);
1555
+ if(ok) {
1556
+ CharT out;
1557
+ Traits::assign(out, *start);
1558
+ output = static_cast<T>(out);
1559
+ }
1560
+ return ok;
806
1561
  }
807
- #endif
808
- };
809
1562
 
810
- template<typename CharT, class Base, class Traits>
811
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
812
- bool value)
813
- {
814
- typedef typename Traits::int_type int_type;
815
- CharT const czero = lcast_char_constants<CharT>::zero;
816
- int_type const zero = Traits::to_int_type(czero);
817
- Traits::assign(*start, Traits::to_char_type(zero + value));
818
- finish = start + 1;
819
- return true;
820
- }
821
-
822
- template<typename CharT, class Base, class Traits>
823
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
824
- char ch)
825
- {
826
- widen_and_assign(start, ch);
827
- finish = start + 1;
828
- return true;
829
- }
830
-
831
- #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
832
- template<typename CharT, class Base, class Traits>
833
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
834
- wchar_t ch)
835
- {
836
- widen_and_assign(start, ch);
837
- finish = start + 1;
838
- return true;
839
- }
1563
+ /************************************ OPERATORS >> ( ... ) ********************************/
1564
+ public:
1565
+ bool operator>>(unsigned short& output) { return shr_unsigned(output); }
1566
+ bool operator>>(unsigned int& output) { return shr_unsigned(output); }
1567
+ bool operator>>(unsigned long int& output) { return shr_unsigned(output); }
1568
+ bool operator>>(short& output) { return shr_signed(output); }
1569
+ bool operator>>(int& output) { return shr_signed(output); }
1570
+ bool operator>>(long int& output) { return shr_signed(output); }
1571
+ #if defined(BOOST_HAS_LONG_LONG)
1572
+ bool operator>>(boost::ulong_long_type& output) { return shr_unsigned(output); }
1573
+ bool operator>>(boost::long_long_type& output) { return shr_signed(output); }
1574
+ #elif defined(BOOST_HAS_MS_INT64)
1575
+ bool operator>>(unsigned __int64& output) { return shr_unsigned(output); }
1576
+ bool operator>>(__int64& output) { return shr_signed(output); }
1577
+ #endif
1578
+ bool operator>>(char& output) { return shr_xchar(output); }
1579
+ bool operator>>(unsigned char& output) { return shr_xchar(output); }
1580
+ bool operator>>(signed char& output) { return shr_xchar(output); }
1581
+ #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
1582
+ bool operator>>(wchar_t& output) { return shr_xchar(output); }
840
1583
  #endif
841
-
842
- template<typename CharT, class Base, class Traits>
843
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
844
- short n)
845
- {
846
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
847
- if(n < 0)
1584
+ #ifndef BOOST_NO_CHAR16_T
1585
+ bool operator>>(char16_t& output) { return shr_xchar(output); }
1586
+ #endif
1587
+ #ifndef BOOST_NO_CHAR32_T
1588
+ bool operator>>(char32_t& output) { return shr_xchar(output); }
1589
+ #endif
1590
+ #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1591
+ bool operator>>(std::string& str) { str.assign(start, finish); return true; }
1592
+ # ifndef BOOST_LCAST_NO_WCHAR_T
1593
+ bool operator>>(std::wstring& str) { str.assign(start, finish); return true; }
1594
+ # endif
1595
+ #else
1596
+ template<class Alloc>
1597
+ bool operator>>(std::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
1598
+ #if !defined(__SUNPRO_CC)
1599
+ template<class Alloc>
1600
+ bool operator>>(::boost::container::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
1601
+ #endif // !defined(__SUNPRO_CC)
1602
+ #endif
1603
+ /*
1604
+ * case "-0" || "0" || "+0" : output = false; return true;
1605
+ * case "1" || "+1": output = true; return true;
1606
+ * default: return false;
1607
+ */
1608
+ bool operator>>(bool& output)
848
1609
  {
849
- --start;
1610
+ CharT const zero = lcast_char_constants<CharT>::zero;
1611
+ CharT const plus = lcast_char_constants<CharT>::plus;
850
1612
  CharT const minus = lcast_char_constants<CharT>::minus;
851
- Traits::assign(*start, minus);
1613
+
1614
+ switch(finish-start)
1615
+ {
1616
+ case 1:
1617
+ output = Traits::eq(start[0], zero+1);
1618
+ return output || Traits::eq(start[0], zero );
1619
+ case 2:
1620
+ if ( Traits::eq( plus, *start) )
1621
+ {
1622
+ ++start;
1623
+ output = Traits::eq(start[0], zero +1);
1624
+ return output || Traits::eq(start[0], zero );
1625
+ } else
1626
+ {
1627
+ output = false;
1628
+ return Traits::eq( minus, *start)
1629
+ && Traits::eq( zero, start[1]);
1630
+ }
1631
+ default:
1632
+ output = false; // Suppress warning about uninitalized variable
1633
+ return false;
1634
+ }
852
1635
  }
853
- return true;
854
- }
855
1636
 
856
- template<typename CharT, class Base, class Traits>
857
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
858
- int n)
859
- {
860
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
861
- if(n < 0)
862
- {
863
- --start;
1637
+ bool operator>>(float& output) { return lcast_ret_float<Traits>(output,start,finish); }
1638
+
1639
+ private:
1640
+ // Not optimised converter
1641
+ template <class T>
1642
+ bool float_types_converter_internal(T& output, int /*tag*/) {
1643
+ if (parse_inf_nan(start, finish, output)) return true;
1644
+ bool return_value = shr_using_base_class(output);
1645
+
1646
+ /* Some compilers and libraries successfully
1647
+ * parse 'inf', 'INFINITY', '1.0E', '1.0E-'...
1648
+ * We are trying to provide a unified behaviour,
1649
+ * so we just forbid such conversions (as some
1650
+ * of the most popular compilers/libraries do)
1651
+ * */
864
1652
  CharT const minus = lcast_char_constants<CharT>::minus;
865
- Traits::assign(*start, minus);
1653
+ CharT const plus = lcast_char_constants<CharT>::plus;
1654
+ CharT const capital_e = lcast_char_constants<CharT>::capital_e;
1655
+ CharT const lowercase_e = lcast_char_constants<CharT>::lowercase_e;
1656
+ if ( return_value &&
1657
+ (
1658
+ *(finish-1) == lowercase_e // 1.0e
1659
+ || *(finish-1) == capital_e // 1.0E
1660
+ || *(finish-1) == minus // 1.0e- or 1.0E-
1661
+ || *(finish-1) == plus // 1.0e+ or 1.0E+
1662
+ )
1663
+ ) return false;
1664
+
1665
+ return return_value;
866
1666
  }
867
- return true;
868
- }
869
1667
 
870
- template<typename CharT, class Base, class Traits>
871
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
872
- long n)
873
- {
874
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
875
- if(n < 0)
876
- {
877
- --start;
878
- CharT const minus = lcast_char_constants<CharT>::minus;
879
- Traits::assign(*start, minus);
1668
+ // Optimised converter
1669
+ bool float_types_converter_internal(double& output,char /*tag*/) {
1670
+ return lcast_ret_float<Traits>(output,start,finish);
880
1671
  }
881
- return true;
882
- }
1672
+ public:
883
1673
 
884
- #if defined(BOOST_HAS_LONG_LONG)
885
- template<typename CharT, class Base, class Traits>
886
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
887
- boost::long_long_type n)
888
- {
889
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
890
- if(n < 0)
1674
+ bool operator>>(double& output)
891
1675
  {
892
- --start;
893
- CharT const minus = lcast_char_constants<CharT>::minus;
894
- Traits::assign(*start, minus);
1676
+ /*
1677
+ * Some compilers implement long double as double. In that case these types have
1678
+ * same size, same precision, same max and min values... And it means,
1679
+ * that current implementation of lcast_ret_float cannot be used for type
1680
+ * double, because it will give a big precision loss.
1681
+ * */
1682
+ boost::mpl::if_c<
1683
+ #if defined(BOOST_HAS_LONG_LONG) || defined(BOOST_HAS_MS_INT64)
1684
+ ::boost::type_traits::ice_eq< sizeof(double), sizeof(long double) >::value,
1685
+ #else
1686
+ 0
1687
+ #endif
1688
+ int,
1689
+ char
1690
+ >::type tag = 0;
1691
+
1692
+ return float_types_converter_internal(output, tag);
895
1693
  }
896
- return true;
897
- }
898
- #elif defined(BOOST_HAS_MS_INT64)
899
- template<typename CharT, class Base, class Traits>
900
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
901
- __int64 n)
902
- {
903
- start = lcast_put_unsigned<Traits>(lcast_to_unsigned(n), finish);
904
- if(n < 0)
1694
+
1695
+ bool operator>>(long double& output)
905
1696
  {
906
- --start;
907
- CharT const minus = lcast_char_constants<CharT>::minus;
908
- Traits::assign(*start, minus);
1697
+ int tag = 0;
1698
+ return float_types_converter_internal(output, tag);
909
1699
  }
910
- return true;
911
- }
912
- #endif
913
-
914
- template<typename CharT, class Base, class Traits>
915
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
916
- unsigned short n)
917
- {
918
- start = lcast_put_unsigned<Traits>(n, finish);
919
- return true;
920
- }
921
1700
 
922
- template<typename CharT, class Base, class Traits>
923
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
924
- unsigned int n)
925
- {
926
- start = lcast_put_unsigned<Traits>(n, finish);
927
- return true;
928
- }
1701
+ // Generic istream-based algorithm.
1702
+ // lcast_streambuf_for_target<InputStreamable>::value is true.
1703
+ template<typename InputStreamable>
1704
+ bool operator>>(InputStreamable& output) { return shr_using_base_class(output); }
1705
+ };
1706
+ }
929
1707
 
930
- template<typename CharT, class Base, class Traits>
931
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
932
- unsigned long n)
933
- {
934
- start = lcast_put_unsigned<Traits>(n, finish);
935
- return true;
936
- }
1708
+ #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
937
1709
 
938
- #if defined(BOOST_HAS_LONG_LONG)
939
- template<typename CharT, class Base, class Traits>
940
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
941
- boost::ulong_long_type n)
942
- {
943
- start = lcast_put_unsigned<Traits>(n, finish);
944
- return true;
945
- }
946
- #elif defined(BOOST_HAS_MS_INT64)
947
- template<typename CharT, class Base, class Traits>
948
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
949
- unsigned __int64 n)
950
- {
951
- start = lcast_put_unsigned<Traits>(n, finish);
952
- return true;
953
- }
954
- #endif
1710
+ // call-by-const reference version
955
1711
 
956
- template<typename CharT, class Base, class Traits>
957
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
958
- float val)
1712
+ namespace detail
1713
+ {
1714
+ template<class T>
1715
+ struct array_to_pointer_decay
959
1716
  {
960
- return this->lcast_put(val);
961
- }
1717
+ typedef T type;
1718
+ };
962
1719
 
963
- template<typename CharT, class Base, class Traits>
964
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
965
- double val)
1720
+ template<class T, std::size_t N>
1721
+ struct array_to_pointer_decay<T[N]>
966
1722
  {
967
- return this->lcast_put(val);
968
- }
1723
+ typedef const T * type;
1724
+ };
969
1725
 
970
- template<typename CharT, class Base, class Traits>
971
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
972
- long double val)
1726
+ template<typename T>
1727
+ struct is_stdstring
973
1728
  {
974
- return this->lcast_put(val);
975
- }
1729
+ BOOST_STATIC_CONSTANT(bool, value = false );
1730
+ };
976
1731
 
977
- template<typename CharT, class Base, class Traits>
978
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator<<(
979
- CharT const* str)
1732
+ template<typename CharT, typename Traits, typename Alloc>
1733
+ struct is_stdstring< std::basic_string<CharT, Traits, Alloc> >
980
1734
  {
981
- start = const_cast<CharT*>(str);
982
- finish = start + Traits::length(str);
983
- return true;
984
- }
985
-
986
- template<typename CharT, class Base, class Traits>
987
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
988
- CharT& output)
1735
+ BOOST_STATIC_CONSTANT(bool, value = true );
1736
+ };
1737
+ #if !defined(__SUNPRO_CC)
1738
+ template<typename CharT, typename Traits, typename Alloc>
1739
+ struct is_stdstring< ::boost::container::basic_string<CharT, Traits, Alloc> >
989
1740
  {
990
- bool const ok = (finish - start == 1);
991
- if(ok)
992
- Traits::assign(output, *start);
993
- return ok;
994
- }
995
-
996
- #ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
997
- template<typename CharT, class Base, class Traits>
998
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
999
- std::string& str)
1741
+ BOOST_STATIC_CONSTANT(bool, value = true );
1742
+ };
1743
+ #endif // !defined(__SUNPRO_CC)
1744
+ template<typename T>
1745
+ struct is_char_or_wchar
1000
1746
  {
1001
- str.assign(start, finish);
1002
- return true;
1003
- }
1004
-
1747
+ private:
1005
1748
  #ifndef BOOST_LCAST_NO_WCHAR_T
1006
- template<typename CharT, class Base, class Traits>
1007
- inline bool lexical_stream_limited_src<CharT,Base,Traits>::operator>>(
1008
- std::wstring& str)
1009
- {
1010
- str.assign(start, finish);
1011
- return true;
1012
- }
1749
+ typedef wchar_t wchar_t_if_supported;
1750
+ #else
1751
+ typedef char wchar_t_if_supported;
1013
1752
  #endif
1753
+
1754
+ #ifndef BOOST_NO_CHAR16_T
1755
+ typedef char16_t char16_t_if_supported;
1756
+ #else
1757
+ typedef char char16_t_if_supported;
1014
1758
  #endif
1015
- }
1016
1759
 
1017
- namespace detail // lcast_streambuf_for_source
1018
- {
1019
- // Returns true if optimized stream wrapper needs ostream for writing.
1020
- template<class Source>
1021
- struct lcast_streambuf_for_source
1022
- {
1023
- BOOST_STATIC_CONSTANT(bool, value = false);
1760
+ #ifndef BOOST_NO_CHAR32_T
1761
+ typedef char32_t char32_t_if_supported;
1762
+ #else
1763
+ typedef char char32_t_if_supported;
1764
+ #endif
1765
+ public:
1766
+
1767
+ BOOST_STATIC_CONSTANT(bool, value =
1768
+ (
1769
+ ::boost::type_traits::ice_or<
1770
+ is_same< T, char >::value,
1771
+ is_same< T, wchar_t_if_supported >::value,
1772
+ is_same< T, char16_t_if_supported >::value,
1773
+ is_same< T, char32_t_if_supported >::value,
1774
+ is_same< T, unsigned char >::value,
1775
+ is_same< T, signed char >::value
1776
+ >::value
1777
+ )
1778
+ );
1024
1779
  };
1025
1780
 
1026
- template<>
1027
- struct lcast_streambuf_for_source<float>
1028
- {
1029
- BOOST_STATIC_CONSTANT(bool, value = true);
1781
+ template<typename Target, typename Source>
1782
+ struct is_arithmetic_and_not_xchars
1783
+ {
1784
+ BOOST_STATIC_CONSTANT(bool, value =
1785
+ (
1786
+ ::boost::type_traits::ice_and<
1787
+ is_arithmetic<Source>::value,
1788
+ is_arithmetic<Target>::value,
1789
+ ::boost::type_traits::ice_not<
1790
+ detail::is_char_or_wchar<Target>::value
1791
+ >::value,
1792
+ ::boost::type_traits::ice_not<
1793
+ detail::is_char_or_wchar<Source>::value
1794
+ >::value
1795
+ >::value
1796
+ )
1797
+ );
1030
1798
  };
1031
-
1032
- template<>
1033
- struct lcast_streambuf_for_source<double>
1034
- {
1035
- BOOST_STATIC_CONSTANT(bool, value = true);
1799
+
1800
+ /*
1801
+ * is_xchar_to_xchar<Target, Source>::value is true, when
1802
+ * Target and Souce are the same char types, or when
1803
+ * Target and Souce are char types of the same size.
1804
+ */
1805
+ template<typename Target, typename Source>
1806
+ struct is_xchar_to_xchar
1807
+ {
1808
+ BOOST_STATIC_CONSTANT(bool, value =
1809
+ (
1810
+ ::boost::type_traits::ice_or<
1811
+ ::boost::type_traits::ice_and<
1812
+ is_same<Source,Target>::value,
1813
+ is_char_or_wchar<Target>::value
1814
+ >::value,
1815
+ ::boost::type_traits::ice_and<
1816
+ ::boost::type_traits::ice_eq< sizeof(char),sizeof(Target)>::value,
1817
+ ::boost::type_traits::ice_eq< sizeof(char),sizeof(Source)>::value,
1818
+ is_char_or_wchar<Target>::value,
1819
+ is_char_or_wchar<Source>::value
1820
+ >::value
1821
+ >::value
1822
+ )
1823
+ );
1036
1824
  };
1037
-
1038
- template<>
1039
- struct lcast_streambuf_for_source<long double>
1825
+
1826
+ template<typename Target, typename Source>
1827
+ struct is_char_array_to_stdstring
1040
1828
  {
1041
- BOOST_STATIC_CONSTANT(bool, value = true);
1829
+ BOOST_STATIC_CONSTANT(bool, value = false );
1042
1830
  };
1043
- }
1044
1831
 
1045
- namespace detail // lcast_streambuf_for_target
1046
- {
1047
- // Returns true if optimized stream wrapper needs istream for reading.
1048
- template<class Target>
1049
- struct lcast_streambuf_for_target
1832
+ template<typename CharT, typename Traits, typename Alloc>
1833
+ struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, CharT* >
1050
1834
  {
1051
- BOOST_STATIC_CONSTANT(bool, value = true);
1835
+ BOOST_STATIC_CONSTANT(bool, value = true );
1052
1836
  };
1053
1837
 
1054
- template<>
1055
- struct lcast_streambuf_for_target<char>
1838
+ template<typename CharT, typename Traits, typename Alloc>
1839
+ struct is_char_array_to_stdstring< std::basic_string<CharT, Traits, Alloc>, const CharT* >
1056
1840
  {
1057
- BOOST_STATIC_CONSTANT(bool, value = false);
1841
+ BOOST_STATIC_CONSTANT(bool, value = true );
1058
1842
  };
1059
-
1060
- #if !defined(BOOST_LCAST_NO_WCHAR_T) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
1061
- template<>
1062
- struct lcast_streambuf_for_target<wchar_t>
1843
+ #if !defined(__SUNPRO_CC)
1844
+ template<typename CharT, typename Traits, typename Alloc>
1845
+ struct is_char_array_to_stdstring< ::boost::container::basic_string<CharT, Traits, Alloc>, CharT* >
1063
1846
  {
1064
- BOOST_STATIC_CONSTANT(bool, value = false);
1847
+ BOOST_STATIC_CONSTANT(bool, value = true );
1065
1848
  };
1066
- #endif
1067
1849
 
1068
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1069
- template<class Traits, class Alloc>
1070
- struct lcast_streambuf_for_target<
1071
- std::basic_string<char,Traits,Alloc> >
1850
+ template<typename CharT, typename Traits, typename Alloc>
1851
+ struct is_char_array_to_stdstring< ::boost::container::basic_string<CharT, Traits, Alloc>, const CharT* >
1072
1852
  {
1073
- BOOST_STATIC_CONSTANT(bool, value = false);
1853
+ BOOST_STATIC_CONSTANT(bool, value = true );
1074
1854
  };
1855
+ #endif // !defined(__SUNPRO_CC)
1075
1856
 
1076
- #ifndef BOOST_LCAST_NO_WCHAR_T
1077
- template<class Traits, class Alloc>
1078
- struct lcast_streambuf_for_target<
1079
- std::basic_string<wchar_t,Traits,Alloc> >
1857
+ #if (defined _MSC_VER)
1858
+ # pragma warning( push )
1859
+ # pragma warning( disable : 4701 ) // possible use of ... before initialization
1860
+ # pragma warning( disable : 4702 ) // unreachable code
1861
+ # pragma warning( disable : 4267 ) // conversion from 'size_t' to 'unsigned int'
1862
+ #endif
1863
+ template<typename Target, typename Source>
1864
+ struct lexical_cast_do_cast
1080
1865
  {
1081
- BOOST_STATIC_CONSTANT(bool, value = false);
1866
+ static inline Target lexical_cast_impl(const Source& arg)
1867
+ {
1868
+ typedef BOOST_DEDUCED_TYPENAME detail::array_to_pointer_decay<Source>::type src;
1869
+
1870
+ typedef BOOST_DEDUCED_TYPENAME detail::widest_char<
1871
+ BOOST_DEDUCED_TYPENAME detail::stream_char<Target>::type
1872
+ , BOOST_DEDUCED_TYPENAME detail::stream_char<src>::type
1873
+ >::type char_type;
1874
+
1875
+ typedef detail::lcast_src_length<src> lcast_src_length;
1876
+ std::size_t const src_len = lcast_src_length::value;
1877
+ char_type buf[src_len + 1];
1878
+ lcast_src_length::check_coverage();
1879
+
1880
+ typedef BOOST_DEDUCED_TYPENAME
1881
+ deduce_char_traits<char_type,Target,Source>::type traits;
1882
+
1883
+ typedef BOOST_DEDUCED_TYPENAME remove_pointer<src >::type removed_ptr_t;
1884
+
1885
+ // is_char_types_match variable value can be computed via
1886
+ // sizeof(char_type) == sizeof(removed_ptr_t). But when
1887
+ // removed_ptr_t is an incomplete type or void*, compilers
1888
+ // produce warnings or errors.
1889
+ const bool is_char_types_match =
1890
+ (::boost::type_traits::ice_or<
1891
+ ::boost::type_traits::ice_and<
1892
+ ::boost::type_traits::ice_eq<sizeof(char_type), sizeof(char) >::value,
1893
+ ::boost::type_traits::ice_or<
1894
+ ::boost::is_same<char, removed_ptr_t>::value,
1895
+ ::boost::is_same<unsigned char, removed_ptr_t>::value,
1896
+ ::boost::is_same<signed char, removed_ptr_t>::value
1897
+ >::value
1898
+ >::value,
1899
+ is_same<char_type, removed_ptr_t>::value
1900
+ >::value);
1901
+
1902
+ const bool requires_stringbuf =
1903
+ !(
1904
+ ::boost::type_traits::ice_or<
1905
+ is_stdstring<src >::value,
1906
+ is_arithmetic<src >::value,
1907
+ ::boost::type_traits::ice_and<
1908
+ is_pointer<src >::value,
1909
+ is_char_or_wchar<removed_ptr_t >::value,
1910
+ is_char_types_match
1911
+ >::value
1912
+ >::value
1913
+ );
1914
+
1915
+ detail::lexical_stream_limited_src<char_type,traits, requires_stringbuf >
1916
+ interpreter(buf, buf + src_len);
1917
+
1918
+ Target result;
1919
+ // Disabling ADL, by directly specifying operators.
1920
+ if(!(interpreter.operator <<(arg) && interpreter.operator >>(result)))
1921
+ BOOST_LCAST_THROW_BAD_CAST(Source, Target);
1922
+ return result;
1923
+ }
1082
1924
  };
1925
+ #if (defined _MSC_VER)
1926
+ # pragma warning( pop )
1083
1927
  #endif
1084
- #else
1085
- template<>
1086
- struct lcast_streambuf_for_target<std::string>
1928
+
1929
+ template<typename Source>
1930
+ struct lexical_cast_copy
1087
1931
  {
1088
- BOOST_STATIC_CONSTANT(bool, value = false);
1932
+ static inline Source lexical_cast_impl(const Source &arg)
1933
+ {
1934
+ return arg;
1935
+ }
1089
1936
  };
1090
1937
 
1091
- #ifndef BOOST_LCAST_NO_WCHAR_T
1092
- template<>
1093
- struct lcast_streambuf_for_target<std::wstring>
1938
+ class precision_loss_error : public boost::numeric::bad_numeric_cast
1094
1939
  {
1095
- BOOST_STATIC_CONSTANT(bool, value = false);
1940
+ public:
1941
+ virtual const char * what() const throw()
1942
+ { return "bad numeric conversion: precision loss error"; }
1096
1943
  };
1097
- #endif
1098
- #endif
1099
- }
1100
1944
 
1101
- #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
1945
+ template<class S >
1946
+ struct throw_on_precision_loss
1947
+ {
1948
+ typedef boost::numeric::Trunc<S> Rounder;
1949
+ typedef S source_type ;
1102
1950
 
1103
- // call-by-const reference version
1951
+ typedef typename mpl::if_< is_arithmetic<S>,S,S const&>::type argument_type ;
1104
1952
 
1105
- namespace detail
1106
- {
1107
- template<class T>
1108
- struct array_to_pointer_decay
1109
- {
1110
- typedef T type;
1111
- };
1953
+ static source_type nearbyint ( argument_type s )
1954
+ {
1955
+ source_type orig_div_round = s / Rounder::nearbyint(s);
1112
1956
 
1113
- template<class T, std::size_t N>
1114
- struct array_to_pointer_decay<T[N]>
1115
- {
1116
- typedef const T * type;
1117
- };
1957
+ if ( (orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > std::numeric_limits<source_type>::epsilon() )
1958
+ BOOST_THROW_EXCEPTION( precision_loss_error() );
1959
+ return s ;
1960
+ }
1118
1961
 
1119
- #if (defined _MSC_VER)
1120
- # pragma warning( push )
1121
- # pragma warning( disable : 4701 ) // possible use of ... before initialization
1122
- # pragma warning( disable : 4702 ) // unreachable code
1123
- #endif
1962
+ typedef typename Rounder::round_style round_style;
1963
+ } ;
1124
1964
 
1125
- template< typename Target
1126
- , typename Source
1127
- , bool Unlimited // string representation of Source is unlimited
1128
- , typename CharT
1129
- >
1130
- Target lexical_cast(
1131
- BOOST_DEDUCED_TYPENAME boost::call_traits<Source>::param_type arg,
1132
- CharT* buf, std::size_t src_len)
1965
+ template<typename Target, typename Source>
1966
+ struct lexical_cast_dynamic_num_not_ignoring_minus
1133
1967
  {
1134
- typedef BOOST_DEDUCED_TYPENAME
1135
- deduce_char_traits<CharT,Target,Source>::type traits;
1968
+ static inline Target lexical_cast_impl(const Source &arg)
1969
+ {
1970
+ try{
1971
+ typedef boost::numeric::converter<
1972
+ Target,
1973
+ Source,
1974
+ boost::numeric::conversion_traits<Target,Source>,
1975
+ boost::numeric::def_overflow_handler,
1976
+ throw_on_precision_loss<Source>
1977
+ > Converter ;
1978
+
1979
+ return Converter::convert(arg);
1980
+ } catch( ::boost::numeric::bad_numeric_cast const& ) {
1981
+ BOOST_LCAST_THROW_BAD_CAST(Source, Target);
1982
+ }
1983
+ BOOST_UNREACHABLE_RETURN(static_cast<Target>(0));
1984
+ }
1985
+ };
1136
1986
 
1137
- typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
1138
- lcast_streambuf_for_target<Target>::value ||
1139
- lcast_streambuf_for_source<Source>::value
1140
- , std::basic_streambuf<CharT>
1141
- , lexical_streambuf_fake
1142
- >::type base;
1987
+ template<typename Target, typename Source>
1988
+ struct lexical_cast_dynamic_num_ignoring_minus
1989
+ {
1990
+ static inline Target lexical_cast_impl(const Source &arg)
1991
+ {
1992
+ try{
1993
+ typedef boost::numeric::converter<
1994
+ Target,
1995
+ Source,
1996
+ boost::numeric::conversion_traits<Target,Source>,
1997
+ boost::numeric::def_overflow_handler,
1998
+ throw_on_precision_loss<Source>
1999
+ > Converter ;
2000
+
2001
+ bool has_minus = ( arg < 0);
2002
+ if ( has_minus ) {
2003
+ return static_cast<Target>(-Converter::convert(-arg));
2004
+ } else {
2005
+ return Converter::convert(arg);
2006
+ }
2007
+ } catch( ::boost::numeric::bad_numeric_cast const& ) {
2008
+ BOOST_LCAST_THROW_BAD_CAST(Source, Target);
2009
+ }
2010
+ BOOST_UNREACHABLE_RETURN(static_cast<Target>(0));
2011
+ }
2012
+ };
1143
2013
 
1144
- BOOST_DEDUCED_TYPENAME boost::mpl::if_c<
1145
- Unlimited
1146
- , detail::lexical_stream<Target,Source,traits>
1147
- , detail::lexical_stream_limited_src<CharT,base,traits>
1148
- >::type interpreter(buf, buf + src_len);
1149
-
1150
- Target result;
1151
- if(!(interpreter << arg && interpreter >> result))
1152
- BOOST_LCAST_THROW_BAD_CAST(Source, Target);
1153
- return result;
1154
- }
1155
- #if (defined _MSC_VER)
1156
- # pragma warning( pop )
1157
- #endif
2014
+ /*
2015
+ * lexical_cast_dynamic_num follows the rules:
2016
+ * 1) If Source can be converted to Target without precision loss and
2017
+ * without overflows, then assign Source to Target and return
2018
+ *
2019
+ * 2) If Source is less than 0 and Target is an unsigned integer,
2020
+ * then negate Source, check the requirements of rule 1) and if
2021
+ * successful, assign static_casted Source to Target and return
2022
+ *
2023
+ * 3) Otherwise throw a bad_lexical_cast exception
2024
+ *
2025
+ *
2026
+ * Rule 2) required because boost::lexical_cast has the behavior of
2027
+ * stringstream, which uses the rules of scanf for conversions. And
2028
+ * in the C99 standard for unsigned input value minus sign is
2029
+ * optional, so if a negative number is read, no errors will arise
2030
+ * and the result will be the two's complement.
2031
+ */
2032
+ template<typename Target, typename Source>
2033
+ struct lexical_cast_dynamic_num
2034
+ {
2035
+ static inline Target lexical_cast_impl(const Source &arg)
2036
+ {
2037
+ typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
2038
+ ::boost::type_traits::ice_and<
2039
+ ::boost::type_traits::ice_or<
2040
+ ::boost::is_signed<Source>::value,
2041
+ ::boost::is_float<Source>::value
2042
+ >::value,
2043
+ ::boost::type_traits::ice_not<
2044
+ is_same<Source, bool>::value
2045
+ >::value,
2046
+ ::boost::type_traits::ice_not<
2047
+ is_same<Target, bool>::value
2048
+ >::value,
2049
+ ::boost::is_unsigned<Target>::value
2050
+ >::value,
2051
+ lexical_cast_dynamic_num_ignoring_minus<Target, Source>,
2052
+ lexical_cast_dynamic_num_not_ignoring_minus<Target, Source>
2053
+ >::type caster_type;
2054
+
2055
+ return caster_type::lexical_cast_impl(arg);
2056
+ }
2057
+ };
1158
2058
  }
1159
2059
 
1160
2060
  template<typename Target, typename Source>
1161
2061
  inline Target lexical_cast(const Source &arg)
1162
2062
  {
1163
- typedef typename detail::array_to_pointer_decay<Source>::type src;
1164
-
1165
- typedef typename detail::widest_char<
1166
- typename detail::stream_char<Target>::type
1167
- , typename detail::stream_char<src>::type
1168
- >::type char_type;
1169
-
1170
- typedef detail::lcast_src_length<char_type, src> lcast_src_length;
1171
- std::size_t const src_len = lcast_src_length::value;
1172
- char_type buf[src_len + 1];
1173
- lcast_src_length::check_coverage();
1174
- return detail::lexical_cast<Target, src, !src_len>(arg, buf, src_len);
2063
+ typedef BOOST_DEDUCED_TYPENAME detail::array_to_pointer_decay<Source>::type src;
2064
+
2065
+ typedef BOOST_DEDUCED_TYPENAME ::boost::type_traits::ice_or<
2066
+ detail::is_xchar_to_xchar<Target, src>::value,
2067
+ detail::is_char_array_to_stdstring<Target,src>::value,
2068
+ ::boost::type_traits::ice_and<
2069
+ is_same<Target, src>::value,
2070
+ detail::is_stdstring<Target>::value
2071
+ >::value
2072
+ > do_copy_type;
2073
+
2074
+ typedef BOOST_DEDUCED_TYPENAME
2075
+ detail::is_arithmetic_and_not_xchars<Target, src> do_copy_with_dynamic_check_type;
2076
+
2077
+ typedef BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
2078
+ do_copy_type::value,
2079
+ detail::lexical_cast_copy<src>,
2080
+ BOOST_DEDUCED_TYPENAME ::boost::mpl::if_c<
2081
+ do_copy_with_dynamic_check_type::value,
2082
+ detail::lexical_cast_dynamic_num<Target, src>,
2083
+ detail::lexical_cast_do_cast<Target, src>
2084
+ >::type
2085
+ >::type caster_type;
2086
+
2087
+ return caster_type::lexical_cast_impl(arg);
1175
2088
  }
1176
2089
 
1177
2090
  #else
1178
2091
 
2092
+ namespace detail // stream wrapper for handling lexical conversions
2093
+ {
2094
+ template<typename Target, typename Source, typename Traits>
2095
+ class lexical_stream
2096
+ {
2097
+ private:
2098
+ typedef typename widest_char<
2099
+ typename stream_char<Target>::type,
2100
+ typename stream_char<Source>::type>::type char_type;
2101
+
2102
+ typedef Traits traits_type;
2103
+
2104
+ public:
2105
+ lexical_stream(char_type* = 0, char_type* = 0)
2106
+ {
2107
+ stream.unsetf(std::ios::skipws);
2108
+ lcast_set_precision(stream, static_cast<Source*>(0), static_cast<Target*>(0) );
2109
+ }
2110
+ ~lexical_stream()
2111
+ {
2112
+ #if defined(BOOST_NO_STRINGSTREAM)
2113
+ stream.freeze(false);
2114
+ #endif
2115
+ }
2116
+ bool operator<<(const Source &input)
2117
+ {
2118
+ return !(stream << input).fail();
2119
+ }
2120
+ template<typename InputStreamable>
2121
+ bool operator>>(InputStreamable &output)
2122
+ {
2123
+ return !is_pointer<InputStreamable>::value &&
2124
+ stream >> output &&
2125
+ stream.get() ==
2126
+ #if defined(__GNUC__) && (__GNUC__<3) && defined(BOOST_NO_STD_WSTRING)
2127
+ // GCC 2.9x lacks std::char_traits<>::eof().
2128
+ // We use BOOST_NO_STD_WSTRING to filter out STLport and libstdc++-v3
2129
+ // configurations, which do provide std::char_traits<>::eof().
2130
+
2131
+ EOF;
2132
+ #else
2133
+ traits_type::eof();
2134
+ #endif
2135
+ }
2136
+
2137
+ bool operator>>(std::string &output)
2138
+ {
2139
+ #if defined(BOOST_NO_STRINGSTREAM)
2140
+ stream << '\0';
2141
+ #endif
2142
+ stream.str().swap(output);
2143
+ return true;
2144
+ }
2145
+ #ifndef BOOST_LCAST_NO_WCHAR_T
2146
+ bool operator>>(std::wstring &output)
2147
+ {
2148
+ stream.str().swap(output);
2149
+ return true;
2150
+ }
2151
+ #endif
2152
+
2153
+ private:
2154
+ #if defined(BOOST_NO_STRINGSTREAM)
2155
+ std::strstream stream;
2156
+ #elif defined(BOOST_NO_STD_LOCALE)
2157
+ std::stringstream stream;
2158
+ #else
2159
+ std::basic_stringstream<char_type,traits_type> stream;
2160
+ #endif
2161
+ };
2162
+ }
2163
+
1179
2164
  // call-by-value fallback version (deprecated)
1180
2165
 
1181
2166
  template<typename Target, typename Source>
@@ -1191,11 +2176,7 @@ namespace boost
1191
2176
  Target result;
1192
2177
 
1193
2178
  if(!(interpreter << arg && interpreter >> result))
1194
- #ifndef BOOST_NO_TYPEID
1195
- throw_exception(bad_lexical_cast(typeid(Source), typeid(Target)));
1196
- #else
1197
- throw_exception(bad_lexical_cast());
1198
- #endif
2179
+ BOOST_LCAST_THROW_BAD_CAST(Source, Target);
1199
2180
  return result;
1200
2181
  }
1201
2182
 
@@ -1203,7 +2184,8 @@ namespace boost
1203
2184
  }
1204
2185
 
1205
2186
  // Copyright Kevlin Henney, 2000-2005.
1206
- // Copyright Alexander Nasonov, 2006-2007.
2187
+ // Copyright Alexander Nasonov, 2006-2010.
2188
+ // Copyright Antony Polukhin, 2011-2012.
1207
2189
  //
1208
2190
  // Distributed under the Boost Software License, Version 1.0. (See
1209
2191
  // accompanying file LICENSE_1_0.txt or copy at