]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / cppcon_2014 / matrix / matrix.hpp
CommitLineData
b32b8144 1// Copyright Louis Dionne 2013-2017
7c673cae
FG
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_MATRIX_HPP
6#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
7
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>
24
25#include <utility>
26
27
28namespace cppcon {
29 template <unsigned Rows, unsigned Columns>
30 struct Matrix { };
31
32 template <unsigned Rows, unsigned Columns, typename Storage>
33 struct matrix_type {
34 using hana_tag = Matrix<Rows, Columns>;
35
36 Storage rows_;
37 constexpr auto ncolumns() const
38 { return boost::hana::length(boost::hana::front(rows_)); }
39
40 constexpr auto nrows() const
41 { return boost::hana::length(rows_); }
42
43 constexpr auto size() const
44 { return nrows() * ncolumns(); }
45
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); }
49 };
50
51 auto row = boost::hana::make_tuple;
52
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;
60 })
61 );
62
63 return matrix_type<
64 sizeof...(rows), hana::value(ncolumns), decltype(storage)
65 >{std::move(storage)};
66 };
67
68 auto vector = boost::hana::on(matrix, row);
69
70
71 // More operations
72 auto rows = [](auto&& m) -> decltype(auto) {
73 return std::forward<decltype(m)>(m).rows_;
74 };
75
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))),
79 matrix
80 );
81 };
82
83 auto columns = [](auto&& m) -> decltype(auto) {
84 return rows(transpose(std::forward<decltype(m)>(m)));
85 };
86
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) {
90 return hana::unpack(
91 hana::zip_with(hana::partial(hana::zip_with, f),
92 rows(std::forward<decltype(m)>(m))...
93 ),
94 matrix
95 );
96 };
97 };
98
99 namespace detail {
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)
105 ));
106 };
107 }
108} // end namespace cppcon
109
110#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP