diff --git a/include/boost/hana/detail/integral_constant.hpp b/include/boost/hana/detail/integral_constant.hpp index aded3ba331..696ce00f7a 100644 --- a/include/boost/hana/detail/integral_constant.hpp +++ b/include/boost/hana/detail/integral_constant.hpp @@ -112,9 +112,11 @@ BOOST_HANA_NAMESPACE_BEGIN //! value>() == v // of type T //! @endcode //! - //! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `EuclideanRing`, `Hashable`\n + //! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `Hashable`\n //! Those models are exactly those provided for `Constant`s, which are //! documented in their respective concepts. + //! + //! 3. `EuclideanRing` for signed types #ifdef BOOST_HANA_DOXYGEN_INVOKED template struct integral_constant { diff --git a/include/boost/hana/div.hpp b/include/boost/hana/div.hpp index ff41a36118..e57d88e52d 100644 --- a/include/boost/hana/div.hpp +++ b/include/boost/hana/div.hpp @@ -72,10 +72,11 @@ BOOST_HANA_NAMESPACE_BEGIN }; ////////////////////////////////////////////////////////////////////////// - // Model for integral data types + // Model for signed integral data types ////////////////////////////////////////////////////////////////////////// template struct div_impl::value && + std::is_signed::value && !std::is_same::value>> { template static constexpr decltype(auto) apply(X&& x, Y&& y) diff --git a/include/boost/hana/fwd/concept/euclidean_ring.hpp b/include/boost/hana/fwd/concept/euclidean_ring.hpp index b33d8b565c..ada023a37d 100644 --- a/include/boost/hana/fwd/concept/euclidean_ring.hpp +++ b/include/boost/hana/fwd/concept/euclidean_ring.hpp @@ -93,10 +93,11 @@ BOOST_HANA_NAMESPACE_BEGIN //! `hana::integral_constant` //! //! - //! Free model for non-boolean integral data types - //! ---------------------------------------------- - //! A data type `T` is integral if `std::is_integral::%value` is true. - //! For a non-boolean integral data type `T`, a model of `EuclideanRing` + //! Free model for non-boolean signed integral data types + //! ----------------------------------------------------- + //! A data type `T` is integral if `std::is_integral::%value` is true, + //! and it is signed if `std::is_signed::%value` is true. For a + //! non-boolean signed integral data type `T`, a model of `EuclideanRing` //! is automatically defined by using the `Ring` model provided for //! arithmetic data types and setting //! @code @@ -104,6 +105,9 @@ BOOST_HANA_NAMESPACE_BEGIN //! mod(x, y) = (x % y) //! @endcode //! + //! Such a model cannot be provided for unsigned integral types, because + //! the fact that overflow wraps breaks the laws of `EuclideanRing`. + //! //! @note //! The rationale for not providing an EuclideanRing model for `bool` is //! the same as for not providing Monoid, Group and Ring models. diff --git a/include/boost/hana/mod.hpp b/include/boost/hana/mod.hpp index 052df99ac9..06389cb5e5 100644 --- a/include/boost/hana/mod.hpp +++ b/include/boost/hana/mod.hpp @@ -72,10 +72,11 @@ BOOST_HANA_NAMESPACE_BEGIN }; ////////////////////////////////////////////////////////////////////////// - // Model for integral data types + // Model for signed integral data types ////////////////////////////////////////////////////////////////////////// template struct mod_impl::value && + std::is_signed::value && !std::is_same::value>> { template static constexpr decltype(auto) apply(X&& x, Y&& y) diff --git a/test/issues/github_240.cpp b/test/issues/github_240.cpp new file mode 100644 index 0000000000..91dd87db0a --- /dev/null +++ b/test/issues/github_240.cpp @@ -0,0 +1,27 @@ +// Copyright Louis Dionne 2013-2016 +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +#include +#include +#include + +#include +namespace hana = boost::hana; + + +static_assert(!hana::EuclideanRing{}, ""); +static_assert(!hana::EuclideanRing{}, ""); +static_assert(!hana::EuclideanRing{}, ""); +static_assert(!hana::EuclideanRing{}, ""); + +template +using minimal_constant = ::cnumeric_t; +static_assert(!hana::EuclideanRing>{}, ""); +static_assert(!hana::EuclideanRing>{}, ""); +static_assert(!hana::EuclideanRing>{}, ""); +static_assert(!hana::EuclideanRing>{}, ""); + +static_assert(!hana::EuclideanRing>{}, ""); + +int main() { }