use std::{
fmt::Debug,
iter::FusedIterator,
ops::{Deref, DerefMut, Range, RangeBounds},
ptr::NonNull,
slice::{from_raw_parts, from_raw_parts_mut},
};
use super::shared::{Shared, SharedCtxGuard};
use crate::{
serde::tri,
util::{arc::Arc, range::range},
value::{node::Value, value_trait::JsonValueTrait},
};
#[derive(Debug, Eq, PartialEq, Clone)]
#[repr(transparent)]
pub struct Array(pub(crate) Value);
pub(crate) const DEFAULT_ARRAY_CAP: usize = 8;
impl Array {
#[inline]
pub fn into_value(self) -> Value {
self.0
}
#[inline]
pub const fn new() -> Self {
let value = Value {
meta: super::node::Meta::new(super::node::ARRAY, std::ptr::null()),
data: super::node::Data {
achildren: std::ptr::null_mut(),
},
};
Array(value)
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
let mut array = Self::new();
array.reserve(capacity);
array
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.0.reserve::<Value>(additional);
}
#[inline]
pub fn resize<T: Clone + Into<Value>>(&mut self, new_len: usize, value: T) {
if new_len > self.len() {
self.reserve(new_len - self.len());
for _ in self.len()..new_len {
self.push(value.clone().into());
}
} else {
self.truncate(new_len);
}
}
#[inline]
pub fn resize_with<F>(&mut self, new_len: usize, mut f: F)
where
F: FnMut() -> Value,
{
if new_len > self.len() {
self.reserve(new_len - self.len());
for _ in self.len()..new_len {
self.push(f());
}
} else {
self.truncate(new_len);
}
}
#[inline]
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&Value) -> bool,
{
self.retain_mut(|elem| f(elem));
}
#[inline]
pub fn split_off(&mut self, at: usize) -> Self {
let len = self.len();
assert!(at <= len, "at {} out of bounds(len: {})", at, len);
let mut arr = Self::new_in(self.0.shared_clone());
if at == len {
return arr;
}
arr.reserve(len - at);
unsafe {
let src = self.as_mut_ptr().add(at);
let dst = arr.as_mut_ptr();
std::ptr::copy_nonoverlapping(src, dst, len - at);
self.set_len(at);
arr.set_len(len - at);
}
arr
}
#[inline]
pub fn swap_remove(&mut self, index: usize) -> Value {
let len = self.len();
assert!(index < len, "index {} out of bounds(len: {})", index, len);
if index != self.len() - 1 {
unsafe {
let src = self.as_mut_ptr().add(index);
let dst = self.as_mut_ptr().add(len - 1);
std::ptr::swap(src, dst);
}
}
self.pop().unwrap()
}
#[inline]
pub fn retain_mut<F>(&mut self, mut f: F)
where
F: FnMut(&mut Value) -> bool,
{
if self.is_empty() {
return;
}
let mut i = 0;
let mut j = 0;
let start = self.as_mut_ptr();
while i < self.len() {
unsafe {
let cur = start.add(i);
if !f(&mut *cur) {
(*cur).take();
i += 1;
continue;
}
if i > j {
std::ptr::copy_nonoverlapping(cur, start.add(j), 1);
}
i += 1;
j += 1;
}
}
unsafe { self.set_len(j) };
}
#[inline]
pub fn truncate(&mut self, len: usize) {
let old_len = self.len();
if len < old_len {
unsafe {
let mut v = self.as_mut_ptr().add(len);
let end = self.as_mut_ptr().add(old_len);
while v != end {
(*v).take();
v = v.add(1);
}
}
unsafe { self.set_len(len) };
}
}
#[inline]
pub fn push<T: Into<Value>>(&mut self, val: T) {
self.reserve(1);
let val = {
let _ = SharedCtxGuard::assign(self.0.shared());
val.into()
};
self.0.append_value(val);
}
#[inline]
pub fn pop(&mut self) -> Option<Value> {
debug_assert!(self.0.is_array());
self.0.pop()
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.len() == 0
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [Value] {
self
}
#[inline]
pub fn as_slice(&self) -> &[Value] {
self
}
#[inline]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
#[inline]
pub fn clear(&mut self) {
self.0.clear();
}
#[inline]
pub fn remove(&mut self, index: usize) {
self.0.remove_index(index);
}
#[inline]
pub fn append(&mut self, other: &mut Self) {
self.reserve(other.len());
while let Some(v) = other.pop() {
debug_assert!(v.is_root() || v.is_static());
self.push(v);
}
}
#[inline]
pub fn drain<R>(&mut self, r: R) -> Drain<'_>
where
R: RangeBounds<usize>,
{
let len = self.len();
let Range { start, end } = range(r, ..len);
unsafe {
self.set_len(start);
let range_slice = std::slice::from_raw_parts(self.as_ptr().add(start), end - start);
Drain {
tail_start: end,
tail_len: len - end,
iter: range_slice.iter(),
arr: NonNull::from(self),
}
}
}
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>,
{
let range: Range<usize> = range(src, ..self.len());
if range.is_empty() {
return;
}
self.reserve(range.len());
unsafe {
let start = self.as_mut_ptr().add(range.start);
let end = self.as_mut_ptr().add(range.end);
let src = std::slice::from_raw_parts(start, end.offset_from(start) as usize);
for v in src.iter() {
self.0.append_value(v.clone_in(self.0.shared()));
}
}
}
#[inline]
pub fn insert<T: Into<Value>>(&mut self, index: usize, element: T) {
let element = {
let _ = SharedCtxGuard::assign(self.0.shared());
element.into()
};
self.0.insert_value(index, element);
}
#[inline]
pub(crate) fn new_in(shared: Arc<Shared>) -> Self {
let mut array = Array::default();
array.0.mark_shared(shared.data_ptr());
array.0.mark_root();
std::mem::forget(shared);
array
}
#[inline]
pub(crate) unsafe fn set_len(&mut self, new_len: usize) {
self.0.set_len(new_len);
}
}
impl Default for Array {
fn default() -> Self {
Self::new()
}
}
impl Deref for Array {
type Target = [Value];
fn deref(&self) -> &Self::Target {
unsafe {
let start = self.0.data.achildren.add(Value::MEAT_NODE_COUNT);
let ptr = start as *const Value;
let len = self.0.len();
from_raw_parts(ptr, len)
}
}
}
impl DerefMut for Array {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
let ptr = self.0.data.achildren.add(Value::MEAT_NODE_COUNT);
let len = self.0.len();
from_raw_parts_mut(ptr, len)
}
}
}
pub struct Drain<'a> {
pub(super) tail_start: usize,
pub(super) tail_len: usize,
pub(super) iter: std::slice::Iter<'a, Value>,
pub(super) arr: NonNull<Array>,
}
impl<'a> Drain<'a> {
#[inline]
pub fn as_slice(&self) -> &'a [Value] {
self.iter.as_slice()
}
}
impl Iterator for Drain<'_> {
type Item = Value;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|v| v.clone_in(unsafe { self.arr.as_ref().0.shared() }))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
use std::{
ops::{Index, IndexMut},
slice::SliceIndex,
};
impl<I: SliceIndex<[Value]>> Index<I> for Array {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
Index::index(&**self, index)
}
}
impl<I: SliceIndex<[Value]>> IndexMut<I> for Array {
fn index_mut(&mut self, index: I) -> &mut Self::Output {
IndexMut::index_mut(&mut **self, index)
}
}
#[derive(Debug, Default, Clone)]
pub struct IntoIter {
array: Array,
index: usize,
len: usize,
}
impl IntoIter {
pub fn as_mut_slice(&mut self) -> &mut [Value] {
unsafe {
let ptr = self.array.0.children_mut_ptr();
let len = self.array.0.len();
from_raw_parts_mut(ptr, len)
}
}
pub fn as_slice(&self) -> &[Value] {
unsafe {
let ptr = self.array.0.children_ptr();
let len = self.array.0.len();
from_raw_parts(ptr, len)
}
}
}
impl AsRef<[Value]> for IntoIter {
fn as_ref(&self) -> &[Value] {
self.as_slice()
}
}
impl AsMut<[Value]> for IntoIter {
fn as_mut(&mut self) -> &mut [Value] {
self.as_mut_slice()
}
}
impl DoubleEndedIterator for IntoIter {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.index < self.len {
self.len -= 1;
let value = self.array.0.get_index_mut(self.len).unwrap();
Some(value.take())
} else {
None
}
}
}
impl ExactSizeIterator for IntoIter {
#[inline]
fn len(&self) -> usize {
self.len - self.index
}
}
impl FusedIterator for IntoIter {}
impl Iterator for IntoIter {
type Item = Value;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.len {
let value = self.array.0.get_index_mut(self.index).unwrap();
self.index += 1;
Some(value.take())
} else {
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len - self.index;
(len, Some(len))
}
}
impl IntoIterator for Array {
type Item = Value;
type IntoIter = IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
let len = self.len();
IntoIter {
array: self,
index: 0,
len,
}
}
}
impl<'a> IntoIterator for &'a Array {
type Item = &'a Value;
type IntoIter = std::slice::Iter<'a, Value>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> IntoIterator for &'a mut Array {
type Item = &'a mut Value;
type IntoIter = std::slice::IterMut<'a, Value>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl serde::ser::Serialize for Array {
#[inline]
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = tri!(serializer.serialize_seq(Some(self.len())));
for v in self {
tri!(seq.serialize_element(v));
}
seq.end()
}
}
impl<'de> serde::de::Deserialize<'de> for Array {
#[inline]
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let value: Value =
deserializer.deserialize_newtype_struct(super::de::TOKEN, super::de::ValueVisitor)?;
if value.is_array() {
Ok(Array(value))
} else {
Err(serde::de::Error::invalid_type(
serde::de::Unexpected::Other("not a array"),
&"array",
))
}
}
}
#[cfg(test)]
mod test {
use super::Array;
use crate::value::{node::Value, value_trait::JsonValueMutTrait};
#[test]
fn test_value_array() {
let mut val = crate::from_str::<Value>(r#"[1,2,3]"#);
let array = val.as_array_mut().unwrap();
assert_eq!(array.len(), 3);
for i in 0..3 {
let old_len = array.len();
let new_node = Value::new_u64(i, std::ptr::null());
array.push(new_node);
assert_eq!(array.len(), old_len + 1);
let old_len = array.len();
let mut new_node = Array::default();
new_node.push(Value::new_u64(i, std::ptr::null()));
array.push(new_node.0);
assert_eq!(array.len(), old_len + 1);
let old_len = array.len();
let mut new_node = Array::new_in(array.0.shared_clone());
new_node.push(Value::new_u64(i, std::ptr::null()));
array.push(new_node.0);
assert_eq!(array.len(), old_len + 1);
}
for (i, v) in array.iter_mut().enumerate() {
*v = Value::new_u64(i as u64, std::ptr::null());
}
while !array.is_empty() {
dbg!(array.pop());
}
}
}