swap.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  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 s8() const { return (s8)swap(); }
  68. operator u8() const { return (u8)swap(); }
  69. operator s16() const { return (s16)swap(); }
  70. operator u16() const { return (u16)swap(); }
  71. operator s32() const { return (s32)swap(); }
  72. operator u32() const { return (u32)swap(); }
  73. operator s64() const { return (s64)swap(); }
  74. operator u64() const { return (u64)swap(); }
  75. operator float() const { return (float)swap(); }
  76. operator double() const { return (double)swap(); }
  77. // +v
  78. swapped_t operator +() const {
  79. return +swap();
  80. }
  81. // -v
  82. swapped_t operator -() const {
  83. return -swap();
  84. }
  85. // v / 5
  86. swapped_t operator/(const swapped_t &i) const {
  87. return swap() / i.swap();
  88. }
  89. template <typename S>
  90. swapped_t operator/(const S &i) const {
  91. return swap() / i;
  92. }
  93. // v * 5
  94. swapped_t operator*(const swapped_t &i) const {
  95. return swap() * i.swap();
  96. }
  97. template <typename S>
  98. swapped_t operator*(const S &i) const {
  99. return swap() * i;
  100. }
  101. // v + 5
  102. swapped_t operator+(const swapped_t &i) const {
  103. return swap() + i.swap();
  104. }
  105. template <typename S>
  106. swapped_t operator+(const S &i) const {
  107. return swap() + (T)i;
  108. }
  109. // v - 5
  110. swapped_t operator-(const swapped_t &i) const {
  111. return swap() - i.swap();
  112. }
  113. template <typename S>
  114. swapped_t operator-(const S &i) const {
  115. return swap() - (T)i;
  116. }
  117. // v += 5
  118. swapped_t& operator+=(const swapped_t &i) {
  119. value = swap(swap() + i.swap());
  120. return *this;
  121. }
  122. template <typename S>
  123. swapped_t& operator+=(const S &i) {
  124. value = swap(swap() + (T)i);
  125. return *this;
  126. }
  127. // v -= 5
  128. swapped_t& operator-=(const swapped_t &i) {
  129. value = swap(swap() - i.swap());
  130. return *this;
  131. }
  132. template <typename S>
  133. swapped_t& operator-=(const S &i) {
  134. value = swap(swap() - (T)i);
  135. return *this;
  136. }
  137. // ++v
  138. swapped_t& operator++() {
  139. value = swap(swap()+1);
  140. return *this;
  141. }
  142. // --v
  143. swapped_t& operator--() {
  144. value = swap(swap()-1);
  145. return *this;
  146. }
  147. // v++
  148. swapped_t operator++(int) {
  149. swapped_t old = *this;
  150. value = swap(swap()+1);
  151. return old;
  152. }
  153. // v--
  154. swapped_t operator--(int) {
  155. swapped_t old = *this;
  156. value = swap(swap()-1);
  157. return old;
  158. }
  159. // Comparaison
  160. // v == i
  161. bool operator==(const swapped_t &i) const {
  162. return swap() == i.swap();
  163. }
  164. template <typename S>
  165. bool operator==(const S &i) const {
  166. return swap() == i;
  167. }
  168. // v != i
  169. bool operator!=(const swapped_t &i) const {
  170. return swap() != i.swap();
  171. }
  172. template <typename S>
  173. bool operator!=(const S &i) const {
  174. return swap() != i;
  175. }
  176. // v > i
  177. bool operator>(const swapped_t &i) const {
  178. return swap() > i.swap();
  179. }
  180. template <typename S>
  181. bool operator>(const S &i) const {
  182. return swap() > i;
  183. }
  184. // v < i
  185. bool operator<(const swapped_t &i) const {
  186. return swap() < i.swap();
  187. }
  188. template <typename S>
  189. bool operator<(const S &i) const {
  190. return swap() < i;
  191. }
  192. // v >= i
  193. bool operator>=(const swapped_t &i) const {
  194. return swap() >= i.swap();
  195. }
  196. template <typename S>
  197. bool operator>=(const S &i) const {
  198. return swap() >= i;
  199. }
  200. // v <= i
  201. bool operator<=(const swapped_t &i) const {
  202. return swap() <= i.swap();
  203. }
  204. template <typename S>
  205. bool operator<=(const S &i) const {
  206. return swap() <= i;
  207. }
  208. // logical
  209. swapped_t operator !() const {
  210. return !swap();
  211. }
  212. // bitmath
  213. swapped_t operator ~() const {
  214. return ~swap();
  215. }
  216. swapped_t operator &(const swapped_t &b) const {
  217. return swap() & b.swap();
  218. }
  219. template <typename S>
  220. swapped_t operator &(const S &b) const {
  221. return swap() & b;
  222. }
  223. swapped_t& operator &=(const swapped_t &b) {
  224. value = swap(swap() & b.swap());
  225. return *this;
  226. }
  227. template <typename S>
  228. swapped_t& operator &=(const S b) {
  229. value = swap(swap() & b);
  230. return *this;
  231. }
  232. swapped_t operator |(const swapped_t &b) const {
  233. return swap() | b.swap();
  234. }
  235. template <typename S>
  236. swapped_t operator |(const S &b) const {
  237. return swap() | b;
  238. }
  239. swapped_t& operator |=(const swapped_t &b) {
  240. value = swap(swap() | b.swap());
  241. return *this;
  242. }
  243. template <typename S>
  244. swapped_t& operator |=(const S &b) {
  245. value = swap(swap() | b);
  246. return *this;
  247. }
  248. swapped_t operator ^(const swapped_t &b) const {
  249. return swap() ^ b.swap();
  250. }
  251. template <typename S>
  252. swapped_t operator ^(const S &b) const {
  253. return swap() ^ b;
  254. }
  255. swapped_t& operator ^=(const swapped_t &b) {
  256. value = swap(swap() ^ b.swap());
  257. return *this;
  258. }
  259. template <typename S>
  260. swapped_t& operator ^=(const S &b) {
  261. value = swap(swap() ^ b);
  262. return *this;
  263. }
  264. template <typename S>
  265. swapped_t operator <<(const S &b) const {
  266. return swap() << b;
  267. }
  268. template <typename S>
  269. swapped_t& operator <<=(const S &b) const {
  270. value = swap(swap() << b);
  271. return *this;
  272. }
  273. template <typename S>
  274. swapped_t operator >>(const S &b) const {
  275. return swap() >> b;
  276. }
  277. template <typename S>
  278. swapped_t& operator >>=(const S &b) const {
  279. value = swap(swap() >> b);
  280. return *this;
  281. }
  282. // Member
  283. /** todo **/
  284. // Arithmetics
  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. template <typename S, typename T2, typename F2>
  292. friend S operator*(const S &p, const swapped_t v);
  293. template <typename S, typename T2, typename F2>
  294. friend S operator%(const S &p, const swapped_t v);
  295. // Arithmetics + assignements
  296. template <typename S, typename T2, typename F2>
  297. friend S operator+=(const S &p, const swapped_t v);
  298. template <typename S, typename T2, typename F2>
  299. friend S operator-=(const S &p, const swapped_t v);
  300. // Bitmath
  301. template <typename S, typename T2, typename F2>
  302. friend S operator&(const S &p, const swapped_t v);
  303. // Comparison
  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. template <typename S, typename T2, typename F2>
  313. friend bool operator!=(const S &p, const swapped_t v);
  314. template <typename S, typename T2, typename F2>
  315. friend bool operator==(const S &p, const swapped_t v);
  316. };
  317. // Arithmetics
  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. template <typename S, typename T, typename F>
  335. S operator%(const S &i, const swap_struct_t<T, F> v) {
  336. return i % v.swap();
  337. }
  338. // Arithmetics + assignements
  339. template <typename S, typename T, typename F>
  340. S &operator+=(S &i, const swap_struct_t<T, F> v) {
  341. i += v.swap();
  342. return i;
  343. }
  344. template <typename S, typename T, typename F>
  345. S &operator-=(S &i, const swap_struct_t<T, F> v) {
  346. i -= v.swap();
  347. return i;
  348. }
  349. // Logical
  350. template <typename S, typename T, typename F>
  351. S operator&(const S &i, const swap_struct_t<T, F> v) {
  352. return i & v.swap();
  353. }
  354. template <typename S, typename T, typename F>
  355. S operator&(const swap_struct_t<T, F> v, const S &i) {
  356. return (S)(v.swap() & i);
  357. }
  358. // Comparaison
  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 S, typename T, typename F>
  380. bool operator==(const S &p, const swap_struct_t<T, F> v) {
  381. return p == v.swap();
  382. }
  383. template <typename T>
  384. struct swap_64_t {
  385. static T swap(T x) {
  386. return (T)bswap64(*(u64 *)&x);
  387. }
  388. };
  389. template <typename T>
  390. struct swap_32_t {
  391. static T swap(T x) {
  392. return (T)bswap32(*(u32 *)&x);
  393. }
  394. };
  395. template <typename T>
  396. struct swap_16_t {
  397. static T swap(T x) {
  398. return (T)bswap16(*(u16 *)&x);
  399. }
  400. };
  401. template <typename T>
  402. struct swap_float_t {
  403. static T swap(T x) {
  404. return (T)bswapf(*(float *)&x);
  405. }
  406. };
  407. template <typename T>
  408. struct swap_double_t {
  409. static T swap(T x) {
  410. return (T)bswapd(*(double *)&x);
  411. }
  412. };
  413. #if COMMON_LITTLE_ENDIAN
  414. typedef u32 u32_le;
  415. typedef u16 u16_le;
  416. typedef u64 u64_le;
  417. typedef s32 s32_le;
  418. typedef s16 s16_le;
  419. typedef s64 s64_le;
  420. typedef float float_le;
  421. typedef double double_le;
  422. typedef swap_struct_t<u64, swap_64_t<u64> > u64_be;
  423. typedef swap_struct_t<s64, swap_64_t<s64> > s64_be;
  424. typedef swap_struct_t<u32, swap_32_t<u32> > u32_be;
  425. typedef swap_struct_t<s32, swap_32_t<s32> > s32_be;
  426. typedef swap_struct_t<u16, swap_16_t<u16> > u16_be;
  427. typedef swap_struct_t<s16, swap_16_t<s16> > s16_be;
  428. typedef swap_struct_t<float, swap_float_t<float> > float_be;
  429. typedef swap_struct_t<double, swap_double_t<double> > double_be;
  430. #else
  431. typedef swap_struct_t<u64, swap_64_t<u64> > u64_le;
  432. typedef swap_struct_t<s64, swap_64_t<s64> > s64_le;
  433. typedef swap_struct_t<u32, swap_32_t<u32> > u32_le;
  434. typedef swap_struct_t<s32, swap_32_t<s32> > s32_le;
  435. typedef swap_struct_t<u16, swap_16_t<u16> > u16_le;
  436. typedef swap_struct_t< s16, swap_16_t<s16> > s16_le;
  437. typedef swap_struct_t<float, swap_float_t<float> > float_le;
  438. typedef swap_struct_t<double, swap_double_t<double> > double_le;
  439. typedef u32 u32_be;
  440. typedef u16 u16_be;
  441. typedef u64 u64_be;
  442. typedef s32 s32_be;
  443. typedef s16 s16_be;
  444. typedef s64 s64_be;
  445. typedef float float_be;
  446. typedef double double_be;
  447. #endif