add matrix and matrix log
This commit is contained in:
121
bin/main.cpp
121
bin/main.cpp
@@ -3,65 +3,92 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "string/string.hpp"
|
#include "string/string.hpp"
|
||||||
#include "range/range.hpp"
|
#include "range/range.hpp"
|
||||||
#include "container/container.hpp"
|
#include "container/container.hpp"
|
||||||
#include "logger/logger.hpp"
|
#include "logger/logger.hpp"
|
||||||
|
#include "matrix/matrix.hpp"
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
{// ex: split_str
|
// {// ex: split_str
|
||||||
std::string str { "asdf,qwer,zxcv" };
|
// std::string str { "asdf,qwer,zxcv" };
|
||||||
hack::string::v_str v = hack::string::split_str(str, ',');
|
// hack::string::v_str v = hack::string::split_str(str, ',');
|
||||||
for (const auto& c : v) hack::log()(c);
|
// for (const auto& c : v) hack::log()(c);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// {// ex: within
|
||||||
|
// hack::log()(hack::range::within(12, 34, 12, 23, 31, 17, 22, 33));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// {// ex: vector_multiset
|
||||||
|
// std::vector<std::string> v;
|
||||||
|
// hack::container::vector_multiset(v, "asdf", "qwer", "zcv");
|
||||||
|
// for(const auto& c : v) std::cout << c << std::endl;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// {// ex: set_multiset
|
||||||
|
// std::set<int> s;
|
||||||
|
// hack::container::set_multiset(s, 1, 2, 3, 3, 2, 1);
|
||||||
|
// for(const auto& c : s) std::cout << c << std::endl;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// {// ex: log
|
||||||
|
// hack::log()(1234, "run in main", 1234);
|
||||||
|
// hack::warn(" # ")(1234, "run in main", 1234);
|
||||||
|
// hack::error(" - ")(1234, "run in main", 1234);
|
||||||
|
//
|
||||||
|
// std::string str { "hi" };
|
||||||
|
// hack::log()(str);
|
||||||
|
//
|
||||||
|
// std::vector<std::string> vs { "asdf", "qwer", "zxcv" };
|
||||||
|
// hack::log()("vector", vs, 1, 2, 'a');
|
||||||
|
//
|
||||||
|
// std::list<std::string> ls { "asdf", "qwer", "zxcv" };
|
||||||
|
// hack::log()(vs, ls);
|
||||||
|
//
|
||||||
|
// std::map<int, std::string> m { { 1, "asdf" }, { 2, "qwer" }, { 3, "zxcv" } };
|
||||||
|
// hack::log()(vs, ls, m);
|
||||||
|
//
|
||||||
|
// std::tuple<int, std::string, bool> tp { 1, "tuple test", false };
|
||||||
|
// hack::log()(tp);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// {// ex: matches
|
||||||
|
// std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||||
|
// hack::log()(hack::container::matches(v, 2, 5, 4, 12));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// {// ex: vector_remove_at
|
||||||
|
// std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||||
|
// hack::container::vector_remove_at(v, 3);
|
||||||
|
// hack::log()(v);
|
||||||
|
// }
|
||||||
|
|
||||||
{// ex: within
|
{// ex: matrix
|
||||||
hack::log()(hack::range::within(12, 34, 12, 23, 31, 17, 22, 33));
|
hack::matrix<int, 3> m_int;
|
||||||
}
|
hack::matrix<int, 3> m_int_c;
|
||||||
|
hack::matrix<float, 3> m_float;
|
||||||
|
|
||||||
{// ex: vector_multiset
|
m_int[0][0][0] = 123;
|
||||||
std::vector<std::string> v;
|
m_int[0][0][1] = 23;
|
||||||
hack::container::vector_multiset(v, "asdf", "qwer", "zcv");
|
m_int[0][0][2] = 43;
|
||||||
for(const auto& c : v) std::cout << c << std::endl;
|
m_int_c[0][0][0] = 123;
|
||||||
}
|
m_float[0][0][0] = 123.123;
|
||||||
|
|
||||||
{// ex: set_multiset
|
auto i = m_int[0][0][0];
|
||||||
std::set<int> s;
|
auto f = m_float[0][0][0];
|
||||||
hack::container::set_multiset(s, 1, 2, 3, 3, 2, 1);
|
|
||||||
for(const auto& c : s) std::cout << c << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
{// ex: log
|
hack::log()("m_int", i);
|
||||||
hack::log()(1234, "run in main", 1234);
|
hack::log()("m_float", f);
|
||||||
hack::warn(" # ")(1234, "run in main", 1234);
|
|
||||||
hack::error(" - ")(1234, "run in main", 1234);
|
|
||||||
|
|
||||||
std::string str { "hi" };
|
hack::log("")("compare (true): ", m_int == m_int_c);
|
||||||
hack::log()(str);
|
hack::log("")("compare (false): ", m_int == m_float);
|
||||||
|
hack::log("")(m_int);
|
||||||
std::vector<std::string> vs { "asdf", "qwer", "zxcv" };
|
|
||||||
hack::log()("vector", vs, 1, 2, 'a');
|
|
||||||
|
|
||||||
std::list<std::string> ls { "asdf", "qwer", "zxcv" };
|
|
||||||
hack::log()(vs, ls);
|
|
||||||
|
|
||||||
std::map<int, std::string> m { { 1, "asdf" }, { 2, "qwer" }, { 3, "zxcv" } };
|
|
||||||
hack::log()(vs, ls, m);
|
|
||||||
|
|
||||||
std::tuple<int, std::string, bool> tp { 1, "tuple test", false };
|
|
||||||
hack::log()(tp);
|
|
||||||
}
|
|
||||||
|
|
||||||
{// ex: matches
|
|
||||||
std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
||||||
hack::log()(hack::container::matches(v, 2, 5, 4, 12));
|
|
||||||
}
|
|
||||||
|
|
||||||
{// ex: vector_remove_at
|
|
||||||
std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
|
||||||
hack::container::vector_remove_at(v, 3);
|
|
||||||
hack::log()(v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ deps += string_dep
|
|||||||
deps += range_dep
|
deps += range_dep
|
||||||
deps += container_dep
|
deps += container_dep
|
||||||
deps += logger_dep
|
deps += logger_dep
|
||||||
|
deps += matrix_dep
|
||||||
|
|
||||||
executable(
|
executable(
|
||||||
'hack', 'main.cpp',
|
'hack', 'main.cpp',
|
||||||
|
|||||||
12
meson.build
12
meson.build
@@ -7,13 +7,21 @@ project(
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_project_arguments (
|
add_project_arguments (
|
||||||
'-pedantic',
|
'-Wpedantic',
|
||||||
|
'-Wshadow',
|
||||||
'-Wno-comment',
|
'-Wno-comment',
|
||||||
'-Wno-gnu-zero-variadic-macro-arguments',
|
#'-Wno-gnu-zero-variadic-macro-arguments',
|
||||||
'-Wunused-but-set-variable',
|
'-Wunused-but-set-variable',
|
||||||
language: 'cpp'
|
language: 'cpp'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
compiler = meson.get_compiler('cpp')
|
||||||
|
if compiler.get_id() == 'gcc'
|
||||||
|
message('Compiler: GCC')
|
||||||
|
elif compiler.get_id() == 'clang'
|
||||||
|
message('Compiler: LLVM/clang')
|
||||||
|
endif
|
||||||
|
|
||||||
args = []
|
args = []
|
||||||
deps = []
|
deps = []
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,17 @@ namespace hack::concepts
|
|||||||
std::tuple_cat(t, std::make_tuple(1, "tuple"));
|
std::tuple_cat(t, std::make_tuple(1, "tuple"));
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<typename T>
|
||||||
concept is_string = std::is_convertible_v<T, std::string_view>;
|
concept is_string = std::is_convertible_v<T, std::string_view>;
|
||||||
|
|
||||||
template<class T>
|
template<typename T>
|
||||||
concept is_map = std::same_as<T, std::map<typename T::key_type, typename T::mapped_type, typename T::key_compare, typename T::allocator_type>> ||
|
concept is_map = std::same_as<T, std::map<typename T::key_type, typename T::mapped_type, typename T::key_compare, typename T::allocator_type>> ||
|
||||||
std::same_as<T, std::unordered_map<typename T::key_type, typename T::mapped_type, typename T::hasher, typename T::key_equal, typename T::allocator_type>>;
|
std::same_as<T, std::unordered_map<typename T::key_type, typename T::mapped_type, typename T::hasher, typename T::key_equal, typename T::allocator_type>>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept not_defined = !std::enable_if_t<!(std::integral<T> ||
|
||||||
|
is_sequence_container<T> ||
|
||||||
|
is_map<T> ||
|
||||||
|
is_tuple<T> ||
|
||||||
|
is_string<T>), bool>() == true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ namespace hack::iterators
|
|||||||
using ostream_type = std::basic_ostream<char, traits>;
|
using ostream_type = std::basic_ostream<char, traits>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::basic_ostream<char, traits>* os;
|
std::basic_ostream<char, traits>* os_;
|
||||||
const std::string devider = ", ";
|
const std::string devider_ = ", ";
|
||||||
std::size_t size;
|
std::size_t size_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
associative_ostream_iterator(std::size_t size, ostream_type& s) : os { &s }, size { size } { }
|
associative_ostream_iterator(std::size_t size, ostream_type& os) : os_ { &os }, size_ { size } { }
|
||||||
|
|
||||||
auto& operator=(T const& item)
|
auto& operator=(T const& item)
|
||||||
{
|
{
|
||||||
--size;
|
--size_;
|
||||||
const auto& [key, value] = item;
|
const auto& [key, value] = item;
|
||||||
*os << "{ " << key << ":" << value << " }" << (size != 0 ? devider : "");
|
*os_ << "{ " << key << ":" << value << " }" << (size_ != 0 ? devider_ : "");
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ namespace hack::iterators
|
|||||||
using ostream_type = std::basic_ostream<char, traits>;
|
using ostream_type = std::basic_ostream<char, traits>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::basic_ostream<char, traits>* os;
|
std::basic_ostream<char, traits>* os_;
|
||||||
const std::string devider = ", ";
|
const std::string devider_ = ", ";
|
||||||
std::size_t size;
|
std::size_t size_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
sequence_ostream_iterator(std::size_t size, ostream_type& s) : os { &s }, size { size } { }
|
sequence_ostream_iterator(std::size_t size, ostream_type& os) : os_ { &os }, size_ { size } { }
|
||||||
|
|
||||||
auto& operator=(T const& item)
|
auto& operator=(T const& item)
|
||||||
{
|
{
|
||||||
--size;
|
--size_;
|
||||||
*os << item << (size != 0 ? devider : "");
|
*os_ << item << (size_ != 0 ? devider_ : "");
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,22 @@
|
|||||||
|
|
||||||
namespace hack
|
namespace hack
|
||||||
{
|
{
|
||||||
std::string log::devider = " ";
|
std::string log::devider_ = " ";
|
||||||
int log::count = 0;
|
int log::count_ = 0;
|
||||||
|
|
||||||
log::log(const std::string devider, std::experimental::source_location location) : location { location }
|
log::log(const std::string devider, std::experimental::source_location location) : location_ { location }
|
||||||
{
|
{
|
||||||
this->devider = devider;
|
this->devider_ = devider;
|
||||||
}
|
}
|
||||||
|
|
||||||
warn::warn(const std::string devider, std::experimental::source_location location) : location { location }
|
warn::warn(const std::string devider, std::experimental::source_location location) : location_ { location }
|
||||||
{
|
{
|
||||||
this->devider = devider;
|
this->devider_ = devider;
|
||||||
}
|
}
|
||||||
|
|
||||||
error::error(const std::string devider, std::experimental::source_location location) : location { location }
|
error::error(const std::string devider, std::experimental::source_location location) : location_ { location }
|
||||||
{
|
{
|
||||||
this->devider = devider;
|
this->devider_ = devider;
|
||||||
}
|
}
|
||||||
|
|
||||||
void log::print() { std::cout << std::endl; }
|
void log::print() { std::cout << std::endl; }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "concepts/concepts.hpp"
|
#include "concepts/concepts.hpp"
|
||||||
#include "iterators/sequence_ostream_iterator.hpp"
|
#include "iterators/sequence_ostream_iterator.hpp"
|
||||||
#include "iterators/associative_ostream_iterator.hpp"
|
#include "iterators/associative_ostream_iterator.hpp"
|
||||||
|
#include "matrix/matrix.hpp"
|
||||||
|
|
||||||
namespace hack
|
namespace hack
|
||||||
{
|
{
|
||||||
@@ -21,17 +22,17 @@ namespace hack
|
|||||||
void operator() (const Args&... args)
|
void operator() (const Args&... args)
|
||||||
{
|
{
|
||||||
std::cout << make_type_view
|
std::cout << make_type_view
|
||||||
<< location.file_name() << ":" << view::color::reset
|
<< location_.file_name() << ":" << view::color::reset
|
||||||
<< view::color::italic << view::color::yellow << location.function_name() << "()" << view::color::reset
|
<< view::color::italic << view::color::yellow << location_.function_name() << "()" << view::color::reset
|
||||||
<< view::color::bold << view::color::blue << "[" << location.line() << "]" << view::color::reset << ": ";
|
<< view::color::bold << view::color::blue << "[" << location_.line() << "]" << view::color::reset << ": ";
|
||||||
count = sizeof...(Args);
|
count_ = sizeof...(Args);
|
||||||
print(args...);
|
print(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::experimental::source_location location;
|
std::experimental::source_location location_;
|
||||||
static int count;
|
static int count_;
|
||||||
static std::string devider;
|
static std::string devider_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void print();
|
static void print();
|
||||||
@@ -45,7 +46,7 @@ namespace hack
|
|||||||
template<typename T, typename... Args>
|
template<typename T, typename... Args>
|
||||||
static void print(const T& data, const Args&... args)
|
static void print(const T& data, const Args&... args)
|
||||||
{
|
{
|
||||||
count--;
|
count_--;
|
||||||
print_t(data);
|
print_t(data);
|
||||||
print(args...);
|
print(args...);
|
||||||
}
|
}
|
||||||
@@ -53,13 +54,13 @@ namespace hack
|
|||||||
template<concepts::is_string T>
|
template<concepts::is_string T>
|
||||||
static void print_t(const T& data)
|
static void print_t(const T& data)
|
||||||
{
|
{
|
||||||
std::cout << data << (count != 0 ? devider : "");
|
std::cout << data << (count_ != 0 ? devider_ : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::integral T>
|
template<std::integral T>
|
||||||
static void print_t(const T& data)
|
static void print_t(const T& data)
|
||||||
{
|
{
|
||||||
std::cout << data << (count != 0 ? devider : "");
|
std::cout << data << (count_ != 0 ? devider_ : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::is_sequence_container T>
|
template<concepts::is_sequence_container T>
|
||||||
@@ -67,7 +68,7 @@ namespace hack
|
|||||||
{
|
{
|
||||||
std::cout << "{ ";
|
std::cout << "{ ";
|
||||||
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
|
std::copy(data.cbegin(), data.cend(), iterators::sequence_ostream_iterator<typename T::value_type>(data.size(), std::cout));
|
||||||
std::cout << " }" << (count != 0 ? devider : "");
|
std::cout << " }" << (count_ != 0 ? devider_ : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::is_map T>
|
template<concepts::is_map T>
|
||||||
@@ -75,7 +76,7 @@ namespace hack
|
|||||||
{
|
{
|
||||||
std::cout << "{";
|
std::cout << "{";
|
||||||
std::copy(data.cbegin(), data.cend(), iterators::associative_ostream_iterator<typename T::value_type>(data.size(), std::cout));
|
std::copy(data.cbegin(), data.cend(), iterators::associative_ostream_iterator<typename T::value_type>(data.size(), std::cout));
|
||||||
std::cout << "}" << (count != 0 ? devider : "");
|
std::cout << "}" << (count_ != 0 ? devider_ : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<concepts::is_tuple T, typename std::size_t... idx>
|
template<concepts::is_tuple T, typename std::size_t... idx>
|
||||||
@@ -88,16 +89,27 @@ namespace hack
|
|||||||
static void print_t(const T& data, std::index_sequence<idx...>)
|
static void print_t(const T& data, std::index_sequence<idx...>)
|
||||||
{
|
{
|
||||||
std::cout << "{ ";
|
std::cout << "{ ";
|
||||||
((std::cout << std::get<idx>(data) << (idx != std::tuple_size<T>::value - 1 ? devider : "")), ...);
|
((std::cout << std::get<idx>(data) << (idx != std::tuple_size<T>::value - 1 ? devider_ : "")), ...);
|
||||||
std::cout << " }" << (count != 0 ? devider : "");
|
std::cout << " }" << (count_ != 0 ? devider_ : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <class, class> typename Function, class ...Args>
|
template<typename T, std::size_t demention>
|
||||||
auto LogCall(std::string fun_name, Function<Args...> fun, std::string fun_param = "", Args... args)
|
static void print_t(const matrix<T, demention>& data)
|
||||||
{
|
{
|
||||||
auto temp{ fun(args...) };
|
std::size_t index = data.size();
|
||||||
std::cout << fun_name << "of" << fun_param << "/t -> /t" << temp << '\n';
|
for (auto& r : data)
|
||||||
return temp;
|
{
|
||||||
|
index--;
|
||||||
|
std::cout << "{ ";
|
||||||
|
print_t(std::get<demention>(r));
|
||||||
|
std::cout << " }" << (index != 0 ? ", " : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<concepts::not_defined T>
|
||||||
|
static void print_t(const T& data)
|
||||||
|
{
|
||||||
|
std::cout << data << (count_ != 0 ? devider_ : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class warn;
|
friend class warn;
|
||||||
@@ -116,15 +128,15 @@ namespace hack
|
|||||||
void operator() (const Args&... args)
|
void operator() (const Args&... args)
|
||||||
{
|
{
|
||||||
std::cout << make_type_view
|
std::cout << make_type_view
|
||||||
<< location.file_name() << ":" << view::color::reset
|
<< location_.file_name() << ":" << view::color::reset
|
||||||
<< view::color::italic << view::color::yellow << location.function_name() << "()" << view::color::reset
|
<< view::color::italic << view::color::yellow << location_.function_name() << "()" << view::color::reset
|
||||||
<< view::color::bold << view::color::blue << "[" << location.line() << "]" << view::color::reset << ": ";
|
<< view::color::bold << view::color::blue << "[" << location_.line() << "]" << view::color::reset << ": ";
|
||||||
count = sizeof...(Args);
|
count_ = sizeof...(Args);
|
||||||
print(args...);
|
print(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::experimental::source_location location;
|
std::experimental::source_location location_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::ostream& make_type_view(std::ostream &os)
|
static std::ostream& make_type_view(std::ostream &os)
|
||||||
@@ -146,15 +158,15 @@ namespace hack
|
|||||||
void operator() (const Args&... args)
|
void operator() (const Args&... args)
|
||||||
{
|
{
|
||||||
std::cout << make_type_view
|
std::cout << make_type_view
|
||||||
<< location.file_name() << ":" << view::color::reset
|
<< location_.file_name() << ":" << view::color::reset
|
||||||
<< view::color::italic << view::color::yellow << location.function_name() << "()" << view::color::reset
|
<< view::color::italic << view::color::yellow << location_.function_name() << "()" << view::color::reset
|
||||||
<< view::color::bold << view::color::blue << "[" << location.line() << "]" << view::color::reset << ": ";
|
<< view::color::bold << view::color::blue << "[" << location_.line() << "]" << view::color::reset << ": ";
|
||||||
count = sizeof...(Args);
|
count_ = sizeof...(Args);
|
||||||
print(args...);
|
print(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::experimental::source_location location;
|
std::experimental::source_location location_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::ostream& make_type_view(std::ostream &os)
|
static std::ostream& make_type_view(std::ostream &os)
|
||||||
|
|||||||
143
src/matrix/matrix.hpp
Normal file
143
src/matrix/matrix.hpp
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace hack::matrix_utils
|
||||||
|
{
|
||||||
|
template<typename T, size_t N>
|
||||||
|
struct generate_tuple
|
||||||
|
{
|
||||||
|
using type = decltype(std::tuple_cat(typename generate_tuple<T, N - 1>::type{}, std::make_tuple(T{})));
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct generate_tuple<T, 1>
|
||||||
|
{
|
||||||
|
using type = std::tuple<T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T,typename index_data, typename index_t>
|
||||||
|
class proxy
|
||||||
|
{
|
||||||
|
using next_index_t = decltype(std::tuple_cat(index_t{}, std::make_tuple(std::size_t{})));
|
||||||
|
|
||||||
|
public:
|
||||||
|
proxy(const std::weak_ptr<index_data>& local_storage, const index_t& index) : local_storage_ { local_storage }, index_ { index } {};
|
||||||
|
|
||||||
|
auto operator[](std::size_t index) const
|
||||||
|
{
|
||||||
|
return proxy<T, index_data, next_index_t>{ local_storage_, std::tuple_cat(index_, std::make_tuple(index)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& operator=(const T& value)
|
||||||
|
{
|
||||||
|
std::shared_ptr<index_data>(local_storage_)->set_value(index_, value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T() const
|
||||||
|
{
|
||||||
|
return std::shared_ptr<index_data>(local_storage_)->get_value(index_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::weak_ptr<index_data> local_storage_;
|
||||||
|
index_t index_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace hack
|
||||||
|
{
|
||||||
|
template <typename... T, std::size_t... I>
|
||||||
|
auto subtuple_s(const std::tuple<T...>& t, std::index_sequence<I...>)
|
||||||
|
{
|
||||||
|
return std::make_tuple(std::get<I>(t)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
auto subtuple(const std::tuple<T...>& t)
|
||||||
|
{
|
||||||
|
return subtuple_s(t, std::make_index_sequence<sizeof...(T) - 1>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, std::size_t dimensions>
|
||||||
|
class matrix
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
matrix() : local_storage_ { new index_data{} } { }
|
||||||
|
|
||||||
|
auto operator[](std::size_t index)
|
||||||
|
{
|
||||||
|
return matrix_utils::proxy<T, index_data, std::tuple<std::size_t>>{ local_storage_, std::make_tuple(index) };
|
||||||
|
}
|
||||||
|
|
||||||
|
int size() const
|
||||||
|
{
|
||||||
|
return local_storage_->values.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto begin() noexcept
|
||||||
|
{
|
||||||
|
return local_storage_->values.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto begin() const noexcept
|
||||||
|
{
|
||||||
|
return local_storage_->values.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end() noexcept
|
||||||
|
{
|
||||||
|
return local_storage_->values.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto end() const noexcept
|
||||||
|
{
|
||||||
|
return local_storage_->values.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cbegin() const noexcept
|
||||||
|
{
|
||||||
|
return local_storage_->values.cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cend() const noexcept
|
||||||
|
{
|
||||||
|
return local_storage_->values.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct index_data
|
||||||
|
{
|
||||||
|
using index_t = typename matrix_utils::generate_tuple<std::size_t, dimensions>::type;
|
||||||
|
using index_data_t = std::vector<decltype(std::tuple_cat(index_t{}, std::make_tuple(T{})))>;
|
||||||
|
|
||||||
|
void set_value(const index_t& index, const T& v)
|
||||||
|
{
|
||||||
|
auto value = std::tuple_cat(index, std::make_tuple(v));
|
||||||
|
values.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_value(const index_t& index)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(values.begin(), values.end(), [&](auto a) { return subtuple(a) == index; });
|
||||||
|
return std::get<dimensions>(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
index_data_t values;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<index_data> local_storage_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U, std::size_t N>
|
||||||
|
bool operator==(const matrix<T, N>& lhs, const matrix<U, N>& rhs)
|
||||||
|
{
|
||||||
|
return std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/matrix/meson.build
Normal file
14
src/matrix/meson.build
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
headers = ['matrix.hpp']
|
||||||
|
sources = []
|
||||||
|
|
||||||
|
lib = library(
|
||||||
|
'matrix',
|
||||||
|
include_directories : inc,
|
||||||
|
install : true,
|
||||||
|
sources: [headers, sources]
|
||||||
|
)
|
||||||
|
|
||||||
|
matrix_dep = declare_dependency(
|
||||||
|
include_directories: inc,
|
||||||
|
link_with: lib
|
||||||
|
)
|
||||||
@@ -7,3 +7,4 @@ subdir('string')
|
|||||||
subdir('range')
|
subdir('range')
|
||||||
subdir('container')
|
subdir('container')
|
||||||
subdir('logger')
|
subdir('logger')
|
||||||
|
subdir('matrix')
|
||||||
|
|||||||
Reference in New Issue
Block a user