namespace tj
{
- /* possible options for the storage class the application may request
- */
- enum Storage
- {
- unknown,
- static_array,
- dynamic_array,
- linked_list_single,
- linked_list_double,
- bst,
- bst_reversible,
- LENGTH // allows application to determine how many storage classes are available
- };
-
- /* A generic Container that can use different internal storage
+ /* A generic Container that can use different internal storage
* representations (Array, Linked-List, Binary Search Tree) based on an
* enum passed by application code at compile time using the power of Templating
* and Metaprogramming of C++11 and later.
* correct type of iterator easier to read and write in application code.
*
*/
- template <typename T, class STORAGE_CLASS>
+ template <typename T, template<typename> class STORAGE_CLASS = StorageClass_DynamicArray>
class GenericStorageContainerTemplateImpl
{
/* XXX: Have to use different template typename value (T, S, etc.) although the types are
* ^
*/
- /* Abstract base class for the different storage classes
- *
- * Defines the API they must implement. The API allows the Container and its
- * Iterator to call common methods to perform store, retrieve, and search operations
- */
-
- public:
- template <typename S>
- class StorageClass
- {
- S& __data;
-
- public:
- StorageClass() {};
- StorageClass(S& data) : __data(data) {};
- virtual ~StorageClass() {};
-
- /* API available to application
- *
- * Some methods are pure virtual making this an Abstract (base) class
- * Sub-classes must implement these methods and over-ride others to
- * provide the specific storage class functionality
- */
- S& get_data()
- {
- return __data;
- };
-
- virtual S& get_first() = 0;
- virtual S& get_previous() = 0;
- virtual S& get_next() = 0;
- virtual S& get_last() = 0;
-
- /*
- * @param data the item (of type S) to be stored
- * @param index position to insert; 0 is 'beginning', -1 is 'end'
- *
- * Depending on the concrete implemenation of this method, values of index other
- * than 0 or -1 may have no meaning and be ignored
- */
- virtual bool insert_at(S& data, long index = -1) = 0;
- virtual bool insert(S& data)
- {
- return insert_at(data, 0);
- };
- virtual bool append(S& data)
- {
- return insert_at(data, -1);
- };
-
- virtual bool remove_at(S& data, long index = -1) = 0;
- virtual bool remove() = 0;
- virtual bool remove(S& data) = 0;
- virtual bool erase(S& data) = 0;
- };
-
-
- /* Specialised storage class implementing a Dynamic Array
- */
- template <typename SAD>
- class StorageClass_DynamicArray : StorageClass<SAD>
- {
- // TODO: implement
- };
-
- /* Specialised storage class implementing a 2-way Linked List
- */
- template <typename SLLD>
- class StorageClass_LinkedListDouble : StorageClass<SLLD>
- {
- // TODO: implement
- };
-
- /* Specialised storage class implementing a Binary Search Tree
- */
- template <typename SBST>
- class StorageClass_BinarySearchTree : StorageClass<SBST>
- {
- // TODO: implement
- };
-
-
// attributes
- /* storage class type is decided when collection is compiled
- * so use the (abstract) base class to keep the Collection's private
- * reference to the internal storage class
- */
- STORAGE_CLASS __storage;
-
+ // storage class type is templated
+ STORAGE_CLASS<T> storage_;
+
public:
- GenericStorageContainerTemplateImpl() : __storage(nullptr) {};
- GenericStorageContainerTemplateImpl(T& data)
+ GenericStorageContainerTemplateImpl() {};
+ GenericStorageContainerTemplateImpl(const GenericStorageContainerTemplateImpl<T, STORAGE_CLASS>& copy)
{
- __storage = new STORAGE_CLASS(data);
+ };
+ ~GenericStorageContainerTemplateImpl()
+ {
+ delete storage_;
};
/* constant and non-constant custom Standard Template Library (STL) iterators
}; // end of GenericStorageContainerTemplateImpl
// handy short-cuts for unweildy names
- template<typename T, class SC> using GSCTI = GenericStorageContainerTemplateImpl< T, SC>;
- template<typename T> using SC_DA = tj::GenericStorageContainerTemplateImpl::StorageClass_DynamicArray<T>;
+ template<typename T, template<class> class SC = StorageClass_DynamicArray> using GSCTI = GenericStorageContainerTemplateImpl< T, SC>;
}; // end of namespace
--- /dev/null
+/*
+ * Implementation of Storage Classes for GenericStorageContainerTemplateImpl
+ * Copyright (c) 2014 TJ <hacker@iam.tj>
+ *
+ * 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.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * see ./COPYRIGHT or http://www.gnu.org/licenses/gpl-3.0.html
+ */
+
+#ifndef _STORAGE_CLASS_HPP_
+#define _STORAGE_CLASS_HPP_
+
+#include <iterator>
+#include <memory>
+
+namespace tj
+{
+
+ /* Abstract base class for the different storage classes
+ *
+ * Defines the API they must implement. The API allows the Container and its
+ * Iterator to call common methods to perform store, retrieve, and search operations
+ */
+
+ template <typename S>
+ class StorageClass
+ {
+ size_t capacity_;
+ size_t size_;
+
+ public:
+ StorageClass() {};
+ virtual ~StorageClass() {};
+
+ /* API available to application
+ *
+ * Some methods are pure virtual making this an Abstract (base) class
+ * Sub-classes must implement these methods and over-ride others to
+ * provide the specific storage class functionality
+ */
+ virtual size_t get_capacity() // available storage (in units of storage type)
+ {
+ return capacity_;
+ };
+
+ virtual size_t get_size() // used storage (in units of storage type)
+ {
+ return size_;
+ };
+
+ /* the concepts of first, last, next and previous may not have a useful meaning in
+ * some storage classes e.g: 'previous' in a 1-way linked list (only has 'next').
+ */
+ virtual S& get_first() = 0;
+ virtual S& get_last() = 0;
+ virtual S& get_next() = 0;
+ virtual S& get_previous() = 0;
+
+ /*
+ * @param data the item (of type S) to be stored
+ * @param index position to insert; 0 is 'beginning', -1 is 'end'
+ *
+ * Depending on the storage class, values of index other than 0 or -1 may have no meaning and be ignored
+ */
+ virtual bool insert_at(S& data, long index = -1) = 0;
+
+ virtual bool insert(S& data)
+ {
+ return insert_at(data, 0);
+ };
+ virtual bool append(S& data)
+ {
+ return insert_at(data, -1);
+ };
+
+ /* the remove operation can perform an optional erasure (delete) of the stored data.
+ *
+ * returns true if the operation succeeded
+ */
+
+ // 'data' element at 'index' must satisfy equality
+ virtual bool remove_at(S& data, long index = -1, bool erase = false) = 0; // element matching 'data' at 'index'
+ virtual bool remove_at(long index = -1, bool erase = false) = 0; // any element at 'index'
+ virtual bool remove_all(S& data, bool erase = false) = 0; // all elements matching 'data'
+
+ /* the replace operation can perform an optional erasure (delete) of the current data element
+ */
+ virtual bool replace_at(S& data_in, S& data_out, long index = -1, bool erase = false) = 0; // element matching 'data_out' at 'index'
+ virtual bool replace_at(S& data_in, long index = -1, bool erase = false) = 0; // any element at 'index'
+ virtual bool replace_all(S& data_in, S& data_out, bool erase = false) = 0; // all elements matching 'data_out'
+
+
+ /* Search for an element matching 'needle'. The stored type must have defined
+ * operator<() and operator==() to allow the container to compare 'needle' with each stored element.
+ *
+ * If find() is called with last_found == nullptr it searches from the start of the container. If
+ * last_found points to an element in the container the search continues from that element. The
+ * implementation must guard against last_found not pointing to a valid object, or that object not
+ * belonging to the container.
+ *
+ * returns a nullptr if there are no (more) matches
+ */
+ virtual S* find(S& needle, S* last_found = nullptr) = 0;
+
+ // mnemonic alternatives to plain 'index' values
+ enum position {
+ BEGIN = 0,
+ END = -1
+ };
+ };
+
+
+ /* Specialised storage class implementing a Dynamic Array
+ */
+ template <typename SAD>
+ class StorageClass_DynamicArray : StorageClass<SAD>
+ {
+ // TODO: implement
+ };
+
+ /* Specialised storage class implementing a 2-way Linked List
+ */
+ template <typename SLLD>
+ class StorageClass_LinkedListDouble : StorageClass<SLLD>
+ {
+ // TODO: implement
+ };
+
+ /* Specialised storage class implementing a Binary Search Tree
+ */
+ template <typename SBST>
+ class StorageClass_BinarySearchTree : StorageClass<SBST>
+ {
+ // TODO: implement
+ };
+
+}; // end of namespace
+
+#endif
+