Loading...
Searching...
No Matches
multi_type_matrix.hpp
// SPDX-FileCopyrightText: 2012 - 2025 Kohei Yoshida
//
// SPDX-License-Identifier: MIT
#pragma once
#ifdef MDDS_MULTI_TYPE_MATRIX_DEBUG
#ifndef MDDS_MULTI_TYPE_VECTOR_DEBUG
#define MDDS_MULTI_TYPE_VECTOR_DEBUG 1
#endif
#endif
#include "multi_type_vector.hpp"
namespace mdds {
namespace mtm {
enum element_t
{
element_empty = mdds::mtv::element_type_empty,
element_boolean = mdds::mtv::element_type_boolean,
element_string = mdds::mtv::element_type_string,
element_numeric = mdds::mtv::element_type_double,
element_integer = mdds::mtv::element_type_int32
};
struct std_string_traits
{
typedef mdds::mtv::int32_element_block integer_element_block;
typedef mdds::mtv::string_element_block string_element_block;
};
} // namespace mtm
template<typename Traits>
class multi_type_matrix
{
using traits_type = Traits;
public:
using string_block_type = typename traits_type::string_element_block;
using integer_block_type = typename traits_type::integer_element_block;
using string_type = typename string_block_type::value_type;
using integer_type = typename integer_block_type::value_type;
using size_type = std::size_t;
private:
struct mtv_traits : public mdds::mtv::default_traits
{
using block_funcs = mdds::mtv::element_block_funcs<
mdds::mtv::boolean_element_block, mdds::mtv::int8_element_block, mdds::mtv::double_element_block,
typename traits_type::string_element_block, typename traits_type::integer_element_block>;
};
using store_type = mdds::multi_type_vector<mtv_traits>;
public:
using position_type = typename store_type::position_type;
using const_position_type = typename store_type::const_position_type;
using element_block_type = typename mtv::base_element_block;
using boolean_block_type = typename mtv::boolean_element_block;
using numeric_block_type = typename mtv::double_element_block;
struct size_pair_type
{
size_type row;
size_type column;
size_pair_type() noexcept(std::is_fundamental_v<size_type>) : row(0), column(0)
{}
size_pair_type(size_type _row, size_type _column) noexcept(std::is_fundamental_v<size_type>)
: row(_row), column(_column)
{}
size_pair_type(std::initializer_list<size_type> vs)
{
if (vs.size() != 2)
throw invalid_arg_error("size_pair_type requires exactly 2 elements.");
size_type* ptrs[2] = {&row, &column};
size_type** p = ptrs;
for (size_type v : vs)
**p++ = v;
}
bool operator==(const size_pair_type& r) const noexcept(std::is_fundamental_v<size_type>)
{
return row == r.row && column == r.column;
}
bool operator!=(const size_pair_type& r) const noexcept(std::is_fundamental_v<size_type>)
{
return !operator==(r);
}
};
struct element_block_node_type
{
friend class multi_type_matrix;
mtm::element_t type;
size_type offset;
size_type size;
const element_block_type* data;
element_block_node_type() noexcept(std::is_fundamental_v<size_type>);
element_block_node_type(const element_block_node_type& other) noexcept(std::is_fundamental_v<size_type>);
template<typename _Blk>
typename _Blk::const_iterator begin() const;
template<typename _Blk>
typename _Blk::const_iterator end() const;
private:
void assign(const const_position_type& pos, size_type section_size);
};
static mtm::element_t to_mtm_type(mdds::mtv::element_t mtv_type)
{
switch (mtv_type)
{
case string_block_type::block_type:
return mdds::mtm::element_string;
case integer_block_type::block_type:
return mdds::mtm::element_integer;
case mdds::mtv::element_type_double:
case mdds::mtv::element_type_boolean:
case mdds::mtv::element_type_empty:
// These types share the same numeric values.
return static_cast<mtm::element_t>(mtv_type);
default:
throw type_error("multi_type_matrix: unknown element type.");
}
}
private:
template<typename FuncT>
struct walk_func
{
FuncT& m_func;
walk_func(FuncT& func) noexcept : m_func(func)
{}
void operator()(const typename store_type::const_iterator::value_type& mtv_node)
{
element_block_node_type mtm_node;
mtm_node.type = to_mtm_type(mtv_node.type);
mtm_node.size = mtv_node.size;
mtm_node.data = mtv_node.data;
m_func(mtm_node);
}
};
static constexpr bool nothrow_default_constructible_v =
std::is_nothrow_default_constructible_v<store_type> && std::is_nothrow_default_constructible_v<size_pair_type>;
static constexpr bool nothrow_eq_comparable_v =
noexcept(std::declval<store_type>() == std::declval<store_type>()) &&
noexcept(std::declval<size_pair_type>() == std::declval<size_pair_type>());
public:
static position_type next_position(const position_type& pos);
static const_position_type next_position(const const_position_type& pos);
multi_type_matrix() noexcept(nothrow_default_constructible_v);
multi_type_matrix(size_type rows, size_type cols);
template<typename _T>
multi_type_matrix(size_type rows, size_type cols, const _T& value);
template<typename _T>
multi_type_matrix(size_type rows, size_type cols, const _T& it_begin, const _T& it_end);
multi_type_matrix(const multi_type_matrix& other);
multi_type_matrix(multi_type_matrix&& other) = default;
~multi_type_matrix() = default;
bool operator==(const multi_type_matrix& other) const noexcept(nothrow_eq_comparable_v);
bool operator!=(const multi_type_matrix& other) const noexcept(nothrow_eq_comparable_v);
multi_type_matrix& operator=(const multi_type_matrix& other) = default;
multi_type_matrix& operator=(multi_type_matrix&& other) = default;
position_type position(size_type row, size_type col);
position_type position(const position_type& pos_hint, size_type row, size_type col);
const_position_type position(size_type row, size_type col) const;
const_position_type position(const const_position_type& pos_hint, size_type row, size_type col) const;
size_pair_type matrix_position(const const_position_type& pos) const;
position_type end_position();
const_position_type end_position() const;
mtm::element_t get_type(const const_position_type& pos) const;
mtm::element_t get_type(size_type row, size_type col) const;
double get_numeric(size_type row, size_type col) const;
double get_numeric(const const_position_type& pos) const;
integer_type get_integer(size_type row, size_type col) const;
integer_type get_integer(const const_position_type& pos) const;
bool get_boolean(size_type row, size_type col) const;
bool get_boolean(const const_position_type& pos) const;
const string_type& get_string(size_type row, size_type col) const;
const string_type& get_string(const const_position_type& pos) const;
template<typename _T>
_T get(size_type row, size_type col) const;
void set_empty(size_type row, size_type col);
void set_empty(size_type row, size_type col, size_type length);
position_type set_empty(const position_type& pos);
void set_column_empty(size_type col);
void set_row_empty(size_type row);
void set(size_type row, size_type col, double val);
position_type set(const position_type& pos, double val);
void set(size_type row, size_type col, bool val);
position_type set(const position_type& pos, bool val);
void set(size_type row, size_type col, const string_type& str);
position_type set(const position_type& pos, const string_type& str);
void set(size_type row, size_type col, integer_type val);
position_type set(const position_type& pos, integer_type val);
template<typename _T>
void set(size_type row, size_type col, const _T& it_begin, const _T& it_end);
template<typename _T>
position_type set(const position_type& pos, const _T& it_begin, const _T& it_end);
template<typename _T>
void set_column(size_type col, const _T& it_begin, const _T& it_end);
size_pair_type size() const;
multi_type_matrix& transpose();
void copy(const multi_type_matrix& src);
template<typename _T>
void copy(size_type rows, size_type cols, const _T& it_begin, const _T& it_end);
void resize(size_type rows, size_type cols);
template<typename _T>
void resize(size_type rows, size_type cols, const _T& value);
void clear();
bool numeric() const;
bool empty() const;
void swap(multi_type_matrix& r);
template<typename FuncT>
FuncT walk(FuncT func) const;
template<typename FuncT>
FuncT walk(FuncT func, const size_pair_type& start, const size_pair_type& end) const;
template<typename FuncT>
FuncT walk(FuncT func, const multi_type_matrix& right) const;
template<typename FuncT>
FuncT walk(
FuncT func, const multi_type_matrix& right, const size_pair_type& start, const size_pair_type& end) const;
#ifdef MDDS_MULTI_TYPE_MATRIX_DEBUG
void dump() const
{
m_store.dump_blocks(std::cout);
}
#endif
private:
inline size_type get_pos(size_type row, size_type col) const
{
return m_size.row * col + row;
}
inline size_type get_pos(const const_position_type& pos) const
{
return pos.first->position + pos.second;
}
private:
store_type m_store;
size_pair_type m_size;
};
} // namespace mdds
#include "multi_type_matrix_def.inl"
mdds::invalid_arg_error
Definition global.hpp:77
mdds::mtv::base_element_block
Definition types.hpp:135
mdds::mtv::soa::multi_type_vector< Traits >::value_type
mdds::detail::mtv::iterator_value_node< multi_type_vector, size_type > value_type
Definition soa/main.hpp:275
mdds::multi_type_matrix::set
void set(size_type row, size_type col, double val)
mdds::multi_type_matrix::get_integer
integer_type get_integer(size_type row, size_type col) const
mdds::multi_type_matrix::set_column_empty
void set_column_empty(size_type col)
mdds::multi_type_matrix::copy
void copy(const multi_type_matrix &src)
mdds::multi_type_matrix::walk
FuncT walk(FuncT func) const
mdds::multi_type_matrix::end_position
position_type end_position()
mdds::multi_type_matrix::matrix_position
size_pair_type matrix_position(const const_position_type &pos) const
mdds::multi_type_matrix::set_empty
void set_empty(size_type row, size_type col)
mdds::multi_type_matrix::swap
void swap(multi_type_matrix &r)
mdds::multi_type_matrix::next_position
static const_position_type next_position(const const_position_type &pos)
mdds::multi_type_matrix::multi_type_matrix
multi_type_matrix() noexcept(nothrow_default_constructible_v)
mdds::multi_type_matrix::empty
bool empty() const
mdds::multi_type_matrix::resize
void resize(size_type rows, size_type cols)
mdds::multi_type_matrix::get_type
mtm::element_t get_type(const const_position_type &pos) const
mdds::multi_type_matrix::clear
void clear()
mdds::multi_type_matrix::transpose
multi_type_matrix & transpose()
mdds::multi_type_matrix::position
position_type position(size_type row, size_type col)
mdds::multi_type_matrix::get_string
const string_type & get_string(size_type row, size_type col) const
mdds::multi_type_matrix::set_row_empty
void set_row_empty(size_type row)
mdds::multi_type_matrix::get_boolean
bool get_boolean(size_type row, size_type col) const
mdds::multi_type_matrix::next_position
static position_type next_position(const position_type &pos)
mdds::multi_type_matrix::numeric
bool numeric() const
mdds::multi_type_matrix::get_numeric
double get_numeric(size_type row, size_type col) const
mdds::multi_type_matrix::get
_T get(size_type row, size_type col) const
mdds::multi_type_matrix::size
size_pair_type size() const
mdds::multi_type_matrix::set_column
void set_column(size_type col, const _T &it_begin, const _T &it_end)
mdds::type_error
Definition global.hpp:91
mdds::mtm::std_string_traits
Definition multi_type_matrix.hpp:35
mdds::mtv::default_traits
Definition util.hpp:56
mdds::mtv::default_traits::block_funcs
element_block_funcs<> block_funcs
Definition util.hpp:82
mdds::mtv::element_block_funcs
Definition block_funcs.hpp:43
mdds::multi_type_matrix::size_pair_type
Definition multi_type_matrix.hpp:84