remove \r
[extl.git] / extl / container / symmetrical_sparse_matrix.h
blob85b12655678d1de99e143985c489ba3cfdabf54f
1 /* ///////////////////////////////////////////////////////////////////////
2 * File: symmetrical_sparse_matrix.h
4 * Created: 08.12.05
5 * Updated: 08.12.05
7 * Brief: symmetrical_sparse_matrix class - compact matrix
9 * [<Home>]
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
13 #ifndef EXTL_CONTAINER_SYMMETRICAL_SPARSE_MATRIX_H
14 #define EXTL_CONTAINER_SYMMETRICAL_SPARSE_MATRIX_H
16 /*!\file symmetrical_sparse_matrix.h
17 * \brief symmetrical_sparse_matrix class
20 /* ///////////////////////////////////////////////////////////////////////
21 * Includes
23 #include "prefix.h"
24 #include "sparse_matrix_base.h"
25 #include "detail/symmetrical_sparse_matrix_rowcole_iterator.h"
26 /* ///////////////////////////////////////////////////////////////////////
27 * ::extl namespace
29 EXTL_BEGIN_NAMESPACE
32 /*!\brief: symmetrical_sparse_matrix class - compact matrix
34 * <pre>
35 * using upper triangular matrix
36 * size = n * (n + 1) / 2
38 * 0 0 0 0 0 0
39 * 0 0 0 0 0
40 * 0 0 0 0
41 * 0 0 0
42 * 0 0
43 * 0
45 * </pre>
47 * \param Val The element type
49 * \ingroup extl_group_container
51 template<typename_param_k Val>
52 class symmetrical_sparse_matrix
53 : public sparse_matrix_base < symmetrical_sparse_matrix<Val>
54 , Val
57 private:
58 typedef sparse_matrix_base < symmetrical_sparse_matrix<Val>
59 , Val
60 > base_type;
62 /// \name Types
63 /// @{
64 public:
65 typedef symmetrical_sparse_matrix class_type;
66 typedef typename_type_k base_type::allocator_type allocator_type;
67 typedef typename_type_k base_type::value_type value_type;
68 typedef typename_type_k base_type::pointer pointer;
69 typedef typename_type_k base_type::const_pointer const_pointer;
70 typedef typename_type_k base_type::reference reference;
71 typedef typename_type_k base_type::const_reference const_reference;
72 typedef typename_type_k base_type::iterator iterator;
73 typedef typename_type_k base_type::const_iterator const_iterator;
74 typedef typename_type_k base_type::reverse_iterator reverse_iterator;
75 typedef typename_type_k base_type::const_reverse_iterator const_reverse_iterator;
76 typedef typename_type_k base_type::size_type size_type;
77 typedef typename_type_k base_type::bool_type bool_type;
78 typedef typename_type_k base_type::difference_type difference_type;
79 typedef typename_type_k base_type::int_type int_type;
80 typedef typename_type_k base_type::index_type index_type;
81 class const_reduced_dimension_type
83 private:
84 class_type const* m_this;
85 index_type m_i;
86 size_type m_dim;
88 public:
89 const_reduced_dimension_type(class_type const* p, index_type i)
90 : m_this(p)
91 , m_i(i)
93 public:
94 const_reference operator[](index_type j) const
96 return at_unchecked(j);
98 const_reference at(index_type j) const
100 return m_this->at(m_i, j);
102 const_reference at_unchecked(index_type j) const
104 return m_this->at_unchecked(m_i, j);
107 class reduced_dimension_type
109 private:
110 class_type const* m_this;
111 index_type m_i;
112 size_type m_dim;
114 public:
115 reduced_dimension_type(class_type const* p, index_type i)
116 : m_this(p)
117 , m_i(i)
119 public:
120 reference operator[](index_type j)
122 return at_unchecked(j);
124 reference at(index_type j)
126 return const_cast<reference>(m_this->at(m_i, j));
128 reference at_unchecked(index_type j)
130 return const_cast<reference>(m_this->at_unchecked(m_i, j));
133 /// @}
135 /// \name Protected Types
136 /// @{
137 protected:
138 typedef typename_type_k base_type::rheads_type rheads_type;
139 typedef typename_type_k base_type::cheads_type cheads_type;
140 typedef typename_type_k base_type::node_type node_type;
141 /// @}
143 /// \name Iterator Types
144 /// @{
145 public:
146 // row element iterator
147 typedef EXTL_NS_DETAIL(symmetrical_sparse_matrix_rowcole_iterator)<value_type, node_type> rowe_iterator;
148 typedef EXTL_NS_DETAIL(const_symmetrical_sparse_matrix_rowcole_iterator)<value_type, node_type> const_rowe_iterator;
149 typedef reverse_bidirectional_iterator_base<const_rowe_iterator> rowe_reverse_iterator;
150 typedef const_reverse_bidirectional_iterator_base<const_rowe_iterator> const_rowe_reverse_iterator;
153 // column element iterator
154 typedef EXTL_NS_DETAIL(symmetrical_sparse_matrix_rowcole_iterator)<value_type, node_type> cole_iterator;
155 typedef EXTL_NS_DETAIL(const_symmetrical_sparse_matrix_rowcole_iterator)<value_type, node_type> const_cole_iterator;
156 typedef reverse_bidirectional_iterator_base<const_cole_iterator> cole_reverse_iterator;
157 typedef const_reverse_bidirectional_iterator_base<const_cole_iterator> const_cole_reverse_iterator;
158 /// @}
161 /// \name Constructors
162 /// @{
163 public:
164 symmetrical_sparse_matrix()
165 : base_type()
168 symmetrical_sparse_matrix(class_type const& rhs)
169 : base_type(rhs)
172 explicit_k symmetrical_sparse_matrix(index_type d0, index_type /*d1*/ = 0)
173 : base_type(d0, d0)
176 /// @}
178 /// \name Attributes
179 /// @{
180 public:
181 size_type dim() const { return this->dim1(); }
182 bool_type exists(index_type i0, index_type i1) const;
183 /// @}
185 /// \name Row Element Iterators
186 /// @{
187 public:
188 const_rowe_iterator rowe_begin(index_type i0) const { return const_rowe_iterator(this->cheads()[i0].bottom(), &(this->rheads()[i0]), &(this->cheads()[i0])); }
189 rowe_iterator rowe_begin(index_type i0) { return rowe_iterator(this->cheads()[i0].bottom(), &(this->rheads()[i0]), &(this->cheads()[i0])); }
191 const_rowe_iterator rowe_end(index_type i0) const { return const_rowe_iterator(&(this->rheads()[i0]), &(this->rheads()[i0]), &(this->cheads()[i0])); }
192 rowe_iterator rowe_end(index_type i0) { return rowe_iterator(&(this->rheads()[i0]), &(this->rheads()[i0]), &(this->cheads()[i0])); }
194 const_rowe_reverse_iterator rowe_rbegin(index_type i0) const { return const_rowe_reverse_iterator(rowe_end(i0)); }
195 rowe_reverse_iterator rowe_rbegin(index_type i0) { return rowe_reverse_iterator(rowe_end(i0)); }
197 const_rowe_reverse_iterator rowe_rend(index_type i0) const { return const_rowe_reverse_iterator(rowe_begin(i0)); }
198 rowe_reverse_iterator rowe_rend(index_type i0) { return rowe_reverse_iterator(rowe_begin(i0)); }
199 /// @}
201 /// \name Column Element Iterators
202 /// @{
203 public:
204 const_cole_iterator cole_begin(index_type i1) const { return const_cole_iterator(this->cheads()[i1].bottom(), &(this->rheads()[i1]), &(this->cheads()[i1])); }
205 cole_iterator cole_begin(index_type i1) { return cole_iterator(this->cheads()[i1].bottom(), &(this->rheads()[i1]), &(this->cheads()[i1])); }
207 const_cole_iterator cole_end(index_type i1) const { return const_cole_iterator(&(this->rheads()[i1]), &(this->rheads()[i1]), &(this->cheads()[i1])); }
208 cole_iterator cole_end(index_type i1) { return cole_iterator(&(this->rheads()[i1]), &(this->rheads()[i1]), &(this->cheads()[i1])); }
210 const_cole_reverse_iterator cole_rbegin(index_type i1) const { return const_cole_reverse_iterator(cole_end(i1)); }
211 cole_reverse_iterator cole_rbegin(index_type i1) { return cole_reverse_iterator(cole_end(i1)); }
213 const_cole_reverse_iterator cole_rend(index_type i1) const { return const_cole_reverse_iterator(cole_begin(i1)); }
214 cole_reverse_iterator cole_rend(index_type i1) { return cole_reverse_iterator(cole_begin(i1)); }
215 /// @}
217 /// \name Accessors
218 /// @{
219 public:
220 reduced_dimension_type at(index_type i0);
221 const_reduced_dimension_type at(index_type i0) const;
223 reduced_dimension_type at_unchecked(index_type i0);
224 const_reduced_dimension_type at_unchecked(index_type i0) const;
226 reduced_dimension_type operator[](index_type i0) { return at_unchecked(i0); }
227 const_reduced_dimension_type operator[](index_type i0) const { return at_unchecked(i0); }
229 reference at(index_type i0, index_type i1);
230 const_reference at(index_type i0, index_type i1) const;
232 reference at_unchecked(index_type i0, index_type i1);
233 const_reference at_unchecked(index_type i0, index_type i1) const;
235 bool_type get_if_exists(index_type i0, index_type i1, reference ret) const;
236 bool_type set_if_exists(index_type i0, index_type i1, const_reference val);
237 /// @}
239 /// \name Mutators
240 /// @{
241 public:
242 const_reference insert(index_type i0, index_type i1, const_reference value, bool_type* has_existed = NULL);
243 void erase(index_type i0, index_type i1, bool_type* has_existed = NULL);
244 /// @}
246 /// \name Operators
247 /// @{
248 public:
249 class_type& operator=(class_type const& rhs) { return base_type::operator=(rhs); }
250 /// @}
255 /* /////////////////////////////////////////////////////////////////////////
256 * Implemention
258 // at_unchecked(i0, i1)
259 template<typename_param_k Val>
260 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
261 const_reference symmetrical_sparse_matrix<Val>::at_unchecked(index_type i0, index_type i1) const
263 EXTL_MESSAGE_ASSERT(i0 < dim() && i1 < dim(), "out of range");
264 return i0 < i1? static_cast<base_type const&>(*this).at_unchecked(i0, i1)
265 : static_cast<base_type const&>(*this).at_unchecked(i1, i0);
267 template<typename_param_k Val>
268 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
269 reference symmetrical_sparse_matrix<Val>::at_unchecked(index_type i0, index_type i1)
271 return const_cast<reference>(static_cast<class_type const&>(*this).at_unchecked(i0, i1));
274 // at(i0, i1)
275 template<typename_param_k Val>
276 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
277 reference symmetrical_sparse_matrix<Val>::at(index_type i0, index_type i1)
279 return const_cast<reference>(static_cast<class_type const&>(*this).at(i0, i1));
281 template<typename_param_k Val>
282 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
283 const_reference symmetrical_sparse_matrix<Val>::at(index_type i0, index_type i1) const
285 EXTL_ASSERT_THROW(i0 < dim() && i1 < dim(), index_error("out of range"));
286 return at_unchecked(i0, i1);
289 // at_unchecked(i0)
290 template<typename_param_k Val>
291 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
292 reduced_dimension_type symmetrical_sparse_matrix<Val>::at_unchecked(index_type i0)
294 EXTL_MESSAGE_ASSERT(i0 < dim(), "out of range");
295 return reduced_dimension_type(this, i0);
297 template<typename_param_k Val>
298 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
299 const_reduced_dimension_type symmetrical_sparse_matrix<Val>::at_unchecked(index_type i0) const
301 EXTL_MESSAGE_ASSERT(i0 < dim(), "out of range");
302 return const_reduced_dimension_type(this, i0);
305 // at(i0)
306 template<typename_param_k Val>
307 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
308 reduced_dimension_type symmetrical_sparse_matrix<Val>::at(index_type i0)
310 EXTL_ASSERT_THROW(i0 < dim(), index_error("out of range"));
311 return at_unchecked(i0);
313 template<typename_param_k Val>
314 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
315 const_reduced_dimension_type symmetrical_sparse_matrix<Val>::at(index_type i0) const
317 EXTL_ASSERT_THROW(i0 < dim(), index_error("out of range"));
318 return at_unchecked(i0);
320 template<typename_param_k Val>
321 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
322 const_reference symmetrical_sparse_matrix<Val>::insert(index_type i0, index_type i1, const_reference value, bool_type* has_existed)
324 return i0 < i1? static_cast<base_type&>(*this).insert(i0, i1, value, has_existed)
325 : static_cast<base_type&>(*this).insert(i1, i0, value, has_existed);
327 template<typename_param_k Val>
328 void symmetrical_sparse_matrix<Val>::erase(index_type i0, index_type i1, bool_type* has_existed)
330 if (i0 < i1)
331 static_cast<base_type&>(*this).erase(i0, i1, has_existed);
332 else static_cast<base_type&>(*this).erase(i1, i0, has_existed);
334 template<typename_param_k Val>
335 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
336 bool_type symmetrical_sparse_matrix<Val>::exists(index_type i0, index_type i1) const
338 return i0 < i1? static_cast<base_type const&>(*this).exists(i0, i1)
339 : static_cast<base_type const&>(*this).exists(i1, i0);
342 template<typename_param_k Val>
343 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
344 bool_type symmetrical_sparse_matrix<Val>::get_if_exists(index_type i0, index_type i1, reference ret) const
346 return i0 < i1? static_cast<base_type const&>(*this).get_if_exists(i0, i1, ret)
347 : static_cast<base_type const&>(*this).get_if_exists(i1, i0, ret);
349 template<typename_param_k Val>
350 inline typename_type_ret_k symmetrical_sparse_matrix<Val>::
351 bool_type symmetrical_sparse_matrix<Val>::set_if_exists(index_type i0, index_type i1, const_reference val)
353 return i0 < i1? static_cast<base_type&>(*this).set_if_exists(i0, i1, val)
354 : static_cast<base_type&>(*this).set_if_exists(i1, i0, val);
358 /* ///////////////////////////////////////////////////////////////////////
359 * ::extl namespace
361 EXTL_END_NAMESPACE
363 /* //////////////////////////////////////////////////////////////////// */
364 #endif /* EXTL_CONTAINER_SYMMETRICAL_SPARSE_MATRIX_H */
365 /* //////////////////////////////////////////////////////////////////// */