Skip to content

Commit

Permalink
Move BuiltinBounds underlying implementation to the data structure crate
Browse files Browse the repository at this point in the history
  • Loading branch information
jroesch committed Jul 2, 2015
1 parent 2b0f13f commit 2c8ab28
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 26 deletions.
39 changes: 13 additions & 26 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,15 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
use util::nodemap::FnvHashMap;
use util::num::ToPrimitive;

use rustc_data_structures::bitset::{U8BitSet, BitSet, BitSetIter};

use arena::TypedArena;
use std::borrow::{Borrow, Cow};
use std::cell::{Cell, RefCell, Ref};
use std::cmp;
use std::fmt;
use std::hash::{Hash, SipHasher, Hasher};
use std::mem;
use std::ops;
use std::rc::Rc;
use std::vec::IntoIter;
Expand Down Expand Up @@ -2059,28 +2062,28 @@ pub struct ExistentialBounds<'tcx> {

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct BuiltinBounds {
bits: u8
bit_set: U8BitSet
}

impl BuiltinBounds {
pub fn empty() -> BuiltinBounds {
BuiltinBounds { bits: 0 }
BuiltinBounds { bit_set: BitSet::empty() }
}

pub fn insert(&mut self, bound: BuiltinBound) {
self.bits |= 1 << (bound as u8);
self.bit_set.insert(bound as u8)
}

pub fn contains(&self, bound: BuiltinBound) -> bool {
((self.bits >> (bound as u8)) & 1) == 1
self.bit_set.contains(bound as u8)
}

pub fn iter(&self) -> BuiltinBoundsIter {
self.into_iter()
}

fn is_empty(&self) -> bool {
self.bits == 0
self.bit_set.is_empty()
}

pub fn to_predicates<'tcx>(&self,
Expand All @@ -2095,36 +2098,19 @@ impl BuiltinBounds {
}

pub fn is_superset(&self, other: &BuiltinBounds) -> bool {
(self.bits & other.bits) == other.bits
self.bit_set.is_superset(other.bit_set)
}
}

pub struct BuiltinBoundsIter {
bounds: BuiltinBounds,
index: u8
bit_set: BitSetIter<u8>
}

impl Iterator for BuiltinBoundsIter {
type Item = BuiltinBound;

fn next(&mut self) -> Option<BuiltinBound> {
while self.index < 4 {
let result = match self.index {
0 if self.bounds.contains(BuiltinBound::Send) => Some(BuiltinBound::Send),
1 if self.bounds.contains(BuiltinBound::Sized) => Some(BuiltinBound::Sized),
2 if self.bounds.contains(BuiltinBound::Copy) => Some(BuiltinBound::Copy),
3 if self.bounds.contains(BuiltinBound::Sync) => Some(BuiltinBound::Sync),
_ => None
};

self.index += 1;

if result.is_some() {
return result;
}
}

return None;
self.bit_set.next().map(|b| unsafe { mem::transmute(b) })
}
}

Expand All @@ -2133,10 +2119,11 @@ impl<'a> IntoIterator for &'a BuiltinBounds {
type IntoIter = BuiltinBoundsIter;

fn into_iter(self) -> BuiltinBoundsIter {
BuiltinBoundsIter { bounds: self.clone(), index: 0 }
BuiltinBoundsIter { bit_set: self.bit_set.into_iter() }
}
}

#[repr(u8)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcDecodable, RustcEncodable, Hash, Debug)]
pub enum BuiltinBound {
Send,
Expand Down
96 changes: 96 additions & 0 deletions src/librustc_data_structures/bitset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ops::{Add, Sub, Shl, Shr, BitAnd, BitOr};
use std::num::{Zero, One};
use std::cmp::PartialEq;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct BitSet<N> {
bits: N
}

pub trait UnsignedInt : Zero
+ One
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Shl<Self, Output=Self>
+ Shr<Self, Output=Self>
+ BitAnd<Self, Output=Self>
+ BitOr<Self, Output=Self>
+ PartialEq<Self>
+ PartialOrd<Self>
+ Copy {}

impl UnsignedInt for u8 {}

pub type U8BitSet = BitSet<u8>;

impl<N: UnsignedInt> BitSet<N> {
pub fn empty() -> BitSet<N> {
BitSet { bits: Zero::zero() }
}

pub fn insert(&mut self, value: N) {
self.bits = self.bits | (N::one() << value);
}

pub fn contains(&self, value: N) -> bool {
((self.bits >> value) & N::one()) == N::one()
}

pub fn iter(&self) -> BitSetIter<N> {
self.into_iter()
}

pub fn is_empty(&self) -> bool {
self.bits == N::zero()
}

pub fn is_superset(&self, other: BitSet<N>) -> bool {
(self.bits & other.bits) == other.bits
}
}

pub struct BitSetIter<N> {
bits: N,
index: N
}

impl<N: UnsignedInt> Iterator for BitSetIter<N> {
type Item = N;

fn next(&mut self) -> Option<N> {
if self.bits == N::zero() {
return None;
}

while (self.bits & N::one()) == N::zero() {
self.index = self.index + N::one();
self.bits = self.bits >> N::one();
}

let result = self.index;

self.index = self.index + N::one();
self.bits = self.bits >> N::one();
Some(result)
}
}


impl<'a, N: UnsignedInt> IntoIterator for &'a BitSet<N> {
type Item = N;
type IntoIter = BitSetIter<N>;

fn into_iter(self) -> BitSetIter<N> {
BitSetIter { bits: self.bits, index: N::zero() }
}
}
2 changes: 2 additions & 0 deletions src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
html_root_url = "http://doc.rust-lang.org/nightly/")]

#![feature(rustc_private, staged_api)]
#![feature(zero_one)]
#![cfg_attr(test, feature(test))]

#[macro_use] extern crate log;
Expand All @@ -36,4 +37,5 @@ extern crate serialize as rustc_serialize; // used by deriving
pub mod snapshot_vec;
pub mod graph;
pub mod bitvec;
pub mod bitset;
pub mod unify;

0 comments on commit 2c8ab28

Please sign in to comment.