1
/*************************************************************************
3
* Copyright (c) 2010 Kohei Yoshida
5
* Permission is hereby granted, free of charge, to any person
6
* obtaining a copy of this software and associated documentation
7
* files (the "Software"), to deal in the Software without
8
* restriction, including without limitation the rights to use,
9
* copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following
14
* The above copyright notice and this permission notice shall be
15
* included in all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
* OTHER DEALINGS IN THE SOFTWARE.
26
************************************************************************/
28
#ifndef __MDDS_QUAD_TYPE_MATRIX_HPP__
29
#define __MDDS_QUAD_TYPE_MATRIX_HPP__
31
#include "mdds/global.hpp"
32
#include "mdds/hash_container/map.hpp"
36
#include <boost/ptr_container/ptr_vector.hpp>
37
#include <boost/ptr_container/ptr_map.hpp>
43
matrix_density_filled_zero,
44
matrix_density_filled_empty,
45
matrix_density_sparse_zero,
46
matrix_density_sparse_empty
57
enum matrix_init_element_t
59
matrix_init_element_zero,
60
matrix_init_element_empty
63
class matrix_error : public ::mdds::general_error
66
matrix_error(const ::std::string& msg) : general_error(msg) {}
69
matrix_init_element_t get_init_element_type(matrix_density_t density)
73
case matrix_density_filled_empty:
74
case matrix_density_sparse_empty:
75
return matrix_init_element_empty;
76
case matrix_density_filled_zero:
77
case matrix_density_sparse_zero:
78
return matrix_init_element_zero;
80
throw matrix_error("unknown matrix density type.");
85
* This data structure represents a matrix where each individual element may
86
* be of one of four types: value, boolean, string, or empty.
88
template<typename _String, typename _Flag>
89
class quad_type_matrix
92
typedef _String string_type;
93
typedef _Flag flag_type;
94
typedef size_t size_type;
95
typedef ::std::pair<size_type, size_type> size_pair_type;
98
* Default constructor.
103
* Construct an empty matrix with specified density type.
105
quad_type_matrix(matrix_density_t density);
108
* Construct a matrix of specified size with specified density type.
110
quad_type_matrix(size_t rows, size_t cols, matrix_density_t density);
112
quad_type_matrix(const quad_type_matrix& r);
115
quad_type_matrix& operator= (const quad_type_matrix& r);
118
* Get the type of element specified by its position. The type can be one
119
* of empty, string, numeric, or boolean.
121
* @return element type.
123
matrix_element_t get_type(size_t row, size_t col) const;
125
double get_numeric(size_t row, size_t col) const;
126
bool get_boolean(size_t row, size_t col) const;
127
const string_type* get_string(size_t row, size_t col) const;
129
void set_numeric(size_t row, size_t col, double val);
130
void set_boolean(size_t row, size_t col, bool val);
131
void set_string(size_t row, size_t col, string_type* str);
132
void set_empty(size_t row, size_t col);
134
void set(size_t row, size_t col, double val);
135
void set(size_t row, size_t col, bool val);
136
void set(size_t row, size_t col, string_type* str);
139
* Set flag value at specified position.
141
* @param row row position
142
* @param col column position
143
* @param flag_type flag value
145
void set_flag(size_t row, size_t col, flag_type flag);
148
* Get flag value at specified position.
150
* @param row row position
151
* @param col column position
153
* @return flag value stored at specified position
155
flag_type get_flag(size_t row, size_t col) const;
157
void clear_flag(size_t row, size_t cols);
160
* Return the size of matrix as a pair. The first value is the row size,
161
* while the second value is the column size.
163
* @return matrix size as a value pair.
165
size_pair_type size() const;
168
* Transpose the stored matrix data.
170
* @return reference to this matrix instance.
172
quad_type_matrix& transpose();
175
* Assign values from the passed matrix instance. If the size of the
176
* passed matrix is smaller, then the element values are assigned by their
177
* positions, while the rest of the elements that fall outside the size of
178
* the passed matrix instance will remain unmodified. If the size of the
179
* pass matrix instance is larger, then only the elements within the size
180
* of this matrix instance will get assigned.
182
* @param r passed matrix object to assign element values from.
184
void assign(const quad_type_matrix& r);
187
* Resize the matrix to specified size. This method supports resizing to
188
* zero-sized matrix; however, either specifying the row or column size to
189
* zero will resize the matrix to 0 x 0.
191
* @param row new row size
192
* @param col new column size
194
void resize(size_t row, size_t col);
202
* Check whether or not this matrix is numeric. A numeric matrix contains
203
* only numeric or boolean elements.
205
* @return true if the matrix contains only numeric or boolean elements,
206
* or false otherwise.
208
bool numeric() const;
211
* Check whether or not this matrix is empty.
213
* @return true if this matrix is empty, or false otherwise.
218
* Swap the content of the matrix with another instance.
220
void swap(quad_type_matrix& r);
224
void dump_flags() const;
228
struct size_pair_type_hash
230
size_t operator() (const size_pair_type& val) const
232
size_t n = val.first + (val.second << 8);
236
typedef _mdds_unordered_map_type<size_pair_type, flag_type, size_pair_type_hash> flag_store_type;
242
flag_storage(const flag_storage& r) : m_flags(r.m_flags) {}
244
void set_flag(size_t row, size_t col, flag_type flag)
246
size_pair_type pos = size_pair_type(row, col);
247
typename flag_store_type::iterator itr = m_flags.find(pos);
248
if (itr == m_flags.end())
250
// flag not stored for this position.
251
::std::pair<typename flag_store_type::iterator, bool> r =
252
m_flags.insert(typename flag_store_type::value_type(pos, flag));
258
flag_type get_flag(size_t row, size_t col)
260
size_pair_type pos = size_pair_type(row, col);
261
typename flag_store_type::iterator itr = m_flags.find(pos);
262
return itr == m_flags.end() ? static_cast<flag_type>(0) : itr->second;
265
void clear_flag(size_t row, size_t col)
267
size_pair_type pos = size_pair_type(row, col);
268
typename flag_store_type::iterator itr = m_flags.find(pos);
269
if (itr != m_flags.end())
270
// Flag is stored at this position. Remove it.
279
cout << "no flags stored" << endl;
283
cout << "flags stored:" << endl;
284
typename flag_store_type::const_iterator itr = m_flags.begin(), itr_end = m_flags.end();
285
for (; itr != itr_end; ++itr)
287
const size_pair_type& pos = itr->first;
288
flag_type val = itr->second;
289
cout << "(row=" << pos.first << ",col=" << pos.second << ") = 0x" << hex << static_cast<size_t>(val) << endl;
294
flag_store_type m_flags;
299
matrix_element_t m_type:2;
305
string_type* mp_string;
308
element() : m_type(element_empty) {}
309
element(const element& r) : m_type(r.m_type)
313
case element_boolean:
314
m_boolean = r.m_boolean;
316
case element_numeric:
317
m_numeric = r.m_numeric;
320
mp_string = new string_type(*r.mp_string);
328
explicit element(double v) : m_type(element_numeric), m_numeric(v) {}
329
explicit element(bool v) : m_type(element_boolean), m_boolean(v) {}
330
explicit element(string_type* p) : m_type(element_string), mp_string(p) {}
332
bool operator== (const element& r) const
334
if (m_type != r.m_type)
339
case element_boolean:
340
return m_boolean == r.m_boolean;
341
case element_numeric:
342
return m_numeric == r.m_numeric;
344
return *mp_string == *r.mp_string;
353
element& operator= (const element& r)
355
if (m_type == element_string)
362
case element_boolean:
363
m_boolean = r.m_boolean;
365
case element_numeric:
366
m_numeric = r.m_numeric;
369
mp_string = new string_type(*r.mp_string);
380
if (m_type == element_string)
386
if (m_type == element_string)
388
m_type = element_empty;
391
void set_numeric(double val)
393
if (m_type == element_string)
395
m_type = element_numeric;
399
void set_boolean(bool val)
401
if (m_type == element_string)
403
m_type = element_boolean;
407
void set_string(string_type* str)
409
if (m_type == element_string)
411
m_type = element_string;
419
storage_base(matrix_init_element_t init) : m_init_type(init) {}
420
storage_base(const storage_base& r) : m_init_type(r.m_init_type), m_flags(r.m_flags) {}
422
virtual ~storage_base() {}
424
virtual element& get_element(size_t row, size_t col) = 0;
426
virtual matrix_element_t get_type(size_t row, size_t col) const = 0;
428
virtual double get_numeric(size_t row, size_t col) const = 0;
429
virtual const string_type* get_string(size_t row, size_t col) const = 0;
430
virtual bool get_boolean(size_t row, size_t col) const = 0;
432
virtual size_t rows() const = 0;
433
virtual size_t cols() const = 0;
435
virtual void transpose() = 0;
436
virtual void resize(size_t row, size_t col) = 0;
437
virtual void clear() = 0;
438
virtual bool numeric() = 0;
439
virtual bool empty() const = 0;
441
virtual storage_base* clone() const = 0;
443
flag_storage& get_flag_storage() { return m_flags; }
446
matrix_init_element_t get_init_type() const { return m_init_type; }
449
matrix_init_element_t m_init_type;
450
flag_storage m_flags;
454
* This storage creates instance for every single element, even for the
457
class storage_filled : public storage_base
459
typedef ::boost::ptr_vector<element> row_type;
460
typedef ::boost::ptr_vector<row_type> rows_type;
463
storage_filled(size_t _rows, size_t _cols, matrix_init_element_t init_type) :
464
storage_base(init_type),
468
m_rows.reserve(_rows);
469
for (size_t i = 0; i < _rows; ++i)
471
m_rows.push_back(new row_type);
472
init_row(m_rows.back(), _cols);
476
storage_filled(const storage_filled& r) :
479
m_numeric(r.m_numeric),
480
m_valid(r.m_valid) {}
482
virtual ~storage_filled() {}
484
virtual element& get_element(size_t row, size_t col)
487
return m_rows.at(row).at(col);
490
virtual matrix_element_t get_type(size_t row, size_t col) const
492
return m_rows.at(row).at(col).m_type;
495
virtual double get_numeric(size_t row, size_t col) const
497
const element& elem = m_rows.at(row).at(col);
498
if (elem.m_type != element_numeric && elem.m_type != element_boolean)
499
throw matrix_error("element type is not numeric.");
501
if (elem.m_type == element_boolean)
502
return static_cast<double>(elem.m_boolean);
504
return elem.m_numeric;
507
virtual const string_type* get_string(size_t row, size_t col) const
509
const element& elem = m_rows.at(row).at(col);
510
if (elem.m_type != element_string)
511
throw matrix_error("element type is not string.");
513
return elem.mp_string;
516
virtual bool get_boolean(size_t row, size_t col) const
518
const element& elem = m_rows.at(row).at(col);
519
if (elem.m_type != element_boolean)
520
throw matrix_error("element type is not boolean.");
522
return elem.m_boolean;
525
virtual size_t rows() const
527
return m_rows.size();
530
virtual size_t cols() const
532
return m_rows.empty() ? 0 : m_rows[0].size();
535
virtual void transpose()
538
size_t row_size = rows(), col_size = cols();
539
trans_mx.reserve(col_size);
540
for (size_t col = 0; col < col_size; ++col)
542
trans_mx.push_back(new row_type);
543
row_type& trans_row = trans_mx.back();
544
trans_row.reserve(row_size);
545
for (size_t row = 0; row < row_size; ++row)
546
trans_row.push_back(new element(m_rows[row][col]));
548
m_rows.swap(trans_mx);
551
virtual void resize(size_t row, size_t col)
561
size_t cur_rows = rows(), cur_cols = cols();
565
// Insert extra rows...
566
size_t new_row_count = row - cur_rows;
568
for (size_t i = 0; i < new_row_count; ++i)
570
m_rows.push_back(new row_type);
571
init_row(m_rows.back(), col);
574
resize_rows(cur_rows-1, cur_cols, col);
576
else if (cur_rows > row)
578
// Remove rows to new size.
580
resize_rows(row-1, cur_cols, col);
584
assert(cur_rows == row);
585
resize_rows(cur_rows-1, cur_cols, col);
596
virtual bool numeric()
601
typename rows_type::const_iterator itr_row = m_rows.begin(), itr_row_end = m_rows.end();
602
for (; itr_row != itr_row_end; ++itr_row)
604
typename row_type::const_iterator itr_col = itr_row->begin(), itr_col_end = itr_row->end();
605
for (; itr_col != itr_col_end; ++itr_col)
607
matrix_element_t elem_type = itr_col->m_type;
608
if (elem_type != element_numeric && elem_type != element_boolean)
622
virtual bool empty() const
624
return m_rows.empty();
627
virtual storage_base* clone() const
629
return new storage_filled(*this);
635
* Resize rows to a new column size, from row 0 up to specified upper
638
void resize_rows(size_t upper_row, size_t cur_cols, size_t new_cols)
640
for (size_t i = 0; i <= upper_row; ++i)
642
// Resize pre-existing rows to new column size.
643
if (new_cols > cur_cols)
645
size_t new_col_count = new_cols - cur_cols;
646
for (size_t j = 0; j < new_col_count; ++j)
647
insert_new_elem(m_rows[i]);
649
else if (new_cols < cur_cols)
650
m_rows[i].resize(new_cols);
654
void init_row(row_type& row, size_t col_size)
656
row.reserve(col_size);
657
for (size_t j = 0; j < col_size; ++j)
658
insert_new_elem(row);
661
void insert_new_elem(row_type& row)
663
matrix_init_element_t init_type = storage_base::get_init_type();
666
case matrix_init_element_zero:
667
row.push_back(new element(static_cast<double>(0.0)));
669
case matrix_init_element_empty:
670
row.push_back(new element);
673
throw matrix_error("unknown init type.");
684
* This storage stores only non-empty elements.
686
class storage_sparse : public storage_base
688
typedef ::boost::ptr_map<size_t, element> row_type;
689
typedef ::boost::ptr_map<size_t, row_type> rows_type;
692
storage_sparse(size_t _rows, size_t _cols, matrix_init_element_t init_type) :
693
storage_base(init_type),
694
m_row_size(_rows), m_col_size(_cols),
695
m_numeric(_rows && _cols), m_valid(true)
697
switch (storage_base::get_init_type())
699
case matrix_init_element_zero:
700
m_empty_elem.m_type = element_numeric;
701
m_empty_elem.m_numeric = 0.0;
704
m_empty_elem.m_type = element_empty;
709
storage_sparse(const storage_sparse& r) :
712
m_empty_elem(r.m_empty_elem),
713
m_row_size(r.m_row_size),
714
m_col_size(r.m_col_size) {}
716
virtual ~storage_sparse() {}
718
virtual element & get_element(size_t row, size_t col)
720
if (row >= m_row_size || col >= m_col_size)
721
throw matrix_error("specified element is out-of-bound.");
725
typename rows_type::iterator itr = m_rows.find(row);
726
if (itr == m_rows.end())
728
// Insert a brand-new row.
729
::std::pair<typename rows_type::iterator, bool> r = m_rows.insert(row, new row_type);
731
throw matrix_error("failed to insert a new row instance into storage_sparse.");
735
row_type& row_store = *itr->second;
736
typename row_type::iterator itr_elem = row_store.find(col);
737
if (itr_elem == row_store.end())
739
// Insert a new element at this column position.
740
::std::pair<typename row_type::iterator, bool> r = row_store.insert(col, new element);
742
throw matrix_error("failed to insert a new element instance.");
745
return *itr_elem->second;
748
virtual matrix_element_t get_type(size_t row, size_t col) const
750
typename rows_type::const_iterator itr = m_rows.find(row);
751
if (itr == m_rows.end())
752
return m_empty_elem.m_type;
754
const row_type& row_store = *itr->second;
755
typename row_type::const_iterator itr_elem = row_store.find(col);
756
if (itr_elem == row_store.end())
757
return m_empty_elem.m_type;
759
return itr_elem->second->m_type;
762
virtual double get_numeric(size_t row, size_t col) const
764
matrix_element_t elem_type = get_type(row, col);
765
if (elem_type != element_numeric && elem_type != element_boolean)
766
throw matrix_error("element type is not numeric.");
768
const element& elem = get_non_empty_element(row, col);
770
if (elem.m_type == element_boolean)
771
return static_cast<double>(elem.m_boolean);
773
return elem.m_numeric;
776
virtual const string_type* get_string(size_t row, size_t col) const
778
matrix_element_t elem_type = get_type(row, col);
779
if (elem_type != element_string)
780
throw matrix_error("element type is not string.");
782
return get_non_empty_element(row, col).mp_string;
785
virtual bool get_boolean(size_t row, size_t col) const
787
matrix_element_t elem_type = get_type(row, col);
788
if (elem_type != element_boolean)
789
throw matrix_error("element type is not string.");
791
return get_non_empty_element(row, col).m_boolean;
794
virtual size_t rows() const
799
virtual size_t cols() const
804
typedef ::std::pair<size_t, size_t> elem_pos_type;
806
struct elem_pos_sorter : ::std::binary_function<elem_pos_type, elem_pos_type, bool>
808
bool operator() (const elem_pos_type& left, const elem_pos_type& right) const
810
if (left.first != right.first)
811
return left.first < right.first;
812
return left.second < right.second;
816
virtual void transpose()
822
// First, pick up the positions of all non-empty elements.
823
vector<elem_pos_type> filled_elems;
825
typename rows_type::const_iterator itr_row = m_rows.begin(), itr_row_end = m_rows.end();
826
for (; itr_row != itr_row_end; ++itr_row)
828
size_t row_idx = itr_row->first;
829
const row_type& row = *itr_row->second;
830
typename row_type::const_iterator itr_col = row.begin(), itr_col_end = row.end();
831
for (; itr_col != itr_col_end; ++itr_col)
833
// Be sure to swap the row and column indices.
834
filled_elems.push_back(elem_pos_type(itr_col->first, row_idx));
838
// Sort by row index first, then by column index.
839
sort(filled_elems.begin(), filled_elems.end(), elem_pos_sorter());
841
// Iterate through the non-empty element positions and perform
843
typename vector<elem_pos_type>::const_iterator
844
itr_pos = filled_elems.begin(), itr_pos_end = filled_elems.end();
845
while (itr_pos != itr_pos_end)
847
// First item of the new row.
848
size_t row_idx = itr_pos->first;
849
size_t col_idx = itr_pos->second;
850
pair<typename rows_type::iterator, bool> r = trans.insert(row_idx, new row_type);
852
throw matrix_error("failed to insert a new row instance during transposition.");
854
typename rows_type::iterator itr_row = r.first;
855
row_type& row = *itr_row->second;
856
pair<typename row_type::iterator, bool> r2 =
857
row.insert(col_idx, new element(m_rows[col_idx][row_idx]));
859
throw matrix_error("afiled to insert a new element instance during transposition.");
861
// Keep iterating until we get a different row index.
862
for (++itr_pos; itr_pos != itr_pos_end && itr_pos->first == row_idx; ++itr_pos)
864
col_idx = itr_pos->second;
865
r2 = row.insert(col_idx, new element(m_rows[col_idx][row_idx]));
867
throw matrix_error("afiled to insert a new element instance during transposition.");
872
::std::swap(m_row_size, m_col_size);
875
virtual void resize(size_t row, size_t col)
885
// Resizing a sparse matrix need to modify the data only when
888
if (m_row_size > row)
890
// Remove all rows where the row index is greater than or
892
typename rows_type::iterator itr = m_rows.lower_bound(row);
893
m_rows.erase(itr, m_rows.end());
896
if (m_col_size > col)
898
typename rows_type::iterator itr = m_rows.begin(), itr_end = m_rows.end();
899
for (; itr != itr_end; ++itr)
901
// Now, remove all columns where the column index is
902
// greater than or equal to 'col'.
903
row_type& row_container = *itr->second;
904
typename row_type::iterator itr_elem = row_container.lower_bound(col);
905
row_container.erase(itr_elem, row_container.end());
922
virtual bool numeric()
929
size_t non_empty_count = 0;
930
typename rows_type::const_iterator itr_row = m_rows.begin(), itr_row_end = m_rows.end();
931
for (; itr_row != itr_row_end; ++itr_row)
933
const row_type& row = *itr_row->second;
934
non_empty_count += row.size();
935
assert(row.size() <= m_col_size);
936
typename row_type::const_iterator itr_col = row.begin(), itr_col_end = row.end();
937
for (; itr_col != itr_col_end; ++itr_col)
939
const element& elem = *itr_col->second;
940
if (elem.m_type != element_numeric && elem.m_type != element_boolean)
949
// All non-empty elements are numeric.
951
matrix_init_element_t init_type = storage_base::get_init_type();
952
if (init_type == matrix_init_element_zero)
956
size_t total_elem_count = m_row_size * m_col_size;
957
assert(non_empty_count <= total_elem_count);
958
m_numeric = total_elem_count == non_empty_count;
965
virtual bool empty() const
967
// If one of row and column sizes are zero, the other size must be
968
// zero, and vise versa.
969
assert((!m_row_size && !m_col_size) || (m_row_size && m_col_size));
971
return m_row_size == 0 || m_col_size == 0;
974
virtual storage_base* clone() const
976
return new storage_sparse(*this);
980
const element& get_non_empty_element(size_t row, size_t col) const
982
typename rows_type::const_iterator itr = m_rows.find(row);
983
if (itr == m_rows.end())
986
const row_type& row_store = *itr->second;
987
typename row_type::const_iterator itr_elem = row_store.find(col);
988
if (itr_elem == row_store.end())
990
return *itr_elem->second;
995
element m_empty_elem;
1003
static storage_base* create_storage(size_t rows, size_t cols, matrix_density_t density);
1006
storage_base* mp_storage;
1009
template<typename _String, typename _Flag>
1010
typename quad_type_matrix<_String,_Flag>::storage_base*
1011
quad_type_matrix<_String,_Flag>::create_storage(size_t rows, size_t cols, matrix_density_t density)
1015
case matrix_density_filled_zero:
1016
return new storage_filled(rows, cols, matrix_init_element_zero);
1017
case matrix_density_filled_empty:
1018
return new storage_filled(rows, cols, matrix_init_element_empty);
1019
case matrix_density_sparse_zero:
1020
return new storage_sparse(rows, cols, matrix_init_element_zero);
1021
case matrix_density_sparse_empty:
1022
return new storage_sparse(rows, cols, matrix_init_element_empty);
1024
throw matrix_error("unknown density type");
1029
template<typename _String, typename _Flag>
1030
quad_type_matrix<_String,_Flag>::quad_type_matrix() :
1033
mp_storage = create_storage(0, 0, matrix_density_filled_zero);
1036
template<typename _String, typename _Flag>
1037
quad_type_matrix<_String,_Flag>::quad_type_matrix(matrix_density_t density) :
1040
mp_storage = create_storage(0, 0, density);
1043
template<typename _String, typename _Flag>
1044
quad_type_matrix<_String,_Flag>::quad_type_matrix(size_t rows, size_t cols, matrix_density_t density) :
1047
mp_storage = create_storage(rows, cols, density);
1050
template<typename _String, typename _Flag>
1051
quad_type_matrix<_String,_Flag>::quad_type_matrix(const quad_type_matrix& r) :
1052
mp_storage(r.mp_storage->clone())
1056
template<typename _String, typename _Flag>
1057
quad_type_matrix<_String,_Flag>::~quad_type_matrix()
1062
template<typename _String, typename _Flag>
1063
quad_type_matrix<_String,_Flag>&
1064
quad_type_matrix<_String,_Flag>::operator= (const quad_type_matrix& r)
1071
mp_storage = r.mp_storage->clone();
1075
template<typename _String, typename _Flag>
1076
matrix_element_t quad_type_matrix<_String,_Flag>::get_type(size_t row, size_t col) const
1078
return mp_storage->get_type(row, col);
1081
template<typename _String, typename _Flag>
1082
double quad_type_matrix<_String,_Flag>::get_numeric(size_t row, size_t col) const
1084
return mp_storage->get_numeric(row, col);
1087
template<typename _String, typename _Flag>
1088
bool quad_type_matrix<_String,_Flag>::get_boolean(size_t row, size_t col) const
1090
return mp_storage->get_boolean(row, col);
1093
template<typename _String, typename _Flag>
1094
const typename quad_type_matrix<_String,_Flag>::string_type*
1095
quad_type_matrix<_String,_Flag>::get_string(size_t row, size_t col) const
1097
return mp_storage->get_string(row, col);
1100
template<typename _String, typename _Flag>
1101
void quad_type_matrix<_String,_Flag>::set_numeric(size_t row, size_t col, double val)
1103
mp_storage->get_element(row, col).set_numeric(val);
1106
template<typename _String, typename _Flag>
1107
void quad_type_matrix<_String,_Flag>::set_boolean(size_t row, size_t col, bool val)
1109
mp_storage->get_element(row, col).set_boolean(val);
1112
template<typename _String, typename _Flag>
1113
void quad_type_matrix<_String,_Flag>::set_string(size_t row, size_t col, string_type* str)
1115
mp_storage->get_element(row, col).set_string(str);
1118
template<typename _String, typename _Flag>
1119
void quad_type_matrix<_String,_Flag>::set_flag(size_t row, size_t col, flag_type flag)
1121
mp_storage->get_flag_storage().set_flag(row, col, flag);
1124
template<typename _String, typename _Flag>
1125
typename quad_type_matrix<_String,_Flag>::flag_type
1126
quad_type_matrix<_String,_Flag>::get_flag(size_t row, size_t col) const
1128
return mp_storage->get_flag_storage().get_flag(row, col);
1131
template<typename _String, typename _Flag>
1132
void quad_type_matrix<_String,_Flag>::clear_flag(size_t row, size_t col)
1134
return mp_storage->get_flag_storage().clear_flag(row, col);
1137
template<typename _String, typename _Flag>
1138
void quad_type_matrix<_String,_Flag>::set_empty(size_t row, size_t col)
1140
mp_storage->get_element(row, col).set_empty();
1143
template<typename _String, typename _Flag>
1144
void quad_type_matrix<_String,_Flag>::set(size_t row, size_t col, double val)
1146
set_numeric(row, col, val);
1149
template<typename _String, typename _Flag>
1150
void quad_type_matrix<_String,_Flag>::set(size_t row, size_t col, bool val)
1152
set_boolean(row, col, val);
1155
template<typename _String, typename _Flag>
1156
void quad_type_matrix<_String,_Flag>::set(size_t row, size_t col, string_type* str)
1158
set_string(row, col, str);
1161
template<typename _String, typename _Flag>
1162
typename quad_type_matrix<_String,_Flag>::size_pair_type
1163
quad_type_matrix<_String,_Flag>::size() const
1165
size_pair_type size_pair(mp_storage->rows(), mp_storage->cols());
1169
template<typename _String, typename _Flag>
1170
quad_type_matrix<_String,_Flag>&
1171
quad_type_matrix<_String,_Flag>::transpose()
1173
mp_storage->transpose();
1177
template<typename _String, typename _Flag>
1178
void quad_type_matrix<_String,_Flag>::assign(const quad_type_matrix& r)
1181
// assignment to self.
1184
size_t row_count = ::std::min(mp_storage->rows(), r.mp_storage->rows());
1185
size_t col_count = ::std::min(mp_storage->cols(), r.mp_storage->cols());
1186
for (size_t i = 0; i < row_count; ++i)
1187
for (size_t j = 0; j < col_count; ++j)
1188
mp_storage->get_element(i, j) = r.mp_storage->get_element(i, j);
1191
template<typename _String, typename _Flag>
1192
void quad_type_matrix<_String,_Flag>::resize(size_t row, size_t col)
1194
mp_storage->resize(row, col);
1197
template<typename _String, typename _Flag>
1198
void quad_type_matrix<_String,_Flag>::clear()
1200
mp_storage->clear();
1203
template<typename _String, typename _Flag>
1204
bool quad_type_matrix<_String,_Flag>::numeric() const
1206
return mp_storage->numeric();
1209
template<typename _String, typename _Flag>
1210
bool quad_type_matrix<_String,_Flag>::empty() const
1212
return mp_storage->empty();
1215
template<typename _String, typename _Flag>
1216
void quad_type_matrix<_String,_Flag>::swap(quad_type_matrix& r)
1218
::std::swap(mp_storage, r.mp_storage);
1222
template<typename _String, typename _Flag>
1223
void quad_type_matrix<_String,_Flag>::dump() const
1225
using namespace std;
1226
size_t rows = mp_storage->rows(), cols = mp_storage->cols();
1227
cout << "rows: " << mp_storage->rows() << " cols: " << mp_storage->cols() << endl;
1228
for (size_t i = 0; i < rows; ++i)
1230
cout << "row " << i << ": ";
1231
for (size_t j = 0; j < cols; ++j)
1233
matrix_element_t etype = mp_storage->get_type(i, j);
1236
cout << "(col " << j << ": ";
1239
case element_boolean:
1240
cout << boolalpha << mp_storage->get_boolean(i, j) << noboolalpha;
1245
case element_numeric:
1246
cout << mp_storage->get_numeric(i, j);
1248
case element_string:
1249
cout << "'" << mp_storage->get_string(i, j) << "'";
1260
template<typename _String, typename _Flag>
1261
void quad_type_matrix<_String,_Flag>::dump_flags() const
1263
mp_storage->get_flag_storage().dump();