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

Make Zero and One const traits #276

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 18 additions & 11 deletions src/identities.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::marker::Destruct;
use core::num::Wrapping;
use core::ops::{Add, Mul};

Expand All @@ -9,6 +10,7 @@ use core::ops::{Add, Mul};
/// a + 0 = a ∀ a ∈ Self
/// 0 + a = a ∀ a ∈ Self
/// ```
#[const_trait]
pub trait Zero: Sized + Add<Self, Output = Self> {
/// Returns the additive identity element of `Self`, `0`.
/// # Purity
Expand All @@ -20,7 +22,8 @@ pub trait Zero: Sized + Add<Self, Output = Self> {
fn zero() -> Self;

/// Sets `self` to the additive identity element of `Self`, `0`.
fn set_zero(&mut self) {
fn set_zero(&mut self)
where Self: ~const Destruct {
*self = Zero::zero();
}

Expand All @@ -30,7 +33,7 @@ pub trait Zero: Sized + Add<Self, Output = Self> {

macro_rules! zero_impl {
($t:ty, $v:expr) => {
impl Zero for $t {
impl const Zero for $t {
#[inline]
fn zero() -> $t {
$v
Expand Down Expand Up @@ -60,15 +63,16 @@ zero_impl!(i128, 0);
zero_impl!(f32, 0.0);
zero_impl!(f64, 0.0);

impl<T: Zero> Zero for Wrapping<T>
impl<T: ~const Zero> const Zero for Wrapping<T>
where
Wrapping<T>: Add<Output = Wrapping<T>>,
{
fn is_zero(&self) -> bool {
self.0.is_zero()
}

fn set_zero(&mut self) {
fn set_zero(&mut self)
where T: ~const Destruct {
self.0.set_zero();
}

Expand All @@ -85,6 +89,7 @@ where
/// a * 1 = a ∀ a ∈ Self
/// 1 * a = a ∀ a ∈ Self
/// ```
#[const_trait]
pub trait One: Sized + Mul<Self, Output = Self> {
/// Returns the multiplicative identity element of `Self`, `1`.
///
Expand All @@ -97,7 +102,8 @@ pub trait One: Sized + Mul<Self, Output = Self> {
fn one() -> Self;

/// Sets `self` to the multiplicative identity element of `Self`, `1`.
fn set_one(&mut self) {
fn set_one(&mut self)
where Self: ~const Destruct {
*self = One::one();
}

Expand All @@ -109,15 +115,15 @@ pub trait One: Sized + Mul<Self, Output = Self> {
#[inline]
fn is_one(&self) -> bool
where
Self: PartialEq,
Self: ~const PartialEq + ~const Destruct,
{
*self == Self::one()
}
}

macro_rules! one_impl {
($t:ty, $v:expr) => {
impl One for $t {
impl const One for $t {
#[inline]
fn one() -> $t {
$v
Expand Down Expand Up @@ -147,11 +153,12 @@ one_impl!(i128, 1);
one_impl!(f32, 1.0);
one_impl!(f64, 1.0);

impl<T: One> One for Wrapping<T>
impl<T: ~const One> const One for Wrapping<T>
where
Wrapping<T>: Mul<Output = Wrapping<T>>,
{
fn set_one(&mut self) {
fn set_one(&mut self)
where T: ~const Destruct {
self.0.set_one();
}

Expand All @@ -164,13 +171,13 @@ where

/// Returns the additive identity, `0`.
#[inline(always)]
pub fn zero<T: Zero>() -> T {
pub const fn zero<T: ~const Zero>() -> T {
Zero::zero()
}

/// Returns the multiplicative identity, `1`.
#[inline(always)]
pub fn one<T: One>() -> T {
pub const fn one<T: ~const One>() -> T {
One::one()
}

Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#![deny(unconditional_recursion)]
#![no_std]

#![feature(const_trait_impl)]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(const_mut_refs)]
#![feature(const_refs_to_cell)]

// Need to explicitly bring the crate in for inherent float methods
#[cfg(feature = "std")]
extern crate std;
Expand Down