<commit_before>#ifndef MJOLNIR_MATH_MATRIX_HPP
#define MJOLNIR_MATH_MATRIX_HPP
#include <mjolnir/util/type_traits.hpp>
#include <algorithm>
#include <array>
#include <ostream>
#include <cmath>

namespace mjolnir
{
namespace math
{

// matrix type.
//    1   ...   C
//  1 x00 ... x0M    N = R-1
//  . x10 ... x1M    M = C-1
//  .   . ...   .
//  R xN0 ... xNM    R * C matrix
//
// Access by using `operator()` in the following way.
// Matrix<double, 3, 3> m;
// assert(m(1,0) == x10);
// assert(m(2,1) == x21);
//
// Note that the order of `operator[]` is not guaranteed.
// *DO NOT* use `mat[i]` to modify the element.
// It is only for the internal use.
template<typename realT, std::size_t R, std::size_t C>
class Matrix
{
  public:

    static constexpr std::size_t    row_size = R;
    static constexpr std::size_t column_size = C;
    static constexpr std::size_t  total_size = R * C;

    using value_type      = realT;
    using storage_type    = std::array<value_type, total_size>;
    using pointer         = value_type*;
    using const_pointer   = value_type const*;
    using reference       = value_type&;
    using const_reference = value_type const&;
    using size_type       = std::size_t;

  public:
    Matrix() : values_{{}}{}
    ~Matrix() = default;
    Matrix(Matrix const&) = default;
    Matrix(Matrix &&)     = default;
    Matrix& operator=(Matrix const&) = default;
    Matrix& operator=(Matrix &&)     = default;

    template<typename ... Ts, typename std::enable_if<
        sizeof...(Ts) == total_size, std::nullptr_t>::type = nullptr>
    Matrix(Ts&& ... vs) noexcept: values_{{static_cast<value_type>(vs)...}}
    {
        static_assert(sizeof...(Ts) == total_size, "");
        static_assert(conjunction<
                std::is_convertible<Ts, value_type> ...>::value, "");
    }

    template<typename T>
    Matrix(const std::array<T, total_size>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] = rhs[i];}
    }
    template<typename T>
    Matrix(const Matrix<T, R, C>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] = rhs[i];}
    }

    template<typename T>
    Matrix& operator=(const Matrix<T, R, C>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] = rhs[i];}
        return *this;
    }

    template<typename T>
    Matrix& operator+=(const Matrix<T, R, C>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] += rhs[i];}
        return *this;
    }
    template<typename T>
    Matrix& operator-=(const Matrix<T, R, C>& rhs) noexcept<commit_msg>feat: add Matrix::ctor from toml::value<commit_after>#ifndef MJOLNIR_MATH_MATRIX_HPP
#define MJOLNIR_MATH_MATRIX_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/util/type_traits.hpp>
#include <algorithm>
#include <array>
#include <ostream>
#include <cmath>

namespace mjolnir
{
namespace math
{

// matrix type.
//    1   ...   C
//  1 x00 ... x0M    N = R-1
//  . x10 ... x1M    M = C-1
//  .   . ...   .
//  R xN0 ... xNM    R * C matrix
//
// Access by using `operator()` in the following way.
// Matrix<double, 3, 3> m;
// assert(m(1,0) == x10);
// assert(m(2,1) == x21);
//
// Note that the order of `operator[]` is not guaranteed.
// *DO NOT* use `mat[i]` to modify the element.
// It is only for the internal use.
template<typename realT, std::size_t R, std::size_t C>
class Matrix
{
  public:

    static constexpr std::size_t    row_size = R;
    static constexpr std::size_t column_size = C;
    static constexpr std::size_t  total_size = R * C;

    using value_type      = realT;
    using storage_type    = std::array<value_type, total_size>;
    using pointer         = value_type*;
    using const_pointer   = value_type const*;
    using reference       = value_type&;
    using const_reference = value_type const&;
    using size_type       = std::size_t;

  public:
    Matrix() : values_{{}}{}
    ~Matrix() = default;
    Matrix(Matrix const&) = default;
    Matrix(Matrix &&)     = default;
    Matrix& operator=(Matrix const&) = default;
    Matrix& operator=(Matrix &&)     = default;

    template<typename ... Ts, typename std::enable_if<
        sizeof...(Ts) == total_size, std::nullptr_t>::type = nullptr>
    Matrix(Ts&& ... vs) noexcept: values_{{static_cast<value_type>(vs)...}}
    {
        static_assert(sizeof...(Ts) == total_size, "");
        static_assert(conjunction<
                std::is_convertible<Ts, value_type> ...>::value, "");
    }

    template<typename Com, template<typename ...> class Tab,
                           template<typename ...> class Arr>
    Matrix(const toml::basic_value<Com, Tab, Arr>& tml)
    {
        values_ = toml::get<storage_type>(tml);
    }

    template<typename T>
    Matrix(const std::array<T, total_size>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] = rhs[i];}
    }
    template<typename T>
    Matrix(const Matrix<T, R, C>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] = rhs[i];}
    }

    template<typename T>
    Matrix& operator=(const Matrix<T, R, C>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] = rhs[i];}
        return *this;
    }

    template<typename T>
    Matrix& operator+=(const Matrix<T, R, C>& rhs) noexcept
    {
        static_assert(std::is_convertible<T, value_type>::value, "");
        for(std::size_t i=0; i<total_size; ++i){this->values_[i] += rhs[i];}
        return *this;
    }
    template<typename T>
    Matrix& operator-=(const Matrix<T, R, C>& rhs) noexcept
{'fraction_non_alphanumeric': 0.1642496333713541, 'fraction_numerical': 0.008147303242626691, 'mean_word_length': 2.899618805590851, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '82205', 'n_tokens_mistral': 2182, 'n_tokens_neox': 2130, 'n_words': 490}