1 // Copyright (c) 1997-2000
2 // Utrecht University (The Netherlands),
3 // ETH Zurich (Switzerland),
4 // INRIA Sophia-Antipolis (France),
5 // Max-Planck-Institute Saarbruecken (Germany),
6 // and Tel-Aviv University (Israel).  All rights reserved.
7 //
8 // This file is part of CGAL (www.cgal.org)
9 //
10 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Hash_map/include/CGAL/Unique_hash_map.h $
11 // $Id: Unique_hash_map.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
13 //
14 //
15 // Author(s)     : Michael Seel <seel@mpi-sb.mpg.de>
16 //                 Lutz Kettner <kettner@inf.ethz.ch>
17 
18 #ifndef CGAL_UNIQUE_HASH_MAP_H
19 #define CGAL_UNIQUE_HASH_MAP_H
20 
21 #include <CGAL/disable_warnings.h>
22 
23 #include <CGAL/config.h>
24 #include <CGAL/memory.h>
25 #include <CGAL/Handle_hash_function.h>
26 #include <CGAL/Tools/chained_map.h>
27 #include <cstddef>
28 
29 namespace CGAL {
30 
31 template <class Key_, class Data_,
32           class UniqueHashFunction = Handle_hash_function,
33           class Allocator_ = CGAL_ALLOCATOR(Data_) >
34 class Unique_hash_map {
35 public:
36     typedef Key_                                     Key;
37     typedef Data_                                    Data;
38     typedef UniqueHashFunction                       Hash_function;
39     typedef Allocator_                               Allocator;
40 
41     // STL compliance
42     typedef Key_                                     key_type;
43     typedef Data_                                    data_type;
44     typedef UniqueHashFunction                       hasher;
45 
46     typedef Unique_hash_map<Key,Data,Hash_function,Allocator> Self;
47 
48 private:
49     typedef internal::chained_map<Data, Allocator>   Map;
50     typedef typename Map::item                       Item;
51 
52 private:
53     Hash_function  m_hash_function;
54     Map            m_map;
55 
56 public:
57 
Unique_hash_map()58     Unique_hash_map() { m_map.xdef() = Data(); }
59 
60     Unique_hash_map( const Data& deflt, std::size_t table_size = 1)
m_map(table_size)61         : m_map( table_size) { m_map.xdef() = deflt; }
62 
Unique_hash_map(const Data & deflt,std::size_t table_size,const Hash_function & fct)63     Unique_hash_map( const Data& deflt,
64                      std::size_t table_size,
65                      const Hash_function& fct)
66         : m_hash_function(fct), m_map( table_size) { m_map.xdef() = deflt; }
67 
Unique_hash_map(Key first1,Key beyond1,Data first2)68     Unique_hash_map( Key first1, Key beyond1, Data first2) {
69         m_map.xdef() = Data();
70         insert( first1, beyond1, first2);
71     }
72     Unique_hash_map( Key first1, Key beyond1, Data first2,
73                      const Data& deflt,
74                      std::size_t table_size   = 1,
75                      const Hash_function& fct = Hash_function())
m_hash_function(fct)76     : m_hash_function(fct), m_map( table_size) {
77         m_map.xdef() = deflt;
78         insert( first1, beyond1, first2);
79     }
80 
default_value()81     Data default_value() const { return m_map.cxdef(); }
82 
hash_function()83     Hash_function  hash_function() const { return m_hash_function; }
84 
clear()85     void clear() { m_map.clear(); }
86 
clear(const Data & deflt)87     void clear( const Data& deflt) {
88         m_map.clear();
89         m_map.xdef() = deflt; }
90 
is_defined(const Key & key)91     bool is_defined( const Key& key) const {
92         return m_map.lookup( m_hash_function(key)) != 0;
93     }
94 
95     const Data& operator[]( const Key& key) const {
96         Item p = m_map.lookup( m_hash_function(key));
97         if ( p != 0 )
98             return m_map.inf(p);
99         return m_map.cxdef();
100     }
101 
102     Data& operator[]( const Key& key) {
103         return m_map.access( m_hash_function(key));
104     }
105 
insert(Key first1,Key beyond1,Data first2)106     Data insert( Key first1, Key beyond1, Data first2) {
107         for ( ; first1 != beyond1; (++first1, ++first2)) {
108             operator[]( first1) = first2;
109         }
110         return first2;
111     }
112 
statistics()113     void statistics() const { m_map.statistics(); }
114 };
115 
116 
117 
118 } //namespace CGAL
119 
120 namespace boost {
121   template <typename UniquePairAssociativeContainer>
122   class associative_property_map;
123 
124   struct lvalue_property_map_tag;
125 
126   template <typename KeyType, typename ValueType,
127             typename HashFunction, typename Allocator>
128   class associative_property_map<CGAL::Unique_hash_map<KeyType, ValueType,
129                                                        HashFunction, Allocator> >
130   {
131     typedef CGAL::Unique_hash_map<KeyType, ValueType, HashFunction, Allocator> C;
132 
133   public:
134     typedef KeyType key_type;
135     typedef ValueType value_type;
136     typedef const value_type& reference;
137     typedef lvalue_property_map_tag category;
associative_property_map()138     associative_property_map() : m_c(0) { }
associative_property_map(C & c)139     associative_property_map(C& c) : m_c(&c) { }
140     value_type& operator[](const key_type& k) const {
141       return (*m_c)[k];
142     }
143 
144   friend
145   const value_type&
get(const associative_property_map<C> & uhm,const key_type & key)146   get(const associative_property_map<C>& uhm, const key_type& key)
147   {
148     return uhm[key];
149   }
150 
151   friend
152   void
put(associative_property_map<C> & uhm,const key_type & key,const value_type & val)153   put(associative_property_map<C>& uhm, const key_type& key, const value_type& val)
154   {
155     uhm[key] = val;
156   }
157 
158   private:
159     C* m_c;
160   };
161 
162   template <typename KeyType, typename ValueType,
163             typename HashFunction, typename Allocator>
164   associative_property_map<CGAL::Unique_hash_map<KeyType, ValueType,
165                                                  HashFunction, Allocator> >
make_assoc_property_map(CGAL::Unique_hash_map<KeyType,ValueType,HashFunction,Allocator> & c)166   make_assoc_property_map(CGAL::Unique_hash_map<KeyType, ValueType,
167                                                 HashFunction, Allocator>& c)
168   {
169     return associative_property_map<CGAL::Unique_hash_map<KeyType, ValueType,
170                                                           HashFunction, Allocator> >(c);
171   }
172 
173 }
174 
175 #include <CGAL/enable_warnings.h>
176 
177 #endif // CGAL_UNIQUE_HASH_MAP_H
178 // EOF
179