Complete refactoring of *DataStructure*
[GenericStorageContainerTemplate.git] / GenericStorageContainerTemplateImpl.hpp
1 /*
2  * Implementation of a Generic Storage Type Container Template including STL Iterator
3  * Copyright (c) 2014 TJ <hacker@iam.tj>
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.
8  *
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.
13  *
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/>.
16  *
17  * see ./COPYRIGHT or http://www.gnu.org/licenses/gpl-3.0.html
18  */
19
20 #ifndef _GENERIC_STORAGE_CONTAINER_TEMPLATE_IMPL_HPP_
21 #define _GENERIC_STORAGE_CONTAINER_TEMPLATE_IMPL_HPP_
22
23 #include "DataStructures.hpp"
24 #include <iterator>
25 #include <memory>
26
27 namespace tj
28 {
29  
30  /* A generic Container that can use different internal data structures
31    * (Array, Linked-List, Binary Search Tree) determined by
32    * application code at compile time using the power of Templating
33    * and Metaprogramming of C++11 and later.
34    *
35    * Default data structure is a Dynamic Array
36    *
37    * Uses Metaprogramming conditionals to create constant and non-constant iterators
38    * from a single iterator definition. Provides typedefs to make instantiating the
39    * correct type of iterator easier to read and write in application code.
40    *
41    */
42   template <typename T, template<typename> class DATA_STRUCTURE = DataStructure_ArrayDynamic>
43   class GenericStorageContainerTemplateImpl
44   {
45     // attributes
46     
47     // data structure type is templated
48     DATA_STRUCTURE<T> data_structure_;
49
50
51     public:
52
53     GenericStorageContainerTemplateImpl() {};
54     GenericStorageContainerTemplateImpl(const GenericStorageContainerTemplateImpl<T, DATA_STRUCTURE>& copy)
55     {
56
57     };
58     ~GenericStorageContainerTemplateImpl()
59     {
60       delete data_structure_;
61     };
62
63     /* constant and non-constant custom Standard Template Library (STL) compatible iterators
64      * avoiding writing 2 separate class definitions that only differ on their
65      * constant vs non-constant type specifiers. This makes extensive use of
66      * template metaprogramming
67      *
68      * defaults to a non-const iterator
69      */
70     template <bool is_const_iterator = false>
71     class iterator : public std::iterator< std::bidirectional_iterator_tag, AbstractDataStructure<T> >
72     {
73       typedef iterator self_type;
74       typedef typename std::conditional< is_const_iterator, const AbstractDataStructure<T>, AbstractDataStructure<T> >::type value_type;
75       typedef typename std::conditional< is_const_iterator, const AbstractDataStructure<T>&, AbstractDataStructure<T>& >::type reference;
76       typedef typename std::conditional< is_const_iterator, const AbstractDataStructure<T>*, AbstractDataStructure<T>* >::type pointer;
77       typedef std::bidirectional_iterator_tag iterator_category;
78       typedef int difference_type;
79
80       AbstractDataStructure<T>& element_;
81
82       public:
83
84       iterator<is_const_iterator> () {};
85       iterator<is_const_iterator> (AbstractDataStructure<T>& element) : element_(element) {};
86       iterator<is_const_iterator> (const iterator<is_const_iterator>& copy) : element_(copy.element_) {}; // copy constructor
87
88       // ForwardIterator methods
89
90       // postfix increment operator
91       self_type operator++()
92       {
93         self_type original = *this; // need to keep a copy of the current value so it can be returned
94         this->element_ = this->element_.get_next(); // after the increment changes the item being referenced
95         return original;
96       }
97
98       // prefix increment operator
99       self_type operator++(int unused)
100       {
101         element_ = element_.get_next();
102         return *this;
103       }
104
105       // BidirectionalIterator methods
106
107       // postfix decrement
108       self_type operator--()
109       {
110         self_type original = *this; // keep reference to value that is to be returned
111         this->element_.get_previous();
112         return original;
113       };
114
115       // prefix decrement
116       self_type operator--(int unused)
117       {
118         element_ = element_.get_previous();
119         return *this;
120       };
121
122       // Comparison methods
123       bool operator==(const self_type& right_hand_side)
124       {
125         return element_ == right_hand_side.element_; 
126       }
127
128       bool operator!=(const self_type& right_hand_side)
129       {
130         return element_ != right_hand_side.element_;
131       }
132
133       T operator* ()
134       {
135         return element_.get_data();
136       }
137
138       std::conditional<is_const_iterator, const T*, T*>  operator->()
139       { 
140         return &element_.get_data();
141       }
142
143       // allow const and non-const iterator copy-contructors access to private members 
144       friend class iterator<!is_const_iterator>;
145
146     }; // end of Iterator
147
148   // use these handy short-cuts in application code
149   typedef iterator<true> _const_iterator;
150   typedef iterator<false> _iterator;
151
152   }; // end of GenericStorageContainerTemplateImpl
153
154   // handy short-cuts for unweildy names
155   template<typename T, template<class> class DS = DataStructure_ArrayDynamic> using GSCTI = GenericStorageContainerTemplateImpl< T, DS>;
156
157 }; // end of namespace
158
159 #endif