cpp_expression_value.hpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. http://www.boost.org/
  4. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  5. Software License, Version 1.0. (See accompanying file
  6. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. =============================================================================*/
  8. #if !defined(BOOST_CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
  9. #define BOOST_CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED
  10. #if defined (BOOST_SPIRIT_DEBUG)
  11. #include <iostream>
  12. #endif // defined(BOOST_SPIRIT_DEBUG)
  13. #include <limits>
  14. #include <boost/wave/wave_config.hpp>
  15. #include <boost/wave/grammars/cpp_value_error.hpp> // value_error
  16. // this must occur after all of the includes and before any code appears
  17. #ifdef BOOST_HAS_ABI_HEADERS
  18. #include BOOST_ABI_PREFIX
  19. #endif
  20. ///////////////////////////////////////////////////////////////////////////////
  21. namespace boost {
  22. namespace wave {
  23. namespace grammars {
  24. namespace closures {
  25. class closure_value;
  26. inline bool as_bool(closure_value const& v);
  27. ///////////////////////////////////////////////////////////////////////////////
  28. //
  29. // The closure_value class represents the closure type, which is used for the
  30. // expression grammar.
  31. //
  32. // This class was introduced to allow the expression grammar to respect
  33. // the numeric type of a numeric literal or expression result.
  34. //
  35. ///////////////////////////////////////////////////////////////////////////////
  36. class closure_value {
  37. public:
  38. enum value_type {
  39. is_int = 1,
  40. is_uint = 2,
  41. is_bool = 3
  42. };
  43. closure_value(value_error valid_ = error_noerror)
  44. : type(is_int), valid(valid_)
  45. { value.i = 0; }
  46. explicit closure_value(int i, value_error valid_ = error_noerror)
  47. : type(is_int), valid(valid_)
  48. { value.i = i; }
  49. explicit closure_value(unsigned int ui, value_error valid_ = error_noerror)
  50. : type(is_uint), valid(valid_)
  51. { value.ui = ui; }
  52. explicit closure_value(int_literal_type i, value_error valid_ = error_noerror)
  53. : type(is_int), valid(valid_)
  54. { value.i = i; }
  55. explicit closure_value(uint_literal_type ui, value_error valid_ = error_noerror)
  56. : type(is_uint), valid(valid_)
  57. { value.ui = ui; }
  58. explicit closure_value(bool b, value_error valid_ = error_noerror)
  59. : type(is_bool), valid(valid_)
  60. { value.b = b; }
  61. value_type get_type() const { return type; }
  62. value_error is_valid() const { return valid; }
  63. // explicit conversion
  64. friend int_literal_type as_int(closure_value const& v)
  65. {
  66. switch (v.type) {
  67. case is_uint: return v.value.ui;
  68. case is_bool: return v.value.b ? 1 : 0;
  69. case is_int: break;
  70. }
  71. return v.value.i;
  72. }
  73. friend uint_literal_type as_uint(closure_value const& v)
  74. {
  75. switch (v.type) {
  76. case is_uint: return v.value.ui;
  77. case is_bool: return v.value.b ? 1 : 0;
  78. case is_int: break;
  79. }
  80. return v.value.i;
  81. }
  82. friend int_literal_type as_long(closure_value const& v)
  83. {
  84. switch (v.type) {
  85. case is_uint: return v.value.ui;
  86. case is_bool: return v.value.b ? 1 : 0;
  87. case is_int: break;
  88. }
  89. return v.value.i;
  90. }
  91. friend uint_literal_type as_ulong(closure_value const& v)
  92. {
  93. switch (v.type) {
  94. case is_uint: return v.value.ui;
  95. case is_bool: return v.value.b ? 1 : 0;
  96. case is_int: break;
  97. }
  98. return v.value.i;
  99. }
  100. friend bool as_bool(closure_value const& v)
  101. {
  102. switch (v.type) {
  103. case is_uint: return v.value.ui != 0;
  104. case is_bool: return v.value.b;
  105. case is_int: break;
  106. }
  107. return v.value.i != 0.0;
  108. }
  109. // assignment
  110. closure_value &operator= (closure_value const &rhs)
  111. {
  112. switch (rhs.get_type()) {
  113. case is_int:
  114. value.i = as_long(rhs);
  115. type = is_int;
  116. break;
  117. case is_uint:
  118. value.ui = as_ulong(rhs);
  119. type = is_uint;
  120. break;
  121. case is_bool:
  122. value.b = as_bool(rhs);
  123. type = is_bool;
  124. break;
  125. }
  126. valid = rhs.valid;
  127. return *this;
  128. }
  129. closure_value &operator= (int rhs)
  130. {
  131. type = is_int;
  132. value.i = rhs;
  133. valid = error_noerror;
  134. return *this;
  135. }
  136. closure_value &operator= (unsigned int rhs)
  137. {
  138. type = is_uint;
  139. value.ui = rhs;
  140. valid = error_noerror;
  141. return *this;
  142. }
  143. closure_value &operator= (int_literal_type rhs)
  144. {
  145. type = is_int;
  146. value.i = rhs;
  147. valid = error_noerror;
  148. return *this;
  149. }
  150. closure_value &operator= (uint_literal_type rhs)
  151. {
  152. type = is_uint;
  153. value.ui = rhs;
  154. valid = error_noerror;
  155. return *this;
  156. }
  157. closure_value &operator= (bool rhs)
  158. {
  159. type = is_bool;
  160. value.b = rhs;
  161. valid = error_noerror;
  162. return *this;
  163. }
  164. // arithmetics
  165. closure_value &operator+= (closure_value const &rhs)
  166. {
  167. switch (type) {
  168. case is_int:
  169. switch(rhs.type) {
  170. case is_bool:
  171. {
  172. // bool is either 0 or 1
  173. if (((std::numeric_limits<int_literal_type>::max)() - as_long(rhs)) < value.i)
  174. {
  175. // signed overflow will occur if addition performed
  176. valid = error_integer_overflow;
  177. }
  178. else {
  179. value.i += as_long(rhs);
  180. }
  181. }
  182. break;
  183. case is_int:
  184. {
  185. if (((rhs.value.i > 0) &&
  186. (((std::numeric_limits<int_literal_type>::max)() - rhs.value.i) < value.i)) ||
  187. ((rhs.value.i < 0) &&
  188. (((std::numeric_limits<int_literal_type>::min)() - rhs.value.i) > value.i)))
  189. {
  190. // signed overflow will occur if addition performed
  191. valid = error_integer_overflow;
  192. }
  193. else {
  194. value.i += rhs.value.i;
  195. }
  196. }
  197. break;
  198. case is_uint:
  199. {
  200. uint_literal_type result = value.ui + rhs.value.ui;
  201. if (result < value.ui) {
  202. valid = error_integer_overflow;
  203. }
  204. else {
  205. value.ui = result;
  206. type = is_uint;
  207. }
  208. }
  209. break;
  210. }
  211. break;
  212. case is_uint:
  213. {
  214. uint_literal_type result = value.ui + as_ulong(rhs);
  215. if (result < value.ui) {
  216. valid = error_integer_overflow;
  217. }
  218. else {
  219. value.ui = result;
  220. }
  221. }
  222. break;
  223. case is_bool:
  224. value.i = value.b + as_bool(rhs);
  225. type = is_int;
  226. }
  227. valid = (value_error)(valid | rhs.valid);
  228. return *this;
  229. }
  230. closure_value &operator-= (closure_value const &rhs)
  231. {
  232. switch (type) {
  233. case is_int:
  234. switch(rhs.type) {
  235. case is_bool:
  236. {
  237. if (((std::numeric_limits<int_literal_type>::min)() + as_long(rhs)) > value.i)
  238. {
  239. // signed overflow will occur if subtraction performed
  240. valid = error_integer_overflow;
  241. }
  242. else {
  243. value.i -= as_long(rhs);
  244. }
  245. }
  246. break;
  247. case is_int:
  248. {
  249. if (((rhs.value.i < 0) &&
  250. (((std::numeric_limits<int_literal_type>::max)() + rhs.value.i) < value.i)) ||
  251. ((rhs.value.i > 0) &&
  252. (((std::numeric_limits<int_literal_type>::min)() + rhs.value.i) > value.i)))
  253. {
  254. // signed overflow will occur if subtraction performed
  255. valid = error_integer_overflow;
  256. }
  257. else {
  258. value.i -= rhs.value.i;
  259. }
  260. }
  261. break;
  262. case is_uint:
  263. {
  264. uint_literal_type result = value.ui - rhs.value.ui;
  265. if (result > value.ui) {
  266. valid = error_integer_overflow;
  267. }
  268. else {
  269. value.ui = result;
  270. type = is_uint;
  271. }
  272. }
  273. break;
  274. }
  275. break;
  276. case is_uint:
  277. switch(rhs.type) {
  278. case is_bool:
  279. {
  280. uint_literal_type result = value.ui - as_ulong(rhs);
  281. if (result > value.ui)
  282. {
  283. valid = error_integer_overflow;
  284. }
  285. else {
  286. value.ui = result;
  287. }
  288. }
  289. break;
  290. case is_int:
  291. {
  292. uint_literal_type result = value.ui - rhs.value.i;
  293. if ((rhs.value.i > 0L && result > value.ui) ||
  294. (rhs.value.i < 0L && result < value.ui))
  295. {
  296. valid = error_integer_overflow;
  297. }
  298. else {
  299. value.ui = result;
  300. }
  301. }
  302. break;
  303. case is_uint:
  304. {
  305. uint_literal_type result = value.ui - rhs.value.ui;
  306. if (result > value.ui) {
  307. valid = error_integer_overflow;
  308. }
  309. else {
  310. value.ui = result;
  311. }
  312. }
  313. break;
  314. }
  315. break;
  316. case is_bool:
  317. value.i = value.b - as_bool(rhs);
  318. type = is_int;
  319. }
  320. valid = (value_error)(valid | rhs.valid);
  321. return *this;
  322. }
  323. closure_value &operator*= (closure_value const &rhs)
  324. {
  325. switch (type) {
  326. case is_int:
  327. switch(rhs.type) {
  328. case is_bool: value.i *= as_long(rhs); break;
  329. case is_int:
  330. {
  331. // overflow tests for signed multiplication taken from
  332. // Warren, Hacker's Delight, 2nd Ed. p32
  333. int_literal_type mx = (std::numeric_limits<int_literal_type>::max)();
  334. int_literal_type mn = (std::numeric_limits<int_literal_type>::min)();
  335. bool ovflw =
  336. (value.i > 0) ? ((rhs.value.i > 0) ? (value.i > (mx / rhs.value.i))
  337. : (rhs.value.i < (mn / value.i)))
  338. : ((rhs.value.i > 0) ? (value.i < (mn / rhs.value.i))
  339. : ((value.i != 0) && (rhs.value.i < (mx / value.i))));
  340. if (ovflw)
  341. {
  342. valid = error_integer_overflow;
  343. }
  344. else {
  345. value.i *= rhs.value.i;
  346. }
  347. }
  348. break;
  349. case is_uint:
  350. {
  351. uint_literal_type result = value.ui * rhs.value.ui;
  352. if (0 != value.ui && 0 != rhs.value.ui &&
  353. (result / value.ui != rhs.value.ui ||
  354. result / rhs.value.ui != value.ui)
  355. )
  356. {
  357. valid = error_integer_overflow;
  358. }
  359. else {
  360. value.ui = result;
  361. type = is_uint;
  362. }
  363. }
  364. break;
  365. }
  366. break;
  367. case is_uint:
  368. {
  369. uint_literal_type rhs_val = as_ulong(rhs);
  370. uint_literal_type result = value.ui * rhs_val;
  371. if (0 != value.ui && 0 != rhs_val &&
  372. (result / value.ui != rhs_val ||
  373. result / rhs_val != value.ui)
  374. )
  375. {
  376. valid = error_integer_overflow;
  377. }
  378. else {
  379. value.ui = result;
  380. type = is_uint;
  381. }
  382. }
  383. break;
  384. case is_bool:
  385. switch (rhs.type) {
  386. case is_int:
  387. value.i = (value.b ? 1 : 0) * rhs.value.i;
  388. type = is_int;
  389. break;
  390. case is_uint:
  391. value.ui = (value.b ? 1 : 0) * rhs.value.ui;
  392. type = is_uint;
  393. break;
  394. case is_bool:
  395. value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0));
  396. break;
  397. }
  398. }
  399. valid = (value_error)(valid | rhs.valid);
  400. return *this;
  401. }
  402. closure_value &operator/= (closure_value const &rhs)
  403. {
  404. switch (type) {
  405. case is_int:
  406. switch(rhs.type) {
  407. case is_bool:
  408. case is_int:
  409. if (as_long(rhs) != 0) {
  410. if (std::numeric_limits<int_literal_type>::min() == value.i &&
  411. -1 == rhs.value.i) {
  412. // LONG_MIN / -1 on two's complement
  413. valid = error_integer_overflow;
  414. }
  415. else {
  416. value.i /= as_long(rhs);
  417. }
  418. }
  419. else {
  420. valid = error_division_by_zero; // division by zero
  421. }
  422. break;
  423. case is_uint:
  424. if (rhs.value.ui != 0) {
  425. value.ui /= rhs.value.ui;
  426. type = is_uint;
  427. }
  428. else {
  429. valid = error_division_by_zero; // division by zero
  430. }
  431. break;
  432. }
  433. break;
  434. case is_uint:
  435. if (as_ulong(rhs) != 0)
  436. value.ui /= as_ulong(rhs);
  437. else
  438. valid = error_division_by_zero; // division by zero
  439. break;
  440. case is_bool:
  441. if (as_bool(rhs)) {
  442. switch(rhs.type) {
  443. case is_int:
  444. value.i = (value.b ? 1 : 0) / rhs.value.i;
  445. type = is_int;
  446. break;
  447. case is_uint:
  448. value.i = (value.b ? 1 : 0) / rhs.value.ui;
  449. type = is_int;
  450. break;
  451. case is_bool:
  452. break;
  453. }
  454. }
  455. else {
  456. valid = error_division_by_zero; // division by zero
  457. }
  458. }
  459. return *this;
  460. }
  461. closure_value &operator%= (closure_value const &rhs)
  462. {
  463. switch (type) {
  464. case is_int:
  465. switch(rhs.type) {
  466. case is_bool:
  467. case is_int:
  468. if (as_long(rhs) != 0) {
  469. if (value.i == -value.i && -1 == rhs.value.i) {
  470. // LONG_MIN % -1 on two's complement
  471. valid = error_integer_overflow;
  472. }
  473. else {
  474. value.i %= as_long(rhs);
  475. }
  476. }
  477. else {
  478. valid = error_division_by_zero; // division by zero
  479. }
  480. break;
  481. case is_uint:
  482. if (rhs.value.ui != 0) {
  483. value.ui %= rhs.value.ui;
  484. type = is_uint;
  485. }
  486. else {
  487. valid = error_division_by_zero; // division by zero
  488. }
  489. break;
  490. }
  491. break;
  492. case is_uint:
  493. if (as_ulong(rhs) != 0)
  494. value.ui %= as_ulong(rhs);
  495. else
  496. valid = error_division_by_zero; // division by zero
  497. break;
  498. case is_bool:
  499. if (as_bool(rhs)) {
  500. switch(rhs.type) {
  501. case is_int:
  502. value.i = (value.b ? 1 : 0) % rhs.value.i;
  503. type = is_int;
  504. break;
  505. case is_uint:
  506. value.i = (value.b ? 1 : 0) % rhs.value.ui;
  507. type = is_int;
  508. break;
  509. case is_bool:
  510. break;
  511. }
  512. }
  513. else {
  514. valid = error_division_by_zero; // division by zero
  515. }
  516. }
  517. return *this;
  518. }
  519. friend closure_value
  520. operator- (closure_value const &rhs)
  521. {
  522. switch (rhs.type) {
  523. case is_int:
  524. {
  525. int_literal_type value = as_long(rhs);
  526. if (value != 0 && value == -value)
  527. return closure_value(-value, error_integer_overflow);
  528. return closure_value(-value, rhs.valid);
  529. }
  530. case is_bool: return closure_value(-as_long(rhs), rhs.valid);
  531. case is_uint: break;
  532. }
  533. int_literal_type value = as_ulong(rhs);
  534. if (value != 0 && value == -value)
  535. return closure_value(-value, error_integer_overflow);
  536. return closure_value(-value, rhs.valid);
  537. }
  538. friend closure_value
  539. operator~ (closure_value const &rhs)
  540. {
  541. return closure_value(~as_ulong(rhs), rhs.valid);
  542. }
  543. friend closure_value
  544. operator! (closure_value const &rhs)
  545. {
  546. switch (rhs.type) {
  547. case is_int: return closure_value(!as_long(rhs), rhs.valid);
  548. case is_bool: return closure_value(!as_bool(rhs), rhs.valid);
  549. case is_uint: break;
  550. }
  551. return closure_value(!as_ulong(rhs), rhs.valid);
  552. }
  553. // comparison
  554. friend closure_value
  555. operator== (closure_value const &lhs, closure_value const &rhs)
  556. {
  557. bool cmp = false;
  558. switch (lhs.type) {
  559. case is_int:
  560. switch(rhs.type) {
  561. case is_bool: cmp = as_bool(lhs) == rhs.value.b; break;
  562. case is_int: cmp = lhs.value.i == rhs.value.i; break;
  563. case is_uint: cmp = lhs.value.ui == rhs.value.ui; break;
  564. }
  565. break;
  566. case is_uint: cmp = lhs.value.ui == as_ulong(rhs); break;
  567. case is_bool: cmp = lhs.value.b == as_bool(rhs); break;
  568. }
  569. return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
  570. }
  571. friend closure_value
  572. operator!= (closure_value const &lhs, closure_value const &rhs)
  573. {
  574. return closure_value(!as_bool(lhs == rhs), (value_error)(lhs.valid | rhs.valid));
  575. }
  576. friend closure_value
  577. operator> (closure_value const &lhs, closure_value const &rhs)
  578. {
  579. bool cmp = false;
  580. switch (lhs.type) {
  581. case is_int:
  582. switch(rhs.type) {
  583. case is_bool: cmp = lhs.value.i > as_long(rhs); break;
  584. case is_int: cmp = lhs.value.i > rhs.value.i; break;
  585. case is_uint: cmp = lhs.value.ui > rhs.value.ui; break;
  586. }
  587. break;
  588. case is_uint: cmp = lhs.value.ui > as_ulong(rhs); break;
  589. case is_bool: cmp = lhs.value.b > as_bool(rhs); break;
  590. }
  591. return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
  592. }
  593. friend closure_value
  594. operator< (closure_value const &lhs, closure_value const &rhs)
  595. {
  596. bool cmp = false;
  597. switch (lhs.type) {
  598. case is_int:
  599. switch(rhs.type) {
  600. case is_bool: cmp = lhs.value.i < as_long(rhs); break;
  601. case is_int: cmp = lhs.value.i < rhs.value.i; break;
  602. case is_uint: cmp = lhs.value.ui < rhs.value.ui; break;
  603. }
  604. break;
  605. case is_uint: cmp = lhs.value.ui < as_ulong(rhs); break;
  606. case is_bool: cmp = as_bool(lhs) < as_bool(rhs); break;
  607. }
  608. return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
  609. }
  610. friend closure_value
  611. operator<= (closure_value const &lhs, closure_value const &rhs)
  612. {
  613. return closure_value(!as_bool(lhs > rhs), (value_error)(lhs.valid | rhs.valid));
  614. }
  615. friend closure_value
  616. operator>= (closure_value const &lhs, closure_value const &rhs)
  617. {
  618. return closure_value(!as_bool(lhs < rhs), (value_error)(lhs.valid | rhs.valid));
  619. }
  620. closure_value &
  621. operator<<= (closure_value const &rhs)
  622. {
  623. switch (type) {
  624. case is_bool:
  625. case is_int:
  626. switch (rhs.type) {
  627. case is_bool:
  628. case is_int:
  629. {
  630. int_literal_type shift_by = as_long(rhs);
  631. if (shift_by > 64)
  632. shift_by = 64;
  633. else if (shift_by < -64)
  634. shift_by = -64;
  635. value.i <<= shift_by;
  636. }
  637. break;
  638. case is_uint:
  639. {
  640. uint_literal_type shift_by = as_ulong(rhs);
  641. if (shift_by > 64)
  642. shift_by = 64;
  643. value.ui <<= shift_by;
  644. // Note: The usual arithmetic conversions are not performed on
  645. // bit shift operations.
  646. }
  647. break;
  648. }
  649. break;
  650. case is_uint:
  651. switch (rhs.type) {
  652. case is_bool:
  653. case is_int:
  654. {
  655. int_literal_type shift_by = as_long(rhs);
  656. if (shift_by > 64)
  657. shift_by = 64;
  658. else if (shift_by < -64)
  659. shift_by = -64;
  660. value.ui <<= shift_by;
  661. }
  662. break;
  663. case is_uint:
  664. {
  665. uint_literal_type shift_by = as_ulong(rhs);
  666. if (shift_by > 64)
  667. shift_by = 64;
  668. value.ui <<= shift_by;
  669. }
  670. break;
  671. }
  672. }
  673. valid = (value_error)(valid | rhs.valid);
  674. return *this;
  675. }
  676. closure_value &
  677. operator>>= (closure_value const &rhs)
  678. {
  679. switch (type) {
  680. case is_bool:
  681. case is_int:
  682. switch (rhs.type) {
  683. case is_bool:
  684. case is_int:
  685. {
  686. int_literal_type shift_by = as_long(rhs);
  687. if (shift_by > 64)
  688. shift_by = 64;
  689. else if (shift_by < -64)
  690. shift_by = -64;
  691. value.i >>= shift_by;
  692. }
  693. break;
  694. case is_uint:
  695. {
  696. uint_literal_type shift_by = as_ulong(rhs);
  697. if (shift_by > 64)
  698. shift_by = 64;
  699. value.ui >>= shift_by;
  700. // Note: The usual arithmetic conversions are not performed on
  701. // bit shift operations.
  702. }
  703. break;
  704. }
  705. break;
  706. case is_uint:
  707. switch (rhs.type) {
  708. case is_bool:
  709. case is_int:
  710. {
  711. int_literal_type shift_by = as_long(rhs);
  712. if (shift_by > 64)
  713. shift_by = 64;
  714. else if (shift_by < -64)
  715. shift_by = -64;
  716. value.ui >>= shift_by;
  717. }
  718. break;
  719. case is_uint:
  720. {
  721. uint_literal_type shift_by = as_ulong(rhs);
  722. if (shift_by > 64)
  723. shift_by = 64;
  724. value.ui >>= shift_by;
  725. }
  726. break;
  727. }
  728. break;
  729. }
  730. valid = (value_error)(valid | rhs.valid);
  731. return *this;
  732. }
  733. friend closure_value
  734. operator|| (closure_value const &lhs, closure_value const &rhs)
  735. {
  736. bool result = as_bool(lhs) || as_bool(rhs);
  737. return closure_value(result, (value_error)(lhs.valid | rhs.valid));
  738. }
  739. friend closure_value
  740. operator&& (closure_value const &lhs, closure_value const &rhs)
  741. {
  742. bool result = as_bool(lhs) && as_bool(rhs);
  743. return closure_value(result, (value_error)(lhs.valid | rhs.valid));
  744. }
  745. friend closure_value
  746. operator| (closure_value const &lhs, closure_value const &rhs)
  747. {
  748. uint_literal_type result = as_ulong(lhs) | as_ulong(rhs);
  749. return closure_value(result, (value_error)(lhs.valid | rhs.valid));
  750. }
  751. friend closure_value
  752. operator& (closure_value const &lhs, closure_value const &rhs)
  753. {
  754. uint_literal_type result = as_ulong(lhs) & as_ulong(rhs);
  755. return closure_value(result, (value_error)(lhs.valid | rhs.valid));
  756. }
  757. friend closure_value
  758. operator^ (closure_value const &lhs, closure_value const &rhs)
  759. {
  760. uint_literal_type result = as_ulong(lhs) ^ as_ulong(rhs);
  761. return closure_value(result, (value_error)(lhs.valid | rhs.valid));
  762. }
  763. // handle the ?: operator
  764. closure_value &
  765. handle_questionmark(closure_value const &cond, closure_value const &val2)
  766. {
  767. switch (type) {
  768. case is_int:
  769. switch (val2.type) {
  770. case is_bool: value.b = as_bool(cond) ? value.b : as_bool(val2); break;
  771. case is_int: value.i = as_bool(cond) ? value.i : as_long(val2); break;
  772. case is_uint:
  773. value.ui = as_bool(cond) ? value.ui : as_ulong(val2);
  774. type = is_uint; // changing type!
  775. break;
  776. }
  777. break;
  778. case is_uint: value.ui = as_bool(cond) ? value.ui : as_ulong(val2); break;
  779. case is_bool: value.b = as_bool(cond) ? value.b : as_bool(val2); break;
  780. }
  781. valid = as_bool(cond) ? valid : val2.valid;
  782. return *this;
  783. }
  784. #if defined (BOOST_SPIRIT_DEBUG)
  785. friend std::ostream&
  786. operator<< (std::ostream &o, closure_value const &val)
  787. {
  788. switch (val.type) {
  789. case is_int: o << "int(" << as_long(val) << ")"; break;
  790. case is_uint: o << "unsigned int(" << as_ulong(val) << ")"; break;
  791. case is_bool: o << "bool(" << as_bool(val) << ")"; break;
  792. }
  793. return o;
  794. }
  795. #endif // defined(BOOST_SPIRIT_DEBUG)
  796. private:
  797. value_type type;
  798. union {
  799. int_literal_type i;
  800. uint_literal_type ui;
  801. bool b;
  802. } value;
  803. value_error valid;
  804. };
  805. ///////////////////////////////////////////////////////////////////////////////
  806. } // namespace closures
  807. } // namespace grammars
  808. } // namespace wave
  809. } // namespace boost
  810. // the suffix header occurs after all of the code
  811. #ifdef BOOST_HAS_ABI_HEADERS
  812. #include BOOST_ABI_SUFFIX
  813. #endif
  814. #endif // !defined(BOOST_CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)