src/Utility/vmap.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Utility/vmap.h"
00028 #include "Profile/Profiler.h"
00029 
00030 #ifdef IPPL_STDSTL
00031 #include <algorithm>
00032 using std::lower_bound;
00033 using std::upper_bound;
00034 using std::equal_range;
00035 #else
00036 #include <algo.h>
00037 #endif
00038 
00040 //
00041 // Copy ctor
00042 //
00044 template<class Key, class T, class Compare>
00045 vmap<Key,T,Compare>::vmap( const vmap<Key,T,Compare>& x_ac )
00046   : Lt(x_ac.Lt)                 // Copy the comparison object.
00047 {
00048   TAU_TYPE_STRING(taustr, "void (" + CT(x_ac) + " )" );
00049   TAU_PROFILE("vmap::vmap()", taustr, TAU_UTILITY );
00050   V_c = x_ac.V_c;               // Copy the vector of data.
00051 }
00052 
00054 //
00055 // Assignment
00056 //
00058 template<class Key, class T, class Compare>
00059 vmap<Key,T,Compare>&
00060 vmap<Key,T,Compare>::operator=( const vmap<Key,T,Compare>& x_ac )
00061 {
00062   TAU_TYPE_STRING(taustr, "void (" + CT(x_ac) + " )" );
00063   TAU_PROFILE("vmap::operator=()", taustr, TAU_UTILITY );
00064   Lt = x_ac.Lt;                 // Copy the comparison object.
00065   V_c = x_ac.V_c;               // Copy the vector of data.
00066   return *this;
00067 }
00068 
00070 //
00071 // Insert operations.
00072 //
00074 
00075 //
00076 // Insert a single value.
00077 // Return ptr to the inserted and a bool for success.
00078 //
00079 
00080 template<class Key, class T, class Compare>
00081 pair<typename vmap<Key,T,Compare>::iterator,bool>
00082 vmap<Key,T,Compare>::insert(const value_type& value)
00083 {
00084   iterator f_i;
00085   TAU_TYPE_STRING(taustr, "pair<" + CT(f_i) + ", bool> (value_type )" );
00086   TAU_PROFILE("vmap::insert()", taustr, TAU_UTILITY );
00087 
00088   bool success;
00089   f_i = lower_bound( value.first );            // Look for it.
00090   if ( f_i == end() )                          // Are we at the end?
00091     {                                          // Yes, we can't deref f_i.
00092       V_c.push_back(value);                    // Append. Could realloc
00093       f_i = begin() + size() - 1;
00094       success = true;
00095     } 
00096   // BFH: Ge -> Le
00097   else if ( Le((*f_i).first,value.first))      // Did you find it?
00098     {
00099       success = false;
00100     }
00101   else 
00102     {
00103       size_type n = f_i - begin();             // Not there, remember location.
00104       V_c.insert( f_i , value );               // Insert. Could cause realloc.
00105       f_i = begin() + n;
00106       success = true;
00107     }
00108   return pair<iterator,bool>(f_i,success);     // Return ptr to inserted.
00109 }
00110 
00111 //
00112 // Insert a single value given a hint for where it should go.
00113 // It is robust: even if the hint is wrong it will insert in the right place.
00114 // If you start with values sorted in increasing order and give it 
00115 // end() as the hint then it will insert in constant time.
00116 // Return a ptr to the inserted position.
00117 //
00118 
00119 template<class Key, class T, class Compare>
00120 typename vmap<Key,T,Compare>::iterator
00121 vmap<Key,T,Compare>::insert(iterator hint_i, const value_type& value)
00122 {
00123   TAU_TYPE_STRING(taustr, CT(hint_i) + " (" + CT(hint_i) + ", value_type )" );
00124   TAU_PROFILE("vmap::insert()", taustr, TAU_UTILITY );
00125   iterator low_i = begin();     // The bounds for the search range
00126   iterator high_i = end();      // to find where to really put it.
00127   if ( hint_i == high_i )       // Is the hint to append?
00128     if ( empty() || Ge( value.first , hint_i[-1].first ) ) // Is that right?
00129       {                         // Yes!
00130         V_c.push_back(value);   // Quick append.  Could cause realloc!
00131         return end()-1;         // return where we put it.
00132       }
00133   else                                          // Hint is not for append.
00134     if ( Lt(value.first,(*hint_i).first) )      // Is it to the left?
00135       high_i = hint_i;                          //   range = (begin,hint)
00136     else                                        // It is to the right.
00137       low_i = hint_i;                           //   range = (hint,end)
00138 
00139   // Given the range figured out above, find where to really put it.
00140   hint_i = ::upper_bound( low_i, high_i, value, value_compare(Lt) );
00141   size_type n = hint_i - begin();            // Remember the location.
00142   V_c.insert(hint_i,value);                  // Insert here, could realloc.
00143   return V_c.begin() + n;                    // return iterator.
00144 }
00145 
00146 //
00147 // Insert a range of values, with append as the hint.
00148 // If the values being inserted are sorted and all greater than or equal
00149 // to the elements in the vmap this works out to a fast append.
00150 //
00151 
00152 template<class Key, class T, class Compare>
00153 void
00154 vmap<Key,T,Compare>::insert(const value_type *first_i,const value_type *last_i)
00155 {
00156   TAU_TYPE_STRING(taustr, CT(*this) + "void (value_type, value_type )" );
00157   TAU_PROFILE("vmap::insert()", taustr, TAU_UTILITY );
00158   for (; first_i != last_i; ++first_i)
00159     insert( end() , *first_i );
00160 }
00161 
00163 //
00164 // erase operations.
00165 //
00167 
00168 //
00169 // Erase a single element.
00170 //
00171 
00172 template<class Key, class T, class Compare>
00173 void
00174 vmap<Key,T,Compare>::erase(iterator p_i)
00175 {
00176   TAU_TYPE_STRING(taustr, " void (" + CT(p_i) + " )" );
00177   TAU_PROFILE("vmap::erase()", taustr, TAU_UTILITY );
00178   V_c.erase(p_i);
00179 }
00180 
00181 //
00182 // Erase a range of elements.
00183 //
00184 
00185 template<class Key, class T, class Compare>
00186 void
00187 vmap<Key,T,Compare>::erase(iterator first_i, iterator last_i)
00188 {
00189   TAU_TYPE_STRING(taustr, " void (" + CT(first_i) + ", " + CT(last_i) + " )" );
00190   TAU_PROFILE("vmap::erase()", taustr, TAU_UTILITY );
00191   V_c.erase(first_i, last_i);
00192 }
00193 
00194 //
00195 // Erase all the values with key equal to the given.
00196 // Return the number erased.
00197 //
00198 
00199 template<class Key, class T, class Compare>
00200 typename vmap<Key,T,Compare>::size_type
00201 vmap<Key,T,Compare>::erase(const key_type& key)
00202 {
00203   TAU_TYPE_STRING(taustr, CT(*this) + "::size_type (key_type )" );
00204   TAU_PROFILE("vmap::erase()", taustr, TAU_UTILITY );
00205   pair<iterator,iterator> range( equal_range(key) );
00206   erase(range.first, range.second);
00207   return range.second - range.first;
00208 }
00209 
00211 //
00212 // Map operations.
00213 //
00215 
00216 //
00217 // Find a value if it is there.
00218 // Return end() if it is not.
00219 //
00220 
00221 template<class Key, class T, class Compare>
00222 typename vmap<Key,T,Compare>::iterator
00223 vmap<Key,T,Compare>::find(const key_type& key)
00224 {
00225   TAU_TYPE_STRING(taustr, CT(*this) + "::iterator (key_type )" );
00226   TAU_PROFILE("vmap::find()", taustr, TAU_UTILITY );
00227   iterator f_i = lower_bound(key); // Look for it.
00228   if ( f_i == end() )              // Are we at the end?
00229     return end();                  //   Yes, don't try to deref.
00230   // BFH: Ge -> Le
00231   if ( Le((*f_i).first , key) )    // Did you find it?
00232     return f_i;                    //   yes, return it.
00233   else                             // or...
00234     return end();                  //   no, return end().
00235 }
00236 
00237 //
00238 // Return ptr to the first element that is >= the given one.
00239 // Can also think of it as the first place it could be put
00240 // without violating the sequence.
00241 //
00242 
00243 template<class Key, class T, class Compare>
00244 typename vmap<Key,T,Compare>::iterator
00245 vmap<Key,T,Compare>::lower_bound(const key_type& key)
00246 {
00247   TAU_TYPE_STRING(taustr, CT(*this) + "::iterator (key_type )" );
00248   TAU_PROFILE("vmap::lower_bound()", taustr, TAU_UTILITY );
00249   return ::lower_bound(begin(),end(),value_type(key,T()),value_compare(Lt));
00250 }
00251 
00252 //
00253 // Return ptr to the first element > the given one.
00254 // Can also think of it as the last place it could be put
00255 // without violating the sequence.
00256 //
00257 
00258 template<class Key, class T, class Compare>
00259 typename vmap<Key,T,Compare>::iterator
00260 vmap<Key,T,Compare>::upper_bound(const key_type& key)
00261 {
00262   TAU_TYPE_STRING(taustr, CT(*this) + "::iterator (key_type )" );
00263   TAU_PROFILE("vmap::upper_bound()", taustr, TAU_UTILITY );
00264   return ::upper_bound(begin(),end(),value_type(key,T()),value_compare(Lt));
00265 }
00266 
00267 //
00268 // Return a lower_bound, upper_bound pair.
00269 //
00270 
00271 template<class Key, class T, class Compare>
00272 pair<typename vmap<Key,T,Compare>::iterator,
00273      typename vmap<Key,T,Compare>::iterator>
00274 vmap<Key,T,Compare>::equal_range(const key_type& key)
00275 {
00276   TAU_TYPE_STRING(taustr, "pair<" + CT(*this) + "::iterator, " + CT(*this) 
00277     + "::iterator> (key_type )" );
00278   TAU_PROFILE("vmap::equal_range()", taustr, TAU_UTILITY );
00279   return ::equal_range(begin(),end(),value_type(key,T()),value_compare(Lt));
00280 }
00281 
00282 //
00283 // Look up an element given a key.
00284 // If there is not one there already, make space for it.
00285 //
00286 
00287 template<class Key, class T, class Compare>
00288 T&
00289 vmap<Key,T,Compare>::operator[](const key_type& key)
00290 {
00291   TAU_TYPE_STRING(taustr, CT(*this) + " T (key_type )" );
00292   TAU_PROFILE("vmap::operator[]()", taustr, TAU_UTILITY );
00293   size_type n;                  // We will need to calculate the offset.
00294   iterator f_i;                 // Pointer to the data we find.
00295   if ( V_c.empty() )            // Is there anything here?
00296     {                           //    No.  Can't dereference.
00297       n = 0;                    //    The new one will be at the beginning.
00298       f_i = begin();            //    Point to the beginning.
00299     }
00300   else                                 // Yes, there is something here.
00301     {                                  // 
00302       f_i = lower_bound(key);          // Search the whole range.
00303       // BFH: Ge -> Le
00304       if ((f_i!=end()) && Le((*f_i).first,key)) // Did we find this one?
00305         return (*f_i).second;          //    Yes, return ref to data.
00306       n = f_i - begin();               // Not there, remember location.
00307     }
00308   V_c.insert( f_i , value_type(key,T()) ); // Insert. Could cause realloc.
00309   return V_c[n].second;                    // Return ref to data.
00310 }
00311 
00313 //
00314 // Const map operations.
00315 //
00317 
00318 //
00319 // Find how many have the given key.
00320 //
00321 
00322 template<class Key, class T, class Compare>
00323 typename vmap<Key,T,Compare>::size_type
00324 vmap<Key,T,Compare>::count(const key_type& key) const
00325 {
00326   TAU_TYPE_STRING(taustr, CT(*this) + "::size_type (key_type )" );
00327   TAU_PROFILE("vmap::count()", taustr, TAU_UTILITY );
00328   pair<const_iterator,const_iterator>
00329     range( equal_range(key) );       // Find the bounds.
00330   return range.second - range.first; // Difference to get the count.
00331 }
00332 
00333 //
00334 // Find a value if it is there.
00335 // Return end() if it is not.
00336 //
00337 
00338 template<class Key, class T, class Compare>
00339 typename vmap<Key,T,Compare>::const_iterator
00340 vmap<Key,T,Compare>::find(const key_type& key) const
00341 {
00342   TAU_TYPE_STRING(taustr, CT(*this) + "::const_iterator (key_type )" );
00343   TAU_PROFILE("vmap::find()", taustr, TAU_UTILITY );
00344   const_iterator f_i = lower_bound(key); // Look for it.
00345   // BFH: Ge -> Le
00346   if ( Le((*f_i).first , key ))          // Did you find it?
00347     return f_i;                          //   yes, return it.
00348   else                                   // or...
00349     return end();                        //   no, return end().
00350 }
00351 
00352 //
00353 // Return ptr to the first element that is >= the given one.
00354 // Can also think of it as the first place it could be put
00355 // without violating the sequence.
00356 //
00357 
00358 template<class Key, class T, class Compare>
00359 typename vmap<Key,T,Compare>::const_iterator
00360 vmap<Key,T,Compare>::lower_bound(const key_type& key) const
00361 {
00362   TAU_TYPE_STRING(taustr, CT(*this) + "::const_iterator (key_type )" );
00363   TAU_PROFILE("vmap::lower_bound()", taustr, TAU_UTILITY );
00364   return ::lower_bound(begin(),end(),value_type(key,T()),value_compare(Lt));
00365 }
00366 
00367 //
00368 // Return ptr to the first element > the given one.
00369 // Can also think of it as the last place it could be put
00370 // without violating the sequence.
00371 //
00372 
00373 template<class Key, class T, class Compare>
00374 typename vmap<Key,T,Compare>::const_iterator
00375 vmap<Key,T,Compare>::upper_bound(const key_type& key) const
00376 {
00377   TAU_TYPE_STRING(taustr, CT(*this) + "::const_iterator (key_type )" );
00378   TAU_PROFILE("vmap::upper_bound()", taustr, TAU_UTILITY );
00379   return ::upper_bound(begin(),end(),value_type(key,T()),value_compare(Lt));
00380 }
00381 
00382 //
00383 // Return a lower_bound, upper_bound pair.
00384 //
00385 
00386 template<class Key, class T, class Compare>
00387 pair<typename vmap<Key,T,Compare>::const_iterator,
00388      typename vmap<Key,T,Compare>::const_iterator>
00389 vmap<Key,T,Compare>::equal_range(const key_type& key) const
00390 {
00391   TAU_TYPE_STRING(taustr, "pair<" + CT(*this) + "::const_iterator, " 
00392     + CT(*this) + "::const_iterator> (key_type )" );
00393   TAU_PROFILE("vmap::equal_range()", taustr, TAU_UTILITY );
00394   return ::equal_range(begin(),end(),value_type(key,T()),value_compare(Lt));
00395 }
00396 
00397 
00398 //
00399 // Look up an element given a key.
00400 // Scream and die if it is not there.
00401 //
00402 
00403 template<class Key, class T, class Compare>
00404 const T&
00405 vmap<Key,T,Compare>::operator[](const key_type& key) const
00406 {
00407   TAU_TYPE_STRING(taustr, CT(*this) + " T (key_type )" );
00408   TAU_PROFILE("vmap::operator[]()", taustr, TAU_UTILITY );
00409   const_iterator f_i = lower_bound(key);   // Search the whole range.
00410   return (*f_i).second;              // Return what you found.
00411 }
00412 
00413 /***************************************************************************
00414  * $RCSfile: vmap.cpp,v $   $Author: adelmann $
00415  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:34 $
00416  * IPPL_VERSION_ID: $Id: vmap.cpp,v 1.1.1.1 2003/01/23 07:40:34 adelmann Exp $ 
00417  ***************************************************************************/

Generated on Mon Jan 16 13:23:59 2006 for IPPL by  doxygen 1.4.6