swap.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. // Copyright (c) 2012- PPSSPP Project / Dolphin Project.
  2. // This program is free software: you can redistribute it and/or modify
  3. // it under the terms of the GNU General Public License as published by
  4. // the Free Software Foundation, version 2.0 or later versions.
  5. // This program is distributed in the hope that it will be useful,
  6. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. // GNU General Public License 2.0 for more details.
  9. // A copy of the GPL 2.0 should have been included with the program.
  10. // If not, see http://www.gnu.org/licenses/
  11. // Official git repository and contact information can be found at
  12. // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
  13. #pragma once
  14. // Android
  15. #if defined(ANDROID)
  16. #include <sys/endian.h>
  17. #if _BYTE_ORDER == _LITTLE_ENDIAN && !defined(COMMON_LITTLE_ENDIAN)
  18. #define COMMON_LITTLE_ENDIAN 1
  19. #elif _BYTE_ORDER == _BIG_ENDIAN && !defined(COMMON_BIG_ENDIAN)
  20. #define COMMON_BIG_ENDIAN 1
  21. #endif
  22. // GCC 4.6+
  23. #elif __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  24. #if __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) && !defined(COMMON_LITTLE_ENDIAN)
  25. #define COMMON_LITTLE_ENDIAN 1
  26. #elif __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) && !defined(COMMON_BIG_ENDIAN)
  27. #define COMMON_BIG_ENDIAN 1
  28. #endif
  29. // LLVM/clang
  30. #elif __clang__
  31. #if __LITTLE_ENDIAN__ && !defined(COMMON_LITTLE_ENDIAN)
  32. #define COMMON_LITTLE_ENDIAN 1
  33. #elif __BIG_ENDIAN__ && !defined(COMMON_BIG_ENDIAN)
  34. #define COMMON_BIG_ENDIAN 1
  35. #endif
  36. // MSVC
  37. #elif defined(_MSC_VER) && !defined(COMMON_BIG_ENDIAN) && !defined(COMMON_LITTLE_ENDIAN)
  38. #ifdef _XBOX
  39. #define COMMON_BIG_ENDIAN 1
  40. #else
  41. #define COMMON_LITTLE_ENDIAN 1
  42. #endif
  43. #endif
  44. // Worst case, default to little endian.
  45. #if !COMMON_BIG_ENDIAN && !COMMON_LITTLE_ENDIAN
  46. #define COMMON_LITTLE_ENDIAN 1
  47. #endif
  48. template <typename T, typename F>
  49. struct swap_struct_t {
  50. typedef swap_struct_t<T, F> swapped_t;
  51. protected:
  52. T value;
  53. static T swap(T v) {
  54. return F::swap(v);
  55. }
  56. public:
  57. T const swap() const {
  58. return swap(value);
  59. }
  60. swap_struct_t() : value((T)0) {}
  61. swap_struct_t(const T &v): value(swap(v)) {}
  62. template <typename S>
  63. swapped_t& operator=(const S &source) {
  64. value = swap((T)source);
  65. return *this;
  66. }
  67. operator long() const { return (long)swap(); }
  68. operator s8() const { return (s8)swap(); }
  69. operator u8() const { return (u8)swap(); }
  70. operator s16() const { return (s16)swap(); }
  71. operator u16() const { return (u16)swap(); }
  72. operator s32() const { return (s32)swap(); }
  73. operator u32() const { return (u32)swap(); }
  74. operator s64() const { return (s64)swap(); }
  75. operator u64() const { return (u64)swap(); }
  76. operator float() const { return (float)swap(); }
  77. operator double() const { return (double)swap(); }
  78. // +v
  79. swapped_t operator +() const {
  80. return +swap();
  81. }
  82. // -v
  83. swapped_t operator -() const {
  84. return -swap();
  85. }
  86. // v / 5
  87. swapped_t operator/(const swapped_t &i) const {
  88. return swap() / i.swap();
  89. }
  90. template <typename S>
  91. swapped_t operator/(const S &i) const {
  92. return swap() / i;
  93. }
  94. // v * 5
  95. swapped_t operator*(const swapped_t &i) const {
  96. return swap() * i.swap();
  97. }
  98. template <typename S>
  99. swapped_t operator*(const S &i) const {
  100. return swap() * i;
  101. }
  102. // v + 5
  103. swapped_t operator+(const swapped_t &i) const {
  104. return swap() + i.swap();
  105. }
  106. template <typename S>
  107. swapped_t operator+(const S &i) const {
  108. return swap() + (T)i;
  109. }
  110. // v - 5
  111. swapped_t operator-(const swapped_t &i) const {
  112. return swap() - i.swap();
  113. }
  114. template <typename S>
  115. swapped_t operator-(const S &i) const {
  116. return swap() - (T)i;
  117. }
  118. // v += 5
  119. swapped_t& operator+=(const swapped_t &i) {
  120. value = swap(swap() + i.swap());
  121. return *this;
  122. }
  123. template <typename S>
  124. swapped_t& operator+=(const S &i) {
  125. value = swap(swap() + (T)i);
  126. return *this;
  127. }
  128. // v -= 5
  129. swapped_t& operator-=(const swapped_t &i) {
  130. value = swap(swap() - i.swap());
  131. return *this;
  132. }
  133. template <typename S>
  134. swapped_t& operator-=(const S &i) {
  135. value = swap(swap() - (T)i);
  136. return *this;
  137. }
  138. // ++v
  139. swapped_t& operator++() {
  140. value = swap(swap()+1);
  141. return *this;
  142. }
  143. // --v
  144. swapped_t& operator--() {
  145. value = swap(swap()-1);
  146. return *this;
  147. }
  148. // v++
  149. swapped_t operator++(int) {
  150. swapped_t old = *this;
  151. value = swap(swap()+1);
  152. return old;
  153. }
  154. // v--
  155. swapped_t operator--(int) {
  156. swapped_t old = *this;
  157. value = swap(swap()-1);
  158. return old;
  159. }
  160. // Comparaison
  161. // v == i
  162. bool operator==(const swapped_t &i) const {
  163. return swap() == i.swap();
  164. }
  165. template <typename S>
  166. bool operator==(const S &i) const {
  167. return swap() == i;
  168. }
  169. // v != i
  170. bool operator!=(const swapped_t &i) const {
  171. return swap() != i.swap();
  172. }
  173. template <typename S>
  174. bool operator!=(const S &i) const {
  175. return swap() != i;
  176. }
  177. // v > i
  178. bool operator>(const swapped_t &i) const {
  179. return swap() > i.swap();
  180. }
  181. template <typename S>
  182. bool operator>(const S &i) const {
  183. return swap() > i;
  184. }
  185. // v < i
  186. bool operator<(const swapped_t &i) const {
  187. return swap() < i.swap();
  188. }
  189. template <typename S>
  190. bool operator<(const S &i) const {
  191. return swap() < i;
  192. }
  193. // v >= i
  194. bool operator>=(const swapped_t &i) const {
  195. return swap() >= i.swap();
  196. }
  197. template <typename S>
  198. bool operator>=(const S &i) const {
  199. return swap() >= i;
  200. }
  201. // v <= i
  202. bool operator<=(const swapped_t &i) const {
  203. return swap() <= i.swap();
  204. }
  205. template <typename S>
  206. bool operator<=(const S &i) const {
  207. return swap() <= i;
  208. }
  209. // logical
  210. swapped_t operator !() const {
  211. return !swap();
  212. }
  213. // bitmath
  214. swapped_t operator ~() const {
  215. return ~swap();
  216. }
  217. swapped_t operator &(const swapped_t &b) const {
  218. return swap() & b.swap();
  219. }
  220. template <typename S>
  221. swapped_t operator &(const S &b) const {
  222. return swap() & b;
  223. }
  224. swapped_t& operator &=(const swapped_t &b) {
  225. value = swap(swap() & b.swap());
  226. return *this;
  227. }
  228. template <typename S>
  229. swapped_t& operator &=(const S b) {
  230. value = swap(swap() & b);
  231. return *this;
  232. }
  233. swapped_t operator |(const swapped_t &b) const {
  234. return swap() | b.swap();
  235. }
  236. template <typename S>
  237. swapped_t operator |(const S &b) const {
  238. return swap() | b;
  239. }
  240. swapped_t& operator |=(const swapped_t &b) {
  241. value = swap(swap() | b.swap());
  242. return *this;
  243. }
  244. template <typename S>
  245. swapped_t& operator |=(const S &b) {
  246. value = swap(swap() | b);
  247. return *this;
  248. }
  249. swapped_t operator ^(const swapped_t &b) const {
  250. return swap() ^ b.swap();
  251. }
  252. template <typename S>
  253. swapped_t operator ^(const S &b) const {
  254. return swap() ^ b;
  255. }
  256. swapped_t& operator ^=(const swapped_t &b) {
  257. value = swap(swap() ^ b.swap());
  258. return *this;
  259. }
  260. template <typename S>
  261. swapped_t& operator ^=(const S &b) {
  262. value = swap(swap() ^ b);
  263. return *this;
  264. }
  265. template <typename S>
  266. swapped_t operator <<(const S &b) const {
  267. return swap() << b;
  268. }
  269. template <typename S>
  270. swapped_t& operator <<=(const S &b) const {
  271. value = swap(swap() << b);
  272. return *this;
  273. }
  274. template <typename S>
  275. swapped_t operator >>(const S &b) const {
  276. return swap() >> b;
  277. }
  278. template <typename S>
  279. swapped_t& operator >>=(const S &b) const {
  280. value = swap(swap() >> b);
  281. return *this;
  282. }
  283. // Member
  284. /** todo **/
  285. // Arithmetics
  286. template <typename S, typename T2, typename F2>
  287. friend S operator+(const S &p, const swapped_t v);
  288. template <typename S, typename T2, typename F2>
  289. friend S operator-(const S &p, const swapped_t v);
  290. template <typename S, typename T2, typename F2>
  291. friend S operator/(const S &p, const swapped_t v);
  292. template <typename S, typename T2, typename F2>
  293. friend S operator*(const S &p, const swapped_t v);
  294. template <typename S, typename T2, typename F2>
  295. friend S operator%(const S &p, const swapped_t v);
  296. // Arithmetics + assignements
  297. template <typename S, typename T2, typename F2>
  298. friend S operator+=(const S &p, const swapped_t v);
  299. template <typename S, typename T2, typename F2>
  300. friend S operator-=(const S &p, const swapped_t v);
  301. // Bitmath
  302. template <typename S, typename T2, typename F2>
  303. friend S operator&(const S &p, const swapped_t v);
  304. // Comparison
  305. template <typename S, typename T2, typename F2>
  306. friend bool operator<(const S &p, const swapped_t v);
  307. template <typename S, typename T2, typename F2>
  308. friend bool operator>(const S &p, const swapped_t v);
  309. template <typename S, typename T2, typename F2>
  310. friend bool operator<=(const S &p, const swapped_t v);
  311. template <typename S, typename T2, typename F2>
  312. friend bool operator>=(const S &p, const swapped_t v);
  313. template <typename S, typename T2, typename F2>
  314. friend bool operator!=(const S &p, const swapped_t v);
  315. template <typename S, typename T2, typename F2>
  316. friend bool operator==(const S &p, const swapped_t v);
  317. };
  318. // Arithmetics
  319. template <typename S, typename T, typename F>
  320. S operator+(const S &i, const swap_struct_t<T, F> v) {
  321. return i + v.swap();
  322. }
  323. template <typename S, typename T, typename F>
  324. S operator-(const S &i, const swap_struct_t<T, F> v) {
  325. return i - v.swap();
  326. }
  327. template <typename S, typename T, typename F>
  328. S operator/(const S &i, const swap_struct_t<T, F> v) {
  329. return i / v.swap();
  330. }
  331. template <typename S, typename T, typename F>
  332. S operator*(const S &i, const swap_struct_t<T, F> v) {
  333. return i * v.swap();
  334. }
  335. template <typename S, typename T, typename F>
  336. S operator%(const S &i, const swap_struct_t<T, F> v) {
  337. return i % v.swap();
  338. }
  339. // Arithmetics + assignements
  340. template <typename S, typename T, typename F>
  341. S &operator+=(S &i, const swap_struct_t<T, F> v) {
  342. i += v.swap();
  343. return i;
  344. }
  345. template <typename S, typename T, typename F>
  346. S &operator-=(S &i, const swap_struct_t<T, F> v) {
  347. i -= v.swap();
  348. return i;
  349. }
  350. // Logical
  351. template <typename S, typename T, typename F>
  352. S operator&(const S &i, const swap_struct_t<T, F> v) {
  353. return i & v.swap();
  354. }
  355. template <typename S, typename T, typename F>
  356. S operator&(const swap_struct_t<T, F> v, const S &i) {
  357. return (S)(v.swap() & i);
  358. }
  359. // Comparaison
  360. template <typename S, typename T, typename F>
  361. bool operator<(const S &p, const swap_struct_t<T, F> v) {
  362. return p < v.swap();
  363. }
  364. template <typename S, typename T, typename F>
  365. bool operator>(const S &p, const swap_struct_t<T, F> v) {
  366. return p > v.swap();
  367. }
  368. template <typename S, typename T, typename F>
  369. bool operator<=(const S &p, const swap_struct_t<T, F> v) {
  370. return p <= v.swap();
  371. }
  372. template <typename S, typename T, typename F>
  373. bool operator>=(const S &p, const swap_struct_t<T, F> v) {
  374. return p >= v.swap();
  375. }
  376. template <typename S, typename T, typename F>
  377. bool operator!=(const S &p, const swap_struct_t<T, F> v) {
  378. return p != v.swap();
  379. }
  380. template <typename S, typename T, typename F>
  381. bool operator==(const S &p, const swap_struct_t<T, F> v) {
  382. return p == v.swap();
  383. }
  384. template <typename T>
  385. struct swap_64_t {
  386. static T swap(T x) {
  387. return (T)bswap64(*(u64 *)&x);
  388. }
  389. };
  390. template <typename T>
  391. struct swap_32_t {
  392. static T swap(T x) {
  393. return (T)bswap32(*(u32 *)&x);
  394. }
  395. };
  396. template <typename T>
  397. struct swap_16_t {
  398. static T swap(T x) {
  399. return (T)bswap16(*(u16 *)&x);
  400. }
  401. };
  402. template <typename T>
  403. struct swap_float_t {
  404. static T swap(T x) {
  405. return (T)bswapf(*(float *)&x);
  406. }
  407. };
  408. template <typename T>
  409. struct swap_double_t {
  410. static T swap(T x) {
  411. return (T)bswapd(*(double *)&x);
  412. }
  413. };
  414. #if COMMON_LITTLE_ENDIAN
  415. typedef u32 u32_le;
  416. typedef u16 u16_le;
  417. typedef u64 u64_le;
  418. typedef s32 s32_le;
  419. typedef s16 s16_le;
  420. typedef s64 s64_le;
  421. typedef float float_le;
  422. typedef double double_le;
  423. typedef swap_struct_t<u64, swap_64_t<u64> > u64_be;
  424. typedef swap_struct_t<s64, swap_64_t<s64> > s64_be;
  425. typedef swap_struct_t<u32, swap_32_t<u32> > u32_be;
  426. typedef swap_struct_t<s32, swap_32_t<s32> > s32_be;
  427. typedef swap_struct_t<u16, swap_16_t<u16> > u16_be;
  428. typedef swap_struct_t<s16, swap_16_t<s16> > s16_be;
  429. typedef swap_struct_t<float, swap_float_t<float> > float_be;
  430. typedef swap_struct_t<double, swap_double_t<double> > double_be;
  431. #else
  432. typedef swap_struct_t<u64, swap_64_t<u64> > u64_le;
  433. typedef swap_struct_t<s64, swap_64_t<s64> > s64_le;
  434. typedef swap_struct_t<u32, swap_32_t<u32> > u32_le;
  435. typedef swap_struct_t<s32, swap_32_t<s32> > s32_le;
  436. typedef swap_struct_t<u16, swap_16_t<u16> > u16_le;
  437. typedef swap_struct_t< s16, swap_16_t<s16> > s16_le;
  438. typedef swap_struct_t<float, swap_float_t<float> > float_le;
  439. typedef swap_struct_t<double, swap_double_t<double> > double_le;
  440. typedef u32 u32_be;
  441. typedef u16 u16_be;
  442. typedef u64 u64_be;
  443. typedef s32 s32_be;
  444. typedef s16 s16_be;
  445. typedef s64 s64_be;
  446. typedef float float_be;
  447. typedef double double_be;
  448. #endif