<commit_before>using Loyc.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Loyc.Syntax
{
	/// <summary>A list of non-null references to LNode.</summary>
	/// <remarks>
	/// Users of Loyc trees previously needed to refer directly to <see cref="VList{LNode}"/> so they 
	/// were dependent on which list implementation is used, which is unfortunate. It is nice to have 
	/// the freedom of a <i>struct</i> for the node list so that implementations like VList are possible,
	/// but to refer to VList by name prevents easily changing list representations.
	/// <para/>
	/// In the future we'll probably move away from VList as a representation, mainly so that 
	/// Loyc.Syntax.dll does not need to take a dependency on Loyc.Collections.dll. This struct
	/// will aid the transition.
	/// <para/>
	/// For now, there are implicit conversions between <see cref="VList{LNode}"/> and LNodeList. These
	/// will be removed eventually.
	/// <para/>
	/// A disadvantage of this approach is that C# does not support user-defined conversions to 
	/// interfaces. Therefore, conversion to IReadOnlyList will box the wrapper instead of the 
	/// underlying implementation. Ugh.
	/// <para/>
	/// This change is issue #100: https://github.com/qwertie/ecsharp/issues/100
	/// </remarks>
	public struct LNodeList : IListAndListSource<LNode>, ICloneable<LNodeList>, IEquatable<LNodeList>
	{
		public static readonly LNodeList Empty = new LNodeList();

		private VList<LNode> _list;

		public static implicit operator LNodeList(VList<LNode> list) => new LNodeList(list);
		public static implicit operator VList<LNode>(LNodeList list) => list._list;

		public LNodeList(LNode item_0) => _list = new VList<LNode>(item_0 ?? throw new ArgumentNullException(nameof(item_0)));
		public LNodeList(LNode item_0, LNode item_1) => _list = new VList<LNode>(item_0 ?? throw new ArgumentNullException(nameof(item_0)), item_1 ?? throw new ArgumentNullException(nameof(item_1)));
		public LNodeList(params LNode[] items) : this(new VList<LNode>(items)) { }
		public LNodeList(IEnumerable<LNode> items) : this(new VList<LNode>(items)) { }
		public LNodeList(VList<LNode> list)
		{
			int i = 0;
			foreach (var n in list.ToFVList()) { // FVList enumerates faster
				i++;
				if (n == null) throw new ArgumentNullException("list[" + (list.Count - i) + "]");
			}
			_list = list;
		}
		
		public LNode this[int index]
		{
			get => _list[index];
			set => _list[index] = value;
		}
		public LNode this[int index, LNode defaultValue] => _list[index, defaultValue];

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int Count => _list.Count;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsReadOnly => false;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsEmpty => _list.IsEmpty;

		void ICollection<LNode>.Add(LNode item) => Add(item);
		public LNodeList Add(LNode item) => new LNodeList(_list.Add(item ?? throw new ArgumentNullException(nameof(item))));
		public void Clear() => _list.Clear();
		public bool Contains(LNode item) => _list.Contains(item);
		public void CopyTo(LNode[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
		public IEnumerator<LNode> GetEnumerator() => _list.GetEnumerator();
		public int IndexOf(LNode item) => _list.IndexOf(item);
		void IList<LNode>.Insert(int index, LNode item) => Insert(index, item);
		public LNodeList Insert(int index, LNode item) => new LNodeList(_list.Insert(index, item ?? throw new ArgumentNullException(nameof(item))));
		public bool Remove(LNode item) => _list.Remove(item);
		void IList<LNode>.RemoveAt(int index) => RemoveAt(index);
		public LNodeList RemoveAt(int index) => new LNodeList(_list.RemoveAt(index));
		IRange<LNode> IListSource<LNode>.Slice(int start, int count) => Slice(start, count);
		public Slice_<LNode> Slice(int start, int count = int.MaxValue) => _list.Slice(start, count);
		public LNode TryGet(int index, out bool fail) => _list.TryGet(index, out fail);<commit_msg>Add `LNodeList.AddIfNotNull`<commit_after>using Loyc.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Loyc.Syntax
{
	/// <summary>A list of non-null references to LNode.</summary>
	/// <remarks>
	/// Users of Loyc trees previously needed to refer directly to <see cref="VList{LNode}"/> so they 
	/// were dependent on which list implementation is used, which is unfortunate. It is nice to have 
	/// the freedom of a <i>struct</i> for the node list so that implementations like VList are possible,
	/// but to refer to VList by name prevents easily changing list representations.
	/// <para/>
	/// In the future we'll probably move away from VList as a representation, mainly so that 
	/// Loyc.Syntax.dll does not need to take a dependency on Loyc.Collections.dll. This struct
	/// will aid the transition.
	/// <para/>
	/// For now, there are implicit conversions between <see cref="VList{LNode}"/> and LNodeList. These
	/// will be removed eventually.
	/// <para/>
	/// A disadvantage of this approach is that C# does not support user-defined conversions to 
	/// interfaces. Therefore, conversion to IReadOnlyList will box the wrapper instead of the 
	/// underlying implementation. Ugh.
	/// <para/>
	/// This change is issue #100: https://github.com/qwertie/ecsharp/issues/100
	/// </remarks>
	public struct LNodeList : IListAndListSource<LNode>, ICloneable<LNodeList>, IEquatable<LNodeList>
	{
		public static readonly LNodeList Empty = new LNodeList();

		private VList<LNode> _list;

		public static implicit operator LNodeList(VList<LNode> list) => new LNodeList(list);
		public static implicit operator VList<LNode>(LNodeList list) => list._list;

		public LNodeList(LNode item_0) => _list = new VList<LNode>(item_0 ?? throw new ArgumentNullException(nameof(item_0)));
		public LNodeList(LNode item_0, LNode item_1) => _list = new VList<LNode>(item_0 ?? throw new ArgumentNullException(nameof(item_0)), item_1 ?? throw new ArgumentNullException(nameof(item_1)));
		public LNodeList(params LNode[] items) : this(new VList<LNode>(items)) { }
		public LNodeList(IEnumerable<LNode> items) : this(new VList<LNode>(items)) { }
		public LNodeList(VList<LNode> list)
		{
			int i = 0;
			foreach (var n in list.ToFVList()) { // FVList enumerates faster
				i++;
				if (n == null) throw new ArgumentNullException("list[" + (list.Count - i) + "]");
			}
			_list = list;
		}
		
		public LNode this[int index]
		{
			get => _list[index];
			set => _list[index] = value;
		}
		public LNode this[int index, LNode defaultValue] => _list[index, defaultValue];

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int Count => _list.Count;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsReadOnly => false;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsEmpty => _list.IsEmpty;

		void ICollection<LNode>.Add(LNode item) => Add(item);
		public LNodeList AddIfNotNull(LNode item) => item == null ? this : Add(item);
		public LNodeList Add(LNode item) => new LNodeList(_list.Add(item ?? throw new ArgumentNullException(nameof(item))));
		public void Clear() => _list.Clear();
		public bool Contains(LNode item) => _list.Contains(item);
		public void CopyTo(LNode[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
		public IEnumerator<LNode> GetEnumerator() => _list.GetEnumerator();
		public int IndexOf(LNode item) => _list.IndexOf(item);
		void IList<LNode>.Insert(int index, LNode item) => Insert(index, item);
		public LNodeList Insert(int index, LNode item) => new LNodeList(_list.Insert(index, item ?? throw new ArgumentNullException(nameof(item))));
		public bool Remove(LNode item) => _list.Remove(item);
		void IList<LNode>.RemoveAt(int index) => RemoveAt(index);
		public LNodeList RemoveAt(int index) => new LNodeList(_list.RemoveAt(index));
		IRange<LNode> IListSource<LNode>.Slice(int start, int count) => Slice(start, count);
		public Slice_<LNode> Slice(int start, int count = int.MaxValue) => _list.Slice(start, count);
		public LNode TryGet(int index, out bool fail) => _list.TryGet(index, out fail);
{'fraction_non_alphanumeric': 0.12531268612269209, 'fraction_numerical': 0.003811792733770101, 'mean_word_length': 4.631120053655265, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 116, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7231333', 'n_tokens_mistral': 2754, 'n_tokens_neox': 2620, 'n_words': 798}