pair.h - Engine C API Reference

pair.h
  1. #pragma once
  2. #include <algorithm>
  3. #include "allocator.h"
  4. #include "template_tools.h"
  5. namespace stingray_plugin_foundation {
  6. // A replacement for std::pair that is allocator aware, so that any
  7. // of the pair members that need to be constructed with an allocator is.
  8. //
  9. // The default template implementation is used when none of the types
  10. // are allocator aware.
  11. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  12. struct Pair {
  13. typedef Pair<FIRST, SECOND, firstaware, secondaware> this_type;
  14. typedef FIRST first_type;
  15. typedef SECOND second_type;
  16. Pair() : first(first_type()), second(second_type()) {}
  17. Pair(Allocator &) : first(first_type()), second(second_type()) {}
  18. Pair(const this_type &t) : first(t.first), second(t.second) {}
  19. Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
  20. void swap(this_type &right) {
  21. std::swap(first, right.first);
  22. std::swap(second, right.second);
  23. }
  24. template <class STREAM> void serialize(STREAM &s) {s & first & second;}
  25. first_type first;
  26. second_type second;
  27. };
  28. // Template specialization to use when the first type is allocator aware.
  29. template <class FIRST, class SECOND>
  30. struct Pair<FIRST, SECOND, true, false>
  31. {
  32. ALLOCATOR_AWARE;
  33. typedef Pair<FIRST, SECOND, true, false> this_type;
  34. typedef FIRST first_type;
  35. typedef SECOND second_type;
  36. Pair(Allocator &a) : first(a), second(second_type()) {}
  37. Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
  38. void swap(this_type &right) {
  39. std::swap(first, right.first);
  40. std::swap(second, right.second);
  41. }
  42. template <class STREAM> void serialize(STREAM &s) {s & first & second;}
  43. first_type first;
  44. second_type second;
  45. };
  46. // Template specialization to use when the second type is allocator aware.
  47. template <class FIRST, class SECOND>
  48. struct Pair<FIRST, SECOND, false, true>
  49. {
  50. ALLOCATOR_AWARE;
  51. typedef Pair<FIRST, SECOND, false, true> this_type;
  52. typedef FIRST first_type;
  53. typedef SECOND second_type;
  54. Pair(Allocator &a) : first(first_type()), second(a) {}
  55. Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
  56. void swap(this_type &right) {
  57. std::swap(first, right.first);
  58. std::swap(second, right.second);
  59. }
  60. template <class STREAM> void serialize(STREAM &s) {s & first & second;}
  61. first_type first;
  62. second_type second;
  63. };
  64. // Template specialization to use when both types are allocator aware.
  65. template <class FIRST, class SECOND>
  66. struct Pair<FIRST, SECOND, true, true>
  67. {
  68. ALLOCATOR_AWARE;
  69. typedef Pair<FIRST, SECOND, true, true> this_type;
  70. typedef FIRST first_type;
  71. typedef SECOND second_type;
  72. Pair(Allocator &a) : first(a), second(a) {}
  73. Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
  74. void swap(this_type &right) {
  75. std::swap(first, right.first);
  76. std::swap(second, right.second);
  77. }
  78. template <class STREAM> void serialize(STREAM &s) {s & first & second;}
  79. first_type first;
  80. second_type second;
  81. };
  82. // Comparison operators.
  83. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  84. bool operator==(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
  85. const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
  86. return left.first == right.first && left.second == right.second;
  87. }
  88. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  89. bool operator!=(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
  90. const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
  91. return !(left == right);
  92. }
  93. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  94. bool operator<(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
  95. const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
  96. return left.first < right.first ||
  97. (!(right.first < left.first) && left.second < right.second);
  98. }
  99. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  100. bool operator>(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
  101. const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
  102. return (right < left);
  103. }
  104. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  105. bool operator<=(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
  106. const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
  107. return !(right < left);
  108. }
  109. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  110. bool operator>=(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
  111. const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
  112. return !(left < right);
  113. }
  114. // make_pair function that constructs a Pair of the right type
  115. template <class FIRST, class SECOND>
  116. Pair<FIRST, SECOND, IS_ALLOCATOR_AWARE(FIRST), IS_ALLOCATOR_AWARE(SECOND)> make_pair(const FIRST &f, const SECOND &s)
  117. {
  118. return Pair<FIRST, SECOND, IS_ALLOCATOR_AWARE(FIRST), IS_ALLOCATOR_AWARE(SECOND)>(f, s);
  119. }
  120. // swap implementation for Pair
  121. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  122. void swap(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
  123. const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
  124. left.swap(right);
  125. }
  126. // Declaration needed for GCC-based compilers
  127. unsigned murmur_hash( const void * key, int len, unsigned seed );
  128. // Pair hashing
  129. template <class HASH_FIRST, class HASH_SECOND = HASH_FIRST>
  130. struct pair_hash
  131. {
  132. template <class FIRST, class SECOND, bool firstaware, bool secondaware>
  133. unsigned operator()(const Pair<FIRST, SECOND, firstaware, secondaware> &pair) const
  134. {
  135. HASH_FIRST hash_first;
  136. HASH_SECOND hash_second;
  137. const unsigned result[2] = { hash_first(pair.first), hash_second(pair.second) };
  138. const unsigned hash = murmur_hash(&result[0], sizeof(result), 0);
  139. return hash;
  140. }
  141. };
  142. } // namespace stingray_plugin_foundation