Daily update on 20250618-051714 by Nitload Youmu. Additional Message : Brief support to collection operation in EXPRESS. A collection type added in core lib and compilestack.

Signed-off-by: Nitload <YoumuLiu_NSI@whv0t.onmicrosoft.com>
This commit is contained in:
Nitload
2025-06-18 05:17:14 +08:00
parent 74c01effe4
commit c624a8ca38
300 changed files with 12227 additions and 4303 deletions
@@ -56,15 +56,16 @@ namespace StgSharp.Commom.Collections
if( _reverse.TryGetValue( key, out TFirst value ) ) {
return value;
}
throw new ArgumentException(
$"Cannot find key {key!.ToString()} in dictionary." );
throw new ArgumentException( $"Cannot find key {key!.ToString()} in dictionary." );
}
set
{
if( _reverse.TryGetValue( key, out TFirst origin ) ) {
if( _reverse.TryGetValue( key, out TFirst origin ) )
{
_reverse[ key ] = value;
_forward.Remove( origin );
} else {
} else
{
_reverse.Add( key, value );
}
_forward.Add( value, key );
@@ -78,15 +79,16 @@ namespace StgSharp.Commom.Collections
if( _forward.TryGetValue( key, out TSecond value ) ) {
return value;
}
throw new ArgumentException(
$"Cannot find key {key!.ToString()} in dictionary." );
throw new ArgumentException( $"Cannot find key {key!.ToString()} in dictionary." );
}
set
{
if( _forward.TryGetValue( key, out TSecond origin ) ) {
if( _forward.TryGetValue( key, out TSecond origin ) )
{
_forward[ key ] = value;
_reverse.Remove( origin );
} else {
} else
{
_forward.Add( key, value );
}
_reverse.Add( value, key );
@@ -109,8 +111,7 @@ namespace StgSharp.Commom.Collections
public void Add( KeyValuePair<TFirst, TSecond> item )
{
if( _forward.ContainsKey( item.Key ) || _reverse.ContainsKey(
item.Value ) ) {
if( _forward.ContainsKey( item.Key ) || _reverse.ContainsKey( item.Value ) ) {
throw new ArgumentException( "Duplicate key or value." );
}
_forward.Add( item.Key, item.Value );
@@ -134,8 +135,9 @@ namespace StgSharp.Commom.Collections
public bool Contains( KeyValuePair<TFirst, TSecond> item )
{
return _forward.Contains( item ) && _reverse.TryGetValue(
item.Value, out TFirst var ) && var!.Equals( item.Key );
return _forward.Contains( item ) &&
_reverse.TryGetValue( item.Value, out TFirst var ) &&
var!.Equals( item.Key );
}
public bool Contains( TSecond key )
@@ -148,9 +150,7 @@ namespace StgSharp.Commom.Collections
return _forward.ContainsKey( key );
}
public void CopyTo(
KeyValuePair<TFirst, TSecond>[] array,
int arrayIndex )
public void CopyTo( KeyValuePair<TFirst, TSecond>[] array, int arrayIndex )
{
if( array == null ) {
throw new ArgumentNullException( nameof( array ) );
@@ -159,8 +159,7 @@ namespace StgSharp.Commom.Collections
throw new ArgumentOutOfRangeException( nameof( arrayIndex ) );
}
if( array.Length - arrayIndex < _forward.Count ) {
throw new ArgumentException(
"The array is too small to copy the elements." );
throw new ArgumentException( "The array is too small to copy the elements." );
}
foreach( KeyValuePair<TFirst, TSecond> pair in _forward ) {
@@ -39,13 +39,17 @@ namespace StgSharp.Commom.Collections
{
public static class CapacityFixedListBuilder
{
internal static CapacityFixedList<T> Create<T>(ReadOnlySpan<T> values)
internal static CapacityFixedList<T> Create<T>( ReadOnlySpan<T> values )
{
return new CapacityFixedList<T>(values);
return new CapacityFixedList<T>( values );
}
}
[CollectionBuilder(typeof(CapacityFixedListBuilder),nameof(CapacityFixedListBuilder.Create))]
[CollectionBuilder(
typeof( CapacityFixedListBuilder ),
nameof( CapacityFixedListBuilder.Create ) )]
public class CapacityFixedList<T> : IList<T>
{
@@ -57,7 +61,7 @@ namespace StgSharp.Commom.Collections
_values = new T[size];
}
public CapacityFixedList(ReadOnlySpan<T> values)
public CapacityFixedList( ReadOnlySpan<T> values )
{
_values = values.ToArray();
}
@@ -65,13 +69,14 @@ namespace StgSharp.Commom.Collections
public T this[ int index ]
{
get => index < _index ?
_values[ index ] : throw new ArgumentOutOfRangeException(
nameof( index ) );
_values[ index ] : throw new ArgumentOutOfRangeException( nameof( index ) );
set
{
if( index < _index ) {
if( index < _index )
{
_values[ index ] = value;
} else {
} else
{
throw new ArgumentOutOfRangeException( nameof( index ) );
}
}
@@ -83,7 +88,8 @@ namespace StgSharp.Commom.Collections
public void Add( T item )
{
if( _index < capacity - 1 ) {
if( _index < capacity - 1 )
{
_index++;
this[ _index ] = item;
}
@@ -97,7 +103,8 @@ namespace StgSharp.Commom.Collections
public bool Contains( T item )
{
for( int i = 0; i <= _index; i++ ) {
for( int i = 0; i <= _index; i++ )
{
if( item.Equals( _values[ i ] ) ) {
return true;
}
@@ -120,7 +127,8 @@ namespace StgSharp.Commom.Collections
public int IndexOf( T item )
{
T v;
for( int i = 0; i <= _index; i++ ) {
for( int i = 0; i <= _index; i++ )
{
if( ( v = _values[ i ] ) != null && v.Equals( item ) ) {
return i;
}
@@ -131,8 +139,10 @@ namespace StgSharp.Commom.Collections
public bool Remove( T item )
{
T v;
for( int i = 0; i <= _index; i++ ) {
if( ( v = _values[ i ] ) != null && v.Equals( item ) ) {
for( int i = 0; i <= _index; i++ )
{
if( ( v = _values[ i ] ) != null && v.Equals( item ) )
{
_values[ i ] = _values[ _index ];
_index--;
return true;
@@ -143,8 +153,10 @@ namespace StgSharp.Commom.Collections
public void RemoveAll( Predicate<T> predicate )
{
for( int i = _index; i > 0; i-- ) {
if( predicate( _values[ i ] ) ) {
for( int i = _index; i > 0; i-- )
{
if( predicate( _values[ i ] ) )
{
_values[ i ] = _values[ _index ];
_index--;
}
@@ -153,7 +165,8 @@ namespace StgSharp.Commom.Collections
public void RemoveAt( int index )
{
if( index <= _index ) {
if( index <= _index )
{
_values[ index ] = _values[ _index ];
_index--;
}
@@ -38,51 +38,39 @@ namespace StgSharp.Commom.Collections
public interface IBidirectionalDictionary<TFirst, TSecond> : IDictionary<TFirst, TSecond>
{
public TFirst this[ TSecond key ]
{
get;
set;
}
public TFirst this[ TSecond key ] { get; set; }
public ICollection<TFirst> FirstIndex
{
get;
}
public ICollection<TFirst> FirstIndex { get; }
public ICollection<TSecond> SecondIndex
{
get;
}
public ICollection<TSecond> SecondIndex { get; }
public IReadOnlyDictionary<TFirst, TSecond> Forward
{
get;
}
public IReadOnlyDictionary<TFirst, TSecond> Forward { get; }
public IReadOnlyDictionary<TSecond, TFirst> Reverse
{
get;
}
public IReadOnlyDictionary<TSecond, TFirst> Reverse { get; }
/// <summary>
/// Determines whether the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains
/// the specified key.
/// Determines whether the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />
/// contains the specified key.
/// </summary>
/// <param _name="key"> The value to locate in the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />. </param>
/// <param _label="key">
/// The value to locate in the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />.
/// </param>
/// <returns>
/// true if the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains an element
/// with the specified key; otherwise, false.
/// true if the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains an
/// element with the specified key; otherwise, false.
/// </returns>
public bool Contains( TSecond key );
/// <summary>
/// Determines whether the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains
/// the specified key.
/// Determines whether the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />
/// contains the specified key.
/// </summary>
/// <param _name="key"> The value to locate in the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />. </param>
/// <param _label="key">
/// The value to locate in the <see cref="IBidirectionalDictionary{TFirst, TSecond}" />.
/// </param>
/// <returns>
/// true if the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains an element
/// with the specified key; otherwise, false.
/// true if the <see cref="IBidirectionalDictionary{TFirst, TSecond}" /> contains an
/// element with the specified key; otherwise, false.
/// </returns>
public bool Contains( TFirst key );
@@ -93,8 +81,7 @@ namespace StgSharp.Commom.Collections
ICollection<TSecond> IDictionary<TFirst, TSecond>.Values => SecondIndex;
bool IDictionary<TFirst, TSecond>.ContainsKey( TFirst key ) => Contains(
key );
bool IDictionary<TFirst, TSecond>.ContainsKey( TFirst key ) => Contains( key );
#pragma warning restore CA1033
}
}
@@ -36,11 +36,7 @@ namespace StgSharp.Collections
public interface IHashMultiplexer<T> : IEqualityComparer<T>
{
int RemainedMultiplexCount
{
get;
set;
}
int RemainedMultiplexCount { get; set; }
void CacheHash( T obj, int count );
+19 -9
View File
@@ -40,10 +40,12 @@ using System.Xml.Serialization;
namespace StgSharp.Collections
{
/// <summary>
/// Part of a collection. This contains a direct reference to _origin collection, so all change
/// to _origin collection will be reflected in this object.
/// Part of a collection. This contains a direct reference to _origin collection, so all
/// change to _origin collection will be reflected in this object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="T">
///
/// </typeparam>
public struct ListSegment<T> : ICollection<T>
{
@@ -56,8 +58,7 @@ namespace StgSharp.Collections
ArgumentNullException.ThrowIfNull( collection );
ArgumentOutOfRangeException.ThrowIfLessThan( begin, 0 );
ArgumentOutOfRangeException.ThrowIfLessThan( length, 0 );
ArgumentOutOfRangeException.ThrowIfLessThan(
begin + length, collection.Count );
ArgumentOutOfRangeException.ThrowIfLessThan( begin + length, collection.Count );
_collection = collection;
_begin = begin;
_length = length;
@@ -68,12 +69,22 @@ namespace StgSharp.Collections
get
{
ArgumentOutOfRangeException.ThrowIfLessThan( indexValue, 0 );
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(
indexValue, _length );
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual( indexValue, _length );
return _collection[ indexValue + _begin ];
}
}
public T this[ Index i ]
{
get
{
int offset = i.IsFromEnd ? _length - i.Value : i.Value;
ArgumentOutOfRangeException.ThrowIfLessThan( offset, 0 );
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual( offset, _length );
return _collection[ offset + _begin ];
}
}
public bool IsReadOnly => true;
public int Count => _length;
@@ -87,8 +98,7 @@ namespace StgSharp.Collections
public void CopyTo( T[] array, int arrayIndex )
{
ArgumentNullException.ThrowIfNull( array );
Span<T> span = CollectionsMarshal.AsSpan<T>( _collection )
.Slice( _begin, _length );
Span<T> span = CollectionsMarshal.AsSpan<T>( _collection ).Slice( _begin, _length );
Span<T> target = new Span<T>( array, arrayIndex, _length );
span.CopyTo( target );
}
@@ -40,17 +40,17 @@ namespace StgSharp.Collections
{
public partial class PartialDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly Dictionary<TKey, TValue> _source;
private readonly HashSet<TKey> _keys;
private readonly PartialDictionaryValues _values;
public PartialDictionary(
Dictionary<TKey, TValue> source,
TKey[] index )
public PartialDictionary( Dictionary<TKey, TValue> source, TKey[] index )
{
_source = source;
_keys = new HashSet<TKey>( index );
foreach( TKey item in _keys ) {
foreach( TKey item in _keys )
{
if( !_source.ContainsKey( item ) ) {
_source.Add( item, default! );
}
@@ -58,13 +58,12 @@ namespace StgSharp.Collections
_values = new PartialDictionaryValues( this );
}
public PartialDictionary(
Dictionary<TKey, TValue> source,
HashSet<TKey> keys )
public PartialDictionary( Dictionary<TKey, TValue> source, HashSet<TKey> keys )
{
_source = source;
_keys = keys;
foreach( TKey item in _keys ) {
foreach( TKey item in _keys )
{
if( !_source.ContainsKey( item ) ) {
_source.Add( item, default! );
}
@@ -73,20 +72,19 @@ namespace StgSharp.Collections
}
public PartialDictionary(
Dictionary<TKey, TValue> source,
TKey[] index, IHashMultiplexer<TKey> multiplexer
)
Dictionary<TKey, TValue> source,
TKey[] index,
IHashMultiplexer<TKey> multiplexer )
{
_source = source;
_keys = new HashSet<TKey>(index);
foreach (TKey item in _keys)
_keys = new HashSet<TKey>( index );
foreach( TKey item in _keys )
{
if (!_source.ContainsKey(item))
{
_source.Add(item, default!);
if( !_source.ContainsKey( item ) ) {
_source.Add( item, default! );
}
}
_values = new PartialDictionaryValues(this);
_values = new PartialDictionaryValues( this );
}
public TValue this[ TKey key ]
@@ -131,14 +129,14 @@ namespace StgSharp.Collections
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
foreach( TKey item in _keys ) {
yield return new KeyValuePair<TKey, TValue>(
item, _source[ item ] );
yield return new KeyValuePair<TKey, TValue>( item, _source[ item ] );
}
}
public bool TryGetValue( TKey key, out TValue value )
{
if( _keys.Contains( key ) ) {
if( _keys.Contains( key ) )
{
value = _source[ key ];
return true;
}
@@ -146,8 +144,7 @@ namespace StgSharp.Collections
return false;
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(
KeyValuePair<TKey, TValue> item )
void ICollection<KeyValuePair<TKey, TValue>>.Add( KeyValuePair<TKey, TValue> item )
{
return;
}
@@ -157,8 +154,7 @@ namespace StgSharp.Collections
throw new NotSupportedException();
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(
KeyValuePair<TKey, TValue> item )
bool ICollection<KeyValuePair<TKey, TValue>>.Remove( KeyValuePair<TKey, TValue> item )
{
throw new NotSupportedException();
}
@@ -43,8 +43,7 @@ namespace StgSharp.Collections
private readonly PartialDictionary<TKey, TValue> _values;
public PartialDictionaryValues(
PartialDictionary<TKey, TValue> value )
public PartialDictionaryValues( PartialDictionary<TKey, TValue> value )
{
_values = value;
}
@@ -55,7 +54,8 @@ namespace StgSharp.Collections
public bool Contains( TValue item )
{
foreach( KeyValuePair<TKey, TValue> kvp in _values ) {
foreach( KeyValuePair<TKey, TValue> kvp in _values )
{
if( kvp.Value != null && kvp.Value.Equals( item ) ) {
return true;
}
@@ -65,7 +65,8 @@ namespace StgSharp.Collections
public void CopyTo( TValue[] array, int arrayIndex )
{
foreach( KeyValuePair<TKey, TValue> kvp in _values ) {
foreach( KeyValuePair<TKey, TValue> kvp in _values )
{
array[ arrayIndex ] = kvp.Value;
arrayIndex++;
}
@@ -0,0 +1,185 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="RandomAccessibleStack.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the “Software”), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and
// this permission notice shall be included in all copies
// or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”,
// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Collections
{
public class RandomAccessibleStack<T> : IEnumerable<T>
{
private const int DefaultCapacity = 4;
private T[] _array;
private int _size;
private int _version;
/// <summary>
/// Initializes a new instance of the RandomAccessStack class that is empty and has the
/// default initial capacity.
/// </summary>
public RandomAccessibleStack()
{
_array = new T[DefaultCapacity];
}
/// <summary>
/// Initializes a new instance of the RandomAccessStack class that is empty and has the
/// specified initial capacity.
/// </summary>
public RandomAccessibleStack( int capacity )
{
if( capacity < 0 ) {
throw new ArgumentOutOfRangeException(
nameof( capacity ), "Capacity must be non-negative." );
}
_array = new T[capacity];
}
/// <summary>
/// Gets or sets the element at the specified index in the stack (0 = bottom, Count-1 =
/// top).
/// </summary>
public T this[ int index ]
{
get
{
if( index < 0 || index >= _size ) {
throw new ArgumentOutOfRangeException( nameof( index ) );
}
return _array[ index ];
}
/*
set
{
if( index < 0 || index >= _size ) {
throw new ArgumentOutOfRangeException( nameof( index ) );
}
_array[ index ] = value;
_version++;
}
/**/
}
/// <summary>
/// Gets the number of elements contained in the stack.
/// </summary>
public int Count => _size;
/// <summary>
/// Removes all objects from the stack.
/// </summary>
public void Clear()
{
Array.Clear( _array, 0, _size );
_size = 0;
_version++;
}
/// <summary>
/// Returns an enumerator that iterates through the stack from top to bottom. Throws if
/// the stack is modified during iteration.
/// </summary>
public IEnumerator<T> GetEnumerator()
{
int expectedVersion = _version;
for( int i = _size - 1; i >= 0; i-- )
{
if( expectedVersion != _version ) {
throw new InvalidOperationException(
"Collection was modified during enumeration." );
}
yield return _array[ i ];
}
}
/// <summary>
/// Returns the object at the top of the stack without removing it.
/// </summary>
public T Peek()
{
if( _size == 0 ) {
throw new InvalidOperationException( "Stack is empty." );
}
return _array[ _size - 1 ];
}
/// <summary>
/// Removes and returns the object at the top of the stack.
/// </summary>
public T Pop()
{
if( _size == 0 ) {
throw new InvalidOperationException( "Stack is empty." );
}
T item = _array[ --_size ];
_array[ _size ] = default!;
_version++;
return item;
}
/// <summary>
/// Adds an item to the top of the stack.
/// </summary>
public void Push( T item )
{
if( _size == _array.Length ) {
EnsureCapacity( _size + 1 );
}
_array[ _size++ ] = item;
_version++;
}
private void EnsureCapacity( int min )
{
int newCapacity = _array.Length == 0 ? DefaultCapacity : _array.Length * 2;
if( newCapacity < min ) {
newCapacity = min;
}
Array.Resize( ref _array, newCapacity );
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}
@@ -1,6 +1,6 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// file="KeyMultiplexer.cs"
// file="StringHashMultiplexer.cs"
// Project: StgSharp
// AuthorGroup: Nitload Space
// Copyright (c) Nitload Space. All rights reserved.
@@ -38,7 +38,7 @@ using System.Threading;
namespace StgSharp.Collections
{
public sealed class StringHashMultiplexer : IHashMultiplexer<string>
public sealed class StringHashMultiplexer : IHashMultiplexer<string>
{
private int _initCount, _remainedCount, _hashCache, _hashLast;
@@ -74,15 +74,15 @@ namespace StgSharp.Collections
{
int hash;
fixed( char* cPtr = obj.AsSpan() ) {
hash = InternalIO.Intrinsic
.city_hash_simplify( cPtr, obj.Length );
hash = InternalIO.Intrinsic.city_hash_simplify( cPtr, obj.Length );
}
return hash;
}
public int GetHashCode( string obj )
{
if( _remainedCount > 0 && ReferenceEquals( _source, obj ) ) {
if( _remainedCount > 0 && ReferenceEquals( _source, obj ) )
{
_remainedCount--;
return _hashCache;
}
@@ -139,8 +139,7 @@ namespace StgSharp.Collections
{
int hash;
fixed( char* cPtr = obj.AsSpan() ) {
hash = InternalIO.Intrinsic
.city_hash_simplify( cPtr, obj.Length );
hash = InternalIO.Intrinsic.city_hash_simplify( cPtr, obj.Length );
}
return hash;
}
@@ -152,7 +151,8 @@ namespace StgSharp.Collections
private void Dispose( bool disposing )
{
if( !disposedValue ) {
if( !disposedValue )
{
if( disposing ) {
_multiplexers.Dispose();
}