Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsigned integral constants are not EuclideanRings #311

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/boost/hana/detail/integral_constant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! value<integral_constant<T, v>>() == 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 <typename T, T v>
struct integral_constant {
Expand Down
3 changes: 2 additions & 1 deletion include/boost/hana/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ BOOST_HANA_NAMESPACE_BEGIN
};

//////////////////////////////////////////////////////////////////////////
// Model for integral data types
// Model for signed integral data types
//////////////////////////////////////////////////////////////////////////
template <typename T>
struct div_impl<T, T, when<std::is_integral<T>::value &&
std::is_signed<T>::value &&
!std::is_same<T, bool>::value>> {
template <typename X, typename Y>
static constexpr decltype(auto) apply(X&& x, Y&& y)
Expand Down
12 changes: 8 additions & 4 deletions include/boost/hana/fwd/concept/euclidean_ring.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,21 @@ 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<T>::%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<T>::%value` is true,
//! and it is signed if `std::is_signed<T>::%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
//! div(x, y) = (x / y)
//! 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.
Expand Down
3 changes: 2 additions & 1 deletion include/boost/hana/mod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ BOOST_HANA_NAMESPACE_BEGIN
};

//////////////////////////////////////////////////////////////////////////
// Model for integral data types
// Model for signed integral data types
//////////////////////////////////////////////////////////////////////////
template <typename T>
struct mod_impl<T, T, when<std::is_integral<T>::value &&
std::is_signed<T>::value &&
!std::is_same<T, bool>::value>> {
template <typename X, typename Y>
static constexpr decltype(auto) apply(X&& x, Y&& y)
Expand Down
27 changes: 27 additions & 0 deletions test/issues/github_240.cpp
Original file line number Diff line number Diff line change
@@ -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 <boost/hana/concept/euclidean_ring.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/not.hpp>

#include <support/cnumeric.hpp>
namespace hana = boost::hana;


static_assert(!hana::EuclideanRing<unsigned short>{}, "");
static_assert(!hana::EuclideanRing<unsigned int>{}, "");
static_assert(!hana::EuclideanRing<unsigned long>{}, "");
static_assert(!hana::EuclideanRing<unsigned long long>{}, "");

template <typename T, T v>
using minimal_constant = ::cnumeric_t<T, v>;
static_assert(!hana::EuclideanRing<minimal_constant<unsigned short, 10>>{}, "");
static_assert(!hana::EuclideanRing<minimal_constant<unsigned int, 10>>{}, "");
static_assert(!hana::EuclideanRing<minimal_constant<unsigned long, 10>>{}, "");
static_assert(!hana::EuclideanRing<minimal_constant<unsigned long long, 10>>{}, "");

static_assert(!hana::EuclideanRing<hana::integral_constant<unsigned int, 10>>{}, "");

int main() { }