]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/example/tutorial/integral.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / tutorial / integral.cpp
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 #include <boost/mpl/equal_to.hpp>
6 #include <boost/mpl/int.hpp>
7 #include <boost/mpl/integral_c.hpp>
8 #include <boost/mpl/minus.hpp>
9 #include <boost/mpl/multiplies.hpp>
10 #include <boost/mpl/pair.hpp>
11 #include <boost/mpl/plus.hpp>
12
13 #include <boost/hana/assert.hpp>
14 #include <boost/hana/concept/constant.hpp>
15 #include <boost/hana/equal.hpp>
16 #include <boost/hana/integral_constant.hpp>
17 #include <boost/hana/minus.hpp>
18 #include <boost/hana/mult.hpp>
19 #include <boost/hana/pair.hpp>
20 #include <boost/hana/plus.hpp>
21
22 #include <type_traits>
23 namespace hana = boost::hana;
24
25
26 template <typename T, typename = std::enable_if_t<
27 !hana::Constant<T>::value
28 >>
29 constexpr T sqrt(T x) {
30 T inf = 0, sup = (x == 1 ? 1 : x/2);
31 while (!((sup - inf) <= 1 || ((sup*sup <= x) && ((sup+1)*(sup+1) > x)))) {
32 T mid = (inf + sup) / 2;
33 bool take_inf = mid*mid > x ? 1 : 0;
34 inf = take_inf ? inf : mid;
35 sup = take_inf ? mid : sup;
36 }
37
38 return sup*sup <= x ? sup : inf;
39 }
40
41 template <typename T, typename = std::enable_if_t<
42 hana::Constant<T>::value
43 >>
44 constexpr auto sqrt(T const&) {
45 return hana::integral_c<typename T::value_type, sqrt(T::value)>;
46 }
47
48
49 namespace then {
50 namespace mpl = boost::mpl;
51
52 template <typename N>
53 struct sqrt
54 : mpl::integral_c<typename N::value_type, ::sqrt(N::value)>
55 { };
56
57 template <typename X, typename Y>
58 struct point {
59 using x = X;
60 using y = Y;
61 };
62
63 //! [distance-mpl]
64 template <typename P1, typename P2>
65 struct distance {
66 using xs = typename mpl::minus<typename P1::x,
67 typename P2::x>::type;
68 using ys = typename mpl::minus<typename P1::y,
69 typename P2::y>::type;
70 using type = typename sqrt<
71 typename mpl::plus<
72 typename mpl::multiplies<xs, xs>::type,
73 typename mpl::multiplies<ys, ys>::type
74 >::type
75 >::type;
76 };
77
78 static_assert(mpl::equal_to<
79 distance<point<mpl::int_<3>, mpl::int_<5>>,
80 point<mpl::int_<7>, mpl::int_<2>>>::type,
81 mpl::int_<5>
82 >::value, "");
83 //! [distance-mpl]
84 }
85
86
87 namespace now {
88 namespace hana = boost::hana;
89 using namespace hana::literals;
90
91 template <typename X, typename Y>
92 struct _point {
93 X x;
94 Y y;
95 };
96 template <typename X, typename Y>
97 constexpr _point<X, Y> point(X x, Y y) { return {x, y}; }
98
99 //! [distance-hana]
100 template <typename P1, typename P2>
101 constexpr auto distance(P1 p1, P2 p2) {
102 auto xs = p1.x - p2.x;
103 auto ys = p1.y - p2.y;
104 return sqrt(xs*xs + ys*ys);
105 }
106
107 BOOST_HANA_CONSTANT_CHECK(distance(point(3_c, 5_c), point(7_c, 2_c)) == 5_c);
108 //! [distance-hana]
109
110 void test() {
111
112 //! [distance-dynamic]
113 auto p1 = point(3, 5); // dynamic values now
114 auto p2 = point(7, 2); //
115 BOOST_HANA_RUNTIME_CHECK(distance(p1, p2) == 5); // same function works!
116 //! [distance-dynamic]
117
118 }
119 }
120
121
122 int main() {
123 now::test();
124 }