diff options
author | Bruno Haible <bruno@clisp.org> | 2020-02-02 19:01:38 +0100 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2020-02-02 19:01:38 +0100 |
commit | adb365b99317e888cdb89dacdfcb16708a47b672 (patch) | |
tree | 9d271e8505bbf88d5548f1bbed38f0b73036934e /lib | |
parent | 770219943d9e9d76daffbc427937b792acf25737 (diff) | |
download | gnulib-adb365b99317e888cdb89dacdfcb16708a47b672.tar.gz |
set-c++: New module.
* lib/gl_set.hh: New file, based on lib/gl_set.h.
* modules/set-c++: New file.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gl_set.hh | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/lib/gl_set.hh b/lib/gl_set.hh new file mode 100644 index 0000000000..357e14175a --- /dev/null +++ b/lib/gl_set.hh @@ -0,0 +1,145 @@ +/* Abstract set data type as a C++ class. + Copyright (C) 2006-2020 Free Software Foundation, Inc. + Written by Bruno Haible <bruno@clisp.org>, 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 <https://www.gnu.org/licenses/>. */ + +#ifndef _GL_SET_HH +#define _GL_SET_HH + +#include "gl_set.h" +#include "gl_xset.h" + +/* gl_Set is a C++ wrapper around the gl_set data type. + Its element type is 'ELTYPE *'. + + 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 T> class gl_Set; + +template <class ELTYPE> +class gl_Set<ELTYPE *> +{ +public: + // ------------------------------ Constructors ------------------------------ + + gl_Set () + : _ptr (NULL) + {} + + /* Creates an empty set. + IMPLEMENTATION is one of GL_ARRAY_SET, GL_LINKEDHASH_SET, GL_HASH_SET. + EQUALS_FN is an element comparison function or NULL. + HASHCODE_FN is an element hash code function or NULL. + DISPOSE_FN is an element disposal function or NULL. */ + gl_Set (gl_set_implementation_t implementation, + bool (*equals_fn) (ELTYPE * /*elt1*/, ELTYPE * /*elt2*/), + size_t (*hashcode_fn) (ELTYPE *), + void (*dispose_fn) (ELTYPE *)) + : _ptr (gl_set_create_empty (implementation, + reinterpret_cast<gl_setelement_equals_fn>(equals_fn), + reinterpret_cast<gl_setelement_hashcode_fn>(hashcode_fn), + reinterpret_cast<gl_setelement_dispose_fn>(dispose_fn))) + {} + + /* Copy constructor. */ + gl_Set (const gl_Set& x) + { _ptr = x._ptr; } + + /* Assignment operator. */ + gl_Set& operator= (const gl_Set& x) + { _ptr = x._ptr; return *this; } + + // ------------------------------- Destructor ------------------------------- + + ~gl_Set () + { _ptr = NULL; } + + // ----------------------- Read-only member functions ----------------------- + + /* Returns the current number of elements in the set. */ + size_t size () const + { return gl_set_size (_ptr); } + + /* Searches whether an element is already in the set. + Returns true if found, or false if not present in the set. */ + bool search (ELTYPE * elt) const + { return gl_set_search (_ptr, elt); } + + // ----------------------- Modifying member functions ----------------------- + + /* Adds an element to the set. + Returns true if it was not already in the set and added, false otherwise. */ + bool add (ELTYPE * elt) + { return gl_set_add (_ptr, elt); } + + /* Removes an element from the set. + Returns true if it was found and removed. */ + bool remove (ELTYPE * elt) + { return gl_set_remove (_ptr, elt); } + + /* Frees the entire set. + (But this call does not free the elements of the set. It only invokes + the DISPOSE_FN on each of the elements of the set.) */ + void free () + { gl_set_free (_ptr); _ptr = NULL; } + + // ------------------------------ Private stuff ------------------------------ + +private: + gl_set_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 element, stores the next element in ELT, advances the + iterator and returns true. Otherwise, returns false. */ + bool next (ELTYPE *& elt) + { return gl_set_iterator_next (&_state, reinterpret_cast<const void **>(&elt)); } + + ~iterator () + { gl_set_iterator_free (&_state); } + + #if defined __xlC__ || defined __HP_aCC || defined __SUNPRO_CC + public: + #else + private: + friend iterator gl_Set::begin (); + #endif + + iterator (gl_set_t ptr) + : _state (gl_set_iterator (ptr)) + {} + + private: + + gl_set_iterator_t _state; + }; + + /* Creates an iterator traversing the set. + The set's contents must not be modified while the iterator is in use, + except for removing the last returned element. */ + iterator begin () + { return iterator (_ptr); } +}; + +#endif /* _GL_SET_HH */ |