/source/Core/Scalar.cpp

https://gitlab.com/jorjpimm/lldb · C++ · 1410 lines · 1218 code · 113 blank · 79 comment · 128 complexity · 0b724427206f3abee648c44985986061 MD5 · raw file

  1. //===-- Scalar.cpp ----------------------------------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "lldb/Core/Scalar.h"
  10. #include <math.h>
  11. #include <inttypes.h>
  12. #include "lldb/Interpreter/Args.h"
  13. #include "lldb/Core/Error.h"
  14. #include "lldb/Core/Stream.h"
  15. #include "lldb/Core/DataExtractor.h"
  16. #include "lldb/Host/Endian.h"
  17. #include "Plugins/Process/Utility/InstructionUtils.h"
  18. using namespace lldb;
  19. using namespace lldb_private;
  20. //----------------------------------------------------------------------
  21. // Promote to max type currently follows the ANSI C rule for type
  22. // promotion in expressions.
  23. //----------------------------------------------------------------------
  24. static Scalar::Type
  25. PromoteToMaxType
  26. (
  27. const Scalar& lhs, // The const left hand side object
  28. const Scalar& rhs, // The const right hand side object
  29. Scalar& temp_value, // A modifiable temp value than can be used to hold either the promoted lhs or rhs object
  30. const Scalar* &promoted_lhs_ptr, // Pointer to the resulting possibly promoted value of lhs (at most one of lhs/rhs will get promoted)
  31. const Scalar* &promoted_rhs_ptr // Pointer to the resulting possibly promoted value of rhs (at most one of lhs/rhs will get promoted)
  32. )
  33. {
  34. Scalar result;
  35. // Initialize the promoted values for both the right and left hand side values
  36. // to be the objects themselves. If no promotion is needed (both right and left
  37. // have the same type), then the temp_value will not get used.
  38. promoted_lhs_ptr = &lhs;
  39. promoted_rhs_ptr = &rhs;
  40. // Extract the types of both the right and left hand side values
  41. Scalar::Type lhs_type = lhs.GetType();
  42. Scalar::Type rhs_type = rhs.GetType();
  43. if (lhs_type > rhs_type)
  44. {
  45. // Right hand side need to be promoted
  46. temp_value = rhs; // Copy right hand side into the temp value
  47. if (temp_value.Promote(lhs_type)) // Promote it
  48. promoted_rhs_ptr = &temp_value; // Update the pointer for the promoted right hand side
  49. }
  50. else if (lhs_type < rhs_type)
  51. {
  52. // Left hand side need to be promoted
  53. temp_value = lhs; // Copy left hand side value into the temp value
  54. if (temp_value.Promote(rhs_type)) // Promote it
  55. promoted_lhs_ptr = &temp_value; // Update the pointer for the promoted left hand side
  56. }
  57. // Make sure our type promotion worked as expected
  58. if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
  59. return promoted_lhs_ptr->GetType(); // Return the resulting max type
  60. // Return the void type (zero) if we fail to promote either of the values.
  61. return Scalar::e_void;
  62. }
  63. //----------------------------------------------------------------------
  64. // Scalar constructor
  65. //----------------------------------------------------------------------
  66. Scalar::Scalar() :
  67. m_type(e_void),
  68. m_data()
  69. {
  70. }
  71. //----------------------------------------------------------------------
  72. // Scalar copy constructor
  73. //----------------------------------------------------------------------
  74. Scalar::Scalar(const Scalar& rhs) :
  75. m_type(rhs.m_type),
  76. m_data(rhs.m_data) // TODO: verify that for C++ this will correctly copy the union??
  77. {
  78. }
  79. //Scalar::Scalar(const RegisterValue& reg) :
  80. // m_type(e_void),
  81. // m_data()
  82. //{
  83. // switch (reg.info.encoding)
  84. // {
  85. // case eEncodingUint: // unsigned integer
  86. // switch (reg.info.byte_size)
  87. // {
  88. // case 1: m_type = e_uint; m_data.uint = reg.value.uint8; break;
  89. // case 2: m_type = e_uint; m_data.uint = reg.value.uint16; break;
  90. // case 4: m_type = e_uint; m_data.uint = reg.value.uint32; break;
  91. // case 8: m_type = e_ulonglong; m_data.ulonglong = reg.value.uint64; break;
  92. // break;
  93. // }
  94. // break;
  95. //
  96. // case eEncodingSint: // signed integer
  97. // switch (reg.info.byte_size)
  98. // {
  99. // case 1: m_type = e_sint; m_data.sint = reg.value.sint8; break;
  100. // case 2: m_type = e_sint; m_data.sint = reg.value.sint16; break;
  101. // case 4: m_type = e_sint; m_data.sint = reg.value.sint32; break;
  102. // case 8: m_type = e_slonglong; m_data.slonglong = reg.value.sint64; break;
  103. // break;
  104. // }
  105. // break;
  106. //
  107. // case eEncodingIEEE754: // float
  108. // switch (reg.info.byte_size)
  109. // {
  110. // case 4: m_type = e_float; m_data.flt = reg.value.float32; break;
  111. // case 8: m_type = e_double; m_data.dbl = reg.value.float64; break;
  112. // break;
  113. // }
  114. // break;
  115. // case eEncodingVector: // vector registers
  116. // break;
  117. // }
  118. //}
  119. bool
  120. Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const
  121. {
  122. size_t byte_size = GetByteSize();
  123. if (byte_size > 0)
  124. {
  125. if (limit_byte_size < byte_size)
  126. {
  127. if (lldb::endian::InlHostByteOrder() == eByteOrderLittle)
  128. {
  129. // On little endian systems if we want fewer bytes from the
  130. // current type we just specify fewer bytes since the LSByte
  131. // is first...
  132. data.SetData((uint8_t*)&m_data, limit_byte_size, lldb::endian::InlHostByteOrder());
  133. }
  134. else if (lldb::endian::InlHostByteOrder() == eByteOrderBig)
  135. {
  136. // On big endian systems if we want fewer bytes from the
  137. // current type have to advance our initial byte pointer and
  138. // trim down the number of bytes since the MSByte is first
  139. data.SetData(((uint8_t*)&m_data) + byte_size - limit_byte_size, limit_byte_size, lldb::endian::InlHostByteOrder());
  140. }
  141. }
  142. else
  143. {
  144. // We want all of the data
  145. data.SetData((uint8_t*)&m_data, byte_size, lldb::endian::InlHostByteOrder());
  146. }
  147. return true;
  148. }
  149. data.Clear();
  150. return false;
  151. }
  152. size_t
  153. Scalar::GetByteSize() const
  154. {
  155. switch (m_type)
  156. {
  157. case e_void:
  158. break;
  159. case e_sint: return sizeof(m_data.sint);
  160. case e_uint: return sizeof(m_data.uint);
  161. case e_slong: return sizeof(m_data.slong);
  162. case e_ulong: return sizeof(m_data.ulong);
  163. case e_slonglong: return sizeof(m_data.slonglong);
  164. case e_ulonglong: return sizeof(m_data.ulonglong);
  165. case e_float: return sizeof(m_data.flt);
  166. case e_double: return sizeof(m_data.dbl);
  167. case e_long_double: return sizeof(m_data.ldbl);
  168. }
  169. return 0;
  170. }
  171. bool
  172. Scalar::IsZero() const
  173. {
  174. switch (m_type)
  175. {
  176. case e_void:
  177. break;
  178. case e_sint: return m_data.sint == 0;
  179. case e_uint: return m_data.uint == 0;
  180. case e_slong: return m_data.slong == 0;
  181. case e_ulong: return m_data.ulong == 0;
  182. case e_slonglong: return m_data.slonglong == 0;
  183. case e_ulonglong: return m_data.ulonglong == 0;
  184. case e_float: return m_data.flt == 0.0f;
  185. case e_double: return m_data.dbl == 0.0;
  186. case e_long_double: return m_data.ldbl == 0.0;
  187. }
  188. return false;
  189. }
  190. void
  191. Scalar::GetValue (Stream *s, bool show_type) const
  192. {
  193. if (show_type)
  194. s->Printf("(%s) ", GetTypeAsCString());
  195. switch (m_type)
  196. {
  197. case e_void:
  198. break;
  199. case e_sint: s->Printf("%i", m_data.sint); break;
  200. case e_uint: s->Printf("0x%8.8x", m_data.uint); break;
  201. case e_slong: s->Printf("%li", m_data.slong); break;
  202. case e_ulong: s->Printf("0x%8.8lx", m_data.ulong); break;
  203. case e_slonglong: s->Printf("%lli", m_data.slonglong); break;
  204. case e_ulonglong: s->Printf("0x%16.16llx", m_data.ulonglong); break;
  205. case e_float: s->Printf("%f", m_data.flt); break;
  206. case e_double: s->Printf("%g", m_data.dbl); break;
  207. case e_long_double: s->Printf("%Lg", m_data.ldbl); break;
  208. }
  209. }
  210. const char *
  211. Scalar::GetTypeAsCString() const
  212. {
  213. switch (m_type)
  214. {
  215. case e_void: return "void";
  216. case e_sint: return "int";
  217. case e_uint: return "unsigned int";
  218. case e_slong: return "long";
  219. case e_ulong: return "unsigned long";
  220. case e_slonglong: return "long long";
  221. case e_ulonglong: return "unsigned long long";
  222. case e_float: return "float";
  223. case e_double: return "double";
  224. case e_long_double: return "long double";
  225. }
  226. return "<invalid Scalar type>";
  227. }
  228. //----------------------------------------------------------------------
  229. // Scalar copy constructor
  230. //----------------------------------------------------------------------
  231. Scalar&
  232. Scalar::operator=(const Scalar& rhs)
  233. {
  234. if (this != &rhs)
  235. {
  236. m_type = rhs.m_type;
  237. ::memcpy (&m_data, &rhs.m_data, sizeof(m_data));
  238. }
  239. return *this;
  240. }
  241. Scalar&
  242. Scalar::operator= (const int v)
  243. {
  244. m_type = e_sint;
  245. m_data.sint = v;
  246. return *this;
  247. }
  248. Scalar&
  249. Scalar::operator= (unsigned int v)
  250. {
  251. m_type = e_uint;
  252. m_data.uint = v;
  253. return *this;
  254. }
  255. Scalar&
  256. Scalar::operator= (long v)
  257. {
  258. m_type = e_slong;
  259. m_data.slong = v;
  260. return *this;
  261. }
  262. Scalar&
  263. Scalar::operator= (unsigned long v)
  264. {
  265. m_type = e_ulong;
  266. m_data.ulong = v;
  267. return *this;
  268. }
  269. Scalar&
  270. Scalar::operator= (long long v)
  271. {
  272. m_type = e_slonglong;
  273. m_data.slonglong = v;
  274. return *this;
  275. }
  276. Scalar&
  277. Scalar::operator= (unsigned long long v)
  278. {
  279. m_type = e_ulonglong;
  280. m_data.ulonglong = v;
  281. return *this;
  282. }
  283. Scalar&
  284. Scalar::operator= (float v)
  285. {
  286. m_type = e_float;
  287. m_data.flt = v;
  288. return *this;
  289. }
  290. Scalar&
  291. Scalar::operator= (double v)
  292. {
  293. m_type = e_double;
  294. m_data.dbl = v;
  295. return *this;
  296. }
  297. Scalar&
  298. Scalar::operator= (long double v)
  299. {
  300. m_type = e_long_double;
  301. m_data.ldbl = v;
  302. return *this;
  303. }
  304. //----------------------------------------------------------------------
  305. // Destructor
  306. //----------------------------------------------------------------------
  307. Scalar::~Scalar()
  308. {
  309. }
  310. bool
  311. Scalar::Promote(Scalar::Type type)
  312. {
  313. bool success = false;
  314. switch (m_type)
  315. {
  316. case e_void:
  317. break;
  318. case e_sint:
  319. switch (type)
  320. {
  321. case e_void: break;
  322. case e_sint: success = true; break;
  323. case e_uint: m_data.uint = m_data.sint; success = true; break;
  324. case e_slong: m_data.slong = m_data.sint; success = true; break;
  325. case e_ulong: m_data.ulong = m_data.sint; success = true; break;
  326. case e_slonglong: m_data.slonglong = m_data.sint; success = true; break;
  327. case e_ulonglong: m_data.ulonglong = m_data.sint; success = true; break;
  328. case e_float: m_data.flt = m_data.sint; success = true; break;
  329. case e_double: m_data.dbl = m_data.sint; success = true; break;
  330. case e_long_double: m_data.ldbl = m_data.sint; success = true; break;
  331. }
  332. break;
  333. case e_uint:
  334. switch (type)
  335. {
  336. case e_void:
  337. case e_sint: break;
  338. case e_uint: success = true; break;
  339. case e_slong: m_data.slong = m_data.uint; success = true; break;
  340. case e_ulong: m_data.ulong = m_data.uint; success = true; break;
  341. case e_slonglong: m_data.slonglong = m_data.uint; success = true; break;
  342. case e_ulonglong: m_data.ulonglong = m_data.uint; success = true; break;
  343. case e_float: m_data.flt = m_data.uint; success = true; break;
  344. case e_double: m_data.dbl = m_data.uint; success = true; break;
  345. case e_long_double: m_data.ldbl = m_data.uint; success = true; break;
  346. }
  347. break;
  348. case e_slong:
  349. switch (type)
  350. {
  351. case e_void:
  352. case e_sint:
  353. case e_uint: break;
  354. case e_slong: success = true; break;
  355. case e_ulong: m_data.ulong = m_data.slong; success = true; break;
  356. case e_slonglong: m_data.slonglong = m_data.slong; success = true; break;
  357. case e_ulonglong: m_data.ulonglong = m_data.slong; success = true; break;
  358. case e_float: m_data.flt = m_data.slong; success = true; break;
  359. case e_double: m_data.dbl = m_data.slong; success = true; break;
  360. case e_long_double: m_data.ldbl = m_data.slong; success = true; break;
  361. }
  362. break;
  363. case e_ulong:
  364. switch (type)
  365. {
  366. case e_void:
  367. case e_sint:
  368. case e_uint:
  369. case e_slong: break;
  370. case e_ulong: success = true; break;
  371. case e_slonglong: m_data.slonglong = m_data.ulong; success = true; break;
  372. case e_ulonglong: m_data.ulonglong = m_data.ulong; success = true; break;
  373. case e_float: m_data.flt = m_data.ulong; success = true; break;
  374. case e_double: m_data.dbl = m_data.ulong; success = true; break;
  375. case e_long_double: m_data.ldbl = m_data.ulong; success = true; break;
  376. }
  377. break;
  378. case e_slonglong:
  379. switch (type)
  380. {
  381. case e_void:
  382. case e_sint:
  383. case e_uint:
  384. case e_slong:
  385. case e_ulong: break;
  386. case e_slonglong: success = true; break;
  387. case e_ulonglong: m_data.ulonglong = m_data.slonglong; success = true; break;
  388. case e_float: m_data.flt = m_data.slonglong; success = true; break;
  389. case e_double: m_data.dbl = m_data.slonglong; success = true; break;
  390. case e_long_double: m_data.ldbl = m_data.slonglong; success = true; break;
  391. }
  392. break;
  393. case e_ulonglong:
  394. switch (type)
  395. {
  396. case e_void:
  397. case e_sint:
  398. case e_uint:
  399. case e_slong:
  400. case e_ulong:
  401. case e_slonglong: break;
  402. case e_ulonglong: success = true; break;
  403. case e_float: m_data.flt = m_data.ulonglong; success = true; break;
  404. case e_double: m_data.dbl = m_data.ulonglong; success = true; break;
  405. case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break;
  406. }
  407. break;
  408. case e_float:
  409. switch (type)
  410. {
  411. case e_void:
  412. case e_sint:
  413. case e_uint:
  414. case e_slong:
  415. case e_ulong:
  416. case e_slonglong:
  417. case e_ulonglong: break;
  418. case e_float: success = true; break;
  419. case e_double: m_data.dbl = m_data.flt; success = true; break;
  420. case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break;
  421. }
  422. break;
  423. case e_double:
  424. switch (type)
  425. {
  426. case e_void:
  427. case e_sint:
  428. case e_uint:
  429. case e_slong:
  430. case e_ulong:
  431. case e_slonglong:
  432. case e_ulonglong:
  433. case e_float: break;
  434. case e_double: success = true; break;
  435. case e_long_double: m_data.ldbl = m_data.dbl; success = true; break;
  436. }
  437. break;
  438. case e_long_double:
  439. switch (type)
  440. {
  441. case e_void:
  442. case e_sint:
  443. case e_uint:
  444. case e_slong:
  445. case e_ulong:
  446. case e_slonglong:
  447. case e_ulonglong:
  448. case e_float:
  449. case e_double: break;
  450. case e_long_double: success = true; break;
  451. }
  452. break;
  453. }
  454. if (success)
  455. m_type = type;
  456. return success;
  457. }
  458. const char *
  459. Scalar::GetValueTypeAsCString (Scalar::Type type)
  460. {
  461. switch (type)
  462. {
  463. case e_void: return "void";
  464. case e_sint: return "int";
  465. case e_uint: return "unsigned int";
  466. case e_slong: return "long";
  467. case e_ulong: return "unsigned long";
  468. case e_slonglong: return "long long";
  469. case e_ulonglong: return "unsigned long long";
  470. case e_float: return "float";
  471. case e_double: return "double";
  472. case e_long_double: return "long double";
  473. }
  474. return "???";
  475. }
  476. Scalar::Type
  477. Scalar::GetValueTypeForSignedIntegerWithByteSize (size_t byte_size)
  478. {
  479. if (byte_size <= sizeof(sint_t))
  480. return e_sint;
  481. if (byte_size <= sizeof(slong_t))
  482. return e_slong;
  483. if (byte_size <= sizeof(slonglong_t))
  484. return e_slonglong;
  485. return e_void;
  486. }
  487. Scalar::Type
  488. Scalar::GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size)
  489. {
  490. if (byte_size <= sizeof(uint_t))
  491. return e_uint;
  492. if (byte_size <= sizeof(ulong_t))
  493. return e_ulong;
  494. if (byte_size <= sizeof(ulonglong_t))
  495. return e_ulonglong;
  496. return e_void;
  497. }
  498. Scalar::Type
  499. Scalar::GetValueTypeForFloatWithByteSize (size_t byte_size)
  500. {
  501. if (byte_size == sizeof(float_t))
  502. return e_float;
  503. if (byte_size == sizeof(double_t))
  504. return e_double;
  505. if (byte_size == sizeof(long_double_t))
  506. return e_long_double;
  507. return e_void;
  508. }
  509. bool
  510. Scalar::Cast(Scalar::Type type)
  511. {
  512. bool success = false;
  513. switch (m_type)
  514. {
  515. case e_void:
  516. break;
  517. case e_sint:
  518. switch (type)
  519. {
  520. case e_void: break;
  521. case e_sint: success = true; break;
  522. case e_uint: m_data.uint = m_data.sint; success = true; break;
  523. case e_slong: m_data.slong = m_data.sint; success = true; break;
  524. case e_ulong: m_data.ulong = m_data.sint; success = true; break;
  525. case e_slonglong: m_data.slonglong = m_data.sint; success = true; break;
  526. case e_ulonglong: m_data.ulonglong = m_data.sint; success = true; break;
  527. case e_float: m_data.flt = m_data.sint; success = true; break;
  528. case e_double: m_data.dbl = m_data.sint; success = true; break;
  529. case e_long_double: m_data.ldbl = m_data.sint; success = true; break;
  530. }
  531. break;
  532. case e_uint:
  533. switch (type)
  534. {
  535. case e_void:
  536. case e_sint: m_data.sint = m_data.uint; success = true; break;
  537. case e_uint: success = true; break;
  538. case e_slong: m_data.slong = m_data.uint; success = true; break;
  539. case e_ulong: m_data.ulong = m_data.uint; success = true; break;
  540. case e_slonglong: m_data.slonglong = m_data.uint; success = true; break;
  541. case e_ulonglong: m_data.ulonglong = m_data.uint; success = true; break;
  542. case e_float: m_data.flt = m_data.uint; success = true; break;
  543. case e_double: m_data.dbl = m_data.uint; success = true; break;
  544. case e_long_double: m_data.ldbl = m_data.uint; success = true; break;
  545. }
  546. break;
  547. case e_slong:
  548. switch (type)
  549. {
  550. case e_void:
  551. case e_sint: m_data.sint = (sint_t)m_data.slong; success = true; break;
  552. case e_uint: m_data.uint = (uint_t)m_data.slong; success = true; break;
  553. case e_slong: success = true; break;
  554. case e_ulong: m_data.ulong = m_data.slong; success = true; break;
  555. case e_slonglong: m_data.slonglong = m_data.slong; success = true; break;
  556. case e_ulonglong: m_data.ulonglong = m_data.slong; success = true; break;
  557. case e_float: m_data.flt = m_data.slong; success = true; break;
  558. case e_double: m_data.dbl = m_data.slong; success = true; break;
  559. case e_long_double: m_data.ldbl = m_data.slong; success = true; break;
  560. }
  561. break;
  562. case e_ulong:
  563. switch (type)
  564. {
  565. case e_void:
  566. case e_sint: m_data.sint = (sint_t)m_data.ulong; success = true; break;
  567. case e_uint: m_data.uint = (uint_t)m_data.ulong; success = true; break;
  568. case e_slong: m_data.slong = m_data.ulong; success = true; break;
  569. case e_ulong: success = true; break;
  570. case e_slonglong: m_data.slonglong = m_data.ulong; success = true; break;
  571. case e_ulonglong: m_data.ulonglong = m_data.ulong; success = true; break;
  572. case e_float: m_data.flt = m_data.ulong; success = true; break;
  573. case e_double: m_data.dbl = m_data.ulong; success = true; break;
  574. case e_long_double: m_data.ldbl = m_data.ulong; success = true; break;
  575. }
  576. break;
  577. case e_slonglong:
  578. switch (type)
  579. {
  580. case e_void:
  581. case e_sint: m_data.sint = (sint_t)m_data.slonglong; success = true; break;
  582. case e_uint: m_data.uint = (uint_t)m_data.slonglong; success = true; break;
  583. case e_slong: m_data.slong = m_data.slonglong; success = true; break;
  584. case e_ulong: m_data.ulong = m_data.slonglong; success = true; break;
  585. case e_slonglong: success = true; break;
  586. case e_ulonglong: m_data.ulonglong = m_data.slonglong; success = true; break;
  587. case e_float: m_data.flt = m_data.slonglong; success = true; break;
  588. case e_double: m_data.dbl = m_data.slonglong; success = true; break;
  589. case e_long_double: m_data.ldbl = m_data.slonglong; success = true; break;
  590. }
  591. break;
  592. case e_ulonglong:
  593. switch (type)
  594. {
  595. case e_void:
  596. case e_sint: m_data.sint = (sint_t)m_data.ulonglong; success = true; break;
  597. case e_uint: m_data.uint = (uint_t)m_data.ulonglong; success = true; break;
  598. case e_slong: m_data.slong = m_data.ulonglong; success = true; break;
  599. case e_ulong: m_data.ulong = m_data.ulonglong; success = true; break;
  600. case e_slonglong: m_data.slonglong = m_data.ulonglong; success = true; break;
  601. case e_ulonglong: success = true; break;
  602. case e_float: m_data.flt = m_data.ulonglong; success = true; break;
  603. case e_double: m_data.dbl = m_data.ulonglong; success = true; break;
  604. case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break;
  605. }
  606. break;
  607. case e_float:
  608. switch (type)
  609. {
  610. case e_void:
  611. case e_sint: m_data.sint = (sint_t)m_data.flt; success = true; break;
  612. case e_uint: m_data.uint = (uint_t)m_data.flt; success = true; break;
  613. case e_slong: m_data.slong = (slong_t)m_data.flt; success = true; break;
  614. case e_ulong: m_data.ulong = (ulong_t)m_data.flt; success = true; break;
  615. case e_slonglong: m_data.slonglong = (slonglong_t)m_data.flt; success = true; break;
  616. case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.flt; success = true; break;
  617. case e_float: success = true; break;
  618. case e_double: m_data.dbl = m_data.flt; success = true; break;
  619. case e_long_double: m_data.ldbl = m_data.flt; success = true; break;
  620. }
  621. break;
  622. case e_double:
  623. switch (type)
  624. {
  625. case e_void:
  626. case e_sint: m_data.sint = (sint_t)m_data.dbl; success = true; break;
  627. case e_uint: m_data.uint = (uint_t)m_data.dbl; success = true; break;
  628. case e_slong: m_data.slong = (slong_t)m_data.dbl; success = true; break;
  629. case e_ulong: m_data.ulong = (ulong_t)m_data.dbl; success = true; break;
  630. case e_slonglong: m_data.slonglong = (slonglong_t)m_data.dbl; success = true; break;
  631. case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.dbl; success = true; break;
  632. case e_float: m_data.flt = (float_t)m_data.dbl; success = true; break;
  633. case e_double: success = true; break;
  634. case e_long_double: m_data.ldbl = m_data.dbl; success = true; break;
  635. }
  636. break;
  637. case e_long_double:
  638. switch (type)
  639. {
  640. case e_void:
  641. case e_sint: m_data.sint = (sint_t)m_data.ldbl; success = true; break;
  642. case e_uint: m_data.uint = (uint_t)m_data.ldbl; success = true; break;
  643. case e_slong: m_data.slong = (slong_t)m_data.ldbl; success = true; break;
  644. case e_ulong: m_data.ulong = (ulong_t)m_data.ldbl; success = true; break;
  645. case e_slonglong: m_data.slonglong = (slonglong_t)m_data.ldbl; success = true; break;
  646. case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.ldbl; success = true; break;
  647. case e_float: m_data.flt = (float_t)m_data.ldbl; success = true; break;
  648. case e_double: m_data.dbl = (double_t)m_data.ldbl; success = true; break;
  649. case e_long_double: success = true; break;
  650. }
  651. break;
  652. }
  653. if (success)
  654. m_type = type;
  655. return success;
  656. }
  657. bool
  658. Scalar::MakeSigned ()
  659. {
  660. bool success = false;
  661. switch (m_type)
  662. {
  663. case e_void: break;
  664. case e_sint: success = true; break;
  665. case e_uint: m_type = e_sint; success = true; break;
  666. case e_slong: success = true; break;
  667. case e_ulong: m_type = e_slong; success = true; break;
  668. case e_slonglong: success = true; break;
  669. case e_ulonglong: m_type = e_slonglong; success = true; break;
  670. case e_float: success = true; break;
  671. case e_double: success = true; break;
  672. case e_long_double: success = true; break;
  673. }
  674. return success;
  675. }
  676. int
  677. Scalar::SInt(int fail_value) const
  678. {
  679. switch (m_type)
  680. {
  681. case e_void: break;
  682. case e_sint: return m_data.sint;
  683. case e_uint: return (int)m_data.uint;
  684. case e_slong: return (int)m_data.slong;
  685. case e_ulong: return (int)m_data.ulong;
  686. case e_slonglong: return (int)m_data.slonglong;
  687. case e_ulonglong: return (int)m_data.ulonglong;
  688. case e_float: return (int)m_data.flt;
  689. case e_double: return (int)m_data.dbl;
  690. case e_long_double: return (int)m_data.ldbl;
  691. }
  692. return fail_value;
  693. }
  694. unsigned int
  695. Scalar::UInt(unsigned int fail_value) const
  696. {
  697. switch (m_type)
  698. {
  699. case e_void: break;
  700. case e_sint: return (unsigned int)m_data.sint;
  701. case e_uint: return (unsigned int)m_data.uint;
  702. case e_slong: return (unsigned int)m_data.slong;
  703. case e_ulong: return (unsigned int)m_data.ulong;
  704. case e_slonglong: return (unsigned int)m_data.slonglong;
  705. case e_ulonglong: return (unsigned int)m_data.ulonglong;
  706. case e_float: return (unsigned int)m_data.flt;
  707. case e_double: return (unsigned int)m_data.dbl;
  708. case e_long_double: return (unsigned int)m_data.ldbl;
  709. }
  710. return fail_value;
  711. }
  712. long
  713. Scalar::SLong(long fail_value) const
  714. {
  715. switch (m_type)
  716. {
  717. case e_void: break;
  718. case e_sint: return (long)m_data.sint;
  719. case e_uint: return (long)m_data.uint;
  720. case e_slong: return (long)m_data.slong;
  721. case e_ulong: return (long)m_data.ulong;
  722. case e_slonglong: return (long)m_data.slonglong;
  723. case e_ulonglong: return (long)m_data.ulonglong;
  724. case e_float: return (long)m_data.flt;
  725. case e_double: return (long)m_data.dbl;
  726. case e_long_double: return (long)m_data.ldbl;
  727. }
  728. return fail_value;
  729. }
  730. unsigned long
  731. Scalar::ULong(unsigned long fail_value) const
  732. {
  733. switch (m_type)
  734. {
  735. case e_void: break;
  736. case e_sint: return (unsigned long)m_data.sint;
  737. case e_uint: return (unsigned long)m_data.uint;
  738. case e_slong: return (unsigned long)m_data.slong;
  739. case e_ulong: return (unsigned long)m_data.ulong;
  740. case e_slonglong: return (unsigned long)m_data.slonglong;
  741. case e_ulonglong: return (unsigned long)m_data.ulonglong;
  742. case e_float: return (unsigned long)m_data.flt;
  743. case e_double: return (unsigned long)m_data.dbl;
  744. case e_long_double: return (unsigned long)m_data.ldbl;
  745. }
  746. return fail_value;
  747. }
  748. uint64_t
  749. Scalar::GetRawBits64(uint64_t fail_value) const
  750. {
  751. switch (m_type)
  752. {
  753. case e_void:
  754. break;
  755. case e_sint:
  756. case e_uint:
  757. return m_data.uint;
  758. case e_slong:
  759. case e_ulong:
  760. return m_data.ulong;
  761. case e_slonglong:
  762. case e_ulonglong:
  763. return m_data.ulonglong;
  764. case e_float:
  765. if (sizeof(m_data.flt) == sizeof(m_data.uint))
  766. return m_data.uint;
  767. else if (sizeof(m_data.flt) == sizeof(m_data.ulong))
  768. return m_data.ulong;
  769. else if (sizeof(m_data.flt) == sizeof(m_data.ulonglong))
  770. return m_data.ulonglong;
  771. break;
  772. case e_double:
  773. if (sizeof(m_data.dbl) == sizeof(m_data.uint))
  774. return m_data.uint;
  775. else if (sizeof(m_data.dbl) == sizeof(m_data.ulong))
  776. return m_data.ulong;
  777. else if (sizeof(m_data.dbl) == sizeof(m_data.ulonglong))
  778. return m_data.ulonglong;
  779. break;
  780. case e_long_double:
  781. if (sizeof(m_data.ldbl) == sizeof(m_data.uint))
  782. return m_data.uint;
  783. else if (sizeof(m_data.ldbl) == sizeof(m_data.ulong))
  784. return m_data.ulong;
  785. else if (sizeof(m_data.ldbl) == sizeof(m_data.ulonglong))
  786. return m_data.ulonglong;
  787. break;
  788. }
  789. return fail_value;
  790. }
  791. long long
  792. Scalar::SLongLong(long long fail_value) const
  793. {
  794. switch (m_type)
  795. {
  796. case e_void: break;
  797. case e_sint: return (long long)m_data.sint;
  798. case e_uint: return (long long)m_data.uint;
  799. case e_slong: return (long long)m_data.slong;
  800. case e_ulong: return (long long)m_data.ulong;
  801. case e_slonglong: return (long long)m_data.slonglong;
  802. case e_ulonglong: return (long long)m_data.ulonglong;
  803. case e_float: return (long long)m_data.flt;
  804. case e_double: return (long long)m_data.dbl;
  805. case e_long_double: return (long long)m_data.ldbl;
  806. }
  807. return fail_value;
  808. }
  809. unsigned long long
  810. Scalar::ULongLong(unsigned long long fail_value) const
  811. {
  812. switch (m_type)
  813. {
  814. case e_void: break;
  815. case e_sint: return (unsigned long long)m_data.sint;
  816. case e_uint: return (unsigned long long)m_data.uint;
  817. case e_slong: return (unsigned long long)m_data.slong;
  818. case e_ulong: return (unsigned long long)m_data.ulong;
  819. case e_slonglong: return (unsigned long long)m_data.slonglong;
  820. case e_ulonglong: return (unsigned long long)m_data.ulonglong;
  821. case e_float: return (unsigned long long)m_data.flt;
  822. case e_double: return (unsigned long long)m_data.dbl;
  823. case e_long_double: return (unsigned long long)m_data.ldbl;
  824. }
  825. return fail_value;
  826. }
  827. float
  828. Scalar::Float(float fail_value) const
  829. {
  830. switch (m_type)
  831. {
  832. case e_void: break;
  833. case e_sint: return (float)m_data.sint;
  834. case e_uint: return (float)m_data.uint;
  835. case e_slong: return (float)m_data.slong;
  836. case e_ulong: return (float)m_data.ulong;
  837. case e_slonglong: return (float)m_data.slonglong;
  838. case e_ulonglong: return (float)m_data.ulonglong;
  839. case e_float: return (float)m_data.flt;
  840. case e_double: return (float)m_data.dbl;
  841. case e_long_double: return (float)m_data.ldbl;
  842. }
  843. return fail_value;
  844. }
  845. double
  846. Scalar::Double(double fail_value) const
  847. {
  848. switch (m_type)
  849. {
  850. case e_void: break;
  851. case e_sint: return (double)m_data.sint;
  852. case e_uint: return (double)m_data.uint;
  853. case e_slong: return (double)m_data.slong;
  854. case e_ulong: return (double)m_data.ulong;
  855. case e_slonglong: return (double)m_data.slonglong;
  856. case e_ulonglong: return (double)m_data.ulonglong;
  857. case e_float: return (double)m_data.flt;
  858. case e_double: return (double)m_data.dbl;
  859. case e_long_double: return (double)m_data.ldbl;
  860. }
  861. return fail_value;
  862. }
  863. long double
  864. Scalar::LongDouble(long double fail_value) const
  865. {
  866. switch (m_type)
  867. {
  868. case e_void: break;
  869. case e_sint: return (long double)m_data.sint;
  870. case e_uint: return (long double)m_data.uint;
  871. case e_slong: return (long double)m_data.slong;
  872. case e_ulong: return (long double)m_data.ulong;
  873. case e_slonglong: return (long double)m_data.slonglong;
  874. case e_ulonglong: return (long double)m_data.ulonglong;
  875. case e_float: return (long double)m_data.flt;
  876. case e_double: return (long double)m_data.dbl;
  877. case e_long_double: return (long double)m_data.ldbl;
  878. }
  879. return fail_value;
  880. }
  881. Scalar&
  882. Scalar::operator+= (const Scalar& rhs)
  883. {
  884. Scalar temp_value;
  885. const Scalar* a;
  886. const Scalar* b;
  887. if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != Scalar::e_void)
  888. {
  889. switch (m_type)
  890. {
  891. case e_void: break;
  892. case e_sint: m_data.sint = a->m_data.sint + b->m_data.sint; break;
  893. case e_uint: m_data.uint = a->m_data.uint + b->m_data.uint; break;
  894. case e_slong: m_data.slong = a->m_data.slong + b->m_data.slong; break;
  895. case e_ulong: m_data.ulong = a->m_data.ulong + b->m_data.ulong; break;
  896. case e_slonglong: m_data.slonglong = a->m_data.slonglong + b->m_data.slonglong; break;
  897. case e_ulonglong: m_data.ulonglong = a->m_data.ulonglong + b->m_data.ulonglong; break;
  898. case e_float: m_data.flt = a->m_data.flt + b->m_data.flt; break;
  899. case e_double: m_data.dbl = a->m_data.dbl + b->m_data.dbl; break;
  900. case e_long_double: m_data.ldbl = a->m_data.ldbl + b->m_data.ldbl; break;
  901. }
  902. }
  903. return *this;
  904. }
  905. Scalar&
  906. Scalar::operator<<= (const Scalar& rhs)
  907. {
  908. switch (m_type)
  909. {
  910. case e_void:
  911. case e_float:
  912. case e_double:
  913. case e_long_double:
  914. m_type = e_void;
  915. break;
  916. case e_sint:
  917. switch (rhs.m_type)
  918. {
  919. case e_void:
  920. case e_float:
  921. case e_double:
  922. case e_long_double:
  923. m_type = e_void;
  924. break;
  925. case e_sint: m_data.sint <<= rhs.m_data.sint; break;
  926. case e_uint: m_data.sint <<= rhs.m_data.uint; break;
  927. case e_slong: m_data.sint <<= rhs.m_data.slong; break;
  928. case e_ulong: m_data.sint <<= rhs.m_data.ulong; break;
  929. case e_slonglong: m_data.sint <<= rhs.m_data.slonglong; break;
  930. case e_ulonglong: m_data.sint <<= rhs.m_data.ulonglong; break;
  931. }
  932. break;
  933. case e_uint:
  934. switch (rhs.m_type)
  935. {
  936. case e_void:
  937. case e_float:
  938. case e_double:
  939. case e_long_double:
  940. m_type = e_void;
  941. break;
  942. case e_sint: m_data.uint <<= rhs.m_data.sint; break;
  943. case e_uint: m_data.uint <<= rhs.m_data.uint; break;
  944. case e_slong: m_data.uint <<= rhs.m_data.slong; break;
  945. case e_ulong: m_data.uint <<= rhs.m_data.ulong; break;
  946. case e_slonglong: m_data.uint <<= rhs.m_data.slonglong; break;
  947. case e_ulonglong: m_data.uint <<= rhs.m_data.ulonglong; break;
  948. }
  949. break;
  950. case e_slong:
  951. switch (rhs.m_type)
  952. {
  953. case e_void:
  954. case e_float:
  955. case e_double:
  956. case e_long_double:
  957. m_type = e_void;
  958. break;
  959. case e_sint: m_data.slong <<= rhs.m_data.sint; break;
  960. case e_uint: m_data.slong <<= rhs.m_data.uint; break;
  961. case e_slong: m_data.slong <<= rhs.m_data.slong; break;
  962. case e_ulong: m_data.slong <<= rhs.m_data.ulong; break;
  963. case e_slonglong: m_data.slong <<= rhs.m_data.slonglong; break;
  964. case e_ulonglong: m_data.slong <<= rhs.m_data.ulonglong; break;
  965. }
  966. break;
  967. case e_ulong:
  968. switch (rhs.m_type)
  969. {
  970. case e_void:
  971. case e_float:
  972. case e_double:
  973. case e_long_double:
  974. m_type = e_void;
  975. break;
  976. case e_sint: m_data.ulong <<= rhs.m_data.sint; break;
  977. case e_uint: m_data.ulong <<= rhs.m_data.uint; break;
  978. case e_slong: m_data.ulong <<= rhs.m_data.slong; break;
  979. case e_ulong: m_data.ulong <<= rhs.m_data.ulong; break;
  980. case e_slonglong: m_data.ulong <<= rhs.m_data.slonglong; break;
  981. case e_ulonglong: m_data.ulong <<= rhs.m_data.ulonglong; break;
  982. }
  983. break;
  984. case e_slonglong:
  985. switch (rhs.m_type)
  986. {
  987. case e_void:
  988. case e_float:
  989. case e_double:
  990. case e_long_double:
  991. m_type = e_void;
  992. break;
  993. case e_sint: m_data.slonglong <<= rhs.m_data.sint; break;
  994. case e_uint: m_data.slonglong <<= rhs.m_data.uint; break;
  995. case e_slong: m_data.slonglong <<= rhs.m_data.slong; break;
  996. case e_ulong: m_data.slonglong <<= rhs.m_data.ulong; break;
  997. case e_slonglong: m_data.slonglong <<= rhs.m_data.slonglong; break;
  998. case e_ulonglong: m_data.slonglong <<= rhs.m_data.ulonglong; break;
  999. }
  1000. break;
  1001. case e_ulonglong:
  1002. switch (rhs.m_type)
  1003. {
  1004. case e_void:
  1005. case e_float:
  1006. case e_double:
  1007. case e_long_double:
  1008. m_type = e_void;
  1009. break;
  1010. case e_sint: m_data.ulonglong <<= rhs.m_data.sint; break;
  1011. case e_uint: m_data.ulonglong <<= rhs.m_data.uint; break;
  1012. case e_slong: m_data.ulonglong <<= rhs.m_data.slong; break;
  1013. case e_ulong: m_data.ulonglong <<= rhs.m_data.ulong; break;
  1014. case e_slonglong: m_data.ulonglong <<= rhs.m_data.slonglong; break;
  1015. case e_ulonglong: m_data.ulonglong <<= rhs.m_data.ulonglong; break;
  1016. }
  1017. break;
  1018. }
  1019. return *this;
  1020. }
  1021. bool
  1022. Scalar::ShiftRightLogical(const Scalar& rhs)
  1023. {
  1024. switch (m_type)
  1025. {
  1026. case e_void:
  1027. case e_float:
  1028. case e_double:
  1029. case e_long_double:
  1030. m_type = e_void;
  1031. break;
  1032. case e_sint:
  1033. case e_uint:
  1034. switch (rhs.m_type)
  1035. {
  1036. case e_void:
  1037. case e_float:
  1038. case e_double:
  1039. case e_long_double:
  1040. m_type = e_void;
  1041. break;
  1042. case e_sint: m_data.uint >>= rhs.m_data.sint; break;
  1043. case e_uint: m_data.uint >>= rhs.m_data.uint; break;
  1044. case e_slong: m_data.uint >>= rhs.m_data.slong; break;
  1045. case e_ulong: m_data.uint >>= rhs.m_data.ulong; break;
  1046. case e_slonglong: m_data.uint >>= rhs.m_data.slonglong; break;
  1047. case e_ulonglong: m_data.uint >>= rhs.m_data.ulonglong; break;
  1048. }
  1049. break;
  1050. case e_slong:
  1051. case e_ulong:
  1052. switch (rhs.m_type)
  1053. {
  1054. case e_void:
  1055. case e_float:
  1056. case e_double:
  1057. case e_long_double:
  1058. m_type = e_void;
  1059. break;
  1060. case e_sint: m_data.ulong >>= rhs.m_data.sint; break;
  1061. case e_uint: m_data.ulong >>= rhs.m_data.uint; break;
  1062. case e_slong: m_data.ulong >>= rhs.m_data.slong; break;
  1063. case e_ulong: m_data.ulong >>= rhs.m_data.ulong; break;
  1064. case e_slonglong: m_data.ulong >>= rhs.m_data.slonglong; break;
  1065. case e_ulonglong: m_data.ulong >>= rhs.m_data.ulonglong; break;
  1066. }
  1067. break;
  1068. case e_slonglong:
  1069. case e_ulonglong:
  1070. switch (rhs.m_type)
  1071. {
  1072. case e_void:
  1073. case e_float:
  1074. case e_double:
  1075. case e_long_double:
  1076. m_type = e_void;
  1077. break;
  1078. case e_sint: m_data.ulonglong >>= rhs.m_data.sint; break;
  1079. case e_uint: m_data.ulonglong >>= rhs.m_data.uint; break;
  1080. case e_slong: m_data.ulonglong >>= rhs.m_data.slong; break;
  1081. case e_ulong: m_data.ulonglong >>= rhs.m_data.ulong; break;
  1082. case e_slonglong: m_data.ulonglong >>= rhs.m_data.slonglong; break;
  1083. case e_ulonglong: m_data.ulonglong >>= rhs.m_data.ulonglong; break;
  1084. }
  1085. break;
  1086. }
  1087. return m_type != e_void;
  1088. }
  1089. Scalar&
  1090. Scalar::operator>>= (const Scalar& rhs)
  1091. {
  1092. switch (m_type)
  1093. {
  1094. case e_void:
  1095. case e_float:
  1096. case e_double:
  1097. case e_long_double:
  1098. m_type = e_void;
  1099. break;
  1100. case e_sint:
  1101. switch (rhs.m_type)
  1102. {
  1103. case e_void:
  1104. case e_float:
  1105. case e_double:
  1106. case e_long_double:
  1107. m_type = e_void;
  1108. break;
  1109. case e_sint: m_data.sint >>= rhs.m_data.sint; break;
  1110. case e_uint: m_data.sint >>= rhs.m_data.uint; break;
  1111. case e_slong: m_data.sint >>= rhs.m_data.slong; break;
  1112. case e_ulong: m_data.sint >>= rhs.m_data.ulong; break;
  1113. case e_slonglong: m_data.sint >>= rhs.m_data.slonglong; break;
  1114. case e_ulonglong: m_data.sint >>= rhs.m_data.ulonglong; break;
  1115. }
  1116. break;
  1117. case e_uint:
  1118. switch (rhs.m_type)
  1119. {
  1120. case e_void:
  1121. case e_float:
  1122. case e_double:
  1123. case e_long_double:
  1124. m_type = e_void;
  1125. break;
  1126. case e_sint: m_data.uint >>= rhs.m_data.sint; break;
  1127. case e_uint: m_data.uint >>= rhs.m_data.uint; break;
  1128. case e_slong: m_data.uint >>= rhs.m_data.slong; break;
  1129. case e_ulong: m_data.uint >>= rhs.m_data.ulong; break;
  1130. case e_slonglong: m_data.uint >>= rhs.m_data.slonglong; break;
  1131. case e_ulonglong: m_data.uint >>= rhs.m_data.ulonglong; break;
  1132. }
  1133. break;
  1134. case e_slong:
  1135. switch (rhs.m_type)
  1136. {
  1137. case e_void:
  1138. case e_float:
  1139. case e_double:
  1140. case e_long_double:
  1141. m_type = e_void;
  1142. break;
  1143. case e_sint: m_data.slong >>= rhs.m_data.sint; break;
  1144. case e_uint: m_data.slong >>= rhs.m_data.uint; break;
  1145. case e_slong: m_data.slong >>= rhs.m_data.slong; break;
  1146. case e_ulong: m_data.slong >>= rhs.m_data.ulong; break;
  1147. case e_slonglong: m_data.slong >>= rhs.m_data.slonglong; break;
  1148. case e_ulonglong: m_data.slong >>= rhs.m_data.ulonglong; break;
  1149. }
  1150. break;
  1151. case e_ulong:
  1152. switch (rhs.m_type)
  1153. {
  1154. case e_void:
  1155. case e_float:
  1156. case e_double:
  1157. case e_long_double:
  1158. m_type = e_void;
  1159. break;
  1160. case e_sint: m_data.ulong >>= rhs.m_data.sint; break;
  1161. case e_uint: m_data.ulong >>= rhs.m_data.uint; break;
  1162. case e_slong: m_data.ulong >>= rhs.m_data.slong; break;
  1163. case e_ulong: m_data.ulong >>= rhs.m_data.ulong; break;
  1164. case e_slonglong: m_data.ulong >>= rhs.m_data.slonglong; break;
  1165. case e_ulonglong: m_data.ulong >>= rhs.m_data.ulonglong; break;
  1166. }
  1167. break;
  1168. case e_slonglong:
  1169. switch (rhs.m_type)
  1170. {
  1171. case e_void:
  1172. case e_float:
  1173. case e_double:
  1174. case e_long_double:
  1175. m_type = e_void;
  1176. break;
  1177. case e_sint: m_data.slonglong >>= rhs.m_data.sint; break;
  1178. case e_uint: m_data.slonglong >>= rhs.m_data.uint; break;
  1179. case e_slong: m_data.slonglong >>= rhs.m_data.slong; break;
  1180. case e_ulong: m_data.slonglong >>= rhs.m_data.ulong; break;
  1181. case e_slonglong: m_data.slonglong >>= rhs.m_data.slonglong; break;
  1182. case e_ulonglong: m_data.slonglong >>= rhs.m_data.ulonglong; break;
  1183. }
  1184. break;
  1185. case e_ulonglong:
  1186. switch (rhs.m_type)
  1187. {
  1188. case e_void:
  1189. case e_float:
  1190. case e_double:
  1191. case e_long_double:
  1192. m_type = e_void;
  1193. break;
  1194. case e_sint: m_data.ulonglong >>= rhs.m_data.sint; break;
  1195. case e_uint: m_data.ulonglong >>= rhs.m_data.uint; break;
  1196. case e_slong: m_data.ulonglong >>= rhs.m_data.slong; break;
  1197. case e_ulong: m_data.ulonglong >>= rhs.m_data.ulong; break;
  1198. case e_slonglong: m_data.ulonglong >>= rhs.m_data.slonglong; break;
  1199. case e_ulonglong: m_data.ulonglong >>= rhs.m_data.ulonglong; break;
  1200. }
  1201. break;
  1202. }
  1203. return *this;
  1204. }
  1205. Scalar&
  1206. Scalar::operator&= (const Scalar& rhs)
  1207. {
  1208. switch (m_type)
  1209. {
  1210. case e_void:
  1211. case e_float:
  1212. case e_double:
  1213. case e_long_double:
  1214. m_type = e_void;
  1215. break;
  1216. case e_sint:
  1217. switch (rhs.m_type)
  1218. {
  1219. case e_void:
  1220. case e_float:
  1221. case e_double:
  1222. case e_long_double:
  1223. m_type = e_void;
  1224. break;
  1225. case e_sint: m_data.sint &= rhs.m_data.sint; break;
  1226. case e_uint: m_data.sint &= rhs.m_data.uint; break;
  1227. case e_slong: m_data.sint &= rhs.m_data.slong; break;
  1228. case e_ulong: m_data.sint &= rhs.m_data.ulong; break;
  1229. case e_slonglong: m_data.sint &= rhs.m_data.slonglong; break;
  1230. case e_ulonglong: m_data.sint &= rhs.m_data.ulonglong; break;
  1231. }
  1232. break;
  1233. case e_uint:
  1234. switch (rhs.m_type)
  1235. {
  1236. case e_void:
  1237. case e_float:
  1238. case e_double:
  1239. case e_long_double:
  1240. m_type = e_void;
  1241. break;
  1242. case e_sint: m_data.uint &= rhs.m_data.sint; break;
  1243. case e_uint: m_data.uint &= rhs.m_data.uint; break;
  1244. case e_slong: m_data.uint &= rhs.m_data.slong; break;
  1245. case e_ulong: m_data.uint &= rhs.m_data.ulong; break;
  1246. case e_slonglong: m_data.uint &= rhs.m_data.slonglong; break;
  1247. case e_ulonglong: m_data.uint &= rhs.m_data.ulonglong; break;
  1248. }
  1249. break;
  1250. case e_slong:
  1251. switch (rhs.m_type)
  1252. {
  1253. case e_void:
  1254. case e_float:
  1255. case e_double:
  1256. case e_long_double:
  1257. m_type = e_void;
  1258. break;
  1259. case e_sint: m_data.slong &= rhs.m_data.sint; break;
  1260. case e_uint: m_data.slong &= rhs.m_data.uint; break;
  1261. case e_slong: m_data.slong &= rhs.m_data.slong; break;
  1262. case e_ulong: m_data.slong &= rhs.m_data.ulong; break;
  1263. case e_slonglong: m_data.slong &= rhs.m_data.slonglong; break;
  1264. case e_ulonglong: m_data.slong &= rhs.m_data.ulonglong; break;
  1265. }
  1266. break;
  1267. case e_ulong:
  1268. switch (rhs.m_type)
  1269. {
  1270. case e_void:
  1271. case e_float:
  1272. case e_double:
  1273. case e_long_double:
  1274. m_type = e_void;
  1275. break;
  1276. case e_sint: m_data.ulong &= rhs.m_data.sint; break;
  1277. case e_uint: m_data.ulong &= rhs.m_data.uint; break;
  1278. case e_slong: m_data.ulong &= rhs.m_data.slong; break;
  1279. case e_ulong: m_data.ulong &= rhs.m_data.ulong; break;
  1280. case e_slonglong: m_data.ulong &= rhs.m_data.slonglong; break;
  1281. case e_ulonglong: m_data.ulong &= rhs.m_data.ulonglong; break;
  1282. }
  1283. break;
  1284. case e_slonglong:
  1285. switch (rhs.m_type)
  1286. {
  1287. case e_void:
  1288. case e_float:
  1289. case e_double:
  1290. case e_long_double:
  1291. m_type = e_void;
  1292. break;
  1293. case e_sint: m_data.slonglong &= rhs.m_data.sint; break;
  1294. case e_uint: m_data.slonglong &= rhs.m_data.uint; break;
  1295. case e_slong: m_data.slonglong &= rhs.m_data.slong; break;
  1296. case e_ulong: m_data.slonglong &= rhs.m_data.ulong; break;
  1297. case e_slonglong: m_dat