• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
4 
5 #ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
6 #define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
7 
8 #include "matrix.hpp"
9 
10 #include <boost/hana/equal.hpp>
11 #include <boost/hana/fwd/mult.hpp>
12 #include <boost/hana/fwd/one.hpp>
13 #include <boost/hana/if.hpp>
14 #include <boost/hana/integral_constant.hpp>
15 #include <boost/hana/range.hpp>
16 #include <boost/hana/replicate.hpp>
17 #include <boost/hana/transform.hpp>
18 #include <boost/hana/tuple.hpp>
19 #include <boost/hana/unpack.hpp>
20 #include <boost/hana/zip_with.hpp>
21 
22 #include <utility>
23 
24 
25 namespace boost { namespace hana {
26     template <unsigned R1, unsigned C1, unsigned R2, unsigned C2>
27     struct mult_impl<cppcon::Matrix<R1, C1>, cppcon::Matrix<R2, C2>> {
28         template <typename M1, typename M2>
applyboost::hana::mult_impl29         static constexpr decltype(auto) apply(M1&& m1, M2&& m2) {
30             static_assert(C1 == R2,
31                 "wrong dimensions for matrix multiplication");
32             auto cols = cppcon::columns(std::forward<M2>(m2));
33             return unpack(
34                 transform(cppcon::rows(std::forward<M1>(m1)),
35                     [&](auto&& row) -> decltype(auto) {
36                         return zip_with(cppcon::detail::tuple_scalar_product,
37                             replicate<tuple_tag>(std::forward<decltype(row)>(row), uint_c<R1>),
38                             cols
39                         );
40                     }
41                 ),
42                 cppcon::matrix
43             );
44         }
45     };
46 
47     template <unsigned R, unsigned C>
48     struct one_impl<cppcon::Matrix<R, C>> {
applyboost::hana::one_impl49         static constexpr decltype(auto) apply() {
50             return unpack(range_c<unsigned, 0, R>, [](auto ...n) {
51                 return unpack(range_c<unsigned, 0, C>, [=](auto ...m) {
52                     auto row = [=](auto n) {
53                         return cppcon::row(if_(n == m, int_c<1>, int_c<0>)...);
54                     };
55                     return cppcon::matrix(row(n)...);
56                 });
57             });
58         }
59     };
60 }}
61 
62 #endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
63