diff --git a/include/boost/gil/detail/std_common_type.hpp b/include/boost/gil/detail/std_common_type.hpp new file mode 100644 index 000000000..305f095ad --- /dev/null +++ b/include/boost/gil/detail/std_common_type.hpp @@ -0,0 +1,39 @@ +// +// Copyright Louis Dionne 2013-2017 +// +// Distributed under the Boost Software License, Version 1.0. +//(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) +// +#ifndef BOOST_GIL_DETAIL_STD_COMMON_TYPE_HPP +#define BOOST_GIL_DETAIL_STD_COMMON_TYPE_HPP + +#include +#include + +namespace boost { namespace gil { namespace detail { + +// Defines a SFINAE-friendly version of `std::common_type`. +// +// Based on boost/hana/detail/std_common_type.hpp +// Equivalent to `std::common_type`, except it is SFINAE-friendly and +// does not support custom specializations. + +template +struct std_common_type {}; + +template +struct std_common_type +< + T, U, + decltype((void)(true ? std::declval() : std::declval())) +> +{ + using type = typename std::decay + < + decltype(true ? std::declval() : std::declval()) + >::type; +}; + +}}} // namespace boost::gil::detail + +#endif diff --git a/include/boost/gil/point.hpp b/include/boost/gil/point.hpp index 7bf105ceb..d2914bb71 100644 --- a/include/boost/gil/point.hpp +++ b/include/boost/gil/point.hpp @@ -9,6 +9,7 @@ #define BOOST_GIL_POINT_HPP #include +#include #include @@ -165,10 +166,15 @@ point operator-(const point& p1, const point& p2) /// \ingroup PointModel template BOOST_FORCEINLINE -auto operator/(point const& p, D d) -> point::type> +auto operator/(point const& p, D d) + -> typename std::enable_if + < + std::is_arithmetic::value, + point::type> + >::type { static_assert(std::is_arithmetic::value, "denominator is not arithmetic type"); - using result_type = typename std::common_type::type; + using result_type = typename detail::std_common_type::type; if (d < 0 || 0 < d) { double const x = p.x / static_cast(d); @@ -188,13 +194,13 @@ template BOOST_FORCEINLINE auto operator*(point const& p, M m) -> typename std::enable_if - < - std::is_arithmetic::value, - point::type> - >::type + < + std::is_arithmetic::value, + point::type> + >::type { static_assert(std::is_arithmetic::value, "multiplier is not arithmetic type"); - using result_type = typename std::common_type::type; + using result_type = typename detail::std_common_type::type; return point{p.x * m, p.y * m}; } @@ -203,13 +209,13 @@ template BOOST_FORCEINLINE auto operator*(M m, point const& p) -> typename std::enable_if - < - std::is_arithmetic::value, - point::type> - >::type + < + std::is_arithmetic::value, + point::type> + >::type { static_assert(std::is_arithmetic::value, "multiplier is not arithmetic type"); - using result_type = typename std::common_type::type; + using result_type = typename detail::std_common_type::type; return point{p.x * m, p.y * m}; }