summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/hana/example/tutorial/integral.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/hana/example/tutorial/integral.cpp')
-rw-r--r--src/boost/libs/hana/example/tutorial/integral.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/boost/libs/hana/example/tutorial/integral.cpp b/src/boost/libs/hana/example/tutorial/integral.cpp
new file mode 100644
index 000000000..be285c560
--- /dev/null
+++ b/src/boost/libs/hana/example/tutorial/integral.cpp
@@ -0,0 +1,128 @@
+// 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/mpl/equal_to.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/minus.hpp>
+#include <boost/mpl/multiplies.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/plus.hpp>
+
+#include <boost/hana/assert.hpp>
+#include <boost/hana/concept/constant.hpp>
+#include <boost/hana/equal.hpp>
+#include <boost/hana/integral_constant.hpp>
+#include <boost/hana/minus.hpp>
+#include <boost/hana/mult.hpp>
+#include <boost/hana/pair.hpp>
+#include <boost/hana/plus.hpp>
+
+#include <type_traits>
+namespace hana = boost::hana;
+
+
+namespace support {
+template <typename T, typename = std::enable_if_t<
+ !hana::Constant<T>::value
+>>
+constexpr T sqrt(T x) {
+ T inf = 0, sup = (x == 1 ? 1 : x/2);
+ while (!((sup - inf) <= 1 || ((sup*sup <= x) && ((sup+1)*(sup+1) > x)))) {
+ T mid = (inf + sup) / 2;
+ bool take_inf = mid*mid > x ? 1 : 0;
+ inf = take_inf ? inf : mid;
+ sup = take_inf ? mid : sup;
+ }
+
+ return sup*sup <= x ? sup : inf;
+}
+
+template <typename T, typename = std::enable_if_t<
+ hana::Constant<T>::value
+>>
+constexpr auto sqrt(T const&) {
+ return hana::integral_c<typename T::value_type, sqrt(T::value)>;
+}
+} // end namespace support
+
+
+namespace then {
+namespace mpl = boost::mpl;
+
+template <typename N>
+struct sqrt
+ : mpl::integral_c<typename N::value_type, support::sqrt(N::value)>
+{ };
+
+template <typename X, typename Y>
+struct point {
+ using x = X;
+ using y = Y;
+};
+
+//! [distance-mpl]
+template <typename P1, typename P2>
+struct distance {
+ using xs = typename mpl::minus<typename P1::x,
+ typename P2::x>::type;
+ using ys = typename mpl::minus<typename P1::y,
+ typename P2::y>::type;
+ using type = typename sqrt<
+ typename mpl::plus<
+ typename mpl::multiplies<xs, xs>::type,
+ typename mpl::multiplies<ys, ys>::type
+ >::type
+ >::type;
+};
+
+static_assert(mpl::equal_to<
+ distance<point<mpl::int_<3>, mpl::int_<5>>,
+ point<mpl::int_<7>, mpl::int_<2>>>::type,
+ mpl::int_<5>
+>::value, "");
+//! [distance-mpl]
+}
+
+
+namespace now {
+namespace hana = boost::hana;
+using namespace hana::literals;
+
+template <typename X, typename Y>
+struct _point {
+ X x;
+ Y y;
+};
+template <typename X, typename Y>
+constexpr _point<X, Y> point(X x, Y y) { return {x, y}; }
+
+using support::sqrt; // avoid conflicts with ::sqrt
+
+//! [distance-hana]
+template <typename P1, typename P2>
+constexpr auto distance(P1 p1, P2 p2) {
+ auto xs = p1.x - p2.x;
+ auto ys = p1.y - p2.y;
+ return sqrt(xs*xs + ys*ys);
+}
+
+BOOST_HANA_CONSTANT_CHECK(distance(point(3_c, 5_c), point(7_c, 2_c)) == 5_c);
+//! [distance-hana]
+
+void test() {
+
+//! [distance-dynamic]
+auto p1 = point(3, 5); // dynamic values now
+auto p2 = point(7, 2); //
+BOOST_HANA_RUNTIME_CHECK(distance(p1, p2) == 5); // same function works!
+//! [distance-dynamic]
+
+}
+}
+
+
+int main() {
+ now::test();
+}