重写rust核心库,构建中断处理框架 #6
|
@ -11,6 +11,7 @@ extern "C" {
|
|||
pub struct SystemTimeError(Duration);
|
||||
|
||||
#[derive(Clone, Copy, Hash)]
|
||||
#[derive(Default)]
|
||||
pub struct SystemTime {
|
||||
unix_time: usize,
|
||||
ns_time: usize,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use crate::libk::alloc::vec::Vec;
|
||||
|
||||
use super::{
|
||||
clock::time::SystemTime,
|
||||
|
@ -28,12 +27,12 @@ pub struct KernelLogger {
|
|||
impl KernelLogger {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
fatal_queue: vec![],
|
||||
error_queue: vec![],
|
||||
warning_queue: vec![],
|
||||
info_queue: vec![],
|
||||
debug_queue: vec![],
|
||||
trace_queue: vec![],
|
||||
fatal_queue: Vec::new(),
|
||||
error_queue: Vec::new(),
|
||||
warning_queue: Vec::new(),
|
||||
info_queue: Vec::new(),
|
||||
debug_queue: Vec::new(),
|
||||
trace_queue: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,105 +90,18 @@ impl KernelLogger {
|
|||
self.trace_queue.push((SystemTime::now(), msg));
|
||||
}
|
||||
|
||||
pub fn iter(&self, level: LoggerLevel) -> LogIterator {
|
||||
let mut logs = vec![];
|
||||
match level {
|
||||
LoggerLevel::Fatal => {
|
||||
logs.push(&self.fatal_queue);
|
||||
}
|
||||
LoggerLevel::Error => {
|
||||
logs.push(&self.fatal_queue);
|
||||
logs.push(&self.error_queue);
|
||||
}
|
||||
LoggerLevel::Warning => {
|
||||
logs.push(&self.fatal_queue);
|
||||
logs.push(&self.error_queue);
|
||||
logs.push(&self.warning_queue);
|
||||
}
|
||||
LoggerLevel::Info => {
|
||||
logs.push(&self.fatal_queue);
|
||||
logs.push(&self.error_queue);
|
||||
logs.push(&self.warning_queue);
|
||||
logs.push(&self.info_queue);
|
||||
}
|
||||
LoggerLevel::Debug => {
|
||||
logs.push(&self.fatal_queue);
|
||||
logs.push(&self.error_queue);
|
||||
logs.push(&self.warning_queue);
|
||||
logs.push(&self.info_queue);
|
||||
logs.push(&self.debug_queue);
|
||||
}
|
||||
LoggerLevel::Trace => {
|
||||
logs.push(&self.fatal_queue);
|
||||
logs.push(&self.error_queue);
|
||||
logs.push(&self.warning_queue);
|
||||
logs.push(&self.info_queue);
|
||||
logs.push(&self.debug_queue);
|
||||
logs.push(&self.trace_queue);
|
||||
}
|
||||
}
|
||||
let mut res = vec![];
|
||||
let mut indeces = Vec::new();
|
||||
for _ in 0..logs.len() {
|
||||
indeces.push(0usize);
|
||||
}
|
||||
let all_end = |indeces: &Vec<usize>, logs: &Vec<&Vec<(SystemTime, Message)>>| {
|
||||
for i in 0..indeces.len() {
|
||||
if indeces[i] < logs.len() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
};
|
||||
while !all_end(&indeces, &logs) {
|
||||
let mut min_ind = None;
|
||||
let mut min = None;
|
||||
for i in 0..indeces.len() {
|
||||
if indeces[i] >= logs[i].len() {
|
||||
continue;
|
||||
}
|
||||
if let Some(minx) = min.as_mut() {
|
||||
if logs[i][indeces[i]].0 < *minx {
|
||||
*minx = logs[i][indeces[i]].0;
|
||||
min_ind = Some(i);
|
||||
}
|
||||
} else {
|
||||
min = Some(logs[i][indeces[i]].0);
|
||||
min_ind = Some(i);
|
||||
}
|
||||
}
|
||||
if let Some(mini) = min_ind {
|
||||
res.push(&logs[mini][indeces[mini]]);
|
||||
indeces[mini] += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
LogIterator { logs: res }
|
||||
pub fn iter(&self, _level: LoggerLevel) -> LogIterator {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LogIterator<'a> {
|
||||
logs: Vec<&'a (SystemTime, Message)>,
|
||||
pub struct LogIterator {
|
||||
}
|
||||
|
||||
impl<'a> Iterator for LogIterator<'a> {
|
||||
impl Iterator for LogIterator {
|
||||
type Item = Message;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let res = if let Some((time, msg)) = self.logs.first() {
|
||||
Some(
|
||||
MessageBuilder::new()
|
||||
.message(time)
|
||||
.append(MessageBuilder::from_message(msg.clone()))
|
||||
.build(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(_) = res {
|
||||
self.logs.remove(0);
|
||||
}
|
||||
res
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
pub mod rwlock;
|
|
@ -1,129 +0,0 @@
|
|||
use core::{ops::{Deref, DerefMut}, ptr::null_mut};
|
||||
|
||||
use alloc::{vec, vec::Vec};
|
||||
|
||||
/// ## RwLock<T>
|
||||
/// 读写锁
|
||||
///
|
||||
/// * 对于写入操作:
|
||||
///
|
||||
/// 锁没有占用时,获取锁,并执行闭包。
|
||||
///
|
||||
/// 当锁已经被占用,将闭包悬挂。
|
||||
///
|
||||
/// 释放锁时,将所有悬挂的闭包都执行。
|
||||
///
|
||||
/// 正在释放锁时,`write`方法返回`Err(())`
|
||||
///
|
||||
/// ```
|
||||
/// let num = 6;
|
||||
/// let num = RwLock::new(num);
|
||||
/// if let Err(()) = num.write(
|
||||
/// |n| *n = 10
|
||||
/// ) {}
|
||||
/// let numstr = format!("{}", num.read());
|
||||
/// ````
|
||||
pub struct RwLock<'a, T> {
|
||||
obj: T,
|
||||
locked: bool,
|
||||
dealing_hanged: bool,
|
||||
ptr: *mut RwLockWriteGuard<'a, T>,
|
||||
hanging: Vec<&'a dyn Fn(&mut T)>,
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for RwLock<'_, T> {}
|
||||
unsafe impl<T> Sync for RwLock<'_, T> {}
|
||||
|
||||
impl<'a, T> RwLock<'a, T> {
|
||||
pub fn new(obj: T) -> Self {
|
||||
Self {
|
||||
obj,
|
||||
locked: false,
|
||||
dealing_hanged: false,
|
||||
ptr: null_mut(),
|
||||
hanging: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&self) -> RwLockReadGuard<T> {
|
||||
RwLockReadGuard { obj: &self.obj }
|
||||
}
|
||||
|
||||
pub fn write(&'a mut self, f: &'a dyn Fn(&mut T)) -> Result<RwLockWriteGuard<T>, ()> {
|
||||
if self.dealing_hanged {
|
||||
Err(())
|
||||
} else if !self.locked {
|
||||
self.locked = true;
|
||||
f(&mut self.obj);
|
||||
let ptr = { self as *mut RwLock<'a, T> };
|
||||
let obj = &mut self.obj;
|
||||
let mut res = RwLockWriteGuard {
|
||||
obj,
|
||||
ptr,
|
||||
must_deal_hang: false,
|
||||
};
|
||||
self.ptr = &mut res as *mut RwLockWriteGuard<'_, T>;
|
||||
Ok(res)
|
||||
} else {
|
||||
self.hanging.push(f);
|
||||
let ptr = { self as *mut RwLock<'a, T> };
|
||||
let obj = &mut self.obj;
|
||||
Ok(RwLockWriteGuard {
|
||||
obj,
|
||||
ptr,
|
||||
must_deal_hang: false,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RwLockReadGuard<'a, T> {
|
||||
obj: &'a T,
|
||||
}
|
||||
|
||||
impl<'a, T> Deref for RwLockReadGuard<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.obj
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for RwLockReadGuard<'a, T> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
pub struct RwLockWriteGuard<'a, T> {
|
||||
obj: &'a mut T,
|
||||
ptr: *mut RwLock<'a, T>,
|
||||
must_deal_hang: bool,
|
||||
}
|
||||
|
||||
impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.obj
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.obj
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
if self.must_deal_hang {
|
||||
let p = unsafe { &mut *self.ptr };
|
||||
p.dealing_hanged = true;
|
||||
for f in p.hanging.iter() {
|
||||
f(self.obj);
|
||||
}
|
||||
p.hanging.clear();
|
||||
p.dealing_hanged = false;
|
||||
p.locked = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
use core::ptr::null_mut;
|
||||
|
||||
use alloc::{
|
||||
use crate::libk::alloc::{
|
||||
boxed::Box,
|
||||
string::{String, ToString},
|
||||
vec,
|
||||
vec::Vec,
|
||||
};
|
||||
|
||||
|
@ -141,7 +141,7 @@ impl Tty {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct Color(pub u8, pub u8, pub u8);
|
||||
|
||||
impl Color {
|
||||
|
@ -169,7 +169,7 @@ pub struct Resolution {
|
|||
pub height: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct MessageSection {
|
||||
msg: String,
|
||||
fgcolor: Color,
|
||||
|
@ -179,14 +179,14 @@ pub struct MessageSection {
|
|||
/// ## Message
|
||||
///
|
||||
/// 用`MessageBuilder`构造一个`Message`对象
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Message(Vec<MessageSection>);
|
||||
|
||||
impl ToString for Message {
|
||||
fn to_string(&self) -> String {
|
||||
let mut res = String::new();
|
||||
for MessageSection { msg, .. } in self.0.iter() {
|
||||
res += msg;
|
||||
res += msg.clone();
|
||||
}
|
||||
res
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ impl ToString for Message {
|
|||
/// ```rust
|
||||
/// use crate::kernel::tty::tty::BuilderFunctions::*;
|
||||
///
|
||||
/// message!(
|
||||
/// message_raw!(
|
||||
/// Msg("Hello, "),
|
||||
/// Msg("Metaverse"),
|
||||
/// FgColor(Color::GREEN),
|
||||
|
@ -242,10 +242,14 @@ pub enum BuilderFunctions<'a> {
|
|||
impl MessageBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
msg: Message(vec![]),
|
||||
msg: Message(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.msg.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn from_message(msg: Message) -> Self {
|
||||
Self { msg }
|
||||
}
|
||||
|
@ -302,3 +306,82 @@ impl MessageBuilder {
|
|||
self.msg
|
||||
}
|
||||
}
|
||||
|
||||
pub enum FmtMeta {
|
||||
Color(Color),
|
||||
String(String),
|
||||
ToStringable(Box<dyn ToString>),
|
||||
Hex(u8),
|
||||
Pointer(usize),
|
||||
}
|
||||
|
||||
pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
|
||||
let mut msgbuilder = MessageBuilder::new();
|
||||
let mut fmt_start = None;
|
||||
let mut fmt_end = None;
|
||||
for i in 0..fmt.len() {
|
||||
if fmt[i] == '{' {
|
||||
fmt_start = Some(i);
|
||||
}
|
||||
if fmt[i] == '}' {
|
||||
fmt_end = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let tohex = |n: u8| {
|
||||
if n < 10 {
|
||||
(b'0' + n) as char
|
||||
} else {
|
||||
(b'a' + n - 10) as char
|
||||
}
|
||||
};
|
||||
if fmt_start == None || fmt_end == None {
|
||||
msgbuilder.message_mut(&String::from_iter(fmt.iter()));
|
||||
} else {
|
||||
let fmt_start = fmt_start.unwrap();
|
||||
let fmt_end = fmt_end.unwrap();
|
||||
let mut formatter = Vec::new();
|
||||
for _ in fmt_start..=fmt_end {
|
||||
formatter.push(fmt.remove(fmt_start));
|
||||
}
|
||||
formatter.remove(formatter.len() - 1);
|
||||
formatter.remove(0);
|
||||
match meta {
|
||||
FmtMeta::Color(color) => {
|
||||
let first = fmt.split_at(fmt_start).0;
|
||||
msgbuilder.message_mut(&String::from_iter(first.iter()));
|
||||
for _ in 0..fmt_start {
|
||||
fmt.remove(0);
|
||||
}
|
||||
msgbuilder.message_mut(&String::from_iter(formatter.iter()));
|
||||
msgbuilder.foreground_color_mut(color);
|
||||
}
|
||||
FmtMeta::String(s) => {
|
||||
for c in s.chars().rev() {
|
||||
fmt.insert(fmt_start, *c);
|
||||
}
|
||||
}
|
||||
FmtMeta::ToStringable(s) => {
|
||||
for c in s.to_string().chars().rev() {
|
||||
fmt.insert(fmt_start, *c);
|
||||
}
|
||||
}
|
||||
FmtMeta::Hex(num) => {
|
||||
fmt.insert(fmt_start, tohex(num >> 4));
|
||||
fmt.insert(fmt_start, tohex(num & 0xf));
|
||||
}
|
||||
FmtMeta::Pointer(mut p) => {
|
||||
for _ in 0..16 {
|
||||
fmt.insert(fmt_start, tohex((p & 0xf) as u8));
|
||||
p >>= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut rests = Vec::new();
|
||||
while !fmt.is_empty() && fmt[0] != '{' {
|
||||
rests.push(fmt.remove(0));
|
||||
}
|
||||
msgbuilder.message_mut(&String::from_iter(rests.iter()));
|
||||
msgbuilder
|
||||
}
|
||||
|
|
61
src/lib.rs
61
src/lib.rs
|
@ -1,69 +1,14 @@
|
|||
#![no_std]
|
||||
#![feature(strict_provenance)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::{
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use core::{panic::PanicInfo, ptr::null_mut};
|
||||
|
||||
use kernel::tty::tty::{self, tty_enable, tty_text_print, Color};
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
pub mod kernel;
|
||||
pub mod libk;
|
||||
|
||||
#[panic_handler]
|
||||
unsafe fn kernel_panic_handler(info: &PanicInfo) -> ! {
|
||||
let line_in_file = if let Some(loca) = info.location() {
|
||||
loca.line().to_string()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let info = {
|
||||
let mut v = Vec::new();
|
||||
v.push(("Kernel Panic: ", (Color::RED, Color::BLACK)));
|
||||
v.push((
|
||||
if let Some(loca) = info.location() {
|
||||
loca.file()
|
||||
} else {
|
||||
"NoFile"
|
||||
},
|
||||
(Color::GREEN, Color::BLACK),
|
||||
));
|
||||
v.push((":", (Color::WHITE, Color::BLACK)));
|
||||
v.push((
|
||||
if let Some(_) = info.location() {
|
||||
line_in_file.as_str()
|
||||
} else {
|
||||
"NoLine"
|
||||
},
|
||||
(Color::WHITE, Color::BLACK),
|
||||
));
|
||||
v.push((": ", (Color::WHITE, Color::BLACK)));
|
||||
v.push((
|
||||
if let Some(&s) = info.payload().downcast_ref::<&str>() {
|
||||
s
|
||||
} else {
|
||||
"Unknown panic."
|
||||
},
|
||||
(Color::BLUE, Color::BLACK),
|
||||
));
|
||||
v.push(("\n", (Color::BLACK, Color::BLACK)));
|
||||
v
|
||||
};
|
||||
let tty = tty::tty_get(0);
|
||||
if tty != null_mut() {
|
||||
let tty = *tty;
|
||||
tty_enable(tty);
|
||||
for (msgo, (fgc, bgc)) in info.into_iter() {
|
||||
let msg = String::from(msgo).as_bytes_mut() as *mut [u8] as *mut u8;
|
||||
let p = msg.offset(msgo.len() as isize);
|
||||
let swp = *p;
|
||||
*p = 0;
|
||||
tty_text_print(tty, msg, u32::from(fgc), u32::from(bgc));
|
||||
*p = swp;
|
||||
}
|
||||
}
|
||||
unsafe fn kernel_panic_handler(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
use core::{
|
||||
alloc::Layout,
|
||||
mem::transmute,
|
||||
ops::{Deref, DerefMut},
|
||||
ptr::addr_of,
|
||||
};
|
||||
|
||||
use alloc::alloc::alloc;
|
||||
|
||||
pub struct Box<T: ?Sized> {
|
||||
inner: *mut T,
|
||||
}
|
||||
|
||||
impl<T> Box<T> {
|
||||
pub fn new(t: T) -> Self {
|
||||
unsafe {
|
||||
let inner = alloc(Layout::for_value(&t));
|
||||
inner.copy_from(addr_of!(t).cast(), 1);
|
||||
Self {
|
||||
inner: transmute(inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Deref for Box<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { self.inner.as_ref().unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> DerefMut for Box<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { self.inner.as_mut().unwrap() }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub mod boxed;
|
||||
pub mod string;
|
||||
pub mod vec;
|
|
@ -0,0 +1,81 @@
|
|||
use core::ops::{Add, AddAssign};
|
||||
|
||||
use super::vec::{Vec, VecIterator};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct String {
|
||||
data: Vec<char>,
|
||||
u8data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl String {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
data: Vec::new(),
|
||||
u8data: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
pub fn chars(&self) -> VecIterator<char> {
|
||||
self.data.iter()
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
&self.u8data[..]
|
||||
}
|
||||
|
||||
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.u8data[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<char> for String {
|
||||
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
|
||||
let data = Vec::from_iter(iter);
|
||||
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
|
||||
Self { data, u8data }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FromIterator<&'a char> for String {
|
||||
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
|
||||
let data = Vec::from_iter(iter.into_iter().map(|c| *c));
|
||||
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
|
||||
Self { data, u8data }
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for String {
|
||||
fn to_string(&self) -> String {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for String {
|
||||
type Output = Self;
|
||||
|
||||
fn add(mut self, rhs: Self) -> Self::Output {
|
||||
self.data.append(&mut rhs.chars().map(|c| *c).collect());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign for String {
|
||||
fn add_assign(&mut self, rhs: String) {
|
||||
*self = self.clone() + rhs;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToString {
|
||||
fn to_string(&self) -> String;
|
||||
}
|
||||
|
||||
impl ToString for str {
|
||||
fn to_string(&self) -> String {
|
||||
String::from_iter(self.chars())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
use core::{
|
||||
alloc::Layout,
|
||||
ops::{Index, IndexMut, Range, RangeFull},
|
||||
ptr::{addr_of_mut, null_mut},
|
||||
slice,
|
||||
};
|
||||
|
||||
use alloc::alloc::{alloc, dealloc};
|
||||
|
||||
pub struct Vec<T> {
|
||||
pointer: *mut T,
|
||||
length: usize,
|
||||
capacity: usize,
|
||||
}
|
||||
|
||||
impl<T: Default> Vec<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
pointer: null_mut(),
|
||||
length: 0,
|
||||
capacity: 0,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn extend_capacity(&mut self) {
|
||||
let newp = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
|
||||
self.pointer.copy_to(newp, self.length);
|
||||
dealloc(
|
||||
self.pointer.cast(),
|
||||
Layout::array::<T>(self.capacity).unwrap(),
|
||||
);
|
||||
self.pointer = newp;
|
||||
self.capacity *= 2;
|
||||
}
|
||||
|
||||
pub fn push(&mut self, item: T) {
|
||||
if self.pointer.is_null() {
|
||||
self.pointer = unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() };
|
||||
self.capacity = 4;
|
||||
self.length = 0;
|
||||
}
|
||||
if self.capacity == self.length {
|
||||
unsafe { self.extend_capacity() }
|
||||
}
|
||||
unsafe { self.pointer.offset(self.length as isize).write(item) };
|
||||
self.length += 1;
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, index: usize, item: T) {
|
||||
if self.capacity == self.length {
|
||||
unsafe { self.extend_capacity() }
|
||||
}
|
||||
let rearlen = self.length - index;
|
||||
unsafe {
|
||||
if rearlen != 0 {
|
||||
let tmp = alloc(Layout::array::<T>(rearlen).unwrap()).cast();
|
||||
self.pointer.offset(index as isize).copy_to(tmp, rearlen);
|
||||
self.pointer.offset(index as isize).write(item);
|
||||
self.pointer
|
||||
.offset(index as isize + 1)
|
||||
.copy_from(tmp, rearlen);
|
||||
} else {
|
||||
self.pointer.offset(self.length as isize).write(item);
|
||||
}
|
||||
}
|
||||
self.length += 1;
|
||||
}
|
||||
|
||||
pub fn append(&mut self, v: &mut Self) {
|
||||
while self.capacity < self.length + v.length {
|
||||
unsafe { self.extend_capacity() }
|
||||
}
|
||||
unsafe {
|
||||
self.pointer
|
||||
.offset(self.length as isize)
|
||||
.copy_from(v.pointer.cast_const(), v.length)
|
||||
};
|
||||
self.length += v.length;
|
||||
}
|
||||
|
||||
pub fn split_at(&self, index: usize) -> (&[T], &[T]) {
|
||||
if index >= self.length {
|
||||
panic!("Index out of bound.");
|
||||
}
|
||||
(&self[0..index], &self[index..self.length])
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.length
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.length == 0
|
||||
}
|
||||
|
||||
pub fn last_mut(&mut self) -> Option<&mut T> {
|
||||
unsafe { self.pointer.offset(self.length as isize - 1).as_mut() }
|
||||
}
|
||||
|
||||
pub fn last(&self) -> Option<&T> {
|
||||
unsafe { self.pointer.offset(self.length as isize - 1).as_ref() }
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index: usize) -> T {
|
||||
if index >= self.length {
|
||||
panic!("Index out of bound.");
|
||||
}
|
||||
let mut t: T = T::default();
|
||||
let pt = addr_of_mut!(t);
|
||||
unsafe {
|
||||
pt.copy_from(self.pointer.offset(index as isize).cast_const(), 1);
|
||||
self.pointer.offset(index as isize).copy_from(
|
||||
self.pointer.offset(index as isize + 1),
|
||||
self.length - index - 1,
|
||||
);
|
||||
}
|
||||
t
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> VecIterator<T> {
|
||||
VecIterator {
|
||||
pointer: self.pointer,
|
||||
index: 0,
|
||||
length: self.length,
|
||||
_phantom: &(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Default for Vec<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Index<usize> for Vec<T> {
|
||||
type Output = T;
|
||||
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
unsafe { self.pointer.offset(index as isize).as_ref().unwrap() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Index<Range<usize>> for Vec<T> {
|
||||
type Output = [T];
|
||||
|
||||
fn index(&self, index: Range<usize>) -> &Self::Output {
|
||||
unsafe { &slice::from_raw_parts_mut(self.pointer, self.length)[index] }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Index<RangeFull> for Vec<T> {
|
||||
type Output = [T];
|
||||
|
||||
fn index(&self, _: RangeFull) -> &Self::Output {
|
||||
unsafe { slice::from_raw_parts(self.pointer.cast(), self.length) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> IndexMut<RangeFull> for Vec<T> {
|
||||
fn index_mut(&mut self, _: RangeFull) -> &mut Self::Output {
|
||||
unsafe { slice::from_raw_parts_mut(self.pointer.cast(), self.length) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Clone for Vec<T> {
|
||||
fn clone(&self) -> Self {
|
||||
let res = Self {
|
||||
pointer: unsafe { alloc(Layout::array::<T>(self.capacity).unwrap()).cast() },
|
||||
length: self.length,
|
||||
capacity: self.capacity,
|
||||
};
|
||||
unsafe {
|
||||
res.pointer
|
||||
.copy_from(self.pointer.cast_const(), self.length)
|
||||
};
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for Vec<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dealloc(
|
||||
self.pointer.cast(),
|
||||
Layout::array::<T>(self.capacity).unwrap(),
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> FromIterator<T> for Vec<T> {
|
||||
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
|
||||
let mut res = Vec::new();
|
||||
for i in iter {
|
||||
res.push(i);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> IntoIterator for Vec<T> {
|
||||
type Item = T;
|
||||
|
||||
type IntoIter = VecIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VecIterator<'a, T> {
|
||||
pointer: *mut T,
|
||||
index: usize,
|
||||
length: usize,
|
||||
_phantom: &'a (),
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> Iterator for VecIterator<'a, T> {
|
||||
type Item = &'a T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.index == self.length {
|
||||
None
|
||||
} else {
|
||||
let res = unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) };
|
||||
self.index += 1;
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: 'a> DoubleEndedIterator for VecIterator<'a, T> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
if self.index == 0 {
|
||||
None
|
||||
} else {
|
||||
self.index -= 1;
|
||||
unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VecIter<T> {
|
||||
pointer: *mut T,
|
||||
index: usize,
|
||||
length: usize,
|
||||
capacity: usize,
|
||||
}
|
||||
|
||||
impl<T: Default> Iterator for VecIter<T> {
|
||||
type Item = T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.index == self.length {
|
||||
None
|
||||
} else {
|
||||
let mut t = T::default();
|
||||
let res = unsafe {
|
||||
self.pointer
|
||||
.offset(self.index as isize)
|
||||
.copy_to(addr_of_mut!(t), 1);
|
||||
Some(t)
|
||||
};
|
||||
self.index += 1;
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for VecIter<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
dealloc(
|
||||
self.pointer.cast(),
|
||||
Layout::array::<T>(self.capacity).unwrap(),
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
pub mod string;
|
||||
pub mod alloc;
|
||||
pub mod core;
|
||||
|
|
Reference in New Issue