1 /* Abstract set data type as a C++ class. 2 Copyright (C) 2006-2021 Free Software Foundation, Inc. 3 Written by Bruno Haible <bruno@clisp.org>, 2018. 4 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. 9 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. 14 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/>. */ 17 18 #ifndef _GL_SET_HH 19 #define _GL_SET_HH 20 21 #include "gl_set.h" 22 #include "gl_xset.h" 23 24 #include <stdlib.h> /* because Gnulib's <stdlib.h> may '#define free ...' */ 25 26 /* gl_Set is a C++ wrapper around the gl_set data type. 27 Its element type is 'ELTYPE *'. 28 29 It is merely a pointer, not a smart pointer. In other words: 30 it does NOT do reference-counting, and the destructor does nothing. */ 31 32 template <class T> class gl_Set; 33 34 template <class ELTYPE> 35 class gl_Set<ELTYPE *> 36 { 37 public: 38 // ------------------------------ Constructors ------------------------------ 39 40 gl_Set () 41 : _ptr (NULL) 42 {} 43 44 /* Creates an empty set. 45 IMPLEMENTATION is one of GL_ARRAY_SET, GL_LINKEDHASH_SET, GL_HASH_SET. 46 EQUALS_FN is an element comparison function or NULL. 47 HASHCODE_FN is an element hash code function or NULL. 48 DISPOSE_FN is an element disposal function or NULL. */ 49 gl_Set (gl_set_implementation_t implementation, 50 bool (*equals_fn) (ELTYPE * /*elt1*/, ELTYPE * /*elt2*/), 51 size_t (*hashcode_fn) (ELTYPE *), 52 void (*dispose_fn) (ELTYPE *)) 53 : _ptr (gl_set_create_empty (implementation, 54 reinterpret_cast<gl_setelement_equals_fn>(equals_fn), 55 reinterpret_cast<gl_setelement_hashcode_fn>(hashcode_fn), 56 reinterpret_cast<gl_setelement_dispose_fn>(dispose_fn))) 57 {} 58 59 /* Copy constructor. */ 60 gl_Set (const gl_Set& x) 61 { _ptr = x._ptr; } 62 63 /* Assignment operator. */ 64 gl_Set& operator= (const gl_Set& x) 65 { _ptr = x._ptr; return *this; } 66 67 // ------------------------------- Destructor ------------------------------- 68 69 ~gl_Set () 70 { _ptr = NULL; } 71 72 // ----------------------- Read-only member functions ----------------------- 73 74 /* Returns the current number of elements in the set. */ 75 size_t size () const 76 { return gl_set_size (_ptr); } 77 78 /* Searches whether an element is already in the set. 79 Returns true if found, or false if not present in the set. */ 80 bool search (ELTYPE * elt) const /* */ 81 { return gl_set_search (_ptr, elt); } 82 83 // ----------------------- Modifying member functions ----------------------- 84 85 /* Adds an element to the set. 86 Returns true if it was not already in the set and added, false otherwise. */ 87 bool add (ELTYPE * elt) /* */ 88 { return gl_set_add (_ptr, elt); } 89 90 /* Removes an element from the set. 91 Returns true if it was found and removed. */ 92 bool remove (ELTYPE * elt) /* */ 93 { return gl_set_remove (_ptr, elt); } 94 95 /* Frees the entire set. 96 (But this call does not free the elements of the set. It only invokes 97 the DISPOSE_FN on each of the elements of the set.) */ 98 void free () /* */ 99 { gl_set_free (_ptr); _ptr = NULL; } 100 101 // ------------------------------ Private stuff ------------------------------ 102 103 private: 104 gl_set_t _ptr; 105 106 public: 107 // -------------------------------- Iterators -------------------------------- 108 // Only a forward iterator. 109 // Does not implement the STL operations (++, *, and != .end()), but a simpler 110 // interface that needs only one virtual function call per iteration instead 111 // of three. 112 113 class iterator { 114 public: 115 116 /* If there is a next element, stores the next element in ELT, advances the 117 iterator and returns true. Otherwise, returns false. */ 118 bool next (ELTYPE *& elt) /* */ 119 { 120 const void *next_elt; 121 bool has_next = gl_set_iterator_next (&_state, &next_elt); 122 if (has_next) 123 elt = static_cast<ELTYPE *>(next_elt); 124 return has_next; 125 } 126 127 ~iterator () 128 { gl_set_iterator_free (&_state); } 129 130 #if defined __xlC__ || defined __HP_aCC || defined __SUNPRO_CC 131 public: 132 #else 133 private: 134 friend iterator gl_Set::begin (); 135 #endif 136 137 iterator (gl_set_t ptr) 138 : _state (gl_set_iterator (ptr)) 139 {} 140 141 private: 142 143 gl_set_iterator_t _state; 144 }; 145 146 /* Creates an iterator traversing the set. 147 The set's contents must not be modified while the iterator is in use, 148 except for removing the last returned element. */ 149 iterator begin () /* */ 150 { return iterator (_ptr); } 151 }; 152 153 #endif /* _GL_SET_HH */