]>
git.proxmox.com Git - ceph.git/blob - 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)
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
;
24 template <typename Domain
, typename Codomain
, typename F
>
25 struct function_type
{
26 using hana_tag
= Function
;
33 constexpr auto operator()(X x
) const {
34 BOOST_HANA_ASSERT(boost::hana::contains(domain_
, x
));
39 template <typename
...F
, typename
...G
>
40 constexpr auto operator==(function_type
<F
...> f
, function_type
<G
...> g
)
41 { return hana::equal(f
, g
); }
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
); }
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
56 template <typename Function
>
57 constexpr auto domain(Function f
)
60 template <typename Function
>
61 constexpr auto codomain(Function f
)
62 { return f
.codomain_
; }
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
));
70 namespace boost
{ namespace hana
{
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
));
79 }} // end namespace boost::hana
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));
86 // return all_of(product(domain(f), domain(f)), check);
89 // BOOST_HANA_CONSTEXPR_LAMBDA auto is_onto = [](auto f) {
90 // return codomain(f) == range(g);
93 //////////////////////////////////////////////////////////////////////////////
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
; }
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
; }
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
; }
108 BOOST_HANA_CONSTANT_CHECK(f
== g
);
109 BOOST_HANA_CONSTANT_CHECK(f
!= h
);
110 BOOST_HANA_CONSTANT_CHECK(f(1_c
) == 2_c
);
112 BOOST_HANA_CONSTANT_CHECK(range(f
) == hana::make_set(4_c
, 3_c
, 2_c
));