1 // Copyright Louis Dionne 2013-2017
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
5 #ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
6 #define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
8 #include <boost/hana/all_of.hpp>
9 #include <boost/hana/assert.hpp>
10 #include <boost/hana/at.hpp>
11 #include <boost/hana/drop_front.hpp>
12 #include <boost/hana/front.hpp>
13 #include <boost/hana/functional/on.hpp>
14 #include <boost/hana/functional/partial.hpp>
15 #include <boost/hana/fuse.hpp>
16 #include <boost/hana/length.hpp>
17 #include <boost/hana/mult.hpp>
18 #include <boost/hana/sum.hpp>
19 #include <boost/hana/tuple.hpp>
20 #include <boost/hana/unpack.hpp>
21 #include <boost/hana/value.hpp>
22 #include <boost/hana/zip.hpp>
23 #include <boost/hana/zip_with.hpp>
29 template <unsigned Rows, unsigned Columns>
32 template <unsigned Rows, unsigned Columns, typename Storage>
34 using hana_tag = Matrix<Rows, Columns>;
37 constexpr auto ncolumns() const
38 { return boost::hana::length(boost::hana::front(rows_)); }
40 constexpr auto nrows() const
41 { return boost::hana::length(rows_); }
43 constexpr auto size() const
44 { return nrows() * ncolumns(); }
46 template <typename I, typename J>
47 constexpr decltype(auto) at(I i, J j) const
48 { return boost::hana::at(boost::hana::at(rows_, i), j); }
51 auto row = boost::hana::make_tuple;
53 auto matrix = [](auto&& ...rows) -> decltype(auto) {
54 namespace hana = boost::hana;
55 auto storage = hana::make_tuple(std::forward<decltype(rows)>(rows)...);
56 auto ncolumns = hana::length(hana::front(storage));
57 BOOST_HANA_CONSTANT_CHECK(
58 hana::all_of(hana::drop_front(storage), [&](auto const& row) {
59 return hana::length(row) == ncolumns;
64 sizeof...(rows), hana::value(ncolumns), decltype(storage)
65 >{std::move(storage)};
68 auto vector = boost::hana::on(matrix, row);
72 auto rows = [](auto&& m) -> decltype(auto) {
73 return std::forward<decltype(m)>(m).rows_;
76 auto transpose = [](auto&& m) -> decltype(auto) {
77 return boost::hana::unpack(
78 boost::hana::fuse(boost::hana::zip)(rows(std::forward<decltype(m)>(m))),
83 auto columns = [](auto&& m) -> decltype(auto) {
84 return rows(transpose(std::forward<decltype(m)>(m)));
87 auto element_wise = [](auto&& f) -> decltype(auto) {
88 namespace hana = boost::hana;
89 return [f(std::forward<decltype(f)>(f))](auto&& ...m) -> decltype(auto) {
91 hana::zip_with(hana::partial(hana::zip_with, f),
92 rows(std::forward<decltype(m)>(m))...
100 auto tuple_scalar_product = [](auto&& u, auto&& v) -> decltype(auto) {
101 namespace hana = boost::hana;
102 return hana::sum<>(hana::zip_with(hana::mult,
103 std::forward<decltype(u)>(u),
104 std::forward<decltype(v)>(v)
108 } // end namespace cppcon
110 #endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP