Skip to content

Commit 376deef

Browse files
committed
[integral_constant] Unsigned integral constants are not EuclideanRings
1 parent 9fe9d2f commit 376deef

5 files changed

Lines changed: 42 additions & 7 deletions

File tree

include/boost/hana/detail/integral_constant.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,11 @@ BOOST_HANA_NAMESPACE_BEGIN
112112
//! value<integral_constant<T, v>>() == v // of type T
113113
//! @endcode
114114
//!
115-
//! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `EuclideanRing`, `Hashable`\n
115+
//! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `Hashable`\n
116116
//! Those models are exactly those provided for `Constant`s, which are
117117
//! documented in their respective concepts.
118+
//!
119+
//! 3. `EuclideanRing` for signed types
118120
#ifdef BOOST_HANA_DOXYGEN_INVOKED
119121
template <typename T, T v>
120122
struct integral_constant {

include/boost/hana/div.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ BOOST_HANA_NAMESPACE_BEGIN
7272
};
7373

7474
//////////////////////////////////////////////////////////////////////////
75-
// Model for integral data types
75+
// Model for signed integral data types
7676
//////////////////////////////////////////////////////////////////////////
7777
template <typename T>
7878
struct div_impl<T, T, when<std::is_integral<T>::value &&
79+
std::is_signed<T>::value &&
7980
!std::is_same<T, bool>::value>> {
8081
template <typename X, typename Y>
8182
static constexpr decltype(auto) apply(X&& x, Y&& y)

include/boost/hana/fwd/concept/euclidean_ring.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,21 @@ BOOST_HANA_NAMESPACE_BEGIN
9393
//! `hana::integral_constant`
9494
//!
9595
//!
96-
//! Free model for non-boolean integral data types
97-
//! ----------------------------------------------
98-
//! A data type `T` is integral if `std::is_integral<T>::%value` is true.
99-
//! For a non-boolean integral data type `T`, a model of `EuclideanRing`
96+
//! Free model for non-boolean signed integral data types
97+
//! -----------------------------------------------------
98+
//! A data type `T` is integral if `std::is_integral<T>::%value` is true,
99+
//! and it is signed if `std::is_signed<T>::%value` is true. For a
100+
//! non-boolean signed integral data type `T`, a model of `EuclideanRing`
100101
//! is automatically defined by using the `Ring` model provided for
101102
//! arithmetic data types and setting
102103
//! @code
103104
//! div(x, y) = (x / y)
104105
//! mod(x, y) = (x % y)
105106
//! @endcode
106107
//!
108+
//! Such a model cannot be provided for unsigned integral types, because
109+
//! the fact that overflow wraps breaks the laws of `EuclideanRing`.
110+
//!
107111
//! @note
108112
//! The rationale for not providing an EuclideanRing model for `bool` is
109113
//! the same as for not providing Monoid, Group and Ring models.

include/boost/hana/mod.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ BOOST_HANA_NAMESPACE_BEGIN
7272
};
7373

7474
//////////////////////////////////////////////////////////////////////////
75-
// Model for integral data types
75+
// Model for signed integral data types
7676
//////////////////////////////////////////////////////////////////////////
7777
template <typename T>
7878
struct mod_impl<T, T, when<std::is_integral<T>::value &&
79+
std::is_signed<T>::value &&
7980
!std::is_same<T, bool>::value>> {
8081
template <typename X, typename Y>
8182
static constexpr decltype(auto) apply(X&& x, Y&& y)

test/issues/github_240.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright Louis Dionne 2013-2016
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4+
5+
#include <boost/hana/concept/euclidean_ring.hpp>
6+
#include <boost/hana/integral_constant.hpp>
7+
#include <boost/hana/not.hpp>
8+
9+
#include <support/cnumeric.hpp>
10+
namespace hana = boost::hana;
11+
12+
13+
static_assert(!hana::EuclideanRing<unsigned short>{}, "");
14+
static_assert(!hana::EuclideanRing<unsigned int>{}, "");
15+
static_assert(!hana::EuclideanRing<unsigned long>{}, "");
16+
static_assert(!hana::EuclideanRing<unsigned long long>{}, "");
17+
18+
template <typename T, T v>
19+
using minimal_constant = ::cnumeric_t<T, v>;
20+
static_assert(!hana::EuclideanRing<minimal_constant<unsigned short, 10>>{}, "");
21+
static_assert(!hana::EuclideanRing<minimal_constant<unsigned int, 10>>{}, "");
22+
static_assert(!hana::EuclideanRing<minimal_constant<unsigned long, 10>>{}, "");
23+
static_assert(!hana::EuclideanRing<minimal_constant<unsigned long long, 10>>{}, "");
24+
25+
static_assert(!hana::EuclideanRing<hana::integral_constant<unsigned int, 10>>{}, "");
26+
27+
int main() { }

0 commit comments

Comments
 (0)