aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llstl.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llstl.h472
1 files changed, 472 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llstl.h b/linden/indra/llcommon/llstl.h
new file mode 100644
index 0000000..ae0dc25
--- /dev/null
+++ b/linden/indra/llcommon/llstl.h
@@ -0,0 +1,472 @@
1/**
2 * @file llstl.h
3 * @brief helper object & functions for use with the stl.
4 *
5 * Copyright (c) 2003-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLSTL_H
29#define LL_LLSTL_H
30
31#include <functional>
32#include <algorithm>
33#include <map>
34#include <vector>
35#include <set>
36#include <deque>
37
38#include <stdio.h>
39#include <stdarg.h>
40
41// Use to compare the first element only of a pair
42// e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t;
43template <typename T1, typename T2>
44struct compare_pair_first
45{
46 bool operator()(const std::pair<T1, T2>& a, const std::pair<T1, T2>& b) const
47 {
48 return a.first < b.first;
49 }
50};
51
52template <typename T1, typename T2>
53struct compare_pair_greater
54{
55 bool operator()(const std::pair<T1, T2>& a, const std::pair<T1, T2>& b) const
56 {
57 if (!(a.first < b.first))
58 return true;
59 else if (!(b.first < a.first))
60 return false;
61 else
62 return !(a.second < b.second);
63 }
64};
65
66// Use to compare the contents of two pointers (e.g. std::string*)
67template <typename T>
68struct compare_pointer_contents
69{
70 typedef const T* Tptr;
71 bool operator()(const Tptr& a, const Tptr& b) const
72 {
73 return *a < *b;
74 }
75};
76
77// DeletePointer is a simple helper for deleting all pointers in a container.
78// The general form is:
79//
80// std::for_each(cont.begin(), cont.end(), DeletePointer());
81
82struct DeletePointer
83{
84 template<typename T> void operator()(T* ptr) const
85 {
86 delete ptr;
87 }
88};
89struct DeletePointerArray
90{
91 template<typename T> void operator()(T* ptr) const
92 {
93 delete[] ptr;
94 }
95};
96
97// DeletePointer is a simple helper for deleting all pointers in a map.
98// The general form is:
99//
100// std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer());
101
102struct DeletePairedPointer
103{
104 template<typename T> void operator()(T &ptr) const
105 {
106 delete ptr.second;
107 }
108};
109struct DeletePairedPointerArray
110{
111 template<typename T> void operator()(T &ptr) const
112 {
113 delete[] ptr.second;
114 }
115};
116
117
118// Alternate version of the above so that has a more cumbersome
119// syntax, but it can be used with compositional functors.
120// NOTE: The functor retuns a bool because msdev bombs during the
121// composition if you return void. Once we upgrade to a newer
122// compiler, the second unary_function template parameter can be set
123// to void.
124//
125// Here's a snippit showing how you use this object:
126//
127// typedef std::map<int, widget*> map_type;
128// map_type widget_map;
129// ... // add elements
130// // delete them all
131// for_each(widget_map.begin(),
132// widget_map.end(),
133// llcompose1(DeletePointerFunctor<widget>(),
134// llselect2nd<map_type::value_type>()));
135
136template<typename T>
137struct DeletePointerFunctor : public std::unary_function<T*, bool>
138{
139 bool operator()(T* ptr) const
140 {
141 delete ptr;
142 return true;
143 }
144};
145
146// See notes about DeleteArray for why you should consider avoiding this.
147template<typename T>
148struct DeleteArrayFunctor : public std::unary_function<T*, bool>
149{
150 bool operator()(T* ptr) const
151 {
152 delete[] ptr;
153 return true;
154 }
155};
156
157// CopyNewPointer is a simple helper which accepts a pointer, and
158// returns a new pointer built with the copy constructor. Example:
159//
160// transform(in.begin(), in.end(), out.end(), CopyNewPointer());
161
162struct CopyNewPointer
163{
164 template<typename T> T* operator()(const T* ptr) const
165 {
166 return new T(*ptr);
167 }
168};
169
170// Simple function to help with finding pointers in maps.
171// For example:
172// typedef map_t;
173// std::map<int, const char*> foo;
174// foo[18] = "there";
175// foo[2] = "hello";
176// const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
177// const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
178template <typename K, typename T>
179inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key)
180{
181 // Typedef here avoids warnings because of new c++ naming rules.
182 typedef typename std::map<K,T*>::const_iterator map_iter;
183 map_iter iter = inmap.find(key);
184 if(iter == inmap.end())
185 {
186 return NULL;
187 }
188 else
189 {
190 return iter->second;
191 }
192};
193
194// helper function which returns true if key is in inmap.
195template <typename K, typename T>
196inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
197{
198 typedef typename std::map<K,T>::const_iterator map_iter;
199 if(inmap.find(key) == inmap.end())
200 {
201 return false;
202 }
203 else
204 {
205 return true;
206 }
207}
208
209// Similar to get_ptr_in_map, but for any type with a valid T(0) constructor.
210// To replace LLSkipMap getIfThere, use:
211// get_if_there(map, key, 0)
212// WARNING: Make sure default_value (generally 0) is not a valid map entry!
213template <typename K, typename T>
214inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
215{
216 // Typedef here avoids warnings because of new c++ naming rules.
217 typedef typename std::map<K,T>::const_iterator map_iter;
218 map_iter iter = inmap.find(key);
219 if(iter == inmap.end())
220 {
221 return default_value;
222 }
223 else
224 {
225 return iter->second;
226 }
227};
228
229// Useful for replacing the removeObj() functionality of LLDynamicArray
230// Example:
231// for (std::vector<T>::iterator iter = mList.begin(); iter != mList.end(); )
232// {
233// if ((*iter)->isMarkedForRemoval())
234// iter = vector_replace_with_last(mList, iter);
235// else
236// ++iter;
237// }
238template <typename T, typename Iter>
239inline Iter vector_replace_with_last(std::vector<T>& invec, Iter iter)
240{
241 typename std::vector<T>::iterator last = invec.end(); --last;
242 if (iter == invec.end())
243 {
244 return iter;
245 }
246 else if (iter == last)
247 {
248 invec.pop_back();
249 return invec.end();
250 }
251 else
252 {
253 *iter = *last;
254 invec.pop_back();
255 return iter;
256 }
257};
258
259// Useful for replacing the removeObj() functionality of LLDynamicArray
260// Example:
261// vector_replace_with_last(mList, x);
262template <typename T>
263inline bool vector_replace_with_last(std::vector<T>& invec, const T& val)
264{
265 typename std::vector<T>::iterator iter = std::find(invec.begin(), invec.end(), val);
266 if (iter != invec.end())
267 {
268 typename std::vector<T>::iterator last = invec.end(); --last;
269 *iter = *last;
270 invec.pop_back();
271 return true;
272 }
273 return false;
274}
275
276// Append N elements to the vector and return a pointer to the first new element.
277template <typename T>
278inline T* vector_append(std::vector<T>& invec, S32 N)
279{
280 U32 sz = invec.size();
281 invec.resize(sz+N);
282 return &(invec[sz]);
283}
284
285// call function f to n members starting at first. similar to std::for_each
286template <class InputIter, class Size, class Function>
287Function ll_for_n(InputIter first, Size n, Function f)
288{
289 for ( ; n > 0; --n, ++first)
290 f(*first);
291 return f;
292}
293
294// copy first to result n times, incrementing each as we go
295template <class InputIter, class Size, class OutputIter>
296OutputIter ll_copy_n(InputIter first, Size n, OutputIter result)
297{
298 for ( ; n > 0; --n, ++result, ++first)
299 *result = *first;
300 return result;
301}
302
303// set *result = op(*f) for n elements of f
304template <class InputIter, class OutputIter, class Size, class UnaryOp>
305OutputIter ll_transform_n(
306 InputIter first,
307 Size n,
308 OutputIter result,
309 UnaryOp op)
310{
311 for ( ; n > 0; --n, ++result, ++first)
312 *result = op(*first);
313 return result;
314}
315
316
317
318/*
319 *
320 * Copyright (c) 1994
321 * Hewlett-Packard Company
322 *
323 * Permission to use, copy, modify, distribute and sell this software
324 * and its documentation for any purpose is hereby granted without fee,
325 * provided that the above copyright notice appear in all copies and
326 * that both that copyright notice and this permission notice appear
327 * in supporting documentation. Hewlett-Packard Company makes no
328 * representations about the suitability of this software for any
329 * purpose. It is provided "as is" without express or implied warranty.
330 *
331 *
332 * Copyright (c) 1996-1998
333 * Silicon Graphics Computer Systems, Inc.
334 *
335 * Permission to use, copy, modify, distribute and sell this software
336 * and its documentation for any purpose is hereby granted without fee,
337 * provided that the above copyright notice appear in all copies and
338 * that both that copyright notice and this permission notice appear
339 * in supporting documentation. Silicon Graphics makes no
340 * representations about the suitability of this software for any
341 * purpose. It is provided "as is" without express or implied warranty.
342 */
343
344
345// helper to deal with the fact that MSDev does not package
346// select... with the stl. Look up usage on the sgi website.
347
348template <class _Pair>
349struct _LLSelect1st : public std::unary_function<_Pair, typename _Pair::first_type> {
350 const typename _Pair::first_type& operator()(const _Pair& __x) const {
351 return __x.first;
352 }
353};
354
355template <class _Pair>
356struct _LLSelect2nd : public std::unary_function<_Pair, typename _Pair::second_type>
357{
358 const typename _Pair::second_type& operator()(const _Pair& __x) const {
359 return __x.second;
360 }
361};
362
363template <class _Pair> struct llselect1st : public _LLSelect1st<_Pair> {};
364template <class _Pair> struct llselect2nd : public _LLSelect2nd<_Pair> {};
365
366// helper to deal with the fact that MSDev does not package
367// compose... with the stl. Look up usage on the sgi website.
368
369template <class _Operation1, class _Operation2>
370class ll_unary_compose :
371 public std::unary_function<typename _Operation2::argument_type,
372 typename _Operation1::result_type>
373{
374protected:
375 _Operation1 __op1;
376 _Operation2 __op2;
377public:
378 ll_unary_compose(const _Operation1& __x, const _Operation2& __y)
379 : __op1(__x), __op2(__y) {}
380 typename _Operation1::result_type
381 operator()(const typename _Operation2::argument_type& __x) const {
382 return __op1(__op2(__x));
383 }
384};
385
386template <class _Operation1, class _Operation2>
387inline ll_unary_compose<_Operation1,_Operation2>
388llcompose1(const _Operation1& __op1, const _Operation2& __op2)
389{
390 return ll_unary_compose<_Operation1,_Operation2>(__op1, __op2);
391}
392
393template <class _Operation1, class _Operation2, class _Operation3>
394class ll_binary_compose
395 : public std::unary_function<typename _Operation2::argument_type,
396 typename _Operation1::result_type> {
397protected:
398 _Operation1 _M_op1;
399 _Operation2 _M_op2;
400 _Operation3 _M_op3;
401public:
402 ll_binary_compose(const _Operation1& __x, const _Operation2& __y,
403 const _Operation3& __z)
404 : _M_op1(__x), _M_op2(__y), _M_op3(__z) { }
405 typename _Operation1::result_type
406 operator()(const typename _Operation2::argument_type& __x) const {
407 return _M_op1(_M_op2(__x), _M_op3(__x));
408 }
409};
410
411template <class _Operation1, class _Operation2, class _Operation3>
412inline ll_binary_compose<_Operation1, _Operation2, _Operation3>
413llcompose2(const _Operation1& __op1, const _Operation2& __op2,
414 const _Operation3& __op3)
415{
416 return ll_binary_compose<_Operation1,_Operation2,_Operation3>
417 (__op1, __op2, __op3);
418}
419
420// helpers to deal with the fact that MSDev does not package
421// bind... with the stl. Again, this is from sgi.
422template <class _Operation>
423class llbinder1st :
424 public std::unary_function<typename _Operation::second_argument_type,
425 typename _Operation::result_type> {
426protected:
427 _Operation op;
428 typename _Operation::first_argument_type value;
429public:
430 llbinder1st(const _Operation& __x,
431 const typename _Operation::first_argument_type& __y)
432 : op(__x), value(__y) {}
433 typename _Operation::result_type
434 operator()(const typename _Operation::second_argument_type& __x) const {
435 return op(value, __x);
436 }
437};
438
439template <class _Operation, class _Tp>
440inline llbinder1st<_Operation>
441llbind1st(const _Operation& __oper, const _Tp& __x)
442{
443 typedef typename _Operation::first_argument_type _Arg1_type;
444 return llbinder1st<_Operation>(__oper, _Arg1_type(__x));
445}
446
447template <class _Operation>
448class llbinder2nd
449 : public std::unary_function<typename _Operation::first_argument_type,
450 typename _Operation::result_type> {
451protected:
452 _Operation op;
453 typename _Operation::second_argument_type value;
454public:
455 llbinder2nd(const _Operation& __x,
456 const typename _Operation::second_argument_type& __y)
457 : op(__x), value(__y) {}
458 typename _Operation::result_type
459 operator()(const typename _Operation::first_argument_type& __x) const {
460 return op(__x, value);
461 }
462};
463
464template <class _Operation, class _Tp>
465inline llbinder2nd<_Operation>
466llbind2nd(const _Operation& __oper, const _Tp& __x)
467{
468 typedef typename _Operation::second_argument_type _Arg2_type;
469 return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
470}
471
472#endif // LL_LLSTL_H