llstl.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLSTL_H
00033 #define LL_LLSTL_H
00034 
00035 #include <functional>
00036 #include <algorithm>
00037 #include <map>
00038 #include <vector>
00039 #include <set>
00040 #include <deque>
00041 
00042 // Use to compare the first element only of a pair
00043 // e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t; 
00044 template <typename T1, typename T2>
00045 struct compare_pair_first
00046 {
00047         bool operator()(const std::pair<T1, T2>& a, const std::pair<T1, T2>& b) const
00048         {
00049                 return a.first < b.first;
00050         }
00051 };
00052 
00053 template <typename T1, typename T2>
00054 struct compare_pair_greater
00055 {
00056         bool operator()(const std::pair<T1, T2>& a, const std::pair<T1, T2>& b) const
00057         {
00058                 if (!(a.first < b.first))
00059                         return true;
00060                 else if (!(b.first < a.first))
00061                         return false;
00062                 else
00063                         return !(a.second < b.second);
00064         }
00065 };
00066 
00067 // Use to compare the contents of two pointers (e.g. std::string*)
00068 template <typename T>
00069 struct compare_pointer_contents
00070 {
00071         typedef const T* Tptr;
00072         bool operator()(const Tptr& a, const Tptr& b) const
00073         {
00074                 return *a < *b;
00075         }
00076 };
00077 
00078 // DeletePointer is a simple helper for deleting all pointers in a container.
00079 // The general form is:
00080 //
00081 //  std::for_each(cont.begin(), cont.end(), DeletePointer());
00082 
00083 struct DeletePointer
00084 {
00085         template<typename T> void operator()(T* ptr) const
00086         {
00087                 delete ptr;
00088         }
00089 };
00090 struct DeletePointerArray
00091 {
00092         template<typename T> void operator()(T* ptr) const
00093         {
00094                 delete[] ptr;
00095         }
00096 };
00097 
00098 // DeletePointer is a simple helper for deleting all pointers in a map.
00099 // The general form is:
00100 //
00101 //  std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer());
00102 
00103 struct DeletePairedPointer
00104 {
00105         template<typename T> void operator()(T &ptr) const
00106         {
00107                 delete ptr.second;
00108         }
00109 };
00110 struct DeletePairedPointerArray
00111 {
00112         template<typename T> void operator()(T &ptr) const
00113         {
00114                 delete[] ptr.second;
00115         }
00116 };
00117 
00118 
00119 // Alternate version of the above so that has a more cumbersome
00120 // syntax, but it can be used with compositional functors.
00121 // NOTE: The functor retuns a bool because msdev bombs during the
00122 // composition if you return void. Once we upgrade to a newer
00123 // compiler, the second unary_function template parameter can be set
00124 // to void.
00125 //
00126 // Here's a snippit showing how you use this object:
00127 //
00128 // typedef std::map<int, widget*> map_type;
00129 // map_type widget_map;
00130 // ... // add elements
00131 // // delete them all
00132 // for_each(widget_map.begin(),
00133 //          widget_map.end(),
00134 //          llcompose1(DeletePointerFunctor<widget>(),
00135 //                     llselect2nd<map_type::value_type>()));
00136 
00137 template<typename T>
00138 struct DeletePointerFunctor : public std::unary_function<T*, bool>
00139 {
00140         bool operator()(T* ptr) const
00141         {
00142                 delete ptr;
00143                 return true;
00144         }
00145 };
00146 
00147 // See notes about DeleteArray for why you should consider avoiding this.
00148 template<typename T>
00149 struct DeleteArrayFunctor : public std::unary_function<T*, bool>
00150 {
00151         bool operator()(T* ptr) const
00152         {
00153                 delete[] ptr;
00154                 return true;
00155         }
00156 };
00157 
00158 // CopyNewPointer is a simple helper which accepts a pointer, and
00159 // returns a new pointer built with the copy constructor. Example:
00160 //
00161 //  transform(in.begin(), in.end(), out.end(), CopyNewPointer());
00162 
00163 struct CopyNewPointer
00164 {
00165         template<typename T> T* operator()(const T* ptr) const
00166         {
00167                 return new T(*ptr);
00168         }
00169 };
00170 
00171 // Simple function to help with finding pointers in maps.
00172 // For example:
00173 //      typedef  map_t;
00174 //  std::map<int, const char*> foo;
00175 //      foo[18] = "there";
00176 //      foo[2] = "hello";
00177 //      const char* bar = get_ptr_in_map(foo, 2); // bar -> "hello"
00178 //  const char* baz = get_ptr_in_map(foo, 3); // baz == NULL
00179 template <typename K, typename T>
00180 inline T* get_ptr_in_map(const std::map<K,T*>& inmap, const K& key)
00181 {
00182         // Typedef here avoids warnings because of new c++ naming rules.
00183         typedef typename std::map<K,T*>::const_iterator map_iter;
00184         map_iter iter = inmap.find(key);
00185         if(iter == inmap.end())
00186         {
00187                 return NULL;
00188         }
00189         else
00190         {
00191                 return iter->second;
00192         }
00193 };
00194 
00195 // helper function which returns true if key is in inmap.
00196 template <typename K, typename T>
00197 inline bool is_in_map(const std::map<K,T>& inmap, const K& key)
00198 {
00199         typedef typename std::map<K,T>::const_iterator map_iter;
00200         if(inmap.find(key) == inmap.end())
00201         {
00202                 return false;
00203         }
00204         else
00205         {
00206                 return true;
00207         }
00208 }
00209 
00210 // Similar to get_ptr_in_map, but for any type with a valid T(0) constructor.
00211 // To replace LLSkipMap getIfThere, use:
00212 //   get_if_there(map, key, 0)
00213 // WARNING: Make sure default_value (generally 0) is not a valid map entry!
00214 template <typename K, typename T>
00215 inline T get_if_there(const std::map<K,T>& inmap, const K& key, T default_value)
00216 {
00217         // Typedef here avoids warnings because of new c++ naming rules.
00218         typedef typename std::map<K,T>::const_iterator map_iter;
00219         map_iter iter = inmap.find(key);
00220         if(iter == inmap.end())
00221         {
00222                 return default_value;
00223         }
00224         else
00225         {
00226                 return iter->second;
00227         }
00228 };
00229 
00230 // Useful for replacing the removeObj() functionality of LLDynamicArray
00231 // Example:
00232 //  for (std::vector<T>::iterator iter = mList.begin(); iter != mList.end(); )
00233 //  {
00234 //    if ((*iter)->isMarkedForRemoval())
00235 //      iter = vector_replace_with_last(mList, iter);
00236 //    else
00237 //      ++iter;
00238 //  }
00239 template <typename T, typename Iter>
00240 inline Iter vector_replace_with_last(std::vector<T>& invec, Iter iter)
00241 {
00242         typename std::vector<T>::iterator last = invec.end(); --last;
00243         if (iter == invec.end())
00244         {
00245                 return iter;
00246         }
00247         else if (iter == last)
00248         {
00249                 invec.pop_back();
00250                 return invec.end();
00251         }
00252         else
00253         {
00254                 *iter = *last;
00255                 invec.pop_back();
00256                 return iter;
00257         }
00258 };
00259 
00260 // Useful for replacing the removeObj() functionality of LLDynamicArray
00261 // Example:
00262 //   vector_replace_with_last(mList, x);
00263 template <typename T>
00264 inline bool vector_replace_with_last(std::vector<T>& invec, const T& val)
00265 {
00266         typename std::vector<T>::iterator iter = std::find(invec.begin(), invec.end(), val);
00267         if (iter != invec.end())
00268         {
00269                 typename std::vector<T>::iterator last = invec.end(); --last;
00270                 *iter = *last;
00271                 invec.pop_back();
00272                 return true;
00273         }
00274         return false;
00275 }
00276 
00277 // Append N elements to the vector and return a pointer to the first new element.
00278 template <typename T>
00279 inline T* vector_append(std::vector<T>& invec, S32 N)
00280 {
00281         U32 sz = invec.size();
00282         invec.resize(sz+N);
00283         return &(invec[sz]);
00284 }
00285 
00286 // call function f to n members starting at first. similar to std::for_each
00287 template <class InputIter, class Size, class Function>
00288 Function ll_for_n(InputIter first, Size n, Function f)
00289 {
00290         for ( ; n > 0; --n, ++first)
00291                 f(*first);
00292         return f;
00293 }
00294 
00295 // copy first to result n times, incrementing each as we go
00296 template <class InputIter, class Size, class OutputIter>
00297 OutputIter ll_copy_n(InputIter first, Size n, OutputIter result)
00298 {
00299         for ( ; n > 0; --n, ++result, ++first)
00300                 *result = *first;
00301         return result;
00302 }
00303 
00304 // set  *result = op(*f) for n elements of f
00305 template <class InputIter, class OutputIter, class Size, class UnaryOp>
00306 OutputIter ll_transform_n(
00307         InputIter first,
00308         Size n,
00309         OutputIter result,
00310         UnaryOp op)
00311 {
00312         for ( ; n > 0; --n, ++result, ++first)
00313                 *result = op(*first);
00314         return result;
00315 }
00316 
00317 
00318 
00319 /*
00320  *
00321  * Copyright (c) 1994
00322  * Hewlett-Packard Company
00323  *
00324  * Permission to use, copy, modify, distribute and sell this software
00325  * and its documentation for any purpose is hereby granted without fee,
00326  * provided that the above copyright notice appear in all copies and
00327  * that both that copyright notice and this permission notice appear
00328  * in supporting documentation.  Hewlett-Packard Company makes no
00329  * representations about the suitability of this software for any
00330  * purpose.  It is provided "as is" without express or implied warranty.
00331  *
00332  *
00333  * Copyright (c) 1996-1998
00334  * Silicon Graphics Computer Systems, Inc.
00335  *
00336  * Permission to use, copy, modify, distribute and sell this software
00337  * and its documentation for any purpose is hereby granted without fee,
00338  * provided that the above copyright notice appear in all copies and
00339  * that both that copyright notice and this permission notice appear
00340  * in supporting documentation.  Silicon Graphics makes no
00341  * representations about the suitability of this software for any
00342  * purpose.  It is provided "as is" without express or implied warranty.
00343  */
00344 
00345 
00346 // helper to deal with the fact that MSDev does not package
00347 // select... with the stl. Look up usage on the sgi website.
00348 
00349 template <class _Pair>
00350 struct _LLSelect1st : public std::unary_function<_Pair, typename _Pair::first_type> {
00351   const typename _Pair::first_type& operator()(const _Pair& __x) const {
00352     return __x.first;
00353   }
00354 };
00355 
00356 template <class _Pair>
00357 struct _LLSelect2nd : public std::unary_function<_Pair, typename _Pair::second_type>
00358 {
00359   const typename _Pair::second_type& operator()(const _Pair& __x) const {
00360     return __x.second;
00361   }
00362 };
00363 
00364 template <class _Pair> struct llselect1st : public _LLSelect1st<_Pair> {};
00365 template <class _Pair> struct llselect2nd : public _LLSelect2nd<_Pair> {};
00366 
00367 // helper to deal with the fact that MSDev does not package
00368 // compose... with the stl. Look up usage on the sgi website.
00369 
00370 template <class _Operation1, class _Operation2>
00371 class ll_unary_compose :
00372         public std::unary_function<typename _Operation2::argument_type,
00373                                                            typename _Operation1::result_type>
00374 {
00375 protected:
00376   _Operation1 __op1;
00377   _Operation2 __op2;
00378 public:
00379   ll_unary_compose(const _Operation1& __x, const _Operation2& __y)
00380     : __op1(__x), __op2(__y) {}
00381   typename _Operation1::result_type
00382   operator()(const typename _Operation2::argument_type& __x) const {
00383     return __op1(__op2(__x));
00384   }
00385 };
00386 
00387 template <class _Operation1, class _Operation2>
00388 inline ll_unary_compose<_Operation1,_Operation2>
00389 llcompose1(const _Operation1& __op1, const _Operation2& __op2)
00390 {
00391   return ll_unary_compose<_Operation1,_Operation2>(__op1, __op2);
00392 }
00393 
00394 template <class _Operation1, class _Operation2, class _Operation3>
00395 class ll_binary_compose
00396   : public std::unary_function<typename _Operation2::argument_type,
00397                                                            typename _Operation1::result_type> {
00398 protected:
00399   _Operation1 _M_op1;
00400   _Operation2 _M_op2;
00401   _Operation3 _M_op3;
00402 public:
00403   ll_binary_compose(const _Operation1& __x, const _Operation2& __y,
00404                                         const _Operation3& __z)
00405     : _M_op1(__x), _M_op2(__y), _M_op3(__z) { }
00406   typename _Operation1::result_type
00407   operator()(const typename _Operation2::argument_type& __x) const {
00408     return _M_op1(_M_op2(__x), _M_op3(__x));
00409   }
00410 };
00411 
00412 template <class _Operation1, class _Operation2, class _Operation3>
00413 inline ll_binary_compose<_Operation1, _Operation2, _Operation3>
00414 llcompose2(const _Operation1& __op1, const _Operation2& __op2,
00415          const _Operation3& __op3)
00416 {
00417   return ll_binary_compose<_Operation1,_Operation2,_Operation3>
00418     (__op1, __op2, __op3);
00419 }
00420 
00421 // helpers to deal with the fact that MSDev does not package
00422 // bind... with the stl. Again, this is from sgi.
00423 template <class _Operation>
00424 class llbinder1st :
00425         public std::unary_function<typename _Operation::second_argument_type,
00426                                                            typename _Operation::result_type> {
00427 protected:
00428   _Operation op;
00429   typename _Operation::first_argument_type value;
00430 public:
00431   llbinder1st(const _Operation& __x,
00432                           const typename _Operation::first_argument_type& __y)
00433       : op(__x), value(__y) {}
00434         typename _Operation::result_type
00435         operator()(const typename _Operation::second_argument_type& __x) const {
00436                 return op(value, __x);
00437         }
00438 };
00439 
00440 template <class _Operation, class _Tp>
00441 inline llbinder1st<_Operation>
00442 llbind1st(const _Operation& __oper, const _Tp& __x)
00443 {
00444   typedef typename _Operation::first_argument_type _Arg1_type;
00445   return llbinder1st<_Operation>(__oper, _Arg1_type(__x));
00446 }
00447 
00448 template <class _Operation>
00449 class llbinder2nd
00450         : public std::unary_function<typename _Operation::first_argument_type,
00451                                                                  typename _Operation::result_type> {
00452 protected:
00453         _Operation op;
00454         typename _Operation::second_argument_type value;
00455 public:
00456         llbinder2nd(const _Operation& __x,
00457                                 const typename _Operation::second_argument_type& __y)
00458                 : op(__x), value(__y) {}
00459         typename _Operation::result_type
00460         operator()(const typename _Operation::first_argument_type& __x) const {
00461                 return op(__x, value);
00462         }
00463 };
00464 
00465 template <class _Operation, class _Tp>
00466 inline llbinder2nd<_Operation>
00467 llbind2nd(const _Operation& __oper, const _Tp& __x)
00468 {
00469   typedef typename _Operation::second_argument_type _Arg2_type;
00470   return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
00471 }
00472 
00473 #endif // LL_LLSTL_H

Generated on Fri May 16 08:32:08 2008 for SecondLife by  doxygen 1.5.5