]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/example/tutorial/integral.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / hana / example / tutorial / integral.cpp
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#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>
23namespace hana = boost::hana;
24
25
92f5a8d4 26namespace support {
7c673cae
FG
27template <typename T, typename = std::enable_if_t<
28 !hana::Constant<T>::value
29>>
30constexpr T sqrt(T x) {
31 T inf = 0, sup = (x == 1 ? 1 : x/2);
32 while (!((sup - inf) <= 1 || ((sup*sup <= x) && ((sup+1)*(sup+1) > x)))) {
33 T mid = (inf + sup) / 2;
34 bool take_inf = mid*mid > x ? 1 : 0;
35 inf = take_inf ? inf : mid;
36 sup = take_inf ? mid : sup;
37 }
38
39 return sup*sup <= x ? sup : inf;
40}
41
42template <typename T, typename = std::enable_if_t<
43 hana::Constant<T>::value
44>>
45constexpr auto sqrt(T const&) {
46 return hana::integral_c<typename T::value_type, sqrt(T::value)>;
47}
92f5a8d4 48} // end namespace support
7c673cae
FG
49
50
51namespace then {
52namespace mpl = boost::mpl;
53
54template <typename N>
55struct sqrt
92f5a8d4 56 : mpl::integral_c<typename N::value_type, support::sqrt(N::value)>
7c673cae
FG
57{ };
58
59template <typename X, typename Y>
60struct point {
61 using x = X;
62 using y = Y;
63};
64
65//! [distance-mpl]
66template <typename P1, typename P2>
67struct distance {
68 using xs = typename mpl::minus<typename P1::x,
69 typename P2::x>::type;
70 using ys = typename mpl::minus<typename P1::y,
71 typename P2::y>::type;
72 using type = typename sqrt<
73 typename mpl::plus<
74 typename mpl::multiplies<xs, xs>::type,
75 typename mpl::multiplies<ys, ys>::type
76 >::type
77 >::type;
78};
79
80static_assert(mpl::equal_to<
81 distance<point<mpl::int_<3>, mpl::int_<5>>,
82 point<mpl::int_<7>, mpl::int_<2>>>::type,
83 mpl::int_<5>
84>::value, "");
85//! [distance-mpl]
86}
87
88
89namespace now {
90namespace hana = boost::hana;
91using namespace hana::literals;
92
93template <typename X, typename Y>
94struct _point {
95 X x;
96 Y y;
97};
98template <typename X, typename Y>
99constexpr _point<X, Y> point(X x, Y y) { return {x, y}; }
100
92f5a8d4
TL
101using support::sqrt; // avoid conflicts with ::sqrt
102
7c673cae
FG
103//! [distance-hana]
104template <typename P1, typename P2>
105constexpr auto distance(P1 p1, P2 p2) {
106 auto xs = p1.x - p2.x;
107 auto ys = p1.y - p2.y;
108 return sqrt(xs*xs + ys*ys);
109}
110
111BOOST_HANA_CONSTANT_CHECK(distance(point(3_c, 5_c), point(7_c, 2_c)) == 5_c);
112//! [distance-hana]
113
114void test() {
115
116//! [distance-dynamic]
117auto p1 = point(3, 5); // dynamic values now
118auto p2 = point(7, 2); //
119BOOST_HANA_RUNTIME_CHECK(distance(p1, p2) == 5); // same function works!
120//! [distance-dynamic]
121
122}
123}
124
125
126int main() {
127 now::test();
128}