- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

# unique.hxx

    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