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
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
#![no_std]
#![allow(incomplete_features)]
#![feature(const_fn)]
#![feature(const_generics)]
#![feature(const_if_match)]
#![feature(const_raw_ptr_to_usize_cast)]
#![feature(core_intrinsics)]
#![feature(doc_cfg)]
#![feature(exact_size_is_empty)]
#![feature(forget_unsized)]
#![feature(maybe_uninit_extra)]
#![feature(maybe_uninit_ref)]
#![feature(maybe_uninit_uninit_array)]
#![cfg_attr(feature = "std", feature(read_initializer))]
#![feature(slice_partition_dedup)]
#![feature(specialization)]
#![feature(trusted_len)]

pub use crate::errors::{CapacityError, PushCapacityError};
pub use crate::iterators::*;
pub use crate::trait_impls::*;
use core::cmp::{Ord, PartialEq};
use core::intrinsics;
use core::marker::PhantomData;
use core::mem::{self, MaybeUninit};
use core::ops::{Bound::Excluded, Bound::Included, Bound::Unbounded, RangeBounds};
use core::ptr;
use core::slice;

#[cfg(any(feature = "std", rustdoc))]
extern crate alloc;

#[cfg(feature = "std")]
extern crate std;

#[cfg(any(feature = "std", rustdoc))]
use alloc::vec::Vec;

mod iterators;
#[macro_use]
mod macros;
#[doc(hidden)]
mod errors;
mod trait_impls;
#[doc(hidden)]
pub mod utils;

/// A [`Vec`](alloc::vec::Vec)-like struct (mostly directly API-compatible where it can be)
/// implemented with const generics around an array of fixed `N` capacity.
pub struct StaticVec<T, const N: usize> {
  data: MaybeUninit<[T; N]>,
  length: usize,
}

impl<T, const N: usize> StaticVec<T, N> {
  /// Returns a new StaticVec instance.
  #[inline(always)]
  pub const fn new() -> Self {
    Self {
      data: Self::new_data_uninit(),
      length: 0,
    }
  }

  /// Returns a new StaticVec instance filled with the contents, if any, of a slice reference,
  /// which can be either `&mut` or `&` as if it is `&mut` it will implicitly coerce to `&`.
  /// If the slice has a length greater than the StaticVec's declared capacity,
  /// any contents after that point are ignored.
  /// Locally requires that `T` implements [`Copy`](core::marker::Copy) to avoid soundness issues.
  #[inline]
  pub fn new_from_slice(values: &[T]) -> Self
  where T: Copy {
    let length = values.len().min(N);
    Self {
      data: {
        let mut data = Self::new_data_uninit();
        unsafe {
          values
            .as_ptr()
            .copy_to_nonoverlapping(data.as_mut_ptr() as *mut T, length);
          data
        }
      },
      length,
    }
  }

  /// Returns a new StaticVec instance filled with the contents, if any, of an array.
  /// If the array has a length greater than the StaticVec's declared capacity,
  /// any contents after that point are ignored.
  ///
  /// The `N2` parameter does not need to be provided explicitly, and can be inferred from the array
  /// itself. This function does *not* leak memory, as any ignored extra elements in the source
  /// array are explicitly dropped with [`drop_in_place`](core::ptr::drop_in_place) before
  /// [`forget`](core::mem::forget) is called on it.
  ///
  /// Example usage:
  /// ```
  /// // Same input length as the declared capacity:
  /// let v = StaticVec::<i32, 3>::new_from_array([1, 2, 3]);
  /// assert_eq!(v, [1, 2, 3]);
  /// // Truncated to fit the declared capacity:
  /// let v2 = StaticVec::<i32, 3>::new_from_array([1, 2, 3, 4, 5, 6]);
  /// assert_eq!(v2, [1, 2, 3]);
  /// ```
  /// Note that StaticVec also implements [`From`](std::convert::From) for both slices and static
  /// arrays, which may prove more ergonomic in some cases as it allows for a greater degree of
  /// type inference:
  /// ```
  /// // The StaticVec on the next line is inferred to be of type `StaticVec<&'static str, 4>`.
  /// let v = StaticVec::from(["A", "B", "C", "D"]);
  /// ```
  #[inline]
  pub fn new_from_array<const N2: usize>(mut values: [T; N2]) -> Self {
    if N == N2 {
      Self::from(values)
    } else {
      Self {
        data: {
          unsafe {
            let mut data = Self::new_data_uninit();
            values
              .as_ptr()
              .copy_to_nonoverlapping(data.as_mut_ptr() as *mut T, N2.min(N));
            // Drops any extra values left in the source array, then "forgets it".
            ptr::drop_in_place(values.get_unchecked_mut(N2.min(N)..N2));
            mem::forget_unsized(values);
            data
          }
        },
        length: N2.min(N),
      }
    }
  }

