unistr/u{8,16,32}-uctomb: Avoid possible trouble with huge strings.
[gnulib.git] / lib / gl_map.hh
blob082694fe6b75c08c614c4bbfe4c8ad859c176010
1 /* Abstract map data type as a C++ class.
2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2018.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 #ifndef _GL_MAP_HH
19 #define _GL_MAP_HH
21 #include "gl_map.h"
22 #include "gl_xmap.h"
24 /* gl_Map is a C++ wrapper around the gl_map data type.
25 Its key type is 'KEYTYPE *'. Its value type is 'VALUETYPE *'.
27 It is merely a pointer, not a smart pointer. In other words:
28 it does NOT do reference-counting, and the destructor does nothing. */
30 template <class K, class V> class gl_Map;
32 template <class KEYTYPE, class VALUETYPE>
33 class gl_Map<KEYTYPE *, VALUETYPE *>
35 public:
36 // ------------------------------ Constructors ------------------------------
38 gl_Map ()
39 : _ptr (NULL)
42 /* Creates an empty map.
43 IMPLEMENTATION is one of GL_ARRAY_MAP, GL_LINKEDHASH_MAP, GL_HASH_MAP.
44 EQUALS_FN is a key comparison function or NULL.
45 HASHCODE_FN is a key hash code function or NULL.
46 KDISPOSE_FN is a key disposal function or NULL.
47 VDISPOSE_FN is a value disposal function or NULL. */
48 gl_Map (gl_map_implementation_t implementation,
49 bool (*equals_fn) (KEYTYPE * /*key1*/, KEYTYPE * /*key2*/),
50 size_t (*hashcode_fn) (KEYTYPE *),
51 void (*kdispose_fn) (KEYTYPE *),
52 void (*vdispose_fn) (VALUETYPE *))
53 : _ptr (gl_map_create_empty (implementation,
54 reinterpret_cast<gl_mapkey_equals_fn>(equals_fn),
55 reinterpret_cast<gl_mapkey_hashcode_fn>(hashcode_fn),
56 reinterpret_cast<gl_mapkey_dispose_fn>(kdispose_fn),
57 reinterpret_cast<gl_mapvalue_dispose_fn>(vdispose_fn)))
60 /* Copy constructor. */
61 gl_Map (const gl_Map& x)
62 { _ptr = x._ptr; }
64 /* Assignment operator. */
65 gl_Map& operator= (const gl_Map& x)
66 { _ptr = x._ptr; return *this; }
68 // ------------------------------- Destructor -------------------------------
70 ~gl_Map ()
71 { _ptr = NULL; }
73 // ----------------------- Read-only member functions -----------------------
75 /* Returns the current number of pairs in the map. */
76 size_t size () const
77 { return gl_map_size (_ptr); }
79 /* Searches whether a pair with the given key is already in the map.
80 Returns the value if found, or NULL if not present in the map. */
81 VALUETYPE * get (KEYTYPE * key) const
82 { return static_cast<VALUETYPE *>(gl_map_get (_ptr, key)); }
84 /* Searches whether a pair with the given key is already in the map.
85 Returns true and sets VALUE to the value if found.
86 Returns false if not present in the map. */
87 bool search (KEYTYPE * key, VALUETYPE *& value) const
88 { return gl_map_search (_ptr, key, &value); }
90 // ----------------------- Modifying member functions -----------------------
92 /* Adds a pair to the map.
93 Returns true if a pair with the given key was not already in the map and so
94 this pair was added.
95 Returns false if a pair with the given key was already in the map and only
96 its value was replaced. */
97 bool put (KEYTYPE * key, VALUETYPE * value)
98 { return gl_map_put (_ptr, key, value); }
100 /* Adds a pair to the map and retrieves the previous value.
101 Returns true if a pair with the given key was not already in the map and so
102 this pair was added.
103 Returns false and sets OLDVALUE to the previous value, if a pair with the
104 given key was already in the map and only its value was replaced. */
105 bool getput (KEYTYPE * key, VALUETYPE * value, VALUETYPE *& oldvalue)
106 { return gl_map_getput (_ptr, key, value, &oldvalue); }
108 /* Removes a pair from the map.
109 Returns true if the key was found and its pair removed.
110 Returns false otherwise. */
111 bool remove (KEYTYPE * key)
112 { return gl_map_remove (_ptr, key); }
114 /* Removes a pair from the map and retrieves the previous value.
115 Returns true and sets OLDVALUE to the previous value, if the key was found
116 and its pair removed.
117 Returns false otherwise. */
118 bool getremove (KEYTYPE * key, VALUETYPE *& oldvalue)
119 { return gl_map_getremove (_ptr, key, &oldvalue); }
121 /* Frees the entire map.
122 (But this call does not free the keys and values of the pairs in the map.
123 It only invokes the KDISPOSE_FN on each key and the VDISPOSE_FN on each value
124 of the pairs in the map.) */
125 void free ()
126 { gl_map_free (_ptr); _ptr = NULL; }
128 // ------------------------------ Private stuff ------------------------------
130 private:
131 gl_map_t _ptr;
133 public:
134 // -------------------------------- Iterators --------------------------------
135 // Only a forward iterator.
136 // Does not implement the STL operations (++, *, and != .end()), but a simpler
137 // interface that needs only one virtual function call per iteration instead
138 // of three.
140 class iterator {
141 public:
143 /* If there is a next pair, stores the next pair in KEY and VALUE, advance
144 the iterator, and returns true. Otherwise, returns false. */
145 bool next (KEYTYPE *& key, VALUETYPE *& value)
147 const void *next_key;
148 const void *next_value;
149 bool has_next = gl_map_iterator_next (&_state, &next_key, &next_value);
150 if (has_next)
152 key = static_cast<KEYTYPE *>(next_key);
153 value = static_cast<VALUETYPE *>(next_value);
155 return has_next;
158 ~iterator ()
159 { gl_map_iterator_free (&_state); }
161 #if defined __xlC__ || defined __HP_aCC || defined __SUNPRO_CC
162 public:
163 #else
164 private:
165 friend iterator gl_Map::begin ();
166 #endif
168 iterator (gl_map_t ptr)
169 : _state (gl_map_iterator (ptr))
172 private:
174 gl_map_iterator_t _state;
177 /* Creates an iterator traversing the map.
178 The map's contents must not be modified while the iterator is in use,
179 except for modifying the value of the last returned key or removing the
180 last returned pair. */
181 iterator begin ()
182 { return iterator (_ptr); }
185 #endif /* _GL_MAP_HH */