Vaucanson  1.4.1
unique.hxx
1 // unique.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_MISC_UNIQUE_HXX
18 # define VCSN_MISC_UNIQUE_HXX
19 
20 # include <vaucanson/misc/unique.hh>
21 
22 namespace vcsn {
23  namespace misc {
24 
25  namespace unique {
26 
27  // This code solves a bug in GCC 4.0.0 for Apple Computer Inc.
28 # if defined (__GNUC__)
29 # if defined (__GNUC_MINOR__) && defined (__GNUC_PATCHLEVEL__)
30 # if (__GNUC__ == 4) && (__GNUC_MINOR__ == 0) && (__GNUC_PATCHLEVEL__ == 0)
31  template class UniqueMap<int>::TiSlot<int>;
32 # endif
33 # endif
34 # endif
35 
36  template <>
37  template <>
38  inline
39  unique_map::ti_slot::TiSlot (const std::type_info& _id) : id (_id)
40  {
41  }
42 
43  template <>
44  template <>
45  inline
46  bool
47  unique_map::ti_slot::
48  operator== (const unique_map::ti_slot& other) const
49  {
50  return id == other.id;
51  }
52 
53  template <>
54  template <>
55  inline
56  bool unique_map::ti_slot::
57  operator< (const unique_map::ti_slot& other) const
58  {
59  return id.before (other.id);
60  }
61 
62  template <typename T>
63  uniquelist<T>::~uniquelist ()
64  {}
65 
66  inline
67  unifiable::unifiable () : unique_ (false)
68  {}
69 
70  inline
71  unifiable::unifiable (const unifiable& ) : unique_ (false)
72  {}
73 
74  template <typename T>
75  const T& get (const T& v)
76  {
77  if (static_cast<const unifiable&> (v).unique_)
78  return v;
79 
81 
82  unique_map::map_t::iterator i = m.find (typeid (T));
83  if (i == m.end ())
84  {
85  uniquelist<T> *l =
86  static_cast<uniquelist<T>* > (m[typeid (T)] = new uniquelist<T>);
87  l->push_front (v);
88  static_cast<unifiable&> (l->front ()).unique_ = true;
89  return l->front ();
90  }
91  uniquelist<T> *l =
92  static_cast<uniquelist<T>*> (i->second);
94  if ((j = std::find (l->begin (), l->end (), v)) == l->end ())
95  {
96  l->push_front (v);
97  static_cast<unifiable&> (l->front ()).unique_ = true;
98  return l->front ();
99  }
100  return *j;
101  }
102 
103  template <typename T>
104  const T* get (const T* v)
105  {
106  return & get (*v);
107  }
108 
109  template <>
110  inline
111  uniquelist_base::~UniqueListBase () {}
112 
113  template <class T>
114  typename UniqueMap<T>::map_t&
116  {
117  static unique_map instance_;
118  return instance_.map_;
119  }
120 
121  template <class T>
123  {
124  }
125 
126  template <class T>
128  {
129  for (typename map_t::iterator i = map_.begin ();
130  i != map_.end ();
131  ++i)
132  delete i->second;
133  }
134 
135  } // unique
136  } // misc
137 } // vcsn
138 
139 #endif // ! VCSN_MISC_UNIQUE_HXX