2 * Implementation of a Generic Storage Type Container Template including STL Iterator
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 _GENERIC_STORAGE_CONTAINER_TEMPLATE_IMPL_HPP_
21 #define _GENERIC_STORAGE_CONTAINER_TEMPLATE_IMPL_HPP_
23 #include "DataStructures.hpp"
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.
35 * Default data structure is a Dynamic Array
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.
42 template <typename T, template<typename> class DATA_STRUCTURE = DataStructure_ArrayDynamic>
43 class GenericStorageContainerTemplateImpl
47 // data structure type is templated
48 DATA_STRUCTURE<T> data_structure_;
53 GenericStorageContainerTemplateImpl() {};
54 GenericStorageContainerTemplateImpl(const GenericStorageContainerTemplateImpl<T, DATA_STRUCTURE>& copy)
58 ~GenericStorageContainerTemplateImpl()
60 delete data_structure_;
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
68 * defaults to a non-const iterator
70 template <bool is_const_iterator = false>
71 class iterator : public std::iterator< std::bidirectional_iterator_tag, AbstractDataStructure<T> >
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;
80 AbstractDataStructure<T>& element_;
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
88 // ForwardIterator methods
90 // postfix increment operator
91 self_type operator++()
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
98 // prefix increment operator
99 self_type operator++(int unused)
101 element_ = element_.get_next();
105 // BidirectionalIterator methods
108 self_type operator--()
110 self_type original = *this; // keep reference to value that is to be returned
111 this->element_.get_previous();
116 self_type operator--(int unused)
118 element_ = element_.get_previous();
122 // Comparison methods
123 bool operator==(const self_type& right_hand_side)
125 return element_ == right_hand_side.element_;
128 bool operator!=(const self_type& right_hand_side)
130 return element_ != right_hand_side.element_;
135 return element_.get_data();
138 std::conditional<is_const_iterator, const T*, T*> operator->()
140 return &element_.get_data();
143 // allow const and non-const iterator copy-contructors access to private members
144 friend class iterator<!is_const_iterator>;
146 }; // end of Iterator
148 // use these handy short-cuts in application code
149 typedef iterator<true> _const_iterator;
150 typedef iterator<false> _iterator;
152 }; // end of GenericStorageContainerTemplateImpl
154 // handy short-cuts for unweildy names
155 template<typename T, template<class> class DS = DataStructure_ArrayDynamic> using GSCTI = GenericStorageContainerTemplateImpl< T, DS>;
157 }; // end of namespace