1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

// ++++++++++++++++++++ meta ++++++++++++++++++++ 

pub trait OrderedCollection {}

//pub trait SequenceCollection {}

//pub trait AssociativeCollection {}

// ++++++++++++++++++++ capacity ++++++++++++++++++++ 

pub trait CollectLen {
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool { self.len() == 0 }
}

pub trait CollectCapacity: CollectLen {
    fn capacity(&self) -> usize;
    fn capacity_reached(&self) -> bool { self.len() == self.capacity() }

    /// TODO naming? `unused_capacity`?
    fn free_space(&self) -> usize { self.capacity() - self.len() }
}

pub trait CollectClear {
    fn clear(&mut self);
}

pub trait CollectShrinkToFit: CollectCapacity {
    fn shrink_to_fit(&mut self);
}

pub trait CollectReserve: CollectCapacity {
    fn reserve(&mut self, n: usize);
    fn reserve_exact(&mut self, n: usize);

    fn reserve_capacity(&mut self, new_cap: usize){  
        let len = self.len();
        if new_cap > len { return }
        self.reserve(new_cap - len);
    }
    fn reserve_capacity_exact(&mut self, new_cap: usize){ 
        let len = self.len();
        if new_cap > len { return }
        self.reserve_exact(new_cap - len);
    }
}

// ++++++++++++++++++++ element access ++++++++++++++++++++ 

pub trait CollectContains<Q: ?Sized> {
    fn contains(&self, query: &Q) -> bool;
}

/// NOTE: Temporary workaround for lack of HK-lifetimes.
pub trait _CollectGet<'a, K: ?Sized> { 
    type Output: 'a;
}

pub trait CollectGet<K: ?Sized>: for<'a> _CollectGet<'a, K> { 
    fn get<'a>(&'a self, key: &K) -> Option<<Self as _CollectGet<'a, K>>::Output>;
}

/// NOTE: Temporary workaround for lack of HK-lifetimes.
pub trait _CollectGetMut<'a, K: ?Sized> { 
    type OutputMut: 'a;
}

pub trait CollectGetMut<K: ?Sized>: CollectGet<K> + for<'a> _CollectGetMut<'a, K> {
    fn get_mut<'a>(&'a mut self, key: &K) -> Option<<Self as _CollectGetMut<'a, K>>::OutputMut>;
}

/// NOTE: Temporary workaround for lack of HK-lifetimes.
pub trait _CollectIter<'a> {
    type Iter: Iterator + 'a;
}

pub trait CollectIter: for<'a> _CollectIter<'a> {
    fn iter<'a>(&'a self) -> <Self as _CollectIter<'a>>::Iter;
}

/// NOTE: Temporary workaround for lack of HK-lifetimes.
pub trait _CollectIterMut<'a> {
    type IterMut: Iterator + 'a;
}

pub trait CollectIterMut: CollectIter + for<'a> _CollectIterMut<'a> {
    fn iter_mut<'a>(&'a mut self) -> <Self as _CollectIterMut<'a>>::IterMut;
}

// ++++++++++++++++++++ modifiers ++++++++++++++++++++ 

pub trait CollectInsert<Val> {
    type Ret;
    fn insert(&mut self, val: Val) -> Self::Ret;
}

pub trait CollectInsert2<Key, Val> {
    type Ret;
    fn insert(&mut self, key: Key, val: Val) -> Self::Ret;
}

// FIXME default impl
/*impl<T: ?Sized, Key, Val> CollectInsert<(Key, Val)> for T
    where T: CollectInsert2<Key, Val> 
{
    type Ret = <Self as CollectInsert2<Key, Val>>::Ret;
    fn insert(&self, pair: (Key, Val)) -> Self::Ret { self.insert(pair.0, pair.1) }
}*/

pub trait CollectRemove<Q: ?Sized> {
    type Ret;
    fn remove(&mut self, query: &Q) -> Self::Ret;
}

pub trait CollectPushFront<Val> {
    fn push_front(&mut self, val: Val);
}

pub trait CollectPushBack<Val> {
    fn push_back(&mut self, val: Val);
}

pub trait CollectPopFront {
    type Val;
    fn pop_front(&mut self) -> Option<Self::Val>;
}

pub trait CollectPopBack {
    type Val;
    fn pop_back(&mut self) -> Option<Self::Val>;
}

/* TODO
    truncate
    split_off/at
    split
    rsplit
    front[_mut]
    back[_mut]
    starts_with
    ends_with
    binary_search[_by]
    sort[_by]
    set_all
    
*/