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 utility {
00023
00024 namespace unique {
00025
00026
00027 #if defined(__GNUC__)
00028 # if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
00029 # if (__GNUC__ == 4) && (__GNUC_MINOR__ == 0) && (__GNUC_PATCHLEVEL__ == 0)
00030 template class UniqueMap<int>::TiSlot<int>;
00031 # endif
00032 # endif
00033 #endif
00034
00035 template <>
00036 template <>
00037 inline
00038 unique_map::ti_slot::TiSlot(const std::type_info& _id) : id(_id)
00039 {
00040 }
00041
00042 template <>
00043 template <>
00044 inline
00045 bool
00046 unique_map::ti_slot::
00047 operator==(const unique_map::ti_slot& other) const
00048 {
00049 return id == other.id;
00050 }
00051
00052 template <>
00053 template <>
00054 inline
00055 bool unique_map::ti_slot::
00056 operator<(const unique_map::ti_slot& other) const
00057 {
00058 return id.before(other.id);
00059 }
00060
00061 template<typename T>
00062 uniquelist<T>::~uniquelist()
00063 {}
00064
00065 inline
00066 unifiable::unifiable() : unique_(false)
00067 {}
00068
00069 inline
00070 unifiable::unifiable(const unifiable& ) : unique_(false)
00071 {}
00072
00073 template<typename T>
00074 const T& get(const T& v)
00075 {
00076 if (static_cast<const unifiable&>(v).unique_)
00077 return v;
00078
00079 unique_map::map_t& m = unique_map::instance();
00080
00081 unique_map::map_t::iterator i = m.find(typeid(T));
00082 if (i == m.end())
00083 {
00084 uniquelist<T> *l =
00085 static_cast<uniquelist<T>* >(m[typeid(T)] = new uniquelist<T>);
00086 l->push_front(v);
00087 static_cast<unifiable&>(l->front()).unique_ = true;
00088 return l->front();
00089 }
00090 uniquelist<T> *l =
00091 static_cast<uniquelist<T>*>(i->second);
00092 typename uniquelist<T>::const_iterator j;
00093 if ((j = std::find(l->begin(), l->end(), v)) == l->end())
00094 {
00095 l->push_front(v);
00096 static_cast<unifiable&>(l->front()).unique_ = true;
00097 return l->front();
00098 }
00099 return *j;
00100 }
00101
00102 template<typename T>
00103 const T* get(const T* v)
00104 {
00105 return & get(*v);
00106 }
00107
00108 template <>
00109 inline
00110 uniquelist_base::~UniqueListBase() {}
00111
00112 template <class T>
00113 typename UniqueMap<T>::map_t&
00114 UniqueMap<T>::instance()
00115 {
00116 static unique_map instance_;
00117 return instance_.map_;
00118 }
00119
00120 template <class T>
00121 UniqueMap<T>::UniqueMap()
00122 {
00123 }
00124
00125 template <class T>
00126 UniqueMap<T>::~UniqueMap()
00127 {
00128 for (typename map_t::iterator i = map_.begin();
00129 i != map_.end();
00130 ++i)
00131 delete i->second;
00132 }
00133
00134 }
00135
00136 }
00137
00138 #endif // ! VCSN_MISC_UNIQUE_HXX