Use descriptive enums for method parameters
[GenericStorageContainerTemplate.git] / GenericStorageContainerTemplateImpl.hpp
index e84b99a..e63ff21 100644 (file)
@@ -38,13 +38,19 @@ namespace tj
    * from a single iterator definition. Provides typedefs to make instantiating the
    * correct type of iterator easier to read and write in application code.
    *
+   * template parameters:
+   * T = type being stored
+   * DATA_STRUCTURE = class providing underlying storage of T elements, defaults to dynamic array
+   *
+   * For template template parameters see http://en.cppreference.com/w/cpp/language/template_parameters
    */
   template <typename T, template<typename> class DATA_STRUCTURE = DataStructure_ArrayDynamic>
   class GenericStorageContainerTemplateImpl
   {
-    // attributes
-    
-    // data structure type is templated
+    // easy to read aliases
+    typedef AbstractDataStructure<T> DS_BASE_CLASS; // for access to enums
+
+    // data structure type is templated and decided by application code at compilation time
     DATA_STRUCTURE<T> data_structure_;
 
 
@@ -75,7 +81,7 @@ namespace tj
       iterator<is_const_iterator> (DATA_STRUCTURE<T>* element) : element_(element) {};
       iterator<is_const_iterator> (const iterator<is_const_iterator>& copy) : element_(copy.element_) {}; // copy constructor
 
-      // ForwardIterator methods
+      /* ForwardIterator methods */
 
       // postfix increment operator
       self_type operator++()
@@ -92,15 +98,16 @@ namespace tj
       // prefix increment operator
       self_type operator++(int unused)
       {
+        DATA_STRUCTURE<T>* result = nullptr;
+
         if (element_) {
-          DATA_STRUCTURE<T>* temp = element_->get_next();
-          if (temp)
-            element_ = temp;
+          result = element_->get_next();
+          element_ = result;
         }
         return *this;
       };
 
-      // BidirectionalIterator methods
+      /* BidirectionalIterator methods */
 
       // postfix decrement
       self_type operator--()
@@ -119,39 +126,62 @@ namespace tj
         return *this;
       };
 
-      // Comparison methods
+
+      /* Comparison */
+
       bool operator==(const self_type& right_hand_side)
       {
         bool result = false;
 
         if (element_ && right_hand_side.element_)
-          result = *element_ == *right_hand_side.element_; 
+          result = *this->element_ == *right_hand_side.element_; 
 
         return result;
       };
 
+      // implemented using operator==()
       bool operator!=(const self_type& right_hand_side)
       {
         return !this->operator==(right_hand_side);
       };
 
-      T operator* ()
+      bool operator<(const self_type& right_hand_side)
+      {
+        bool result = false;
+
+        if (element_ && right_hand_side.element_)
+          result = *this->element_ < *right_hand_side.element_;
+
+        return result;
+      };
+
+      // implemented using operator==() and operator<()
+      bool operator<=(const self_type& right_hand_side)
       {
+        return this->operator==(right_hand_side) | this->operator<(right_hand_side);
+      };
 
+      /* 
+       * Data access */
+
+      // value-at
+      T operator* ()
+      {
         return element_ ? *element_->get_data() : 0;
       };
 
+      // pointer-to
       std::conditional<is_const_iterator, const T*, T*>  operator->()
       { 
         return &element_->get_data();
       };
 
-      // allow const and non-const iterator copy-contructors access to private members 
+      // allow const and non-const iterator copy-contructors access to private members of each other
       friend class iterator<!is_const_iterator>;
 
     }; // end of Iterator
 
-    // use these handy short-cuts in application code
+    // use these handy aliases in application code
     typedef iterator<true> _const_iterator;
     typedef iterator<false> _iterator;
 
@@ -161,8 +191,8 @@ namespace tj
      * begin() and end() are used in code that instantiates the iterator:
      *
      * GSCTI<int> container;
-     * container.insert(1);
-     * container.insert(2);
+     * container.append(1);
+     * container.append(2);
      *
      * for (_const_iterator i = container.begin(); i != container.end(); ++i) 
      * {
@@ -185,8 +215,10 @@ namespace tj
     { 
       return iterator<is_const_iterator>(data_structure_.get_end());
     };
-  
-    // object life-cycle
+
+
+    /* Object life-cycle */
+
     GenericStorageContainerTemplateImpl<T, DATA_STRUCTURE> () {};
     GenericStorageContainerTemplateImpl<T, DATA_STRUCTURE> (const GenericStorageContainerTemplateImpl<T, DATA_STRUCTURE>& copy)
     {
@@ -195,39 +227,43 @@ namespace tj
 
     ~GenericStorageContainerTemplateImpl<T, DATA_STRUCTURE>()
     {
-      delete &data_structure_;
     };
 
-    // capacity
+
+    /* Capacity */
+
+    // storage allocated (in units of stored type)
     size_t get_capacity()
     {
       return data_structure_.get_capacity();
     };
 
+    // storage used (in units of stored type)
     size_t get_size()
     {
       return data_structure_.get_size();
     };
 
-    // modifiers
+    /* Modifiers */
 
-    // append at tail
+    // append
     bool append(T& data)
     {
       return data_structure_.append(data);
     };
 
-    // remove from tail
+    // remove
     bool remove()
     {
-      return false;
+      return data_structure_.remove_at(DS_BASE_CLASS::HEAD, DS_BASE_CLASS::NO_ERASE);
     };
 
   }; // end of GenericStorageContainerTemplateImpl
 
-  // handy short-cuts for unweildy names
+  // GSCTI: handy alias for unweildy type name
   template<typename T, template<class> class DS = DataStructure_ArrayDynamic> using GSCTI = GenericStorageContainerTemplateImpl< T, DS>;
 
 }; // end of namespace
 
 #endif
+