C++ lambda powered matrix
#pragma once | |
// (c) 2019-2020 by dbj@dbj.org | |
// License: CC BY SA 4.0 | |
#include <iomanip> // setw | |
#include <sstream> | |
#include <array> | |
#include <cassert> | |
#include <string> | |
#include <vector> | |
namespace dbj::mtx { | |
enum class version { major = 5, minor = 0, patch = 0 }; | |
template< typename T, size_t len_ > | |
inline constexpr auto arr_stack() { return std::array<T, len_>{ {}}; } | |
template< typename T, size_t len_ > | |
inline std::vector<T> arr_heap() { return std::vector<T>(len_); } | |
template< typename T, size_t rows, size_t cols, typename F > | |
inline constexpr auto mx(F source_) | |
{ | |
return[arry = source_()] | |
(size_t row_, size_t col_) /*constexpr*/ mutable->T& | |
{ | |
assert(row_ <= rows); | |
assert(col_ <= cols); | |
return arry[row_ * rows + col_]; | |
}; | |
} // mx | |
#undef dbj_mx_make | |
#undef dbj_mx_make_heap | |
#undef dbj_mx_make_stack | |
#define dbj_mx_make(T, R, C, K) dbj::mtx::mx<T, R, C>(dbj::mtx::K<T, R * C>) | |
#define dbj_mx_make_heap(T,R,C) dbj_mx_make(T, R, C, arr_heap) | |
#define dbj_mx_make_stack(T,R,C) dbj_mx_make(T, R, C, arr_stack) | |
/// | |
/// Testing | |
/// | |
#ifdef DBJ_MTX_TESTING | |
inline auto changer = []( auto matrix_, size_t row_, size_t col_, auto value_) { | |
matrix_(row_, col_) = value_; | |
return matrix_; | |
}; | |
// print to buffer | |
inline auto | |
printer = [](auto matrix_, size_t width_, size_t height_) | |
-> std::string { | |
using namespace std; | |
std::ostringstream rez_; | |
for (size_t row_ = 0; row_ < width_; row_++) { | |
rez_ << endl << "{"; | |
for (size_t col_ = 0; col_ < height_; col_++) { | |
rez_ << setw(3) << matrix_(row_, col_) << " "; | |
} | |
rez_ << "}"; | |
} | |
rez_ << endl; | |
return rez_.str(); | |
}; | |
/// | |
/// log callback signature: | |
/// void (*)( std::string_view ) | |
/// | |
template<typename log_callback > | |
inline void test_dbj_matrix_creation( log_callback log ) | |
{ | |
using namespace dbj::mtx; | |
using namespace std; | |
constexpr size_t width_ = 3; // 0,1,2 | |
constexpr size_t height_ = 3; // 0,1,2 | |
constexpr size_t last_col_ = width_ - 1; // 0,1,2 | |
constexpr size_t last_row_ = height_ - 1; // 0,1,2 | |
// test move in, move out and the rest | |
auto reporter = [&](auto matrix_, const char* prompt_) { | |
string report = prompt_ + | |
printer(changer(matrix_, last_col_, last_row_, 42), width_, height_); | |
log(report); | |
return matrix_; | |
}; | |
auto mxs = reporter(dbj_mx_make_stack(int, width_, height_), | |
"\n matrix_on_stack \n" ); | |
auto mxh = reporter(dbj_mx_make_heap(int, width_, height_), | |
"\n matrix_on_heap \n"); | |
} | |
#endif // DBJ_MTX_TESTING | |
} // dbj::mtx |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
5.0.0 is "dramatic" change. Had to use
std::vector
for heap based matrix after all.std::unique_ptr
disables ability to copy andstd::shared_ptr
is abomination.