sort_map.inl - エンジンの C API リファレンス

sort_map.inl
  1. #include "assert.h"
  2. namespace stingray_plugin_foundation {
  3. template <class K, class D, class C>
  4. SortMap<K,D,C>::SortMap(Allocator &a) : _data(a)
  5. {
  6. mark_sorted();
  7. }
  8. template <class K, class D, class C>
  9. SortMap<K,D,C>::SortMap(const NoAllocator &a) : _data(a)
  10. {
  11. mark_sorted();
  12. }
  13. template <class K, class D, class C>
  14. void SortMap<K,D,C>::set_capacity(unsigned capacity)
  15. {
  16. _data.set_capacity(capacity);
  17. }
  18. template <class K, class D, class C>
  19. void SortMap<K,D,C>::set_allocator(Allocator &allocator)
  20. {
  21. _data.set_allocator(allocator);
  22. }
  23. template <class K, class D, class C>
  24. SortMap<K,D,C>::SortMap(const SortMap<K,D,C> &o) : _less(o._less), _data(o._data)
  25. {
  26. #ifdef DEVELOPMENT
  27. _is_sorted = o._is_sorted;
  28. #endif
  29. }
  30. template <class K, class D, class C>
  31. void SortMap<K,D,C>::operator=(const SortMap<K,D,C> &o)
  32. {
  33. _less = o._less;
  34. _data = o._data;
  35. #ifdef DEVELOPMENT
  36. _is_sorted = o._is_sorted;
  37. #endif
  38. }
  39. template <class K, class D, class C>
  40. void SortMap<K,D,C>::swap(SortMap<K,D,C> &o)
  41. {
  42. std::swap(_less, o._less);
  43. std::swap(_data, o._data);
  44. #ifdef DEVELOPMENT
  45. std::swap(_is_sorted, o._is_sorted);
  46. #endif
  47. }
  48. template <class K, class D, class C>
  49. Allocator &SortMap<K,D,C>::allocator() const
  50. {
  51. return _data.allocator();
  52. }
  53. template <class K, class D, class C>
  54. unsigned SortMap<K,D,C>::size() const
  55. {
  56. return _data.size();
  57. }
  58. template <class K, class D, class C>
  59. bool SortMap<K,D,C>::empty() const
  60. {
  61. return _data.empty();
  62. }
  63. template <class K, class D, class C>
  64. typename SortMap<K,D,C>::iterator SortMap<K,D,C>::begin()
  65. {
  66. return _data.begin();
  67. }
  68. template <class K, class D, class C>
  69. typename SortMap<K,D,C>::const_iterator SortMap<K,D,C>::begin() const
  70. {
  71. return _data.begin();
  72. }
  73. template <class K, class D, class C>
  74. typename SortMap<K,D,C>::iterator SortMap<K,D,C>::end()
  75. {
  76. return _data.end();
  77. }
  78. template <class K, class D, class C>
  79. typename SortMap<K,D,C>::const_iterator SortMap<K,D,C>::end() const
  80. {
  81. return _data.end();
  82. }
  83. template <class K, class D, class C> template <class KEY_EQ>
  84. typename SortMap<K,D,C>::iterator SortMap<K,D,C>::find(const KEY_EQ &k)
  85. {
  86. check_sorted();
  87. return begin() + find_index(k);
  88. }
  89. template <class K, class D, class C> template <class KEY_EQ>
  90. typename SortMap<K,D,C>::const_iterator SortMap<K,D,C>::find(const KEY_EQ &k) const
  91. {
  92. check_sorted();
  93. return begin() + find_index(k);
  94. }
  95. template <class K, class D, class C> template <class KEY_EQ>
  96. typename SortMap<K,D,C>::iterator SortMap<K,D,C>::lower_bound(const KEY_EQ &k)
  97. {
  98. check_sorted();
  99. return begin() + lower_bound_index(k);
  100. }
  101. template <class K, class D, class C> template <class KEY_EQ>
  102. const typename SortMap<K,D,C>::iterator SortMap<K,D,C>::lower_bound(const KEY_EQ &k) const
  103. {
  104. check_sorted();
  105. return begin() + lower_bound_index(k);
  106. }
  107. template <class K, class D, class C> template <class KEY_EQ>
  108. typename SortMap<K,D,C>::iterator SortMap<K,D,C>::upper_bound(const KEY_EQ &k)
  109. {
  110. check_sorted();
  111. return begin() + upper_bound_index(k);
  112. }
  113. template <class K, class D, class C> template <class KEY_EQ>
  114. const typename SortMap<K,D,C>::iterator SortMap<K,D,C>::upper_bound(const KEY_EQ &k) const
  115. {
  116. check_sorted();
  117. return begin() + upper_bound_index(k);
  118. }
  119. template <class K, class D, class C> template <class KEY_EQ>
  120. bool SortMap<K,D,C>::has(const KEY_EQ &k) const
  121. {
  122. return find(k) != end();
  123. }
  124. template <class K, class D, class C> template <class KEY_EQ>
  125. int SortMap<K,D,C>::count(const KEY_EQ &k) const
  126. {
  127. return upper_bound_index(k) - lower_bound_index(k);
  128. }
  129. template <class K, class D, class C>
  130. typename SortMap<K,D,C>::key_type &SortMap<K,D,C>::key(int i)
  131. {
  132. return _data[i].first;
  133. }
  134. template <class K, class D, class C>
  135. const typename SortMap<K,D,C>::key_type &SortMap<K,D,C>::key(int i) const
  136. {
  137. return _data[i].first;
  138. }
  139. template <class K, class D, class C>
  140. typename SortMap<K,D,C>::data_type &SortMap<K,D,C>::data(int i)
  141. {
  142. return _data[i].second;
  143. }
  144. template <class K, class D, class C>
  145. const typename SortMap<K,D,C>::data_type & SortMap<K,D,C>::data(int i) const
  146. {
  147. return _data[i].second;
  148. }
  149. template <class K, class D, class C>
  150. typename SortMap<K,D,C>::value_type &SortMap<K,D,C>::value(int i)
  151. {
  152. return _data[i];
  153. }
  154. template <class K, class D, class C>
  155. const typename SortMap<K,D,C>::value_type & SortMap<K,D,C>::value(int i) const
  156. {
  157. return _data[i];
  158. }
  159. template <class K, class D, class C>
  160. typename SortMap<K,D,C>::value_type &SortMap<K,D,C>::front()
  161. {
  162. return _data.front();
  163. }
  164. template <class K, class D, class C>
  165. const typename SortMap<K,D,C>::value_type & SortMap<K,D,C>::front() const
  166. {
  167. return _data.front();
  168. }
  169. template <class K, class D, class C>
  170. typename SortMap<K,D,C>::value_type &SortMap<K,D,C>::back()
  171. {
  172. return _data.back();
  173. }
  174. template <class K, class D, class C>
  175. const typename SortMap<K,D,C>::value_type & SortMap<K,D,C>::back() const
  176. {
  177. return _data.back();
  178. }
  179. template <class K, class D, class C> template <class KEY_EQ>
  180. const typename SortMap<K,D,C>::data_type & SortMap<K,D,C>::operator[](const KEY_EQ &k) const
  181. {
  182. return find(k)->second;
  183. }
  184. template <class K, class D, class C> template <class KEY_EQ>
  185. typename SortMap<K,D,C>::data_type & SortMap<K,D,C>::operator[](const KEY_EQ &k)
  186. {
  187. iterator it = find(k);
  188. XENSURE(it != end());
  189. return it->second;
  190. }
  191. template <class K, class D, class C> template <class KEY_EQ>
  192. const typename SortMap<K,D,C>::data_type & SortMap<K,D,C>::get(const KEY_EQ &k, const data_type &def) const
  193. {
  194. const_iterator it = find(k);
  195. if (it == end()) return def;
  196. return it->second;
  197. }
  198. template <class K, class D, class C>
  199. void SortMap<K,D,C>::clear()
  200. {
  201. _data.clear();
  202. mark_sorted();
  203. }
  204. template <class K, class D, class C> template <class KEY_EQ, class DATA_EQ>
  205. void SortMap<K,D,C>::insert(const KEY_EQ &k, const DATA_EQ &v)
  206. {
  207. // It might be better to inplace construct the pair in the
  208. // vector rather than constructing and copying... I'm not sure
  209. // if that can be done.
  210. _data.resize( _data.size() + 1);
  211. _data.back().first = k;
  212. #pragma warning(push)
  213. #pragma warning(disable : 4267) // templated, hard to fix warning for possible data loss
  214. _data.back().second = v;
  215. #pragma warning(pop)
  216. mark_unsorted();
  217. }
  218. template <class K, class D, class C> template <class KEY_EQ>
  219. void SortMap<K,D,C>::insert(iterator pos, const KEY_EQ &k, const data_type &v)
  220. {
  221. value_type value(k,v);
  222. _data.insert(pos, value);
  223. mark_unsorted();
  224. }
  225. template <class K, class D, class C>
  226. typename SortMap<K,D,C>::iterator SortMap<K,D,C>::erase(iterator i)
  227. {
  228. return _data.erase(i);
  229. }
  230. template <class K, class D, class C> template <class KEY_EQ>
  231. void SortMap<K,D,C>::erase(const KEY_EQ &k)
  232. {
  233. _data.erase( find(k) );
  234. }
  235. template <class K, class D, class C>
  236. void SortMap<K,D,C>::sort()
  237. {
  238. std::sort(_data.begin(), _data.end(), value_compare(_less));
  239. mark_sorted();
  240. }
  241. template <class K, class D, class C>
  242. bool SortMap<K,D,C>::is_multi_map()
  243. {
  244. check_sorted();
  245. for (unsigned i=1; i<_data.size(); ++i) {
  246. if (!_less(_data[i].first, _data[i-1].first) &&
  247. !_less(_data[i-1].first, _data[i].first))
  248. return true;
  249. }
  250. return false;
  251. }
  252. template <class K, class D, class C>
  253. void SortMap<K,D,C>::trim()
  254. {
  255. _data.trim();
  256. }
  257. template <class K, class D, class C>
  258. void SortMap<K,D,C>::reserve(unsigned n)
  259. {
  260. _data.reserve(n);
  261. }
  262. template <class K, class D, class C>
  263. void SortMap<K,D,C>::resize(unsigned n)
  264. {
  265. _data.resize(n);
  266. }
  267. template <class K, class D, class C> template <class KEY_EQ>
  268. unsigned SortMap<K,D,C>::find_index(const KEY_EQ &k) const
  269. {
  270. unsigned lo = 0;
  271. unsigned hi = size();
  272. while (true) {
  273. if (hi <= lo)
  274. return size();
  275. unsigned mid = (lo + hi) / 2;
  276. if (_less(_data[mid].first, k))
  277. lo = mid+1;
  278. else if (_less(k, _data[mid].first))
  279. hi = mid;
  280. else
  281. return mid;
  282. }
  283. }
  284. template <class K, class D, class C> template <class KEY_EQ>
  285. unsigned SortMap<K,D,C>::lower_bound_index(const KEY_EQ &k) const
  286. {
  287. unsigned lo = 0;
  288. unsigned hi = size();
  289. if (hi == 0 || !_less(_data[lo].first, k))
  290. return 0;
  291. while (true) {
  292. if (hi <= lo+1)
  293. return hi;
  294. unsigned mid = (lo + hi) / 2;
  295. if (_less(_data[mid].first, k))
  296. lo = mid;
  297. else
  298. hi = mid;
  299. }
  300. }
  301. template <class K, class D, class C> template <class KEY_EQ>
  302. unsigned SortMap<K,D,C>::upper_bound_index(const KEY_EQ &k) const
  303. {
  304. unsigned lo = 0;
  305. unsigned hi = size();
  306. if (hi == 0 || _less(k, _data[lo].first))
  307. return 0;
  308. while (true) {
  309. if (hi <= lo+1)
  310. return hi;
  311. unsigned mid = (lo + hi) / 2;
  312. if (_less(k, _data[mid].first))
  313. hi = mid;
  314. else
  315. lo = mid;
  316. }
  317. }
  318. template <class K, class D, class C>
  319. void SortMap<K,D,C>::mark_sorted()
  320. {
  321. #ifdef DEVELOPMENT
  322. _is_sorted = true;
  323. #endif
  324. }
  325. template <class K, class D, class C>
  326. void SortMap<K,D,C>::mark_unsorted()
  327. {
  328. #ifdef DEVELOPMENT
  329. _is_sorted = false;
  330. #endif
  331. }
  332. template <class K, class D, class C>
  333. void SortMap<K,D,C>::check_sorted() const
  334. {
  335. XASSERT(_is_sorted, "SortMap not sorted");
  336. }
  337. template<class K, class D, class C>
  338. template <class STREAM> void SortMap<K,D,C>::serialize(STREAM &stream)
  339. {
  340. check_sorted();
  341. stream & _data;
  342. mark_sorted();
  343. }
  344. } // namespace stingray_plugin_foundation