mdds
multi_type_matrix.hpp
1 /*************************************************************************
2  *
3  * Copyright (c) 2012-2021 Kohei Yoshida
4  *
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
12  * conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
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.
25  *
26  ************************************************************************/
27 
28 #ifndef __MDDS_MULTI_TYPE_MATRIX_HPP__
29 #define __MDDS_MULTI_TYPE_MATRIX_HPP__
30 
31 #ifdef MDDS_MULTI_TYPE_MATRIX_DEBUG
32 #ifndef MDDS_MULTI_TYPE_VECTOR_DEBUG
33 #define MDDS_MULTI_TYPE_VECTOR_DEBUG 1
34 #endif
35 #endif
36 
37 #include "multi_type_vector.hpp"
38 
39 namespace mdds {
40 
41 namespace mtm {
42 
46 enum element_t
47 {
48  element_empty = mdds::mtv::element_type_empty,
49  element_boolean = mdds::mtv::element_type_boolean,
50  element_string = mdds::mtv::element_type_string,
51  element_numeric = mdds::mtv::element_type_double,
52  element_integer = mdds::mtv::element_type_int32
53 };
54 
59 {
62 };
63 
64 } // namespace mtm
65 
75 template<typename Traits>
77 {
78  typedef Traits traits_type;
79 
80 public:
81  typedef typename traits_type::string_element_block string_block_type;
82  typedef typename traits_type::integer_element_block integer_block_type;
83 
84  typedef typename string_block_type::value_type string_type;
85  typedef typename integer_block_type::value_type integer_type;
86  typedef size_t size_type;
87 
88 private:
89  struct mtv_trait : public mdds::mtv::default_traits
90  {
91  using block_funcs = mdds::mtv::element_block_funcs<
93  typename traits_type::string_element_block, typename traits_type::integer_element_block>;
94  };
95 
97 
98 public:
99  typedef typename store_type::position_type position_type;
100  typedef typename store_type::const_position_type const_position_type;
101 
103 
106 
108  {
109  size_type row;
110  size_type column;
111  size_pair_type() : row(0), column(0)
112  {}
113  size_pair_type(size_type _row, size_type _column) : row(_row), column(_column)
114  {}
115  size_pair_type(std::initializer_list<size_type> vs)
116  {
117  if (vs.size() != 2)
118  throw invalid_arg_error("size_pair_type requires exactly 2 elements.");
119 
120  size_type* ptrs[2] = {&row, &column};
121  size_type** p = ptrs;
122 
123  for (size_type v : vs)
124  **p++ = v;
125  }
126 
127  bool operator==(const size_pair_type& r) const
128  {
129  return row == r.row && column == r.column;
130  }
131  bool operator!=(const size_pair_type& r) const
132  {
133  return !operator==(r);
134  }
135  };
136 
138  {
139  friend class multi_type_matrix;
140 
141  mtm::element_t type;
142  size_type offset;
143  size_type size;
144  const element_block_type* data;
145 
148 
149  template<typename _Blk>
150  typename _Blk::const_iterator begin() const;
151 
152  template<typename _Blk>
153  typename _Blk::const_iterator end() const;
154 
155  private:
156  void assign(const const_position_type& pos, size_type section_size);
157  };
158 
159  static mtm::element_t to_mtm_type(mdds::mtv::element_t mtv_type)
160  {
161  switch (mtv_type)
162  {
163  case string_block_type::block_type:
164  return mdds::mtm::element_string;
165  case integer_block_type::block_type:
166  return mdds::mtm::element_integer;
167  case mdds::mtv::element_type_double:
168  case mdds::mtv::element_type_boolean:
169  case mdds::mtv::element_type_empty:
170  // These types share the same numeric values.
171  return static_cast<mtm::element_t>(mtv_type);
172  default:
173  throw type_error("multi_type_matrix: unknown element type.");
174  }
175  }
176 
177 private:
178  template<typename FuncT>
179  struct walk_func
180  {
181  FuncT& m_func;
182  walk_func(FuncT& func) : m_func(func)
183  {}
184 
185  void operator()(const typename store_type::const_iterator::value_type& mtv_node)
186  {
187  element_block_node_type mtm_node;
188  mtm_node.type = to_mtm_type(mtv_node.type);
189  mtm_node.size = mtv_node.size;
190  mtm_node.data = mtv_node.data;
191  m_func(mtm_node);
192  }
193  };
194 
195 public:
205  static position_type next_position(const position_type& pos);
206 
216  static const_position_type next_position(const const_position_type& pos);
217 
222 
229  multi_type_matrix(size_type rows, size_type cols);
230 
239  template<typename _T>
240  multi_type_matrix(size_type rows, size_type cols, const _T& value);
241 
254  template<typename _T>
255  multi_type_matrix(size_type rows, size_type cols, const _T& it_begin, const _T& it_end);
256 
261 
266 
267  bool operator==(const multi_type_matrix& other) const;
268  bool operator!=(const multi_type_matrix& other) const;
269 
270  multi_type_matrix& operator=(const multi_type_matrix& r);
271 
283  position_type position(size_type row, size_type col);
284 
298  position_type position(const position_type& pos_hint, size_type row, size_type col);
299 
310  const_position_type position(size_type row, size_type col) const;
311 
324  const_position_type position(const const_position_type& pos_hint, size_type row, size_type col) const;
325 
334  size_pair_type matrix_position(const const_position_type& pos) const;
335 
343  position_type end_position();
344 
352  const_position_type end_position() const;
353 
362  mtm::element_t get_type(const const_position_type& pos) const;
363 
370  mtm::element_t get_type(size_type row, size_type col) const;
371 
383  double get_numeric(size_type row, size_type col) const;
384 
395  double get_numeric(const const_position_type& pos) const;
396 
408  integer_type get_integer(size_type row, size_type col) const;
409 
420  integer_type get_integer(const const_position_type& pos) const;
421 
433  bool get_boolean(size_type row, size_type col) const;
434 
445  bool get_boolean(const const_position_type& pos) const;
446 
456  const string_type& get_string(size_type row, size_type col) const;
457 
466  const string_type& get_string(const const_position_type& pos) const;
467 
478  template<typename _T>
479  _T get(size_type row, size_type col) const;
480 
487  void set_empty(size_type row, size_type col);
488 
500  void set_empty(size_type row, size_type col, size_type length);
501 
509  position_type set_empty(const position_type& pos);
510 
516  void set_column_empty(size_type col);
517 
523  void set_row_empty(size_type row);
524 
532  void set(size_type row, size_type col, double val);
533 
542  position_type set(const position_type& pos, double val);
543 
551  void set(size_type row, size_type col, bool val);
552 
561  position_type set(const position_type& pos, bool val);
562 
570  void set(size_type row, size_type col, const string_type& str);
571 
580  position_type set(const position_type& pos, const string_type& str);
581 
589  void set(size_type row, size_type col, integer_type val);
590 
599  position_type set(const position_type& pos, integer_type val);
600 
617  template<typename _T>
618  void set(size_type row, size_type col, const _T& it_begin, const _T& it_end);
619 
634  template<typename _T>
635  position_type set(const position_type& pos, const _T& it_begin, const _T& it_end);
636 
648  template<typename _T>
649  void set_column(size_type col, const _T& it_begin, const _T& it_end);
650 
657  size_pair_type size() const;
658 
665 
676  void copy(const multi_type_matrix& src);
677 
689  template<typename _T>
690  void copy(size_type rows, size_type cols, const _T& it_begin, const _T& it_end);
691 
702  void resize(size_type rows, size_type cols);
703 
713  template<typename _T>
714  void resize(size_type rows, size_type cols, const _T& value);
715 
719  void clear();
720 
728  bool numeric() const;
729 
735  bool empty() const;
736 
740  void swap(multi_type_matrix& r);
741 
750  template<typename FuncT>
751  FuncT walk(FuncT func) const;
752 
769  template<typename FuncT>
770  FuncT walk(FuncT func, const size_pair_type& start, const size_pair_type& end) const;
771 
782  template<typename FuncT>
783  FuncT walk(FuncT func, const multi_type_matrix& right) const;
784 
803  template<typename FuncT>
804  FuncT walk(
805  FuncT func, const multi_type_matrix& right, const size_pair_type& start, const size_pair_type& end) const;
806 
807 #ifdef MDDS_MULTI_TYPE_MATRIX_DEBUG
808  void dump() const
809  {
810  m_store.dump_blocks(std::cout);
811  }
812 #endif
813 
814 private:
825  inline size_type get_pos(size_type row, size_type col) const
826  {
827  return m_size.row * col + row;
828  }
829 
830  inline size_type get_pos(const const_position_type& pos) const
831  {
832  return pos.first->position + pos.second;
833  }
834 
835 private:
836  store_type m_store;
837  size_pair_type m_size;
838 };
839 
840 } // namespace mdds
841 
842 #include "multi_type_matrix_def.inl"
843 
844 #endif
position_type end_position()
static position_type next_position(const position_type &pos)
double get_numeric(size_type row, size_type col) const
bool get_boolean(size_type row, size_type col) const
size_pair_type size() const
void set_column_empty(size_type col)
FuncT walk(FuncT func) const
Definition: global.hpp:114
mtm::element_t get_type(const const_position_type &pos) const
void resize(size_type rows, size_type cols)
integer_type get_integer(size_type row, size_type col) const
Definition: global.hpp:100
Definition: multi_type_matrix.hpp:107
void set_column(size_type col, const _T &it_begin, const _T &it_end)
void set(size_type row, size_type col, double val)
Definition: types.hpp:830
size_pair_type matrix_position(const const_position_type &pos) const
void copy(const multi_type_matrix &src)
Definition: multi_type_matrix.hpp:76
void set_empty(size_type row, size_type col)
multi_type_matrix & transpose()
const string_type & get_string(size_type row, size_type col) const
Definition: util.hpp:74
Definition: flat_segment_tree.hpp:46
void set_row_empty(size_type row)
Definition: block_funcs.hpp:64
Definition: types.hpp:159
position_type position(size_type row, size_type col)
Definition: multi_type_matrix.hpp:58
Definition: main.hpp:72
Definition: multi_type_matrix.hpp:137
void swap(multi_type_matrix &r)