refactor: move StorageClass to separate translation unit
authorTJ <hacker@iam.tj>
Mon, 13 Apr 2015 12:26:47 +0000 (13:26 +0100)
committerTJ <hacker@iam.tj>
Mon, 13 Apr 2015 12:26:47 +0000 (13:26 +0100)
GenericStorageContainerTemplateImpl.hpp
GenericStorageContainerTest.cpp
StorageClass.hpp [new file with mode: 0644]

index 6bc98dd..2ed07e1 100644 (file)
 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.
@@ -50,7 +36,7 @@ namespace tj
    * 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
@@ -66,104 +52,22 @@ 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
-     */
-
-    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
@@ -273,8 +177,7 @@ namespace tj
   }; // 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
 
index 86d2667..45c9822 100644 (file)
@@ -12,7 +12,7 @@ main (int argc, char **argv, char **env)
        << "Licensed on terms of the GNU General Public License version 3.0" << endl;
 
   int* test = new int(320596); // initial test value
-  GSCTI<int, SC_DA<int>> my_collection_of_ints(*test);
+  GSCTI<int, StorageClass_DynamicArray> my_collection_of_ints(*test);
 
   unsigned menu_choice;
 
diff --git a/StorageClass.hpp b/StorageClass.hpp
new file mode 100644 (file)
index 0000000..b2f8c15
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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
+