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

Generated on Thu Jul 1 06:09:13 2010 for Second Life Viewer by  doxygen 1.4.7