2 * Implementation of Data Structures for GenericStorageContainerTemplateImpl
3 * Copyright (c) 2014 TJ <hacker@iam.tj>
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.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 * see ./COPYRIGHT or http://www.gnu.org/licenses/gpl-3.0.html
20 #ifndef _DATASTRUCTURE_HPP_
21 #define _DATASTRUCTURE_HPP_
23 // #include <iterator>
25 #include <new> // for std::nothrow
30 /* Abstract base class for the different data structures
32 * Defines the API they must implement. The API allows the Container and its
33 * Iterator to call common methods to perform store, retrieve, and search operations
36 // mnemonic alternatives to plain 'index' values
45 class AbstractDataStructure
48 typedef AbstractDataStructure<D> self_type;
57 AbstractDataStructure(size_t capacity = 0) : data_(nullptr), capacity_(capacity), size_(0), current_(0)
60 data_ = new(std::nothrow) D[capacity_];
63 virtual ~AbstractDataStructure()
69 /* API available to application
71 * Some methods are pure virtual making this an Abstract (base) class
72 * Sub-classes must implement these methods and over-ride others to
73 * provide the specific storage class functionality
76 virtual size_t get_capacity() // available storage (in units of storage type)
81 virtual size_t get_size() // used storage (in units of storage type)
86 /* the concepts of first, last, next and previous may not have a useful meaning in
87 * some storage classes e.g: 'previous' in a 1-way linked list (only has 'next').
91 return (data_ && size_ > 0) ? &data_[current_] : nullptr;
94 virtual self_type* get_begin() = 0;
95 virtual self_type* get_end() = 0;
96 virtual self_type* get_next() = 0;
97 virtual self_type* get_previous() = 0;
100 * @param data the item (of type S) to be stored
101 * @param index position to insert; 0 is 'beginning', -1 is 'end'
103 * Depending on the data structure, values of index other than 0 or -1 may have no meaning and be ignored
105 virtual bool insert_at(D& data, long index = -1) = 0;
107 virtual bool insert(D& data)
109 return insert_at(data, TAIL);
111 virtual bool append(D& data)
113 return insert_at(data, HEAD);
116 /* the remove operation can perform an optional erasure (delete) of the stored data.
118 * returns true if the operation succeeded
121 // 'data' element at 'index' must satisfy equality
122 virtual bool remove_at(D& data, long index = -1, bool erase = false) = 0; // element matching 'data' at 'index'
123 virtual bool remove_at(long index = -1, bool erase = false) = 0; // any element at 'index'
124 virtual bool remove_all(D& data, bool erase = false) = 0; // all elements matching 'data'
126 /* the replace operation can perform an optional erasure (delete) of the current data element
128 virtual bool replace_at(D& data_in, D& data_out, long index = -1, bool erase = false) = 0; // element matching 'data_out' at 'index'
129 virtual bool replace_at(D& data_in, long index = -1, bool erase = false) = 0; // any element at 'index'
130 virtual bool replace_all(D& data_in, D& data_out, bool erase = false) = 0; // all elements matching 'data_out'
133 /* Search for an element matching 'needle'. The stored type must have defined
134 * operator<() and operator==() to allow the container to compare 'needle' with each stored element.
136 * If find() is called with last_found == nullptr it searches from the start of the container. If
137 * last_found points to an element in the container the search continues from that element. The
138 * implementation must guard against last_found not pointing to a valid object, or that object not
139 * belonging to the container.
141 * returns a nullptr if there are no (more) matches
143 virtual D* find(D& needle, D* last_found = nullptr) = 0;
145 virtual bool operator==(const D& right_hand_side)
154 /* Specialised data structure implementing a Dynamic Array
156 template <typename AD>
157 class DataStructure_ArrayDynamic : public AbstractDataStructure<AD>
159 typedef DataStructure_ArrayDynamic<AD> self_type;
164 DataStructure_ArrayDynamic<AD>(size_t capacity = 512) : AbstractDataStructure<AD>(capacity), growth_(512) {};
166 virtual self_type* get_begin()
168 self_type* result = nullptr;
170 if (this->size_ > 0) {
177 virtual self_type* get_end()
179 self_type* result = nullptr;
183 this->current_ = this->size_ - 1;
189 virtual self_type* get_next()
191 self_type* result = nullptr;
195 if (this->current_ + 1 < this->size_)
205 virtual self_type* get_previous()
207 self_type* result = nullptr;
211 if (this->current_ - 1 >= 0)
221 virtual bool insert_at(AD& data, long index = TAIL)
225 if (this->data_ != nullptr)
229 else if (index == HEAD)
232 if (this->capacity_ <= index)
235 if (this->capacity_ > index)
237 this->data_[index] = data;
239 if (index >= this->size_)
240 this->size_ = index + 1;
249 virtual bool remove_at(AD& data, long index = TAIL, bool erase = false)
256 virtual bool remove_at(long index = TAIL, bool erase = false)
263 virtual bool remove_all(AD& data, bool eraser = false)
270 virtual bool replace_at(AD& data_in, AD& data_out, long index = TAIL, bool erase = false)
277 virtual bool replace_at(AD& data_in, long index = TAIL, bool erase = false)
284 virtual bool replace_all(AD& data_in, AD& data_out, bool erase = false)
291 virtual AD* find(AD& needle, AD* last_found = nullptr)
293 AD* result = nullptr;
298 virtual bool operator==(const self_type& right_hand_side)
308 AD* temp = new (std::nothrow) AD[this->capacity_ + this->growth_];
311 for (size_t index = 0; index < this->size_; ++index)
312 temp[index] = this->data_[index];
314 delete[] this->data_;
317 this->capacity_ += this->growth_;
327 /* Specialised data structure implementing a 1-way Linked List
329 template <typename LLS>
330 class DataStructure_LinkedListSingle : protected AbstractDataStructure<LLS>
335 /* Specialised data structure implementing a 2-way Linked List
337 template <typename LLD>
338 class DataStructure_LinkedListDouble : public DataStructure_LinkedListSingle<LLD>
343 /* Specialised data structure implementing a Binary Search Tree
345 template <typename BST>
346 class DataStructure_BinarySearchTree : protected AbstractDataStructure<BST>
351 }; // end of namespace