  /// A version of [`new_from_array`](crate::StaticVec::new_from_array) specifically designed
  /// for use as a `const fn` constructor (although it can of course be used in non-const contexts
  /// as well.)
  ///
  /// Being `const` necessitates that this function can only accept arrays with a length
  /// exactly equivalent to the declared capacity of the resulting StaticVec, so if you do need
  /// flexibility with regards to input lengths it's recommended that you use
  /// [`new_from_array`](crate::StaticVec::new_from_array) or the [`From`](std::convert::From)
  /// implementations instead.
  ///
  /// Note that both forms of the [`staticvec!`] macro are implemented using
  /// [`new_from_const_array`](crate::StaticVec::new_from_const_array), so you may also prefer
  /// to use them instead of it directly.
  #[inline(always)]
  pub const fn new_from_const_array(values: [T; N]) -> Self {
    Self {
      data: MaybeUninit::new(values),
      length: N,
    }
  }

  /// Returns a new StaticVec instance filled with the return value of an initializer function.
  /// The length field of the newly created StaticVec will be equal to its capacity.
  ///
  /// Example usage:
  /// ```
  /// let mut i = 0;
  /// let v = StaticVec::<i32, 64>::filled_with(|| { i += 1; i });
  /// assert_eq!(v.len(), 64);
  /// assert_eq!(v[0], 1);
  /// assert_eq!(v[1], 2);
  /// assert_eq!(v[2], 3);
  /// assert_eq!(v[3], 4);
  /// ```
  #[inline]
  pub fn filled_with<F>(mut initializer: F) -> Self
  where F: FnMut() -> T {
    let mut res = Self::new();
    // You might think it would make more sense to use `push_unchecked` here.
    // Originally, I did also! However, as of today (November 19, 2019), doing so
    // both in this function and several others throughout the crate inhibits the ability
    // of `rustc` to fully unroll and autovectorize various constant-bounds loops. If this changes
    // in the future, feel free to open a PR switching out the manual code for `get_unchecked`, if
    // you happen to notice it before I do.
    for i in 0..N {
      unsafe {
        res.mut_ptr_at_unchecked(i).write(initializer());
        res.length += 1;
      }
    }
    res
  }

  /// Returns a new StaticVec instance filled with the return value of an initializer function.
  /// Unlike for [`filled_with`](crate::StaticVec::filled_with), the initializer function in
  /// this case must take a single usize variable as an input parameter, which will be called
  /// with the current index of the `0..N` loop that
  /// [`filled_with_by_index`](crate::StaticVec::filled_with_by_index) is implemented with
  /// internally. The length field of the newly created StaticVec will be equal to its capacity.
  ///
  /// Example usage:
  /// ```
  /// let v = StaticVec::<usize, 64>::filled_with_by_index(|i| { i + 1 });
  /// assert_eq!(v.len(), 64);
  /// assert_eq!(v[0], 1);
  /// assert_eq!(v[1], 2);
  /// assert_eq!(v[2], 3);
  /// assert_eq!(v[3], 4);
  /// ```
  #[inline]
  pub fn filled_with_by_index<F>(mut initializer: F) -> Self
  where F: FnMut(usize) -> T {
    let mut res = Self::new();
    for i in 0..N {
      unsafe {
        res.mut_ptr_at_unchecked(i).write(initializer(i));
        res.length += 1;
      }
    }
    res
  }

  /// Returns the current length of the StaticVec.
  /// Just as for a normal [`Vec`](alloc::vec::Vec), this means the number of elements that
  /// have been added to it with [`push`](crate::StaticVec::push),
  /// [`insert`](crate::StaticVec::insert), etc. except in the case that it has been set directly
  /// with the unsafe [`set_len`](crate::StaticVec::set_len) function.
  #[inline(always)]
  pub const fn len(&self) -> usize {
    self.length
  }

  /// Returns the total capacity of the StaticVec.
  /// This is always equivalent to the generic `N` parameter it was declared with,
  /// which determines the fixed size of the backing array.
  #[inline(always)]
  pub const fn capacity(&self) -> usize {
    N
  }

  /// Does the same thing as [`capacity`](crate::StaticVec::capacity), but as an associated
  /// function rather than a method.
  #[inline(always)]
  pub const fn cap() -> usize {
    N
  }

