<commit_before>// Needed for NET40

using System;
using System.Collections.Generic;
using Theraot.Collections.Specialized;
using Theraot.Collections.ThreadSafe;

#if LESSTHAN_NET40

using System.Runtime.CompilerServices;

#endif

namespace Theraot.Collections
{
    public static partial class Extensions
    {
        public static T[] AsArray<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case T[] array:
                    return array;
#if LESSTHAN_NET40
                case TrueReadOnlyCollection<T> trueReadOnlyCollection:
                    return trueReadOnlyCollection.Wrapped;
#endif
                case ICollection<T> collection when collection.Count == 0:
                    return ArrayReservoir<T>.EmptyArray;

                case ICollection<T> collection:
                    var result = new T[collection.Count];
                    collection.CopyTo(result, 0);
                    return result;

                default:
                    return new List<T>(source).ToArray();
            }
        }

        public static ICollection<T> AsDistinctICollection<T>(IEnumerable<T> source)
        {
#if NET35
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case ISet<T> set:
                    return set;

                case HashSet<T> resultHashSet:
                    // Workaround for .NET 3.5 when all you want is Contains and no duplicates
                    // Remember that On .NET 3.5 HashSet is not an ISet
                    return resultHashSet;

                default:
                    return new ProgressiveSet<T>(source);
            }
#else
            return AsISet(source);
#endif
        }

        public static ICollection<T> AsICollection<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case ICollection<T> result:
                    return result;

                default:
                    return new ProgressiveCollection<T>(source);
            }
        }

        public static IList<T> AsIList<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case IList<T> list:
                    return list;

                case ICollection<T> collection when collection.Count == 0:
                    return EmptyCollection<T>.Instance;

                case ICollection<T> collection:
                    var result = new T[collection.Count];
                    collection.CopyTo(result, 0);
                    return result;

                default:
                    return new ProgressiveList<T>(source);
            }
        }

        public static IReadOnlyCollection<T> AsIReadOnlyCollection<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return EmptyCollection<T>.Instance;

                case IReadOnlyCollection<T> result:
                    return result;

                default:
                    return new ProgressiveList<T>(source);
            }
        }

        public static IReadOnlyCollection<T> AsIReadOnlyList<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return EmptyCollection<T>.Instance;

                case IReadOnlyList<T> result:
                    return result;

                default:
                    return new ProgressiveCollection<T>(source);
            }
        }

        public static ISet<T> AsISet<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return EmptySet<T>.Instance;

                case ISet<T> resultISet:
                    return resultISet;

                default:
                    return new ProgressiveSet<T>(source);
            }
        }

        public static IEnumerable<T> AsUnaryIEnumerable<T>(T source)
        {
            yield return source;
        }

        public static IReadOnlyCollection<T> WrapAsIReadOnlyCollection<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    throw new ArgumentNullException(nameof(source));

                case T[] array:
#if LESSTHAN_NETSTANDARD20 || LESSTHAN_NETCOREAPP20 || LESSTHAN_NET45
                    return new EnumerationList<T>(array);
#else
                    return Array.AsReadOnly(array);
#endif
                case List<T> list:
#if LESSTHAN_NETSTANDARD13 || LESSTHAN_NET45<commit_msg>Added WrapAsICollection and WrapAsIList<commit_after>// Needed for NET40

using System;
using System.Collections.Generic;
using Theraot.Collections.Specialized;
using Theraot.Collections.ThreadSafe;

#if LESSTHAN_NET40

using System.Runtime.CompilerServices;

#endif

namespace Theraot.Collections
{
    public static partial class Extensions
    {
        public static T[] AsArray<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case T[] array:
                    return array;
#if LESSTHAN_NET40
                case TrueReadOnlyCollection<T> trueReadOnlyCollection:
                    return trueReadOnlyCollection.Wrapped;
#endif
                case ICollection<T> collection when collection.Count == 0:
                    return ArrayReservoir<T>.EmptyArray;

                case ICollection<T> collection:
                    var result = new T[collection.Count];
                    collection.CopyTo(result, 0);
                    return result;

                default:
                    return new List<T>(source).ToArray();
            }
        }

        public static ICollection<T> AsDistinctICollection<T>(IEnumerable<T> source)
        {
#if NET35
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case ISet<T> set:
                    return set;

                case HashSet<T> resultHashSet:
                    // Workaround for .NET 3.5 when all you want is Contains and no duplicates
                    // Remember that On .NET 3.5 HashSet is not an ISet
                    return resultHashSet;

                default:
                    return new ProgressiveSet<T>(source);
            }
#else
            return AsISet(source);
#endif
        }

        public static ICollection<T> AsICollection<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case ICollection<T> result:
                    return result;

                default:
                    return new ProgressiveCollection<T>(source);
            }
        }

        public static IList<T> AsIList<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return ArrayReservoir<T>.EmptyArray;

                case IList<T> list:
                    return list;

                case ICollection<T> collection when collection.Count == 0:
                    return EmptyCollection<T>.Instance;

                case ICollection<T> collection:
                    var result = new T[collection.Count];
                    collection.CopyTo(result, 0);
                    return result;

                default:
                    return new ProgressiveList<T>(source);
            }
        }

        public static IReadOnlyCollection<T> AsIReadOnlyCollection<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return EmptyCollection<T>.Instance;

                case IReadOnlyCollection<T> result:
                    return result;

                default:
                    return new ProgressiveList<T>(source);
            }
        }

        public static IReadOnlyCollection<T> AsIReadOnlyList<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return EmptyCollection<T>.Instance;

                case IReadOnlyList<T> result:
                    return result;

                default:
                    return new ProgressiveCollection<T>(source);
            }
        }

        public static ISet<T> AsISet<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    return EmptySet<T>.Instance;

                case ISet<T> resultISet:
                    return resultISet;

                default:
                    return new ProgressiveSet<T>(source);
            }
        }

        public static IEnumerable<T> AsUnaryIEnumerable<T>(T source)
        {
            yield return source;
        }

        public static ICollection<T> WrapAsICollection<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    throw new ArgumentNullException(nameof(source));

                case ICollection<T> collection:
                    return collection;

                default:
                    return new EnumerationList<T>(source);
            }
        }

        public static IList<T> WrapAsIList<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    throw new ArgumentNullException(nameof(source));

                case IList<T> list:
                    return list;

                default:
                    return new EnumerationList<T>(source);
            }
        }

        public static IReadOnlyCollection<T> WrapAsIReadOnlyCollection<T>(IEnumerable<T> source)
        {
            switch (source)
            {
                case null:
                    throw new ArgumentNullException(nameof(source));

                case T[] array:
#if LESSTHAN_NETSTANDARD20 || LESSTHAN_NETCOREAPP20 || LESSTHAN_NET45
                    return new EnumerationList<T>(array);
#else
                    return Array.AsReadOnly(array);
#endif
                case List<T> list:
#if LESSTHAN_NETSTANDARD13 || LESSTHAN_NET45
{'fraction_non_alphanumeric': 0.07209913631242959, 'fraction_numerical': 0.00488171235448742, 'mean_word_length': 1.3068427890861845, 'pattern_counts': {'":': 0, '<': 123, '<?xml version=': 0, '>': 123, 'https://': 0, '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': '3433366', 'n_tokens_mistral': 2746, 'n_tokens_neox': 2509, 'n_words': 612}