• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2 @file
3 Defines arithmetic operators.
4 
5 @copyright Louis Dionne 2013-2017
6 Distributed 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_DETAIL_OPERATORS_ARITHMETIC_HPP
11 #define BOOST_HANA_DETAIL_OPERATORS_ARITHMETIC_HPP
12 
13 #include <boost/hana/config.hpp>
14 #include <boost/hana/core/tag_of.hpp>
15 #include <boost/hana/fwd/div.hpp>
16 #include <boost/hana/fwd/minus.hpp>
17 #include <boost/hana/fwd/mod.hpp>
18 #include <boost/hana/fwd/mult.hpp>
19 #include <boost/hana/fwd/negate.hpp>
20 #include <boost/hana/fwd/plus.hpp>
21 
22 #include <type_traits>
23 
24 
25 BOOST_HANA_NAMESPACE_BEGIN namespace detail {
26     template <typename Tag>
27     struct arithmetic_operators {
28         static constexpr bool value = false;
29     };
30 
31     namespace operators {
32         template <typename X, typename Y, typename = typename std::enable_if<
33             detail::arithmetic_operators<typename hana::tag_of<X>::type>::value ||
34             detail::arithmetic_operators<typename hana::tag_of<Y>::type>::value
35         >::type>
operator +(X && x,Y && y)36         constexpr auto operator+(X&& x, Y&& y)
37         { return hana::plus(static_cast<X&&>(x), static_cast<Y&&>(y)); }
38 
39 
40         template <typename X, typename Y, typename = typename std::enable_if<
41             detail::arithmetic_operators<typename hana::tag_of<X>::type>::value ||
42             detail::arithmetic_operators<typename hana::tag_of<Y>::type>::value
43         >::type>
operator -(X && x,Y && y)44         constexpr auto operator-(X&& x, Y&& y)
45         { return hana::minus(static_cast<X&&>(x), static_cast<Y&&>(y)); }
46 
47         template <typename X, typename = typename std::enable_if<
48             detail::arithmetic_operators<typename hana::tag_of<X>::type>::value
49         >::type>
operator -(X && x)50         constexpr auto operator-(X&& x)
51         { return hana::negate(static_cast<X&&>(x)); }
52 
53 
54         template <typename X, typename Y, typename = typename std::enable_if<
55             detail::arithmetic_operators<typename hana::tag_of<X>::type>::value ||
56             detail::arithmetic_operators<typename hana::tag_of<Y>::type>::value
57         >::type>
operator *(X && x,Y && y)58         constexpr auto operator*(X&& x, Y&& y)
59         { return hana::mult(static_cast<X&&>(x), static_cast<Y&&>(y)); }
60 
61 
62         template <typename X, typename Y, typename = typename std::enable_if<
63             detail::arithmetic_operators<typename hana::tag_of<X>::type>::value ||
64             detail::arithmetic_operators<typename hana::tag_of<Y>::type>::value
65         >::type>
operator /(X && x,Y && y)66         constexpr auto operator/(X&& x, Y&& y)
67         { return hana::div(static_cast<X&&>(x), static_cast<Y&&>(y)); }
68 
69         template <typename X, typename Y, typename = typename std::enable_if<
70             detail::arithmetic_operators<typename hana::tag_of<X>::type>::value ||
71             detail::arithmetic_operators<typename hana::tag_of<Y>::type>::value
72         >::type>
operator %(X && x,Y && y)73         constexpr auto operator%(X&& x, Y&& y)
74         { return hana::mod(static_cast<X&&>(x), static_cast<Y&&>(y)); }
75     } // end namespace operators
76 } BOOST_HANA_NAMESPACE_END
77 
78 #endif // !BOOST_HANA_DETAIL_OPERATORS_ARITHMETIC_HPP
79