Skip to content

Commit

Permalink
[integral_constant] Unsigned integral constants are not EuclideanRings
Browse files Browse the repository at this point in the history
Fixes #240
  • Loading branch information
ldionne committed Nov 17, 2016
1 parent 9fe9d2f commit be252aa
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
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() { }

0 comments on commit be252aa

Please sign in to comment.