lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
00001 /*****************************************************/ 00002 /* lean Containers (c) Tobias Zirr 2011 */ 00003 /*****************************************************/ 00004 00005 #ifndef LEAN_CONTAINERS_ACCUMULATION_MAP 00006 #define LEAN_CONTAINERS_ACCUMULATION_MAP 00007 00008 #include "../lean.h" 00009 #include <utility> 00010 00011 namespace lean 00012 { 00013 namespace containers 00014 { 00015 00017 00021 template <class Container> 00022 class accumulation_map 00023 { 00024 public: 00026 typedef Container container_type; 00028 typedef typename container_type::allocator_type allocator_type; 00030 typedef typename container_type::size_type size_type; 00032 typedef typename container_type::difference_type difference_type; 00033 00035 typedef typename container_type::pointer pointer; 00037 typedef typename container_type::const_pointer const_pointer; 00039 typedef typename container_type::reference reference; 00041 typedef typename container_type::const_reference const_reference; 00043 typedef typename container_type::value_type value_type; 00044 00046 typedef typename container_type::iterator iterator; 00048 typedef typename container_type::const_iterator const_iterator; 00049 00051 typedef typename container_type::reverse_iterator reverse_iterator; 00053 typedef typename container_type::const_reverse_iterator const_reverse_iterator; 00054 00056 typedef typename container_type::key_compare key_compare; 00058 typedef typename container_type::key_type key_type; 00060 typedef typename container_type::mapped_type mapped_type; 00062 typedef typename container_type::value_compare value_compare; 00063 00064 private: 00065 // Container 00066 container_type m_container; 00067 00068 // Invalid marker 00069 mapped_type m_invalidValue; 00070 00072 LEAN_INLINE void invalidate(mapped_type &value) const 00073 { 00074 // Const method modifier makes m_invalidValue const 00075 value = m_invalidValue; 00076 } 00077 00078 public: 00080 accumulation_map() { } 00082 explicit accumulation_map(const key_compare& predicate) 00083 : m_container(predicate) { } 00085 accumulation_map(const key_compare& predicate, const allocator_type& allocator) 00086 : m_container(predicate, allocator) { } 00088 accumulation_map(const accumulation_map& right) 00089 : m_container(right.m_container) { } 00090 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00091 00092 accumulation_map(accumulation_map&& right) 00093 : m_container(std::move(right.m_container)) { } 00094 #endif 00095 00096 template<class Iterator> 00097 accumulation_map(Iterator itFirst, Iterator itEnd) 00098 : m_container(itFirst, itEnd) { } 00100 template<class Iterator> 00101 accumulation_map(Iterator itFirst, Iterator itEnd, const key_compare& predicate) 00102 : m_container(itFirst, itEnd, predicate) { } 00104 template<class Iterator> 00105 accumulation_map(Iterator itFirst, Iterator itEnd, const key_compare& predicate, const allocator_type& allocator) 00106 : m_container(itFirst, itEnd, predicate, allocator) { } 00107 00109 accumulation_map& operator =(const accumulation_map &right) 00110 { 00111 if (this != &right) 00112 { 00113 m_invalidValue = right.m_invalidValue; 00114 00115 key_compare keyComp = m_container.key_comp(); 00116 00117 iterator itDest = m_container.begin(); 00118 const_iterator itSource = right.begin(); 00119 00120 while (itSource != right.end() && itDest != m_container.end()) 00121 { 00122 // Replace old value with new one on exact match 00123 if (itSource->first == itDest->first) 00124 (itDest++)->second = (itSource++)->second; 00125 // Wait for next source element, if still less than dest 00126 else if (keyComp(itSource->first, itDest->first)) 00127 m_container.insert(itDest, *(itSource++)); 00128 // Source element already greater than dest, invalidate dest 00129 else 00130 invalidate((itDest++)->second); 00131 } 00132 00133 // Invalidate remaining old elements 00134 while (itDest != m_container.end()) 00135 invalidate((itDest++)->second); 00136 00137 // Append remaining source elements 00138 while (itSource != right.end()) 00139 m_container.insert(m_container.end(), *(itSource++)); 00140 } 00141 return *this; 00142 } 00143 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00144 00145 inline accumulation_map& operator =(accumulation_map &&right) 00146 { 00147 m_container = std::move(right.m_container); 00148 return *this; 00149 } 00150 #endif 00151 00153 LEAN_INLINE void inv_elem(const mapped_type &invalid) { m_invalidValue = invalid; } 00155 LEAN_INLINE mapped_type inv_elem(void) { return m_invalidValue; } 00156 00158 LEAN_INLINE size_type size(void) const { return m_container.size(); }; 00160 LEAN_INLINE bool empty(void) const { return m_container.empty(); }; 00161 00163 LEAN_INLINE std::pair<iterator, bool> insert(const value_type &element) { return m_container.insert(element); } 00165 LEAN_INLINE iterator insert(iterator itWhere, const value_type &element) { return m_container.insert(itWhere, element); } 00166 #ifndef LEAN0X_NO_RVALUE_REFERENCES 00167 00168 LEAN_INLINE std::pair<iterator, bool> insert(value_type &&element) { return m_container.insert(std::move(element)); } 00170 LEAN_INLINE iterator insert(iterator itWhere, value_type &&element) { return m_container.insert(itWhere, std::move(element)); } 00171 #endif 00172 00173 template<class Iterator> 00174 LEAN_INLINE void insert(Iterator itFirst, Iterator itEnd) { m_container.insert(itFirst, itEnd); } 00175 00177 LEAN_INLINE size_type erase(const key_type &key) 00178 { 00179 iterator itElem = m_container.find(key); 00180 00181 if (itElem != m_container.end()) 00182 { 00183 invalidate(itElem->second); 00184 return 1; 00185 } 00186 else 00187 return 0; 00188 } 00190 LEAN_INLINE iterator erase(iterator itWhere) 00191 { 00192 invalidate(itWhere->second); 00193 return itWhere; 00194 } 00196 LEAN_INLINE void erase(iterator itFirst, iterator itEnd) 00197 { 00198 while (itFirst != itEnd) 00199 invalidate((itFirst++)->second); 00200 } 00201 00203 LEAN_INLINE size_type erase_fully(const key_type &key) { return m_container.erase(key); } 00205 LEAN_INLINE iterator erase_fully(iterator itWhere) { return m_container.erase(itWhere); } 00207 LEAN_INLINE void erase_fully(iterator itFirst, iterator itEnd) { m_container.erase(itFirst, itEnd); } 00208 00210 LEAN_INLINE void clear(void) 00211 { 00212 // Invalidate all elements 00213 for (iterator itElem = begin(); itElem != end(); ++itElem) 00214 invalidate(itElem->second); 00215 } 00217 LEAN_INLINE void reset(void) { m_container.clear(); } 00218 00220 LEAN_INLINE key_compare key_comp(void) const { return m_container.key_comp(); } 00222 LEAN_INLINE value_compare value_comp(void) const { return m_container.value_comp(); } 00223 00225 LEAN_INLINE allocator_type get_allocator() const { return m_container.get_allocator(); } 00227 LEAN_INLINE size_type max_size(void) const { return m_container.max_size(); } 00228 00230 LEAN_INLINE iterator lower_bound(const key_type &key) { return m_container.lower_bound(key); } 00232 LEAN_INLINE const_iterator lower_bound(const key_type &key) const { return m_container.lower_bound(key); } 00234 LEAN_INLINE iterator upper_bound(const key_type &key) { return m_container.upper_bound(key); } 00236 LEAN_INLINE const_iterator upper_bound(const key_type &key) const { return m_container.upper_bound(key); } 00238 LEAN_INLINE std::pair<iterator, iterator> equal_range(const key_type &key) { return m_container.equal_range(key); } 00240 LEAN_INLINE std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const { return m_container.equal_range(key); } 00241 00243 LEAN_INLINE iterator find(const key_type &key) { return m_container.find(key); } 00245 LEAN_INLINE const_iterator find(const key_type &key) const { return m_container.find(key); } 00247 LEAN_INLINE size_type count(const key_type &key) const { return m_container.count(key); } 00248 00250 LEAN_INLINE mapped_type& operator [](const key_type &key) { return m_container[key]; } 00251 00253 LEAN_INLINE iterator begin(void) { return m_container.begin(); } 00255 LEAN_INLINE const_iterator begin(void) const { return m_container.begin(); } 00257 LEAN_INLINE iterator end(void) { return m_container.end(); } 00259 LEAN_INLINE const_iterator end(void) const { return m_container.end(); } 00260 00262 LEAN_INLINE reverse_iterator rbegin(void) { return m_container.rbegin(); } 00264 LEAN_INLINE const_reverse_iterator rbegin(void) const { return m_container.rbegin(); } 00266 LEAN_INLINE reverse_iterator rend(void) { return m_container.rend(); } 00268 LEAN_INLINE const_reverse_iterator rend(void) const { return m_container.rend(); } 00269 00270 // Swaps the elements of two accumulation maps. 00271 LEAN_INLINE void swap(accumulation_map& right) 00272 { 00273 using std::swap; 00274 00275 swap(m_container, right.m_container); 00276 } 00277 }; 00278 00279 // Swaps the elements of two accumulation maps. 00280 template<class Container> 00281 LEAN_INLINE void swap(accumulation_map<Container>& left, accumulation_map<Container>& right) 00282 { 00283 left.swap(right); 00284 } 00285 00286 } // namespace 00287 00288 using containers::accumulation_map; 00289 00290 } // namespace 00291 00292 #endif