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