1
2use std::cmp;
3use std::ops;
4use std::ptr;
5use std::mem;
6
7use std::fmt::{self, Debug};
8
9use std::marker::PhantomData;
10
11use crate::index_error::IndexingError;
12use crate::index_error::index_error;
13use crate::proof::*;
14use std;
15
16use crate::container_traits::*;
17use crate::indexing::{IntoCheckedRange};
18use crate::{Id, Index, Range};
19use crate::ContainerPrivate;
20
21pub struct Container<'id, Array, Mode = ()> {
35 id: Id<'id>,
36 arr: Array,
37 mode: PhantomData<Mode>,
38}
39
40#[derive(Debug, Copy, Clone)]
42pub enum OnlyIndex { }
43
44impl<'id, Array, Mode> Debug for Container<'id, Array, Mode>
45 where Array: Debug
46{
47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48 self.arr.fmt(f)
49 }
50}
51
52impl<'id, Array, Mode> Clone for Container<'id, Array, Mode>
64 where Array: Clone + FixedLength
65{
66 fn clone(&self) -> Self {
67 Container {
68 id: self.id,
69 arr: self.arr.clone(),
70 mode: self.mode,
71 }
72 }
73}
74
75impl<'id, Array, Mode> ContainerPrivate for Container<'id, Array, Mode> {
76 type Array = Array;
77 #[inline(always)]
78 fn array(&self) -> &Self::Array {
79 &self.arr
80 }
81 #[inline(always)]
82 fn array_mut(&mut self) -> &mut Self::Array {
83 &mut self.arr
84 }
85}
86
87impl<'id, Array, T, Mode> Container<'id, Array, Mode>
88 where Array: Trustworthy<Item=T>,
89{
90 #[inline]
91 pub fn len(&self) -> usize {
92 self.arr.base_len()
93 }
94
95 pub fn only_index(self) -> Container<'id, Array, OnlyIndex> {
100 Container {
101 id: self.id,
102 arr: self.arr,
103 mode: PhantomData,
104 }
105 }
106
107 #[inline]
109 pub fn empty_range(&self) -> Range<'id> {
110 unsafe {
111 Range::from(0, 0)
112 }
113 }
114
115 #[inline]
117 pub fn range(&self) -> Range<'id> {
118 unsafe {
119 Range::from(0, self.len())
120 }
121 }
122
123 #[inline]
125 pub fn vet(&self, index: usize) -> Result<Index<'id>, IndexingError> {
126 if index < self.len() {
127 unsafe {
128 Ok(Index::new(index))
129 }
130 } else {
131 Err(index_error())
132 }
133 }
134
135 #[inline]
137 pub fn vet_range(&self, r: ops::Range<usize>) -> Result<Range<'id>, IndexingError> {
138 if r.start <= r.end && r.end <= self.len() {
139 unsafe {
140 Ok(Range::from(r.start, r.end))
141 }
142 } else {
143 Err(index_error())
144 }
145 }
146
147 #[inline]
148 pub fn split_at<P>(&self, index: Index<'id, P>) -> (Range<'id>, Range<'id, P>) {
149 unsafe {
150 (Range::from(0, index.index), Range::from_any(index.index, self.len()))
151 }
152 }
153
154 #[inline]
157 pub fn split_after(&self, index: Index<'id>) -> (Range<'id, NonEmpty>, Range<'id>) {
158 let mid = index.index + 1; unsafe {
160 (Range::from_ne(0, mid), Range::from(mid, self.len()))
161 }
162 }
163
164 #[inline]
170 pub fn split_around<P>(&self, r: Range<'id, P>) -> (Range<'id>, Range<'id>) {
171 unsafe {
172 (Range::from(0, r.start), Range::from(r.end, self.len()))
173 }
174 }
175
176
177 #[inline]
179 pub fn before<P>(&self, index: Index<'id, P>) -> Range<'id> {
180 self.range_of(..index)
181 }
182
183 #[inline]
185 pub fn after(&self, index: Index<'id>) -> Range<'id> {
186 self.range_of(index.after()..)
187 }
188
189 #[inline]
190 pub fn range_of<P, R>(&self, r: R) -> Range<'id>
191 where R: OnePointRange<Index<'id, P>>,
192 {
193 debug_assert!(!(r.start().is_some() && r.end().is_some()));
194 unsafe {
195 let start = r.start().map(|i| i.index).unwrap_or(0);
196 let end = r.end().map(|i| i.index).unwrap_or(self.len());
197 debug_assert!(start <= end && end <= self.len());
198 Range::from(start, end)
199 }
200 }
201
202
203 #[inline]
207 pub fn forward(&self, index: &mut Index<'id>) -> bool {
208 let i = index.index + 1;
209 if i < self.len() {
210 index.index = i;
211 true
212 } else { false }
213 }
214
215 #[inline]
219 pub fn forward_by(&self, index: &mut Index<'id>, offset: usize) -> bool {
220 let i = index.index + offset;
221 if i < self.len() {
222 index.index = i;
223 true
224 } else { false }
225 }
226
227 #[inline]
229 pub fn forward_range_by<P>(&self, r: Range<'id, P>, offset: usize) -> Range<'id> {
230 let start = r.start.saturating_add(offset);
231 let end = r.end.saturating_add(offset);
232 let len = self.len();
233 unsafe {
234 Range::from(cmp::min(len, start), cmp::min(len, end))
235 }
236 }
237
238 #[inline]
242 pub fn backward(&self, index: &mut Index<'id>) -> bool {
243 let i = index.index;
244 if i > 0 {
245 index.index = i - 1;
246 true
247 } else { false }
248 }
249
250 #[inline]
256 pub fn scan_from<'b, F>(&'b self, index: Index<'id>, mut f: F) -> Range<'id, NonEmpty>
257 where F: FnMut(&'b T) -> bool, T: 'b,
258 Array: Contiguous<Item=T>,
259 {
260 let mut end = index;
261 for elt in &self[self.after(index)] {
262 if !f(elt) {
263 break;
264 }
265 end.index += 1;
266 }
267 end.index += 1;
268 unsafe {
269 Range::from_ne(index.index, end.index)
270 }
271 }
272
273 #[inline]
279 pub fn scan_from_rev<'b, F>(&'b self, index: Index<'id>, mut f: F) -> Range<'id, NonEmpty>
280 where F: FnMut(&'b T) -> bool, T: 'b,
281 Array: Contiguous<Item=T>,
282 {
283 unsafe {
284 let mut start = index;
285 for elt in self[..index].iter().rev() {
286 if !f(elt) {
287 break;
288 }
289 start.index -= 1;
290 }
291 Range::from_ne(start.index, index.index + 1)
292 }
293 }
294
295 #[inline]
299 pub fn scan_range<'b, F, P>(&'b self, range: Range<'id, P>, mut f: F)
300 -> (Range<'id>, Range<'id>)
301 where F: FnMut(&'b T) -> bool, T: 'b,
302 Array: Contiguous<Item=T>,
303 {
304 let mut end = range.start;
305 for elt in &self[range] {
306 if !f(elt) {
307 break;
308 }
309 end += 1;
310 }
311 unsafe {
312 (Range::from(range.start, end),
313 Range::from(end, range.end))
314 }
315 }
316
317 #[inline]
319 pub fn swap(&mut self, i: Index<'id>, j: Index<'id>)
320 where Array: GetUncheckedMut
321 {
322 unsafe {
323 let self_mut = self as *mut Self;
324 let pi: *mut _ = &mut (*self_mut)[i];
325 let pj: *mut _ = &mut (*self_mut)[j];
326 ptr::swap(pi, pj);
327 }
328 }
329
330 #[inline]
332 pub fn rotate1_up<R>(&mut self, r: R)
333 where Array: Contiguous + GetUncheckedMut,
334 R: IntoCheckedRange<'id>
335 {
336 if let Ok(r) = r.into() {
337 if r.first() != r.last() {
338 unsafe {
339 let last_ptr = &self[r.last()] as *const Array::Item;
340 let first_ptr = &mut self[r.first()] as *mut Array::Item;
341 let tmp = ptr::read(last_ptr);
342 ptr::copy(first_ptr,
343 first_ptr.offset(1),
344 r.len() - 1);
345 ptr::copy_nonoverlapping(&tmp, first_ptr, 1);
346 mem::forget(tmp);
347 }
348 }
349 }
350 }
351
352 #[inline]
354 pub fn rotate1_down<R>(&mut self, r: R)
355 where Array: Contiguous + GetUncheckedMut,
356 R: IntoCheckedRange<'id>
357 {
358 if let Ok(r) = r.into() {
359 if r.first() != r.last() {
360 unsafe {
361 let last_ptr = &mut self[r.last()] as *mut Array::Item;
362 let first_ptr = &mut self[r.first()] as *mut Array::Item;
363 let tmp = ptr::read(first_ptr);
364 ptr::copy(first_ptr.offset(1),
365 first_ptr,
366 r.len() - 1);
367 ptr::copy_nonoverlapping(&tmp, last_ptr, 1);
368 mem::forget(tmp);
369 }
370 }
371 }
372 }
373
374 #[inline]
376 pub fn index_twice<P, Q>(&mut self, r: Range<'id, P>, s: Range<'id, Q>)
377 -> Result<(&mut [T], &mut [T]), IndexingError>
378 where Array: ContiguousMut
379 {
380 if r.end <= s.start {
381 let self_mut = self as *mut Self;
382 unsafe {
383 Ok((&mut (*self_mut)[r], &mut (*self_mut)[s]))
384 }
385 } else {
386 Err(index_error())
387 }
388 }
389
390 pub fn zip_mut_raw<P, Q, F>(&mut self, r: Range<'id, P>, s: Range<'id, Q>, mut f: F)
392 where F: FnMut(*mut T, *mut T),
393 Array: GetUncheckedMut,
394 {
395 let len = cmp::min(r.len(), s.len());
396 for i in 0..len {
397 unsafe {
398 f(
399 self.arr.xget_unchecked_mut(r.start + i),
400 self.arr.xget_unchecked_mut(s.start + i)
401 )
402 }
403 }
404 }
405}
406
407impl<'id, Array, T> Container<'id, Array, OnlyIndex>
409 where Array: Pushable<Item=T>,
410{
411 pub fn push(&mut self, element: T) -> Index<'id> {
416 let i = self.arr.push(element);
417 debug_assert!(i < self.arr.base_len());
418 unsafe {
419 Index::new(i)
420 }
421 }
422
423 pub fn insert<Q>(&mut self, index: Index<'id, Q>, element: T) {
428 debug_assert!(index.index <= self.arr.base_len());
429 unsafe {
430 self.arr.insert_unchecked(index.index, element);
431 }
432 }
433}
434
435impl<'id, Array, T, Mode> Container<'id, Array, Mode>
436 where Array: Trustworthy<Item=T> + FixedLength
437{
438 pub fn make_twin<Array2>(&self, arr: Array2) -> Result<Container<'id, Array2, OnlyIndex>, IndexingError>
446 where Array2: Trustworthy + FixedLength
447 {
448 if self.len() != arr.base_len() {
449 Err(index_error())
450 } else {
451 Ok(Container { id: self.id, arr: arr, mode: PhantomData })
452 }
453 }
454}
455
456impl<'id, Array, M> ops::Index<Index<'id>> for Container<'id, Array, M>
458 where Array: GetUnchecked
459{
460 type Output = Array::Item;
461 #[inline(always)]
462 fn index(&self, index: Index<'id>) -> &Self::Output {
463 unsafe {
464 self.arr.xget_unchecked(index.index)
465 }
466 }
467}
468
469impl<'id, Array, M> ops::IndexMut<Index<'id>> for Container<'id, Array, M>
471 where Array: GetUncheckedMut
472{
473 #[inline(always)]
474 fn index_mut(&mut self, index: Index<'id>) -> &mut Self::Output {
475 unsafe {
476 self.arr.xget_unchecked_mut(index.index)
477 }
478 }
479}
480
481impl<'id, T, Array, P, M> ops::Index<Range<'id, P>> for Container<'id, Array, M>
483 where Array: Contiguous<Item=T>,
484{
485 type Output = [T];
486 #[inline(always)]
487 fn index(&self, r: Range<'id, P>) -> &Self::Output {
488 unsafe {
489 std::slice::from_raw_parts(
490 self.arr.begin().offset(r.start as isize),
491 r.len())
492 }
493 }
494}
495
496impl<'id, Array, P, M> ops::IndexMut<Range<'id, P>> for Container<'id, Array, M>
498 where Array: ContiguousMut,
499{
500 #[inline(always)]
501 fn index_mut(&mut self, r: Range<'id, P>) -> &mut Self::Output {
502 unsafe {
503 std::slice::from_raw_parts_mut(
504 self.arr.begin_mut().offset(r.start as isize),
505 r.len())
506 }
507 }
508}
509
510impl<'id, T, P, Array, M> ops::Index<ops::RangeFrom<Index<'id, P>>> for Container<'id, Array, M>
512 where Array: Contiguous<Item=T>,
513{
514 type Output = [T];
515 #[inline(always)]
516 fn index(&self, r: ops::RangeFrom<Index<'id, P>>) -> &[T] {
517 let i = r.start.index;
518 unsafe {
519 std::slice::from_raw_parts(
520 self.arr.begin().offset(i as isize),
521 self.len() - i)
522 }
523 }
524}
525
526impl<'id, T, P, Array, M> ops::IndexMut<ops::RangeFrom<Index<'id, P>>> for Container<'id, Array, M>
528 where Array: ContiguousMut<Item=T>,
529{
530 #[inline(always)]
531 fn index_mut(&mut self, r: ops::RangeFrom<Index<'id, P>>) -> &mut [T] {
532 let i = r.start.index;
533 unsafe {
534 std::slice::from_raw_parts_mut(
535 self.arr.begin_mut().offset(i as isize),
536 self.len() - i)
537 }
538 }
539}
540
541impl<'id, T, P, Array, M> ops::Index<ops::RangeTo<Index<'id, P>>> for Container<'id, Array, M>
543 where Array: Contiguous<Item=T>,
544{
545 type Output = [T];
546 #[inline(always)]
547 fn index(&self, r: ops::RangeTo<Index<'id, P>>) -> &[T] {
548 let i = r.end.index;
549 unsafe {
550 std::slice::from_raw_parts(self.arr.begin(), i)
551 }
552 }
553}
554
555impl<'id, T, P, Array, M> ops::IndexMut<ops::RangeTo<Index<'id, P>>> for Container<'id, Array, M>
557 where Array: ContiguousMut<Item=T>,
558{
559 #[inline(always)]
560 fn index_mut(&mut self, r: ops::RangeTo<Index<'id, P>>) -> &mut [T] {
561 let i = r.end.index;
562 unsafe {
563 std::slice::from_raw_parts_mut(self.arr.begin_mut(), i)
564 }
565 }
566}
567
568impl<'id, T, Array, M> ops::Index<ops::RangeFull> for Container<'id, Array, M>
570 where Array: Contiguous<Item=T>,
571{
572 type Output = [T];
573 #[inline(always)]
574 fn index(&self, _: ops::RangeFull) -> &[T] {
575 self.arr.as_slice()
576 }
577}
578
579impl<'id, T, Array> ops::IndexMut<ops::RangeFull> for Container<'id, Array>
581 where Array: ContiguousMut<Item=T>,
582{
583 #[inline(always)]
584 fn index_mut(&mut self, _: ops::RangeFull) -> &mut [T] {
585 self.arr.as_mut_slice()
586 }
587}
588
589
590pub fn scope<Array, F, Out>(arr: Array, f: F) -> Out
649 where F: for<'id> FnOnce(Container<'id, Array>) -> Out,
650 Array: Trustworthy,
651{
652 f(Container { id: Id::default(), arr: arr, mode: PhantomData })
670}
671
672#[test]
673fn test_intervals() {
674 let mut data = [0; 8];
675 scope(&mut data[..], |mut data| {
676 let r = data.range();
677 for (index, part) in r.subdivide(3).enumerate() {
678 for elt in &mut data[part] {
679 *elt = index;
680 }
681 }
682 });
683 assert_eq!(&data[..], &[0, 0, 1, 1, 1, 2, 2, 2]);
684}
685
686
687#[test]
688fn intervals() {
689 let mut data = [0; 16];
690 scope(&mut data[..], |mut arr| {
691 let r = arr.range();
692 for elt in &mut arr[r] {
693 *elt += 1;
694 }
695 });
697}
698
699
700#[test]
701fn test_scan() {
702 let mut data = [0, 0, 0, 1, 2];
703 scope(&mut data[..], |data| {
704 let r = data.range().nonempty().unwrap();
705 let range = data.scan_from(r.first(), |elt| *elt == 0);
706 assert_eq!(&data[range], &[0, 0, 0]);
707 let range = data.scan_from(range.last(), |elt| *elt != 0);
708 assert_eq!(&data[range], &[0, 1, 2]);
709 });
710}
711
712#[test]
713fn test_nonempty() {
714 let mut data = [0, 1, 2, 3, 4, 5];
715 scope(&mut data[..], |data| {
716 let mut r = data.range().nonempty().unwrap();
717 assert_eq!(data[r.first()], 0);
718 assert_eq!(data[r.lower_middle()], 2);
719 assert_eq!(data[r.upper_middle()], 3);
720 assert_eq!(data[r.last()], 5);
721
722 assert!(r.advance());
723 assert_eq!(data[r.first()], 1);
724 assert_eq!(data[r.lower_middle()], 3);
725 assert_eq!(data[r.upper_middle()], 3);
726 assert_eq!(data[r.last()], 5);
727
728 assert!(r.advance());
729 assert_eq!(data[r.first()], 2);
730 assert_eq!(data[r.lower_middle()], 3);
731 assert_eq!(data[r.upper_middle()], 4);
732 assert_eq!(data[r.last()], 5);
733
734 while r.advance() { }
736 assert_eq!(data[r.first()], 5);
737 assert_eq!(data[r.lower_middle()], 5);
738 assert_eq!(data[r.upper_middle()], 5);
739 assert_eq!(data[r.last()], 5);
740 });
741}
742
743#[test]
744fn test_contains() {
745 let mut data = [0, 1, 2, 3, 4, 5];
746 scope(&mut data[..], |data| {
747 let r = data.range();
748 for i in 0..data.len() {
749 assert!(r.contains(i).is_some());
750 assert_eq!(r.contains(i).unwrap(), data.vet(i).unwrap());
751 }
752 assert!(r.contains(r.len()).is_none());
753 assert!(data.vet(r.len()).is_err());
754 });
755}
756
757#[test]
758fn test_is_send_sync() {
759 fn _is_send_sync<T: Send + Sync>() { }
760
761 fn _test<'id>() {
762 _is_send_sync::<Id<'id>>();
763 _is_send_sync::<Index<'id>>();
764 _is_send_sync::<Range<'id>>();
765 }
766}