  /// Serves the same purpose as [`capacity`](crate::StaticVec::capacity), but as an associated
  /// constant rather than a method.
  pub const CAPACITY: usize = N;

  /// Returns the remaining capacity of the StaticVec.
  #[inline(always)]
  pub const fn remaining_capacity(&self) -> usize {
    N - self.length
  }

  /// Directly sets the length field of the StaticVec to `new_len`. Useful if you intend
  /// to write to it solely element-wise, but marked unsafe due to how it creates
  /// the potential for reading from uninitialized memory later on.
  ///
  /// # Safety
  ///
  /// It is up to the caller to ensure that `new_len` is less than or equal to the StaticVec's
  /// constant `N` parameter, and that the range of elements covered by a length of `new_len` is
  /// actually initialized. Failure to do so will almost certainly result in undefined behavior.
  #[inline(always)]
  pub unsafe fn set_len(&mut self, new_len: usize) {
    debug_assert!(
      new_len <= N,
      "Attempted to unsafely set length to {}; maximum is {}!",
      new_len,
      N
    );
    self.length = new_len;
  }

  /// Returns true if the current length of the StaticVec is 0.
  #[inline(always)]
  pub const fn is_empty(&self) -> bool {
    self.length == 0
  }

  /// Returns true if the current length of the StaticVec is greater than 0.
  #[inline(always)]
  pub const fn is_not_empty(&self) -> bool {
    self.length > 0
  }

  /// Returns true if the current length of the StaticVec is equal to its capacity.
  #[inline(always)]
  pub const fn is_full(&self) -> bool {
    self.length == N
  }

  /// Returns true if the current length of the StaticVec is less than its capacity.
  #[inline(always)]
  pub const fn is_not_full(&self) -> bool {
    self.length < N
  }

  /// Returns a constant pointer to the first element of the StaticVec's internal array.
  #[inline(always)]
  pub const fn as_ptr(&self) -> *const T {
    &self.data as *const _ as *const T
  }

  /// Returns a mutable pointer to the first element of the StaticVec's internal array.
  #[inline(always)]
  pub fn as_mut_ptr(&mut self) -> *mut T {
    &mut self.data as *mut _ as *mut T
  }

  /// Returns a constant reference to a slice of the StaticVec's inhabited area.
  #[inline(always)]
  pub fn as_slice(&self) -> &[T] {
    // Safety: `self.as_ptr()` is a pointer to an array for which the first `length`
    // elements are guaranteed to be initialized. Therefore this is a valid slice.
    unsafe { slice::from_raw_parts(self.as_ptr(), self.length) }
  }

