summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/example/cppcon_2014
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/comparable.cpp55
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/det.cpp48
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/functor.cpp33
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix.cpp69
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp33
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp60
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp33
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp28
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp110
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp37
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp62
-rw-r--r--src/boost/libs/hana/example/cppcon_2014/ring.cpp96
12 files changed, 664 insertions, 0 deletions
diff --git a/src/boost/libs/hana/example/cppcon_2014/comparable.cpp b/src/boost/libs/hana/example/cppcon_2014/comparable.cpp
new file mode 100644
index 000000000..f93151460
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/comparable.cpp
@@ -0,0 +1,55 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/not.hpp>
+
+#include "matrix/comparable.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ matrix(row(1, 2)),
+ matrix(row(1, 2))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(
+ matrix(row(1, 2)),
+ matrix(row(1, 5))
+ )));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ matrix(row(1, 2),
+ row(3, 4)),
+ matrix(row(1, 2),
+ row(3, 4))
+ ));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(
+ matrix(row(1, 2),
+ row(3, 4)),
+ matrix(row(1, 2),
+ row(0, 4))
+ )));
+ BOOST_HANA_CONSTEXPR_CHECK(hana::not_(hana::equal(
+ matrix(row(1, 2),
+ row(3, 4)),
+ matrix(row(0, 2),
+ row(3, 4))
+ )));
+
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ matrix(row(1),
+ row(2)),
+ matrix(row(3, 4),
+ row(5, 6))
+ )));
+ BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::equal(
+ matrix(row(1),
+ row(2)),
+ matrix(row(3, 4))
+ )));
+}
+
diff --git a/src/boost/libs/hana/example/cppcon_2014/det.cpp b/src/boost/libs/hana/example/cppcon_2014/det.cpp
new file mode 100644
index 000000000..8597e70fc
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/det.cpp
@@ -0,0 +1,48 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+
+#include "matrix/det.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // det
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(det(matrix(row(1))) == 1);
+ BOOST_HANA_CONSTEXPR_CHECK(det(matrix(row(2))) == 2);
+
+ BOOST_HANA_CONSTEXPR_CHECK(det(matrix(row(1, 2), row(3, 4))) == -2);
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ det(matrix(
+ row(1, 5, 6),
+ row(3, 2, 4),
+ row(7, 8, 9)
+ ))
+ == 51
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ det(matrix(
+ row(1, 5, 6, -3),
+ row(3, 2, 4, -5),
+ row(7, 8, 9, -1),
+ row(8, 2, 1, 10)
+ )) == 214
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(
+ det(matrix(
+ row(1, 5, 6, -3, 92),
+ row(3, 2, 4, -5, 13),
+ row(7, 8, 9, -1, 0),
+ row(8, 2, 1, 10, 41),
+ row(3, 12, 92, -7, -4)
+ )) == -3115014
+ );
+ }
+}
diff --git a/src/boost/libs/hana/example/cppcon_2014/functor.cpp b/src/boost/libs/hana/example/cppcon_2014/functor.cpp
new file mode 100644
index 000000000..b616a5241
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/functor.cpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/functional/placeholder.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "matrix/comparable.hpp"
+#include "matrix/functor.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // transform
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, hana::int_c<2>, 3),
+ row(hana::int_c<4>, 5, 6),
+ row(7, 8, hana::int_c<9>)
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::transform(m, hana::_ + hana::int_c<1>),
+ matrix(
+ row(2, hana::int_c<3>, 4),
+ row(hana::int_c<5>, 6, 7),
+ row(8, 9, hana::int_c<10>)
+ )
+ ));
+ }
+}
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix.cpp b/src/boost/libs/hana/example/cppcon_2014/matrix.cpp
new file mode 100644
index 000000000..0d5d020f1
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix.cpp
@@ -0,0 +1,69 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/integral_constant.hpp>
+
+#include "matrix/comparable.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // transpose
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, 2.2, '3'),
+ row(4, '5', 6)
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ transpose(m),
+ matrix(
+ row(1, 4),
+ row(2.2, '5'),
+ row('3', 6)
+ )
+ ));
+ }
+
+ // vector
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto v = vector(1, '2', hana::int_c<3>, 4.2f);
+ BOOST_HANA_CONSTEXPR_CHECK(v.size() == 4ul);
+ BOOST_HANA_CONSTEXPR_CHECK(v.nrows() == 4ul);
+ BOOST_HANA_CONSTEXPR_CHECK(v.ncolumns() == 1ul);
+ }
+
+ // matrix.at
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, '2', 3),
+ row('4', hana::char_c<'5'>, 6),
+ row(hana::int_c<7>, '8', 9.3)
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<0>, hana::int_c<0>) == 1);
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<0>, hana::int_c<1>) == '2');
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<0>, hana::int_c<2>) == 3);
+
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<1>, hana::int_c<0>) == '4');
+ BOOST_HANA_CONSTANT_CHECK(m.at(hana::int_c<1>, hana::int_c<1>) == hana::char_c<'5'>);
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<1>, hana::int_c<2>) == 6);
+
+ BOOST_HANA_CONSTANT_CHECK(m.at(hana::int_c<2>, hana::int_c<0>) == hana::int_c<7>);
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<2>, hana::int_c<1>) == '8');
+ BOOST_HANA_CONSTEXPR_CHECK(m.at(hana::int_c<2>, hana::int_c<2>) == 9.3);
+ }
+
+ // size, ncolumns, nrows
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto m = matrix(
+ row(1, '2', 3),
+ row('4', hana::char_c<'5'>, 6)
+ );
+ BOOST_HANA_CONSTEXPR_CHECK(m.size() == 6ul);
+ BOOST_HANA_CONSTEXPR_CHECK(m.ncolumns() == 3ul);
+ BOOST_HANA_CONSTEXPR_CHECK(m.nrows() == 2ul);
+ }
+}
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp
new file mode 100644
index 000000000..d84b0dac8
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/comparable.hpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_COMPARABLE_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_COMPARABLE_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/all.hpp>
+#include <boost/hana/bool.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/zip_with.hpp>
+
+
+namespace boost { namespace hana {
+ template <unsigned R1, unsigned C1, unsigned R2, unsigned C2>
+ struct equal_impl<cppcon::Matrix<R1, C1>, cppcon::Matrix<R2, C2>> {
+ template <typename M1, typename M2>
+ static constexpr auto apply(M1 const& m1, M2 const& m2) {
+ return eval_if(bool_c<R1 == R2 && C1 == C2>,
+ [&](auto _) {
+ return all(zip_with(_(equal), cppcon::rows(m1),
+ cppcon::rows(m2)));
+ },
+ [] { return false_c; }
+ );
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_COMPARABLE_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp
new file mode 100644
index 000000000..f499fda7e
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/det.hpp
@@ -0,0 +1,60 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/eval_if.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/functional/always.hpp>
+#include <boost/hana/functional/fix.hpp>
+#include <boost/hana/functional/flip.hpp>
+#include <boost/hana/functional/on.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/plus.hpp>
+#include <boost/hana/power.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/remove_at.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+
+#include <utility>
+
+#include "matrix.hpp"
+
+
+namespace cppcon {
+ namespace hana = boost::hana;
+ auto det = hana::fix([](auto det, auto&& m) -> decltype(auto) {
+ auto matrix_minor = [=](auto&& m, auto i, auto j) -> decltype(auto) {
+ return det(hana::unpack(
+ hana::transform(
+ hana::remove_at(rows(std::forward<decltype(m)>(m)), i),
+ hana::partial(hana::flip(hana::remove_at), j)
+ ),
+ matrix
+ ));
+ };
+
+ auto cofactor = [=](auto&& m, auto i, auto j) {
+ return hana::power(hana::int_c<-1>, hana::plus(i, j)) *
+ matrix_minor(std::forward<decltype(m)>(m), i, j);
+ };
+
+ return hana::eval_if(m.size() == hana::size_c<1>,
+ hana::always(m.at(hana::size_c<0>, hana::size_c<0>)),
+ [=](auto _) {
+ auto cofactors_1st_row = hana::unpack(_(hana::make_range)(hana::size_c<0>, m.ncolumns()),
+ hana::on(hana::make_tuple, hana::partial(cofactor, m, hana::size_c<0>))
+ );
+ return detail::tuple_scalar_product(hana::front(rows(m)), cofactors_1st_row);
+ }
+ );
+ });
+} // end namespace cppcon
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp
new file mode 100644
index 000000000..5bb3cd85d
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/functor.hpp
@@ -0,0 +1,33 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_FUNCTOR_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_FUNCTOR_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/functional/flip.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/concept/functor.hpp>
+
+#include <utility>
+
+
+namespace boost { namespace hana {
+ template <unsigned Rows, unsigned Columns>
+ struct transform_impl<cppcon::Matrix<Rows, Columns>> {
+ template <typename M, typename F>
+ static constexpr decltype(auto) apply(M&& m, F&& f) {
+ return unpack(
+ transform(
+ cppcon::rows(std::forward<M>(m)),
+ partial(flip(transform), std::forward<F>(f))
+ ),
+ cppcon::matrix
+ );
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_FUNCTOR_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp
new file mode 100644
index 000000000..87c90b7a7
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/group.hpp
@@ -0,0 +1,28 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_GROUP_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_GROUP_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/concept/group.hpp>
+
+#include <utility>
+
+
+namespace boost { namespace hana {
+ template <unsigned R, unsigned C>
+ struct minus_impl<cppcon::Matrix<R, C>, cppcon::Matrix<R, C>> {
+ template <typename M1, typename M2>
+ static constexpr decltype(auto) apply(M1&& m1, M2&& m2) {
+ return element_wise(minus)(
+ std::forward<M1>(m1),
+ std::forward<M2>(m2)
+ );
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_GROUP_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp
new file mode 100644
index 000000000..d7e142460
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/matrix.hpp
@@ -0,0 +1,110 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
+
+#include <boost/hana/all_of.hpp>
+#include <boost/hana/assert.hpp>
+#include <boost/hana/at.hpp>
+#include <boost/hana/drop_front.hpp>
+#include <boost/hana/front.hpp>
+#include <boost/hana/functional/on.hpp>
+#include <boost/hana/functional/partial.hpp>
+#include <boost/hana/fuse.hpp>
+#include <boost/hana/length.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/sum.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/value.hpp>
+#include <boost/hana/zip.hpp>
+#include <boost/hana/zip_with.hpp>
+
+#include <utility>
+
+
+namespace cppcon {
+ template <unsigned Rows, unsigned Columns>
+ struct Matrix { };
+
+ template <unsigned Rows, unsigned Columns, typename Storage>
+ struct matrix_type {
+ using hana_tag = Matrix<Rows, Columns>;
+
+ Storage rows_;
+ constexpr auto ncolumns() const
+ { return boost::hana::length(boost::hana::front(rows_)); }
+
+ constexpr auto nrows() const
+ { return boost::hana::length(rows_); }
+
+ constexpr auto size() const
+ { return nrows() * ncolumns(); }
+
+ template <typename I, typename J>
+ constexpr decltype(auto) at(I i, J j) const
+ { return boost::hana::at(boost::hana::at(rows_, i), j); }
+ };
+
+ auto row = boost::hana::make_tuple;
+
+ auto matrix = [](auto&& ...rows) -> decltype(auto) {
+ namespace hana = boost::hana;
+ auto storage = hana::make_tuple(std::forward<decltype(rows)>(rows)...);
+ auto ncolumns = hana::length(hana::front(storage));
+ BOOST_HANA_CONSTANT_CHECK(
+ hana::all_of(hana::drop_front(storage), [&](auto const& row) {
+ return hana::length(row) == ncolumns;
+ })
+ );
+
+ return matrix_type<
+ sizeof...(rows), hana::value(ncolumns), decltype(storage)
+ >{std::move(storage)};
+ };
+
+ auto vector = boost::hana::on(matrix, row);
+
+
+ // More operations
+ auto rows = [](auto&& m) -> decltype(auto) {
+ return std::forward<decltype(m)>(m).rows_;
+ };
+
+ auto transpose = [](auto&& m) -> decltype(auto) {
+ return boost::hana::unpack(
+ boost::hana::fuse(boost::hana::zip)(rows(std::forward<decltype(m)>(m))),
+ matrix
+ );
+ };
+
+ auto columns = [](auto&& m) -> decltype(auto) {
+ return rows(transpose(std::forward<decltype(m)>(m)));
+ };
+
+ auto element_wise = [](auto&& f) -> decltype(auto) {
+ namespace hana = boost::hana;
+ return [f(std::forward<decltype(f)>(f))](auto&& ...m) -> decltype(auto) {
+ return hana::unpack(
+ hana::zip_with(hana::partial(hana::zip_with, f),
+ rows(std::forward<decltype(m)>(m))...
+ ),
+ matrix
+ );
+ };
+ };
+
+ namespace detail {
+ auto tuple_scalar_product = [](auto&& u, auto&& v) -> decltype(auto) {
+ namespace hana = boost::hana;
+ return hana::sum<>(hana::zip_with(hana::mult,
+ std::forward<decltype(u)>(u),
+ std::forward<decltype(v)>(v)
+ ));
+ };
+ }
+} // end namespace cppcon
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MATRIX_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp
new file mode 100644
index 000000000..87d62817c
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/monoid.hpp
@@ -0,0 +1,37 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MONOID_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MONOID_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/concept/sequence.hpp>
+#include <boost/hana/concept/monoid.hpp>
+#include <boost/hana/range.hpp>
+
+
+namespace boost { namespace hana {
+ template <unsigned R, unsigned C>
+ struct plus_impl<cppcon::Matrix<R, C>, cppcon::Matrix<R, C>> {
+ template <typename M1, typename M2>
+ static constexpr decltype(auto) apply(M1&& m1, M2&& m2) {
+ return element_wise(plus)(
+ std::forward<M1>(m1),
+ std::forward<M2>(m2)
+ );
+ }
+ };
+
+ template <unsigned R, unsigned C>
+ struct zero_impl<cppcon::Matrix<R, C>> {
+ static constexpr decltype(auto) apply() {
+ auto zeros = replicate(int_<0>, int_<C>);
+ return unpack(replicate(zeros, int_<R>), cppcon::matrix);
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_MONOID_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp b/src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp
new file mode 100644
index 000000000..748f4f8a3
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/matrix/ring.hpp
@@ -0,0 +1,62 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
+#define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
+
+#include "matrix.hpp"
+
+#include <boost/hana/equal.hpp>
+#include <boost/hana/fwd/mult.hpp>
+#include <boost/hana/fwd/one.hpp>
+#include <boost/hana/if.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/range.hpp>
+#include <boost/hana/replicate.hpp>
+#include <boost/hana/transform.hpp>
+#include <boost/hana/tuple.hpp>
+#include <boost/hana/unpack.hpp>
+#include <boost/hana/zip_with.hpp>
+
+#include <utility>
+
+
+namespace boost { namespace hana {
+ template <unsigned R1, unsigned C1, unsigned R2, unsigned C2>
+ struct mult_impl<cppcon::Matrix<R1, C1>, cppcon::Matrix<R2, C2>> {
+ template <typename M1, typename M2>
+ static constexpr decltype(auto) apply(M1&& m1, M2&& m2) {
+ static_assert(C1 == R2,
+ "wrong dimensions for matrix multiplication");
+ auto cols = cppcon::columns(std::forward<M2>(m2));
+ return unpack(
+ transform(cppcon::rows(std::forward<M1>(m1)),
+ [&](auto&& row) -> decltype(auto) {
+ return zip_with(cppcon::detail::tuple_scalar_product,
+ replicate<tuple_tag>(std::forward<decltype(row)>(row), uint_c<R1>),
+ cols
+ );
+ }
+ ),
+ cppcon::matrix
+ );
+ }
+ };
+
+ template <unsigned R, unsigned C>
+ struct one_impl<cppcon::Matrix<R, C>> {
+ static constexpr decltype(auto) apply() {
+ return unpack(range_c<unsigned, 0, R>, [](auto ...n) {
+ return unpack(range_c<unsigned, 0, C>, [=](auto ...m) {
+ auto row = [=](auto n) {
+ return cppcon::row(if_(n == m, int_c<1>, int_c<0>)...);
+ };
+ return cppcon::matrix(row(n)...);
+ });
+ });
+ }
+ };
+}}
+
+#endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_RING_HPP
diff --git a/src/boost/libs/hana/example/cppcon_2014/ring.cpp b/src/boost/libs/hana/example/cppcon_2014/ring.cpp
new file mode 100644
index 000000000..9d06400de
--- /dev/null
+++ b/src/boost/libs/hana/example/cppcon_2014/ring.cpp
@@ -0,0 +1,96 @@
+// Copyright Louis Dionne 2013-2017
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/one.hpp>
+
+#include "matrix/comparable.hpp"
+#include "matrix/ring.hpp"
+namespace hana = boost::hana;
+using namespace cppcon;
+
+
+int main() {
+ // mult
+ {
+ BOOST_HANA_CONSTEXPR_LAMBDA auto a = matrix(
+ row(1, 2, 3),
+ row(4, 5, 6)
+ );
+
+ BOOST_HANA_CONSTEXPR_LAMBDA auto b = matrix(
+ row(1, 2),
+ row(3, 4),
+ row(5, 6)
+ );
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::mult(a, b),
+ matrix(
+ row(1*1 + 2*3 + 5*3, 1*2 + 2*4 + 3*6),
+ row(4*1 + 3*5 + 5*6, 4*2 + 5*4 + 6*6)
+ )
+ ));
+ }
+
+ // one
+ {
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<1, 1>>(),
+ matrix(
+ row(1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<2, 2>>(),
+ matrix(
+ row(1, 0),
+ row(0, 1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<3, 3>>(),
+ matrix(
+ row(1, 0, 0),
+ row(0, 1, 0),
+ row(0, 0, 1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<4, 4>>(),
+ matrix(
+ row(1, 0, 0, 0),
+ row(0, 1, 0, 0),
+ row(0, 0, 1, 0),
+ row(0, 0, 0, 1)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<4, 5>>(),
+ matrix(
+ row(1, 0, 0, 0, 0),
+ row(0, 1, 0, 0, 0),
+ row(0, 0, 1, 0, 0),
+ row(0, 0, 0, 1, 0)
+ )
+ ));
+
+ BOOST_HANA_CONSTEXPR_CHECK(hana::equal(
+ hana::one<Matrix<5, 4>>(),
+ matrix(
+ row(1, 0, 0, 0),
+ row(0, 1, 0, 0),
+ row(0, 0, 1, 0),
+ row(0, 0, 0, 1),
+ row(0, 0, 0, 0)
+ )
+ ));
+ }
+}