FEI Version of the Day
fei_IndexType.hpp
00001 /*
00002 // @HEADER
00003 // ************************************************************************
00004 //             FEI: Finite Element Interface to Linear Solvers
00005 //                  Copyright (2005) Sandia Corporation.
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
00008 // U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Alan Williams (william@sandia.gov) 
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 */
00042 
00043 
00044 #ifndef _fei_IndexType_hpp_
00045 #define _fei_IndexType_hpp_
00046 
00047 #include <fei_macros.hpp>
00048 
00049 #include <map>
00050 #include <algorithm>
00051 #include <functional>
00052 
00053 #ifdef HAVE_FEI_BOOST
00054 #include <boost/unordered_map.hpp>
00055 #endif
00056 
00057 
00058 namespace fei {
00059 
00060 template< typename T_Key, typename T_Value>
00061 class IndexType : public
00062 #ifdef HAVE_FEI_BOOST
00063    boost::unordered_map<T_Key, T_Value>
00064 #else
00065   std::map<T_Key, T_Value>
00066 #endif
00067 {
00068   typedef std::map<T_Key, T_Value> mapRep;
00069 public:
00070 #ifdef HAVE_FEI_BOOST
00071 public:
00072   typedef boost::unordered_map<T_Key, T_Value> base;
00073   bool isStdMap() const {return false;}
00074   const mapRep& asMap(mapRep &map_rep) const {
00075     resyncToMap(map_rep);
00076     return map_rep;
00077   }
00078   mapRep& asMap(mapRep &map_rep) {
00079     resyncToMap(map_rep);
00080     return map_rep;
00081   }
00082 
00083   T_Key getMaxKey() const {
00084     if (this->size() == 0 ) 
00085       return T_Value(0);
00086     T_Key k = this->begin()->first;
00087     typename base::const_iterator iter=++(this->begin()),end=this->end();
00088     for ( ; iter != end; ++iter) 
00089       k = std::max(k,iter->first);
00090     return k;
00091   }
00092 
00093   T_Key getMinKey() const {
00094     if (this->size() == 0 ) 
00095       return T_Value(0);
00096     T_Key k = this->begin()->first;
00097     typename base::const_iterator iter=++(this->begin()),end=this->end();
00098     for ( ; iter != end; ++iter) 
00099       k = std::min(k,iter->first);
00100     return k;
00101   }
00102 
00103 #else
00104   typedef std::map<T_Key, T_Value> base;
00105   bool isStdMap() const {return true;}
00106   mapRep &asMap(mapRep &rep) const{ return *static_cast<base *>(&rep);}
00107   const mapRep &asMap(const mapRep&rep) const { return *static_cast<const base *>( &rep);}
00108 
00109   T_Key getMaxKey() const {
00110     IndexType<int,int>::const_iterator highest = this->end();
00111     if (this->size() > 0) 
00112       return (--highest)->first;
00113     return T_Key(0);
00114   }
00115 
00116   T_Key getMinKey() const {
00117     if (this->size() > 0) 
00118       return this->begin()->first;
00119     return T_Key(0);
00120   }
00121 
00122 #endif
00123   
00124   bool lightWeightCompare(const mapRep &map_rep) const {
00125     return (this->size() == map_rep.size());
00126   }
00127 
00128   bool heavyWeightCompare(const mapRep &map_rep) const {
00129 
00130     if (this->size() != map_rep.size())
00131       return false;
00132     typename base::const_iterator iter=this->begin(),end=this->end();
00133     for ( ; iter != end; ++iter) {
00134       typename mapRep::const_iterator lookup = map_rep.find(iter->first);
00135       if ( lookup == map_rep.end())
00136   return false;
00137       if (lookup->second  != iter->second)
00138   return false;
00139     }
00140     return true;
00141   }
00142 
00143   void resyncToMap( mapRep &map_rep) const {
00144     if ( !heavyWeightCompare(map_rep) ) {
00145       map_rep.clear();
00146       typename base::const_iterator iter=this->begin(), end=this->end();
00147       for ( ; iter != end; ++iter) 
00148   map_rep.insert(*iter);
00149     }
00150   }
00151 
00152   void resyncFromMap(const mapRep &map_rep) {
00153     if ( !heavyWeightCompare(map_rep) ) {
00154       this->clear();
00155       typename mapRep::const_iterator iter=map_rep.begin(), end=map_rep.end();
00156       for ( ; iter != end; ++iter) 
00157   this->insert(*iter);
00158     }
00159   }  
00160 }; 
00161 }
00162 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends