00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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 }
00136 }
00137 }
00138
00139 #endif // ! VCSN_MISC_UNIQUE_HXX