]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/hana/experimental/function.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / experimental / function.cpp
1 // Copyright Louis Dionne 2013-2016
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/hana/all_of.hpp>
6 #include <boost/hana/assert.hpp>
7 #include <boost/hana/contains.hpp>
8 #include <boost/hana/core/to.hpp>
9 #include <boost/hana/equal.hpp>
10 #include <boost/hana/functional/demux.hpp>
11 #include <boost/hana/integral_constant.hpp>
12 #include <boost/hana/minus.hpp>
13 #include <boost/hana/not_equal.hpp>
14 #include <boost/hana/plus.hpp>
15 #include <boost/hana/set.hpp>
16 #include <boost/hana/transform.hpp>
17 #include <boost/hana/tuple.hpp>
18 namespace hana = boost::hana;
19 using namespace hana::literals;
20
21
22 struct Function { };
23
24 template <typename Domain, typename Codomain, typename F>
25 struct function_type {
26 using hana_tag = Function;
27
28 Domain domain_;
29 Codomain codomain_;
30 F f_;
31
32 template <typename X>
33 constexpr auto operator()(X x) const {
34 BOOST_HANA_ASSERT(boost::hana::contains(domain_, x));
35 return f_(x);
36 }
37 };
38
39 template <typename ...F, typename ...G>
40 constexpr auto operator==(function_type<F...> f, function_type<G...> g)
41 { return hana::equal(f, g); }
42
43 template <typename ...F, typename ...G>
44 constexpr auto operator!=(function_type<F...> f, function_type<G...> g)
45 { return hana::not_equal(f, g); }
46
47
48 auto function = [](auto domain, auto codomain) {
49 return [=](auto definition) {
50 return function_type<decltype(domain), decltype(codomain), decltype(definition)>{
51 domain, codomain, definition
52 };
53 };
54 };
55
56 template <typename Function>
57 constexpr auto domain(Function f)
58 { return f.domain_; }
59
60 template <typename Function>
61 constexpr auto codomain(Function f)
62 { return f.codomain_; }
63
64 template <typename Function>
65 constexpr auto range(Function f) {
66 // We must convert to hana::tuple first because hana::set is not a Functor
67 return hana::to_set(hana::transform(hana::to_tuple(domain(f)), f));
68 }
69
70 namespace boost { namespace hana {
71 template <>
72 struct equal_impl<Function, Function> {
73 template <typename F, typename G>
74 static constexpr auto apply(F f, G g) {
75 return domain(f) == domain(g) &&
76 hana::all_of(domain(f), hana::demux(hana::equal)(f, g));
77 }
78 };
79 }} // end namespace boost::hana
80
81
82 // BOOST_HANA_CONSTEXPR_LAMBDA auto is_injective = [](auto f) {
83 // auto check = [](auto x, auto y) {
84 // return (x != y) ^implies^ (f(x) != f(y));
85 // };
86 // return all_of(product(domain(f), domain(f)), check);
87 // };
88
89 // BOOST_HANA_CONSTEXPR_LAMBDA auto is_onto = [](auto f) {
90 // return codomain(f) == range(g);
91 // };
92
93 //////////////////////////////////////////////////////////////////////////////
94
95 int main() {
96 auto f = function(hana::make_set(1_c, 2_c, 3_c), hana::make_set(1_c, 2_c, 3_c, 4_c, 5_c, 6_c))(
97 [](auto x) { return x + 1_c; }
98 );
99
100 auto g = function(hana::make_set(1_c, 2_c, 3_c), hana::make_set(2_c, 3_c, 4_c))(
101 [](auto x) { return x + 1_c; }
102 );
103
104 auto h = function(hana::make_set(1_c, 2_c, 3_c), hana::make_set(0_c, 1_c, 2_c))(
105 [](auto x) { return x - 1_c; }
106 );
107
108 BOOST_HANA_CONSTANT_CHECK(f == g);
109 BOOST_HANA_CONSTANT_CHECK(f != h);
110 BOOST_HANA_CONSTANT_CHECK(f(1_c) == 2_c);
111
112 BOOST_HANA_CONSTANT_CHECK(range(f) == hana::make_set(4_c, 3_c, 2_c));
113 }