  /// Returns a mutable reference to a slice of the StaticVec's inhabited area.
  #[inline(always)]
  pub fn as_mut_slice(&mut self) -> &mut [T] {
    // Safety: See as_slice.
    unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.length) }
  }

  /// Returns a constant reference to the element of the StaticVec at `index`,
  /// if `index` is within the range `0..length`. No checks are performed to
  /// ensure that is the case, so this function is marked `unsafe` and should
  /// be used with caution only when performance is absolutely paramount.
  ///
  /// Note that unlike [`slice::get_unchecked`](https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.get_unchecked),
  /// this method only supports accessing individual elements via `usize`; it cannot also produce
  /// subslices. To unsafely get a subslice without a bounds check, use
  /// `self.as_slice().get_unchecked(a..b)`.
  ///
  /// # Safety
  ///
  /// It is up to the caller to ensure that `index` is within the appropriate bounds.
  #[inline(always)]
  pub unsafe fn get_unchecked(&self, index: usize) -> &T {
    debug_assert!(
      index < self.length,
      "Attempted to unsafely get at index {} when length is {}!",
      index,
      self.length
    );
    &*self.ptr_at_unchecked(index)
  }

  /// Returns a mutable reference to the element of the StaticVec at `index`,
  /// if `index` is within the range `0..length`. No checks are performed to
  /// ensure that is the case, so this function is marked `unsafe` and should
  /// be used with caution only when performance is absolutely paramount.
  ///
  /// The same differences between this method and the slice method of the same name
  /// apply as do for [`get_unchecked`](crate::StaticVec::get_unchecked).
  ///
  /// # Safety
  ///
  /// It is up to the caller to ensure that `index` is within the appropriate bounds.
  #[inline(always)]
  pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
    debug_assert!(
      index < self.length,
      "Attempted to unsafely get at index {} when length is {}!",
      index,
      self.length
    );
    &mut *self.mut_ptr_at_unchecked(index)
  }

  /// Returns a constant pointer to the element of the StaticVec at `index` without doing any
  /// checking to ensure that `index` is within the range `0..length`. The return value of this
  /// function is equivalent to what would be returned from `as_ptr().add(index)`.
  ///
  /// # Safety
  ///
  /// It is up to the caller to ensure that `index` is within the appropriate bounds such that the
  /// function returns a pointer to valid data.
  #[inline(always)]
  pub unsafe fn ptr_at_unchecked(&self, index: usize) -> *const T {
    self.as_ptr().add(index)
  }

  /// Returns a mutable pointer to the element of the StaticVec at `index` without doing any
  /// checking to ensure that `index` is within the range `0..length`. The return value of this
  /// function is equivalent to what would be returned from `as_mut_ptr().add(index)`.
  ///
  /// # Safety
  ///
  /// It is up to the caller to ensure that `index` is within the appropriate bounds such that the
  /// function returns a pointer to valid data.
  #[inline(always)]
  pub unsafe fn mut_ptr_at_unchecked(&mut self, index: usize) -> *mut T {
    self.as_mut_ptr().add(index)
  }

  /// Returns a constant pointer to the element of the StaticVec at `index` if `index`
  /// is within the range `0..length`, or panics if it is not. The return value of this function is
  /// equivalent to what would be returned from `as_ptr().add(index)`.
  #[inline(always)]
  pub fn ptr_at(&self, index: usize) -> *const T {
    assert!(
      index < self.length,
      "Provided index {} must be between 0 and {}!",
      index,
      self.length
    );
    unsafe { self.ptr_at_unchecked(index) }
  }

  /// Returns a mutable pointer to the element of the StaticVec at `index` if `index`
  /// is within the range `0..length`, or panics if it is not. The return value of this function is
  /// equivalent to what would be returned from `as_mut_ptr().add(index)`.
  #[inline(always)]
  pub fn mut_ptr_at(&mut self, index: usize) -> *mut T {
    assert!(
      index < self.length,
      "Provided index {} must be between 0 and {}!",
      index,
      self.length
    );
    unsafe { self.mut_ptr_at_unchecked(index) }
  }

  /// Appends a value to the end of the StaticVec without asserting that
  /// its current length is less than `N`.
  ///
  /// # Safety
  ///
  /// It is up to the caller to ensure that the length of the StaticVec
  /// prior to using this function is less than `N`. Failure to do so will result
  /// in writing to an out-of-bounds memory region.
  #[inline(always)]
  pub unsafe fn push_unchecked(&mut self, value: T) {
    debug_assert!(
      self.is_not_full(),
      "Attempted to unsafely push to a full StaticVec!"
    );
    self.mut_ptr_at_unchecked(self.length).write(value);
    self.length += 1;
  }

  /// Pops a value from the end of the StaticVec and returns it directly without asserting that
  /// the StaticVec's current length is greater than 0.
  ///
  /// # Safety
  ///
  /// It is up to the caller to ensure that the StaticVec contains at least one
  /// element prior to using this function. Failure to do so will result in reading
  /// from uninitialized memory.
  #[inline(always)]
  pub unsafe fn pop_unchecked(&mut self) -> T {
    debug_assert!(
      self.is_not_empty(),
      "Attempted to unsafely pop from an empty StaticVec!"
    );
    self.length -= 1;
    self.ptr_at_unchecked(self.length).read()
  }

  /// Pushes `value` to the StaticVec if its current length is less than its capacity,
  /// or returns a [`PushCapacityError`](crate::errors::PushCapacityError) otherwise.
  #[inline(always)]
  pub fn try_push(&mut self, value: T) -> Result<(), PushCapacityError<T, N>> {
    if self.length < N {
      unsafe { self.push_unchecked(value) };
      Ok(())
    } else {
      Err(PushCapacityError::new(value))
    }
  }

  /// Pushes a value to the end of the StaticVec. Panics if the collection is
  /// full; that is, if `self.len() == self.capacity()`.
  #[inline(always)]
  pub fn push(&mut self, value: T) {
    self
      .try_push(value)
      .expect("Insufficient remaining capacity for push!")
  }

  /// Removes the value at the last position of the StaticVec and returns it in `Some` if
  /// the StaticVec has a current length greater than 0, and returns `None` otherwise.
  #[inline(always)]
  pub fn pop(&mut self) -> Option<T> {
    if self.is_empty() {
      None
    } else {
      Some(unsafe { self.pop_unchecked() })
    }
  }

  /// Returns a constant reference to the first element of the StaticVec in `Some` if the StaticVec
  /// is not empty, or `None` otherwise.
  #[inline(always)]
  pub fn first(&self) -> Option<&T> {
    if self.is_empty() {
      None
    } else {
      Some(unsafe { self.get_unchecked(0) })
    }
  }

  /// Returns a mutable reference to the first element of the StaticVec in `Some` if the StaticVec
  /// is not empty, or `None` otherwise.
  #[inline(always)]
  pub fn first_mut(&mut self) -> Option<&mut T> {
    if self.is_empty() {
      None
    } else {
      Some(unsafe { self.get_unchecked_mut(0) })
    }
  }

  /// Returns a constant reference to the last element of the StaticVec in `Some` if the StaticVec
  /// is not empty, or `None` otherwise.
  #[inline(always)]
  pub fn last(&self) -> Option<&T> {
    if self.is_empty() {
      None
    } else {
      Some(unsafe { self.get_unchecked(self.length - 1) })
    }
  }

  /// Returns a mutable reference to the last element of the StaticVec in `Some` if the StaticVec is
  /// not empty, or `None` otherwise.
  #[inline(always)]
  pub fn last_mut(&mut self) -> Option<&mut T> {
    if self.is_empty() {
      None
    } else {
      Some(unsafe { self.get_unchecked_mut(self.length - 1) })
    }
  }

  /// Asserts that `index` is less than the current length of the StaticVec,
  /// and if so removes the value at that position and returns it. Any values
  /// that exist in later positions are shifted to the left.
  #[inline]
  pub fn remove(&mut self, index: usize) -> T {
    assert!(index < self.length);
    unsafe {
      let p = self.mut_ptr_at_unchecked(index);
      let res = p.read();
      p.offset(1).copy_to(p, self.length - index - 1);
      self.length -= 1;
      res
    }
  }

  /// Removes the first instance of `item` from the StaticVec if the item exists.
  #[inline(always)]
  pub fn remove_item(&mut self, item: &T) -> Option<T>
  where T: PartialEq {
    // Adapted this from normal Vec's implementation.
    if let Some(pos) = self.iter().position(|x| *x == *item) {
      Some(self.remove(pos))
    } else {
      None
    }
  }

  /// Returns `None` if `index` is greater than or equal to the current length of the StaticVec.
  /// otherwise, removes the value at that position and returns it in `Some`, and then
  /// moves the last value in the StaticVec into the empty slot.
  #[inline(always)]
  pub fn swap_pop(&mut self, index: usize) -> Option<T> {
    if index < self.length {
      unsafe {
        let last_value = self.ptr_at_unchecked(self.length - 1).read();
        self.length -= 1;
        Some(self.mut_ptr_at_unchecked(index).replace(last_value))
      }
    } else {
      None
    }
  }

  /// Asserts that `index` is less than the current length of the StaticVec,
  /// and if so removes the value at that position and returns it, and then
  /// moves the last value in the StaticVec into the empty slot.
  #[inline(always)]
  pub fn swap_remove(&mut self, index: usize) -> T {
    assert!(index < self.length);
    unsafe {
      let last_value = self.ptr_at_unchecked(self.length - 1).read();
      self.length -= 1;
      self.mut_ptr_at_unchecked(index).replace(last_value)
    }
  }

  /// Asserts that the current length of the StaticVec is less than `N` and that
  /// `index` is less than the length, and if so inserts `value` at that position.
  /// Any values that exist in positions after `index` are shifted to the right.
  #[inline]
  pub fn insert(&mut self, index: usize, value: T) {
    assert!(self.length < N && index <= self.length);
    unsafe {
      let p = self.mut_ptr_at_unchecked(index);
      p.copy_to(p.offset(1), self.length - index);
      p.write(value);
      self.length += 1;
    }
  }

  /// Inserts `value` at `index` if the current length of the StaticVec is less than `N` and `index`
  /// is less than the length, or returns a [`CapacityError`](crate::errors::CapacityError)
  /// otherwise. Any values that exist in positions after `index` are shifted to the right.
  #[inline]
  pub fn try_insert(&mut self, index: usize, value: T) -> Result<(), CapacityError<N>> {
    if self.length < N && index <= self.length {
      unsafe {
        let p = self.mut_ptr_at_unchecked(index);
        p.copy_to(p.offset(1), self.length - index);
        p.write(value);
        self.length += 1;
        Ok(())
      }
    } else {
      Err(CapacityError {})
    }
  }

  /// Removes all contents from the StaticVec and sets its length back to 0.
  #[inline(always)]
  pub fn clear(&mut self) {
    unsafe {
      ptr::drop_in_place(self.as_mut_slice());
    }
    self.length = 0;
  }

  /// Returns a [`StaticVecIterConst`](crate::iterators::StaticVecIterConst) over the StaticVec's
  /// inhabited area.
  #[inline(always)]
  pub fn iter(&self) -> StaticVecIterConst<T, N> {
    StaticVecIterConst {
      start: self.as_ptr(),
      end: match intrinsics::size_of::<T>() {
        0 => (self.as_ptr() as *const u8).wrapping_add(self.length) as *const T,
        _ => unsafe { self.ptr_at_unchecked(self.length) },
      },
      marker: PhantomData,
    }
  }

  /// Returns a [`StaticVecIterMut`](crate::iterators::StaticVecIterMut) over the StaticVec's
  /// inhabited area.
  #[inline(always)]
  pub fn iter_mut(&mut self) -> StaticVecIterMut<T, N> {
    StaticVecIterMut {
      start: self.as_mut_ptr(),
      end: match intrinsics::size_of::<T>() {
        0 => (self.as_mut_ptr() as *mut u8).wrapping_add(self.length) as *mut T,
        _ => unsafe { self.mut_ptr_at_unchecked(self.length) },
      },
      marker: PhantomData,
    }
  }

  /// Returns a separate, stable-sorted StaticVec of the contents of the
  /// StaticVec's inhabited area without modifying the original data.
  /// Locally requires that `T` implements [`Copy`](core::marker::Copy) to avoid soundness issues,
  /// and [`Ord`](core::cmp::Ord) to make the sorting possible.
  #[cfg(feature = "std")]
  #[doc(cfg(feature = "std"))]
  #[inline]
  pub fn sorted(&self) -> Self
  where T: Copy + Ord {
    let mut res = self.clone();
    res.sort();
    res
  }

  /// Returns a separate, unstable-sorted StaticVec of the contents of the
  /// StaticVec's inhabited area without modifying the original data.
  /// Locally requires that `T` implements [`Copy`](core::marker::Copy) to avoid soundness issues,
  /// and [`Ord`](core::cmp::Ord) to make the sorting possible.
  #[inline]
  pub fn sorted_unstable(&self) -> Self
  where T: Copy + Ord {
    let mut res = self.clone();
    res.sort_unstable();
    res
  }

  /// Returns a separate, reversed StaticVec of the contents of the StaticVec's
  /// inhabited area without modifying the original data.
  /// Locally requires that `T` implements [`Copy`](core::marker::Copy) to avoid soundness issues.
  #[inline]
  pub fn reversed(&self) -> Self
  where T: Copy {
    Self {
      data: unsafe {
        let mut res = Self::new_data_uninit();
        self
          .as_ptr()
          .copy_to_nonoverlapping(res.as_mut_ptr() as *mut T, self.length);
        res.get_mut().get_unchecked_mut(0..self.length).reverse();
        res
      },
      length: self.length,
    }
  }

  /// Copies and appends all elements, if any, of a slice (which can also be `&mut` as it will
  /// coerce implicitly to `&`) to the StaticVec. If the slice has a length greater than the
  /// StaticVec's remaining capacity, any contents after that point are ignored.
  /// Locally requires that `T` implements [`Copy`](core::marker::Copy) to avoid soundness issues.
  #[inline(always)]
  pub fn extend_from_slice(&mut self, other: &[T])
  where T: Copy {
    let added_length = other.len().min(self.remaining_capacity());
    // Safety: added_length is <= our remaining capacity and other.len.
    unsafe {
      other
        .as_ptr()
        .copy_to_nonoverlapping(self.mut_ptr_at_unchecked(self.length), added_length);
    }
    self.length += added_length;
  }

  /// Copies and appends all elements, if any, of a slice to the StaticVec if the
  /// StaticVec's remaining capacity is greater than the length of the slice, or returns
  /// a [`CapacityError`](crate::errors::CapacityError) otherwise.
  #[inline(always)]
  pub fn try_extend_from_slice(&mut self, other: &[T]) -> Result<(), CapacityError<N>>
  where T: Copy {
    let added_length = other.len();
    if self.remaining_capacity() < added_length {
      return Err(CapacityError {});
    }
    unsafe {
      other
        .as_ptr()
        .copy_to_nonoverlapping(self.mut_ptr_at_unchecked(self.length), added_length);
    }
    self.length += added_length;
    Ok(())
  }

  /// Appends `self.remaining_capacity()` (or as many as available) items from
  /// `other` to `self`. The appended items (if any) will no longer exist in `other` afterwards,
  /// as `other`'s `length` field will be adjusted to indicate.
  ///
  /// The `N2` parameter does not need to be provided explicitly, and can be inferred directly from
  /// the constant `N2` constraint of `other` (which may or may not be the same as the `N`
  /// constraint of `self`.)
  #[inline]
  pub fn append<const N2: usize>(&mut self, other: &mut StaticVec<T, N2>) {
    let item_count = self.remaining_capacity().min(other.length);
    let other_new_length = other.length - item_count;
    unsafe {
      self
        .mut_ptr_at_unchecked(self.length)
        .copy_from_nonoverlapping(other.as_ptr(), item_count);
      other
        .as_mut_ptr()
        .copy_from(other.ptr_at_unchecked(item_count), other_new_length);
    }
    other.length = other_new_length;
    self.length += item_count;
  }

  /// Returns a [`Vec`](alloc::vec::Vec) containing the contents of the StaticVec instance.
  /// The returned [`Vec`](alloc::vec::Vec) will initially have the same value for
  /// [`len`](alloc::vec::Vec::len) and [`capacity`](alloc::vec::Vec::capacity) as the source
  /// StaticVec. Note that while using this function does *not* consume the source StaticVec in
  /// the sense of rendering it completely inaccessible / unusable, it *does* empty it (that is,
  /// it will have no contents and a length of 0 afterwards.)
  #[cfg(feature = "std")]
  #[doc(cfg(feature = "std"))]
  #[allow(clippy::wrong_self_convention)]
  #[inline(always)]
  pub fn into_vec(&mut self) -> Vec<T> {
    let mut res = Vec::with_capacity(N);
    unsafe {
      self
        .as_ptr()
        .copy_to_nonoverlapping(res.as_mut_ptr(), self.length);
      res.set_len(self.length);
      self.length = 0;
      res
    }
  }

  /// Removes the specified range of elements from the StaticVec and returns them in a new one.
  #[inline]
  pub fn drain<R>(&mut self, range: R) -> Self
  // No Copy bounds here because the original StaticVec gives up all access to the values in
  // question.
  where R: RangeBounds<usize> {
    // Borrowed this part from normal Vec's implementation.
    let start = match range.start_bound() {
      Included(&idx) => idx,
      Excluded(&idx) => idx + 1,
      Unbounded => 0,
    };
    let end = match range.end_bound() {
      Included(&idx) => idx + 1,
      Excluded(&idx) => idx,
      Unbounded => self.length,
    };
    assert!(start <= end && end <= self.length);
    let res_length = end - start;
    Self {
      data: {
        let mut res = Self::new_data_uninit();
        unsafe {
          self
            .ptr_at_unchecked(start)
            .copy_to_nonoverlapping(res.as_mut_ptr() as *mut T, res_length);
          self
            .ptr_at_unchecked(end)
            .copy_to(self.mut_ptr_at_unchecked(start), self.length - end);
          self.length -= res_length;
          res
        }
      },
      length: res_length,
    }
  }

  /// Removes all elements in the StaticVec for which `filter` returns true and
  /// returns them in a new one.
  #[inline]
  pub fn drain_filter<F>(&mut self, mut filter: F) -> Self
  where F: FnMut(&mut T) -> bool {
    let mut res = Self::new();
    let old_length = self.length;
    self.length = 0;
    unsafe {
      for i in 0..old_length {
        let val = self.mut_ptr_at_unchecked(i);
        if filter(&mut *val) {
          res.mut_ptr_at_unchecked(res.length).write(val.read());
          res.length += 1;
        } else if res.length > 0 {
          self
            .ptr_at_unchecked(i)
            .copy_to_nonoverlapping(self.mut_ptr_at_unchecked(i - res.length), 1);
        }
      }
    }
    self.length = old_length - res.length;
    res
  }

  /// Removes all elements in the StaticVec for which `filter` returns false.
  #[inline(always)]
  pub fn retain<F>(&mut self, mut filter: F)
  where F: FnMut(&T) -> bool {
    self.drain_filter(|val| !filter(val));
  }

  /// Shortens the StaticVec, keeping the first `length` elements and dropping the rest.
  /// Does nothing if `length` is greater than or equal to the current length of the StaticVec.
  #[inline(always)]
  pub fn truncate(&mut self, length: usize) {
    if length < self.length {
      let old_length = self.length;
      self.length = length;
      unsafe {
        ptr::drop_in_place(self.as_mut_slice().get_unchecked_mut(length..old_length));
      }
    }
  }

  /// Splits the StaticVec into two at the given index.
  /// The original StaticVec will contain elements `0..at`,
  /// and the new one will contain elements `at..length`.
  #[inline]
  pub fn split_off(&mut self, at: usize) -> Self {
    assert!(at <= self.length);
    let split_length = self.length - at;
    self.length = at;
    Self {
      data: unsafe {
        let mut split = Self::new_data_uninit();
        self
          .ptr_at_unchecked(at)
          .copy_to_nonoverlapping(split.as_mut_ptr() as *mut T, split_length);
        split
      },
      length: split_length,
    }
  }

  /// Removes all but the first of consecutive elements in the StaticVec satisfying a given equality
  /// relation.
  #[inline(always)]
  pub fn dedup_by<F>(&mut self, same_bucket: F)
  where F: FnMut(&mut T, &mut T) -> bool {
    // Mostly the same as Vec's version.
    let new_length = self.as_mut_slice().partition_dedup_by(same_bucket).0.len();
    self.truncate(new_length);
  }

  /// Removes consecutive repeated elements in the StaticVec according to the
  /// locally required [`PartialEq`](core::cmp::PartialEq) trait implementation for `T`.
  #[inline(always)]
  pub fn dedup(&mut self)
  where T: PartialEq {
    // Exactly the same as Vec's version.
    self.dedup_by(|a, b| a == b)
  }

  /// Removes all but the first of consecutive elements in the StaticVec that
  /// resolve to the same key.
  #[inline(always)]
  pub fn dedup_by_key<F, K>(&mut self, mut key: F)
  where
    F: FnMut(&mut T) -> K,
    K: PartialEq<K>, {
    // Exactly the same as Vec's version.
    self.dedup_by(|a, b| key(a) == key(b))
  }

  /// Returns a new StaticVec representing the difference of `self` and `other` (that is,
  /// all items present in `self`, but *not* present in `other`.)
  ///
  /// The `N2` parameter does not need to be provided explicitly, and can be inferred from `other`
  /// itself.
  ///
  /// Locally requires that `T` implements [`Clone`](core::clone::Clone) to avoid soundness issues
  /// while accommodating for more types than [`Copy`](core::marker::Copy) would appropriately for
  /// this function, and [`PartialEq`](core::cmp::PartialEq) to make the item comparisons possible.
  ///
  /// Example usage:
  /// ```
  /// assert_eq!(
  ///   staticvec![4, 5, 6, 7].difference(&staticvec![1, 2, 3, 7]),
  ///   [4, 5, 6]
  /// );
  /// ```
  #[inline]
  pub fn difference<const N2: usize>(&self, other: &StaticVec<T, N2>) -> Self
  where T: Clone + PartialEq {
    let mut res = Self::new();
    for left in self {
      let mut found = false;
      for right in other {
        match left == right {
          false => (),
          true => {
            found = true;
            break;
          }
        }
      }
      if !found {
        unsafe { res.push_unchecked(left.clone()) }
      }
    }
    res
  }

  /// Returns a new StaticVec representing the symmetric difference of `self` and `other` (that is,
  /// all items present in at least one of `self` or `other`, but *not* present in both.)
  ///
  /// The `N2` parameter does not need to be provided explicitly, and can be inferred from `other`
  /// itself.
  ///
  /// Locally requires that `T` implements [`Clone`](core::clone::Clone) to avoid soundness issues
  /// while accommodating for more types than [`Copy`](core::marker::Copy) would appropriately for
  /// this function, and [`PartialEq`](core::cmp::PartialEq) to make the item comparisons possible.
  ///
  /// Example usage:
  /// ```
  /// assert_eq!(
  ///   staticvec![1, 2, 3].symmetric_difference(&staticvec![3, 4, 5]),
  ///   [1, 2, 4, 5]
  /// );
  /// ```
  #[inline]
  pub fn symmetric_difference<const N2: usize>(
    &self,
    other: &StaticVec<T, N2>,
  ) -> StaticVec<T, { N + N2 }>
  where
    T: Clone + PartialEq,
  {
    let mut res = StaticVec::new();
    for left in self {
      let mut found = false;
      for right in other {
        match left == right {
          false => (),
          true => {
            found = true;
            break;
          }
        }
      }
      if !found {
        unsafe { res.push_unchecked(left.clone()) }
      }
    }
    for right in other {
      let mut found = false;
      for left in self {
        match right == left {
          false => (),
          true => {
            found = true;
            break;
          }
        }
      }
      if !found {
        unsafe { res.push_unchecked(right.clone()) }
      }
    }
    res
  }

  #[doc(hidden)]
  #[inline(always)]
  pub(crate) const fn new_data_uninit() -> MaybeUninit<[T; N]> {
    // An internal convenience function to get an *uninitialized* instance of
    // `MaybeUninit<[T; N]>`.
    MaybeUninit::uninit()
  }
}