]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/include/boost/hana/minus.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / hana / include / boost / hana / minus.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Defines `boost::hana::minus`.
4
5@copyright Louis Dionne 2013-2016
6Distributed under the Boost Software License, Version 1.0.
7(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10#ifndef BOOST_HANA_MINUS_HPP
11#define BOOST_HANA_MINUS_HPP
12
13#include <boost/hana/fwd/minus.hpp>
14
15#include <boost/hana/concept/constant.hpp>
16#include <boost/hana/concept/group.hpp>
17#include <boost/hana/config.hpp>
18#include <boost/hana/core/common.hpp>
19#include <boost/hana/core/to.hpp>
20#include <boost/hana/core/dispatch.hpp>
21#include <boost/hana/detail/canonical_constant.hpp>
22#include <boost/hana/detail/has_common_embedding.hpp>
23#include <boost/hana/fwd/negate.hpp>
24#include <boost/hana/plus.hpp>
25#include <boost/hana/value.hpp>
26
27#include <type_traits>
28
29
30BOOST_HANA_NAMESPACE_BEGIN
31 //! @cond
32 template <typename X, typename Y>
33 constexpr decltype(auto) minus_t::operator()(X&& x, Y&& y) const {
34 using T = typename hana::tag_of<X>::type;
35 using U = typename hana::tag_of<Y>::type;
36 using Minus = BOOST_HANA_DISPATCH_IF(decltype(minus_impl<T, U>{}),
37 hana::Group<T>::value &&
38 hana::Group<U>::value
39 );
40
41 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
42 static_assert(hana::Group<T>::value,
43 "hana::minus(x, y) requires 'x' to be in a Group");
44
45 static_assert(hana::Group<U>::value,
46 "hana::minus(x, y) requires 'y' to be in a Group");
47 #endif
48
49 return Minus::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
50 }
51 //! @endcond
52
53 template <typename T, typename U, bool condition>
54 struct minus_impl<T, U, when<condition>> : default_ {
55 template <typename ...Args>
56 static constexpr auto apply(Args&& ...) = delete;
57 };
58
59 template <typename T, bool condition>
60 struct minus_impl<T, T, when<condition>> : default_ {
61 template <typename X, typename Y>
62 static constexpr decltype(auto) apply(X&& x, Y&& y) {
63 return hana::plus(static_cast<X&&>(x),
64 hana::negate(static_cast<Y&&>(y)));
65 }
66 };
67
68 // Cross-type overload
69 template <typename T, typename U>
70 struct minus_impl<T, U, when<
71 detail::has_nontrivial_common_embedding<Group, T, U>::value
72 >> {
73 using C = typename common<T, U>::type;
74 template <typename X, typename Y>
75 static constexpr decltype(auto) apply(X&& x, Y&& y) {
76 return hana::minus(hana::to<C>(static_cast<X&&>(x)),
77 hana::to<C>(static_cast<Y&&>(y)));
78 }
79 };
80
81 //////////////////////////////////////////////////////////////////////////
82 // Model for arithmetic data types
83 //////////////////////////////////////////////////////////////////////////
84 template <typename T>
85 struct minus_impl<T, T, when<std::is_arithmetic<T>::value &&
86 !std::is_same<bool, T>::value>> {
87 template <typename X, typename Y>
88 static constexpr decltype(auto) apply(X&& x, Y&& y)
89 { return static_cast<X&&>(x) - static_cast<Y&&>(y); }
90 };
91
92 //////////////////////////////////////////////////////////////////////////
93 // Model for Constants over a Group
94 //////////////////////////////////////////////////////////////////////////
95 namespace detail {
96 template <typename C, typename X, typename Y>
97 struct constant_from_minus {
98 static constexpr auto value = hana::minus(hana::value<X>(), hana::value<Y>());
99 using hana_tag = detail::CanonicalConstant<typename C::value_type>;
100 };
101 }
102
103 template <typename C>
104 struct minus_impl<C, C, when<
105 hana::Constant<C>::value &&
106 Group<typename C::value_type>::value
107 >> {
108 template <typename X, typename Y>
109 static constexpr decltype(auto) apply(X const&, Y const&)
110 { return hana::to<C>(detail::constant_from_minus<C, X, Y>{}); }
111 };
112BOOST_HANA_NAMESPACE_END
113
114#endif // !BOOST_HANA_MINUS_HPP