swap.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  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. #define COMMON_LITTLE_ENDIAN 1
  39. #endif
  40. // Worst case, default to little endian.
  41. #if !COMMON_BIG_ENDIAN && !COMMON_LITTLE_ENDIAN
  42. #define COMMON_LITTLE_ENDIAN 1
  43. #endif
  44. template <typename T, typename F>
  45. struct swap_struct_t {
  46. typedef swap_struct_t<T, F> swapped_t;
  47. protected:
  48. T value;
  49. static T swap(T v) {
  50. return F::swap(v);
  51. }
  52. public:
  53. T const swap() const {
  54. return swap(value);
  55. }
  56. swap_struct_t() : value((T)0) {}
  57. swap_struct_t(const T &v): value(swap(v)) {}
  58. template <typename S>
  59. swapped_t& operator=(const S &source) {
  60. value = swap((T)source);
  61. return *this;
  62. }
  63. operator s8() const { return (s8)swap(); }
  64. operator u8() const { return (u8)swap(); }
  65. operator s16() const { return (s16)swap(); }
  66. operator u16() const { return (u16)swap(); }
  67. operator s32() const { return (s32)swap(); }
  68. operator u32() const { return (u32)swap(); }
  69. operator s64() const { return (s64)swap(); }
  70. operator u64() const { return (u64)swap(); }
  71. operator float() const { return (float)swap(); }
  72. operator double() const { return (double)swap(); }
  73. // +v
  74. swapped_t operator +() const {
  75. return +swap();
  76. }
  77. // -v
  78. swapped_t operator -() const {
  79. return -swap();
  80. }
  81. // v / 5
  82. swapped_t operator/(const swapped_t &i) const {
  83. return swap() / i.swap();
  84. }
  85. template <typename S>
  86. swapped_t operator/(const S &i) const {
  87. return swap() / i;
  88. }
  89. // v * 5
  90. swapped_t operator*(const swapped_t &i) const {
  91. return swap() * i.swap();
  92. }
  93. template <typename S>
  94. swapped_t operator*(const S &i) const {
  95. return swap() * i;
  96. }
  97. // v + 5
  98. swapped_t operator+(const swapped_t &i) const {
  99. return swap() + i.swap();
  100. }
  101. template <typename S>
  102. swapped_t operator+(const S &i) const {
  103. return swap() + (T)i;
  104. }
  105. // v - 5
  106. swapped_t operator-(const swapped_t &i) const {
  107. return swap() - i.swap();
  108. }
  109. template <typename S>
  110. swapped_t operator-(const S &i) const {
  111. return swap() - (T)i;
  112. }
  113. // v += 5
  114. swapped_t& operator+=(const swapped_t &i) {
  115. value = swap(swap() + i.swap());
  116. return *this;
  117. }
  118. template <typename S>
  119. swapped_t& operator+=(const S &i) {
  120. value = swap(swap() + (T)i);
  121. return *this;
  122. }
  123. // v -= 5
  124. swapped_t& operator-=(const swapped_t &i) {
  125. value = swap(swap() - i.swap());
  126. return *this;
  127. }
  128. template <typename S>
  129. swapped_t& operator-=(const S &i) {
  130. value = swap(swap() - (T)i);
  131. return *this;
  132. }
  133. // ++v
  134. swapped_t& operator++() {
  135. value = swap(swap()+1);
  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++(int) {
  145. swapped_t old = *this;
  146. value = swap(swap()+1);
  147. return old;
  148. }
  149. // v--
  150. swapped_t operator--(int) {
  151. swapped_t old = *this;
  152. value = swap(swap()-1);
  153. return old;
  154. }
  155. // Comparaison
  156. // v == i
  157. bool operator==(const swapped_t &i) const {
  158. return swap() == i.swap();
  159. }
  160. template <typename S>
  161. bool operator==(const S &i) const {
  162. return swap() == i;
  163. }
  164. // v != i
  165. bool operator!=(const swapped_t &i) const {
  166. return swap() != i.swap();
  167. }
  168. template <typename S>
  169. bool operator!=(const S &i) const {
  170. return swap() != i;
  171. }
  172. // v > i
  173. bool operator>(const swapped_t &i) const {
  174. return swap() > i.swap();
  175. }
  176. template <typename S>
  177. bool operator>(const S &i) const {
  178. return swap() > i;
  179. }
  180. // v < i
  181. bool operator<(const swapped_t &i) const {
  182. return swap() < i.swap();
  183. }
  184. template <typename S>
  185. bool operator<(const S &i) const {
  186. return swap() < i;
  187. }
  188. // v >= i
  189. bool operator>=(const swapped_t &i) const {
  190. return swap() >= i.swap();
  191. }
  192. template <typename S>
  193. bool operator>=(const S &i) const {
  194. return swap() >= i;
  195. }
  196. // v <= i
  197. bool operator<=(const swapped_t &i) const {
  198. return swap() <= i.swap();
  199. }
  200. template <typename S>
  201. bool operator<=(const S &i) const {
  202. return swap() <= i;
  203. }
  204. // logical
  205. swapped_t operator !() const {
  206. return !swap();
  207. }
  208. // bitmath
  209. swapped_t operator ~() const {
  210. return ~swap();
  211. }
  212. swapped_t operator &(const swapped_t &b) const {
  213. return swap() & b.swap();
  214. }
  215. template <typename S>
  216. swapped_t operator &(const S &b) const {
  217. return swap() & b;
  218. }
  219. swapped_t& operator &=(const swapped_t &b) {
  220. value = swap(swap() & b.swap());
  221. return *this;
  222. }
  223. template <typename S>
  224. swapped_t& operator &=(const S b) {
  225. value = swap(swap() & b);
  226. return *this;
  227. }
  228. swapped_t operator |(const swapped_t &b) const {
  229. return swap() | b.swap();
  230. }
  231. template <typename S>
  232. swapped_t operator |(const S &b) const {
  233. return swap() | b;
  234. }
  235. swapped_t& operator |=(const swapped_t &b) {
  236. value = swap(swap() | b.swap());
  237. return *this;
  238. }
  239. template <typename S>
  240. swapped_t& operator |=(const S &b) {
  241. value = swap(swap() | b);
  242. return *this;
  243. }
  244. swapped_t operator ^(const swapped_t &b) const {
  245. return swap() ^ b.swap();
  246. }
  247. template <typename S>
  248. swapped_t operator ^(const S &b) const {
  249. return swap() ^ b;
  250. }
  251. swapped_t& operator ^=(const swapped_t &b) {
  252. value = swap(swap() ^ b.swap());
  253. return *this;
  254. }
  255. template <typename S>
  256. swapped_t& operator ^=(const S &b) {
  257. value = swap(swap() ^ b);
  258. return *this;
  259. }
  260. template <typename S>
  261. swapped_t operator <<(const S &b) const {
  262. return swap() << b;
  263. }
  264. template <typename S>
  265. swapped_t& operator <<=(const S &b) const {
  266. value = swap(swap() << b);
  267. return *this;
  268. }
  269. template <typename S>
  270. swapped_t operator >>(const S &b) const {
  271. return swap() >> b;
  272. }
  273. template <typename S>
  274. swapped_t& operator >>=(const S &b) const {
  275. value = swap(swap() >> b);
  276. return *this;
  277. }
  278. // Member
  279. /** todo **/
  280. // Arithmetics
  281. template <typename S, typename T2, typename F2>
  282. friend S operator+(const S &p, const swapped_t v);
  283. template <typename S, typename T2, typename F2>
  284. friend S operator-(const S &p, const swapped_t v);
  285. template <typename S, typename T2, typename F2>
  286. friend S operator/(const S &p, const swapped_t v);
  287. template <typename S, typename T2, typename F2>
  288. friend S operator*(const S &p, const swapped_t v);
  289. template <typename S, typename T2, typename F2>
  290. friend S operator%(const S &p, const swapped_t v);
  291. // Arithmetics + assignements
  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. // Bitmath
  297. template <typename S, typename T2, typename F2>
  298. friend S operator&(const S &p, const swapped_t v);
  299. // Comparison
  300. template <typename S, typename T2, typename F2>
  301. friend bool operator<(const S &p, const swapped_t v);
  302. template <typename S, typename T2, typename F2>
  303. friend bool operator>(const S &p, const swapped_t v);
  304. template <typename S, typename T2, typename F2>
  305. friend bool operator<=(const S &p, const swapped_t v);
  306. template <typename S, typename T2, typename F2>
  307. friend bool operator>=(const S &p, const swapped_t v);
  308. template <typename S, typename T2, typename F2>
  309. friend bool operator!=(const S &p, const swapped_t v);
  310. template <typename S, typename T2, typename F2>
  311. friend bool operator==(const S &p, const swapped_t v);
  312. };
  313. // Arithmetics
  314. template <typename S, typename T, typename F>
  315. S operator+(const S &i, const swap_struct_t<T, F> v) {
  316. return i + v.swap();
  317. }
  318. template <typename S, typename T, typename F>
  319. S operator-(const S &i, const swap_struct_t<T, F> v) {
  320. return i - v.swap();
  321. }
  322. template <typename S, typename T, typename F>
  323. S operator/(const S &i, const swap_struct_t<T, F> v) {
  324. return i / v.swap();
  325. }
  326. template <typename S, typename T, typename F>
  327. S operator*(const S &i, const swap_struct_t<T, F> v) {
  328. return i * v.swap();
  329. }
  330. template <typename S, typename T, typename F>
  331. S operator%(const S &i, const swap_struct_t<T, F> v) {
  332. return i % v.swap();
  333. }
  334. // Arithmetics + assignements
  335. template <typename S, typename T, typename F>
  336. S &operator+=(S &i, const swap_struct_t<T, F> v) {
  337. i += v.swap();
  338. return i;
  339. }
  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. // Logical
  346. template <typename S, typename T, typename F>
  347. S operator&(const S &i, const swap_struct_t<T, F> v) {
  348. return i & v.swap();
  349. }
  350. template <typename S, typename T, typename F>
  351. S operator&(const swap_struct_t<T, F> v, const S &i) {
  352. return (S)(v.swap() & i);
  353. }
  354. // Comparaison
  355. template <typename S, typename T, typename F>
  356. bool operator<(const S &p, const swap_struct_t<T, F> v) {
  357. return p < v.swap();
  358. }
  359. template <typename S, typename T, typename F>
  360. bool operator>(const S &p, const swap_struct_t<T, F> v) {
  361. return p > v.swap();
  362. }
  363. template <typename S, typename T, typename F>
  364. bool operator<=(const S &p, const swap_struct_t<T, F> v) {
  365. return p <= v.swap();
  366. }
  367. template <typename S, typename T, typename F>
  368. bool operator>=(const S &p, const swap_struct_t<T, F> v) {
  369. return p >= v.swap();
  370. }
  371. template <typename S, typename T, typename F>
  372. bool operator!=(const S &p, const swap_struct_t<T, F> v) {
  373. return p != v.swap();
  374. }
  375. template <typename S, typename T, typename F>
  376. bool operator==(const S &p, const swap_struct_t<T, F> v) {
  377. return p == v.swap();
  378. }
  379. template <typename T>
  380. struct swap_64_t {
  381. static T swap(T x) {
  382. return (T)bswap64(*(u64 *)&x);
  383. }
  384. };
  385. template <typename T>
  386. struct swap_32_t {
  387. static T swap(T x) {
  388. return (T)bswap32(*(u32 *)&x);
  389. }
  390. };
  391. template <typename T>
  392. struct swap_16_t {
  393. static T swap(T x) {
  394. return (T)bswap16(*(u16 *)&x);
  395. }
  396. };
  397. template <typename T>
  398. struct swap_float_t {
  399. static T swap(T x) {
  400. return (T)bswapf(*(float *)&x);
  401. }
  402. };
  403. template <typename T>
  404. struct swap_double_t {
  405. static T swap(T x) {
  406. return (T)bswapd(*(double *)&x);
  407. }
  408. };
  409. #if COMMON_LITTLE_ENDIAN
  410. typedef u32 u32_le;
  411. typedef u16 u16_le;
  412. typedef u64 u64_le;
  413. typedef s32 s32_le;
  414. typedef s16 s16_le;
  415. typedef s64 s64_le;
  416. typedef float float_le;
  417. typedef double double_le;
  418. typedef swap_struct_t<u64, swap_64_t<u64> > u64_be;
  419. typedef swap_struct_t<s64, swap_64_t<s64> > s64_be;
  420. typedef swap_struct_t<u32, swap_32_t<u32> > u32_be;
  421. typedef swap_struct_t<s32, swap_32_t<s32> > s32_be;
  422. typedef swap_struct_t<u16, swap_16_t<u16> > u16_be;
  423. typedef swap_struct_t<s16, swap_16_t<s16> > s16_be;
  424. typedef swap_struct_t<float, swap_float_t<float> > float_be;
  425. typedef swap_struct_t<double, swap_double_t<double> > double_be;
  426. #else
  427. typedef swap_struct_t<u64, swap_64_t<u64> > u64_le;
  428. typedef swap_struct_t<s64, swap_64_t<s64> > s64_le;
  429. typedef swap_struct_t<u32, swap_32_t<u32> > u32_le;
  430. typedef swap_struct_t<s32, swap_32_t<s32> > s32_le;
  431. typedef swap_struct_t<u16, swap_16_t<u16> > u16_le;
  432. typedef swap_struct_t< s16, swap_16_t<s16> > s16_le;
  433. typedef swap_struct_t<float, swap_float_t<float> > float_le;
  434. typedef swap_struct_t<double, swap_double_t<double> > double_le;
  435. typedef u32 u32_be;
  436. typedef u16 u16_be;
  437. typedef u64 u64_be;
  438. typedef s32 s32_be;
  439. typedef s16 s16_be;
  440. typedef s64 s64_be;
  441. typedef float float_be;
  442. typedef double double_be;
  443. #endif