Vaucanson 1.4
|
00001 // unique.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 The Vaucanson Group. 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // The complete GNU General Public Licence Notice can be found as the 00013 // `COPYING' file in the root directory. 00014 // 00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 00016 // 00017 #ifndef VCSN_MISC_UNIQUE_HXX 00018 # define VCSN_MISC_UNIQUE_HXX 00019 00020 # include <vaucanson/misc/unique.hh> 00021 00022 namespace vcsn { 00023 namespace misc { 00024 00025 namespace unique { 00026 00027 // This code solves a bug in GCC 4.0.0 for Apple Computer Inc. 00028 # if defined (__GNUC__) 00029 # if defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__) 00030 # if (__GNUC__ == 4) && (__GNUC_MINOR__ == 0) && (__GNUC_PATCHLEVEL__ == 0) 00031 template class UniqueMap<int>::TiSlot<int>; 00032 # endif 00033 # endif 00034 # endif 00035 00036 template <> 00037 template <> 00038 inline 00039 unique_map::ti_slot::TiSlot (const std::type_info& _id) : id (_id) 00040 { 00041 } 00042 00043 template <> 00044 template <> 00045 inline 00046 bool 00047 unique_map::ti_slot:: 00048 operator== (const unique_map::ti_slot& other) const 00049 { 00050 return id == other.id; 00051 } 00052 00053 template <> 00054 template <> 00055 inline 00056 bool unique_map::ti_slot:: 00057 operator< (const unique_map::ti_slot& other) const 00058 { 00059 return id.before (other.id); 00060 } 00061 00062 template <typename T> 00063 uniquelist<T>::~uniquelist () 00064 {} 00065 00066 inline 00067 unifiable::unifiable () : unique_ (false) 00068 {} 00069 00070 inline 00071 unifiable::unifiable (const unifiable& ) : unique_ (false) 00072 {} 00073 00074 template <typename T> 00075 const T& get (const T& v) 00076 { 00077 if (static_cast<const unifiable&> (v).unique_) 00078 return v; 00079 00080 unique_map::map_t& m = unique_map::instance (); 00081 00082 unique_map::map_t::iterator i = m.find (typeid (T)); 00083 if (i == m.end ()) 00084 { 00085 uniquelist<T> *l = 00086 static_cast<uniquelist<T>* > (m[typeid (T)] = new uniquelist<T>); 00087 l->push_front (v); 00088 static_cast<unifiable&> (l->front ()).unique_ = true; 00089 return l->front (); 00090 } 00091 uniquelist<T> *l = 00092 static_cast<uniquelist<T>*> (i->second); 00093 typename uniquelist<T>::const_iterator j; 00094 if ((j = std::find (l->begin (), l->end (), v)) == l->end ()) 00095 { 00096 l->push_front (v); 00097 static_cast<unifiable&> (l->front ()).unique_ = true; 00098 return l->front (); 00099 } 00100 return *j; 00101 } 00102 00103 template <typename T> 00104 const T* get (const T* v) 00105 { 00106 return & get (*v); 00107 } 00108 00109 template <> 00110 inline 00111 uniquelist_base::~UniqueListBase () {} 00112 00113 template <class T> 00114 typename UniqueMap<T>::map_t& 00115 UniqueMap<T>::instance () 00116 { 00117 static unique_map instance_; 00118 return instance_.map_; 00119 } 00120 00121 template <class T> 00122 UniqueMap<T>::UniqueMap () 00123 { 00124 } 00125 00126 template <class T> 00127 UniqueMap<T>::~UniqueMap () 00128 { 00129 for (typename map_t::iterator i = map_.begin (); 00130 i != map_.end (); 00131 ++i) 00132 delete i->second; 00133 } 00134 00135 } // unique 00136 } // misc 00137 } // vcsn 00138 00139 #endif // ! VCSN_MISC_UNIQUE_HXX