mdds
multi_type_matrix.hpp
1 // SPDX-FileCopyrightText: 2012 - 2025 Kohei Yoshida
2 //
3 // SPDX-License-Identifier: MIT
4 
5 #pragma once
6 
7 #ifdef MDDS_MULTI_TYPE_MATRIX_DEBUG
8 #ifndef MDDS_MULTI_TYPE_VECTOR_DEBUG
9 #define MDDS_MULTI_TYPE_VECTOR_DEBUG 1
10 #endif
11 #endif
12 
13 #include "multi_type_vector.hpp"
14 
15 namespace mdds {
16 
17 namespace mtm {
18 
22 enum element_t
23 {
24  element_empty = mdds::mtv::element_type_empty,
25  element_boolean = mdds::mtv::element_type_boolean,
26  element_string = mdds::mtv::element_type_string,
27  element_numeric = mdds::mtv::element_type_double,
28  element_integer = mdds::mtv::element_type_int32
29 };
30 
35 {
38 };
39 
40 } // namespace mtm
41 
51 template<typename Traits>
53 {
54  using traits_type = Traits;
55 
56 public:
57  using string_block_type = typename traits_type::string_element_block;
58  using integer_block_type = typename traits_type::integer_element_block;
59 
60  using string_type = typename string_block_type::value_type;
61  using integer_type = typename integer_block_type::value_type;
62  using size_type = std::size_t;
63 
64 private:
65  struct mtv_traits : public mdds::mtv::default_traits
66  {
67  using block_funcs = mdds::mtv::element_block_funcs<
69  typename traits_type::string_element_block, typename traits_type::integer_element_block>;
70  };
71 
73 
74 public:
75  using position_type = typename store_type::position_type;
76  using const_position_type = typename store_type::const_position_type;
77 
78  using element_block_type = typename mtv::base_element_block;
79 
80  using boolean_block_type = typename mtv::boolean_element_block;
81  using numeric_block_type = typename mtv::double_element_block;
82 
84  {
85  size_type row;
86  size_type column;
87  size_pair_type() noexcept(std::is_fundamental_v<size_type>) : row(0), column(0)
88  {}
89  size_pair_type(size_type _row, size_type _column) noexcept(std::is_fundamental_v<size_type>)
90  : row(_row), column(_column)
91  {}
92  size_pair_type(std::initializer_list<size_type> vs)
93  {
94  if (vs.size() != 2)
95  throw invalid_arg_error("size_pair_type requires exactly 2 elements.");
96 
97  size_type* ptrs[2] = {&row, &column};
98  size_type** p = ptrs;
99 
100  for (size_type v : vs)
101  **p++ = v;
102  }
103 
104  bool operator==(const size_pair_type& r) const noexcept(std::is_fundamental_v<size_type>)
105  {
106  return row == r.row && column == r.column;
107  }
108  bool operator!=(const size_pair_type& r) const noexcept(std::is_fundamental_v<size_type>)
109  {
110  return !operator==(r);
111  }
112  };
113 
115  {
116  friend class multi_type_matrix;
117 
118  mtm::element_t type;
119  size_type offset;
120  size_type size;
121  const element_block_type* data;
122 
123  element_block_node_type() noexcept(std::is_fundamental_v<size_type>);
124  element_block_node_type(const element_block_node_type& other) noexcept(std::is_fundamental_v<size_type>);
125 
126  template<typename _Blk>
127  typename _Blk::const_iterator begin() const;
128 
129  template<typename _Blk>
130  typename _Blk::const_iterator end() const;
131 
132  private:
133  void assign(const const_position_type& pos, size_type section_size);
134  };
135 
136  static mtm::element_t to_mtm_type(mdds::mtv::element_t mtv_type)
137  {
138  switch (mtv_type)
139  {
140  case string_block_type::block_type:
141  return mdds::mtm::element_string;
142  case integer_block_type::block_type:
143  return mdds::mtm::element_integer;
144  case mdds::mtv::element_type_double:
145  case mdds::mtv::element_type_boolean:
146  case mdds::mtv::element_type_empty:
147  // These types share the same numeric values.
148  return static_cast<mtm::element_t>(mtv_type);
149  default:
150  throw type_error("multi_type_matrix: unknown element type.");
151  }
152  }
153 
154 private:
155  template<typename FuncT>
156  struct walk_func
157  {
158  FuncT& m_func;
159  walk_func(FuncT& func) noexcept : m_func(func)
160  {}
161 
162  void operator()(const typename store_type::const_iterator::value_type& mtv_node)
163  {
164  element_block_node_type mtm_node;
165  mtm_node.type = to_mtm_type(mtv_node.type);
166  mtm_node.size = mtv_node.size;
167  mtm_node.data = mtv_node.data;
168  m_func(mtm_node);
169  }
170  };
171 
172  static constexpr bool nothrow_default_constructible_v =
173  std::is_nothrow_default_constructible_v<store_type> && std::is_nothrow_default_constructible_v<size_pair_type>;
174 
175  static constexpr bool nothrow_eq_comparable_v =
176  noexcept(std::declval<store_type>() == std::declval<store_type>()) &&
177  noexcept(std::declval<size_pair_type>() == std::declval<size_pair_type>());
178 
179 public:
189  static position_type next_position(const position_type& pos);
190 
200  static const_position_type next_position(const const_position_type& pos);
201 
205  multi_type_matrix() noexcept(nothrow_default_constructible_v);
206 
213  multi_type_matrix(size_type rows, size_type cols);
214 
223  template<typename _T>
224  multi_type_matrix(size_type rows, size_type cols, const _T& value);
225 
238  template<typename _T>
239  multi_type_matrix(size_type rows, size_type cols, const _T& it_begin, const _T& it_end);
240 
244  multi_type_matrix(const multi_type_matrix& other);
245 
249  multi_type_matrix(multi_type_matrix&& other) = default;
250 
254  ~multi_type_matrix() = default;
255 
256  bool operator==(const multi_type_matrix& other) const noexcept(nothrow_eq_comparable_v);
257  bool operator!=(const multi_type_matrix& other) const noexcept(nothrow_eq_comparable_v);
258 
259  multi_type_matrix& operator=(const multi_type_matrix& other) = default;
260  multi_type_matrix& operator=(multi_type_matrix&& other) = default;
261 
273  position_type position(size_type row, size_type col);
274 
288  position_type position(const position_type& pos_hint, size_type row, size_type col);
289 
300  const_position_type position(size_type row, size_type col) const;
301 
314  const_position_type position(const const_position_type& pos_hint, size_type row, size_type col) const;
315 
324  size_pair_type matrix_position(const const_position_type& pos) const;
325 
333  position_type end_position();
334 
342  const_position_type end_position() const;
343 
352  mtm::element_t get_type(const const_position_type& pos) const;
353 
360  mtm::element_t get_type(size_type row, size_type col) const;
361 
373  double get_numeric(size_type row, size_type col) const;
374 
385  double get_numeric(const const_position_type& pos) const;
386 
398  integer_type get_integer(size_type row, size_type col) const;
399 
410  integer_type get_integer(const const_position_type& pos) const;
411 
423  bool get_boolean(size_type row, size_type col) const;
424 
435  bool get_boolean(const const_position_type& pos) const;
436 
446  const string_type& get_string(size_type row, size_type col) const;
447 
456  const string_type& get_string(const const_position_type& pos) const;
457 
468  template<typename _T>
469  _T get(size_type row, size_type col) const;
470 
477  void set_empty(size_type row, size_type col);
478 
490  void set_empty(size_type row, size_type col, size_type length);
491 
499  position_type set_empty(const position_type& pos);
500 
506  void set_column_empty(size_type col);
507 
513  void set_row_empty(size_type row);
514 
522  void set(size_type row, size_type col, double val);
523 
532  position_type set(const position_type& pos, double val);
533 
541  void set(size_type row, size_type col, bool val);
542 
551  position_type set(const position_type& pos, bool val);
552 
560  void set(size_type row, size_type col, const string_type& str);
561 
570  position_type set(const position_type& pos, const string_type& str);
571 
579  void set(size_type row, size_type col, integer_type val);
580 
589  position_type set(const position_type& pos, integer_type val);
590 
607  template<typename _T>
608  void set(size_type row, size_type col, const _T& it_begin, const _T& it_end);
609 
624  template<typename _T>
625  position_type set(const position_type& pos, const _T& it_begin, const _T& it_end);
626 
638  template<typename _T>
639  void set_column(size_type col, const _T& it_begin, const _T& it_end);
640 
647  size_pair_type size() const;
648 
655 
666  void copy(const multi_type_matrix& src);
667 
679  template<typename _T>
680  void copy(size_type rows, size_type cols, const _T& it_begin, const _T& it_end);
681 
692  void resize(size_type rows, size_type cols);
693 
703  template<typename _T>
704  void resize(size_type rows, size_type cols, const _T& value);
705 
709  void clear();
710 
718  bool numeric() const;
719 
725  bool empty() const;
726 
730  void swap(multi_type_matrix& r);
731 
740  template<typename FuncT>
741  FuncT walk(FuncT func) const;
742 
759  template<typename FuncT>
760  FuncT walk(FuncT func, const size_pair_type& start, const size_pair_type& end) const;
761 
772  template<typename FuncT>
773  FuncT walk(FuncT func, const multi_type_matrix& right) const;
774 
793  template<typename FuncT>
794  FuncT walk(
795  FuncT func, const multi_type_matrix& right, const size_pair_type& start, const size_pair_type& end) const;
796 
797 #ifdef MDDS_MULTI_TYPE_MATRIX_DEBUG
798  void dump() const
799  {
800  m_store.dump_blocks(std::cout);
801  }
802 #endif
803 
804 private:
815  inline size_type get_pos(size_type row, size_type col) const
816  {
817  return m_size.row * col + row;
818  }
819 
820  inline size_type get_pos(const const_position_type& pos) const
821  {
822  return pos.first->position + pos.second;
823  }
824 
825 private:
826  store_type m_store;
827  size_pair_type m_size;
828 };
829 
830 } // namespace mdds
831 
832 #include "multi_type_matrix_def.inl"
_T get(size_type row, size_type col) const
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:90
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:76
Definition: multi_type_matrix.hpp:83
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:706
size_pair_type matrix_position(const const_position_type &pos) const
void copy(const multi_type_matrix &src)
multi_type_matrix() noexcept(nothrow_default_constructible_v)
Definition: multi_type_matrix.hpp:52
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:55
Definition: cref_wrapper.hpp:12
void set_row_empty(size_type row)
Definition: block_funcs.hpp:42
Definition: types.hpp:134
position_type position(size_type row, size_type col)
Definition: multi_type_matrix.hpp:34
Definition: main.hpp:49
Definition: multi_type_matrix.hpp:114
void swap(multi_type_matrix &r)