PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llstl.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 473 lines | 308 code | 42 blank | 123 comment | 19 complexity | 11560759e96e34635f88e3fc147b904f MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llstl.h
  3. * @brief helper object & functions for use with the stl.
  4. *
  5. * $LicenseInfo:firstyear=2003&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLSTL_H
  27. #define LL_LLSTL_H
  28. #include <functional>
  29. #include <algorithm>
  30. #include <map>
  31. #include <vector>
  32. #include <set>
  33. #include <deque>
  34. // Use to compare the first element only of a pair
  35. // e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t;
  36. template <typename T1, typename T2>
  37. struct compare_pair_first
  38. {
  39. bool operator()(const std::pair<T1, T2>& a, const std::pair<T1, T2>& b) const
  40. {
  41. return a.first < b.first;
  42. }
  43. };
  44. template <typename T1, typename T2>
  45. struct compare_pair_greater
  46. {
  47. bool operator()(const std::pair<T1, T2>& a, const std::pair<T1, T2>& b) const
  48. {
  49. if (!(a.first < b.first))
  50. return true;
  51. else if (!(b.first < a.first))
  52. return false;
  53. else
  54. return !(a.second < b.second);
  55. }
  56. };
  57. // Use to compare the contents of two pointers (e.g. std::string*)
  58. template <typename T>
  59. struct compare_pointer_contents
  60. {
  61. typedef const T* Tptr;
  62. bool operator()(const Tptr& a, const Tptr& b) const
  63. {
  64. return *a < *b;
  65. }
  66. };
  67. // DeletePointer is a simple helper for deleting all pointers in a container.
  68. // The general form is:
  69. //
  70. // std::for_each(cont.begin(), cont.end(), DeletePointer());
  71. // somemap.clear();
  72. //
  73. // Don't forget to clear()!
  74. struct DeletePointer
  75. {
  76. template<typename T> void operator()(T* ptr) const
  77. {
  78. delete ptr;
  79. }
  80. };
  81. struct DeletePointerArray
  82. {
  83. template<typename T> void operator()(T* ptr) const
  84. {
  85. delete[] ptr;
  86. }
  87. };
  88. // DeletePairedPointer is a simple helper for deleting all pointers in a map.
  89. // The general form is:
  90. //
  91. // std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer());
  92. struct DeletePairedPointer
  93. {
  94. template<typename T> void operator()(T &ptr) const
  95. {
  96. delete ptr.second;
  97. ptr.second = NULL;
  98. }
  99. };
  100. struct DeletePairedPointerArray
  101. {
  102. template<typename T> void operator()(T &ptr) const
  103. {
  104. delete[] ptr.second;
  105. ptr.second = NULL;
  106. }
  107. };
  108. // Alternate version of the above so that has a more cumbersome
  109. // syntax, but it can be used with compositional functors.
  110. // NOTE: The functor retuns a bool because msdev bombs during the
  111. // composition if you return void. Once we upgrade to a newer
  112. // compiler, the second unary_function template parameter can be set
  113. // to void.
  114. //
  115. // Here's a snippit showing how you use this object:
  116. //
  117. // typedef std::map<int, widget*> map_type;
  118. // map_type widget_map;
  119. // ... // add elements
  120. // // delete them all
  121. // for_each(widget_map.begin(),
  122. // widget_map.end(),
  123. // llcompose1(DeletePointerFunctor<widget>(),
  124. // llselect2nd<map_type::value_type>()));
  125. template<typename T>
  126. struct DeletePointerFunctor : public std::unary_function<T*, bool>
  127. {
  128. bool operator()(T* ptr) const
  129. {
  130. delete ptr;
  131. return true;
  132. }
  133. };
  134. // See notes about DeleteArray for why you should consider avoiding this.
  135. template<typename T>
  136. struct DeleteArrayFunctor : public std::unary_function<T*, bool>
  137. {
  138. bool operator()(T* ptr) const
  139. {
  140. delete[] ptr;
  141. return true;
  142. }
  143. };
  144. // CopyNewPointer is a simple helper which accepts a pointer, and
  145. // returns a new pointer built with the copy constructor. Example:
  146. //
  147. // transform(in.begin(), in.end(), out.end(), CopyNewPointer());
  148. struct CopyNewPointer
  149. {
  150. template<typename T> T* operator()(const T* ptr) const
  151. {
  152. return new T(*ptr);
  153. }
  154. };
  155. // Simple function to help with finding pointers in maps.
  156. // For example:
  157. // typedef map_t;
  158. // std::map<int, const char*> foo;
  159. // foo[18] = "there";
  160. // foo[2] = "hello";
  161. // const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
  162. // const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
  163. template <typename K, typename T>
  164. inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key)
  165. {
  166. // Typedef here avoids warnings because of new c++ naming rules.
  167. typedef typename std::map<K,T*>::const_iterator map_iter;
  168. map_iter iter = inmap.find(key);
  169. if(iter == inmap.end())
  170. {
  171. return NULL;
  172. }
  173. else
  174. {
  175. return iter->second;
  176. }
  177. };
  178. // helper function which returns true if key is in inmap.
  179. template <typename K, typename T>
  180. inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
  181. {
  182. typedef typename std::map<K,T>::const_iterator map_iter;
  183. if(inmap.find(key) == inmap.end())
  184. {
  185. return false;
  186. }
  187. else
  188. {
  189. return true;
  190. }
  191. }
  192. // Similar to get_ptr_in_map, but for any type with a valid T(0) constructor.
  193. // To replace LLSkipMap getIfThere, use:
  194. // get_if_there(map, key, 0)
  195. // WARNING: Make sure default_value (generally 0) is not a valid map entry!
  196. template <typename K, typename T>
  197. inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
  198. {
  199. // Typedef here avoids warnings because of new c++ naming rules.
  200. typedef typename std::map<K,T>::const_iterator map_iter;
  201. map_iter iter = inmap.find(key);
  202. if(iter == inmap.end())
  203. {
  204. return default_value;
  205. }
  206. else
  207. {
  208. return iter->second;
  209. }
  210. };
  211. // Useful for replacing the removeObj() functionality of LLDynamicArray
  212. // Example:
  213. // for (std::vector<T>::iterator iter = mList.begin(); iter != mList.end(); )
  214. // {
  215. // if ((*iter)->isMarkedForRemoval())
  216. // iter = vector_replace_with_last(mList, iter);
  217. // else
  218. // ++iter;
  219. // }
  220. template <typename T, typename Iter>
  221. inline Iter vector_replace_with_last(std::vector<T>& invec, Iter iter)
  222. {
  223. typename std::vector<T>::iterator last = invec.end(); --last;
  224. if (iter == invec.end())
  225. {
  226. return iter;
  227. }
  228. else if (iter == last)
  229. {
  230. invec.pop_back();
  231. return invec.end();
  232. }
  233. else
  234. {
  235. *iter = *last;
  236. invec.pop_back();
  237. return iter;
  238. }
  239. };
  240. // Useful for replacing the removeObj() functionality of LLDynamicArray
  241. // Example:
  242. // vector_replace_with_last(mList, x);
  243. template <typename T>
  244. inline bool vector_replace_with_last(std::vector<T>& invec, const T& val)
  245. {
  246. typename std::vector<T>::iterator iter = std::find(invec.begin(), invec.end(), val);
  247. if (iter != invec.end())
  248. {
  249. typename std::vector<T>::iterator last = invec.end(); --last;
  250. *iter = *last;
  251. invec.pop_back();
  252. return true;
  253. }
  254. return false;
  255. }
  256. // Append N elements to the vector and return a pointer to the first new element.
  257. template <typename T>
  258. inline T* vector_append(std::vector<T>& invec, S32 N)
  259. {
  260. U32 sz = invec.size();
  261. invec.resize(sz+N);
  262. return &(invec[sz]);
  263. }
  264. // call function f to n members starting at first. similar to std::for_each
  265. template <class InputIter, class Size, class Function>
  266. Function ll_for_n(InputIter first, Size n, Function f)
  267. {
  268. for ( ; n > 0; --n, ++first)
  269. f(*first);
  270. return f;
  271. }
  272. // copy first to result n times, incrementing each as we go
  273. template <class InputIter, class Size, class OutputIter>
  274. OutputIter ll_copy_n(InputIter first, Size n, OutputIter result)
  275. {
  276. for ( ; n > 0; --n, ++result, ++first)
  277. *result = *first;
  278. return result;
  279. }
  280. // set *result = op(*f) for n elements of f
  281. template <class InputIter, class OutputIter, class Size, class UnaryOp>
  282. OutputIter ll_transform_n(
  283. InputIter first,
  284. Size n,
  285. OutputIter result,
  286. UnaryOp op)
  287. {
  288. for ( ; n > 0; --n, ++result, ++first)
  289. *result = op(*first);
  290. return result;
  291. }
  292. /*
  293. *
  294. * Copyright (c) 1994
  295. * Hewlett-Packard Company
  296. *
  297. * Permission to use, copy, modify, distribute and sell this software
  298. * and its documentation for any purpose is hereby granted without fee,
  299. * provided that the above copyright notice appear in all copies and
  300. * that both that copyright notice and this permission notice appear
  301. * in supporting documentation. Hewlett-Packard Company makes no
  302. * representations about the suitability of this software for any
  303. * purpose. It is provided "as is" without express or implied warranty.
  304. *
  305. *
  306. * Copyright (c) 1996-1998
  307. * Silicon Graphics Computer Systems, Inc.
  308. *
  309. * Permission to use, copy, modify, distribute and sell this software
  310. * and its documentation for any purpose is hereby granted without fee,
  311. * provided that the above copyright notice appear in all copies and
  312. * that both that copyright notice and this permission notice appear
  313. * in supporting documentation. Silicon Graphics makes no
  314. * representations about the suitability of this software for any
  315. * purpose. It is provided "as is" without express or implied warranty.
  316. */
  317. // helper to deal with the fact that MSDev does not package
  318. // select... with the stl. Look up usage on the sgi website.
  319. template <class _Pair>
  320. struct _LLSelect1st : public std::unary_function<_Pair, typename _Pair::first_type> {
  321. const typename _Pair::first_type& operator()(const _Pair& __x) const {
  322. return __x.first;
  323. }
  324. };
  325. template <class _Pair>
  326. struct _LLSelect2nd : public std::unary_function<_Pair, typename _Pair::second_type>
  327. {
  328. const typename _Pair::second_type& operator()(const _Pair& __x) const {
  329. return __x.second;
  330. }
  331. };
  332. template <class _Pair> struct llselect1st : public _LLSelect1st<_Pair> {};
  333. template <class _Pair> struct llselect2nd : public _LLSelect2nd<_Pair> {};
  334. // helper to deal with the fact that MSDev does not package
  335. // compose... with the stl. Look up usage on the sgi website.
  336. template <class _Operation1, class _Operation2>
  337. class ll_unary_compose :
  338. public std::unary_function<typename _Operation2::argument_type,
  339. typename _Operation1::result_type>
  340. {
  341. protected:
  342. _Operation1 __op1;
  343. _Operation2 __op2;
  344. public:
  345. ll_unary_compose(const _Operation1& __x, const _Operation2& __y)
  346. : __op1(__x), __op2(__y) {}
  347. typename _Operation1::result_type
  348. operator()(const typename _Operation2::argument_type& __x) const {
  349. return __op1(__op2(__x));
  350. }
  351. };
  352. template <class _Operation1, class _Operation2>
  353. inline ll_unary_compose<_Operation1,_Operation2>
  354. llcompose1(const _Operation1& __op1, const _Operation2& __op2)
  355. {
  356. return ll_unary_compose<_Operation1,_Operation2>(__op1, __op2);
  357. }
  358. template <class _Operation1, class _Operation2, class _Operation3>
  359. class ll_binary_compose
  360. : public std::unary_function<typename _Operation2::argument_type,
  361. typename _Operation1::result_type> {
  362. protected:
  363. _Operation1 _M_op1;
  364. _Operation2 _M_op2;
  365. _Operation3 _M_op3;
  366. public:
  367. ll_binary_compose(const _Operation1& __x, const _Operation2& __y,
  368. const _Operation3& __z)
  369. : _M_op1(__x), _M_op2(__y), _M_op3(__z) { }
  370. typename _Operation1::result_type
  371. operator()(const typename _Operation2::argument_type& __x) const {
  372. return _M_op1(_M_op2(__x), _M_op3(__x));
  373. }
  374. };
  375. template <class _Operation1, class _Operation2, class _Operation3>
  376. inline ll_binary_compose<_Operation1, _Operation2, _Operation3>
  377. llcompose2(const _Operation1& __op1, const _Operation2& __op2,
  378. const _Operation3& __op3)
  379. {
  380. return ll_binary_compose<_Operation1,_Operation2,_Operation3>
  381. (__op1, __op2, __op3);
  382. }
  383. // helpers to deal with the fact that MSDev does not package
  384. // bind... with the stl. Again, this is from sgi.
  385. template <class _Operation>
  386. class llbinder1st :
  387. public std::unary_function<typename _Operation::second_argument_type,
  388. typename _Operation::result_type> {
  389. protected:
  390. _Operation op;
  391. typename _Operation::first_argument_type value;
  392. public:
  393. llbinder1st(const _Operation& __x,
  394. const typename _Operation::first_argument_type& __y)
  395. : op(__x), value(__y) {}
  396. typename _Operation::result_type
  397. operator()(const typename _Operation::second_argument_type& __x) const {
  398. return op(value, __x);
  399. }
  400. };
  401. template <class _Operation, class _Tp>
  402. inline llbinder1st<_Operation>
  403. llbind1st(const _Operation& __oper, const _Tp& __x)
  404. {
  405. typedef typename _Operation::first_argument_type _Arg1_type;
  406. return llbinder1st<_Operation>(__oper, _Arg1_type(__x));
  407. }
  408. template <class _Operation>
  409. class llbinder2nd
  410. : public std::unary_function<typename _Operation::first_argument_type,
  411. typename _Operation::result_type> {
  412. protected:
  413. _Operation op;
  414. typename _Operation::second_argument_type value;
  415. public:
  416. llbinder2nd(const _Operation& __x,
  417. const typename _Operation::second_argument_type& __y)
  418. : op(__x), value(__y) {}
  419. typename _Operation::result_type
  420. operator()(const typename _Operation::first_argument_type& __x) const {
  421. return op(__x, value);
  422. }
  423. };
  424. template <class _Operation, class _Tp>
  425. inline llbinder2nd<_Operation>
  426. llbind2nd(const _Operation& __oper, const _Tp& __x)
  427. {
  428. typedef typename _Operation::second_argument_type _Arg2_type;
  429. return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
  430. }
  431. #endif // LL_LLSTL_H