>From 4105a91334fd9f88115d0776cdb6d5ec54cf19d6 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 2 Feb 2020 19:05:19 +0100 Subject: [PATCH 07/11] map-c++: New module. * lib/gl_map.hh: New file, based on lib/gl_map.h. * modules/map-c++: New file. --- ChangeLog | 6 ++ lib/gl_map.hh | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ modules/map-c++ | 21 +++++++ 3 files changed, 202 insertions(+) create mode 100644 lib/gl_map.hh create mode 100644 modules/map-c++ diff --git a/ChangeLog b/ChangeLog index 1529ebd..15e36fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2020-02-02 Bruno Haible + map-c++: New module. + * lib/gl_map.hh: New file, based on lib/gl_map.h. + * modules/map-c++: New file. + +2020-02-02 Bruno Haible + oset-c++: Add tests. * tests/test-oset-c++.cc: New file. * modules/oset-c++-tests: New file. diff --git a/lib/gl_map.hh b/lib/gl_map.hh new file mode 100644 index 0000000..f3d0a46 --- /dev/null +++ b/lib/gl_map.hh @@ -0,0 +1,175 @@ +/* Abstract map data type as a C++ class. + Copyright (C) 2006-2020 Free Software Foundation, Inc. + Written by Bruno Haible , 2018. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef _GL_MAP_HH +#define _GL_MAP_HH + +#include "gl_map.h" +#include "gl_xmap.h" + +/* gl_Map is a C++ wrapper around the gl_map data type. + Its key type is 'KEYTYPE *'. Its value type is 'VALUETYPE *'. + + It is merely a pointer, not a smart pointer. In other words: + it does NOT do reference-counting, and the destructor does nothing. */ + +template class gl_Map; + +template +class gl_Map +{ +public: + // ------------------------------ Constructors ------------------------------ + + gl_Map () + : _ptr (NULL) + {} + + /* Creates an empty map. + IMPLEMENTATION is one of GL_ARRAY_MAP, GL_LINKEDHASH_MAP, GL_HASH_MAP. + EQUALS_FN is a key comparison function or NULL. + HASHCODE_FN is a key hash code function or NULL. + KDISPOSE_FN is a key disposal function or NULL. + VDISPOSE_FN is a value disposal function or NULL. */ + gl_Map (gl_map_implementation_t implementation, + bool (*equals_fn) (KEYTYPE * /*key1*/, KEYTYPE * /*key2*/), + size_t (*hashcode_fn) (KEYTYPE *), + void (*kdispose_fn) (KEYTYPE *), + void (*vdispose_fn) (VALUETYPE *)) + : _ptr (gl_map_create_empty (implementation, + reinterpret_cast(equals_fn), + reinterpret_cast(hashcode_fn), + reinterpret_cast(kdispose_fn), + reinterpret_cast(vdispose_fn))) + {} + + /* Copy constructor. */ + gl_Map (const gl_Map& x) + { _ptr = x._ptr; } + + /* Assignment operator. */ + gl_Map& operator= (const gl_Map& x) + { _ptr = x._ptr; return *this; } + + // ------------------------------- Destructor ------------------------------- + + ~gl_Map () + { _ptr = NULL; } + + // ----------------------- Read-only member functions ----------------------- + + /* Returns the current number of pairs in the map. */ + size_t size () const + { return gl_map_size (_ptr); } + + /* Searches whether a pair with the given key is already in the map. + Returns the value if found, or NULL if not present in the map. */ + VALUETYPE * get (KEYTYPE * key) const + { return static_cast(gl_map_get (_ptr, key)); } + + /* Searches whether a pair with the given key is already in the map. + Returns true and sets VALUE to the value if found. + Returns false if not present in the map. */ + bool search (KEYTYPE * key, VALUETYPE *& value) const + { return gl_map_search (_ptr, key, &value); } + + // ----------------------- Modifying member functions ----------------------- + + /* Adds a pair to the map. + Returns true if a pair with the given key was not already in the map and so + this pair was added. + Returns false if a pair with the given key was already in the map and only + its value was replaced. */ + bool put (KEYTYPE * key, VALUETYPE * value) + { return gl_map_put (_ptr, key, value); } + + /* Adds a pair to the map and retrieves the previous value. + Returns true if a pair with the given key was not already in the map and so + this pair was added. + Returns false and sets OLDVALUE to the previous value, if a pair with the + given key was already in the map and only its value was replaced. */ + bool getput (KEYTYPE * key, VALUETYPE * value, VALUETYPE *& oldvalue) + { return gl_map_getput (_ptr, key, value, &oldvalue); } + + /* Removes a pair from the map. + Returns true if the key was found and its pair removed. + Returns false otherwise. */ + bool remove (KEYTYPE * key) + { return gl_map_remove (_ptr, key); } + + /* Removes a pair from the map and retrieves the previous value. + Returns true and sets OLDVALUE to the previous value, if the key was found + and its pair removed. + Returns false otherwise. */ + bool getremove (KEYTYPE * key, VALUETYPE *& oldvalue) + { return gl_map_getremove (_ptr, key, &oldvalue); } + + /* Frees the entire map. + (But this call does not free the keys and values of the pairs in the map. + It only invokes the KDISPOSE_FN on each key and the VDISPOSE_FN on each value + of the pairs in the map.) */ + void free () + { gl_map_free (_ptr); _ptr = NULL; } + + // ------------------------------ Private stuff ------------------------------ + +private: + gl_map_t _ptr; + +public: + // -------------------------------- Iterators -------------------------------- + // Only a forward iterator. + // Does not implement the STL operations (++, *, and != .end()), but a simpler + // interface that needs only one virtual function call per iteration instead + // of three. + + class iterator { + public: + + /* If there is a next pair, stores the next pair in KEY and VALUE, advance + the iterator, and returns true. Otherwise, returns false. */ + bool next (KEYTYPE *& key, VALUETYPE *& value) + { return gl_map_iterator_next (&_state, reinterpret_cast(&key), reinterpret_cast(&value)); } + + ~iterator () + { gl_map_iterator_free (&_state); } + + #if defined __xlC__ || defined __HP_aCC || defined __SUNPRO_CC + public: + #else + private: + friend iterator gl_Map::begin (); + #endif + + iterator (gl_map_t ptr) + : _state (gl_map_iterator (ptr)) + {} + + private: + + gl_map_iterator_t _state; + }; + + /* Creates an iterator traversing the map. + The map's contents must not be modified while the iterator is in use, + except for modifying the value of the last returned key or removing the + last returned pair. */ + iterator begin () + { return iterator (_ptr); } +}; + +#endif /* _GL_MAP_HH */ diff --git a/modules/map-c++ b/modules/map-c++ new file mode 100644 index 0000000..e9a7058 --- /dev/null +++ b/modules/map-c++ @@ -0,0 +1,21 @@ +Description: +Abstract map data type as a C++ class. + +Files: +lib/gl_map.hh + +Depends-on: +xmap + +configure.ac: + +Makefile.am: + +Include: +"gl_map.hh" + +License: +GPL + +Maintainer: +all -- 2.7.4