+++ /dev/null
-The C5 library can be built by opening the solution file C5.sln in the\r
-current directory with Microsoft Visual Studio 2005 or \r
-Microsoft Visual C# 2005 Express Edition and performing a build all. \r
-This will build C5.dll to the fileC5\C5\bin\Debug\C5.dll.\r
-\r
-Building all in the C5.sln solution will also build the projects\r
-* 'PreProcess' which does some preprocessing of the C5 sources and is an \r
- integral part of the C5 build process.\r
-* 'docNet' for generation of on-line documentation \r
-* 'UserGuideExample' containing the examples from the User's Guide.\r
-\r
-The build should complete with a few compilation warnings.\r
-\r
-To build the 'nunit' project you need to have NUnit 2.0 installed, else an enormous\r
-number of compilation errors will result. The project is configured for NUnit\r
-version 2.2.6 and tested with that version.\r
-The NUnit tests should pass except for a single one due to missing implementation \r
-of events on the class SortedArray.\r
-\r
-
\ No newline at end of file
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 9.00\r
-# Visual Studio 2005\r
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "C5", "C5\C5.csproj", "{D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F} = {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}\r
- EndProjectSection\r
-EndProject\r
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nunit", "nunit\nunit.csproj", "{08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}"\r
-EndProject\r
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "docNet", "docNet\docNet.csproj", "{42811A81-6A99-4C7A-A6DA-DF104C767B72}"\r
-EndProject\r
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserGuideExamples", "UserGuideExamples\UserGuideExamples.csproj", "{B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}"\r
-EndProject\r
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PreProcess", "PreProcess\PreProcess.csproj", "{6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}"\r
-EndProject\r
-Global\r
- GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
- Debug|Any CPU = Debug|Any CPU\r
- Debug|Mixed platforms = Debug|Mixed platforms\r
- Debug|Win32 = Debug|Win32\r
- Release|Any CPU = Release|Any CPU\r
- Release|Mixed platforms = Release|Mixed platforms\r
- Release|Win32 = Release|Win32\r
- EndGlobalSection\r
- GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Debug|Mixed platforms.Build.0 = Debug|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Debug|Win32.ActiveCfg = Debug|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Release|Any CPU.Build.0 = Release|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Release|Mixed platforms.ActiveCfg = Release|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Release|Mixed platforms.Build.0 = Release|Any CPU\r
- {D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}.Release|Win32.ActiveCfg = Release|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Debug|Win32.ActiveCfg = Debug|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Release|Mixed platforms.ActiveCfg = Release|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Release|Mixed platforms.Build.0 = Release|Any CPU\r
- {08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}.Release|Win32.ActiveCfg = Release|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Debug|Mixed platforms.Build.0 = Debug|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Debug|Win32.ActiveCfg = Debug|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Release|Mixed platforms.ActiveCfg = Release|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Release|Mixed platforms.Build.0 = Release|Any CPU\r
- {42811A81-6A99-4C7A-A6DA-DF104C767B72}.Release|Win32.ActiveCfg = Release|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Debug|Mixed platforms.Build.0 = Debug|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Debug|Win32.ActiveCfg = Debug|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Release|Any CPU.Build.0 = Release|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Release|Mixed platforms.ActiveCfg = Release|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Release|Mixed platforms.Build.0 = Release|Any CPU\r
- {B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}.Release|Win32.ActiveCfg = Release|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Debug|Mixed platforms.ActiveCfg = Debug|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Debug|Mixed platforms.Build.0 = Debug|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Debug|Win32.ActiveCfg = Debug|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Release|Any CPU.Build.0 = Release|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Release|Mixed platforms.ActiveCfg = Release|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Release|Mixed platforms.Build.0 = Release|Any CPU\r
- {6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}.Release|Win32.ActiveCfg = Release|Any CPU\r
- EndGlobalSection\r
- GlobalSection(SolutionProperties) = preSolution\r
- HideSolutionNode = FALSE\r
- EndGlobalSection\r
-EndGlobal\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System.Reflection;\r
-using System.Runtime.CompilerServices;\r
-\r
-//\r
-// General Information about an assembly is controlled through the following \r
-// set of attributes. Change these attribute values to modify the information\r
-// associated with an assembly.\r
-//\r
-[assembly: AssemblyTitle("C5: Copenhagen Comprehensive Collection Classes for CLI")]\r
-[assembly: AssemblyDescription("This is a debug build of release 1.0.0")]\r
-[assembly: AssemblyConfiguration("")]\r
-[assembly: AssemblyCompany("")]\r
-[assembly: AssemblyProduct("")]\r
-[assembly: AssemblyCopyright("(c) 2003-2006 Niels Kokholm and Peter Sestoft")]\r
-[assembly: AssemblyTrademark("")]\r
-[assembly: AssemblyCulture("")]\r
-\r
-//\r
-// Version information for an assembly consists of the following four values:\r
-//\r
-// Major Version\r
-// Minor Version \r
-// Build Number\r
-// Revision\r
-//\r
-// You can specify all the values or you can default the Revision and Build Numbers \r
-// by using the '*' as shown below:\r
-\r
-[assembly: AssemblyVersion("1.0.0")]\r
-\r
-//\r
-// In order to sign your assembly you must specify a key to use. Refer to the \r
-// Microsoft .NET Framework documentation for more information on assembly signing.\r
-//\r
-// Use the attributes below to control which key is used for signing. \r
-//\r
-// Notes: \r
-// (*) If no key is specified, the assembly is not signed.\r
-// (*) KeyName refers to a key that has been installed in the Crypto Service\r
-// Provider (CSP) on your machine. KeyFile refers to a file which contains\r
-// a key.\r
-// (*) If the KeyFile and the KeyName values are both specified, the \r
-// following processing occurs:\r
-// (1) If the KeyName can be found in the CSP, that key is used.\r
-// (2) If the KeyName does not exist and the KeyFile does exist, the key \r
-// in the KeyFile is installed into the CSP and used.\r
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.\r
-// When specifying the KeyFile, the location of the KeyFile should be\r
-// relative to the project output directory which is\r
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is\r
-// located in the project directory, you would specify the AssemblyKeyFile \r
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]\r
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework\r
-// documentation for more information on this.\r
-//\r
-//[assembly: AssemblyDelaySign(false)]\r
-//[assembly: AssemblyKeyFile("..\\..\\..\\c5.snk")]\r
-//[assembly: AssemblyKeyName("")]\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A custom attribute to mark methods and properties as being tested \r
- /// sufficiently in the regression test suite.\r
- /// </summary>\r
- [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]\r
- public class TestedAttribute : Attribute\r
- {\r
-\r
- /// <summary>\r
- /// Optional reference to test case\r
- /// </summary>\r
- [Tested]\r
- public string via;\r
-\r
-\r
- /// <summary>\r
- /// Pretty print attribute value\r
- /// </summary>\r
- /// <returns>"Tested via " + via</returns>\r
- [Tested]\r
- public override string ToString() { return "Tested via " + via; }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- #region int stuff\r
- [Serializable]\r
- class IntComparer : SCG.IComparer<int>\r
- {\r
- [Tested]\r
- public int Compare(int a, int b) { return a > b ? 1 : a < b ? -1 : 0; }\r
- }\r
-\r
- /// <summary>\r
- /// An equalityComparer for System.Int32 integers. \r
- /// <para>This class is a singleton and the instance can be accessed\r
- /// via the static <see cref="P:C5.IntEqualityComparer.Default"/> property</para>\r
- /// </summary>\r
- [Serializable]\r
- public class IntEqualityComparer : SCG.IEqualityComparer<int>\r
- {\r
- static IntEqualityComparer cached;\r
- IntEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- [Tested]\r
- public static IntEqualityComparer Default { get { return cached ?? (cached = new IntEqualityComparer()); } }\r
- /// <summary>\r
- /// Get the hash code of this integer, that is, itself\r
- /// </summary>\r
- /// <param name="item">The integer</param>\r
- /// <returns>The same</returns>\r
- [Tested]\r
- public int GetHashCode(int item) { return item; }\r
-\r
-\r
- /// <summary>\r
- /// Determine whether two integers are equal\r
- /// </summary>\r
- /// <param name="int1">first integer</param>\r
- /// <param name="int2">second integer</param>\r
- /// <returns>True if equal</returns>\r
- [Tested]\r
- public bool Equals(int int1, int int2) { return int1 == int2; }\r
- }\r
-\r
- #endregion\r
-\r
- #region double stuff\r
- class DoubleComparer : SCG.IComparer<double>\r
- {\r
- public int Compare(double a, double b) { return a > b ? 1 : a < b ? -1 : 0; }\r
- }\r
-\r
- /// <summary>\r
- /// An equalityComparer for double. \r
- /// <para>This class is a singleton and the instance can be accessed\r
- /// via the static <see cref="P:C5.DoubleEqualityComparer.Default"/> property</para>\r
- /// </summary>\r
- public class DoubleEqualityComparer : SCG.IEqualityComparer<double>\r
- {\r
- static DoubleEqualityComparer cached;\r
- DoubleEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- [Tested]\r
- public static DoubleEqualityComparer Default { get { return cached ?? (cached = new DoubleEqualityComparer()); } }\r
- /// <summary>\r
- /// Get the hash code of this double,\r
- /// </summary>\r
- /// <param name="item">The double</param>\r
- /// <returns>The same</returns>\r
- [Tested]\r
- public int GetHashCode(double item) { return item.GetHashCode(); }\r
-\r
-\r
- /// <summary>\r
- /// Check if two doubles are equal\r
- /// </summary>\r
- /// <param name="item1">first double</param>\r
- /// <param name="item2">second double</param>\r
- /// <returns>True if equal</returns>\r
- [Tested]\r
- public bool Equals(double item1, double item2) { return item1 == item2; }\r
- }\r
- #endregion\r
-\r
- #region byte stuff\r
- class ByteComparer : SCG.IComparer<byte>\r
- {\r
- public int Compare(byte a, byte b) { return a > b ? 1 : a < b ? -1 : 0; }\r
- }\r
-\r
- /// <summary>\r
- /// An equalityComparer for byte\r
- /// <para>This class is a singleton and the instance can be accessed\r
- /// via the <see cref="P:C5.ByteEqualityComparer.Default"/> property</para>\r
- /// </summary>\r
- public class ByteEqualityComparer : SCG.IEqualityComparer<byte>\r
- {\r
- static ByteEqualityComparer cached = new ByteEqualityComparer();\r
- ByteEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public static ByteEqualityComparer Default { get { return cached ?? (cached = new ByteEqualityComparer()); } }\r
- /// <summary>\r
- /// Get the hash code of this byte, i.e. itself\r
- /// </summary>\r
- /// <param name="item">The byte</param>\r
- /// <returns>The same</returns>\r
- public int GetHashCode(byte item) { return item; }\r
-\r
- /// <summary>\r
- /// Check if two bytes are equal\r
- /// </summary>\r
- /// <param name="item1">first byte</param>\r
- /// <param name="item2">second byte</param>\r
- /// <returns>True if equal</returns>\r
- public bool Equals(byte item1, byte item2) { return item1 == item2; }\r
- }\r
- #endregion\r
-\r
- #region char stuff\r
- class CharComparer : SCG.IComparer<char>\r
- {\r
- public int Compare(char a, char b) { return a > b ? 1 : a < b ? -1 : 0; }\r
- }\r
-\r
- /// <summary>\r
- /// An equalityComparer for char.\r
- /// </summary>\r
- public class CharEqualityComparer : SCG.IEqualityComparer<char>\r
- {\r
- static CharEqualityComparer cached = new CharEqualityComparer();\r
- CharEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public static CharEqualityComparer Default { get { return cached ?? (cached = new CharEqualityComparer()); } }\r
-\r
- /// <summary>\r
- /// Get the hash code of this char\r
- /// </summary>\r
- /// <param name="item">The char</param>\r
- /// <returns>The same</returns>\r
- public int GetHashCode(char item) { return item.GetHashCode(); }\r
-\r
-\r
- /// <summary>\r
- /// Check if two chars are equal\r
- /// </summary>\r
- /// <param name="item1">first char</param>\r
- /// <param name="item2">second char</param>\r
- /// <returns>True if equal</returns>\r
- public bool Equals(char item1, char item2) { return item1 == item2; }\r
- }\r
- #endregion\r
-\r
-}
\ No newline at end of file
+++ /dev/null
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
- <ProductVersion>8.0.40607</ProductVersion>\r
- <SchemaVersion>2.0</SchemaVersion>\r
- <ProjectGuid>{D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}</ProjectGuid>\r
- <OutputType>Library</OutputType>\r
- <StartupObject>\r
- </StartupObject>\r
- <RootNamespace>C5</RootNamespace>\r
- <NoStandardLibraries>false</NoStandardLibraries>\r
- <AssemblyName>C5</AssemblyName>\r
- <FileUpgradeFlags>\r
- </FileUpgradeFlags>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">\r
- <DebugSymbols>true</DebugSymbols>\r
- <Optimize>false</Optimize>\r
- <OutputPath>.\bin\Debug\</OutputPath>\r
- <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>\r
- <DefineConstants>DEBUG</DefineConstants>\r
- <WarningLevel>4</WarningLevel>\r
- <IncrementalBuild>false</IncrementalBuild>\r
- <DocumentationFile>c5.xml</DocumentationFile>\r
- <FxCopRules>+ComRules.dll;+DesignRules.dll|AbstractTypesShouldNotHaveConstructors;+DesignRules.dll|AddAndSubtractOverrideShouldHaveOperatorEqualsOverride;-DesignRules.dll|AssembliesAreMarkedClsCompliant;-DesignRules.dll|AssembliesHaveStrongNames;+DesignRules.dll|AssembliesHaveVersionNumbers;-DesignRules.dll|AssembliesShouldBeComVisibleAttributed;+DesignRules.dll|AttributesAreAttributeUsageAttributed;+DesignRules.dll|AttributesShouldHaveAccessorsForAllArguments;+DesignRules.dll|AvoidNamespacesWithFewMembers;-DesignRules.dll|AvoidOutParameters;+DesignRules.dll|AvoidValueTypesPassedAsByRefParameters;+DesignRules.dll|ConsiderHavingOnlyOneDimensionForIndexer;+DesignRules.dll|ConsiderPassingBaseTypesAsParameters;+DesignRules.dll|ConsiderReplacingMethodsWithProperties;+DesignRules.dll|ConsiderReplacingRepetitiveArgsWithParameterArray;+DesignRules.dll|DefaultParametersAreNotUsed;+DesignRules.dll|EnumerationsShouldBeFlagsAttributed;+DesignRules.dll|EnumerationsShouldBeInt32;+DesignRules.dll|EnumerationsShouldBeIntegralType;+DesignRules.dll|EventFirstParametersAreTypeObject;+DesignRules.dll|EventHandlersReturnVoid;+DesignRules.dll|EventSecondParametersAreEventArgsType;+DesignRules.dll|EventsHaveTwoParameters;+DesignRules.dll|EventsShouldBeUsed;+DesignRules.dll|ExceptionAndSystemExceptionTypesAreNotCaught;+DesignRules.dll|ExceptionsRequireMultipleConstructors;-DesignRules.dll|ExplicitMethodImplementationsInUnsealedClassesHaveVisibleAlternates;+DesignRules.dll|ExternallyVisibleNestedTypesShouldNotBeUsed;+DesignRules.dll|ICollectionImplementationsHaveStronglyTypedMembers;+DesignRules.dll|IComparableImplementationsOverrideEquals;+DesignRules.dll|IComparableImplementationsOverrideOperators;+DesignRules.dll|IEnumeratorImplementationsHaveStronglyTypedMembers;+DesignRules.dll|IListImplementationsHaveStronglyTypedMembers;+DesignRules.dll|InterfacesShouldNotBeEmpty;+DesignRules.dll|ISerializableTypesAreMarkedSerializable;+DesignRules.dll|ObsoleteAttributeOnMemberShouldProvideMessage;+DesignRules.dll|ObsoleteAttributeOnTypeShouldProvideMessage;-DesignRules.dll|OnlyIntegralValuesOrStringsShouldBeUsedForIndexers;+DesignRules.dll|PropertiesShouldNotBeWriteOnly;+DesignRules.dll|ReferenceTypesAreNotPassedAsByRefParameters;+DesignRules.dll|ReferenceTypesShouldNotOverrideOperatorEquals;+DesignRules.dll|SealedTypesDoNotDeclareProtectedMembers;+DesignRules.dll|SealedTypesDoNotDeclareVirtualMembers;+DesignRules.dll|TypesAllocatingUnmanagedResourcesImplementIDisposable;+DesignRules.dll|TypesBelongToNamespaces;+DesignRules.dll|TypesDoNotHavePublicInstanceFields;+DesignRules.dll|TypesHavingOnlyStaticMembersShouldBeSealed;+DesignRules.dll|TypesHavingOnlyStaticMembersShouldNotHaveConstructors;+DesignRules.dll|UriParametersShouldNotBeStrings;+DesignRules.dll|UriPropertiesShouldNotBeStrings;+DesignRules.dll|UriReturnValuesShouldNotBeStrings;+GlobalizationRules.dll;+MaintainabilityRules.dll;+NamingRules.dll;+PerformanceRules.dll;+ReliabilityRules.dll;+SecurityRules.dll;+UsageRules.dll</FxCopRules>\r
- <RunFxCop>false</RunFxCop>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">\r
- <DebugSymbols>false</DebugSymbols>\r
- <Optimize>true</Optimize>\r
- <OutputPath>.\bin\Release\</OutputPath>\r
- <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>\r
- <DefineConstants>TRACE</DefineConstants>\r
- <WarningLevel>4</WarningLevel>\r
- <IncrementalBuild>false</IncrementalBuild>\r
- <DocumentationFile>\r
- </DocumentationFile>\r
- </PropertyGroup>\r
- <ItemGroup>\r
- <Reference Include="System">\r
- <HintPath>..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.2.30703\System.dll</HintPath>\r
- <Name>System</Name>\r
- </Reference>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Compile Include="arrays\CircularQueue.cs" />\r
- <Compile Include="arrays\HashedArrayList.cs" />\r
- <Compile Include="AssemblyInfo.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="Attributes.cs" />\r
- <Compile Include="Builtin.cs" />\r
- <Compile Include="Comparer.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="Delegates.cs" />\r
- <Compile Include="Enums.cs" />\r
- <Compile Include="Exceptions.cs" />\r
- <Compile Include="Formatting.cs" />\r
- <Compile Include="Hashers.cs" />\r
- <Compile Include="Events.cs" />\r
- <Compile Include="Collections.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="Dictionaries.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="Interfaces.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="linkedlists\HashedLinkedList.cs" />\r
- <Compile Include="Random.cs" />\r
- <Compile Include="Records.cs" />\r
- <Compile Include="Sorting.cs" />\r
- <Compile Include="ViewSupport.cs" />\r
- <Compile Include="MappedEnumerators.cs" />\r
- <Compile Include="WrappedArray.cs" />\r
- <Compile Include="Wrappers.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="arrays\ArrayList.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="arrays\SortedArray.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="hashing\HashBag.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="hashing\HashDictionary.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="hashing\HashTable.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="heaps\IntervalHeap.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="linkedlists\LinkedList.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="trees\RedBlackTreeSet.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="trees\RedBlackTreeBag.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="trees\RedBlackTreeDictionary.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <AppDesigner Include="Properties\" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Folder Include="Properties\" />\r
- </ItemGroup>\r
- <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />\r
- <PropertyGroup>\r
- <PreBuildEvent>"$(SolutionDir)PreProcess\$(OutDir)PreProcess.exe"</PreBuildEvent>\r
- <PostBuildEvent>\r
- </PostBuildEvent>\r
- </PropertyGroup>\r
- <ProjectExtensions>\r
- <VisualStudio>\r
- </VisualStudio>\r
- </ProjectExtensions>\r
-</Project>
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-#define IMPROVED_COLLECTION_HASHFUNCTION\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A base class for implementing an IEnumerable<T>\r
- /// </summary>\r
- [Serializable]\r
- public abstract class EnumerableBase<T> : SCG.IEnumerable<T>\r
- {\r
- /// <summary>\r
- /// Create an enumerator for this collection.\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- public abstract SCG.IEnumerator<T> GetEnumerator();\r
-\r
- /// <summary>\r
- /// Count the number of items in an enumerable by enumeration\r
- /// </summary>\r
- /// <param name="items">The enumerable to count</param>\r
- /// <returns>The size of the enumerable</returns>\r
- [Tested]\r
- protected static int countItems(SCG.IEnumerable<T> items)\r
- {\r
- ICollectionValue<T> jtems = items as ICollectionValue<T>;\r
-\r
- if (jtems != null)\r
- return jtems.Count;\r
-\r
- int count = 0;\r
-\r
- using (SCG.IEnumerator<T> e = items.GetEnumerator())\r
- while (e.MoveNext()) count++;\r
-\r
- return count;\r
- }\r
-\r
- #region IEnumerable Members\r
-\r
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
- {\r
- return GetEnumerator();\r
- }\r
-\r
- #endregion\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Base class for classes implementing ICollectionValue[T]\r
- /// </summary>\r
- [Serializable]\r
- public abstract class CollectionValueBase<T> : EnumerableBase<T>, ICollectionValue<T>, IShowable\r
- {\r
- #region Event handling\r
- EventBlock<T> eventBlock;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual EventTypeEnum ListenableEvents { get { return 0; } }\r
-\r
- /// <summary>\r
- /// A flag bitmap of the events currently subscribed to by this collection.\r
- /// </summary>\r
- /// <value></value>\r
- public virtual EventTypeEnum ActiveEvents { get { return eventBlock == null ? 0 : eventBlock.events; } }\r
-\r
- private void checkWillListen(EventTypeEnum eventType)\r
- {\r
- if ((ListenableEvents & eventType) == 0)\r
- throw new UnlistenableEventException();\r
- }\r
-\r
- /// <summary>\r
- /// The change event. Will be raised for every change operation on the collection.\r
- /// </summary>\r
- public virtual event CollectionChangedHandler<T> CollectionChanged\r
- {\r
- add { checkWillListen(EventTypeEnum.Changed); (eventBlock ?? (eventBlock = new EventBlock<T>())).CollectionChanged += value; }\r
- remove\r
- {\r
- checkWillListen(EventTypeEnum.Changed);\r
- if (eventBlock != null)\r
- {\r
- eventBlock.CollectionChanged -= value;\r
- if (eventBlock.events == 0) eventBlock = null;\r
- }\r
- }\r
- }\r
- /// <summary>\r
- /// Fire the CollectionChanged event\r
- /// </summary>\r
- protected virtual void raiseCollectionChanged()\r
- { if (eventBlock != null) eventBlock.raiseCollectionChanged(this); }\r
-\r
- /// <summary>\r
- /// The clear event. Will be raised for every Clear operation on the collection.\r
- /// </summary>\r
- public virtual event CollectionClearedHandler<T> CollectionCleared\r
- {\r
- add { checkWillListen(EventTypeEnum.Cleared); (eventBlock ?? (eventBlock = new EventBlock<T>())).CollectionCleared += value; }\r
- remove\r
- {\r
- checkWillListen(EventTypeEnum.Cleared);\r
- if (eventBlock != null)\r
- {\r
- eventBlock.CollectionCleared -= value;\r
- if (eventBlock.events == 0) eventBlock = null;\r
- }\r
- }\r
- }\r
- /// <summary>\r
- /// Fire the CollectionCleared event\r
- /// </summary>\r
- protected virtual void raiseCollectionCleared(bool full, int count)\r
- { if (eventBlock != null) eventBlock.raiseCollectionCleared(this, full, count); }\r
-\r
- /// <summary>\r
- /// Fire the CollectionCleared event\r
- /// </summary>\r
- protected virtual void raiseCollectionCleared(bool full, int count, int? offset)\r
- { if (eventBlock != null) eventBlock.raiseCollectionCleared(this, full, count, offset); }\r
-\r
- /// <summary>\r
- /// The item added event. Will be raised for every individual addition to the collection.\r
- /// </summary>\r
- public virtual event ItemsAddedHandler<T> ItemsAdded\r
- {\r
- add { checkWillListen(EventTypeEnum.Added); (eventBlock ?? (eventBlock = new EventBlock<T>())).ItemsAdded += value; }\r
- remove\r
- {\r
- checkWillListen(EventTypeEnum.Added);\r
- if (eventBlock != null)\r
- {\r
- eventBlock.ItemsAdded -= value;\r
- if (eventBlock.events == 0) eventBlock = null;\r
- }\r
- }\r
- }\r
- /// <summary>\r
- /// Fire the ItemsAdded event\r
- /// </summary>\r
- /// <param name="item">The item that was added</param>\r
- /// <param name="count"></param>\r
- protected virtual void raiseItemsAdded(T item, int count)\r
- { if (eventBlock != null) eventBlock.raiseItemsAdded(this, item, count); }\r
-\r
- /// <summary>\r
- /// The item removed event. Will be raised for every individual removal from the collection.\r
- /// </summary>\r
- public virtual event ItemsRemovedHandler<T> ItemsRemoved\r
- {\r
- add { checkWillListen(EventTypeEnum.Removed); (eventBlock ?? (eventBlock = new EventBlock<T>())).ItemsRemoved += value; }\r
- remove\r
- {\r
- checkWillListen(EventTypeEnum.Removed);\r
- if (eventBlock != null)\r
- {\r
- eventBlock.ItemsRemoved -= value;\r
- if (eventBlock.events == 0) eventBlock = null;\r
- }\r
- }\r
- }\r
- /// <summary>\r
- /// Fire the ItemsRemoved event\r
- /// </summary>\r
- /// <param name="item">The item that was removed</param>\r
- /// <param name="count"></param>\r
- protected virtual void raiseItemsRemoved(T item, int count)\r
- { if (eventBlock != null) eventBlock.raiseItemsRemoved(this, item, count); }\r
-\r
- /// <summary>\r
- /// The item added event. Will be raised for every individual addition to the collection.\r
- /// </summary>\r
- public virtual event ItemInsertedHandler<T> ItemInserted\r
- {\r
- add { checkWillListen(EventTypeEnum.Inserted); (eventBlock ?? (eventBlock = new EventBlock<T>())).ItemInserted += value; }\r
- remove\r
- {\r
- checkWillListen(EventTypeEnum.Inserted);\r
- if (eventBlock != null)\r
- {\r
- eventBlock.ItemInserted -= value;\r
- if (eventBlock.events == 0) eventBlock = null;\r
- }\r
- }\r
- }\r
- /// <summary>\r
- /// Fire the ItemInserted event\r
- /// </summary>\r
- /// <param name="item">The item that was added</param>\r
- /// <param name="index"></param>\r
- protected virtual void raiseItemInserted(T item, int index)\r
- { if (eventBlock != null) eventBlock.raiseItemInserted(this, item, index); }\r
-\r
- /// <summary>\r
- /// The item removed event. Will be raised for every individual removal from the collection.\r
- /// </summary>\r
- public virtual event ItemRemovedAtHandler<T> ItemRemovedAt\r
- {\r
- add { checkWillListen(EventTypeEnum.RemovedAt); (eventBlock ?? (eventBlock = new EventBlock<T>())).ItemRemovedAt += value; }\r
- remove\r
- {\r
- checkWillListen(EventTypeEnum.RemovedAt);\r
- if (eventBlock != null)\r
- {\r
- eventBlock.ItemRemovedAt -= value;\r
- if (eventBlock.events == 0) eventBlock = null;\r
- }\r
- }\r
- }\r
- /// <summary> \r
- /// Fire the ItemRemovedAt event\r
- /// </summary>\r
- /// <param name="item">The item that was removed</param>\r
- /// <param name="index"></param>\r
- protected virtual void raiseItemRemovedAt(T item, int index)\r
- { if (eventBlock != null) eventBlock.raiseItemRemovedAt(this, item, index); }\r
-\r
- #region Event support for IList\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <param name="value"></param>\r
- /// <param name="item"></param>\r
- protected virtual void raiseForSetThis(int index, T value, T item)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsRemoved(item, 1);\r
- raiseItemRemovedAt(item, index);\r
- raiseItemsAdded(value, 1);\r
- raiseItemInserted(value, index);\r
- raiseCollectionChanged();\r
- }\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="i"></param>\r
- /// <param name="item"></param>\r
- protected virtual void raiseForInsert(int i, T item)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemInserted(item, i);\r
- raiseItemsAdded(item, 1);\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- protected void raiseForRemove(T item)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsRemoved(item, 1);\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="count"></param>\r
- protected void raiseForRemove(T item, int count)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsRemoved(item, count);\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <param name="item"></param>\r
- protected void raiseForRemoveAt(int index, T item)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemRemovedAt(item, index);\r
- raiseItemsRemoved(item, 1);\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region Event Support for ICollection\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="newitem"></param>\r
- /// <param name="olditem"></param>\r
- protected virtual void raiseForUpdate(T newitem, T olditem)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsRemoved(olditem, 1);\r
- raiseItemsAdded(newitem, 1);\r
- raiseCollectionChanged();\r
- }\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="newitem"></param>\r
- /// <param name="olditem"></param>\r
- /// <param name="count"></param>\r
- protected virtual void raiseForUpdate(T newitem, T olditem, int count)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsRemoved(olditem, count);\r
- raiseItemsAdded(newitem, count);\r
- raiseCollectionChanged();\r
- }\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- protected virtual void raiseForAdd(T item)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsAdded(item, 1);\r
- raiseCollectionChanged();\r
- }\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="wasRemoved"></param>\r
- protected virtual void raiseForRemoveAll(ICollectionValue<T> wasRemoved)\r
- {\r
- if ((ActiveEvents & EventTypeEnum.Removed) != 0)\r
- foreach (T item in wasRemoved)\r
- raiseItemsRemoved(item, 1);\r
- if (wasRemoved != null && wasRemoved.Count > 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- protected class RaiseForRemoveAllHandler\r
- {\r
- CollectionValueBase<T> collection;\r
- CircularQueue<T> wasRemoved;\r
- bool wasChanged = false;\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="collection"></param>\r
- public RaiseForRemoveAllHandler(CollectionValueBase<T> collection)\r
- {\r
- this.collection = collection;\r
- mustFireRemoved = (collection.ActiveEvents & EventTypeEnum.Removed) != 0;\r
- MustFire = (collection.ActiveEvents & (EventTypeEnum.Removed | EventTypeEnum.Changed)) != 0;\r
- }\r
-\r
- bool mustFireRemoved;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly bool MustFire;\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- public void Remove(T item)\r
- {\r
- if (mustFireRemoved)\r
- {\r
- if (wasRemoved == null)\r
- wasRemoved = new CircularQueue<T>();\r
- wasRemoved.Enqueue(item);\r
- }\r
- if (!wasChanged)\r
- wasChanged = true;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public void Raise()\r
- {\r
- if (wasRemoved != null)\r
- foreach (T item in wasRemoved)\r
- collection.raiseItemsRemoved(item, 1);\r
- if (wasChanged)\r
- collection.raiseCollectionChanged();\r
- }\r
- }\r
- #endregion\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// Check if collection is empty.\r
- /// </summary>\r
- /// <value>True if empty</value>\r
- public abstract bool IsEmpty { get;}\r
-\r
- /// <summary>\r
- /// The number of items in this collection.\r
- /// </summary>\r
- /// <value></value>\r
- public abstract int Count { get;}\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>A characterization of the speed of the \r
- /// <code>Count</code> property in this collection.</value>\r
- public abstract Speed CountSpeed { get; }\r
-\r
- /// <summary>\r
- /// Copy the items of this collection to part of an array.\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException"> if <code>index</code> \r
- /// is not a valid index\r
- /// into the array (i.e. negative or not less than the size of the array)\r
- /// or the array does not have room for the items.</exception>\r
- /// <param name="array">The array to copy to.</param>\r
- /// <param name="index">The starting index.</param>\r
- [Tested]\r
- public virtual void CopyTo(T[] array, int index)\r
- {\r
-#warning This code does not fit the doc comment and unit tests\r
- if (index < 0 || index + Count > array.Length)\r
- throw new ArgumentOutOfRangeException();\r
-\r
- foreach (T item in this) array[index++] = item;\r
- }\r
-\r
- /// <summary>\r
- /// Create an array with the items of this collection (in the same order as an\r
- /// enumerator would output them).\r
- /// </summary>\r
- /// <returns>The array</returns>\r
- //[Tested]\r
- public virtual T[] ToArray()\r
- {\r
- T[] res = new T[Count];\r
- int i = 0;\r
-\r
- foreach (T item in this) res[i++] = item;\r
-\r
- return res;\r
- }\r
-\r
- /// <summary>\r
- /// Apply an single argument action, <see cref="T:C5.Act`1"/> to this enumerable\r
- /// </summary>\r
- /// <param name="action">The action delegate</param>\r
- [Tested]\r
- public virtual void Apply(Act<T> action)\r
- {\r
- foreach (T item in this)\r
- action(item);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R = bool</code>) \r
- /// defining the predicate</param>\r
- /// <returns>True if such an item exists</returns>\r
- [Tested]\r
- public virtual bool Exists(Fun<T, bool> predicate)\r
- {\r
- foreach (T item in this)\r
- if (predicate(item))\r
- return true;\r
-\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the first one in enumeration order.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <param name="item"></param>\r
- /// <returns>True is such an item exists</returns>\r
- public virtual bool Find(Fun<T, bool> predicate, out T item)\r
- {\r
- foreach (T jtem in this)\r
- if (predicate(jtem))\r
- {\r
- item = jtem;\r
- return true;\r
- }\r
- item = default(T);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Check if all items in this collection satisfies a specific predicate.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R = bool</code>) \r
- /// defining the predicate</param>\r
- /// <returns>True if all items satisfies the predicate</returns>\r
- [Tested]\r
- public virtual bool All(Fun<T, bool> predicate)\r
- {\r
- foreach (T item in this)\r
- if (!predicate(item))\r
- return false;\r
-\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// Create an enumerable, enumerating the items of this collection that satisfies \r
- /// a certain condition.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R = bool</code>) \r
- /// defining the predicate</param>\r
- /// <returns>The filtered enumerable</returns>\r
- public virtual SCG.IEnumerable<T> Filter(Fun<T, bool> predicate)\r
- {\r
- foreach (T item in this)\r
- if (predicate(item))\r
- yield return item;\r
- }\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- public abstract T Choose();\r
-\r
-\r
- /// <summary>\r
- /// Create an enumerator for this collection.\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- public override abstract SCG.IEnumerator<T> GetEnumerator();\r
-\r
- #region IShowable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public virtual bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowCollectionValue<T>(this, stringbuilder, ref rest, formatProvider);\r
- }\r
- #endregion\r
-\r
- #region IFormattable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public virtual string ToString(string format, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowString(this, format, formatProvider);\r
- }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return ToString(null, null);\r
- }\r
-\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public abstract class DirectedCollectionValueBase<T> : CollectionValueBase<T>, IDirectedCollectionValue<T>\r
- {\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- public virtual EnumerationDirection Direction { [Tested]get { return EnumerationDirection.Forwards; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public abstract IDirectedCollectionValue<T> Backwards();\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return this.Backwards(); }\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the first one in enumeration order.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <param name="item"></param>\r
- /// <returns>True is such an item exists</returns>\r
- public virtual bool FindLast(Fun<T, bool> predicate, out T item)\r
- {\r
- foreach (T jtem in Backwards())\r
- if (predicate(jtem))\r
- {\r
- item = jtem;\r
- return true;\r
- }\r
- item = default(T);\r
- return false;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Base class (abstract) for ICollection implementations.\r
- /// </summary>\r
- [Serializable]\r
- public abstract class CollectionBase<T> : CollectionValueBase<T>\r
- {\r
- #region Fields\r
-\r
- object syncroot = new object();\r
-\r
- /// <summary>\r
- /// The underlying field of the ReadOnly property\r
- /// </summary>\r
- protected bool isReadOnly = false;\r
-\r
- /// <summary>\r
- /// The current stamp value\r
- /// </summary>\r
- protected int stamp;\r
-\r
- /// <summary>\r
- /// The number of items in the collection\r
- /// </summary>\r
- protected int size;\r
-\r
- /// <summary>\r
- /// The item equalityComparer of the collection\r
- /// </summary>\r
- protected readonly SCG.IEqualityComparer<T> itemequalityComparer;\r
-\r
- int iUnSequencedHashCode, iUnSequencedHashCodeStamp = -1;\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="itemequalityComparer"></param>\r
- public CollectionBase(SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- if (itemequalityComparer == null)\r
- throw new NullReferenceException("Item EqualityComparer cannot be null.");\r
- this.itemequalityComparer = itemequalityComparer;\r
- }\r
-\r
- #region Util\r
-\r
- /// <summary>\r
- /// Utility method for range checking.\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the start or count is negative or\r
- /// if the range does not fit within collection size.</exception>\r
- /// <param name="start">start of range</param>\r
- /// <param name="count">size of range</param>\r
- [Tested]\r
- protected void checkRange(int start, int count)\r
- {\r
- if (start < 0 || count < 0 || start + count > size)\r
- throw new ArgumentOutOfRangeException();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Compute the unsequenced hash code of a collection\r
- /// </summary>\r
- /// <param name="items">The collection to compute hash code for</param>\r
- /// <param name="itemequalityComparer">The item equalityComparer</param>\r
- /// <returns>The hash code</returns>\r
- [Tested]\r
- public static int ComputeHashCode(ICollectionValue<T> items, SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- int h = 0;\r
-\r
-#if IMPROVED_COLLECTION_HASHFUNCTION\r
- //But still heuristic: \r
- //Note: the three odd factors should really be random, \r
- //but there will be a problem with serialization/deserialization!\r
- //Two products is too few\r
- foreach (T item in items)\r
- {\r
- uint h1 = (uint)itemequalityComparer.GetHashCode(item);\r
-\r
- h += (int)((h1 * 1529784657 + 1) ^ (h1 * 2912831877) ^ (h1 * 1118771817 + 2));\r
- }\r
-\r
- return h;\r
- /*\r
- The pairs (-1657792980, -1570288808) and (1862883298, -272461342) gives the same\r
- unsequenced hashcode with this hashfunction. The pair was found with code like\r
-\r
- HashDictionary<int, int[]> set = new HashDictionary<int, int[]>();\r
- Random rnd = new C5Random(12345);\r
- while (true)\r
- {\r
- int[] a = new int[2];\r
- a[0] = rnd.Next(); a[1] = rnd.Next();\r
- int h = unsequencedhashcode(a);\r
- int[] b = a;\r
- if (set.FindOrAdd(h, ref b))\r
- {\r
- Console.WriteLine("Code {5}, Pair ({1},{2}) number {0} matched other pair ({3},{4})", set.Count, a[0], a[1], b[0], b[1], h);\r
- }\r
- }\r
- */\r
-#else\r
- foreach (T item in items)\r
- h ^= itemequalityComparer.GetHashCode(item);\r
-\r
- return (items.Count << 16) + h;\r
-#endif\r
- }\r
-\r
- static Type isortedtype = typeof(ISorted<T>);\r
-\r
- /// <summary>\r
- /// Examine if tit and tat are equal as unsequenced collections\r
- /// using the specified item equalityComparer (assumed compatible with the two collections).\r
- /// </summary>\r
- /// <param name="collection1">The first collection</param>\r
- /// <param name="collection2">The second collection</param>\r
- /// <param name="itemequalityComparer">The item equalityComparer to use for comparison</param>\r
- /// <returns>True if equal</returns>\r
- [Tested]\r
- public static bool StaticEquals(ICollection<T> collection1, ICollection<T> collection2, SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- if (object.ReferenceEquals(collection1, collection2))\r
- return true;\r
-\r
- if (collection1.Count != collection2.Count)\r
- return false;\r
-\r
- //This way we might run through both enumerations twice, but\r
- //probably not (if the hash codes are good)\r
- //TODO: cehck equal equalityComparers, at least here!\r
- if (collection1.GetUnsequencedHashCode() != collection2.GetUnsequencedHashCode())\r
- return false;\r
-\r
- //TODO: move this to the sorted implementation classes? \r
- //Really depends on speed of IntanceOfType: we could save a cast\r
- {\r
- ISorted<T> stit, stat;\r
- if ((stit = collection1 as ISorted<T>) != null && (stat = collection2 as ISorted<T>) != null && stit.Comparer == stat.Comparer)\r
- {\r
- using (SCG.IEnumerator<T> dat = collection2.GetEnumerator(), dit = collection1.GetEnumerator())\r
- {\r
- while (dit.MoveNext())\r
- {\r
- dat.MoveNext();\r
- if (!itemequalityComparer.Equals(dit.Current, dat.Current))\r
- return false;\r
- }\r
- return true;\r
- }\r
- }\r
- }\r
-\r
- if (!collection1.AllowsDuplicates && (collection2.AllowsDuplicates || collection2.ContainsSpeed >= collection1.ContainsSpeed))\r
- {\r
- foreach (T x in collection1) if (!collection2.Contains(x)) return false;\r
- }\r
- else if (!collection2.AllowsDuplicates)\r
- {\r
- foreach (T x in collection2) if (!collection1.Contains(x)) return false;\r
- }\r
- // Now tit.AllowsDuplicates && tat.AllowsDuplicates\r
- else if (collection1.DuplicatesByCounting && collection2.DuplicatesByCounting)\r
- {\r
- foreach (T item in collection2) if (collection1.ContainsCount(item) != collection2.ContainsCount(item)) return false;\r
- }\r
- else\r
- {\r
- //To avoid an O(n^2) algorithm, we make an aux hashtable to hold the count of items\r
- HashDictionary<T, int> dict = new HashDictionary<T, int>();\r
- foreach (T item in collection2)\r
- {\r
- int count = 1;\r
- if (dict.FindOrAdd(item, ref count))\r
- dict[item] = count + 1;\r
- }\r
- foreach (T item in collection1)\r
- {\r
- int count;\r
- if (dict.Find(item, out count) && count > 0)\r
- dict[item] = count - 1;\r
- else\r
- return false;\r
- }\r
- return true;\r
- }\r
-\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get the unsequenced collection hash code of this collection: from the cached \r
- /// value if present and up to date, else (re)compute.\r
- /// </summary>\r
- /// <returns>The hash code</returns>\r
- public virtual int GetUnsequencedHashCode()\r
- {\r
- if (iUnSequencedHashCodeStamp == stamp)\r
- return iUnSequencedHashCode;\r
-\r
- iUnSequencedHashCode = ComputeHashCode(this, itemequalityComparer);\r
- iUnSequencedHashCodeStamp = stamp;\r
- return iUnSequencedHashCode;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if the contents of that is equal to the contents of this\r
- /// in the unsequenced sense. Using the item equalityComparer of this collection. \r
- /// Assuming that the item EqualityComparer is compatible with otherCollection!\r
- /// </summary>\r
- /// <param name="otherCollection">The collection to compare to.</param>\r
- /// <returns>True if equal</returns>\r
- public virtual bool UnsequencedEquals(ICollection<T> otherCollection)\r
- {\r
- return otherCollection != null && StaticEquals((ICollection<T>)this, otherCollection, itemequalityComparer);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if the collection has been modified since a specified time, expressed as a stamp value.\r
- /// </summary>\r
- /// <exception cref="CollectionModifiedException"> if this collection has been updated \r
- /// since a target time</exception>\r
- /// <param name="thestamp">The stamp identifying the target time</param>\r
- protected virtual void modifycheck(int thestamp)\r
- {\r
- if (this.stamp != thestamp)\r
- throw new CollectionModifiedException();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if it is valid to perform update operations, and if so increment stamp.\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException">If colection is read-only</exception>\r
- protected virtual void updatecheck()\r
- {\r
- if (isReadOnly)\r
- throw new ReadOnlyCollectionException();\r
-\r
- stamp++;\r
- }\r
-\r
- #endregion\r
-\r
- #region ICollection<T> members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if this collection is read only</value>\r
- [Tested]\r
- public virtual bool IsReadOnly { [Tested]get { return isReadOnly; } }\r
-\r
- #endregion\r
-\r
- #region ICollectionValue<T> members\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The size of this collection</value>\r
- [Tested]\r
- public override int Count { [Tested]get { return size; } }\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>A characterization of the speed of the \r
- /// <code>Count</code> property in this collection.</value>\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
-\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual SCG.IEqualityComparer<T> EqualityComparer { get { return itemequalityComparer; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>A distinguished object to use for locking to synchronize multithreaded access</value>\r
- [Tested]\r
- public virtual object SyncRoot { get { return syncroot; } }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if this collection is empty</value>\r
- [Tested]\r
- public override bool IsEmpty { [Tested]get { return size == 0; } }\r
-\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
- /// <summary>\r
- /// Create an enumerator for this collection.\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- public override abstract SCG.IEnumerator<T> GetEnumerator();\r
- #endregion\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- [Serializable]\r
- public abstract class DirectedCollectionBase<T> : CollectionBase<T>, IDirectedCollectionValue<T>\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="itemequalityComparer"></param>\r
- public DirectedCollectionBase(SCG.IEqualityComparer<T> itemequalityComparer) : base(itemequalityComparer) { }\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- public virtual EnumerationDirection Direction { [Tested]get { return EnumerationDirection.Forwards; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public abstract IDirectedCollectionValue<T> Backwards();\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return this.Backwards(); }\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the first one in enumeration order.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <param name="item"></param>\r
- /// <returns>True is such an item exists</returns>\r
- public virtual bool FindLast(Fun<T, bool> predicate, out T item)\r
- {\r
- foreach (T jtem in Backwards())\r
- if (predicate(jtem))\r
- {\r
- item = jtem;\r
- return true;\r
- }\r
- item = default(T);\r
- return false;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Base class (abstract) for sequenced collection implementations.\r
- /// </summary>\r
- [Serializable]\r
- public abstract class SequencedBase<T> : DirectedCollectionBase<T>, IDirectedCollectionValue<T>\r
- {\r
- #region Fields\r
-\r
- int iSequencedHashCode, iSequencedHashCodeStamp = -1;\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="itemequalityComparer"></param>\r
- public SequencedBase(SCG.IEqualityComparer<T> itemequalityComparer) : base(itemequalityComparer) { }\r
-\r
- #region Util\r
-\r
- //TODO: make random for release\r
- const int HASHFACTOR = 31;\r
-\r
- /// <summary>\r
- /// Compute the unsequenced hash code of a collection\r
- /// </summary>\r
- /// <param name="items">The collection to compute hash code for</param>\r
- /// <param name="itemequalityComparer">The item equalityComparer</param>\r
- /// <returns>The hash code</returns>\r
- [Tested]\r
- public static int ComputeHashCode(ISequenced<T> items, SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- //NOTE: It must be possible to devise a much stronger combined hashcode, \r
- //but unfortunately, it has to be universal. OR we could use a (strong)\r
- //family and initialise its parameter randomly at load time of this class!\r
- //(We would not want to have yet a flag to check for invalidation?!)\r
- //NBNBNB: the current hashcode has the very bad property that items with hashcode 0\r
- // is ignored.\r
- int iIndexedHashCode = 0;\r
-\r
- foreach (T item in items)\r
- iIndexedHashCode = iIndexedHashCode * HASHFACTOR + itemequalityComparer.GetHashCode(item);\r
-\r
- return iIndexedHashCode;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Examine if tit and tat are equal as sequenced collections\r
- /// using the specified item equalityComparer (assumed compatible with the two collections).\r
- /// </summary>\r
- /// <param name="collection1">The first collection</param>\r
- /// <param name="collection2">The second collection</param>\r
- /// <param name="itemequalityComparer">The item equalityComparer to use for comparison</param>\r
- /// <returns>True if equal</returns>\r
- [Tested]\r
- public static bool StaticEquals(ISequenced<T> collection1, ISequenced<T> collection2, SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- if (object.ReferenceEquals(collection1, collection2))\r
- return true;\r
-\r
- if (collection1.Count != collection2.Count)\r
- return false;\r
-\r
- //This way we might run through both enumerations twice, but\r
- //probably not (if the hash codes are good)\r
- if (collection1.GetSequencedHashCode() != collection2.GetSequencedHashCode())\r
- return false;\r
-\r
- using (SCG.IEnumerator<T> dat = collection2.GetEnumerator(), dit = collection1.GetEnumerator())\r
- {\r
- while (dit.MoveNext())\r
- {\r
- dat.MoveNext();\r
- if (!itemequalityComparer.Equals(dit.Current, dat.Current))\r
- return false;\r
- }\r
- }\r
-\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get the sequenced collection hash code of this collection: from the cached \r
- /// value if present and up to date, else (re)compute.\r
- /// </summary>\r
- /// <returns>The hash code</returns>\r
- public virtual int GetSequencedHashCode()\r
- {\r
- if (iSequencedHashCodeStamp == stamp)\r
- return iSequencedHashCode;\r
-\r
- iSequencedHashCode = ComputeHashCode((ISequenced<T>)this, itemequalityComparer);\r
- iSequencedHashCodeStamp = stamp;\r
- return iSequencedHashCode;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if the contents of that is equal to the contents of this\r
- /// in the sequenced sense. Using the item equalityComparer of this collection.\r
- /// </summary>\r
- /// <param name="otherCollection">The collection to compare to.</param>\r
- /// <returns>True if equal</returns>\r
- public virtual bool SequencedEquals(ISequenced<T> otherCollection)\r
- {\r
- return StaticEquals((ISequenced<T>)this, otherCollection, itemequalityComparer);\r
- }\r
-\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// Create an enumerator for this collection.\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- public override abstract SCG.IEnumerator<T> GetEnumerator();\r
-\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- [Tested]\r
- public override EnumerationDirection Direction { [Tested]get { return EnumerationDirection.Forwards; } }\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the index of the first one.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>the index, if found, a negative value else</returns>\r
- public int FindIndex(Fun<T, bool> predicate)\r
- {\r
- int index = 0;\r
- foreach (T item in this)\r
- {\r
- if (predicate(item))\r
- return index;\r
- index++;\r
- }\r
- return -1;\r
- }\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the index of the last one.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>the index, if found, a negative value else</returns>\r
- public int FindLastIndex(Fun<T, bool> predicate)\r
- {\r
- int index = Count - 1;\r
- foreach (T item in Backwards())\r
- {\r
- if (predicate(item))\r
- return index;\r
- index--;\r
- }\r
- return -1;\r
- }\r
-\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Base class for collection classes of dynamic array type implementations.\r
- /// </summary>\r
- [Serializable]\r
- public abstract class ArrayBase<T> : SequencedBase<T>\r
- {\r
- #region Fields\r
- /// <summary>\r
- /// The actual internal array container. Will be extended on demand.\r
- /// </summary>\r
- protected T[] array;\r
-\r
- /// <summary>\r
- /// The offset into the internal array container of the first item. The offset is 0 for a \r
- /// base dynamic array and may be positive for an updatable view into a base dynamic array.\r
- /// </summary>\r
- protected int offset;\r
- #endregion\r
-\r
- #region Util\r
- /// <summary>\r
- /// Double the size of the internal array.\r
- /// </summary>\r
- protected virtual void expand()\r
- {\r
- expand(2 * array.Length, size);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Expand the internal array container.\r
- /// </summary>\r
- /// <param name="newcapacity">The new size of the internal array - \r
- /// will be rounded upwards to a power of 2.</param>\r
- /// <param name="newsize">The (new) size of the (base) collection.</param>\r
- protected virtual void expand(int newcapacity, int newsize)\r
- {\r
- Debug.Assert(newcapacity >= newsize);\r
-\r
- int newlength = array.Length;\r
-\r
- while (newlength < newcapacity) newlength *= 2;\r
-\r
- T[] newarray = new T[newlength];\r
-\r
- Array.Copy(array, newarray, newsize);\r
- array = newarray;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Insert an item at a specific index, moving items to the right\r
- /// upwards and expanding the array if necessary.\r
- /// </summary>\r
- /// <param name="i">The index at which to insert.</param>\r
- /// <param name="item">The item to insert.</param>\r
- protected virtual void insert(int i, T item)\r
- {\r
- if (size == array.Length)\r
- expand();\r
-\r
- if (i < size)\r
- Array.Copy(array, i, array, i + 1, size - i);\r
-\r
- array[i] = item;\r
- size++;\r
- }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
-\r
- /// <summary>\r
- /// Create an empty ArrayBase object.\r
- /// </summary>\r
- /// <param name="capacity">The initial capacity of the internal array container.\r
- /// Will be rounded upwards to the nearest power of 2 greater than or equal to 8.</param>\r
- /// <param name="itemequalityComparer">The item equalityComparer to use, primarily for item equality</param>\r
- public ArrayBase(int capacity, SCG.IEqualityComparer<T> itemequalityComparer)\r
- : base(itemequalityComparer)\r
- {\r
- int newlength = 8;\r
- while (newlength < capacity) newlength *= 2;\r
- array = new T[newlength];\r
- }\r
-\r
- #endregion\r
-\r
- #region IIndexed members\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException">If the arguments does not describe a \r
- /// valid range in the indexed collection, cf. <see cref="M:C5.CollectionBase`1.checkRange(System.Int32,System.Int32)"/>.</exception>\r
- /// <value>The directed collection of items in a specific index interval.</value>\r
- /// <param name="start">The low index of the interval (inclusive).</param>\r
- /// <param name="count">The size of the range.</param>\r
- [Tested]\r
- public virtual IDirectedCollectionValue<T> this[int start, int count]\r
- {\r
- [Tested]\r
- get\r
- {\r
- checkRange(start, count);\r
- return new Range(this, start, count, true);\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region IEditableCollection members\r
- /// <summary>\r
- /// Remove all items and reset size of internal array container.\r
- /// </summary>\r
- [Tested]\r
- public virtual void Clear()\r
- {\r
- updatecheck();\r
- array = new T[8];\r
- size = 0;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create an array containing (copies) of the items of this collection in enumeration order.\r
- /// </summary>\r
- /// <returns>The new array</returns>\r
- [Tested]\r
- public override T[] ToArray()\r
- {\r
- T[] res = new T[size];\r
-\r
- Array.Copy(array, offset, res, 0, size);\r
- return res;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Perform an internal consistency (invariant) test on the array base.\r
- /// </summary>\r
- /// <returns>True if test succeeds.</returns>\r
- [Tested]\r
- public virtual bool Check()\r
- {\r
- bool retval = true;\r
-\r
- if (size > array.Length)\r
- {\r
- Console.WriteLine("Bad size ({0}) > array.Length ({1})", size, array.Length);\r
- return false;\r
- }\r
-\r
- for (int i = 0; i < size; i++)\r
- {\r
- if ((object)(array[i]) == null)\r
- {\r
- Console.WriteLine("Bad element: null at index {0}", i);\r
- return false;\r
- }\r
- }\r
-\r
- return retval;\r
- }\r
-\r
- #endregion\r
-\r
- #region IDirectedCollection<T> Members\r
-\r
- /// <summary>\r
- /// Create a directed collection with the same contents as this one, but \r
- /// opposite enumeration sequence.\r
- /// </summary>\r
- /// <returns>The mirrored collection.</returns>\r
- [Tested]\r
- public override IDirectedCollectionValue<T> Backwards() { return this[0, size].Backwards(); }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. The result is the last item in the internal array,\r
- /// making it efficient to remove.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- public override T Choose() { if (size > 0) return array[size - 1]; throw new NoSuchItemException(); }\r
-\r
- #region IEnumerable<T> Members\r
- /// <summary>\r
- /// Create an enumerator for this array based collection.\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- int thestamp = stamp, theend = size + offset, thestart = offset;\r
-\r
- for (int i = thestart; i < theend; i++)\r
- {\r
- modifycheck(thestamp);\r
- yield return array[i];\r
- }\r
- }\r
- #endregion\r
-\r
- #region Range nested class\r
- /// <summary>\r
- /// A helper class for defining results of interval queries on array based collections.\r
- /// </summary>\r
- protected class Range : DirectedCollectionValueBase<T>, IDirectedCollectionValue<T>\r
- {\r
- int start, count, delta, stamp;\r
-\r
- ArrayBase<T> thebase;\r
-\r
-\r
- internal Range(ArrayBase<T> thebase, int start, int count, bool forwards)\r
- {\r
- this.thebase = thebase; stamp = thebase.stamp;\r
- delta = forwards ? 1 : -1;\r
- this.start = start + thebase.offset; this.count = count;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="CollectionModifiedException">if underlying collection has been modified.</exception>\r
- /// <value>True if this collection is empty.</value>\r
- public override bool IsEmpty { get { thebase.modifycheck(stamp); return count == 0; } }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="CollectionModifiedException">if underlying collection has been modified.</exception>\r
- /// <value>The number of items in the range</value>\r
- [Tested]\r
- public override int Count { [Tested]get { thebase.modifycheck(stamp); return count; } }\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>A characterization of the speed of the \r
- /// <exception cref="CollectionModifiedException">if underlying collection has been modified.</exception>\r
- /// <code>Count</code> property in this collection.</value>\r
- public override Speed CountSpeed { get { thebase.modifycheck(stamp); return Speed.Constant; } }\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// </summary>\r
- /// <exception cref="CollectionModifiedException">if underlying collection has been modified.</exception>\r
- /// <exception cref="NoSuchItemException">if range is empty.</exception>\r
- /// <returns></returns>\r
- public override T Choose()\r
- {\r
- thebase.modifycheck(stamp);\r
- if (count == 0)\r
- throw new NoSuchItemException();\r
- return thebase.array[start];\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create an enumerator for this range of an array based collection.\r
- /// </summary>\r
- /// <exception cref="CollectionModifiedException">if underlying collection has been modified.</exception>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- for (int i = 0; i < count; i++)\r
- {\r
- thebase.modifycheck(stamp);\r
- yield return thebase.array[start + delta * i];\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a araay collection range with the same contents as this one, but \r
- /// opposite enumeration sequence.\r
- /// </summary>\r
- /// <exception cref="CollectionModifiedException">if underlying collection has been modified.</exception>\r
- /// <returns>The mirrored collection.</returns>\r
- [Tested]\r
- public override IDirectedCollectionValue<T> Backwards()\r
- {\r
- thebase.modifycheck(stamp);\r
-\r
- Range res = (Range)MemberwiseClone();\r
-\r
- res.delta = -delta;\r
- res.start = start + (count - 1) * delta;\r
- return res;\r
- }\r
-\r
-\r
- IDirectedEnumerable<T> C5.IDirectedEnumerable<T>.Backwards()\r
- {\r
- return Backwards();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <exception cref="CollectionModifiedException">if underlying collection has been modified.</exception>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- [Tested]\r
- public override EnumerationDirection Direction\r
- {\r
- [Tested]\r
- get\r
- {\r
- thebase.modifycheck(stamp);\r
- return delta > 0 ? EnumerationDirection.Forwards : EnumerationDirection.Backwards;\r
- }\r
- }\r
- }\r
- #endregion\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using C5;\r
-using System;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{ \r
-/// <summary>\r
-/// A default item comparer for an item type that is either generic (IComparable<T>)\r
-/// or ordinarily (System.IComparable) comparable.\r
-/// </summary>\r
- public static class Comparer<T>\r
- {\r
- readonly static Type naturalComparerO = typeof(NaturalComparerO<>);\r
-\r
- readonly static Type naturalComparer = typeof(NaturalComparer<>);\r
-\r
- static SCG.IComparer<T> cachedComparer = null;\r
-\r
- /// <summary>\r
- /// Create a default comparer. \r
- /// <para>The IComparer[T] object is constructed when this class is initialised, i.e. \r
- /// its static constructors called. Thus, the property will be the same object \r
- /// for the duration of an invocation of the runtime, but a value serialized in \r
- /// another invocation and deserialized here will not be the same object.</para>\r
- /// </summary>\r
- /// <exception cref="NotComparableException">If T is not comparable</exception>\r
- /// <value>The comparer</value>\r
- [Tested]\r
- public static SCG.IComparer<T> Default\r
- {\r
- get\r
- {\r
- if (cachedComparer != null)\r
- return cachedComparer;\r
-\r
- Type t = typeof(T);\r
-\r
- if (t.IsValueType)\r
- {\r
- if (t.Equals(typeof(int)))\r
- return cachedComparer = (SCG.IComparer<T>)(new IntComparer());\r
-\r
- if (t.Equals(typeof(double)))\r
- return cachedComparer = (SCG.IComparer<T>)(new DoubleComparer());\r
-\r
- if (t.Equals(typeof(byte)))\r
- return cachedComparer = (SCG.IComparer<T>)(new ByteComparer());\r
- }\r
-\r
- if (typeof(IComparable<T>).IsAssignableFrom(t))\r
- {\r
- Type c = naturalComparer.MakeGenericType(new Type[] { t });\r
-\r
- return cachedComparer = (SCG.IComparer<T>)(c.GetConstructor(System.Type.EmptyTypes).Invoke(null));\r
- }\r
-\r
- if (t.GetInterface("System.IComparable") != null)\r
- {\r
- Type c = naturalComparerO.MakeGenericType(new Type[] { t });\r
-\r
- return cachedComparer = (SCG.IComparer<T>)(c.GetConstructor(System.Type.EmptyTypes).Invoke(null));\r
- }\r
-\r
- throw new NotComparableException(String.Format("Cannot make comparer for type {0}", t));\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// A natural generic IComparer for an IComparable<T> item type\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class NaturalComparer<T> : SCG.IComparer<T>\r
- where T : IComparable<T>\r
- {\r
- /// <summary>\r
- /// Compare two items\r
- /// </summary>\r
- /// <param name="item1">First item</param>\r
- /// <param name="item2">Second item</param>\r
- /// <returns>item1 <=> item2</returns>\r
- [Tested]\r
- public int Compare(T item1, T item2) { return item1 != null ? item1.CompareTo(item2) : item2 != null ? -1 : 0; }\r
- }\r
-\r
- /// <summary>\r
- /// A natural generic IComparer for a System.IComparable item type\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class NaturalComparerO<T> : SCG.IComparer<T>\r
- where T : System.IComparable\r
- {\r
- /// <summary>\r
- /// Compare two items\r
- /// </summary>\r
- /// <param name="item1">First item</param>\r
- /// <param name="item2">Second item</param>\r
- /// <returns>item1 <=> item2</returns>\r
- [Tested]\r
- public int Compare(T item1, T item2) { return item1 != null ? item1.CompareTo(item2) : item2 != null ? -1 : 0; }\r
- }\r
-\r
- /// <summary>\r
- /// A generic comparer for type T based on a Comparison[T] delegate\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class DelegateComparer<T> : SCG.IComparer<T>\r
- {\r
- readonly Comparison<T> cmp;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="comparison"></param>\r
- public DelegateComparer(Comparison<T> comparison)\r
- {\r
- if (comparison == null)\r
- throw new NullReferenceException("Comparison cannot be null");\r
- this.cmp = comparison;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item1">First item</param>\r
- /// <param name="item2">Second item</param>\r
- /// <returns>item1 <=> item2</returns>\r
- public int Compare(T item1, T item2) { return cmp(item1, item2); }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using C5;\r
-using System;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Diagnostics;\r
-\r
-#pragma warning disable 1711\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public delegate void Act();\r
- /// <summary>\r
- /// <para>\r
- /// The type Act[T] corresponds to System.Action[T] in the .Net\r
- /// Framework class library.\r
- ///</para>\r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <param name="x1"></param>\r
- public delegate void Act<A1>(A1 x1);\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <typeparam name="A2"></typeparam>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- public delegate void Act<A1, A2>(A1 x1, A2 x2);\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <typeparam name="A2"></typeparam>\r
- /// <typeparam name="A3"></typeparam>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- /// <param name="x3"></param>\r
- public delegate void Act<A1, A2, A3>(A1 x1, A2 x2, A3 x3);\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <typeparam name="A2"></typeparam>\r
- /// <typeparam name="A3"></typeparam>\r
- /// <typeparam name="A4"></typeparam>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- /// <param name="x3"></param>\r
- /// <param name="x4"></param>\r
- public delegate void Act<A1, A2, A3, A4>(A1 x1, A2 x2, A3 x3, A4 x4);\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="R"></typeparam>\r
- /// <returns></returns>\r
- public delegate R Fun<R>();\r
- /// <summary>\r
- /// Delegate type Fun[A1,R] is the type of functions (methods) from A1\r
- /// to R, used to compute some transformation for a given collection\r
- /// item. \r
- /// <para>\r
- /// The type Fun[T,U] corresponds to System.Converter[T,U] in the .Net\r
- /// Framework class library, and the type Fun[T,bool] corresponds\r
- /// System.Predicate[T] in the .Net Framework class library.</para>\r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <typeparam name="R"></typeparam>\r
- /// <param name="x1"></param>\r
- /// <returns></returns>\r
- public delegate R Fun<A1, R>(A1 x1);\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <typeparam name="A2"></typeparam>\r
- /// <typeparam name="R"></typeparam>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- /// <returns></returns>\r
- public delegate R Fun<A1, A2, R>(A1 x1, A2 x2);\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <typeparam name="A2"></typeparam>\r
- /// <typeparam name="A3"></typeparam>\r
- /// <typeparam name="R"></typeparam>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- /// <param name="x3"></param>\r
- /// <returns></returns>\r
- public delegate R Fun<A1, A2, A3, R>(A1 x1, A2 x2, A3 x3);\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="A1"></typeparam>\r
- /// <typeparam name="A2"></typeparam>\r
- /// <typeparam name="A3"></typeparam>\r
- /// <typeparam name="A4"></typeparam>\r
- /// <typeparam name="R"></typeparam>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- /// <param name="x3"></param>\r
- /// <param name="x4"></param>\r
- /// <returns></returns>\r
- public delegate R Fun<A1, A2, A3, A4, R>(A1 x1, A2 x2, A3 x3, A4 x4);\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// An entry in a dictionary from K to V.\r
- /// </summary>\r
- [Serializable]\r
- public struct KeyValuePair<K, V> : IEquatable<KeyValuePair<K, V>>, IShowable\r
- {\r
- /// <summary>\r
- /// The key field of the entry\r
- /// </summary>\r
- public K Key;\r
-\r
- /// <summary>\r
- /// The value field of the entry\r
- /// </summary>\r
- public V Value;\r
-\r
- /// <summary>\r
- /// Create an entry with specified key and value\r
- /// </summary>\r
- /// <param name="key">The key</param>\r
- /// <param name="value">The value</param>\r
- public KeyValuePair(K key, V value) { Key = key; Value = value; }\r
-\r
-\r
- /// <summary>\r
- /// Create an entry with a specified key. The value will be the default value of type <code>V</code>.\r
- /// </summary>\r
- /// <param name="key">The key</param>\r
- public KeyValuePair(K key) { Key = key; Value = default(V); }\r
-\r
-\r
- /// <summary>\r
- /// Pretty print an entry\r
- /// </summary>\r
- /// <returns>(key, value)</returns>\r
- [Tested]\r
- public override string ToString() { return "(" + Key + ", " + Value + ")"; }\r
-\r
-\r
- /// <summary>\r
- /// Check equality of entries. \r
- /// </summary>\r
- /// <param name="obj">The other object</param>\r
- /// <returns>True if obj is an entry of the same type and has the same key and value</returns>\r
- [Tested]\r
- public override bool Equals(object obj)\r
- {\r
- if (!(obj is KeyValuePair<K, V>))\r
- return false;\r
- KeyValuePair<K, V> other = (KeyValuePair<K, V>)obj;\r
- return Equals(other);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get the hash code of the pair.\r
- /// </summary>\r
- /// <returns>The hash code</returns>\r
- [Tested]\r
- public override int GetHashCode() { return EqualityComparer<K>.Default.GetHashCode(Key) + 13984681 * EqualityComparer<V>.Default.GetHashCode(Value); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="other"></param>\r
- /// <returns></returns>\r
- public bool Equals(KeyValuePair<K, V> other)\r
- {\r
- return EqualityComparer<K>.Default.Equals(Key, other.Key) && EqualityComparer<V>.Default.Equals(Value, other.Value);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="pair1"></param>\r
- /// <param name="pair2"></param>\r
- /// <returns></returns>\r
- public static bool operator ==(KeyValuePair<K, V> pair1, KeyValuePair<K, V> pair2) { return pair1.Equals(pair2); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="pair1"></param>\r
- /// <param name="pair2"></param>\r
- /// <returns></returns>\r
- public static bool operator !=(KeyValuePair<K, V> pair1, KeyValuePair<K, V> pair2) { return !pair1.Equals(pair2); }\r
-\r
- #region IShowable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <param name="rest"></param>\r
- /// <returns></returns>\r
- public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- if (rest < 0)\r
- return false;\r
- if (!Showing.Show(Key, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- stringbuilder.Append(" => ");\r
- rest -= 4;\r
- if (!Showing.Show(Value, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- return rest >= 0;\r
- }\r
- #endregion\r
-\r
- #region IFormattable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public string ToString(string format, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowString(this, format, formatProvider);\r
- }\r
-\r
- #endregion\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// Default comparer for dictionary entries in a sorted dictionary.\r
- /// Entry comparisons only look at keys and uses an externally defined comparer for that.\r
- /// </summary>\r
- [Serializable]\r
- public class KeyValuePairComparer<K, V> : SCG.IComparer<KeyValuePair<K, V>>\r
- {\r
- SCG.IComparer<K> comparer;\r
-\r
-\r
- /// <summary>\r
- /// Create an entry comparer for a item comparer of the keys\r
- /// </summary>\r
- /// <param name="comparer">Comparer of keys</param>\r
- public KeyValuePairComparer(SCG.IComparer<K> comparer)\r
- {\r
- if (comparer == null)\r
- throw new NullReferenceException();\r
- this.comparer = comparer;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Compare two entries\r
- /// </summary>\r
- /// <param name="entry1">First entry</param>\r
- /// <param name="entry2">Second entry</param>\r
- /// <returns>The result of comparing the keys</returns>\r
- [Tested]\r
- public int Compare(KeyValuePair<K, V> entry1, KeyValuePair<K, V> entry2)\r
- { return comparer.Compare(entry1.Key, entry2.Key); }\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// Default equalityComparer for dictionary entries.\r
- /// Operations only look at keys and uses an externaly defined equalityComparer for that.\r
- /// </summary>\r
- [Serializable]\r
- public sealed class KeyValuePairEqualityComparer<K, V> : SCG.IEqualityComparer<KeyValuePair<K, V>>\r
- {\r
- SCG.IEqualityComparer<K> keyequalityComparer;\r
-\r
-\r
- /// <summary>\r
- /// Create an entry equalityComparer using the default equalityComparer for keys\r
- /// </summary>\r
- public KeyValuePairEqualityComparer() { keyequalityComparer = EqualityComparer<K>.Default; }\r
-\r
-\r
- /// <summary>\r
- /// Create an entry equalityComparer from a specified item equalityComparer for the keys\r
- /// </summary>\r
- /// <param name="keyequalityComparer">The key equalityComparer</param>\r
- public KeyValuePairEqualityComparer(SCG.IEqualityComparer<K> keyequalityComparer)\r
- {\r
- if (keyequalityComparer == null)\r
- throw new NullReferenceException("Key equality comparer cannot be null");\r
- this.keyequalityComparer = keyequalityComparer;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get the hash code of the entry\r
- /// </summary>\r
- /// <param name="entry">The entry</param>\r
- /// <returns>The hash code of the key</returns>\r
- [Tested]\r
- public int GetHashCode(KeyValuePair<K, V> entry) { return keyequalityComparer.GetHashCode(entry.Key); }\r
-\r
-\r
- /// <summary>\r
- /// Test two entries for equality\r
- /// </summary>\r
- /// <param name="entry1">First entry</param>\r
- /// <param name="entry2">Second entry</param>\r
- /// <returns>True if keys are equal</returns>\r
- [Tested]\r
- public bool Equals(KeyValuePair<K, V> entry1, KeyValuePair<K, V> entry2)\r
- { return keyequalityComparer.Equals(entry1.Key, entry2.Key); }\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A base class for implementing a dictionary based on a set collection implementation.\r
- /// <i>See the source code for <see cref="T:C5.HashDictionary`2"/> for an example</i>\r
- /// \r
- /// </summary>\r
- [Serializable]\r
- public abstract class DictionaryBase<K, V> : CollectionValueBase<KeyValuePair<K, V>>, IDictionary<K, V>\r
- {\r
- /// <summary>\r
- /// The set collection of entries underlying this dictionary implementation\r
- /// </summary>\r
- protected ICollection<KeyValuePair<K, V>> pairs;\r
-\r
- SCG.IEqualityComparer<K> keyequalityComparer;\r
-\r
- #region Events\r
- ProxyEventBlock<KeyValuePair<K, V>> eventBlock;\r
-\r
- /// <summary>\r
- /// The change event. Will be raised for every change operation on the collection.\r
- /// </summary>\r
- public override event CollectionChangedHandler<KeyValuePair<K, V>> CollectionChanged\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<KeyValuePair<K, V>>(this, pairs))).CollectionChanged += value; }\r
- remove { if (eventBlock != null) eventBlock.CollectionChanged -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The change event. Will be raised for every change operation on the collection.\r
- /// </summary>\r
- public override event CollectionClearedHandler<KeyValuePair<K, V>> CollectionCleared\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<KeyValuePair<K, V>>(this, pairs))).CollectionCleared += value; }\r
- remove { if (eventBlock != null) eventBlock.CollectionCleared -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The item added event. Will be raised for every individual addition to the collection.\r
- /// </summary>\r
- public override event ItemsAddedHandler<KeyValuePair<K, V>> ItemsAdded\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<KeyValuePair<K, V>>(this, pairs))).ItemsAdded += value; }\r
- remove { if (eventBlock != null) eventBlock.ItemsAdded -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The item added event. Will be raised for every individual removal from the collection.\r
- /// </summary>\r
- public override event ItemsRemovedHandler<KeyValuePair<K, V>> ItemsRemoved\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<KeyValuePair<K, V>>(this, pairs))).ItemsRemoved += value; }\r
- remove { if (eventBlock != null) eventBlock.ItemsRemoved -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public override EventTypeEnum ListenableEvents\r
- {\r
- get\r
- {\r
- return EventTypeEnum.Basic;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public override EventTypeEnum ActiveEvents\r
- {\r
- get\r
- {\r
- return pairs.ActiveEvents;\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="keyequalityComparer"></param>\r
- public DictionaryBase(SCG.IEqualityComparer<K> keyequalityComparer) {\r
- if (keyequalityComparer == null)\r
- throw new NullReferenceException("Key equality comparer cannot be null");\r
- this.keyequalityComparer = keyequalityComparer; }\r
-\r
- #region IDictionary<K,V> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual SCG.IEqualityComparer<K> EqualityComparer { get { return keyequalityComparer; } }\r
-\r
-\r
- /// <summary>\r
- /// Add a new (key, value) pair (a mapping) to the dictionary.\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException"> if there already is an entry with the same key. </exception>\r
- /// <param name="key">Key to add</param>\r
- /// <param name="value">Value to add</param>\r
- [Tested]\r
- public virtual void Add(K key, V value)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key, value);\r
-\r
- if (!pairs.Add(p))\r
- throw new DuplicateNotAllowedException("Key being added: '" + key + "'");\r
- }\r
-\r
- /// <summary>\r
- /// Add the entries from a collection of <see cref="T:C5.KeyValuePair`2"/> pairs to this dictionary.\r
- /// <para><b>TODO: add restrictions L:K and W:V when the .Net SDK allows it </b></para>\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException"> \r
- /// If the input contains duplicate keys or a key already present in this dictionary.</exception>\r
- /// <param name="entries"></param>\r
- public virtual void AddAll<L,W>(SCG.IEnumerable<KeyValuePair<L, W>> entries)\r
- where L : K\r
- where W : V\r
- {\r
- foreach (KeyValuePair<L, W> pair in entries)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(pair.Key, pair.Value);\r
- if (!pairs.Add(p))\r
- throw new DuplicateNotAllowedException("Key being added: '" + pair.Key + "'");\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Remove an entry with a given key from the dictionary\r
- /// </summary>\r
- /// <param name="key">The key of the entry to remove</param>\r
- /// <returns>True if an entry was found (and removed)</returns>\r
- [Tested]\r
- public virtual bool Remove(K key)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- return pairs.Remove(p);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove an entry with a given key from the dictionary and report its value.\r
- /// </summary>\r
- /// <param name="key">The key of the entry to remove</param>\r
- /// <param name="value">On exit, the value of the removed entry</param>\r
- /// <returns>True if an entry was found (and removed)</returns>\r
- [Tested]\r
- public virtual bool Remove(K key, out V value)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- if (pairs.Remove(p, out p))\r
- {\r
- value = p.Value;\r
- return true;\r
- }\r
- else\r
- {\r
- value = default(V);\r
- return false;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all entries from the dictionary\r
- /// </summary>\r
- [Tested]\r
- public virtual void Clear() { pairs.Clear(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual Speed ContainsSpeed { get { return pairs.ContainsSpeed; } }\r
-\r
- /// <summary>\r
- /// Check if there is an entry with a specified key\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <returns>True if key was found</returns>\r
- [Tested]\r
- public virtual bool Contains(K key)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- return pairs.Contains(p);\r
- }\r
-\r
- class LiftedEnumerable<H> : SCG.IEnumerable<KeyValuePair<K, V>> where H : K\r
- {\r
- SCG.IEnumerable<H> keys;\r
- public LiftedEnumerable(SCG.IEnumerable<H> keys) { this.keys = keys; }\r
- public SCG.IEnumerator<KeyValuePair<K, V>> GetEnumerator() { foreach (H key in keys) yield return new KeyValuePair<K, V>(key); }\r
-\r
- #region IEnumerable Members\r
-\r
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
-\r
- #endregion\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="keys"></param>\r
- /// <returns></returns>\r
- public virtual bool ContainsAll<H>(SCG.IEnumerable<H> keys) where H : K\r
- {\r
- return pairs.ContainsAll(new LiftedEnumerable<H>(keys));\r
- }\r
-\r
- /// <summary>\r
- /// Check if there is an entry with a specified key and report the corresponding\r
- /// value if found. This can be seen as a safe form of "val = this[key]".\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="value">On exit, the value of the entry</param>\r
- /// <returns>True if key was found</returns>\r
- [Tested]\r
- public virtual bool Find(K key, out V value)\r
- {\r
- return Find(ref key, out value);\r
- }\r
- /// <summary>\r
- /// Check if there is an entry with a specified key and report the corresponding\r
- /// value if found. This can be seen as a safe form of "val = this[key]".\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="value">On exit, the value of the entry</param>\r
- /// <returns>True if key was found</returns>\r
- public virtual bool Find(ref K key, out V value)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- if (pairs.Find(ref p))\r
- {\r
- key = p.Key;\r
- value = p.Value;\r
- return true;\r
- }\r
- else\r
- {\r
- value = default(V);\r
- return false;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Look for a specific key in the dictionary and if found replace the value with a new one.\r
- /// This can be seen as a non-adding version of "this[key] = val".\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="value">The new value</param>\r
- /// <returns>True if key was found</returns>\r
- [Tested]\r
- public virtual bool Update(K key, V value)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key, value);\r
-\r
- return pairs.Update(p);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="key"></param>\r
- /// <param name="value"></param>\r
- /// <param name="oldvalue"></param>\r
- /// <returns></returns>\r
- public virtual bool Update(K key, V value, out V oldvalue)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key, value);\r
-\r
- bool retval = pairs.Update(p, out p);\r
- oldvalue = p.Value;\r
- return retval;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Look for a specific key in the dictionary. If found, report the corresponding value,\r
- /// else add an entry with the key and the supplied value.\r
- /// </summary>\r
- /// <param name="key">On entry the key to look for</param>\r
- /// <param name="value">On entry the value to add if the key is not found.\r
- /// On exit the value found if any.</param>\r
- /// <returns>True if key was found</returns>\r
- [Tested]\r
- public virtual bool FindOrAdd(K key, ref V value)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key, value);\r
-\r
- if (!pairs.FindOrAdd(ref p))\r
- return false;\r
- else\r
- {\r
- value = p.Value;\r
- //key = p.key;\r
- return true;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Update value in dictionary corresponding to key if found, else add new entry.\r
- /// More general than "this[key] = val;" by reporting if key was found.\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="value">The value to add or replace with.</param>\r
- /// <returns>True if entry was updated.</returns>\r
- [Tested]\r
- public virtual bool UpdateOrAdd(K key, V value)\r
- {\r
- return pairs.UpdateOrAdd(new KeyValuePair<K, V>(key, value));\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Update value in dictionary corresponding to key if found, else add new entry.\r
- /// More general than "this[key] = val;" by reporting if key was found and the old value if any.\r
- /// </summary>\r
- /// <param name="key"></param>\r
- /// <param name="value"></param>\r
- /// <param name="oldvalue"></param>\r
- /// <returns></returns>\r
- public virtual bool UpdateOrAdd(K key, V value, out V oldvalue)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key, value);\r
- bool retval = pairs.UpdateOrAdd(p, out p);\r
- oldvalue = p.Value;\r
- return retval;\r
- }\r
-\r
-\r
-\r
- #region Keys,Values support classes\r
-\r
- internal class ValuesCollection : CollectionValueBase<V>, ICollectionValue<V>\r
- {\r
- ICollection<KeyValuePair<K, V>> pairs;\r
-\r
-\r
- internal ValuesCollection(ICollection<KeyValuePair<K, V>> pairs)\r
- { this.pairs = pairs; }\r
-\r
-\r
- public override V Choose() { return pairs.Choose().Value; }\r
-\r
- [Tested]\r
- public override SCG.IEnumerator<V> GetEnumerator()\r
- {\r
- //Updatecheck is performed by the pairs enumerator\r
- foreach (KeyValuePair<K, V> p in pairs)\r
- yield return p.Value;\r
- }\r
-\r
- public override bool IsEmpty { get { return pairs.IsEmpty; } }\r
-\r
- [Tested]\r
- public override int Count { [Tested]get { return pairs.Count; } }\r
-\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
- }\r
-\r
-\r
-\r
- internal class KeysCollection : CollectionValueBase<K>, ICollectionValue<K>\r
- {\r
- ICollection<KeyValuePair<K, V>> pairs;\r
-\r
-\r
- internal KeysCollection(ICollection<KeyValuePair<K, V>> pairs)\r
- { this.pairs = pairs; }\r
-\r
- public override K Choose() { return pairs.Choose().Key; }\r
-\r
- [Tested]\r
- public override SCG.IEnumerator<K> GetEnumerator()\r
- {\r
- foreach (KeyValuePair<K, V> p in pairs)\r
- yield return p.Key;\r
- }\r
-\r
- public override bool IsEmpty { get { return pairs.IsEmpty; } }\r
-\r
- [Tested]\r
- public override int Count { [Tested]get { return pairs.Count; } }\r
-\r
- public override Speed CountSpeed { get { return pairs.CountSpeed; } }\r
- }\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>A collection containg the all the keys of the dictionary</value>\r
- [Tested]\r
- public virtual ICollectionValue<K> Keys { [Tested]get { return new KeysCollection(pairs); } }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>A collection containing all the values of the dictionary</value>\r
- [Tested]\r
- public virtual ICollectionValue<V> Values { [Tested]get { return new ValuesCollection(pairs); } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public virtual Fun<K, V> Fun { get { return delegate(K k) { return this[k]; }; } }\r
-\r
- /// <summary>\r
- /// Indexer by key for dictionary. \r
- /// <para>The get method will throw an exception if no entry is found. </para>\r
- /// <para>The set method behaves like <see cref="M:C5.DictionaryBase`2.UpdateOrAdd(`0,`1)"/>.</para>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> On get if no entry is found. </exception>\r
- /// <value>The value corresponding to the key</value>\r
- [Tested]\r
- public virtual V this[K key]\r
- {\r
- [Tested]\r
- get\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- if (pairs.Find(ref p))\r
- return p.Value;\r
- else\r
- throw new NoSuchItemException("Key '" + key.ToString() + "' not present in Dictionary");\r
- }\r
- [Tested]\r
- set\r
- { pairs.UpdateOrAdd(new KeyValuePair<K, V>(key, value)); }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if dictionary is read only</value>\r
- [Tested]\r
- public virtual bool IsReadOnly { [Tested]get { return pairs.IsReadOnly; } }\r
-\r
-\r
- /// <summary>\r
- /// Check the integrity of the internal data structures of this dictionary.\r
- /// </summary>\r
- /// <returns>True if check does not fail.</returns>\r
- [Tested]\r
- public virtual bool Check() { return pairs.Check(); }\r
-\r
- #endregion\r
-\r
- #region ICollectionValue<KeyValuePair<K,V>> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if this collection is empty.</value>\r
- public override bool IsEmpty { get { return pairs.IsEmpty; } }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of entrues in the dictionary</value>\r
- [Tested]\r
- public override int Count { [Tested]get { return pairs.Count; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of entrues in the dictionary</value>\r
- [Tested]\r
- public override Speed CountSpeed { [Tested]get { return pairs.CountSpeed; } }\r
-\r
- /// <summary>\r
- /// Choose some entry in this Dictionary. \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- public override KeyValuePair<K, V> Choose() { return pairs.Choose(); }\r
-\r
- /// <summary>\r
- /// Create an enumerator for the collection of entries of the dictionary\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<KeyValuePair<K, V>> GetEnumerator()\r
- {\r
- return pairs.GetEnumerator(); ;\r
- }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public override bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowDictionary<K, V>(this, stringbuilder, ref rest, formatProvider);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public abstract object Clone();\r
-\r
- }\r
-\r
- /// <summary>\r
- /// A base class for implementing a sorted dictionary based on a sorted set collection implementation.\r
- /// <i>See the source code for <see cref="T:C5.TreeDictionary`2"/> for an example</i>\r
- /// \r
- /// </summary>\r
- public abstract class SortedDictionaryBase<K, V> : DictionaryBase<K, V>, ISortedDictionary<K, V>\r
- {\r
- #region Fields\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- protected ISorted<KeyValuePair<K, V>> sortedpairs;\r
- SCG.IComparer<K> keycomparer;\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="keycomparer"></param>\r
- /// <param name="keyequalityComparer"></param>\r
- public SortedDictionaryBase(SCG.IComparer<K> keycomparer, SCG.IEqualityComparer<K> keyequalityComparer) : base(keyequalityComparer) { this.keycomparer = keycomparer; }\r
-\r
- #endregion\r
-\r
- #region ISortedDictionary<K,V> Members\r
-\r
- /// <summary>\r
- /// The key comparer used by this dictionary.\r
- /// </summary>\r
- /// <value></value>\r
- public SCG.IComparer<K> Comparer { get { return keycomparer; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public new ISorted<K> Keys { get { return new SortedKeysCollection(this, sortedpairs, keycomparer, EqualityComparer); } }\r
-\r
- /// <summary>\r
- /// Get the entry in the dictionary whose key is the\r
- /// predecessor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"></exception>\r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- [Tested]\r
- public KeyValuePair<K, V> Predecessor(K key)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- return sortedpairs.Predecessor(p);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get the entry in the dictionary whose key is the\r
- /// weak predecessor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"></exception>\r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- [Tested]\r
- public KeyValuePair<K, V> WeakPredecessor(K key)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- return sortedpairs.WeakPredecessor(p);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get the entry in the dictionary whose key is the\r
- /// successor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"></exception>\r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- [Tested]\r
- public KeyValuePair<K, V> Successor(K key)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(key);\r
-\r
- return sortedpairs.Successor(p);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get the entry in the dictionary whose key is the\r
- /// weak successor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"></exception>\r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- [Tested]\r
- public KeyValuePair<K, V> WeakSuccessor(K key)\r
- {\r
- return sortedpairs.WeakSuccessor(new KeyValuePair<K, V>(key));\r
- }\r
-\r
- #endregion\r
-\r
- #region ISortedDictionary<K,V> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> FindMin()\r
- {\r
- return sortedpairs.FindMin();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> DeleteMin()\r
- {\r
- return sortedpairs.DeleteMin();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> FindMax()\r
- {\r
- return sortedpairs.FindMax();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> DeleteMax()\r
- {\r
- return sortedpairs.DeleteMax();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="cutter"></param>\r
- /// <param name="lowEntry"></param>\r
- /// <param name="lowIsValid"></param>\r
- /// <param name="highEntry"></param>\r
- /// <param name="highIsValid"></param>\r
- /// <returns></returns>\r
- public bool Cut(IComparable<K> cutter, out KeyValuePair<K, V> lowEntry, out bool lowIsValid, out KeyValuePair<K, V> highEntry, out bool highIsValid)\r
- {\r
- return sortedpairs.Cut(new KeyValuePairComparable(cutter), out lowEntry, out lowIsValid, out highEntry, out highIsValid);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<KeyValuePair<K, V>> RangeFrom(K bot)\r
- {\r
- return sortedpairs.RangeFrom(new KeyValuePair<K, V>(bot));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<KeyValuePair<K, V>> RangeFromTo(K bot, K top)\r
- {\r
- return sortedpairs.RangeFromTo(new KeyValuePair<K, V>(bot), new KeyValuePair<K, V>(top));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<KeyValuePair<K, V>> RangeTo(K top)\r
- {\r
- return sortedpairs.RangeTo(new KeyValuePair<K, V>(top));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public IDirectedCollectionValue<KeyValuePair<K, V>> RangeAll()\r
- {\r
- return sortedpairs.RangeAll();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="items"></param>\r
- public void AddSorted(SCG.IEnumerable<KeyValuePair<K, V>> items)\r
- {\r
- sortedpairs.AddSorted(items);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="lowKey"></param>\r
- public void RemoveRangeFrom(K lowKey)\r
- {\r
- sortedpairs.RemoveRangeFrom(new KeyValuePair<K, V>(lowKey));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="lowKey"></param>\r
- /// <param name="highKey"></param>\r
- public void RemoveRangeFromTo(K lowKey, K highKey)\r
- {\r
- sortedpairs.RemoveRangeFromTo(new KeyValuePair<K, V>(lowKey), new KeyValuePair<K, V>(highKey));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="highKey"></param>\r
- public void RemoveRangeTo(K highKey)\r
- {\r
- sortedpairs.RemoveRangeTo(new KeyValuePair<K, V>(highKey));\r
- }\r
-\r
- #endregion\r
-\r
- class KeyValuePairComparable : IComparable<KeyValuePair<K, V>>\r
- {\r
- IComparable<K> cutter;\r
-\r
- internal KeyValuePairComparable(IComparable<K> cutter) { this.cutter = cutter; }\r
-\r
- public int CompareTo(KeyValuePair<K, V> other) { return cutter.CompareTo(other.Key); }\r
-\r
- public bool Equals(KeyValuePair<K, V> other) { return cutter.Equals(other.Key); }\r
- }\r
-\r
- class ProjectedDirectedEnumerable : MappedDirectedEnumerable<KeyValuePair<K, V>, K>\r
- {\r
- public ProjectedDirectedEnumerable(IDirectedEnumerable<KeyValuePair<K, V>> directedpairs) : base(directedpairs) { }\r
-\r
- public override K Map(KeyValuePair<K, V> pair) { return pair.Key; }\r
-\r
- }\r
-\r
- class ProjectedDirectedCollectionValue : MappedDirectedCollectionValue<KeyValuePair<K, V>, K>\r
- {\r
- public ProjectedDirectedCollectionValue(IDirectedCollectionValue<KeyValuePair<K, V>> directedpairs) : base(directedpairs) { }\r
-\r
- public override K Map(KeyValuePair<K, V> pair) { return pair.Key; }\r
-\r
- }\r
-\r
- class SortedKeysCollection : SequencedBase<K>, ISorted<K>\r
- {\r
- ISortedDictionary<K, V> sorteddict;\r
- //TODO: eliminate this. Only problem is the Find method because we lack method on dictionary that also \r
- // returns the actual key.\r
- ISorted<KeyValuePair<K, V>> sortedpairs;\r
- SCG.IComparer<K> comparer;\r
-\r
- internal SortedKeysCollection(ISortedDictionary<K, V> sorteddict, ISorted<KeyValuePair<K, V>> sortedpairs, SCG.IComparer<K> comparer, SCG.IEqualityComparer<K> itemequalityComparer) \r
- :base(itemequalityComparer)\r
- {\r
- this.sorteddict = sorteddict;\r
- this.sortedpairs = sortedpairs;\r
- this.comparer = comparer;\r
- }\r
-\r
- public override K Choose() { return sorteddict.Choose().Key; }\r
-\r
- public override SCG.IEnumerator<K> GetEnumerator()\r
- {\r
- foreach (KeyValuePair<K, V> p in sorteddict)\r
- yield return p.Key;\r
- }\r
-\r
- public override bool IsEmpty { get { return sorteddict.IsEmpty; } }\r
-\r
- public override int Count { [Tested]get { return sorteddict.Count; } }\r
-\r
- public override Speed CountSpeed { get { return sorteddict.CountSpeed; } }\r
-\r
- #region ISorted<K> Members\r
-\r
- public K FindMin() { return sorteddict.FindMin().Key; }\r
-\r
- public K DeleteMin() { throw new ReadOnlyCollectionException(); }\r
-\r
- public K FindMax() { return sorteddict.FindMax().Key; }\r
-\r
- public K DeleteMax() { throw new ReadOnlyCollectionException(); }\r
-\r
- public SCG.IComparer<K> Comparer { get { return comparer; } }\r
-\r
- public K Predecessor(K item) { return sorteddict.Predecessor(item).Key; }\r
-\r
- public K Successor(K item) { return sorteddict.Successor(item).Key; }\r
-\r
- public K WeakPredecessor(K item) { return sorteddict.WeakPredecessor(item).Key; }\r
-\r
- public K WeakSuccessor(K item) { return sorteddict.WeakSuccessor(item).Key; }\r
-\r
- public bool Cut(IComparable<K> c, out K low, out bool lowIsValid, out K high, out bool highIsValid)\r
- {\r
- KeyValuePair<K, V> lowpair, highpair;\r
- bool retval = sorteddict.Cut(c, out lowpair, out lowIsValid, out highpair, out highIsValid);\r
- low = lowpair.Key;\r
- high = highpair.Key;\r
- return retval;\r
- }\r
-\r
- public IDirectedEnumerable<K> RangeFrom(K bot)\r
- {\r
- return new ProjectedDirectedEnumerable(sorteddict.RangeFrom(bot));\r
- }\r
-\r
- public IDirectedEnumerable<K> RangeFromTo(K bot, K top)\r
- {\r
- return new ProjectedDirectedEnumerable(sorteddict.RangeFromTo(bot, top));\r
- }\r
-\r
- public IDirectedEnumerable<K> RangeTo(K top)\r
- {\r
- return new ProjectedDirectedEnumerable(sorteddict.RangeTo(top));\r
- }\r
-\r
- public IDirectedCollectionValue<K> RangeAll()\r
- {\r
- return new ProjectedDirectedCollectionValue(sorteddict.RangeAll());\r
- }\r
-\r
- public void AddSorted<U>(SCG.IEnumerable<U> items) where U : K { throw new ReadOnlyCollectionException(); }\r
-\r
- public void RemoveRangeFrom(K low) { throw new ReadOnlyCollectionException(); }\r
-\r
- public void RemoveRangeFromTo(K low, K hi) { throw new ReadOnlyCollectionException(); }\r
-\r
- public void RemoveRangeTo(K hi) { throw new ReadOnlyCollectionException(); }\r
- #endregion\r
-\r
- #region ICollection<K> Members\r
- public Speed ContainsSpeed { get { return sorteddict.ContainsSpeed; } }\r
-\r
- public bool Contains(K key) { return sorteddict.Contains(key); ; }\r
-\r
- public int ContainsCount(K item) { return sorteddict.Contains(item) ? 1 : 0; }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<K> UniqueItems()\r
- {\r
- return this;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<K, int>> ItemMultiplicities()\r
- {\r
- return new MultiplicityOne<K>(this);\r
- }\r
-\r
-\r
- public bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : K\r
- {\r
- //TODO: optimize?\r
- foreach (K item in items)\r
- if (!sorteddict.Contains(item))\r
- return false;\r
- return true;\r
- }\r
-\r
- public bool Find(ref K item)\r
- {\r
- KeyValuePair<K, V> p = new KeyValuePair<K, V>(item);\r
- bool retval = sortedpairs.Find(ref p);\r
- item = p.Key;\r
- return retval;\r
- }\r
-\r
- public bool FindOrAdd(ref K item) { throw new ReadOnlyCollectionException(); }\r
-\r
- public bool Update(K item) { throw new ReadOnlyCollectionException(); }\r
-\r
- public bool Update(K item, out K olditem) { throw new ReadOnlyCollectionException(); }\r
-\r
- public bool UpdateOrAdd(K item) { throw new ReadOnlyCollectionException(); }\r
-\r
- public bool UpdateOrAdd(K item, out K olditem) { throw new ReadOnlyCollectionException(); }\r
-\r
- public bool Remove(K item) { throw new ReadOnlyCollectionException(); }\r
-\r
- public bool Remove(K item, out K removeditem) { throw new ReadOnlyCollectionException(); }\r
-\r
- public void RemoveAllCopies(K item) { throw new ReadOnlyCollectionException(); }\r
-\r
- public void RemoveAll<U> (SCG.IEnumerable<U> items) where U : K { throw new ReadOnlyCollectionException(); }\r
-\r
- public void Clear() { throw new ReadOnlyCollectionException(); }\r
-\r
- public void RetainAll<U>(SCG.IEnumerable<U> items) where U : K { throw new ReadOnlyCollectionException(); }\r
-\r
- #endregion\r
-\r
- #region IExtensible<K> Members\r
- public override bool IsReadOnly { get { return true; } }\r
-\r
- public bool AllowsDuplicates { get { return false; } }\r
-\r
- public bool DuplicatesByCounting { get { return true; } }\r
-\r
- public bool Add(K item) { throw new ReadOnlyCollectionException(); }\r
-\r
- public void AddAll(System.Collections.Generic.IEnumerable<K> items) { throw new ReadOnlyCollectionException(); }\r
-\r
- public void AddAll<U>(System.Collections.Generic.IEnumerable<U> items) where U : K { throw new ReadOnlyCollectionException(); }\r
-\r
- public bool Check() { return sorteddict.Check(); }\r
-\r
- #endregion\r
-\r
- #region IDirectedCollectionValue<K> Members\r
-\r
- public override IDirectedCollectionValue<K> Backwards()\r
- {\r
- return RangeAll().Backwards();\r
- }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<K> Members\r
-\r
- IDirectedEnumerable<K> IDirectedEnumerable<K>.Backwards() { return Backwards(); }\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- //TODO: test\r
- /// <summary>\r
- /// Make a shallow copy of this SortedKeysCollection.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- //\r
- SortedArrayDictionary<K, V> dictclone = new SortedArrayDictionary<K, V>(sortedpairs.Count, comparer, EqualityComparer);\r
- SortedArray<KeyValuePair<K, V>> sortedpairsclone = (SortedArray<KeyValuePair<K, V>>)(dictclone.sortedpairs);\r
- foreach (K key in sorteddict.Keys)\r
- {\r
- sortedpairsclone.Add(new KeyValuePair<K, V>(key, default(V)));\r
- }\r
- return new SortedKeysCollection(dictclone, sortedpairsclone, comparer, EqualityComparer);\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public override bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowDictionary<K, V>(this, stringbuilder, ref rest, formatProvider);\r
- }\r
-\r
- }\r
-\r
- class SortedArrayDictionary<K, V> : SortedDictionaryBase<K, V>, IDictionary<K, V>, ISortedDictionary<K, V>\r
- {\r
- #region Constructors\r
-\r
- public SortedArrayDictionary() : this(Comparer<K>.Default, EqualityComparer<K>.Default) { }\r
-\r
- /// <summary>\r
- /// Create a red-black tree dictionary using an external comparer for keys.\r
- /// </summary>\r
- /// <param name="comparer">The external comparer</param>\r
- public SortedArrayDictionary(SCG.IComparer<K> comparer) : this(comparer, new ComparerZeroHashCodeEqualityComparer<K>(comparer)) { }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="comparer"></param>\r
- /// <param name="equalityComparer"></param>\r
- public SortedArrayDictionary(SCG.IComparer<K> comparer, SCG.IEqualityComparer<K> equalityComparer) : base(comparer,equalityComparer)\r
- {\r
- pairs = sortedpairs = new SortedArray<KeyValuePair<K, V>>(new KeyValuePairComparer<K, V>(comparer));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="comparer"></param>\r
- /// <param name="equalityComparer"></param>\r
- /// <param name="capacity"></param>\r
- public SortedArrayDictionary(int capacity, SCG.IComparer<K> comparer, SCG.IEqualityComparer<K> equalityComparer) : base(comparer,equalityComparer)\r
- {\r
- pairs = sortedpairs = new SortedArray<KeyValuePair<K, V>>(capacity, new KeyValuePairComparer<K, V>(comparer));\r
- }\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override object Clone()\r
- {\r
- SortedArrayDictionary<K, V> clone = new SortedArrayDictionary<K, V>(Comparer, EqualityComparer);\r
- clone.sortedpairs.AddSorted(sortedpairs);\r
- return clone;\r
- }\r
-\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
-\r
- /// <summary>\r
- /// The symbolic characterization of the speed of lookups for a collection.\r
- /// The values may refer to worst-case, amortized and/or expected asymtotic \r
- /// complexity wrt. the collection size.\r
- /// </summary>\r
- public enum Speed : short\r
- {\r
- /// <summary>\r
- /// Counting the collection with the <code>Count property</code> may not return\r
- /// (for a synthetic and potentially infinite collection).\r
- /// </summary>\r
- PotentiallyInfinite = 1,\r
- /// <summary>\r
- /// Lookup operations like <code>Contains(T item)</code> or the <code>Count</code>\r
- /// property may take time O(n),\r
- /// where n is the size of the collection.\r
- /// </summary>\r
- Linear = 2,\r
- /// <summary>\r
- /// Lookup operations like <code>Contains(T item)</code> or the <code>Count</code>\r
- /// property takes time O(log n),\r
- /// where n is the size of the collection.\r
- /// </summary>\r
- Log = 3,\r
- /// <summary>\r
- /// Lookup operations like <code>Contains(T item)</code> or the <code>Count</code>\r
- /// property takes time O(1),\r
- /// where n is the size of the collection.\r
- /// </summary>\r
- Constant = 4\r
- }\r
- /*\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public enum ItemEqualityTypeEnum\r
- {\r
- /// <summary>\r
- /// Only an Equals(T,T)\r
- /// </summary>\r
- Equator, \r
- /// <summary>\r
- /// Equals(T,T) and GetHashCode(T)\r
- /// </summary>\r
- HashingEqualityComparer, \r
- /// <summary>\r
- /// Compare(T,T)\r
- /// </summary>\r
- Comparer, \r
- /// <summary>\r
- /// Compatible Compare(T,T) and GetHashCode(T)\r
- /// </summary>\r
- Both\r
- }\r
-*/\r
-\r
- /// <summary>\r
- /// Direction of enumeration order relative to original collection.\r
- /// </summary>\r
- public enum EnumerationDirection\r
- {\r
- /// <summary>\r
- /// Same direction\r
- /// </summary>\r
- Forwards,\r
- /// <summary>\r
- /// Opposite direction\r
- /// </summary>\r
- Backwards\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- [Flags]\r
- public enum EventTypeEnum\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- None = 0x00000000,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- Changed = 0x00000001,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- Cleared = 0x00000002,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- Added = 0x00000004,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- Removed = 0x00000008,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- Basic = 0x0000000f,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- Inserted = 0x00000010,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- RemovedAt = 0x00000020,\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- All = 0x0000003f\r
- }\r
-\r
- /// <summary>\r
- /// Holds the real events for a collection\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- [Serializable]\r
- internal sealed class EventBlock<T>\r
- {\r
- internal EventTypeEnum events;\r
-\r
- event CollectionChangedHandler<T> collectionChanged;\r
- internal event CollectionChangedHandler<T> CollectionChanged\r
- {\r
- add\r
- {\r
- collectionChanged += value;\r
- events |= EventTypeEnum.Changed;\r
- }\r
- remove\r
- {\r
- collectionChanged -= value;\r
- if (collectionChanged == null)\r
- events &= ~EventTypeEnum.Changed;\r
- }\r
- }\r
- internal void raiseCollectionChanged(object sender)\r
- { if (collectionChanged != null) collectionChanged(sender); }\r
-\r
- event CollectionClearedHandler<T> collectionCleared;\r
- internal event CollectionClearedHandler<T> CollectionCleared\r
- {\r
- add\r
- {\r
- collectionCleared += value;\r
- events |= EventTypeEnum.Cleared;\r
- }\r
- remove\r
- {\r
- collectionCleared -= value;\r
- if (collectionCleared == null)\r
- events &= ~EventTypeEnum.Cleared;\r
- }\r
- }\r
- internal void raiseCollectionCleared(object sender, bool full, int count)\r
- { if (collectionCleared != null) collectionCleared(sender, new ClearedEventArgs(full, count)); }\r
- internal void raiseCollectionCleared(object sender, bool full, int count, int? start)\r
- { if (collectionCleared != null) collectionCleared(sender, new ClearedRangeEventArgs(full, count, start)); }\r
-\r
- event ItemsAddedHandler<T> itemsAdded;\r
- internal event ItemsAddedHandler<T> ItemsAdded\r
- {\r
- add\r
- {\r
- itemsAdded += value;\r
- events |= EventTypeEnum.Added;\r
- }\r
- remove\r
- {\r
- itemsAdded -= value;\r
- if (itemsAdded == null)\r
- events &= ~EventTypeEnum.Added;\r
- }\r
- }\r
- internal void raiseItemsAdded(object sender, T item, int count)\r
- { if (itemsAdded != null) itemsAdded(sender, new ItemCountEventArgs<T>(item, count)); }\r
-\r
- event ItemsRemovedHandler<T> itemsRemoved;\r
- internal event ItemsRemovedHandler<T> ItemsRemoved\r
- {\r
- add\r
- {\r
- itemsRemoved += value;\r
- events |= EventTypeEnum.Removed;\r
- }\r
- remove\r
- {\r
- itemsRemoved -= value;\r
- if (itemsRemoved == null)\r
- events &= ~EventTypeEnum.Removed;\r
- }\r
- }\r
- internal void raiseItemsRemoved(object sender, T item, int count)\r
- { if (itemsRemoved != null) itemsRemoved(sender, new ItemCountEventArgs<T>(item, count)); }\r
-\r
- event ItemInsertedHandler<T> itemInserted;\r
- internal event ItemInsertedHandler<T> ItemInserted\r
- {\r
- add\r
- {\r
- itemInserted += value;\r
- events |= EventTypeEnum.Inserted;\r
- }\r
- remove\r
- {\r
- itemInserted -= value;\r
- if (itemInserted == null)\r
- events &= ~EventTypeEnum.Inserted;\r
- }\r
- }\r
- internal void raiseItemInserted(object sender, T item, int index)\r
- { if (itemInserted != null) itemInserted(sender, new ItemAtEventArgs<T>(item, index)); }\r
-\r
- event ItemRemovedAtHandler<T> itemRemovedAt;\r
- internal event ItemRemovedAtHandler<T> ItemRemovedAt\r
- {\r
- add\r
- {\r
- itemRemovedAt += value;\r
- events |= EventTypeEnum.RemovedAt;\r
- }\r
- remove\r
- {\r
- itemRemovedAt -= value;\r
- if (itemRemovedAt == null)\r
- events &= ~EventTypeEnum.RemovedAt;\r
- }\r
- }\r
- internal void raiseItemRemovedAt(object sender, T item, int index)\r
- { if (itemRemovedAt != null) itemRemovedAt(sender, new ItemAtEventArgs<T>(item, index)); }\r
- }\r
-\r
- /// <summary>\r
- /// Tentative, to conserve memory in GuardedCollectionValueBase\r
- /// This should really be nested in Guarded collection value, only have a guardereal field\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- [Serializable]\r
- internal sealed class ProxyEventBlock<T>\r
- {\r
- ICollectionValue<T> proxy, real;\r
-\r
- internal ProxyEventBlock(ICollectionValue<T> proxy, ICollectionValue<T> real)\r
- { this.proxy = proxy; this.real = real; }\r
-\r
- event CollectionChangedHandler<T> collectionChanged;\r
- CollectionChangedHandler<T> collectionChangedProxy;\r
- internal event CollectionChangedHandler<T> CollectionChanged\r
- {\r
- add\r
- {\r
- if (collectionChanged == null)\r
- {\r
- if (collectionChangedProxy == null)\r
- collectionChangedProxy = delegate(object sender) { collectionChanged(proxy); };\r
- real.CollectionChanged += collectionChangedProxy;\r
- }\r
- collectionChanged += value;\r
- }\r
- remove\r
- {\r
- collectionChanged -= value;\r
- if (collectionChanged == null)\r
- real.CollectionChanged -= collectionChangedProxy;\r
- }\r
- }\r
-\r
- event CollectionClearedHandler<T> collectionCleared;\r
- CollectionClearedHandler<T> collectionClearedProxy;\r
- internal event CollectionClearedHandler<T> CollectionCleared\r
- {\r
- add\r
- {\r
- if (collectionCleared == null)\r
- {\r
- if (collectionClearedProxy == null)\r
- collectionClearedProxy = delegate(object sender, ClearedEventArgs e) { collectionCleared(proxy, e); };\r
- real.CollectionCleared += collectionClearedProxy;\r
- }\r
- collectionCleared += value;\r
- }\r
- remove\r
- {\r
- collectionCleared -= value;\r
- if (collectionCleared == null)\r
- real.CollectionCleared -= collectionClearedProxy;\r
- }\r
- }\r
-\r
- event ItemsAddedHandler<T> itemsAdded;\r
- ItemsAddedHandler<T> itemsAddedProxy;\r
- internal event ItemsAddedHandler<T> ItemsAdded\r
- {\r
- add\r
- {\r
- if (itemsAdded == null)\r
- {\r
- if (itemsAddedProxy == null)\r
- itemsAddedProxy = delegate(object sender, ItemCountEventArgs<T> e) { itemsAdded(proxy, e); };\r
- real.ItemsAdded += itemsAddedProxy;\r
- }\r
- itemsAdded += value;\r
- }\r
- remove\r
- {\r
- itemsAdded -= value;\r
- if (itemsAdded == null)\r
- real.ItemsAdded -= itemsAddedProxy;\r
- }\r
- }\r
-\r
- event ItemInsertedHandler<T> itemInserted;\r
- ItemInsertedHandler<T> itemInsertedProxy;\r
- internal event ItemInsertedHandler<T> ItemInserted\r
- {\r
- add\r
- {\r
- if (itemInserted == null)\r
- {\r
- if (itemInsertedProxy == null)\r
- itemInsertedProxy = delegate(object sender, ItemAtEventArgs<T> e) { itemInserted(proxy, e); };\r
- real.ItemInserted += itemInsertedProxy;\r
- }\r
- itemInserted += value;\r
- }\r
- remove\r
- {\r
- itemInserted -= value;\r
- if (itemInserted == null)\r
- real.ItemInserted -= itemInsertedProxy;\r
- }\r
- }\r
-\r
- event ItemsRemovedHandler<T> itemsRemoved;\r
- ItemsRemovedHandler<T> itemsRemovedProxy;\r
- internal event ItemsRemovedHandler<T> ItemsRemoved\r
- {\r
- add\r
- {\r
- if (itemsRemoved == null)\r
- {\r
- if (itemsRemovedProxy == null)\r
- itemsRemovedProxy = delegate(object sender, ItemCountEventArgs<T> e) { itemsRemoved(proxy, e); };\r
- real.ItemsRemoved += itemsRemovedProxy;\r
- }\r
- itemsRemoved += value;\r
- }\r
- remove\r
- {\r
- itemsRemoved -= value;\r
- if (itemsRemoved == null)\r
- real.ItemsRemoved -= itemsRemovedProxy;\r
- }\r
- }\r
-\r
- event ItemRemovedAtHandler<T> itemRemovedAt;\r
- ItemRemovedAtHandler<T> itemRemovedAtProxy;\r
- internal event ItemRemovedAtHandler<T> ItemRemovedAt\r
- {\r
- add\r
- {\r
- if (itemRemovedAt == null)\r
- {\r
- if (itemRemovedAtProxy == null)\r
- itemRemovedAtProxy = delegate(object sender, ItemAtEventArgs<T> e) { itemRemovedAt(proxy, e); };\r
- real.ItemRemovedAt += itemRemovedAtProxy;\r
- }\r
- itemRemovedAt += value;\r
- }\r
- remove\r
- {\r
- itemRemovedAt -= value;\r
- if (itemRemovedAt == null)\r
- real.ItemRemovedAt -= itemRemovedAtProxy;\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class ItemAtEventArgs<T> : EventArgs\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T Item;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly int Index;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="index"></param>\r
- public ItemAtEventArgs(T item, int index) { Item = item; Index = index; }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return String.Format("(ItemAtEventArgs {0} '{1}')", Index, Item);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class ItemCountEventArgs<T> : EventArgs\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T Item;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly int Count;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="count"></param>\r
- /// <param name="item"></param>\r
- public ItemCountEventArgs(T item, int count) { Item = item; Count = count; }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return String.Format("(ItemCountEventArgs {0} '{1}')", Count, Item);\r
- }\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public class ClearedEventArgs : EventArgs\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly bool Full;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly int Count;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// \r
- /// <param name="full">True if the operation cleared all of the collection</param>\r
- /// <param name="count">The number of items removed by the clear.</param>\r
- public ClearedEventArgs(bool full, int count) { Full = full; Count = count; }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return String.Format("(ClearedEventArgs {0} {1})", Count, Full);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public class ClearedRangeEventArgs : ClearedEventArgs\r
- {\r
- //WE could let this be of type int? to allow \r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly int? Start;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="full"></param>\r
- /// <param name="count"></param>\r
- /// <param name="start"></param>\r
- public ClearedRangeEventArgs(bool full, int count, int? start) : base(full,count) { Start = start; }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return String.Format("(ClearedRangeEventArgs {0} {1} {2})", Count, Full, Start);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// The type of event raised after an operation on a collection has changed its contents.\r
- /// Normally, a multioperation like AddAll, \r
- /// <see cref="M:C5.IExtensible`1.AddAll(System.Collections.Generic.IEnumerable{`0})"/> \r
- /// will only fire one CollectionChanged event. Any operation that changes the collection\r
- /// must fire CollectionChanged as its last event.\r
- /// </summary>\r
- public delegate void CollectionChangedHandler<T>(object sender);\r
-\r
- /// <summary>\r
- /// The type of event raised after the Clear() operation on a collection.\r
- /// <para/>\r
- /// Note: The Clear() operation will not fire ItemsRemoved events. \r
- /// </summary>\r
- /// <param name="sender"></param>\r
- /// <param name="eventArgs"></param>\r
- public delegate void CollectionClearedHandler<T>(object sender, ClearedEventArgs eventArgs);\r
-\r
- /// <summary>\r
- /// The type of event raised after an item has been added to a collection.\r
- /// The event will be raised at a point of time, where the collection object is \r
- /// in an internally consistent state and before the corresponding CollectionChanged \r
- /// event is raised.\r
- /// <para/>\r
- /// Note: an Update operation will fire an ItemsRemoved and an ItemsAdded event.\r
- /// <para/>\r
- /// Note: When an item is inserted into a list (<see cref="T:C5.IList`1"/>), both\r
- /// ItemInserted and ItemsAdded events will be fired.\r
- /// </summary>\r
- /// <param name="sender"></param>\r
- /// <param name="eventArgs">An object with the item that was added</param>\r
- public delegate void ItemsAddedHandler<T>(object sender, ItemCountEventArgs<T> eventArgs);\r
-\r
- /// <summary>\r
- /// The type of event raised after an item has been removed from a collection.\r
- /// The event will be raised at a point of time, where the collection object is \r
- /// in an internally consistent state and before the corresponding CollectionChanged \r
- /// event is raised.\r
- /// <para/>\r
- /// Note: The Clear() operation will not fire ItemsRemoved events. \r
- /// <para/>\r
- /// Note: an Update operation will fire an ItemsRemoved and an ItemsAdded event.\r
- /// <para/>\r
- /// Note: When an item is removed from a list by the RemoveAt operation, both an \r
- /// ItemsRemoved and an ItemRemovedAt event will be fired.\r
- /// </summary>\r
- /// <param name="sender"></param>\r
- /// <param name="eventArgs">An object with the item that was removed</param>\r
- public delegate void ItemsRemovedHandler<T>(object sender, ItemCountEventArgs<T> eventArgs);\r
-\r
- /// <summary>\r
- /// The type of event raised after an item has been inserted into a list by an Insert, \r
- /// InsertFirst or InsertLast operation.\r
- /// The event will be raised at a point of time, where the collection object is \r
- /// in an internally consistent state and before the corresponding CollectionChanged \r
- /// event is raised.\r
- /// <para/>\r
- /// Note: an ItemsAdded event will also be fired.\r
- /// </summary>\r
- /// <param name="sender"></param>\r
- /// <param name="eventArgs"></param>\r
- public delegate void ItemInsertedHandler<T>(object sender, ItemAtEventArgs<T> eventArgs);\r
-\r
- /// <summary>\r
- /// The type of event raised after an item has been removed from a list by a RemoveAt(int i)\r
- /// operation (or RemoveFirst(), RemoveLast(), Remove() operation).\r
- /// The event will be raised at a point of time, where the collection object is \r
- /// in an internally consistent state and before the corresponding CollectionChanged \r
- /// event is raised.\r
- /// <para/>\r
- /// Note: an ItemRemoved event will also be fired.\r
- /// </summary>\r
- /// <param name="sender"></param>\r
- /// <param name="eventArgs"></param>\r
- public delegate void ItemRemovedAtHandler<T>(object sender, ItemAtEventArgs<T> eventArgs);\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// An exception to throw from library code when an internal inconsistency is encountered.\r
- /// </summary>\r
- public class InternalException : Exception\r
- {\r
- internal InternalException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An exception thrown by an update operation on a Read-Only collection or dictionary.\r
- /// <para>This exception will be thrown unconditionally when an update operation \r
- /// (method or set property) is called. No check is made to see if the update operation, \r
- /// if allowed, would actually change the collection. </para>\r
- /// </summary>\r
- [Serializable]\r
- public class ReadOnlyCollectionException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public ReadOnlyCollectionException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public ReadOnlyCollectionException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- [Serializable]\r
- public class FixedSizeCollectionException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public FixedSizeCollectionException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public FixedSizeCollectionException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- [Serializable]\r
- public class UnlistenableEventException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public UnlistenableEventException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public UnlistenableEventException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An exception thrown by enumerators, range views etc. when accessed after \r
- /// the underlying collection has been modified.\r
- /// </summary>\r
- [Serializable]\r
- public class CollectionModifiedException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public CollectionModifiedException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public CollectionModifiedException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An excption thrown when trying to access a view (a list view on a <see cref="T:C5.IList`1"/> or \r
- /// a snapshot on a <see cref="T:C5.IPersistentSorted`1"/>)\r
- /// that has been invalidated by some earlier operation.\r
- /// <para>\r
- /// The typical scenario is a view on a list that hash been invalidated by a call to \r
- /// Sort, Reverse or Shuffle on some other, overlapping view or the whole list.\r
- /// </para>\r
- /// </summary>\r
- [Serializable]\r
- public class ViewDisposedException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public ViewDisposedException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public ViewDisposedException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An exception thrown by a lookup or lookup with update operation that does not \r
- /// find the lookup item and has no other means to communicate failure.\r
- /// <para>The typical scenario is a lookup by key in a dictionary with an indexer,\r
- /// see e.g. <see cref="P:C5.IDictionary`2.Item(`0)"/></para>\r
- /// </summary>\r
- [Serializable]\r
- public class NoSuchItemException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public NoSuchItemException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public NoSuchItemException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An exception thrown by an operation on a list (<see cref="T:C5.IList`1"/>)\r
- /// that only makes sense for a view, not for an underlying list.\r
- /// </summary>\r
- [Serializable]\r
- public class NotAViewException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public NotAViewException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public NotAViewException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An exception thrown when an operation attempts to create a duplicate in a collection with set semantics \r
- /// (<see cref="P:C5.IExtensible`1.AllowsDuplicates"/> is false) or attempts to create a duplicate key in a dictionary.\r
- /// <para>With collections this can only happen with Insert operations on lists, since the Add operations will\r
- /// not try to create duplictes and either ignore the failure or report it in a bool return value.\r
- /// </para>\r
- /// <para>With dictionaries this can happen with the <see cref="M:C5.IDictionary`2.Add(`0,`1)"/> metod.</para>\r
- /// </summary>\r
- [Serializable]\r
- public class DuplicateNotAllowedException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public DuplicateNotAllowedException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public DuplicateNotAllowedException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- [Serializable]\r
- public class InvalidPriorityQueueHandleException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public InvalidPriorityQueueHandleException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public InvalidPriorityQueueHandleException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An exception thrown by an operation that need to construct a natural\r
- /// comparer for a type.\r
- /// </summary>\r
- [Serializable]\r
- public class NotComparableException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public NotComparableException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public NotComparableException(string message) : base(message) { }\r
- }\r
-\r
- /// <summary>\r
- /// An exception thrown by operations on a list that expects an argument\r
- /// that is a view on the same underlying list.\r
- /// </summary>\r
- [Serializable]\r
- public class IncompatibleViewException : Exception\r
- {\r
- /// <summary>\r
- /// Create a simple exception with no further explanation.\r
- /// </summary>\r
- public IncompatibleViewException() : base() { }\r
- /// <summary>\r
- /// Create the exception with an explanation of the reason.\r
- /// </summary>\r
- /// <param name="message"></param>\r
- public IncompatibleViewException(string message) : base(message) { }\r
- }\r
-\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using C5;\r
-using System;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Diagnostics;\r
-using System.Text;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// <i>(Describe usage of "L:300" format string.)</i>\r
- /// </summary>\r
- public interface IShowable : IFormattable\r
- {\r
- //TODO: wonder if we should use TextWriters instead of StringBuilders?\r
- /// <summary>\r
- /// Format <code>this</code> using at most approximately <code>rest</code> chars and \r
- /// append the result, possibly truncated, to stringbuilder.\r
- /// Subtract the actual number of used chars from <code>rest</code>.\r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns>True if the appended formatted string was complete (not truncated).</returns>\r
- bool Show(StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider);\r
- }\r
- // ------------------------------------------------------------\r
-\r
- // Static helper methods for Showing collections \r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public static class Showing\r
- {\r
- /// <summary>\r
- /// Show <code>Object obj</code> by appending it to <code>stringbuilder</code>\r
- /// </summary>\r
- /// <param name="obj"></param>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns>True if <code>obj</code> was shown completely.</returns>\r
- public static bool Show(Object obj, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- if (rest <= 0)\r
- return false;\r
- else if (obj is IShowable)\r
- return ((IShowable)obj).Show(stringbuilder, ref rest, formatProvider);\r
- int oldLength = stringbuilder.Length;\r
- stringbuilder.AppendFormat(formatProvider, "{0}", obj);\r
- rest -= (stringbuilder.Length - oldLength);\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="showable"></param>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public static String ShowString(IShowable showable, String format, IFormatProvider formatProvider)\r
- {\r
- int rest = maxLength(format);\r
- StringBuilder sb = new StringBuilder();\r
- showable.Show(sb, ref rest, formatProvider);\r
- return sb.ToString();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <returns></returns>\r
- static int maxLength(String format)\r
- {\r
- //TODO: validate format string\r
- if (format == null)\r
- return 80;\r
- if (format.Length > 1 && format.StartsWith("L"))\r
- {\r
- return int.Parse(format.Substring(1));\r
- }\r
- else\r
- return int.MaxValue;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- /// <param name="items"></param>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns>True if collection was shown completely</returns>\r
- public static bool ShowCollectionValue<T>(ICollectionValue<T> items, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- string startdelim = "{ ", enddelim = " }";\r
- bool showIndexes = false;\r
- bool showMultiplicities = false;\r
- //TODO: do not test here at run time, but select code at compile time\r
- // perhaps by delivering the print type to this metod\r
- if (items is IList<T>)\r
- {\r
- startdelim = "[ ";\r
- enddelim = " ]";\r
- //TODO: should have been (items as IIndexed<T>).IndexingSpeed\r
- showIndexes = (items as IList<T>).IndexingSpeed == Speed.Constant;\r
- }\r
- else if (items is ICollection<T>)\r
- {\r
- ICollection<T> coll = items as ICollection<T>;\r
- if (coll.AllowsDuplicates)\r
- {\r
- startdelim = "{{ ";\r
- enddelim = " }}";\r
- if (coll.DuplicatesByCounting)\r
- showMultiplicities = true;\r
- }\r
- }\r
-\r
- stringbuilder.Append(startdelim);\r
- rest -= 2 * startdelim.Length;\r
- bool first = true;\r
- bool complete = true;\r
- int index = 0;\r
-\r
- if (showMultiplicities)\r
- {\r
- foreach (KeyValuePair<T, int> p in (items as ICollection<T>).ItemMultiplicities())\r
- {\r
- complete = false;\r
- if (rest <= 0)\r
- break;\r
- if (first)\r
- first = false;\r
- else\r
- {\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- }\r
- if (complete = Showing.Show(p.Key, stringbuilder, ref rest, formatProvider))\r
- {\r
- string multiplicityString = string.Format("(*{0})", p.Value);\r
- stringbuilder.Append(multiplicityString);\r
- rest -= multiplicityString.Length;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- foreach (T x in items)\r
- {\r
- complete = false;\r
- if (rest <= 0)\r
- break;\r
- if (first)\r
- first = false;\r
- else\r
- {\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- }\r
- if (showIndexes)\r
- {\r
- string indexString = string.Format("{0}:", index++);\r
- stringbuilder.Append(indexString);\r
- rest -= indexString.Length;\r
- }\r
- complete = Showing.Show(x, stringbuilder, ref rest, formatProvider);\r
- }\r
- }\r
- if (!complete)\r
- {\r
- stringbuilder.Append("...");\r
- rest -= 3;\r
- }\r
- stringbuilder.Append(enddelim);\r
- return complete;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="K"></typeparam>\r
- /// <typeparam name="V"></typeparam>\r
- /// \r
- /// <param name="dictionary"></param>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <param name="rest"></param>\r
- /// <returns></returns>\r
- public static bool ShowDictionary<K, V>(IDictionary<K, V> dictionary, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- bool sorted = dictionary is ISortedDictionary<K, V>;\r
- stringbuilder.Append(sorted ? "[ " : "{ ");\r
- rest -= 4; // Account for "( " and " )"\r
- bool first = true;\r
- bool complete = true;\r
-\r
- foreach (KeyValuePair<K, V> p in dictionary)\r
- {\r
- complete = false;\r
- if (rest <= 0)\r
- break;\r
- if (first)\r
- first = false;\r
- else\r
- {\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- }\r
- complete = Showing.Show(p, stringbuilder, ref rest, formatProvider);\r
- }\r
- if (!complete)\r
- {\r
- stringbuilder.Append("...");\r
- rest -= 3;\r
- }\r
- stringbuilder.Append(sorted ? " ]" : " }");\r
- return complete;\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using C5;\r
-using System;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// Utility class for building default generic equalityComparers.\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public static class EqualityComparer<T>\r
- {\r
- readonly static Type isequenced = typeof(ISequenced<>);\r
-\r
- readonly static Type icollection = typeof(ICollection<>);\r
-\r
- readonly static Type orderedcollectionequalityComparer = typeof(SequencedCollectionEqualityComparer<,>);\r
-\r
- readonly static Type unorderedcollectionequalityComparer = typeof(UnsequencedCollectionEqualityComparer<,>);\r
-\r
- readonly static Type equalityequalityComparer = typeof(EquatableEqualityComparer<>);\r
-\r
- readonly static Type iequalitytype = typeof(IEquatable<T>);\r
-\r
- static SCG.IEqualityComparer<T> cachedDefault = null;\r
-\r
- //TODO: find the right word for initialized+invocation \r
- /// <summary>\r
- /// A default generic equalityComparer for type T. The procedure is as follows:\r
- /// <list>\r
- /// <item>If T is int, double, byte or char, \r
- /// the equalityComparer will be a standard equalityComparer for that type</item>\r
- /// <item>If the actual generic argument T implements the generic interface\r
- /// <see cref="T:C5.ISequenced`1"/> for some value W of its generic parameter T,\r
- /// the equalityComparer will be <see cref="T:C5.SequencedCollectionEqualityComparer`2"/></item>\r
- /// <item>If the actual generic argument T implements \r
- /// <see cref="T:C5.ICollectionValue`1"/> for some value W of its generic parameter T,\r
- /// the equalityComparer will be <see cref="T:C5.UnsequencedCollectionEqualityComparer`2"/></item>\r
- /// <item>If T is a type implementing <see cref="T:C5.IEquatable`1"/>, the equalityComparer\r
- /// will be <see cref="T:C5.EquatableEqualityComparer`1"/></item>\r
- /// <item>If T is a type not implementing <see cref="T:C5.IEquatable`1"/>, the equalityComparer\r
- /// will be <see cref="T:C5.NaturalEqualityComparer`1"/> </item>\r
- /// </list> \r
- /// The <see cref="T:C5.IEqualityComparer`1"/> object is constructed when this class is initialised, i.e. \r
- /// its static constructors called. Thus, the property will be the same object \r
- /// for the duration of an invocation of the runtime, but a value serialized in \r
- /// another invocation and deserialized here will not be the same object.\r
- /// </summary>\r
- /// <value></value>\r
- public static SCG.IEqualityComparer<T> Default\r
- {\r
- get\r
- {\r
- if (cachedDefault != null)\r
- return cachedDefault;\r
-\r
- Type t = typeof(T);\r
-\r
- if (t.IsValueType)\r
- {\r
- if (t.Equals(typeof(int)))\r
- return cachedDefault = (SCG.IEqualityComparer<T>)(IntEqualityComparer.Default);\r
- else if (t.Equals(typeof(double)))\r
- return cachedDefault = (SCG.IEqualityComparer<T>)(DoubleEqualityComparer.Default);\r
- else if (t.Equals(typeof(byte)))\r
- return cachedDefault = (SCG.IEqualityComparer<T>)(ByteEqualityComparer.Default);\r
- else if (t.Equals(typeof(char)))\r
- return cachedDefault = (SCG.IEqualityComparer<T>)(CharEqualityComparer.Default);\r
- }\r
- Type[] interfaces = t.GetInterfaces();\r
- if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(isequenced))\r
- return createAndCache(orderedcollectionequalityComparer.MakeGenericType(new Type[] { t, t.GetGenericArguments()[0] }));\r
- foreach (Type ty in interfaces)\r
- {\r
- if (ty.IsGenericType && ty.GetGenericTypeDefinition().Equals(isequenced))\r
- return createAndCache(orderedcollectionequalityComparer.MakeGenericType(new Type[] { t, ty.GetGenericArguments()[0] }));\r
- }\r
- if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(icollection))\r
- return createAndCache(unorderedcollectionequalityComparer.MakeGenericType(new Type[] { t, t.GetGenericArguments()[0] }));\r
- foreach (Type ty in interfaces)\r
- {\r
- if (ty.IsGenericType && ty.GetGenericTypeDefinition().Equals(icollection))\r
- return createAndCache(unorderedcollectionequalityComparer.MakeGenericType(new Type[] { t, ty.GetGenericArguments()[0] }));\r
- }\r
- if (iequalitytype.IsAssignableFrom(t))\r
- return createAndCache(equalityequalityComparer.MakeGenericType(new Type[] { t }));\r
- else\r
- return cachedDefault = NaturalEqualityComparer<T>.Default;\r
- }\r
- }\r
- static SCG.IEqualityComparer<T> createAndCache(Type equalityComparertype)\r
- {\r
- return cachedDefault = (SCG.IEqualityComparer<T>)(equalityComparertype.GetProperty("Default", BindingFlags.Static | BindingFlags.Public).GetValue(null, null));\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// A default item equalityComparer calling through to\r
- /// the GetHashCode and Equals methods inherited from System.Object.\r
- /// </summary>\r
- public sealed class NaturalEqualityComparer<T> : SCG.IEqualityComparer<T>\r
- {\r
- static NaturalEqualityComparer<T> cached;\r
- NaturalEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public static NaturalEqualityComparer<T> Default { get { return cached ?? (cached = new NaturalEqualityComparer<T>()); } }\r
- //TODO: check if null check is reasonable\r
- //Answer: if we have struct C<T> { T t; int i;} and implement GetHashCode as\r
- //the sum of hashcodes, and T may be any type, we cannot make the null check \r
- //inside the definition of C<T> in a reasonable way.\r
- /// <summary>\r
- /// Get the hash code with respect to this item equalityComparer\r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- /// <returns>The hash code</returns>\r
- [Tested]\r
- public int GetHashCode(T item) { return item == null ? 0 : item.GetHashCode(); }\r
-\r
-\r
- /// <summary>\r
- /// Check if two items are equal with respect to this item equalityComparer\r
- /// </summary>\r
- /// <param name="item1">first item</param>\r
- /// <param name="item2">second item</param>\r
- /// <returns>True if equal</returns>\r
- [Tested]\r
- public bool Equals(T item1, T item2)\r
- {\r
- return item1 == null ? item2 == null : item1.Equals(item2);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// A default equalityComparer for a type, T, implementing <see cref="T:C5.IEquatable`1"/>. \r
- /// \r
- /// The equalityComparer forwards calls to GetHashCode and Equals to the methods \r
- /// on T. The point is that it is Equals(T) and not Equals(object)\r
- /// that is called. This will save a boxing/unboxing pair if T is a value type\r
- /// and in general a runtime type check.\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class EquatableEqualityComparer<T> : SCG.IEqualityComparer<T> where T : IEquatable<T>\r
- {\r
- static EquatableEqualityComparer<T> cached = new EquatableEqualityComparer<T>();\r
- EquatableEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public static EquatableEqualityComparer<T> Default { get { return cached ?? (cached = new EquatableEqualityComparer<T>()); } }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int GetHashCode(T item) { return item == null ? 0 : item.GetHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item1"></param>\r
- /// <param name="item2"></param>\r
- /// <returns></returns>\r
- public bool Equals(T item1, T item2) { return item1 == null ? item2 == null : item1.Equals(item2); }\r
- }\r
-\r
- /// <summary>\r
- /// A equalityComparer for a reference type that uses reference equality for equality and the hash code from object as hash code.\r
- /// </summary>\r
- /// <typeparam name="T">The item type. Must be a reference type.</typeparam>\r
- public class ReferenceEqualityComparer<T> : SCG.IEqualityComparer<T> where T : class\r
- {\r
- static ReferenceEqualityComparer<T> cached;\r
- ReferenceEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public static ReferenceEqualityComparer<T> Default { get { return cached ?? (cached = new ReferenceEqualityComparer<T>()); } }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int GetHashCode(T item)\r
- {\r
- return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(item);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="i1"></param>\r
- /// <param name="i2"></param>\r
- /// <returns></returns>\r
- public bool Equals(T i1, T i2)\r
- {\r
- return object.ReferenceEquals(i1, i2);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// An equalityComparer compatible with a given comparer. All hash codes are 0, \r
- /// meaning that anything based on hash codes will be quite inefficient.\r
- /// <para><b>Note: this will give a new EqualityComparer each time created!</b></para>\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class ComparerZeroHashCodeEqualityComparer<T> : SCG.IEqualityComparer<T>\r
- {\r
- SCG.IComparer<T> comparer;\r
- /// <summary>\r
- /// Create a trivial <see cref="T:C5.IEqualityComparer`1"/> compatible with the \r
- /// <see cref="T:C5.IComparer`1"/> <code>comparer</code>\r
- /// </summary>\r
- /// <param name="comparer"></param>\r
- public ComparerZeroHashCodeEqualityComparer(SCG.IComparer<T> comparer)\r
- {\r
- if (comparer == null)\r
- throw new NullReferenceException("Compaer cannot be null");\r
- this.comparer = comparer;\r
- }\r
- /// <summary>\r
- /// A trivial, inefficient hash fuction. Compatible with any equality relation.\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns>0</returns>\r
- public int GetHashCode(T item) { return 0; }\r
- /// <summary>\r
- /// Equality of two items as defined by the comparer.\r
- /// </summary>\r
- /// <param name="item1"></param>\r
- /// <param name="item2"></param>\r
- /// <returns></returns>\r
- public bool Equals(T item1, T item2) { return comparer.Compare(item1, item2) == 0; }\r
- }\r
-\r
- /// <summary>\r
- /// Prototype for an sequenced equalityComparer for something (T) that implements ISequenced[W]\r
- /// This will use ISequenced[W] specific implementations of the equalityComparer operations\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- /// <typeparam name="W"></typeparam>\r
- public class SequencedCollectionEqualityComparer<T, W> : SCG.IEqualityComparer<T>\r
- where T : ISequenced<W>\r
- {\r
- static SequencedCollectionEqualityComparer<T, W> cached;\r
- SequencedCollectionEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public static SequencedCollectionEqualityComparer<T, W> Default { get { return cached ?? (cached = new SequencedCollectionEqualityComparer<T, W>()); } }\r
- /// <summary>\r
- /// Get the hash code with respect to this sequenced equalityComparer\r
- /// </summary>\r
- /// <param name="collection">The collection</param>\r
- /// <returns>The hash code</returns>\r
- [Tested]\r
- public int GetHashCode(T collection) { return collection.GetSequencedHashCode(); }\r
-\r
-\r
- /// <summary>\r
- /// Check if two items are equal with respect to this sequenced equalityComparer\r
- /// </summary>\r
- /// <param name="collection1">first collection</param>\r
- /// <param name="collection2">second collection</param>\r
- /// <returns>True if equal</returns>\r
- [Tested]\r
- public bool Equals(T collection1, T collection2) { return collection1 == null ? collection2 == null : collection1.SequencedEquals(collection2); }\r
- }\r
-\r
- /// <summary>\r
- /// Prototype for an unsequenced equalityComparer for something (T) that implements ICollection[W]\r
- /// This will use ICollection[W] specific implementations of the equalityComparer operations\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- /// <typeparam name="W"></typeparam>\r
- public class UnsequencedCollectionEqualityComparer<T, W> : SCG.IEqualityComparer<T>\r
- where T : ICollection<W>\r
- {\r
- static UnsequencedCollectionEqualityComparer<T, W> cached;\r
- UnsequencedCollectionEqualityComparer() { }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public static UnsequencedCollectionEqualityComparer<T, W> Default { get { return cached ?? (cached = new UnsequencedCollectionEqualityComparer<T, W>()); } }\r
- /// <summary>\r
- /// Get the hash code with respect to this unsequenced equalityComparer\r
- /// </summary>\r
- /// <param name="collection">The collection</param>\r
- /// <returns>The hash code</returns>\r
- [Tested]\r
- public int GetHashCode(T collection) { return collection.GetUnsequencedHashCode(); }\r
-\r
-\r
- /// <summary>\r
- /// Check if two collections are equal with respect to this unsequenced equalityComparer\r
- /// </summary>\r
- /// <param name="collection1">first collection</param>\r
- /// <param name="collection2">second collection</param>\r
- /// <returns>True if equal</returns>\r
- [Tested]\r
- public bool Equals(T collection1, T collection2) { return collection1 == null ? collection2 == null : collection1.UnsequencedEquals(collection2); }\r
- }\r
-\r
-}\r
-\r
-\r
-\r
-\r
-\r
-#if EXPERIMENTAL\r
-namespace C5.EqualityComparerBuilder\r
-{\r
-\r
- /// <summary>\r
- /// IEqualityComparer factory class: examines at instatiation time if T is an\r
- /// interface implementing "int GetHashCode()" and "bool Equals(T)".\r
- /// If those are not present, MakeEqualityComparer will return a default equalityComparer,\r
- /// else this class will implement IequalityComparer[T] via Invoke() on the\r
- /// reflected method infos.\r
- /// </summary>\r
- public class ByInvoke<T> : SCG.IEqualityComparer<T>\r
- {\r
- internal static readonly System.Reflection.MethodInfo hinfo, einfo;\r
-\r
-\r
- static ByInvoke()\r
- {\r
- Type t = typeof(T);\r
-\r
- if (!t.IsInterface) return;\r
-\r
- BindingFlags f = BindingFlags.Public | BindingFlags.Instance;\r
-\r
- hinfo = t.GetMethod("GetHashCode", f, null, new Type[0], null);\r
- einfo = t.GetMethod("Equals", f, null, new Type[1] { t }, null);\r
- }\r
-\r
-\r
- private ByInvoke() { }\r
-\r
-/// <summary>\r
-/// \r
-/// </summary>\r
-/// <returns></returns>\r
- public static SCG.IEqualityComparer<T> MakeEqualityComparer()\r
- {\r
- if (hinfo != null && einfo != null)\r
- return new ByInvoke<T>();\r
- else\r
- return NaturalEqualityComparer<T>.Default;\r
- }\r
-\r
-/// <summary>\r
-/// \r
-/// </summary>\r
-/// <param name="item"></param>\r
-/// <returns></returns>\r
- public int GetHashCode(T item)\r
- {\r
- return (int)(hinfo.Invoke(item, null));\r
- }\r
-\r
-/// <summary>\r
-/// \r
-/// </summary>\r
-/// <param name="i1"></param>\r
-/// <param name="i2"></param>\r
-/// <returns></returns>\r
- public bool Equals(T i1, T i2)\r
- {\r
- return (bool)(einfo.Invoke(i1, new object[1] { i2 }));\r
- }\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// Like ByInvoke, but tries to build a equalityComparer by RTCG to\r
- /// avoid the Invoke() overhead. \r
- /// </summary>\r
- public class ByRTCG\r
- {\r
- private static ModuleBuilder moduleBuilder;\r
-\r
- private static AssemblyBuilder assemblyBuilder;\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="hinfo"></param>\r
- /// <param name="einfo"></param>\r
- /// <returns></returns>\r
- public static SCG.IEqualityComparer<T> CreateEqualityComparer<T>(MethodInfo hinfo, MethodInfo einfo)\r
- {\r
- if (moduleBuilder == null)\r
- {\r
- string assmname = "LeFake";\r
- string filename = assmname + ".dll";\r
- AssemblyName assemblyName = new AssemblyName("LeFake");\r
- AppDomain appdomain = AppDomain.CurrentDomain;\r
- AssemblyBuilderAccess acc = AssemblyBuilderAccess.RunAndSave;\r
-\r
- assemblyBuilder = appdomain.DefineDynamicAssembly(assemblyName, acc);\r
- moduleBuilder = assemblyBuilder.DefineDynamicModule(assmname, filename);\r
- }\r
-\r
- Type t = typeof(T);\r
- Type o_t = typeof(object);\r
- Type h_t = typeof(SCG.IEqualityComparer<T>);\r
- Type i_t = typeof(int);\r
- //TODO: protect uid for thread safety!\r
- string name = "C5.Dynamic.EqualityComparer_" + Guid.NewGuid().ToString();\r
- TypeAttributes tatt = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed;\r
- TypeBuilder tb = moduleBuilder.DefineType(name, tatt, o_t, new Type[1] { h_t });\r
- MethodAttributes matt = MethodAttributes.Public | MethodAttributes.Virtual;\r
- MethodBuilder mb = tb.DefineMethod("GetHashCode", matt, i_t, new Type[1] { t });\r
- ILGenerator ilg = mb.GetILGenerator();\r
-\r
- ilg.Emit(OpCodes.Ldarg_1);\r
- ilg.Emit(OpCodes.Callvirt, hinfo);\r
- ilg.Emit(OpCodes.Ret);\r
- mb = tb.DefineMethod("Equals", matt, typeof(bool), new Type[2] { t, t });\r
- ilg = mb.GetILGenerator();\r
- ilg.Emit(OpCodes.Ldarg_1);\r
- ilg.Emit(OpCodes.Ldarg_2);\r
- ilg.Emit(OpCodes.Callvirt, einfo);\r
- ilg.Emit(OpCodes.Ret);\r
-\r
- Type equalityComparer_t = tb.CreateType();\r
- object equalityComparer = equalityComparer_t.GetConstructor(new Type[0]).Invoke(null);\r
-\r
- return (SCG.IEqualityComparer<T>)equalityComparer;\r
- }\r
-\r
-/// <summary>\r
-/// \r
-/// </summary>\r
-/// <typeparam name="T"></typeparam>\r
-/// <returns></returns>\r
- public static SCG.IEqualityComparer<T> build<T>()\r
- {\r
- MethodInfo hinfo = ByInvoke<T>.hinfo, einfo = ByInvoke<T>.einfo;\r
-\r
- if (hinfo != null && einfo != null)\r
- return CreateEqualityComparer<T>(hinfo, einfo);\r
- else\r
- return EqualityComparer<T>.Default;\r
- }\r
-\r
-/// <summary>\r
-/// \r
-/// </summary>\r
- public void dump()\r
- {\r
- assemblyBuilder.Save("LeFake.dll");\r
- }\r
- }\r
-}\r
-#endif\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A generic collection, that can be enumerated backwards.\r
- /// </summary>\r
- public interface IDirectedEnumerable<T> : SCG.IEnumerable<T>\r
- {\r
- /// <summary>\r
- /// Create a collection containing the same items as this collection, but\r
- /// whose enumerator will enumerate the items backwards. The new collection\r
- /// will become invalid if the original is modified. Method typically used as in\r
- /// <code>foreach (T x in coll.Backwards()) {...}</code>\r
- /// </summary>\r
- /// <returns>The backwards collection.</returns>\r
- IDirectedEnumerable<T> Backwards();\r
-\r
-\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- EnumerationDirection Direction { get;}\r
- }\r
-\r
- /// <summary>\r
- /// A generic collection that may be enumerated and can answer\r
- /// efficiently how many items it contains. Like <code>IEnumerable<T></code>,\r
- /// this interface does not prescribe any operations to initialize or update the \r
- /// collection. The main usage for this interface is to be the return type of \r
- /// query operations on generic collection.\r
- /// </summary>\r
- public interface ICollectionValue<T> : SCG.IEnumerable<T>, IShowable\r
- {\r
- /// <summary>\r
- /// A flag bitmap of the events subscribable to by this collection.\r
- /// </summary>\r
- /// <value></value>\r
- EventTypeEnum ListenableEvents { get;}\r
-\r
- /// <summary>\r
- /// A flag bitmap of the events currently subscribed to by this collection.\r
- /// </summary>\r
- /// <value></value>\r
- EventTypeEnum ActiveEvents { get;}\r
-\r
- /// <summary>\r
- /// The change event. Will be raised for every change operation on the collection.\r
- /// </summary>\r
- event CollectionChangedHandler<T> CollectionChanged;\r
-\r
- /// <summary>\r
- /// The change event. Will be raised for every clear operation on the collection.\r
- /// </summary>\r
- event CollectionClearedHandler<T> CollectionCleared;\r
-\r
- /// <summary>\r
- /// The item added event. Will be raised for every individual addition to the collection.\r
- /// </summary>\r
- event ItemsAddedHandler<T> ItemsAdded;\r
-\r
- /// <summary>\r
- /// The item inserted event. Will be raised for every individual insertion to the collection.\r
- /// </summary>\r
- event ItemInsertedHandler<T> ItemInserted;\r
-\r
- /// <summary>\r
- /// The item removed event. Will be raised for every individual removal from the collection.\r
- /// </summary>\r
- event ItemsRemovedHandler<T> ItemsRemoved;\r
-\r
- /// <summary>\r
- /// The item removed at event. Will be raised for every individual removal at from the collection.\r
- /// </summary>\r
- event ItemRemovedAtHandler<T> ItemRemovedAt;\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if this collection is empty.</value>\r
- bool IsEmpty { get;}\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of items in this collection</value>\r
- int Count { get;}\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>A characterization of the speed of the \r
- /// <code>Count</code> property in this collection.</value>\r
- Speed CountSpeed { get;}\r
-\r
- /// <summary>\r
- /// Copy the items of this collection to a contiguous part of an array.\r
- /// </summary>\r
- /// <param name="array">The array to copy to</param>\r
- /// <param name="index">The index at which to copy the first item</param>\r
- void CopyTo(T[] array, int index);\r
-\r
- /// <summary>\r
- /// Create an array with the items of this collection (in the same order as an\r
- /// enumerator would output them).\r
- /// </summary>\r
- /// <returns>The array</returns>\r
- T[] ToArray();\r
-\r
- /// <summary>\r
- /// Apply a delegate to all items of this collection.\r
- /// </summary>\r
- /// <param name="action">The delegate to apply</param>\r
- void Apply(Act<T> action);\r
-\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>True is such an item exists</returns>\r
- bool Exists(Fun<T, bool> predicate);\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the first one in enumeration order.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <param name="item"></param>\r
- /// <returns>True is such an item exists</returns>\r
- bool Find(Fun<T, bool> predicate, out T item);\r
-\r
-\r
- /// <summary>\r
- /// Check if all items in this collection satisfies a specific predicate.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>True if all items satisfies the predicate</returns>\r
- bool All(Fun<T, bool> predicate);\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// <para>Implementations must assure that the item \r
- /// returned may be efficiently removed.</para>\r
- /// <para>Implementors may decide to implement this method in a way such that repeated\r
- /// calls do not necessarily give the same result, i.e. so that the result of the following \r
- /// test is undetermined:\r
- /// <code>coll.Choose() == coll.Choose()</code></para>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- T Choose();\r
-\r
- /// <summary>\r
- /// Create an enumerable, enumerating the items of this collection that satisfies \r
- /// a certain condition.\r
- /// </summary>\r
- /// <param name="filter">The T->bool filter delegate defining the condition</param>\r
- /// <returns>The filtered enumerable</returns>\r
- SCG.IEnumerable<T> Filter(Fun<T, bool> filter);\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A sized generic collection, that can be enumerated backwards.\r
- /// </summary>\r
- public interface IDirectedCollectionValue<T> : ICollectionValue<T>, IDirectedEnumerable<T>\r
- {\r
- /// <summary>\r
- /// Create a collection containing the same items as this collection, but\r
- /// whose enumerator will enumerate the items backwards. The new collection\r
- /// will become invalid if the original is modified. Method typically used as in\r
- /// <code>foreach (T x in coll.Backwards()) {...}</code>\r
- /// </summary>\r
- /// <returns>The backwards collection.</returns>\r
- new IDirectedCollectionValue<T> Backwards();\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the first one in enumeration order.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <param name="item"></param>\r
- /// <returns>True is such an item exists</returns>\r
- bool FindLast(Fun<T, bool> predicate, out T item);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// A generic collection to which one may add items. This is just the intersection\r
- /// of the main stream generic collection interfaces and the priority queue interface,\r
- /// <see cref="T:C5.ICollection`1"/> and <see cref="T:C5.IPriorityQueue`1"/>.\r
- /// </summary>\r
- public interface IExtensible<T> : ICollectionValue<T>, ICloneable\r
- {\r
- /// <summary>\r
- /// If true any call of an updating operation will throw an\r
- /// <code>ReadOnlyCollectionException</code>\r
- /// </summary>\r
- /// <value>True if this collection is read-only.</value>\r
- bool IsReadOnly { get;}\r
-\r
- //TODO: wonder where the right position of this is\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>False if this collection has set semantics, true if bag semantics.</value>\r
- bool AllowsDuplicates { get;}\r
-\r
- //TODO: wonder where the right position of this is. And the semantics.\r
- /// <summary>\r
- /// (Here should be a discussion of the role of equalityComparers. Any ). \r
- /// </summary>\r
- /// <value>The equalityComparer used by this collection to check equality of items. \r
- /// Or null (????) if collection does not check equality at all or uses a comparer.</value>\r
- SCG.IEqualityComparer<T> EqualityComparer { get;}\r
-\r
- //ItemEqualityTypeEnum ItemEqualityType {get ;}\r
-\r
- //TODO: find a good name\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- bool DuplicatesByCounting { get;}\r
-\r
- /// <summary>\r
- /// Add an item to this collection if possible. If this collection has set\r
- /// semantics, the item will be added if not already in the collection. If\r
- /// bag semantics, the item will always be added.\r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True if item was added.</returns>\r
- bool Add(T item);\r
-\r
- /// <summary>\r
- /// Add the elements from another collection with a more specialized item type \r
- /// to this collection. If this\r
- /// collection has set semantics, only items not already in the collection\r
- /// will be added.\r
- /// </summary>\r
- /// <typeparam name="U">The type of items to add</typeparam>\r
- /// <param name="items">The items to add</param>\r
- void AddAll<U>(SCG.IEnumerable<U> items) where U : T;\r
-\r
- //void Clear(); // for priority queue\r
- //int Count why not?\r
- /// <summary>\r
- /// Check the integrity of the internal data structures of this collection.\r
- /// <i>This is only relevant for developers of the library</i>\r
- /// </summary>\r
- /// <returns>True if check was passed.</returns>\r
- bool Check();\r
- }\r
-\r
- /// <summary>\r
- /// The simplest interface of a main stream generic collection\r
- /// with lookup, insertion and removal operations. \r
- /// </summary>\r
- public interface ICollection<T> : IExtensible<T>\r
- {\r
- //This is somewhat similar to the RandomAccess marker itf in java\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant). \r
- /// <para>See <see cref="T:C5.Speed"/> for the set of symbols.</para>\r
- /// </summary>\r
- /// <value>A characterization of the speed of lookup operations\r
- /// (<code>Contains()</code> etc.) of the implementation of this collection.</value>\r
- Speed ContainsSpeed { get;}\r
-\r
- /// <summary>\r
- /// The unordered collection hashcode is defined as the sum of \r
- /// <code>h(hashcode(item))</code> over the items\r
- /// of the collection, where the function <code>h</code> is a function from \r
- /// int to int of the form <code> t -> (a0*t+b0)^(a1*t+b1)^(a2*t+b2)</code>, where \r
- /// the ax and bx are the same for all collection classes. \r
- /// <para>The current implementation uses fixed values for the ax and bx, \r
- /// specified as constants in the code.</para>\r
- /// </summary>\r
- /// <returns>The unordered hashcode of this collection.</returns>\r
- int GetUnsequencedHashCode();\r
-\r
-\r
- /// <summary>\r
- /// Compare the contents of this collection to another one without regards to\r
- /// the sequence order. The comparison will use this collection's itemequalityComparer\r
- /// to compare individual items.\r
- /// </summary>\r
- /// <param name="otherCollection">The collection to compare to.</param>\r
- /// <returns>True if this collection and that contains the same items.</returns>\r
- bool UnsequencedEquals(ICollection<T> otherCollection);\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains (an item equivalent to according to the\r
- /// itemequalityComparer) a particular value.\r
- /// </summary>\r
- /// <param name="item">The value to check for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- bool Contains(T item);\r
-\r
-\r
- /// <summary>\r
- /// Count the number of items of the collection equal to a particular value.\r
- /// Returns 0 if and only if the value is not in the collection.\r
- /// </summary>\r
- /// <param name="item">The value to count.</param>\r
- /// <returns>The number of copies found.</returns>\r
- int ContainsCount(T item);\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- ICollectionValue<T> UniqueItems();\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities();\r
-\r
- /// <summary>\r
- /// Check whether this collection contains all the values in another collection.\r
- /// If this collection has bag semantics (<code>AllowsDuplicates==true</code>)\r
- /// the check is made with respect to multiplicities, else multiplicities\r
- /// are not taken into account.\r
- /// </summary>\r
- /// <param name="items">The </param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if all values in <code>items</code>is in this collection.</returns>\r
- bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T;\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- bool Find(ref T item);\r
-\r
-\r
- //This should probably just be bool Add(ref T item); !!!\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found. Else, add the item to the collection.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the item was found (hence not added).</returns>\r
- bool FindOrAdd(ref T item);\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// with a (binary copy of) the supplied value. If the collection has bag semantics,\r
- /// it depends on the value of DuplicatesByCounting if this updates all equivalent copies in\r
- /// the collection or just one.\r
- /// </summary>\r
- /// <param name="item">Value to update.</param>\r
- /// <returns>True if the item was found and hence updated.</returns>\r
- bool Update(T item);\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// with a (binary copy of) the supplied value. If the collection has bag semantics,\r
- /// it depends on the value of DuplicatesByCounting if this updates all equivalent copies in\r
- /// the collection or just one.\r
- /// </summary>\r
- /// <param name="item">Value to update.</param>\r
- /// <param name="olditem">On output the olditem, if found.</param>\r
- /// <returns>True if the item was found and hence updated.</returns>\r
- bool Update(T item, out T olditem);\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value; else add the value to the collection. \r
- /// </summary>\r
- /// <param name="item">Value to add or update.</param>\r
- /// <returns>True if the item was found and updated (hence not added).</returns>\r
- bool UpdateOrAdd(T item);\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value; else add the value to the collection. \r
- /// </summary>\r
- /// <param name="item">Value to add or update.</param>\r
- /// <param name="olditem">On output the olditem, if found.</param>\r
- /// <returns>True if the item was found and updated (hence not added).</returns>\r
- bool UpdateOrAdd(T item, out T olditem);\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection. If the collection has bag\r
- /// semantics only one copy equivalent to the supplied item is removed. \r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- bool Remove(T item);\r
-\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection if found. If the collection\r
- /// has bag semantics only one copy equivalent to the supplied item is removed,\r
- /// which one is implementation dependent. \r
- /// If an item was removed, report a binary copy of the actual item removed in \r
- /// the argument.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <param name="removeditem">The value removed if any.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- bool Remove(T item, out T removeditem);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items equivalent to a given value.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- void RemoveAllCopies(T item);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items in another collection from this one. If this collection\r
- /// has bag semantics, take multiplicities into account.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to remove.</param>\r
- void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T;\r
-\r
- //void RemoveAll(Fun<T, bool> predicate);\r
-\r
- /// <summary>\r
- /// Remove all items from this collection.\r
- /// </summary>\r
- void Clear();\r
-\r
-\r
- /// <summary>\r
- /// Remove all items not in some other collection from this one. If this collection\r
- /// has bag semantics, take multiplicities into account.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to retain.</param>\r
- void RetainAll<U>(SCG.IEnumerable<U> items) where U : T;\r
-\r
- //void RetainAll(Fun<T, bool> predicate);\r
- //IDictionary<T> UniqueItems()\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// An editable collection maintaining a definite sequence order of the items.\r
- ///\r
- /// <i>Implementations of this interface must compute the hash code and \r
- /// equality exactly as prescribed in the method definitions in order to\r
- /// be consistent with other collection classes implementing this interface.</i>\r
- /// <i>This interface is usually implemented by explicit interface implementation,\r
- /// not as ordinary virtual methods.</i>\r
- /// </summary>\r
- public interface ISequenced<T> : ICollection<T>, IDirectedCollectionValue<T>\r
- {\r
- /// <summary>\r
- /// The hashcode is defined as <code>h(...h(h(h(x1),x2),x3),...,xn)</code> for\r
- /// <code>h(a,b)=CONSTANT*a+b</code> and the x's the hash codes of the items of \r
- /// this collection.\r
- /// </summary>\r
- /// <returns>The sequence order hashcode of this collection.</returns>\r
- int GetSequencedHashCode();\r
-\r
-\r
- /// <summary>\r
- /// Compare this sequenced collection to another one in sequence order.\r
- /// </summary>\r
- /// <param name="otherCollection">The sequenced collection to compare to.</param>\r
- /// <returns>True if this collection and that contains equal (according to\r
- /// this collection's itemequalityComparer) in the same sequence order.</returns>\r
- bool SequencedEquals(ISequenced<T> otherCollection);\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A sequenced collection, where indices of items in the order are maintained\r
- /// </summary>\r
- public interface IIndexed<T> : ISequenced<T>\r
- {\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if <code>index</code> is negative or\r
- /// >= the size of the collection.</exception>\r
- /// <value>The <code>index</code>'th item of this list.</value>\r
- /// <param name="index">the index to lookup</param>\r
- T this[int index] { get;}\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- Speed IndexingSpeed { get;}\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException"></exception>\r
- /// <value>The directed collection of items in a specific index interval.</value>\r
- /// <param name="start">The low index of the interval (inclusive).</param>\r
- /// <param name="count">The size of the range.</param>\r
- IDirectedCollectionValue<T> this[int start, int count] { get;}\r
-\r
-\r
- /// <summary>\r
- /// Searches for an item in the list going forwards from the start. \r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of item from start. A negative number if item not found, \r
- /// namely the two-complement of the index at which the Add operation would put the item.</returns>\r
- int IndexOf(T item);\r
-\r
-\r
- /// <summary>\r
- /// Searches for an item in the list going backwards from the end.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of of item from the end. A negative number if item not found, \r
- /// namely the two-complement of the index at which the Add operation would put the item.</returns>\r
- int LastIndexOf(T item);\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the index of the first one.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>the index, if found, a negative value else</returns>\r
- int FindIndex(Fun<T, bool> predicate);\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the index of the last one.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>the index, if found, a negative value else</returns>\r
- int FindLastIndex(Fun<T, bool> predicate);\r
-\r
-\r
- /// <summary>\r
- /// Remove the item at a specific position of the list.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if <code>index</code> is negative or\r
- /// >= the size of the collection.</exception>\r
- /// <param name="index">The index of the item to remove.</param>\r
- /// <returns>The removed item.</returns>\r
- T RemoveAt(int index);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items in an index interval.\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException"> if start or count \r
- /// is negative or start+count > the size of the collection.</exception>\r
- /// <param name="start">The index of the first item to remove.</param>\r
- /// <param name="count">The number of items to remove.</param>\r
- void RemoveInterval(int start, int count);\r
- }\r
-\r
- //TODO: decide if this should extend ICollection\r
- /// <summary>\r
- /// The interface describing the operations of a LIFO stack data structure.\r
- /// </summary>\r
- /// <typeparam name="T">The item type</typeparam>\r
- public interface IStack<T> : IDirectedCollectionValue<T>\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- bool AllowsDuplicates { get;}\r
- /// <summary>\r
- /// Get the <code>index</code>'th element of the stack. The bottom of the stack has index 0.\r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <returns></returns>\r
- T this[int index] { get;}\r
- /// <summary>\r
- /// Push an item to the top of the stack.\r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- void Push(T item);\r
- /// <summary>\r
- /// Pop the item at the top of the stack from the stack.\r
- /// </summary>\r
- /// <returns>The popped item.</returns>\r
- T Pop();\r
- }\r
-\r
- /// <summary>\r
- /// The interface describing the operations of a FIFO queue data structure.\r
- /// </summary>\r
- /// <typeparam name="T">The item type</typeparam>\r
- public interface IQueue<T> : IDirectedCollectionValue<T>\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- bool AllowsDuplicates { get;}\r
- /// <summary>\r
- /// Get the <code>index</code>'th element of the queue. The front of the queue has index 0.\r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <returns></returns>\r
- T this[int index] { get;}\r
- /// <summary>\r
- /// Enqueue an item at the back of the queue. \r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- void Enqueue(T item);\r
- /// <summary>\r
- /// Dequeue an item from the front of the queue.\r
- /// </summary>\r
- /// <returns>The item</returns>\r
- T Dequeue();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// This is an indexed collection, where the item order is chosen by \r
- /// the user at insertion time.\r
- ///\r
- /// NBNBNB: we need a description of the view functionality here!\r
- /// </summary>\r
- public interface IList<T> : IIndexed<T>, IDisposable\r
- {\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <value>The first item in this list.</value>\r
- T First { get;}\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <value>The last item in this list.</value>\r
- T Last { get;}\r
-\r
- /// <summary>\r
- /// Since <code>Add(T item)</code> always add at the end of the list,\r
- /// this describes if list has FIFO or LIFO semantics.\r
- /// </summary>\r
- /// <value>True if the <code>Remove()</code> operation removes from the\r
- /// start of the list, false if it removes from the end.</value>\r
- bool FIFO { get; set;}\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- bool IsFixedSize { get; }\r
-\r
- /// <summary>\r
- /// On this list, this indexer is read/write.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if index is negative or\r
- /// >= the size of the collection.</exception>\r
- /// <value>The index'th item of this list.</value>\r
- /// <param name="index">The index of the item to fetch or store.</param>\r
- new T this[int index] { get; set;}\r
-\r
- /// <summary>\r
- /// Insert an item at a specific index location in this list. \r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if <code>index</code> is negative or\r
- /// > the size of the collection.</exception>\r
- /// <exception cref="DuplicateNotAllowedException"> if the list has\r
- /// <code>AllowsDuplicates==false</code> and the item is \r
- /// already in the list.</exception>\r
- /// <param name="index">The index at which to insert.</param>\r
- /// <param name="item">The item to insert.</param>\r
- void Insert(int index, T item);\r
-\r
- /// <summary>\r
- /// Insert an item at the end of a compatible view, used as a pointer.\r
- /// <para>The <code>pointer</code> must be a view on the same list as\r
- /// <code>this</code> and the endpoitn of <code>pointer</code> must be\r
- /// a valid insertion point of <code>this</code></para>\r
- /// </summary>\r
- /// <exception cref="IncompatibleViewException">If <code>pointer</code> \r
- /// is not a view on the same list as <code>this</code></exception>\r
- /// <exception cref="IndexOutOfRangeException"><b>??????</b> if the endpoint of \r
- /// <code>pointer</code> is not inside <code>this</code></exception>\r
- /// <exception cref="DuplicateNotAllowedException"> if the list has\r
- /// <code>AllowsDuplicates==false</code> and the item is \r
- /// already in the list.</exception>\r
- /// <param name="pointer"></param>\r
- /// <param name="item"></param>\r
- void Insert(IList<T> pointer, T item);\r
-\r
- /// <summary>\r
- /// Insert an item at the front of this list.\r
- /// <exception cref="DuplicateNotAllowedException"/> if the list has\r
- /// <code>AllowsDuplicates==false</code> and the item is \r
- /// already in the list.\r
- /// </summary>\r
- /// <param name="item">The item to insert.</param>\r
- void InsertFirst(T item);\r
-\r
- /// <summary>\r
- /// Insert an item at the back of this list.\r
- /// <exception cref="DuplicateNotAllowedException"/> if the list has\r
- /// <code>AllowsDuplicates==false</code> and the item is \r
- /// already in the list.\r
- /// </summary>\r
- /// <param name="item">The item to insert.</param>\r
- void InsertLast(T item);\r
-\r
- /// <summary>\r
- /// Insert into this list all items from an enumerable collection starting \r
- /// at a particular index.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if <code>index</code> is negative or\r
- /// > the size of the collection.</exception>\r
- /// <exception cref="DuplicateNotAllowedException"> if the list has \r
- /// <code>AllowsDuplicates==false</code> and one of the items to insert is\r
- /// already in the list.</exception>\r
- /// <param name="index">Index to start inserting at</param>\r
- /// <param name="items">Items to insert</param>\r
- /// <typeparam name="U"></typeparam>\r
- void InsertAll<U>(int index, SCG.IEnumerable<U> items) where U : T;\r
-\r
- /// <summary>\r
- /// Create a new list consisting of the items of this list satisfying a \r
- /// certain predicate.\r
- /// </summary>\r
- /// <param name="filter">The filter delegate defining the predicate.</param>\r
- /// <returns>The new list.</returns>\r
- IList<T> FindAll(Fun<T, bool> filter);\r
-\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list. The new list will use the default equalityComparer for the item type V.\r
- /// </summary>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <returns>The new list.</returns>\r
- IList<V> Map<V>(Fun<T, V> mapper);\r
-\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list. The new list will use a specified equalityComparer for the item type.\r
- /// </summary>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <param name="equalityComparer">The equalityComparer to use for the new list</param>\r
- /// <returns>The new list.</returns>\r
- IList<V> Map<V>(Fun<T, V> mapper, SCG.IEqualityComparer<V> equalityComparer);\r
-\r
- /// <summary>\r
- /// Remove one item from the list: from the front if <code>FIFO</code>\r
- /// is true, else from the back.\r
- /// <exception cref="NoSuchItemException"/> if this list is empty.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- T Remove();\r
-\r
- /// <summary>\r
- /// Remove one item from the front of the list.\r
- /// <exception cref="NoSuchItemException"/> if this list is empty.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- T RemoveFirst();\r
-\r
- /// <summary>\r
- /// Remove one item from the back of the list.\r
- /// <exception cref="NoSuchItemException"/> if this list is empty.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- T RemoveLast();\r
-\r
- /// <summary>\r
- /// Create a list view on this list. \r
- /// <exception cref="ArgumentOutOfRangeException"/> if the view would not fit into\r
- /// this list.\r
- /// </summary>\r
- /// <param name="start">The index in this list of the start of the view.</param>\r
- /// <param name="count">The size of the view.</param>\r
- /// <returns>The new list view.</returns>\r
- IList<T> View(int start, int count);\r
-\r
- /// <summary>\r
- /// Create a list view on this list containing the (first) occurrence of a particular item. \r
- /// <exception cref="NoSuchItemException"/> if the item is not in this list.\r
- /// </summary>\r
- /// <param name="item">The item to find.</param>\r
- /// <returns>The new list view.</returns>\r
- IList<T> ViewOf(T item);\r
-\r
- /// <summary>\r
- /// Create a list view on this list containing the last occurrence of a particular item. \r
- /// <exception cref="NoSuchItemException"/> if the item is not in this list.\r
- /// </summary>\r
- /// <param name="item">The item to find.</param>\r
- /// <returns>The new list view.</returns>\r
- IList<T> LastViewOf(T item);\r
-\r
- /// <summary>\r
- /// Null if this list is not a view.\r
- /// </summary>\r
- /// <value>Underlying list for view.</value>\r
- IList<T> Underlying { get;}\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <value>Offset for this list view or 0 for an underlying list.</value>\r
- int Offset { get;}\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- bool IsValid { get;}\r
-\r
- /// <summary>\r
- /// Slide this list view along the underlying list.\r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the operation\r
- /// would bring either end of the view outside the underlying list.</exception>\r
- /// <param name="offset">The signed amount to slide: positive to slide\r
- /// towards the end.</param>\r
- IList<T> Slide(int offset);\r
-\r
- /// <summary>\r
- /// Slide this list view along the underlying list, changing its size.\r
- /// \r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the operation\r
- /// would bring either end of the view outside the underlying list.</exception>\r
- /// <param name="offset">The signed amount to slide: positive to slide\r
- /// towards the end.</param>\r
- /// <param name="size">The new size of the view.</param>\r
- IList<T> Slide(int offset, int size);\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <returns></returns>\r
- bool TrySlide(int offset);\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <param name="size"></param>\r
- /// <returns></returns>\r
- bool TrySlide(int offset, int size);\r
-\r
- /// <summary>\r
- /// \r
- /// <para>Returns null if <code>otherView</code> is strictly to the left of this view</para>\r
- /// </summary>\r
- /// <param name="otherView"></param>\r
- /// <exception cref="IncompatibleViewException">If otherView does not have the same underlying list as this</exception>\r
- /// <exception cref="ArgumentOutOfRangeException">If <code>otherView</code> is strictly to the left of this view</exception>\r
- /// <returns></returns>\r
- IList<T> Span(IList<T> otherView);\r
-\r
- /// <summary>\r
- /// Reverse the list so the items are in the opposite sequence order.\r
- /// </summary>\r
- void Reverse();\r
-\r
- /// <summary>\r
- /// Check if this list is sorted according to the default sorting order\r
- /// for the item type T, as defined by the <see cref="T:C5.Comparer`1"/> class \r
- /// </summary>\r
- /// <exception cref="NotComparableException">if T is not comparable</exception>\r
- /// <returns>True if the list is sorted, else false.</returns>\r
- bool IsSorted();\r
-\r
- /// <summary>\r
- /// Check if this list is sorted according to a specific sorting order.\r
- /// </summary>\r
- /// <param name="comparer">The comparer defining the sorting order.</param>\r
- /// <returns>True if the list is sorted, else false.</returns>\r
- bool IsSorted(SCG.IComparer<T> comparer);\r
-\r
- /// <summary>\r
- /// Sort the items of the list according to the default sorting order\r
- /// for the item type T, as defined by the <see cref="T:C5.Comparer`1"/> class \r
- /// </summary>\r
- /// <exception cref="NotComparableException">if T is not comparable</exception>\r
- void Sort();\r
-\r
- /// <summary>\r
- /// Sort the items of the list according to a specified sorting order.\r
- /// <para>The sorting does not perform duplicate elimination or identify items\r
- /// according to the comparer or itemequalityComparer. I.e. the list as an \r
- /// unsequenced collection with binary equality, will not change.\r
- /// </para>\r
- /// </summary>\r
- /// <param name="comparer">The comparer defining the sorting order.</param>\r
- void Sort(SCG.IComparer<T> comparer);\r
-\r
-\r
- /// <summary>\r
- /// Randomly shuffle the items of this list. \r
- /// </summary>\r
- void Shuffle();\r
-\r
-\r
- /// <summary>\r
- /// Shuffle the items of this list according to a specific random source.\r
- /// </summary>\r
- /// <param name="rnd">The random source.</param>\r
- void Shuffle(Random rnd);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// The base type of a priority queue handle\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public interface IPriorityQueueHandle<T>\r
- {\r
- //TODO: make abstract and prepare for double dispatch:\r
- //public virtual bool Delete(IPriorityQueue<T> q) { throw new InvalidFooException();}\r
- //bool Replace(T item);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// A generic collection of items prioritized by a comparison (order) relation.\r
- /// Supports adding items and reporting or removing extremal elements. \r
- /// <para>\r
- /// \r
- /// </para>\r
- /// When adding an item, the user may choose to have a handle allocated for this item in the queue. \r
- /// The resulting handle may be used for deleting the item even if not extremal, and for replacing the item.\r
- /// A priority queue typically only holds numeric priorities associated with some objects\r
- /// maintained separately in other collection objects.\r
- /// </summary>\r
- public interface IPriorityQueue<T> : IExtensible<T>\r
- {\r
- /// <summary>\r
- /// Find the current least item of this priority queue.\r
- /// </summary>\r
- /// <returns>The least item.</returns>\r
- T FindMin();\r
-\r
-\r
- /// <summary>\r
- /// Remove the least item from this priority queue.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- T DeleteMin();\r
-\r
-\r
- /// <summary>\r
- /// Find the current largest item of this priority queue.\r
- /// </summary>\r
- /// <returns>The largest item.</returns>\r
- T FindMax();\r
-\r
-\r
- /// <summary>\r
- /// Remove the largest item from this priority queue.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- T DeleteMax();\r
-\r
- /// <summary>\r
- /// The comparer object supplied at creation time for this collection\r
- /// </summary>\r
- /// <value>The comparer</value>\r
- SCG.IComparer<T> Comparer { get;}\r
- /// <summary>\r
- /// Get or set the item corresponding to a handle. Throws exceptions on \r
- /// invalid handles.\r
- /// </summary>\r
- /// <param name="handle"></param>\r
- /// <returns></returns>\r
- T this[IPriorityQueueHandle<T> handle] { get; set;}\r
-\r
- /// <summary>\r
- /// Check if the entry corresponding to a handle is in the priority queue.\r
- /// </summary>\r
- /// <param name="handle"></param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- bool Find(IPriorityQueueHandle<T> handle, out T item);\r
-\r
- /// <summary>\r
- /// Add an item to the priority queue, receiving a \r
- /// handle for the item in the queue, \r
- /// or reusing an existing unused handle.\r
- /// </summary>\r
- /// <param name="handle">On output: a handle for the added item. \r
- /// On input: null for allocating a new handle, or a currently unused handle for reuse. \r
- /// A handle for reuse must be compatible with this priority queue, \r
- /// by being created by a priority queue of the same runtime type, but not \r
- /// necessarily the same priority queue object.</param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- bool Add(ref IPriorityQueueHandle<T> handle, T item);\r
-\r
- /// <summary>\r
- /// Delete an item with a handle from a priority queue\r
- /// </summary>\r
- /// <param name="handle">The handle for the item. The handle will be invalidated, but reusable.</param>\r
- /// <returns>The deleted item</returns>\r
- T Delete(IPriorityQueueHandle<T> handle);\r
-\r
- /// <summary>\r
- /// Replace an item with a handle in a priority queue with a new item. \r
- /// Typically used for changing the priority of some queued object.\r
- /// </summary>\r
- /// <param name="handle">The handle for the old item</param>\r
- /// <param name="item">The new item</param>\r
- /// <returns>The old item</returns>\r
- T Replace(IPriorityQueueHandle<T> handle, T item);\r
-\r
- /// <summary>\r
- /// Find the current least item of this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the item.</param>\r
- /// <returns>The least item.</returns>\r
- T FindMin(out IPriorityQueueHandle<T> handle);\r
-\r
- /// <summary>\r
- /// Find the current largest item of this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the item.</param>\r
- /// <returns>The largest item.</returns>\r
-\r
- T FindMax(out IPriorityQueueHandle<T> handle);\r
-\r
- /// <summary>\r
- /// Remove the least item from this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the removed item.</param>\r
- /// <returns>The removed item.</returns>\r
-\r
- T DeleteMin(out IPriorityQueueHandle<T> handle);\r
-\r
- /// <summary>\r
- /// Remove the largest item from this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the removed item.</param>\r
- /// <returns>The removed item.</returns>\r
- T DeleteMax(out IPriorityQueueHandle<T> handle);\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A sorted collection, i.e. a collection where items are maintained and can be searched for in sorted order.\r
- /// Thus the sequence order is given as a sorting order.\r
- /// \r
- /// <para>The sorting order is defined by a comparer, an object of type IComparer<T> \r
- /// (<see cref="T:C5.IComparer`1"/>). Implementors of this interface will normally let the user \r
- /// define the comparer as an argument to a constructor. \r
- /// Usually there will also be constructors without a comparer argument, in which case the \r
- /// comparer should be the defalt comparer for the item type, <see cref="P:C5.Comparer`1.Default"/>.</para>\r
- /// \r
- /// <para>The comparer of the sorted collection is available as the <code>Comparer</code> property \r
- /// (<see cref="P:C5.ISorted`1.Comparer"/>).</para>\r
- /// \r
- /// <para>The methods are grouped according to\r
- /// <list>\r
- /// <item>Extrema: report or report and delete an extremal item. This is reminiscent of simplified priority queues.</item>\r
- /// <item>Nearest neighbor: report predecessor or successor in the collection of an item. Cut belongs to this group.</item>\r
- /// <item>Range: report a view of a range of elements or remove all elements in a range.</item>\r
- /// <item>AddSorted: add a collection of items known to be sorted in the same order (should be faster) (to be removed?)</item>\r
- /// </list>\r
- /// </para>\r
- /// \r
- /// <para>Since this interface extends ISequenced<T>, sorted collections will also have an \r
- /// item equalityComparer (<see cref="P:C5.IExtensible`1.EqualityComparer"/>). This equalityComparer will not be used in connection with \r
- /// the inner workings of the sorted collection, but will be used if the sorted collection is used as \r
- /// an item in a collection of unsequenced or sequenced collections, \r
- /// (<see cref="T:C5.ICollection`1"/> and <see cref="T:C5.ISequenced`1"/>)</para>\r
- /// \r
- /// <para>Note that code may check if two sorted collections has the same sorting order \r
- /// by checking if the Comparer properties are equal. This is done a few places in this library\r
- /// for optimization purposes.</para>\r
- /// </summary>\r
- public interface ISorted<T> : ISequenced<T>\r
- {\r
- /// <summary>\r
- /// Find the current least item of this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The least item.</returns>\r
- T FindMin();\r
-\r
-\r
- /// <summary>\r
- /// Remove the least item from this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The removed item.</returns>\r
- T DeleteMin();\r
-\r
-\r
- /// <summary>\r
- /// Find the current largest item of this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The largest item.</returns>\r
- T FindMax();\r
-\r
-\r
- /// <summary>\r
- /// Remove the largest item from this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The removed item.</returns>\r
- T DeleteMax();\r
-\r
- /// <summary>\r
- /// The comparer object supplied at creation time for this sorted collection.\r
- /// </summary>\r
- /// <value>The comparer</value>\r
- SCG.IComparer<T> Comparer { get;}\r
-\r
- /// <summary>\r
- /// Find the strict predecessor in the sorted collection of a particular value,\r
- /// that is, the largest item in the collection less than the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is less than or equal to the minimum of this collection.)</exception>\r
- /// <param name="item">The item to find the predecessor for.</param>\r
- /// <returns>The predecessor.</returns>\r
- T Predecessor(T item);\r
-\r
-\r
- /// <summary>\r
- /// Find the strict successor in the sorted collection of a particular value,\r
- /// that is, the least item in the collection greater than the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is greater than or equal to the maximum of this collection.)</exception>\r
- /// <param name="item">The item to find the successor for.</param>\r
- /// <returns>The successor.</returns>\r
- T Successor(T item);\r
-\r
-\r
- /// <summary>\r
- /// Find the weak predecessor in the sorted collection of a particular value,\r
- /// that is, the largest item in the collection less than or equal to the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is less than the minimum of this collection.)</exception>\r
- /// <param name="item">The item to find the weak predecessor for.</param>\r
- /// <returns>The weak predecessor.</returns>\r
- T WeakPredecessor(T item);\r
-\r
-\r
- /// <summary>\r
- /// Find the weak successor in the sorted collection of a particular value,\r
- /// that is, the least item in the collection greater than or equal to the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is greater than the maximum of this collection.)</exception>\r
- ///<param name="item">The item to find the weak successor for.</param>\r
- /// <returns>The weak successor.</returns>\r
- T WeakSuccessor(T item);\r
-\r
-\r
- /// <summary>\r
- /// Given a "cut" function from the items of the sorted collection to <code>int</code>\r
- /// whose only sign changes when going through items in increasing order\r
- /// can be \r
- /// <list>\r
- /// <item>from positive to zero</item>\r
- /// <item>from positive to negative</item>\r
- /// <item>from zero to negative</item>\r
- /// </list>\r
- /// The "cut" function is supplied as the <code>CompareTo</code> method \r
- /// of an object <code>c</code> implementing \r
- /// <code>IComparable<T></code>. \r
- /// A typical example is the case where <code>T</code> is comparable and \r
- /// <code>cutFunction</code> is itself of type <code>T</code>.\r
- /// <para>This method performs a search in the sorted collection for the ranges in which the\r
- /// "cut" function is negative, zero respectively positive. If <code>T</code> is comparable\r
- /// and <code>c</code> is of type <code>T</code>, this is a safe way (no exceptions thrown) \r
- /// to find predecessor and successor of <code>c</code>.\r
- /// </para>\r
- /// <para> If the supplied cut function does not satisfy the sign-change condition, \r
- /// the result of this call is undefined.\r
- /// </para>\r
- /// \r
- /// </summary>\r
- /// <param name="cutFunction">The cut function <code>T</code> to <code>int</code>, given\r
- /// by the <code>CompareTo</code> method of an object implementing \r
- /// <code>IComparable<T></code>.</param>\r
- /// <param name="low">Returns the largest item in the collection, where the\r
- /// cut function is positive (if any).</param>\r
- /// <param name="lowIsValid">Returns true if the cut function is positive somewhere\r
- /// on this collection.</param>\r
- /// <param name="high">Returns the least item in the collection, where the\r
- /// cut function is negative (if any).</param>\r
- /// <param name="highIsValid">Returns true if the cut function is negative somewhere\r
- /// on this collection.</param>\r
- /// <returns>True if the cut function is zero somewhere\r
- /// on this collection.</returns>\r
- bool Cut(IComparable<T> cutFunction, out T low, out bool lowIsValid, out T high, out bool highIsValid);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items greater than or equal to a supplied value.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedEnumerable<T> RangeFrom(T bot);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items between two supplied values.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedEnumerable<T> RangeFromTo(T bot, T top);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items less than a supplied value.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedEnumerable<T> RangeTo(T top);\r
-\r
-\r
- /// <summary>\r
- /// Create a directed collection with the same items as this collection.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedCollectionValue<T> RangeAll();\r
-\r
-\r
- //TODO: remove now that we assume that we can check the sorting order?\r
- /// <summary>\r
- /// Add all the items from another collection with an enumeration order that \r
- /// is increasing in the items.\r
- /// </summary>\r
- /// <exception cref="ArgumentException"> if the enumerated items turns out\r
- /// not to be in increasing order.</exception>\r
- /// <param name="items">The collection to add.</param>\r
- /// <typeparam name="U"></typeparam>\r
- void AddSorted<U>(SCG.IEnumerable<U> items) where U : T;\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection above or at a supplied threshold.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- void RemoveRangeFrom(T low);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection between two supplied thresholds.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- void RemoveRangeFromTo(T low, T hi);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection below a supplied threshold.\r
- /// </summary>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- void RemoveRangeTo(T hi);\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A collection where items are maintained in sorted order together\r
- /// with their indexes in that order.\r
- /// </summary>\r
- public interface IIndexedSorted<T> : ISorted<T>, IIndexed<T>\r
- {\r
- /// <summary>\r
- /// Determine the number of items at or above a supplied threshold.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- int CountFrom(T bot);\r
-\r
-\r
- /// <summary>\r
- /// Determine the number of items between two supplied thresholds.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive)</param>\r
- /// <param name="top">The upper bound (exclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- int CountFromTo(T bot, T top);\r
-\r
-\r
- /// <summary>\r
- /// Determine the number of items below a supplied threshold.\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- int CountTo(T top);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items greater than or equal to a supplied value.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- new IDirectedCollectionValue<T> RangeFrom(T bot);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items between two supplied values.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- new IDirectedCollectionValue<T> RangeFromTo(T bot, T top);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items less than a supplied value.\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- new IDirectedCollectionValue<T> RangeTo(T top);\r
-\r
-\r
- /// <summary>\r
- /// Create a new indexed sorted collection consisting of the items of this\r
- /// indexed sorted collection satisfying a certain predicate.\r
- /// </summary>\r
- /// <param name="predicate">The filter delegate defining the predicate.</param>\r
- /// <returns>The new indexed sorted collection.</returns>\r
- IIndexedSorted<T> FindAll(Fun<T, bool> predicate);\r
-\r
-\r
- /// <summary>\r
- /// Create a new indexed sorted collection consisting of the results of\r
- /// mapping all items of this list.\r
- /// <exception cref="ArgumentException"/> if the map is not increasing over \r
- /// the items of this collection (with respect to the two given comparison \r
- /// relations).\r
- /// </summary>\r
- /// <param name="mapper">The delegate definging the map.</param>\r
- /// <param name="comparer">The comparion relation to use for the result.</param>\r
- /// <returns>The new sorted collection.</returns>\r
- IIndexedSorted<V> Map<V>(Fun<T, V> mapper, SCG.IComparer<V> comparer);\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// The type of a sorted collection with persistence\r
- /// </summary>\r
- public interface IPersistentSorted<T> : ISorted<T>, IDisposable\r
- {\r
- /// <summary>\r
- /// Make a (read-only) snap shot of this collection.\r
- /// </summary>\r
- /// <returns>The snap shot.</returns>\r
- ISorted<T> Snapshot();\r
- }\r
-\r
-\r
-\r
- /*************************************************************************/\r
- /// <summary>\r
- /// A dictionary with keys of type K and values of type V. Equivalent to a\r
- /// finite partial map from K to V.\r
- /// </summary>\r
- public interface IDictionary<K, V> : ICollectionValue<KeyValuePair<K, V>>, ICloneable\r
- {\r
- /// <summary>\r
- /// The key equalityComparer.\r
- /// </summary>\r
- /// <value></value>\r
- SCG.IEqualityComparer<K> EqualityComparer { get;}\r
-\r
- /// <summary>\r
- /// Indexer for dictionary.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no entry is found. </exception>\r
- /// <value>The value corresponding to the key</value>\r
- V this[K key] { get; set;}\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if dictionary is read-only</value>\r
- bool IsReadOnly { get;}\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>A collection containg the all the keys of the dictionary</value>\r
- ICollectionValue<K> Keys { get;}\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>A collection containing all the values of the dictionary</value>\r
- ICollectionValue<V> Values { get;}\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>A delegate of type <see cref="T:C5.Fun`2"/> defining the partial function from K to V give by the dictionary.</value>\r
- Fun<K, V> Fun { get; }\r
-\r
-\r
- //TODO: resolve inconsistency: Add thows exception if key already there, AddAll ignores keys already There?\r
- /// <summary>\r
- /// Add a new (key, value) pair (a mapping) to the dictionary.\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException"> if there already is an entry with the same key. </exception>>\r
- /// <param name="key">Key to add</param>\r
- /// <param name="val">Value to add</param>\r
- void Add(K key, V val);\r
-\r
- /// <summary>\r
- /// Add the entries from a collection of <see cref="T:C5.KeyValuePair`2"/> pairs to this dictionary.\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException"> \r
- /// If the input contains duplicate keys or a key already present in this dictionary.</exception>\r
- /// <param name="entries"></param>\r
- void AddAll<U, W>(SCG.IEnumerable<KeyValuePair<U, W>> entries)\r
- where U : K\r
- where W : V\r
- ;\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant). \r
- /// <para>See <see cref="T:C5.Speed"/> for the set of symbols.</para>\r
- /// </summary>\r
- /// <value>A characterization of the speed of lookup operations\r
- /// (<code>Contains()</code> etc.) of the implementation of this dictionary.</value>\r
- Speed ContainsSpeed { get;}\r
-\r
- /// <summary>\r
- /// Check whether this collection contains all the values in another collection.\r
- /// If this collection has bag semantics (<code>AllowsDuplicates==true</code>)\r
- /// the check is made with respect to multiplicities, else multiplicities\r
- /// are not taken into account.\r
- /// </summary>\r
- /// <param name="items">The </param>\r
- /// <returns>True if all values in <code>items</code>is in this collection.</returns>\r
- bool ContainsAll<H>(SCG.IEnumerable<H> items) where H : K;\r
-\r
- /// <summary>\r
- /// Remove an entry with a given key from the dictionary\r
- /// </summary>\r
- /// <param name="key">The key of the entry to remove</param>\r
- /// <returns>True if an entry was found (and removed)</returns>\r
- bool Remove(K key);\r
-\r
-\r
- /// <summary>\r
- /// Remove an entry with a given key from the dictionary and report its value.\r
- /// </summary>\r
- /// <param name="key">The key of the entry to remove</param>\r
- /// <param name="val">On exit, the value of the removed entry</param>\r
- /// <returns>True if an entry was found (and removed)</returns>\r
- bool Remove(K key, out V val);\r
-\r
-\r
- /// <summary>\r
- /// Remove all entries from the dictionary\r
- /// </summary>\r
- void Clear();\r
-\r
-\r
- /// <summary>\r
- /// Check if there is an entry with a specified key\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <returns>True if key was found</returns>\r
- bool Contains(K key);\r
-\r
-\r
- /// <summary>\r
- /// Check if there is an entry with a specified key and report the corresponding\r
- /// value if found. This can be seen as a safe form of "val = this[key]".\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="val">On exit, the value of the entry</param>\r
- /// <returns>True if key was found</returns>\r
- bool Find(K key, out V val);\r
-\r
- /// <summary>\r
- /// Check if there is an entry with a specified key and report the corresponding\r
- /// value if found. This can be seen as a safe form of "val = this[key]".\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="val">On exit, the value of the entry</param>\r
- /// <returns>True if key was found</returns>\r
- bool Find(ref K key, out V val);\r
-\r
-\r
- /// <summary>\r
- /// Look for a specific key in the dictionary and if found replace the value with a new one.\r
- /// This can be seen as a non-adding version of "this[key] = val".\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="val">The new value</param>\r
- /// <returns>True if key was found</returns>\r
- bool Update(K key, V val); //no-adding \r
-\r
-\r
- /// <summary>\r
- /// Look for a specific key in the dictionary and if found replace the value with a new one.\r
- /// This can be seen as a non-adding version of "this[key] = val" reporting the old value.\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="val">The new value</param>\r
- /// <param name="oldval">The old value if any</param>\r
- /// <returns>True if key was found</returns>\r
- bool Update(K key, V val, out V oldval); //no-adding \r
-\r
- /// <summary>\r
- /// Look for a specific key in the dictionary. If found, report the corresponding value,\r
- /// else add an entry with the key and the supplied value.\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="val">On entry the value to add if the key is not found.\r
- /// On exit the value found if any.</param>\r
- /// <returns>True if key was found</returns>\r
- bool FindOrAdd(K key, ref V val); //mixture\r
-\r
-\r
- /// <summary>\r
- /// Update value in dictionary corresponding to key if found, else add new entry.\r
- /// More general than "this[key] = val;" by reporting if key was found.\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="val">The value to add or replace with.</param>\r
- /// <returns>True if key was found and value updated.</returns>\r
- bool UpdateOrAdd(K key, V val);\r
-\r
-\r
- /// <summary>\r
- /// Update value in dictionary corresponding to key if found, else add new entry.\r
- /// More general than "this[key] = val;" by reporting if key was found.\r
- /// </summary>\r
- /// <param name="key">The key to look for</param>\r
- /// <param name="val">The value to add or replace with.</param>\r
- /// <param name="oldval">The old value if any</param>\r
- /// <returns>True if key was found and value updated.</returns>\r
- bool UpdateOrAdd(K key, V val, out V oldval);\r
-\r
-\r
- /// <summary>\r
- /// Check the integrity of the internal data structures of this dictionary.\r
- /// Only avaliable in DEBUG builds???\r
- /// </summary>\r
- /// <returns>True if check does not fail.</returns>\r
- bool Check();\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A dictionary with sorted keys.\r
- /// </summary>\r
- public interface ISortedDictionary<K, V> : IDictionary<K, V>\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- new ISorted<K> Keys { get;}\r
-\r
- /// <summary>\r
- /// Find the current least item of this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The least item.</returns>\r
- KeyValuePair<K, V> FindMin();\r
-\r
-\r
- /// <summary>\r
- /// Remove the least item from this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The removed item.</returns>\r
- KeyValuePair<K, V> DeleteMin();\r
-\r
-\r
- /// <summary>\r
- /// Find the current largest item of this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The largest item.</returns>\r
- KeyValuePair<K, V> FindMax();\r
-\r
-\r
- /// <summary>\r
- /// Remove the largest item from this sorted collection.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if the collection is empty.</exception>\r
- /// <returns>The removed item.</returns>\r
- KeyValuePair<K, V> DeleteMax();\r
-\r
- /// <summary>\r
- /// The key comparer used by this dictionary.\r
- /// </summary>\r
- /// <value></value>\r
- SCG.IComparer<K> Comparer { get;}\r
-\r
- /// <summary>\r
- /// Find the entry with the largest key less than a given key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if there is no such entry. </exception>\r
- /// <param name="key">The key to compare to</param>\r
- /// <returns>The entry</returns>\r
- KeyValuePair<K, V> Predecessor(K key);\r
-\r
-\r
- /// <summary>\r
- /// Find the entry with the least key greater than a given key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if there is no such entry. </exception>\r
- /// <param name="key">The key to compare to</param>\r
- /// <returns>The entry</returns>\r
- KeyValuePair<K, V> Successor(K key);\r
-\r
-\r
- /// <summary>\r
- /// Find the entry with the largest key less than or equal to a given key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if there is no such entry. </exception>\r
- /// <param name="key">The key to compare to</param>\r
- /// <returns>The entry</returns>\r
- KeyValuePair<K, V> WeakPredecessor(K key);\r
-\r
-\r
- /// <summary>\r
- /// Find the entry with the least key greater than or equal to a given key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if there is no such entry. </exception>\r
- /// <param name="key">The key to compare to</param>\r
- /// <returns>The entry</returns>\r
- KeyValuePair<K, V> WeakSuccessor(K key);\r
-\r
- /// <summary>\r
- /// Given a "cut" function from the items of the sorted collection to <code>int</code>\r
- /// whose only sign changes when going through items in increasing order\r
- /// can be \r
- /// <list>\r
- /// <item>from positive to zero</item>\r
- /// <item>from positive to negative</item>\r
- /// <item>from zero to negative</item>\r
- /// </list>\r
- /// The "cut" function is supplied as the <code>CompareTo</code> method \r
- /// of an object <code>c</code> implementing \r
- /// <code>IComparable<K></code>. \r
- /// A typical example is the case where <code>K</code> is comparable and \r
- /// <code>c</code> is itself of type <code>K</code>.\r
- /// <para>This method performs a search in the sorted collection for the ranges in which the\r
- /// "cut" function is negative, zero respectively positive. If <code>K</code> is comparable\r
- /// and <code>c</code> is of type <code>K</code>, this is a safe way (no exceptions thrown) \r
- /// to find predecessor and successor of <code>c</code>.\r
- /// </para>\r
- /// <para> If the supplied cut function does not satisfy the sign-change condition, \r
- /// the result of this call is undefined.\r
- /// </para>\r
- /// \r
- /// </summary>\r
- /// <param name="cutFunction">The cut function <code>K</code> to <code>int</code>, given\r
- /// by the <code>CompareTo</code> method of an object implementing \r
- /// <code>IComparable<K></code>.</param>\r
- /// <param name="lowEntry">Returns the largest item in the collection, where the\r
- /// cut function is positive (if any).</param>\r
- /// <param name="lowIsValid">Returns true if the cut function is positive somewhere\r
- /// on this collection.</param>\r
- /// <param name="highEntry">Returns the least item in the collection, where the\r
- /// cut function is negative (if any).</param>\r
- /// <param name="highIsValid">Returns true if the cut function is negative somewhere\r
- /// on this collection.</param>\r
- /// <returns>True if the cut function is zero somewhere\r
- /// on this collection.</returns>\r
- bool Cut(IComparable<K> cutFunction, out KeyValuePair<K, V> lowEntry, out bool lowIsValid, out KeyValuePair<K, V> highEntry, out bool highIsValid);\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items greater than or equal to a supplied value.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedEnumerable<KeyValuePair<K, V>> RangeFrom(K bot);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items between two supplied values.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <param name="lowerBound">The lower bound (inclusive).</param>\r
- /// <param name="upperBound">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedEnumerable<KeyValuePair<K, V>> RangeFromTo(K lowerBound, K upperBound);\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items less than a supplied value.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedEnumerable<KeyValuePair<K, V>> RangeTo(K top);\r
-\r
-\r
- /// <summary>\r
- /// Create a directed collection with the same items as this collection.\r
- /// <para>The returned collection is not a copy but a view into the collection.</para>\r
- /// <para>The view is fragile in the sense that changes to the underlying collection will \r
- /// invalidate the view so that further operations on the view throws InvalidView exceptions.</para>\r
- /// </summary>\r
- /// <returns>The result directed collection.</returns>\r
- IDirectedCollectionValue<KeyValuePair<K, V>> RangeAll();\r
-\r
-\r
- //TODO: remove now that we assume that we can check the sorting order?\r
- /// <summary>\r
- /// Add all the items from another collection with an enumeration order that \r
- /// is increasing in the items.\r
- /// </summary>\r
- /// <exception cref="ArgumentException"> if the enumerated items turns out\r
- /// not to be in increasing order.</exception>\r
- /// <param name="items">The collection to add.</param>\r
- void AddSorted(SCG.IEnumerable<KeyValuePair<K, V>> items);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection above or at a supplied threshold.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- void RemoveRangeFrom(K low);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection between two supplied thresholds.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- void RemoveRangeFromTo(K low, K hi);\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection below a supplied threshold.\r
- /// </summary>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- void RemoveRangeTo(K hi);\r
- }\r
-\r
-\r
-\r
- /*******************************************************************/\r
- /*/// <summary>\r
- /// The type of an item comparer\r
- /// <i>Implementations of this interface must asure that the method is self-consistent\r
- /// and defines a sorting order on items, or state precise conditions under which this is true.</i>\r
- /// <i>Implementations <b>must</b> assure that repeated calls of\r
- /// the method to the same (in reference or binary identity sense) arguments \r
- /// will return values with the same sign (-1, 0 or +1), or state precise conditions\r
- /// under which the user \r
- /// can be assured repeated calls will return the same sign.</i>\r
- /// <i>Implementations of this interface must always return values from the method\r
- /// and never throw exceptions.</i>\r
- /// <i>This interface is identical to System.Collections.Generic.IComparer<T></i>\r
- /// </summary>\r
- public interface IComparer<T>\r
- {\r
- /// <summary>\r
- /// Compare two items with respect to this item comparer\r
- /// </summary>\r
- /// <param name="item1">First item</param>\r
- /// <param name="item2">Second item</param>\r
- /// <returns>Positive if item1 is greater than item2, 0 if they are equal, negative if item1 is less than item2</returns>\r
- int Compare(T item1, T item2);\r
- }\r
-\r
- /// <summary>\r
- /// The type of an item equalityComparer. \r
- /// <i>Implementations of this interface <b>must</b> assure that the methods are \r
- /// consistent, that is, that whenever two items i1 and i2 satisfies that Equals(i1,i2)\r
- /// returns true, then GetHashCode returns the same value for i1 and i2.</i>\r
- /// <i>Implementations of this interface <b>must</b> assure that repeated calls of\r
- /// the methods to the same (in reference or binary identity sense) arguments \r
- /// will return the same values, or state precise conditions under which the user \r
- /// can be assured repeated calls will return the same values.</i>\r
- /// <i>Implementations of this interface must always return values from the methods\r
- /// and never throw exceptions.</i>\r
- /// <i>This interface is similar in function to System.IKeyComparer<T></i>\r
- /// </summary>\r
- public interface SCG.IEqualityComparer<T>\r
- {\r
- /// <summary>\r
- /// Get the hash code with respect to this item equalityComparer\r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- /// <returns>The hash code</returns>\r
- int GetHashCode(T item);\r
-\r
-\r
- /// <summary>\r
- /// Check if two items are equal with respect to this item equalityComparer\r
- /// </summary>\r
- /// <param name="item1">first item</param>\r
- /// <param name="item2">second item</param>\r
- /// <returns>True if equal</returns>\r
- bool Equals(T item1, T item2);\r
- }*/\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- abstract class MappedDirectedCollectionValue<T, V> : DirectedCollectionValueBase<V>, IDirectedCollectionValue<V>\r
- {\r
- IDirectedCollectionValue<T> directedcollectionvalue;\r
-\r
- abstract public V Map(T item);\r
-\r
- public MappedDirectedCollectionValue(IDirectedCollectionValue<T> directedcollectionvalue)\r
- {\r
- this.directedcollectionvalue = directedcollectionvalue;\r
- }\r
-\r
- public override V Choose() { return Map(directedcollectionvalue.Choose()); }\r
-\r
- public override bool IsEmpty { get { return directedcollectionvalue.IsEmpty; } }\r
-\r
- public override int Count { get { return directedcollectionvalue.Count; } }\r
-\r
- public override Speed CountSpeed { get { return directedcollectionvalue.CountSpeed; } }\r
-\r
- public override IDirectedCollectionValue<V> Backwards()\r
- {\r
- MappedDirectedCollectionValue<T, V> retval = (MappedDirectedCollectionValue<T, V>)MemberwiseClone();\r
- retval.directedcollectionvalue = directedcollectionvalue.Backwards();\r
- return retval;\r
- //If we made this classs non-abstract we could do\r
- //return new MappedDirectedCollectionValue<T,V>(directedcollectionvalue.Backwards());;\r
- }\r
-\r
-\r
- public override SCG.IEnumerator<V> GetEnumerator()\r
- {\r
- foreach (T item in directedcollectionvalue)\r
- yield return Map(item);\r
- }\r
-\r
- public override EnumerationDirection Direction\r
- {\r
- get { return directedcollectionvalue.Direction; }\r
- }\r
-\r
- IDirectedEnumerable<V> IDirectedEnumerable<V>.Backwards()\r
- {\r
- return Backwards();\r
- }\r
-\r
-\r
- }\r
-\r
- abstract class MappedCollectionValue<T, V> : CollectionValueBase<V>, ICollectionValue<V>\r
- {\r
- ICollectionValue<T> collectionvalue;\r
-\r
- abstract public V Map(T item);\r
-\r
- public MappedCollectionValue(ICollectionValue<T> collectionvalue)\r
- {\r
- this.collectionvalue = collectionvalue;\r
- }\r
-\r
- public override V Choose() { return Map(collectionvalue.Choose()); }\r
-\r
- public override bool IsEmpty { get { return collectionvalue.IsEmpty; } }\r
-\r
- public override int Count { get { return collectionvalue.Count; } }\r
-\r
- public override Speed CountSpeed { get { return collectionvalue.CountSpeed; } }\r
-\r
- public override SCG.IEnumerator<V> GetEnumerator()\r
- {\r
- foreach (T item in collectionvalue)\r
- yield return Map(item);\r
- }\r
- }\r
- \r
- class MultiplicityOne<K> : MappedCollectionValue<K, KeyValuePair<K, int>>\r
- {\r
- public MultiplicityOne(ICollectionValue<K> coll):base(coll) { }\r
- public override KeyValuePair<K, int> Map(K k) { return new KeyValuePair<K, int>(k, 1); }\r
- }\r
-\r
- class DropMultiplicity<K> : MappedCollectionValue<KeyValuePair<K, int>, K>\r
- {\r
- public DropMultiplicity(ICollectionValue<KeyValuePair<K, int>> coll):base(coll) { }\r
- public override K Map(KeyValuePair<K, int> kvp) { return kvp.Key; }\r
- }\r
- \r
- abstract class MappedDirectedEnumerable<T, V> : EnumerableBase<V>, IDirectedEnumerable<V>\r
- {\r
- IDirectedEnumerable<T> directedenumerable;\r
-\r
- abstract public V Map(T item);\r
-\r
- public MappedDirectedEnumerable(IDirectedEnumerable<T> directedenumerable)\r
- {\r
- this.directedenumerable = directedenumerable;\r
- }\r
-\r
- public IDirectedEnumerable<V> Backwards()\r
- {\r
- MappedDirectedEnumerable<T, V> retval = (MappedDirectedEnumerable<T, V>)MemberwiseClone();\r
- retval.directedenumerable = directedenumerable.Backwards();\r
- return retval;\r
- //If we made this classs non-abstract we could do\r
- //return new MappedDirectedCollectionValue<T,V>(directedcollectionvalue.Backwards());;\r
- }\r
-\r
-\r
- public override SCG.IEnumerator<V> GetEnumerator()\r
- {\r
- foreach (T item in directedenumerable)\r
- yield return Map(item);\r
- }\r
-\r
- public EnumerationDirection Direction\r
- {\r
- get { return directedenumerable.Direction; }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A modern random number generator based on G. Marsaglia: \r
- /// Seeds for Random Number Generators, Communications of the\r
- /// ACM 46, 5 (May 2003) 90-93; and a posting by Marsaglia to \r
- /// comp.lang.c on 2003-04-03.\r
- /// </summary>\r
- public class C5Random : Random\r
- {\r
- private uint[] Q = new uint[16];\r
-\r
- private uint c = 362436, i = 15;\r
-\r
-\r
- private uint Cmwc()\r
- {\r
- ulong t, a = 487198574UL;\r
- uint x, r = 0xfffffffe;\r
-\r
- i = (i + 1) & 15;\r
- t = a * Q[i] + c;\r
- c = (uint)(t >> 32);\r
- x = (uint)(t + c);\r
- if (x < c)\r
- {\r
- x++;\r
- c++;\r
- }\r
-\r
- return Q[i] = r - x;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get a new random System.Double value\r
- /// </summary>\r
- /// <returns>The random double</returns>\r
- public override double NextDouble()\r
- {\r
- return Cmwc() / 4294967296.0;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get a new random System.Double value\r
- /// </summary>\r
- /// <returns>The random double</returns>\r
- protected override double Sample()\r
- {\r
- return NextDouble();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get a new random System.Int32 value\r
- /// </summary>\r
- /// <returns>The random int</returns>\r
- public override int Next()\r
- {\r
- return (int)Cmwc();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get a random non-negative integer less than a given upper bound\r
- /// </summary>\r
- /// <exception cref="ArgumentException">If max is negative</exception>\r
- /// <param name="max">The upper bound (exclusive)</param>\r
- /// <returns></returns>\r
- public override int Next(int max)\r
- {\r
- if (max < 0)\r
- throw new ArgumentException("max must be non-negative");\r
-\r
- return (int)(Cmwc() / 4294967296.0 * max);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Get a random integer between two given bounds\r
- /// </summary>\r
- /// <exception cref="ArgumentException">If max is less than min</exception>\r
- /// <param name="min">The lower bound (inclusive)</param>\r
- /// <param name="max">The upper bound (exclusive)</param>\r
- /// <returns></returns>\r
- public override int Next(int min, int max)\r
- {\r
- if (min > max)\r
- throw new ArgumentException("min must be less than or equal to max");\r
-\r
- return min + (int)(Cmwc() / 4294967296.0 * (max - min));\r
- }\r
-\r
- /// <summary>\r
- /// Fill a array of byte with random bytes\r
- /// </summary>\r
- /// <param name="buffer">The array to fill</param>\r
- public override void NextBytes(byte[] buffer)\r
- {\r
- for (int i = 0, length = buffer.Length; i < length; i++)\r
- buffer[i] = (byte)Cmwc();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a random number generator seed by system time.\r
- /// </summary>\r
- public C5Random() : this(DateTime.Now.Ticks)\r
- {\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a random number generator with a given seed\r
- /// </summary>\r
- /// <exception cref="ArgumentException">If seed is zero</exception>\r
- /// <param name="seed">The seed</param>\r
- public C5Random(long seed)\r
- {\r
- if (seed == 0)\r
- throw new ArgumentException("Seed must be non-zero");\r
-\r
- uint j = (uint)(seed & 0xFFFFFFFF);\r
-\r
- for (int i = 0; i < 16; i++)\r
- {\r
- j ^= j << 13;\r
- j ^= j >> 17;\r
- j ^= j << 5;\r
- Q[i] = j;\r
- }\r
-\r
- Q[15] = (uint)(seed ^ (seed >> 32));\r
- }\r
-\r
- /// <summary>\r
- /// Create a random number generator with a specified internal start state.\r
- /// </summary>\r
- /// <exception cref="ArgumentException">If Q is not of length exactly 16</exception>\r
- /// <param name="Q">The start state. Must be a collection of random bits given by an array of exactly 16 uints.</param>\r
- public C5Random(uint[] Q)\r
- {\r
- if (Q.Length != 16)\r
- throw new ArgumentException("Q must have length 16, was " + Q.Length);\r
- Array.Copy(Q, this.Q, 16);\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using C5;\r
-using System;\r
-using System.Reflection;\r
-using System.Reflection.Emit;\r
-using System.Diagnostics;\r
-\r
-namespace C5\r
-{\r
- struct RecConst\r
- {\r
- public const int HASHFACTOR = 387281;\r
- }\r
- /// <summary>\r
- /// A generic record type with two fields. \r
- /// <para>\r
- /// Equality is defined field by field, using the <code>Equals</code> method \r
- /// inherited from <code>System.Object</code> (i.e. using <see cref="T:C5.NaturalEqualityComparer`1"/>).\r
- /// </para>\r
- /// <para>\r
- /// This type is similar to <see cref="T:C5.KeyValuePair`2"/>, but the latter\r
- /// uses <see cref="P:C5.EqualityComparer`1.Default"/> to define field equality instead of <see cref="T:C5.NaturalEqualityComparer`1"/>.\r
- /// </para>\r
- /// </summary>\r
- /// <typeparam name="T1"></typeparam>\r
- /// <typeparam name="T2"></typeparam>\r
- public struct Rec<T1, T2> : IEquatable<Rec<T1, T2>>, IShowable\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T1 X1;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T2 X2;\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- [Tested]\r
- public Rec(T1 x1, T2 x2)\r
- {\r
- this.X1 = x1; this.X2 = x2;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="other"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public bool Equals(Rec<T1, T2> other)\r
- {\r
- return\r
- (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&\r
- (X2 == null ? other.X2 == null : X2.Equals(other.X2))\r
- ;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="obj"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public override bool Equals(object obj)\r
- {\r
- return obj is Rec<T1, T2> ? Equals((Rec<T1, T2>)obj) : false;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="record1"></param>\r
- /// <param name="record2"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public static bool operator ==(Rec<T1, T2> record1, Rec<T1, T2> record2)\r
- {\r
- return record1.Equals(record2);\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="record1"></param>\r
- /// <param name="record2"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public static bool operator !=(Rec<T1, T2> record1, Rec<T1, T2> record2)\r
- {\r
- return !record1.Equals(record2);\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public override int GetHashCode()\r
- {\r
- //TODO: don't use 0 as hashcode for null, but something else!\r
- int hashcode = X1 == null ? 0 : X1.GetHashCode();\r
- hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());\r
- return hashcode;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return String.Format("({0}, {1})", X1, X2);\r
- }\r
-\r
- #region IShowable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- bool incomplete = true;\r
- stringbuilder.Append("(");\r
- rest -= 2;\r
- try\r
- {\r
- if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- }\r
- finally\r
- {\r
- if (incomplete)\r
- {\r
- stringbuilder.Append("...");\r
- rest -= 3;\r
- }\r
- stringbuilder.Append(")");\r
- }\r
- return true;\r
- }\r
- #endregion\r
-\r
- #region IFormattable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public string ToString(string format, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowString(this, format, formatProvider);\r
- }\r
-\r
- #endregion\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T1"></typeparam>\r
- /// <typeparam name="T2"></typeparam>\r
- /// <typeparam name="T3"></typeparam>\r
- public struct Rec<T1, T2, T3> : IEquatable<Rec<T1, T2, T3>>, IShowable\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T1 X1;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T2 X2;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T3 X3;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- /// <param name="x3"></param>\r
- [Tested]\r
- public Rec(T1 x1, T2 x2, T3 x3)\r
- {\r
- this.X1 = x1; this.X2 = x2; this.X3 = x3;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="other"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public bool Equals(Rec<T1, T2, T3> other)\r
- {\r
- return\r
- (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&\r
- (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&\r
- (X3 == null ? other.X3 == null : X3.Equals(other.X3))\r
- ;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="obj"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public override bool Equals(object obj)\r
- {\r
- return obj is Rec<T1, T2, T3> ? Equals((Rec<T1, T2, T3>)obj) : false;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="record1"></param>\r
- /// <param name="record2"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public static bool operator ==(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)\r
- {\r
- return record1.Equals(record2);\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="record1"></param>\r
- /// <param name="record2"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public static bool operator !=(Rec<T1, T2, T3> record1, Rec<T1, T2, T3> record2)\r
- {\r
- return !record1.Equals(record2);\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public override int GetHashCode()\r
- {\r
- //TODO: don't use 0 as hashcode for null, but something else!\r
- int hashcode = X1 == null ? 0 : X1.GetHashCode();\r
- hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());\r
- hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());\r
- return hashcode;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return String.Format("({0}, {1}, {2})", X1, X2, X3);\r
- }\r
- #region IShowable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- bool incomplete = true;\r
- stringbuilder.Append("(");\r
- rest -= 2;\r
- try\r
- {\r
- if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- }\r
- finally\r
- {\r
- if (incomplete)\r
- {\r
- stringbuilder.Append("...");\r
- rest -= 3;\r
- }\r
- stringbuilder.Append(")");\r
- }\r
- return true;\r
- }\r
- #endregion\r
-\r
- #region IFormattable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public string ToString(string format, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowString(this, format, formatProvider);\r
- }\r
-\r
- #endregion\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T1"></typeparam>\r
- /// <typeparam name="T2"></typeparam>\r
- /// <typeparam name="T3"></typeparam>\r
- /// <typeparam name="T4"></typeparam>\r
- public struct Rec<T1, T2, T3, T4> : IEquatable<Rec<T1, T2, T3, T4>>, IShowable\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T1 X1;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T2 X2;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T3 X3;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public readonly T4 X4;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="x1"></param>\r
- /// <param name="x2"></param>\r
- /// <param name="x3"></param>\r
- /// <param name="x4"></param>\r
- [Tested]\r
- public Rec(T1 x1, T2 x2, T3 x3, T4 x4)\r
- {\r
- this.X1 = x1; this.X2 = x2; this.X3 = x3; this.X4 = x4;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="other"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public bool Equals(Rec<T1, T2, T3, T4> other)\r
- {\r
- return\r
- (X1 == null ? other.X1 == null : X1.Equals(other.X1)) &&\r
- (X2 == null ? other.X2 == null : X2.Equals(other.X2)) &&\r
- (X3 == null ? other.X3 == null : X3.Equals(other.X3)) &&\r
- (X4 == null ? other.X4 == null : X4.Equals(other.X4))\r
- ;\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="obj"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public override bool Equals(object obj)\r
- {\r
- return obj is Rec<T1, T2, T3, T4> ? Equals((Rec<T1, T2, T3, T4>)obj) : false;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="record1"></param>\r
- /// <param name="record2"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public static bool operator ==(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)\r
- {\r
- return record1.Equals(record2);\r
- }\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="record1"></param>\r
- /// <param name="record2"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public static bool operator !=(Rec<T1, T2, T3, T4> record1, Rec<T1, T2, T3, T4> record2)\r
- {\r
- return !record1.Equals(record2);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public override int GetHashCode()\r
- {\r
- //TODO: don't use 0 as hashcode for null, but something else!\r
- int hashcode = X1 == null ? 0 : X1.GetHashCode();\r
- hashcode = hashcode * RecConst.HASHFACTOR + (X2 == null ? 0 : X2.GetHashCode());\r
- hashcode = hashcode * RecConst.HASHFACTOR + (X3 == null ? 0 : X3.GetHashCode());\r
- hashcode = hashcode * RecConst.HASHFACTOR + (X4 == null ? 0 : X4.GetHashCode());\r
- return hashcode;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString()\r
- {\r
- return String.Format("({0}, {1}, {2}, {3})", X1, X2, X3, X4);\r
- }\r
- #region IShowable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- bool incomplete = true;\r
- stringbuilder.Append("(");\r
- rest -= 2;\r
- try\r
- {\r
- if (incomplete = !Showing.Show(X1, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- if (incomplete = !Showing.Show(X2, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- if (incomplete = !Showing.Show(X3, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- stringbuilder.Append(", ");\r
- rest -= 2;\r
- if (incomplete = !Showing.Show(X4, stringbuilder, ref rest, formatProvider))\r
- return false;\r
- }\r
- finally\r
- {\r
- if (incomplete)\r
- {\r
- stringbuilder.Append("...");\r
- rest -= 3;\r
- }\r
- stringbuilder.Append(")");\r
- }\r
- return true;\r
- }\r
- #endregion\r
-\r
- #region IFormattable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public string ToString(string format, IFormatProvider formatProvider)\r
- {\r
- return Showing.ShowString(this, format, formatProvider);\r
- }\r
-\r
- #endregion\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A utility class with functions for sorting arrays with respect to an IComparer<T>\r
- /// </summary>\r
- public class Sorting\r
- {\r
- Sorting() { }\r
-\r
- /// <summary>\r
- /// Sort part of array in place using IntroSort\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException">If the <code>start</code>\r
- /// and <code>count</code> arguments does not describe a valid range.</exception>\r
- /// <param name="array">Array to sort</param>\r
- /// <param name="start">Index of first position to sort</param>\r
- /// <param name="count">Number of elements to sort</param>\r
- /// <param name="comparer">IComparer<T> to sort by</param>\r
- [Tested]\r
- public static void IntroSort<T>(T[] array, int start, int count, SCG.IComparer<T> comparer)\r
- {\r
- if (start < 0 || count < 0 || start + count > array.Length)\r
- throw new ArgumentOutOfRangeException();\r
- new Sorter<T>(array, comparer).IntroSort(start, start + count);\r
- }\r
-\r
- /// <summary>\r
- /// Sort an array in place using IntroSort and default comparer\r
- /// </summary>\r
- /// <exception cref="NotComparableException">If T is not comparable</exception>\r
- /// <param name="array">Array to sort</param>\r
- [Tested]\r
- public static void IntroSort<T>(T[] array)\r
- {\r
- new Sorter<T>(array, Comparer<T>.Default).IntroSort(0, array.Length);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Sort part of array in place using Insertion Sort\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException">If the <code>start</code>\r
- /// and <code>count</code> arguments does not describe a valid range.</exception>\r
- /// <param name="array">Array to sort</param>\r
- /// <param name="start">Index of first position to sort</param>\r
- /// <param name="count">Number of elements to sort</param>\r
- /// <param name="comparer">IComparer<T> to sort by</param>\r
- [Tested]\r
- public static void InsertionSort<T>(T[] array, int start, int count, SCG.IComparer<T> comparer)\r
- {\r
- if (start < 0 || count < 0 || start + count > array.Length)\r
- throw new ArgumentOutOfRangeException();\r
- new Sorter<T>(array, comparer).InsertionSort(start, start + count);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Sort part of array in place using Heap Sort\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException">If the <code>start</code>\r
- /// and <code>count</code> arguments does not describe a valid range.</exception>\r
- /// <param name="array">Array to sort</param>\r
- /// <param name="start">Index of first position to sort</param>\r
- /// <param name="count">Number of elements to sort</param>\r
- /// <param name="comparer">IComparer<T> to sort by</param>\r
- [Tested]\r
- public static void HeapSort<T>(T[] array, int start, int count, SCG.IComparer<T> comparer)\r
- {\r
- if (start < 0 || count < 0 || start + count > array.Length)\r
- throw new ArgumentOutOfRangeException();\r
- new Sorter<T>(array, comparer).HeapSort(start, start + count);\r
- }\r
-\r
-\r
- class Sorter<T>\r
- {\r
- T[] a;\r
-\r
- SCG.IComparer<T> c;\r
-\r
-\r
- internal Sorter(T[] a, SCG.IComparer<T> c) { this.a = a; this.c = c; }\r
-\r
-\r
- internal void IntroSort(int f, int b)\r
- {\r
- if (b - f > 31)\r
- {\r
- int depth_limit = (int)Math.Floor(2.5 * Math.Log(b - f, 2));\r
-\r
- introSort(f, b, depth_limit);\r
- }\r
- else\r
- InsertionSort(f, b);\r
- }\r
-\r
-\r
- private void introSort(int f, int b, int depth_limit)\r
- {\r
- const int size_threshold = 14;//24;\r
-\r
- if (depth_limit-- == 0)\r
- HeapSort(f, b);\r
- else if (b - f <= size_threshold)\r
- InsertionSort(f, b);\r
- else\r
- {\r
- int p = partition(f, b);\r
-\r
- introSort(f, p, depth_limit);\r
- introSort(p, b, depth_limit);\r
- }\r
- }\r
-\r
-\r
- private int compare(T i1, T i2) { return c.Compare(i1, i2); }\r
-\r
-\r
- private int partition(int f, int b)\r
- {\r
- int bot = f, mid = (b + f) / 2, top = b - 1;\r
- T abot = a[bot], amid = a[mid], atop = a[top];\r
-\r
- if (compare(abot, amid) < 0)\r
- {\r
- if (compare(atop, abot) < 0)//atop<abot<amid\r
- { a[top] = amid; amid = a[mid] = abot; a[bot] = atop; }\r
- else if (compare(atop, amid) < 0) //abot<=atop<amid\r
- { a[top] = amid; amid = a[mid] = atop; }\r
- //else abot<amid<=atop\r
- }\r
- else\r
- {\r
- if (compare(amid, atop) > 0) //atop<amid<=abot\r
- { a[bot] = atop; a[top] = abot; }\r
- else if (compare(abot, atop) > 0) //amid<=atop<abot\r
- { a[bot] = amid; amid = a[mid] = atop; a[top] = abot; }\r
- else //amid<=abot<=atop\r
- { a[bot] = amid; amid = a[mid] = abot; }\r
- }\r
-\r
- int i = bot, j = top;\r
-\r
- while (true)\r
- {\r
- while (compare(a[++i], amid) < 0) ;\r
-\r
- while (compare(amid, a[--j]) < 0) ;\r
-\r
- if (i < j)\r
- {\r
- T tmp = a[i]; a[i] = a[j]; a[j] = tmp;\r
- }\r
- else\r
- return i;\r
- }\r
- }\r
-\r
-\r
- internal void InsertionSort(int f, int b)\r
- {\r
- for (int j = f + 1; j < b; j++)\r
- {\r
- T key = a[j], other;\r
- int i = j - 1;\r
-\r
- if (c.Compare(other = a[i], key) > 0)\r
- {\r
- a[j] = other;\r
- while (i > f && c.Compare(other = a[i - 1], key) > 0) { a[i--] = other; }\r
-\r
- a[i] = key;\r
- }\r
- }\r
- }\r
-\r
-\r
- internal void HeapSort(int f, int b)\r
- {\r
- for (int i = (b + f) / 2; i >= f; i--) heapify(f, b, i);\r
-\r
- for (int i = b - 1; i > f; i--)\r
- {\r
- T tmp = a[f]; a[f] = a[i]; a[i] = tmp;\r
- heapify(f, i, f);\r
- }\r
- }\r
-\r
-\r
- private void heapify(int f, int b, int i)\r
- {\r
- T pv = a[i], lv, rv, max = pv;\r
- int j = i, maxpt = j;\r
-\r
- while (true)\r
- {\r
- int l = 2 * j - f + 1, r = l + 1;\r
-\r
- if (l < b && compare(lv = a[l], max) > 0) { maxpt = l; max = lv; }\r
-\r
- if (r < b && compare(rv = a[r], max) > 0) { maxpt = r; max = rv; }\r
-\r
- if (maxpt == j)\r
- break;\r
-\r
- a[j] = max;\r
- max = pv;\r
- j = maxpt;\r
- }\r
-\r
- if (j > i)\r
- a[j] = pv;\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// Characterize the mutual position of some view B (other) relative to view A (this)\r
- /// </summary>\r
- enum MutualViewPosition\r
- {\r
- /// <summary>\r
- /// B contains A(this)\r
- /// </summary>\r
- Contains,\r
- /// <summary>\r
- /// B is containd in A(this), but not vice versa\r
- /// </summary>\r
- ContainedIn,\r
- /// <summary>\r
- /// A and B does not overlap\r
- /// </summary>\r
- NonOverlapping,\r
- /// <summary>\r
- /// A and B overlap, but neither is contained in the other\r
- /// </summary>\r
- Overlapping\r
- }\r
-\r
- #region View List Nested class\r
- /// <summary>\r
- /// This class is shared between the linked list and array list implementations.\r
- /// </summary>\r
- /// <typeparam name="V"></typeparam>\r
- [Serializable]\r
- class WeakViewList<V> where V : class\r
- {\r
- Node start;\r
- [Serializable]\r
- internal class Node\r
- {\r
- internal WeakReference weakview; internal Node prev, next;\r
- internal Node(V view) { weakview = new WeakReference(view); }\r
- }\r
- internal Node Add(V view)\r
- {\r
- Node newNode = new Node(view);\r
- if (start != null) { start.prev = newNode; newNode.next = start; }\r
- start = newNode;\r
- return newNode;\r
- }\r
- internal void Remove(Node n)\r
- {\r
- if (n == start) { start = start.next; if (start != null) start.prev = null; }\r
- else { n.prev.next = n.next; if (n.next != null) n.next.prev = n.prev; }\r
- }\r
- /// <summary>\r
- /// Note that it is safe to call views.Remove(view.myWeakReference) if view\r
- /// is the currently yielded object\r
- /// </summary>\r
- /// <returns></returns>\r
- public SCG.IEnumerator<V> GetEnumerator()\r
- {\r
- Node n = start;\r
- while (n != null)\r
- {\r
- //V view = n.weakview.Target as V; //This provokes a bug in the beta1 verifyer\r
- object o = n.weakview.Target;\r
- V view = o is V ? (V)o : null;\r
- if (view == null)\r
- Remove(n);\r
- else\r
- yield return view;\r
- n = n.next;\r
- }\r
- }\r
- }\r
-\r
- #endregion\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Text;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// An advanced interface to operations on an array. The array is viewed as an \r
- /// <see cref="T:C5.IList`1"/> of fixed size, and so all operations that would change the\r
- /// size of the array will be invalid (and throw <see cref="T:C5.FixedSizeCollectionException"/>\r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class WrappedArray<T> : IList<T>\r
- {\r
- class InnerList : ArrayList<T>\r
- {\r
- internal InnerList(T[] array) { this.array = array; size = array.Length; }\r
- }\r
- ArrayList<T> innerlist;\r
- //TODO: remember a ref to the wrapped array in WrappedArray to save a little on indexing?\r
- WrappedArray<T> underlying;\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="wrappedarray"></param>\r
- public WrappedArray(T[] wrappedarray) { innerlist = new InnerList(wrappedarray); }\r
-\r
- //for views\r
- WrappedArray(ArrayList<T> arraylist, WrappedArray<T> underlying) { innerlist = arraylist; this.underlying = underlying; }\r
-\r
- #region IList<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public T First { get { return innerlist.First; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public T Last { get { return innerlist.Last; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <returns></returns>\r
- public T this[int index]\r
- {\r
- get { return innerlist[index]; }\r
- set { innerlist[index] = value; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="filter"></param>\r
- /// <returns></returns>\r
- public IList<T> FindAll(Fun<T, bool> filter) { return innerlist.FindAll(filter); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="V"></typeparam>\r
- /// <param name="mapper"></param>\r
- /// <returns></returns>\r
- public IList<V> Map<V>(Fun<T, V> mapper) { return innerlist.Map<V>(mapper); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="V"></typeparam>\r
- /// <param name="mapper"></param>\r
- /// <param name="equalityComparer"></param>\r
- /// <returns></returns>\r
- public IList<V> Map<V>(Fun<T, V> mapper, SCG.IEqualityComparer<V> equalityComparer) { return innerlist.Map<V>(mapper, equalityComparer); }\r
-\r
- /// <summary>\r
- /// ???? should we throw NotRelevantException\r
- /// </summary>\r
- /// <value></value>\r
- public bool FIFO\r
- {\r
- get { throw new FixedSizeCollectionException(); }\r
- set { throw new FixedSizeCollectionException(); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public virtual bool IsFixedSize\r
- {\r
- get { return true; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="index"></param>\r
- /// <param name="item"></param>\r
- public void Insert(int index, T item)\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="pointer"></param>\r
- /// <param name="item"></param>\r
- public void Insert(IList<T> pointer, T item)\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- public void InsertFirst(T item)\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- public void InsertLast(T item)\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="i"></param>\r
- /// <param name="items"></param>\r
- public void InsertAll<U>(int i, System.Collections.Generic.IEnumerable<U> items) where U : T\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public T Remove()\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public T RemoveFirst()\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public T RemoveLast()\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="count"></param>\r
- /// <returns></returns>\r
- public IList<T> View(int start, int count)\r
- {\r
- return new WrappedArray<T>((ArrayList<T>)innerlist.View(start, count), underlying ?? this);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public IList<T> ViewOf(T item)\r
- {\r
- return new WrappedArray<T>((ArrayList<T>)innerlist.ViewOf(item), underlying ?? this);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public IList<T> LastViewOf(T item)\r
- {\r
- return new WrappedArray<T>((ArrayList<T>)innerlist.LastViewOf(item), underlying ?? this);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public IList<T> Underlying { get { return underlying; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public int Offset { get { return innerlist.Offset; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public bool IsValid { get { return innerlist.IsValid; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <returns></returns>\r
- public IList<T> Slide(int offset) { return innerlist.Slide(offset); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <param name="size"></param>\r
- /// <returns></returns>\r
- public IList<T> Slide(int offset, int size) { return innerlist.Slide(offset, size); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <returns></returns>\r
- public bool TrySlide(int offset) { return innerlist.TrySlide(offset); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <param name="size"></param>\r
- /// <returns></returns>\r
- public bool TrySlide(int offset, int size) { return innerlist.TrySlide(offset, size); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="otherView"></param>\r
- /// <returns></returns>\r
- public IList<T> Span(IList<T> otherView) { return innerlist.Span(((WrappedArray<T>)otherView).innerlist); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public void Reverse() { innerlist.Reverse(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public bool IsSorted() { return innerlist.IsSorted(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="comparer"></param>\r
- /// <returns></returns>\r
- public bool IsSorted(SCG.IComparer<T> comparer) { return innerlist.IsSorted(comparer); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public void Sort() { innerlist.Sort(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="comparer"></param>\r
- public void Sort(SCG.IComparer<T> comparer) { innerlist.Sort(comparer); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public void Shuffle() { innerlist.Shuffle(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="rnd"></param>\r
- public void Shuffle(Random rnd) { innerlist.Shuffle(rnd); }\r
-\r
- #endregion\r
-\r
- #region IIndexed<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public Speed IndexingSpeed { get { return Speed.Constant; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="count"></param>\r
- /// <returns></returns>\r
- public IDirectedCollectionValue<T> this[int start, int count] { get { return innerlist[start, count]; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int IndexOf(T item) { return innerlist.IndexOf(item); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int LastIndexOf(T item) { return innerlist.LastIndexOf(item); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <returns></returns>\r
- public int FindIndex(Fun<T, bool> predicate) { return innerlist.FindIndex(predicate); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <returns></returns>\r
- public int FindLastIndex(Fun<T, bool> predicate) { return innerlist.FindLastIndex(predicate); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="i"></param>\r
- /// <returns></returns>\r
- public T RemoveAt(int i) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="count"></param>\r
- public void RemoveInterval(int start, int count) { throw new FixedSizeCollectionException(); }\r
-\r
- #endregion\r
-\r
- #region ISequenced<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public int GetSequencedHashCode() { return innerlist.GetSequencedHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="that"></param>\r
- /// <returns></returns>\r
- public bool SequencedEquals(ISequenced<T> that) { return innerlist.SequencedEquals(that); }\r
-\r
- #endregion\r
-\r
- #region ICollection<T> Members\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public Speed ContainsSpeed { get { return Speed.Linear; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public int GetUnsequencedHashCode() { return innerlist.GetUnsequencedHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="that"></param>\r
- /// <returns></returns>\r
- public bool UnsequencedEquals(ICollection<T> that) { return innerlist.UnsequencedEquals(that); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool Contains(T item) { return innerlist.Contains(item); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int ContainsCount(T item) { return innerlist.ContainsCount(item); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public ICollectionValue<T> UniqueItems() { return innerlist.UniqueItems(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities() { return innerlist.ItemMultiplicities(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- /// <returns></returns>\r
- public bool ContainsAll<U>(System.Collections.Generic.IEnumerable<U> items) where U : T\r
- { return innerlist.ContainsAll(items); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool Find(ref T item) { return innerlist.Find(ref item); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool FindOrAdd(ref T item) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool Update(T item) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public bool Update(T item, out T olditem) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool UpdateOrAdd(T item) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public bool UpdateOrAdd(T item, out T olditem) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool Remove(T item) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="removeditem"></param>\r
- /// <returns></returns>\r
- public bool Remove(T item, out T removeditem) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- public void RemoveAllCopies(T item) { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- public void RemoveAll<U>(System.Collections.Generic.IEnumerable<U> items) where U : T { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public void Clear() { throw new FixedSizeCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- public void RetainAll<U>(System.Collections.Generic.IEnumerable<U> items) where U : T { throw new FixedSizeCollectionException(); }\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> Members\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public object SyncRoot { get { return innerlist.SyncRoot; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public bool IsReadOnly { get { return true; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public bool AllowsDuplicates\r
- {\r
- get { return true; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public SCG.IEqualityComparer<T> EqualityComparer { get { return innerlist.EqualityComparer; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public bool DuplicatesByCounting\r
- {\r
- get { return false; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool Add(T item)\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- public void AddAll<U>(System.Collections.Generic.IEnumerable<U> items) where U : T\r
- {\r
- throw new FixedSizeCollectionException();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public bool Check()\r
- {\r
- return innerlist.Check() && (underlying == null || underlying.innerlist == innerlist.Underlying);\r
- }\r
-\r
- #endregion\r
-\r
- #region ICollectionValue<T> Members\r
- /// <summary>\r
- /// No listeners may be installed\r
- /// </summary>\r
- /// <value>0</value>\r
- public virtual EventTypeEnum ListenableEvents { get { return 0; } }\r
-\r
- /// <summary>\r
- /// No listeners ever installed\r
- /// </summary>\r
- /// <value>0</value>\r
- public virtual EventTypeEnum ActiveEvents { get { return 0; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public event CollectionChangedHandler<T> CollectionChanged\r
- {\r
- add { throw new UnlistenableEventException(); }\r
- remove { throw new UnlistenableEventException(); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public event CollectionClearedHandler<T> CollectionCleared\r
- {\r
- add { throw new UnlistenableEventException(); }\r
- remove { throw new UnlistenableEventException(); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public event ItemsAddedHandler<T> ItemsAdded\r
- {\r
- add { throw new UnlistenableEventException(); }\r
- remove { throw new UnlistenableEventException(); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public event ItemInsertedHandler<T> ItemInserted\r
- {\r
- add { throw new UnlistenableEventException(); }\r
- remove { throw new UnlistenableEventException(); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public event ItemsRemovedHandler<T> ItemsRemoved\r
- {\r
- add { throw new UnlistenableEventException(); }\r
- remove { throw new UnlistenableEventException(); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public event ItemRemovedAtHandler<T> ItemRemovedAt\r
- {\r
- add { throw new UnlistenableEventException(); }\r
- remove { throw new UnlistenableEventException(); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public bool IsEmpty { get { return innerlist.IsEmpty; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public int Count { get { return innerlist.Count; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public Speed CountSpeed { get { return innerlist.CountSpeed; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="array"></param>\r
- /// <param name="index"></param>\r
- public void CopyTo(T[] array, int index) { innerlist.CopyTo(array, index); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public T[] ToArray() { return innerlist.ToArray(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="action"></param>\r
- public void Apply(Act<T> action) { innerlist.Apply(action); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <returns></returns>\r
- public bool Exists(Fun<T, bool> predicate) { return innerlist.Exists(predicate); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool Find(Fun<T, bool> predicate, out T item) { return innerlist.Find(predicate, out item); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <returns></returns>\r
- public bool All(Fun<T, bool> predicate) { return innerlist.All(predicate); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public T Choose() { return innerlist.Choose(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="filter"></param>\r
- /// <returns></returns>\r
- public SCG.IEnumerable<T> Filter(Fun<T, bool> filter) { return innerlist.Filter(filter); }\r
-\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public SCG.IEnumerator<T> GetEnumerator() { return innerlist.GetEnumerator(); }\r
- #endregion\r
-\r
- #region IShowable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="rest"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public bool Show(StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- { return innerlist.Show(stringbuilder, ref rest, formatProvider); }\r
-\r
- #endregion\r
-\r
- #region IFormattable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override string ToString() { return innerlist.ToString(); }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public virtual string ToString(string format, IFormatProvider formatProvider) { return innerlist.ToString(format, formatProvider); }\r
-\r
- #endregion\r
-\r
- #region IDirectedCollectionValue<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public IDirectedCollectionValue<T> Backwards() { return innerlist.Backwards(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public bool FindLast(Fun<T, bool> predicate, out T item) { return innerlist.FindLast(predicate, out item); }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return Backwards(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public EnumerationDirection Direction { get { return EnumerationDirection.Forwards; } }\r
-\r
- #endregion\r
-\r
- #region IDisposable Members\r
-\r
- /// <summary>\r
- /// Dispose this if a view else operation is illegal \r
- /// </summary>\r
- /// <exception cref="FixedSizeCollectionException">If not a view</exception>\r
- public void Dispose()\r
- {\r
- if (underlying == null)\r
- throw new FixedSizeCollectionException();\r
- else\r
- innerlist.Dispose();\r
- }\r
-\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this WrappedArray.\r
- /// \r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- return new WrappedArray<T>(innerlist.ToArray());\r
- }\r
-\r
- #endregion\r
-\r
-\r
-\r
- #region IEnumerable Members\r
-\r
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
-\r
- #endregion\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A read-only wrapper class for a generic enumerator\r
- /// </summary>\r
- public class GuardedEnumerator<T> : SCG.IEnumerator<T>\r
- {\r
- #region Fields\r
-\r
- SCG.IEnumerator<T> enumerator;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Create a wrapper around a generic enumerator\r
- /// </summary>\r
- /// <param name="enumerator">The enumerator to wrap</param>\r
- public GuardedEnumerator(SCG.IEnumerator<T> enumerator)\r
- { this.enumerator = enumerator; }\r
-\r
- #endregion\r
-\r
- #region IEnumerator<T> Members\r
-\r
- /// <summary>\r
- /// Move wrapped enumerator to next item, or the first item if\r
- /// this is the first call to MoveNext. \r
- /// </summary>\r
- /// <returns>True if enumerator is valid now</returns>\r
- public bool MoveNext() { return enumerator.MoveNext(); }\r
-\r
-\r
- /// <summary>\r
- /// Undefined if enumerator is not valid (MoveNext hash been called returning true)\r
- /// </summary>\r
- /// <value>The current item of the wrapped enumerator.</value>\r
- public T Current { get { return enumerator.Current; } }\r
-\r
- #endregion\r
-\r
- #region IDisposable Members\r
-\r
- //TODO: consider possible danger of calling through to Dispose. \r
- /// <summary>\r
- /// Dispose wrapped enumerator.\r
- /// </summary>\r
- public void Dispose() { enumerator.Dispose(); }\r
-\r
- #endregion\r
-\r
-\r
- #region IEnumerator Members\r
-\r
- object System.Collections.IEnumerator.Current\r
- {\r
- get { return enumerator.Current; }\r
- }\r
-\r
- void System.Collections.IEnumerator.Reset()\r
- {\r
- enumerator.Reset();\r
- }\r
-\r
- #endregion\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper class for a generic enumerable\r
- ///\r
- /// <i>This is mainly interesting as a base of other guard classes</i>\r
- /// </summary>\r
- public class GuardedEnumerable<T> : SCG.IEnumerable<T>\r
- {\r
- #region Fields\r
-\r
- SCG.IEnumerable<T> enumerable;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap an enumerable in a read-only wrapper\r
- /// </summary>\r
- /// <param name="enumerable">The enumerable to wrap</param>\r
- public GuardedEnumerable(SCG.IEnumerable<T> enumerable)\r
- { this.enumerable = enumerable; }\r
-\r
- #endregion\r
-\r
- #region SCG.IEnumerable<T> Members\r
-\r
- /// <summary>\r
- /// Get an enumerator from the wrapped enumerable\r
- /// </summary>\r
- /// <returns>The enumerator (itself wrapped)</returns>\r
- public SCG.IEnumerator<T> GetEnumerator()\r
- { return new GuardedEnumerator<T>(enumerable.GetEnumerator()); }\r
-\r
- #endregion\r
-\r
- #region IEnumerable Members\r
-\r
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
- {\r
- return GetEnumerator();\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a generic directed enumerable\r
- ///\r
- /// <i>This is mainly interesting as a base of other guard classes</i>\r
- /// </summary>\r
- public class GuardedDirectedEnumerable<T> : GuardedEnumerable<T>, IDirectedEnumerable<T>\r
- {\r
- #region Fields\r
-\r
- IDirectedEnumerable<T> directedenumerable;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a directed enumerable in a read-only wrapper\r
- /// </summary>\r
- /// <param name="directedenumerable">the collection to wrap</param>\r
- public GuardedDirectedEnumerable(IDirectedEnumerable<T> directedenumerable)\r
- : base(directedenumerable)\r
- { this.directedenumerable = directedenumerable; }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- /// <summary>\r
- /// Get a enumerable that enumerates the wrapped collection in the opposite direction\r
- /// </summary>\r
- /// <returns>The mirrored enumerable</returns>\r
- public IDirectedEnumerable<T> Backwards()\r
- { return new GuardedDirectedEnumerable<T>(directedenumerable.Backwards()); }\r
-\r
-\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- public EnumerationDirection Direction\r
- { get { return directedenumerable.Direction; } }\r
-\r
- #endregion\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for an ICollectionValue<T>\r
- ///\r
- /// <i>This is mainly interesting as a base of other guard classes</i>\r
- /// </summary>\r
- public class GuardedCollectionValue<T> : GuardedEnumerable<T>, ICollectionValue<T>\r
- {\r
- #region Events\r
- /// <summary>\r
- /// The ListenableEvents value of the wrapped collection\r
- /// </summary>\r
- /// <value></value>\r
- public virtual EventTypeEnum ListenableEvents { get { return collectionvalue.ListenableEvents; } }\r
-\r
- /// <summary>\r
- /// The ActiveEvents value of the wrapped collection\r
- /// </summary>\r
- /// <value></value>\r
- public virtual EventTypeEnum ActiveEvents { get { return collectionvalue.ActiveEvents; } }\r
-\r
- ProxyEventBlock<T> eventBlock;\r
- /// <summary>\r
- /// The change event. Will be raised for every change operation on the collection.\r
- /// </summary>\r
- public event CollectionChangedHandler<T> CollectionChanged\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).CollectionChanged += value; }\r
- remove { if (eventBlock != null) eventBlock.CollectionChanged -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The change event. Will be raised for every change operation on the collection.\r
- /// </summary>\r
- public event CollectionClearedHandler<T> CollectionCleared\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).CollectionCleared += value; }\r
- remove { if (eventBlock != null) eventBlock.CollectionCleared -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The item added event. Will be raised for every individual addition to the collection.\r
- /// </summary>\r
- public event ItemsAddedHandler<T> ItemsAdded\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemsAdded += value; }\r
- remove { if (eventBlock != null) eventBlock.ItemsAdded -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The item added event. Will be raised for every individual addition to the collection.\r
- /// </summary>\r
- public event ItemInsertedHandler<T> ItemInserted\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemInserted += value; }\r
- remove { if (eventBlock != null) eventBlock.ItemInserted -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The item removed event. Will be raised for every individual removal from the collection.\r
- /// </summary>\r
- public event ItemsRemovedHandler<T> ItemsRemoved\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemsRemoved += value; }\r
- remove { if (eventBlock != null) eventBlock.ItemsRemoved -= value; }\r
- }\r
-\r
- /// <summary>\r
- /// The item removed event. Will be raised for every individual removal from the collection.\r
- /// </summary>\r
- public event ItemRemovedAtHandler<T> ItemRemovedAt\r
- {\r
- add { (eventBlock ?? (eventBlock = new ProxyEventBlock<T>(this, collectionvalue))).ItemRemovedAt += value; }\r
- remove { if (eventBlock != null) eventBlock.ItemRemovedAt -= value; }\r
- }\r
- #endregion\r
-\r
- #region Fields\r
-\r
- ICollectionValue<T> collectionvalue;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a ICollectionValue<T> in a read-only wrapper\r
- /// </summary>\r
- /// <param name="collectionvalue">the collection to wrap</param>\r
- public GuardedCollectionValue(ICollectionValue<T> collectionvalue)\r
- : base(collectionvalue)\r
- { this.collectionvalue = collectionvalue; }\r
-\r
- #endregion\r
-\r
- #region ICollection<T> Members\r
-\r
- /// <summary>\r
- /// Get the size of the wrapped collection\r
- /// </summary>\r
- /// <value>The size</value>\r
- public virtual bool IsEmpty { get { return collectionvalue.IsEmpty; } }\r
-\r
- /// <summary>\r
- /// Get the size of the wrapped collection\r
- /// </summary>\r
- /// <value>The size</value>\r
- public virtual int Count { get { return collectionvalue.Count; } }\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>A characterization of the speed of the \r
- /// <code>Count</code> property in this collection.</value>\r
- public virtual Speed CountSpeed { get { return collectionvalue.CountSpeed; } }\r
-\r
- /// <summary>\r
- /// Copy the items of the wrapped collection to an array\r
- /// </summary>\r
- /// <param name="a">The array</param>\r
- /// <param name="i">Starting offset</param>\r
- public virtual void CopyTo(T[] a, int i) { collectionvalue.CopyTo(a, i); }\r
-\r
- /// <summary>\r
- /// Create an array from the items of the wrapped collection\r
- /// </summary>\r
- /// <returns>The array</returns>\r
- public virtual T[] ToArray() { return collectionvalue.ToArray(); }\r
-\r
- /// <summary>\r
- /// Apply a delegate to all items of the wrapped enumerable.\r
- /// </summary>\r
- /// <param name="a">The delegate to apply</param>\r
- //TODO: change this to throw an exception?\r
- public virtual void Apply(Act<T> a) { collectionvalue.Apply(a); }\r
-\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in the wrapped enumerable.\r
- /// </summary>\r
- /// <param name="filter">A filter delegate \r
- /// (<see cref="T:C5.Filter`1"/>) defining the predicate</param>\r
- /// <returns>True is such an item exists</returns>\r
- public virtual bool Exists(Fun<T, bool> filter) { return collectionvalue.Exists(filter); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="filter"></param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool Find(Fun<T, bool> filter, out T item) { return collectionvalue.Find(filter, out item); }\r
-\r
- /// <summary>\r
- /// Check if all items in the wrapped enumerable satisfies a specific predicate.\r
- /// </summary>\r
- /// <param name="filter">A filter delegate \r
- /// (<see cref="T:C5.Filter`1"/>) defining the predicate</param>\r
- /// <returns>True if all items satisfies the predicate</returns>\r
- public virtual bool All(Fun<T, bool> filter) { return collectionvalue.All(filter); }\r
-\r
- /// <summary>\r
- /// Create an enumerable, enumerating the items of this collection that satisfies \r
- /// a certain condition.\r
- /// </summary>\r
- /// <param name="filter">The T->bool filter delegate defining the condition</param>\r
- /// <returns>The filtered enumerable</returns>\r
- public virtual SCG.IEnumerable<T> Filter(Fun<T, bool> filter) { return collectionvalue.Filter(filter); }\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- public virtual T Choose() { return collectionvalue.Choose(); }\r
-\r
- #endregion\r
-\r
- #region IShowable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="stringbuilder"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <param name="rest"></param>\r
- /// <returns></returns>\r
- public bool Show(System.Text.StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)\r
- {\r
- return collectionvalue.Show(stringbuilder, ref rest, formatProvider);\r
- }\r
- #endregion\r
-\r
- #region IFormattable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="format"></param>\r
- /// <param name="formatProvider"></param>\r
- /// <returns></returns>\r
- public string ToString(string format, IFormatProvider formatProvider)\r
- {\r
- return collectionvalue.ToString(format, formatProvider);\r
- }\r
-\r
- #endregion\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a directed collection\r
- ///\r
- /// <i>This is mainly interesting as a base of other guard classes</i>\r
- /// </summary>\r
- public class GuardedDirectedCollectionValue<T> : GuardedCollectionValue<T>, IDirectedCollectionValue<T>\r
- {\r
- #region Fields\r
-\r
- IDirectedCollectionValue<T> directedcollection;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a directed collection in a read-only wrapper\r
- /// </summary>\r
- /// <param name="directedcollection">the collection to wrap</param>\r
- public GuardedDirectedCollectionValue(IDirectedCollectionValue<T> directedcollection)\r
- :\r
- base(directedcollection)\r
- { this.directedcollection = directedcollection; }\r
-\r
- #endregion\r
-\r
- #region IDirectedCollection<T> Members\r
-\r
- /// <summary>\r
- /// Get a collection that enumerates the wrapped collection in the opposite direction\r
- /// </summary>\r
- /// <returns>The mirrored collection</returns>\r
- public virtual IDirectedCollectionValue<T> Backwards()\r
- { return new GuardedDirectedCollectionValue<T>(directedcollection.Backwards()); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool FindLast(Fun<T, bool> predicate, out T item) { return directedcollection.FindLast(predicate, out item); }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()\r
- { return Backwards(); }\r
-\r
-\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- public EnumerationDirection Direction\r
- { get { return directedcollection.Direction; } }\r
-\r
- #endregion\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for an <see cref="T:C5.ICollection`1"/>,\r
- /// <para>\r
- /// <i>Suitable for wrapping hash tables, <see cref="T:C5.HashSet`1"/>\r
- /// and <see cref="T:C5.HashBag`1"/> </i></para>\r
- /// </summary>\r
- public class GuardedCollection<T> : GuardedCollectionValue<T>, ICollection<T>\r
- {\r
- #region Fields\r
-\r
- ICollection<T> collection;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap an ICollection<T> in a read-only wrapper\r
- /// </summary>\r
- /// <param name="collection">the collection to wrap</param>\r
- public GuardedCollection(ICollection<T> collection)\r
- : base(collection)\r
- {\r
- this.collection = collection;\r
- }\r
-\r
- #endregion\r
-\r
- #region ICollection<T> Members\r
-\r
- /// <summary>\r
- /// (This is a read-only wrapper)\r
- /// </summary>\r
- /// <value>True</value>\r
- public virtual bool IsReadOnly { get { return true; } }\r
-\r
-\r
- /// <summary> </summary>\r
- /// <value>Speed of wrapped collection</value>\r
- public virtual Speed ContainsSpeed { get { return collection.ContainsSpeed; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual int GetUnsequencedHashCode()\r
- { return collection.GetUnsequencedHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="that"></param>\r
- /// <returns></returns>\r
- public virtual bool UnsequencedEquals(ICollection<T> that)\r
- { return collection.UnsequencedEquals(that); }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item is in the wrapped collection\r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- /// <returns>True if found</returns>\r
- public virtual bool Contains(T item) { return collection.Contains(item); }\r
-\r
-\r
- /// <summary>\r
- /// Count the number of times an item appears in the wrapped collection\r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- /// <returns>The number of copies</returns>\r
- public virtual int ContainsCount(T item) { return collection.ContainsCount(item); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<T> UniqueItems() { return new GuardedCollectionValue<T>(collection.UniqueItems()); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities() { return new GuardedCollectionValue<KeyValuePair<T, int>>(collection.ItemMultiplicities()); }\r
-\r
- /// <summary>\r
- /// Check if all items in the argument is in the wrapped collection\r
- /// </summary>\r
- /// <param name="items">The items</param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if so</returns>\r
- public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T { return collection.ContainsAll(items); }\r
-\r
- /// <summary> \r
- /// Search for an item in the wrapped collection\r
- /// </summary>\r
- /// <param name="item">On entry the item to look for, on exit the equivalent item found (if any)</param>\r
- /// <returns></returns>\r
- public virtual bool Find(ref T item) { return collection.Find(ref item); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool FindOrAdd(ref T item)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool Update(T item)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool Update(T item, out T olditem)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool UpdateOrAdd(T item)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool UpdateOrAdd(T item, out T olditem)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool Remove(T item)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item">The value to remove.</param>\r
- /// <param name="removeditem">The removed value.</param>\r
- /// <returns></returns>\r
- public virtual bool Remove(T item, out T removeditem)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- public virtual void RemoveAllCopies(T item)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- public virtual void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- public virtual void Clear()\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- public virtual void RetainAll<U>(SCG.IEnumerable<U> items) where U : T\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- /// <summary>\r
- /// Check wrapped collection for internal consistency\r
- /// </summary>\r
- /// <returns>True if check passed</returns>\r
- public virtual bool Check() { return collection.Check(); }\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> Members\r
-\r
- /// <summary> </summary>\r
- /// <value>False if wrapped collection has set semantics</value>\r
- public virtual bool AllowsDuplicates { get { return collection.AllowsDuplicates; } }\r
-\r
- //TODO: the equalityComparer should be guarded\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual SCG.IEqualityComparer<T> EqualityComparer { get { return collection.EqualityComparer; } }\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting { get { return collection.DuplicatesByCounting; } }\r
-\r
-\r
- /// <summary> </summary>\r
- /// <value>True if wrapped collection is empty</value>\r
- public override bool IsEmpty { get { return collection.IsEmpty; } }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool Add(T item)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- public virtual void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- return new GuardedCollection<T>((ICollection<T>)(collection.Clone()));\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a sequenced collection\r
- ///\r
- /// <i>This is mainly interesting as a base of other guard classes</i>\r
- /// </summary>\r
- public class GuardedSequenced<T> : GuardedCollection<T>, ISequenced<T>\r
- {\r
- #region Fields\r
-\r
- ISequenced<T> sequenced;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a sequenced collection in a read-only wrapper\r
- /// </summary>\r
- /// <param name="sorted"></param>\r
- public GuardedSequenced(ISequenced<T> sorted) : base(sorted) { this.sequenced = sorted; }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the index of the first one.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>the index, if found, a negative value else</returns>\r
- public int FindIndex(Fun<T, bool> predicate)\r
- {\r
- IIndexed<T> indexed = sequenced as IIndexed<T>;\r
- if (indexed != null)\r
- return indexed.FindIndex(predicate);\r
- int index = 0;\r
- foreach (T item in this)\r
- {\r
- if (predicate(item))\r
- return index;\r
- index++;\r
- }\r
- return -1;\r
- }\r
-\r
- /// <summary>\r
- /// Check if there exists an item that satisfies a\r
- /// specific predicate in this collection and return the index of the last one.\r
- /// </summary>\r
- /// <param name="predicate">A delegate \r
- /// (<see cref="T:C5.Fun`2"/> with <code>R == bool</code>) defining the predicate</param>\r
- /// <returns>the index, if found, a negative value else</returns>\r
- public int FindLastIndex(Fun<T, bool> predicate)\r
- {\r
- IIndexed<T> indexed = sequenced as IIndexed<T>;\r
- if (indexed != null)\r
- return indexed.FindLastIndex(predicate);\r
- int index = Count - 1;\r
- foreach (T item in Backwards())\r
- {\r
- if (predicate(item))\r
- return index;\r
- index--;\r
- }\r
- return -1;\r
- }\r
-\r
-\r
-\r
- #region ISequenced<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public int GetSequencedHashCode()\r
- { return sequenced.GetSequencedHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="that"></param>\r
- /// <returns></returns>\r
- public bool SequencedEquals(ISequenced<T> that)\r
- { return sequenced.SequencedEquals(that); }\r
-\r
- #endregion\r
-\r
- #region IDirectedCollection<T> Members\r
-\r
- /// <summary>\r
- /// Get a collection that enumerates the wrapped collection in the opposite direction\r
- /// </summary>\r
- /// <returns>The mirrored collection</returns>\r
- public virtual IDirectedCollectionValue<T> Backwards()\r
- { return new GuardedDirectedCollectionValue<T>(sequenced.Backwards()); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public virtual bool FindLast(Fun<T, bool> predicate, out T item) { return sequenced.FindLast(predicate, out item); }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()\r
- { return Backwards(); }\r
-\r
-\r
-\r
- /// <summary>\r
- /// <code>Forwards</code> if same, else <code>Backwards</code>\r
- /// </summary>\r
- /// <value>The enumeration direction relative to the original collection.</value>\r
- public EnumerationDirection Direction\r
- { get { return EnumerationDirection.Forwards; } }\r
-\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override object Clone()\r
- {\r
- return new GuardedCollection<T>((ISequenced<T>)(sequenced.Clone()));\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a sorted collection\r
- ///\r
- /// <i>This is mainly interesting as a base of other guard classes</i>\r
- /// </summary>\r
- public class GuardedSorted<T> : GuardedSequenced<T>, ISorted<T>\r
- {\r
- #region Fields\r
-\r
- ISorted<T> sorted;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a sorted collection in a read-only wrapper\r
- /// </summary>\r
- /// <param name="sorted"></param>\r
- public GuardedSorted(ISorted<T> sorted) : base(sorted) { this.sorted = sorted; }\r
-\r
- #endregion\r
-\r
- #region ISorted<T> Members\r
-\r
- /// <summary>\r
- /// Find the predecessor of the item in the wrapped sorted collection\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists </exception> \r
- /// <param name="item">The item</param>\r
- /// <returns>The predecessor</returns>\r
- public T Predecessor(T item) { return sorted.Predecessor(item); }\r
-\r
-\r
- /// <summary>\r
- /// Find the Successor of the item in the wrapped sorted collection\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists </exception> \r
- /// <param name="item">The item</param>\r
- /// <returns>The Successor</returns>\r
- public T Successor(T item) { return sorted.Successor(item); }\r
-\r
-\r
- /// <summary>\r
- /// Find the weak predecessor of the item in the wrapped sorted collection\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists </exception> \r
- /// <param name="item">The item</param>\r
- /// <returns>The weak predecessor</returns>\r
- public T WeakPredecessor(T item) { return sorted.WeakPredecessor(item); }\r
-\r
-\r
- /// <summary>\r
- /// Find the weak Successor of the item in the wrapped sorted collection\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists </exception> \r
- /// <param name="item">The item</param>\r
- /// <returns>The weak Successor</returns>\r
- public T WeakSuccessor(T item) { return sorted.WeakSuccessor(item); }\r
-\r
-\r
- /// <summary>\r
- /// Run Cut on the wrapped sorted collection\r
- /// </summary>\r
- /// <param name="c"></param>\r
- /// <param name="low"></param>\r
- /// <param name="lval"></param>\r
- /// <param name="high"></param>\r
- /// <param name="hval"></param>\r
- /// <returns></returns>\r
- public bool Cut(IComparable<T> c, out T low, out bool lval, out T high, out bool hval)\r
- { return sorted.Cut(c, out low, out lval, out high, out hval); }\r
-\r
-\r
- /// <summary>\r
- /// Get the specified range from the wrapped collection. \r
- /// (The current implementation erroneously does not wrap the result.)\r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<T> RangeFrom(T bot) { return sorted.RangeFrom(bot); }\r
-\r
-\r
- /// <summary>\r
- /// Get the specified range from the wrapped collection. \r
- /// (The current implementation erroneously does not wrap the result.)\r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<T> RangeFromTo(T bot, T top)\r
- { return sorted.RangeFromTo(bot, top); }\r
-\r
-\r
- /// <summary>\r
- /// Get the specified range from the wrapped collection. \r
- /// (The current implementation erroneously does not wrap the result.)\r
- /// </summary>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<T> RangeTo(T top) { return sorted.RangeTo(top); }\r
-\r
-\r
- /// <summary>\r
- /// Get the specified range from the wrapped collection. \r
- /// (The current implementation erroneously does not wrap the result.)\r
- /// </summary>\r
- /// <returns></returns>\r
- public IDirectedCollectionValue<T> RangeAll() { return sorted.RangeAll(); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="items"></param>\r
- /// <typeparam name="U"></typeparam>\r
- public void AddSorted<U>(SCG.IEnumerable<U> items) where U : T\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="low"></param>\r
- public void RemoveRangeFrom(T low)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="low"></param>\r
- /// <param name="hi"></param>\r
- public void RemoveRangeFromTo(T low, T hi)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="hi"></param>\r
- public void RemoveRangeTo(T hi)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- #endregion\r
-\r
- #region IPriorityQueue<T> Members\r
-\r
- /// <summary>\r
- /// Find the minimum of the wrapped collection\r
- /// </summary>\r
- /// <returns>The minimum</returns>\r
- public T FindMin() { return sorted.FindMin(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns></returns>\r
- public T DeleteMin()\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// Find the maximum of the wrapped collection\r
- /// </summary>\r
- /// <returns>The maximum</returns>\r
- public T FindMax() { return sorted.FindMax(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns></returns>\r
- public T DeleteMax()\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- //TODO: we should guard the comparer!\r
- /// <summary>\r
- /// The comparer object supplied at creation time for the underlying collection\r
- /// </summary>\r
- /// <value>The comparer</value>\r
- public SCG.IComparer<T> Comparer { get { return sorted.Comparer; } }\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()\r
- { return Backwards(); }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override object Clone()\r
- {\r
- return new GuardedSorted<T>((ISorted<T>)(sorted.Clone()));\r
- }\r
-\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// Read-only wrapper for indexed sorted collections\r
- ///\r
- /// <i>Suitable for wrapping TreeSet, TreeBag and SortedArray</i>\r
- /// </summary>\r
- public class GuardedIndexedSorted<T> : GuardedSorted<T>, IIndexedSorted<T>\r
- {\r
- #region Fields\r
-\r
- IIndexedSorted<T> indexedsorted;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap an indexed sorted collection in a read-only wrapper\r
- /// </summary>\r
- /// <param name="list">the indexed sorted collection</param>\r
- public GuardedIndexedSorted(IIndexedSorted<T> list)\r
- : base(list)\r
- { this.indexedsorted = list; }\r
-\r
- #endregion\r
-\r
- #region IIndexedSorted<T> Members\r
-\r
- /// <summary>\r
- /// Get the specified range from the wrapped collection. \r
- /// (The current implementation erroneously does not wrap the result.)\r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <returns></returns>\r
- public new IDirectedCollectionValue<T> RangeFrom(T bot)\r
- { return indexedsorted.RangeFrom(bot); }\r
-\r
-\r
- /// <summary>\r
- /// Get the specified range from the wrapped collection. \r
- /// (The current implementation erroneously does not wrap the result.)\r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public new IDirectedCollectionValue<T> RangeFromTo(T bot, T top)\r
- { return indexedsorted.RangeFromTo(bot, top); }\r
-\r
-\r
- /// <summary>\r
- /// Get the specified range from the wrapped collection. \r
- /// (The current implementation erroneously does not wrap the result.)\r
- /// </summary>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public new IDirectedCollectionValue<T> RangeTo(T top)\r
- { return indexedsorted.RangeTo(top); }\r
-\r
-\r
- /// <summary>\r
- /// Report the number of items in the specified range of the wrapped collection\r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <returns></returns>\r
- public int CountFrom(T bot) { return indexedsorted.CountFrom(bot); }\r
-\r
-\r
- /// <summary>\r
- /// Report the number of items in the specified range of the wrapped collection\r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public int CountFromTo(T bot, T top) { return indexedsorted.CountFromTo(bot, top); }\r
-\r
-\r
- /// <summary>\r
- /// Report the number of items in the specified range of the wrapped collection\r
- /// </summary>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public int CountTo(T top) { return indexedsorted.CountTo(top); }\r
-\r
-\r
- /// <summary>\r
- /// Run FindAll on the wrapped collection with the indicated filter.\r
- /// The result will <b>not</b> be read-only.\r
- /// </summary>\r
- /// <param name="f"></param>\r
- /// <returns></returns>\r
- public IIndexedSorted<T> FindAll(Fun<T, bool> f)\r
- { return indexedsorted.FindAll(f); }\r
-\r
-\r
- /// <summary>\r
- /// Run Map on the wrapped collection with the indicated mapper.\r
- /// The result will <b>not</b> be read-only.\r
- /// </summary>\r
- /// <param name="m"></param>\r
- /// <param name="c">The comparer to use in the result</param>\r
- /// <returns></returns>\r
- public IIndexedSorted<V> Map<V>(Fun<T, V> m, SCG.IComparer<V> c)\r
- { return indexedsorted.Map(m, c); }\r
-\r
- #endregion\r
-\r
- #region IIndexed<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The i'th item of the wrapped sorted collection</value>\r
- public T this[int i] { get { return indexedsorted[i]; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual Speed IndexingSpeed { get { return indexedsorted.IndexingSpeed; } }\r
-\r
- /// <summary> </summary>\r
- /// <value>A directed collection of the items in the indicated interval of the wrapped collection</value>\r
- public IDirectedCollectionValue<T> this[int start, int end]\r
- { get { return new GuardedDirectedCollectionValue<T>(indexedsorted[start, end]); } }\r
-\r
-\r
- /// <summary>\r
- /// Find the (first) index of an item in the wrapped collection\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int IndexOf(T item) { return indexedsorted.IndexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// Find the last index of an item in the wrapped collection\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int LastIndexOf(T item) { return indexedsorted.LastIndexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="i"></param>\r
- /// <returns></returns>\r
- public T RemoveAt(int i)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="start"></param>\r
- /// <param name="count"></param>\r
- public void RemoveInterval(int start, int count)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()\r
- { return Backwards(); }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override object Clone()\r
- {\r
- return new GuardedIndexedSorted<T>((IIndexedSorted<T>)(indexedsorted.Clone()));\r
- }\r
-\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a generic list collection\r
- /// <i>Suitable as a wrapper for LinkedList, HashedLinkedList, ArrayList and HashedArray.\r
- /// <see cref="T:C5.LinkedList`1"/>, \r
- /// <see cref="T:C5.HashedLinkedList`1"/>, \r
- /// <see cref="T:C5.ArrayList`1"/> or\r
- /// <see cref="T:C5.HashedArray`1"/>.\r
- /// </i>\r
- /// </summary>\r
- public class GuardedList<T> : GuardedSequenced<T>, IList<T>\r
- {\r
- #region Fields\r
-\r
- IList<T> innerlist;\r
- GuardedList<T> underlying;\r
- bool slidableView = false;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a list in a read-only wrapper\r
- /// </summary>\r
- /// <param name="list">The list</param>\r
- public GuardedList(IList<T> list)\r
- : base(list)\r
- {\r
- this.innerlist = list;\r
- if (list.Underlying != null)\r
- underlying = new GuardedList<T>(list.Underlying, null, false);\r
- }\r
-\r
- GuardedList(IList<T> list, GuardedList<T> underlying, bool slidableView)\r
- : base(list)\r
- {\r
- this.innerlist = list; this.underlying = underlying; this.slidableView = slidableView;\r
- }\r
- #endregion\r
-\r
- #region IList<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The first item of the wrapped list</value>\r
- public T First { get { return innerlist.First; } }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The last item of the wrapped list</value>\r
- public T Last { get { return innerlist.Last; } }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> if used as setter</exception>\r
- /// <value>True if wrapped list has FIFO semantics for the Add(T item) and Remove() methods</value>\r
- public bool FIFO\r
- {\r
- get { return innerlist.FIFO; }\r
- set { throw new ReadOnlyCollectionException("List is read only"); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public virtual bool IsFixedSize\r
- {\r
- get { return true; }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> if used as setter</exception>\r
- /// <value>The i'th item of the wrapped list</value>\r
- public T this[int i]\r
- {\r
- get { return innerlist[i]; }\r
- set { throw new ReadOnlyCollectionException("List is read only"); }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual Speed IndexingSpeed { get { return innerlist.IndexingSpeed; } }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="i"></param>\r
- /// <param name="item"></param>\r
- public void Insert(int i, T item)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="pointer"></param>\r
- /// <param name="item"></param>\r
- public void Insert(IList<T> pointer, T item)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- public void InsertFirst(T item)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- public void InsertLast(T item)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <param name="target"></param>\r
- public void InsertBefore(T item, T target)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="item"></param>\r
- /// <param name="target"></param>\r
- public void InsertAfter(T item, T target)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="i"></param>\r
- /// <param name="items"></param>\r
- public void InsertAll<U>(int i, SCG.IEnumerable<U> items) where U : T\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// Perform FindAll on the wrapped list. The result is <b>not</b> necessarily read-only.\r
- /// </summary>\r
- /// <param name="filter">The filter to use</param>\r
- /// <returns></returns>\r
- public IList<T> FindAll(Fun<T, bool> filter) { return innerlist.FindAll(filter); }\r
-\r
-\r
- /// <summary>\r
- /// Perform Map on the wrapped list. The result is <b>not</b> necessarily read-only.\r
- /// </summary>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The mapper to use.</param>\r
- /// <returns>The mapped list</returns>\r
- public IList<V> Map<V>(Fun<T, V> mapper) { return innerlist.Map(mapper); }\r
-\r
- /// <summary>\r
- /// Perform Map on the wrapped list. The result is <b>not</b> necessarily read-only.\r
- /// </summary>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <param name="itemequalityComparer">The itemequalityComparer to use for the new list</param>\r
- /// <returns>The new list.</returns>\r
- public IList<V> Map<V>(Fun<T, V> mapper, SCG.IEqualityComparer<V> itemequalityComparer) { return innerlist.Map(mapper, itemequalityComparer); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns></returns>\r
- public T Remove() { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns></returns>\r
- public T RemoveFirst() { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns></returns>\r
- public T RemoveLast() { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// Create the indicated view on the wrapped list and wrap it read-only.\r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="count"></param>\r
- /// <returns></returns>\r
- public IList<T> View(int start, int count)\r
- {\r
- IList<T> view = innerlist.View(start, count);\r
- return view == null ? null : new GuardedList<T>(view, underlying ?? this, true);\r
- }\r
-\r
- /// <summary>\r
- /// Create the indicated view on the wrapped list and wrap it read-only.\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public IList<T> ViewOf(T item)\r
- {\r
- IList<T> view = innerlist.ViewOf(item);\r
- return view == null ? null : new GuardedList<T>(view, underlying ?? this, true);\r
- }\r
-\r
- /// <summary>\r
- /// Create the indicated view on the wrapped list and wrap it read-only.\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public IList<T> LastViewOf(T item)\r
- {\r
- IList<T> view = innerlist.LastViewOf(item);\r
- return view == null ? null : new GuardedList<T>(view, underlying ?? this, true);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <value>The wrapped underlying list of the wrapped view </value>\r
- public IList<T> Underlying { get { return underlying; } }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The offset of the wrapped list as a view.</value>\r
- public int Offset { get { return innerlist.Offset; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual bool IsValid { get { return innerlist.IsValid; } }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> if this is a wrapped view and not a view that was made on a wrapper</exception>\r
- /// <param name="offset"></param>\r
- public IList<T> Slide(int offset)\r
- {\r
- if (slidableView)\r
- {\r
- innerlist.Slide(offset);\r
- return this;\r
- }\r
- else\r
- throw new ReadOnlyCollectionException("List is read only");\r
- }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="offset"></param>\r
- /// <param name="size"></param>\r
- public IList<T> Slide(int offset, int size)\r
- {\r
- if (slidableView)\r
- {\r
- innerlist.Slide(offset, size);\r
- return this;\r
- }\r
- else\r
- throw new ReadOnlyCollectionException("List is read only");\r
- }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="offset"></param>\r
- /// <returns></returns>\r
- public bool TrySlide(int offset)\r
- {\r
- if (slidableView)\r
- return innerlist.TrySlide(offset);\r
- else\r
- throw new ReadOnlyCollectionException("List is read only");\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="offset"></param>\r
- /// <param name="size"></param>\r
- /// <returns></returns>\r
- public bool TrySlide(int offset, int size)\r
- {\r
- if (slidableView)\r
- return innerlist.TrySlide(offset, size);\r
- else\r
- throw new ReadOnlyCollectionException("List is read only");\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="otherView"></param>\r
- /// <returns></returns>\r
- public IList<T> Span(IList<T> otherView)\r
- {\r
- GuardedList<T> otherGuardedList = otherView as GuardedList<T>;\r
- if (otherGuardedList == null)\r
- throw new IncompatibleViewException();\r
- IList<T> span = innerlist.Span(otherGuardedList.innerlist);\r
- if (span == null)\r
- return null;\r
- return new GuardedList<T>(span, underlying ?? otherGuardedList.underlying ?? this, true);\r
- }\r
-\r
- /// <summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// </summary>\r
- public void Reverse() { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="start"></param>\r
- /// <param name="count"></param>\r
- public void Reverse(int start, int count)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// Check if wrapped list is sorted according to the default sorting order\r
- /// for the item type T, as defined by the <see cref="T:C5.Comparer`1"/> class \r
- /// </summary>\r
- /// <exception cref="NotComparableException">if T is not comparable</exception>\r
- /// <returns>True if the list is sorted, else false.</returns>\r
- public bool IsSorted() { return innerlist.IsSorted(Comparer<T>.Default); }\r
-\r
- /// <summary>\r
- /// Check if wrapped list is sorted\r
- /// </summary>\r
- /// <param name="c">The sorting order to use</param>\r
- /// <returns>True if sorted</returns>\r
- public bool IsSorted(SCG.IComparer<T> c) { return innerlist.IsSorted(c); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- public void Sort()\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="c"></param>\r
- public void Sort(SCG.IComparer<T> c)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- public void Shuffle()\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="rnd"></param>\r
- public void Shuffle(Random rnd)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
- #endregion\r
-\r
- #region IIndexed<T> Members\r
-\r
- /// <summary> </summary>\r
- /// <value>A directed collection of the items in the indicated interval of the wrapped collection</value>\r
- public IDirectedCollectionValue<T> this[int start, int end]\r
- { get { return new GuardedDirectedCollectionValue<T>(innerlist[start, end]); } }\r
-\r
-\r
- /// <summary>\r
- /// Find the (first) index of an item in the wrapped collection\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int IndexOf(T item) { return innerlist.IndexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// Find the last index of an item in the wrapped collection\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int LastIndexOf(T item) { return innerlist.LastIndexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="i"></param>\r
- /// <returns></returns>\r
- public T RemoveAt(int i)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="start"></param>\r
- /// <param name="count"></param>\r
- public void RemoveInterval(int start, int count)\r
- { throw new ReadOnlyCollectionException("List is read only"); }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()\r
- { return Backwards(); }\r
-\r
- #endregion\r
-\r
- #region IStack<T> Members\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns>-</returns>\r
- public void Push(T item)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns>-</returns>\r
- public T Pop()\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- #endregion\r
-\r
- #region IQueue<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns>-</returns>\r
- public void Enqueue(T item)\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns>-</returns>\r
- public T Dequeue()\r
- { throw new ReadOnlyCollectionException("Collection cannot be modified through this guard object"); }\r
-\r
- #endregion\r
-\r
- #region IDisposable Members\r
-\r
- /// <summary>\r
- /// Ignore: this may be called by a foreach or using statement.\r
- /// </summary>\r
- public void Dispose() { }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override object Clone()\r
- {\r
- return new GuardedList<T>((IList<T>)(innerlist.Clone()));\r
- }\r
-\r
- }\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a generic indexable queue (allows indexing).\r
- /// \r
- /// <para>Suitable for wrapping a <see cref="T:C5.CircularQueue`1"/></para>\r
- /// </summary>\r
- /// <typeparam name="T">The item type.</typeparam>\r
- public class GuardedQueue<T> : GuardedDirectedCollectionValue<T>, IQueue<T>\r
- {\r
- #region Fields\r
-\r
- IQueue<T> queue;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a queue in a read-only wrapper\r
- /// </summary>\r
- /// <param name="queue">The queue</param>\r
- public GuardedQueue(IQueue<T> queue) : base(queue) { this.queue = queue; }\r
-\r
- #endregion\r
-\r
- #region IQueue<T> Members\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public bool AllowsDuplicates { get { return queue.AllowsDuplicates; } }\r
-\r
- /// <summary>\r
- /// Index into the wrapped queue\r
- /// </summary>\r
- /// <param name="i"></param>\r
- /// <returns></returns>\r
- public T this[int i] { get { return queue[i]; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns>-</returns>\r
- public void Enqueue(T item)\r
- { throw new ReadOnlyCollectionException("Queue cannot be modified through this guard object"); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns>-</returns>\r
- public T Dequeue()\r
- { throw new ReadOnlyCollectionException("Queue cannot be modified through this guard object"); }\r
-\r
- #endregion\r
- }\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a dictionary.\r
- ///\r
- /// <i>Suitable for wrapping a HashDictionary. <see cref="T:C5.HashDictionary`2"/></i>\r
- /// </summary>\r
- public class GuardedDictionary<K, V> : GuardedCollectionValue<KeyValuePair<K, V>>, IDictionary<K, V>\r
- {\r
- #region Fields\r
-\r
- IDictionary<K, V> dict;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a dictionary in a read-only wrapper\r
- /// </summary>\r
- /// <param name="dict">the dictionary</param>\r
- public GuardedDictionary(IDictionary<K, V> dict) : base(dict) { this.dict = dict; }\r
-\r
- #endregion\r
-\r
- #region IDictionary<K,V> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public SCG.IEqualityComparer<K> EqualityComparer { get { return dict.EqualityComparer; } }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a\r
- /// read-only wrappper if used as a setter</exception>\r
- /// <value>Get the value corresponding to a key in the wrapped dictionary</value>\r
- public V this[K key]\r
- {\r
- get { return dict[key]; }\r
- set { throw new ReadOnlyCollectionException(); }\r
- }\r
-\r
- /// <summary>\r
- /// (This is a read-only wrapper)\r
- /// </summary>\r
- /// <value>True</value>\r
- public bool IsReadOnly { get { return true; } }\r
-\r
-\r
- //TODO: guard with a read-only wrapper? Probably so!\r
- /// <summary> </summary>\r
- /// <value>The collection of keys of the wrapped dictionary</value>\r
- public ICollectionValue<K> Keys\r
- { get { return dict.Keys; } }\r
-\r
-\r
- /// <summary> </summary>\r
- /// <value>The collection of values of the wrapped dictionary</value>\r
- public ICollectionValue<V> Values { get { return dict.Values; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public virtual Fun<K, V> Fun { get { return delegate(K k) { return this[k]; }; } }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <param name="val"></param>\r
- public void Add(K key, V val)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="items"></param>\r
- public void AddAll<L, W>(SCG.IEnumerable<KeyValuePair<L, W>> items)\r
- where L : K\r
- where W : V\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <returns></returns>\r
- public bool Remove(K key)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <param name="val"></param>\r
- /// <returns></returns>\r
- public bool Remove(K key, out V val)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- public void Clear()\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public Speed ContainsSpeed { get { return dict.ContainsSpeed; } }\r
-\r
- /// <summary>\r
- /// Check if the wrapped dictionary contains a specific key\r
- /// </summary>\r
- /// <param name="key">The key</param>\r
- /// <returns>True if it does</returns>\r
- public bool Contains(K key) { return dict.Contains(key); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="keys"></param>\r
- /// <returns></returns>\r
- public bool ContainsAll<H>(SCG.IEnumerable<H> keys) where H : K { return dict.ContainsAll(keys); }\r
-\r
- /// <summary>\r
- /// Search for a key in the wrapped dictionary, reporting the value if found\r
- /// </summary>\r
- /// <param name="key">The key</param>\r
- /// <param name="val">On exit: the value if found</param>\r
- /// <returns>True if found</returns>\r
- public bool Find(K key, out V val) { return dict.Find(key, out val); }\r
-\r
- /// <summary>\r
- /// Search for a key in the wrapped dictionary, reporting the value if found\r
- /// </summary>\r
- /// <param name="key">The key</param>\r
- /// <param name="val">On exit: the value if found</param>\r
- /// <returns>True if found</returns>\r
- public bool Find(ref K key, out V val) { return dict.Find(ref key, out val); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <param name="val"></param>\r
- /// <returns></returns>\r
- public bool Update(K key, V val)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <param name="val"></param>\r
- /// <param name="oldval"></param>\r
- /// <returns></returns>\r
- public bool Update(K key, V val, out V oldval)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <param name="val"></param>\r
- /// <returns></returns>\r
- public bool FindOrAdd(K key, ref V val)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <param name="val"></param>\r
- /// <returns></returns>\r
- public bool UpdateOrAdd(K key, V val)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="key"></param>\r
- /// <param name="val"></param>\r
- /// <param name="oldval"></param>\r
- /// <returns></returns>\r
- public bool UpdateOrAdd(K key, V val, out V oldval)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
-\r
- /// <summary>\r
- /// Check the internal consistency of the wrapped dictionary\r
- /// </summary>\r
- /// <returns>True if check passed</returns>\r
- public bool Check() { return dict.Check(); }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- return new GuardedDictionary<K, V>((IDictionary<K, V>)(dict.Clone()));\r
- }\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// A read-only wrapper for a sorted dictionary.\r
- ///\r
- /// <i>Suitable for wrapping a Dictionary. <see cref="T:C5.Dictionary`2"/></i>\r
- /// </summary>\r
- public class GuardedSortedDictionary<K, V> : GuardedDictionary<K, V>, ISortedDictionary<K, V>\r
- {\r
- #region Fields\r
-\r
- ISortedDictionary<K, V> sorteddict;\r
-\r
- #endregion\r
-\r
- #region Constructor\r
-\r
- /// <summary>\r
- /// Wrap a sorted dictionary in a read-only wrapper\r
- /// </summary>\r
- /// <param name="sorteddict">the dictionary</param>\r
- public GuardedSortedDictionary(ISortedDictionary<K, V> sorteddict)\r
- : base(sorteddict)\r
- { this.sorteddict = sorteddict; }\r
-\r
- #endregion\r
-\r
- #region ISortedDictionary<K,V> Members\r
-\r
- /// <summary>\r
- /// The key comparer used by this dictionary.\r
- /// </summary>\r
- /// <value></value>\r
- public SCG.IComparer<K> Comparer { get { return sorteddict.Comparer; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public new ISorted<K> Keys { get { return null; } }\r
-\r
- /// <summary>\r
- /// Get the entry in the wrapped dictionary whose key is the\r
- /// predecessor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such entry exists </exception> \r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- public KeyValuePair<K, V> Predecessor(K key)\r
- { return sorteddict.Predecessor(key); }\r
-\r
-\r
- /// <summary>\r
- /// Get the entry in the wrapped dictionary whose key is the\r
- /// successor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such entry exists </exception> \r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- public KeyValuePair<K, V> Successor(K key)\r
- { return sorteddict.Successor(key); }\r
-\r
-\r
- /// <summary>\r
- /// Get the entry in the wrapped dictionary whose key is the\r
- /// weak predecessor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such entry exists </exception> \r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- public KeyValuePair<K, V> WeakPredecessor(K key)\r
- { return sorteddict.WeakPredecessor(key); }\r
-\r
-\r
- /// <summary>\r
- /// Get the entry in the wrapped dictionary whose key is the\r
- /// weak successor of a specified key.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such entry exists </exception> \r
- /// <param name="key">The key</param>\r
- /// <returns>The entry</returns>\r
- public KeyValuePair<K, V> WeakSuccessor(K key)\r
- { return sorteddict.WeakSuccessor(key); }\r
-\r
- #endregion\r
-\r
- #region ISortedDictionary<K,V> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> FindMin()\r
- {\r
- return sorteddict.FindMin();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> DeleteMin()\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> FindMax()\r
- {\r
- return sorteddict.FindMax();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <returns></returns>\r
- public KeyValuePair<K, V> DeleteMax()\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="c"></param>\r
- /// <param name="lowEntry"></param>\r
- /// <param name="lowIsValid"></param>\r
- /// <param name="highEntry"></param>\r
- /// <param name="highIsValid"></param>\r
- /// <returns></returns>\r
- public bool Cut(IComparable<K> c, out KeyValuePair<K, V> lowEntry, out bool lowIsValid, out KeyValuePair<K, V> highEntry, out bool highIsValid)\r
- {\r
- return sorteddict.Cut(c, out lowEntry, out lowIsValid, out highEntry, out highIsValid); ;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<KeyValuePair<K, V>> RangeFrom(K bot)\r
- {\r
- return new GuardedDirectedEnumerable<KeyValuePair<K, V>>(sorteddict.RangeFrom(bot));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="bot"></param>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<KeyValuePair<K, V>> RangeFromTo(K bot, K top)\r
- {\r
- return new GuardedDirectedEnumerable<KeyValuePair<K, V>>(sorteddict.RangeFromTo(bot, top));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="top"></param>\r
- /// <returns></returns>\r
- public IDirectedEnumerable<KeyValuePair<K, V>> RangeTo(K top)\r
- {\r
- return new GuardedDirectedEnumerable<KeyValuePair<K, V>>(sorteddict.RangeTo(top));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public IDirectedCollectionValue<KeyValuePair<K, V>> RangeAll()\r
- {\r
- return new GuardedDirectedCollectionValue<KeyValuePair<K, V>>(sorteddict.RangeAll());\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="items"></param>\r
- public void AddSorted(System.Collections.Generic.IEnumerable<KeyValuePair<K, V>> items)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="low"></param>\r
- public void RemoveRangeFrom(K low)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="low"></param>\r
- /// <param name="hi"></param>\r
- public void RemoveRangeFromTo(K low, K hi)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="ReadOnlyCollectionException"> since this is a read-only wrappper</exception>\r
- /// <param name="hi"></param>\r
- public void RemoveRangeTo(K hi)\r
- { throw new ReadOnlyCollectionException(); }\r
-\r
- #endregion\r
- }\r
-\r
-}
\ No newline at end of file
+++ /dev/null
-\r
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-#define HASHINDEXnot\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A list collection based on a plain dynamic array data structure.\r
- /// Expansion of the internal array is performed by doubling on demand. \r
- /// The internal array is only shrinked by the Clear method. \r
- ///\r
- /// <i>When the FIFO property is set to false this class works fine as a stack of T.\r
- /// When the FIFO property is set to true the class will function as a (FIFO) queue\r
- /// but very inefficiently, use a LinkedList (<see cref="T:C5.LinkedList`1"/>) instead.</i>\r
- /// </summary>\r
- [Serializable]\r
- public class ArrayList<T> : ArrayBase<T>, IList<T> //, System.Runtime.Serialization.ISerializable\r
-#if HASHINDEX\r
-#else\r
-, IStack<T>, IQueue<T>\r
-#endif\r
- {\r
- #region Fields\r
-\r
- /// <summary>\r
- /// Has this list or view not been invalidated by some operation (by someone calling Dispose())\r
- /// </summary>\r
- bool isValid = true;\r
-\r
- //TODO: wonder if we should save some memory on none-view situations by \r
- // putting these three fields into a single ref field?\r
- /// <summary>\r
- /// The underlying list if we are a view, null else.\r
- /// </summary>\r
- ArrayList<T> underlying;\r
- WeakViewList<ArrayList<T>> views;\r
- WeakViewList<ArrayList<T>>.Node myWeakReference;\r
-\r
- /// <summary>\r
- /// The size of the underlying list.\r
- /// </summary>\r
- int underlyingsize { get { return (underlying ?? this).size; } }\r
-\r
- /// <summary>\r
- /// The underlying field of the FIFO property\r
- /// </summary>\r
- bool fIFO = false;\r
-\r
-#if HASHINDEX\r
- HashSet<KeyValuePair<T, int>> itemIndex;\r
-#endif\r
- #endregion\r
- #region Events\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override EventTypeEnum ListenableEvents { get { return underlying == null ? EventTypeEnum.All : EventTypeEnum.None; } }\r
-\r
-/*\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override event CollectionChangedHandler<T> CollectionChanged\r
- {\r
- add\r
- {\r
- if (underlying == null)\r
- base.CollectionChanged += value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- remove\r
- {\r
- if (underlying == null)\r
- base.CollectionChanged -= value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override event CollectionClearedHandler<T> CollectionCleared\r
- {\r
- add\r
- {\r
- if (underlying == null)\r
- base.CollectionCleared += value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- remove\r
- {\r
- if (underlying == null)\r
- base.CollectionCleared -= value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override event ItemsAddedHandler<T> ItemsAdded\r
- {\r
- add\r
- {\r
- if (underlying == null)\r
- base.ItemsAdded += value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- remove\r
- {\r
- if (underlying == null)\r
- base.ItemsAdded -= value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override event ItemInsertedHandler<T> ItemInserted\r
- {\r
- add\r
- {\r
- if (underlying == null)\r
- base.ItemInserted += value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- remove\r
- {\r
- if (underlying == null)\r
- base.ItemInserted -= value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override event ItemsRemovedHandler<T> ItemsRemoved\r
- {\r
- add\r
- {\r
- if (underlying == null)\r
- base.ItemsRemoved += value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- remove\r
- {\r
- if (underlying == null)\r
- base.ItemsRemoved -= value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override event ItemRemovedAtHandler<T> ItemRemovedAt\r
- {\r
- add\r
- {\r
- if (underlying == null)\r
- base.ItemRemovedAt += value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- remove\r
- {\r
- if (underlying == null)\r
- base.ItemRemovedAt -= value;\r
- else\r
- throw new UnlistenableEventException("Can't listen to a view");\r
- }\r
- }\r
-\r
- */\r
-\r
- #endregion\r
- #region Util\r
-\r
- bool equals(T i1, T i2) { return itemequalityComparer.Equals(i1, i2); }\r
-\r
- /// <summary>\r
- /// Increment or decrement the private size fields\r
- /// </summary>\r
- /// <param name="delta">Increment (with sign)</param>\r
- void addtosize(int delta)\r
- {\r
- size += delta;\r
- if (underlying != null)\r
- underlying.size += delta;\r
- }\r
-\r
- #region Array handling\r
- /// <summary>\r
- /// Double the size of the internal array.\r
- /// </summary>\r
- protected override void expand()\r
- { expand(2 * array.Length, underlyingsize); }\r
-\r
-\r
- /// <summary>\r
- /// Expand the internal array, resetting the index of the first unused element.\r
- /// </summary>\r
- /// <param name="newcapacity">The new capacity (will be rouded upwards to a power of 2).</param>\r
- /// <param name="newsize">The new count of </param>\r
- protected override void expand(int newcapacity, int newsize)\r
- {\r
- base.expand(newcapacity, newsize);\r
- if (underlying != null)\r
- underlying.array = array;\r
- }\r
-\r
- #endregion\r
-\r
- #region Checks\r
- /// <summary>\r
- /// Check if it is valid to perform updates and increment stamp if so.\r
- /// </summary>\r
- /// <exception cref="ViewDisposedException"> If check fails by this list being a disposed view.</exception>\r
- /// <exception cref="ReadOnlyCollectionException"> If check fails by this being a read only list.</exception>\r
- protected override void updatecheck()\r
- {\r
- validitycheck();\r
- base.updatecheck();\r
- if (underlying != null)\r
- underlying.stamp++;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if we are a view that the underlying list has only been updated through us.\r
- /// <para>This method should be called from enumerators etc to guard against \r
- /// modification of the base collection.</para>\r
- /// </summary>\r
- /// <exception cref="ViewDisposedException"> if check fails.</exception>\r
- void validitycheck()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check that the list has not been updated since a particular time.\r
- /// <para>To be used by enumerators and range </para>\r
- /// </summary>\r
- /// <exception cref="ViewDisposedException"> If check fails by this list being a disposed view.</exception>\r
- /// <exception cref="CollectionModifiedException">If the list *has* beeen updated since that time..</exception>\r
- /// <param name="stamp">The stamp indicating the time.</param>\r
- protected override void modifycheck(int stamp)\r
- {\r
- validitycheck();\r
- if (this.stamp != stamp)\r
- throw new CollectionModifiedException();\r
- }\r
-\r
- #endregion\r
-\r
- #region Searching\r
-\r
- /// <summary>\r
- /// Internal version of IndexOf without modification checks.\r
- /// </summary>\r
- /// <param name="item">Item to look for</param>\r
- /// <returns>The index of first occurrence</returns>\r
- int indexOf(T item)\r
- {\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item);\r
- if (itemIndex.Find(ref p) && p.Value >= offset && p.Value < offset + size)\r
- return p.Value - offset;\r
-#else\r
- for (int i = 0; i < size; i++)\r
- if (equals(item, array[offset + i]))\r
- return i;\r
-#endif\r
- return ~size;\r
- }\r
-\r
- /// <summary>\r
- /// Internal version of LastIndexOf without modification checks.\r
- /// </summary>\r
- /// <param name="item">Item to look for</param>\r
- /// <returns>The index of last occurrence</returns>\r
- int lastIndexOf(T item)\r
- {\r
-#if HASHINDEX\r
- return indexOf(item);\r
-#else\r
- for (int i = size - 1; i >= 0; i--)\r
- if (equals(item, array[offset + i]))\r
- return i;\r
- return ~size;\r
-#endif\r
- }\r
- #endregion\r
-\r
- #region Inserting\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// Internal version of Insert with no modification checks.\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException"> if item already in list.</exception>\r
- /// <param name="i">Index to insert at</param>\r
- /// <param name="item">Item to insert</param>\r
-#else\r
- /// <summary>\r
- /// Internal version of Insert with no modification checks.\r
- /// </summary>\r
- /// <param name="i">Index to insert at</param>\r
- /// <param name="item">Item to insert</param>\r
-#endif\r
- protected override void insert(int i, T item)\r
- {\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, offset + i);\r
- if (itemIndex.FindOrAdd(ref p))\r
- throw new DuplicateNotAllowedException("Item already in indexed list: " + item);\r
-#endif\r
- baseinsert(i, item);\r
-#if HASHINDEX\r
- reindex(i + offset + 1);\r
-#endif\r
- }\r
-\r
- private void baseinsert(int i, T item)\r
- {\r
- if (underlyingsize == array.Length)\r
- expand();\r
- i += offset;\r
- if (i < underlyingsize)\r
- Array.Copy(array, i, array, i + 1, underlyingsize - i);\r
- array[i] = item;\r
- addtosize(1);\r
- fixViewsAfterInsert(1, i);\r
- }\r
- #endregion\r
-\r
- #region Removing\r
-\r
- /// <summary>\r
- /// Internal version of RemoveAt with no modification checks.\r
- /// </summary>\r
- /// <param name="i">Index to remove at</param>\r
- /// <returns>The removed item</returns>\r
- T removeAt(int i)\r
- {\r
- i += offset;\r
- fixViewsBeforeSingleRemove(i);\r
- T retval = array[i];\r
- addtosize(-1);\r
- if (underlyingsize > i)\r
- Array.Copy(array, i + 1, array, i, underlyingsize - i);\r
- array[underlyingsize] = default(T);\r
-#if HASHINDEX\r
- itemIndex.Remove(new KeyValuePair<T, int>(retval));\r
- reindex(i);\r
-#endif\r
- return retval;\r
- }\r
- #endregion\r
-\r
- #region Indexing\r
-\r
-#if HASHINDEX\r
- private void reindex(int start) { reindex(start, underlyingsize); }\r
-\r
- private void reindex(int start, int end)\r
- {\r
- for (int j = start; j < end; j++)\r
- itemIndex.UpdateOrAdd(new KeyValuePair<T, int>(array[j], j));\r
- }\r
-#endif\r
- #endregion\r
-\r
- #region fixView utilities\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="added">The actual number of inserted nodes</param>\r
- /// <param name="realInsertionIndex"></param>\r
- void fixViewsAfterInsert(int added, int realInsertionIndex)\r
- {\r
- if (views != null)\r
- foreach (ArrayList<T> view in views)\r
- {\r
- if (view != this)\r
- {\r
- if (view.offset < realInsertionIndex && view.offset + view.size > realInsertionIndex)\r
- view.size += added;\r
- if (view.offset > realInsertionIndex || (view.offset == realInsertionIndex && view.size > 0))\r
- view.offset += added;\r
- }\r
- }\r
- }\r
-\r
- void fixViewsBeforeSingleRemove(int realRemovalIndex)\r
- {\r
- if (views != null)\r
- foreach (ArrayList<T> view in views)\r
- {\r
- if (view != this)\r
- {\r
- if (view.offset <= realRemovalIndex && view.offset + view.size > realRemovalIndex)\r
- view.size--;\r
- if (view.offset > realRemovalIndex)\r
- view.offset--;\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Fix offsets and sizes of other views before removing an interval from this \r
- /// </summary>\r
- /// <param name="start">the start of the interval relative to the array/underlying</param>\r
- /// <param name="count"></param>\r
- void fixViewsBeforeRemove(int start, int count)\r
- {\r
- int clearend = start + count - 1;\r
- if (views != null)\r
- foreach (ArrayList<T> view in views)\r
- {\r
- if (view == this)\r
- continue;\r
- int viewoffset = view.offset, viewend = viewoffset + view.size - 1;\r
- if (start < viewoffset)\r
- {\r
- if (clearend < viewoffset)\r
- view.offset = viewoffset - count;\r
- else\r
- {\r
- view.offset = start;\r
- view.size = clearend < viewend ? viewend - clearend : 0;\r
- }\r
- }\r
- else if (start <= viewend)\r
- view.size = clearend <= viewend ? view.size - count : start - viewoffset;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="otherOffset"></param>\r
- /// <param name="otherSize"></param>\r
- /// <returns>The position of View(otherOffset, otherSize) wrt. this view</returns>\r
- MutualViewPosition viewPosition(int otherOffset, int otherSize)\r
- {\r
- int end = offset + size, otherEnd = otherOffset + otherSize;\r
- if (otherOffset >= end || otherEnd <= offset)\r
- return MutualViewPosition.NonOverlapping;\r
- if (size == 0 || (otherOffset <= offset && end <= otherEnd))\r
- return MutualViewPosition.Contains;\r
- if (otherSize == 0 || (offset <= otherOffset && otherEnd <= end))\r
- return MutualViewPosition.ContainedIn;\r
- return MutualViewPosition.Overlapping;\r
- }\r
-\r
- //TODO: make version that fits the new, more forgiving rules for disposing\r
- void disposeOverlappingViews(bool reverse)\r
- {\r
- if (views != null)\r
- foreach (ArrayList<T> view in views)\r
- {\r
- if (view != this)\r
- {\r
- switch (viewPosition(view.offset, view.size))\r
- {\r
- case MutualViewPosition.ContainedIn:\r
- if (reverse)\r
- view.offset = 2 * offset + size - view.size - view.offset;\r
- else\r
- view.Dispose();\r
- break;\r
- case MutualViewPosition.Overlapping:\r
- view.Dispose();\r
- break;\r
- case MutualViewPosition.Contains:\r
- case MutualViewPosition.NonOverlapping:\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- #endregion\r
-\r
- #endregion\r
-\r
- #region Position, PositionComparer and ViewHandler nested types\r
- class PositionComparer : SCG.IComparer<Position>\r
- {\r
- public int Compare(Position a, Position b)\r
- {\r
- return a.index.CompareTo(b.index);\r
- }\r
- }\r
- /// <summary>\r
- /// During RemoveAll, we need to cache the original endpoint indices of views (??? also for ArrayList?)\r
- /// </summary>\r
- struct Position\r
- {\r
- public readonly ArrayList<T> view;\r
- public readonly int index;\r
- public Position(ArrayList<T> view, bool left)\r
- {\r
- this.view = view;\r
- index = left ? view.offset : view.offset + view.size - 1;\r
- }\r
- public Position(int index) { this.index = index; view = null; }\r
- }\r
-\r
- /// <summary>\r
- /// Handle the update of (other) views during a multi-remove operation.\r
- /// </summary>\r
- struct ViewHandler\r
- {\r
- ArrayList<Position> leftEnds;\r
- ArrayList<Position> rightEnds;\r
- int leftEndIndex, rightEndIndex;\r
- internal readonly int viewCount;\r
- internal ViewHandler(ArrayList<T> list)\r
- {\r
- leftEndIndex = rightEndIndex = viewCount = 0;\r
- leftEnds = rightEnds = null;\r
- if (list.views != null)\r
- foreach (ArrayList<T> v in list.views)\r
- if (v != list)\r
- {\r
- if (leftEnds == null)\r
- {\r
- leftEnds = new ArrayList<Position>();\r
- rightEnds = new ArrayList<Position>();\r
- }\r
- leftEnds.Add(new Position(v, true));\r
- rightEnds.Add(new Position(v, false));\r
- }\r
- if (leftEnds == null)\r
- return;\r
- viewCount = leftEnds.Count;\r
- leftEnds.Sort(new PositionComparer());\r
- rightEnds.Sort(new PositionComparer());\r
- }\r
- /// <summary>\r
- /// This is to be called with realindex pointing to the first node to be removed after a (stretch of) node that was not removed\r
- /// </summary>\r
- /// <param name="removed"></param>\r
- /// <param name="realindex"></param>\r
- internal void skipEndpoints(int removed, int realindex)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex < viewCount && (endpoint = leftEnds[leftEndIndex]).index <= realindex)\r
- {\r
- ArrayList<T> view = endpoint.view;\r
- view.offset = view.offset - removed;\r
- view.size += removed;\r
- leftEndIndex++;\r
- }\r
- while (rightEndIndex < viewCount && (endpoint = rightEnds[rightEndIndex]).index < realindex)\r
- {\r
- endpoint.view.size -= removed;\r
- rightEndIndex++;\r
- }\r
- }\r
- }\r
- internal void updateViewSizesAndCounts(int removed, int realindex)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex < viewCount && (endpoint = leftEnds[leftEndIndex]).index <= realindex)\r
- {\r
- ArrayList<T> view = endpoint.view;\r
- view.offset = view.Offset - removed;\r
- view.size += removed;\r
- leftEndIndex++;\r
- }\r
- while (rightEndIndex < viewCount && (endpoint = rightEnds[rightEndIndex]).index < realindex)\r
- {\r
- endpoint.view.size -= removed;\r
- rightEndIndex++;\r
- }\r
- }\r
- }\r
- }\r
- #endregion\r
-\r
- #region Constructors\r
- /// <summary>\r
- /// Create an array list with default item equalityComparer and initial capacity 8 items.\r
- /// </summary>\r
- public ArrayList() : this(8) { }\r
-\r
-\r
- /// <summary>\r
- /// Create an array list with external item equalityComparer and initial capacity 8 items.\r
- /// </summary>\r
- /// <param name="itemequalityComparer">The external item equalityComparer</param>\r
- public ArrayList(SCG.IEqualityComparer<T> itemequalityComparer) : this(8,itemequalityComparer) { }\r
-\r
-\r
- /// <summary>\r
- /// Create an array list with default item equalityComparer and prescribed initial capacity.\r
- /// </summary>\r
- /// <param name="capacity">The prescribed capacity</param>\r
- public ArrayList(int capacity) : this(capacity,EqualityComparer<T>.Default) { }\r
-\r
-\r
- /// <summary>\r
- /// Create an array list with external item equalityComparer and prescribed initial capacity.\r
- /// </summary>\r
- /// <param name="capacity">The prescribed capacity</param>\r
- /// <param name="itemequalityComparer">The external item equalityComparer</param>\r
- public ArrayList(int capacity, SCG.IEqualityComparer<T> itemequalityComparer) : base(capacity,itemequalityComparer)\r
- {\r
-#if HASHINDEX\r
- itemIndex = new HashSet<KeyValuePair<T, int>>(new KeyValuePairEqualityComparer<T, int>(itemequalityComparer));\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region IList<T> Members\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <value>The first item in this list.</value>\r
- [Tested]\r
- public virtual T First\r
- {\r
- [Tested]\r
- get\r
- {\r
- validitycheck();\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- return array[offset];\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <value>The last item in this list.</value>\r
- [Tested]\r
- public virtual T Last\r
- {\r
- [Tested]\r
- get\r
- {\r
- validitycheck();\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- return array[offset + size - 1];\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Since <code>Add(T item)</code> always add at the end of the list,\r
- /// this describes if list has FIFO or LIFO semantics.\r
- /// </summary>\r
- /// <value>True if the <code>Remove()</code> operation removes from the\r
- /// start of the list, false if it removes from the end. The default for a new array list is false.</value>\r
- [Tested]\r
- public virtual bool FIFO\r
- {\r
- [Tested]\r
- get { validitycheck(); return fIFO; }\r
- [Tested]\r
- set { updatecheck(); fIFO = value; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public virtual bool IsFixedSize\r
- {\r
- get { validitycheck(); return false; }\r
- }\r
-\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// On this list, this indexer is read/write.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if index is negative or\r
- /// >= the size of the collection.</exception>\r
- /// <exception cref="DuplicateNotAllowedException"> By the get operation\r
- /// if the item already is present somewhere else in the list.</exception>\r
- /// <value>The index'th item of this list.</value>\r
- /// <param name="index">The index of the item to fetch or store.</param>\r
-#else\r
- /// <summary>\r
- /// On this list, this indexer is read/write.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if index is negative or\r
- /// >= the size of the collection.</exception>\r
- /// <value>The index'th item of this list.</value>\r
- /// <param name="index">The index of the item to fetch or store.</param>\r
-#endif\r
- [Tested]\r
- public virtual T this[int index]\r
- {\r
- [Tested]\r
- get\r
- {\r
- validitycheck();\r
- if (index < 0 || index >= size)\r
- throw new IndexOutOfRangeException();\r
-\r
- return array[offset + index];\r
- }\r
- [Tested]\r
- set\r
- {\r
- updatecheck();\r
- if (index < 0 || index >= size)\r
- throw new IndexOutOfRangeException();\r
- index += offset;\r
- T item = array[index];\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(value, index);\r
- if (itemequalityComparer.Equals(value, item))\r
- {\r
- array[index] = value;\r
- itemIndex.Update(p);\r
- }\r
- else if (!itemIndex.FindOrAdd(ref p))\r
- {\r
- itemIndex.Remove(new KeyValuePair<T, int>(item));\r
- array[index] = value;\r
- }\r
- else\r
- throw new DuplicateNotAllowedException("Item already in indexed list");\r
-#else\r
- array[index] = value;\r
-#endif\r
- (underlying ?? this).raiseForSetThis(index, value, item);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual Speed IndexingSpeed { get { return Speed.Constant; } }\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// Insert an item at a specific index location in this list. \r
- ///</summary>\r
- /// <exception cref="IndexOutOfRangeException"> if index is negative or\r
- /// > the size of the collection. </exception>\r
- /// <exception cref="DuplicateNotAllowedException"> \r
- /// If the item is already present in the list.</exception>\r
- /// <param name="index">The index at which to insert.</param>\r
- /// <param name="item">The item to insert.</param>\r
-#else\r
- /// <summary>\r
- /// Insert an item at a specific index location in this list. \r
- ///</summary>\r
- /// <exception cref="IndexOutOfRangeException"> if i is negative or\r
- /// > the size of the collection. </exception>\r
- /// <param name="index">The index at which to insert.</param>\r
- /// <param name="item">The item to insert.</param>\r
-#endif\r
- [Tested]\r
- public virtual void Insert(int index, T item)\r
- {\r
- updatecheck();\r
- if (index < 0 || index > size)\r
- throw new IndexOutOfRangeException();\r
-\r
- insert(index, item);\r
- (underlying ?? this).raiseForInsert(index + offset, item);\r
- }\r
-\r
- /// <summary>\r
- /// Insert an item at the end of a compatible view, used as a pointer.\r
- /// <para>The <code>pointer</code> must be a view on the same list as\r
- /// <code>this</code> and the endpoitn of <code>pointer</code> must be\r
- /// a valid insertion point of <code>this</code></para>\r
- /// </summary>\r
- /// <exception cref="IncompatibleViewException">If <code>pointer</code> \r
- /// is not a view on or the same list as <code>this</code></exception>\r
- /// <exception cref="IndexOutOfRangeException"><b>??????</b> if the endpoint of \r
- /// <code>pointer</code> is not inside <code>this</code></exception>\r
- /// <exception cref="DuplicateNotAllowedException"> if the list has\r
- /// <code>AllowsDuplicates==false</code> and the item is \r
- /// already in the list.</exception>\r
- /// <param name="pointer"></param>\r
- /// <param name="item"></param>\r
- public void Insert(IList<T> pointer, T item)\r
- {\r
- if ((pointer == null) || ((pointer.Underlying ?? pointer) != (underlying ?? this)))\r
- throw new IncompatibleViewException();\r
- Insert(pointer.Offset + pointer.Count - Offset, item);\r
- }\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// Insert into this list all items from an enumerable collection starting \r
- /// at a particular index.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if index is negative or\r
- /// > the size of the collection.</exception>\r
- /// <exception cref="DuplicateNotAllowedException"> If <code>items</code> \r
- /// contains duplicates or some item already present in the list.</exception>\r
- /// <param name="index">Index to start inserting at</param>\r
- /// <param name="items">Items to insert</param>\r
-#else\r
- /// <summary>\r
- /// Insert into this list all items from an enumerable collection starting \r
- /// at a particular index.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if index is negative or\r
- /// > the size of the collection.</exception>\r
- /// <param name="index">Index to start inserting at</param>\r
- /// <param name="items">Items to insert</param>\r
- /// <typeparam name="U"></typeparam>\r
-#endif\r
- [Tested]\r
- public virtual void InsertAll<U>(int index, SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- if (index < 0 || index > size)\r
- throw new IndexOutOfRangeException();\r
- index += offset;\r
- int toadd = EnumerableBase<U>.countItems(items);\r
- if (toadd == 0)\r
- return;\r
- if (toadd + underlyingsize > array.Length)\r
- expand(toadd + underlyingsize, underlyingsize);\r
- if (underlyingsize > index)\r
- Array.Copy(array, index, array, index + toadd, underlyingsize - index);\r
- int i = index;\r
- try\r
- {\r
-\r
- foreach (T item in items)\r
- {\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, i);\r
- if (itemIndex.FindOrAdd(ref p))\r
- throw new DuplicateNotAllowedException("Item already in indexed list");\r
-#endif\r
- array[i++] = item;\r
- }\r
- }\r
- finally\r
- {\r
- int added = i - index;\r
- if (added < toadd)\r
- {\r
- Array.Copy(array, index + toadd, array, i, underlyingsize - index);\r
- Array.Clear(array, underlyingsize + added, toadd - added);\r
- }\r
- if (added > 0)\r
- {\r
- addtosize(added);\r
-#if HASHINDEX\r
- reindex(i);\r
-#endif\r
- fixViewsAfterInsert(added, index);\r
- (underlying ?? this).raiseForInsertAll(index, added);\r
- }\r
- }\r
- }\r
- private void raiseForInsertAll(int index, int added)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- if ((ActiveEvents & (EventTypeEnum.Added | EventTypeEnum.Inserted)) != 0)\r
- for (int j = index; j < index + added; j++)\r
- {\r
- raiseItemInserted(array[j], j);\r
- raiseItemsAdded(array[j], 1);\r
- }\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// Insert an item at the front of this list;\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException">If the item is already in the list</exception>\r
- /// <param name="item">The item to insert.</param>\r
-#else\r
- /// <summary>\r
- /// Insert an item at the front of this list;\r
- /// </summary>\r
- /// <param name="item">The item to insert.</param>\r
-#endif\r
- [Tested]\r
- public virtual void InsertFirst(T item)\r
- {\r
- updatecheck();\r
- insert(0, item);\r
- (underlying ?? this).raiseForInsert(offset, item);\r
- }\r
-\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// Insert an item at the back of this list.\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException">If the item is already in the list</exception>\r
- /// <param name="item">The item to insert.</param>\r
-#else\r
- /// <summary>\r
- /// Insert an item at the back of this list.\r
- /// </summary>\r
- /// <param name="item">The item to insert.</param>\r
-#endif\r
- [Tested]\r
- public virtual void InsertLast(T item)\r
- {\r
- updatecheck();\r
- insert(size, item);\r
- (underlying ?? this).raiseForInsert(size - 1 + offset, item);\r
- }\r
-\r
-\r
- //NOTE: if the filter throws an exception, no result will be returned.\r
- /// <summary>\r
- /// Create a new list consisting of the items of this list satisfying a \r
- /// certain predicate.\r
- /// <para>The new list will be of type ArrayList</para>\r
- /// </summary>\r
- /// <param name="filter">The filter delegate defining the predicate.</param>\r
- /// <returns>The new list.</returns>\r
- [Tested]\r
- public virtual IList<T> FindAll(Fun<T, bool> filter)\r
- {\r
- validitycheck();\r
- int stamp = this.stamp;\r
- ArrayList<T> res = new ArrayList<T>(itemequalityComparer);\r
- int j = 0, rescap = res.array.Length;\r
- for (int i = 0; i < size; i++)\r
- {\r
- T a = array[offset + i];\r
- bool found = filter(a);\r
- modifycheck(stamp);\r
- if (found)\r
- {\r
- if (j == rescap) res.expand(rescap = 2 * rescap, j);\r
- res.array[j++] = a;\r
- }\r
- }\r
- res.size = j;\r
-#if HASHINDEX\r
- res.reindex(0);\r
-#endif\r
- return res;\r
- }\r
-\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list. The new list will use the default item equalityComparer for the item type V.\r
- /// <para>The new list will be of type ArrayList</para>\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException">If <code>mapper</code>\r
- /// creates duplicates</exception>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <returns>The new list.</returns>\r
-#else\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list. The new list will use the default item equalityComparer for the item type V.\r
- /// <para>The new list will be of type ArrayList</para>\r
- /// </summary>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <returns>The new list.</returns>\r
-#endif\r
- [Tested]\r
- public virtual IList<V> Map<V>(Fun<T, V> mapper)\r
- {\r
- validitycheck();\r
-\r
- ArrayList<V> res = new ArrayList<V>(size);\r
-\r
- return map<V>(mapper, res);\r
- }\r
-\r
-#if HASHINDEX\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list. The new list will use a specified item equalityComparer for the item type.\r
- /// <para>The new list will be of type ArrayList</para>\r
- /// </summary>\r
- /// <exception cref="DuplicateNotAllowedException">If <code>mapper</code>\r
- /// creates duplicates</exception>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <param name="itemequalityComparer">The item equalityComparer to use for the new list</param>\r
- /// <returns>The new list.</returns>\r
-#else\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list. The new list will use a specified item equalityComparer for the item type.\r
- /// <para>The new list will be of type ArrayList</para>\r
- /// </summary>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <param name="itemequalityComparer">The item equalityComparer to use for the new list</param>\r
- /// <returns>The new list.</returns>\r
-#endif\r
- public virtual IList<V> Map<V>(Fun<T, V> mapper, SCG.IEqualityComparer<V> itemequalityComparer)\r
- {\r
- validitycheck();\r
-\r
- ArrayList<V> res = new ArrayList<V>(size, itemequalityComparer);\r
-\r
- return map<V>(mapper, res);\r
- }\r
-\r
- private IList<V> map<V>(Fun<T, V> mapper, ArrayList<V> res)\r
- {\r
- int stamp = this.stamp;\r
- if (size > 0)\r
- for (int i = 0; i < size; i++)\r
- {\r
- V mappeditem = mapper(array[offset + i]);\r
- modifycheck(stamp);\r
-#if HASHINDEX\r
- KeyValuePair<V, int> p = new KeyValuePair<V, int>(mappeditem, i);\r
- if (res.itemIndex.FindOrAdd(ref p))\r
- throw new ArgumentException("Mapped item already in indexed list");\r
-#endif\r
- res.array[i] = mappeditem;\r
- }\r
- res.size = size;\r
- return res;\r
- }\r
-\r
- /// <summary>\r
- /// Remove one item from the list: from the front if <code>FIFO</code>\r
- /// is true, else from the back.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T Remove()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException("List is empty");\r
-\r
- T item = removeAt(fIFO ? 0 : size - 1);\r
- (underlying ?? this).raiseForRemove(item);\r
- return item;\r
- }\r
-\r
- /// <summary>\r
- /// Remove one item from the fromnt of the list.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T RemoveFirst()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException("List is empty");\r
-\r
- T item = removeAt(0);\r
- (underlying ?? this).raiseForRemoveAt(offset, item);\r
- return item;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove one item from the back of the list.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T RemoveLast()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException("List is empty");\r
-\r
- T item = removeAt(size - 1);\r
- (underlying ?? this).raiseForRemoveAt(size + offset, item);\r
- return item;\r
- }\r
-\r
- /// <summary>\r
- /// Create a list view on this list. \r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the start or count is negative\r
- /// or the range does not fit within list.</exception>\r
- /// <param name="start">The index in this list of the start of the view.</param>\r
- /// <param name="count">The size of the view.</param>\r
- /// <returns>The new list view.</returns>\r
- [Tested]\r
- public virtual IList<T> View(int start, int count)\r
- {\r
- validitycheck();\r
- checkRange(start, count);\r
- if (views == null)\r
- views = new WeakViewList<ArrayList<T>>();\r
- ArrayList<T> retval = (ArrayList<T>)MemberwiseClone();\r
-\r
-\r
- retval.underlying = underlying != null ? underlying : this;\r
- retval.offset = start + offset;\r
- retval.size = count;\r
- retval.myWeakReference = views.Add(retval);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Create a list view on this list containing the (first) occurrence of a particular item.\r
- /// <para>Returns <code>null</code> if the item is not in this list.</para>\r
- /// </summary>\r
- /// <param name="item">The item to find.</param>\r
- /// <returns>The new list view.</returns>\r
- [Tested]\r
- public virtual IList<T> ViewOf(T item)\r
- {\r
- int index = indexOf(item);\r
- if (index < 0)\r
- return null;\r
- return View(index, 1);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a list view on this list containing the last occurrence of a particular item. \r
- /// <para>Returns <code>null</code> if the item is not in this list.</para>\r
- /// </summary>\r
- /// <param name="item">The item to find.</param>\r
- /// <returns>The new list view.</returns>\r
- [Tested]\r
- public virtual IList<T> LastViewOf(T item)\r
- {\r
- int index = lastIndexOf(item);\r
- if (index < 0)\r
- return null;\r
- return View(index, 1);\r
- }\r
-\r
- /// <summary>\r
- /// Null if this list is not a view.\r
- /// </summary>\r
- /// <value>Underlying list for view.</value>\r
- [Tested]\r
- public virtual IList<T> Underlying { [Tested]get { return underlying; } }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <value>Offset for this list view or 0 for an underlying list.</value>\r
- [Tested]\r
- public virtual int Offset { [Tested]get { return offset; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual bool IsValid { get { return isValid; } }\r
-\r
- /// <summary>\r
- /// Slide this list view along the underlying list.\r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the operation\r
- /// would bring either end of the view outside the underlying list.</exception>\r
- /// <param name="offset">The signed amount to slide: positive to slide\r
- /// towards the end.</param>\r
- [Tested]\r
- public virtual IList<T> Slide(int offset)\r
- {\r
- if (!TrySlide(offset, size))\r
- throw new ArgumentOutOfRangeException();\r
- return this;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Slide this list view along the underlying list, changing its size.\r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the operation\r
- /// would bring either end of the view outside the underlying list.</exception>\r
- /// <param name="offset">The signed amount to slide: positive to slide\r
- /// towards the end.</param>\r
- /// <param name="size">The new size of the view.</param>\r
- [Tested]\r
- public virtual IList<T> Slide(int offset, int size)\r
- {\r
- if (!TrySlide(offset, size))\r
- throw new ArgumentOutOfRangeException();\r
- return this;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <param name="offset"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public virtual bool TrySlide(int offset)\r
- {\r
- return TrySlide(offset, size);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <param name="offset"></param>\r
- /// <param name="size"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public virtual bool TrySlide(int offset, int size)\r
- {\r
- updatecheck();\r
- if (underlying == null)\r
- throw new NotAViewException("Not a view");\r
-\r
- int newoffset = this.offset + offset;\r
- int newsize = size;\r
-\r
- if (newoffset < 0 || newsize < 0 || newoffset + newsize > underlyingsize)\r
- return false;\r
-\r
- this.offset = newoffset;\r
- this.size = newsize;\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// <para>Returns null if <code>otherView</code> is strictly to the left of this view</para>\r
- /// </summary>\r
- /// <param name="otherView"></param>\r
- /// <exception cref="IncompatibleViewException">If otherView does not have the same underlying list as this</exception>\r
- /// <returns></returns>\r
- public virtual IList<T> Span(IList<T> otherView)\r
- {\r
- if ((otherView == null) || ((otherView.Underlying ?? otherView) != (underlying ?? this)))\r
- throw new IncompatibleViewException();\r
- if (otherView.Offset + otherView.Count - Offset < 0)\r
- return null;\r
- return (underlying ?? this).View(Offset, otherView.Offset + otherView.Count - Offset);\r
- }\r
-\r
- /// <summary>\r
- /// Reverst the list so the items are in the opposite sequence order.\r
- /// </summary>\r
- [Tested]\r
- public virtual void Reverse()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- for (int i = 0, length = size / 2, end = offset + size - 1; i < length; i++)\r
- {\r
- T swap = array[offset + i];\r
-\r
- array[offset + i] = array[end - i];\r
- array[end - i] = swap;\r
- }\r
-#if HASHINDEX\r
- reindex(offset, offset + size);\r
-#endif\r
- //TODO: be more forgiving wrt. disposing\r
- disposeOverlappingViews(true);\r
- (underlying ?? this).raiseCollectionChanged();\r
- }\r
-\r
- /// <summary>\r
- /// Check if this list is sorted according to the default sorting order\r
- /// for the item type T, as defined by the <see cref="T:C5.Comparer`1"/> class \r
- /// </summary>\r
- /// <exception cref="NotComparableException">if T is not comparable</exception>\r
- /// <returns>True if the list is sorted, else false.</returns>\r
- [Tested]\r
- public bool IsSorted() { return IsSorted(Comparer<T>.Default); }\r
-\r
- /// <summary>\r
- /// Check if this list is sorted according to a specific sorting order.\r
- /// </summary>\r
- /// <param name="c">The comparer defining the sorting order.</param>\r
- /// <returns>True if the list is sorted, else false.</returns>\r
- [Tested]\r
- public virtual bool IsSorted(SCG.IComparer<T> c)\r
- {\r
- validitycheck();\r
- for (int i = offset + 1, end = offset + size; i < end; i++)\r
- if (c.Compare(array[i - 1], array[i]) > 0)\r
- return false;\r
-\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// Sort the items of the list according to the default sorting order\r
- /// for the item type T, as defined by the Comparer[T] class \r
- /// (<see cref="T:C5.Comparer`1"/>).\r
- /// </summary>\r
- /// <exception cref="InvalidOperationException">if T is not comparable</exception>\r
- public virtual void Sort()\r
- {\r
- Sort(Comparer<T>.Default);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Sort the items of the list according to a specific sorting order.\r
- /// </summary>\r
- /// <param name="comparer">The comparer defining the sorting order.</param>\r
- [Tested]\r
- public virtual void Sort(SCG.IComparer<T> comparer)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- Sorting.IntroSort<T>(array, offset, size, comparer);\r
- disposeOverlappingViews(false);\r
-#if HASHINDEX\r
- reindex(offset, offset + size);\r
-#endif\r
- (underlying ?? this).raiseCollectionChanged();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Randomly shuffle the items of this list. \r
- /// </summary>\r
- public virtual void Shuffle() { Shuffle(new C5Random()); }\r
-\r
-\r
- /// <summary>\r
- /// Shuffle the items of this list according to a specific random source.\r
- /// </summary>\r
- /// <param name="rnd">The random source.</param>\r
- public virtual void Shuffle(Random rnd)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- for (int i = offset, top = offset + size, end = top - 1; i < end; i++)\r
- {\r
- int j = rnd.Next(i, top);\r
- if (j != i)\r
- {\r
- T tmp = array[i];\r
- array[i] = array[j];\r
- array[j] = tmp;\r
- }\r
- }\r
- disposeOverlappingViews(false);\r
-#if HASHINDEX\r
- reindex(offset, offset + size);\r
-#endif\r
- (underlying ?? this).raiseCollectionChanged();\r
- }\r
- #endregion\r
-\r
- #region IIndexed<T> Members\r
-\r
- /// <summary>\r
- /// Search for an item in the list going forwrds from the start.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of item from start.</returns>\r
- [Tested]\r
- public virtual int IndexOf(T item) { validitycheck(); return indexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// Search for an item in the list going backwords from the end.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of item from the end.</returns>\r
- [Tested]\r
- public virtual int LastIndexOf(T item) { validitycheck(); return lastIndexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// Remove the item at a specific position of the list.\r
- /// </summary>\r
- /// <exception cref="IndexOutOfRangeException"> if index is negative or\r
- /// >= the size of the collection.</exception>\r
- /// <param name="index">The index of the item to remove.</param>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T RemoveAt(int index)\r
- {\r
- updatecheck();\r
- if (index < 0 || index >= size)\r
- throw new IndexOutOfRangeException("Index out of range for sequenced collection");\r
-\r
- T item = removeAt(index);\r
- (underlying ?? this).raiseForRemoveAt(offset + index, item);\r
- return item;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items in an index interval.\r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException">If <code>start</code>\r
- /// and <code>count</code> does not describe a valid interval in the list</exception> \r
- /// <param name="start">The index of the first item to remove.</param>\r
- /// <param name="count">The number of items to remove.</param>\r
- [Tested]\r
- public virtual void RemoveInterval(int start, int count)\r
- {\r
- updatecheck();\r
- if (count == 0)\r
- return;\r
- checkRange(start, count);\r
- start += offset;\r
- fixViewsBeforeRemove(start, count);\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>();\r
- for (int i = start, end = start + count; i < end; i++)\r
- {\r
- p.Key = array[i];\r
- itemIndex.Remove(p);\r
- }\r
-#endif\r
- Array.Copy(array, start + count, array, start, underlyingsize - start - count);\r
- addtosize(-count);\r
- Array.Clear(array, underlyingsize, count);\r
-#if HASHINDEX\r
- reindex(start);\r
-#endif\r
- (underlying ?? this).raiseForRemoveInterval(start, count);\r
- }\r
- void raiseForRemoveInterval(int start, int count)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseCollectionCleared(size == 0, count, start);\r
- raiseCollectionChanged();\r
- }\r
- }\r
-#endregion\r
-\r
- #region ICollection<T> Members\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>Speed.Linear</value>\r
- [Tested]\r
- public virtual Speed ContainsSpeed\r
- {\r
- [Tested]\r
- get\r
- {\r
-#if HASHINDEX\r
- return Speed.Constant;\r
-#else\r
- return Speed.Linear;\r
-#endif\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public override int GetUnsequencedHashCode()\r
- { validitycheck(); return base.GetUnsequencedHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="that"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public override bool UnsequencedEquals(ICollection<T> that)\r
- { validitycheck(); return base.UnsequencedEquals(that); }\r
-\r
- /// <summary>\r
- /// Check if this collection contains (an item equivalent to according to the\r
- /// itemequalityComparer) a particular value.\r
- /// </summary>\r
- /// <param name="item">The value to check for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public virtual bool Contains(T item)\r
- { validitycheck(); return indexOf(item) >= 0; }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public virtual bool Find(ref T item)\r
- {\r
- validitycheck();\r
-\r
- int i;\r
-\r
- if ((i = indexOf(item)) >= 0)\r
- {\r
- item = array[offset + i];\r
- return true;\r
- }\r
-\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value. This will only update the first \r
- /// mathching item.\r
- /// </summary>\r
- /// <param name="item">Value to update.</param>\r
- /// <returns>True if the item was found and hence updated.</returns>\r
- [Tested]\r
- public virtual bool Update(T item)\r
- {\r
- T olditem;\r
- return Update(item, out olditem);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool Update(T item, out T olditem)\r
- {\r
- updatecheck();\r
- int i;\r
-\r
- if ((i = indexOf(item)) >= 0)\r
- {\r
- olditem = array[offset + i];\r
- array[offset + i] = item;\r
-#if HASHINDEX\r
- itemIndex.Update(new KeyValuePair<T, int>(item, offset + i));\r
-#endif\r
- (underlying ?? this).raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found. Else, add the item to the collection.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the item was found (hence not added).</returns>\r
- [Tested]\r
- public virtual bool FindOrAdd(ref T item)\r
- {\r
- updatecheck();\r
- if (Find(ref item))\r
- return true;\r
-\r
- Add(item);\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value. This will only update the first \r
- /// mathching item.\r
- /// </summary>\r
- /// <param name="item">Value to update.</param>\r
- /// <returns>True if the item was found and hence updated.</returns>\r
- [Tested]\r
- public virtual bool UpdateOrAdd(T item)\r
- {\r
- updatecheck();\r
- if (Update(item))\r
- return true;\r
-\r
- Add(item);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool UpdateOrAdd(T item, out T olditem)\r
- {\r
- updatecheck();\r
- if (Update(item, out olditem))\r
- return true;\r
-\r
- Add(item);\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Remove a particular item from this list. The item will be searched \r
- /// for from the end of the list if <code>FIFO == false</code> (the default), \r
- /// else from the start.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public virtual bool Remove(T item)\r
- {\r
- updatecheck();\r
-\r
- int i = fIFO ? indexOf(item) : lastIndexOf(item);\r
-\r
- if (i < 0)\r
- return false;\r
-\r
- T removeditem = removeAt(i);\r
- (underlying ?? this).raiseForRemove(removeditem);\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the first copy of a particular item from this collection if found.\r
- /// If an item was removed, report a binary copy of the actual item removed in \r
- /// the argument. The item will be searched \r
- /// for from the end of the list if <code>FIFO == false</code> (the default), \r
- /// else from the start.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <param name="removeditem">The removed value.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public virtual bool Remove(T item, out T removeditem)\r
- {\r
- updatecheck();\r
-\r
- int i = fIFO ? indexOf(item) : lastIndexOf(item);\r
-\r
- if (i < 0)\r
- {\r
- removeditem = default(T);\r
- return false;\r
- }\r
-\r
- removeditem = removeAt(i);\r
- (underlying ?? this).raiseForRemove(removeditem);\r
- return true;\r
- }\r
-\r
-\r
- //TODO: remove from end or according to FIFO?\r
- /// <summary>\r
- /// Remove all items in another collection from this one, taking multiplicities into account.\r
- /// Matching items will be removed from the front. Current implementation is not optimal.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to remove.</param>\r
- [Tested]\r
- public virtual void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- //TODO: reactivate the old code for small sizes\r
- HashBag<T> toremove = new HashBag<T>(itemequalityComparer);\r
- toremove.AddAll(items);\r
- if (toremove.Count == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int j = offset;\r
- int removed = 0;\r
- int i = offset, end = offset + size;\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>();\r
-#endif\r
- while (i < end)\r
- {\r
- T item;\r
- //pass by a stretch of nodes\r
- while (i < end && !toremove.Contains(item = array[i]))\r
- {\r
-#if HASHINDEX\r
- if (j < i)\r
- {\r
- p.Key = item;\r
- p.Value = j;\r
- itemIndex.Update(p);\r
- }\r
-#endif\r
- //if (j<i)\r
- array[j] = item;\r
- i++; j++;\r
- }\r
- viewHandler.skipEndpoints(removed, i);\r
- //Remove a stretch of nodes\r
- while (i < end && toremove.Remove(item = array[i]))\r
- {\r
-#if HASHINDEX\r
- p.Key = item;\r
- itemIndex.Remove(p);\r
-#endif\r
- if (mustFire)\r
- raiseHandler.Remove(item);\r
- removed++;\r
- i++;\r
- viewHandler.updateViewSizesAndCounts(removed, i);\r
- }\r
- }\r
- if (removed == 0)\r
- return;\r
- viewHandler.updateViewSizesAndCounts(removed, underlyingsize);\r
- Array.Copy(array, offset + size, array, j, underlyingsize - offset - size);\r
- addtosize(-removed);\r
- Array.Clear(array, underlyingsize, removed);\r
-#if HASHINDEX\r
- reindex(j);\r
-#endif\r
- if (mustFire)\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- void RemoveAll(Fun<T,bool> predicate)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int j = offset;\r
- int removed = 0;\r
- int i = offset, end = offset + size;\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>();\r
-#endif\r
- while (i < end)\r
- {\r
- T item;\r
- //pass by a stretch of nodes\r
- while (i < end && !predicate(item = array[i]))\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- if (j < i)\r
- {\r
- p.Key = item;\r
- p.Value = j;\r
- itemIndex.Update(p);\r
- }\r
-#endif\r
- //if (j<i)\r
- array[j] = item;\r
- i++; j++;\r
- }\r
- updatecheck();\r
- viewHandler.skipEndpoints(removed, i);\r
- //Remove a stretch of nodes\r
- while (i < end && predicate(item = array[i]))\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- p.Key = item;\r
- itemIndex.Remove(p);\r
-#endif\r
- if (mustFire)\r
- raiseHandler.Remove(item);\r
- removed++;\r
- i++;\r
- viewHandler.updateViewSizesAndCounts(removed, i);\r
- }\r
- updatecheck();\r
- }\r
- if (removed == 0)\r
- return;\r
- viewHandler.updateViewSizesAndCounts(removed, underlyingsize);\r
- Array.Copy(array, offset + size, array, j, underlyingsize - offset - size);\r
- addtosize(-removed);\r
- Array.Clear(array, underlyingsize, removed);\r
-#if HASHINDEX\r
- reindex(j);\r
-#endif\r
- if (mustFire)\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items from this collection, resetting internal array size.\r
- /// </summary>\r
- [Tested]\r
- public override void Clear()\r
- {\r
- if (underlying == null)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- int oldsize = size;\r
- fixViewsBeforeRemove(0, size);\r
-#if HASHINDEX\r
- itemIndex.Clear();\r
-#endif\r
- array = new T[8];\r
- size = 0;\r
- (underlying ?? this).raiseForRemoveInterval(offset, oldsize);\r
- }\r
- else\r
- RemoveInterval(0, size);\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items not in some other collection from this one, taking multiplicities into account.\r
- /// Items are retained front first. \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to retain.</param>\r
- [Tested]\r
- public virtual void RetainAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- HashBag<T> toretain = new HashBag<T>(itemequalityComparer);\r
- toretain.AddAll(items);\r
- if (toretain.Count == 0)\r
- {\r
- Clear();\r
- return;\r
- }\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int j = offset;\r
- int removed = 0;\r
- int i = offset, end = offset + size;\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>();\r
-#endif\r
- while (i < end)\r
- {\r
- T item;\r
- //pass by a stretch of nodes\r
- while (i < end && toretain.Remove(item = array[i]))\r
- {\r
-#if HASHINDEX\r
- if (j < i)\r
- {\r
- p.Key = item;\r
- p.Value = j;\r
- itemIndex.Update(p);\r
- }\r
-#endif\r
- //if (j<i)\r
- array[j] = item;\r
- i++; j++;\r
- }\r
- viewHandler.skipEndpoints(removed, i);\r
- //Remove a stretch of nodes\r
- while (i < end && !toretain.Contains(item = array[i]))\r
- {\r
-#if HASHINDEX\r
- p.Key = item;\r
- itemIndex.Remove(p);\r
-#endif\r
- if (mustFire)\r
- raiseHandler.Remove(item);\r
- removed++;\r
- i++;\r
- viewHandler.updateViewSizesAndCounts(removed, i);\r
- }\r
- }\r
- if (removed == 0)\r
- return;\r
- viewHandler.updateViewSizesAndCounts(removed, underlyingsize);\r
- Array.Copy(array, offset + size, array, j, underlyingsize - offset - size);\r
- addtosize(-removed);\r
- Array.Clear(array, underlyingsize, removed);\r
-#if HASHINDEX\r
- reindex(j);\r
-#endif\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- void RetainAll(Fun<T, bool> predicate)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int j = offset;\r
- int removed = 0;\r
- int i = offset, end = offset + size;\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>();\r
-#endif\r
- while (i < end)\r
- {\r
- T item;\r
- //pass by a stretch of nodes\r
- while (i < end && predicate(item = array[i]))\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- if (j < i)\r
- {\r
- p.Key = item;\r
- p.Value = j;\r
- itemIndex.Update(p);\r
- }\r
-#endif\r
- //if (j<i)\r
- array[j] = item;\r
- i++; j++;\r
- }\r
- updatecheck();\r
- viewHandler.skipEndpoints(removed, i);\r
- //Remove a stretch of nodes\r
- while (i < end && !predicate(item = array[i]))\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- p.Key = item;\r
- itemIndex.Remove(p);\r
-#endif\r
- if (mustFire)\r
- raiseHandler.Remove(item);\r
- removed++;\r
- i++;\r
- viewHandler.updateViewSizesAndCounts(removed, i);\r
- }\r
- updatecheck();\r
- }\r
- if (removed == 0)\r
- return;\r
- viewHandler.updateViewSizesAndCounts(removed, underlyingsize);\r
- Array.Copy(array, offset + size, array, j, underlyingsize - offset - size);\r
- addtosize(-removed);\r
- Array.Clear(array, underlyingsize, removed);\r
-#if HASHINDEX\r
- reindex(j);\r
-#endif\r
- raiseHandler.Raise();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains all the values in another collection,\r
- /// taking multiplicities into account.\r
- /// Current implementation is not optimal.\r
- /// </summary>\r
- /// <param name="items">The </param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if all values in <code>items</code>is in this collection.</returns>\r
- [Tested]\r
- public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- validitycheck();\r
-#if HASHINDEX\r
- foreach (T item in items)\r
- if (indexOf(item) < 0)\r
- return false;\r
-\r
- return true;\r
-#else\r
- //TODO: use aux hash bag to obtain linear time procedure\r
- HashBag<T> tomatch = new HashBag<T>(itemequalityComparer);\r
- tomatch.AddAll(items);\r
- if (tomatch.Count == 0)\r
- return true;\r
- for (int i = offset, end = offset + size; i < end; i++)\r
- {\r
- tomatch.Remove(array[i]);\r
- if (tomatch.Count == 0)\r
- return true;\r
- }\r
- return false;\r
-#endif\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Count the number of items of the collection equal to a particular value.\r
- /// Returns 0 if and only if the value is not in the collection.\r
- /// </summary>\r
- /// <param name="item">The value to count.</param>\r
- /// <returns>The number of copies found.</returns>\r
- [Tested]\r
- public virtual int ContainsCount(T item)\r
- {\r
- validitycheck();\r
-#if HASHINDEX\r
- return indexOf(item) >= 0 ? 1 : 0;\r
-#else\r
- int count = 0;\r
- for (int i = 0; i < size; i++)\r
- if (equals(item, array[offset + i]))\r
- count++;\r
- return count;\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<T> UniqueItems()\r
- {\r
-#if HASHINDEX\r
- return this;\r
-#else\r
- HashBag<T> hashbag = new HashBag<T>(itemequalityComparer);\r
- hashbag.AddAll(this);\r
- return hashbag.UniqueItems();\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities()\r
- {\r
-#if HASHINDEX\r
- return new MultiplicityOne<T>(this);\r
-#else\r
- HashBag<T> hashbag = new HashBag<T>(itemequalityComparer);\r
- hashbag.AddAll(this);\r
- return hashbag.ItemMultiplicities();\r
-#endif\r
- }\r
-\r
-\r
-\r
-\r
-\r
- /// <summary>\r
- /// Remove all items equal to a given one.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- [Tested]\r
- public virtual void RemoveAllCopies(T item)\r
- {\r
-#if HASHINDEX\r
- Remove(item);\r
-#else\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int j = offset;\r
- int removed = 0;\r
- int i = offset, end = offset + size;\r
- while (i < end)\r
- {\r
- //pass by a stretch of nodes\r
- while (i < end && !equals(item, array[i]))\r
- array[j++] = array[i++];\r
- viewHandler.skipEndpoints(removed, i);\r
- //Remove a stretch of nodes\r
- while (i < end && equals(item, array[i]))\r
- {\r
- if (mustFire)\r
- raiseHandler.Remove(array[i]);\r
- removed++;\r
- i++;\r
- viewHandler.updateViewSizesAndCounts(removed, i);\r
- }\r
- }\r
- if (removed == 0)\r
- return;\r
- viewHandler.updateViewSizesAndCounts(removed, underlyingsize);\r
- Array.Copy(array, offset + size, array, j, underlyingsize - offset - size);\r
- addtosize(-removed);\r
- Array.Clear(array, underlyingsize, removed);\r
- raiseHandler.Raise();\r
-#endif\r
- }\r
-\r
-\r
- //TODO: check views\r
- /// <summary>\r
- /// Check the integrity of the internal data structures of this array list.\r
- /// </summary>\r
- /// <returns>True if check does not fail.</returns>\r
- [Tested]\r
- public override bool Check()\r
- {\r
- bool retval = true;\r
-\r
- if (underlyingsize > array.Length)\r
- {\r
- Console.WriteLine("underlyingsize ({0}) > array.Length ({1})", size, array.Length);\r
- return false;\r
- }\r
-\r
- if (offset + size > underlyingsize)\r
- {\r
- Console.WriteLine("offset({0})+size({1}) > underlyingsize ({2})", offset, size, underlyingsize);\r
- return false;\r
- }\r
-\r
- if (offset < 0)\r
- {\r
- Console.WriteLine("offset({0}) < 0", offset);\r
- return false;\r
- }\r
-\r
- for (int i = 0; i < underlyingsize; i++)\r
- {\r
- if ((object)(array[i]) == null)\r
- {\r
- Console.WriteLine("Bad element: null at (base)index {0}", i);\r
- retval = false;\r
- }\r
- }\r
-\r
- for (int i = underlyingsize, length = array.Length; i < length; i++)\r
- {\r
- if (!equals(array[i], default(T)))\r
- {\r
- Console.WriteLine("Bad element: != default(T) at (base)index {0}", i);\r
- retval = false;\r
- }\r
- }\r
-\r
-#if HASHINDEX\r
- if (underlyingsize != itemIndex.Count)\r
- {\r
- Console.WriteLine("size ({0})!= index.Count ({1})", size, itemIndex.Count);\r
- retval = false;\r
- }\r
-\r
- for (int i = 0; i < underlyingsize; i++)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(array[i]);\r
-\r
- if (!itemIndex.Find(ref p))\r
- {\r
- Console.WriteLine("Item {1} at {0} not in hashindex", i, array[i]);\r
- retval = false;\r
- }\r
-\r
- if (p.Value != i)\r
- {\r
- Console.WriteLine("Item {1} at {0} has hashindex {2}", i, array[i], p.Value);\r
- retval = false;\r
- }\r
- }\r
-#endif\r
- return retval;\r
- }\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True, indicating array list has bag semantics.</value>\r
- [Tested]\r
- public virtual bool AllowsDuplicates\r
- {\r
- [Tested]\r
- get\r
- {\r
-#if HASHINDEX\r
- return false;\r
-#else\r
- return true;\r
-#endif\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting\r
- {\r
- get\r
- {\r
-#if HASHINDEX\r
- return true;\r
-#else\r
- return false;\r
-#endif\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Add an item to end of this list.\r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True</returns>\r
- [Tested]\r
- public virtual bool Add(T item)\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, size + offset);\r
- if (itemIndex.FindOrAdd(ref p))\r
- return false;\r
-#endif\r
- baseinsert(size, item);\r
-#if HASHINDEX\r
- reindex(size + offset);\r
-#endif\r
- (underlying ?? this).raiseForAdd(item);\r
- return true;\r
- }\r
- \r
-\r
- /// <summary>\r
- /// Add the elements from another collection to this collection.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items"></param>\r
- [Tested]\r
- public virtual void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- int toadd = EnumerableBase<U>.countItems(items);\r
- if (toadd == 0)\r
- return;\r
-\r
- if (toadd + underlyingsize > array.Length)\r
- expand(toadd + underlyingsize, underlyingsize);\r
-\r
- int i = size + offset;\r
- if (underlyingsize > i)\r
- Array.Copy(array, i, array, i + toadd, underlyingsize - i);\r
- try\r
- {\r
- foreach (T item in items)\r
- {\r
-#if HASHINDEX\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, i);\r
- if (itemIndex.FindOrAdd(ref p))\r
- continue;\r
-#endif\r
- array[i++] = item;\r
- }\r
- }\r
- finally\r
- {\r
- int added = i - size - offset;\r
- if (added < toadd)\r
- {\r
- Array.Copy(array, size + offset + toadd, array, i, underlyingsize - size - offset);\r
- Array.Clear(array, underlyingsize + added, toadd - added);\r
- }\r
- if (added > 0)\r
- {\r
- addtosize(added);\r
-#if HASHINDEX\r
- reindex(i);\r
-#endif\r
- fixViewsAfterInsert(added, i - added);\r
- (underlying ?? this).raiseForAddAll(i - added, added);\r
- }\r
- }\r
- }\r
- private void raiseForAddAll(int start, int added)\r
- {\r
- if ((ActiveEvents & EventTypeEnum.Added) != 0)\r
- for (int i = start, end = start + added; i < end; i++)\r
- raiseItemsAdded(array[i], 1);\r
- raiseCollectionChanged();\r
- }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- /// <summary>\r
- /// Create a collection containing the same items as this collection, but\r
- /// whose enumerator will enumerate the items backwards. The new collection\r
- /// will become invalid if the original is modified. Method typicaly used as in\r
- /// <code>foreach (T x in coll.Backwards()) {...}</code>\r
- /// </summary>\r
- /// <returns>The backwards collection.</returns>\r
- [Tested]\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return Backwards(); }\r
-\r
- #endregion\r
-\r
- #region ICollectionValue<T> Members\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of items in this collection</value>\r
- [Tested]\r
- public override int Count { [Tested]get { validitycheck(); return size; } }\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
- //TODO: make tests of all calls on a disposed view throws the right exception! (Which should be C5.InvalidListViewException)\r
- /// <summary>\r
- /// Create an enumerator for the collection\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- validitycheck();\r
- return base.GetEnumerator();\r
- }\r
- #endregion\r
-\r
-#if HASHINDEX\r
-#else\r
- #region IStack<T> Members\r
-\r
- /// <summary>\r
- /// Push an item to the top of the stack.\r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- [Tested]\r
- public virtual void Push(T item)\r
- {\r
- InsertLast(item);\r
- }\r
-\r
- /// <summary>\r
- /// Pop the item at the top of the stack from the stack.\r
- /// </summary>\r
- /// <returns>The popped item.</returns>\r
- [Tested]\r
- public virtual T Pop()\r
- {\r
- return RemoveLast();\r
- }\r
-\r
- #endregion\r
-\r
- #region IQueue<T> Members\r
-\r
- /// <summary>\r
- /// Enqueue an item at the back of the queue. \r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- [Tested]\r
- public virtual void Enqueue(T item)\r
- {\r
- InsertLast(item);\r
- }\r
-\r
- /// <summary>\r
- /// Dequeue an item from the front of the queue.\r
- /// </summary>\r
- /// <returns>The item</returns>\r
- [Tested]\r
- public virtual T Dequeue()\r
- {\r
- return RemoveFirst();\r
- }\r
-\r
- #endregion\r
-#endif\r
- #region IDisposable Members\r
-\r
- /// <summary>\r
- /// Invalidate this list. If a view, just invalidate the view. \r
- /// If not a view, invalidate the list and all views on it.\r
- /// </summary>\r
- public virtual void Dispose()\r
- {\r
- Dispose(false);\r
- }\r
-\r
- void Dispose(bool disposingUnderlying)\r
- {\r
- if (isValid)\r
- {\r
- if (underlying != null)\r
- {\r
- isValid = false;\r
- if (!disposingUnderlying)\r
- views.Remove(myWeakReference);\r
- underlying = null;\r
- views = null;\r
- myWeakReference = null;\r
- }\r
- else\r
- {\r
- //isValid = false;\r
- foreach (ArrayList<T> view in views)\r
- view.Dispose(true);\r
- Clear();\r
- }\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this ArrayList.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- ArrayList<T> clone = new ArrayList<T>(size, itemequalityComparer);\r
- clone.AddAll(this);\r
- return clone;\r
- }\r
-\r
- #endregion\r
-\r
- #region ISerializable Members\r
-/*\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="info"></param>\r
- /// <param name="context"></param>\r
- public ArrayList(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) :\r
- this(info.GetInt32("sz"),(SCG.IEqualityComparer<T>)(info.GetValue("eq",typeof(SCG.IEqualityComparer<T>))))\r
- {\r
- size = info.GetInt32("sz");\r
- for (int i = 0; i < size; i++)\r
- {\r
- array[i] = (T)(info.GetValue("elem" + i,typeof(T)));\r
- }\r
-#if HASHINDEX\r
- reindex(0);\r
-#endif \r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="info"></param>\r
- /// <param name="context"></param>\r
- public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)\r
- {\r
- info.AddValue("sz", size);\r
- info.AddValue("eq", EqualityComparer);\r
- for (int i = 0; i < size; i++)\r
- {\r
- info.AddValue("elem" + i, array[i + offset]);\r
- }\r
- }\r
-*/\r
-#endregion\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <typeparam name="T"></typeparam>\r
- public class CircularQueue<T> : SequencedBase<T>, IQueue<T>, IStack<T>\r
- {\r
- #region Fields\r
- /*\r
- Invariant: the itemes in the queue ar the elements from front upwards, \r
- possibly wrapping around at the end of array, to back.\r
-\r
- if front<=back then size = back - front + 1;\r
- else size = array.Length + back - front + 1;\r
-\r
- */\r
- int front, back;\r
- /// <summary>\r
- /// The internal container array is doubled when necessary, but never shrinked.\r
- /// </summary>\r
- T[] array;\r
- bool forwards = true, original = true;\r
- #endregion\r
-\r
- #region Events\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override EventTypeEnum ListenableEvents { get { return EventTypeEnum.Basic; } }\r
-\r
- #endregion\r
-\r
- #region Util\r
- void expand()\r
- {\r
- int newlength = 2 * array.Length;\r
- T[] newarray = new T[newlength];\r
-\r
- if (front <= back)\r
- Array.Copy(array, front, newarray, 0, size);\r
- else\r
- {\r
- int half = array.Length - front;\r
- Array.Copy(array, front, newarray, 0, half);\r
- Array.Copy(array, 0, newarray, half, size - half);\r
- }\r
-\r
- front = 0;\r
- back = size;\r
- array = newarray;\r
- }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public CircularQueue() : this(8) { }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="capacity"></param>\r
- public CircularQueue(int capacity)\r
- : base(EqualityComparer<T>.Default)\r
- {\r
- int newlength = 8;\r
- while (newlength < capacity) newlength *= 2;\r
- array = new T[newlength];\r
- }\r
-\r
- #endregion\r
-\r
- #region IQueue<T> Members\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual bool AllowsDuplicates { get { return true; } }\r
-\r
- /// <summary>\r
- /// Get the i'th item in the queue. The front of the queue is at index 0.\r
- /// </summary>\r
- /// <param name="i"></param>\r
- /// <returns></returns>\r
- public virtual T this[int i]\r
- {\r
- get\r
- {\r
- if (i < 0 || i >= size)\r
- throw new IndexOutOfRangeException();\r
- i = i + front;\r
- return array[i >= size ? i - size : i];\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- [Tested]\r
- public virtual void Enqueue(T item)\r
- {\r
- if (!original)\r
- throw new ReadOnlyCollectionException();\r
- stamp++;\r
- if (size == array.Length - 1) expand();\r
- size++;\r
- int oldback = back++;\r
- if (back == array.Length) back = 0;\r
- array[oldback] = item;\r
- if (ActiveEvents != 0)\r
- raiseForAdd(item);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public virtual T Dequeue()\r
- {\r
- if (!original)\r
- throw new ReadOnlyCollectionException("Object is a non-updatable clone");\r
- stamp++;\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- size--;\r
- int oldfront = front++;\r
- if (front == array.Length) front = 0;\r
- T retval = array[oldfront];\r
- array[oldfront] = default(T);\r
- if (ActiveEvents != 0)\r
- raiseForRemove(retval);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- public void Push(T item) //== Enqueue\r
- {\r
- if (!original)\r
- throw new ReadOnlyCollectionException();\r
- stamp++;\r
- if (size == array.Length - 1) expand();\r
- size++;\r
- int oldback = back++;\r
- if (back == array.Length) back = 0;\r
- array[oldback] = item;\r
- if (ActiveEvents != 0)\r
- raiseForAdd(item);\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public T Pop()\r
- {\r
- if (!original)\r
- throw new ReadOnlyCollectionException("Object is a non-updatable clone");\r
- stamp++;\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- size--;\r
- back--;\r
- if (back == -1) back = array.Length - 1;\r
- T retval = array[back];\r
- array[back] = default(T);\r
- if (ActiveEvents != 0)\r
- raiseForRemove(retval);\r
- return retval;\r
- }\r
- #endregion\r
-\r
- #region ICollectionValue<T> Members\r
-\r
- //TODO: implement these with Array.Copy instead of relying on XxxBase:\r
- /*\r
- public void CopyTo(T[] a, int i)\r
- {\r
- }\r
-\r
- public T[] ToArray()\r
- {\r
- }*/\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public override T Choose()\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- return array[front];\r
- }\r
-\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- int stamp = this.stamp;\r
- if (forwards)\r
- {\r
- int position = front;\r
- int end = front <= back ? back : array.Length;\r
- while (position < end)\r
- {\r
- if (stamp != this.stamp)\r
- throw new CollectionModifiedException();\r
- yield return array[position++];\r
- }\r
- if (front > back)\r
- {\r
- position = 0;\r
- while (position < back)\r
- {\r
- if (stamp != this.stamp)\r
- throw new CollectionModifiedException();\r
- yield return array[position++];\r
- }\r
- }\r
- }\r
- else\r
- {\r
- int position = back - 1;\r
- int end = front <= back ? front : 0;\r
- while (position >= end)\r
- {\r
- if (stamp != this.stamp)\r
- throw new CollectionModifiedException();\r
- yield return array[position--];\r
- }\r
- if (front > back)\r
- {\r
- position = array.Length - 1;\r
- while (position >= front)\r
- {\r
- if (stamp != this.stamp)\r
- throw new CollectionModifiedException();\r
- yield return array[position--];\r
- }\r
- }\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region IDirectedCollectionValue<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override IDirectedCollectionValue<T> Backwards()\r
- {\r
- CircularQueue<T> retval = (CircularQueue<T>)MemberwiseClone();\r
- retval.original = false;\r
- retval.forwards = !forwards;\r
- return retval;\r
- }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()\r
- {\r
- return Backwards();\r
- }\r
-\r
- #endregion\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual bool Check()\r
- {\r
- if (front < 0 || front >= array.Length || back < 0 || back >= array.Length ||\r
- (front <= back && size != back - front) || (front > back && size != array.Length + back - front))\r
- {\r
- Console.WriteLine("Bad combination of (front,back,size,array.Length): ({0},{1},{2},{3})",\r
- front, back, size, array.Length);\r
- return false;\r
- }\r
- return true;\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A collection class implementing a sorted dynamic array data structure.\r
- /// </summary>\r
- [Serializable]\r
- public class SortedArray<T> : ArrayBase<T>, IIndexedSorted<T>\r
- {\r
- #region Features\r
- /// <summary>\r
- /// A debugging artifact. To be removed.\r
- /// </summary>\r
- [Flags]\r
- public enum Feature : short\r
- {\r
- /// <summary>\r
- /// A debugging artifact. To be removed.\r
- /// </summary>\r
- Standard = 0\r
- }\r
-\r
-\r
- static Feature features = Feature.Standard;\r
-\r
-\r
- /// <summary>\r
- /// A debugging artifact. To be removed.\r
- /// </summary>\r
- /// <value></value>\r
- public static Feature Features { get { return features; } }\r
-\r
- #endregion\r
-\r
- #region Fields\r
-\r
- SCG.IComparer<T> comparer;\r
-\r
- #endregion\r
-\r
- #region Util\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item">The item to search for</param>\r
- /// <param name="mid">The least index, mid, for which array[mid] >= item</param>\r
- /// <returns>True if item found</returns>\r
- private bool binarySearch(T item, out int mid)\r
- {\r
- int bot = 0, top = size;\r
-\r
- mid = top / 2;\r
- while (top > bot)\r
- {\r
- int c;\r
-\r
- if ((c = comparer.Compare(array[mid], item)) == 0)\r
- return true;\r
-\r
- if (c > 0)\r
- { top = mid; }\r
- else\r
- { bot = mid + 1; }\r
-\r
- mid = (bot + top) / 2;\r
- }\r
-\r
- return false;\r
- }\r
-\r
- private int indexOf(T item)\r
- {\r
- int ind;\r
-\r
- if (binarySearch(item, out ind))\r
- return ind;\r
-\r
- return ~ind;\r
- }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
-\r
- /// <summary>\r
- /// Create a dynamic sorted array with a natural comparer\r
- /// (and item equalityComparer, assumed compatible)\r
- /// </summary>\r
- /// <exception cref="NotComparableException">If <code>T</code> is not comparable.\r
- /// </exception>\r
- public SortedArray() : this(8) { }\r
-\r
-\r
- /// <summary>\r
- /// Create a dynamic sorted array with a natural comparer \r
- /// (and item equalityComparer, assumed compatible)\r
- /// and prescribed initial capacity.\r
- /// </summary>\r
- /// <exception cref="NotComparableException">If <code>T</code> is not comparable.\r
- /// </exception>\r
- /// <param name="capacity">The capacity</param>\r
- public SortedArray(int capacity)\r
- : this(capacity, Comparer<T>.Default, EqualityComparer<T>.Default) { }\r
-\r
-\r
- /// <summary>\r
- /// Create a dynamic sorted array with an external comparer.\r
- /// <para>The itemequalityComparer will be compatible \r
- /// <see cref="T:C5.ComparerZeroHashCodeEqualityComparer`1"/> since the \r
- /// default equalityComparer for T (<see cref="P:C5.EqualityComparer`1.Default"/>)\r
- /// is unlikely to be compatible with the external comparer. This makes the\r
- /// array inadequate for use as item in a collection of unsequenced or sequenced sets or bags\r
- /// (<see cref="T:C5.ICollection`1"/> and <see cref="T:C5.ISequenced`1"/>)\r
- /// </para>\r
- /// </summary>\r
- /// <param name="comparer">The comparer</param>\r
- public SortedArray(SCG.IComparer<T> comparer)\r
- : this(8, comparer) { }\r
-\r
- /// <summary>\r
- /// Create a dynamic sorted array with an external comparer\r
- /// and prescribed initial capacity.\r
- /// <para>The itemequalityComparer will be a compatible \r
- /// <see cref="T:C5.ComparerZeroHashCodeEqualityComparer`1"/> since the \r
- /// default equalityComparer for T (<see cref="P:C5.EqualityComparer`1.Default"/>)\r
- /// is unlikely to be compatible with the external comparer. This makes the\r
- /// sorted array inadequate for use as item in a collection of unsequenced or sequenced sets or bags\r
- /// (<see cref="T:C5.ICollection`1"/> and <see cref="T:C5.ISequenced`1"/>)\r
- /// </para>\r
- /// </summary>\r
- /// <param name="capacity">The capacity</param>\r
- /// <param name="comparer">The comparer</param>\r
- public SortedArray(int capacity, SCG.IComparer<T> comparer)\r
- : this(capacity, comparer, new ComparerZeroHashCodeEqualityComparer<T>(comparer)) { }\r
-\r
- /// <summary>\r
- /// Create a dynamic sorted array with an external comparer, an external item equalityComparer\r
- /// and prescribed initial capacity. This is the constructor to use if the collection \r
- /// will be used as item in a hash table based collection.\r
- /// </summary>\r
- /// <param name="capacity">The capacity</param>\r
- /// <param name="comparer">The item comparer</param>\r
- /// <param name="equalityComparer">The item equalityComparer (assumed compatible)</param>\r
- public SortedArray(int capacity, SCG.IComparer<T> comparer, SCG.IEqualityComparer<T> equalityComparer)\r
- : base(capacity, equalityComparer)\r
- {\r
- if (comparer == null)\r
- throw new NullReferenceException("Comparer cannot be null");\r
- this.comparer = comparer;\r
- }\r
-\r
- #endregion\r
-\r
- #region IIndexedSorted<T> Members\r
-\r
- /// <summary>\r
- /// Determine the number of items at or above a supplied threshold.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- [Tested]\r
- public int CountFrom(T bot)\r
- {\r
- int lo;\r
-\r
- binarySearch(bot, out lo);\r
- return size - lo;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Determine the number of items between two supplied thresholds.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive)</param>\r
- /// <param name="top">The upper bound (exclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- [Tested]\r
- public int CountFromTo(T bot, T top)\r
- {\r
- int lo, hi;\r
-\r
- binarySearch(bot, out lo);\r
- binarySearch(top, out hi);\r
- return hi > lo ? hi - lo : 0;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Determine the number of items below a supplied threshold.\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- [Tested]\r
- public int CountTo(T top)\r
- {\r
- int hi;\r
-\r
- binarySearch(top, out hi);\r
- return hi;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items greater than or equal to a supplied value.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeFrom(T bot)\r
- {\r
- int lo;\r
-\r
- binarySearch(bot, out lo);\r
- return new Range(this, lo, size - lo, true);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items between two supplied values.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeFromTo(T bot, T top)\r
- {\r
- int lo, hi;\r
-\r
- binarySearch(bot, out lo);\r
- binarySearch(top, out hi);\r
-\r
- int sz = hi - lo;\r
-\r
- return new Range(this, lo, sz, true);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items less than a supplied value.\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeTo(T top)\r
- {\r
- int hi;\r
-\r
- binarySearch(top, out hi);\r
- return new Range(this, 0, hi, true);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a new indexed sorted collection consisting of the items of this\r
- /// indexed sorted collection satisfying a certain predicate.\r
- /// </summary>\r
- /// <param name="f">The filter delegate defining the predicate.</param>\r
- /// <returns>The new indexed sorted collection.</returns>\r
- [Tested]\r
- public IIndexedSorted<T> FindAll(Fun<T, bool> f)\r
- {\r
- SortedArray<T> res = new SortedArray<T>(comparer);\r
- int j = 0, rescap = res.array.Length;\r
-\r
- for (int i = 0; i < size; i++)\r
- {\r
- T a = array[i];\r
-\r
- if (f(a))\r
- {\r
- if (j == rescap) res.expand(rescap = 2 * rescap, j);\r
-\r
- res.array[j++] = a;\r
- }\r
- }\r
-\r
- res.size = j;\r
- return res;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a new indexed sorted collection consisting of the results of\r
- /// mapping all items of this list.\r
- /// <exception cref="ArgumentException"/> if the map is not increasing over \r
- /// the items of this collection (with respect to the two given comparison \r
- /// relations).\r
- /// </summary>\r
- /// <param name="m">The delegate definging the map.</param>\r
- /// <param name="c">The comparion relation to use for the result.</param>\r
- /// <returns>The new sorted collection.</returns>\r
- [Tested]\r
- public IIndexedSorted<V> Map<V>(Fun<T, V> m, SCG.IComparer<V> c)\r
- {\r
- SortedArray<V> res = new SortedArray<V>(size, c);\r
-\r
- if (size > 0)\r
- {\r
- V oldv = res.array[0] = m(array[0]), newv;\r
-\r
- for (int i = 1; i < size; i++)\r
- {\r
- if (c.Compare(oldv, newv = res.array[i] = m(array[i])) >= 0)\r
- throw new ArgumentException("mapper not monotonic");\r
-\r
- oldv = newv;\r
- }\r
- }\r
-\r
- res.size = size;\r
- return res;\r
- }\r
-\r
- #endregion\r
-\r
- #region ISorted<T> Members\r
-\r
- /// <summary>\r
- /// Find the strict predecessor in the sorted collection of a particular value,\r
- /// i.e. the largest item in the collection less than the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is less than or equal to the minimum of this collection.)</exception>\r
- /// <param name="item">The item to find the predecessor for.</param>\r
- /// <returns>The predecessor.</returns>\r
- [Tested]\r
- public T Predecessor(T item)\r
- {\r
- int lo;\r
-\r
- binarySearch(item, out lo);\r
- if (lo == 0)\r
- throw new NoSuchItemException();\r
-\r
- return array[lo - 1];\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the strict successor in the sorted collection of a particular value,\r
- /// i.e. the least item in the collection greater than the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is greater than or equal to the maximum of this collection.)</exception>\r
- /// <param name="item">The item to find the successor for.</param>\r
- /// <returns>The successor.</returns>\r
- [Tested]\r
- public T Successor(T item)\r
- {\r
- int hi;\r
-\r
- if (binarySearch(item, out hi)) hi++;\r
-\r
- if (hi >= size)\r
- throw new NoSuchItemException();\r
-\r
- return array[hi];\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the weak predecessor in the sorted collection of a particular value,\r
- /// i.e. the largest item in the collection less than or equal to the supplied value.\r
- /// <exception cref="NoSuchItemException"/> if no such element exists (the\r
- /// supplied value is less than the minimum of this collection.)\r
- /// </summary>\r
- /// <param name="item">The item to find the weak predecessor for.</param>\r
- /// <returns>The weak predecessor.</returns>\r
- [Tested]\r
- public T WeakPredecessor(T item)\r
- {\r
- int lo;\r
-\r
- if (!binarySearch(item, out lo)) lo--;\r
-\r
- if (lo < 0)\r
- throw new NoSuchItemException();\r
-\r
- return array[lo];\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the weak successor in the sorted collection of a particular value,\r
- /// i.e. the least item in the collection greater than or equal to the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is greater than the maximum of this collection.)</exception>\r
- /// <param name="item">The item to find the weak successor for.</param>\r
- /// <returns>The weak successor.</returns>\r
- [Tested]\r
- public T WeakSuccessor(T item)\r
- {\r
- int hi;\r
-\r
- binarySearch(item, out hi);\r
- if (hi >= size)\r
- throw new NoSuchItemException();\r
-\r
- return array[hi];\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Perform a search in the sorted collection for the ranges in which a\r
- /// non-increasing (i.e. weakly decrerasing) function from the item type to \r
- /// <code>int</code> is\r
- /// negative, zero respectively positive. If the supplied cut function is\r
- /// not non-increasing, the result of this call is undefined.\r
- /// </summary>\r
- /// <param name="c">The cut function <code>T</code> to <code>int</code>, given\r
- /// as an <code>IComparable<T></code> object, where the cut function is\r
- /// the <code>c.CompareTo(T that)</code> method.</param>\r
- /// <param name="low">Returns the largest item in the collection, where the\r
- /// cut function is positive (if any).</param>\r
- /// <param name="lowIsValid">True if the cut function is positive somewhere\r
- /// on this collection.</param>\r
- /// <param name="high">Returns the least item in the collection, where the\r
- /// cut function is negative (if any).</param>\r
- /// <param name="highIsValid">True if the cut function is negative somewhere\r
- /// on this collection.</param>\r
- /// <returns></returns>\r
- [Tested]\r
- public bool Cut(IComparable<T> c, out T low, out bool lowIsValid, out T high, out bool highIsValid)\r
- {\r
- int lbest = -1, rbest = size;\r
-\r
- low = default(T);\r
- lowIsValid = false;\r
- high = default(T);\r
- highIsValid = false;\r
-\r
- int bot = 0, top = size, mid, comp = -1, sol;\r
-\r
- mid = top / 2;\r
- while (top > bot)\r
- {\r
- if ((comp = c.CompareTo(array[mid])) == 0)\r
- break;\r
-\r
- if (comp < 0)\r
- { rbest = top = mid; }\r
- else\r
- { lbest = mid; bot = mid + 1; }\r
-\r
- mid = (bot + top) / 2;\r
- }\r
-\r
- if (comp != 0)\r
- {\r
- if (lbest >= 0) { lowIsValid = true; low = array[lbest]; }\r
-\r
- if (rbest < size) { highIsValid = true; high = array[rbest]; }\r
-\r
- return false;\r
- }\r
-\r
- sol = mid;\r
- bot = sol - 1;\r
-\r
- //Invariant: c.Compare(array[x]) < 0 when rbest <= x < size \r
- // c.Compare(array[x]) >= 0 when x < bot)\r
- //(Assuming c.Compare monotonic)\r
- while (rbest > bot)\r
- {\r
- mid = (bot + rbest) / 2;\r
- if (c.CompareTo(array[mid]) < 0)\r
- { rbest = mid; }\r
- else\r
- { bot = mid + 1; }\r
- }\r
-\r
- if (rbest < size) { highIsValid = true; high = array[rbest]; }\r
-\r
- top = sol + 1;\r
-\r
- //Invariant: c.Compare(array[x]) > 0 when 0 <= x <= lbest\r
- // c.Compare(array[x]) <= 0 when x>top)\r
- //(Assuming c.Compare monotonic)\r
- while (top > lbest)\r
- {\r
- mid = (lbest + top + 1) / 2;\r
- if (c.CompareTo(array[mid]) > 0)\r
- { lbest = mid; }\r
- else\r
- { top = mid - 1; }\r
- }\r
-\r
- if (lbest >= 0) { lowIsValid = true; low = array[lbest]; }\r
-\r
- return true;\r
- }\r
-\r
-\r
- IDirectedEnumerable<T> ISorted<T>.RangeFrom(T bot)\r
- { return RangeFrom(bot); }\r
-\r
-\r
- IDirectedEnumerable<T> ISorted<T>.RangeFromTo(T bot, T top)\r
- { return RangeFromTo(bot, top); }\r
-\r
-\r
- IDirectedEnumerable<T> ISorted<T>.RangeTo(T top)\r
- { return RangeTo(top); }\r
-\r
-\r
- /// <summary>\r
- /// Create a directed collection with the same items as this collection.\r
- /// </summary>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeAll()\r
- { return new Range(this, 0, size, true); }\r
-\r
-\r
- /// <summary>\r
- /// Add all the items from another collection with an enumeration order that \r
- /// is increasing in the items.\r
- /// <exception cref="ArgumentException"/> if the enumerated items turns out\r
- /// not to be in increasing order.\r
- /// </summary>\r
- /// <param name="items">The collection to add.</param>\r
- /// <typeparam name="U"></typeparam>\r
- [Tested]\r
- public void AddSorted<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- //Unless items have <=1 elements we would expect it to be\r
- //too expensive to do repeated inserts, thus:\r
- updatecheck();\r
-\r
- int j = 0, i = 0, c = -1, itemcount = EnumerableBase<U>.countItems(items);\r
- SortedArray<T> res = new SortedArray<T>(size + itemcount, comparer);\r
- T lastitem = default(T);\r
-\r
- foreach (T item in items)\r
- {\r
- while (i < size && (c = comparer.Compare(array[i], item)) <= 0)\r
- {\r
- lastitem = res.array[j++] = array[i++];\r
- if (c == 0)\r
- goto next;\r
- }\r
-\r
- if (j > 0 && comparer.Compare(lastitem, item) >= 0)\r
- throw new ArgumentException("Argument not sorted");\r
-\r
- lastitem = res.array[j++] = item;\r
- next:\r
- c = -1;\r
- }\r
-\r
- while (i < size) res.array[j++] = array[i++];\r
-\r
- size = j;\r
- array = res.array;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection above or at a supplied threshold.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- [Tested]\r
- public void RemoveRangeFrom(T low)\r
- {\r
- int lowind;\r
-\r
- binarySearch(low, out lowind);\r
- if (lowind == size)\r
- return;\r
-\r
- Array.Clear(array, lowind, size - lowind);\r
- size = lowind;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection between two supplied thresholds.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- [Tested]\r
- public void RemoveRangeFromTo(T low, T hi)\r
- {\r
- int lowind, highind;\r
-\r
- binarySearch(low, out lowind);\r
- binarySearch(hi, out highind);\r
- if (highind <= lowind)\r
- return;\r
-\r
- Array.Copy(array, highind, array, lowind, size - highind);\r
- Array.Clear(array, size - highind + lowind, highind - lowind);\r
- size -= highind - lowind;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection below a supplied threshold.\r
- /// </summary>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- [Tested]\r
- public void RemoveRangeTo(T hi)\r
- {\r
- int highind;\r
-\r
- binarySearch(hi, out highind);\r
- if (highind == 0)\r
- return;\r
-\r
- Array.Copy(array, highind, array, 0, size - highind);\r
- Array.Clear(array, size - highind, highind);\r
- size = size - highind;\r
- }\r
-\r
- #endregion\r
-\r
- #region ICollection<T> Members\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case).\r
- /// </summary>\r
- /// <value>Speed.Log</value>\r
- [Tested]\r
- public Speed ContainsSpeed { [Tested]get { return Speed.Log; } }\r
-\r
- /// <summary>\r
- /// Check if this collection contains (an item equivalent to according to the\r
- /// itemequalityComparer) a particular value.\r
- /// </summary>\r
- /// <param name="item">The value to check for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public bool Contains(T item)\r
- {\r
- int ind;\r
-\r
- return binarySearch(item, out ind);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public bool Find(ref T item)\r
- {\r
- int ind;\r
-\r
- if (binarySearch(item, out ind))\r
- {\r
- item = array[ind];\r
- return true;\r
- }\r
-\r
- return false;\r
- }\r
-\r
-\r
- //This should probably just be bool Add(ref T item); !!!\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found. Else, add the item to the collection.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the item was added (hence not found).</returns>\r
- [Tested]\r
- public bool FindOrAdd(ref T item)\r
- {\r
- updatecheck();\r
-\r
- int ind;\r
-\r
- if (binarySearch(item, out ind))\r
- {\r
- item = array[ind];\r
- return true;\r
- }\r
-\r
- if (size == array.Length - 1) expand();\r
-\r
- Array.Copy(array, ind, array, ind + 1, size - ind);\r
- array[ind] = item;\r
- size++;\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value. If the collection has bag semantics,\r
- /// it is implementation dependent if this updates all equivalent copies in\r
- /// the collection or just one.\r
- /// </summary>\r
- /// <param name="item">Value to update.</param>\r
- /// <returns>True if the item was found and hence updated.</returns>\r
- [Tested]\r
- public bool Update(T item)\r
- { T olditem; return Update(item, out olditem); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public bool Update(T item, out T olditem)\r
- {\r
- updatecheck();\r
-\r
- int ind;\r
-\r
- if (binarySearch(item, out ind))\r
- {\r
- olditem = array[ind];\r
- array[ind] = item;\r
- return true;\r
- }\r
-\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value; else add the value to the collection. \r
- /// </summary>\r
- /// <param name="item">Value to add or update.</param>\r
- /// <returns>True if the item was found and updated (hence not added).</returns>\r
- [Tested]\r
- public bool UpdateOrAdd(T item)\r
- { T olditem; return UpdateOrAdd(item, out olditem); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public bool UpdateOrAdd(T item, out T olditem)\r
- {\r
- updatecheck();\r
-\r
- int ind;\r
-\r
- if (binarySearch(item, out ind))\r
- {\r
- olditem = array[ind];\r
- array[ind] = item;\r
- return true;\r
- }\r
-\r
- if (size == array.Length - 1) expand();\r
-\r
- Array.Copy(array, ind, array, ind + 1, size - ind);\r
- array[ind] = item;\r
- size++;\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection. If the collection has bag\r
- /// semantics only one copy equivalent to the supplied item is removed. \r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public bool Remove(T item)\r
- {\r
- int ind;\r
-\r
- updatecheck();\r
- if (binarySearch(item, out ind))\r
- {\r
- Array.Copy(array, ind + 1, array, ind, size - ind - 1);\r
- array[--size] = default(T);\r
- return true;\r
- }\r
-\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection if found. If the collection\r
- /// has bag semantics only one copy equivalent to the supplied item is removed,\r
- /// which one is implementation dependent. \r
- /// If an item was removed, report a binary copy of the actual item removed in \r
- /// the argument.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <param name="removeditem">The removed value.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public bool Remove(T item, out T removeditem)\r
- {\r
- int ind;\r
-\r
- updatecheck();\r
- if (binarySearch(item, out ind))\r
- {\r
- removeditem = array[ind];\r
- Array.Copy(array, ind + 1, array, ind, size - ind - 1);\r
- array[--size] = default(T);\r
- return true;\r
- }\r
-\r
- removeditem = default(T);\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items in another collection from this one. \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to remove.</param>\r
- [Tested]\r
- public void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- //This is O(m*logn) with n bits extra storage\r
- //(Not better to collect the m items and sort them)\r
- updatecheck();\r
-\r
- int[] toremove = new int[(size >> 5) + 1];\r
- int ind, j = 0;\r
-\r
- foreach (T item in items)\r
- if (binarySearch(item, out ind))\r
- toremove[ind >> 5] |= 1 << (ind & 31);\r
-\r
- for (int i = 0; i < size; i++)\r
- if ((toremove[i >> 5] & (1 << (i & 31))) == 0)\r
- array[j++] = array[i];\r
-\r
- Array.Clear(array, j, size - j);\r
- size = j;\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items not in some other collection from this one. \r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to retain.</param>\r
- [Tested]\r
- public void RetainAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- //This is O(m*logn) with n bits extra storage\r
- //(Not better to collect the m items and sort them)\r
- updatecheck();\r
-\r
- int[] toretain = new int[(size >> 5) + 1];\r
- int ind, j = 0;\r
-\r
- foreach (T item in items)\r
- if (binarySearch(item, out ind))\r
- toretain[ind >> 5] |= 1 << (ind & 31);\r
-\r
- for (int i = 0; i < size; i++)\r
- if ((toretain[i >> 5] & (1 << (i & 31))) != 0)\r
- array[j++] = array[i];\r
-\r
- Array.Clear(array, j, size - j);\r
- size = j;\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains all the values in another collection.\r
- /// Multiplicities are not taken into account.\r
- /// </summary>\r
- /// <param name="items">The </param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if all values in <code>items</code>is in this collection.</returns>\r
- [Tested]\r
- public bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- int tmp;\r
-\r
- foreach (T item in items)\r
- if (!binarySearch(item, out tmp))\r
- return false;\r
-\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Count the number of items of the collection equal to a particular value.\r
- /// Returns 0 if and only if the value is not in the collection.\r
- /// </summary>\r
- /// <param name="item">The value to count.</param>\r
- /// <returns>The number of copies found (0 or 1).</returns>\r
- [Tested]\r
- public int ContainsCount(T item)\r
- {\r
- int tmp;\r
-\r
- return binarySearch(item, out tmp) ? 1 : 0;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<T> UniqueItems() { return this; }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities()\r
- {\r
- return new MultiplicityOne<T>(this);\r
- }\r
-\r
- /// <summary>\r
- /// Remove all (0 or 1) items equivalent to a given value.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- [Tested]\r
- public void RemoveAllCopies(T item) { Remove(item); }\r
-\r
-\r
- /// <summary>\r
- /// Check the integrity of the internal data structures of this collection.\r
- /// Only avaliable in DEBUG builds???\r
- /// </summary>\r
- /// <returns>True if check does not fail.</returns>\r
- [Tested]\r
- public override bool Check()\r
- {\r
- bool retval = true;\r
-\r
- if (size > array.Length)\r
- {\r
- Console.WriteLine("Bad size ({0}) > array.Length ({1})", size, array.Length);\r
- return false;\r
- }\r
-\r
- for (int i = 0; i < size; i++)\r
- {\r
- if ((object)(array[i]) == null)\r
- {\r
- Console.WriteLine("Bad element: null at index {0}", i);\r
- return false;\r
- }\r
-\r
- if (i > 0 && comparer.Compare(array[i], array[i - 1]) <= 0)\r
- {\r
- Console.WriteLine("Inversion at index {0}", i);\r
- retval = false;\r
- }\r
- }\r
-\r
- return retval;\r
- }\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>False since this collection has set semantics</value>\r
- [Tested]\r
- public bool AllowsDuplicates { [Tested]get { return false; } }\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting { get { return true; } }\r
-\r
- /// <summary>\r
- /// Add an item to this collection if possible. If this collection has set\r
- /// semantics, the item will be added if not already in the collection. If\r
- /// bag semantics, the item will always be added.\r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True if item was added.</returns>\r
- [Tested]\r
- public bool Add(T item)\r
- {\r
- updatecheck();\r
-\r
- int ind;\r
-\r
- if (binarySearch(item, out ind)) return false;\r
-\r
- insert(ind, item);\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// Add the elements from another collection with a more specialized item type \r
- /// to this collection. Since this\r
- /// collection has set semantics, only items not already in the collection\r
- /// will be added.\r
- /// </summary>\r
- /// <typeparam name="U">The type of items to add</typeparam>\r
- /// <param name="items">The items to add</param>\r
- [Tested]\r
- public void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- int toadd = EnumerableBase<U>.countItems(items), newsize = array.Length;\r
-\r
- while (newsize < size + toadd) { newsize *= 2; }\r
-\r
- T[] newarr = new T[newsize];\r
-\r
- toadd = 0;\r
- foreach (T item in items) newarr[size + toadd++] = item;\r
-\r
- Sorting.IntroSort<T>(newarr, size, toadd, comparer);\r
-\r
- int j = 0, i = 0;\r
- T lastitem = default(T);\r
-\r
- //The following eliminates duplicates (including duplicates in input)\r
- //while merging the old and new collection\r
- for (int k = size, klimit = size + toadd; k < klimit; k++)\r
- {\r
- while (i < size && comparer.Compare(array[i], newarr[k]) <= 0)\r
- lastitem = newarr[j++] = array[i++];\r
-\r
- if (j == 0 || comparer.Compare(lastitem, newarr[k]) < 0)\r
- lastitem = newarr[j++] = newarr[k];\r
- }\r
-\r
- while (i < size) newarr[j++] = array[i++];\r
-\r
- Array.Clear(newarr, j, size + toadd - j);\r
- size = j;\r
- array = newarr;\r
- }\r
-\r
- #endregion\r
-\r
- #region IPriorityQueue<T> Members\r
-\r
- /// <summary>\r
- /// Find the current least item of this priority queue.\r
- /// </summary>\r
- /// <returns>The least item.</returns>\r
- [Tested]\r
- public T FindMin()\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- return array[0];\r
- }\r
-\r
- /// <summary>\r
- /// Remove the least item from this priority queue.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T DeleteMin()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- T retval = array[0];\r
-\r
- size--;\r
- Array.Copy(array, 1, array, 0, size);\r
- array[size] = default(T);\r
- return retval;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the current largest item of this priority queue.\r
- /// </summary>\r
- /// <returns>The largest item.</returns>\r
- [Tested]\r
- public T FindMax()\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- return array[size - 1];\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the largest item from this priority queue.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T DeleteMax()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- T retval = array[size - 1];\r
-\r
- size--;\r
- array[size] = default(T);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// The comparer object supplied at creation time for this collection\r
- /// </summary>\r
- /// <value>The comparer</value>\r
- public SCG.IComparer<T> Comparer { get { return comparer; } }\r
-\r
- #endregion\r
-\r
- #region IIndexed<T> Members\r
-\r
- /// <summary>\r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// >= the size of the collection.\r
- /// </summary>\r
- /// <value>The i'th item of this list.</value>\r
- /// <param name="i">the index to lookup</param>\r
- [Tested]\r
- public T this[int i]\r
- {\r
- [Tested]\r
- get\r
- {\r
- if (i < 0 || i >= size)\r
- throw new IndexOutOfRangeException();\r
-\r
- return array[i];\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual Speed IndexingSpeed { get { return Speed.Constant; } }\r
-\r
- /// <summary>\r
- /// Searches for an item in the list going forwrds from the start.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of item from start.</returns>\r
- [Tested]\r
- public int IndexOf(T item) { return indexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// Searches for an item in the list going backwords from the end.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of of item from the end.</returns>\r
- [Tested]\r
- public int LastIndexOf(T item) { return indexOf(item); }\r
-\r
-\r
- /// <summary>\r
- /// Remove the item at a specific position of the list.\r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// >= the size of the collection.\r
- /// </summary>\r
- /// <param name="i">The index of the item to remove.</param>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T RemoveAt(int i)\r
- {\r
- if (i < 0 || i >= size)\r
- throw new IndexOutOfRangeException("Index out of range for sequenced collectionvalue");\r
-\r
- updatecheck();\r
-\r
- T retval = array[i];\r
-\r
- size--;\r
- Array.Copy(array, i + 1, array, i, size - i);\r
- array[size] = default(T);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items in an index interval.\r
- /// <exception cref="IndexOutOfRangeException"/>???. \r
- /// </summary>\r
- /// <param name="start">The index of the first item to remove.</param>\r
- /// <param name="count">The number of items to remove.</param>\r
- [Tested]\r
- public void RemoveInterval(int start, int count)\r
- {\r
- updatecheck();\r
- checkRange(start, count);\r
- Array.Copy(array, start + count, array, start, size - start - count);\r
- size -= count;\r
- Array.Clear(array, size, count);\r
- }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- /// <summary>\r
- /// Create a collection containing the same items as this collection, but\r
- /// whose enumerator will enumerate the items backwards. The new collection\r
- /// will become invalid if the original is modified. Method typicaly used as in\r
- /// <code>foreach (T x in coll.Backwards()) {...}</code>\r
- /// </summary>\r
- /// <returns>The backwards collection.</returns>\r
- [Tested]\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards()\r
- { return Backwards(); }\r
-\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this SortedArray.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- SortedArray<T> clone = new SortedArray<T>(size, comparer, itemequalityComparer);\r
- clone.AddSorted(this);\r
- return clone;\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A bag collection based on a hash table of (item,count) pairs. \r
- /// </summary>\r
- [Serializable]\r
- public class HashBag<T> : CollectionBase<T>, ICollection<T>\r
- {\r
- #region Fields\r
- HashSet<KeyValuePair<T, int>> dict;\r
- #endregion\r
-\r
- #region Events\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override EventTypeEnum ListenableEvents { get { return EventTypeEnum.Basic; } }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
- /// <summary>\r
- /// Create a hash bag with the deafult item equalityComparer.\r
- /// </summary>\r
- public HashBag() : this(EqualityComparer<T>.Default) { }\r
-\r
- /// <summary>\r
- /// Create a hash bag with an external item equalityComparer.\r
- /// </summary>\r
- /// <param name="itemequalityComparer">The external item equalityComparer.</param>\r
- public HashBag(SCG.IEqualityComparer<T> itemequalityComparer)\r
- : base(itemequalityComparer)\r
- {\r
- dict = new HashSet<KeyValuePair<T, int>>(new KeyValuePairEqualityComparer<T, int>(itemequalityComparer));\r
- }\r
-\r
- /// <summary>\r
- /// Create a hash bag with external item equalityComparer, prescribed initial table size and default fill threshold (66%)\r
- /// </summary>\r
- /// <param name="capacity">Initial table size (rounded to power of 2, at least 16)</param>\r
- /// <param name="itemequalityComparer">The external item equalityComparer</param>\r
- public HashBag(int capacity, SCG.IEqualityComparer<T> itemequalityComparer)\r
- : base(itemequalityComparer)\r
- {\r
- dict = new HashSet<KeyValuePair<T, int>>(capacity, new KeyValuePairEqualityComparer<T, int>(itemequalityComparer));\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a hash bag with external item equalityComparer, prescribed initial table size and fill threshold.\r
- /// </summary>\r
- /// <param name="capacity">Initial table size (rounded to power of 2, at least 16)</param>\r
- /// <param name="fill">Fill threshold (valid range 10% to 90%)</param>\r
- /// <param name="itemequalityComparer">The external item equalityComparer</param>\r
- public HashBag(int capacity, double fill, SCG.IEqualityComparer<T> itemequalityComparer)\r
- : base(itemequalityComparer)\r
- {\r
- dict = new HashSet<KeyValuePair<T, int>>(capacity, fill, new KeyValuePairEqualityComparer<T, int>(itemequalityComparer));\r
- }\r
-\r
- #endregion\r
-\r
- #region IEditableCollection<T> Members\r
-\r
- /// <summary>\r
- /// The complexity of the Contains operation\r
- /// </summary>\r
- /// <value>Always returns Speed.Constant</value>\r
- [Tested]\r
- public virtual Speed ContainsSpeed { [Tested]get { return Speed.Constant; } }\r
-\r
- /// <summary>\r
- /// Check if an item is in the bag \r
- /// </summary>\r
- /// <param name="item">The item to look for</param>\r
- /// <returns>True if bag contains item</returns>\r
- [Tested]\r
- public virtual bool Contains(T item)\r
- { return dict.Contains(new KeyValuePair<T, int>(item, 0)); }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a given one) is in the bag and\r
- /// if so report the actual item object found.\r
- /// </summary>\r
- /// <param name="item">On entry, the item to look for.\r
- /// On exit the item found, if any</param>\r
- /// <returns>True if bag contains item</returns>\r
- [Tested]\r
- public virtual bool Find(ref T item)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);\r
-\r
- if (dict.Find(ref p))\r
- {\r
- item = p.Key;\r
- return true;\r
- }\r
-\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a given one) is in the bag and\r
- /// if so replace the item object in the bag with the supplied one.\r
- /// </summary>\r
- /// <param name="item">The item object to update with</param>\r
- /// <returns>True if item was found (and updated)</returns>\r
- [Tested]\r
- public virtual bool Update(T item)\r
- { T olditem = default(T); return Update(item, out olditem); }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool Update(T item, out T olditem)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);\r
-\r
- updatecheck();\r
-\r
- //Note: we cannot just do dict.Update: we have to lookup the count before we \r
- //know what to update with. There is of course a way around if we use the \r
- //implementation of hashset -which we do not want to do.\r
- //The hashbag is moreover mainly a proof of concept\r
- if (dict.Find(ref p))\r
- {\r
- olditem = p.Key;\r
- p.Key = item;\r
- dict.Update(p);\r
- if (ActiveEvents != 0)\r
- raiseForUpdate(item, olditem, p.Value);\r
- return true;\r
- }\r
-\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a given one) is in the bag.\r
- /// If found, report the actual item object in the bag,\r
- /// else add the supplied one.\r
- /// </summary>\r
- /// <param name="item">On entry, the item to look for or add.\r
- /// On exit the actual object found, if any.</param>\r
- /// <returns>True if item was found</returns>\r
- [Tested]\r
- public virtual bool FindOrAdd(ref T item)\r
- {\r
- updatecheck();\r
- if (Find(ref item))\r
- return true;\r
-\r
- Add(item);\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a supplied one) is in the bag and\r
- /// if so replace the item object in the set with the supplied one; else\r
- /// add the supplied one.\r
- /// </summary>\r
- /// <param name="item">The item to look for and update or add</param>\r
- /// <returns>True if item was updated</returns>\r
- [Tested]\r
- public virtual bool UpdateOrAdd(T item)\r
- {\r
- updatecheck();\r
- if (Update(item))\r
- return true;\r
-\r
- Add(item);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool UpdateOrAdd(T item, out T olditem)\r
- {\r
- updatecheck();\r
- if (Update(item, out olditem))\r
- return true;\r
-\r
- Add(item);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Remove one copy af an item from the bag\r
- /// </summary>\r
- /// <param name="item">The item to remove</param>\r
- /// <returns>True if item was (found and) removed </returns>\r
- [Tested]\r
- public virtual bool Remove(T item)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);\r
-\r
- updatecheck();\r
- if (dict.Find(ref p))\r
- {\r
- size--;\r
- if (p.Value == 1)\r
- dict.Remove(p);\r
- else\r
- {\r
- p.Value--;\r
- dict.Update(p);\r
- }\r
- if (ActiveEvents != 0)\r
- raiseForRemove(p.Key);\r
- return true;\r
- }\r
-\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove one copy of an item from the bag, reporting the actual matching item object.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <param name="removeditem">The removed value.</param>\r
- /// <returns>True if item was found.</returns>\r
- [Tested]\r
- public virtual bool Remove(T item, out T removeditem)\r
- {\r
- updatecheck();\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);\r
- if (dict.Find(ref p))\r
- {\r
- removeditem = p.Key;\r
- size--;\r
- if (p.Value == 1)\r
- dict.Remove(p);\r
- else\r
- {\r
- p.Value--;\r
- dict.Update(p);\r
- }\r
- if (ActiveEvents != 0)\r
- raiseForRemove(removeditem);\r
-\r
- return true;\r
- }\r
-\r
- removeditem = default(T);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items in a supplied collection from this bag, counting multiplicities.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to remove.</param>\r
- [Tested]\r
- public virtual void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
-#warning Improve if items is a counting bag\r
- updatecheck();\r
- bool mustRaise = (ActiveEvents & (EventTypeEnum.Changed | EventTypeEnum.Removed)) != 0;\r
- RaiseForRemoveAllHandler raiseHandler = mustRaise ? new RaiseForRemoveAllHandler(this) : null;\r
- foreach (U item in items)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);\r
- if (dict.Find(ref p))\r
- {\r
- size--;\r
- if (p.Value == 1)\r
- dict.Remove(p);\r
- else\r
- {\r
- p.Value--;\r
- dict.Update(p);\r
- }\r
- if (mustRaise)\r
- raiseHandler.Remove(p.Key);\r
- }\r
- }\r
- if (mustRaise)\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items from the bag, resetting internal table to initial size.\r
- /// </summary>\r
- [Tested]\r
- public virtual void Clear()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- dict.Clear();\r
- int oldsize = size;\r
- size = 0;\r
- if ((ActiveEvents & EventTypeEnum.Cleared) != 0)\r
- raiseCollectionCleared(true, oldsize);\r
- if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items *not* in a supplied collection from this bag,\r
- /// counting multiplicities.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to retain</param>\r
- [Tested]\r
- public virtual void RetainAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
-\r
- HashBag<T> res = new HashBag<T>(itemequalityComparer);\r
-\r
- foreach (U item in items)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item);\r
- if (dict.Find(ref p))\r
- {\r
- KeyValuePair<T, int> q = p;\r
- if (res.dict.Find(ref q))\r
- {\r
- if (q.Value < p.Value)\r
- {\r
- q.Value++;\r
- res.dict.Update(q);\r
- res.size++;\r
- }\r
- }\r
- else\r
- {\r
- q.Value = 1;\r
- res.dict.Add(q);\r
- res.size++;\r
- }\r
- }\r
- }\r
-\r
- if (size == res.size)\r
- return;\r
-\r
- CircularQueue<T> wasRemoved = null;\r
- if ((ActiveEvents & EventTypeEnum.Removed) != 0)\r
- {\r
- wasRemoved = new CircularQueue<T>();\r
- foreach (KeyValuePair<T, int> p in dict)\r
- {\r
- int removed = p.Value - res.ContainsCount(p.Key);\r
- if (removed > 0)\r
-#warning We could send bag events here easily using a CircularQueue of (should?)\r
- for (int i = 0; i < removed; i++)\r
- wasRemoved.Enqueue(p.Key);\r
- }\r
- }\r
- dict = res.dict;\r
- size = res.size;\r
-\r
- if ((ActiveEvents & EventTypeEnum.Removed) != 0)\r
- raiseForRemoveAll(wasRemoved);\r
- else if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
- /// <summary>\r
- /// Check if all items in a supplied collection is in this bag\r
- /// (counting multiplicities). \r
- /// </summary>\r
- /// <param name="items">The items to look for.</param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if all items are found.</returns>\r
- [Tested]\r
- public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- HashBag<T> res = new HashBag<T>(itemequalityComparer);\r
-\r
- foreach (T item in items)\r
- if (res.ContainsCount(item) < ContainsCount(item))\r
- res.Add(item);\r
- else\r
- return false;\r
-\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create an array containing all items in this bag (in enumeration order).\r
- /// </summary>\r
- /// <returns>The array</returns>\r
- [Tested]\r
- public override T[] ToArray()\r
- {\r
- T[] res = new T[size];\r
- int ind = 0;\r
-\r
- foreach (KeyValuePair<T, int> p in dict)\r
- for (int i = 0; i < p.Value; i++)\r
- res[ind++] = p.Key;\r
-\r
- return res;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Count the number of times an item is in this set.\r
- /// </summary>\r
- /// <param name="item">The item to look for.</param>\r
- /// <returns>The count</returns>\r
- [Tested]\r
- public virtual int ContainsCount(T item)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);\r
-\r
- if (dict.Find(ref p))\r
- return p.Value;\r
-\r
- return 0;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<T> UniqueItems() { return new DropMultiplicity<T>(dict); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities()\r
- {\r
- return new GuardedCollectionValue<KeyValuePair<T, int>>(dict);\r
- }\r
-\r
- /// <summary>\r
- /// Remove all copies of item from this set.\r
- /// </summary>\r
- /// <param name="item">The item to remove</param>\r
- [Tested]\r
- public virtual void RemoveAllCopies(T item)\r
- {\r
- updatecheck();\r
-\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 0);\r
-\r
- if (dict.Find(ref p))\r
- {\r
- size -= p.Value;\r
- dict.Remove(p);\r
- if ((ActiveEvents & EventTypeEnum.Removed) != 0)\r
- raiseItemsRemoved(p.Key, p.Value);\r
- if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region ICollection<T> Members\r
-\r
-\r
- /// <summary>\r
- /// Copy the items of this bag to part of an array.\r
- /// <exception cref="ArgumentOutOfRangeException"/> if i is negative.\r
- /// <exception cref="ArgumentException"/> if the array does not have room for the items.\r
- /// </summary>\r
- /// <param name="array">The array to copy to</param>\r
- /// <param name="index">The starting index.</param>\r
- [Tested]\r
- public override void CopyTo(T[] array, int index)\r
- {\r
- if (index < 0 || index >= array.Length || index + Count > array.Length)\r
- throw new ArgumentOutOfRangeException();\r
-\r
- foreach (KeyValuePair<T, int> p in dict)\r
- for (int j = 0; j < p.Value; j++)\r
- array[index++] = p.Key;\r
- }\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> Members\r
-\r
- /// <summary>\r
- /// Report if this is a set collection.\r
- /// </summary>\r
- /// <value>Always true</value>\r
- [Tested]\r
- public virtual bool AllowsDuplicates { [Tested] get { return true; } }\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting { get { return true; } }\r
-\r
- /// <summary>\r
- /// Add an item to this bag.\r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>Always true</returns>\r
- [Tested]\r
- public virtual bool Add(T item)\r
- {\r
- updatecheck();\r
- add(ref item);\r
- if (ActiveEvents != 0)\r
- raiseForAdd(item);\r
- return true;\r
- }\r
-\r
- private void add(ref T item)\r
- {\r
- KeyValuePair<T, int> p = new KeyValuePair<T, int>(item, 1);\r
- if (dict.Find(ref p))\r
- {\r
- p.Value++;\r
- dict.Update(p);\r
- item = p.Key;\r
- }\r
- else\r
- dict.Add(p);\r
- size++;\r
- }\r
-\r
- /// <summary>\r
- /// Add the elements from another collection with a more specialized item type \r
- /// to this collection. \r
- /// </summary>\r
- /// <typeparam name="U">The type of items to add</typeparam>\r
- /// <param name="items">The items to add</param>\r
- public virtual void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
-#warning We could easily raise bag events\r
- bool mustRaiseAdded = (ActiveEvents & EventTypeEnum.Added) != 0;\r
- CircularQueue<T> wasAdded = mustRaiseAdded ? new CircularQueue<T>() : null;\r
- bool wasChanged = false;\r
- foreach (T item in items)\r
- {\r
- T jtem = item;\r
- add(ref jtem);\r
- wasChanged = true;\r
- if (mustRaiseAdded)\r
- wasAdded.Enqueue(jtem);\r
- }\r
- if (!wasChanged)\r
- return;\r
- if (mustRaiseAdded)\r
- foreach (T item in wasAdded)\r
- raiseItemsAdded(item, 1);\r
- if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
-\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- public override T Choose()\r
- {\r
- return dict.Choose().Key;\r
- }\r
-\r
- /// <summary>\r
- /// Create an enumerator for this bag.\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- int left;\r
- int mystamp = stamp;\r
-\r
- foreach (KeyValuePair<T, int> p in dict)\r
- {\r
- left = p.Value;\r
- while (left > 0)\r
- {\r
- if (mystamp != stamp)\r
- throw new CollectionModifiedException();\r
-\r
- left--;\r
- yield return p.Key;\r
- }\r
- }\r
- }\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this HashBag.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- //TODO: make sure this \r
- HashBag<T> clone = new HashBag<T>(dict.Count > 0 ? dict.Count : 1, itemequalityComparer);\r
- //TODO: make sure this really adds in the counting bag way!\r
- clone.AddAll(this);\r
- return clone;\r
- }\r
-\r
- #endregion\r
-\r
-\r
- #region Diagnostics\r
- /// <summary>\r
- /// Test internal structure of data (invariants)\r
- /// </summary>\r
- /// <returns>True if pass</returns>\r
- [Tested]\r
- public virtual bool Check()\r
- {\r
- bool retval = dict.Check();\r
- int count = 0;\r
-\r
- foreach (KeyValuePair<T, int> p in dict)\r
- count += p.Value;\r
-\r
- if (count != size)\r
- {\r
- Console.WriteLine("count({0}) != size({1})", count, size);\r
- retval = false;\r
- }\r
-\r
- return retval;\r
- }\r
- #endregion\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A generic dictionary class based on a hash set class <see cref="T:C5.HashSet`1"/>. \r
- /// </summary>\r
- [Serializable]\r
- public class HashDictionary<K, V> : DictionaryBase<K, V>, IDictionary<K, V>\r
- {\r
- /// <summary>\r
- /// Create a hash dictionary using a default equalityComparer for the keys.\r
- /// Initial capacity of internal table will be 16 entries and threshold for \r
- /// expansion is 66% fill.\r
- /// </summary>\r
- public HashDictionary() : this(EqualityComparer<K>.Default) { }\r
-\r
- /// <summary>\r
- /// Create a hash dictionary using a custom equalityComparer for the keys.\r
- /// Initial capacity of internal table will be 16 entries and threshold for \r
- /// expansion is 66% fill.\r
- /// </summary>\r
- /// <param name="keyequalityComparer">The external key equalityComparer</param>\r
- public HashDictionary(SCG.IEqualityComparer<K> keyequalityComparer) : base(keyequalityComparer)\r
- {\r
- pairs = new HashSet<KeyValuePair<K, V>>(new KeyValuePairEqualityComparer<K, V>(keyequalityComparer));\r
- }\r
-\r
- /// <summary>\r
- /// Create a hash dictionary using a custom equalityComparer and prescribing the \r
- /// initial size of the dictionary and a non-default threshold for internal table expansion.\r
- /// </summary>\r
- /// <param name="capacity">The initial capacity. Will be rounded upwards to nearest\r
- /// power of 2, at least 16.</param>\r
- /// <param name="fill">The expansion threshold. Must be between 10% and 90%.</param>\r
- /// <param name="keyequalityComparer">The external key equalityComparer</param>\r
- public HashDictionary(int capacity, double fill, SCG.IEqualityComparer<K> keyequalityComparer): base(keyequalityComparer)\r
- {\r
- pairs = new HashSet<KeyValuePair<K, V>>(capacity, fill, new KeyValuePairEqualityComparer<K, V>(keyequalityComparer));\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override object Clone()\r
- {\r
- HashDictionary<K, V> clone = new HashDictionary<K, V>(EqualityComparer);\r
- clone.pairs.AddAll(pairs);\r
- return clone;\r
- }\r
-\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-#define LINEARPROBINGnot\r
-#define REFBUCKET\r
-#define SHRINKnot\r
-#define INTERHASHINGnot\r
-#define RANDOMINTERHASHING\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A set collection class based on linear hashing\r
- /// </summary>\r
- [Serializable]\r
- public class HashSet<T> : CollectionBase<T>, ICollection<T>\r
- {\r
- #region Feature\r
- /// <summary>\r
- /// Enum class to assist printing of compilation alternatives.\r
- /// </summary>\r
- [Flags]\r
- public enum Feature : short\r
- {\r
- /// <summary>\r
- /// Nothing\r
- /// </summary>\r
- Dummy = 0,\r
- /// <summary>\r
- /// Buckets are of reference type\r
- /// </summary>\r
- RefTypeBucket = 1,\r
- /// <summary>\r
- /// Primary buckets are of value type\r
- /// </summary>\r
- ValueTypeBucket = 2,\r
- /// <summary>\r
- /// Using linear probing to resolve index clashes\r
- /// </summary>\r
- LinearProbing = 4,\r
- /// <summary>\r
- /// Shrink table when very sparsely filled\r
- /// </summary>\r
- ShrinkTable = 8,\r
- /// <summary>\r
- /// Use chaining to resolve index clashes\r
- /// </summary>\r
- Chaining = 16,\r
- /// <summary>\r
- /// Use hash function on item hash code\r
- /// </summary>\r
- InterHashing = 32,\r
- /// <summary>\r
- /// Use a universal family of hash functions on item hash code\r
- /// </summary>\r
- RandomInterHashing = 64\r
- }\r
-\r
-\r
-\r
- static Feature features = Feature.Dummy\r
-#if REFBUCKET\r
- | Feature.RefTypeBucket\r
-#else\r
- | Feature.ValueTypeBucket\r
-#endif\r
-#if SHRINK\r
- | Feature.ShrinkTable\r
-#endif\r
-#if LINEARPROBING\r
- | Feature.LinearProbing\r
-#else\r
- | Feature.Chaining\r
-#endif\r
-#if INTERHASHING\r
- | Feature.InterHashing\r
-#elif RANDOMINTERHASHING\r
- | Feature.RandomInterHashing\r
-#endif\r
-;\r
-\r
-\r
- /// <summary>\r
- /// Show which implementation features was chosen at compilation time\r
- /// </summary>\r
- public static Feature Features { get { return features; } }\r
-\r
- #endregion\r
-\r
- #region Fields\r
-\r
- int indexmask, bits, bitsc, origbits, lastchosen; //bitsc==32-bits; indexmask==(1<<bits)-1;\r
-\r
- Bucket[] table;\r
-\r
-#if !REFBUCKET\r
- bool defaultvalid = false;\r
-\r
- T defaultitem;\r
-#endif\r
- double fillfactor = 0.66;\r
-\r
- int resizethreshhold;\r
-\r
-#if RANDOMINTERHASHING\r
-#if DEBUG\r
- const uint randomhashfactor = 1529784659;\r
-#else\r
- uint randomhashfactor = (2 * (uint)(new Random()).Next() + 1) * 1529784659;\r
-#endif\r
-#endif\r
-\r
- #endregion\r
-\r
- #region Events\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override EventTypeEnum ListenableEvents { get { return EventTypeEnum.Basic; } }\r
-\r
- #endregion\r
-\r
- #region Bucket nested class(es)\r
-#if REFBUCKET\r
- [Serializable]\r
- class Bucket\r
- {\r
- internal T item;\r
-\r
- internal int hashval; //Cache!\r
-\r
-#if LINEARPROBING\r
- internal Bucket(T item, int hashval)\r
- {\r
- this.item = item;\r
- this.hashval = hashval;\r
- }\r
-#else\r
- internal Bucket overflow;\r
-\r
- internal Bucket(T item, int hashval, Bucket overflow)\r
- {\r
- this.item = item;\r
- this.hashval = hashval;\r
- this.overflow = overflow;\r
- }\r
-#endif\r
- }\r
-#else\r
- struct Bucket\r
- {\r
- internal T item;\r
-\r
- internal int hashval; //Cache!\r
-\r
-#if LINEARPROBING\r
- internal Bucket(T item, int hashval)\r
- {\r
- this.item = item;\r
- this.hashval = hashval;\r
- }\r
-#else\r
- internal OverflowBucket overflow;\r
-\r
-\r
- internal Bucket(T item, int hashval)\r
- {\r
- this.item = item;\r
- this.hashval = hashval;\r
- this.overflow = default(OverflowBucket);\r
- }\r
-#endif\r
- }\r
-\r
-\r
-#if !LINEARPROBING\r
- class OverflowBucket\r
- {\r
- internal T item;\r
-\r
- internal int hashval; //Cache!\r
-\r
- internal OverflowBucket overflow;\r
-\r
-\r
- internal OverflowBucket(T item, int hashval, OverflowBucket overflow)\r
- {\r
- this.item = item;\r
- this.hashval = hashval;\r
- this.overflow = overflow;\r
- }\r
- }\r
-#endif\r
-#endif\r
-\r
- #endregion\r
-\r
- #region Basic Util\r
-\r
- bool equals(T i1, T i2) { return itemequalityComparer.Equals(i1, i2); }\r
-\r
-#if !REFBUCKET\r
- bool isnull(T item) { return itemequalityComparer.Equals(item, default(T)); }\r
-#endif\r
-\r
- int gethashcode(T item) { return itemequalityComparer.GetHashCode(item); }\r
-\r
-\r
- int hv2i(int hashval)\r
- {\r
-#if INTERHASHING\r
- //Note: *inverse mod 2^32 is -1503427877\r
- return (int)(((uint)hashval * 1529784659) >>bitsc); \r
-#elif RANDOMINTERHASHING\r
- return (int)(((uint)hashval * randomhashfactor) >> bitsc);\r
-#else\r
- return indexmask & hashval;\r
-#endif\r
- }\r
-\r
-\r
- void expand()\r
- {\r
- //Console.WriteLine(String.Format("Expand to {0} bits", bits+1));\r
- resize(bits + 1);\r
- }\r
-\r
-\r
- void shrink()\r
- {\r
- if (bits > 3)\r
- {\r
- //Console.WriteLine(String.Format("Shrink to {0} bits", bits - 1));\r
- resize(bits - 1);\r
- }\r
- }\r
-\r
-\r
- void resize(int bits)\r
- {\r
- //Console.WriteLine(String.Format("Resize to {0} bits", bits));\r
- this.bits = bits;\r
- bitsc = 32 - bits;\r
- indexmask = (1 << bits) - 1;\r
-\r
- Bucket[] newtable = new Bucket[indexmask + 1];\r
-\r
- for (int i = 0, s = table.Length; i < s; i++)\r
- {\r
- Bucket b = table[i];\r
-\r
-#if LINEARPROBING\r
-#if REFBUCKET\r
- if (b != null)\r
- {\r
- int j = hv2i(b.hashval);\r
-\r
- while (newtable[j] != null) { j = indexmask & (j + 1); }\r
-\r
- newtable[j] = b;\r
- }\r
-#else\r
- if (!isnull(b.item))\r
- {\r
- int j = hv2i(b.hashval);\r
-\r
- while (!isnull(newtable[j].item)) { j = indexmask & (j + 1); }\r
-\r
- newtable[j] = b;\r
- }\r
-#endif\r
-#else\r
-#if REFBUCKET\r
- while (b != null)\r
- {\r
- int j = hv2i(b.hashval);\r
-\r
- newtable[j] = new Bucket(b.item, b.hashval, newtable[j]);\r
- b = b.overflow;\r
- }\r
-#else\r
- if (!isnull(b.item))\r
- {\r
- insert(b.item, b.hashval, newtable);\r
-\r
- OverflowBucket ob = b.overflow;\r
-\r
- while (ob != null)\r
- {\r
- insert(ob.item, ob.hashval, newtable);\r
- ob = ob.overflow;\r
- }\r
- }\r
-#endif\r
-#endif\r
- }\r
-\r
- table = newtable;\r
- resizethreshhold = (int)(table.Length * fillfactor);\r
- //Console.WriteLine(String.Format("Resize to {0} bits done", bits));\r
- }\r
-\r
-#if REFBUCKET\r
-#else\r
-#if LINEARPROBING\r
-#else\r
- //Only for resize!!!\r
- private void insert(T item, int hashval, Bucket[] t)\r
- {\r
- int i = hv2i(hashval);\r
- Bucket b = t[i];\r
-\r
- if (!isnull(b.item))\r
- {\r
- t[i].overflow = new OverflowBucket(item, hashval, b.overflow);\r
- }\r
- else\r
- t[i] = new Bucket(item, hashval);\r
- }\r
-#endif\r
-#endif\r
-\r
- /// <summary>\r
- /// Search for an item equal (according to itemequalityComparer) to the supplied item. \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="add">If true, add item to table if not found.</param>\r
- /// <param name="update">If true, update table entry if item found.</param>\r
- /// <param name="raise">If true raise events</param>\r
- /// <returns>True if found</returns>\r
- private bool searchoradd(ref T item, bool add, bool update, bool raise)\r
- {\r
-\r
-#if LINEARPROBING\r
-#if REFBUCKET\r
- int hashval = gethashcode(item);\r
- int i = hv2i(hashval);\r
- Bucket b = table[i];\r
-\r
- while (b != null)\r
- {\r
- T olditem = b.item;\r
- if (equals(olditem, item))\r
- {\r
- if (update)\r
- b.item = item;\r
- else\r
- item = olditem;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- b = table[i = indexmask & (i + 1)];\r
- }\r
-\r
- if (!add) goto notfound;\r
-\r
- table[i] = new Bucket(item, hashval);\r
-\r
-#else\r
- if (isnull(item))\r
- {\r
- if (defaultvalid)\r
- {\r
- T olditem = defaultitem;\r
- if (update)\r
- defaultitem = item;\r
- else\r
- item = defaultitem;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- if (!add) goto notfound;\r
-\r
- defaultvalid = true;\r
- defaultitem = item;\r
- }\r
- else\r
- {\r
- int hashval = gethashcode(item);\r
- int i = hv2i(hashval);\r
- T t = table[i].item;\r
-\r
- while (!isnull(t))\r
- {\r
- if (equals(t, item))\r
- {\r
- if (update)\r
- table[i].item = item;\r
- else\r
- item = t;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, t);\r
- return true;\r
- }\r
-\r
- t = table[i = indexmask & (i + 1)].item;\r
- }\r
-\r
- if (!add) goto notfound;\r
-\r
- table[i] = new Bucket(item, hashval);\r
- }\r
-#endif\r
-#else\r
-#if REFBUCKET\r
- int hashval = gethashcode(item);\r
- int i = hv2i(hashval);\r
- Bucket b = table[i], bold = null;\r
-\r
- if (b != null)\r
- {\r
- while (b != null)\r
- {\r
- T olditem = b.item;\r
- if (equals(olditem, item))\r
- {\r
- if (update)\r
- {\r
- b.item = item;\r
- }\r
- item = b.item;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- bold = b;\r
- b = b.overflow;\r
- }\r
-\r
- if (!add) goto notfound;\r
-\r
- bold.overflow = new Bucket(item, hashval, null);\r
- }\r
- else\r
- {\r
- if (!add) goto notfound;\r
-\r
- table[i] = new Bucket(item, hashval, null);\r
- }\r
-#else\r
- if (isnull(item))\r
- {\r
- if (defaultvalid)\r
- {\r
- T olditem = defaultitem;\r
- if (update)\r
- defaultitem = item;\r
- else\r
- item = defaultitem;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- if (!add) goto notfound;\r
-\r
- defaultvalid = true;\r
- defaultitem = item;\r
- }\r
- else\r
- {\r
- int hashval = gethashcode(item);\r
- int i = hv2i(hashval);\r
- Bucket b = table[i];\r
-\r
- if (!isnull(b.item))\r
- {\r
- if (equals(b.item, item))\r
- {\r
- if (update)\r
- table[i].item = item;\r
- else\r
- item = b.item;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, b.item);\r
- return true;\r
- }\r
-\r
- OverflowBucket ob = table[i].overflow;\r
-\r
- if (ob == null)\r
- {\r
- if (!add) goto notfound;\r
-\r
- table[i].overflow = new OverflowBucket(item, hashval, null);\r
- }\r
- else\r
- {\r
- T olditem = ob.item;\r
- while (ob.overflow != null)\r
- {\r
- if (equals(item, olditem))\r
- {\r
- if (update)\r
- ob.item = item;\r
- else\r
- item = olditem;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- ob = ob.overflow;\r
- olditem = ob.item;\r
- }\r
-\r
- if (equals(item, olditem))\r
- {\r
- if (update)\r
- ob.item = item;\r
- else\r
- item = olditem;\r
-\r
- if (raise && update)\r
- raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- if (!add) goto notfound;\r
-\r
- ob.overflow = new OverflowBucket(item, hashval, null);\r
- }\r
- }\r
- else\r
- {\r
- if (!add) goto notfound;\r
-\r
- table[i] = new Bucket(item, hashval);\r
- }\r
- }\r
-#endif\r
-#endif\r
- size++;\r
- if (size > resizethreshhold)\r
- expand();\r
- notfound:\r
- if (raise && add)\r
- raiseForAdd(item);\r
- return false;\r
- }\r
-\r
-\r
- private bool remove(ref T item)\r
- {\r
-\r
- if (size == 0)\r
- return false;\r
-#if LINEARPROBING\r
-#if REFBUCKET\r
- int hashval = gethashcode(item);\r
- int index = hv2i(hashval);\r
- Bucket b = table[index];\r
-\r
- while (b != null)\r
- {\r
- if (equals(item, b.item))\r
- {\r
- //ref\r
- item = table[index].item;\r
- table[index] = null;\r
-\r
- //Algorithm R\r
- int j = (index + 1) & indexmask;\r
-\r
- b = table[j];\r
- while (b != null)\r
- {\r
- int k = hv2i(b.hashval);\r
-\r
- if ((k <= index && index < j) || (index < j && j < k) || (j < k && k <= index))\r
- //if (index > j ? (j < k && k <= index): (k <= index || j < k) )\r
- {\r
- table[index] = b;\r
- table[j] = null;\r
- index = j;\r
- }\r
-\r
- j = (j + 1) & indexmask;\r
- b = table[j];\r
- }\r
-\r
- goto found;\r
- }\r
-\r
- b = table[index = indexmask & (index + 1)];\r
- }\r
- return false;\r
-#else\r
- if (isnull(item))\r
- {\r
- if (!defaultvalid)\r
- return false;\r
-\r
- //ref\r
- item = defaultitem;\r
- defaultvalid = false;\r
- defaultitem = default(T); //No spaceleaks!\r
- }\r
- else\r
- {\r
- int hashval = gethashcode(item);\r
- int index = hv2i(hashval);\r
- T t = table[index].item;\r
-\r
- while (!isnull(t))\r
- {\r
- if (equals(item, t))\r
- {\r
- //ref\r
- item = table[index].item;\r
- table[index].item = default(T);\r
-\r
- //algorithm R\r
- int j = (index + 1) & indexmask;\r
- Bucket b = table[j];\r
-\r
- while (!isnull(b.item))\r
- {\r
- int k = hv2i(b.hashval);\r
-\r
- if ((k <= index && index < j) || (index < j && j < k) || (j < k && k <= index))\r
- {\r
- table[index] = b;\r
- table[j].item = default(T);\r
- index = j;\r
- }\r
-\r
- j = (j + 1) & indexmask;\r
- b = table[j];\r
- }\r
-\r
- goto found;\r
- }\r
-\r
- t = table[index = indexmask & (index + 1)].item;\r
- }\r
-\r
- return false;\r
- }\r
-#endif\r
- found:\r
-#else\r
-#if REFBUCKET\r
- int hashval = gethashcode(item);\r
- int index = hv2i(hashval);\r
- Bucket b = table[index], bold;\r
-\r
- if (b == null)\r
- return false;\r
-\r
- if (equals(item, b.item))\r
- {\r
- //ref\r
- item = b.item;\r
- table[index] = b.overflow;\r
- }\r
- else\r
- {\r
- bold = b;\r
- b = b.overflow;\r
- while (b != null && !equals(item, b.item))\r
- {\r
- bold = b;\r
- b = b.overflow;\r
- }\r
-\r
- if (b == null)\r
- return false;\r
-\r
- //ref\r
- item = b.item;\r
- bold.overflow = b.overflow;\r
- }\r
-\r
-#else\r
- if (isnull(item))\r
- {\r
- if (!defaultvalid)\r
- return false;\r
-\r
- //ref\r
- item = defaultitem;\r
- defaultvalid = false;\r
- defaultitem = default(T); //No spaceleaks!\r
- }\r
- else\r
- {\r
- int hashval = gethashcode(item);\r
- int index = hv2i(hashval);\r
- Bucket b = table[index];\r
- OverflowBucket ob = b.overflow;\r
-\r
- if (equals(item, b.item))\r
- {\r
- //ref\r
- item = b.item;\r
- if (ob == null)\r
- {\r
- table[index] = new Bucket();\r
- }\r
- else\r
- {\r
- b = new Bucket(ob.item, ob.hashval);\r
- b.overflow = ob.overflow;\r
- table[index] = b;\r
- }\r
- }\r
- else\r
- {\r
- if (ob == null)\r
- return false;\r
-\r
- if (equals(item, ob.item)) \r
- {\r
- //ref\r
- item=ob.item;\r
- table[index].overflow = ob.overflow;\r
- }\r
- else\r
- {\r
- while (ob.overflow != null)\r
- if (equals(item, ob.overflow.item))\r
- {\r
- //ref\r
- item = ob.overflow.item;\r
- break;\r
- }\r
- else\r
- ob = ob.overflow;\r
-\r
- if (ob.overflow == null)\r
- return false;\r
-\r
- ob.overflow = ob.overflow.overflow;\r
- }\r
- }\r
- }\r
-#endif\r
-#endif\r
- size--;\r
-\r
- return true;\r
- }\r
-\r
-\r
- private void clear()\r
- {\r
- bits = origbits;\r
- bitsc = 32 - bits;\r
- indexmask = (1 << bits) - 1;\r
- size = 0;\r
- table = new Bucket[indexmask + 1];\r
- resizethreshhold = (int)(table.Length * fillfactor);\r
-#if !REFBUCKET\r
- defaultitem = default(T);\r
- defaultvalid = false;\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
- /// <summary>\r
- /// Create a hash set with natural item equalityComparer and default fill threshold (66%)\r
- /// and initial table size (16).\r
- /// </summary>\r
- public HashSet() \r
- : this(EqualityComparer<T>.Default) { }\r
-\r
-\r
- /// <summary>\r
- /// Create a hash set with external item equalityComparer and default fill threshold (66%)\r
- /// and initial table size (16).\r
- /// </summary>\r
- /// <param name="itemequalityComparer">The external item equalityComparer</param>\r
- public HashSet(SCG.IEqualityComparer<T> itemequalityComparer) \r
- : this(16, itemequalityComparer) { }\r
-\r
-\r
- /// <summary>\r
- /// Create a hash set with external item equalityComparer and default fill threshold (66%)\r
- /// </summary>\r
- /// <param name="capacity">Initial table size (rounded to power of 2, at least 16)</param>\r
- /// <param name="itemequalityComparer">The external item equalityComparer</param>\r
- public HashSet(int capacity, SCG.IEqualityComparer<T> itemequalityComparer) \r
- : this(capacity, 0.66, itemequalityComparer) { }\r
-\r
-\r
- /// <summary>\r
- /// Create a hash set with external item equalityComparer.\r
- /// </summary>\r
- /// <param name="capacity">Initial table size (rounded to power of 2, at least 16)</param>\r
- /// <param name="fill">Fill threshold (in range 10% to 90%)</param>\r
- /// <param name="itemequalityComparer">The external item equalityComparer</param>\r
- public HashSet(int capacity, double fill, SCG.IEqualityComparer<T> itemequalityComparer) : base(itemequalityComparer)\r
- {\r
- if (fill < 0.1 || fill > 0.9)\r
- throw new ArgumentException("Fill outside valid range [0.1, 0.9]");\r
- if (capacity <= 0)\r
- throw new ArgumentException("Capacity must be non-negative");\r
- //this.itemequalityComparer = itemequalityComparer;\r
- origbits = 4;\r
- while (capacity - 1 >> origbits > 0) origbits++;\r
- clear();\r
- }\r
-\r
-\r
-\r
- #endregion\r
-\r
- #region IEditableCollection<T> Members\r
-\r
- /// <summary>\r
- /// The complexity of the Contains operation\r
- /// </summary>\r
- /// <value>Always returns Speed.Constant</value>\r
- [Tested]\r
- public virtual Speed ContainsSpeed { [Tested]get { return Speed.Constant; } }\r
-\r
- /// <summary>\r
- /// Check if an item is in the set \r
- /// </summary>\r
- /// <param name="item">The item to look for</param>\r
- /// <returns>True if set contains item</returns>\r
- [Tested]\r
- public virtual bool Contains(T item) { return searchoradd(ref item, false, false, false); }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a given one) is in the set and\r
- /// if so report the actual item object found.\r
- /// </summary>\r
- /// <param name="item">On entry, the item to look for.\r
- /// On exit the item found, if any</param>\r
- /// <returns>True if set contains item</returns>\r
- [Tested]\r
- public virtual bool Find(ref T item) { return searchoradd(ref item, false, false, false); }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a given one) is in the set and\r
- /// if so replace the item object in the set with the supplied one.\r
- /// </summary>\r
- /// <param name="item">The item object to update with</param>\r
- /// <returns>True if item was found (and updated)</returns>\r
- [Tested]\r
- public virtual bool Update(T item)\r
- { updatecheck(); return searchoradd(ref item, false, true, true); }\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a given one) is in the set and\r
- /// if so replace the item object in the set with the supplied one.\r
- /// </summary>\r
- /// <param name="item">The item object to update with</param>\r
- /// <param name="olditem"></param>\r
- /// <returns>True if item was found (and updated)</returns>\r
- public virtual bool Update(T item, out T olditem)\r
- { updatecheck(); olditem = item; return searchoradd(ref olditem, false, true, true); }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a given one) is in the set.\r
- /// If found, report the actual item object in the set,\r
- /// else add the supplied one.\r
- /// </summary>\r
- /// <param name="item">On entry, the item to look for or add.\r
- /// On exit the actual object found, if any.</param>\r
- /// <returns>True if item was found</returns>\r
- [Tested]\r
- public virtual bool FindOrAdd(ref T item)\r
- { updatecheck(); return searchoradd(ref item, true, false, true); }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a supplied one) is in the set and\r
- /// if so replace the item object in the set with the supplied one; else\r
- /// add the supplied one.\r
- /// </summary>\r
- /// <param name="item">The item to look for and update or add</param>\r
- /// <returns>True if item was updated</returns>\r
- [Tested]\r
- public virtual bool UpdateOrAdd(T item)\r
- { updatecheck(); return searchoradd(ref item, true, true, true); }\r
-\r
-\r
- /// <summary>\r
- /// Check if an item (collection equal to a supplied one) is in the set and\r
- /// if so replace the item object in the set with the supplied one; else\r
- /// add the supplied one.\r
- /// </summary>\r
- /// <param name="item">The item to look for and update or add</param>\r
- /// <param name="olditem"></param>\r
- /// <returns>True if item was updated</returns>\r
- public virtual bool UpdateOrAdd(T item, out T olditem)\r
- { updatecheck(); olditem = item; return searchoradd(ref olditem, true, true, true); }\r
-\r
-\r
- /// <summary>\r
- /// Remove an item from the set\r
- /// </summary>\r
- /// <param name="item">The item to remove</param>\r
- /// <returns>True if item was (found and) removed </returns>\r
- [Tested]\r
- public virtual bool Remove(T item)\r
- {\r
- updatecheck();\r
- if (remove(ref item))\r
- {\r
-#if SHRINK\r
- if (size<resizethreshhold/2 && resizethreshhold>8)\r
- shrink();\r
-#endif\r
- raiseForRemove(item);\r
- return true;\r
- }\r
- else\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove an item from the set, reporting the actual matching item object.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <param name="removeditem">The removed value.</param>\r
- /// <returns>True if item was found.</returns>\r
- [Tested]\r
- public virtual bool Remove(T item, out T removeditem)\r
- {\r
- updatecheck();\r
- removeditem = item;\r
- if (remove(ref removeditem))\r
- {\r
-#if SHRINK\r
- if (size<resizethreshhold/2 && resizethreshhold>8)\r
- shrink();\r
-#endif\r
- raiseForRemove(removeditem);\r
- return true;\r
- }\r
- else\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items in a supplied collection from this set.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to remove.</param>\r
- [Tested]\r
- public virtual void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(this);\r
- bool raise = raiseHandler.MustFire;\r
- T jtem;\r
- foreach (U item in items)\r
- { jtem = item; if (remove(ref jtem) && raise) raiseHandler.Remove(jtem); }\r
-#if SHRINK\r
- if (size < resizethreshhold / 2 && resizethreshhold > 16)\r
- {\r
- int newlength = table.Length;\r
-\r
- while (newlength >= 32 && newlength * fillfactor / 2 > size)\r
- newlength /= 2;\r
-\r
- resize(newlength - 1);\r
- }\r
-#endif\r
- if (raise) raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items from the set, resetting internal table to initial size.\r
- /// </summary>\r
- [Tested]\r
- public virtual void Clear()\r
- {\r
- updatecheck();\r
- int oldsize = size;\r
- clear();\r
- if (ActiveEvents != 0 && oldsize > 0)\r
- {\r
- raiseCollectionCleared(true, oldsize);\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items *not* in a supplied collection from this set.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to retain</param>\r
- [Tested]\r
- public virtual void RetainAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
-\r
- HashSet<T> aux = new HashSet<T>(EqualityComparer);\r
-\r
- //This only works for sets:\r
- foreach (U item in items)\r
- if (Contains(item))\r
- {\r
- T jtem = item;\r
-\r
- aux.searchoradd(ref jtem, true, false, false);\r
- }\r
-\r
- if (size == aux.size)\r
- return;\r
-\r
- CircularQueue<T> wasRemoved = null;\r
- if ((ActiveEvents & EventTypeEnum.Removed) != 0)\r
- {\r
- wasRemoved = new CircularQueue<T>();\r
- foreach (T item in this)\r
- if (!aux.Contains(item))\r
- wasRemoved.Enqueue(item);\r
- }\r
-\r
- table = aux.table;\r
- size = aux.size;\r
-#if !REFBUCKET\r
- defaultvalid = aux.defaultvalid;\r
- defaultitem = aux.defaultitem;\r
-#endif\r
- indexmask = aux.indexmask;\r
- resizethreshhold = aux.resizethreshhold;\r
-\r
-\r
- if ((ActiveEvents & EventTypeEnum.Removed) != 0)\r
- raiseForRemoveAll(wasRemoved);\r
- else if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
- /// <summary>\r
- /// Check if all items in a supplied collection is in this set\r
- /// (ignoring multiplicities). \r
- /// </summary>\r
- /// <param name="items">The items to look for.</param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if all items are found.</returns>\r
- [Tested]\r
- public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- foreach (U item in items)\r
- if (!Contains(item))\r
- return false;\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create an array containing all items in this set (in enumeration order).\r
- /// </summary>\r
- /// <returns>The array</returns>\r
- [Tested]\r
- public override T[] ToArray()\r
- {\r
- T[] res = new T[size];\r
- int index = 0;\r
-\r
-#if !REFBUCKET\r
- if (defaultvalid)\r
- res[index++] = defaultitem;\r
-#endif\r
- for (int i = 0; i < table.Length; i++)\r
- {\r
- Bucket b = table[i];\r
-#if LINEARPROBING\r
-#if REFBUCKET\r
- if (b != null)\r
- res[index++] = b.item;\r
-#else\r
- if (!isnull(b.item))\r
- res[index++] = b.item;\r
-#endif\r
-#else\r
-#if REFBUCKET\r
- while (b != null)\r
- {\r
- res[index++] = b.item;\r
- b = b.overflow;\r
- }\r
-#else\r
- if (!isnull(b.item))\r
- {\r
- res[index++] = b.item;\r
-\r
- OverflowBucket ob = b.overflow;\r
-\r
- while (ob != null)\r
- {\r
- res[index++] = ob.item;\r
- ob = ob.overflow;\r
- }\r
- }\r
-#endif\r
-#endif\r
- }\r
-\r
- Debug.Assert(size == index);\r
- return res;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Count the number of times an item is in this set (either 0 or 1).\r
- /// </summary>\r
- /// <param name="item">The item to look for.</param>\r
- /// <returns>1 if item is in set, 0 else</returns>\r
- [Tested]\r
- public virtual int ContainsCount(T item) { return Contains(item) ? 1 : 0; }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<T> UniqueItems() { return this; }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities()\r
- {\r
- return new MultiplicityOne<T>(this);\r
- }\r
-\r
- /// <summary>\r
- /// Remove all (at most 1) copies of item from this set.\r
- /// </summary>\r
- /// <param name="item">The item to remove</param>\r
- [Tested]\r
- public virtual void RemoveAllCopies(T item) { Remove(item); }\r
-\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
-\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- [Tested]\r
- public override T Choose()\r
- {\r
- int len = table.Length;\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-#if REFBUCKET\r
- do { if (++lastchosen >= len) lastchosen = 0; } while (table[lastchosen] == null);\r
-#else\r
- if (defaultvalid) return defaultitem;\r
- do { if (++lastchosen >= len) lastchosen = 0; } while (isnull(table[lastchosen].item));\r
-#endif\r
- return table[lastchosen].item;\r
- }\r
-\r
- /// <summary>\r
- /// Create an enumerator for this set.\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- int index = -1;\r
- int mystamp = stamp;\r
- int len = table.Length;\r
-\r
-#if LINEARPROBING\r
-#if REFBUCKET\r
- while (++index < len)\r
- {\r
- if (mystamp != stamp) throw new CollectionModifiedException();\r
-\r
- if (table[index] != null) yield return table[index].item;\r
- }\r
-#else\r
- if (defaultvalid)\r
- yield return defaultitem;\r
-\r
- while (++index < len)\r
- {\r
- if (mystamp != stamp) throw new CollectionModifiedException();\r
-\r
- T item = table[index].item;\r
-\r
- if (!isnull(item)) yield return item;\r
- }\r
-#endif\r
-#else\r
-#if REFBUCKET\r
- Bucket b = null;\r
-#else\r
- OverflowBucket ob = null;\r
-\r
- if (defaultvalid)\r
- yield return defaultitem;\r
-#endif\r
- while (true)\r
- {\r
- if (mystamp != stamp)\r
- throw new CollectionModifiedException();\r
-\r
-#if REFBUCKET\r
- if (b == null || b.overflow == null)\r
- {\r
- do\r
- {\r
- if (++index >= len) yield break;\r
- } while (table[index] == null);\r
-\r
- b = table[index];\r
- yield return b.item;\r
- }\r
- else\r
- {\r
- b = b.overflow;\r
- yield return b.item;\r
- }\r
-#else\r
- if (ob != null && ob.overflow != null)\r
- {\r
- ob = ob.overflow;\r
- yield return ob.item;\r
- }\r
- else if (index >= 0 && ob == null && (ob = table[index].overflow) != null)\r
- {\r
- yield return ob.item;\r
- }\r
- else\r
- {\r
- do\r
- {\r
- if (++index >= len) yield break;\r
- } while (isnull(table[index].item));\r
-\r
- yield return table[index].item;\r
- ob = null;\r
- }\r
-#endif\r
- }\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region ISink<T> Members\r
- /// <summary>\r
- /// Report if this is a set collection.\r
- /// </summary>\r
- /// <value>Always false</value>\r
- [Tested]\r
- public virtual bool AllowsDuplicates { [Tested]get { return false; } }\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting { get { return true; } }\r
-\r
- /// <summary>\r
- /// Add an item to this set.\r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True if item was added (i.e. not found)</returns>\r
- [Tested]\r
- public virtual bool Add(T item)\r
- {\r
- updatecheck();\r
- return !searchoradd(ref item, true, false, true);\r
- }\r
-\r
- /// <summary>\r
- /// Add the elements from another collection with a more specialized item type \r
- /// to this collection. Since this\r
- /// collection has set semantics, only items not already in the collection\r
- /// will be added.\r
- /// </summary>\r
- /// <typeparam name="U">The type of items to add</typeparam>\r
- /// <param name="items">The items to add</param>\r
- [Tested]\r
- public virtual void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- bool wasChanged = false;\r
- bool raiseAdded = (ActiveEvents & EventTypeEnum.Added) != 0;\r
- CircularQueue<T> wasAdded = raiseAdded ? new CircularQueue<T>() : null;\r
- foreach (T item in items)\r
- {\r
- T jtem = item;\r
-\r
- if (!searchoradd(ref jtem, true, false, false))\r
- {\r
- wasChanged = true;\r
- if (raiseAdded)\r
- wasAdded.Enqueue(item);\r
- }\r
- }\r
- //TODO: implement a RaiseForAddAll() method\r
- if (raiseAdded & wasChanged)\r
- foreach (T item in wasAdded)\r
- raiseItemsAdded(item, 1);\r
- if (((ActiveEvents & EventTypeEnum.Changed) != 0 && wasChanged))\r
- raiseCollectionChanged();\r
- }\r
-\r
-\r
- #endregion\r
-\r
- #region Diagnostics\r
-\r
- /// <summary>\r
- /// Test internal structure of data (invariants)\r
- /// </summary>\r
- /// <returns>True if pass</returns>\r
- [Tested]\r
- public virtual bool Check()\r
- {\r
- int count = 0;\r
-#if LINEARPROBING\r
- int lasthole = table.Length - 1;\r
-\r
-#if REFBUCKET\r
- while (lasthole >= 0 && table[lasthole] != null)\r
-#else\r
- while (lasthole >= 0 && !isnull(table[lasthole].item))\r
-#endif\r
- {\r
- lasthole--;\r
- count++;\r
- }\r
-\r
- if (lasthole < 0)\r
- {\r
- Console.WriteLine("Table is completely filled!");\r
- return false;\r
- }\r
-\r
- for (int cellindex = lasthole + 1, s = table.Length; cellindex < s; cellindex++)\r
- {\r
- Bucket b = table[cellindex];\r
- int hashindex = hv2i(b.hashval);\r
-\r
- if (hashindex <= lasthole || hashindex > cellindex)\r
- {\r
- Console.WriteLine("Bad cell item={0}, hashval={1}, hashindex={2}, cellindex={3}, lasthole={4}", b.item, b.hashval, hashindex, cellindex, lasthole);\r
- return false;\r
- }\r
- }\r
-\r
- int latesthole = -1;\r
-\r
- for (int cellindex = 0; cellindex < lasthole; cellindex++)\r
- {\r
- Bucket b = table[cellindex];\r
-\r
-#if REFBUCKET\r
- if (b != null)\r
-#else\r
- if (!isnull(b.item))\r
-#endif\r
- {\r
- count++;\r
-\r
- int hashindex = hv2i(b.hashval);\r
-\r
- if (cellindex < hashindex && hashindex <= lasthole)\r
- {\r
- Console.WriteLine("Bad cell item={0}, hashval={1}, hashindex={2}, cellindex={3}, latesthole={4}", b.item, b.hashval, hashindex, cellindex, latesthole);\r
- return false;\r
- }\r
- }\r
- else\r
- {\r
- latesthole = cellindex;\r
- break;\r
- }\r
- }\r
-\r
- for (int cellindex = latesthole + 1; cellindex < lasthole; cellindex++)\r
- {\r
- Bucket b = table[cellindex];\r
-\r
-#if REFBUCKET\r
- if (b != null)\r
-#else\r
- if (!isnull(b.item))\r
-#endif\r
- {\r
- count++;\r
-\r
- int hashindex = hv2i(b.hashval);\r
-\r
- if (hashindex <= latesthole || cellindex < hashindex)\r
- {\r
- Console.WriteLine("Bad cell item={0}, hashval={1}, hashindex={2}, cellindex={3}, latesthole={4}", b.item, b.hashval, hashindex, cellindex, latesthole);\r
- return false;\r
- }\r
- }\r
- else\r
- {\r
- latesthole = cellindex;\r
- }\r
- }\r
-\r
- return true;\r
-#else\r
- bool retval = true;\r
- for (int i = 0, s = table.Length; i < s; i++)\r
- {\r
- int level = 0;\r
- Bucket b = table[i];\r
-#if REFBUCKET\r
- while (b != null)\r
- {\r
- if (i != hv2i(b.hashval))\r
- {\r
- Console.WriteLine("Bad cell item={0}, hashval={1}, index={2}, level={3}", b.item, b.hashval, i, level);\r
- retval = false;\r
- }\r
-\r
- count++;\r
- level++;\r
- b = b.overflow;\r
- }\r
-#else\r
- if (!isnull(b.item))\r
- {\r
- count++;\r
- if (i != hv2i(b.hashval))\r
- {\r
- Console.WriteLine("Bad cell item={0}, hashval={1}, index={2}, level={3}", b.item, b.hashval, i, level);\r
- retval = false;\r
- }\r
-\r
- OverflowBucket ob = b.overflow;\r
-\r
- while (ob != null)\r
- {\r
- level++;\r
- count++;\r
- if (i != hv2i(ob.hashval))\r
- {\r
- Console.WriteLine("Bad cell item={0}, hashval={1}, index={2}, level={3}", b.item, b.hashval, i, level);\r
- retval = false;\r
- }\r
-\r
- ob = ob.overflow;\r
- }\r
- }\r
-#endif\r
- }\r
-\r
- if (count != size)\r
- {\r
- Console.WriteLine("size({0}) != count({1})", size, count);\r
- retval = false;\r
- }\r
-\r
- return retval;\r
-#endif\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Produce statistics on distribution of bucket sizes. Current implementation is incomplete.\r
- /// </summary>\r
- /// <returns>Histogram data.</returns>\r
- [Tested(via = "Manually")]\r
- public ISortedDictionary<int, int> BucketCostDistribution()\r
- {\r
- TreeDictionary<int, int> res = new TreeDictionary<int, int>();\r
-#if LINEARPROBING\r
- int count = 0;\r
-#if REFBUCKET\r
- while (table[count] != null)\r
-#else\r
- while (!isnull(table[count].item))\r
-#endif\r
- count++;\r
- for (int i = table.Length - 1; i >= 0; i--)\r
- {\r
-#if REFBUCKET\r
- if (table[i] != null)\r
-#else\r
- if (!isnull(table[i].item))\r
-#endif\r
- count++;\r
- else\r
- count = 0;\r
- if (res.Contains(count))\r
- res[count]++;\r
- else\r
- res[count] = 1;\r
- }\r
-\r
- return res;\r
-#else\r
- for (int i = 0, s = table.Length; i < s; i++)\r
- {\r
- int count = 0;\r
-#if REFBUCKET\r
- Bucket b = table[i];\r
-\r
- while (b != null)\r
- {\r
- count++;\r
- b = b.overflow;\r
- }\r
-#else\r
- Bucket b = table[i];\r
-\r
- if (!isnull(b.item))\r
- {\r
- count = 1;\r
-\r
- OverflowBucket ob = b.overflow;\r
-\r
- while (ob != null)\r
- {\r
- count++;\r
- ob = ob.overflow;\r
- }\r
- }\r
-#endif\r
- if (res.Contains(count))\r
- res[count]++;\r
- else\r
- res[count] = 1;\r
- }\r
-\r
- return res;\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this HashSet.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- HashSet<T> clone = new HashSet<T>(size > 0 ? size : 1, itemequalityComparer);\r
- //TODO: make sure this really adds in the counting bag way!\r
- clone.AddAll(this);\r
- return clone;\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A priority queue class based on an interval heap data structure.\r
- /// </summary>\r
- /// <typeparam name="T">The item type</typeparam>\r
- [Serializable]\r
- public class IntervalHeap<T> : CollectionValueBase<T>, IPriorityQueue<T>\r
- {\r
- #region Events\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override EventTypeEnum ListenableEvents { get { return EventTypeEnum.Basic; } }\r
-\r
- #endregion\r
-\r
- #region Fields\r
- [Serializable]\r
- struct Interval\r
- {\r
- internal T first, last; internal Handle firsthandle, lasthandle;\r
-\r
-\r
- public override string ToString() { return String.Format("[{0}; {1}]", first, last); }\r
- }\r
-\r
-\r
-\r
- object syncroot = new object();\r
-\r
- int stamp;\r
-\r
- SCG.IComparer<T> comparer;\r
- SCG.IEqualityComparer<T> itemequalityComparer;\r
-\r
- Interval[] heap;\r
-\r
- int size;\r
- #endregion\r
-\r
- #region Util\r
- bool heapifyMin(int i)\r
- {\r
- bool swappedroot = false;\r
- int cell = i, currentmin = cell;\r
- T currentitem = heap[cell].first;\r
- Handle currenthandle = heap[cell].firsthandle;\r
-\r
- if (i > 0)\r
- {\r
- T other = heap[cell].last;\r
- if (2 * cell + 1 < size && comparer.Compare(currentitem, other) > 0)\r
- {\r
- swappedroot = true;\r
- Handle otherhandle = heap[cell].lasthandle;\r
- updateLast(cell, currentitem, currenthandle);\r
- currentitem = other;\r
- currenthandle = otherhandle;\r
- }\r
- }\r
-\r
- T minitem = currentitem;\r
- Handle minhandle = currenthandle;\r
-\r
- while (true)\r
- {\r
- int l = 2 * cell + 1, r = l + 1;\r
- T lv, rv;\r
-\r
- if (2 * l < size && comparer.Compare(lv = heap[l].first, minitem) < 0)\r
- { currentmin = l; minitem = lv; }\r
-\r
- if (2 * r < size && comparer.Compare(rv = heap[r].first, minitem) < 0)\r
- { currentmin = r; minitem = rv; }\r
-\r
- if (currentmin == cell)\r
- break;\r
-\r
- minhandle = heap[currentmin].firsthandle;\r
- updateFirst(cell, minitem, minhandle);\r
- cell = currentmin;\r
-\r
- //Maybe swap first and last\r
- T other = heap[cell].last;\r
- if (2 * currentmin + 1 < size && comparer.Compare(currentitem, other) > 0)\r
- {\r
- Handle otherhandle = heap[cell].lasthandle;\r
- updateLast(cell, currentitem, currenthandle);\r
- currentitem = other;\r
- currenthandle = otherhandle;\r
- }\r
-\r
-\r
- minitem = currentitem;\r
- minhandle = currenthandle;\r
- }\r
-\r
- if (cell != i || swappedroot)\r
- updateFirst(cell, minitem, minhandle);\r
- return swappedroot;\r
- }\r
-\r
-\r
- bool heapifyMax(int i)\r
- {\r
- bool swappedroot = false;\r
- int cell = i, currentmax = cell;\r
- T currentitem = heap[cell].last;\r
- Handle currenthandle = heap[cell].lasthandle;\r
-\r
- if (i > 0)\r
- {\r
- T other = heap[cell].first;\r
- if (comparer.Compare(currentitem, other) < 0)\r
- {\r
- swappedroot = true;\r
- Handle otherhandle = heap[cell].firsthandle;\r
- updateFirst(cell, currentitem, currenthandle);\r
- currentitem = other;\r
- currenthandle = otherhandle;\r
- }\r
- }\r
-\r
- T maxitem = currentitem;\r
- Handle maxhandle = currenthandle;\r
-\r
- while (true)\r
- {\r
- int l = 2 * cell + 1, r = l + 1;\r
- T lv, rv;\r
-\r
- if (2 * l + 1 < size && comparer.Compare(lv = heap[l].last, maxitem) > 0)\r
- { currentmax = l; maxitem = lv; }\r
-\r
- if (2 * r + 1 < size && comparer.Compare(rv = heap[r].last, maxitem) > 0)\r
- { currentmax = r; maxitem = rv; }\r
-\r
- if (currentmax == cell)\r
- break;\r
-\r
- maxhandle = heap[currentmax].lasthandle;\r
- updateLast(cell, maxitem, maxhandle);\r
- cell = currentmax;\r
-\r
- //Maybe swap first and last\r
- T other = heap[cell].first;\r
- if (comparer.Compare(currentitem, other) < 0)\r
- {\r
- Handle otherhandle = heap[cell].firsthandle;\r
- updateFirst(cell, currentitem, currenthandle);\r
- currentitem = other;\r
- currenthandle = otherhandle;\r
- }\r
-\r
- maxitem = currentitem;\r
- maxhandle = currenthandle;\r
- }\r
-\r
- if (cell != i || swappedroot) //Check could be better?\r
- updateLast(cell, maxitem, maxhandle);\r
- return swappedroot;\r
- }\r
-\r
-\r
- void bubbleUpMin(int i)\r
- {\r
- if (i > 0)\r
- {\r
- T min = heap[i].first, iv = min;\r
- Handle minhandle = heap[i].firsthandle;\r
- int p = (i + 1) / 2 - 1;\r
-\r
- while (i > 0)\r
- {\r
- if (comparer.Compare(iv, min = heap[p = (i + 1) / 2 - 1].first) < 0)\r
- {\r
- updateFirst(i, min, heap[p].firsthandle);\r
- min = iv;\r
- i = p;\r
- }\r
- else\r
- break;\r
- }\r
-\r
- updateFirst(i, iv, minhandle);\r
- }\r
- }\r
-\r
-\r
- void bubbleUpMax(int i)\r
- {\r
- if (i > 0)\r
- {\r
- T max = heap[i].last, iv = max;\r
- Handle maxhandle = heap[i].lasthandle;\r
- int p = (i + 1) / 2 - 1;\r
-\r
- while (i > 0)\r
- {\r
- if (comparer.Compare(iv, max = heap[p = (i + 1) / 2 - 1].last) > 0)\r
- {\r
- updateLast(i, max, heap[p].lasthandle);\r
- max = iv;\r
- i = p;\r
- }\r
- else\r
- break;\r
- }\r
-\r
- updateLast(i, iv, maxhandle);\r
-\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
- /// <summary>\r
- /// Create an interval heap with natural item comparer and default initial capacity (16)\r
- /// </summary>\r
- public IntervalHeap() : this(16) { }\r
-\r
-\r
- /// <summary>\r
- /// Create an interval heap with external item comparer and default initial capacity (16)\r
- /// </summary>\r
- /// <param name="comparer">The external comparer</param>\r
- public IntervalHeap(SCG.IComparer<T> comparer) : this(16,comparer) { }\r
-\r
-\r
- //TODO: maybe remove\r
- /// <summary>\r
- /// Create an interval heap with natural item comparer and prescribed initial capacity\r
- /// </summary>\r
- /// <param name="capacity">The initial capacity</param>\r
- public IntervalHeap(int capacity) : this(capacity, Comparer<T>.Default, EqualityComparer<T>.Default) { }\r
-\r
-\r
- /// <summary>\r
- /// Create an interval heap with external item comparer and prescribed initial capacity\r
- /// </summary>\r
- /// <param name="comparer">The external comparer</param>\r
- /// <param name="capacity">The initial capacity</param>\r
- public IntervalHeap(int capacity, SCG.IComparer<T> comparer) : this(capacity,comparer,new ComparerZeroHashCodeEqualityComparer<T>(comparer)) { }\r
-\r
- IntervalHeap(int capacity, SCG.IComparer<T> comparer, SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- if (comparer == null)\r
- throw new NullReferenceException("Item comparer cannot be null");\r
- if (itemequalityComparer == null)\r
- throw new NullReferenceException("Item equality comparer cannot be null");\r
- this.comparer = comparer;\r
- this.itemequalityComparer = itemequalityComparer;\r
- int length = 1;\r
- while (length < capacity) length <<= 1;\r
- heap = new Interval[length];\r
- }\r
-\r
- #endregion\r
-\r
- #region IPriorityQueue<T> Members\r
-\r
- /// <summary>\r
- /// Find the current least item of this priority queue.\r
- /// <exception cref="NoSuchItemException"/> if queue is empty\r
- /// </summary>\r
- /// <returns>The least item.</returns>\r
- [Tested]\r
- public T FindMin()\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- return heap[0].first;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the least item from this priority queue.\r
- /// <exception cref="NoSuchItemException"/> if queue is empty\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T DeleteMin()\r
- {\r
- IPriorityQueueHandle<T> handle = null;\r
- return DeleteMin(out handle);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the current largest item of this priority queue.\r
- /// <exception cref="NoSuchItemException"/> if queue is empty\r
- /// </summary>\r
- /// <returns>The largest item.</returns>\r
- [Tested]\r
- public T FindMax()\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException("Heap is empty");\r
- else if (size == 1)\r
- return heap[0].first;\r
- else\r
- return heap[0].last;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the largest item from this priority queue.\r
- /// <exception cref="NoSuchItemException"/> if queue is empty\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T DeleteMax()\r
- {\r
- IPriorityQueueHandle<T> handle = null;\r
- return DeleteMax(out handle);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// The comparer object supplied at creation time for this collection\r
- /// </summary>\r
- /// <value>The comparer</value>\r
- public SCG.IComparer<T> Comparer { get { return comparer; } }\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> Members\r
-\r
- /// <summary>\r
- /// If true any call of an updating operation will throw an\r
- /// <code>ReadOnlyCollectionException</code>\r
- /// </summary>\r
- /// <value>True if this collection is read-only.</value>\r
- public bool IsReadOnly { get { return false; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True since this collection has bag semantics</value>\r
- [Tested]\r
- public bool AllowsDuplicates { [Tested]get { return true; } }\r
-\r
- /// <summary>\r
- /// Value is null since this collection has no equality concept for its items. \r
- /// </summary>\r
- /// <value></value>\r
- public virtual SCG.IEqualityComparer<T> EqualityComparer { get { return itemequalityComparer; } }\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting { get { return false; } }\r
-\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The distinguished object to use for locking to synchronize multithreaded access</value>\r
- [Tested]\r
- public object SyncRoot { [Tested]get { return syncroot; } }\r
-\r
-\r
- /// <summary>\r
- /// Add an item to this priority queue.\r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True</returns>\r
- [Tested]\r
- public bool Add(T item)\r
- {\r
- stamp++;\r
- if (add(null, item))\r
- {\r
- raiseItemsAdded(item, 1);\r
- raiseCollectionChanged();\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- private bool add(Handle itemhandle, T item)\r
- {\r
- if (size == 0)\r
- {\r
- size = 1;\r
- updateFirst(0, item, itemhandle);\r
- return true;\r
- }\r
-\r
- if (size == 2 * heap.Length)\r
- {\r
- Interval[] newheap = new Interval[2 * heap.Length];\r
-\r
- Array.Copy(heap, newheap, heap.Length);\r
- heap = newheap;\r
- }\r
-\r
- if (size % 2 == 0)\r
- {\r
- int i = size / 2, p = (i + 1) / 2 - 1;\r
- T tmp = heap[p].last;\r
-\r
- if (comparer.Compare(item, tmp) > 0)\r
- {\r
- updateFirst(i, tmp, heap[p].lasthandle);\r
- updateLast(p, item, itemhandle);\r
- bubbleUpMax(p);\r
- }\r
- else\r
- {\r
- updateFirst(i, item, itemhandle);\r
-\r
- if (comparer.Compare(item, heap[p].first) < 0)\r
- bubbleUpMin(i);\r
- }\r
- }\r
- else\r
- {\r
- int i = size / 2;\r
- T other = heap[i].first;\r
-\r
- if (comparer.Compare(item, other) < 0)\r
- {\r
- updateLast(i, other, heap[i].firsthandle);\r
- updateFirst(i, item, itemhandle);\r
- bubbleUpMin(i);\r
- }\r
- else\r
- {\r
- updateLast(i, item, itemhandle);\r
- bubbleUpMax(i);\r
- }\r
- }\r
- size++;\r
-\r
- return true;\r
- }\r
-\r
- private void updateLast(int cell, T item, Handle handle)\r
- {\r
- heap[cell].last = item;\r
- if (handle != null)\r
- handle.index = 2 * cell + 1;\r
- heap[cell].lasthandle = handle;\r
- }\r
-\r
- private void updateFirst(int cell, T item, Handle handle)\r
- {\r
- heap[cell].first = item;\r
- if (handle != null)\r
- handle.index = 2 * cell;\r
- heap[cell].firsthandle = handle;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Add the elements from another collection with a more specialized item type \r
- /// to this collection. \r
- /// </summary>\r
- /// <typeparam name="U">The type of items to add</typeparam>\r
- /// <param name="items">The items to add</param>\r
- [Tested]\r
- public void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- stamp++;\r
- int oldsize = size;\r
- foreach (T item in items)\r
- add(null, item);\r
- if (size != oldsize)\r
- {\r
- if ((ActiveEvents & EventTypeEnum.Added) != 0)\r
- foreach (T item in items)\r
- raiseItemsAdded(item, 1);\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region ICollection<T> members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if this collection is empty.</value>\r
- [Tested]\r
- public override bool IsEmpty { [Tested]get { return size == 0; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The size of this collection</value>\r
- [Tested]\r
- public override int Count { [Tested]get { return size; } }\r
-\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>A characterization of the speed of the \r
- /// <code>Count</code> property in this collection.</value>\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- public override T Choose()\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException("Collection is empty");\r
- return heap[0].first;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create an enumerator for the collection\r
- /// <para>Note: the enumerator does *not* enumerate the items in sorted order, \r
- /// but in the internal table order.</para>\r
- /// </summary>\r
- /// <returns>The enumerator(SIC)</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- int mystamp = stamp;\r
- for (int i = 0; i < size; i++)\r
- {\r
- if (mystamp != stamp) throw new CollectionModifiedException();\r
- yield return i % 2 == 0 ? heap[i >> 1].first : heap[i >> 1].last;\r
- }\r
- yield break;\r
- }\r
-\r
-\r
- #endregion\r
-\r
- #region Diagnostics\r
- private bool check(int i, T min, T max)\r
- {\r
- bool retval = true;\r
- Interval interval = heap[i];\r
- T first = interval.first, last = interval.last;\r
-\r
- if (2 * i + 1 == size)\r
- {\r
- if (comparer.Compare(min, first) > 0)\r
- {\r
- Console.WriteLine("Cell {0}: parent.first({1}) > first({2}) [size={3}]", i, min, first, size);\r
- retval = false;\r
- }\r
-\r
- if (comparer.Compare(first, max) > 0)\r
- {\r
- Console.WriteLine("Cell {0}: first({1}) > parent.last({2}) [size={3}]", i, first, max, size);\r
- retval = false;\r
- }\r
- if (interval.firsthandle != null && interval.firsthandle.index != 2 * i)\r
- {\r
- Console.WriteLine("Cell {0}: firsthandle.index({1}) != 2*cell({2}) [size={3}]", i, interval.firsthandle.index, 2 * i, size);\r
- retval = false;\r
- }\r
-\r
- return retval;\r
- }\r
- else\r
- {\r
- if (comparer.Compare(min, first) > 0)\r
- {\r
- Console.WriteLine("Cell {0}: parent.first({1}) > first({2}) [size={3}]", i, min, first, size);\r
- retval = false;\r
- }\r
-\r
- if (comparer.Compare(first, last) > 0)\r
- {\r
- Console.WriteLine("Cell {0}: first({1}) > last({2}) [size={3}]", i, first, last, size);\r
- retval = false;\r
- }\r
-\r
- if (comparer.Compare(last, max) > 0)\r
- {\r
- Console.WriteLine("Cell {0}: last({1}) > parent.last({2}) [size={3}]", i, last, max, size);\r
- retval = false;\r
- }\r
- if (interval.firsthandle != null && interval.firsthandle.index != 2 * i)\r
- {\r
- Console.WriteLine("Cell {0}: firsthandle.index({1}) != 2*cell({2}) [size={3}]", i, interval.firsthandle.index, 2 * i, size);\r
- retval = false;\r
- }\r
- if (interval.lasthandle != null && interval.lasthandle.index != 2 * i + 1)\r
- {\r
- Console.WriteLine("Cell {0}: lasthandle.index({1}) != 2*cell+1({2}) [size={3}]", i, interval.lasthandle.index, 2 * i + 1, size);\r
- retval = false;\r
- }\r
-\r
- int l = 2 * i + 1, r = l + 1;\r
-\r
- if (2 * l < size)\r
- retval = retval && check(l, first, last);\r
-\r
- if (2 * r < size)\r
- retval = retval && check(r, first, last);\r
- }\r
-\r
- return retval;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check the integrity of the internal data structures of this collection.\r
- /// Only avaliable in DEBUG builds???\r
- /// </summary>\r
- /// <returns>True if check does not fail.</returns>\r
- [Tested]\r
- public bool Check()\r
- {\r
- if (size == 0)\r
- return true;\r
-\r
- if (size == 1)\r
- return (object)(heap[0].first) != null;\r
-\r
- return check(0, heap[0].first, heap[0].last);\r
- }\r
-\r
- #endregion\r
-\r
- #region IPriorityQueue<T> Members\r
-\r
- [Serializable]\r
- class Handle : IPriorityQueueHandle<T>\r
- {\r
- /// <summary>\r
- /// To save space, the index is 2*cell for heap[cell].first, and 2*cell+1 for heap[cell].last\r
- /// </summary>\r
- internal int index = -1;\r
-\r
- public override string ToString()\r
- {\r
- return String.Format("[{0}]", index);\r
- }\r
-\r
- }\r
-\r
- /// <summary>\r
- /// Get or set the item corresponding to a handle. \r
- /// </summary>\r
- /// <exception cref="InvalidPriorityQueueHandleException">if the handle is invalid for this queue</exception>\r
- /// <param name="handle">The reference into the heap</param>\r
- /// <returns></returns>\r
- [Tested]\r
- public T this[IPriorityQueueHandle<T> handle]\r
- {\r
- get\r
- {\r
- int cell;\r
- bool isfirst;\r
- Handle myhandle = checkHandle(handle, out cell, out isfirst);\r
-\r
- return isfirst ? heap[cell].first : heap[cell].last;\r
- }\r
- set\r
- {\r
- Replace(handle, value);\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check safely if a handle is valid for this queue and if so, report the corresponding queue item.\r
- /// </summary>\r
- /// <param name="handle">The handle to check</param>\r
- /// <param name="item">If the handle is valid this will contain the corresponding item on output.</param>\r
- /// <returns>True if the handle is valid.</returns>\r
- public bool Find(IPriorityQueueHandle<T> handle, out T item)\r
- {\r
- Handle myhandle = handle as Handle;\r
- if (myhandle == null)\r
- {\r
- item = default(T);\r
- return false;\r
- }\r
- int toremove = myhandle.index;\r
- int cell = toremove / 2;\r
- bool isfirst = toremove % 2 == 0;\r
- {\r
- if (toremove == -1 || toremove >= size)\r
- {\r
- item = default(T);\r
- return false;\r
- }\r
- Handle actualhandle = isfirst ? heap[cell].firsthandle : heap[cell].lasthandle;\r
- if (actualhandle != myhandle)\r
- {\r
- item = default(T);\r
- return false;\r
- }\r
- }\r
- item = isfirst ? heap[cell].first : heap[cell].last;\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Add an item to the priority queue, receiving a \r
- /// handle for the item in the queue, \r
- /// or reusing an already existing handle.\r
- /// </summary>\r
- /// <param name="handle">On output: a handle for the added item. \r
- /// On input: null for allocating a new handle, an invalid handle for reuse. \r
- /// A handle for reuse must be compatible with this priority queue, \r
- /// by being created by a priority queue of the same runtime type, but not \r
- /// necessarily the same priority queue object.</param>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True since item will always be added unless the call throws an exception.</returns>\r
- [Tested]\r
- public bool Add(ref IPriorityQueueHandle<T> handle, T item)\r
- {\r
- stamp++;\r
- Handle myhandle = (Handle)handle;\r
- if (myhandle == null)\r
- handle = myhandle = new Handle();\r
- else\r
- if (myhandle.index != -1)\r
- throw new InvalidPriorityQueueHandleException("Handle not valid for reuse");\r
- if (add(myhandle, item))\r
- {\r
- raiseItemsAdded(item, 1);\r
- raiseCollectionChanged();\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Delete an item with a handle from a priority queue.\r
- /// </summary>\r
- /// <exception cref="InvalidPriorityQueueHandleException">if the handle is invalid</exception>\r
- /// <param name="handle">The handle for the item. The handle will be invalidated, but reusable.</param>\r
- /// <returns>The deleted item</returns>\r
- [Tested]\r
- public T Delete(IPriorityQueueHandle<T> handle)\r
- {\r
- stamp++;\r
- int cell;\r
- bool isfirst;\r
- Handle myhandle = checkHandle(handle, out cell, out isfirst);\r
-\r
- T retval;\r
- myhandle.index = -1;\r
- int lastcell = (size - 1) / 2;\r
-\r
- if (cell == lastcell)\r
- {\r
- if (isfirst)\r
- {\r
- retval = heap[cell].first;\r
- if (size % 2 == 0)\r
- {\r
- updateFirst(cell, heap[cell].last, heap[cell].lasthandle);\r
- heap[cell].last = default(T);\r
- heap[cell].lasthandle = null;\r
- }\r
- else\r
- {\r
- heap[cell].first = default(T);\r
- heap[cell].firsthandle = null;\r
- }\r
- }\r
- else\r
- {\r
- retval = heap[cell].last;\r
- heap[cell].last = default(T);\r
- heap[cell].lasthandle = null;\r
- }\r
- size--;\r
- }\r
- else if (isfirst)\r
- {\r
- retval = heap[cell].first;\r
-\r
- if (size % 2 == 0)\r
- {\r
- updateFirst(cell, heap[lastcell].last, heap[lastcell].lasthandle);\r
- heap[lastcell].last = default(T);\r
- heap[lastcell].lasthandle = null;\r
- }\r
- else\r
- {\r
- updateFirst(cell, heap[lastcell].first, heap[lastcell].firsthandle);\r
- heap[lastcell].first = default(T);\r
- heap[lastcell].firsthandle = null;\r
- }\r
-\r
- size--;\r
- if (heapifyMin(cell))\r
- bubbleUpMax(cell);\r
- else\r
- bubbleUpMin(cell);\r
- }\r
- else\r
- {\r
- retval = heap[cell].last;\r
-\r
- if (size % 2 == 0)\r
- {\r
- updateLast(cell, heap[lastcell].last, heap[lastcell].lasthandle);\r
- heap[lastcell].last = default(T);\r
- heap[lastcell].lasthandle = null;\r
- }\r
- else\r
- {\r
- updateLast(cell, heap[lastcell].first, heap[lastcell].firsthandle);\r
- heap[lastcell].first = default(T);\r
- heap[lastcell].firsthandle = null;\r
- }\r
-\r
- size--;\r
- if (heapifyMax(cell))\r
- bubbleUpMin(cell);\r
- else\r
- bubbleUpMax(cell);\r
- }\r
-\r
- raiseItemsRemoved(retval, 1);\r
- raiseCollectionChanged();\r
-\r
- return retval;\r
- }\r
-\r
- private Handle checkHandle(IPriorityQueueHandle<T> handle, out int cell, out bool isfirst)\r
- {\r
- Handle myhandle = (Handle)handle;\r
- int toremove = myhandle.index;\r
- cell = toremove / 2;\r
- isfirst = toremove % 2 == 0;\r
- {\r
- if (toremove == -1 || toremove >= size)\r
- throw new InvalidPriorityQueueHandleException("Invalid handle, index out of range");\r
- Handle actualhandle = isfirst ? heap[cell].firsthandle : heap[cell].lasthandle;\r
- if (actualhandle != myhandle)\r
- throw new InvalidPriorityQueueHandleException("Invalid handle, doesn't match queue");\r
- }\r
- return myhandle;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Replace an item with a handle in a priority queue with a new item. \r
- /// Typically used for changing the priority of some queued object.\r
- /// </summary>\r
- /// <param name="handle">The handle for the old item</param>\r
- /// <param name="item">The new item</param>\r
- /// <returns>The old item</returns>\r
- [Tested]\r
- public T Replace(IPriorityQueueHandle<T> handle, T item)\r
- {\r
- stamp++;\r
- int cell;\r
- bool isfirst;\r
- checkHandle(handle, out cell, out isfirst);\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- T retval;\r
-\r
- if (isfirst)\r
- {\r
- retval = heap[cell].first;\r
- heap[cell].first = item;\r
- if (size == 2 * cell + 1) // cell == lastcell\r
- {\r
- int p = (cell + 1) / 2 - 1;\r
- if (comparer.Compare(item, heap[p].last) > 0)\r
- {\r
- Handle thehandle = heap[cell].firsthandle;\r
- updateFirst(cell, heap[p].last, heap[p].lasthandle);\r
- updateLast(p, item, thehandle);\r
- bubbleUpMax(p);\r
- }\r
- else\r
- bubbleUpMin(cell);\r
- }\r
- else if (heapifyMin(cell))\r
- bubbleUpMax(cell);\r
- else\r
- bubbleUpMin(cell);\r
- }\r
- else\r
- {\r
- retval = heap[cell].last;\r
- heap[cell].last = item;\r
- if (heapifyMax(cell))\r
- bubbleUpMin(cell);\r
- else\r
- bubbleUpMax(cell);\r
- }\r
-\r
- raiseItemsRemoved(retval, 1);\r
- raiseItemsAdded(item, 1);\r
- raiseCollectionChanged();\r
-\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Find the current least item of this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the item.</param>\r
- /// <returns>The least item.</returns>\r
- public T FindMin(out IPriorityQueueHandle<T> handle)\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- handle = heap[0].firsthandle;\r
-\r
- return heap[0].first;\r
- }\r
-\r
- /// <summary>\r
- /// Find the current largest item of this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the item.</param>\r
- /// <returns>The largest item.</returns>\r
- public T FindMax(out IPriorityQueueHandle<T> handle)\r
- {\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- else if (size == 1)\r
- {\r
- handle = heap[0].firsthandle;\r
- return heap[0].first;\r
- }\r
- else\r
- {\r
- handle = heap[0].lasthandle;\r
- return heap[0].last;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Remove the least item from this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the removed item.</param>\r
- /// <returns>The removed item.</returns>\r
- public T DeleteMin(out IPriorityQueueHandle<T> handle)\r
- {\r
- stamp++;\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- T retval = heap[0].first;\r
- Handle myhandle = heap[0].firsthandle;\r
- handle = myhandle;\r
- if (myhandle != null)\r
- myhandle.index = -1;\r
-\r
- if (size == 1)\r
- {\r
- size = 0;\r
- heap[0].first = default(T);\r
- heap[0].firsthandle = null;\r
- }\r
- else\r
- {\r
- int lastcell = (size - 1) / 2;\r
-\r
- if (size % 2 == 0)\r
- {\r
- updateFirst(0, heap[lastcell].last, heap[lastcell].lasthandle);\r
- heap[lastcell].last = default(T);\r
- heap[lastcell].lasthandle = null;\r
- }\r
- else\r
- {\r
- updateFirst(0, heap[lastcell].first, heap[lastcell].firsthandle);\r
- heap[lastcell].first = default(T);\r
- heap[lastcell].firsthandle = null;\r
- }\r
-\r
- size--;\r
- heapifyMin(0);\r
- }\r
-\r
- raiseItemsRemoved(retval, 1);\r
- raiseCollectionChanged();\r
- return retval;\r
-\r
- }\r
-\r
- /// <summary>\r
- /// Remove the largest item from this priority queue.\r
- /// </summary>\r
- /// <param name="handle">On return: the handle of the removed item.</param>\r
- /// <returns>The removed item.</returns>\r
- public T DeleteMax(out IPriorityQueueHandle<T> handle)\r
- {\r
- stamp++;\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- T retval;\r
- Handle myhandle;\r
-\r
- if (size == 1)\r
- {\r
- size = 0;\r
- retval = heap[0].first;\r
- myhandle = heap[0].firsthandle;\r
- if (myhandle != null)\r
- myhandle.index = -1;\r
- heap[0].first = default(T);\r
- heap[0].firsthandle = null;\r
- }\r
- else\r
- {\r
- retval = heap[0].last;\r
- myhandle = heap[0].lasthandle;\r
- if (myhandle != null)\r
- myhandle.index = -1;\r
-\r
- int lastcell = (size - 1) / 2;\r
-\r
- if (size % 2 == 0)\r
- {\r
- updateLast(0, heap[lastcell].last, heap[lastcell].lasthandle);\r
- heap[lastcell].last = default(T);\r
- heap[lastcell].lasthandle = null;\r
- }\r
- else\r
- {\r
- updateLast(0, heap[lastcell].first, heap[lastcell].firsthandle);\r
- heap[lastcell].first = default(T);\r
- heap[lastcell].firsthandle = null;\r
- }\r
-\r
- size--;\r
- heapifyMax(0);\r
- }\r
- raiseItemsRemoved(retval, 1);\r
- raiseCollectionChanged();\r
- handle = myhandle;\r
- return retval;\r
- }\r
-\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this IntervalHeap.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- IntervalHeap<T> clone = new IntervalHeap<T>(size, comparer, itemequalityComparer);\r
- clone.AddAll(this);\r
- return clone;\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-#define HASHINDEXnot\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A list collection class based on a doubly linked list data structure.\r
- /// </summary>\r
- [Serializable]\r
- public class LinkedList<T> : SequencedBase<T>, IList<T>\r
-#if HASHINDEX\r
-#else\r
-, IStack<T>, IQueue<T>\r
-#endif\r
- {\r
- #region Fields\r
- /// <summary>\r
- /// IExtensible.Add(T) always does AddLast(T), fIFO determines \r
- /// if T Remove() does RemoveFirst() or RemoveLast()\r
- /// </summary>\r
- bool fIFO = true;\r
-\r
- #region Events\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override EventTypeEnum ListenableEvents { get { return underlying == null ? EventTypeEnum.All : EventTypeEnum.None; } }\r
-\r
- #endregion\r
-\r
- //Invariant: startsentinel != null && endsentinel != null\r
- //If size==0: startsentinel.next == endsentinel && endsentinel.prev == startsentinel\r
- //Else: startsentinel.next == First && endsentinel.prev == Last)\r
- /// <summary>\r
- /// Node to the left of first node \r
- /// </summary>\r
- Node startsentinel;\r
- /// <summary>\r
- /// Node to the right of last node\r
- /// </summary>\r
- Node endsentinel;\r
- /// <summary>\r
- /// Offset of this view in underlying list\r
- /// </summary>\r
-#if HASHINDEX\r
- int? offset;\r
-#else\r
- int offset;\r
-#endif\r
-\r
- /// <summary>\r
- /// underlying list of this view (or null for the underlying list)\r
- /// </summary>\r
- LinkedList<T> underlying;\r
-\r
- //Note: all views will have the same views list since all view objects are created by MemeberwiseClone()\r
- WeakViewList<LinkedList<T>> views;\r
- WeakViewList<LinkedList<T>>.Node myWeakReference;\r
-\r
- /// <summary>\r
- /// Has this list or view not been invalidated by some operation (by someone calling Dispose())\r
- /// </summary>\r
- bool isValid = true;\r
-\r
-\r
-#if HASHINDEX\r
- HashDictionary<T, Node> dict;\r
- /// <summary>\r
- /// Number of taggroups\r
- /// </summary>\r
- int taggroups;\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- int Taggroups\r
- {\r
- get { return underlying == null ? taggroups : underlying.taggroups; }\r
- set { if (underlying == null) taggroups = value; else underlying.taggroups = value; }\r
- }\r
-#endif\r
-\r
- #endregion\r
-\r
- #region Util\r
-\r
- bool equals(T i1, T i2) { return itemequalityComparer.Equals(i1, i2); }\r
-\r
- #region Check utilities\r
- /// <summary>\r
- /// Check if it is valid to perform updates and increment stamp of \r
- /// underlying if this is a view.\r
- /// <para>This method should be called in every public modifying \r
- /// methods before any modifications are performed.\r
- /// </para>\r
- /// </summary>\r
- /// <exception cref="InvalidOperationException"> if check fails.</exception>\r
- protected override void updatecheck()\r
- {\r
- validitycheck();\r
- base.updatecheck();\r
- if (underlying != null)\r
- underlying.stamp++;\r
- }\r
-\r
- /// <summary>\r
- /// Check if we are a view that the underlyinglist has only been updated through us.\r
- /// <br/>\r
- /// This method should be called from enumerators etc to guard against \r
- /// modification of the base collection.\r
- /// </summary>\r
- /// <exception cref="InvalidOperationException"> if check fails.</exception>\r
- void validitycheck()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException();\r
- }\r
-\r
- /// <summary>\r
- /// Check that the list has not been updated since a particular time.\r
- /// </summary>\r
- /// <param name="stamp">The stamp indicating the time.</param>\r
- /// <exception cref="CollectionModifiedException"> if check fails.</exception>\r
- protected override void modifycheck(int stamp)\r
- {\r
- validitycheck();\r
- if ((underlying != null ? underlying.stamp : this.stamp) != stamp)\r
- throw new CollectionModifiedException();\r
- }\r
- #endregion\r
-\r
- #region Searching\r
- bool contains(T item, out Node node)\r
- {\r
-#if HASHINDEX\r
- if (dict.Find(item, out node))\r
- return insideview(node);\r
-#else\r
- //TODO: search from both ends? Or search from the end selected by FIFO?\r
- node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- if (equals(item, node.item))\r
- return true;\r
- node = node.next;\r
- }\r
-#endif\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Search forwards from a node for a node with a particular item.\r
- /// </summary>\r
- /// <param name="item">The item to look for</param>\r
- /// <param name="node">On input, the node to start at. If item was found, the node found on output.</param>\r
- /// <param name="index">If node was found, the value will be the number of links followed higher than \r
- /// the value on input. If item was not found, the value on output is undefined.</param>\r
- /// <returns>True if node was found.</returns>\r
- bool find(T item, ref Node node, ref int index)\r
- {\r
- while (node != endsentinel)\r
- {\r
- //if (item.Equals(node.item))\r
- if (itemequalityComparer.Equals(item, node.item))\r
- return true;\r
-\r
- index++;\r
- node = node.next;\r
- }\r
-\r
- return false;\r
- }\r
-\r
- bool dnif(T item, ref Node node, ref int index)\r
- {\r
- while (node != startsentinel)\r
- {\r
- //if (item.Equals(node.item))\r
- if (itemequalityComparer.Equals(item, node.item))\r
- return true;\r
-\r
- index--;\r
- node = node.prev;\r
- }\r
-\r
- return false;\r
- }\r
-\r
-#if HASHINDEX\r
- bool insideview(Node node)\r
- {\r
- if (underlying == null)\r
- return true;\r
- return (startsentinel.precedes(node) && node.precedes(endsentinel));\r
- }\r
-#endif\r
-\r
- #endregion\r
-\r
- #region Indexing\r
- /// <summary>\r
- /// Return the node at position pos\r
- /// </summary>\r
- /// <param name="pos"></param>\r
- /// <returns></returns>\r
- Node get(int pos)\r
- {\r
- if (pos < 0 || pos >= size)\r
- throw new IndexOutOfRangeException();\r
- else if (pos < size / 2)\r
- { // Closer to front\r
- Node node = startsentinel;\r
-\r
- for (int i = 0; i <= pos; i++)\r
- node = node.next;\r
-\r
- return node;\r
- }\r
- else\r
- { // Closer to end\r
- Node node = endsentinel;\r
-\r
- for (int i = size; i > pos; i--)\r
- node = node.prev;\r
-\r
- return node;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Find the distance from pos to the set given by positions. Return the\r
- /// signed distance as return value and as an out parameter, the\r
- /// array index of the nearest position. This is used for up to length 5 of\r
- /// positions, and we do not assume it is sorted. \r
- /// </summary>\r
- /// <param name="pos"></param>\r
- /// <param name="positions"></param>\r
- /// <param name="nearest"></param>\r
- /// <returns></returns>\r
- int dist(int pos, out int nearest, int[] positions)\r
- {\r
- nearest = -1;\r
- int bestdist = int.MaxValue;\r
- int signeddist = bestdist;\r
- for (int i = 0; i < positions.Length; i++)\r
- {\r
- int thisdist = positions[i] - pos;\r
- if (thisdist >= 0 && thisdist < bestdist) { nearest = i; bestdist = thisdist; signeddist = thisdist; }\r
- if (thisdist < 0 && -thisdist < bestdist) { nearest = i; bestdist = -thisdist; signeddist = thisdist; }\r
- }\r
- return signeddist;\r
- }\r
-\r
- /// <summary>\r
- /// Find the node at position pos, given known positions of several nodes.\r
- /// </summary>\r
- /// <param name="pos"></param>\r
- /// <param name="positions"></param>\r
- /// <param name="nodes"></param>\r
- /// <returns></returns>\r
- Node get(int pos, int[] positions, Node[] nodes)\r
- {\r
- int nearest;\r
- int delta = dist(pos, out nearest, positions);\r
- Node node = nodes[nearest];\r
- if (delta > 0)\r
- for (int i = 0; i < delta; i++)\r
- node = node.prev;\r
- else\r
- for (int i = 0; i > delta; i--)\r
- node = node.next;\r
- return node;\r
- }\r
-\r
- /// <summary>\r
- /// Get nodes at positions p1 and p2, given nodes at several positions.\r
- /// </summary>\r
- /// <param name="p1"></param>\r
- /// <param name="p2"></param>\r
- /// <param name="n1"></param>\r
- /// <param name="n2"></param>\r
- /// <param name="positions"></param>\r
- /// <param name="nodes"></param>\r
- void getPair(int p1, int p2, out Node n1, out Node n2, int[] positions, Node[] nodes)\r
- {\r
- int nearest1, nearest2;\r
- int delta1 = dist(p1, out nearest1, positions), d1 = delta1 < 0 ? -delta1 : delta1;\r
- int delta2 = dist(p2, out nearest2, positions), d2 = delta2 < 0 ? -delta2 : delta2;\r
-\r
- if (d1 < d2)\r
- {\r
- n1 = get(p1, positions, nodes);\r
- n2 = get(p2, new int[] { positions[nearest2], p1 }, new Node[] { nodes[nearest2], n1 });\r
- }\r
- else\r
- {\r
- n2 = get(p2, positions, nodes);\r
- n1 = get(p1, new int[] { positions[nearest1], p2 }, new Node[] { nodes[nearest1], n2 });\r
- }\r
- }\r
- #endregion\r
-\r
- #region Insertion\r
-#if HASHINDEX\r
- void insert(int index, Node succ, T item)\r
- {\r
- Node newnode = new Node(item);\r
- if (dict.FindOrAdd(item, ref newnode))\r
- throw new DuplicateNotAllowedException("Item already in indexed list");\r
- insertNode(true, succ, newnode);\r
- }\r
-\r
- /// <summary>\r
- /// Insert a Node before another one. Unchecked version. \r
- /// </summary>\r
- /// <param name="succ">The successor to be</param>\r
- /// <param name="newnode">Node to insert</param>\r
- /// <param name="updateViews">update overlapping view in this call</param>\r
- void insertNode(bool updateViews, Node succ, Node newnode)\r
- {\r
- newnode.next = succ;\r
- Node pred = newnode.prev = succ.prev;\r
- succ.prev.next = newnode;\r
- succ.prev = newnode;\r
- size++;\r
- if (underlying != null)\r
- underlying.size++;\r
- settag(newnode);\r
- if (updateViews)\r
- fixViewsAfterInsert(succ, pred, 1, 0);\r
- }\r
-#else\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="index">The index in this view</param>\r
- /// <param name="succ"></param>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- Node insert(int index, Node succ, T item)\r
- {\r
- Node newnode = new Node(item, succ.prev, succ);\r
- succ.prev.next = newnode;\r
- succ.prev = newnode;\r
- size++;\r
- if (underlying != null)\r
- underlying.size++;\r
- fixViewsAfterInsert(succ, newnode.prev, 1, Offset + index);\r
- return newnode;\r
- }\r
-#endif\r
- #endregion\r
-\r
- #region Removal\r
- T remove(Node node, int index)\r
- {\r
- fixViewsBeforeSingleRemove(node, Offset + index);\r
- node.prev.next = node.next;\r
- node.next.prev = node.prev;\r
- size--;\r
- if (underlying != null)\r
- underlying.size--;\r
-#if HASHINDEX\r
- removefromtaggroup(node);\r
-#endif\r
- return node.item;\r
- }\r
-\r
-#if HASHINDEX\r
- private bool dictremove(T item, out Node node)\r
- {\r
- if (underlying == null)\r
- {\r
- if (!dict.Remove(item, out node))\r
- return false;\r
- }\r
- else\r
- {\r
- //We cannot avoid calling dict twice - have to intersperse the listorder test!\r
- if (!contains(item, out node))\r
- return false;\r
- dict.Remove(item);\r
- }\r
- return true;\r
- }\r
-#endif\r
- #endregion\r
-\r
- #region fixView utilities\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="added">The actual number of inserted nodes</param>\r
- /// <param name="pred">The predecessor of the inserted nodes</param>\r
- /// <param name="succ">The successor of the added nodes</param>\r
- /// <param name="realInsertionIndex"></param>\r
- void fixViewsAfterInsert(Node succ, Node pred, int added, int realInsertionIndex)\r
- {\r
- if (views != null)\r
- foreach (LinkedList<T> view in views)\r
- {\r
- if (view != this)\r
- {\r
-#if HASHINDEX\r
- if (pred.precedes(view.startsentinel) || (view.startsentinel == pred && view.size > 0))\r
- view.offset += added;\r
- if (view.startsentinel.precedes(pred) && succ.precedes(view.endsentinel))\r
- view.size += added;\r
- if (view.startsentinel == pred && view.size > 0)\r
- view.startsentinel = succ.prev;\r
- if (view.endsentinel == succ)\r
- view.endsentinel = pred.next;\r
-#else\r
- if (view.Offset == realInsertionIndex && view.size > 0)\r
- view.startsentinel = succ.prev;\r
- if (view.Offset + view.size == realInsertionIndex)\r
- view.endsentinel = pred.next;\r
- if (view.Offset < realInsertionIndex && view.Offset + view.size > realInsertionIndex)\r
- view.size += added;\r
- if (view.Offset > realInsertionIndex || (view.Offset == realInsertionIndex && view.size > 0))\r
- view.offset += added;\r
-#endif\r
- }\r
- }\r
- }\r
-\r
- void fixViewsBeforeSingleRemove(Node node, int realRemovalIndex)\r
- {\r
- if (views != null)\r
- foreach (LinkedList<T> view in views)\r
- {\r
- if (view != this)\r
- {\r
-#if HASHINDEX\r
- if (view.startsentinel.precedes(node) && node.precedes(view.endsentinel))\r
- view.size--;\r
- if (!view.startsentinel.precedes(node))\r
- view.offset--;\r
- if (view.startsentinel == node)\r
- view.startsentinel = node.prev;\r
- if (view.endsentinel == node)\r
- view.endsentinel = node.next;\r
-#else\r
- if (view.offset - 1 == realRemovalIndex)\r
- view.startsentinel = node.prev;\r
- if (view.offset + view.size == realRemovalIndex)\r
- view.endsentinel = node.next;\r
- if (view.offset <= realRemovalIndex && view.offset + view.size > realRemovalIndex)\r
- view.size--;\r
- if (view.offset > realRemovalIndex)\r
- view.offset--;\r
-#endif\r
- }\r
- }\r
- }\r
-\r
-#if HASHINDEX\r
-#else\r
- void fixViewsBeforeRemove(int start, int count, Node first, Node last)\r
- {\r
- int clearend = start + count - 1;\r
- if (views != null)\r
- foreach (LinkedList<T> view in views)\r
- {\r
- if (view == this)\r
- continue;\r
- int viewoffset = view.Offset, viewend = viewoffset + view.size - 1;\r
- //sentinels\r
- if (start < viewoffset && viewoffset - 1 <= clearend)\r
- view.startsentinel = first.prev;\r
- if (start <= viewend + 1 && viewend < clearend)\r
- view.endsentinel = last.next;\r
- //offsets and sizes\r
- if (start < viewoffset)\r
- {\r
- if (clearend < viewoffset)\r
- view.offset = viewoffset - count;\r
- else\r
- {\r
- view.offset = start;\r
- view.size = clearend < viewend ? viewend - clearend : 0;\r
- }\r
- }\r
- else if (start <= viewend)\r
- view.size = clearend <= viewend ? view.size - count : start - viewoffset;\r
- }\r
- }\r
-#endif\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="otherView"></param>\r
- /// <returns>The position of View(otherOffset, otherSize) wrt. this view</returns>\r
- MutualViewPosition viewPosition(LinkedList<T> otherView)\r
- {\r
-#if HASHINDEX\r
- Node otherstartsentinel = otherView.startsentinel, otherendsentinel = otherView.endsentinel,\r
- first = startsentinel.next, last = endsentinel.prev,\r
- otherfirst = otherstartsentinel.next, otherlast = otherendsentinel.prev;\r
- if (last.precedes(otherfirst) || otherlast.precedes(first))\r
- return MutualViewPosition.NonOverlapping;\r
- if (size == 0 || (otherstartsentinel.precedes(first) && last.precedes(otherendsentinel)))\r
- return MutualViewPosition.Contains;\r
- if (otherView.size == 0 || (startsentinel.precedes(otherfirst) && otherlast.precedes(endsentinel)))\r
- return MutualViewPosition.ContainedIn;\r
- return MutualViewPosition.Overlapping;\r
-#else\r
- int end = offset + size, otherOffset = otherView.offset, otherSize = otherView.size, otherEnd = otherOffset + otherSize;\r
- if (otherOffset >= end || otherEnd <= offset)\r
- return MutualViewPosition.NonOverlapping;\r
- if (size == 0 || (otherOffset <= offset && end <= otherEnd))\r
- return MutualViewPosition.Contains;\r
- if (otherSize == 0 || (offset <= otherOffset && otherEnd <= end))\r
- return MutualViewPosition.ContainedIn;\r
- return MutualViewPosition.Overlapping;\r
-#endif\r
- }\r
-\r
- void disposeOverlappingViews(bool reverse)\r
- {\r
- if (views != null)\r
- {\r
- foreach (LinkedList<T> view in views)\r
- {\r
- if (view != this)\r
- {\r
- switch (viewPosition(view))\r
- {\r
- case MutualViewPosition.ContainedIn:\r
- if (reverse)\r
- { }\r
- else\r
- view.Dispose();\r
- break;\r
- case MutualViewPosition.Overlapping:\r
- view.Dispose();\r
- break;\r
- case MutualViewPosition.Contains:\r
- case MutualViewPosition.NonOverlapping:\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #endregion\r
-\r
- #region Constructors\r
-\r
- /// <summary>\r
- /// Create a linked list with en external item equalityComparer\r
- /// </summary>\r
- /// <param name="itemequalityComparer">The external equalityComparer</param>\r
- public LinkedList(SCG.IEqualityComparer<T> itemequalityComparer)\r
- : base(itemequalityComparer)\r
- {\r
- offset = 0;\r
- size = stamp = 0;\r
- startsentinel = new Node(default(T));\r
- endsentinel = new Node(default(T));\r
- startsentinel.next = endsentinel;\r
- endsentinel.prev = startsentinel;\r
-#if HASHINDEX\r
- //It is important that the sentinels are different:\r
- startsentinel.taggroup = new TagGroup();\r
- startsentinel.taggroup.tag = int.MinValue;\r
- startsentinel.taggroup.count = 0;\r
- endsentinel.taggroup = new TagGroup();\r
- endsentinel.taggroup.tag = int.MaxValue;\r
- endsentinel.taggroup.count = 0;\r
- dict = new HashDictionary<T, Node>(itemequalityComparer);\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// Create a linked list with the natural item equalityComparer\r
- /// </summary>\r
- public LinkedList() : this(EqualityComparer<T>.Default) { }\r
-\r
- #endregion\r
-\r
- #region Node nested class\r
-\r
- /// <summary>\r
- /// An individual cell in the linked list\r
- /// </summary>\r
- [Serializable]\r
- class Node\r
- {\r
- public Node prev;\r
-\r
- public Node next;\r
-\r
- public T item;\r
-\r
- #region Tag support\r
-#if HASHINDEX\r
- internal int tag;\r
-\r
- internal TagGroup taggroup;\r
-\r
- internal bool precedes(Node that)\r
- {\r
- //Debug.Assert(taggroup != null, "taggroup field null");\r
- //Debug.Assert(that.taggroup != null, "that.taggroup field null");\r
- int t1 = taggroup.tag;\r
- int t2 = that.taggroup.tag;\r
-\r
- return t1 < t2 ? true : t1 > t2 ? false : tag < that.tag;\r
- }\r
-#endif\r
- #endregion\r
-\r
- [Tested]\r
- internal Node(T item) { this.item = item; }\r
-\r
- [Tested]\r
- internal Node(T item, Node prev, Node next)\r
- {\r
- this.item = item; this.prev = prev; this.next = next;\r
- }\r
-\r
- public override string ToString()\r
- {\r
-#if HASHINDEX\r
- return String.Format("Node: (item={0}, tag={1})", item, tag);\r
-#else\r
- return String.Format("Node(item={0})", item);\r
-#endif\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region Taggroup nested class and tag maintenance utilities\r
-#if HASHINDEX\r
- /// <summary>\r
- /// A group of nodes with the same high tag. Purpose is to be\r
- /// able to tell the sequence order of two nodes without having to scan through\r
- /// the list.\r
- /// </summary>\r
- [Serializable]\r
- class TagGroup\r
- {\r
- internal int tag, count;\r
-\r
- internal Node first, last;\r
-\r
- /// <summary>\r
- /// Pretty print a tag group\r
- /// </summary>\r
- /// <returns>Formatted tag group</returns>\r
- public override string ToString()\r
- { return String.Format("TagGroup(tag={0}, cnt={1}, fst={2}, lst={3})", tag, count, first, last); }\r
- }\r
-\r
- //Constants for tag maintenance\r
- const int wordsize = 32;\r
-\r
- const int lobits = 3;\r
-\r
- const int hibits = lobits + 1;\r
-\r
- const int losize = 1 << lobits;\r
-\r
- const int hisize = 1 << hibits;\r
-\r
- const int logwordsize = 5;\r
-\r
- TagGroup gettaggroup(Node pred, Node succ, out int lowbound, out int highbound)\r
- {\r
- TagGroup predgroup = pred.taggroup, succgroup = succ.taggroup;\r
-\r
- if (predgroup == succgroup)\r
- {\r
- lowbound = pred.tag + 1;\r
- highbound = succ.tag - 1;\r
- return predgroup;\r
- }\r
- else if (predgroup.first != null)\r
- {\r
- lowbound = pred.tag + 1;\r
- highbound = int.MaxValue;\r
- return predgroup;\r
- }\r
- else if (succgroup.first != null)\r
- {\r
- lowbound = int.MinValue;\r
- highbound = succ.tag - 1;\r
- return succgroup;\r
- }\r
- else\r
- {\r
- lowbound = int.MinValue;\r
- highbound = int.MaxValue;\r
- return new TagGroup();\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Put a tag on a node (already inserted in the list). Split taggroups and renumber as \r
- /// necessary.\r
- /// </summary>\r
- /// <param name="node">The node to tag</param>\r
- void settag(Node node)\r
- {\r
- Node pred = node.prev, succ = node.next;\r
- TagGroup predgroup = pred.taggroup, succgroup = succ.taggroup;\r
-\r
- if (predgroup == succgroup)\r
- {\r
- node.taggroup = predgroup;\r
- predgroup.count++;\r
- if (pred.tag + 1 == succ.tag)\r
- splittaggroup(predgroup);\r
- else\r
- node.tag = (pred.tag + 1) / 2 + (succ.tag - 1) / 2;\r
- }\r
- else if (predgroup.first != null)\r
- {\r
- node.taggroup = predgroup;\r
- predgroup.last = node;\r
- predgroup.count++;\r
- if (pred.tag == int.MaxValue)\r
- splittaggroup(predgroup);\r
- else\r
- node.tag = pred.tag / 2 + int.MaxValue / 2 + 1;\r
- }\r
- else if (succgroup.first != null)\r
- {\r
- node.taggroup = succgroup;\r
- succgroup.first = node;\r
- succgroup.count++;\r
- if (succ.tag == int.MinValue)\r
- splittaggroup(node.taggroup);\r
- else\r
- node.tag = int.MinValue / 2 + (succ.tag - 1) / 2;\r
- }\r
- else\r
- {\r
- Debug.Assert(Taggroups == 0);\r
-\r
- TagGroup newgroup = new TagGroup();\r
-\r
- Taggroups = 1;\r
- node.taggroup = newgroup;\r
- newgroup.first = newgroup.last = node;\r
- newgroup.count = 1;\r
- return;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove a node from its taggroup.\r
- /// <br/> When this is called, node must already have been removed from the underlying list\r
- /// </summary>\r
- /// <param name="node">The node to remove</param>\r
- void removefromtaggroup(Node node)\r
- {\r
- //\r
- TagGroup taggroup = node.taggroup;\r
-\r
- if (--taggroup.count == 0)\r
- {\r
- Taggroups--;\r
- return;\r
- }\r
-\r
- if (node == taggroup.first)\r
- taggroup.first = node.next;\r
-\r
- if (node == taggroup.last)\r
- taggroup.last = node.prev;\r
-\r
- //node.taggroup = null;\r
- if (taggroup.count != losize || Taggroups == 1)\r
- return;\r
-\r
- TagGroup otg;\r
-\r
- if ((otg = taggroup.first.prev.taggroup).count <= losize)\r
- taggroup.first = otg.first;\r
- else if ((otg = taggroup.last.next.taggroup).count <= losize)\r
- taggroup.last = otg.last;\r
- else\r
- return;\r
-\r
- Node n = otg.first;\r
-\r
- for (int i = 0, length = otg.count; i < length; i++)\r
- {\r
- n.taggroup = taggroup;\r
- n = n.next;\r
- }\r
-\r
- taggroup.count += otg.count;\r
- Taggroups--;\r
- n = taggroup.first;\r
-\r
- const int ofs = wordsize - hibits;\r
-\r
- for (int i = 0, count = taggroup.count; i < count; i++)\r
- {\r
- n.tag = (i - losize) << ofs; //(i-8)<<28 \r
- n = n.next;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Split a tag group to make rom for more tags.\r
- /// </summary>\r
- /// <param name="taggroup">The tag group</param>\r
- void splittaggroup(TagGroup taggroup)\r
- {\r
- Node n = taggroup.first;\r
- int ptgt = taggroup.first.prev.taggroup.tag;\r
- int ntgt = taggroup.last.next.taggroup.tag;\r
-\r
- Debug.Assert(ptgt + 1 <= ntgt - 1);\r
-\r
- int ofs = wordsize - hibits;\r
-#warning hack alert was there a -1 here?\r
- int newtgs = taggroup.count / hisize;// - 1;\r
- int tgtdelta = (int)((ntgt + 0.0 - ptgt) / (newtgs + 2)), tgtag = ptgt;\r
-\r
- tgtdelta = tgtdelta == 0 ? 1 : tgtdelta;\r
- for (int j = 0; j < newtgs; j++)\r
- {\r
- TagGroup newtaggroup = new TagGroup();\r
-\r
- newtaggroup.tag = (tgtag = tgtag >= ntgt - tgtdelta ? ntgt : tgtag + tgtdelta);\r
- newtaggroup.first = n;\r
- newtaggroup.count = hisize;\r
- for (int i = 0; i < hisize; i++)\r
- {\r
- n.taggroup = newtaggroup;\r
- n.tag = (i - losize) << ofs; //(i-8)<<28 \r
- n = n.next;\r
- }\r
-\r
- newtaggroup.last = n.prev;\r
- }\r
-\r
- int rest = taggroup.count - hisize * newtgs;\r
-\r
- taggroup.first = n;\r
- taggroup.count = rest;\r
- taggroup.tag = (tgtag = tgtag >= ntgt - tgtdelta ? ntgt : tgtag + tgtdelta); ofs--;\r
- for (int i = 0; i < rest; i++)\r
- {\r
- n.tag = (i - hisize) << ofs; //(i-16)<<27 \r
- n = n.next;\r
- }\r
-\r
- taggroup.last = n.prev;\r
- Taggroups += newtgs;\r
- if (tgtag == ntgt)\r
- redistributetaggroups(taggroup);\r
- }\r
-\r
-\r
- private void redistributetaggroups(TagGroup taggroup)\r
- {\r
- TagGroup pred = taggroup, succ = taggroup, tmp;\r
- double limit = 1, bigt = Math.Pow(Taggroups, 1.0 / 30);//?????\r
- int bits = 1, count = 1, lowmask = 0, himask = 0, target = 0;\r
-\r
- do\r
- {\r
- bits++;\r
- lowmask = (1 << bits) - 1;\r
- himask = ~lowmask;\r
- target = taggroup.tag & himask;\r
- while ((tmp = pred.first.prev.taggroup).first != null && (tmp.tag & himask) == target)\r
- { count++; pred = tmp; }\r
-\r
- while ((tmp = succ.last.next.taggroup).last != null && (tmp.tag & himask) == target)\r
- { count++; succ = tmp; }\r
-\r
- limit *= bigt;\r
- } while (count > limit);\r
-\r
- //redistibute tags\r
- int lob = pred.first.prev.taggroup.tag, upb = succ.last.next.taggroup.tag;\r
- int delta = upb / (count + 1) - lob / (count + 1);\r
-\r
- Debug.Assert(delta > 0);\r
- for (int i = 0; i < count; i++)\r
- {\r
- pred.tag = lob + (i + 1) * delta;\r
- pred = pred.last.next.taggroup;\r
- }\r
- }\r
-#endif\r
-\r
- #endregion\r
-\r
- #region Position, PositionComparer and ViewHandler nested types\r
- class PositionComparer : SCG.IComparer<Position>\r
- {\r
- static PositionComparer _default;\r
- PositionComparer() { }\r
- public static PositionComparer Default { get { return _default ?? (_default = new PositionComparer()); } }\r
- public int Compare(Position a, Position b)\r
- {\r
-#if HASHINDEX\r
- return a.Endpoint == b.Endpoint ? 0 : a.Endpoint.precedes(b.Endpoint) ? -1 : 1;\r
-#else\r
- return a.Index.CompareTo(b.Index);\r
-#endif\r
- }\r
- }\r
- /// <summary>\r
- /// During RemoveAll, we need to cache the original endpoint indices of views\r
- /// </summary>\r
- struct Position\r
- {\r
- public readonly LinkedList<T> View;\r
- public bool Left;\r
-#if HASHINDEX\r
- public readonly Node Endpoint;\r
-#else\r
- public readonly int Index;\r
-#endif\r
- public Position(LinkedList<T> view, bool left)\r
- {\r
- View = view;\r
- Left = left;\r
-#if HASHINDEX\r
- Endpoint = left ? view.startsentinel.next : view.endsentinel.prev;\r
-#else\r
- Index = left ? view.Offset : view.Offset + view.size - 1;\r
-#endif\r
- }\r
-#if HASHINDEX\r
- public Position(Node node, int foo) { this.Endpoint = node; View = null; Left = false;}\r
-#else\r
- public Position(int index) { this.Index = index; View = null; Left = false; }\r
-#endif\r
- }\r
-\r
- //TODO: merge the two implementations using Position values as arguments\r
- /// <summary>\r
- /// Handle the update of (other) views during a multi-remove operation.\r
- /// </summary>\r
- struct ViewHandler\r
- {\r
- ArrayList<Position> leftEnds;\r
- ArrayList<Position> rightEnds;\r
- int leftEndIndex, rightEndIndex, leftEndIndex2, rightEndIndex2;\r
- internal readonly int viewCount;\r
- internal ViewHandler(LinkedList<T> list)\r
- {\r
- leftEndIndex = rightEndIndex = leftEndIndex2 = rightEndIndex2 = viewCount = 0;\r
- leftEnds = rightEnds = null;\r
- if (list.views != null)\r
- foreach (LinkedList<T> v in list.views)\r
- if (v != list)\r
- {\r
- if (leftEnds == null)\r
- {\r
- leftEnds = new ArrayList<Position>();\r
- rightEnds = new ArrayList<Position>();\r
- }\r
- leftEnds.Add(new Position(v, true));\r
- rightEnds.Add(new Position(v, false));\r
- }\r
- if (leftEnds == null)\r
- return;\r
- viewCount = leftEnds.Count;\r
- leftEnds.Sort(PositionComparer.Default);\r
- rightEnds.Sort(PositionComparer.Default);\r
- }\r
-#if HASHINDEX\r
- internal void skipEndpoints(int removed, Node n)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex < viewCount && ((endpoint = leftEnds[leftEndIndex]).Endpoint.prev.precedes(n)))\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.offset = view.offset - removed;//TODO: extract offset.Value?\r
- view.size += removed;\r
- leftEndIndex++;\r
- }\r
- while (rightEndIndex < viewCount && (endpoint = rightEnds[rightEndIndex]).Endpoint.precedes(n))\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.size -= removed;\r
- rightEndIndex++;\r
- }\r
- }\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex2 < viewCount && (endpoint = leftEnds[leftEndIndex2]).Endpoint.prev.precedes(n))\r
- leftEndIndex2++;\r
- while (rightEndIndex2 < viewCount && (endpoint = rightEnds[rightEndIndex2]).Endpoint.next.precedes(n))\r
- rightEndIndex2++;\r
- }\r
- }\r
- /// <summary>\r
- /// To be called with n pointing to the right of each node to be removed in a stretch. \r
- /// And at the endsentinel. \r
- /// \r
- /// Update offset of a view whose left endpoint (has not already been handled and) is n or precedes n.\r
- /// I.e. startsentinel precedes n.\r
- /// Also update the size as a prelude to handling the right endpoint.\r
- /// \r
- /// Update size of a view not already handled and whose right endpoint precedes n.\r
- /// </summary>\r
- /// <param name="removed">The number of nodes left of n to be removed</param>\r
- /// <param name="n"></param>\r
- internal void updateViewSizesAndCounts(int removed, Node n)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex < viewCount && ((endpoint = leftEnds[leftEndIndex]).Endpoint.prev.precedes(n)))\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.offset = view.offset - removed; //TODO: fix use of offset\r
- view.size += removed;\r
- leftEndIndex++;\r
- }\r
- while (rightEndIndex < viewCount && (endpoint = rightEnds[rightEndIndex]).Endpoint.precedes(n))\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.size -= removed;\r
- rightEndIndex++;\r
- }\r
- }\r
- }\r
- /// <summary>\r
- /// To be called with n being the first not-to-be-removed node after a (stretch of) node(s) to be removed.\r
- /// \r
- /// It will update the startsentinel of views (that have not been handled before and) \r
- /// whose startsentinel precedes n, i.e. is to be deleted.\r
- /// \r
- /// It will update the endsentinel of views (...) whose endsentinel precedes n, i.e. is to be deleted.\r
- /// \r
- /// PROBLEM: DOESNT WORK AS ORIGINALLY ADVERTISED. WE MUST DO THIS BEFORE WE ACTUALLY REMOVE THE NODES. WHEN THE \r
- /// NODES HAVE BEEN REMOVED, THE precedes METHOD WILL NOT WORK!\r
- /// </summary>\r
- /// <param name="n"></param>\r
- /// <param name="newstart"></param>\r
- /// <param name="newend"></param>\r
- internal void updateSentinels(Node n, Node newstart, Node newend)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex2 < viewCount && (endpoint = leftEnds[leftEndIndex2]).Endpoint.prev.precedes(n))\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.startsentinel = newstart;\r
- leftEndIndex2++;\r
- }\r
- while (rightEndIndex2 < viewCount && (endpoint = rightEnds[rightEndIndex2]).Endpoint.next.precedes(n))\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.endsentinel = newend;\r
- rightEndIndex2++;\r
- }\r
- }\r
- }\r
-#else\r
- /// <summary>\r
- /// This is to be called with realindex pointing to the first node to be removed after a (stretch of) node that was not removed\r
- /// </summary>\r
- /// <param name="removed"></param>\r
- /// <param name="realindex"></param>\r
- internal void skipEndpoints(int removed, int realindex)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex < viewCount && (endpoint = leftEnds[leftEndIndex]).Index <= realindex)\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.offset = view.offset - removed;\r
- view.size += removed;\r
- leftEndIndex++;\r
- }\r
- while (rightEndIndex < viewCount && (endpoint = rightEnds[rightEndIndex]).Index < realindex)\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.size -= removed;\r
- rightEndIndex++;\r
- }\r
- }\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex2 < viewCount && (endpoint = leftEnds[leftEndIndex2]).Index <= realindex)\r
- leftEndIndex2++;\r
- while (rightEndIndex2 < viewCount && (endpoint = rightEnds[rightEndIndex2]).Index < realindex - 1)\r
- rightEndIndex2++;\r
- }\r
- }\r
- internal void updateViewSizesAndCounts(int removed, int realindex)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex < viewCount && (endpoint = leftEnds[leftEndIndex]).Index <= realindex)\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.offset = view.Offset - removed;\r
- view.size += removed;\r
- leftEndIndex++;\r
- }\r
- while (rightEndIndex < viewCount && (endpoint = rightEnds[rightEndIndex]).Index < realindex)\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.size -= removed;\r
- rightEndIndex++;\r
- }\r
- }\r
- }\r
- internal void updateSentinels(int realindex, Node newstart, Node newend)\r
- {\r
- if (viewCount > 0)\r
- {\r
- Position endpoint;\r
- while (leftEndIndex2 < viewCount && (endpoint = leftEnds[leftEndIndex2]).Index <= realindex)\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.startsentinel = newstart;\r
- leftEndIndex2++;\r
- }\r
- while (rightEndIndex2 < viewCount && (endpoint = rightEnds[rightEndIndex2]).Index < realindex - 1)\r
- {\r
- LinkedList<T> view = endpoint.View;\r
- view.endsentinel = newend;\r
- rightEndIndex2++;\r
- }\r
- }\r
- }\r
-#endif\r
- }\r
- #endregion\r
-\r
- #region Range nested class\r
-\r
- class Range : DirectedCollectionValueBase<T>, IDirectedCollectionValue<T>\r
- {\r
- int start, count, rangestamp;\r
- Node startnode, endnode;\r
-\r
- LinkedList<T> list;\r
-\r
- bool forwards;\r
-\r
-\r
- internal Range(LinkedList<T> list, int start, int count, bool forwards)\r
- {\r
- this.list = list; this.rangestamp = list.underlying != null ? list.underlying.stamp : list.stamp;\r
- this.start = start; this.count = count; this.forwards = forwards;\r
- if (count > 0)\r
- {\r
- startnode = list.get(start);\r
- endnode = list.get(start + count - 1);\r
- }\r
- }\r
-\r
- public override bool IsEmpty { get { list.modifycheck(rangestamp); return count == 0; } }\r
-\r
- [Tested]\r
- public override int Count { [Tested]get { list.modifycheck(rangestamp); return count; } }\r
-\r
-\r
- public override Speed CountSpeed { get { list.modifycheck(rangestamp); return Speed.Constant; } }\r
-\r
-\r
- public override T Choose()\r
- {\r
- list.modifycheck(rangestamp);\r
- if (count > 0) return startnode.item;\r
- throw new NoSuchItemException();\r
- }\r
-\r
-\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- int togo = count;\r
-\r
- list.modifycheck(rangestamp);\r
- if (togo == 0)\r
- yield break;\r
-\r
- Node cursor = forwards ? startnode : endnode;\r
-\r
- yield return cursor.item;\r
- while (--togo > 0)\r
- {\r
- cursor = forwards ? cursor.next : cursor.prev;\r
- list.modifycheck(rangestamp);\r
- yield return cursor.item;\r
- }\r
- }\r
-\r
-\r
- [Tested]\r
- public override IDirectedCollectionValue<T> Backwards()\r
- {\r
- list.modifycheck(rangestamp);\r
-\r
- Range b = (Range)MemberwiseClone();\r
-\r
- b.forwards = !forwards;\r
- return b;\r
- }\r
-\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return Backwards(); }\r
-\r
-\r
- [Tested]\r
- public override EnumerationDirection Direction\r
- {\r
- [Tested]\r
- get\r
- { return forwards ? EnumerationDirection.Forwards : EnumerationDirection.Backwards; }\r
- }\r
- }\r
-\r
-\r
- #endregion\r
-\r
- #region IDisposable Members\r
-\r
- /// <summary>\r
- /// Invalidate this list. If a view, just invalidate the view. \r
- /// If not a view, invalidate the list and all views on it.\r
- /// </summary>\r
- public virtual void Dispose()\r
- {\r
- Dispose(false);\r
- }\r
-\r
- void Dispose(bool disposingUnderlying)\r
- {\r
- if (isValid)\r
- {\r
- if (underlying != null)\r
- {\r
- isValid = false;\r
- if (!disposingUnderlying)\r
- views.Remove(myWeakReference);\r
- endsentinel = null;\r
- startsentinel = null;\r
- underlying = null;\r
- views = null;\r
- myWeakReference = null;\r
- }\r
- else\r
- {\r
- //isValid = false;\r
- //endsentinel = null;\r
- //startsentinel = null;\r
- foreach (LinkedList<T> view in views)\r
- view.Dispose(true);\r
- //views = null;\r
- Clear();\r
- }\r
- }\r
- }\r
-\r
- #endregion IDisposable stuff\r
-\r
- #region IList<T> Members\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <value>The first item in this list.</value>\r
- [Tested]\r
- public virtual T First\r
- {\r
- [Tested]\r
- get\r
- {\r
- validitycheck();\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- return startsentinel.next.item;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if this list is empty.</exception>\r
- /// <value>The last item in this list.</value>\r
- [Tested]\r
- public virtual T Last\r
- {\r
- [Tested]\r
- get\r
- {\r
- validitycheck();\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- return endsentinel.prev.item;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Since <code>Add(T item)</code> always add at the end of the list,\r
- /// this describes if list has FIFO or LIFO semantics.\r
- /// </summary>\r
- /// <value>True if the <code>Remove()</code> operation removes from the\r
- /// start of the list, false if it removes from the end. THe default for a new linked list is true.</value>\r
- [Tested]\r
- public virtual bool FIFO\r
- {\r
- [Tested]\r
- get { validitycheck(); return fIFO; }\r
- [Tested]\r
- set { updatecheck(); fIFO = value; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- public virtual bool IsFixedSize\r
- {\r
- get { validitycheck(); return false; }\r
- }\r
-\r
- /// <summary>\r
- /// On this list, this indexer is read/write.\r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// >= the size of the collection.\r
- /// </summary>\r
- /// <value>The i'th item of this list.</value>\r
- /// <param name="index">The index of the item to fetch or store.</param>\r
- [Tested]\r
- public virtual T this[int index]\r
- {\r
- [Tested]\r
- get { validitycheck(); return get(index).item; }\r
- [Tested]\r
- set\r
- {\r
- updatecheck();\r
- Node n = get(index);\r
- //\r
- T item = n.item;\r
-#if HASHINDEX\r
-\r
- if (itemequalityComparer.Equals(value, item))\r
- {\r
- n.item = value;\r
- dict.Update(value, n);\r
- }\r
- else if (!dict.FindOrAdd(value, ref n))\r
- {\r
- dict.Remove(item);\r
- n.item = value;\r
- }\r
- else\r
- throw new ArgumentException("Item already in indexed list");\r
-#else\r
- n.item = value;\r
-#endif\r
- (underlying ?? this).raiseForSetThis(index, value, item);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual Speed IndexingSpeed { get { return Speed.Linear; } }\r
-\r
- /// <summary>\r
- /// Insert an item at a specific index location in this list. \r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// > the size of the collection.</summary>\r
- /// <param name="i">The index at which to insert.</param>\r
- /// <param name="item">The item to insert.</param>\r
- [Tested]\r
- public virtual void Insert(int i, T item)\r
- {\r
- updatecheck();\r
- insert(i, i == size ? endsentinel : get(i), item);\r
- if (ActiveEvents != EventTypeEnum.None)\r
- (underlying ?? this).raiseForInsert(i + Offset, item);\r
- }\r
-\r
- /// <summary>\r
- /// Insert an item at the end of a compatible view, used as a pointer.\r
- /// <para>The <code>pointer</code> must be a view on the same list as\r
- /// <code>this</code> and the endpoitn of <code>pointer</code> must be\r
- /// a valid insertion point of <code>this</code></para>\r
- /// </summary>\r
- /// <exception cref="IncompatibleViewException">If <code>pointer</code> \r
- /// is not a view on the same list as <code>this</code></exception>\r
- /// <exception cref="IndexOutOfRangeException"><b>??????</b> if the endpoint of \r
- /// <code>pointer</code> is not inside <code>this</code></exception>\r
- /// <exception cref="DuplicateNotAllowedException"> if the list has\r
- /// <code>AllowsDuplicates==false</code> and the item is \r
- /// already in the list.</exception>\r
- /// <param name="pointer"></param>\r
- /// <param name="item"></param>\r
- public void Insert(IList<T> pointer, T item)\r
- {\r
- updatecheck();\r
- if ((pointer == null) || ((pointer.Underlying ?? pointer) != (underlying ?? this)))\r
- throw new IncompatibleViewException();\r
-#warning INEFFICIENT\r
- //TODO: make this efficient (the whole point of the method:\r
- //Do NOT use Insert, but insert the node at pointer.endsentinel, checking\r
- //via the ordering that this is a valid insertion point\r
- Insert(pointer.Offset + pointer.Count - Offset, item);\r
- }\r
-\r
- /// <summary>\r
- /// Insert into this list all items from an enumerable collection starting \r
- /// at a particular index.\r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// > the size of the collection.\r
- /// </summary>\r
- /// <param name="i">Index to start inserting at</param>\r
- /// <param name="items">Items to insert</param>\r
- /// <typeparam name="U"></typeparam>\r
- [Tested]\r
- public virtual void InsertAll<U>(int i, SCG.IEnumerable<U> items) where U : T\r
- {\r
- insertAll(i, items, true);\r
- }\r
-\r
- void insertAll<U>(int i, SCG.IEnumerable<U> items, bool insertion) where U : T\r
- {\r
- updatecheck();\r
- Node succ, node, pred;\r
- int count = 0;\r
- succ = i == size ? endsentinel : get(i);\r
- pred = node = succ.prev;\r
-#if HASHINDEX\r
- TagGroup taggroup = null;\r
- int taglimit = 0, thetag = 0;\r
- taggroup = gettaggroup(node, succ, out thetag, out taglimit);\r
- try\r
- {\r
- foreach (T item in items)\r
- {\r
- Node tmp = new Node(item, node, null);\r
- if (!dict.FindOrAdd(item, ref tmp))\r
- {\r
- tmp.tag = thetag < taglimit ? ++thetag : thetag;\r
- tmp.taggroup = taggroup;\r
- node.next = tmp;\r
- count++;\r
- node = tmp;\r
- }\r
- else\r
- throw new DuplicateNotAllowedException("Item already in indexed list");\r
- }\r
- }\r
- finally\r
- {\r
- taggroup.count += count;\r
- taggroup.first = succ.prev;\r
- taggroup.last = node;\r
- succ.prev = node;\r
- node.next = succ;\r
- if (node.tag == node.prev.tag)\r
- splittaggroup(taggroup);\r
- size += count;\r
- if (underlying != null)\r
- underlying.size += count;\r
- if (count > 0)\r
- {\r
- fixViewsAfterInsert(succ, pred, count, 0);\r
- raiseForInsertAll(pred, i, count, insertion);\r
- }\r
- }\r
-#else\r
- foreach (T item in items)\r
- {\r
- Node tmp = new Node(item, node, null);\r
- node.next = tmp;\r
- count++;\r
- node = tmp;\r
- }\r
- if (count == 0)\r
- return;\r
- succ.prev = node;\r
- node.next = succ;\r
- size += count;\r
- if (underlying != null)\r
- underlying.size += count;\r
- if (count > 0)\r
- {\r
- fixViewsAfterInsert(succ, pred, count, offset + i);\r
- raiseForInsertAll(pred, i, count, insertion);\r
- }\r
-#endif\r
- }\r
-\r
- private void raiseForInsertAll(Node node, int i, int added, bool insertion)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- int index = Offset + i;\r
- if ((ActiveEvents & (EventTypeEnum.Added | EventTypeEnum.Inserted)) != 0)\r
- for (int j = index; j < index + added; j++)\r
- {\r
-#warning must we check stamps here?\r
- node = node.next;\r
- T item = node.item;\r
- if (insertion) raiseItemInserted(item, j);\r
- raiseItemsAdded(item, 1);\r
- }\r
- raiseCollectionChanged();\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Insert an item at the front of this list.\r
- /// </summary>\r
- /// <param name="item">The item to insert.</param>\r
- [Tested]\r
- public virtual void InsertFirst(T item)\r
- {\r
- updatecheck();\r
- insert(0, startsentinel.next, item);\r
- if (ActiveEvents != EventTypeEnum.None)\r
- (underlying ?? this).raiseForInsert(0 + Offset, item);\r
- }\r
-\r
- /// <summary>\r
- /// Insert an item at the back of this list.\r
- /// </summary>\r
- /// <param name="item">The item to insert.</param>\r
- [Tested]\r
- public virtual void InsertLast(T item)\r
- {\r
- updatecheck();\r
- insert(size, endsentinel, item);\r
- if (ActiveEvents != EventTypeEnum.None)\r
- (underlying ?? this).raiseForInsert(size - 1 + Offset, item);\r
- }\r
-\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list.\r
- /// </summary>\r
- /// <param name="mapper">The delegate definging the map.</param>\r
- /// <returns>The new list.</returns>\r
- [Tested]\r
- public IList<V> Map<V>(Fun<T, V> mapper)\r
- {\r
- validitycheck();\r
-\r
- LinkedList<V> retval = new LinkedList<V>();\r
- return map<V>(mapper, retval);\r
- }\r
-\r
- /// <summary>\r
- /// Create a new list consisting of the results of mapping all items of this\r
- /// list. The new list will use a specified equalityComparer for the item type.\r
- /// </summary>\r
- /// <typeparam name="V">The type of items of the new list</typeparam>\r
- /// <param name="mapper">The delegate defining the map.</param>\r
- /// <param name="equalityComparer">The equalityComparer to use for the new list</param>\r
- /// <returns>The new list.</returns>\r
- public IList<V> Map<V>(Fun<T, V> mapper, SCG.IEqualityComparer<V> equalityComparer)\r
- {\r
- validitycheck();\r
-\r
- LinkedList<V> retval = new LinkedList<V>(equalityComparer);\r
- return map<V>(mapper, retval);\r
- }\r
-\r
- private IList<V> map<V>(Fun<T, V> mapper, LinkedList<V> retval)\r
- {\r
- if (size == 0)\r
- return retval;\r
- int stamp = this.stamp;\r
- Node cursor = startsentinel.next;\r
- LinkedList<V>.Node mcursor = retval.startsentinel;\r
-\r
-#if HASHINDEX\r
- double tagdelta = int.MaxValue / (size + 1.0);\r
- int count = 1;\r
- LinkedList<V>.TagGroup taggroup = null;\r
- taggroup = new LinkedList<V>.TagGroup();\r
- retval.taggroups = 1;\r
- taggroup.count = size;\r
-#endif\r
- while (cursor != endsentinel)\r
- {\r
- V v = mapper(cursor.item);\r
- modifycheck(stamp);\r
- mcursor.next = new LinkedList<V>.Node(v, mcursor, null);\r
- cursor = cursor.next;\r
- mcursor = mcursor.next;\r
-#if HASHINDEX\r
- retval.dict.Add(v, mcursor);\r
- mcursor.taggroup = taggroup;\r
- mcursor.tag = (int)(tagdelta * count++);\r
-#endif\r
- }\r
-\r
- retval.endsentinel.prev = mcursor;\r
- mcursor.next = retval.endsentinel;\r
- retval.size = size;\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Remove one item from the list: from the front if <code>FIFO</code>\r
- /// is true, else from the back.\r
- /// <exception cref="NoSuchItemException"/> if this list is empty.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T Remove()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException("List is empty");\r
- T item = fIFO ? remove(startsentinel.next, 0) : remove(endsentinel.prev, size - 1);\r
-#if HASHINDEX\r
- dict.Remove(item);\r
-#endif\r
- (underlying ?? this).raiseForRemove(item);\r
- return item;\r
- }\r
-\r
- /// <summary>\r
- /// Remove one item from the front of the list.\r
- /// <exception cref="NoSuchItemException"/> if this list is empty.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T RemoveFirst()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException("List is empty");\r
-\r
- T item = remove(startsentinel.next, 0);\r
-#if HASHINDEX\r
- dict.Remove(item);\r
-#endif\r
- if (ActiveEvents != EventTypeEnum.None)\r
- (underlying ?? this).raiseForRemoveAt(Offset, item);\r
- return item;\r
- }\r
-\r
- /// <summary>\r
- /// Remove one item from the back of the list.\r
- /// <exception cref="NoSuchItemException"/> if this list is empty.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T RemoveLast()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException("List is empty");\r
-\r
- T item = remove(endsentinel.prev, size - 1);\r
-#if HASHINDEX\r
- dict.Remove(item);\r
-#endif\r
- if (ActiveEvents != EventTypeEnum.None)\r
- (underlying ?? this).raiseForRemoveAt(size + Offset, item);\r
- return item;\r
- }\r
-\r
- /// <summary>\r
- /// Create a list view on this list. \r
- /// </summary>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the start or count is negative</exception>\r
- /// <exception cref="ArgumentException"> if the range does not fit within list.</exception>\r
- /// <param name="start">The index in this list of the start of the view.</param>\r
- /// <param name="count">The size of the view.</param>\r
- /// <returns>The new list view.</returns>\r
- [Tested]\r
- public virtual IList<T> View(int start, int count)\r
- {\r
- checkRange(start, count);\r
- validitycheck();\r
- if (views == null)\r
- views = new WeakViewList<LinkedList<T>>();\r
- LinkedList<T> retval = (LinkedList<T>)MemberwiseClone();\r
- retval.underlying = underlying != null ? underlying : this;\r
- retval.offset = offset + start;\r
- retval.size = count;\r
- getPair(start - 1, start + count, out retval.startsentinel, out retval.endsentinel,\r
- new int[] { -1, size }, new Node[] { startsentinel, endsentinel });\r
- //retval.startsentinel = start == 0 ? startsentinel : get(start - 1);\r
- //retval.endsentinel = start + count == size ? endsentinel : get(start + count);\r
-\r
- //TODO: for the purpose of Dispose, we need to retain a ref to the node\r
- retval.myWeakReference = views.Add(retval);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Create a list view on this list containing the (first) occurrence of a particular item. \r
- /// </summary>\r
- /// <exception cref="ArgumentException"> if the item is not in this list.</exception>\r
- /// <param name="item">The item to find.</param>\r
- /// <returns>The new list view.</returns>\r
- public virtual IList<T> ViewOf(T item)\r
- {\r
-#if HASHINDEX\r
- Node n;\r
- validitycheck();\r
- if (!contains(item, out n))\r
- return null;\r
- LinkedList<T> retval = (LinkedList<T>)MemberwiseClone();\r
- retval.underlying = underlying != null ? underlying : this;\r
- retval.offset = null;\r
- retval.startsentinel = n.prev;\r
- retval.endsentinel = n.next;\r
- retval.size = 1;\r
- return retval;\r
-#else\r
- int index = 0;\r
- Node n = startsentinel.next;\r
- if (!find(item, ref n, ref index))\r
- return null;\r
- //TODO: optimize with getpair!\r
- return View(index, 1);\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// Create a list view on this list containing the last occurrence of a particular item. \r
- /// <exception cref="ArgumentException"/> if the item is not in this list.\r
- /// </summary>\r
- /// <param name="item">The item to find.</param>\r
- /// <returns>The new list view.</returns>\r
- public virtual IList<T> LastViewOf(T item)\r
- {\r
-#if HASHINDEX\r
- return ViewOf(item);\r
-#else\r
- int index = size - 1;\r
- Node n = endsentinel.prev;\r
- if (!dnif(item, ref n, ref index))\r
- return null;\r
- return View(index, 1);\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// Null if this list is not a view.\r
- /// </summary>\r
- /// <value>Underlying list for view.</value>\r
- [Tested]\r
- public virtual IList<T> Underlying { [Tested]get { validitycheck(); return underlying; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual bool IsValid { get { return isValid; } }\r
-\r
- /// <summary>\r
- /// </summary>\r
- /// <value>Offset for this list view or 0 for a underlying list.</value>\r
- [Tested]\r
- public virtual int Offset\r
- {\r
- [Tested]\r
- get\r
- {\r
- validitycheck();\r
-#if HASHINDEX\r
- if (offset == null && underlying != null)\r
- {\r
- //TODO: search from both ends simultaneously!\r
- Node n = underlying.startsentinel;\r
- int i = 0;\r
- while (n != startsentinel) { n = n.next; i++; }\r
- offset = i;\r
- }\r
-#endif\r
- return (int)offset;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Slide this list view along the underlying list.\r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the operation\r
- /// would bring either end of the view outside the underlying list.</exception>\r
- /// <param name="offset">The signed amount to slide: positive to slide\r
- /// towards the end.</param>\r
- [Tested]\r
- public IList<T> Slide(int offset)\r
- {\r
- if (!TrySlide(offset, size))\r
- throw new ArgumentOutOfRangeException();\r
- return this;\r
- }\r
-\r
- //TODO: more test cases\r
- /// <summary>\r
- /// Slide this list view along the underlying list, perhaps changing its size.\r
- /// </summary>\r
- /// <exception cref="NotAViewException"> if this list is not a view.</exception>\r
- /// <exception cref="ArgumentOutOfRangeException"> if the operation\r
- /// would bring either end of the view outside the underlying list.</exception>\r
- /// <param name="offset">The signed amount to slide: positive to slide\r
- /// towards the end.</param>\r
- /// <param name="size">The new size of the view.</param>\r
- public IList<T> Slide(int offset, int size)\r
- {\r
- if (!TrySlide(offset, size))\r
- throw new ArgumentOutOfRangeException();\r
- return this;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <returns></returns>\r
- public virtual bool TrySlide(int offset) { return TrySlide(offset, size); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="offset"></param>\r
- /// <param name="size"></param>\r
- /// <returns></returns>\r
- public virtual bool TrySlide(int offset, int size)\r
- {\r
- updatecheck();\r
- if (underlying == null)\r
- throw new NotAViewException("List not a view");\r
-\r
-#pragma warning disable 472\r
- if (this.offset == null) //Note: only possible with HASHINDEX\r
-#pragma warning restore 472\r
- {\r
-#pragma warning disable 162\r
- try\r
- {\r
- getPair(offset - 1, offset + size, out startsentinel, out endsentinel,\r
- new int[] { -1, this.size }, new Node[] { startsentinel, endsentinel });\r
- //TODO: maybe-update offset field\r
- }\r
- catch (NullReferenceException)\r
- {\r
- return false;\r
- }\r
-#pragma warning restore 162\r
- }\r
- else\r
- {\r
- if (offset + this.offset < 0 || offset + this.offset + size > underlying.size)\r
- return false;\r
- int oldoffset = (int)(this.offset);\r
- getPair(offset - 1, offset + size, out startsentinel, out endsentinel,\r
- new int[] { -oldoffset - 1, -1, this.size, underlying.size - oldoffset },\r
- new Node[] { underlying.startsentinel, startsentinel, endsentinel, underlying.endsentinel });\r
- }\r
- this.size = size;\r
- this.offset += offset;\r
- return true;\r
- }\r
-\r
-\r
- //TODO: improve the complexity of the implementation\r
- /// <summary>\r
- /// \r
- /// <para>Returns null if <code>otherView</code> is strictly to the left of this view</para>\r
- /// </summary>\r
- /// <param name="otherView"></param>\r
- /// <exception cref="IncompatibleViewException">If otherView does not have the same underlying list as this</exception>\r
- /// <returns></returns>\r
- public virtual IList<T> Span(IList<T> otherView)\r
- {\r
- if ((otherView == null) || ((otherView.Underlying ?? otherView) != (underlying ?? this)))\r
- throw new IncompatibleViewException();\r
- if (otherView.Offset + otherView.Count - Offset < 0)\r
- return null;\r
- return (underlying ?? this).View(Offset, otherView.Offset + otherView.Count - Offset);\r
- }\r
-\r
-\r
- //Question: should we swap items or move nodes around?\r
- //The first seems much more efficient unless the items are value types \r
- //with a large memory footprint.\r
- //(Swapping will do count*3/2 T assignments, linking around will do \r
- // 4*count ref assignments; note that ref assignments are more expensive \r
- //than copying non-ref bits)\r
- /// <summary>\r
- /// Reverse the list so the items are in the opposite sequence order.\r
- /// </summary>\r
- [Tested]\r
- public virtual void Reverse()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
-\r
- Position[] positions = null;\r
- int poslow = 0, poshigh = 0;\r
- if (views != null)\r
- {\r
- CircularQueue<Position> _positions = null;\r
- foreach (LinkedList<T> view in views)\r
- {\r
- if (view != this)\r
- {\r
- switch (viewPosition(view))\r
- {\r
- case MutualViewPosition.ContainedIn:\r
- (_positions ?? (_positions = new CircularQueue<Position>())).Enqueue(new Position(view, true));\r
- _positions.Enqueue(new Position(view, false));\r
- break;\r
- case MutualViewPosition.Overlapping:\r
- view.Dispose();\r
- break;\r
- case MutualViewPosition.Contains:\r
- case MutualViewPosition.NonOverlapping:\r
- break;\r
- }\r
- }\r
- }\r
- if (_positions != null)\r
- {\r
- positions = _positions.ToArray();\r
- Sorting.IntroSort<Position>(positions, 0, positions.Length, PositionComparer.Default);\r
- poshigh = positions.Length - 1;\r
- }\r
- }\r
-\r
- Node a = get(0), b = get(size - 1);\r
- for (int i = 0; i < size / 2; i++)\r
- {\r
- T swap;\r
- swap = a.item; a.item = b.item; b.item = swap;\r
-#if HASHINDEX\r
- dict[a.item] = a; dict[b.item] = b;\r
-#endif\r
- if (positions != null)\r
- mirrorViewSentinelsForReverse(positions, ref poslow, ref poshigh, a, b, i);\r
- a = a.next; b = b.prev;\r
- }\r
- if (positions != null && size % 2 != 0)\r
- mirrorViewSentinelsForReverse(positions, ref poslow, ref poshigh, a, b, size / 2);\r
- (underlying ?? this).raiseCollectionChanged();\r
- }\r
-\r
- private void mirrorViewSentinelsForReverse(Position[] positions, ref int poslow, ref int poshigh, Node a, Node b, int i)\r
- {\r
-#if HASHINDEX\r
- int? aindex = offset + i, bindex = offset + size - 1 - i;\r
-#else\r
- int aindex = offset + i, bindex = offset + size - 1 - i;\r
-#endif\r
- Position pos;\r
-#if HASHINDEX\r
- while (poslow <= poshigh && (pos = positions[poslow]).Endpoint == a)\r
-#else\r
- while (poslow <= poshigh && (pos = positions[poslow]).Index == aindex)\r
-#endif\r
- {\r
- //TODO: Note: in the case og hashed linked list, if this.offset == null, but pos.View.offset!=null\r
- //we may at this point compute this.offset and non-null values of aindex and bindex\r
- if (pos.Left)\r
- pos.View.endsentinel = b.next;\r
- else\r
- {\r
- pos.View.startsentinel = b.prev;\r
- pos.View.offset = bindex;\r
- }\r
- poslow++;\r
- }\r
-#if HASHINDEX\r
- while (poslow < poshigh && (pos = positions[poshigh]).Endpoint == b)\r
-#else\r
- while (poslow < poshigh && (pos = positions[poshigh]).Index == bindex)\r
-#endif\r
- {\r
- if (pos.Left)\r
- pos.View.endsentinel = a.next;\r
- else\r
- {\r
- pos.View.startsentinel = a.prev;\r
- pos.View.offset = aindex;\r
- }\r
- poshigh--;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Check if this list is sorted according to the default sorting order\r
- /// for the item type T, as defined by the <see cref="T:C5.Comparer`1"/> class \r
- /// </summary>\r
- /// <exception cref="NotComparableException">if T is not comparable</exception>\r
- /// <returns>True if the list is sorted, else false.</returns>\r
- public bool IsSorted() { return IsSorted(Comparer<T>.Default); }\r
-\r
- /// <summary>\r
- /// Check if this list is sorted according to a specific sorting order.\r
- /// </summary>\r
- /// <param name="c">The comparer defining the sorting order.</param>\r
- /// <returns>True if the list is sorted, else false.</returns>\r
- [Tested]\r
- public virtual bool IsSorted(SCG.IComparer<T> c)\r
- {\r
- validitycheck();\r
- if (size <= 1)\r
- return true;\r
-\r
- Node node = startsentinel.next;\r
- T prevItem = node.item;\r
-\r
- node = node.next;\r
- while (node != endsentinel)\r
- {\r
- if (c.Compare(prevItem, node.item) > 0)\r
- return false;\r
- else\r
- {\r
- prevItem = node.item;\r
- node = node.next;\r
- }\r
- }\r
-\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// Sort the items of the list according to the default sorting order\r
- /// for the item type T, as defined by the Comparer[T] class. \r
- /// (<see cref="T:C5.Comparer`1"/>).\r
- /// The sorting is stable.\r
- /// </summary>\r
- /// <exception cref="InvalidOperationException">if T is not comparable</exception>\r
- public virtual void Sort() { Sort(Comparer<T>.Default); }\r
-\r
- // Sort the linked list using mergesort\r
- /// <summary>\r
- /// Sort the items of the list according to a specific sorting order.\r
- /// The sorting is stable.\r
- /// </summary>\r
- /// <param name="c">The comparer defining the sorting order.</param>\r
- [Tested]\r
- public virtual void Sort(SCG.IComparer<T> c)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- disposeOverlappingViews(false);\r
-#if HASHINDEX\r
- if (underlying != null)\r
- {\r
- Node cursor = startsentinel.next;\r
- while (cursor != endsentinel)\r
- {\r
- cursor.taggroup.count--;\r
- cursor = cursor.next;\r
- }\r
- }\r
-#endif\r
- // Build a linked list of non-empty runs.\r
- // The prev field in first node of a run points to next run's first node\r
- Node runTail = startsentinel.next;\r
- Node prevNode = startsentinel.next;\r
-\r
- endsentinel.prev.next = null;\r
- while (prevNode != null)\r
- {\r
- Node node = prevNode.next;\r
-\r
- while (node != null && c.Compare(prevNode.item, node.item) <= 0)\r
- {\r
- prevNode = node;\r
- node = prevNode.next;\r
- }\r
-\r
- // Completed a run; prevNode is the last node of that run\r
- prevNode.next = null; // Finish the run\r
- runTail.prev = node; // Link it into the chain of runs\r
- runTail = node;\r
- if (c.Compare(endsentinel.prev.item, prevNode.item) <= 0)\r
- endsentinel.prev = prevNode; // Update last pointer to point to largest\r
-\r
- prevNode = node; // Start a new run\r
- }\r
-\r
- // Repeatedly merge runs two and two, until only one run remains\r
- while (startsentinel.next.prev != null)\r
- {\r
- Node run = startsentinel.next;\r
- Node newRunTail = null;\r
-\r
- while (run != null && run.prev != null)\r
- { // At least two runs, merge\r
- Node nextRun = run.prev.prev;\r
- Node newrun = mergeRuns(run, run.prev, c);\r
-\r
- if (newRunTail != null)\r
- newRunTail.prev = newrun;\r
- else\r
- startsentinel.next = newrun;\r
-\r
- newRunTail = newrun;\r
- run = nextRun;\r
- }\r
-\r
- if (run != null) // Add the last run, if any\r
- newRunTail.prev = run;\r
- }\r
-\r
- endsentinel.prev.next = endsentinel;\r
- startsentinel.next.prev = startsentinel;\r
-\r
- //assert invariant();\r
- //assert isSorted();\r
-#if HASHINDEX\r
- {\r
- Node cursor = startsentinel.next, end = endsentinel;\r
- int tag, taglimit;\r
- TagGroup t = gettaggroup(startsentinel, endsentinel, out tag, out taglimit);\r
- int tagdelta = taglimit / (size + 1) - tag / (size + 1);\r
- tagdelta = tagdelta == 0 ? 1 : tagdelta;\r
- if (underlying == null)\r
- taggroups = 1;\r
- while (cursor != end)\r
- {\r
- tag = tag + tagdelta > taglimit ? taglimit : tag + tagdelta;\r
- cursor.tag = tag;\r
- t.count++;\r
- cursor = cursor.next;\r
- }\r
- if (tag == taglimit)\r
- splittaggroup(t);\r
- }\r
-#endif\r
- (underlying ?? this).raiseCollectionChanged();\r
- }\r
-\r
- private static Node mergeRuns(Node run1, Node run2, SCG.IComparer<T> c)\r
- {\r
- //assert run1 != null && run2 != null;\r
- Node prev;\r
- bool prev1; // is prev from run1?\r
-\r
- if (c.Compare(run1.item, run2.item) <= 0)\r
- {\r
- prev = run1;\r
- prev1 = true;\r
- run1 = run1.next;\r
- }\r
- else\r
- {\r
- prev = run2;\r
- prev1 = false;\r
- run2 = run2.next;\r
- }\r
-\r
- Node start = prev;\r
-\r
- //assert start != null;\r
- start.prev = null;\r
- while (run1 != null && run2 != null)\r
- {\r
- if (prev1)\r
- {\r
- //assert prev.next == run1;\r
- //Comparable run2item = (Comparable)run2.item;\r
- while (run1 != null && c.Compare(run2.item, run1.item) >= 0)\r
- {\r
- prev = run1;\r
- run1 = prev.next;\r
- }\r
-\r
- if (run1 != null)\r
- { // prev.item <= run2.item < run1.item; insert run2\r
- prev.next = run2;\r
- run2.prev = prev;\r
- prev = run2;\r
- run2 = prev.next;\r
- prev1 = false;\r
- }\r
- }\r
- else\r
- {\r
- //assert prev.next == run2;\r
- //Comparable run1item = (Comparable)run1.item;\r
- while (run2 != null && c.Compare(run1.item, run2.item) > 0)\r
- {\r
- prev = run2;\r
- run2 = prev.next;\r
- }\r
-\r
- if (run2 != null)\r
- { // prev.item < run1.item <= run2.item; insert run1\r
- prev.next = run1;\r
- run1.prev = prev;\r
- prev = run1;\r
- run1 = prev.next;\r
- prev1 = true;\r
- }\r
- }\r
- }\r
-\r
- //assert !(run1 != null && prev1) && !(run2 != null && !prev1);\r
- if (run1 != null)\r
- { // last run2 < all of run1; attach run1 at end\r
- prev.next = run1;\r
- run1.prev = prev;\r
- }\r
- else if (run2 != null)\r
- { // last run1 \r
- prev.next = run2;\r
- run2.prev = prev;\r
- }\r
-\r
- return start;\r
- }\r
-\r
- /// <summary>\r
- /// Randomly shuffle the items of this list. \r
- /// <para>Will invalidate overlapping views???</para>\r
- /// </summary>\r
- public virtual void Shuffle() { Shuffle(new C5Random()); }\r
-\r
-\r
- /// <summary>\r
- /// Shuffle the items of this list according to a specific random source.\r
- /// <para>Will invalidate overlapping views???</para>\r
- /// </summary>\r
- /// <param name="rnd">The random source.</param>\r
- public virtual void Shuffle(Random rnd)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- disposeOverlappingViews(false);\r
- ArrayList<T> a = new ArrayList<T>();\r
- a.AddAll(this);\r
- a.Shuffle(rnd);\r
- Node cursor = startsentinel.next;\r
- int j = 0;\r
- while (cursor != endsentinel)\r
- {\r
- cursor.item = a[j++];\r
-#if HASHINDEX\r
- dict[cursor.item] = cursor;\r
-#endif\r
- cursor = cursor.next;\r
- }\r
- (underlying ?? this).raiseCollectionChanged();\r
- }\r
-\r
- #endregion\r
-\r
- #region IIndexed<T> Members\r
-\r
- /// <summary>\r
- /// <exception cref="IndexOutOfRangeException"/>.\r
- /// </summary>\r
- /// <value>The directed collection of items in a specific index interval.</value>\r
- /// <param name="start">The low index of the interval (inclusive).</param>\r
- /// <param name="count">The size of the range.</param>\r
- [Tested]\r
- public IDirectedCollectionValue<T> this[int start, int count]\r
- {\r
- [Tested]\r
- get\r
- {\r
- validitycheck();\r
- checkRange(start, count);\r
- return new Range(this, start, count, true);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Searches for an item in the list going forwrds from the start.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of item from start.</returns>\r
- [Tested]\r
- public virtual int IndexOf(T item)\r
- {\r
- validitycheck();\r
- Node node;\r
-#if HASHINDEX\r
- if (!dict.Find(item, out node) || !insideview(node))\r
- return ~size;\r
-#endif\r
- node = startsentinel.next;\r
- int index = 0;\r
- if (find(item, ref node, ref index))\r
- return index;\r
- else\r
- return ~size;\r
- }\r
-\r
- /// <summary>\r
- /// Searches for an item in the list going backwords from the end.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of of item from the end.</returns>\r
- [Tested]\r
- public virtual int LastIndexOf(T item)\r
- {\r
-#if HASHINDEX\r
- return IndexOf(item);\r
-#else\r
- validitycheck();\r
-\r
- Node node = endsentinel.prev;\r
- int index = size - 1;\r
-\r
- if (dnif(item, ref node, ref index))\r
- return index;\r
- else\r
- return ~size;\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// Remove the item at a specific position of the list.\r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// >= the size of the collection.\r
- /// </summary>\r
- /// <param name="i">The index of the item to remove.</param>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public virtual T RemoveAt(int i)\r
- {\r
- updatecheck();\r
- T retval = remove(get(i), i);\r
-#if HASHINDEX\r
- dict.Remove(retval);\r
-#endif\r
- if (ActiveEvents != EventTypeEnum.None)\r
- (underlying ?? this).raiseForRemoveAt(Offset + i, retval);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items in an index interval.\r
- /// <exception cref="IndexOutOfRangeException"/>???. \r
- /// </summary>\r
- /// <param name="start">The index of the first item to remove.</param>\r
- /// <param name="count">The number of items to remove.</param>\r
- [Tested]\r
- public virtual void RemoveInterval(int start, int count)\r
- {\r
-#if HASHINDEX\r
- updatecheck();\r
- checkRange(start, count);\r
- if (count == 0)\r
- return;\r
-\r
- View(start, count).Clear();\r
-#else\r
- //Note: this is really almost equaivalent to Clear on a view\r
- updatecheck();\r
- checkRange(start, count);\r
- if (count == 0)\r
- return;\r
-\r
- //for small count: optimize\r
- //use an optimal get(int i, int j, ref Node ni, ref Node nj)?\r
- Node a = get(start), b = get(start + count - 1);\r
- fixViewsBeforeRemove(start, count, a, b);\r
- a.prev.next = b.next;\r
- b.next.prev = a.prev;\r
- if (underlying != null)\r
- underlying.size -= count;\r
-\r
- size -= count;\r
- if (ActiveEvents != EventTypeEnum.None)\r
- (underlying ?? this).raiseForRemoveInterval(start + Offset, count);\r
-#endif\r
- }\r
-\r
- void raiseForRemoveInterval(int start, int count)\r
- {\r
- if (ActiveEvents != 0)\r
- {\r
- raiseCollectionCleared(size == 0, count, start);\r
- raiseCollectionChanged();\r
- }\r
- }\r
- #endregion\r
-\r
- #region ISequenced<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public override int GetSequencedHashCode() { validitycheck(); return base.GetSequencedHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="that"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public override bool SequencedEquals(ISequenced<T> that) { validitycheck(); return base.SequencedEquals(that); }\r
-\r
- #endregion\r
-\r
- #region IDirectedCollection<T> Members\r
-\r
- /// <summary>\r
- /// Create a collection containing the same items as this collection, but\r
- /// whose enumerator will enumerate the items backwards. The new collection\r
- /// will become invalid if the original is modified. Method typicaly used as in\r
- /// <code>foreach (T x in coll.Backwards()) {...}</code>\r
- /// </summary>\r
- /// <returns>The backwards collection.</returns>\r
- [Tested]\r
- public override IDirectedCollectionValue<T> Backwards()\r
- { return this[0, size].Backwards(); }\r
-\r
- #endregion\r
-\r
- #region IDirectedEnumerable<T> Members\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return Backwards(); }\r
-\r
- #endregion\r
-\r
- #region IEditableCollection<T> Members\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>Speed.Linear</value>\r
- [Tested]\r
- public virtual Speed ContainsSpeed\r
- {\r
- [Tested]\r
- get\r
- {\r
-#if HASHINDEX\r
- return Speed.Constant ;\r
-#else\r
- return Speed.Linear;\r
-#endif\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Performs a check for view validity before calling base.GetUnsequencedHashCode()\r
- /// </summary>\r
- /// <returns></returns>\r
- [Tested]\r
- public override int GetUnsequencedHashCode()\r
- { validitycheck(); return base.GetUnsequencedHashCode(); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="that"></param>\r
- /// <returns></returns>\r
- [Tested]\r
- public override bool UnsequencedEquals(ICollection<T> that)\r
- { validitycheck(); return base.UnsequencedEquals(that); }\r
-\r
- /// <summary>\r
- /// Check if this collection contains (an item equivalent to according to the\r
- /// itemequalityComparer) a particular value.\r
- /// </summary>\r
- /// <param name="item">The value to check for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public virtual bool Contains(T item)\r
- {\r
- validitycheck();\r
- Node node;\r
- return contains(item, out node);\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public virtual bool Find(ref T item)\r
- {\r
- validitycheck();\r
- Node node;\r
- if (contains(item, out node)) { item = node.item; return true; }\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value. Will update a single item.\r
- /// </summary>\r
- /// <param name="item">Value to update.</param>\r
- /// <returns>True if the item was found and hence updated.</returns>\r
- [Tested]\r
- public virtual bool Update(T item) { T olditem; return Update(item, out olditem); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool Update(T item, out T olditem)\r
- {\r
- updatecheck();\r
- Node node;\r
-\r
- if (contains(item, out node))\r
- {\r
- olditem = node.item;\r
- node.item = item;\r
-#if HASHINDEX\r
- //Avoid clinging onto a reference to olditem via dict!\r
- dict.Update(item, node);\r
-#endif\r
- (underlying ?? this).raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
-\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found. Else, add the item to the collection.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the item was found (hence not added).</returns>\r
- [Tested]\r
- public virtual bool FindOrAdd(ref T item)\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- //This is an extended myinsert:\r
- Node node = new Node(item);\r
- if (!dict.FindOrAdd(item, ref node))\r
- {\r
- insertNode(true, endsentinel, node);\r
- (underlying ?? this).raiseForAdd(item);\r
- return false; \r
- }\r
- if (!insideview(node))\r
- throw new ArgumentException("Item alredy in indexed list but outside view");\r
- item = node.item;\r
- return true;\r
-#else\r
- if (Find(ref item))\r
- return true;\r
-\r
- Add(item);\r
- return false;\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value; else add the value to the collection. \r
- /// </summary>\r
- /// <param name="item">Value to add or update.</param>\r
- /// <returns>True if the item was found and updated (hence not added).</returns>\r
- [Tested]\r
- public virtual bool UpdateOrAdd(T item) { T olditem; return UpdateOrAdd(item, out olditem); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public virtual bool UpdateOrAdd(T item, out T olditem)\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- Node node = new Node(item);\r
- //NOTE: it is hard to do this without double access to the dictionary\r
- //in the update case\r
- if (dict.FindOrAdd(item, ref node))\r
- {\r
- if (!insideview(node))\r
- throw new ArgumentException("Item in indexed list but outside view");\r
- olditem = node.item;\r
- //Avoid clinging onto a reference to olditem via dict!\r
- dict.Update(item, node);\r
- node.item = item;\r
- (underlying ?? this).raiseForUpdate(item, olditem);\r
- return true;\r
- }\r
- insertNode(true, endsentinel, node);\r
- (underlying ?? this).raiseForAdd(item);\r
-#else\r
- if (Update(item, out olditem))\r
- return true;\r
- Add(item);\r
-#endif\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection. Since the collection has bag\r
- /// semantics only one copy equivalent to the supplied item is removed. \r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public virtual bool Remove(T item)\r
- {\r
- updatecheck();\r
- int i = 0;\r
- Node node;\r
-#if HASHINDEX\r
- if (!dictremove(item, out node))\r
-#else\r
- node = fIFO ? startsentinel.next : endsentinel.prev;\r
- if (!(fIFO ? find(item, ref node, ref i) : dnif(item, ref node, ref i)))\r
-#endif\r
- return false;\r
- T removeditem = remove(node, i);\r
- (underlying ?? this).raiseForRemove(removeditem);\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection if found (only one copy). \r
- /// If an item was removed, report a binary copy of the actual item removed in \r
- /// the argument.\r
- /// </summary>\r
- /// <param name="item">The value to remove on input.</param>\r
- /// <param name="removeditem">The value removed.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public virtual bool Remove(T item, out T removeditem)\r
- {\r
- updatecheck();\r
- int i = 0;\r
- Node node;\r
-#if HASHINDEX\r
- if (!dictremove(item, out node))\r
-#else\r
- node = fIFO ? startsentinel.next : endsentinel.prev;\r
- if (!(fIFO ? find(item, ref node, ref i) : dnif(item, ref node, ref i)))\r
-#endif\r
- {\r
- removeditem = default(T);\r
- return false;\r
- }\r
- removeditem = node.item;\r
- remove(node, i);\r
- (underlying ?? this).raiseForRemove(removeditem);\r
- return true;\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items in another collection from this one, taking multiplicities into account.\r
- /// <para>Always removes from the front of the list.\r
- /// </para>\r
- /// <para>The asymptotic running time complexity of this method is <code>O(n+m+v*log(v))</code>, \r
- /// where <code>n</code> is the size of this list, <code>m</code> is the size of the\r
- /// <code>items</code> collection and <code>v</code> is the number of views. \r
- /// The method will temporarily allocate memory of size <code>O(m+v)</code>.\r
- /// </para>\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to remove.</param>\r
- [Tested]\r
- public virtual void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
-#if HASHINDEX\r
- Node node;\r
- foreach (T item in items)\r
- if (dictremove(item, out node))\r
- {\r
- if (mustFire)\r
- raiseHandler.Remove(node.item);\r
- remove(node, 118);\r
- }\r
-#else\r
- HashBag<T> toremove = new HashBag<T>(itemequalityComparer);\r
- toremove.AddAll(items);\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int index = 0, removed = 0, myoffset = Offset;\r
- Node node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- //pass by a stretch of nodes\r
- while (node != endsentinel && !toremove.Contains(node.item))\r
- {\r
- node = node.next;\r
- index++;\r
- }\r
- viewHandler.skipEndpoints(removed, myoffset + index);\r
- //Remove a stretch of nodes\r
- Node localend = node.prev; //Latest node not to be removed\r
- while (node != endsentinel && toremove.Remove(node.item))\r
- {\r
- if (mustFire)\r
- raiseHandler.Remove(node.item);\r
- removed++;\r
- node = node.next;\r
- index++;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- }\r
- viewHandler.updateSentinels(myoffset + index, localend, node);\r
- localend.next = node;\r
- node.prev = localend;\r
- }\r
- index = underlying != null ? underlying.size + 1 - myoffset : size + 1 - myoffset;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- size -= removed;\r
- if (underlying != null)\r
- underlying.size -= removed;\r
-#endif\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- void RemoveAll(Fun<T, bool> predicate)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
-#if HASHINDEX\r
- {\r
- Node n = startsentinel.next;\r
-\r
- while (n != endsentinel)\r
- {\r
- bool removeIt = predicate(n.item);\r
- updatecheck();\r
- if (removeIt)\r
- {\r
- dict.Remove(n.item);\r
- remove(n, 119);\r
- if (mustFire)\r
- raiseHandler.Remove(n.item);\r
- }\r
-\r
- n = n.next;\r
- }\r
- }\r
-#else\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int index = 0, removed = 0, myoffset = Offset;\r
- Node node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- //pass by a stretch of nodes\r
- while (node != endsentinel && !predicate(node.item))\r
- {\r
- updatecheck();\r
- node = node.next;\r
- index++;\r
- }\r
- updatecheck();\r
- viewHandler.skipEndpoints(removed, myoffset + index);\r
- //Remove a stretch of nodes\r
- Node localend = node.prev; //Latest node not to be removed\r
- while (node != endsentinel && predicate(node.item))\r
- {\r
- updatecheck();\r
- if (mustFire)\r
- raiseHandler.Remove(node.item);\r
- removed++;\r
- node = node.next;\r
- index++;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- }\r
- updatecheck();\r
- viewHandler.updateSentinels(myoffset + index, localend, node);\r
- localend.next = node;\r
- node.prev = localend;\r
- }\r
- index = underlying != null ? underlying.size + 1 - myoffset : size + 1 - myoffset;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- size -= removed;\r
- if (underlying != null)\r
- underlying.size -= removed;\r
-#endif\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items from this collection.\r
- /// </summary>\r
- [Tested]\r
- public virtual void Clear()\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- int oldsize = size;\r
-#if HASHINDEX\r
- if (underlying == null)\r
- dict.Clear();\r
- else\r
- foreach (T item in this)\r
- dict.Remove(item);\r
-#endif\r
- clear();\r
- (underlying ?? this).raiseForRemoveInterval(Offset, oldsize);\r
- }\r
-\r
- void clear()\r
- {\r
- if (size == 0)\r
- return;\r
-#if HASHINDEX\r
- //TODO: mix with tag maintenance to only run through list once?\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- if (viewHandler.viewCount > 0)\r
- {\r
- int removed = 0;\r
- Node n = startsentinel.next;\r
- viewHandler.skipEndpoints(0, n);\r
- while (n != endsentinel)\r
- {\r
- removed++;\r
- n = n.next;\r
- viewHandler.updateViewSizesAndCounts(removed, n);\r
- }\r
- viewHandler.updateSentinels(endsentinel, startsentinel, endsentinel);\r
- if (underlying != null)\r
- viewHandler.updateViewSizesAndCounts(removed, underlying.endsentinel);\r
- }\r
-#else\r
- fixViewsBeforeRemove(Offset, size, startsentinel.next, endsentinel.prev);\r
-#endif\r
-#if HASHINDEX\r
- if (underlying != null)\r
- {\r
- Node n = startsentinel.next;\r
-\r
- while (n != endsentinel)\r
- {\r
- n.next.prev = startsentinel;\r
- startsentinel.next = n.next;\r
- removefromtaggroup(n);\r
- n = n.next;\r
- }\r
- }\r
- else\r
- taggroups = 0;\r
-#endif\r
- endsentinel.prev = startsentinel;\r
- startsentinel.next = endsentinel;\r
- if (underlying != null)\r
- underlying.size -= size;\r
- size = 0;\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items not in some other collection from this one, taking multiplicities into account.\r
- /// <para>The asymptotic running time complexity of this method is <code>O(n+m+v*log(v))</code>, \r
- /// where <code>n</code> is the size of this collection, <code>m</code> is the size of the\r
- /// <code>items</code> collection and <code>v</code> is the number of views. \r
- /// The method will temporarily allocate memory of size <code>O(m+v)</code>. The stated complexitiy \r
- /// holds under the assumption that the itemequalityComparer of this list is well-behaved.\r
- /// </para>\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to retain.</param>\r
- [Tested]\r
- public virtual void RetainAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
-#if HASHINDEX\r
- /*if (underlying == null)\r
- {\r
- HashDictionary<T, Node> newdict = new HashDictionary<T, Node>(itemequalityComparer);\r
- foreach (T item in items)\r
- {\r
- Node node;\r
-\r
- if (dict.Remove(item, out node))\r
- newdict.Add(item, node);\r
- }\r
- foreach (KeyValuePair<T, Node> pair in dict)\r
- {\r
- Node n = pair.Value;\r
- fixViewsBeforeSingleRemove(n, 117);\r
- Node p = n.prev, s = n.next; s.prev = p; p.next = s;\r
- removefromtaggroup(n);\r
- }\r
- dict = newdict;\r
- size = dict.Count;\r
- //For a small number of items to retain it might be faster to \r
- //iterate through the list and splice out the chunks not needed\r
- }\r
- else*/\r
- {\r
- HashSet<T> toremove = new HashSet<T>(itemequalityComparer);\r
-\r
- foreach (T item in this)\r
- toremove.Add(item);\r
-\r
- foreach (T item in items)\r
- toremove.Remove(item);\r
-\r
- Node n = startsentinel.next;\r
-\r
- while (n != endsentinel && toremove.Count > 0)\r
- {\r
- if (toremove.Contains(n.item))\r
- {\r
- dict.Remove(n.item);\r
- remove(n, 119);\r
- if (mustFire)\r
- raiseHandler.Remove(n.item);\r
- }\r
-\r
- n = n.next;\r
- }\r
- }\r
-#else\r
- HashBag<T> toretain = new HashBag<T>(itemequalityComparer);\r
- toretain.AddAll(items);\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int index = 0, removed = 0, myoffset = Offset;\r
- Node node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- //Skip a stretch of nodes\r
- while (node != endsentinel && toretain.Remove(node.item))\r
- {\r
- node = node.next;\r
- index++;\r
- }\r
- viewHandler.skipEndpoints(removed, myoffset + index);\r
- //Remove a stretch of nodes\r
- Node localend = node.prev; //Latest node not to be removed\r
- while (node != endsentinel && !toretain.Contains(node.item))\r
- {\r
- if (mustFire)\r
- raiseHandler.Remove(node.item);\r
- removed++;\r
- node = node.next;\r
- index++;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- }\r
- viewHandler.updateSentinels(myoffset + index, localend, node);\r
- localend.next = node;\r
- node.prev = localend;\r
- }\r
- index = underlying != null ? underlying.size + 1 - myoffset : size + 1 - myoffset;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- size -= removed;\r
- if (underlying != null)\r
- underlying.size -= removed;\r
-#endif\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="predicate"></param>\r
- void RetainAll(Fun<T,bool> predicate)\r
- {\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
-#if HASHINDEX\r
- {\r
- Node n = startsentinel.next;\r
-\r
- while (n != endsentinel)\r
- {\r
- bool removeIt = !predicate(n.item);\r
- updatecheck();\r
- if (removeIt)\r
- {\r
- dict.Remove(n.item);\r
- remove(n, 119);\r
- if (mustFire)\r
- raiseHandler.Remove(n.item);\r
- }\r
-\r
- n = n.next;\r
- }\r
- }\r
-#else\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int index = 0, removed = 0, myoffset = Offset;\r
- Node node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- //Skip a stretch of nodes\r
- while (node != endsentinel && predicate(node.item))\r
- {\r
- updatecheck();\r
- node = node.next;\r
- index++;\r
- }\r
- updatecheck();\r
- viewHandler.skipEndpoints(removed, myoffset + index);\r
- //Remove a stretch of nodes\r
- Node localend = node.prev; //Latest node not to be removed\r
- while (node != endsentinel && !predicate(node.item))\r
- {\r
- updatecheck();\r
- if (mustFire)\r
- raiseHandler.Remove(node.item);\r
- removed++;\r
- node = node.next;\r
- index++;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- }\r
- updatecheck();\r
- viewHandler.updateSentinels(myoffset + index, localend, node);\r
- localend.next = node;\r
- node.prev = localend;\r
- }\r
- index = underlying != null ? underlying.size + 1 - myoffset : size + 1 - myoffset;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- size -= removed;\r
- if (underlying != null)\r
- underlying.size -= removed;\r
-#endif\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains all the values in another collection\r
- /// with respect to multiplicities.\r
- /// </summary>\r
- /// <param name="items">The </param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if all values in <code>items</code>is in this collection.</returns>\r
- [Tested]\r
- public virtual bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- validitycheck();\r
-#if HASHINDEX\r
- Node node;\r
- foreach (T item in items)\r
- if (!contains(item, out node))\r
- return false;\r
- return true;\r
-#else\r
- HashBag<T> tocheck = new HashBag<T>(itemequalityComparer);\r
- tocheck.AddAll(items);\r
- if (tocheck.Count > size)\r
- return false;\r
- Node node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- tocheck.Remove(node.item);\r
- node = node.next;\r
- }\r
- return tocheck.IsEmpty;\r
-#endif\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a new list consisting of the items of this list satisfying a \r
- /// certain predicate.\r
- /// </summary>\r
- /// <param name="filter">The filter delegate defining the predicate.</param>\r
- /// <returns>The new list.</returns>\r
- [Tested]\r
- public IList<T> FindAll(Fun<T, bool> filter)\r
- {\r
- validitycheck();\r
- int stamp = this.stamp;\r
- LinkedList<T> retval = new LinkedList<T>();\r
- Node cursor = startsentinel.next;\r
- Node mcursor = retval.startsentinel;\r
-#if HASHINDEX\r
- double tagdelta = int.MaxValue / (size + 1.0);\r
- int count = 1;\r
- TagGroup taggroup = new TagGroup();\r
- retval.taggroups = 1;\r
-#endif\r
- while (cursor != endsentinel)\r
- {\r
- bool found = filter(cursor.item);\r
- modifycheck(stamp);\r
- if (found)\r
- {\r
- mcursor.next = new Node(cursor.item, mcursor, null);\r
- mcursor = mcursor.next;\r
- retval.size++;\r
-#if HASHINDEX\r
- retval.dict.Add(cursor.item, mcursor); \r
- mcursor.taggroup = taggroup;\r
- mcursor.tag = (int)(tagdelta * count++);\r
-#endif\r
- }\r
- cursor = cursor.next;\r
- }\r
-#if HASHINDEX\r
- taggroup.count = retval.size;\r
-#endif\r
- retval.endsentinel.prev = mcursor;\r
- mcursor.next = retval.endsentinel;\r
- return retval;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Count the number of items of the collection equal to a particular value.\r
- /// Returns 0 if and only if the value is not in the collection.\r
- /// </summary>\r
- /// <param name="item">The value to count.</param>\r
- /// <returns>The number of copies found.</returns>\r
- [Tested]\r
- public virtual int ContainsCount(T item)\r
- {\r
-#if HASHINDEX\r
- return Contains(item) ? 1 : 0;\r
-#else\r
- validitycheck();\r
- int retval = 0;\r
- Node node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- if (itemequalityComparer.Equals(node.item, item))\r
- retval++;\r
- node = node.next;\r
- }\r
- return retval;\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<T> UniqueItems()\r
- {\r
-#if HASHINDEX\r
- return this;\r
-#else\r
- HashBag<T> hashbag = new HashBag<T>(itemequalityComparer);\r
- hashbag.AddAll(this);\r
- return hashbag.UniqueItems();\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities()\r
- {\r
-#if HASHINDEX\r
- return new MultiplicityOne<T>(this);\r
-#else\r
- HashBag<T> hashbag = new HashBag<T>(itemequalityComparer);\r
- hashbag.AddAll(this);\r
- return hashbag.ItemMultiplicities();\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items equivalent to a given value.\r
- /// <para>The asymptotic complexity of this method is <code>O(n+v*log(v))</code>, \r
- /// where <code>n</code> is the size of the collection and <code>v</code> \r
- /// is the number of views.\r
- /// </para>\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- [Tested]\r
- public virtual void RemoveAllCopies(T item)\r
- {\r
-#if HASHINDEX\r
- Remove(item);\r
-#else\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- RaiseForRemoveAllHandler raiseHandler = new RaiseForRemoveAllHandler(underlying ?? this);\r
- bool mustFire = raiseHandler.MustFire;\r
- ViewHandler viewHandler = new ViewHandler(this);\r
- int index = 0, removed = 0, myoffset = Offset;\r
- //\r
- Node node = startsentinel.next;\r
- while (node != endsentinel)\r
- {\r
- //pass by a stretch of nodes\r
- while (node != endsentinel && !itemequalityComparer.Equals(node.item, item))\r
- {\r
- node = node.next;\r
- index++;\r
- }\r
- viewHandler.skipEndpoints(removed, myoffset + index);\r
- //Remove a stretch of nodes\r
- Node localend = node.prev; //Latest node not to be removed\r
- while (node != endsentinel && itemequalityComparer.Equals(node.item, item))\r
- {\r
- if (mustFire)\r
- raiseHandler.Remove(node.item);\r
- removed++;\r
- node = node.next;\r
- index++;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- }\r
- viewHandler.updateSentinels(myoffset + index, localend, node);\r
- localend.next = node;\r
- node.prev = localend;\r
- }\r
- index = underlying != null ? underlying.size + 1 - myoffset : size + 1 - myoffset;\r
- viewHandler.updateViewSizesAndCounts(removed, myoffset + index);\r
- size -= removed;\r
- if (underlying != null)\r
- underlying.size -= removed;\r
- raiseHandler.Raise();\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region ICollectionValue<T> Members\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of items in this collection</value>\r
- [Tested]\r
- public override int Count { [Tested]get { validitycheck(); return size; } }\r
-\r
- /// <summary>\r
- /// Choose some item of this collection. \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">if collection is empty.</exception>\r
- /// <returns></returns>\r
- [Tested]\r
- public override T Choose() { return First; }\r
-\r
- /// <summary>\r
- /// Create an enumerable, enumerating the items of this collection that satisfies \r
- /// a certain condition.\r
- /// </summary>\r
- /// <param name="filter">The T->bool filter delegate defining the condition</param>\r
- /// <returns>The filtered enumerable</returns>\r
- public override SCG.IEnumerable<T> Filter(Fun<T, bool> filter) { validitycheck(); return base.Filter(filter); }\r
-\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
- /// <summary>\r
- /// Create an enumerator for the collection\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- validitycheck();\r
- Node cursor = startsentinel.next;\r
- int enumeratorstamp = underlying != null ? underlying.stamp : this.stamp;\r
-\r
- while (cursor != endsentinel)\r
- {\r
- modifycheck(enumeratorstamp);\r
- yield return cursor.item;\r
- cursor = cursor.next;\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region IExtensible<T> Members\r
- /// <summary>\r
- /// Add an item to this collection if possible. \r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True.</returns>\r
- [Tested]\r
- public virtual bool Add(T item)\r
- {\r
- updatecheck();\r
-#if HASHINDEX\r
- Node node = new Node(item);\r
- if (!dict.FindOrAdd(item, ref node))\r
- {\r
- insertNode(true, endsentinel, node);\r
- (underlying ?? this).raiseForAdd(item);\r
- return true;\r
- }\r
- return false;\r
-#else\r
- insert(size, endsentinel, item);\r
- (underlying ?? this).raiseForAdd(item);\r
- return true;\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True since this collection has bag semantics.</value>\r
- [Tested]\r
- public virtual bool AllowsDuplicates\r
- {\r
- [Tested]\r
- get\r
- {\r
-#if HASHINDEX\r
- return false;\r
-#else\r
- return true;\r
-#endif\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting\r
- {\r
- get\r
- {\r
-#if HASHINDEX\r
- return true;\r
-#else\r
- return false;\r
-#endif\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Add the elements from another collection with a more specialized item type \r
- /// to this collection. \r
- /// </summary>\r
- /// <typeparam name="U">The type of items to add</typeparam>\r
- /// <param name="items">The items to add</param>\r
- [Tested]\r
- public virtual void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
-#if HASHINDEX\r
- updatecheck();\r
- int added = 0;\r
- Node pred = endsentinel.prev;\r
- foreach (U item in items)\r
- {\r
- Node node = new Node(item);\r
- if (!dict.FindOrAdd(item, ref node))\r
- {\r
- insertNode(false, endsentinel, node);\r
- added++;\r
- }\r
- }\r
- if (added > 0)\r
- {\r
- fixViewsAfterInsert(endsentinel, pred, added, 0);\r
- raiseForInsertAll(pred, size - added, added, false);\r
- }\r
-#else\r
- insertAll(size, items, false);\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
-#if HASHINDEX\r
-#else\r
- #region IStack<T> Members\r
-\r
- /// <summary>\r
- /// Push an item to the top of the stack.\r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- [Tested]\r
- public void Push(T item)\r
- {\r
- InsertLast(item);\r
- }\r
-\r
- /// <summary>\r
- /// Pop the item at the top of the stack from the stack.\r
- /// </summary>\r
- /// <returns>The popped item.</returns>\r
- [Tested]\r
- public T Pop()\r
- {\r
- return RemoveLast();\r
- }\r
-\r
- #endregion\r
-\r
- #region IQueue<T> Members\r
-\r
- /// <summary>\r
- /// Enqueue an item at the back of the queue. \r
- /// </summary>\r
- /// <param name="item">The item</param>\r
- [Tested]\r
- public virtual void Enqueue(T item)\r
- {\r
- InsertLast(item);\r
- }\r
-\r
- /// <summary>\r
- /// Dequeue an item from the front of the queue.\r
- /// </summary>\r
- /// <returns>The item</returns>\r
- [Tested]\r
- public virtual T Dequeue()\r
- {\r
- return RemoveFirst();\r
- }\r
- #endregion\r
-#endif\r
-\r
- #region Diagnostic\r
-\r
- private bool checkViews()\r
- {\r
- if (underlying != null)\r
- throw new InternalException(System.Reflection.MethodInfo.GetCurrentMethod() + " called on a view");\r
- if (views == null)\r
- return true;\r
- bool retval = true;\r
-\r
- Node[] nodes = new Node[size + 2];\r
- int i = 0;\r
- Node n = startsentinel;\r
- while (n != null)\r
- {\r
- nodes[i++] = n;\r
- n = n.next;\r
- }\r
- //Console.WriteLine("###");\r
- foreach (LinkedList<T> view in views)\r
- {\r
- if (!view.isValid)\r
- {\r
- Console.WriteLine("Invalid view(hash {0}, offset {1}, size {2})",\r
- view.GetHashCode(), view.offset, view.size);\r
- retval = false;\r
- continue;\r
- }\r
- if (view.Offset > size || view.Offset < 0)\r
- {\r
- Console.WriteLine("Bad view(hash {0}, offset {1}, size {2}), Offset > underlying.size ({2})",\r
- view.GetHashCode(), view.offset, view.size, size);\r
- retval = false;\r
- }\r
- else if (view.startsentinel != nodes[view.Offset])\r
- {\r
- Console.WriteLine("Bad view(hash {0}, offset {1}, size {2}), startsentinel {3} should be {4}",\r
- view.GetHashCode(), view.offset, view.size,\r
- view.startsentinel + " " + view.startsentinel.GetHashCode(),\r
- nodes[view.Offset] + " " + nodes[view.Offset].GetHashCode());\r
- retval = false;\r
- }\r
- if (view.Offset + view.size > size || view.Offset + view.size < 0)\r
- {\r
- Console.WriteLine("Bad view(hash {0}, offset {1}, size {2}), end index > underlying.size ({3})",\r
- view.GetHashCode(), view.offset, view.size, size);\r
- retval = false;\r
- }\r
- else if (view.endsentinel != nodes[view.Offset + view.size + 1])\r
- {\r
- Console.WriteLine("Bad view(hash {0}, offset {1}, size {2}), endsentinel {3} should be {4}",\r
- view.GetHashCode(), view.offset, view.size,\r
- view.endsentinel + " " + view.endsentinel.GetHashCode(),\r
- nodes[view.Offset + view.size + 1] + " " + nodes[view.Offset + view.size + 1].GetHashCode());\r
- retval = false;\r
- }\r
- if (view.views != views)\r
- {\r
- Console.WriteLine("Bad view(hash {0}, offset {1}, size {2}), wrong views list {3} <> {4}",\r
- view.GetHashCode(), view.offset, view.size, view.views.GetHashCode(), views.GetHashCode());\r
- retval = false;\r
- }\r
- if (view.underlying != this)\r
- {\r
- Console.WriteLine("Bad view(hash {0}, offset {1}, size {2}), wrong underlying {3} <> this {4}",\r
- view.GetHashCode(), view.offset, view.size, view.underlying.GetHashCode(), GetHashCode());\r
- retval = false;\r
- }\r
- if (view.stamp != stamp)\r
- {\r
- //Console.WriteLine("Bad view(hash {0}, offset {1}, size {2}), wrong stamp view:{2} underlying: {3}", view.GetHashCode(),view.offset, view.size, view.stamp, stamp);\r
- //retval = false;\r
- }\r
- }\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Check the sanity of this list\r
- /// </summary>\r
- /// <returns>true if sane</returns>\r
- [Tested]\r
- public virtual bool Check()\r
- {\r
- bool retval = true;\r
-\r
- /*if (underlying != null && underlying.stamp != stamp)\r
- {\r
- Console.WriteLine("underlying != null && underlying.stamp({0}) != stamp({1})", underlying.stamp, stamp);\r
- retval = false;\r
- }*/\r
-\r
- if (underlying != null)\r
- {\r
- //TODO: check that this view is included in viewsEndpoints tree\r
- return underlying.Check();\r
- }\r
-\r
- if (startsentinel == null)\r
- {\r
- Console.WriteLine("startsentinel == null");\r
- retval = false;\r
- }\r
-\r
- if (endsentinel == null)\r
- {\r
- Console.WriteLine("endsentinel == null");\r
- retval = false;\r
- }\r
-\r
- if (size == 0)\r
- {\r
- if (startsentinel != null && startsentinel.next != endsentinel)\r
- {\r
- Console.WriteLine("size == 0 but startsentinel.next != endsentinel");\r
- retval = false;\r
- }\r
-\r
- if (endsentinel != null && endsentinel.prev != startsentinel)\r
- {\r
- Console.WriteLine("size == 0 but endsentinel.prev != startsentinel");\r
- retval = false;\r
- }\r
- }\r
-\r
- if (startsentinel == null)\r
- {\r
- Console.WriteLine("NULL startsentinel");\r
- return retval;\r
- }\r
-\r
- int count = 0;\r
- Node node = startsentinel.next, prev = startsentinel;\r
-#if HASHINDEX\r
- int taggroupsize = 0, oldtaggroupsize = losize + 1, seentaggroups = 0;\r
- TagGroup oldtg = null;\r
-\r
- if (underlying == null)\r
- {\r
- TagGroup tg = startsentinel.taggroup;\r
-\r
- if (tg.count != 0 || tg.first != null || tg.last != null || tg.tag != int.MinValue)\r
- {\r
- Console.WriteLine("Bad startsentinel tag group: {0}", tg);\r
- retval = false;\r
- }\r
-\r
- tg = endsentinel.taggroup;\r
- if (tg.count != 0 || tg.first != null || tg.last != null || tg.tag != int.MaxValue)\r
- {\r
- Console.WriteLine("Bad endsentinel tag group: {0}", tg);\r
- retval = false;\r
- }\r
- }\r
-#endif\r
- while (node != endsentinel)\r
- {\r
- count++;\r
- if (node.prev != prev)\r
- {\r
- Console.WriteLine("Bad backpointer at node {0}", count);\r
- retval = false;\r
- }\r
-#if HASHINDEX\r
- if (underlying == null)\r
- {\r
- if (!node.prev.precedes(node))\r
- {\r
- Console.WriteLine("node.prev.tag ({0}, {1}) >= node.tag ({2}, {3}) at index={4} item={5} ", node.prev.taggroup.tag, node.prev.tag, node.taggroup.tag, node.tag, count, node.item);\r
- retval = false;\r
- }\r
-\r
- if (node.taggroup != oldtg)\r
- {\r
- if (oldtg != null)\r
- {\r
- if (oldtg.count != taggroupsize)\r
- {\r
- Console.WriteLine("Bad taggroupsize: oldtg.count ({0}) != taggroupsize ({1}) at index={2} item={3}", oldtg.count, taggroupsize, count, node.item);\r
- retval = false;\r
- }\r
-\r
- if (oldtaggroupsize <= losize && taggroupsize <= losize)\r
- {\r
- Console.WriteLine("Two small taggroups in a row: oldtaggroupsize ({0}), taggroupsize ({1}) at index={2} item={3}", oldtaggroupsize, taggroupsize, count, node.item);\r
- retval = false;\r
- }\r
-\r
- oldtaggroupsize = taggroupsize;\r
- }\r
-\r
- seentaggroups++;\r
- oldtg = node.taggroup;\r
- taggroupsize = 1;\r
- }\r
- else\r
- {\r
- taggroupsize++;\r
- }\r
- }\r
-\r
-#endif\r
- prev = node;\r
- node = node.next;\r
- if (node == null)\r
- {\r
- Console.WriteLine("Null next pointer at node {0}", count);\r
- return false;\r
- }\r
- }\r
-\r
-#if HASHINDEX\r
- if (underlying == null && size == 0 && taggroups != 0)\r
- {\r
- Console.WriteLine("Bad taggroups for empty list: size={0} taggroups={1}", size, taggroups);\r
- retval = false;\r
- }\r
- if (underlying == null && size > 0)\r
- {\r
- oldtg = node.prev.taggroup;\r
- if (oldtg != null)\r
- {\r
- if (oldtg.count != taggroupsize)\r
- {\r
- Console.WriteLine("Bad taggroupsize: oldtg.count ({0}) != taggroupsize ({1}) at index={2} item={3}", oldtg.count, taggroupsize, count, node.item);\r
- retval = false;\r
- }\r
-\r
- if (oldtaggroupsize <= losize && taggroupsize <= losize)\r
- {\r
- Console.WriteLine("Two small taggroups in a row: oldtaggroupsize ({0}), taggroupsize ({1}) at index={2} item={3}", oldtaggroupsize, taggroupsize, count, node.item);\r
- retval = false;\r
- }\r
- }\r
-\r
- if (seentaggroups != taggroups)\r
- {\r
- Console.WriteLine("seentaggroups ({0}) != taggroups ({1}) (at size {2})", seentaggroups, taggroups, size);\r
- retval = false;\r
- }\r
- }\r
-#endif\r
- if (count != size)\r
- {\r
- Console.WriteLine("size={0} but enumeration gives {1} nodes ", size, count);\r
- retval = false;\r
- }\r
-\r
- retval = checkViews() && retval;\r
-\r
-#if HASHINDEX\r
- if (!retval)\r
- return false;\r
- if (underlying == null)\r
- {\r
- if (size != dict.Count)\r
- {\r
- Console.WriteLine("list.size ({0}) != dict.Count ({1})", size, dict.Count);\r
- retval = false;\r
- }\r
- Node n = startsentinel.next, n2;\r
- while (n != endsentinel)\r
- {\r
- if (!dict.Find(n.item, out n2))\r
- {\r
- Console.WriteLine("Item in list but not dict: {0}", n.item);\r
- retval = false;\r
- }\r
- else if (n != n2)\r
- {\r
- Console.WriteLine("Wrong node in dict for item: {0}", n.item);\r
- retval = false;\r
- }\r
- n = n.next;\r
- }\r
- }\r
-#endif\r
- return retval;\r
- }\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this LinkedList.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- LinkedList<T> clone = new LinkedList<T>(itemequalityComparer);\r
- clone.AddAll(this);\r
- return clone;\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-}\r
+++ /dev/null
-RedBlackTreeBag.cs
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5\r
-{\r
- /// <summary>\r
- /// A sorted generic dictionary based on a red-black tree set.\r
- /// </summary>\r
- public class TreeDictionary<K, V> : SortedDictionaryBase<K, V>, IDictionary<K, V>, ISortedDictionary<K, V>\r
- {\r
-\r
- #region Constructors\r
-\r
- /// <summary>\r
- /// Create a red-black tree dictionary using the natural comparer for keys.\r
- /// <exception cref="ArgumentException"/> if the key type K is not comparable.\r
- /// </summary>\r
- public TreeDictionary() : this(Comparer<K>.Default, EqualityComparer<K>.Default) { }\r
-\r
- /// <summary>\r
- /// Create a red-black tree dictionary using an external comparer for keys.\r
- /// </summary>\r
- /// <param name="comparer">The external comparer</param>\r
- public TreeDictionary(SCG.IComparer<K> comparer) : this(comparer, new ComparerZeroHashCodeEqualityComparer<K>(comparer)) { }\r
-\r
- TreeDictionary(SCG.IComparer<K> comparer, SCG.IEqualityComparer<K> equalityComparer) : base(comparer,equalityComparer)\r
- {\r
- pairs = sortedpairs = new TreeSet<KeyValuePair<K, V>>(new KeyValuePairComparer<K, V>(comparer));\r
- }\r
-\r
- #endregion\r
-\r
- //TODO: put in interface\r
- /// <summary>\r
- /// Make a snapshot of the current state of this dictionary\r
- /// </summary>\r
- /// <returns>The snapshot</returns>\r
- [Tested]\r
- public SCG.IEnumerable<KeyValuePair<K, V>> Snapshot()\r
- {\r
- TreeDictionary<K, V> res = (TreeDictionary<K, V>)MemberwiseClone();\r
-\r
- res.pairs = (TreeSet<KeyValuePair<K, V>>)((TreeSet<KeyValuePair<K, V>>)sortedpairs).Snapshot();\r
- return res;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override object Clone()\r
- {\r
- TreeDictionary<K, V> clone = new TreeDictionary<K, V>(Comparer, EqualityComparer);\r
- clone.sortedpairs.AddSorted(sortedpairs);\r
- return clone;\r
- }\r
-\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-#define MAINTAIN_SIZE\r
-#define BAGnot\r
-#define NCP\r
-\r
-#if BAG\r
-#if !MAINTAIN_SIZE\r
-#error BAG defined without MAINTAIN_SIZE!\r
-#endif\r
-#endif\r
-\r
-\r
-using System;\r
-using SCG = System.Collections.Generic;\r
-\r
-// NOTE NOTE NOTE NOTE\r
-// This source file is used to produce both TreeSet<T> and TreeBag<T>\r
-// It should be copied to a file called TreeBag.cs in which all code mentions of \r
-// TreeSet is changed to TreeBag and the preprocessor symbol BAG is defined.\r
-// NOTE: there may be problems with documentation comments.\r
-\r
-namespace C5\r
-{\r
-#if BAG\r
- /// <summary>\r
- /// An implementation of Red-Black trees as an indexed, sorted collection with bag semantics,\r
- /// cf. <a href="litterature.htm#CLRS">CLRS</a>. (<see cref="T:C5.TreeSet`1"/> for an \r
- /// implementation with set semantics).\r
- /// <br/>\r
- /// The comparer (sorting order) may be either natural, because the item type is comparable \r
- /// (generic: <see cref="T:C5.IComparable`1"/> or non-generic: System.IComparable) or it can\r
- /// be external and supplied by the user in the constructor.\r
- /// <br/>\r
- /// Each distinct item is only kept in one place in the tree - together with the number\r
- /// of times it is a member of the bag. Thus, if two items that are equal according\r
- /// </summary>\r
-#else\r
- /// <summary>\r
- /// An implementation of Red-Black trees as an indexed, sorted collection with set semantics,\r
- /// cf. <a href="litterature.htm#CLRS">CLRS</a>. <see cref="T:C5.TreeBag`1"/> for a version \r
- /// with bag semantics. <see cref="T:C5.TreeDictionary`2"/> for a sorted dictionary \r
- /// based on this tree implementation.\r
- /// <i>\r
- /// The comparer (sorting order) may be either natural, because the item type is comparable \r
- /// (generic: <see cref="T:C5.IComparable`1"/> or non-generic: System.IComparable) or it can\r
- /// be external and supplied by the user in the constructor.</i>\r
- ///\r
- /// <i>TODO: describe performance here</i>\r
- /// <i>TODO: discuss persistence and its useful usage modes. Warn about the space\r
- /// leak possible with other usage modes.</i>\r
- /// </summary>\r
-#endif\r
- [Serializable]\r
- public class TreeSet<T> : SequencedBase<T>, IIndexedSorted<T>, IPersistentSorted<T>\r
- {\r
- #region Fields\r
-\r
- SCG.IComparer<T> comparer;\r
-\r
- Node root;\r
-\r
- //TODO: wonder if we should remove that\r
- int blackdepth = 0;\r
-\r
- //We double these stacks for the iterative add and remove on demand\r
- //TODO: refactor dirs[] into bool fields on Node (?)\r
- private int[] dirs = new int[2];\r
-\r
- private Node[] path = new Node[2];\r
-#if NCP\r
- //TODO: refactor into separate class\r
- bool isSnapShot = false;\r
-\r
- int generation;\r
-\r
- bool isValid = true;\r
-\r
- SnapRef snapList;\r
-#endif\r
- #endregion\r
-\r
- #region Events\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public override EventTypeEnum ListenableEvents { get { return EventTypeEnum.Basic; } }\r
-\r
- #endregion\r
- #region Util\r
-\r
- /// <summary>\r
- /// Fetch the left child of n taking node-copying persistence into\r
- /// account if relevant. \r
- /// </summary>\r
- /// <param name="n"></param>\r
- /// <returns></returns>\r
- private Node left(Node n)\r
- {\r
-#if NCP\r
- if (isSnapShot)\r
- {\r
-#if SEPARATE_EXTRA\r
- Node.Extra e = n.extra;\r
-\r
- if (e != null && e.lastgeneration >= treegen && e.leftnode)\r
- return e.oldref;\r
-#else\r
- if (n.lastgeneration >= generation && n.leftnode)\r
- return n.oldref;\r
-#endif\r
- }\r
-#endif\r
- return n.left;\r
- }\r
-\r
-\r
- private Node right(Node n)\r
- {\r
-#if NCP\r
- if (isSnapShot)\r
- {\r
-#if SEPARATE_EXTRA\r
- Node.Extra e = n.extra;\r
-\r
- if (e != null && e.lastgeneration >= treegen && !e.leftnode)\r
- return e.oldref;\r
-#else\r
- if (n.lastgeneration >= generation && !n.leftnode)\r
- return n.oldref;\r
-#endif\r
- }\r
-#endif\r
- return n.right;\r
- }\r
-\r
-\r
- //This method should be called by methods that use the internal \r
- //traversal stack, unless certain that there is room enough\r
- private void stackcheck()\r
- {\r
- while (dirs.Length < 2 * blackdepth)\r
- {\r
- dirs = new int[2 * dirs.Length];\r
- path = new Node[2 * dirs.Length];\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region Node nested class\r
-\r
-\r
- /// <summary>\r
- /// The type of node in a Red-Black binary tree\r
- /// </summary>\r
- [Serializable]\r
- class Node\r
- {\r
- public bool red = true;\r
-\r
- public T item;\r
-\r
- public Node left;\r
-\r
- public Node right;\r
-\r
-#if MAINTAIN_SIZE\r
- public int size = 1;\r
-#endif\r
-\r
-#if BAG\r
- public int items = 1;\r
-#endif\r
-\r
-#if NCP\r
- //TODO: move everything into (separate) Extra\r
- public int generation;\r
-#if SEPARATE_EXTRA\r
- internal class Extra\r
- {\r
- public int lastgeneration;\r
-\r
- public Node oldref;\r
-\r
- public bool leftnode;\r
-\r
- //public Node next;\r
- }\r
-\r
- public Extra extra;\r
-\r
-#else\r
- public int lastgeneration = -1;\r
-\r
- public Node oldref;\r
-\r
- public bool leftnode;\r
-#endif\r
-\r
- /// <summary>\r
- /// Update a child pointer\r
- /// </summary>\r
- /// <param name="cursor"></param>\r
- /// <param name="leftnode"></param>\r
- /// <param name="child"></param>\r
- /// <param name="maxsnapid"></param>\r
- /// <param name="generation"></param>\r
- /// <returns>True if node was *copied*</returns>\r
- internal static bool update(ref Node cursor, bool leftnode, Node child, int maxsnapid, int generation)\r
- {\r
- Node oldref = leftnode ? cursor.left : cursor.right;\r
-\r
- if (child == oldref)\r
- return false;\r
-\r
- bool retval = false;\r
-\r
- if (cursor.generation <= maxsnapid)\r
- {\r
-#if SEPARATE_EXTRA\r
- if (cursor.extra == null)\r
- {\r
- Extra extra = cursor.extra = new Extra(); \r
-\r
- extra.leftnode = leftnode;\r
- extra.lastgeneration = maxsnapid;\r
- extra.oldref = oldref;\r
- }\r
- else if (cursor.extra.leftnode != leftnode || cursor.extra.lastgeneration < maxsnapid)\r
-#else\r
- if (cursor.lastgeneration == -1)\r
- {\r
- cursor.leftnode = leftnode;\r
- cursor.lastgeneration = maxsnapid;\r
- cursor.oldref = oldref;\r
- }\r
- else if (cursor.leftnode != leftnode || cursor.lastgeneration < maxsnapid)\r
-#endif\r
- {\r
- CopyNode(ref cursor, maxsnapid, generation);\r
- retval = true;\r
- }\r
- }\r
-\r
- if (leftnode)\r
- cursor.left = child;\r
- else\r
- cursor.right = child;\r
-\r
- return retval;\r
- }\r
-\r
-\r
- //If cursor.extra.lastgeneration==maxsnapid, the extra pointer will \r
- //always be used in the old copy of cursor. Therefore, after \r
- //making the clone, we should update the old copy by restoring\r
- //the child pointer and setting extra to null.\r
- //OTOH then we cannot clean up unused Extra objects unless we link\r
- //them together in a doubly linked list.\r
- public static bool CopyNode(ref Node cursor, int maxsnapid, int generation)\r
- {\r
- if (cursor.generation <= maxsnapid)\r
- {\r
- cursor = (Node)(cursor.MemberwiseClone());\r
- cursor.generation = generation;\r
-#if SEPARATE_EXTRA\r
- cursor.extra = null;\r
-#else\r
- cursor.lastgeneration = -1;\r
-#endif\r
- return true;\r
- }\r
- else\r
- return false;\r
- }\r
-\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region Constructors\r
-\r
- /// <summary>\r
- /// Create a red-black tree collection with natural comparer and item equalityComparer.\r
- /// We assume that if <code>T</code> is comparable, its default equalityComparer \r
- /// will be compatible with the comparer.\r
- /// </summary>\r
- /// <exception cref="NotComparableException">If <code>T</code> is not comparable.\r
- /// </exception>\r
- public TreeSet() : this(Comparer<T>.Default, EqualityComparer<T>.Default) { }\r
-\r
-\r
- /// <summary>\r
- /// Create a red-black tree collection with an external comparer. \r
- /// <para>The itemequalityComparer will be a compatible \r
- /// <see cref="T:C5.ComparerZeroHashCodeEqualityComparer`1"/> since the \r
- /// default equalityComparer for T (<see cref="P:C5.EqualityComparer`1.Default"/>)\r
- /// is unlikely to be compatible with the external comparer. This makes the\r
- /// tree inadequate for use as item in a collection of unsequenced or sequenced sets or bags\r
- /// (<see cref="T:C5.ICollection`1"/> and <see cref="T:C5.ISequenced`1"/>)\r
- /// </para>\r
- /// </summary>\r
- /// <param name="comparer">The external comparer</param>\r
- public TreeSet(SCG.IComparer<T> comparer) : this(comparer, new ComparerZeroHashCodeEqualityComparer<T>(comparer)) { }\r
-\r
- /// <summary>\r
- /// Create a red-black tree collection with an external comparer and an external\r
- /// item equalityComparer, assumed consistent.\r
- /// </summary>\r
- /// <param name="comparer">The external comparer</param>\r
- /// <param name="equalityComparer">The external item equalityComparer</param>\r
- public TreeSet(SCG.IComparer<T> comparer, SCG.IEqualityComparer<T> equalityComparer)\r
- : base(equalityComparer)\r
- {\r
- if (comparer == null)\r
- throw new NullReferenceException("Item comparer cannot be null");\r
- this.comparer = comparer;\r
- }\r
-\r
- #endregion\r
-\r
- #region TreeSet.Enumerator nested class\r
-\r
- /// <summary>\r
- /// An enumerator for a red-black tree collection. Based on an explicit stack\r
- /// of subtrees waiting to be enumerated. Currently only used for the tree set \r
- /// enumerators (tree bag enumerators use an iterator block based enumerator).\r
- /// </summary>\r
- internal class Enumerator : SCG.IEnumerator<T>\r
- {\r
- #region Private Fields\r
- TreeSet<T> tree;\r
-\r
- bool valid = false;\r
-\r
- int stamp;\r
-\r
- T current;\r
-\r
- Node cursor;\r
-\r
- Node[] path; // stack of nodes\r
-\r
- int level = 0;\r
- #endregion\r
- /// <summary>\r
- /// Create a tree enumerator\r
- /// </summary>\r
- /// <param name="tree">The red-black tree to enumerate</param>\r
- public Enumerator(TreeSet<T> tree)\r
- {\r
- this.tree = tree;\r
- stamp = tree.stamp;\r
- path = new Node[2 * tree.blackdepth];\r
- cursor = new Node();\r
- cursor.right = tree.root;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Undefined if enumerator is not valid (MoveNext hash been called returning true)\r
- /// </summary>\r
- /// <value>The current item of the enumerator.</value>\r
- [Tested]\r
- public T Current\r
- {\r
- [Tested]\r
- get\r
- {\r
- if (valid)\r
- return current;\r
- else\r
- throw new InvalidOperationException();\r
- }\r
- }\r
-\r
-\r
- //Maintain a stack of nodes that are roots of\r
- //subtrees not completely exported yet. Invariant:\r
- //The stack nodes together with their right subtrees\r
- //consists of exactly the items we have not passed\r
- //yet (the top of the stack holds current item).\r
- /// <summary>\r
- /// Move enumerator to next item in tree, or the first item if\r
- /// this is the first call to MoveNext. \r
- /// <exception cref="CollectionModifiedException"/> if underlying tree was modified.\r
- /// </summary>\r
- /// <returns>True if enumerator is valid now</returns>\r
- [Tested]\r
- public bool MoveNext()\r
- {\r
- tree.modifycheck(stamp);\r
- if (cursor.right != null)\r
- {\r
- path[level] = cursor = cursor.right;\r
- while (cursor.left != null)\r
- path[++level] = cursor = cursor.left;\r
- }\r
- else if (level == 0)\r
- return valid = false;\r
- else\r
- cursor = path[--level];\r
-\r
- current = cursor.item;\r
- return valid = true;\r
- }\r
-\r
-\r
- #region IDisposable Members for Enumerator\r
-\r
- bool disposed;\r
-\r
-\r
- /// <summary>\r
- /// Call Dispose(true) and then suppress finalization of this enumerator.\r
- /// </summary>\r
- [Tested]\r
- public void Dispose()\r
- {\r
- Dispose(true);\r
- GC.SuppressFinalize(this);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the internal data (notably the stack array).\r
- /// </summary>\r
- /// <param name="disposing">True if called from Dispose(),\r
- /// false if called from the finalizer</param>\r
- protected virtual void Dispose(bool disposing)\r
- {\r
- if (!disposed)\r
- {\r
- if (disposing)\r
- {\r
- }\r
-\r
- current = default(T);\r
- cursor = null;\r
- path = null;\r
- disposed = true;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Finalizer for enumerator\r
- /// </summary>\r
- ~Enumerator()\r
- {\r
- Dispose(false);\r
- }\r
- #endregion\r
-\r
-\r
- #region IEnumerator Members\r
-\r
- object System.Collections.IEnumerator.Current\r
- {\r
- get { return Current; }\r
- }\r
-\r
- bool System.Collections.IEnumerator.MoveNext()\r
- {\r
- return MoveNext();\r
- }\r
-\r
- void System.Collections.IEnumerator.Reset()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
-\r
- #endregion\r
- }\r
-#if NCP\r
- /// <summary>\r
- /// An enumerator for a snapshot of a node copy persistent red-black tree\r
- /// collection.\r
- /// </summary>\r
- internal class SnapEnumerator : SCG.IEnumerator<T>\r
- {\r
- #region Private Fields\r
- TreeSet<T> tree;\r
-\r
- bool valid = false;\r
-\r
- int stamp;\r
-#if BAG\r
- int togo;\r
-#endif\r
-\r
- T current;\r
-\r
- Node cursor;\r
-\r
- Node[] path; // stack of nodes\r
-\r
- int level;\r
- #endregion\r
-\r
- /// <summary>\r
- /// Creta an enumerator for a snapshot of a node copy persistent red-black tree\r
- /// collection\r
- /// </summary>\r
- /// <param name="tree">The snapshot</param>\r
- public SnapEnumerator(TreeSet<T> tree)\r
- {\r
- this.tree = tree;\r
- stamp = tree.stamp;\r
- path = new Node[2 * tree.blackdepth];\r
- cursor = new Node();\r
- cursor.right = tree.root;\r
- }\r
-\r
-\r
- #region SCG.IEnumerator<T> Members\r
-\r
- /// <summary>\r
- /// Move enumerator to next item in tree, or the first item if\r
- /// this is the first call to MoveNext. \r
- /// <exception cref="CollectionModifiedException"/> if underlying tree was modified.\r
- /// </summary>\r
- /// <returns>True if enumerator is valid now</returns>\r
- [Tested]\r
- public bool MoveNext()\r
- {\r
- tree.modifycheck(stamp);//???\r
-\r
-#if BAG\r
- if (--togo > 0)\r
- return true;\r
-#endif\r
- Node next = tree.right(cursor);\r
-\r
- if (next != null)\r
- {\r
- path[level] = cursor = next;\r
- next = tree.left(cursor);\r
- while (next != null)\r
- {\r
- path[++level] = cursor = next;\r
- next = tree.left(cursor);\r
- }\r
- }\r
- else if (level == 0)\r
- return valid = false;\r
- else\r
- cursor = path[--level];\r
-\r
-#if BAG\r
- togo = cursor.items;\r
-#endif\r
- current = cursor.item;\r
- return valid = true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Undefined if enumerator is not valid (MoveNext hash been called returning true)\r
- /// </summary>\r
- /// <value>The current value of the enumerator.</value>\r
- [Tested]\r
- public T Current\r
- {\r
- [Tested]\r
- get\r
- {\r
- if (valid)\r
- return current;\r
- else\r
- throw new InvalidOperationException();\r
- }\r
- }\r
-\r
- #endregion\r
-\r
- #region IDisposable Members\r
-\r
- [Tested]\r
- void System.IDisposable.Dispose()\r
- {\r
- tree = null;\r
- valid = false;\r
- current = default(T);\r
- cursor = null;\r
- path = null;\r
- }\r
-\r
- #endregion\r
-\r
- #region IEnumerator Members\r
-\r
- object System.Collections.IEnumerator.Current\r
- {\r
- get { return Current; }\r
- }\r
-\r
- bool System.Collections.IEnumerator.MoveNext()\r
- {\r
- return MoveNext();\r
- }\r
-\r
- void System.Collections.IEnumerator.Reset()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
-\r
- #endregion\r
- }\r
-#endif\r
- #endregion\r
-\r
- #region IEnumerable<T> Members\r
-\r
- private SCG.IEnumerator<T> getEnumerator(Node node, int origstamp)\r
- {\r
- if (node == null)\r
- yield break;\r
-\r
- if (node.left != null)\r
- {\r
- SCG.IEnumerator<T> child = getEnumerator(node.left, origstamp);\r
-\r
- while (child.MoveNext())\r
- {\r
- modifycheck(origstamp);\r
- yield return child.Current;\r
- }\r
- }\r
-#if BAG\r
- int togo = node.items;\r
- while (togo-- > 0)\r
- {\r
- modifycheck(origstamp);\r
- yield return node.item;\r
- }\r
-#else\r
- modifycheck(origstamp);\r
- yield return node.item;\r
-#endif\r
- if (node.right != null)\r
- {\r
- SCG.IEnumerator<T> child = getEnumerator(node.right, origstamp);\r
-\r
- while (child.MoveNext())\r
- {\r
- modifycheck(origstamp);\r
- yield return child.Current;\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <exception cref="NoSuchItemException">If tree is empty</exception>\r
- /// <returns></returns>\r
- [Tested]\r
- public override T Choose()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
-\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- return root.item;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create an enumerator for this tree\r
- /// </summary>\r
- /// <returns>The enumerator</returns>\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
-#if NCP\r
- if (isSnapShot)\r
- return new SnapEnumerator(this);\r
-#endif\r
-#if BAG\r
- return getEnumerator(root, stamp);\r
-#else\r
- return new Enumerator(this);\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region ISink<T> Members\r
-\r
- /// <summary>\r
- /// Add item to tree. If already there, return the found item in the second argument.\r
- /// </summary>\r
- /// <param name="item">Item to add</param>\r
- /// <param name="founditem">item found</param>\r
- /// <param name="update">whether item in node should be updated</param>\r
- /// <param name="wasfound">true if found in bag, false if not found or tre is a set</param>\r
- /// <returns>True if item was added</returns>\r
- bool addIterative(T item, ref T founditem, bool update, out bool wasfound)\r
- {\r
- wasfound = false;\r
- if (root == null)\r
- {\r
- root = new Node();\r
- root.red = false;\r
- blackdepth = 1;\r
- root.item = item;\r
-#if NCP\r
- root.generation = generation;\r
-#endif\r
- return true;\r
- }\r
-\r
- stackcheck();\r
-\r
- int level = 0;\r
- Node cursor = root;\r
-\r
- while (true)\r
- {\r
- int comp = comparer.Compare(cursor.item, item);\r
-\r
- if (comp == 0)\r
- {\r
- founditem = cursor.item;\r
-#if BAG\r
- wasfound = true;\r
- bool nodeWasUpdated = true;\r
-#if NCP\r
- Node.CopyNode(ref cursor, maxsnapid, generation);\r
-#endif\r
- if (update)\r
- cursor.item = item;\r
- else\r
- {\r
- cursor.items++;\r
- cursor.size++;\r
- }\r
-#else\r
- bool nodeWasUpdated = update;\r
- if (update)\r
- {\r
-#if NCP\r
- Node.CopyNode(ref cursor, maxsnapid, generation);\r
-#endif\r
- cursor.item = item;\r
- }\r
-#endif\r
-\r
- while (level-- > 0)\r
- {\r
- if (nodeWasUpdated)\r
- {\r
- Node kid = cursor;\r
-\r
- cursor = path[level];\r
-#if NCP\r
- Node.update(ref cursor, dirs[level] > 0, kid, maxsnapid, generation);\r
-#endif\r
-#if BAG\r
- if (!update)\r
- cursor.size++;\r
-#endif\r
- }\r
-\r
- path[level] = null;\r
- }\r
-#if BAG\r
- return !update;\r
-#else\r
- if (update)\r
- root = cursor;\r
-\r
- return false;\r
-#endif\r
- }\r
-\r
- //else\r
- Node child = comp > 0 ? cursor.left : cursor.right;\r
-\r
- if (child == null)\r
- {\r
- child = new Node();\r
- child.item = item;\r
-#if NCP\r
- child.generation = generation;\r
- Node.update(ref cursor, comp > 0, child, maxsnapid, generation);\r
-#else\r
- if (comp > 0) { cursor.left = child; }\r
- else { cursor.right = child; }\r
-#endif\r
-#if MAINTAIN_SIZE\r
- cursor.size++;\r
-#endif\r
- dirs[level] = comp;\r
- break;\r
- }\r
- else\r
- {\r
- dirs[level] = comp;\r
- path[level++] = cursor;\r
- cursor = child;\r
- }\r
- }\r
-\r
- //We have just added the red node child to "cursor"\r
- while (cursor.red)\r
- {\r
- //take one step up:\r
- Node child = cursor;\r
-\r
- cursor = path[--level];\r
- path[level] = null;\r
-#if NCP\r
- Node.update(ref cursor, dirs[level] > 0, child, maxsnapid, generation);\r
-#endif\r
-#if MAINTAIN_SIZE\r
- cursor.size++;\r
-#endif\r
- int comp = dirs[level];\r
- Node childsibling = comp > 0 ? cursor.right : cursor.left;\r
-\r
- if (childsibling != null && childsibling.red)\r
- {\r
- //Promote\r
- child.red = false;\r
-#if NCP\r
- Node.update(ref cursor, comp < 0, childsibling, maxsnapid, generation);\r
-#endif\r
- childsibling.red = false;\r
-\r
- //color cursor red & take one step up the tree unless at root\r
- if (level == 0)\r
- {\r
- root = cursor;\r
- blackdepth++;\r
- return true;\r
- }\r
- else\r
- {\r
- cursor.red = true;\r
-#if NCP\r
- child = cursor;\r
- cursor = path[--level];\r
- Node.update(ref cursor, dirs[level] > 0, child, maxsnapid, generation);\r
-#endif\r
- path[level] = null;\r
-#if MAINTAIN_SIZE\r
- cursor.size++;\r
-#endif\r
- }\r
- }\r
- else\r
- {\r
- //ROTATE!!!\r
- int childcomp = dirs[level + 1];\r
-\r
- cursor.red = true;\r
- if (comp > 0)\r
- {\r
- if (childcomp > 0)\r
- {//zagzag\r
-#if NCP\r
- Node.update(ref cursor, true, child.right, maxsnapid, generation);\r
- Node.update(ref child, false, cursor, maxsnapid, generation);\r
-#else\r
- cursor.left = child.right;\r
- child.right = cursor;\r
-#endif\r
- cursor = child;\r
- }\r
- else\r
- {//zagzig\r
- Node badgrandchild = child.right;\r
-#if NCP\r
- Node.update(ref cursor, true, badgrandchild.right, maxsnapid, generation);\r
- Node.update(ref child, false, badgrandchild.left, maxsnapid, generation);\r
- Node.CopyNode(ref badgrandchild, maxsnapid, generation);\r
-#else\r
- cursor.left = badgrandchild.right;\r
- child.right = badgrandchild.left;\r
-#endif\r
- badgrandchild.left = child;\r
- badgrandchild.right = cursor;\r
- cursor = badgrandchild;\r
- }\r
- }\r
- else\r
- {//comp < 0\r
- if (childcomp < 0)\r
- {//zigzig\r
-#if NCP\r
- Node.update(ref cursor, false, child.left, maxsnapid, generation);\r
- Node.update(ref child, true, cursor, maxsnapid, generation);\r
-#else\r
- cursor.right = child.left;\r
- child.left = cursor;\r
-#endif\r
- cursor = child;\r
- }\r
- else\r
- {//zigzag\r
- Node badgrandchild = child.left;\r
-#if NCP\r
- Node.update(ref cursor, false, badgrandchild.left, maxsnapid, generation);\r
- Node.update(ref child, true, badgrandchild.right, maxsnapid, generation);\r
- Node.CopyNode(ref badgrandchild, maxsnapid, generation);\r
-#else\r
- cursor.right = badgrandchild.left;\r
- child.left = badgrandchild.right;\r
-#endif\r
- badgrandchild.right = child;\r
- badgrandchild.left = cursor;\r
- cursor = badgrandchild;\r
- }\r
- }\r
-\r
- cursor.red = false;\r
-\r
-#if MAINTAIN_SIZE\r
- Node n;\r
-\r
-#if BAG\r
- n = cursor.right;\r
- cursor.size = n.size = (n.left == null ? 0 : n.left.size) + (n.right == null ? 0 : n.right.size) + n.items;\r
- n = cursor.left;\r
- n.size = (n.left == null ? 0 : n.left.size) + (n.right == null ? 0 : n.right.size) + n.items;\r
- cursor.size += n.size + cursor.items;\r
-#else\r
- n = cursor.right;\r
- cursor.size = n.size = (n.left == null ? 0 : n.left.size) + (n.right == null ? 0 : n.right.size) + 1;\r
- n = cursor.left;\r
- n.size = (n.left == null ? 0 : n.left.size) + (n.right == null ? 0 : n.right.size) + 1;\r
- cursor.size += n.size + 1;\r
-#endif\r
-#endif\r
- if (level == 0)\r
- {\r
- root = cursor;\r
- return true;\r
- }\r
- else\r
- {\r
- child = cursor;\r
- cursor = path[--level];\r
- path[level] = null;\r
-#if NCP\r
- Node.update(ref cursor, dirs[level] > 0, child, maxsnapid, generation);\r
-#else\r
- if (dirs[level] > 0)\r
- cursor.left = child;\r
- else\r
- cursor.right = child;\r
-#endif\r
-#if MAINTAIN_SIZE\r
- cursor.size++;\r
-#endif\r
- break;\r
- }\r
- }\r
- }\r
-#if NCP\r
- bool stillmore = true;\r
-#endif\r
- while (level > 0)\r
- {\r
- Node child = cursor;\r
-\r
- cursor = path[--level];\r
- path[level] = null;\r
-#if NCP\r
- if (stillmore)\r
- stillmore = Node.update(ref cursor, dirs[level] > 0, child, maxsnapid, generation);\r
-#endif\r
-#if MAINTAIN_SIZE\r
- cursor.size++;\r
-#endif\r
- }\r
-\r
- root = cursor;\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Add an item to this collection if possible. If this collection has set\r
- /// semantics, the item will be added if not already in the collection. If\r
- /// bag semantics, the item will always be added.\r
- /// </summary>\r
- /// <param name="item">The item to add.</param>\r
- /// <returns>True if item was added.</returns>\r
- [Tested]\r
- public bool Add(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- //Note: blackdepth of the tree is set inside addIterative\r
- T jtem = default(T);\r
- if (!add(item, ref jtem))\r
- return false;\r
- if (ActiveEvents != 0)\r
- raiseForAdd(jtem);\r
- return true;\r
- }\r
-\r
- private bool add(T item, ref T j)\r
- {\r
- bool wasFound;\r
-\r
- if (addIterative(item, ref j, false, out wasFound))\r
- {\r
- size++;\r
- if (!wasFound)\r
- j = item;\r
- return true;\r
- }\r
- else\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// Add the elements from another collection with a more specialized item type \r
- /// to this collection. If this\r
- /// collection has set semantics, only items not already in the collection\r
- /// will be added.\r
- /// </summary>\r
- /// <typeparam name="U">The type of items to add</typeparam>\r
- /// <param name="items">The items to add</param>\r
- [Tested]\r
- public void AddAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- int c = 0;\r
- T j = default(T);\r
- bool tmp;\r
-\r
- bool raiseAdded = (ActiveEvents & EventTypeEnum.Added) != 0;\r
- CircularQueue<T> wasAdded = raiseAdded ? new CircularQueue<T>() : null;\r
-\r
- foreach (T i in items)\r
- if (addIterative(i, ref j, false, out tmp))\r
- {\r
- c++;\r
- if (raiseAdded)\r
- wasAdded.Enqueue(tmp ? j : i);\r
- }\r
- if (c == 0)\r
- return;\r
-\r
- size += c;\r
- //TODO: implement a RaiseForAddAll() method\r
- if (raiseAdded)\r
- foreach (T item in wasAdded)\r
- raiseItemsAdded(item, 1);\r
- if (((ActiveEvents & EventTypeEnum.Changed) != 0))\r
- raiseCollectionChanged();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Add all the items from another collection with an enumeration order that \r
- /// is increasing in the items. <para>The idea is that the implementation may use\r
- /// a faster algorithm to merge the two collections.</para>\r
- /// <exception cref="ArgumentException"/> if the enumerated items turns out\r
- /// not to be in increasing order.\r
- /// </summary>\r
- /// <param name="items">The collection to add.</param>\r
- /// <typeparam name="U"></typeparam>\r
- [Tested]\r
- public void AddSorted<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- if (size > 0)\r
- AddAll(items);\r
- else\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- addSorted(items, true, true);\r
- }\r
- }\r
-\r
- #region add-sorted helpers\r
-\r
- //Create a RB tree from x+2^h-1 (x < 2^h, h>=1) nodes taken from a\r
- //singly linked list of red nodes using only the right child refs.\r
- //The x nodes at depth h+1 will be red, the rest black.\r
- //(h is the blackdepth of the resulting tree)\r
- static Node maketreer(ref Node rest, int blackheight, int maxred, int red)\r
- {\r
- if (blackheight == 1)\r
- {\r
- Node top = rest;\r
-\r
- rest = rest.right;\r
- if (red > 0)\r
- {\r
- top.right = null;\r
- rest.left = top;\r
- top = rest;\r
-#if BAG\r
- top.size += top.left.size;\r
-#elif MAINTAIN_SIZE\r
- top.size = 1 + red;\r
-#endif\r
- rest = rest.right;\r
- red--;\r
- }\r
-\r
- if (red > 0)\r
- {\r
-#if BAG\r
- top.size += rest.size;\r
-#endif\r
- top.right = rest;\r
- rest = rest.right;\r
- top.right.right = null;\r
- }\r
- else\r
- top.right = null;\r
-\r
- top.red = false;\r
- return top;\r
- }\r
- else\r
- {\r
- maxred >>= 1;\r
-\r
- int lred = red > maxred ? maxred : red;\r
- Node left = maketreer(ref rest, blackheight - 1, maxred, lred);\r
- Node top = rest;\r
-\r
- rest = rest.right;\r
- top.left = left;\r
- top.red = false;\r
- top.right = maketreer(ref rest, blackheight - 1, maxred, red - lred);\r
-#if BAG\r
- top.size = top.items + top.left.size + top.right.size;\r
-#elif MAINTAIN_SIZE\r
- top.size = (maxred << 1) - 1 + red;\r
-#endif\r
- return top;\r
- }\r
- }\r
-\r
-\r
- void addSorted<U>(SCG.IEnumerable<U> items, bool safe, bool raise) where U : T\r
- {\r
- SCG.IEnumerator<U> e = items.GetEnumerator(); ;\r
- if (size > 0)\r
- throw new InternalException("This can't happen");\r
-\r
- if (!e.MoveNext())\r
- return;\r
-\r
- //To count theCollect \r
- Node head = new Node(), tail = head;\r
- int z = 1;\r
- T lastitem = tail.item = e.Current;\r
-#if BAG\r
- int ec = 0;\r
-#endif\r
-\r
- while (e.MoveNext())\r
- {\r
-#if BAG\r
- T thisitem = e.Current;\r
- int comp = comparer.Compare(lastitem, thisitem);\r
- if (comp > 0)\r
- throw new ArgumentException("Argument not sorted");\r
- if (comp == 0)\r
- {\r
- tail.items++;\r
- ec++;\r
- }\r
- else\r
- {\r
- tail.size = tail.items;\r
- z++;\r
- tail.right = new Node();\r
- tail = tail.right;\r
- lastitem = tail.item = thisitem;\r
-#if NCP\r
- tail.generation = generation;\r
-#endif\r
- }\r
-#else\r
- z++;\r
- tail.right = new Node();\r
- tail = tail.right;\r
- tail.item = e.Current;\r
- if (safe)\r
- {\r
- if (comparer.Compare(lastitem, tail.item) >= 0)\r
- throw new ArgumentException("Argument not sorted");\r
-\r
- lastitem = tail.item;\r
- }\r
-#if NCP\r
- tail.generation = generation;\r
-#endif\r
-#endif\r
- }\r
-#if BAG\r
- tail.size = tail.items;\r
-#endif\r
- int blackheight = 0, red = z, maxred = 1;\r
-\r
- while (maxred <= red)\r
- {\r
- red -= maxred;\r
- maxred <<= 1;\r
- blackheight++;\r
- }\r
-\r
- root = TreeSet<T>.maketreer(ref head, blackheight, maxred, red);\r
- blackdepth = blackheight;\r
- size = z;\r
-#if BAG\r
- size += ec;\r
-#endif\r
-\r
- if (raise)\r
- {\r
- if ((ActiveEvents & EventTypeEnum.Added) != 0)\r
- {\r
- CircularQueue<T> wasAdded = new CircularQueue<T>();\r
- foreach (T item in this)\r
- wasAdded.Enqueue(item);\r
- foreach (T item in wasAdded)\r
- raiseItemsAdded(item, 1);\r
- }\r
- if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
- return;\r
- }\r
-\r
- #endregion\r
-\r
-#if BAG\r
- /// <summary></summary>\r
- /// <value>True since this collection has bag semantics.</value>\r
- [Tested]\r
- public bool AllowsDuplicates { [Tested]get { return true; } }\r
-#else\r
- /// <summary></summary>\r
- /// <value>False since this tree has set semantics.</value>\r
- [Tested]\r
- public bool AllowsDuplicates { [Tested]get { return false; } }\r
-#endif\r
- /// <summary>\r
- /// By convention this is true for any collection with set semantics.\r
- /// </summary>\r
- /// <value>True if only one representative of a group of equal items \r
- /// is kept in the collection together with the total count.</value>\r
- public virtual bool DuplicatesByCounting { get { return true; } }\r
-\r
- #endregion\r
-\r
- #region IEditableCollection<T> Members\r
-\r
-\r
- /// <summary>\r
- /// The value is symbolic indicating the type of asymptotic complexity\r
- /// in terms of the size of this collection (worst-case or amortized as\r
- /// relevant).\r
- /// </summary>\r
- /// <value>Speed.Log</value>\r
- [Tested]\r
- public Speed ContainsSpeed { [Tested]get { return Speed.Log; } }\r
-\r
- /// <summary>\r
- /// Check if this collection contains (an item equivalent to according to the\r
- /// itemequalityComparer) a particular value.\r
- /// </summary>\r
- /// <param name="item">The value to check for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public bool Contains(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- Node next; int comp = 0;\r
-\r
- next = root;\r
- while (next != null)\r
- {\r
- comp = comparer.Compare(next.item, item);\r
- if (comp == 0)\r
- return true;\r
-\r
- next = comp < 0 ? right(next) : left(next);\r
- }\r
-\r
- return false;\r
- }\r
-\r
-\r
- //Variant for dictionary use\r
- //Will return the actual matching item in the ref argument.\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, return in the ref argument (a\r
- /// binary copy of) the actual value found.\r
- /// </summary>\r
- /// <param name="item">The value to look for.</param>\r
- /// <returns>True if the items is in this collection.</returns>\r
- [Tested]\r
- public bool Find(ref T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- Node next; int comp = 0;\r
-\r
- next = root;\r
- while (next != null)\r
- {\r
- comp = comparer.Compare(next.item, item);\r
- if (comp == 0)\r
- {\r
- item = next.item;\r
- return true;\r
- }\r
-\r
- next = comp < 0 ? right(next) : left(next);\r
- }\r
-\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find or add the item to the tree. If the tree does not contain\r
- /// an item equivalent to this item add it, else return the exisiting\r
- /// one in the ref argument. \r
- ///\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns>True if item was found</returns>\r
- [Tested]\r
- public bool FindOrAdd(ref T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- bool wasfound;\r
-\r
- //Note: blackdepth of the tree is set inside addIterative\r
- if (addIterative(item, ref item, false, out wasfound))\r
- {\r
- size++;\r
- if (ActiveEvents != 0 && !wasfound)\r
- raiseForAdd(item);\r
- return wasfound;\r
- }\r
- else\r
- return true;\r
-\r
- }\r
-\r
-\r
- //For dictionary use. \r
- //If found, the matching entry will be updated with the new item.\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// to with a binary copy of the supplied value. If the collection has bag semantics,\r
- /// this updates all equivalent copies in\r
- /// the collection.\r
- /// </summary>\r
- /// <param name="item">Value to update.</param>\r
- /// <returns>True if the item was found and hence updated.</returns>\r
- [Tested]\r
- public bool Update(T item)\r
- {\r
- T olditem = item;\r
- return Update(item, out olditem);\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// with a binary copy of the supplied value. If the collection has bag semantics,\r
- /// this updates all equivalent copies in\r
- /// the collection.\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public bool Update(T item, out T olditem)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-#if NCP\r
- stackcheck();\r
-\r
- int level = 0;\r
-#endif\r
- Node cursor = root;\r
- int comp = 0;\r
-\r
- while (cursor != null)\r
- {\r
- comp = comparer.Compare(cursor.item, item);\r
- if (comp == 0)\r
- {\r
-#if NCP\r
- Node.CopyNode(ref cursor, maxsnapid, generation);\r
-#endif\r
- olditem = cursor.item;\r
-#if BAG\r
- int items = cursor.items;\r
-#endif\r
- cursor.item = item;\r
-#if NCP\r
- while (level > 0)\r
- {\r
- Node child = cursor;\r
-\r
- cursor = path[--level];\r
- path[level] = null;\r
-#if NCP\r
- Node.update(ref cursor, dirs[level] > 0, child, maxsnapid, generation);\r
-#else\r
- if (Node.CopyNode(maxsnapid, ref cursor, generation))\r
- {\r
- if (dirs[level] > 0)\r
- cursor.left = child;\r
- else\r
- cursor.right = child;\r
- }\r
-#endif\r
- }\r
-\r
- root = cursor;\r
-#endif\r
-#if BAG\r
- if (ActiveEvents != 0)\r
- raiseForUpdate(item, olditem, items);\r
-#else\r
- if (ActiveEvents != 0)\r
- raiseForUpdate(item, olditem);\r
-#endif\r
- return true;\r
- }\r
-#if NCP\r
- dirs[level] = comp;\r
- path[level++] = cursor;\r
-#endif\r
- cursor = comp < 0 ? cursor.right : cursor.left;\r
- }\r
-\r
- olditem = default(T);\r
- return false;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Check if this collection contains an item equivalent according to the\r
- /// itemequalityComparer to a particular value. If so, update the item in the collection \r
- /// with a binary copy of the supplied value; else add the value to the collection. \r
- ///\r
- /// <i>NOTE: the bag implementation is currently wrong! ?????</i>\r
- /// </summary>\r
- /// <param name="item">Value to add or update.</param>\r
- /// <returns>True if the item was found and updated (hence not added).</returns>\r
- [Tested]\r
- public bool UpdateOrAdd(T item)\r
- { T olditem; return UpdateOrAdd(item, out olditem); }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <param name="olditem"></param>\r
- /// <returns></returns>\r
- public bool UpdateOrAdd(T item, out T olditem)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- bool wasfound;\r
- olditem = default(T);\r
-\r
-\r
- //Note: blackdepth of the tree is set inside addIterative\r
- if (addIterative(item, ref olditem, true, out wasfound))\r
- {\r
- size++;\r
- if (ActiveEvents != 0)\r
- raiseForAdd(wasfound ? olditem : item);\r
- return wasfound;\r
- }\r
- else\r
- {\r
-#warning for bag implementation: count is wrong\r
- if (ActiveEvents != 0)\r
- raiseForUpdate(item, olditem, 1);\r
- return true;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection. If the collection has bag\r
- /// semantics only one copy equivalent to the supplied item is removed. \r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public bool Remove(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- if (root == null)\r
- return false;\r
-\r
- int junk;\r
- bool retval = removeIterative(ref item, false, out junk);\r
- if (ActiveEvents != 0 && retval)\r
- raiseForRemove(item);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// Remove a particular item from this collection if found. If the collection\r
- /// has bag semantics only one copy equivalent to the supplied item is removed,\r
- /// which one is implementation dependent. \r
- /// If an item was removed, report a binary copy of the actual item removed in \r
- /// the argument.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- /// <param name="removeditem">The removed value.</param>\r
- /// <returns>True if the item was found (and removed).</returns>\r
- [Tested]\r
- public bool Remove(T item, out T removeditem)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- removeditem = item;\r
- if (root == null)\r
- return false;\r
-\r
- int junk;\r
- bool retval = removeIterative(ref removeditem, false, out junk);\r
- if (ActiveEvents != 0 && retval)\r
- raiseForRemove(item);\r
- return retval;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <param name="item">input: item to remove; output: item actually removed</param>\r
- /// <param name="all">If true, remove all copies</param>\r
- /// <param name="wasRemoved"></param>\r
- /// <returns></returns>\r
- private bool removeIterative(ref T item, bool all, out int wasRemoved)\r
- {\r
- wasRemoved = 0;\r
- //Stage 1: find item\r
- stackcheck();\r
-\r
- int level = 0, comp;\r
- Node cursor = root;\r
-\r
- while (true)\r
- {\r
- comp = comparer.Compare(cursor.item, item);\r
- if (comp == 0)\r
- {\r
- item = cursor.item;\r
-#if BAG\r
- if (!all && cursor.items > 1)\r
- {\r
-#if NCP\r
- Node.CopyNode(ref cursor, maxsnapid, generation);\r
-#endif\r
- cursor.items--;\r
- cursor.size--;\r
- while (level-- > 0)\r
- {\r
- Node kid = cursor;\r
-\r
- cursor = path[level];\r
-#if NCP\r
- Node.update(ref cursor, dirs[level] > 0, kid, maxsnapid, generation);\r
-#endif\r
- cursor.size--;\r
- path[level] = null;\r
- }\r
- size--;\r
- wasRemoved = 1;\r
- return true;\r
- }\r
- wasRemoved = cursor.items;\r
-#else\r
- wasRemoved = 1;\r
-#endif\r
- break;\r
- }\r
-\r
- Node child = comp > 0 ? cursor.left : cursor.right;\r
-\r
- if (child == null)\r
- return false;\r
-\r
- dirs[level] = comp;\r
- path[level++] = cursor;\r
- cursor = child;\r
- }\r
-\r
- return removeIterativePhase2(cursor, level);\r
- }\r
-\r
-\r
- private bool removeIterativePhase2(Node cursor, int level)\r
- {\r
- if (size == 1)\r
- {\r
- clear();\r
- return true;\r
- }\r
-\r
-#if BAG\r
- int removedcount = cursor.items;\r
- size -= removedcount;\r
-#else\r
- //We are certain to remove one node:\r
- size--;\r
-#endif\r
- //Stage 2: if item's node has no null child, find predecessor\r
- int level_of_item = level;\r
-\r
- if (cursor.left != null && cursor.right != null)\r
- {\r
- dirs[level] = 1;\r
- path[level++] = cursor;\r
- cursor = cursor.left;\r
- while (cursor.right != null)\r
- {\r
- dirs[level] = -1;\r
- path[level++] = cursor;\r
- cursor = cursor.right;\r
- }\r
-#if NCP\r
- Node.CopyNode(ref path[level_of_item], maxsnapid, generation);\r
-#endif\r
- path[level_of_item].item = cursor.item;\r
-#if BAG\r
- path[level_of_item].items = cursor.items;\r
-#endif\r
- }\r
-\r
- //Stage 3: splice out node to be removed\r
- Node newchild = cursor.right == null ? cursor.left : cursor.right;\r
- bool demote_or_rotate = newchild == null && !cursor.red;\r
-\r
- //assert newchild.red \r
- if (newchild != null)\r
- {\r
- newchild.red = false;\r
- }\r
-\r
- if (level == 0)\r
- {\r
- root = newchild;\r
- return true;\r
- }\r
-\r
- level--;\r
- cursor = path[level];\r
- path[level] = null;\r
-\r
- int comp = dirs[level];\r
- Node childsibling;\r
-#if NCP\r
- Node.update(ref cursor, comp > 0, newchild, maxsnapid, generation);\r
-#else\r
- if (comp > 0)\r
- cursor.left = newchild;\r
- else\r
- cursor.right = newchild;\r
-#endif\r
- childsibling = comp > 0 ? cursor.right : cursor.left;\r
-#if BAG\r
- cursor.size -= removedcount;\r
-#elif MAINTAIN_SIZE\r
- cursor.size--;\r
-#endif\r
-\r
- //Stage 4: demote till we must rotate\r
- Node farnephew = null, nearnephew = null;\r
-\r
- while (demote_or_rotate)\r
- {\r
- if (childsibling.red)\r
- break; //rotate 2+?\r
-\r
- farnephew = comp > 0 ? childsibling.right : childsibling.left;\r
- if (farnephew != null && farnephew.red)\r
- break; //rotate 1b\r
-\r
- nearnephew = comp > 0 ? childsibling.left : childsibling.right;\r
- if (nearnephew != null && nearnephew.red)\r
- break; //rotate 1c\r
-\r
- //demote cursor\r
- childsibling.red = true;\r
- if (level == 0)\r
- {\r
- cursor.red = false;\r
- blackdepth--;\r
-#if NCP\r
- root = cursor;\r
-#endif\r
- return true;\r
- }\r
- else if (cursor.red)\r
- {\r
- cursor.red = false;\r
- demote_or_rotate = false;\r
- break; //No rotation\r
- }\r
- else\r
- {\r
- Node child = cursor;\r
-\r
- cursor = path[--level];\r
- path[level] = null;\r
- comp = dirs[level];\r
- childsibling = comp > 0 ? cursor.right : cursor.left;\r
-#if NCP\r
- Node.update(ref cursor, comp > 0, child, maxsnapid, generation);\r
-#endif\r
-#if BAG\r
- cursor.size -= removedcount;\r
-#elif MAINTAIN_SIZE\r
- cursor.size--;\r
-#endif\r
- }\r
- }\r
-\r
- //Stage 5: rotate \r
- if (demote_or_rotate)\r
- {\r
- //At start:\r
- //parent = cursor (temporary for swapping nodes)\r
- //childsibling is the sibling of the updated child (x)\r
- //cursor is always the top of the subtree\r
- Node parent = cursor;\r
-\r
- if (childsibling.red)\r
- {//Case 2 and perhaps more. \r
- //The y.rank == px.rank >= x.rank+2 >=2 so both nephews are != null \r
- //(and black). The grandnephews are children of nearnephew\r
- Node neargrandnephew, fargrandnephew;\r
-\r
- if (comp > 0)\r
- {\r
- nearnephew = childsibling.left;\r
- farnephew = childsibling.right;\r
- neargrandnephew = nearnephew.left;\r
- fargrandnephew = nearnephew.right;\r
- }\r
- else\r
- {\r
- nearnephew = childsibling.right;\r
- farnephew = childsibling.left;\r
- neargrandnephew = nearnephew.right;\r
- fargrandnephew = nearnephew.left;\r
- }\r
-\r
- if (fargrandnephew != null && fargrandnephew.red)\r
- {//Case 2+1b\r
-#if NCP\r
- Node.CopyNode(ref nearnephew, maxsnapid, generation);\r
-\r
- //The end result of this will always be e copy of parent\r
- Node.update(ref parent, comp < 0, neargrandnephew, maxsnapid, generation);\r
- Node.update(ref childsibling, comp > 0, nearnephew, maxsnapid, generation);\r
-#endif\r
- if (comp > 0)\r
- {\r
- nearnephew.left = parent;\r
- parent.right = neargrandnephew;\r
- }\r
- else\r
- {\r
- nearnephew.right = parent;\r
- parent.left = neargrandnephew;\r
- }\r
-\r
- cursor = childsibling;\r
- childsibling.red = false;\r
- nearnephew.red = true;\r
- fargrandnephew.red = false;\r
-#if BAG\r
- cursor.size = parent.size;\r
- nearnephew.size = cursor.size - cursor.items - farnephew.size;\r
- parent.size = nearnephew.size - nearnephew.items - fargrandnephew.size;\r
-#elif MAINTAIN_SIZE\r
- cursor.size = parent.size;\r
- nearnephew.size = cursor.size - 1 - farnephew.size;\r
- parent.size = nearnephew.size - 1 - fargrandnephew.size;\r
-#endif\r
- }\r
- else if (neargrandnephew != null && neargrandnephew.red)\r
- {//Case 2+1c\r
-#if NCP\r
- Node.CopyNode(ref neargrandnephew, maxsnapid, generation);\r
-#endif\r
- if (comp > 0)\r
- {\r
-#if NCP\r
- Node.update(ref childsibling, true, neargrandnephew, maxsnapid, generation);\r
- Node.update(ref nearnephew, true, neargrandnephew.right, maxsnapid, generation);\r
- Node.update(ref parent, false, neargrandnephew.left, maxsnapid, generation);\r
-#else\r
- childsibling.left = neargrandnephew;\r
- nearnephew.left = neargrandnephew.right;\r
- parent.right = neargrandnephew.left;\r
-#endif\r
- neargrandnephew.left = parent;\r
- neargrandnephew.right = nearnephew;\r
- }\r
- else\r
- {\r
-#if NCP\r
- Node.update(ref childsibling, false, neargrandnephew, maxsnapid, generation);\r
- Node.update(ref nearnephew, false, neargrandnephew.left, maxsnapid, generation);\r
- Node.update(ref parent, true, neargrandnephew.right, maxsnapid, generation);\r
-#else\r
- childsibling.right = neargrandnephew;\r
- nearnephew.right = neargrandnephew.left;\r
- parent.left = neargrandnephew.right;\r
-#endif\r
- neargrandnephew.right = parent;\r
- neargrandnephew.left = nearnephew;\r
- }\r
-\r
- cursor = childsibling;\r
- childsibling.red = false;\r
-#if BAG\r
- cursor.size = parent.size;\r
- parent.size = parent.items + (parent.left == null ? 0 : parent.left.size) + (parent.right == null ? 0 : parent.right.size);\r
- nearnephew.size = nearnephew.items + (nearnephew.left == null ? 0 : nearnephew.left.size) + (nearnephew.right == null ? 0 : nearnephew.right.size);\r
- neargrandnephew.size = neargrandnephew.items + parent.size + nearnephew.size;\r
-#elif MAINTAIN_SIZE\r
- cursor.size = parent.size;\r
- parent.size = 1 + (parent.left == null ? 0 : parent.left.size) + (parent.right == null ? 0 : parent.right.size);\r
- nearnephew.size = 1 + (nearnephew.left == null ? 0 : nearnephew.left.size) + (nearnephew.right == null ? 0 : nearnephew.right.size);\r
- neargrandnephew.size = 1 + parent.size + nearnephew.size;\r
-#endif\r
- }\r
- else\r
- {//Case 2 only\r
-#if NCP\r
- Node.update(ref parent, comp < 0, nearnephew, maxsnapid, generation);\r
- Node.update(ref childsibling, comp > 0, parent, maxsnapid, generation);\r
-#else\r
- if (comp > 0)\r
- {\r
- childsibling.left = parent;\r
- parent.right = nearnephew;\r
- }\r
- else\r
- {\r
- childsibling.right = parent;\r
- parent.left = nearnephew;\r
- }\r
-#endif\r
- cursor = childsibling;\r
- childsibling.red = false;\r
- nearnephew.red = true;\r
-#if BAG\r
- cursor.size = parent.size;\r
- parent.size -= farnephew.size + cursor.items;\r
-#elif MAINTAIN_SIZE\r
- cursor.size = parent.size;\r
- parent.size -= farnephew.size + 1;\r
-#endif\r
- }\r
- }\r
- else if (farnephew != null && farnephew.red)\r
- {//Case 1b\r
- nearnephew = comp > 0 ? childsibling.left : childsibling.right;\r
-#if NCP\r
- Node.update(ref parent, comp < 0, nearnephew, maxsnapid, generation);\r
- Node.CopyNode(ref childsibling, maxsnapid, generation);\r
- if (comp > 0)\r
- {\r
- childsibling.left = parent;\r
- childsibling.right = farnephew;\r
- }\r
- else\r
- {\r
- childsibling.right = parent;\r
- childsibling.left = farnephew;\r
- }\r
-#else\r
- if (comp > 0)\r
- {\r
- childsibling.left = parent;\r
- parent.right = nearnephew;\r
- }\r
- else\r
- {\r
- childsibling.right = parent;\r
- parent.left = nearnephew;\r
- }\r
-#endif\r
- cursor = childsibling;\r
- cursor.red = parent.red;\r
- parent.red = false;\r
- farnephew.red = false;\r
-\r
-#if BAG\r
- cursor.size = parent.size;\r
- parent.size -= farnephew.size + cursor.items;\r
-#elif MAINTAIN_SIZE\r
- cursor.size = parent.size;\r
- parent.size -= farnephew.size + 1;\r
-#endif\r
- }\r
- else if (nearnephew != null && nearnephew.red)\r
- {//Case 1c\r
-#if NCP\r
- Node.CopyNode(ref nearnephew, maxsnapid, generation);\r
-#endif\r
- if (comp > 0)\r
- {\r
-#if NCP\r
- Node.update(ref childsibling, true, nearnephew.right, maxsnapid, generation);\r
- Node.update(ref parent, false, nearnephew.left, maxsnapid, generation);\r
-#else\r
- childsibling.left = nearnephew.right;\r
- parent.right = nearnephew.left;\r
-#endif\r
- nearnephew.left = parent;\r
- nearnephew.right = childsibling;\r
- }\r
- else\r
- {\r
-#if NCP\r
- Node.update(ref childsibling, false, nearnephew.left, maxsnapid, generation);\r
- Node.update(ref parent, true, nearnephew.right, maxsnapid, generation);\r
-#else\r
- childsibling.right = nearnephew.left;\r
- parent.left = nearnephew.right;\r
-#endif\r
- nearnephew.right = parent;\r
- nearnephew.left = childsibling;\r
- }\r
-\r
- cursor = nearnephew;\r
- cursor.red = parent.red;\r
- parent.red = false;\r
-#if BAG\r
- cursor.size = parent.size;\r
- parent.size = parent.items + (parent.left == null ? 0 : parent.left.size) + (parent.right == null ? 0 : parent.right.size);\r
- childsibling.size = childsibling.items + (childsibling.left == null ? 0 : childsibling.left.size) + (childsibling.right == null ? 0 : childsibling.right.size);\r
-#elif MAINTAIN_SIZE\r
- cursor.size = parent.size;\r
- parent.size = 1 + (parent.left == null ? 0 : parent.left.size) + (parent.right == null ? 0 : parent.right.size);\r
- childsibling.size = 1 + (childsibling.left == null ? 0 : childsibling.left.size) + (childsibling.right == null ? 0 : childsibling.right.size);\r
-#endif\r
- }\r
- else\r
- {//Case 1a can't happen\r
- throw new InternalException("Case 1a can't happen here");\r
- }\r
-\r
- //Resplice cursor:\r
- if (level == 0)\r
- {\r
- root = cursor;\r
- }\r
- else\r
- {\r
- Node swap = cursor;\r
-\r
- cursor = path[--level];\r
- path[level] = null;\r
-#if NCP\r
- Node.update(ref cursor, dirs[level] > 0, swap, maxsnapid, generation);\r
-#else\r
- \r
- if (dirs[level] > 0)\r
- cursor.left = swap;\r
- else\r
- cursor.right = swap;\r
-#endif\r
-#if BAG\r
- cursor.size -= removedcount;\r
-#elif MAINTAIN_SIZE\r
- cursor.size--;\r
-#endif\r
- }\r
- }\r
-\r
- //Stage 6: fixup to the root\r
- while (level > 0)\r
- {\r
- Node child = cursor;\r
-\r
- cursor = path[--level];\r
- path[level] = null;\r
-#if NCP\r
- if (child != (dirs[level] > 0 ? cursor.left : cursor.right))\r
- Node.update(ref cursor, dirs[level] > 0, child, maxsnapid, generation);\r
-#endif\r
-#if BAG\r
- cursor.size -= removedcount;\r
-#elif MAINTAIN_SIZE\r
- cursor.size--;\r
-#endif\r
- }\r
-\r
-#if NCP\r
- root = cursor;\r
-#endif\r
- return true;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items from this collection.\r
- /// </summary>\r
- [Tested]\r
- public void Clear()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- if (size == 0)\r
- return;\r
- int oldsize = size;\r
- clear();\r
- if ((ActiveEvents & EventTypeEnum.Cleared) != 0)\r
- raiseCollectionCleared(true, oldsize);\r
- if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
-\r
- private void clear()\r
- {\r
- size = 0;\r
- root = null;\r
- blackdepth = 0;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items in another collection from this one. If this collection\r
- /// has bag semantics, take multiplicities into account.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to remove.</param>\r
- [Tested]\r
- public void RemoveAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- T jtem;\r
-\r
- bool mustRaise = (ActiveEvents & (EventTypeEnum.Removed | EventTypeEnum.Changed)) != 0;\r
- RaiseForRemoveAllHandler raiseHandler = mustRaise ? new RaiseForRemoveAllHandler(this) : null;\r
-\r
- foreach (T item in items)\r
- {\r
- if (root == null)\r
- break;\r
-\r
- jtem = item;\r
- int junk;\r
- if (removeIterative(ref jtem, false, out junk) && mustRaise)\r
- raiseHandler.Remove(jtem);\r
- }\r
- if (mustRaise)\r
- raiseHandler.Raise();\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items not in some other collection from this one. If this collection\r
- /// has bag semantics, take multiplicities into account.\r
- /// </summary>\r
- /// <typeparam name="U"></typeparam>\r
- /// <param name="items">The items to retain.</param>\r
- [Tested]\r
- public void RetainAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- //A much more efficient version is possible if items is sorted like this.\r
- //Well, it is unclear how efficient it would be.\r
- //We could use a marking method!?\r
-#warning how does this work together with persistence?\r
- TreeSet<T> t = (TreeSet<T>)MemberwiseClone();\r
-\r
- T jtem = default(T);\r
- t.clear();\r
- foreach (T item in items)\r
- if (ContainsCount(item) > t.ContainsCount(item))\r
- {\r
- t.add(item, ref jtem);\r
- }\r
- if (size == t.size)\r
- return;\r
-\r
-#warning improve (mainly for bag) by usig a Node iterator instead of ItemMultiplicities()\r
- CircularQueue<KeyValuePair<T, int>> wasRemoved = null;\r
- if ((ActiveEvents & EventTypeEnum.Removed) != 0)\r
- {\r
- wasRemoved = new CircularQueue<KeyValuePair<T, int>>();\r
- SCG.IEnumerator<KeyValuePair<T, int>> ie = ItemMultiplicities().GetEnumerator();\r
- foreach (KeyValuePair<T, int> p in t.ItemMultiplicities())\r
- {\r
- //We know p.Key is in this!\r
- while (ie.MoveNext())\r
- {\r
- if (comparer.Compare(ie.Current.Key, p.Key) == 0)\r
- {\r
-#if BAG\r
- int removed = ie.Current.Value - p.Value;\r
- if (removed > 0)\r
- wasRemoved.Enqueue(new KeyValuePair<T,int>(p.Key, removed));\r
-#endif\r
- break;\r
- }\r
- else\r
- wasRemoved.Enqueue(ie.Current);\r
- }\r
- }\r
- while (ie.MoveNext())\r
- wasRemoved.Enqueue(ie.Current);\r
- }\r
-\r
- root = t.root;\r
- size = t.size;\r
- blackdepth = t.blackdepth;\r
- if (wasRemoved != null)\r
- foreach (KeyValuePair<T, int> p in wasRemoved)\r
- raiseItemsRemoved(p.Key, p.Value);\r
- if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
- /// <summary>\r
- /// Check if this collection contains all the values in another collection.\r
- /// If this collection has bag semantics (<code>AllowsDuplicates==true</code>)\r
- /// the check is made with respect to multiplicities, else multiplicities\r
- /// are not taken into account.\r
- /// </summary>\r
- /// <param name="items">The </param>\r
- /// <typeparam name="U"></typeparam>\r
- /// <returns>True if all values in <code>items</code>is in this collection.</returns>\r
- [Tested]\r
- public bool ContainsAll<U>(SCG.IEnumerable<U> items) where U : T\r
- {\r
- //TODO: fix bag implementation\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- //This is worst-case O(m*logn)\r
- foreach (T item in items)\r
- if (!Contains(item)) return false;\r
-\r
- return true;\r
- }\r
-\r
-\r
- //Higher order:\r
- /// <summary>\r
- /// Create a new indexed sorted collection consisting of the items of this\r
- /// indexed sorted collection satisfying a certain predicate.\r
- /// </summary>\r
- /// <param name="filter">The filter delegate defining the predicate.</param>\r
- /// <returns>The new indexed sorted collection.</returns>\r
- [Tested]\r
- public IIndexedSorted<T> FindAll(Fun<T, bool> filter)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- TreeSet<T> res = new TreeSet<T>(comparer);\r
- SCG.IEnumerator<T> e = GetEnumerator();\r
- Node head = null, tail = null;\r
- int z = 0;\r
-#if BAG\r
- int ec = 0;\r
-#endif\r
- while (e.MoveNext())\r
- {\r
- T thisitem = e.Current;\r
-#if BAG\r
- //We could document that filter will only be called \r
- //once on each unique item. That might even be good for the user!\r
- if (tail != null && comparer.Compare(thisitem, tail.item) == 0)\r
- {\r
- tail.items++;\r
- ec++;\r
- continue;\r
- }\r
-#endif\r
- if (filter(thisitem))\r
- {\r
- if (head == null)\r
- {\r
- head = tail = new Node();\r
- }\r
- else\r
- {\r
-#if BAG\r
- tail.size = tail.items;\r
-#endif\r
- tail.right = new Node();\r
- tail = tail.right;\r
- }\r
-\r
- tail.item = thisitem;\r
- z++;\r
- }\r
- }\r
-#if BAG\r
- if (tail != null)\r
- tail.size = tail.items;\r
-#endif\r
-\r
- if (z == 0)\r
- return res;\r
-\r
- int blackheight = 0, red = z, maxred = 1;\r
-\r
- while (maxred <= red)\r
- {\r
- red -= maxred;\r
- maxred <<= 1;\r
- blackheight++;\r
- }\r
-\r
- res.root = TreeSet<T>.maketreer(ref head, blackheight, maxred, red);\r
- res.blackdepth = blackheight;\r
- res.size = z;\r
-#if BAG\r
- res.size += ec;\r
-#endif\r
- return res;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a new indexed sorted collection consisting of the results of\r
- /// mapping all items of this list.\r
- /// <exception cref="ArgumentException"/> if the map is not increasing over \r
- /// the items of this collection (with respect to the two given comparison \r
- /// relations).\r
- /// </summary>\r
- /// <param name="mapper">The delegate definging the map.</param>\r
- /// <param name="c">The comparion relation to use for the result.</param>\r
- /// <returns>The new sorted collection.</returns>\r
- [Tested]\r
- public IIndexedSorted<V> Map<V>(Fun<T, V> mapper, SCG.IComparer<V> c)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- TreeSet<V> res = new TreeSet<V>(c);\r
-\r
- if (size == 0)\r
- return res;\r
-\r
- SCG.IEnumerator<T> e = GetEnumerator();\r
- TreeSet<V>.Node head = null, tail = null;\r
- V oldv = default(V);\r
- int z = 0;\r
-#if BAG\r
- T lastitem = default(T);\r
-#endif\r
- while (e.MoveNext())\r
- {\r
- T thisitem = e.Current;\r
-#if BAG\r
- //We could document that mapper will only be called \r
- //once on each unique item. That might even be good for the user!\r
- if (tail != null && comparer.Compare(thisitem, lastitem) == 0)\r
- {\r
- tail.items++;\r
- continue;\r
- }\r
-#endif\r
- V newv = mapper(thisitem);\r
-\r
- if (head == null)\r
- {\r
- head = tail = new TreeSet<V>.Node();\r
- z++;\r
- }\r
- else\r
- {\r
- int comp = c.Compare(oldv, newv);\r
-#if BAG\r
- if (comp == 0)\r
- {\r
- tail.items++;\r
- continue;\r
- }\r
- if (comp > 0)\r
-#else\r
- if (comp >= 0)\r
-#endif\r
- throw new ArgumentException("mapper not monotonic");\r
-#if BAG\r
- tail.size = tail.items;\r
-#endif\r
- tail.right = new TreeSet<V>.Node();\r
- tail = tail.right;\r
- z++;\r
- }\r
-#if BAG\r
- lastitem = thisitem;\r
-#endif\r
- tail.item = oldv = newv;\r
- }\r
-\r
-#if BAG\r
- tail.size = tail.items;\r
-#endif\r
-\r
- int blackheight = 0, red = z, maxred = 1;\r
-\r
- while (maxred <= red)\r
- {\r
- red -= maxred;\r
- maxred <<= 1;\r
- blackheight++;\r
- }\r
-\r
- res.root = TreeSet<V>.maketreer(ref head, blackheight, maxred, red);\r
- res.blackdepth = blackheight;\r
- res.size = size;\r
- return res;\r
- }\r
-\r
-\r
- //below is the bag utility stuff\r
- /// <summary>\r
- /// Count the number of items of the collection equal to a particular value.\r
- /// Returns 0 if and only if the value is not in the collection.\r
- /// </summary>\r
- /// <param name="item">The value to count.</param>\r
- /// <returns>The number of copies found.</returns>\r
- [Tested]\r
- public int ContainsCount(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
-#if BAG\r
- Node next; int comp = 0;\r
-\r
- next = root;\r
- while (next != null)\r
- {\r
- comp = comparer.Compare(next.item, item);\r
- if (comp == 0)\r
- return next.items;\r
-\r
- next = comp < 0 ? right(next) : left(next);\r
- }\r
-\r
- return 0;\r
-#else\r
- //Since we are strictly not AllowsDuplicates we just do\r
- return Contains(item) ? 1 : 0;\r
-#endif\r
- }\r
-\r
-#if BAG\r
- //TODO: make work with snapshots\r
- class Multiplicities : CollectionValueBase<KeyValuePair<T, int>>, ICollectionValue<KeyValuePair<T, int>>\r
- {\r
- TreeBag<T> treebag;\r
- int origstamp;\r
- internal Multiplicities(TreeBag<T> treebag) { this.treebag = treebag; this.origstamp = treebag.stamp; }\r
- public override KeyValuePair<T, int> Choose() { return new KeyValuePair<T, int>(treebag.root.item, treebag.root.items); }\r
-\r
- public override SCG.IEnumerator<KeyValuePair<T, int>> GetEnumerator()\r
- {\r
- return getEnumerator(treebag.root, origstamp); //TODO: NBNBNB\r
- }\r
-\r
- private SCG.IEnumerator<KeyValuePair<T, int>> getEnumerator(Node node, int origstamp)\r
- {\r
- if (node == null)\r
- yield break;\r
-\r
- if (node.left != null)\r
- {\r
- SCG.IEnumerator<KeyValuePair<T, int>> child = getEnumerator(node.left, origstamp);\r
-\r
- while (child.MoveNext())\r
- {\r
- treebag.modifycheck(origstamp);\r
- yield return child.Current;\r
- }\r
- }\r
- yield return new KeyValuePair<T, int>(node.item, node.items);\r
- if (node.right != null)\r
- {\r
- SCG.IEnumerator<KeyValuePair<T, int>> child = getEnumerator(node.right, origstamp);\r
-\r
- while (child.MoveNext())\r
- {\r
- treebag.modifycheck(origstamp);\r
- yield return child.Current;\r
- }\r
- }\r
- }\r
-\r
- public override bool IsEmpty { get { return treebag.IsEmpty; } }\r
- public override int Count { get { int i = 0; foreach (KeyValuePair<T, int> p in this) i++; return i; } } //TODO: make better\r
- public override Speed CountSpeed { get { return Speed.Linear; } } //TODO: make better\r
- }\r
-#endif\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<T> UniqueItems()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
-#if BAG\r
- return new DropMultiplicity<T>(ItemMultiplicities());\r
-#else\r
- return this;\r
-#endif\r
- }\r
-\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual ICollectionValue<KeyValuePair<T, int>> ItemMultiplicities()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
-#if BAG\r
- return new Multiplicities(this);\r
-#else\r
- return new MultiplicityOne<T>(this);\r
-#endif\r
- }\r
-\r
- /// <summary>\r
- /// Remove all items equivalent to a given value.\r
- /// </summary>\r
- /// <param name="item">The value to remove.</param>\r
- [Tested]\r
- public void RemoveAllCopies(T item)\r
- {\r
-#if BAG\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- int removed;\r
- if (removeIterative(ref item, true, out removed) && ActiveEvents != 0)\r
- {\r
- raiseForRemove(item, removed);\r
- }\r
-#else\r
- Remove(item);\r
-#endif\r
- }\r
-\r
-\r
- #endregion\r
-\r
- #region IIndexed<T> Members\r
-\r
- private Node findNode(int i)\r
- {\r
-#if NCP\r
- if (isSnapShot)\r
- throw new NotSupportedException("Indexing not supported for snapshots");\r
-#endif\r
-#if MAINTAIN_SIZE\r
- Node next = root;\r
-\r
- if (i >= 0 && i < size)\r
- while (true)\r
- {\r
- int j = next.left == null ? 0 : next.left.size;\r
-\r
- if (i > j)\r
- {\r
-#if BAG\r
- i -= j + next.items;\r
- if (i < 0)\r
- return next;\r
-#else\r
- i -= j + 1;\r
-#endif\r
- next = next.right;\r
- }\r
- else if (i == j)\r
- return next;\r
- else\r
- next = next.left;\r
- }\r
-\r
- throw new IndexOutOfRangeException();\r
-#else\r
- throw new NotSupportedException();\r
-#endif\r
- }\r
-\r
-\r
- /// <summary>\r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// >= the size of the collection.\r
- /// </summary>\r
- /// <value>The i'th item of this list.</value>\r
- /// <param name="i">the index to lookup</param>\r
- [Tested]\r
- public T this[int i] { [Tested] get { return findNode(i).item; } }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value></value>\r
- public virtual Speed IndexingSpeed { get { return Speed.Log; } }\r
-\r
-\r
- //TODO: return -upper instead of -1 in case of not found\r
- /// <summary>\r
- /// Searches for an item in this indexed collection going forwards from the start.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of first occurrence from start of the item\r
- /// if found, else the two-complement \r
- /// (always negative) of the index at which the item would be put if it was added.</returns>\r
- [Tested]\r
- public int IndexOf(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- int upper;\r
- return indexOf(item, out upper);\r
- }\r
-\r
-\r
- private int indexOf(T item, out int upper)\r
- {\r
-#if NCP\r
- if (isSnapShot)\r
- throw new NotSupportedException("Indexing not supported for snapshots");\r
-#endif\r
-#if MAINTAIN_SIZE\r
- int ind = 0; Node next = root;\r
-\r
- while (next != null)\r
- {\r
- int comp = comparer.Compare(item, next.item);\r
-\r
- if (comp < 0)\r
- next = next.left;\r
- else\r
- {\r
- int leftcnt = next.left == null ? 0 : next.left.size;\r
-\r
- if (comp == 0)\r
- {\r
-#if BAG\r
- upper = ind + leftcnt + next.items - 1;\r
- return ind + leftcnt;\r
-#else\r
- return upper = ind + leftcnt;\r
-#endif\r
- }\r
- else\r
- {\r
-#if BAG\r
- ind = ind + next.items + leftcnt;\r
-#else\r
- ind = ind + 1 + leftcnt;\r
-#endif\r
- next = next.right;\r
- }\r
- }\r
- }\r
-#endif\r
- upper = ~ind;\r
- return ~ind;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Searches for an item in the tree going backwords from the end.\r
- /// </summary>\r
- /// <param name="item">Item to search for.</param>\r
- /// <returns>Index of last occurrence from the end of item if found, \r
- /// else the two-complement (always negative) of the index at which \r
- /// the item would be put if it was added.</returns>\r
- [Tested]\r
- public int LastIndexOf(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
-#if BAG\r
- int res;\r
- indexOf(item, out res);\r
- return res;\r
-#else\r
- //We have AllowsDuplicates==false for the set\r
- return IndexOf(item);\r
-#endif\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the item at a specific position of the list.\r
- /// <exception cref="IndexOutOfRangeException"/> if i is negative or\r
- /// >= the size of the collection.\r
- /// </summary>\r
- /// <param name="i">The index of the item to remove.</param>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T RemoveAt(int i)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
- T retval = removeAt(i);\r
- if (ActiveEvents != 0)\r
- raiseForRemove(retval);\r
- return retval;\r
- }\r
-\r
- T removeAt(int i)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-#if MAINTAIN_SIZE\r
- if (i < 0 || i >= size)\r
- throw new IndexOutOfRangeException("Index out of range for sequenced collectionvalue");\r
-\r
- //We must follow the pattern of removeIterative()\r
- while (dirs.Length < 2 * blackdepth)\r
- {\r
- dirs = new int[2 * dirs.Length];\r
- path = new Node[2 * dirs.Length];\r
- }\r
-\r
- int level = 0;\r
- Node cursor = root;\r
-\r
- while (true)\r
- {\r
- int j = cursor.left == null ? 0 : cursor.left.size;\r
-\r
- if (i > j)\r
- {\r
-#if BAG\r
- i -= j + cursor.items;\r
- if (i < 0)\r
- break;\r
-#else\r
- i -= j + 1;\r
-#endif\r
- dirs[level] = -1;\r
- path[level++] = cursor;\r
- cursor = cursor.right;\r
- }\r
- else if (i == j)\r
- break;\r
- else\r
- {\r
- dirs[level] = 1;\r
- path[level++] = cursor;\r
- cursor = cursor.left;\r
- }\r
- }\r
-\r
- T retval = cursor.item;\r
-\r
-#if BAG\r
- if (cursor.items > 1)\r
- {\r
- resplicebag(level, cursor);\r
- size--;\r
- return retval;\r
- }\r
-#endif\r
- removeIterativePhase2(cursor, level);\r
- return retval;\r
-#else\r
- throw new NotSupportedException();\r
-#endif\r
- }\r
-\r
-#if BAG\r
- private void resplicebag(int level, Node cursor)\r
- {\r
-#if NCP\r
- Node.CopyNode(ref cursor, maxsnapid, generation);\r
-#endif\r
- cursor.items--;\r
- cursor.size--;\r
- while (level-- > 0)\r
- {\r
- Node kid = cursor;\r
-\r
- cursor = path[level];\r
-#if NCP\r
- Node.update(ref cursor, dirs[level] > 0, kid, maxsnapid, generation);\r
-#endif\r
- cursor.size--;\r
- path[level] = null;\r
- }\r
- }\r
-#endif\r
- /// <summary>\r
- /// Remove all items in an index interval.\r
- /// <exception cref="IndexOutOfRangeException"/>???. \r
- /// </summary>\r
- /// <param name="start">The index of the first item to remove.</param>\r
- /// <param name="count">The number of items to remove.</param>\r
- [Tested]\r
- public void RemoveInterval(int start, int count)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- if (start < 0 || count < 0 || start + count > this.size)\r
- throw new ArgumentOutOfRangeException();\r
-\r
- updatecheck();\r
-\r
- if (count == 0)\r
- return;\r
-\r
- //This is terrible for large count. We should split the tree at \r
- //the endpoints of the range and fuse the parts!\r
- //We really need good internal destructive split and catenate functions!\r
- //Alternative for large counts: rebuild tree using maketree()\r
- for (int i = 0; i < count; i++)\r
- removeAt(start);\r
-\r
- if ((ActiveEvents & EventTypeEnum.Cleared) != 0)\r
- raiseCollectionCleared(false, count);\r
- if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// <exception cref="IndexOutOfRangeException"/>.\r
- /// </summary>\r
- /// <value>The directed collection of items in a specific index interval.</value>\r
- /// <param name="start">The low index of the interval (inclusive).</param>\r
- /// <param name="end">The high index of the interval (exclusive).</param>\r
- [Tested]\r
- public IDirectedCollectionValue<T> this[int start, int end]\r
- {\r
- [Tested]\r
- get\r
- {\r
- checkRange(start, end - start);\r
- return new Interval(this, start, end - start, true);\r
- }\r
- }\r
-\r
- #region Interval nested class\r
- class Interval : DirectedCollectionValueBase<T>, IDirectedCollectionValue<T>\r
- {\r
- int start, length, stamp;\r
-\r
- bool forwards;\r
-\r
- TreeSet<T> tree;\r
-\r
-\r
- internal Interval(TreeSet<T> tree, int start, int count, bool forwards)\r
- {\r
-#if NCP\r
- if (tree.isSnapShot)\r
- throw new NotSupportedException("Indexing not supported for snapshots");\r
-#endif\r
- this.start = start; this.length = count; this.forwards = forwards;\r
- this.tree = tree; this.stamp = tree.stamp;\r
- }\r
-\r
- public override bool IsEmpty { get { return length == 0; } }\r
-\r
- [Tested]\r
- public override int Count { [Tested]get { return length; } }\r
-\r
-\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
-\r
-\r
- public override T Choose()\r
- {\r
- if (length == 0)\r
- throw new NoSuchItemException();\r
- return tree[start];\r
- }\r
-\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
-#if MAINTAIN_SIZE\r
- tree.modifycheck(stamp);\r
-#if BAG\r
- int togo;\r
-#endif\r
- Node cursor = tree.root;\r
- Node[] path = new Node[2 * tree.blackdepth];\r
- int level = 0, totaltogo = length;\r
-\r
- if (totaltogo == 0)\r
- yield break;\r
-\r
- if (forwards)\r
- {\r
- int i = start;\r
-\r
- while (true)\r
- {\r
- int j = cursor.left == null ? 0 : cursor.left.size;\r
-\r
- if (i > j)\r
- {\r
-#if BAG\r
- i -= j + cursor.items;\r
- if (i < 0)\r
- {\r
- togo = cursor.items + i;\r
- break;\r
- }\r
-#else\r
- i -= j + 1;\r
-#endif\r
- cursor = cursor.right;\r
- }\r
- else if (i == j)\r
- {\r
-#if BAG\r
- togo = cursor.items;\r
-#endif\r
- break;\r
- }\r
- else\r
- {\r
- path[level++] = cursor;\r
- cursor = cursor.left;\r
- }\r
- }\r
-\r
- T current = cursor.item;\r
-\r
- while (totaltogo-- > 0)\r
- {\r
- yield return current;\r
- tree.modifycheck(stamp);\r
-#if BAG\r
- if (--togo > 0)\r
- continue;\r
-#endif\r
- if (cursor.right != null)\r
- {\r
- path[level] = cursor = cursor.right;\r
- while (cursor.left != null)\r
- path[++level] = cursor = cursor.left;\r
- }\r
- else if (level == 0)\r
- yield break;\r
- else\r
- cursor = path[--level];\r
-\r
- current = cursor.item;\r
-#if BAG\r
- togo = cursor.items;\r
-#endif\r
- }\r
- }\r
- else\r
- {\r
- int i = start + length - 1;\r
-\r
- while (true)\r
- {\r
- int j = cursor.left == null ? 0 : cursor.left.size;\r
-\r
- if (i > j)\r
- {\r
-#if BAG\r
- if (i - j < cursor.items)\r
- {\r
- togo = i - j + 1;\r
- break;\r
- }\r
- i -= j + cursor.items;\r
-#else\r
- i -= j + 1;\r
-#endif\r
- path[level++] = cursor;\r
- cursor = cursor.right;\r
- }\r
- else if (i == j)\r
- {\r
-#if BAG\r
- togo = 1;\r
-#endif\r
- break;\r
- }\r
- else\r
- {\r
- cursor = cursor.left;\r
- }\r
- }\r
-\r
- T current = cursor.item;\r
-\r
- while (totaltogo-- > 0)\r
- {\r
- yield return current;\r
- tree.modifycheck(stamp);\r
-#if BAG\r
- if (--togo > 0)\r
- continue;\r
-#endif\r
- if (cursor.left != null)\r
- {\r
- path[level] = cursor = cursor.left;\r
- while (cursor.right != null)\r
- path[++level] = cursor = cursor.right;\r
- }\r
- else if (level == 0)\r
- yield break;\r
- else\r
- cursor = path[--level];\r
-\r
- current = cursor.item;\r
-#if BAG\r
- togo = cursor.items;\r
-#endif\r
- }\r
- }\r
-\r
-#else\r
- throw new NotSupportedException();\r
-#endif\r
- }\r
-\r
-\r
- [Tested]\r
- public override IDirectedCollectionValue<T> Backwards()\r
- { return new Interval(tree, start, length, !forwards); }\r
-\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> C5.IDirectedEnumerable<T>.Backwards()\r
- { return Backwards(); }\r
-\r
-\r
- [Tested]\r
- public override EnumerationDirection Direction\r
- {\r
- [Tested]\r
- get\r
- {\r
- return forwards ? EnumerationDirection.Forwards : EnumerationDirection.Backwards;\r
- }\r
- }\r
- }\r
- #endregion\r
-\r
- /// <summary>\r
- /// Create a collection containing the same items as this collection, but\r
- /// whose enumerator will enumerate the items backwards. The new collection\r
- /// will become invalid if the original is modified. Method typicaly used as in\r
- /// <code>foreach (T x in coll.Backwards()) {...}</code>\r
- /// </summary>\r
- /// <returns>The backwards collection.</returns>\r
- [Tested]\r
- public override IDirectedCollectionValue<T> Backwards() { return RangeAll().Backwards(); }\r
-\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return Backwards(); }\r
-\r
- #endregion\r
-\r
- #region PriorityQueue Members\r
-\r
- /// <summary>\r
- /// The comparer object supplied at creation time for this collection\r
- /// </summary>\r
- /// <value>The comparer</value>\r
- public SCG.IComparer<T> Comparer { get { return comparer; } }\r
-\r
-\r
- /// <summary>\r
- /// Find the current least item of this priority queue.\r
- /// </summary>\r
- /// <returns>The least item.</returns>\r
- [Tested]\r
- public T FindMin()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
- Node cursor = root, next = left(cursor);\r
-\r
- while (next != null)\r
- {\r
- cursor = next;\r
- next = left(cursor);\r
- }\r
-\r
- return cursor.item;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the least item from this priority queue.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T DeleteMin()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- //persistence guard?\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- //We must follow the pattern of removeIterative()\r
- stackcheck();\r
-\r
- T retval = deleteMin();\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsRemoved(retval, 1);\r
- raiseCollectionChanged();\r
- }\r
- return retval;\r
- }\r
-\r
- private T deleteMin()\r
- {\r
- int level = 0;\r
- Node cursor = root;\r
-\r
- while (cursor.left != null)\r
- {\r
- dirs[level] = 1;\r
- path[level++] = cursor;\r
- cursor = cursor.left;\r
- }\r
-\r
- T retval = cursor.item;\r
-\r
-#if BAG\r
- if (cursor.items > 1)\r
- {\r
- resplicebag(level, cursor);\r
- size--;\r
- return retval;\r
- }\r
-#endif\r
- removeIterativePhase2(cursor, level);\r
- return retval;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the current largest item of this priority queue.\r
- /// </summary>\r
- /// <returns>The largest item.</returns>\r
- [Tested]\r
- public T FindMax()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- Node cursor = root, next = right(cursor);\r
-\r
- while (next != null)\r
- {\r
- cursor = next;\r
- next = right(cursor);\r
- }\r
-\r
- return cursor.item;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove the largest item from this priority queue.\r
- /// </summary>\r
- /// <returns>The removed item.</returns>\r
- [Tested]\r
- public T DeleteMax()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- //persistence guard?\r
- updatecheck();\r
- if (size == 0)\r
- throw new NoSuchItemException();\r
-\r
- //We must follow the pattern of removeIterative()\r
- stackcheck();\r
-\r
- T retval = deleteMax();\r
- if (ActiveEvents != 0)\r
- {\r
- raiseItemsRemoved(retval, 1);\r
- raiseCollectionChanged();\r
- }\r
- return retval;\r
- }\r
-\r
- private T deleteMax()\r
- {\r
- int level = 0;\r
- Node cursor = root;\r
-\r
- while (cursor.right != null)\r
- {\r
- dirs[level] = -1;\r
- path[level++] = cursor;\r
- cursor = cursor.right;\r
- }\r
-\r
- T retval = cursor.item;\r
-\r
-#if BAG\r
- if (cursor.items > 1)\r
- {\r
- resplicebag(level, cursor);\r
- size--;\r
- return retval;\r
- }\r
-#endif\r
- removeIterativePhase2(cursor, level);\r
- return retval;\r
- }\r
- #endregion\r
-\r
- #region IPredecesorStructure<T> Members\r
-\r
- /// <summary>\r
- /// Find the strict predecessor in the sorted collection of a particular value,\r
- /// i.e. the largest item in the collection less than the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is less than or equal to the minimum of this collection.)</exception>\r
- /// <param name="item">The item to find the predecessor for.</param>\r
- /// <returns>The predecessor.</returns>\r
- [Tested]\r
- public T Predecessor(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- Node cursor = root, bestsofar = null;\r
-\r
- while (cursor != null)\r
- {\r
- int comp = comparer.Compare(cursor.item, item);\r
-\r
- if (comp < 0)\r
- {\r
- bestsofar = cursor;\r
- cursor = right(cursor);\r
- }\r
- else if (comp == 0)\r
- {\r
- cursor = left(cursor);\r
- while (cursor != null)\r
- {\r
- bestsofar = cursor;\r
- cursor = right(cursor);\r
- }\r
- }\r
- else\r
- cursor = left(cursor);\r
- }\r
-\r
- if (bestsofar != null)\r
- return bestsofar.item;\r
- else\r
- throw new NoSuchItemException();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the weak predecessor in the sorted collection of a particular value,\r
- /// i.e. the largest item in the collection less than or equal to the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is less than the minimum of this collection.)</exception>\r
- /// <param name="item">The item to find the weak predecessor for.</param>\r
- /// <returns>The weak predecessor.</returns>\r
- [Tested]\r
- public T WeakPredecessor(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- Node cursor = root, bestsofar = null;\r
-\r
- while (cursor != null)\r
- {\r
- int comp = comparer.Compare(cursor.item, item);\r
-\r
- if (comp < 0)\r
- {\r
- bestsofar = cursor;\r
- cursor = right(cursor);\r
- }\r
- else if (comp == 0)\r
- return cursor.item;\r
- else\r
- cursor = left(cursor);\r
- }\r
-\r
- if (bestsofar != null)\r
- return bestsofar.item;\r
- else\r
- throw new NoSuchItemException();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the strict successor in the sorted collection of a particular value,\r
- /// i.e. the least item in the collection greater than the supplied value.\r
- /// </summary>\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is greater than or equal to the maximum of this collection.)</exception>\r
- /// <param name="item">The item to find the successor for.</param>\r
- /// <returns>The successor.</returns>\r
- [Tested]\r
- public T Successor(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- Node cursor = root, bestsofar = null;\r
-\r
- while (cursor != null)\r
- {\r
- int comp = comparer.Compare(cursor.item, item);\r
-\r
- if (comp > 0)\r
- {\r
- bestsofar = cursor;\r
- cursor = left(cursor);\r
- }\r
- else if (comp == 0)\r
- {\r
- cursor = right(cursor);\r
- while (cursor != null)\r
- {\r
- bestsofar = cursor;\r
- cursor = left(cursor);\r
- }\r
- }\r
- else\r
- cursor = right(cursor);\r
- }\r
-\r
- if (bestsofar != null)\r
- return bestsofar.item;\r
- else\r
- throw new NoSuchItemException();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Find the weak successor in the sorted collection of a particular value,\r
- /// i.e. the least item in the collection greater than or equal to the supplied value.\r
- /// <exception cref="NoSuchItemException"> if no such element exists (the\r
- /// supplied value is greater than the maximum of this collection.)</exception>\r
- /// </summary>\r
- /// <param name="item">The item to find the weak successor for.</param>\r
- /// <returns>The weak successor.</returns>\r
- [Tested]\r
- public T WeakSuccessor(T item)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- Node cursor = root, bestsofar = null;\r
-\r
- while (cursor != null)\r
- {\r
- int comp = comparer.Compare(cursor.item, item);\r
-\r
- if (comp == 0)\r
- return cursor.item;\r
- else if (comp > 0)\r
- {\r
- bestsofar = cursor;\r
- cursor = left(cursor);\r
- }\r
- else\r
- cursor = right(cursor);\r
- }\r
-\r
- if (bestsofar != null)\r
- return bestsofar.item;\r
- else\r
- throw new NoSuchItemException();\r
- }\r
-\r
- #endregion\r
-\r
- #region ISorted<T> Members\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items greater than or equal to a supplied value.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeFrom(T bot)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- return new Range(this, true, bot, false, default(T), EnumerationDirection.Forwards);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items between two supplied values.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive).</param>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeFromTo(T bot, T top)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- return new Range(this, true, bot, true, top, EnumerationDirection.Forwards);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Query this sorted collection for items less than a supplied value.\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive).</param>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeTo(T top)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- return new Range(this, false, default(T), true, top, EnumerationDirection.Forwards);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Create a directed collection with the same items as this collection.\r
- /// </summary>\r
- /// <returns>The result directed collection.</returns>\r
- [Tested]\r
- public IDirectedCollectionValue<T> RangeAll()\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- return new Range(this, false, default(T), false, default(T), EnumerationDirection.Forwards);\r
- }\r
-\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> ISorted<T>.RangeFrom(T bot) { return RangeFrom(bot); }\r
-\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> ISorted<T>.RangeFromTo(T bot, T top) { return RangeFromTo(bot, top); }\r
-\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> ISorted<T>.RangeTo(T top) { return RangeTo(top); }\r
-\r
-\r
- //Utility for CountXxxx. Actually always called with strict = true.\r
- private int countTo(T item, bool strict)\r
- {\r
-#if NCP\r
- if (isSnapShot)\r
- throw new NotSupportedException("Indexing not supported for snapshots");\r
-#endif\r
-#if MAINTAIN_SIZE\r
- int ind = 0, comp = 0; Node next = root;\r
-\r
- while (next != null)\r
- {\r
- comp = comparer.Compare(item, next.item);\r
- if (comp < 0)\r
- next = next.left;\r
- else\r
- {\r
- int leftcnt = next.left == null ? 0 : next.left.size;\r
-#if BAG\r
- if (comp == 0)\r
- return strict ? ind + leftcnt : ind + leftcnt + next.items;\r
- else\r
- {\r
- ind = ind + next.items + leftcnt;\r
- next = next.right;\r
- }\r
-#else\r
- if (comp == 0)\r
- return strict ? ind + leftcnt : ind + leftcnt + 1;\r
- else\r
- {\r
- ind = ind + 1 + leftcnt;\r
- next = next.right;\r
- }\r
-#endif\r
- }\r
- }\r
-\r
- //if we get here, we are at the same side of the whole collection:\r
- return ind;\r
-#else\r
- throw new NotSupportedException("Code compiled w/o size!");\r
-#endif\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Perform a search in the sorted collection for the ranges in which a\r
- /// non-increasing (i.e. weakly decrerasing) function from the item type to \r
- /// <code>int</code> is\r
- /// negative, zero respectively positive. If the supplied cut function is\r
- /// not non-increasing, the result of this call is undefined.\r
- /// </summary>\r
- /// <param name="c">The cut function <code>T</code> to <code>int</code>, given\r
- /// as an <code>IComparable<T></code> object, where the cut function is\r
- /// the <code>c.CompareTo(T that)</code> method.</param>\r
- /// <param name="low">Returns the largest item in the collection, where the\r
- /// cut function is positive (if any).</param>\r
- /// <param name="lowIsValid">True if the cut function is positive somewhere\r
- /// on this collection.</param>\r
- /// <param name="high">Returns the least item in the collection, where the\r
- /// cut function is negative (if any).</param>\r
- /// <param name="highIsValid">True if the cut function is negative somewhere\r
- /// on this collection.</param>\r
- /// <returns></returns>\r
- [Tested]\r
- public bool Cut(IComparable<T> c, out T low, out bool lowIsValid, out T high, out bool highIsValid)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- Node cursor = root, lbest = null, rbest = null;\r
- bool res = false;\r
-\r
- while (cursor != null)\r
- {\r
- int comp = c.CompareTo(cursor.item);\r
-\r
- if (comp > 0)\r
- {\r
- lbest = cursor;\r
- cursor = right(cursor);\r
- }\r
- else if (comp < 0)\r
- {\r
- rbest = cursor;\r
- cursor = left(cursor);\r
- }\r
- else\r
- {\r
- res = true;\r
-\r
- Node tmp = left(cursor);\r
-\r
- while (tmp != null && c.CompareTo(tmp.item) == 0)\r
- tmp = left(tmp);\r
-\r
- if (tmp != null)\r
- {\r
- lbest = tmp;\r
- tmp = right(tmp);\r
- while (tmp != null)\r
- {\r
- if (c.CompareTo(tmp.item) > 0)\r
- {\r
- lbest = tmp;\r
- tmp = right(tmp);\r
- }\r
- else\r
- tmp = left(tmp);\r
- }\r
- }\r
-\r
- tmp = right(cursor);\r
- while (tmp != null && c.CompareTo(tmp.item) == 0)\r
- tmp = right(tmp);\r
-\r
- if (tmp != null)\r
- {\r
- rbest = tmp;\r
- tmp = left(tmp);\r
- while (tmp != null)\r
- {\r
- if (c.CompareTo(tmp.item) < 0)\r
- {\r
- rbest = tmp;\r
- tmp = left(tmp);\r
- }\r
- else\r
- tmp = right(tmp);\r
- }\r
- }\r
-\r
- break;\r
- }\r
- }\r
-\r
- if (highIsValid = (rbest != null))\r
- high = rbest.item;\r
- else\r
- high = default(T);\r
-\r
- if (lowIsValid = (lbest != null))\r
- low = lbest.item;\r
- else\r
- low = default(T);\r
-\r
- return res;\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Determine the number of items at or above a supplied threshold.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- [Tested]\r
- public int CountFrom(T bot)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- return size - countTo(bot, true);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Determine the number of items between two supplied thresholds.\r
- /// </summary>\r
- /// <param name="bot">The lower bound (inclusive)</param>\r
- /// <param name="top">The upper bound (exclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- [Tested]\r
- public int CountFromTo(T bot, T top)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- if (comparer.Compare(bot, top) >= 0)\r
- return 0;\r
-\r
- return countTo(top, true) - countTo(bot, true);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Determine the number of items below a supplied threshold.\r
- /// </summary>\r
- /// <param name="top">The upper bound (exclusive)</param>\r
- /// <returns>The number of matcing items.</returns>\r
- [Tested]\r
- public int CountTo(T top)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- return countTo(top, true);\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection above or at a supplied threshold.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- [Tested]\r
- public void RemoveRangeFrom(T low)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- int count = CountFrom(low);\r
-\r
- if (count == 0)\r
- return;\r
-\r
- stackcheck();\r
- CircularQueue<T> wasRemoved = (ActiveEvents & EventTypeEnum.Removed) != 0 ? new CircularQueue<T>() : null;\r
-\r
- for (int i = 0; i < count; i++)\r
- {\r
- T item = deleteMax();\r
- if (wasRemoved != null)\r
- wasRemoved.Enqueue(item);\r
- }\r
- if (wasRemoved != null)\r
- raiseForRemoveAll(wasRemoved);\r
- else if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection between two supplied thresholds.\r
- /// </summary>\r
- /// <param name="low">The lower threshold (inclusive).</param>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- [Tested]\r
- public void RemoveRangeFromTo(T low, T hi)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- int count = CountFromTo(low, hi);\r
-\r
- if (count == 0)\r
- return;\r
-\r
- CircularQueue<T> wasRemoved = (ActiveEvents & EventTypeEnum.Removed) != 0 ? new CircularQueue<T>() : null;\r
- int junk;\r
- for (int i = 0; i < count; i++)\r
- {\r
- T item = Predecessor(hi);\r
- removeIterative(ref item, false, out junk);\r
- if (wasRemoved != null)\r
- wasRemoved.Enqueue(item);\r
- }\r
- if (wasRemoved != null)\r
- raiseForRemoveAll(wasRemoved);\r
- else if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Remove all items of this collection below a supplied threshold.\r
- /// </summary>\r
- /// <param name="hi">The upper threshold (exclusive).</param>\r
- [Tested]\r
- public void RemoveRangeTo(T hi)\r
- {\r
- if (!isValid)\r
- throw new ViewDisposedException("Snapshot has been disposed");\r
- updatecheck();\r
-\r
- int count = CountTo(hi);\r
-\r
- if (count == 0)\r
- return;\r
-\r
- stackcheck();\r
- CircularQueue<T> wasRemoved = (ActiveEvents & EventTypeEnum.Removed) != 0 ? new CircularQueue<T>() : null;\r
-\r
- for (int i = 0; i < count; i++)\r
- {\r
- T item = deleteMin();\r
- if (wasRemoved != null)\r
- wasRemoved.Enqueue(item);\r
- }\r
- if (wasRemoved != null)\r
- raiseForRemoveAll(wasRemoved);\r
- else if ((ActiveEvents & EventTypeEnum.Changed) != 0)\r
- raiseCollectionChanged();\r
- }\r
-\r
- #endregion\r
-\r
- #region IPersistent<T> Members\r
-#if NCP\r
- int maxsnapid { get { return snapList == null ? -1 : findLastLiveSnapShot(); } }\r
-\r
- int findLastLiveSnapShot()\r
- {\r
- if (snapList == null)\r
- return -1;\r
- SnapRef lastLiveSnapRef = snapList.Prev;\r
- object _snapshot = null;\r
- while (lastLiveSnapRef != null && (_snapshot = lastLiveSnapRef.Tree.Target) == null)\r
- lastLiveSnapRef = lastLiveSnapRef.Prev;\r
- if (lastLiveSnapRef == null)\r
- {\r
- snapList = null;\r
- return -1;\r
- }\r
- if (snapList.Prev != lastLiveSnapRef)\r
- {\r
- snapList.Prev = lastLiveSnapRef;\r
- lastLiveSnapRef.Next = snapList;\r
- }\r
- return ((TreeSet<T>)_snapshot).generation;\r
- }\r
-\r
- [Serializable]\r
- class SnapRef\r
- {\r
- public SnapRef Prev, Next;\r
- public WeakReference Tree;\r
- public SnapRef(TreeSet<T> tree) { Tree = new WeakReference(tree); }\r
- public void Dispose()\r
- {\r
- Next.Prev = Prev;\r
- if (Prev != null)\r
- Prev.Next = Next;\r
- Next = Prev = null;\r
- }\r
- }\r
-#endif\r
-\r
- /// <summary>\r
- /// If this tree is a snapshot, remove registration in base tree\r
- /// </summary>\r
- [Tested]\r
- public void Dispose()\r
- {\r
-#if NCP\r
- if (!isValid)\r
- return;\r
- if (isSnapShot)\r
- {\r
- snapList.Dispose();\r
- snapDispose();\r
- }\r
- else\r
- {\r
- if (snapList != null)\r
- {\r
- SnapRef someSnapRef = snapList.Prev;\r
- while (someSnapRef != null)\r
- {\r
- TreeSet<T> lastsnap;\r
- if ((lastsnap = someSnapRef.Tree.Target as TreeSet<T>) != null)\r
- lastsnap.snapDispose();\r
- someSnapRef = someSnapRef.Prev;\r
- }\r
- }\r
- snapList = null;\r
- Clear();\r
- }\r
-#else\r
- Clear();\r
-#endif\r
- }\r
-\r
- private void snapDispose()\r
- {\r
- root = null;\r
- dirs = null;\r
- path = null;\r
- comparer = null;\r
- isValid = false;\r
- snapList = null;\r
- }\r
-\r
- /// <summary>\r
- /// Make a (read-only) snapshot of this collection.\r
- /// </summary>\r
- /// <returns>The snapshot.</returns>\r
- [Tested]\r
- public ISorted<T> Snapshot()\r
- {\r
-#if NCP\r
- if (isSnapShot)\r
- throw new InvalidOperationException("Cannot snapshot a snapshot");\r
-\r
- TreeSet<T> res = (TreeSet<T>)MemberwiseClone();\r
- SnapRef newSnapRef = new SnapRef(res);\r
- res.isReadOnly = true;\r
- res.isSnapShot = true;\r
- res.snapList = newSnapRef;\r
-\r
- findLastLiveSnapShot();\r
- if (snapList == null)\r
- snapList = new SnapRef(this);\r
- SnapRef lastLiveSnapRef = snapList.Prev;\r
-\r
- newSnapRef.Prev = lastLiveSnapRef;\r
- if (lastLiveSnapRef != null)\r
- lastLiveSnapRef.Next = newSnapRef;\r
- newSnapRef.Next = snapList;\r
- snapList.Prev = newSnapRef;\r
-\r
- generation++;\r
-\r
- return res;\r
-#endif\r
- }\r
-\r
- #endregion\r
-\r
- #region TreeSet.Range nested class\r
-\r
- internal class Range : DirectedCollectionValueBase<T>, IDirectedCollectionValue<T>\r
- {\r
- //We actually need exclusive upper and lower bounds, and flags to \r
- //indicate whether the bound is present (we canot rely on default(T))\r
- private int stamp, size;\r
-\r
- private TreeSet<T> basis;\r
-\r
- private T lowend, highend;\r
-\r
- private bool haslowend, hashighend;\r
-\r
- EnumerationDirection direction;\r
-\r
-\r
- [Tested]\r
- public Range(TreeSet<T> basis, bool haslowend, T lowend, bool hashighend, T highend, EnumerationDirection direction)\r
- {\r
- this.basis = basis;\r
- stamp = basis.stamp;\r
-\r
- //lowind will be const; should we cache highind?\r
- this.lowend = lowend; //Inclusive\r
- this.highend = highend;//Exclusive\r
- this.haslowend = haslowend;\r
- this.hashighend = hashighend;\r
- this.direction = direction;\r
- if (!basis.isSnapShot)\r
- size = haslowend ?\r
- (hashighend ? basis.CountFromTo(lowend, highend) : basis.CountFrom(lowend)) :\r
- (hashighend ? basis.CountTo(highend) : basis.Count);\r
- }\r
-\r
- #region IEnumerable<T> Members\r
-\r
-\r
- #region TreeSet.Range.Enumerator nested class\r
-\r
- internal class Enumerator : SCG.IEnumerator<T>\r
- {\r
- #region Private Fields\r
- private bool valid = false, ready = true;\r
-\r
- private SCG.IComparer<T> comparer;\r
-\r
- private T current;\r
-#if BAG\r
- int togo;\r
-#endif\r
-\r
- private Node cursor;\r
-\r
- private Node[] path; // stack of nodes\r
-\r
- private int level = 0;\r
-\r
- private Range range;\r
-\r
- private bool forwards;\r
-\r
- #endregion\r
- [Tested]\r
- public Enumerator(Range range)\r
- {\r
- comparer = range.basis.comparer;\r
- path = new Node[2 * range.basis.blackdepth];\r
- this.range = range;\r
- forwards = range.direction == EnumerationDirection.Forwards;\r
- cursor = new Node();\r
- if (forwards)\r
- cursor.right = range.basis.root;\r
- else\r
- cursor.left = range.basis.root;\r
- range.basis.modifycheck(range.stamp);\r
- }\r
-\r
-\r
- int compare(T i1, T i2) { return comparer.Compare(i1, i2); }\r
-\r
-\r
- /// <summary>\r
- /// Undefined if enumerator is not valid (MoveNext hash been called returning true)\r
- /// </summary>\r
- /// <value>The current value of the enumerator.</value>\r
- [Tested]\r
- public T Current\r
- {\r
- [Tested]\r
- get\r
- {\r
- if (valid)\r
- return current;\r
- else\r
- throw new InvalidOperationException();\r
- }\r
- }\r
-\r
-\r
- //Maintain a stack of nodes that are roots of\r
- //subtrees not completely exported yet. Invariant:\r
- //The stack nodes together with their right subtrees\r
- //consists of exactly the items we have not passed\r
- //yet (the top of the stack holds current item).\r
- /// <summary>\r
- /// Move enumerator to next item in tree, or the first item if\r
- /// this is the first call to MoveNext. \r
- /// <exception cref="CollectionModifiedException"/> if underlying tree was modified.\r
- /// </summary>\r
- /// <returns>True if enumerator is valid now</returns>\r
- [Tested]\r
- public bool MoveNext()\r
- {\r
- range.basis.modifycheck(range.stamp);\r
- if (!ready)\r
- return false;\r
-#if BAG\r
- if (--togo > 0)\r
- return true;\r
-#endif\r
- if (forwards)\r
- {\r
- if (!valid && range.haslowend)\r
- {\r
- cursor = cursor.right;\r
- while (cursor != null)\r
- {\r
- int comp = compare(cursor.item, range.lowend);\r
-\r
- if (comp > 0)\r
- {\r
- path[level++] = cursor;\r
-#if NCP\r
- cursor = range.basis.left(cursor);\r
-#else\r
- cursor = cursor.left;\r
-#endif\r
- }\r
- else if (comp < 0)\r
- {\r
-#if NCP\r
- cursor = range.basis.right(cursor);\r
-#else\r
- cursor = cursor.right;\r
-#endif\r
- }\r
- else\r
- {\r
- path[level] = cursor;\r
- break;\r
- }\r
- }\r
-\r
- if (cursor == null)\r
- {\r
- if (level == 0)\r
- return valid = ready = false;\r
- else\r
- cursor = path[--level];\r
- }\r
- }\r
-#if NCP\r
- else if (range.basis.right(cursor) != null)\r
- {\r
- path[level] = cursor = range.basis.right(cursor);\r
-\r
- Node next = range.basis.left(cursor);\r
-\r
- while (next != null)\r
- {\r
- path[++level] = cursor = next;\r
- next = range.basis.left(cursor);\r
- }\r
- }\r
-#else\r
- else if (cursor.right != null)\r
- {\r
- path[level] = cursor = cursor.right;\r
- while (cursor.left != null)\r
- path[++level] = cursor = cursor.left;\r
- }\r
-#endif\r
- else if (level == 0)\r
- return valid = ready = false;\r
- else\r
- cursor = path[--level];\r
-\r
- current = cursor.item;\r
- if (range.hashighend && compare(current, range.highend) >= 0)\r
- return valid = ready = false;\r
-\r
-#if BAG\r
- togo = cursor.items;\r
-#endif\r
- return valid = true;\r
- }\r
- else\r
- {\r
- if (!valid && range.hashighend)\r
- {\r
- cursor = cursor.left;\r
- while (cursor != null)\r
- {\r
- int comp = compare(cursor.item, range.highend);\r
-\r
- if (comp < 0)\r
- {\r
- path[level++] = cursor;\r
-#if NCP\r
- cursor = range.basis.right(cursor);\r
-#else\r
- cursor = cursor.right;\r
-#endif\r
- }\r
- else\r
- {\r
-#if NCP\r
- cursor = range.basis.left(cursor);\r
-#else\r
- cursor = cursor.left;\r
-#endif\r
- }\r
- }\r
-\r
- if (cursor == null)\r
- {\r
- if (level == 0)\r
- return valid = ready = false;\r
- else\r
- cursor = path[--level];\r
- }\r
- }\r
-#if NCP\r
- else if (range.basis.left(cursor) != null)\r
- {\r
- path[level] = cursor = range.basis.left(cursor);\r
-\r
- Node next = range.basis.right(cursor);\r
-\r
- while (next != null)\r
- {\r
- path[++level] = cursor = next;\r
- next = range.basis.right(cursor);\r
- }\r
- }\r
-#else\r
- else if (cursor.left != null)\r
- {\r
- path[level] = cursor = cursor.left;\r
- while (cursor.right != null)\r
- path[++level] = cursor = cursor.right;\r
- }\r
-#endif\r
- else if (level == 0)\r
- return valid = ready = false;\r
- else\r
- cursor = path[--level];\r
-\r
- current = cursor.item;\r
- if (range.haslowend && compare(current, range.lowend) < 0)\r
- return valid = ready = false;\r
-\r
-#if BAG\r
- togo = cursor.items;\r
-#endif\r
- return valid = true;\r
- }\r
- }\r
-\r
-\r
- [Tested]\r
- public void Dispose()\r
- {\r
- comparer = null;\r
- current = default(T);\r
- cursor = null;\r
- path = null;\r
- range = null;\r
- }\r
-\r
- #region IEnumerator Members\r
-\r
- object System.Collections.IEnumerator.Current\r
- {\r
- get { return Current; }\r
- }\r
-\r
- bool System.Collections.IEnumerator.MoveNext()\r
- {\r
- return MoveNext();\r
- }\r
-\r
- void System.Collections.IEnumerator.Reset()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
-\r
- #endregion\r
- }\r
-\r
- #endregion\r
-\r
-\r
- public override T Choose()\r
- {\r
- if (size == 0) throw new NoSuchItemException();\r
- return lowend;\r
- }\r
-\r
- [Tested]\r
- public override SCG.IEnumerator<T> GetEnumerator() { return new Enumerator(this); }\r
-\r
-\r
- [Tested]\r
- public override EnumerationDirection Direction { [Tested]get { return direction; } }\r
-\r
-\r
- #endregion\r
-\r
- #region Utility\r
-\r
- bool inside(T item)\r
- {\r
- return (!haslowend || basis.comparer.Compare(item, lowend) >= 0) && (!hashighend || basis.comparer.Compare(item, highend) < 0);\r
- }\r
-\r
-\r
- void checkstamp()\r
- {\r
- if (stamp < basis.stamp)\r
- throw new CollectionModifiedException();\r
- }\r
-\r
-\r
- void syncstamp() { stamp = basis.stamp; }\r
-\r
- #endregion\r
-\r
- [Tested]\r
- public override IDirectedCollectionValue<T> Backwards()\r
- {\r
- Range b = (Range)MemberwiseClone();\r
-\r
- b.direction = direction == EnumerationDirection.Forwards ? EnumerationDirection.Backwards : EnumerationDirection.Forwards;\r
- return b;\r
- }\r
-\r
-\r
- [Tested]\r
- IDirectedEnumerable<T> IDirectedEnumerable<T>.Backwards() { return Backwards(); }\r
-\r
-\r
- public override bool IsEmpty { get { return size == 0; } }\r
-\r
- [Tested]\r
- public override int Count { [Tested] get { return size; } }\r
-\r
- //TODO: check that this is correct\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
-\r
- }\r
-\r
- #endregion\r
-\r
- #region Diagnostics\r
- /// <summary>\r
- /// Display this node on the console, and recursively its subnodes.\r
- /// </summary>\r
- /// <param name="n">Node to display</param>\r
- /// <param name="space">Indentation</param>\r
- private void minidump(Node n, string space)\r
- {\r
- if (n == null)\r
- {\r
- // System.Console.WriteLine(space + "null");\r
- }\r
- else\r
- {\r
- minidump(n.right, space + " ");\r
- Console.WriteLine(String.Format("{0} {4} (size={1}, items={8}, h={2}, gen={3}, id={6}){7}", space + n.item,\r
-#if MAINTAIN_SIZE\r
- n.size,\r
-#else\r
- 0,\r
-#endif\r
- 0,\r
-#if NCP\r
- n.generation,\r
-#endif\r
- n.red ? "RED" : "BLACK",\r
- 0,\r
- 0,\r
-#if NCP\r
-#if SEPARATE_EXTRA\r
- n.extra == null ? "" : String.Format(" [extra: lg={0}, c={1}, i={2}]", n.extra.lastgeneration, n.extra.leftnode ? "L" : "R", n.extra.oldref == null ? "()" : "" + n.extra.oldref.item),\r
-#else\r
- n.lastgeneration == -1 ? "" : String.Format(" [extra: lg={0}, c={1}, i={2}]", n.lastgeneration, n.leftnode ? "L" : "R", n.oldref == null ? "()" : "" + n.oldref.item),\r
-#endif\r
-#else\r
- "",\r
-#endif\r
-#if BAG\r
- n.items\r
-#else\r
- 1\r
-#endif\r
-));\r
- minidump(n.left, space + " ");\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Print the tree structure to the console stdout.\r
- /// </summary>\r
- [Tested(via = "Sawtooth")]\r
- public void dump() { dump(""); }\r
-\r
-\r
- /// <summary>\r
- /// Print the tree structure to the console stdout.\r
- /// </summary>\r
- [Tested(via = "Sawtooth")]\r
- public void dump(string msg)\r
- {\r
- Console.WriteLine(String.Format(">>>>>>>>>>>>>>>>>>> dump {0} (count={1}, blackdepth={2}, depth={3}, gen={4})", msg, size, blackdepth,\r
- 0\r
- ,\r
-#if NCP\r
- generation\r
-#endif\r
-));\r
- minidump(root, "");\r
- check("", Console.Out); Console.WriteLine("<<<<<<<<<<<<<<<<<<<");\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Display this tree on the console.\r
- /// </summary>\r
- /// <param name="msg">Identifying string of this call to dump</param>\r
- /// <param name="err">Extra (error)message to include</param>\r
- void dump(string msg, string err)\r
- {\r
- Console.WriteLine(String.Format(">>>>>>>>>>>>>>>>>>> dump {0} (count={1}, blackdepth={2}, depth={3}, gen={4})", msg, size, blackdepth,\r
- 0\r
- ,\r
-#if NCP\r
- generation\r
-#endif\r
-));\r
- minidump(root, ""); Console.Write(err);\r
- Console.WriteLine("<<<<<<<<<<<<<<<<<<<");\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Print warning m on o if b is false.\r
- /// </summary>\r
- /// <param name="b">Condition that should hold</param>\r
- /// <param name="n">Place (used for id display)</param>\r
- /// <param name="m">Message</param>\r
- /// <param name="o">Output stream</param>\r
- /// <returns>b</returns>\r
- bool massert(bool b, Node n, string m, System.IO.TextWriter o)\r
- {\r
- if (!b) o.WriteLine("*** Node (item={0}, id={1}): {2}", n.item,\r
- 0\r
- , m);\r
-\r
- return b;\r
- }\r
-\r
-\r
- bool rbminicheck(Node n, bool redp, System.IO.TextWriter o, out T min, out T max, out int blackheight, int maxgen)\r
- {//Red-Black invariant\r
- bool res = true;\r
-\r
- res = massert(!(n.red && redp), n, "RED parent of RED node", o) && res;\r
- res = massert(n.left == null || n.right != null || n.left.red, n, "Left child black, but right child empty", o) && res;\r
- res = massert(n.right == null || n.left != null || n.right.red, n, "Right child black, but left child empty", o) && res;\r
-#if BAG\r
- bool sb = n.size == (n.left == null ? 0 : n.left.size) + (n.right == null ? 0 : n.right.size) + n.items;\r
-\r
- res = massert(sb, n, "Bad size", o) && res;\r
-#elif MAINTAIN_SIZE\r
- bool sb = n.size == (n.left == null ? 0 : n.left.size) + (n.right == null ? 0 : n.right.size) + 1;\r
-\r
- res = massert(sb, n, "Bad size", o) && res;\r
-#endif\r
- min = max = n.item;\r
-\r
- T otherext;\r
- int lbh = 0, rbh = 0;\r
-\r
- if (n.left != null)\r
- {\r
- res = rbminicheck(n.left, n.red, o, out min, out otherext, out lbh, generation) && res;\r
- res = massert(comparer.Compare(n.item, otherext) > 0, n, "Value not > all left children", o) && res;\r
- }\r
-\r
- if (n.right != null)\r
- {\r
- res = rbminicheck(n.right, n.red, o, out otherext, out max, out rbh, generation) && res;\r
- res = massert(comparer.Compare(n.item, otherext) < 0, n, "Value not < all right children", o) && res;\r
- }\r
-\r
- res = massert(rbh == lbh, n, "Different blackheights of children", o) && res;\r
- blackheight = n.red ? rbh : rbh + 1;\r
- return res;\r
- }\r
-\r
-\r
-\r
-\r
-#if NCP\r
-\r
- bool rbminisnapcheck(Node n, System.IO.TextWriter o, out int size, out T min, out T max)\r
- {\r
- bool res = true;\r
-\r
- min = max = n.item;\r
-\r
- int lsz = 0, rsz = 0;\r
- T otherext;\r
-#if SEPARATE_EXTRA\r
- Node.Extra extra = n.extra;\r
- Node child = (extra != null && extra.lastgeneration >= treegen && extra.leftnode) ? extra.oldref : n.left;\r
-#else\r
- Node child = (n.lastgeneration >= generation && n.leftnode) ? n.oldref : n.left;\r
-#endif\r
- if (child != null)\r
- {\r
- res = rbminisnapcheck(child, o, out lsz, out min, out otherext) && res;\r
- res = massert(comparer.Compare(n.item, otherext) > 0, n, "Value not > all left children", o) && res;\r
- }\r
-\r
-#if SEPARATE_EXTRA\r
- child = (extra != null && extra.lastgeneration >= treegen && !extra.leftnode) ? extra.oldref : n.right;\r
-#else\r
- child = (n.lastgeneration >= generation && !n.leftnode) ? n.oldref : n.right;\r
-#endif\r
- if (child != null)\r
- {\r
- res = rbminisnapcheck(child, o, out rsz, out otherext, out max) && res;\r
- res = massert(comparer.Compare(n.item, otherext) < 0, n, "Value not < all right children", o) && res;\r
- }\r
-#if BAG\r
- size = n.items + lsz + rsz;\r
-#else\r
- size = 1 + lsz + rsz;\r
-#endif\r
- return res;\r
- }\r
-#endif\r
-\r
- /// <summary>\r
- /// Checks red-black invariant. Dumps tree to console if bad\r
- /// </summary>\r
- /// <param name="name">Title of dump</param>\r
- /// <returns>false if invariant violation</returns>\r
- [Tested(via = "Sawtooth")]\r
- public bool Check(string name)\r
- {\r
- System.Text.StringBuilder e = new System.Text.StringBuilder();\r
- System.IO.TextWriter o = new System.IO.StringWriter(e);\r
-\r
- if (!check(name, o))\r
- return true;\r
- else\r
- {\r
- dump(name, e.ToString());\r
- return false;\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Checks red-black invariant. Dumps tree to console if bad\r
- /// </summary>\r
- /// <returns>false if invariant violation</returns>\r
- [Tested]\r
- public bool Check()\r
- {\r
- //return check("", System.IO.TextWriter.Null);\r
- //Console.WriteLine("bamse");\r
- if (!isValid)\r
- return true;\r
- return Check("-");\r
- }\r
-\r
-\r
- bool check(string msg, System.IO.TextWriter o)\r
- {\r
- if (root != null)\r
- {\r
- T max, min;\r
- int blackheight;\r
-#if NCP\r
- if (isSnapShot)\r
- {\r
- //Console.WriteLine("Im'a snapshot");\r
- int thesize;\r
- bool rv = rbminisnapcheck(root, o, out thesize, out min, out max);\r
-\r
- rv = massert(size == thesize, root, "bad snapshot size", o) && rv;\r
- return !rv;\r
- }\r
-#endif\r
- bool res = rbminicheck(root, false, o, out min, out max, out blackheight, generation);\r
- res = massert(blackheight == blackdepth, root, "bad blackh/d", o) && res;\r
- res = massert(!root.red, root, "root is red", o) && res;\r
-#if MAINTAIN_SIZE\r
- res = massert(root.size == size, root, "count!=root.size", o) && res;\r
-#endif\r
- return !res;\r
- }\r
- else\r
- return false;\r
- }\r
- #endregion\r
-\r
- #region ICloneable Members\r
-\r
- /// <summary>\r
- /// Make a shallow copy of this TreeSet.\r
- /// </summary>\r
- /// <returns></returns>\r
- public virtual object Clone()\r
- {\r
- TreeSet<T> clone = new TreeSet<T>(comparer, EqualityComparer);\r
- //TODO: make sure the TreeBag AddSorted copies tree bags smartly!!!\r
- clone.AddSorted(this);\r
- return clone;\r
- }\r
-\r
- #endregion\r
-\r
- }\r
-}\r
-\r
+++ /dev/null
-Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft.\r
-\r
-Permission is hereby granted, free of charge, to any person obtaining a copy\r
-of this software and associated documentation files (the "Software"), to deal\r
-in the Software without restriction, including without limitation the rights\r
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-copies of the Software, and to permit persons to whom the Software is\r
-furnished to do so, subject to the following conditions:\r
-\r
-The above copyright notice and this permission notice shall be included in\r
-all copies or substantial portions of the Software.\r
-\r
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
-SOFTWARE.\r
+++ /dev/null
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
- <ProductVersion>8.0.40607</ProductVersion>\r
- <SchemaVersion>2.0</SchemaVersion>\r
- <ProjectGuid>{6222CA51-7D1A-4D42-B6A7-B5CE9608C18F}</ProjectGuid>\r
- <OutputType>Exe</OutputType>\r
- <RootNamespace>PreProcess</RootNamespace>\r
- <AssemblyName>PreProcess</AssemblyName>\r
- <WarningLevel>4</WarningLevel>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
- <DebugSymbols>true</DebugSymbols>\r
- <DebugType>full</DebugType>\r
- <Optimize>false</Optimize>\r
- <OutputPath>.\bin\Debug\</OutputPath>\r
- <DefineConstants>DEBUG;TRACE</DefineConstants>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
- <DebugSymbols>false</DebugSymbols>\r
- <Optimize>true</Optimize>\r
- <OutputPath>.\bin\Release\</OutputPath>\r
- <DefineConstants>TRACE</DefineConstants>\r
- </PropertyGroup>\r
- <ItemGroup>\r
- <Compile Include="Program.cs" />\r
- </ItemGroup>\r
- <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />\r
-</Project>
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Text;\r
-using System.IO;\r
-\r
-namespace PreProcess\r
-{\r
- class Program\r
- {\r
- static void preprocess(string dir, string filein, string fileout, string symbol, string classin, string classout)\r
- {\r
- fileout = Path.Combine(dir, fileout);\r
- string[] contents = File.ReadAllLines(Path.Combine(dir, filein));\r
- string symboldef = "#define " + symbol + "not";\r
- bool equal = File.Exists(fileout);\r
- TextReader oldversion = equal ? new StreamReader(fileout) : null;\r
- for (int lineno = 0; lineno < contents.Length; lineno++)\r
- {\r
- if (contents[lineno].StartsWith(symboldef))\r
- contents[lineno] = "#define " + symbol;\r
- else\r
- contents[lineno] = contents[lineno].Replace(classin, classout);\r
- if (equal)\r
- equal = contents[lineno] == oldversion.ReadLine();\r
- }\r
- if (equal && oldversion.ReadLine() == null)\r
- {\r
- Console.Error.WriteLine("File {0} is up-to-date", fileout);\r
- return;\r
- }\r
- File.WriteAllLines(fileout + "-new", contents);\r
- if (oldversion != null)\r
- {\r
- oldversion.Close();\r
- File.Replace(fileout + "-new", fileout, fileout + ".bak");\r
- Console.Error.WriteLine("Updated {0}", fileout);\r
- }\r
- else\r
- {\r
- File.Move(fileout + "-new", fileout);\r
- Console.Error.WriteLine("Created {0}", fileout);\r
- }\r
- }\r
- static void Main(string[] args)\r
- {\r
- System.Environment.CurrentDirectory = @"..\..\..\C5";\r
- preprocess("trees", "RedBlackTreeSet.cs", "RedBlackTreeBag.cs", "BAG", "TreeSet", "TreeBag");\r
- preprocess("arrays", "ArrayList.cs", "HashedArrayList.cs", "HASHINDEX", "ArrayList", "HashedArrayList");\r
- preprocess("linkedlists", "LinkedList.cs", "HashedLinkedList.cs", "HASHINDEX", "LinkedList", "HashedLinkedList");\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System.Reflection;\r
-using System.Runtime.CompilerServices;\r
-\r
-//\r
-// General Information about an assembly is controlled through the following \r
-// set of attributes. Change these attribute values to modify the information\r
-// associated with an assembly.\r
-//\r
-[assembly: AssemblyTitle("")]\r
-[assembly: AssemblyDescription("")]\r
-[assembly: AssemblyConfiguration("")]\r
-[assembly: AssemblyCompany("")]\r
-[assembly: AssemblyProduct("")]\r
-[assembly: AssemblyCopyright("")]\r
-[assembly: AssemblyTrademark("")]\r
-[assembly: AssemblyCulture("")]\r
-\r
-//\r
-// Version information for an assembly consists of the following four values:\r
-//\r
-// Major Version\r
-// Minor Version \r
-// Build Number\r
-// Revision\r
-//\r
-// You can specify all the values or you can default the Revision and Build Numbers \r
-// by using the '*' as shown below:\r
-\r
-[assembly: AssemblyVersion("1.0.*")]\r
-\r
-//\r
-// In order to sign your assembly you must specify a key to use. Refer to the \r
-// Microsoft .NET Framework documentation for more information on assembly signing.\r
-//\r
-// Use the attributes below to control which key is used for signing. \r
-//\r
-// Notes: \r
-// (*) If no key is specified, the assembly is not signed.\r
-// (*) KeyName refers to a key that has been installed in the Crypto Service\r
-// Provider (CSP) on your machine. KeyFile refers to a file which contains\r
-// a key.\r
-// (*) If the KeyFile and the KeyName values are both specified, the \r
-// following processing occurs:\r
-// (1) If the KeyName can be found in the CSP, that key is used.\r
-// (2) If the KeyName does not exist and the KeyFile does exist, the key \r
-// in the KeyFile is installed into the CSP and used.\r
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.\r
-// When specifying the KeyFile, the location of the KeyFile should be\r
-// relative to the project output directory which is\r
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is\r
-// located in the project directory, you would specify the AssemblyKeyFile \r
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]\r
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework\r
-// documentation for more information on this.\r
-//\r
-[assembly: AssemblyDelaySign(false)]\r
-[assembly: AssemblyKeyFile("")]\r
-[assembly: AssemblyKeyName("")]\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests.support\r
-{\r
- namespace bases\r
- {\r
- [TestFixture]\r
- public class ArrayBaseTest\r
- {\r
- class ABT : ArrayBase<string>\r
- {\r
- public ABT() : base(8,NaturalEqualityComparer<string>.Default) { }\r
-\r
- public override string Choose() { if (size > 0) return array[0]; throw new NoSuchItemException(); }\r
-\r
- public string this[int i] { get { return array[i]; } set { array[i] = value; } }\r
-\r
-\r
- public int thesize { get { return size; } set { size = value; } }\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- ABT abt = new ABT();\r
-\r
- abt.thesize = 3;\r
- abt[2] = "aaa";\r
- // Assert.IsFalse(abt.Check());\r
- abt[0] = "##";\r
- abt[1] = "##";\r
- Assert.IsTrue(abt.Check());\r
- }\r
- }\r
- }\r
-\r
- namespace itemops\r
- {\r
- [TestFixture]\r
- public class Comparers\r
- {\r
- class dbl : IComparable<dbl>\r
- {\r
- double d;\r
-\r
- public dbl(double din) { d = din; }\r
-\r
- public int CompareTo(dbl that)\r
- {\r
- return d < that.d ? -1 : d == that.d ? 0 : 1;\r
- }\r
- public bool Equals(dbl that) { return d == that.d; }\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NotComparableException))]\r
- public void NotComparable()\r
- {\r
- SCG.IComparer<object> foo = Comparer<object>.Default;\r
- }\r
-\r
- [Test]\r
- public void GenericC()\r
- {\r
- SCG.IComparer<dbl> h = new NaturalComparer<dbl>();\r
- dbl s = new dbl(3.4);\r
- dbl t = new dbl(3.4);\r
- dbl u = new dbl(7.4);\r
-\r
- Assert.AreEqual(0, h.Compare(s, t));\r
- Assert.IsTrue(h.Compare(s, u) < 0);\r
- }\r
-\r
-\r
- [Test]\r
- public void OrdinaryC()\r
- {\r
- SCG.IComparer<string> h = new NaturalComparerO<string>();\r
- string s = "bamse";\r
- string t = "bamse";\r
- string u = "bimse";\r
-\r
- Assert.AreEqual(0, h.Compare(s, t));\r
- Assert.IsTrue(h.Compare(s, u) < 0);\r
- }\r
-\r
-\r
- [Test]\r
- public void GenericCViaBuilder()\r
- {\r
- SCG.IComparer<dbl> h = Comparer<dbl>.Default;\r
- dbl s = new dbl(3.4);\r
- dbl t = new dbl(3.4);\r
- dbl u = new dbl(7.4);\r
-\r
- Assert.AreEqual(0, h.Compare(s, t));\r
- Assert.IsTrue(h.Compare(s, u) < 0);\r
- Assert.AreSame(h, Comparer<dbl>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void OrdinaryCViaBuilder()\r
- {\r
- SCG.IComparer<string> h = Comparer<string>.Default;\r
- string s = "bamse";\r
- string t = "bamse";\r
- string u = "bimse";\r
-\r
- Assert.AreEqual(0, h.Compare(s, t));\r
- Assert.IsTrue(h.Compare(s, u) < 0);\r
- Assert.AreSame(h, Comparer<string>.Default);\r
-\r
- }\r
-\r
-\r
- [Test]\r
- public void ICViaBuilder()\r
- {\r
- SCG.IComparer<int> h = Comparer<int>.Default;\r
- int s = 4;\r
- int t = 4;\r
- int u = 5;\r
-\r
- Assert.AreEqual(0, h.Compare(s, t));\r
- Assert.IsTrue(h.Compare(s, u) < 0);\r
- Assert.AreSame(h, Comparer<int>.Default);\r
-\r
- }\r
-\r
- [Test]\r
- public void Nulls()\r
- {\r
- Assert.IsTrue(Comparer<string>.Default.Compare(null, "abe") < 0);\r
- Assert.IsTrue(Comparer<string>.Default.Compare(null, null) == 0);\r
- Assert.IsTrue(Comparer<string>.Default.Compare("abe", null) > 0);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class EqualityComparers\r
- {\r
- [Test]\r
- public void ReftypeequalityComparer()\r
- {\r
- SCG.IEqualityComparer<string> h = NaturalEqualityComparer<string>.Default;\r
- string s = "bamse";\r
- string t = "bamse";\r
- string u = "bimse";\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- }\r
-\r
-\r
- [Test]\r
- public void ValuetypeequalityComparer()\r
- {\r
- SCG.IEqualityComparer<double> h = NaturalEqualityComparer<double>.Default;\r
- double s = 3.4;\r
- double t = 3.4;\r
- double u = 5.7;\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- }\r
-\r
- internal class REHTest { public override int GetHashCode() { return 37; } }\r
-\r
- [Test]\r
- public void ReferenceEqualityEqualityComparerTest()\r
- {\r
- REHTest rehtest = new REHTest();\r
- SCG.IEqualityComparer<REHTest> equalityComparer = ReferenceEqualityComparer<REHTest>.Default;\r
- Assert.AreEqual(37, rehtest.GetHashCode());\r
- Assert.IsFalse(equalityComparer.GetHashCode(rehtest) == 37);\r
- }\r
-\r
- [Test]\r
- public void ReftypeequalityComparerViaBuilder()\r
- {\r
- SCG.IEqualityComparer<string> h = EqualityComparer<string>.Default;\r
- string s = "bamse";\r
- string t = "bamse";\r
- string u = "bimse";\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- Assert.AreSame(h, EqualityComparer<string>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void ValuetypeequalityComparerViaBuilder()\r
- {\r
- SCG.IEqualityComparer<double> h = EqualityComparer<double>.Default;\r
- double s = 3.4;\r
- double t = 3.4;\r
- double u = 5.7;\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- Assert.AreSame(h, EqualityComparer<double>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void IntequalityComparerViaBuilder()\r
- {\r
- SCG.IEqualityComparer<int> h = EqualityComparer<int>.Default;\r
- int s = 3;\r
- int t = 3;\r
- int u = 5;\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- Assert.AreSame(h, EqualityComparer<int>.Default);\r
- }\r
-\r
- [Test]\r
- public void DoubleequalityComparerViaBuilder()\r
- {\r
- SCG.IEqualityComparer<double> h = EqualityComparer<double>.Default;\r
- double s = 3.1;\r
- double t = 3.1;\r
- double u = 5.2;\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- Assert.AreSame(h, EqualityComparer<double>.Default);\r
- }\r
-\r
- [Test]\r
- public void CharequalityComparerViaBuilder()\r
- {\r
- SCG.IEqualityComparer<char> h = EqualityComparer<char>.Default;\r
- char s = 'Ã¥';\r
- char t = 'Ã¥';\r
- char u = 'r';\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- Assert.AreSame(h, EqualityComparer<char>.Default);\r
- }\r
-\r
- [Test]\r
- public void ByteequalityComparerViaBuilder()\r
- {\r
- SCG.IEqualityComparer<byte> h = EqualityComparer<byte>.Default;\r
- byte s = 3;\r
- byte t = 3;\r
- byte u = 5;\r
-\r
- Assert.AreEqual(s.GetHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- Assert.AreSame(h, EqualityComparer<byte>.Default);\r
- }\r
-\r
- [Test]\r
- public void UnseqequalityComparerViaBuilder()\r
- {\r
- SCG.IEqualityComparer<ICollection<int>> h = EqualityComparer<ICollection<int>>.Default;\r
- ICollection<int> s = new LinkedList<int>();\r
- ICollection<int> t = new LinkedList<int>();\r
- ICollection<int> u = new LinkedList<int>();\r
- s.Add(1); s.Add(2); s.Add(3);\r
- t.Add(3); t.Add(2); t.Add(1);\r
- u.Add(3); u.Add(2); u.Add(4);\r
- Assert.AreEqual(s.GetUnsequencedHashCode(), h.GetHashCode(s));\r
- Assert.IsTrue(h.Equals(s, t));\r
- Assert.IsFalse(h.Equals(s, u));\r
- Assert.AreSame(h, EqualityComparer<ICollection<int>>.Default);\r
- }\r
-\r
- [Test]\r
- public void SeqequalityComparerViaBuilder2()\r
- {\r
- SCG.IEqualityComparer<LinkedList<int>> h = EqualityComparer<LinkedList<int>>.Default;\r
- LinkedList<int> s = new LinkedList<int>();\r
- s.Add(1); s.Add(2); s.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(1, 2, 3), h.GetHashCode(s));\r
- }\r
-\r
- [Test]\r
- public void UnseqequalityComparerViaBuilder2()\r
- {\r
- SCG.IEqualityComparer<HashSet<int>> h = EqualityComparer<HashSet<int>>.Default;\r
- HashSet<int> s = new HashSet<int>();\r
- s.Add(1); s.Add(2); s.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(1, 2, 3), h.GetHashCode(s));\r
- }\r
-\r
- //generic types implementing collection interfaces\r
- [Test]\r
- public void SeqequalityComparerViaBuilder3()\r
- {\r
- SCG.IEqualityComparer<IList<int>> h = EqualityComparer<IList<int>>.Default;\r
- IList<int> s = new LinkedList<int>();\r
- s.Add(1); s.Add(2); s.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(1, 2, 3), h.GetHashCode(s));\r
- }\r
-\r
- interface IFoo<T> : ICollection<T> { void Bamse(); }\r
-\r
- class Foo<T> : HashSet<T>, IFoo<T>\r
- {\r
- internal Foo() : base() { }\r
- public void Bamse() { }\r
- }\r
-\r
- [Test]\r
- public void UnseqequalityComparerViaBuilder3()\r
- {\r
- SCG.IEqualityComparer<IFoo<int>> h = EqualityComparer<IFoo<int>>.Default;\r
- IFoo<int> s = new Foo<int>();\r
- s.Add(1); s.Add(2); s.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(1, 2, 3), h.GetHashCode(s));\r
- }\r
-\r
- //Nongeneric types implementing collection types:\r
- interface IBaz : ISequenced<int> { void Bamse(); }\r
-\r
- class Baz : LinkedList<int>, IBaz\r
- {\r
- internal Baz() : base() { }\r
- public void Bamse() { }\r
- //int ISequenced<int>.GetHashCode() { return sequencedhashcode(); }\r
- //bool ISequenced<int>.Equals(ISequenced<int> that) { return sequencedequals(that); }\r
- }\r
-\r
-#warning This test fails because of an error in .Net 2.0\r
- //[Test]\r
- public void SeqequalityComparerViaBuilder4()\r
- {\r
- SCG.IEqualityComparer<IBaz> h = EqualityComparer<IBaz>.Default;\r
- IBaz s = new Baz();\r
- s.Add(1); s.Add(2); s.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(1, 2, 3), h.GetHashCode(s));\r
- }\r
-\r
- interface IBar : ICollection<int>\r
- {\r
- void Bamse();\r
- }\r
-\r
- class Bar : HashSet<int>, IBar\r
- {\r
- internal Bar() : base() { }\r
- public void Bamse() { }\r
-\r
- //TODO: remove all this workaround stuff:\r
- \r
- bool ICollection<int>.ContainsAll<U>(System.Collections.Generic.IEnumerable<U> items) \r
- {\r
- throw new NotImplementedException();\r
- }\r
- \r
- void ICollection<int>.RemoveAll<U>(System.Collections.Generic.IEnumerable<U> items) \r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void ICollection<int>.RetainAll<U>(System.Collections.Generic.IEnumerable<U> items) \r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void IExtensible<int>.AddAll<U>(System.Collections.Generic.IEnumerable<U> items) \r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- }\r
-\r
- [Test]\r
- public void UnseqequalityComparerViaBuilder4()\r
- {\r
- SCG.IEqualityComparer<IBar> h = EqualityComparer<IBar>.Default;\r
- IBar s = new Bar();\r
- s.Add(1); s.Add(2); s.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(1, 2, 3), h.GetHashCode(s));\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.RecordsTests\r
-{\r
- [TestFixture]\r
- public class Basic\r
- {\r
- [SetUp]\r
- public void Init()\r
- {\r
- }\r
- [Test]\r
- public void FourElement()\r
- {\r
- Rec<string, string, int, int> rec1, rec2, rec3;\r
- rec1 = new Rec<string, string, int, int>("abe", null, 0, 1);\r
- rec2 = new Rec<string, string, int, int>("abe", null, 0, 1);\r
- rec3 = new Rec<string, string, int, int>("abe", "kat", 0, 1);\r
- Assert.IsTrue(rec1 == rec2);\r
- Assert.IsFalse(rec1 != rec2);\r
- Assert.IsFalse(rec1 == rec3);\r
- Assert.IsTrue(rec1 != rec3);\r
- Assert.IsTrue(rec1.Equals(rec2));\r
- Assert.IsFalse(rec1.Equals(rec3));\r
- //\r
- Assert.IsFalse(rec1.Equals(null));\r
- Assert.IsFalse(rec1.Equals("bamse"));\r
- //\r
- Assert.IsTrue(rec1.GetHashCode() == rec2.GetHashCode());\r
- Assert.IsFalse(rec1.GetHashCode() == rec3.GetHashCode());\r
- //\r
- Assert.AreEqual("abe", rec1.X1);\r
- Assert.IsNull(rec1.X2);\r
- Assert.AreEqual(0, rec1.X3);\r
- Assert.AreEqual(1, rec1.X4);\r
- }\r
-\r
-\r
- [Test]\r
- public void ThreeElement()\r
- {\r
- Rec<string, string, int> rec1, rec2, rec3;\r
- rec1 = new Rec<string, string, int>("abe", null, 0);\r
- rec2 = new Rec<string, string, int>("abe", null, 0);\r
- rec3 = new Rec<string, string, int>("abe", "kat", 0);\r
- Assert.IsTrue(rec1 == rec2);\r
- Assert.IsFalse(rec1 != rec2);\r
- Assert.IsFalse(rec1 == rec3);\r
- Assert.IsTrue(rec1 != rec3);\r
- Assert.IsTrue(rec1.Equals(rec2));\r
- Assert.IsFalse(rec1.Equals(rec3));\r
- //\r
- Assert.IsFalse(rec1.Equals(null));\r
- Assert.IsFalse(rec1.Equals("bamse"));\r
- //\r
- Assert.IsTrue(rec1.GetHashCode() == rec2.GetHashCode());\r
- Assert.IsFalse(rec1.GetHashCode() == rec3.GetHashCode());\r
- //\r
- Assert.AreEqual("abe", rec1.X1);\r
- Assert.IsNull(rec1.X2);\r
- Assert.AreEqual(0, rec1.X3);\r
-\r
- }\r
-\r
- [Test]\r
- public void TwoElement()\r
- {\r
- Rec<string, string> rec1, rec2, rec3;\r
- rec1 = new Rec<string, string>("abe", null);\r
- rec2 = new Rec<string, string>("abe", null);\r
- rec3 = new Rec<string, string>("abe", "kat");\r
- Assert.IsTrue(rec1 == rec2);\r
- Assert.IsFalse(rec1 != rec2);\r
- Assert.IsFalse(rec1 == rec3);\r
- Assert.IsTrue(rec1 != rec3);\r
- Assert.IsTrue(rec1.Equals(rec2));\r
- Assert.IsFalse(rec1.Equals(rec3));\r
- //\r
- Assert.IsFalse(rec1.Equals(null));\r
- Assert.IsFalse(rec1.Equals("bamse"));\r
- //\r
- Assert.IsTrue(rec1.GetHashCode() == rec2.GetHashCode());\r
- Assert.IsFalse(rec1.GetHashCode() == rec3.GetHashCode());\r
- //\r
- Assert.AreEqual("abe", rec1.X1);\r
- Assert.IsNull(rec1.X2);\r
- }\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- }\r
- }\r
-\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.SortingTests\r
-{\r
- [TestFixture]\r
- public class SortRandom\r
- {\r
- IC ic;\r
-\r
- Random ran;\r
-\r
- int[] a;\r
-\r
- int length;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- ran = new Random(3456);\r
- length = 100000;\r
- a = new int[length];\r
- for (int i = 0; i < length; i++)\r
- a[i] = ran.Next();\r
- }\r
-\r
-\r
- [Test]\r
- public void HeapSort()\r
- {\r
- Sorting.HeapSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void IntroSort()\r
- {\r
- Sorting.IntroSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertionSort()\r
- {\r
- length = 1000;\r
- Sorting.InsertionSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
-\r
- Sorting.InsertionSort<int>(a, length, 2 * length, ic);\r
- for (int i = length + 1; i < 2 * length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { ic = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class SortRandomDuplicates\r
- {\r
- IC ic;\r
-\r
- Random ran;\r
-\r
- int[] a;\r
-\r
- int length;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- ran = new Random(3456);\r
- length = 100000;\r
- a = new int[length];\r
- for (int i = 0; i < length; i++)\r
- a[i] = ran.Next(3, 23);\r
- }\r
-\r
-\r
- [Test]\r
- public void HeapSort()\r
- {\r
- Sorting.HeapSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void IntroSort()\r
- {\r
- Sorting.IntroSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertionSort()\r
- {\r
- length = 1000;\r
- Sorting.InsertionSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
-\r
- Sorting.InsertionSort<int>(a, length, 2 * length, ic);\r
- for (int i = length + 1; i < 2 * length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { ic = null; a = null; ran = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class SortIncreasing\r
- {\r
- IC ic;\r
-\r
- int[] a;\r
-\r
- int length;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- length = 100000;\r
- a = new int[length];\r
- for (int i = 0; i < length; i++)\r
- a[i] = i;\r
- }\r
-\r
-\r
- [Test]\r
- public void HeapSort()\r
- {\r
- Sorting.HeapSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void IntroSort()\r
- {\r
- Sorting.IntroSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertionSort()\r
- {\r
- length = 1000;\r
- Sorting.InsertionSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
-\r
- Sorting.InsertionSort<int>(a, length, 2 * length, ic);\r
- for (int i = length + 1; i < 2 * length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { ic = null; a = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class SortDecreasing\r
- {\r
- IC ic;\r
-\r
- int[] a;\r
-\r
- int length;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- length = 100000;\r
- a = new int[length];\r
- for (int i = 0; i < length; i++)\r
- a[i] = -i;\r
- }\r
-\r
-\r
- [Test]\r
- public void HeapSort()\r
- {\r
- Sorting.HeapSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void IntroSort()\r
- {\r
- Sorting.IntroSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertionSort()\r
- {\r
- length = 1000;\r
- Sorting.InsertionSort<int>(a, 0, length, ic);\r
- for (int i = 1; i < length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
-\r
- Sorting.InsertionSort<int>(a, length, 2 * length, ic);\r
- for (int i = length + 1; i < 2 * length; i++)\r
- Assert.IsTrue(a[i - 1] <= a[i], "Inversion at " + i);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { ic = null; a = null; }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests\r
-{\r
- class SC : SCG.IComparer<string>\r
- {\r
- public int Compare(string a, string b)\r
- {\r
- return a.CompareTo(b);\r
- }\r
-\r
-\r
- public void appl(String s)\r
- {\r
- System.Console.WriteLine("--{0}", s);\r
- }\r
- }\r
-\r
- class TenEqualityComparer : SCG.IEqualityComparer<int>, SCG.IComparer<int>\r
- {\r
- TenEqualityComparer() { }\r
- public static TenEqualityComparer Default { get { return new TenEqualityComparer(); } }\r
- public int GetHashCode(int item) { return (item / 10).GetHashCode(); }\r
- public bool Equals(int item1, int item2) { return item1 / 10 == item2 / 10; }\r
- public int Compare(int a, int b) { return (a / 10).CompareTo(b / 10); }\r
- }\r
-\r
- class IC : SCG.IComparer<int>, IComparable<int>, SCG.IComparer<IC>, IComparable<IC>\r
- {\r
- public int Compare(int a, int b)\r
- {\r
- return a > b ? 1 : a < b ? -1 : 0;\r
- }\r
-\r
-\r
- public int Compare(IC a, IC b)\r
- {\r
- return a._i > b._i ? 1 : a._i < b._i ? -1 : 0;\r
- }\r
-\r
-\r
- private int _i;\r
-\r
-\r
- public int i\r
- {\r
- get { return _i; }\r
- set { _i = value; }\r
- }\r
-\r
-\r
- public IC() { }\r
-\r
-\r
- public IC(int i) { _i = i; }\r
-\r
-\r
- public int CompareTo(int that) { return _i > that ? 1 : _i < that ? -1 : 0; }\r
-\r
- public bool Equals(int that) { return _i == that; }\r
-\r
-\r
- public int CompareTo(IC that) { return _i > that._i ? 1 : _i < that._i ? -1 : 0; }\r
- public bool Equals(IC that) { return _i == that._i; }\r
-\r
-\r
- public static bool eq(SCG.IEnumerable<int> me, params int[] that)\r
- {\r
- int i = 0, maxind = that.Length - 1;\r
-\r
- foreach (int item in me)\r
- if (i > maxind || item != that[i++])\r
- return false;\r
-\r
- return i == maxind + 1;\r
- }\r
- public static bool seteq(ICollectionValue<int> me, params int[] that)\r
- {\r
- int[] me2 = me.ToArray();\r
-\r
- Array.Sort(me2);\r
-\r
- int i = 0, maxind = that.Length - 1;\r
-\r
- foreach (int item in me2)\r
- if (i > maxind || item != that[i++])\r
- return false;\r
-\r
- return i == maxind + 1;\r
- }\r
- public static bool seteq(ICollectionValue<KeyValuePair<int, int>> me, params int[] that)\r
- {\r
- ArrayList<KeyValuePair<int, int>> first = new ArrayList<KeyValuePair<int, int>>();\r
- first.AddAll(me);\r
- ArrayList<KeyValuePair<int, int>> other = new ArrayList<KeyValuePair<int, int>>();\r
- for (int i = 0; i < that.Length; i += 2)\r
- {\r
- other.Add(new KeyValuePair<int, int>(that[i], that[i + 1]));\r
- }\r
- return other.UnsequencedEquals(first);\r
- }\r
- }\r
-\r
- class RevIC : SCG.IComparer<int>\r
- {\r
- public int Compare(int a, int b)\r
- {\r
- return a > b ? -1 : a < b ? 1 : 0;\r
- }\r
- }\r
-\r
- public class FunEnumerable : SCG.IEnumerable<int>\r
- {\r
- int size;\r
- Fun<int, int> f;\r
-\r
- public FunEnumerable(int size, Fun<int, int> f)\r
- {\r
- this.size = size; this.f = f;\r
- }\r
-\r
- public SCG.IEnumerator<int> GetEnumerator()\r
- {\r
- for (int i = 0; i < size; i++)\r
- yield return f(i);\r
- }\r
-\r
-\r
- #region IEnumerable Members\r
-\r
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
-\r
- #endregion\r
- }\r
-\r
- public class BadEnumerableException : Exception { }\r
-\r
- public class BadEnumerable<T> : CollectionValueBase<T>, ICollectionValue<T>\r
- {\r
- T[] contents;\r
- Exception exception;\r
-\r
- public BadEnumerable(Exception exception, params T[] contents)\r
- {\r
- this.contents = (T[])contents.Clone();\r
- this.exception = exception;\r
- }\r
-\r
- public override SCG.IEnumerator<T> GetEnumerator()\r
- {\r
- for (int i = 0; i < contents.Length; i++)\r
- yield return contents[i];\r
- throw exception;\r
- }\r
-\r
- public override bool IsEmpty { get { return false; } }\r
-\r
- public override int Count { get { return contents.Length + 1; } }\r
-\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
-\r
- public override T Choose() { throw exception; }\r
- }\r
-\r
- public class CollectionEventList<T>\r
- {\r
- ArrayList<CollectionEvent<T>> happened;\r
- EventTypeEnum listenTo;\r
- SCG.IEqualityComparer<T> itemequalityComparer;\r
- public CollectionEventList(SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- happened = new ArrayList<CollectionEvent<T>>();\r
- this.itemequalityComparer = itemequalityComparer;\r
- }\r
- public void Listen(ICollectionValue<T> list, EventTypeEnum listenTo)\r
- {\r
- this.listenTo = listenTo;\r
- if ((listenTo & EventTypeEnum.Changed) != 0)\r
- list.CollectionChanged += new CollectionChangedHandler<T>(changed);\r
- if ((listenTo & EventTypeEnum.Cleared) != 0)\r
- list.CollectionCleared += new CollectionClearedHandler<T>(cleared);\r
- if ((listenTo & EventTypeEnum.Removed) != 0)\r
- list.ItemsRemoved += new ItemsRemovedHandler<T>(removed);\r
- if ((listenTo & EventTypeEnum.Added) != 0)\r
- list.ItemsAdded += new ItemsAddedHandler<T>(added);\r
- if ((listenTo & EventTypeEnum.Inserted) != 0)\r
- list.ItemInserted += new ItemInsertedHandler<T>(inserted);\r
- if ((listenTo & EventTypeEnum.RemovedAt) != 0)\r
- list.ItemRemovedAt += new ItemRemovedAtHandler<T>(removedAt);\r
- }\r
- public void Add(CollectionEvent<T> e) { happened.Add(e); }\r
- /// <summary>\r
- /// Check that we have seen exactly the events in expected that match listenTo.\r
- /// </summary>\r
- /// <param name="expected"></param>\r
- public void Check(SCG.IEnumerable<CollectionEvent<T>> expected)\r
- {\r
- int i = 0;\r
- foreach (CollectionEvent<T> expectedEvent in expected)\r
- {\r
- if ((expectedEvent.Act & listenTo) == 0)\r
- continue;\r
- if (i >= happened.Count)\r
- Assert.Fail(string.Format("Event number {0} did not happen:\n expected {1}", i, expectedEvent));\r
- if (!expectedEvent.Equals(happened[i], itemequalityComparer))\r
- Assert.Fail(string.Format("Event number {0}:\n expected {1}\n but saw {2}", i, expectedEvent, happened[i]));\r
- i++;\r
- }\r
- if (i < happened.Count)\r
- Assert.Fail(string.Format("Event number {0} seen but no event expected:\n {1}", i, happened[i]));\r
- happened.Clear();\r
- }\r
- public void Clear() { happened.Clear(); }\r
- public void Print(System.IO.TextWriter writer)\r
- {\r
- happened.Apply(delegate(CollectionEvent<T> e) { writer.WriteLine(e); });\r
- }\r
- void changed(object sender)\r
- {\r
- happened.Add(new CollectionEvent<T>(EventTypeEnum.Changed, new EventArgs(), sender));\r
- }\r
- void cleared(object sender, ClearedEventArgs eventArgs)\r
- {\r
- happened.Add(new CollectionEvent<T>(EventTypeEnum.Cleared, eventArgs, sender));\r
- }\r
- void added(object sender, ItemCountEventArgs<T> eventArgs)\r
- {\r
- happened.Add(new CollectionEvent<T>(EventTypeEnum.Added, eventArgs, sender));\r
- }\r
- void removed(object sender, ItemCountEventArgs<T> eventArgs)\r
- {\r
- happened.Add(new CollectionEvent<T>(EventTypeEnum.Removed, eventArgs, sender));\r
- }\r
- void inserted(object sender, ItemAtEventArgs<T> eventArgs)\r
- {\r
- happened.Add(new CollectionEvent<T>(EventTypeEnum.Inserted, eventArgs, sender));\r
- }\r
- void removedAt(object sender, ItemAtEventArgs<T> eventArgs)\r
- {\r
- happened.Add(new CollectionEvent<T>(EventTypeEnum.RemovedAt, eventArgs, sender));\r
- }\r
- }\r
-\r
- public sealed class CollectionEvent<T>\r
- {\r
- public readonly EventTypeEnum Act;\r
- public readonly EventArgs Args;\r
- public readonly object Sender;\r
-\r
- public CollectionEvent(EventTypeEnum act, EventArgs args, object sender)\r
- {\r
- this.Act = act;\r
- this.Args = args;\r
- this.Sender = sender;\r
- }\r
-\r
- public bool Equals(CollectionEvent<T> otherEvent, SCG.IEqualityComparer<T> itemequalityComparer)\r
- {\r
- if (otherEvent == null || Act != otherEvent.Act || !object.ReferenceEquals(Sender, otherEvent.Sender))\r
- return false;\r
- switch (Act)\r
- {\r
- case EventTypeEnum.None:\r
- break;\r
- case EventTypeEnum.Changed:\r
- return true;\r
- case EventTypeEnum.Cleared:\r
- if (Args is ClearedRangeEventArgs)\r
- {\r
- ClearedRangeEventArgs a = Args as ClearedRangeEventArgs, o = otherEvent.Args as ClearedRangeEventArgs;\r
- if (o == null)\r
- return false;\r
- return a.Full == o.Full && a.Start == o.Start && a.Count == o.Count;\r
- }\r
- else\r
- {\r
- if (otherEvent.Args is ClearedRangeEventArgs)\r
- return false;\r
- ClearedEventArgs a = Args as ClearedEventArgs, o = otherEvent.Args as ClearedEventArgs;\r
- return a.Full == o.Full && a.Count == o.Count;\r
- }\r
- case EventTypeEnum.Added:\r
- {\r
- ItemCountEventArgs<T> a = Args as ItemCountEventArgs<T>, o = otherEvent.Args as ItemCountEventArgs<T>;\r
- return itemequalityComparer.Equals(a.Item, o.Item) && a.Count == o.Count;\r
- }\r
- case EventTypeEnum.Removed:\r
- {\r
- ItemCountEventArgs<T> a = Args as ItemCountEventArgs<T>, o = otherEvent.Args as ItemCountEventArgs<T>;\r
- return itemequalityComparer.Equals(a.Item, o.Item) && a.Count == o.Count;\r
- }\r
- case EventTypeEnum.Inserted:\r
- {\r
- ItemAtEventArgs<T> a = Args as ItemAtEventArgs<T>, o = otherEvent.Args as ItemAtEventArgs<T>;\r
- return a.Index == o.Index && itemequalityComparer.Equals(a.Item, o.Item);\r
- }\r
- case EventTypeEnum.RemovedAt:\r
- {\r
- ItemAtEventArgs<T> a = Args as ItemAtEventArgs<T>, o = otherEvent.Args as ItemAtEventArgs<T>;\r
- return a.Index == o.Index && itemequalityComparer.Equals(a.Item, o.Item);\r
- }\r
- }\r
- throw new ApplicationException("Illegat Act: " + Act);\r
- }\r
-\r
- public override string ToString()\r
- {\r
- return string.Format("Act: {0}, Args : {1}, Source : {2}", Act, Args, Sender);\r
- }\r
-\r
- }\r
-\r
- public class CHC\r
- {\r
- static public int unsequencedhashcode(params int[] a)\r
- {\r
- int h = 0;\r
- foreach (int i in a)\r
- {\r
- h += (int)(((uint)i * 1529784657 + 1) ^ ((uint)i * 2912831877) ^ ((uint)i * 1118771817 + 2));\r
- }\r
- return h;\r
- }\r
- static public int sequencedhashcode(params int[] a)\r
- {\r
- int h = 0;\r
- foreach (int i in a) { h = h * 31 + i; }\r
- return h;\r
- }\r
- }\r
-\r
- //This class is a modified sample from VS2005 beta1 documentation\r
- public class RadixFormatProvider : IFormatProvider\r
- {\r
- RadixFormatter _radixformatter;\r
- public RadixFormatProvider(int radix)\r
- {\r
- if (radix < 2 || radix > 36)\r
- throw new ArgumentException(String.Format(\r
- "The radix \"{0}\" is not in the range 2..36.",\r
- radix));\r
- _radixformatter = new RadixFormatter(radix);\r
- }\r
- public object GetFormat(Type argType)\r
- {\r
- if (argType == typeof(ICustomFormatter))\r
- return _radixformatter;\r
- else\r
- return null;\r
- }\r
- }\r
-\r
- //This class is a modified sample from VS2005 beta1 documentation\r
- public class RadixFormatter : ICustomFormatter\r
- {\r
- int radix;\r
- public RadixFormatter(int radix)\r
- {\r
- if (radix < 2 || radix > 36)\r
- throw new ArgumentException(String.Format(\r
- "The radix \"{0}\" is not in the range 2..36.",\r
- radix));\r
- this.radix = radix;\r
- }\r
-\r
- // The value to be formatted is returned as a signed string \r
- // of digits from the rDigits array. \r
- private static char[] rDigits = {\r
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', \r
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', \r
- 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', \r
- 'U', 'V', 'W', 'X', 'Y', 'Z' };\r
-\r
- public string Format(string formatString,\r
- object argToBeFormatted, IFormatProvider provider)\r
- {\r
- /*switch (Type.GetTypeCode(argToBeFormatted.GetType()))\r
- {\r
- case TypeCode.Boolean:\r
- break;\r
- case TypeCode.Byte:\r
- break;\r
- case TypeCode.Char:\r
- break;\r
- case TypeCode.DBNull:\r
- break;\r
- case TypeCode.DateTime:\r
- break;\r
- case TypeCode.Decimal:\r
- break;\r
- case TypeCode.Double:\r
- break;\r
- case TypeCode.Empty:\r
- break;\r
- case TypeCode.Int16:\r
- break;\r
- case TypeCode.Int32:\r
- break;\r
- case TypeCode.Int64:\r
- break;\r
- case TypeCode.Object:\r
- break;\r
- case TypeCode.SByte:\r
- break;\r
- case TypeCode.Single:\r
- break;\r
- case TypeCode.String:\r
- break;\r
- case TypeCode.UInt16:\r
- break;\r
- case TypeCode.UInt32:\r
- break;\r
- case TypeCode.UInt64:\r
- break;\r
- }*/\r
- int intToBeFormatted;\r
- try\r
- {\r
- intToBeFormatted = (int)argToBeFormatted;\r
- }\r
- catch (Exception)\r
- {\r
- if (argToBeFormatted is IFormattable)\r
- return ((IFormattable)argToBeFormatted).\r
- ToString(formatString, provider);\r
- else\r
- return argToBeFormatted.ToString();\r
- }\r
- return formatInt(intToBeFormatted);\r
- }\r
-\r
- private string formatInt(int intToBeFormatted)\r
- {\r
- // The formatting is handled here.\r
- if (intToBeFormatted == 0)\r
- return "0";\r
- int digitIndex = 0;\r
- int intPositive;\r
- char[] outDigits = new char[31];\r
-\r
- // Verify that the argument can be converted to a int integer.\r
- // Extract the magnitude for conversion.\r
- intPositive = Math.Abs(intToBeFormatted);\r
-\r
- // Convert the magnitude to a digit string.\r
- for (digitIndex = 0; digitIndex <= 32; digitIndex++)\r
- {\r
- if (intPositive == 0) break;\r
-\r
- outDigits[outDigits.Length - digitIndex - 1] =\r
- rDigits[intPositive % radix];\r
- intPositive /= radix;\r
- }\r
-\r
- // Add a minus sign if the argument is negative.\r
- if (intToBeFormatted < 0)\r
- outDigits[outDigits.Length - digitIndex++ - 1] =\r
- '-';\r
-\r
- return new string(outDigits,\r
- outDigits.Length - digitIndex, digitIndex);\r
- }\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests.wrappers\r
-{\r
- namespace Events\r
- {\r
- [TestFixture]\r
- public class IList_\r
- {\r
- private ArrayList<int> list;\r
- ICollectionValue<int> guarded;\r
- CollectionEventList<int> seen;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>(TenEqualityComparer.Default);\r
- guarded = new GuardedList<int>(list);\r
- seen = new CollectionEventList<int>(IntEqualityComparer.Default);\r
- }\r
-\r
- private void listen() { seen.Listen(guarded, EventTypeEnum.All); }\r
-\r
- [Test]\r
- public void Listenable()\r
- {\r
- Assert.AreEqual(EventTypeEnum.All, guarded.ListenableEvents);\r
- Assert.AreEqual(EventTypeEnum.None, guarded.ActiveEvents);\r
- listen();\r
- Assert.AreEqual(EventTypeEnum.All, guarded.ActiveEvents);\r
- }\r
-\r
- [Test]\r
- public void SetThis()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list[1] = 45;\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Insert(1, 45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- }\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.InsertAll<int>(1, new int[] { 666, 777, 888 });\r
- //seen.Print(Console.Error);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(666,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(666, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(777,2), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(777, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(888,3), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(888, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.InsertAll<int>(1, new int[] {});\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.InsertFirst(45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.InsertLast(88);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(88,4), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(88, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Remove();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(8, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [Test]\r
- public void RemoveFirst()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveFirst();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(4,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(4, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [Test]\r
- public void RemoveLast()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveLast();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(8,2), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(8, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Reverse();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.View(1, 0).Reverse();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Sort();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.View(1, 0).Sort();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Shuffle()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Shuffle();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.View(1, 0).Shuffle();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveAt(1);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveInterval(1, 2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,2,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.RemoveInterval(1, 0);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Update(53);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.Update(67);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- int val = 53;\r
- list.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- val = 67;\r
- list.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- }\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- int val = 53;\r
- list.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- val = 67;\r
- list.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.UpdateOrAdd(51, out val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(53, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(51, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- val = 67;\r
- list.UpdateOrAdd(81, out val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(81, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- }\r
-\r
- [Test]\r
- public void RemoveItem()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- listen();\r
- list.Remove(53);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.Remove(11);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.RemoveAll<int>(new int[] { 32, 187, 45 });\r
- //TODO: the order depends on internals of the HashSet\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(35, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(45, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.RemoveAll<int>(new int[] { 200, 300 });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.View(1, 1).Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,1,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,2,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.Clear();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void ListDispose()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.View(1, 1).Dispose();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- list.Dispose();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,3,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)\r
- });\r
- list.Dispose();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.RetainAll<int>(new int[] { 32, 187, 45, 62, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(15, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(25, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(55, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(75, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.RetainAll<int>(new int[] { 32, 187, 45, 62, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(3 * i + 5);\r
- }\r
- listen();\r
- list.RemoveAllCopies(14);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(14, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(17, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.RemoveAllCopies(14);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- list.Add(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.AddAll<int>(new int[] { 45, 56, 67 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.AddAll<int>(new int[] { });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; seen = null; }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewChanged()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.CollectionChanged += new CollectionChangedHandler<int>(w_CollectionChanged);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewCleared()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.CollectionCleared += new CollectionClearedHandler<int>(w_CollectionCleared);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewAdded()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemsAdded += new ItemsAddedHandler<int>(w_ItemAdded);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewInserted()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemInserted += new ItemInsertedHandler<int>(w_ItemInserted);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewRemoved()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemsRemoved += new ItemsRemovedHandler<int>(w_ItemRemoved);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewRemovedAt()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemRemovedAt += new ItemRemovedAtHandler<int>(w_ItemRemovedAt);\r
- }\r
-\r
- void w_CollectionChanged(object sender)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_CollectionCleared(object sender, ClearedEventArgs eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemAdded(object sender, ItemCountEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemInserted(object sender, ItemAtEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemRemoved(object sender, ItemCountEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemRemovedAt(object sender, ItemAtEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class StackQueue\r
- {\r
- private ArrayList<int> list;\r
- ICollectionValue<int> guarded;\r
- CollectionEventList<int> seen;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>(TenEqualityComparer.Default);\r
- guarded = new GuardedList<int>(list);\r
- seen = new CollectionEventList<int>(IntEqualityComparer.Default);\r
- }\r
-\r
- private void listen() { seen.Listen(guarded, EventTypeEnum.All); }\r
-\r
-\r
- [Test]\r
- public void EnqueueDequeue()\r
- {\r
- listen();\r
- list.Enqueue(67);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(67,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.Enqueue(2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(2,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(2, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(67,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(67, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(2,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(2, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [Test]\r
- public void PushPop()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- list.Push(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(23,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.Push(-12);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(-12,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(-12, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(-12,1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(-12, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- list.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(23,0), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(23, 1), guarded),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), guarded)});\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; seen = null; }\r
- }\r
-\r
-\r
- }\r
-\r
- namespace wrappedarray\r
- {\r
- [TestFixture]\r
- public class Basic\r
- {\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- }\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- }\r
-\r
- [Test]\r
- public void NoExc()\r
- {\r
- WrappedArray<int> wrapped = new WrappedArray<int>(new int[] { 4, 6, 5 });\r
- Assert.AreEqual(6, wrapped[1]);\r
- Assert.IsTrue(IC.eq(wrapped[1, 2], 6, 5));\r
- //\r
- Fun<int, bool> is4 = delegate(int i) { return i == 4; };\r
- Assert.AreEqual(EventTypeEnum.None, wrapped.ActiveEvents);\r
- Assert.AreEqual(false, wrapped.All(is4));\r
- Assert.AreEqual(true, wrapped.AllowsDuplicates);\r
- wrapped.Apply(delegate(int i) { });\r
- Assert.AreEqual("{ 5, 6, 4 }", wrapped.Backwards().ToString());\r
- Assert.AreEqual(true, wrapped.Check());\r
- wrapped.Choose();\r
- Assert.AreEqual(true, wrapped.Contains(4));\r
- Assert.AreEqual(true, wrapped.ContainsAll(new ArrayList<int>()));\r
- Assert.AreEqual(1, wrapped.ContainsCount(4));\r
- Assert.AreEqual(Speed.Linear, wrapped.ContainsSpeed);\r
- int[] extarray = new int[5];\r
- wrapped.CopyTo(extarray, 1);\r
- Assert.IsTrue(IC.eq(extarray, 0, 4, 6, 5, 0));\r
- Assert.AreEqual(3, wrapped.Count);\r
- Assert.AreEqual(Speed.Constant, wrapped.CountSpeed);\r
- Assert.AreEqual(EnumerationDirection.Forwards, wrapped.Direction);\r
- Assert.AreEqual(false, wrapped.DuplicatesByCounting);\r
- Assert.AreEqual(IntEqualityComparer.Default, wrapped.EqualityComparer);\r
- Assert.AreEqual(true, wrapped.Exists(is4));\r
- Assert.IsTrue(IC.eq(wrapped.Filter(is4), 4));\r
- int j = 5;\r
- Assert.AreEqual(true, wrapped.Find(ref j));\r
- Assert.AreEqual(true, wrapped.Find(is4, out j));\r
- Assert.AreEqual("[ 0:4 ]", wrapped.FindAll(is4).ToString());\r
- Assert.AreEqual(0, wrapped.FindIndex(is4));\r
- Assert.AreEqual(true, wrapped.FindLast(is4, out j));\r
- Assert.AreEqual(0, wrapped.FindLastIndex(is4));\r
- Assert.AreEqual(4, wrapped.First);\r
- wrapped.GetEnumerator();\r
- Assert.AreEqual(CHC.sequencedhashcode(4, 6, 5), wrapped.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(4, 6, 5), wrapped.GetUnsequencedHashCode());\r
- Assert.AreEqual(Speed.Constant, wrapped.IndexingSpeed);\r
- Assert.AreEqual(2, wrapped.IndexOf(5));\r
- Assert.AreEqual(false, wrapped.IsEmpty);\r
- Assert.AreEqual(true, wrapped.IsReadOnly);\r
- Assert.AreEqual(false, wrapped.IsSorted());\r
- Assert.AreEqual(true, wrapped.IsValid);\r
- Assert.AreEqual(5, wrapped.Last);\r
- Assert.AreEqual(2, wrapped.LastIndexOf(5));\r
- Assert.AreEqual(EventTypeEnum.None, wrapped.ListenableEvents);\r
- Fun<int, string> i2s = delegate(int i) { return string.Format("T{0}", i); };\r
- Assert.AreEqual("[ 0:T4, 1:T6, 2:T5 ]", wrapped.Map<string>(i2s).ToString());\r
- Assert.AreEqual(0, wrapped.Offset);\r
- wrapped.Reverse();\r
- Assert.AreEqual("[ 0:5, 1:6, 2:4 ]", wrapped.ToString());\r
- IList<int> other = new ArrayList<int>(); other.AddAll<int>(new int[] { 4, 5, 6 });\r
- Assert.IsFalse(wrapped.SequencedEquals(other));\r
- j = 30;\r
- Assert.AreEqual(true, wrapped.Show(new System.Text.StringBuilder(), ref j, null));\r
- wrapped.Sort();\r
- Assert.AreEqual("[ 0:4, 1:5, 2:6 ]", wrapped.ToString());\r
- Assert.IsNotNull(wrapped.SyncRoot);\r
- Assert.IsTrue(IC.eq(wrapped.ToArray(), 4, 5, 6));\r
- Assert.AreEqual("[ ... ]", wrapped.ToString("L4", null));\r
- Assert.AreEqual(null, wrapped.Underlying);\r
- Assert.IsTrue(IC.seteq(wrapped.UniqueItems(), 4, 5, 6));\r
- Assert.IsTrue(wrapped.UnsequencedEquals(other));\r
- wrapped.Shuffle();\r
- Assert.IsTrue(IC.seteq(wrapped.UniqueItems(), 4, 5, 6));\r
- }\r
-\r
- [Test]\r
- public void WithExc()\r
- {\r
- WrappedArray<int> wrapped = new WrappedArray<int>(new int[] { 3, 4, 6, 5, 7 });\r
- //\r
- try { wrapped.Add(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.AddAll<int>(null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Clear(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Dispose(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- int j = 1;\r
- try { wrapped.FindOrAdd(ref j); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Insert(1, 1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Insert(wrapped.View(0, 0), 1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.InsertAll<int>(1, null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.InsertFirst(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.InsertLast(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Remove(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Remove(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveAll<int>(null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveAllCopies(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveAt(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveFirst(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveInterval(0, 0); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveLast(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RetainAll<int>(null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Update(1, out j); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.UpdateOrAdd(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- }\r
-\r
- [Test]\r
- public void View()\r
- {\r
- WrappedArray<int> outerwrapped = new WrappedArray<int>(new int[] { 3, 4, 6, 5, 7 });\r
- WrappedArray<int> wrapped = (WrappedArray<int>)outerwrapped.View(1, 3);\r
- //\r
- Assert.AreEqual(6, wrapped[1]);\r
- Assert.IsTrue(IC.eq(wrapped[1, 2], 6, 5));\r
- //\r
- Fun<int, bool> is4 = delegate(int i) { return i == 4; };\r
- Assert.AreEqual(EventTypeEnum.None, wrapped.ActiveEvents);\r
- Assert.AreEqual(false, wrapped.All(is4));\r
- Assert.AreEqual(true, wrapped.AllowsDuplicates);\r
- wrapped.Apply(delegate(int i) { });\r
- Assert.AreEqual("{ 5, 6, 4 }", wrapped.Backwards().ToString());\r
- Assert.AreEqual(true, wrapped.Check());\r
- wrapped.Choose();\r
- Assert.AreEqual(true, wrapped.Contains(4));\r
- Assert.AreEqual(true, wrapped.ContainsAll(new ArrayList<int>()));\r
- Assert.AreEqual(1, wrapped.ContainsCount(4));\r
- Assert.AreEqual(Speed.Linear, wrapped.ContainsSpeed);\r
- int[] extarray = new int[5];\r
- wrapped.CopyTo(extarray, 1);\r
- Assert.IsTrue(IC.eq(extarray, 0, 4, 6, 5, 0));\r
- Assert.AreEqual(3, wrapped.Count);\r
- Assert.AreEqual(Speed.Constant, wrapped.CountSpeed);\r
- Assert.AreEqual(EnumerationDirection.Forwards, wrapped.Direction);\r
- Assert.AreEqual(false, wrapped.DuplicatesByCounting);\r
- Assert.AreEqual(IntEqualityComparer.Default, wrapped.EqualityComparer);\r
- Assert.AreEqual(true, wrapped.Exists(is4));\r
- Assert.IsTrue(IC.eq(wrapped.Filter(is4), 4));\r
- int j = 5;\r
- Assert.AreEqual(true, wrapped.Find(ref j));\r
- Assert.AreEqual(true, wrapped.Find(is4, out j));\r
- Assert.AreEqual("[ 0:4 ]", wrapped.FindAll(is4).ToString());\r
- Assert.AreEqual(0, wrapped.FindIndex(is4));\r
- Assert.AreEqual(true, wrapped.FindLast(is4, out j));\r
- Assert.AreEqual(0, wrapped.FindLastIndex(is4));\r
- Assert.AreEqual(4, wrapped.First);\r
- wrapped.GetEnumerator();\r
- Assert.AreEqual(CHC.sequencedhashcode(4, 6, 5), wrapped.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(4, 6, 5), wrapped.GetUnsequencedHashCode());\r
- Assert.AreEqual(Speed.Constant, wrapped.IndexingSpeed);\r
- Assert.AreEqual(2, wrapped.IndexOf(5));\r
- Assert.AreEqual(false, wrapped.IsEmpty);\r
- Assert.AreEqual(true, wrapped.IsReadOnly);\r
- Assert.AreEqual(false, wrapped.IsSorted());\r
- Assert.AreEqual(true, wrapped.IsValid);\r
- Assert.AreEqual(5, wrapped.Last);\r
- Assert.AreEqual(2, wrapped.LastIndexOf(5));\r
- Assert.AreEqual(EventTypeEnum.None, wrapped.ListenableEvents);\r
- Fun<int, string> i2s = delegate(int i) { return string.Format("T{0}", i); };\r
- Assert.AreEqual("[ 0:T4, 1:T6, 2:T5 ]", wrapped.Map<string>(i2s).ToString());\r
- Assert.AreEqual(1, wrapped.Offset);\r
- wrapped.Reverse();\r
- Assert.AreEqual("[ 0:5, 1:6, 2:4 ]", wrapped.ToString());\r
- IList<int> other = new ArrayList<int>(); other.AddAll<int>(new int[] { 4, 5, 6 });\r
- Assert.IsFalse(wrapped.SequencedEquals(other));\r
- j = 30;\r
- Assert.AreEqual(true, wrapped.Show(new System.Text.StringBuilder(), ref j, null));\r
- wrapped.Sort();\r
- Assert.AreEqual("[ 0:4, 1:5, 2:6 ]", wrapped.ToString());\r
- Assert.IsNotNull(wrapped.SyncRoot);\r
- Assert.IsTrue(IC.eq(wrapped.ToArray(), 4, 5, 6));\r
- Assert.AreEqual("[ ... ]", wrapped.ToString("L4", null));\r
- Assert.AreEqual(outerwrapped, wrapped.Underlying);\r
- Assert.IsTrue(IC.seteq(wrapped.UniqueItems(), 4, 5, 6));\r
- Assert.IsTrue(wrapped.UnsequencedEquals(other));\r
- //\r
- Assert.IsTrue(wrapped.TrySlide(1));\r
- Assert.IsTrue(IC.eq(wrapped, 5, 6, 7));\r
- Assert.IsTrue(wrapped.TrySlide(-1, 2));\r
- Assert.IsTrue(IC.eq(wrapped, 4, 5));\r
- Assert.IsFalse(wrapped.TrySlide(-2));\r
- Assert.IsTrue(IC.eq(wrapped.Span(outerwrapped.ViewOf(7)), 4, 5, 6, 7));\r
- //\r
- wrapped.Shuffle();\r
- Assert.IsTrue(IC.seteq(wrapped.UniqueItems(), 4, 5));\r
- Assert.IsTrue(wrapped.IsValid);\r
- wrapped.Dispose();\r
- Assert.IsFalse(wrapped.IsValid);\r
- }\r
-\r
- [Test]\r
- public void ViewWithExc()\r
- {\r
- WrappedArray<int> outerwrapped = new WrappedArray<int>(new int[] { 3, 4, 6, 5, 7 });\r
- WrappedArray<int> wrapped = (WrappedArray<int>)outerwrapped.View(1, 3);\r
- //\r
- try { wrapped.Add(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.AddAll<int>(null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Clear(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- //Should not throw\r
- //try { wrapped.Dispose(); Assert.Fail("No throw"); }\r
- //catch (FixedSizeCollectionException) { }\r
- int j = 1;\r
- try { wrapped.FindOrAdd(ref j); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Insert(1, 1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Insert(wrapped.View(0, 0), 1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.InsertAll<int>(1, null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.InsertFirst(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.InsertLast(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Remove(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Remove(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveAll<int>(null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveAllCopies(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveAt(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveFirst(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveInterval(0, 0); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RemoveLast(); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.RetainAll<int>(null); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.Update(1, out j); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- try { wrapped.UpdateOrAdd(1); Assert.Fail("No throw"); }\r
- catch (FixedSizeCollectionException) { }\r
- }\r
- }\r
- }\r
-}\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.arrays.list\r
-{\r
- using CollectionOfInt = ArrayList<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.ListTester<CollectionOfInt>().Test(factory);\r
- new C5UnitTests.Templates.Events.QueueTester<CollectionOfInt>().Test(factory);\r
- new C5UnitTests.Templates.Events.StackTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Clone.ViewTester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.ViewTester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new ArrayList<T>(); }\r
- }\r
-\r
- namespace Events\r
- {\r
- [TestFixture]\r
- public class IList_\r
- {\r
- private ArrayList<int> list;\r
- CollectionEventList<int> seen;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>(TenEqualityComparer.Default);\r
- seen = new CollectionEventList<int>(IntEqualityComparer.Default);\r
- }\r
-\r
- private void listen() { seen.Listen(list, EventTypeEnum.Added); }\r
-\r
- [Test]\r
- public void Listenable()\r
- {\r
- Assert.AreEqual(EventTypeEnum.All, list.ListenableEvents);\r
- Assert.AreEqual(EventTypeEnum.None, list.ActiveEvents);\r
- listen();\r
- Assert.AreEqual(EventTypeEnum.Added, list.ActiveEvents);\r
- }\r
-\r
- [Test]\r
- public void SetThis()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list[1] = 45;\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Insert(1, 45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.InsertAll<int>(1, new int[] { 666, 777, 888 });\r
- //seen.Print(Console.Error);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(666,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(666, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(777,2), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(777, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(888,3), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(888, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.InsertAll<int>(1, new int[] {});\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.InsertFirst(45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.InsertLast(88);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(88,4), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(88, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Remove();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(8, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveFirst()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveFirst();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(4,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(4, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveLast()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveLast();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(8,2), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(8, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Reverse();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.View(1, 0).Reverse();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Sort();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.View(1, 0).Sort();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Shuffle()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Shuffle();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.View(1, 0).Shuffle();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveAt(1);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveInterval(1, 2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,2,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.RemoveInterval(1, 0);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Update(53);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Update(67);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- int val = 53;\r
- list.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- val = 67;\r
- list.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- int val = 53;\r
- list.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- val = 67;\r
- list.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.UpdateOrAdd(51, out val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(53, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(51, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- val = 67;\r
- list.UpdateOrAdd(81, out val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(81, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void RemoveItem()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- listen();\r
- list.Remove(53);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Remove(11);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.RemoveAll<int>(new int[] { 32, 187, 45 });\r
- //TODO: the order depends on internals of the HashSet\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(35, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.RemoveAll<int>(new int[] { 200, 300 });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.View(1, 1).Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,1,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,2,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Clear();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void ListDispose()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.View(1, 1).Dispose();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- list.Dispose();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,3,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Dispose();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.RetainAll<int>(new int[] { 32, 187, 45, 62, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(15, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(25, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(55, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(75, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.RetainAll<int>(new int[] { 32, 187, 45, 62, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(3 * i + 5);\r
- }\r
- listen();\r
- list.RemoveAllCopies(14);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(14, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(17, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.RemoveAllCopies(14);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- list.Add(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.AddAll<int>(new int[] { 45, 56, 67 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.AddAll<int>(new int[] { });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; seen = null; }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewChanged()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.CollectionChanged += new CollectionChangedHandler<int>(w_CollectionChanged);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewCleared()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.CollectionCleared += new CollectionClearedHandler<int>(w_CollectionCleared);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewAdded()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemsAdded += new ItemsAddedHandler<int>(w_ItemAdded);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewInserted()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemInserted += new ItemInsertedHandler<int>(w_ItemInserted);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewRemoved()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemsRemoved += new ItemsRemovedHandler<int>(w_ItemRemoved);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewRemovedAt()\r
- {\r
- IList<int> w = list.View(0, 0);\r
- w.ItemRemovedAt += new ItemRemovedAtHandler<int>(w_ItemRemovedAt);\r
- }\r
-\r
- void w_CollectionChanged(object sender)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_CollectionCleared(object sender, ClearedEventArgs eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemAdded(object sender, ItemCountEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemInserted(object sender, ItemAtEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemRemoved(object sender, ItemCountEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemRemovedAt(object sender, ItemAtEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class StackQueue\r
- {\r
-\r
- private ArrayList<int> list;\r
- CollectionEventList<int> seen;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>(TenEqualityComparer.Default);\r
- seen = new CollectionEventList<int>(IntEqualityComparer.Default);\r
- }\r
-\r
- private void listen() { seen.Listen(list, EventTypeEnum.All); }\r
-\r
- [Test]\r
- public void EnqueueDequeue()\r
- {\r
- listen();\r
- list.Enqueue(67);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(67,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Enqueue(2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(2,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(2, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(67,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(2,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(2, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void PushPop()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- list.Push(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(23,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Push(-12);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(-12,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(-12, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(-12,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(-12, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(23,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(23, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; seen = null; }\r
- }\r
- }\r
-\r
- namespace Safety\r
- {\r
- /// <summary>\r
- /// Tests to see if the collection classes are robust for enumerable arguments that throw exceptions.\r
- /// </summary>\r
- [TestFixture]\r
- public class BadEnumerable\r
- {\r
- private ArrayList<int> list;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>();\r
- }\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- try\r
- {\r
- list.InsertAll<int>(1, new BadEnumerable<int>(new BadEnumerableException(), 9, 8, 7));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 9, 8, 7, 56, 8));\r
-\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- try\r
- {\r
- list.View(0, 1).AddAll<int>(new BadEnumerable<int>(new BadEnumerableException(), 9, 8, 7));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 9, 8, 7, 56, 8));\r
- }\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- try\r
- {\r
- list.RemoveAll(new BadEnumerable<int>(new BadEnumerableException(), 9, 8, 7));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 56, 8));\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- try\r
- {\r
- list.RetainAll(new BadEnumerable<int>(new BadEnumerableException(), 9, 8, 7));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 56, 8));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- try\r
- {\r
- list.ContainsAll(new BadEnumerable<int>(new BadEnumerableException(), 4, 18));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 56, 8));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
- /// <summary>\r
- /// Tests to see if the collection classes are robust for delegate arguments that throw exceptions.\r
- /// </summary>\r
- [TestFixture]\r
- public class BadFun\r
- {\r
- private ArrayList<int> list;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>();\r
- }\r
-\r
- [Test]\r
- public void NoTests() { }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
- namespace Enumerable\r
- {\r
- [TestFixture]\r
- public class Multiops\r
- {\r
- private ArrayList<int> list;\r
-\r
- private Fun<int, bool> always, never, even;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>();\r
- always = delegate { return true; };\r
- never = delegate { return false; };\r
- even = delegate(int i) { return i % 2 == 0; };\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsTrue(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsFalse(list.All(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsTrue(list.Exists(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- int sum = 0;\r
- Act<int> a = delegate(int i) { sum = i + 10 * sum; };\r
-\r
- list.Apply(a);\r
- Assert.AreEqual(0, sum);\r
- sum = 0;\r
- list.Add(5); list.Add(8); list.Add(7); list.Add(5);\r
- list.Apply(a);\r
- Assert.AreEqual(5875, sum);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class GetEnumerator\r
- {\r
- private ArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new ArrayList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Empty()\r
- {\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
- list.Add(5);\r
- list.Add(10);\r
- list.Add(1);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(8, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(10, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(1, e.Current);\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void DoDispose()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- e.MoveNext();\r
- e.Dispose();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- list.Add(99);\r
- e.MoveNext();\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
- namespace CollectionOrSink\r
- {\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("[ ]", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("[ 0:-4, 1:28, 2:129, 3:65530 ]", coll.ToString());\r
- Assert.AreEqual("[ 0:-4, 1:1C, 2:81, 3:FFFA ]", coll.ToString(null, rad16));\r
- Assert.AreEqual("[ 0:-4, 1:28... ]", coll.ToString("L14", null));\r
- Assert.AreEqual("[ 0:-4, 1:1C... ]", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class CollectionOrSink\r
- {\r
- private ArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new ArrayList<int>(); }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- list.Add(7);\r
- Assert.AreEqual(7, list.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- list.Choose();\r
- }\r
-\r
- [Test]\r
- public void CountEtAl()\r
- {\r
- Assert.AreEqual(0, list.Count);\r
- Assert.IsTrue(list.IsEmpty);\r
- Assert.IsTrue(list.AllowsDuplicates);\r
- list.Add(5);\r
- Assert.AreEqual(1, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- list.Add(5);\r
- Assert.AreEqual(2, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- list.Add(8);\r
- Assert.AreEqual(3, list.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- list.Add(3); list.Add(4); list.Add(5);\r
-\r
- ArrayList<int> list2 = new ArrayList<int>();\r
-\r
- list2.AddAll(list);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- list.AddAll(list2);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- Assert.IsTrue(IC.eq(list, 3, 4, 5, 3, 4, 5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private ArrayList<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- [Test]\r
- public void FindLast()\r
- {\r
- int i;\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.FindLast(pred, out i));\r
- Assert.AreEqual(675, i);\r
- }\r
-\r
- [Test]\r
- public void FindIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(4, list.FindIndex(pred));\r
- }\r
-\r
- [Test]\r
- public void FindLastIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(6, list.FindLastIndex(pred));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private ArrayList<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new ArrayList<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 2, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private ArrayList<int> list;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>();\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray()));\r
- list.Add(7);\r
- list.Add(7);\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray(), 7, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- list.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(6);\r
- list.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(4);\r
- list.Add(4);\r
- list.Add(9);\r
- list.CopyTo(a, 4);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 4, 9, 1008, 1009));\r
- list.Clear();\r
- list.Add(7);\r
- list.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 4, 9, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- list.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- list.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- list.Add(3);\r
- list.Add(3);\r
- list.CopyTo(a, 9);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Sync\r
- {\r
- private ArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- [Test]\r
- public void Get()\r
- {\r
- Assert.IsNotNull(list.SyncRoot);\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace EditableCollection\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private ArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new ArrayList<int>(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new ArrayList<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor2()\r
- {\r
- new ArrayList<int>(5, null);\r
- }\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsFalse(list.Contains(5));\r
- list.Add(5);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- list.Add(8);\r
- list.Add(10);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsTrue(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- list.Remove(8);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsFalse(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsCount()\r
- {\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- list.Add(5);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- list.Add(8);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- Assert.AreEqual(1, list.ContainsCount(8));\r
- list.Add(5);\r
- Assert.AreEqual(2, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- Assert.AreEqual(1, list.ContainsCount(8));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- list.Add(5); list.Add(7); list.Add(5);\r
- Assert.AreEqual(2, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.RemoveAllCopies(5);\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.Add(5); list.Add(8); list.Add(5);\r
- list.RemoveAllCopies(8);\r
- Assert.IsTrue(IC.eq(list, 7, 5, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindAll()\r
- {\r
- Fun<int, bool> f = delegate(int i) { return i % 2 == 0; };\r
-\r
- Assert.IsTrue(list.FindAll(f).IsEmpty);\r
- list.Add(5); list.Add(8); list.Add(5); list.Add(10); list.Add(8);\r
- Assert.IsTrue(((ArrayList<int>)list.FindAll(f)).Check());\r
- Assert.IsTrue(IC.eq(list.FindAll(f), 8, 10, 8));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
-\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(list.ContainsAll(list2));\r
- list.Add(4);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list.Add(5);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(list.ContainsAll(list2));\r
- list.Add(4);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
-\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7); list2.Add(7); list2.Add(4);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4, 5));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(5); list2.Add(5); list2.Add(6);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 5, 6));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
-\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7); list2.Add(7); list2.Add(4);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 6));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(6); list2.Add(5); list2.Add(5); list2.Add(6);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- Assert.IsFalse(list.FIFO);\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- Assert.IsFalse(list.Remove(2));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(list.Remove(4));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4, 5, 6));\r
- Assert.AreEqual(6, list.RemoveLast());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4, 5));\r
- list.Add(7);\r
- Assert.AreEqual(4, list.RemoveFirst());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5, 7));\r
-\r
- list.FIFO = true;\r
- list.Clear();\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- Assert.IsFalse(list.Remove(2));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(list.Remove(4));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5, 4, 6));\r
- Assert.AreEqual(6, list.RemoveLast());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5, 4));\r
- list.Add(7);\r
- Assert.AreEqual(4, list.RemoveFirst());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 4, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- list.Add(7); list.Add(7);\r
- list.Clear();\r
- Assert.IsTrue(list.IsEmpty);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace Indexed\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void IndexOf()\r
- {\r
- Assert.AreEqual(~0, dit.IndexOf(6));\r
- dit.Add(7);\r
- Assert.AreEqual(~1, dit.IndexOf(6));\r
- Assert.AreEqual(~1, dit.LastIndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- dit.Add(5); dit.Add(7); dit.Add(8); dit.Add(7);\r
- Assert.AreEqual(~5, dit.IndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- Assert.AreEqual(4, dit.LastIndexOf(7));\r
- Assert.AreEqual(3, dit.IndexOf(8));\r
- Assert.AreEqual(1, dit.LastIndexOf(5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Removing\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- dit.Add(5); dit.Add(7); dit.Add(9); dit.Add(1); dit.Add(2);\r
- Assert.AreEqual(7, dit.RemoveAt(1));\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 5, 9, 1, 2));\r
- Assert.AreEqual(5, dit.RemoveAt(0));\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1, 2));\r
- Assert.AreEqual(2, dit.RemoveAt(2));\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad0()\r
- {\r
- dit.RemoveAt(0);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBadM1()\r
- {\r
- dit.RemoveAt(-1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad1()\r
- {\r
- dit.Add(8);\r
- dit.RemoveAt(1);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- dit.RemoveInterval(0, 0);\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(3, 0);\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 40, 50, 60));\r
- dit.RemoveInterval(3, 1);\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 50, 60));\r
- dit.RemoveInterval(1, 3);\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 60));\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit));\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40, 50, 60));\r
- dit.RemoveInterval(2, 2);\r
- Assert.IsTrue(((ArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace List\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new ArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void FirstBad()\r
- {\r
- int f = lst.First;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void LastBad()\r
- {\r
- int f = lst.Last;\r
- }\r
-\r
-\r
- [Test]\r
- public void FirstLast()\r
- {\r
- lst.Add(19);\r
- Assert.AreEqual(19, lst.First);\r
- Assert.AreEqual(19, lst.Last);\r
- lst.Add(34); lst.InsertFirst(12);\r
- Assert.AreEqual(12, lst.First);\r
- Assert.AreEqual(34, lst.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void This()\r
- {\r
- lst.Add(34);\r
- Assert.AreEqual(34, lst[0]);\r
- lst[0] = 56;\r
- Assert.AreEqual(56, lst.First);\r
- lst.Add(7); lst.Add(7); lst.Add(7); lst.Add(7);\r
- lst[0] = 45; lst[2] = 78; lst[4] = 101;\r
- Assert.IsTrue(IC.eq(lst, 45, 7, 78, 7, 101));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptyGet()\r
- {\r
- int f = lst[0];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowGet()\r
- {\r
- lst.Add(7);\r
-\r
- int f = lst[-1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiGet()\r
- {\r
- lst.Add(6);\r
-\r
- int f = lst[1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptySet()\r
- {\r
- lst[0] = 4;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowSet()\r
- {\r
- lst.Add(7);\r
- lst[-1] = 9;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiSet()\r
- {\r
- lst.Add(6);\r
- lst[1] = 11;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Inserting\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new ArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 4);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5));\r
- lst.Insert(3, 2);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5, 2));\r
- }\r
-\r
- [Test]\r
- public void InsertDuplicate()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 5);\r
- Assert.IsTrue(IC.eq(lst, 7, 5, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAllDuplicate1()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- lst.InsertAll<int>(1, new int[] { 1, 2, 3, 4 });\r
- Assert.IsTrue(IC.eq(lst, 7, 1, 2, 3, 4, 3));\r
- Assert.IsTrue(lst.Check());\r
- }\r
- [Test]\r
- public void InsertAllDuplicate2()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- lst.InsertAll<int>(1, new int[] { 5, 6, 5, 8 });\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 5, 6, 5, 8, 3));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertLow()\r
- {\r
- lst.Add(7);\r
- lst.Insert(-1, 9);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertHi()\r
- {\r
- lst.Add(6);\r
- lst.Insert(2, 11);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- for (int i = 0; i < 7; i++)\r
- lst.Add(2 * i);\r
-\r
- Assert.IsFalse(lst.FIFO);\r
- Assert.AreEqual(12, lst.Remove());\r
- Assert.AreEqual(10, lst.Remove());\r
- lst.FIFO = true;\r
- Assert.AreEqual(0, lst.Remove());\r
- Assert.AreEqual(2, lst.Remove());\r
- lst.FIFO = false;\r
- Assert.AreEqual(8, lst.Remove());\r
- Assert.AreEqual(6, lst.Remove());\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- lst.InsertFirst(4);\r
- lst.InsertLast(5);\r
- lst.InsertFirst(14);\r
- lst.InsertLast(15);\r
- lst.InsertFirst(24);\r
- lst.InsertLast(25);\r
- lst.InsertFirst(34);\r
- lst.InsertLast(55);\r
- Assert.IsTrue(IC.eq(lst, 34, 24, 14, 4, 5, 15, 25, 55));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirst()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- lst.ViewOf(2).InsertFirst(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 3, 2, 5));\r
- lst.ViewOf(3).InsertFirst(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 2, 5));\r
- lst.ViewOf(5).InsertFirst(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 2, 9, 5));\r
- }\r
-\r
- [Test]\r
- public void InsertAfter()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- lst.LastViewOf(2).InsertLast(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 3, 2, 7, 5));\r
- lst.LastViewOf(1).InsertLast(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 3, 2, 7, 5));\r
- lst.LastViewOf(5).InsertLast(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 3, 2, 7, 5, 9));\r
- }\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
-\r
- IList<int> lst2 = new ArrayList<int>();\r
-\r
- lst2.Add(7); lst2.Add(8); lst2.Add(9);\r
- lst.InsertAll(0, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 3, 4));\r
- lst.InsertAll(7, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 3, 4, 7, 8, 9));\r
- lst.InsertAll(5, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 7, 8, 9, 3, 4, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void Map()\r
- {\r
- Fun<int, string> m = delegate(int i) { return "<<" + i + ">>"; };\r
- IList<string> r = lst.Map(m);\r
-\r
- Assert.IsTrue(r.Check());\r
- Assert.IsTrue(r.IsEmpty);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- r = lst.Map(m);\r
- Assert.IsTrue(r.Check());\r
- Assert.AreEqual(4, r.Count);\r
- for (int i = 0; i < 4; i++)\r
- Assert.AreEqual("<<" + (i + 1) + ">>", r[i]);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapper()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapperView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAllView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemove() { lst.Remove(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveFirst() { lst.RemoveFirst(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveLast() { lst.RemoveLast(); }\r
-\r
-\r
- [Test]\r
- public void RemoveFirstLast()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- Assert.AreEqual(1, lst.RemoveFirst());\r
- Assert.AreEqual(4, lst.RemoveLast());\r
- Assert.AreEqual(2, lst.RemoveFirst());\r
- Assert.AreEqual(3, lst.RemoveLast());\r
- Assert.IsTrue(lst.IsEmpty);\r
- }\r
-\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(0, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 0).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- lst.View(5, 1).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void BadReverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.View(8, 3).Reverse();\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private IList<KeyValuePair<int, int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new ArrayList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int, int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- Assert.AreEqual(4, lst[3].Key);\r
- Assert.AreEqual(34, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class SortingTests\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new ArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- lst.Add(5); lst.Add(6); lst.Add(5); lst.Add(7); lst.Add(3);\r
- Assert.IsFalse(lst.IsSorted(new IC()));\r
- lst.Sort(new IC());\r
- Assert.IsTrue(lst.IsSorted());\r
- Assert.IsTrue(lst.IsSorted(new IC()));\r
- Assert.IsTrue(IC.eq(lst, 3, 5, 5, 6, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void Stability()\r
- {\r
- IList<KeyValuePair<int, string>> lst2 = new ArrayList<KeyValuePair<int, string>>();\r
- SCG.IComparer<KeyValuePair<int, string>> c = new KeyValuePairComparer<int, string>(new IC());\r
-\r
- lst2.Add(new KeyValuePair<int, string>(5, "a"));\r
- lst2.Add(new KeyValuePair<int, string>(5, "b"));\r
- lst2.Add(new KeyValuePair<int, string>(6, "c"));\r
- lst2.Add(new KeyValuePair<int, string>(4, "d"));\r
- lst2.Add(new KeyValuePair<int, string>(3, "e"));\r
- lst2.Add(new KeyValuePair<int, string>(4, "f"));\r
- lst2.Add(new KeyValuePair<int, string>(5, "handle"));\r
- Assert.IsFalse(lst2.IsSorted(c));\r
- lst2.Sort(c);\r
- Assert.IsTrue(lst2.IsSorted(c));\r
-\r
- KeyValuePair<int, string> p = lst2.RemoveFirst();\r
-\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual("e", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(4, p.Key);\r
- Assert.AreEqual("d", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(4, p.Key);\r
- Assert.AreEqual("f", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(5, p.Key);\r
- Assert.AreEqual("a", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(5, p.Key);\r
- Assert.AreEqual("b", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(5, p.Key);\r
- Assert.AreEqual("handle", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(6, p.Key);\r
- Assert.AreEqual("c", p.Value);\r
- Assert.IsTrue(lst2.IsEmpty);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ShuffleTests\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new ArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Shuffle()\r
- {\r
- lst.Add(5); lst.Add(6); lst.Add(5); lst.Add(7); lst.Add(3);\r
- for (int i = 0; i < 100; i++)\r
- {\r
- lst.Shuffle(new C5Random(i + 1));\r
- Assert.IsTrue(lst.Check(), "Check " + i);\r
- int[] lst2 = lst.ToArray();\r
- Sorting.IntroSort<int>(lst2);\r
- Assert.IsTrue(IC.eq(lst2, 3, 5, 5, 6, 7), "Contents " + i);\r
- }\r
- }\r
- }\r
-\r
- }\r
-\r
-\r
- namespace IStackQueue\r
- {\r
- [TestFixture]\r
- public class Stack\r
- {\r
- private IStack<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new ArrayList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Push(7);\r
- list.Push(5);\r
- list.Push(7);\r
- list.Push(8);\r
- list.Push(9);\r
- Assert.AreEqual(9, list.Pop());\r
- Assert.AreEqual(8, list.Pop());\r
- Assert.AreEqual(7, list.Pop());\r
- Assert.AreEqual(5, list.Pop());\r
- Assert.AreEqual(7, list.Pop());\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PopEmpty()\r
- {\r
- list.Push(5);\r
- Assert.AreEqual(5, list.Pop());\r
- list.Pop();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- [TestFixture]\r
- public class Queue\r
- {\r
- private IQueue<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new ArrayList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Enqueue(7);\r
- list.Enqueue(5);\r
- list.Enqueue(7);\r
- list.Enqueue(8);\r
- list.Enqueue(9);\r
- Assert.AreEqual(7, list.Dequeue());\r
- Assert.AreEqual(5, list.Dequeue());\r
- Assert.AreEqual(7, list.Dequeue());\r
- Assert.AreEqual(8, list.Dequeue());\r
- Assert.AreEqual(9, list.Dequeue());\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void DeQueueEmpty()\r
- {\r
- list.Enqueue(5);\r
- Assert.AreEqual(5, list.Dequeue());\r
- list.Dequeue();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
-\r
- namespace Range\r
- {\r
- [TestFixture]\r
- public class Range\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new ArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void GetRange()\r
- {\r
- //Assert.IsTrue(IC.eq(lst[0, 0)));\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst[0, 3], 0, 1, 2));\r
- Assert.IsTrue(IC.eq(lst[3, 4], 3, 4, 5, 6));\r
- Assert.IsTrue(IC.eq(lst[6, 4], 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void BadGetRange()\r
- {\r
- object foo = lst[0, 11];\r
- }\r
-\r
-\r
- [Test]\r
- public void Backwards()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst.Backwards(), 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[0, 4].Backwards(), 3, 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[3, 4].Backwards(), 6, 5, 4, 3));\r
- Assert.IsTrue(IC.eq(lst[6, 4].Backwards(), 9, 8, 7, 6));\r
- }\r
-\r
-\r
- [Test]\r
- public void DirectionAndCount()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst.Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst[3, 4].Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst[3, 4].Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst.Backwards().Direction);\r
- Assert.AreEqual(4, lst[3, 4].Count);\r
- Assert.AreEqual(4, lst[3, 4].Backwards().Count);\r
- Assert.AreEqual(10, lst.Backwards().Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- foreach (int i in lst)\r
- {\r
- lst.Add(45 + i);\r
- }\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace View\r
- {\r
- [TestFixture]\r
- public class Simple\r
- {\r
- ArrayList<int> list, view;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>();\r
- list.Add(0); list.Add(1); list.Add(2); list.Add(3);\r
- view = (ArrayList<int>)list.View(1, 2);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = view = null;\r
- }\r
-\r
-\r
- void check()\r
- {\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(view.Check());\r
- }\r
-\r
-\r
- //static void pint(IEnumerable<int> l) { foreach (int cell in l) Console.WriteLine(cell); }\r
-\r
- [Test]\r
- public void InsertPointer()\r
- {\r
- IList<int> view2 = list.View(2, 0);\r
- list.Insert(view2, 7);\r
- check();\r
- list.Insert(list, 8);\r
- check();\r
- view.Insert(view2, 9);\r
- check();\r
- view.Insert(list.View(3, 2), 10);\r
- check();\r
- view.Insert(list.ViewOf(0), 11);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 11, 1, 9, 7, 2, 10, 3, 8));\r
- Assert.IsTrue(IC.eq(view, 11, 1, 9, 7, 2, 10));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad1()\r
- {\r
- view.Insert(list.View(0, 0), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad2()\r
- {\r
- view.Insert(list, 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad3()\r
- {\r
- list.Insert(new ArrayList<int>(), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad4()\r
- {\r
- list.Insert(new ArrayList<int>().View(0, 0), 7);\r
- }\r
-\r
-\r
- [Test]\r
- public void Span()\r
- {\r
- IList<int> span = list.View(1, 0).Span(list.View(2, 0));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(1, span.Offset);\r
- Assert.AreEqual(1, span.Count);\r
- span = list.View(0, 2).Span(list.View(2, 2));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(0, span.Offset);\r
- Assert.AreEqual(4, span.Count);\r
- span = list.View(3, 1).Span(list.View(1, 1));\r
- Assert.IsNull(span);\r
- }\r
-\r
- [Test]\r
- public void ViewOf()\r
- {\r
- for (int i = 0; i < 4; i++)\r
- list.Add(i);\r
- IList<int> v = view.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.LastViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(6, v.Offset);\r
- }\r
-\r
- [Test]\r
- public void ArrayStuff()\r
- {\r
- Assert.IsTrue(IC.eq(view.ToArray(), 1, 2));\r
- int[] extarray = new int[5];\r
- view.CopyTo(extarray, 2);\r
- Assert.IsTrue(IC.eq(extarray, 0, 0, 1, 2, 0));\r
- }\r
-\r
- [Test]\r
- public void BadViewOf()\r
- {\r
- Assert.IsNull(view.ViewOf(5));\r
- Assert.IsNull(view.LastViewOf(5));\r
- Assert.IsNull(view.ViewOf(3));\r
- Assert.IsNull(view.LastViewOf(3));\r
- Assert.IsNull(view.ViewOf(0));\r
- Assert.IsNull(view.LastViewOf(0));\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2));\r
- view.InsertFirst(10);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 10, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 10, 1, 2));\r
- view.Clear();\r
- Assert.IsFalse(view.IsReadOnly);\r
- Assert.IsTrue(view.AllowsDuplicates);\r
- Assert.IsTrue(view.IsEmpty);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 3));\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(8);\r
- Assert.IsFalse(view.IsEmpty);\r
- Assert.IsTrue(view.AllowsDuplicates);\r
- Assert.IsFalse(view.IsReadOnly);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 3));\r
- Assert.IsTrue(IC.eq(view, 8));\r
- view.Add(12);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12));\r
- view./*ViewOf(12)*/InsertLast(15);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12, 15));\r
- view.ViewOf(12).InsertFirst(18);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15));\r
-\r
- ArrayList<int> lst2 = new ArrayList<int>();\r
-\r
- lst2.Add(90); lst2.Add(92);\r
- view.AddAll(lst2);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92));\r
- view.InsertLast(66);\r
- check();\r
-\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 66, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92, 66));\r
- }\r
-\r
-\r
- [Test]\r
- public void Bxxx()\r
- {\r
- Assert.IsTrue(IC.eq(view.Backwards(), 2, 1));\r
- Assert.AreSame(list, view.Underlying);\r
- Assert.IsNull(list.Underlying);\r
- Assert.AreEqual(EnumerationDirection.Forwards, view.Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, view.Backwards().Direction);\r
- Assert.AreEqual(0, list.Offset);\r
- Assert.AreEqual(1, view.Offset);\r
- }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsTrue(view.Contains(1));\r
- Assert.IsFalse(view.Contains(0));\r
-\r
- ArrayList<int> lst2 = new ArrayList<int>();\r
-\r
- lst2.Add(2);\r
- Assert.IsTrue(view.ContainsAll(lst2));\r
- lst2.Add(3);\r
- Assert.IsFalse(view.ContainsAll(lst2));\r
- Assert.AreEqual(Speed.Linear, view.ContainsSpeed);\r
- Assert.AreEqual(2, view.Count);\r
- view.Add(1);\r
- Assert.AreEqual(1, view.ContainsCount(2));\r
- Assert.AreEqual(2, view.ContainsCount(1));\r
- Assert.AreEqual(3, view.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void CreateView()\r
- {\r
- ArrayList<int> view2 = (ArrayList<int>)view.View(1, 0);\r
-\r
- Assert.AreSame(list, view2.Underlying);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- Assert.IsFalse(view.FIFO);\r
- view.FIFO = true;\r
- view.Add(23); view.Add(24); view.Add(25);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 23, 24, 25));\r
- Assert.AreEqual(1, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24, 25));\r
- view.FIFO = false;\r
- Assert.IsFalse(view.FIFO);\r
- Assert.AreEqual(25, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24));\r
- }\r
-\r
-\r
- [Test]\r
- public void MapEtc()\r
- {\r
- ArrayList<double> dbl = (ArrayList<double>)view.Map(new Fun<int, double>(delegate(int i) { return i / 10.0; }));\r
-\r
- Assert.IsTrue(dbl.Check());\r
- Assert.AreEqual(0.1, dbl[0]);\r
- Assert.AreEqual(0.2, dbl[1]);\r
- for (int i = 0; i < 10; i++) view.Add(i);\r
-\r
- list = (ArrayList<int>)view.FindAll(new Fun<int, bool>(delegate(int i) { return i % 4 == 1; }));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 1, 1, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void FL()\r
- {\r
- Assert.AreEqual(1, view.First);\r
- Assert.AreEqual(2, view.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void Indexing()\r
- {\r
- list.Clear();\r
- for (int i = 0; i < 20; i++) list.Add(i);\r
-\r
- view = (ArrayList<int>)list.View(5, 7);\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i + 5, view[i]);\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.IndexOf(i + 5));\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.LastIndexOf(i + 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- view.Insert(0, 34);\r
- view.Insert(1, 35);\r
- view.Insert(4, 36);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 2, 36));\r
-\r
- IList<int> list2 = new ArrayList<int>();\r
-\r
- list2.AddAll(view);\r
- view.InsertAll(3, list2);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 34, 35, 1, 2, 36, 2, 36));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RangeCheck1()\r
- {\r
- IList<int> lst = new ArrayList<int>();\r
- lst.Add(2);\r
- lst = lst.View(1, 1);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RangeCheck2()\r
- {\r
- IList<int> lst = new ArrayList<int>();\r
- lst.Add(2);\r
- lst = lst.View(1, -1);\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- view.Add(45); view.Add(47); view.Add(46); view.Add(48);\r
- Assert.IsFalse(view.IsSorted(new IC()));\r
- view.Sort(new IC());\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 45, 46, 47, 48, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2, 45, 46, 47, 48));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 1, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 1, 5, 3, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5, 3, 3, 0));\r
- Assert.IsTrue(view.Remove(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5, 3, 3));\r
- view.RemoveAllCopies(3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5));\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 5, 3));\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5, 1, 5, 3, 1, 3, 0));\r
-\r
- view.FIFO = true;\r
- view.Clear(); view.Add(1); view.Add(2);\r
-\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 1, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 1, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5, 3, 1, 3));\r
- view.RemoveAllCopies(3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5, 1));\r
- Assert.IsTrue(IC.eq(list, 0, 2, 5, 1, 3));\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 2, 5, 1, 1, 5, 3, 1, 3, 0));\r
-\r
- view.FIFO = false;\r
-\r
- ArrayList<int> l2 = new ArrayList<int>();\r
-\r
- l2.Add(1); l2.Add(2); l2.Add(2); l2.Add(3); l2.Add(1);\r
- view.RemoveAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 5, 5, 1, 3, 0));\r
- view.RetainAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 3));\r
- view.Add(2); view.Add(4); view.Add(5);\r
- Assert.AreEqual(1, view.RemoveAt(0));\r
- Assert.AreEqual(5, view.RemoveAt(3));\r
- Assert.AreEqual(2, view.RemoveAt(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 3, 4));\r
- view.Add(8);\r
- Assert.AreEqual(3, view.RemoveFirst());\r
- Assert.AreEqual(8, view.RemoveLast());\r
- view.Add(2); view.Add(5); view.Add(3); view.Add(1);\r
- view.RemoveInterval(1, 2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 4, 3, 1));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- view.Clear();\r
- for (int i = 0; i < 10; i++) view.Add(10 + i);\r
-\r
- view.View(3, 4).Reverse();\r
- check();\r
- Assert.IsTrue(IC.eq(view, 10, 11, 12, 16, 15, 14, 13, 17, 18, 19));\r
- view.Reverse();\r
- Assert.IsTrue(IC.eq(view, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10));\r
- Assert.IsTrue(IC.eq(list, 0, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10, 3));\r
- }\r
-\r
-\r
- [Test]\r
- public void Slide()\r
- {\r
- view.Slide(1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 3));\r
- view.Slide(-2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1));\r
- view.Slide(0, 3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1, 2));\r
- view.Slide(2, 1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2));\r
- Assert.AreEqual(view, view.Slide(-1, 0));\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(28);\r
- Assert.IsTrue(IC.eq(list, 0, 28, 1, 2, 3));\r
- }\r
- [Test]\r
- public void Iterate()\r
- {\r
- list.Clear();\r
- view = null;\r
- foreach (int i in new int[] { 2, 4, 8, 13, 6, 1, 2, 7 }) list.Add(i);\r
-\r
- view = (ArrayList<int>)list.View(list.Count - 2, 2);\r
- while (true)\r
- {\r
- if ((view.Last - view.First) % 2 == 1)\r
- view.Insert(1, 666);\r
- check();\r
- if (view.Offset == 0)\r
- break;\r
- else\r
- view.Slide(-1, 2);\r
- }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 2, 4, 8, 666, 13, 6, 1, 666, 2, 666, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void SyncRoot()\r
- {\r
- Assert.AreSame(view.SyncRoot, list.SyncRoot);\r
- }\r
- }\r
- [TestFixture]\r
- public class MulipleViews\r
- {\r
- IList<int> list;\r
- IList<int>[][] views;\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>();\r
- for (int i = 0; i < 6; i++)\r
- list.Add(i);\r
- views = new IList<int>[7][];\r
- for (int i = 0; i < 7; i++)\r
- {\r
- views[i] = new IList<int>[7 - i];\r
- for (int j = 0; j < 7 - i; j++)\r
- views[i][j] = list.View(i, j);\r
- }\r
- }\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = null;\r
- views = null;\r
- }\r
- [Test]\r
- public void Insert()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(3, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(3);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 3 && i + j > 3 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveInterval(3, 2);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i <= 5 ? 3 : i - 2, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j == 0 ? 0 : i <= 3 && i + j > 4 ? j - 2 : i > 4 || i + j <= 3 ? j : j - 1, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.InsertLast(777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(5);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 5 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 5 && i + j > 5 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void InsertAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(0, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 && j == 0 ? 0 : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(0);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i == 0 && j > 0 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void Clear()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before clear");\r
- views[2][3].Clear();\r
- Assert.IsTrue(list.Check(), "list check after clear");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 2 ? i : i < 6 ? 2 : i - 3, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(s(i, j), views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- private int s(int i, int j)\r
- {\r
- if (j == 0) return 0;\r
- int k = i + j - 1; //end\r
- if (i > 4 || k <= 1) return j;\r
- if (i >= 2) return k > 4 ? k - 4 : 0;\r
- if (i <= 2) return k >= 4 ? j - 3 : 2 - i;\r
- return -1;\r
- }\r
- [Test]\r
- public void InsertAll()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before insertAll");\r
- list.InsertAll(3, list2);\r
- Assert.IsTrue(list.Check(), "list check after insertAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before AddAll");\r
- list.View(1, 2).AddAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after AddAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void RemoveAll1()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
-\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new ArrayList<int>();\r
- for (int k = 0; k < 6; k++) list.Add(k);\r
- ArrayList<int> v = (ArrayList<int>)list.View(i, j);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
- [Test]\r
- public void RemoveAll2()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
- Assert.IsTrue(list.Check(), "list check before RemoveAll");\r
- list.RemoveAll(list2);\r
-\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(1, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(1, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(1, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(1, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(1, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(1, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(1, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(1, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(1, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(1, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(1, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(2, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(2, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(2, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(2, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(2, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(2, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(2, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(1, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(1, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(2, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(2, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(1, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(2, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(1, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(2, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(0, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(1, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(0, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(1, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll");\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
- list2.Add(2); list2.Add(4); list2.Add(5);\r
- Assert.IsTrue(list.Check(), "list check before RetainAll");\r
- list.RetainAll(list2);\r
-\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(0, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(0, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(0, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(0, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(0, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(0, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(0, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(0, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(0, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(0, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(0, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(1, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(1, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(1, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(1, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(1, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(1, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(1, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(0, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(0, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(1, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(1, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(2, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(3, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(2, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(3, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(1, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(2, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(1, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(2, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
- Assert.IsTrue(list.Check(), "list check after RetainAll");\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- ArrayList<int> list2 = new ArrayList<int>();\r
- list2.Add(0); list2.Add(2); list2.Add(2); list2.Add(2); list2.Add(5); list2.Add(2); list2.Add(1);\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new ArrayList<int>();\r
- list.AddAll(list2);\r
- ArrayList<int> v = (ArrayList<int>)list.View(i, j);\r
- list.RemoveAllCopies(2);\r
- Assert.AreEqual((i == 0 && j > 0 ? 1 : 0) + (i <= 4 && i + j > 4 ? 1 : 0) + (i <= 6 && i + j > 6 ? 1 : 0), v.Count, "v.Count, i=" + i + ", j=" + j);\r
- Assert.AreEqual(i == 0 ? 0 : i <= 4 ? 1 : i <= 6 ? 2 : 3, v.Offset, "v.Offset, i=" + i + ", j=" + j);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAllCopies, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
-\r
- private void checkDisposed(bool reverse, int start, int count)\r
- {\r
- int k = 0;\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- if (i + j <= start || i >= start + count || (i <= start && i + j >= start + count) || (reverse && start <= i && start + count >= i + j))\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- }\r
- catch (ViewDisposedException)\r
- {\r
- Assert.Fail("view[" + i + "][" + j + "] threw");\r
- }\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] size");\r
- if (reverse && ((j > 0 && start <= i && start + count >= i + j) || (j == 0 && start < i && start + count > i)))\r
- Assert.AreEqual(start + (start + count - i - j), views[i][j].Offset, "view[" + i + "][" + j + "] offset (mirrored)");\r
- else\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- }\r
- else\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- Assert.Fail("view[" + i + "][" + j + "] no throw");\r
- }\r
- catch (ViewDisposedException) { }\r
- }\r
- }\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Reverse");\r
- list2.Reverse();\r
- Assert.IsTrue(list.Check(), "list check after Reverse");\r
- checkDisposed(true, start, count);\r
- }\r
- [Test]\r
- public void Sort()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Sort");\r
- list2.Sort();\r
- Assert.IsTrue(list.Check(), "list check after Sort");\r
- checkDisposed(false, start, count);\r
- }\r
- [Test]\r
- public void Shuffle()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Shuffle");\r
- list2.Shuffle();\r
- Assert.IsTrue(list.Check(), "list check after Shuffle");\r
- checkDisposed(false, start, count);\r
- }\r
-\r
-\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace ArrayListOfTreesORLists\r
- {\r
- [TestFixture]\r
- public class MultiLevelUnorderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ICollection<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new ArrayList<ICollection<int>>();\r
- Dat = new ArrayList<ICollection<int>>();\r
- Dut = new ArrayList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dat));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ISequenced<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new ArrayList<ICollection<int>>();\r
- Dat = new ArrayList<ICollection<int>>();\r
- Dut = new ArrayList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dit); Dut.Add(dut); Dut.Add(dat);\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ICollection<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- dot = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(2); dat.Add(1);\r
- dut.Add(3);\r
- dot.Add(1); dot.Add(2);\r
- Dit = new ArrayList<ISequenced<int>>();\r
- Dat = new ArrayList<ISequenced<int>>();\r
- Dut = new ArrayList<ISequenced<int>>();\r
- Dot = new ArrayList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dut));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dat));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ISequenced<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- dot = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(2); dat.Add(1);\r
- dut.Add(3);\r
- dot.Add(1); dot.Add(2);\r
- Dit = new ArrayList<ISequenced<int>>();\r
- Dat = new ArrayList<ISequenced<int>>();\r
- Dut = new ArrayList<ISequenced<int>>();\r
- Dot = new ArrayList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsFalse(Dit.SequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace HashingAndEquals\r
- {\r
- [TestFixture]\r
- public class ISequenced\r
- {\r
- private ISequenced<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- }\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.sequencedhashcode(), dit.GetSequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dit.GetSequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(3, 7), dit.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.sequencedhashcode(), dut.GetSequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(7), dut.GetSequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(7, 3), dut.GetSequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(0); dit.Add(31);\r
- dat.Add(1); dat.Add(0);\r
- Assert.AreEqual(dit.GetSequencedHashCode(), dat.GetSequencedHashCode());\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dat.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dut));\r
- Assert.IsTrue(dut.SequencedEquals(dit));\r
- dit.Add(7);\r
- ((ArrayList<int>)dut).InsertFirst(7);\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- Assert.IsFalse(dut.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(-1657792980); dit.Add(-1570288808);\r
- dat.Add(1862883298); dat.Add(-272461342);\r
- Assert.AreEqual(dit.GetUnsequencedHashCode(), dat.GetUnsequencedHashCode());\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnorderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ICollection<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new ArrayList<ICollection<int>>();\r
- Dat = new ArrayList<ICollection<int>>();\r
- Dut = new ArrayList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dat));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ISequenced<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new ArrayList<ICollection<int>>();\r
- Dat = new ArrayList<ICollection<int>>();\r
- Dut = new ArrayList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dit); Dut.Add(dut); Dut.Add(dat);\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ICollection<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- dot = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- dot.Add(2); dot.Add(1);\r
- Dit = new ArrayList<ISequenced<int>>();\r
- Dat = new ArrayList<ISequenced<int>>();\r
- Dut = new ArrayList<ISequenced<int>>();\r
- Dot = new ArrayList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dut));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dat));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ISequenced<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new ArrayList<int>();\r
- dat = new ArrayList<int>();\r
- dut = new ArrayList<int>();\r
- dot = new ArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- dot.Add(2); dot.Add(1);\r
- Dit = new ArrayList<ISequenced<int>>();\r
- Dat = new ArrayList<ISequenced<int>>();\r
- Dut = new ArrayList<ISequenced<int>>();\r
- Dot = new ArrayList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsFalse(Dit.SequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-namespace C5UnitTests.arrays.circularqueue\r
-{\r
- using CollectionOfInt = CircularQueue<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(); };\r
- new C5UnitTests.Templates.Events.QueueTester<CollectionOfInt>().Test(factory);\r
- new C5UnitTests.Templates.Events.StackTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- //TODO: Test Circular Queue for Clone(?) and Serializable \r
- //C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- //C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- //[TestFixture]\r
- public class Template\r
- {\r
- private CircularQueue<int> queue;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- queue = new CircularQueue<int>();\r
- }\r
-\r
- [Test]\r
- public void LeTest()\r
- {\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { queue = null; }\r
-\r
- }\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- CircularQueue<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = new CircularQueue<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{ }", coll.ToString());\r
- foreach (int i in new int[] { -4, 28, 129, 65530 })\r
- coll.Enqueue(i);\r
- Assert.AreEqual("{ -4, 28, 129, 65530 }", coll.ToString());\r
- Assert.AreEqual("{ -4, 1C, 81, FFFA }", coll.ToString(null, rad16));\r
- Assert.AreEqual("{ -4, 28, 129... }", coll.ToString("L14", null));\r
- Assert.AreEqual("{ -4, 1C, 81... }", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class CircularQueue\r
- {\r
- private CircularQueue<int> queue;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- queue = new CircularQueue<int>();\r
- }\r
-\r
- void loadup1()\r
- {\r
- queue.Enqueue(11);\r
- queue.Enqueue(12);\r
- queue.Enqueue(13);\r
- queue.Dequeue();\r
- queue.Enqueue(103);\r
- queue.Enqueue(14);\r
- queue.Enqueue(15);\r
- }\r
-\r
- void loadup2()\r
- {\r
- loadup1();\r
- for (int i = 0; i < 4; i++)\r
- {\r
- queue.Dequeue();\r
- queue.Enqueue(1000 + i);\r
- }\r
- }\r
-\r
- void loadup3()\r
- {\r
- for (int i = 0; i < 18; i++)\r
- {\r
- queue.Enqueue(i);\r
- Assert.IsTrue(queue.Check());\r
- }\r
- for (int i = 0; i < 14; i++)\r
- {\r
- Assert.IsTrue(queue.Check());\r
- queue.Dequeue();\r
- }\r
- }\r
-\r
- [Test]\r
- public void Expand()\r
- {\r
- Assert.IsTrue(queue.Check());\r
- loadup3();\r
- Assert.IsTrue(IC.eq(queue, 14, 15, 16, 17));\r
- }\r
-\r
- [Test]\r
- public void Simple()\r
- {\r
- loadup1();\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(5, queue.Count);\r
- Assert.IsTrue(IC.eq(queue, 12, 13, 103, 14, 15));\r
- Assert.AreEqual(12, queue.Choose());\r
- }\r
-\r
- [Test]\r
- public void Stack()\r
- {\r
- queue.Push(1);\r
- Assert.IsTrue(queue.Check());\r
- queue.Push(2);\r
- Assert.IsTrue(queue.Check());\r
- queue.Push(3);\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(3, queue.Pop());\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(2, queue.Pop());\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(1, queue.Pop());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- queue.Choose();\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadDequeue()\r
- {\r
- queue.Dequeue();\r
- }\r
-\r
- [Test]\r
- public void Simple2()\r
- {\r
- loadup2();\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(5, queue.Count);\r
- Assert.IsTrue(IC.eq(queue, 15, 1000, 1001, 1002, 1003));\r
- Assert.AreEqual(15, queue.Choose());\r
- }\r
-\r
- [Test]\r
- public void Counting()\r
- {\r
- Assert.IsTrue(queue.IsEmpty);\r
- Assert.AreEqual(0, queue.Count);\r
- Assert.AreEqual(Speed.Constant, queue.CountSpeed);\r
- queue.Enqueue(11);\r
- Assert.IsFalse(queue.IsEmpty);\r
- queue.Enqueue(12);\r
- Assert.AreEqual(2, queue.Count);\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { queue = null; }\r
-\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests.arrays.hashed\r
-{\r
- using CollectionOfInt = HashedArrayList<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.ListTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Clone.ViewTester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.ViewTester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new HashedArrayList<T>(); }\r
- }\r
-\r
- namespace Events\r
- {\r
- class TenEqualityComparer : SCG.IEqualityComparer<int>\r
- {\r
- TenEqualityComparer() { }\r
- public static TenEqualityComparer Default { get { return new TenEqualityComparer(); } }\r
- public int GetHashCode(int item) { return (item / 10).GetHashCode(); }\r
- public bool Equals(int item1, int item2) { return item1 / 10 == item2 / 10; }\r
- }\r
-\r
- [TestFixture]\r
- public class IList_\r
- {\r
- private HashedArrayList<int> list;\r
- CollectionEventList<int> seen;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>(TenEqualityComparer.Default);\r
- seen = new CollectionEventList<int>(IntEqualityComparer.Default);\r
- }\r
-\r
- private void listen() { seen.Listen(list, EventTypeEnum.All); }\r
-\r
- [Test]\r
- public void SetThis()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list[1] = 45;\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Insert(1, 45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.InsertAll<int>(1, new int[] { 666, 777, 888 });\r
- //seen.Print(Console.Error);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(666,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(666, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(777,2), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(777, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(888,3), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(888, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.InsertAll<int>(1, new int[] {});\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- listen();\r
- list.InsertFirst(45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.InsertLast(88);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(88,4), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(88, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Remove();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveFirst()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveFirst();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(4,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(4, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveLast()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveLast();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Reverse();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.View(1, 0).Reverse();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Sort();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.View(1, 0).Sort();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Shuffle()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Shuffle();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.View(1, 0).Shuffle();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.RemoveAt(1);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- listen();\r
- list.RemoveInterval(1, 2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,2,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.RemoveInterval(1, 0);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- list.Update(53);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Update(67);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- int val = 53;\r
- list.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- val = 67;\r
- list.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- list.Add(4); list.Add(56); list.Add(8);\r
- listen();\r
- int val = 53;\r
- list.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- val = 67;\r
- list.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.UpdateOrAdd(51, out val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(53, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(51, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- val = 67;\r
- list.UpdateOrAdd(81, out val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(81, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- }\r
-\r
- [Test]\r
- public void RemoveItem()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- listen();\r
- list.Remove(53);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Remove(11);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.RemoveAll<int>(new int[] { 32, 187, 45 });\r
- //TODO: the order depends on internals of the HashSet\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(35, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(45, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.RemoveAll<int>(new int[] { 200, 300 });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- listen();\r
- list.View(1, 1).Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,1,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,2,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Clear();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void ListDispose()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- listen();\r
- list.View(1, 1).Dispose();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- list.Dispose();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,3,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)\r
- });\r
- list.Dispose();\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.RetainAll<int>(new int[] { 32, 187, 45, 62, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(15, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(25, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(55, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(75, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.RetainAll<int>(new int[] { 32, 187, 45, 62, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(3 * i + 5);\r
- }\r
- listen();\r
- list.RemoveAllCopies(14);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.RemoveAllCopies(14);\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- list.Add(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- list.Add(10 * i + 5);\r
- }\r
- listen();\r
- list.AddAll<int>(new int[] { 145, 56, 167 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(145, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(167, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.AddAll<int>(new int[] { });\r
- seen.Check(new CollectionEvent<int>[] {});\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; seen = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class StackQueue\r
- {\r
-\r
- private ArrayList<int> list;\r
- CollectionEventList<int> seen;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new ArrayList<int>(TenEqualityComparer.Default);\r
- seen = new CollectionEventList<int>(IntEqualityComparer.Default);\r
- }\r
-\r
- private void listen() { seen.Listen(list, EventTypeEnum.All); }\r
-\r
- [Test]\r
- public void EnqueueDequeue()\r
- {\r
- listen();\r
- list.Enqueue(67);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(67,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Enqueue(2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(2,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(2, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(67,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(67, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(2,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(2, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [Test]\r
- public void PushPop()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- list.Push(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(23,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Push(-12);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(-12,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(-12, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(-12,1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(-12, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- list.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(23,0), list),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(23, 1), list),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), list)});\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; seen = null; }\r
- }\r
-\r
-\r
- }\r
-\r
- namespace Safety\r
- {\r
- /// <summary>\r
- /// Tests to see if the collection classes are robust for enumerable arguments that throw exceptions.\r
- /// </summary>\r
- [TestFixture]\r
- public class BadEnumerable\r
- {\r
- private HashedArrayList<int> list;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>();\r
- }\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- try\r
- {\r
- list.InsertAll<int>(1, new BadEnumerable<int>(new BadEnumerableException(), 91, 81, 71));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 91, 81, 71, 56, 18));\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- try\r
- {\r
- list.View(0, 1).AddAll<int>(new BadEnumerable<int>(new BadEnumerableException(), 91, 81, 71));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 91, 81, 71, 56, 18));\r
- }\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- try\r
- {\r
- list.RemoveAll(new BadEnumerable<int>(new BadEnumerableException(), 9, 8, 7));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 56, 18));\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- try\r
- {\r
- list.RetainAll(new BadEnumerable<int>(new BadEnumerableException(), 9, 8, 7));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 56, 18));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- list.Add(4); list.Add(56); list.Add(18);\r
- try\r
- {\r
- list.ContainsAll(new BadEnumerable<int>(new BadEnumerableException(), 4, 18));\r
- Assert.Fail("Should not get here");\r
- }\r
- catch (BadEnumerableException) { }\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 56, 18));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
- /// <summary>\r
- /// Tests to see if the collection classes are robust for delegate arguments that throw exceptions.\r
- /// </summary>\r
- [TestFixture]\r
- public class BadFun\r
- {\r
- private HashedArrayList<int> list;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>();\r
- }\r
-\r
- [Test]\r
- public void NoTests() { }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
-\r
- namespace Enumerable\r
- {\r
- [TestFixture]\r
- public class Multiops\r
- {\r
- private HashedArrayList<int> list;\r
-\r
- private Fun<int, bool> always, never, even;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>();\r
- always = delegate { return true; };\r
- never = delegate { return false; };\r
- even = delegate(int i) { return i % 2 == 0; };\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsTrue(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsFalse(list.All(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsTrue(list.Exists(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- int sum = 0;\r
- Act<int> a = delegate(int i) { sum = i + 10 * sum; };\r
-\r
- list.Apply(a);\r
- Assert.AreEqual(0, sum);\r
- sum = 0;\r
- list.Add(5); list.Add(8); list.Add(7); list.Add(5);\r
- list.Apply(a);\r
- Assert.AreEqual(587, sum);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class GetEnumerator\r
- {\r
- private HashedArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedArrayList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Empty()\r
- {\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
- list.Add(5);\r
- list.Add(10);\r
- list.Add(1);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(8, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(10, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(1, e.Current);\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void DoDispose()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- e.MoveNext();\r
- e.Dispose();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- list.Add(99);\r
- e.MoveNext();\r
- }\r
-\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
- namespace CollectionOrSink\r
- {\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("[ ]", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("[ 0:-4, 1:28, 2:129, 3:65530 ]", coll.ToString());\r
- Assert.AreEqual("[ 0:-4, 1:1C, 2:81, 3:FFFA ]", coll.ToString(null, rad16));\r
- Assert.AreEqual("[ 0:-4, 1:28... ]", coll.ToString("L14", null));\r
- Assert.AreEqual("[ 0:-4, 1:1C... ]", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class CollectionOrSink\r
- {\r
- private HashedArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedArrayList<int>(); }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- list.Add(7);\r
- Assert.AreEqual(7, list.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- list.Choose();\r
- }\r
-\r
-\r
- [Test]\r
- public void CountEtAl()\r
- {\r
- Assert.AreEqual(0, list.Count);\r
- Assert.IsTrue(list.IsEmpty);\r
- Assert.IsFalse(list.AllowsDuplicates);\r
- Assert.IsTrue(list.Add(5));\r
- Assert.AreEqual(1, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- Assert.IsFalse(list.Add(5));\r
- Assert.AreEqual(1, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- Assert.IsTrue(list.Add(8));\r
- Assert.AreEqual(2, list.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- list.Add(3); list.Add(4); list.Add(5);\r
-\r
- HashedArrayList<int> list2 = new HashedArrayList<int>();\r
-\r
- list2.AddAll(list);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- list.AddAll(list2);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- Assert.IsTrue(IC.eq(list, 3, 4, 5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private HashedArrayList<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- [Test]\r
- public void FindLast()\r
- {\r
- int i;\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.FindLast(pred, out i));\r
- Assert.AreEqual(675, i);\r
- }\r
-\r
- [Test]\r
- public void FindIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(4, list.FindIndex(pred));\r
- }\r
-\r
- [Test]\r
- public void FindLastIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(6, list.FindLastIndex(pred));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private HashedArrayList<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedArrayList<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 1, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private HashedArrayList<int> list;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>();\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray()));\r
- list.Add(7);\r
- list.Add(8);\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray(), 7, 8));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- list.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(6);\r
- list.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(4);\r
- list.Add(5);\r
- list.Add(9);\r
- list.CopyTo(a, 4);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 5, 9, 1008, 1009));\r
- list.Clear();\r
- list.Add(7);\r
- list.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 5, 9, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- list.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- list.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- list.Add(3);\r
- list.Add(4);\r
- list.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Sync\r
- {\r
- private HashedArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- [Test]\r
- public void Get()\r
- {\r
- Assert.IsNotNull(list.SyncRoot);\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace EditableCollection\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private HashedArrayList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedArrayList<int>(); }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new HashedArrayList<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor2()\r
- {\r
- new HashedArrayList<int>(5, null);\r
- }\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsFalse(list.Contains(5));\r
- list.Add(5);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- list.Add(8);\r
- list.Add(10);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsTrue(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- list.Remove(8);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsFalse(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- }\r
-\r
- [Test]\r
- public void BadAdd()\r
- {\r
- Assert.IsTrue(list.Add(5));\r
- Assert.IsTrue(list.Add(8));\r
- Assert.IsFalse(list.Add(5));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsCount()\r
- {\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- list.Add(5);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- list.Add(8);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- Assert.AreEqual(1, list.ContainsCount(8));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- list.Add(5); list.Add(7);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.RemoveAllCopies(5);\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.Add(5); list.Add(8);\r
- list.RemoveAllCopies(8);\r
- Assert.IsTrue(IC.eq(list, 7, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindAll()\r
- {\r
- Fun<int, bool> f = delegate(int i) { return i % 2 == 0; };\r
-\r
- Assert.IsTrue(list.FindAll(f).IsEmpty);\r
- list.Add(5); list.Add(8); list.Add(10);\r
- Assert.IsTrue(((HashedArrayList<int>)list.FindAll(f)).Check());\r
- Assert.IsTrue(IC.eq(list.FindAll(f), 8, 10));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- HashedArrayList<int> list2 = new HashedArrayList<int>();\r
-\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(list.ContainsAll(list2));\r
- list.Add(4);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list.Add(5);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- HashedArrayList<int> list2 = new HashedArrayList<int>();\r
-\r
- list.Add(4); list.Add(5); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(5); list2.Add(5); list2.Add(6);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 6));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- HashedArrayList<int> list2 = new HashedArrayList<int>();\r
-\r
- list.Add(4); list.Add(5); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 6));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(6); list2.Add(5);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- list.Add(4); list.Add(5); list.Add(6);\r
- Assert.IsFalse(list.Remove(2));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(list.Remove(4));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 6));\r
- Assert.AreEqual(6, list.RemoveLast());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5));\r
- list.Add(7);\r
- Assert.AreEqual(5, list.RemoveFirst());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- list.Add(7); list.Add(6);\r
- list.Clear();\r
- Assert.IsTrue(list.IsEmpty);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace IIndexed\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void IndexOf()\r
- {\r
- Assert.AreEqual(~0, dit.IndexOf(6));\r
- dit.Add(7);\r
- Assert.AreEqual(~1, dit.IndexOf(6));\r
- Assert.AreEqual(~1, dit.LastIndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- dit.Add(5); dit.Add(7); dit.Add(8); dit.Add(7);\r
- Assert.AreEqual(~3, dit.IndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- Assert.AreEqual(0, dit.LastIndexOf(7));\r
- Assert.AreEqual(2, dit.IndexOf(8));\r
- Assert.AreEqual(1, dit.LastIndexOf(5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Removing\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- dit.Add(5); dit.Add(7); dit.Add(9); dit.Add(1); dit.Add(2);\r
- Assert.AreEqual(7, dit.RemoveAt(1));\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 5, 9, 1, 2));\r
- Assert.AreEqual(5, dit.RemoveAt(0));\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1, 2));\r
- Assert.AreEqual(2, dit.RemoveAt(2));\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad0()\r
- {\r
- dit.RemoveAt(0);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBadM1()\r
- {\r
- dit.RemoveAt(-1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad1()\r
- {\r
- dit.Add(8);\r
- dit.RemoveAt(1);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- dit.RemoveInterval(0, 0);\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(3, 0);\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 40, 50, 60));\r
- dit.RemoveInterval(3, 1);\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 50, 60));\r
- dit.RemoveInterval(1, 3);\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 60));\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit));\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40, 50, 60));\r
- dit.RemoveInterval(2, 2);\r
- Assert.IsTrue(((HashedArrayList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace IList\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void FirstBad()\r
- {\r
- int f = lst.First;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void LastBad()\r
- {\r
- int f = lst.Last;\r
- }\r
-\r
-\r
- [Test]\r
- public void FirstLast()\r
- {\r
- lst.Add(19);\r
- Assert.AreEqual(19, lst.First);\r
- Assert.AreEqual(19, lst.Last);\r
- lst.Add(34); lst.InsertFirst(12);\r
- Assert.AreEqual(12, lst.First);\r
- Assert.AreEqual(34, lst.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void This()\r
- {\r
- lst.Add(34);\r
- Assert.AreEqual(34, lst[0]);\r
- lst[0] = 56;\r
- Assert.AreEqual(56, lst.First);\r
- lst.Add(7); lst.Add(77); lst.Add(777); lst.Add(7777);\r
- lst[0] = 45; lst[2] = 78; lst[4] = 101;\r
- Assert.IsTrue(IC.eq(lst, 45, 7, 78, 777, 101));\r
- }\r
-\r
- [Test]\r
- public void ThisWithUpdates()\r
- {\r
- HashedArrayList<KeyValuePair<int, int>> pairlist = new HashedArrayList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- pairlist.Add(new KeyValuePair<int, int>(10, 50));\r
- pairlist.Add(new KeyValuePair<int, int>(11, 51));\r
- pairlist.Add(new KeyValuePair<int, int>(12, 52));\r
- pairlist.Add(new KeyValuePair<int, int>(13, 53));\r
- pairlist[2] = new KeyValuePair<int, int>(12, 102);\r
- Assert.IsTrue(pairlist.Check());\r
- Assert.AreEqual(new KeyValuePair<int, int>(12, 102), pairlist[2]);\r
- pairlist[2] = new KeyValuePair<int, int>(22, 202);\r
- Assert.IsTrue(pairlist.Check());\r
- Assert.AreEqual(new KeyValuePair<int, int>(22, 202), pairlist[2]);\r
- pairlist[1] = new KeyValuePair<int, int>(12, 303);\r
- Assert.IsTrue(pairlist.Check());\r
- Assert.AreEqual(new KeyValuePair<int, int>(12, 303), pairlist[1]);\r
- Assert.AreEqual(new KeyValuePair<int, int>(22, 202), pairlist[2]);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(DuplicateNotAllowedException))]\r
- public void ThisWithUpdatesBad()\r
- {\r
- HashedArrayList<KeyValuePair<int, int>> pairlist = new HashedArrayList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- pairlist.Add(new KeyValuePair<int, int>(10, 50));\r
- pairlist.Add(new KeyValuePair<int, int>(11, 51));\r
- pairlist.Add(new KeyValuePair<int, int>(12, 52));\r
- pairlist.Add(new KeyValuePair<int, int>(13, 53));\r
- pairlist[2] = new KeyValuePair<int, int>(11, 102);\r
- }\r
-\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptyGet()\r
- {\r
- int f = lst[0];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowGet()\r
- {\r
- lst.Add(7);\r
-\r
- int f = lst[-1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiGet()\r
- {\r
- lst.Add(6);\r
-\r
- int f = lst[1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptySet()\r
- {\r
- lst[0] = 4;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowSet()\r
- {\r
- lst.Add(7);\r
- lst[-1] = 9;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiSet()\r
- {\r
- lst.Add(6);\r
- lst[1] = 11;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Inserting\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 4);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5));\r
- lst.Insert(3, 2);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5, 2));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(DuplicateNotAllowedException))]\r
- public void InsertDuplicate()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 5);\r
- }\r
-\r
- [Test]\r
- public void InsertAllDuplicate1()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- try\r
- {\r
- lst.InsertAll<int>(1, new int[] { 1, 2, 3, 4 });\r
- }\r
- catch (DuplicateNotAllowedException)\r
- {\r
- }\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 1, 2, 3));\r
- }\r
-\r
- [Test]\r
- public void InsertAllDuplicate2()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- try\r
- {\r
- lst.InsertAll<int>(1, new int[] { 5, 6, 5, 8 });\r
- }\r
- catch (DuplicateNotAllowedException)\r
- {\r
- }\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 5, 6, 3));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertLow()\r
- {\r
- lst.Add(7);\r
- lst.Insert(-1, 9);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertHi()\r
- {\r
- lst.Add(6);\r
- lst.Insert(2, 11);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- for (int i = 0; i < 7; i++)\r
- lst.Add(2 * i);\r
-\r
- Assert.IsFalse(lst.FIFO);\r
- Assert.AreEqual(12, lst.Remove());\r
- Assert.AreEqual(10, lst.Remove());\r
- lst.FIFO = true;\r
- Assert.AreEqual(0, lst.Remove());\r
- Assert.AreEqual(2, lst.Remove());\r
- lst.FIFO = false;\r
- Assert.AreEqual(8, lst.Remove());\r
- Assert.AreEqual(6, lst.Remove());\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- lst.InsertFirst(4);\r
- lst.InsertLast(5);\r
- lst.InsertFirst(14);\r
- lst.InsertLast(15);\r
- lst.InsertFirst(24);\r
- lst.InsertLast(25);\r
- lst.InsertFirst(34);\r
- lst.InsertLast(55);\r
- Assert.IsTrue(IC.eq(lst, 34, 24, 14, 4, 5, 15, 25, 55));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirst()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- lst.Add(5);\r
- lst.ViewOf(2).InsertFirst(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 3, 4, 5));\r
- lst.ViewOf(3).InsertFirst(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 4, 5));\r
- lst.ViewOf(5).InsertFirst(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 4, 9, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void BadFirst()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- Assert.IsNull(lst.ViewOf(4));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAfter()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- lst.Add(5);\r
- lst.LastViewOf(2).InsertLast(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 7, 3, 4, 5));\r
- lst.LastViewOf(1).InsertLast(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 7, 3, 4, 5));\r
- lst.LastViewOf(5).InsertLast(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 7, 3, 4, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void BadInsertAfter()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(6);\r
- lst.Add(5);\r
- Assert.IsNull(lst.ViewOf(4));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
-\r
- IList<int> lst2 = new HashedArrayList<int>();\r
-\r
- lst2.Add(7); lst2.Add(8); lst2.Add(9);\r
- lst.InsertAll(0, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 3, 4));\r
- lst.RemoveAll(lst2);\r
- lst.InsertAll(4, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 3, 4, 7, 8, 9));\r
- lst.RemoveAll(lst2);\r
- lst.InsertAll(2, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 7, 8, 9, 3, 4));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(DuplicateNotAllowedException))]\r
- public void InsertAllBad()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
-\r
- IList<int> lst2 = new HashedArrayList<int>();\r
-\r
- lst2.Add(5); lst2.Add(2); lst2.Add(9);\r
- lst.InsertAll(0, lst2);\r
- }\r
-\r
-\r
- [Test]\r
- public void Map()\r
- {\r
- Fun<int, string> m = delegate(int i) { return "<<" + i + ">>"; };\r
- IList<string> r = lst.Map(m);\r
-\r
- Assert.IsTrue(((HashedArrayList<string>)r).Check());\r
- Assert.IsTrue(r.IsEmpty);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- r = lst.Map(m);\r
- Assert.IsTrue(((HashedArrayList<string>)r).Check());\r
- Assert.AreEqual(4, r.Count);\r
- for (int i = 0; i < 4; i++)\r
- Assert.AreEqual("<<" + (i + 1) + ">>", r[i]);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapper()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapperView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAllView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemove() { lst.Remove(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveFirst() { lst.RemoveFirst(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveLast() { lst.RemoveLast(); }\r
-\r
-\r
- [Test]\r
- public void RemoveFirstLast()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- Assert.AreEqual(1, lst.RemoveFirst());\r
- Assert.AreEqual(4, lst.RemoveLast());\r
- Assert.AreEqual(2, lst.RemoveFirst());\r
- Assert.AreEqual(3, lst.RemoveLast());\r
- Assert.IsTrue(lst.IsEmpty);\r
- }\r
-\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(0, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 0).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- lst.View(5, 1).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void BadReverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.View(8, 3).Reverse();\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private IList<KeyValuePair<int, int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new HashedArrayList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int, int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- Assert.AreEqual(4, lst[3].Key);\r
- Assert.AreEqual(34, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Sorting\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- lst.Add(5); lst.Add(6); lst.Add(55); lst.Add(7); lst.Add(3);\r
- Assert.IsFalse(lst.IsSorted(new IC()));\r
- lst.Sort(new IC());\r
- Assert.IsTrue(lst.IsSorted());\r
- Assert.IsTrue(lst.IsSorted(new IC()));\r
- Assert.IsTrue(IC.eq(lst, 3, 5, 6, 7, 55));\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace Range\r
- {\r
- [TestFixture]\r
- public class Range\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedArrayList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void GetRange()\r
- {\r
- //Assert.IsTrue(IC.eq(lst[0, 0)));\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst[0, 3], 0, 1, 2));\r
- Assert.IsTrue(IC.eq(lst[3, 3], 3, 4, 5));\r
- Assert.IsTrue(IC.eq(lst[6, 3], 6, 7, 8));\r
- Assert.IsTrue(IC.eq(lst[6, 4], 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void Backwards()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst.Backwards(), 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[0, 3].Backwards(), 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[3, 3].Backwards(), 5, 4, 3));\r
- Assert.IsTrue(IC.eq(lst[6, 4].Backwards(), 9, 8, 7, 6));\r
- }\r
-\r
-\r
- [Test]\r
- public void DirectionAndCount()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst.Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst[3, 4].Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst[3, 4].Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst.Backwards().Direction);\r
- Assert.AreEqual(4, lst[3, 4].Count);\r
- Assert.AreEqual(4, lst[3, 4].Backwards().Count);\r
- Assert.AreEqual(10, lst.Backwards().Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- foreach (int i in lst)\r
- {\r
- lst.Add(45 + i);\r
- }\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace View\r
- {\r
- [TestFixture]\r
- public class Simple\r
- {\r
- HashedArrayList<int> list;\r
- HashedArrayList<int> view;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>();\r
- list.Add(0); list.Add(1); list.Add(2); list.Add(3);\r
- view = (HashedArrayList<int>)list.View(1, 2);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = null;\r
- view = null;\r
- }\r
-\r
-\r
- void check()\r
- {\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(view.Check());\r
- }\r
-\r
- [Test]\r
- public void InsertPointer()\r
- {\r
- IList<int> view2 = list.View(2, 0);\r
- list.Insert(view2, 7);\r
- check();\r
- list.Insert(list, 8);\r
- check();\r
- view.Insert(view2, 9);\r
- check();\r
- view.Insert(list.View(3, 2), 10);\r
- check();\r
- view.Insert(list.ViewOf(0), 11);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 11, 1, 9, 7, 2, 10, 3, 8));\r
- Assert.IsTrue(IC.eq(view, 11, 1, 9, 7, 2, 10));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad1()\r
- {\r
- view.Insert(list.View(0, 0), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad2()\r
- {\r
- view.Insert(list, 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad3()\r
- {\r
- list.Insert(new ArrayList<int>(), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad4()\r
- {\r
- list.Insert(new ArrayList<int>().View(0, 0), 7);\r
- }\r
-\r
-\r
- [Test]\r
- public void Span()\r
- {\r
- IList<int> span = list.View(1, 0).Span(list.View(2, 0));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(1, span.Offset);\r
- Assert.AreEqual(1, span.Count);\r
- span = list.View(0, 2).Span(list.View(2, 2));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(0, span.Offset);\r
- Assert.AreEqual(4, span.Count);\r
- span = list.View(3, 1).Span(list.View(1, 1));\r
- Assert.IsNull(span);\r
- }\r
-\r
- [Test]\r
- public void ViewOf()\r
- {\r
- for (int i = 0; i < 4; i++)\r
- list.Add(i);\r
- IList<int> v = view.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.LastViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- }\r
-\r
- [Test]\r
- public void BadViewOf()\r
- {\r
- Assert.IsNull(view.ViewOf(5));\r
- Assert.IsNull(view.LastViewOf(5));\r
- Assert.IsNull(view.ViewOf(3));\r
- Assert.IsNull(view.LastViewOf(3));\r
- Assert.IsNull(view.ViewOf(0));\r
- Assert.IsNull(view.LastViewOf(0));\r
- }\r
-\r
-\r
- [Test]\r
- public void ArrayStuff()\r
- {\r
- Assert.IsTrue(IC.eq(view.ToArray(), 1, 2));\r
- int[] extarray = new int[5];\r
- view.CopyTo(extarray, 2);\r
- Assert.IsTrue(IC.eq(extarray, 0, 0, 1, 2, 0));\r
- }\r
-\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2));\r
- view.InsertFirst(10);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 10, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 10, 1, 2));\r
- view.Clear();\r
- Assert.IsFalse(view.IsReadOnly);\r
- Assert.IsFalse(view.AllowsDuplicates);\r
- Assert.IsTrue(view.IsEmpty);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 3));\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(8);\r
- Assert.IsFalse(view.IsEmpty);\r
- Assert.IsFalse(view.AllowsDuplicates);\r
- Assert.IsFalse(view.IsReadOnly);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 3));\r
- Assert.IsTrue(IC.eq(view, 8));\r
- view.Add(12);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12));\r
- view./*ViewOf(12).*/InsertLast(15);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12, 15));\r
- view.ViewOf(12).InsertFirst(18);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15));\r
-\r
- HashedArrayList<int> lst2 = new HashedArrayList<int>();\r
-\r
- lst2.Add(90); lst2.Add(92);\r
- view.AddAll(lst2);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92));\r
- view.InsertLast(66);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 66, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92, 66));\r
- }\r
-\r
-\r
- [Test]\r
- public void Bxxx()\r
- {\r
- Assert.IsTrue(IC.eq(view.Backwards(), 2, 1));\r
- Assert.AreSame(list, view.Underlying);\r
- Assert.IsNull(list.Underlying);\r
- Assert.AreEqual(EnumerationDirection.Forwards, view.Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, view.Backwards().Direction);\r
- Assert.AreEqual(0, list.Offset);\r
- Assert.AreEqual(1, view.Offset);\r
- }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsTrue(view.Contains(1));\r
- Assert.IsFalse(view.Contains(0));\r
-\r
- HashedArrayList<int> lst2 = new HashedArrayList<int>();\r
-\r
- lst2.Add(2);\r
- Assert.IsTrue(view.ContainsAll(lst2));\r
- lst2.Add(3);\r
- Assert.IsFalse(view.ContainsAll(lst2));\r
- Assert.AreEqual(Speed.Constant, view.ContainsSpeed);\r
- Assert.AreEqual(2, view.Count);\r
- view.Add(1);\r
- Assert.AreEqual(1, view.ContainsCount(2));\r
- Assert.AreEqual(1, view.ContainsCount(1));\r
- Assert.AreEqual(2, view.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void CreateView()\r
- {\r
- HashedArrayList<int> view2 = (HashedArrayList<int>)view.View(1, 0);\r
-\r
- Assert.AreSame(list, view2.Underlying);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- Assert.IsFalse(view.FIFO);\r
- view.FIFO = true;\r
- view.Add(23); view.Add(24); view.Add(25);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 23, 24, 25));\r
- Assert.AreEqual(1, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24, 25));\r
- view.FIFO = false;\r
- Assert.IsFalse(view.FIFO);\r
- Assert.AreEqual(25, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24));\r
- }\r
-\r
-\r
- [Test]\r
- public void MapEtc()\r
- {\r
- HashedArrayList<double> dbl = (HashedArrayList<double>)view.Map(new Fun<int, double>(delegate(int i) { return i / 10.0; }));\r
-\r
- Assert.IsTrue(dbl.Check());\r
- Assert.AreEqual(0.1, dbl[0]);\r
- Assert.AreEqual(0.2, dbl[1]);\r
- for (int i = 0; i < 10; i++) view.Add(i);\r
-\r
- HashedArrayList<int> list2 = (HashedArrayList<int>)view.FindAll(new Fun<int, bool>(delegate(int i) { return i % 4 == 1; }));\r
-\r
- Assert.IsTrue(list2.Check());\r
- Assert.IsTrue(IC.eq(list2, 1, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void FL()\r
- {\r
- Assert.AreEqual(1, view.First);\r
- Assert.AreEqual(2, view.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void Indexing()\r
- {\r
- list.Clear();\r
- for (int i = 0; i < 20; i++) list.Add(i);\r
-\r
- view = (HashedArrayList<int>)list.View(5, 7);\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i + 5, view[i]);\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.IndexOf(i + 5));\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.LastIndexOf(i + 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- view.Insert(0, 34);\r
- view.Insert(1, 35);\r
- view.Insert(4, 36);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 2, 36));\r
-\r
- IList<int> list2 = new HashedArrayList<int>();\r
-\r
- list2.Add(40); list2.Add(41);\r
- view.InsertAll(3, list2);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 40, 41, 2, 36));\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- view.Add(45); view.Add(47); view.Add(46); view.Add(48);\r
- Assert.IsFalse(view.IsSorted(new IC()));\r
- view.Sort(new IC());\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 45, 46, 47, 48, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2, 45, 46, 47, 48));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- Assert.IsFalse(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- Assert.IsFalse(view.Remove(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- view.RemoveAllCopies(3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- Assert.IsTrue(IC.eq(list, 0, 2, 5, 3));\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 2, 5, 1));\r
-\r
- HashedArrayList<int> l2 = new HashedArrayList<int>();\r
-\r
- l2.Add(1); l2.Add(2); l2.Add(2); l2.Add(3); l2.Add(1);\r
- view.RemoveAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 5));\r
- view.RetainAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(2); view.Add(4); view.Add(5);\r
- Assert.AreEqual(2, view.RemoveAt(0));\r
- Assert.AreEqual(5, view.RemoveAt(1));\r
- Assert.AreEqual(4, view.RemoveAt(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(8); view.Add(6); view.Add(78);\r
- Assert.AreEqual(8, view.RemoveFirst());\r
- Assert.AreEqual(78, view.RemoveLast());\r
- view.Add(2); view.Add(5); view.Add(3); view.Add(1);\r
- view.RemoveInterval(1, 2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 6, 1));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- view.Clear();\r
- for (int i = 0; i < 10; i++) view.Add(10 + i);\r
-\r
- view.View(3, 4).Reverse();\r
- check();\r
- Assert.IsTrue(IC.eq(view, 10, 11, 12, 16, 15, 14, 13, 17, 18, 19));\r
- view.Reverse();\r
- Assert.IsTrue(IC.eq(view, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10));\r
- Assert.IsTrue(IC.eq(list, 0, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10, 3));\r
- }\r
-\r
-\r
- [Test]\r
- public void Slide()\r
- {\r
- view.Slide(1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 3));\r
- view.Slide(-2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1));\r
- view.Slide(0, 3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1, 2));\r
- view.Slide(2, 1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2));\r
- view.Slide(-1, 0);\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(28);\r
- Assert.IsTrue(IC.eq(list, 0, 28, 1, 2, 3));\r
- }\r
- [Test]\r
- public void Iterate()\r
- {\r
- list.Clear();\r
- view = null;\r
- foreach (int i in new int[] { 2, 4, 8, 13, 6, 1, 10, 11 }) list.Add(i);\r
-\r
- view = (HashedArrayList<int>)list.View(list.Count - 2, 2);\r
- int j = 666;\r
- while (true)\r
- {\r
- //Console.WriteLine("View: {0}: {1} --> {2}", view.Count, view.First, view.Last);\r
- if ((view.Last - view.First) % 2 == 1)\r
- view.Insert(1, j++);\r
- check();\r
- if (view.Offset == 0)\r
- break;\r
- else\r
- view.Slide(-1, 2);\r
- }\r
- //foreach (int cell in list) Console.Write(" " + cell);\r
- //Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 2, 4, 8, 668, 13, 6, 1, 667, 10, 666, 11));\r
- }\r
-\r
-\r
- [Test]\r
- public void SyncRoot()\r
- {\r
- Assert.AreSame(view.SyncRoot, list.SyncRoot);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class MulipleViews\r
- {\r
- IList<int> list;\r
- IList<int>[][] views;\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedArrayList<int>();\r
- for (int i = 0; i < 6; i++)\r
- list.Add(i);\r
- views = new IList<int>[7][];\r
- for (int i = 0; i < 7; i++)\r
- {\r
- views[i] = new IList<int>[7 - i];\r
- for (int j = 0; j < 7 - i; j++)\r
- views[i][j] = list.View(i, j);\r
- }\r
- }\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = null;\r
- views = null;\r
- }\r
- [Test]\r
- public void Insert()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(3, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(3);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 3 && i + j > 3 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveInterval(3, 2);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i <= 5 ? 3 : i - 2, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j == 0 ? 0 : i <= 3 && i + j > 4 ? j - 2 : i > 4 || i + j <= 3 ? j : j - 1, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void InsertAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.InsertLast(777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(5);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 5 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 5 && i + j > 5 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void InsertAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(0, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 && j == 0 ? 0 : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(0);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i == 0 && j > 0 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void Clear()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before clear");\r
- //for (int i = 0; i < 7; i++)\r
- //for (int j = 0; j < 7 - i; j++)\r
- //Console.WriteLine("// view[{0}][{1}] : {2}", i, j, ((HashedArrayList<int>) views[i][j]).GetHashCode());\r
- views[2][3].Clear();\r
- Assert.IsTrue(list.Check(), "list check after clear");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 2 ? i : i < 6 ? 2 : i - 3, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(s(i, j), views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- private int s(int i, int j)\r
- {\r
- if (j == 0) return 0;\r
- int k = i + j - 1; //end\r
- if (i > 4 || k <= 1) return j;\r
- if (i >= 2) return k > 4 ? k - 4 : 0;\r
- if (i <= 2) return k >= 4 ? j - 3 : 2 - i;\r
- return -1;\r
- }\r
- [Test]\r
- public void InsertAll()\r
- {\r
- IList<int> list2 = new HashedArrayList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before insertAll");\r
- list.InsertAll(3, list2);\r
- Assert.IsTrue(list.Check(), "list check after insertAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- IList<int> list2 = new HashedArrayList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before AddAll");\r
- list.View(1, 2).AddAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after AddAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new HashedArrayList<int>();\r
- for (int k = 0; k < 6; k++) list.Add(k);\r
- HashedArrayList<int> v = (HashedArrayList<int>)list.View(i, j);\r
- list.Remove(3);\r
- Assert.IsTrue(list.Check(), "list check after Remove, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
- [Test]\r
- public void RemoveAll1()\r
- {\r
- IList<int> list2 = new HashedArrayList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
-\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new HashedArrayList<int>();\r
- for (int k = 0; k < 6; k++) list.Add(k);\r
- HashedArrayList<int> v = (HashedArrayList<int>)list.View(i, j);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
- [Test]\r
- public void RemoveAll2()\r
- {\r
- IList<int> list2 = new HashedArrayList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
- Assert.IsTrue(list.Check(), "list check before RemoveAll");\r
- list.RemoveAll(list2);\r
-\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(1, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(1, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(1, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(1, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(1, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(1, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(1, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(1, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(1, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(1, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(1, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(2, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(2, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(2, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(2, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(2, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(2, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(2, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(1, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(1, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(2, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(2, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(1, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(2, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(1, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(2, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(0, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(1, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(0, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(1, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll");\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- IList<int> list2 = new HashedArrayList<int>();\r
- list2.Add(2); list2.Add(4); list2.Add(5);\r
- Assert.IsTrue(list.Check(), "list check before RetainAll");\r
- list.RetainAll(list2);\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(0, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(0, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(0, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(0, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(0, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(0, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(0, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(0, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(0, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(0, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(0, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(1, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(1, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(1, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(1, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(1, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(1, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(1, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(0, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(0, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(1, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(1, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(2, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(3, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(2, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(3, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(1, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(2, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(1, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(2, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
- Assert.IsTrue(list.Check(), "list check after RetainAll");\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- IList<int> list2 = new HashedArrayList<int>();\r
- list2.Add(0); list2.Add(2); list2.Add(82); list2.Add(92); list2.Add(5); list2.Add(2); list2.Add(1);\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new HashedArrayList<int>();\r
- list.AddAll(list2);\r
- HashedArrayList<int> v = (HashedArrayList<int>)list.View(i, j);\r
- list.RemoveAllCopies(2);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAllCopies, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
-\r
- private void checkDisposed(bool reverse, int start, int count)\r
- {\r
- int k = 0;\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- if (i + j <= start || i >= start + count || (i <= start && i + j >= start + count) || (reverse && start <= i && start + count >= i + j))\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- }\r
- catch (ViewDisposedException)\r
- {\r
- Assert.Fail("view[" + i + "][" + j + "] threw");\r
- }\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] size");\r
- if (reverse && ((j > 0 && start <= i && start + count >= i + j) || (j == 0 && start < i && start + count > i)))\r
- Assert.AreEqual(start + (start + count - i - j), views[i][j].Offset, "view[" + i + "][" + j + "] offset (mirrored)");\r
- else\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- }\r
- else\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- Assert.Fail("view[" + i + "][" + j + "] no throw");\r
- }\r
- catch (ViewDisposedException) { }\r
- }\r
- }\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Reverse");\r
- list2.Reverse();\r
- Assert.IsTrue(list.Check(), "list check after Reverse");\r
- checkDisposed(true, start, count);\r
- }\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Sort");\r
- list2.Sort();\r
- Assert.IsTrue(list.Check(), "list check after Sort");\r
- checkDisposed(false, start, count);\r
- }\r
- [Test]\r
- public void Shuffle()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Shuffle");\r
- list2.Shuffle();\r
- Assert.IsTrue(list.Check(), "list check after Shuffle");\r
- checkDisposed(false, start, count);\r
- }\r
-\r
-\r
- }\r
-\r
- }\r
-\r
- namespace HashingAndEquals\r
- {\r
- [TestFixture]\r
- public class IIndexed\r
- {\r
- private ISequenced<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- dat = new HashedArrayList<int>();\r
- dut = new HashedArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- }\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.sequencedhashcode(), dit.GetSequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dit.GetSequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(3, 7), dit.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.sequencedhashcode(), dut.GetSequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(7), dut.GetSequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(7, 3), dut.GetSequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(0); dit.Add(31);\r
- dat.Add(1); dat.Add(0);\r
- Assert.AreEqual(dit.GetSequencedHashCode(), dat.GetSequencedHashCode());\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dat.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dut));\r
- Assert.IsTrue(dut.SequencedEquals(dit));\r
- dit.Add(7);\r
- ((HashedArrayList<int>)dut).InsertFirst(7);\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- Assert.IsFalse(dut.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- dat = new HashedArrayList<int>();\r
- dut = new HashedArrayList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(-1657792980); dit.Add(-1570288808);\r
- dat.Add(1862883298); dat.Add(-272461342);\r
- Assert.AreEqual(dit.GetUnsequencedHashCode(), dat.GetUnsequencedHashCode());\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnorderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ICollection<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- dat = new HashedArrayList<int>();\r
- dut = new HashedArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new HashedArrayList<ICollection<int>>();\r
- Dat = new HashedArrayList<ICollection<int>>();\r
- Dut = new HashedArrayList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dat));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ISequenced<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- dat = new HashedArrayList<int>();\r
- dut = new HashedArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new HashedArrayList<ICollection<int>>();\r
- Dat = new HashedArrayList<ICollection<int>>();\r
- Dut = new HashedArrayList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dit); Dut.Add(dut); Dut.Add(dat);\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ICollection<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- dat = new HashedArrayList<int>();\r
- dut = new HashedArrayList<int>();\r
- dot = new HashedArrayList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- dot.Add(2); dot.Add(1);\r
- Dit = new HashedArrayList<ISequenced<int>>();\r
- Dat = new HashedArrayList<ISequenced<int>>();\r
- Dut = new HashedArrayList<ISequenced<int>>();\r
- Dot = new HashedArrayList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dut));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dat));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ISequenced<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedArrayList<int>();\r
- dat = new HashedArrayList<int>();\r
- dut = new HashedArrayList<int>();\r
- dot = new HashedArrayList<int>();\r
- dit.Add(2); dit.Add(1); //{2,1}\r
- dat.Add(1); dat.Add(2); //{1,2}\r
- dut.Add(3); //{3}\r
- dot.Add(2); dot.Add(1); //{2,1}\r
- Dit = new HashedArrayList<ISequenced<int>>();\r
- Dat = new HashedArrayList<ISequenced<int>>();\r
- Dut = new HashedArrayList<ISequenced<int>>();\r
- Dot = new HashedArrayList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit); // {{2,1},{3}}\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat); // {{3},{2,1},{1,2}}\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit); // {{2,1},{3}}\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut); // {{2,1},{3}}\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.arrays.sorted\r
-{\r
- using CollectionOfInt = SortedArray<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.SortedIndexedTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new SortedArray<T>(); }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{ }", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("{ -4, 28, 129, 65530 }", coll.ToString());\r
- Assert.AreEqual("{ -4, 1C, 81, FFFA }", coll.ToString(null, rad16));\r
- Assert.AreEqual("{ -4, 28, 129... }", coll.ToString("L14", null));\r
- Assert.AreEqual("{ -4, 1C, 81... }", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Ranges\r
- {\r
- private SortedArray<int> array;\r
-\r
- private SCG.IComparer<int> c;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- c = new IC();\r
- array = new SortedArray<int>(c);\r
- for (int i = 1; i <= 10; i++)\r
- {\r
- array.Add(i * 2);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Enumerator()\r
- {\r
- SCG.IEnumerator<int> e = array.RangeFromTo(5, 17).GetEnumerator();\r
- int i = 3;\r
-\r
- while (e.MoveNext())\r
- {\r
- Assert.AreEqual(2 * i++, e.Current);\r
- }\r
-\r
- Assert.AreEqual(9, i);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void Enumerator3()\r
- {\r
- SCG.IEnumerator<int> e = array.RangeFromTo(5, 17).GetEnumerator();\r
-\r
- e.MoveNext();\r
- array.Add(67);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- int[] all = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };\r
-\r
- array.RemoveRangeFrom(18);\r
- Assert.IsTrue(IC.eq(array, new int[] { 2, 4, 6, 8, 10, 12, 14, 16 }));\r
- array.RemoveRangeFrom(28);\r
- Assert.IsTrue(IC.eq(array, new int[] { 2, 4, 6, 8, 10, 12, 14, 16 }));\r
- array.RemoveRangeFrom(13);\r
- Assert.IsTrue(IC.eq(array, new int[] { 2, 4, 6, 8, 10, 12 }));\r
- array.RemoveRangeFrom(2);\r
- Assert.IsTrue(IC.eq(array));\r
- foreach (int i in all) array.Add(i);\r
-\r
- array.RemoveRangeTo(10);\r
- Assert.IsTrue(IC.eq(array, new int[] { 10, 12, 14, 16, 18, 20 }));\r
- array.RemoveRangeTo(2);\r
- Assert.IsTrue(IC.eq(array, new int[] { 10, 12, 14, 16, 18, 20 }));\r
- array.RemoveRangeTo(21);\r
- Assert.IsTrue(IC.eq(array));\r
- foreach (int i in all) array.Add(i);\r
-\r
- array.RemoveRangeFromTo(4, 8);\r
- Assert.IsTrue(IC.eq(array, 2, 8, 10, 12, 14, 16, 18, 20));\r
- array.RemoveRangeFromTo(14, 28);\r
- Assert.IsTrue(IC.eq(array, 2, 8, 10, 12));\r
- array.RemoveRangeFromTo(0, 9);\r
- Assert.IsTrue(IC.eq(array, 10, 12));\r
- array.RemoveRangeFromTo(0, 81);\r
- Assert.IsTrue(IC.eq(array));\r
- }\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- int[] all = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };\r
-\r
- Assert.IsTrue(IC.eq(array, all));\r
- Assert.IsTrue(IC.eq(array.RangeAll(), all));\r
- Assert.AreEqual(10, array.RangeAll().Count);\r
- Assert.IsTrue(IC.eq(array.RangeFrom(11), new int[] { 12, 14, 16, 18, 20 }));\r
- Assert.AreEqual(5, array.RangeFrom(11).Count);\r
- Assert.IsTrue(IC.eq(array.RangeFrom(12), new int[] { 12, 14, 16, 18, 20 }));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(2), all));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(1), all));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(21), new int[] { }));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(20), new int[] { 20 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(8), new int[] { 2, 4, 6 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(7), new int[] { 2, 4, 6 }));\r
- Assert.AreEqual(3, array.RangeTo(7).Count);\r
- Assert.IsTrue(IC.eq(array.RangeTo(2), new int[] { }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(1), new int[] { }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(3), new int[] { 2 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(20), new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(21), all));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(7, 12), new int[] { 8, 10 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(6, 11), new int[] { 6, 8, 10 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(1, 12), new int[] { 2, 4, 6, 8, 10 }));\r
- Assert.AreEqual(5, array.RangeFromTo(1, 12).Count);\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(2, 12), new int[] { 2, 4, 6, 8, 10 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(6, 21), new int[] { 6, 8, 10, 12, 14, 16, 18, 20 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(6, 20), new int[] { 6, 8, 10, 12, 14, 16, 18 }));\r
- }\r
-\r
-\r
- [Test]\r
- public void Backwards()\r
- {\r
- int[] all = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };\r
- int[] lla = new int[] { 20, 18, 16, 14, 12, 10, 8, 6, 4, 2 };\r
-\r
- Assert.IsTrue(IC.eq(array, all));\r
- Assert.IsTrue(IC.eq(array.RangeAll().Backwards(), lla));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(11).Backwards(), new int[] { 20, 18, 16, 14, 12 }));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(12).Backwards(), new int[] { 20, 18, 16, 14, 12 }));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(2).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(1).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(21).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(array.RangeFrom(20).Backwards(), new int[] { 20 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(8).Backwards(), new int[] { 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(7).Backwards(), new int[] { 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(2).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(1).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(3).Backwards(), new int[] { 2 }));\r
- Assert.IsTrue(IC.eq(array.RangeTo(20).Backwards(), new int[] { 18, 16, 14, 12, 10, 8, 6, 4, 2}));\r
- Assert.IsTrue(IC.eq(array.RangeTo(21).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(7, 12).Backwards(), new int[] { 10, 8 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(6, 11).Backwards(), new int[] { 10, 8, 6 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(1, 12).Backwards(), new int[] { 10, 8, 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(2, 12).Backwards(), new int[] { 10, 8, 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(6, 21).Backwards(), new int[] { 20, 18, 16, 14, 12, 10, 8, 6 }));\r
- Assert.IsTrue(IC.eq(array.RangeFromTo(6, 20).Backwards(), new int[] { 18, 16, 14, 12, 10, 8, 6 }));\r
- }\r
-\r
- [Test]\r
- public void Direction()\r
- {\r
- Assert.AreEqual(EnumerationDirection.Forwards, array.Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, array.RangeFrom(20).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, array.RangeTo(7).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, array.RangeFromTo(1, 12).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, array.RangeAll().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, array.Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, array.RangeFrom(20).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, array.RangeTo(7).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, array.RangeFromTo(1, 12).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, array.RangeAll().Backwards().Direction);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- array = null;\r
- c = null;\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class BagItf\r
- {\r
- private SortedArray<int> array;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- array = new SortedArray<int>(new IC());\r
- for (int i = 10; i < 20; i++)\r
- {\r
- array.Add(i);\r
- array.Add(i + 10);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Both()\r
- {\r
- Assert.AreEqual(0, array.ContainsCount(7));\r
- Assert.AreEqual(1, array.ContainsCount(10));\r
- array.RemoveAllCopies(10);\r
- Assert.AreEqual(0, array.ContainsCount(10));\r
- array.RemoveAllCopies(7);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- array = null;\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Div\r
- {\r
- private SortedArray<int> array;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- array = new SortedArray<int>(new IC());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new SortedArray<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor2()\r
- {\r
- new SortedArray<int>(5, null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor3()\r
- {\r
- new SortedArray<int>(5, null, EqualityComparer<int>.Default);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor4()\r
- {\r
- new SortedArray<int>(5, Comparer<int>.Default, null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor5()\r
- {\r
- new SortedArray<int>(5, null, null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- array.Add(7);\r
- Assert.AreEqual(7, array.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- array.Choose();\r
- }\r
-\r
-\r
-\r
- private void loadup()\r
- {\r
- for (int i = 10; i < 20; i++)\r
- {\r
- array.Add(i);\r
- array.Add(i + 10);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void NoDuplicatesEtc()\r
- {\r
- Assert.IsFalse(array.AllowsDuplicates);\r
- loadup();\r
- Assert.IsFalse(array.AllowsDuplicates);\r
- Assert.AreEqual(Speed.Log, array.ContainsSpeed);\r
- Assert.IsTrue(array.Comparer.Compare(2, 3) < 0);\r
- Assert.IsTrue(array.Comparer.Compare(4, 3) > 0);\r
- Assert.IsTrue(array.Comparer.Compare(3, 3) == 0);\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- Assert.IsTrue(array.Add(17));\r
- Assert.IsFalse(array.Add(17));\r
- Assert.IsTrue(array.Add(18));\r
- Assert.IsFalse(array.Add(18));\r
- Assert.AreEqual(2, array.Count);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- array = null;\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class FindOrAdd\r
- {\r
- private SortedArray<KeyValuePair<int,string>> bag;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- bag = new SortedArray<KeyValuePair<int,string>>(new KeyValuePairComparer<int,string>(new IC()));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- bag = null;\r
- }\r
-\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- KeyValuePair<int,string> p = new KeyValuePair<int,string>(3, "tre");\r
-\r
- Assert.IsFalse(bag.FindOrAdd(ref p));\r
- p.Value = "drei";\r
- Assert.IsTrue(bag.FindOrAdd(ref p));\r
- Assert.AreEqual("tre", p.Value);\r
- p.Value = "three";\r
- Assert.AreEqual(1, bag.ContainsCount(p));\r
- Assert.AreEqual("tre", bag[0].Value);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private SortedArray<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new SortedArray<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- [Test]\r
- public void FindLast()\r
- {\r
- int i;\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.FindLast(pred, out i));\r
- Assert.AreEqual(675, i);\r
- }\r
-\r
- [Test]\r
- public void FindIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(3, list.FindIndex(pred));\r
- }\r
-\r
- [Test]\r
- public void FindLastIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(7, list.FindLastIndex(pred));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private SortedArray<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new SortedArray<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 1, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private SortedArray<int> tree;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new SortedArray<int>(new IC());\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(tree.ToArray()));\r
- tree.Add(7);\r
- tree.Add(4);\r
- Assert.AreEqual("Alles klar", aeq(tree.ToArray(), 4, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- tree.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- tree.Add(6);\r
- tree.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- tree.Add(4);\r
- tree.Add(9);\r
- tree.CopyTo(a, 4);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 4, 6, 9, 1007, 1008, 1009));\r
- tree.Clear();\r
- tree.Add(7);\r
- tree.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 4, 6, 9, 1007, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- tree.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- tree.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- tree.Add(3);\r
- tree.Add(4);\r
- tree.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private IIndexedSorted<KeyValuePair<int,int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new SortedArray<KeyValuePair<int,int>>(new KeyValuePairComparer<int,int>(new IC()));\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int,int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int,int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int,int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- Assert.AreEqual(4, lst[3].Key);\r
- Assert.AreEqual(34, lst[3].Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Remove\r
- {\r
- private SortedArray<int> array;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- array = new SortedArray<int>(new IC());\r
- for (int i = 10; i < 20; i++)\r
- {\r
- array.Add(i);\r
- array.Add(i + 10);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void SmallTrees()\r
- {\r
- array.Clear();\r
- array.Add(7);\r
- array.Add(9);\r
- Assert.IsTrue(array.Remove(7));\r
- Assert.IsTrue(array.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void ByIndex()\r
- {\r
- //Remove root!\r
- int n = array.Count;\r
- int i = array[10];\r
-\r
- array.RemoveAt(10);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsFalse(array.Contains(i));\r
- Assert.AreEqual(n - 1, array.Count);\r
-\r
- //Low end\r
- i = array.FindMin();\r
- array.RemoveAt(0);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsFalse(array.Contains(i));\r
- Assert.AreEqual(n - 2, array.Count);\r
-\r
- //high end\r
- i = array.FindMax();\r
- array.RemoveAt(array.Count - 1);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsFalse(array.Contains(i));\r
- Assert.AreEqual(n - 3, array.Count);\r
-\r
- //Some leaf\r
- i = 18;\r
- array.RemoveAt(7);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsFalse(array.Contains(i));\r
- Assert.AreEqual(n - 4, array.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AlmostEmpty()\r
- {\r
- //Almost empty\r
- array.Clear();\r
- array.Add(3);\r
- array.RemoveAt(0);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsFalse(array.Contains(3));\r
- Assert.AreEqual(0, array.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void Empty()\r
- {\r
- array.Clear();\r
- array.RemoveAt(0);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void HighIndex()\r
- {\r
- array.RemoveAt(array.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void LowIndex()\r
- {\r
- array.RemoveAt(-1);\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- Assert.IsFalse(array.Remove(-20));\r
-\r
- //No demote case, with move_item\r
- Assert.IsTrue(array.Remove(20));\r
- Assert.IsTrue(array.Check());\r
- Assert.IsFalse(array.Remove(20));\r
-\r
- //plain case 2\r
- Assert.IsTrue(array.Remove(14));\r
- Assert.IsTrue(array.Check(), "Bad tree");\r
-\r
- //case 1b\r
- Assert.IsTrue(array.Remove(25));\r
- Assert.IsTrue(array.Check(), "Bad tree");\r
-\r
- //case 1c\r
- Assert.IsTrue(array.Remove(29));\r
- Assert.IsTrue(array.Check(), "Bad tree");\r
-\r
- //1a (terminating)\r
- Assert.IsTrue(array.Remove(10));\r
- Assert.IsTrue(array.Check(), "Bad tree");\r
-\r
- //2+1b\r
- Assert.IsTrue(array.Remove(12));\r
- Assert.IsTrue(array.Remove(11));\r
-\r
- //1a+1b\r
- Assert.IsTrue(array.Remove(18));\r
- Assert.IsTrue(array.Remove(13));\r
- Assert.IsTrue(array.Remove(15));\r
-\r
- //2+1c\r
- for (int i = 0; i < 10; i++)\r
- array.Add(50 - 2 * i);\r
-\r
- Assert.IsTrue(array.Remove(42));\r
- Assert.IsTrue(array.Remove(38));\r
- Assert.IsTrue(array.Remove(28));\r
- Assert.IsTrue(array.Remove(40));\r
-\r
- //\r
- Assert.IsTrue(array.Remove(16));\r
- Assert.IsTrue(array.Remove(23));\r
- Assert.IsTrue(array.Remove(17));\r
- Assert.IsTrue(array.Remove(19));\r
- Assert.IsTrue(array.Remove(50));\r
- Assert.IsTrue(array.Remove(26));\r
- Assert.IsTrue(array.Remove(21));\r
- Assert.IsTrue(array.Remove(22));\r
- Assert.IsTrue(array.Remove(24));\r
- for (int i = 0; i < 48; i++)\r
- array.Remove(i);\r
-\r
- //Almost empty tree:\r
- Assert.IsFalse(array.Remove(26));\r
- Assert.IsTrue(array.Remove(48));\r
- Assert.IsTrue(array.Check(), "Bad tree");\r
-\r
- //Empty tree:\r
- Assert.IsFalse(array.Remove(26));\r
- Assert.IsTrue(array.Check(), "Bad tree");\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- array = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class PredecessorStructure\r
- {\r
- private SortedArray<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new SortedArray<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- for (int i = 0; i < 20; i++)\r
- tree.Add(2 * i);\r
- }\r
-\r
-\r
- [Test]\r
- public void Predecessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.Predecessor(7));\r
- Assert.AreEqual(6, tree.Predecessor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.Predecessor(1));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.Predecessor(39));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PredecessorTooLow1()\r
- {\r
- tree.Predecessor(-2);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PredecessorTooLow2()\r
- {\r
- tree.Predecessor(0);\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakPredecessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.WeakPredecessor(7));\r
- Assert.AreEqual(8, tree.WeakPredecessor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.WeakPredecessor(1));\r
- Assert.AreEqual(0, tree.WeakPredecessor(0));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.WeakPredecessor(39));\r
- Assert.AreEqual(38, tree.WeakPredecessor(38));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void WeakPredecessorTooLow1()\r
- {\r
- tree.WeakPredecessor(-1);\r
- }\r
-\r
-\r
- [Test]\r
- public void Successor()\r
- {\r
- loadup();\r
- Assert.AreEqual(8, tree.Successor(7));\r
- Assert.AreEqual(10, tree.Successor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(2, tree.Successor(0));\r
- Assert.AreEqual(0, tree.Successor(-1));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.Successor(37));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void SuccessorTooHigh1()\r
- {\r
- tree.Successor(38);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void SuccessorTooHigh2()\r
- {\r
- tree.Successor(39);\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakSuccessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.WeakSuccessor(6));\r
- Assert.AreEqual(8, tree.WeakSuccessor(7));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.WeakSuccessor(-1));\r
- Assert.AreEqual(0, tree.WeakSuccessor(0));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.WeakSuccessor(37));\r
- Assert.AreEqual(38, tree.WeakSuccessor(38));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void WeakSuccessorTooHigh1()\r
- {\r
- tree.WeakSuccessor(39);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class PriorityQueue\r
- {\r
- private SortedArray<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new SortedArray<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- foreach (int i in new int[] { 1, 2, 3, 4 })\r
- tree.Add(i);\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- loadup();\r
- Assert.AreEqual(1, tree.FindMin());\r
- Assert.AreEqual(4, tree.FindMax());\r
- Assert.AreEqual(1, tree.DeleteMin());\r
- Assert.AreEqual(4, tree.DeleteMax());\r
- Assert.IsTrue(tree.Check(), "Bad tree");\r
- Assert.AreEqual(2, tree.FindMin());\r
- Assert.AreEqual(3, tree.FindMax());\r
- Assert.AreEqual(2, tree.DeleteMin());\r
- Assert.AreEqual(3, tree.DeleteMax());\r
- Assert.IsTrue(tree.Check(), "Bad tree");\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty1()\r
- {\r
- tree.FindMin();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty2()\r
- {\r
- tree.FindMax();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty3()\r
- {\r
- tree.DeleteMin();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty4()\r
- {\r
- tree.DeleteMax();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IndexingAndCounting\r
- {\r
- private SortedArray<int> array;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- array = new SortedArray<int>(new IC());\r
- }\r
-\r
-\r
- private void populate()\r
- {\r
- array.Add(30);\r
- array.Add(50);\r
- array.Add(10);\r
- array.Add(70);\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- populate();\r
-\r
- int[] a = array.ToArray();\r
-\r
- Assert.AreEqual(4, a.Length);\r
- Assert.AreEqual(10, a[0]);\r
- Assert.AreEqual(30, a[1]);\r
- Assert.AreEqual(50, a[2]);\r
- Assert.AreEqual(70, a[3]);\r
- }\r
-\r
-\r
- [Test]\r
- public void GoodIndex()\r
- {\r
- Assert.AreEqual(~0, array.IndexOf(20));\r
- Assert.AreEqual(~0, array.LastIndexOf(20));\r
- populate();\r
- Assert.AreEqual(10, array[0]);\r
- Assert.AreEqual(30, array[1]);\r
- Assert.AreEqual(50, array[2]);\r
- Assert.AreEqual(70, array[3]);\r
- Assert.AreEqual(0, array.IndexOf(10));\r
- Assert.AreEqual(1, array.IndexOf(30));\r
- Assert.AreEqual(2, array.IndexOf(50));\r
- Assert.AreEqual(3, array.IndexOf(70));\r
- Assert.AreEqual(~1, array.IndexOf(20));\r
- Assert.AreEqual(~0, array.IndexOf(0));\r
- Assert.AreEqual(~4, array.IndexOf(90));\r
- Assert.AreEqual(0, array.LastIndexOf(10));\r
- Assert.AreEqual(1, array.LastIndexOf(30));\r
- Assert.AreEqual(2, array.LastIndexOf(50));\r
- Assert.AreEqual(3, array.LastIndexOf(70));\r
- Assert.AreEqual(~1, array.LastIndexOf(20));\r
- Assert.AreEqual(~0, array.LastIndexOf(0));\r
- Assert.AreEqual(~4, array.LastIndexOf(90));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void IndexTooLarge()\r
- {\r
- populate();\r
- Console.WriteLine(array[4]);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void IndexTooSmall()\r
- {\r
- populate();\r
- Console.WriteLine(array[-1]);\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeOutsideInput()\r
- {\r
- populate();\r
- Assert.AreEqual(0, array.CountFrom(90));\r
- Assert.AreEqual(0, array.CountFromTo(-20, 0));\r
- Assert.AreEqual(0, array.CountFromTo(80, 100));\r
- Assert.AreEqual(0, array.CountTo(0));\r
- Assert.AreEqual(4, array.CountTo(90));\r
- Assert.AreEqual(4, array.CountFromTo(-20, 90));\r
- Assert.AreEqual(4, array.CountFrom(0));\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeIntermediateInput()\r
- {\r
- populate();\r
- Assert.AreEqual(3, array.CountFrom(20));\r
- Assert.AreEqual(1, array.CountFromTo(20, 40));\r
- Assert.AreEqual(2, array.CountTo(40));\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeMatchingInput()\r
- {\r
- populate();\r
- Assert.AreEqual(3, array.CountFrom(30));\r
- Assert.AreEqual(2, array.CountFromTo(30, 70));\r
- Assert.AreEqual(0, array.CountFromTo(50, 30));\r
- Assert.AreEqual(0, array.CountFromTo(50, 50));\r
- Assert.AreEqual(0, array.CountTo(10));\r
- Assert.AreEqual(2, array.CountTo(50));\r
- }\r
-\r
-\r
- [Test]\r
- public void CountEmptyTree()\r
- {\r
- Assert.AreEqual(0, array.CountFrom(20));\r
- Assert.AreEqual(0, array.CountFromTo(20, 40));\r
- Assert.AreEqual(0, array.CountTo(40));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- array = null;\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace ModificationCheck\r
- {\r
- [TestFixture]\r
- public class Enumerator\r
- {\r
- private SortedArray<int> tree;\r
-\r
- private SCG.IEnumerator<int> e;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new SortedArray<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- e = tree.GetEnumerator();\r
- }\r
-\r
-\r
- [Test]\r
- public void CurrentAfterModification()\r
- {\r
- e.MoveNext();\r
- tree.Add(34);\r
- Assert.AreEqual(0, e.Current);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterAdd()\r
- {\r
- e.MoveNext();\r
- tree.Add(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterRemove()\r
- {\r
- e.MoveNext();\r
- tree.Remove(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterClear()\r
- {\r
- e.MoveNext();\r
- tree.Clear();\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- e = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class RangeEnumerator\r
- {\r
- private SortedArray<int> tree;\r
-\r
- private SCG.IEnumerator<int> e;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new SortedArray<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- e = tree.RangeFromTo(3, 7).GetEnumerator();\r
- }\r
-\r
-\r
- [Test]\r
- public void CurrentAfterModification()\r
- {\r
- e.MoveNext();\r
- tree.Add(34);\r
- Assert.AreEqual(3, e.Current);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterAdd()\r
- {\r
- tree.Add(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterRemove()\r
- {\r
- tree.Remove(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterClear()\r
- {\r
- tree.Clear();\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- e = null;\r
- }\r
- }\r
- }\r
-\r
- namespace HigherOrder\r
- {\r
- internal class CubeRoot: IComparable<int>\r
- {\r
- private int c;\r
-\r
-\r
- internal CubeRoot(int c) { this.c = c; }\r
-\r
-\r
- public int CompareTo(int that) { return c - that * that * that; }\r
-\r
- public bool Equals(int that) { return c == that * that * that; }\r
-\r
- }\r
-\r
-\r
-\r
- class Interval: IComparable<int>\r
- {\r
- private int b, t;\r
-\r
-\r
- internal Interval(int b, int t) { this.b = b; this.t = t; }\r
-\r
-\r
- public int CompareTo(int that) { return that < b ? 1 : that > t ? -1 : 0; }\r
-\r
- public bool Equals(int that) { return that >= b && that <= t; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Simple\r
- {\r
- private SortedArray<int> array;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- array = new SortedArray<int>(ic);\r
- }\r
-\r
-\r
- private bool never(int i) { return false; }\r
-\r
-\r
- private bool always(int i) { return true; }\r
-\r
-\r
- private bool even(int i) { return i % 2 == 0; }\r
-\r
-\r
- private string themap(int i) { return String.Format("AA {0,4} BB", i); }\r
-\r
-\r
- private string badmap(int i) { return String.Format("AA {0} BB", i); }\r
-\r
-\r
- private int appfield1;\r
-\r
- private int appfield2;\r
-\r
-\r
- private void apply(int i) { appfield1++; appfield2 += i * i; }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- Simple simple1 = new Simple();\r
-\r
- array.Apply(new Act<int>(simple1.apply));\r
- Assert.AreEqual(0, simple1.appfield1);\r
- Assert.AreEqual(0, simple1.appfield2);\r
-\r
- Simple simple2 = new Simple();\r
-\r
- for (int i = 0; i < 10; i++) array.Add(i);\r
-\r
- array.Apply(new Act<int>(simple2.apply));\r
- Assert.AreEqual(10, simple2.appfield1);\r
- Assert.AreEqual(285, simple2.appfield2);\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(array.All(new Fun<int, bool>(never)));\r
- Assert.IsTrue(array.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(array.All(new Fun<int, bool>(always)));\r
- for (int i = 0; i < 10; i++) array.Add(i);\r
-\r
- Assert.IsFalse(array.All(new Fun<int, bool>(never)));\r
- Assert.IsFalse(array.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(array.All(new Fun<int, bool>(always)));\r
- array.Clear();\r
- for (int i = 0; i < 10; i++) array.Add(i * 2);\r
-\r
- Assert.IsFalse(array.All(new Fun<int, bool>(never)));\r
- Assert.IsTrue(array.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(array.All(new Fun<int, bool>(always)));\r
- array.Clear();\r
- for (int i = 0; i < 10; i++) array.Add(i * 2 + 1);\r
-\r
- Assert.IsFalse(array.All(new Fun<int, bool>(never)));\r
- Assert.IsFalse(array.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(array.All(new Fun<int, bool>(always)));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(array.Exists(new Fun<int, bool>(never)));\r
- Assert.IsFalse(array.Exists(new Fun<int, bool>(even)));\r
- Assert.IsFalse(array.Exists(new Fun<int, bool>(always)));\r
- for (int i = 0; i < 10; i++) array.Add(i);\r
-\r
- Assert.IsFalse(array.Exists(new Fun<int, bool>(never)));\r
- Assert.IsTrue(array.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(array.Exists(new Fun<int, bool>(always)));\r
- array.Clear();\r
- for (int i = 0; i < 10; i++) array.Add(i * 2);\r
-\r
- Assert.IsFalse(array.Exists(new Fun<int, bool>(never)));\r
- Assert.IsTrue(array.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(array.Exists(new Fun<int, bool>(always)));\r
- array.Clear();\r
- for (int i = 0; i < 10; i++) array.Add(i * 2 + 1);\r
-\r
- Assert.IsFalse(array.Exists(new Fun<int, bool>(never)));\r
- Assert.IsFalse(array.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(array.Exists(new Fun<int, bool>(always)));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindAll()\r
- {\r
- Assert.AreEqual(0, array.FindAll(new Fun<int, bool>(never)).Count);\r
- for (int i = 0; i < 10; i++)\r
- array.Add(i);\r
-\r
- Assert.AreEqual(0, array.FindAll(new Fun<int, bool>(never)).Count);\r
- Assert.AreEqual(10, array.FindAll(new Fun<int, bool>(always)).Count);\r
- Assert.AreEqual(5, array.FindAll(new Fun<int, bool>(even)).Count);\r
- Assert.IsTrue(((SortedArray<int>)array.FindAll(new Fun<int, bool>(even))).Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void Map()\r
- {\r
- Assert.AreEqual(0, array.Map(new Fun<int,string>(themap), new SC()).Count);\r
- for (int i = 0; i < 11; i++)\r
- array.Add(i * i * i);\r
-\r
- IIndexedSorted<string> res = array.Map(new Fun<int,string>(themap), new SC());\r
-\r
- Assert.IsTrue(((SortedArray<string>)res).Check());\r
- Assert.AreEqual(11, res.Count);\r
- Assert.AreEqual("AA 0 BB", res[0]);\r
- Assert.AreEqual("AA 27 BB", res[3]);\r
- Assert.AreEqual("AA 125 BB", res[5]);\r
- Assert.AreEqual("AA 1000 BB", res[10]);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentException), "mapper not monotonic")]\r
- public void BadMap()\r
- {\r
- for (int i = 0; i < 11; i++)\r
- array.Add(i * i * i);\r
-\r
- ISorted<string> res = array.Map(new Fun<int,string>(badmap), new SC());\r
- }\r
-\r
-\r
- [Test]\r
- public void Cut()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- array.Add(i);\r
-\r
- int low, high;\r
- bool lval, hval;\r
-\r
- Assert.IsTrue(array.Cut(new CubeRoot(27), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(2, low);\r
- Assert.IsFalse(array.Cut(new CubeRoot(30), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(3, low);\r
- }\r
-\r
-\r
- [Test]\r
- public void CutInt()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- array.Add(2 * i);\r
-\r
- int low, high;\r
- bool lval, hval;\r
-\r
- Assert.IsFalse(array.Cut(new IC(3), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(2, low);\r
- Assert.IsTrue(array.Cut(new IC(6), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(8, high);\r
- Assert.AreEqual(4, low);\r
- }\r
-\r
-\r
- [Test]\r
- public void CutInterval()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- array.Add(2 * i);\r
-\r
- int lo, hi;\r
- bool lv, hv;\r
-\r
- Assert.IsTrue(array.Cut(new Interval(5, 9), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(10, hi);\r
- Assert.AreEqual(4, lo);\r
- Assert.IsTrue(array.Cut(new Interval(6, 10), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(12, hi);\r
- Assert.AreEqual(4, lo);\r
- for (int i = 0; i < 100; i++)\r
- array.Add(2 * i);\r
-\r
- array.Cut(new Interval(77, 105), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(106, hi);\r
- Assert.AreEqual(76, lo);\r
- array.Cut(new Interval(5, 7), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(8, hi);\r
- Assert.AreEqual(4, lo);\r
- array.Cut(new Interval(80, 110), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(112, hi);\r
- Assert.AreEqual(78, lo);\r
- }\r
-\r
-\r
- [Test]\r
- public void UpperCut()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- array.Add(i);\r
-\r
- int l, h;\r
- bool lv, hv;\r
-\r
- Assert.IsFalse(array.Cut(new CubeRoot(1000), out l, out lv, out h, out hv));\r
- Assert.IsTrue(lv && !hv);\r
- Assert.AreEqual(9, l);\r
- Assert.IsFalse(array.Cut(new CubeRoot(-50), out l, out lv, out h, out hv));\r
- Assert.IsTrue(!lv && hv);\r
- Assert.AreEqual(0, h);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { ic = null; array = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace MultiOps\r
- {\r
- [TestFixture]\r
- public class AddAll\r
- {\r
- private int sqr(int i) { return i * i; }\r
-\r
-\r
- SortedArray<int> array;\r
-\r
-\r
- [SetUp]\r
- public void Init() { array = new SortedArray<int>(new IC()); }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- array.AddAll(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(0, array.Count);\r
- Assert.IsTrue(array.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeEmpty()\r
- {\r
- for (int i = 4; i < 9; i++) array.Add(i);\r
-\r
- array.AddAll(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(5, array.Count);\r
- Assert.IsTrue(array.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptySome()\r
- {\r
- array.AddAll(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(4, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.AreEqual(0, array[0]);\r
- Assert.AreEqual(1, array[1]);\r
- Assert.AreEqual(4, array[2]);\r
- Assert.AreEqual(9, array[3]);\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeSome()\r
- {\r
- for (int i = 3; i < 9; i++) array.Add(i);\r
-\r
- array.AddAll(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(9, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 0, 1, 3,4, 5, 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { array = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class AddSorted\r
- {\r
- private int sqr(int i) { return i * i; }\r
-\r
-\r
- private int bad(int i) { return i * (5 - i); }\r
-\r
-\r
- SortedArray<int> array;\r
-\r
-\r
- [SetUp]\r
- public void Init() { array = new SortedArray<int>(new IC()); }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- array.AddSorted(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(0, array.Count);\r
- Assert.IsTrue(array.Check());\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void SomeEmpty()\r
- {\r
- for (int i = 4; i < 9; i++) array.Add(i);\r
-\r
- array.AddSorted(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(5, array.Count);\r
- Assert.IsTrue(array.Check());\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void EmptySome()\r
- {\r
- array.AddSorted(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(4, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.AreEqual(0, array[0]);\r
- Assert.AreEqual(1, array[1]);\r
- Assert.AreEqual(4, array[2]);\r
- Assert.AreEqual(9, array[3]);\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void SomeSome()\r
- {\r
- for (int i = 3; i < 9; i++) array.Add(i);\r
-\r
- array.AddSorted(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(9, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 0, 1, 3, 4, 5, 6, 7, 8, 9));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentException), "Argument not sorted")]\r
- public void EmptyBad()\r
- {\r
- array.AddSorted(new FunEnumerable(9, new Fun<int,int>(bad)));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { array = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class Rest\r
- {\r
- SortedArray<int> array, array2;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- array = new SortedArray<int>(new IC());\r
- array2 = new SortedArray<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- array.Add(i);\r
-\r
- for (int i = 0; i < 10; i++)\r
- array2.Add(2 * i);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- array.RemoveAll(array2.RangeFromTo(3, 7));\r
- Assert.AreEqual(8, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 0, 1, 2, 3, 5, 7, 8, 9));\r
- array.RemoveAll(array2.RangeFromTo(3, 7));\r
- Assert.AreEqual(8, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 0, 1, 2, 3, 5, 7, 8, 9));\r
- array.RemoveAll(array2.RangeFromTo(13, 17));\r
- Assert.AreEqual(8, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 0, 1, 2, 3, 5, 7, 8, 9));\r
- array.RemoveAll(array2.RangeFromTo(3, 17));\r
- Assert.AreEqual(7, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 0, 1, 2, 3, 5, 7, 9));\r
- for (int i = 0; i < 10; i++) array2.Add(i);\r
-\r
- array.RemoveAll(array2.RangeFromTo(-1, 10));\r
- Assert.AreEqual(0, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- array.RetainAll(array2.RangeFromTo(3, 17));\r
- Assert.AreEqual(3, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 4, 6, 8));\r
- array.RetainAll(array2.RangeFromTo(1, 17));\r
- Assert.AreEqual(3, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 4, 6, 8));\r
- array.RetainAll(array2.RangeFromTo(3, 5));\r
- Assert.AreEqual(1, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array, 4));\r
- array.RetainAll(array2.RangeFromTo(7, 17));\r
- Assert.AreEqual(0, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array));\r
- for (int i = 0; i < 10; i++) array.Add(i);\r
-\r
- array.RetainAll(array2.RangeFromTo(5, 5));\r
- Assert.AreEqual(0, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array));\r
- for (int i = 0; i < 10; i++) array.Add(i);\r
-\r
- array.RetainAll(array2.RangeFromTo(15, 25));\r
- Assert.AreEqual(0, array.Count);\r
- Assert.IsTrue(array.Check());\r
- Assert.IsTrue(IC.eq(array));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- Assert.IsFalse(array.ContainsAll(array2));\r
- Assert.IsTrue(array.ContainsAll(array));\r
- array2.Clear();\r
- Assert.IsTrue(array.ContainsAll(array2));\r
- array.Clear();\r
- Assert.IsTrue(array.ContainsAll(array2));\r
- array2.Add(8);\r
- Assert.IsFalse(array.ContainsAll(array2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- array.RemoveInterval(3, 4);\r
- Assert.IsTrue(array.Check());\r
- Assert.AreEqual(6, array.Count);\r
- Assert.IsTrue(IC.eq(array, 0, 1, 2, 7, 8, 9));\r
- array.RemoveInterval(2, 3);\r
- Assert.IsTrue(array.Check());\r
- Assert.AreEqual(3, array.Count);\r
- Assert.IsTrue(IC.eq(array, 0, 1, 9));\r
- array.RemoveInterval(0, 3);\r
- Assert.IsTrue(array.Check());\r
- Assert.AreEqual(0, array.Count);\r
- Assert.IsTrue(IC.eq(array));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad1()\r
- {\r
- array.RemoveInterval(-3, 8);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad2()\r
- {\r
- array.RemoveInterval(3, -8);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad3()\r
- {\r
- array.RemoveInterval(3, 8);\r
- }\r
-\r
-\r
- [Test]\r
- public void GetRange()\r
- {\r
- SCG.IEnumerable<int> e = array[3, 3];\r
-\r
- Assert.IsTrue(IC.eq(e, 3, 4, 5));\r
- e = array[3, 0];\r
- Assert.IsTrue(IC.eq(e));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad1()\r
- {\r
- object foo = array[-3, 0];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad2()\r
- {\r
- object foo = array[3, -1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad3()\r
- {\r
- object foo = array[3, 8];\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { array = null; array2 = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace Sync\r
- {\r
- [TestFixture]\r
- public class SyncRoot\r
- {\r
- private SortedArray<int> tree;\r
-\r
- int sz = 5000;\r
-\r
-\r
- [Test]\r
- public void Safe()\r
- {\r
- System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(safe1));\r
- System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(safe2));\r
-\r
- t1.Start();\r
- t2.Start();\r
- t1.Join();\r
- t2.Join();\r
- Assert.AreEqual(2 * sz + 1, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- //[Test]\r
- public void UnSafe()\r
- {\r
- bool bad = false;\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe1));\r
- System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe2));\r
-\r
- t1.Start();\r
- t2.Start();\r
- t1.Join();\r
- t2.Join();\r
- if (bad = 2 * sz + 1 != tree.Count)\r
- {\r
- Console.WriteLine("{0}::Unsafe(): bad at {1}", GetType(), i);\r
- break;\r
- }\r
- }\r
-\r
- Assert.IsTrue(bad, "No sync problems!");\r
- }\r
-\r
-\r
- [Test]\r
- public void SafeUnSafe()\r
- {\r
- System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe1));\r
- System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe2));\r
-\r
- t1.Start();\r
- t1.Join();\r
- t2.Start();\r
- t2.Join();\r
- Assert.AreEqual(2 * sz + 1, tree.Count);\r
- }\r
-\r
-\r
- [SetUp]\r
- public void Init() { tree = new SortedArray<int>(new IC()); }\r
-\r
-\r
- private void unsafe1()\r
- {\r
- for (int i = 0; i < 2 * sz; i++)\r
- tree.Add(i * 2);\r
-\r
- for (int i = 1; i < sz; i++)\r
- tree.Remove(i * 4);\r
- }\r
-\r
-\r
- private void safe1()\r
- {\r
- for (int i = 0; i < 2 * sz; i++)\r
- lock (tree.SyncRoot)\r
- tree.Add(i * 2);\r
-\r
- for (int i = 1; i < sz; i++)\r
- lock (tree.SyncRoot)\r
- tree.Remove(i * 4);\r
- }\r
-\r
-\r
- private void unsafe2()\r
- {\r
- for (int i = 2 * sz; i > 0; i--)\r
- tree.Add(i * 2 + 1);\r
-\r
- for (int i = sz; i > 0; i--)\r
- tree.Remove(i * 4 + 1);\r
- }\r
-\r
-\r
- private void safe2()\r
- {\r
- for (int i = 2 * sz; i > 0; i--)\r
- lock (tree.SyncRoot)\r
- tree.Add(i * 2 + 1);\r
-\r
- for (int i = sz; i > 0; i--)\r
- lock (tree.SyncRoot)\r
- tree.Remove(i * 4 + 1);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
-\r
-\r
-\r
- //[TestFixture]\r
- public class ConcurrentQueries\r
- {\r
- private SortedArray<int> tree;\r
-\r
- int sz = 500000;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new SortedArray<int>(new IC());\r
- for (int i = 0; i < sz; i++)\r
- {\r
- tree.Add(i);\r
- }\r
- }\r
-\r
-\r
-\r
- class A\r
- {\r
- public int count = 0;\r
-\r
- SortedArray<int> t;\r
-\r
-\r
- public A(SortedArray<int> t) { this.t = t; }\r
-\r
-\r
- public void a(int i) { count++; }\r
-\r
-\r
- public void traverse() { t.Apply(new Act<int>(a)); }\r
- }\r
-\r
-\r
-\r
-\r
- [Test]\r
- public void Safe()\r
- {\r
- A a = new A(tree);\r
-\r
- a.traverse();\r
- Assert.AreEqual(sz, a.count);\r
- }\r
-\r
-\r
- [Test]\r
- public void RegrettablyUnsafe()\r
- {\r
- System.Threading.Thread[] t = new System.Threading.Thread[10];\r
- A[] a = new A[10];\r
- for (int i = 0; i < 10; i++)\r
- {\r
- a[i] = new A(tree);\r
- t[i] = new System.Threading.Thread(new System.Threading.ThreadStart(a[i].traverse));\r
- }\r
-\r
- for (int i = 0; i < 10; i++)\r
- t[i].Start();\r
- for (int i = 0; i < 10; i++)\r
- t[i].Join();\r
- for (int i = 0; i < 10; i++)\r
- Assert.AreEqual(sz,a[i].count);\r
-\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace Hashing\r
- {\r
- [TestFixture]\r
- public class ISequenced\r
- {\r
- private ISequenced<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new SortedArray<int>(8,Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new SortedArray<int>(8,Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new SortedArray<int>(8,new RevIC(), EqualityComparer<int>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- }\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.sequencedhashcode(), dit.GetSequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dit.GetSequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(3, 7), dit.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.sequencedhashcode(), dut.GetSequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dut.GetSequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(7, 3), dut.GetSequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dat.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dut));\r
- Assert.IsTrue(dut.SequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- Assert.IsFalse(dut.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new SortedArray<int>(8,Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new SortedArray<int>(8,Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new SortedArray<int>(8,new RevIC(), EqualityComparer<int>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-namespace C5UnitTests.hashtable.bag\r
-{\r
- using CollectionOfInt = HashBag<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.CollectionTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new HashBag<T>(); }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{{ }}", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530, -4, 28 });\r
- Assert.AreEqual("{{ 65530(*1), -4(*2), 28(*2), 129(*1) }}", coll.ToString());\r
- Assert.AreEqual("{{ FFFA(*1), -4(*2), 1C(*2), 81(*1) }}", coll.ToString(null, rad16));\r
- Assert.AreEqual("{{ 65530(*1), -4(*2)... }}", coll.ToString("L18", null));\r
- Assert.AreEqual("{{ FFFA(*1), -4(*2)... }}", coll.ToString("L18", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private ICollection<KeyValuePair<int, int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new HashBag<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int, int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
- KeyValuePair<int, int> q = new KeyValuePair<int, int>();\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- q.Key = 13;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(13, q.Key);\r
- Assert.AreEqual(79, q.Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
- KeyValuePair<int, int> q = new KeyValuePair<int, int>();\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- q.Key = 3;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(3, q.Key);\r
- Assert.AreEqual(78, q.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
- KeyValuePair<int, int> q = new KeyValuePair<int, int>();\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- q.Key = 3;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(3, q.Key);\r
- Assert.AreEqual(78, q.Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- q.Key = 13;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(13, q.Key);\r
- Assert.AreEqual(79, q.Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
- //KeyValuePair<int, int> q = new KeyValuePair<int, int>();\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class CollectionOrSink\r
- {\r
- private HashBag<int> hashbag;\r
-\r
-\r
- [SetUp]\r
- public void Init() { hashbag = new HashBag<int>(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new HashBag<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor2()\r
- {\r
- new HashBag<int>(5, null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor3()\r
- {\r
- new HashBag<int>(5, 0.5, null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- hashbag.Add(7);\r
- Assert.AreEqual(7, hashbag.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- hashbag.Choose();\r
- }\r
-\r
-\r
- [Test]\r
- public void CountEtAl()\r
- {\r
- Assert.IsFalse(hashbag.IsReadOnly);\r
- Assert.IsFalse(hashbag.SyncRoot == null);\r
- Assert.AreEqual(0, hashbag.Count);\r
- Assert.IsTrue(hashbag.IsEmpty);\r
- Assert.IsTrue(hashbag.AllowsDuplicates);\r
- Assert.IsTrue(hashbag.Add(0));\r
- Assert.AreEqual(1, hashbag.Count);\r
- Assert.IsFalse(hashbag.IsEmpty);\r
- Assert.IsTrue(hashbag.Add(5));\r
- Assert.AreEqual(2, hashbag.Count);\r
- Assert.IsTrue(hashbag.Add(5));\r
- Assert.AreEqual(3, hashbag.Count);\r
- Assert.IsFalse(hashbag.IsEmpty);\r
- Assert.IsTrue(hashbag.Add(8));\r
- Assert.AreEqual(4, hashbag.Count);\r
- Assert.AreEqual(2, hashbag.ContainsCount(5));\r
- Assert.AreEqual(1, hashbag.ContainsCount(8));\r
- Assert.AreEqual(1, hashbag.ContainsCount(0));\r
- }\r
-\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- hashbag.Add(3); hashbag.Add(4); hashbag.Add(4); hashbag.Add(5); hashbag.Add(4);\r
-\r
- HashBag<int> hashbag2 = new HashBag<int>();\r
-\r
- hashbag2.AddAll(hashbag);\r
- Assert.IsTrue(IC.seteq(hashbag2, 3, 4, 4, 4, 5));\r
- hashbag.Add(9);\r
- hashbag.AddAll(hashbag2);\r
- Assert.IsTrue(IC.seteq(hashbag2, 3, 4, 4, 4, 5));\r
- Assert.IsTrue(IC.seteq(hashbag, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsCount()\r
- {\r
- Assert.AreEqual(0, hashbag.ContainsCount(5));\r
- hashbag.Add(5);\r
- Assert.AreEqual(1, hashbag.ContainsCount(5));\r
- Assert.AreEqual(0, hashbag.ContainsCount(7));\r
- hashbag.Add(8);\r
- Assert.AreEqual(1, hashbag.ContainsCount(5));\r
- Assert.AreEqual(0, hashbag.ContainsCount(7));\r
- Assert.AreEqual(1, hashbag.ContainsCount(8));\r
- hashbag.Add(5);\r
- Assert.AreEqual(2, hashbag.ContainsCount(5));\r
- Assert.AreEqual(0, hashbag.ContainsCount(7));\r
- Assert.AreEqual(1, hashbag.ContainsCount(8));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- hashbag.Add(5); hashbag.Add(7); hashbag.Add(5);\r
- Assert.AreEqual(2, hashbag.ContainsCount(5));\r
- Assert.AreEqual(1, hashbag.ContainsCount(7));\r
- hashbag.RemoveAllCopies(5);\r
- Assert.AreEqual(0, hashbag.ContainsCount(5));\r
- Assert.AreEqual(1, hashbag.ContainsCount(7));\r
- hashbag.Add(5); hashbag.Add(8); hashbag.Add(5);\r
- hashbag.RemoveAllCopies(8);\r
- Assert.IsTrue(IC.eq(hashbag, 7, 5, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- HashBag<int> list2 = new HashBag<int>();\r
-\r
- Assert.IsTrue(hashbag.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(hashbag.ContainsAll(list2));\r
- hashbag.Add(4);\r
- Assert.IsTrue(hashbag.ContainsAll(list2));\r
- hashbag.Add(5);\r
- Assert.IsTrue(hashbag.ContainsAll(list2));\r
- list2.Add(20);\r
- Assert.IsFalse(hashbag.ContainsAll(list2));\r
- hashbag.Add(20);\r
- Assert.IsTrue(hashbag.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(hashbag.ContainsAll(list2));\r
- hashbag.Add(4);\r
- Assert.IsTrue(hashbag.ContainsAll(list2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- HashBag<int> list2 = new HashBag<int>();\r
-\r
- hashbag.Add(4); hashbag.Add(5); hashbag.Add(4); hashbag.Add(6); hashbag.Add(4);\r
- list2.Add(5); list2.Add(4); list2.Add(7); list2.Add(4);\r
- hashbag.RetainAll(list2);\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 4, 5));\r
- hashbag.Add(6);\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- hashbag.RetainAll(list2);\r
- Assert.IsTrue(IC.eq(hashbag));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- HashBag<int> list2 = new HashBag<int>();\r
-\r
- hashbag.Add(4); hashbag.Add(5); hashbag.Add(6); hashbag.Add(4); hashbag.Add(5);\r
- list2.Add(5); list2.Add(4); list2.Add(7); list2.Add(4);\r
- hashbag.RemoveAll(list2);\r
- Assert.IsTrue(IC.seteq(hashbag, 5, 6));\r
- hashbag.Add(5); hashbag.Add(4);\r
- list2.Clear();\r
- list2.Add(6); list2.Add(5);\r
- hashbag.RemoveAll(list2);\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 5));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- hashbag.RemoveAll(list2);\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- hashbag.Add(4); hashbag.Add(4); hashbag.Add(5); hashbag.Add(4); hashbag.Add(6);\r
- Assert.IsFalse(hashbag.Remove(2));\r
- Assert.IsTrue(hashbag.Remove(4));\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 4, 5, 6));\r
- hashbag.Add(7);\r
- hashbag.Add(21); hashbag.Add(37); hashbag.Add(53); hashbag.Add(69); hashbag.Add(53); hashbag.Add(85);\r
- Assert.IsTrue(hashbag.Remove(5));\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 4, 6, 7, 21, 37, 53, 53, 69, 85));\r
- Assert.IsFalse(hashbag.Remove(165));\r
- Assert.IsTrue(hashbag.Check());\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 4, 6, 7, 21, 37, 53, 53, 69, 85));\r
- Assert.IsTrue(hashbag.Remove(53));\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 4, 6, 7, 21, 37, 53, 69, 85));\r
- Assert.IsTrue(hashbag.Remove(37));\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 4, 6, 7, 21, 53, 69, 85));\r
- Assert.IsTrue(hashbag.Remove(85));\r
- Assert.IsTrue(IC.seteq(hashbag, 4, 4, 6, 7, 21, 53, 69));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { hashbag = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private HashBag<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashBag<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private HashBag<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new HashBag<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 2, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private HashBag<int> hashbag;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- hashbag = new HashBag<int>();\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { hashbag = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(hashbag.ToArray()));\r
- hashbag.Add(7);\r
- hashbag.Add(3);\r
- hashbag.Add(10);\r
- hashbag.Add(3);\r
-\r
- int[] r = hashbag.ToArray();\r
-\r
- Array.Sort(r);\r
- Assert.AreEqual("Alles klar", aeq(r, 3, 3, 7, 10));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- //Note: for small ints the itemequalityComparer is the identity!\r
- hashbag.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- hashbag.Add(6);\r
- hashbag.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- hashbag.Add(4);\r
- hashbag.Add(6);\r
- hashbag.Add(9);\r
- hashbag.CopyTo(a, 4);\r
-\r
- //TODO: make independent of interequalityComparer\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 6, 9, 4, 1008, 1009));\r
- hashbag.Clear();\r
- hashbag.Add(7);\r
- hashbag.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 6, 9, 4, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- hashbag.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- hashbag.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- hashbag.Add(3);\r
- hashbag.Add(8);\r
- hashbag.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class HashingEquals\r
- {\r
- private ICollection<int> h1, h2;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- h1 = new HashBag<int>();\r
- h2 = new LinkedList<int>();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- h1 = h2 = null;\r
- }\r
-\r
-\r
- [Test]\r
- public void Hashing()\r
- {\r
- Assert.AreEqual(h1.GetUnsequencedHashCode(), h2.GetUnsequencedHashCode());\r
- h1.Add(7);\r
- h2.Add(9);\r
- Assert.IsTrue(h1.GetUnsequencedHashCode() != h2.GetUnsequencedHashCode());\r
- h2.Add(7);\r
- h1.Add(9);\r
- Assert.IsTrue(h1.GetUnsequencedHashCode() == h2.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void Equals()\r
- {\r
- Assert.IsTrue(h1.UnsequencedEquals(h2));\r
-// Code 1550734257, Pair (3 x 1602896434, 2 x 1186320090) number 169185 matched oth\r
-//er pair (3 x -1615223932, 2 x 1019546595)\r
- h1.Add(1602896434);\r
- h1.Add(1186320090);\r
- h1.Add(1602896434);\r
- h1.Add(1186320090);\r
- h1.Add(1602896434);\r
- h2.Add(-1615223932);\r
- h2.Add(1019546595);\r
- h2.Add(-1615223932);\r
- h2.Add(1019546595);\r
- h2.Add(-1615223932);\r
- Assert.IsTrue(h1.GetUnsequencedHashCode() == h2.GetUnsequencedHashCode());\r
- Assert.IsTrue(!h1.UnsequencedEquals(h2));\r
- h1.Clear();\r
- h2.Clear();\r
- h1.Add(1);\r
- h1.Add(2);\r
- h2.Add(2);\r
- h2.Add(1);\r
- Assert.IsTrue(h1.GetUnsequencedHashCode() == h2.GetUnsequencedHashCode());\r
- Assert.IsTrue(h1.UnsequencedEquals(h2));\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-namespace C5UnitTests.hashtable.dictionary\r
-{\r
- using DictionaryIntToInt = HashDictionary<int,int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<DictionaryIntToInt> factory = delegate() { return new DictionaryIntToInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.DictionaryTester<DictionaryIntToInt>().Test(factory);\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static IDictionary<K, V> New<K, V>() { return new HashDictionary<K, V>(); }\r
- }\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- IDictionary<int, int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int, int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{ }", coll.ToString());\r
- coll.Add(23, 67); coll.Add(45, 89);\r
- Assert.AreEqual("{ 45 => 89, 23 => 67 }", coll.ToString());\r
- Assert.AreEqual("{ 2D => 59, 17 => 43 }", coll.ToString(null, rad16));\r
- Assert.AreEqual("{ 45 => 89, ... }", coll.ToString("L14", null));\r
- Assert.AreEqual("{ 2D => 59, ... }", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class HashDict\r
- {\r
- private HashDictionary<string, string> dict;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dict = new HashDictionary<string, string>();\r
- //dict = TreeDictionary<string,string>.MakeNaturalO<string,string>();\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new HashDictionary<int, int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor2()\r
- {\r
- new HashDictionary<int, int>(5, 0.5, null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- dict.Add("ER", "FOO");\r
- Assert.AreEqual(new KeyValuePair<string, string>("ER", "FOO"), dict.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- dict.Choose();\r
- }\r
-\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dict = null;\r
- }\r
-\r
-\r
- [Test]\r
- public void Initial()\r
- {\r
- bool res;\r
-\r
- Assert.IsFalse(dict.IsReadOnly);\r
- Assert.AreEqual(0, dict.Count, "new dict should be empty");\r
- dict.Add("A", "B");\r
- Assert.AreEqual(1, dict.Count, "bad count");\r
- Assert.AreEqual("B", dict["A"], "Wrong value for dict[A]");\r
- dict.Add("C", "D");\r
- Assert.AreEqual(2, dict.Count, "bad count");\r
- Assert.AreEqual("B", dict["A"], "Wrong value");\r
- Assert.AreEqual("D", dict["C"], "Wrong value");\r
- res = dict.Remove("A");\r
- Assert.IsTrue(res, "bad return value from Remove(A)");\r
- Assert.AreEqual(1, dict.Count, "bad count");\r
- Assert.AreEqual("D", dict["C"], "Wrong value of dict[C]");\r
- res = dict.Remove("Z");\r
- Assert.IsFalse(res, "bad return value from Remove(Z)");\r
- Assert.AreEqual(1, dict.Count, "bad count");\r
- Assert.AreEqual("D", dict["C"], "Wrong value of dict[C] (2)");\r
- }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- dict.Add("C", "D");\r
- Assert.IsTrue(dict.Contains("C"));\r
- Assert.IsFalse(dict.Contains("D"));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(DuplicateNotAllowedException), "Key being added: 'A'")]\r
- public void IllegalAdd()\r
- {\r
- dict.Add("A", "B");\r
- dict.Add("A", "B");\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void GettingNonExisting()\r
- {\r
- Console.WriteLine(dict["R"]);\r
- }\r
-\r
-\r
- [Test]\r
- public void Setter()\r
- {\r
- dict["R"] = "UYGUY";\r
- Assert.AreEqual("UYGUY", dict["R"]);\r
- dict["R"] = "UIII";\r
- Assert.AreEqual("UIII", dict["R"]);\r
- dict["S"] = "VVV";\r
- Assert.AreEqual("UIII", dict["R"]);\r
- Assert.AreEqual("VVV", dict["S"]);\r
- //dict.dump();\r
- }\r
-\r
- [Test]\r
- public void CombinedOps()\r
- {\r
- dict["R"] = "UIII";\r
- dict["S"] = "VVV";\r
- dict["T"] = "XYZ";\r
-\r
- string s;\r
-\r
- Assert.IsTrue(dict.Remove("S", out s));\r
- Assert.AreEqual("VVV", s);\r
- Assert.IsFalse(dict.Contains("S"));\r
- Assert.IsFalse(dict.Remove("A", out s));\r
-\r
- //\r
- Assert.IsTrue(dict.Find("T", out s));\r
- Assert.AreEqual("XYZ", s);\r
- Assert.IsFalse(dict.Find("A", out s));\r
-\r
- //\r
- Assert.IsTrue(dict.Update("R", "UHU"));\r
- Assert.AreEqual("UHU", dict["R"]);\r
- Assert.IsFalse(dict.Update("A", "W"));\r
- Assert.IsFalse(dict.Contains("A"));\r
-\r
- //\r
- s = "KKK";\r
- Assert.IsFalse(dict.FindOrAdd("B", ref s));\r
- Assert.AreEqual("KKK", dict["B"]);\r
- Assert.IsTrue(dict.FindOrAdd("T", ref s));\r
- Assert.AreEqual("XYZ", s);\r
-\r
- //\r
- s = "LLL";\r
- Assert.IsTrue(dict.UpdateOrAdd("R", s));\r
- Assert.AreEqual("LLL", dict["R"]);\r
- s = "MMM";\r
- Assert.IsFalse(dict.UpdateOrAdd("C", s));\r
- Assert.AreEqual("MMM", dict["C"]);\r
- }\r
-\r
- [Test]\r
- public void DeepBucket()\r
- {\r
- HashDictionary<int, int> dict2 = new HashDictionary<int, int>();\r
-\r
- for (int i = 0; i < 5; i++)\r
- dict2[16 * i] = 5 * i;\r
-\r
- for (int i = 0; i < 5; i++)\r
- Assert.AreEqual(5 * i, dict2[16 * i]);\r
-\r
- for (int i = 0; i < 5; i++)\r
- dict2[16 * i] = 7 * i + 1;\r
-\r
- for (int i = 0; i < 5; i++)\r
- Assert.AreEqual(7 * i + 1, dict2[16 * i]);\r
- Assert.IsTrue(dict.Check());\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Enumerators\r
- {\r
- private HashDictionary<string, string> dict;\r
-\r
- private SCG.IEnumerator<KeyValuePair<string, string>> dictenum;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dict = new HashDictionary<string, string>();\r
- dict["S"] = "A";\r
- dict["T"] = "B";\r
- dict["R"] = "C";\r
- dictenum = dict.GetEnumerator();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dictenum = null;\r
- dict = null;\r
- }\r
-\r
-\r
- [Test]\r
- public void Keys()\r
- {\r
- SCG.IEnumerator<string> keys = dict.Keys.GetEnumerator();\r
-\r
- Assert.IsTrue(keys.MoveNext());\r
- Assert.AreEqual("R", keys.Current);\r
- Assert.IsTrue(keys.MoveNext());\r
- Assert.AreEqual("T", keys.Current);\r
- Assert.IsTrue(keys.MoveNext());\r
- Assert.AreEqual("S", keys.Current);\r
- Assert.IsFalse(keys.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void Values()\r
- {\r
- SCG.IEnumerator<string> values = dict.Values.GetEnumerator();\r
-\r
- Assert.IsTrue(values.MoveNext());\r
- Assert.AreEqual("C", values.Current);\r
- Assert.IsTrue(values.MoveNext());\r
- Assert.AreEqual("B", values.Current);\r
- Assert.IsTrue(values.MoveNext());\r
- Assert.AreEqual("A", values.Current);\r
- Assert.IsFalse(values.MoveNext());\r
- }\r
-\r
- [Test]\r
- public void Fun()\r
- {\r
- Assert.AreEqual("B", dict.Fun("T"));\r
- }\r
-\r
-\r
- [Test]\r
- public void NormalUse()\r
- {\r
- Assert.IsTrue(dictenum.MoveNext());\r
- Assert.AreEqual(dictenum.Current, new KeyValuePair<string, string>("R", "C"));\r
- Assert.IsTrue(dictenum.MoveNext());\r
- Assert.AreEqual(dictenum.Current, new KeyValuePair<string, string>("T", "B"));\r
- Assert.IsTrue(dictenum.MoveNext());\r
- Assert.AreEqual(dictenum.Current, new KeyValuePair<string, string>("S", "A"));\r
- Assert.IsFalse(dictenum.MoveNext());\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-namespace C5UnitTests.hashtable.set\r
-{\r
- using CollectionOfInt = HashSet<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.CollectionTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new HashSet<T>(); }\r
- }\r
-\r
-\r
- namespace Enumerable\r
- {\r
- [TestFixture]\r
- public class Multiops\r
- {\r
- private HashSet<int> list;\r
-\r
- private Fun<int, bool> always, never, even;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashSet<int>();\r
- always = delegate{return true;};\r
- never = delegate{return false;};\r
- even = delegate(int i){return i%2==0;};\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsTrue(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(0);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsFalse(list.All(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsTrue(list.Exists(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- int sum = 0;\r
- Act<int> a = delegate(int i){sum=i+10*sum;};\r
-\r
- list.Apply(a);\r
- Assert.AreEqual(0, sum);\r
- sum = 0;\r
- list.Add(5);list.Add(8);list.Add(7);list.Add(5);\r
- list.Apply(a);\r
- Assert.AreEqual(758, sum);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class GetEnumerator\r
- {\r
- private HashSet<int> hashset;\r
-\r
-\r
- [SetUp]\r
- public void Init() { hashset = new HashSet<int>(); }\r
-\r
-\r
- [Test]\r
- public void Empty()\r
- {\r
- SCG.IEnumerator<int> e = hashset.GetEnumerator();\r
-\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- hashset.Add(5);\r
- hashset.Add(8);\r
- hashset.Add(5);\r
- hashset.Add(5);\r
- hashset.Add(10);\r
- hashset.Add(1);\r
- hashset.Add(16);\r
- hashset.Add(18);\r
- hashset.Add(17);\r
- hashset.Add(33);\r
- Assert.IsTrue(IC.seteq(hashset, 1, 5, 8, 10, 16, 17, 18, 33));\r
- }\r
-\r
- [Test]\r
- public void DoDispose()\r
- {\r
- hashset.Add(5);\r
- hashset.Add(8);\r
- hashset.Add(5);\r
-\r
- SCG.IEnumerator<int> e = hashset.GetEnumerator();\r
-\r
- e.MoveNext();\r
- e.MoveNext();\r
- e.Dispose();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- hashset.Add(5);\r
- hashset.Add(8);\r
- hashset.Add(5);\r
-\r
- SCG.IEnumerator<int> e = hashset.GetEnumerator();\r
-\r
- e.MoveNext();\r
- hashset.Add(99);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { hashset = null; }\r
- }\r
- }\r
-\r
- namespace CollectionOrSink\r
- {\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{ }", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("{ 65530, -4, 28, 129 }", coll.ToString());\r
- Assert.AreEqual("{ FFFA, -4, 1C, 81 }", coll.ToString(null, rad16));\r
- Assert.AreEqual("{ 65530, -4, ... }", coll.ToString("L14", null));\r
- Assert.AreEqual("{ FFFA, -4, ... }", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class CollectionOrSink\r
- {\r
- private HashSet<int> hashset;\r
-\r
-\r
- [SetUp]\r
- public void Init() { hashset = new HashSet<int>(); }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- hashset.Add(7);\r
- Assert.AreEqual(7, hashset.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- hashset.Choose();\r
- }\r
-\r
- [Test]\r
- public void CountEtAl()\r
- {\r
- Assert.AreEqual(0, hashset.Count);\r
- Assert.IsTrue(hashset.IsEmpty);\r
- Assert.IsFalse(hashset.AllowsDuplicates);\r
- Assert.IsTrue(hashset.Add(0));\r
- Assert.AreEqual(1, hashset.Count);\r
- Assert.IsFalse(hashset.IsEmpty);\r
- Assert.IsTrue(hashset.Add(5));\r
- Assert.AreEqual(2, hashset.Count);\r
- Assert.IsFalse(hashset.Add(5));\r
- Assert.AreEqual(2, hashset.Count);\r
- Assert.IsFalse(hashset.IsEmpty);\r
- Assert.IsTrue(hashset.Add(8));\r
- Assert.AreEqual(3, hashset.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- hashset.Add(3);hashset.Add(4);hashset.Add(5);\r
-\r
- HashSet<int> hashset2 = new HashSet<int>();\r
-\r
- hashset2.AddAll(hashset);\r
- Assert.IsTrue(IC.seteq(hashset2, 3, 4, 5));\r
- hashset.Add(9);\r
- hashset.AddAll(hashset2);\r
- Assert.IsTrue(IC.seteq(hashset2, 3, 4, 5));\r
- Assert.IsTrue(IC.seteq(hashset, 3, 4, 5, 9));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { hashset = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private HashSet<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashSet<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private HashSet<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new HashSet<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 1, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private HashSet<int> hashset;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- hashset = new HashSet<int>();\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { hashset = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(hashset.ToArray()));\r
- hashset.Add(7);\r
- hashset.Add(3);\r
- hashset.Add(10);\r
-\r
- int[] r = hashset.ToArray();\r
-\r
- Array.Sort(r);\r
- Assert.AreEqual("Alles klar", aeq(r, 3, 7, 10));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- //Note: for small ints the itemequalityComparer is the identity!\r
- hashset.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- hashset.Add(6);\r
- hashset.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- hashset.Add(4);\r
- hashset.Add(9);\r
- hashset.CopyTo(a, 4);\r
-\r
- //TODO: make test independent on onterequalityComparer\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 9, 4, 1007, 1008, 1009));\r
- hashset.Clear();\r
- hashset.Add(7);\r
- hashset.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 9, 4, 1007, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- hashset.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- hashset.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- hashset.Add(3);\r
- hashset.Add(8);\r
- hashset.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Sync\r
- {\r
- private HashSet<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashSet<int>();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- [Test]\r
- public void Get()\r
- {\r
- Assert.IsNotNull(list.SyncRoot);\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace EditableCollection\r
- {\r
- [TestFixture]\r
- public class Collision\r
- {\r
- HashSet<int> hashset;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- hashset = new HashSet<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void SingleCollision()\r
- {\r
- hashset.Add(7);\r
- hashset.Add(7 - 1503427877);\r
-\r
- //foreach (int cell in hashset) Console.WriteLine("A: {0}", cell);\r
- hashset.Remove(7);\r
- Assert.IsTrue(hashset.Contains(7 - 1503427877));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- hashset = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private HashSet<int> hashset;\r
-\r
-\r
- [SetUp]\r
- public void Init() { hashset = new HashSet<int>(); }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new HashSet<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor2()\r
- {\r
- new HashSet<int>(5, null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor3()\r
- {\r
- new HashSet<int>(5, 0.5, null);\r
- }\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsFalse(hashset.Contains(5));\r
- hashset.Add(5);\r
- Assert.IsTrue(hashset.Contains(5));\r
- Assert.IsFalse(hashset.Contains(7));\r
- hashset.Add(8);\r
- hashset.Add(10);\r
- Assert.IsTrue(hashset.Contains(5));\r
- Assert.IsFalse(hashset.Contains(7));\r
- Assert.IsTrue(hashset.Contains(8));\r
- Assert.IsTrue(hashset.Contains(10));\r
- hashset.Remove(8);\r
- Assert.IsTrue(hashset.Contains(5));\r
- Assert.IsFalse(hashset.Contains(7));\r
- Assert.IsFalse(hashset.Contains(8));\r
- Assert.IsTrue(hashset.Contains(10));\r
- hashset.Add(0);hashset.Add(16);hashset.Add(32);hashset.Add(48);hashset.Add(64);\r
- Assert.IsTrue(hashset.Contains(0));\r
- Assert.IsTrue(hashset.Contains(16));\r
- Assert.IsTrue(hashset.Contains(32));\r
- Assert.IsTrue(hashset.Contains(48));\r
- Assert.IsTrue(hashset.Contains(64));\r
- Assert.IsTrue(hashset.Check());\r
-\r
- int i = 0, j = i;\r
-\r
- Assert.IsTrue(hashset.Find(ref i));\r
- Assert.AreEqual(j, i);\r
- j = i = 16;\r
- Assert.IsTrue(hashset.Find(ref i));\r
- Assert.AreEqual(j, i);\r
- j = i = 32;\r
- Assert.IsTrue(hashset.Find(ref i));\r
- Assert.AreEqual(j, i);\r
- j = i = 48;\r
- Assert.IsTrue(hashset.Find(ref i));\r
- Assert.AreEqual(j, i);\r
- j = i = 64;\r
- Assert.IsTrue(hashset.Find(ref i));\r
- Assert.AreEqual(j, i);\r
- j = i = 80;\r
- Assert.IsFalse(hashset.Find(ref i));\r
- Assert.AreEqual(j, i);\r
- }\r
-\r
-\r
- [Test]\r
- public void Many()\r
- {\r
- int j = 7373;\r
- int[] a = new int[j];\r
-\r
- for (int i = 0; i < j; i++)\r
- {\r
- hashset.Add(3 * i + 1);\r
- a[i] = 3 * i + 1;\r
- }\r
-\r
- Assert.IsTrue(IC.seteq(hashset, a));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsCount()\r
- {\r
- Assert.AreEqual(0, hashset.ContainsCount(5));\r
- hashset.Add(5);\r
- Assert.AreEqual(1, hashset.ContainsCount(5));\r
- Assert.AreEqual(0, hashset.ContainsCount(7));\r
- hashset.Add(8);\r
- Assert.AreEqual(1, hashset.ContainsCount(5));\r
- Assert.AreEqual(0, hashset.ContainsCount(7));\r
- Assert.AreEqual(1, hashset.ContainsCount(8));\r
- hashset.Add(5);\r
- Assert.AreEqual(1, hashset.ContainsCount(5));\r
- Assert.AreEqual(0, hashset.ContainsCount(7));\r
- Assert.AreEqual(1, hashset.ContainsCount(8));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- hashset.Add(5);hashset.Add(7);hashset.Add(5);\r
- Assert.AreEqual(1, hashset.ContainsCount(5));\r
- Assert.AreEqual(1, hashset.ContainsCount(7));\r
- hashset.RemoveAllCopies(5);\r
- Assert.AreEqual(0, hashset.ContainsCount(5));\r
- Assert.AreEqual(1, hashset.ContainsCount(7));\r
- hashset.Add(5);hashset.Add(8);hashset.Add(5);\r
- hashset.RemoveAllCopies(8);\r
- Assert.IsTrue(IC.eq(hashset, 7, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- HashSet<int> list2 = new HashSet<int>();\r
-\r
- Assert.IsTrue(hashset.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(hashset.ContainsAll(list2));\r
- hashset.Add(4);\r
- Assert.IsTrue(hashset.ContainsAll(list2));\r
- hashset.Add(5);\r
- Assert.IsTrue(hashset.ContainsAll(list2));\r
- list2.Add(20);\r
- Assert.IsFalse(hashset.ContainsAll(list2));\r
- hashset.Add(20);\r
- Assert.IsTrue(hashset.ContainsAll(list2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- HashSet<int> list2 = new HashSet<int>();\r
-\r
- hashset.Add(4);hashset.Add(5);hashset.Add(6);\r
- list2.Add(5);list2.Add(4);list2.Add(7);\r
- hashset.RetainAll(list2);\r
- Assert.IsTrue(IC.seteq(hashset, 4, 5));\r
- hashset.Add(6);\r
- list2.Clear();\r
- list2.Add(7);list2.Add(8);list2.Add(9);\r
- hashset.RetainAll(list2);\r
- Assert.IsTrue(IC.seteq(hashset));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- HashSet<int> list2 = new HashSet<int>();\r
-\r
- hashset.Add(4);hashset.Add(5);hashset.Add(6);\r
- list2.Add(5);list2.Add(7);list2.Add(4);\r
- hashset.RemoveAll(list2);\r
- Assert.IsTrue(IC.eq(hashset, 6));\r
- hashset.Add(5);hashset.Add(4);\r
- list2.Clear();\r
- list2.Add(6);list2.Add(5);\r
- hashset.RemoveAll(list2);\r
- Assert.IsTrue(IC.eq(hashset, 4));\r
- list2.Clear();\r
- list2.Add(7);list2.Add(8);list2.Add(9);\r
- hashset.RemoveAll(list2);\r
- Assert.IsTrue(IC.eq(hashset, 4));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- hashset.Add(4);hashset.Add(4);hashset.Add(5);hashset.Add(4);hashset.Add(6);\r
- Assert.IsFalse(hashset.Remove(2));\r
- Assert.IsTrue(hashset.Remove(4));\r
- Assert.IsTrue(IC.seteq(hashset, 5, 6));\r
- hashset.Add(7);\r
- hashset.Add(21);hashset.Add(37);hashset.Add(53);hashset.Add(69);hashset.Add(85);\r
- Assert.IsTrue(hashset.Remove(5));\r
- Assert.IsTrue(IC.seteq(hashset, 6, 7, 21, 37, 53, 69, 85));\r
- Assert.IsFalse(hashset.Remove(165));\r
- Assert.IsTrue(IC.seteq(hashset, 6, 7, 21, 37, 53, 69, 85));\r
- Assert.IsTrue(hashset.Remove(53));\r
- Assert.IsTrue(IC.seteq(hashset, 6, 7, 21, 37, 69, 85));\r
- Assert.IsTrue(hashset.Remove(37));\r
- Assert.IsTrue(IC.seteq(hashset, 6, 7, 21, 69, 85));\r
- Assert.IsTrue(hashset.Remove(85));\r
- Assert.IsTrue(IC.seteq(hashset, 6, 7, 21, 69));\r
- }\r
-\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- hashset.Add(7);hashset.Add(7);\r
- hashset.Clear();\r
- Assert.IsTrue(hashset.IsEmpty);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { hashset = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private ICollection<KeyValuePair<int,int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new HashSet<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int,int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
- KeyValuePair<int,int> q = new KeyValuePair<int,int>();\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int,int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- q.Key = 13;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(13, q.Key);\r
- Assert.AreEqual(79, q.Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
- KeyValuePair<int,int> q = new KeyValuePair<int,int>();\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- q.Key = 3;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(3, q.Key);\r
- Assert.AreEqual(78, q.Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
- KeyValuePair<int,int> q = new KeyValuePair<int,int>();\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- q.Key = 3;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(3, q.Key);\r
- Assert.AreEqual(78, q.Value);\r
- p = new KeyValuePair<int,int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- q.Key = 13;\r
- Assert.IsTrue(lst.Find(ref q));\r
- Assert.AreEqual(13, q.Key);\r
- Assert.AreEqual(79, q.Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
- //KeyValuePair<int,int> q = new KeyValuePair<int,int>();\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- }\r
-\r
-\r
-\r
-\r
- namespace HashingAndEquals\r
- {\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashSet<int>();\r
- dat = new HashSet<int>();\r
- dut = new HashSet<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(-1657792980);dit.Add(-1570288808);\r
- dat.Add(1862883298);dat.Add(-272461342);\r
- Assert.AreEqual(dit.GetUnsequencedHashCode(), dat.GetUnsequencedHashCode());\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnorderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ICollection<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashSet<int>();\r
- dat = new HashSet<int>();\r
- dut = new HashSet<int>();\r
- dit.Add(2);dit.Add(1);\r
- dat.Add(1);dat.Add(2);\r
- dut.Add(3);\r
- Dit = new HashSet<ICollection<int>>();\r
- Dat = new HashSet<ICollection<int>>();\r
- Dut = new HashSet<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit);Dit.Add(dut);Dit.Add(dit);\r
- Dat.Add(dut);Dat.Add(dit);Dat.Add(dat);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dat));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ISequenced<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashSet<int>();\r
- dat = new HashSet<int>();\r
- dut = new HashSet<int>();\r
- dit.Add(2);dit.Add(1);\r
- dat.Add(1);dat.Add(2);\r
- dut.Add(3);\r
- Dit = new LinkedList<ICollection<int>>();\r
- Dat = new LinkedList<ICollection<int>>();\r
- Dut = new LinkedList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit);Dit.Add(dut);Dit.Add(dit);\r
- Dat.Add(dut);Dat.Add(dit);Dat.Add(dat);\r
- Dut.Add(dit);Dut.Add(dut);Dut.Add(dat);\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ICollection<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- dot = new LinkedList<int>();\r
- dit.Add(2);dit.Add(1);\r
- dat.Add(1);dat.Add(2);\r
- dut.Add(3);\r
- dot.Add(2);dot.Add(1);\r
- Dit = new HashSet<ISequenced<int>>();\r
- Dat = new HashSet<ISequenced<int>>();\r
- Dut = new HashSet<ISequenced<int>>();\r
- Dot = new HashSet<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit);Dit.Add(dut);//Dit.Add(dit);\r
- Dat.Add(dut);Dat.Add(dit);Dat.Add(dat);\r
- Dut.Add(dot);Dut.Add(dut);//Dut.Add(dit);\r
- Dot.Add(dit);Dot.Add(dit);Dot.Add(dut);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dit));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dut));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dat));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.heaps\r
-{\r
- using CollectionOfInt = IntervalHeap<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.PriorityQueueTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Events\r
- {\r
- IPriorityQueue<int> queue;\r
- ArrayList<KeyValuePair<Acts, int>> events;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- queue = new IntervalHeap<int>();\r
- events = new ArrayList<KeyValuePair<Acts, int>>();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { queue = null; events = null; }\r
-\r
- [Test]\r
- public void Listenable()\r
- {\r
- Assert.AreEqual(EventTypeEnum.Basic, queue.ListenableEvents);\r
- }\r
- \r
- enum Acts\r
- {\r
- Add, Remove, Changed\r
- }\r
-\r
- [Test]\r
- public void Direct()\r
- {\r
- CollectionChangedHandler<int> cch;\r
- ItemsAddedHandler<int> iah;\r
- ItemsRemovedHandler<int> irh;\r
- Assert.AreEqual(EventTypeEnum.None, queue.ActiveEvents);\r
- queue.CollectionChanged += (cch = new CollectionChangedHandler<int>(queue_CollectionChanged));\r
- Assert.AreEqual(EventTypeEnum.Changed, queue.ActiveEvents);\r
- queue.ItemsAdded += (iah = new ItemsAddedHandler<int>(queue_ItemAdded));\r
- Assert.AreEqual(EventTypeEnum.Changed | EventTypeEnum.Added, queue.ActiveEvents);\r
- queue.ItemsRemoved += (irh = new ItemsRemovedHandler<int>(queue_ItemRemoved));\r
- Assert.AreEqual(EventTypeEnum.Changed | EventTypeEnum.Added | EventTypeEnum.Removed, queue.ActiveEvents);\r
- queue.Add(34);\r
- queue.Add(56);\r
- queue.AddAll<int>(new int[] {});\r
- queue.Add(34);\r
- queue.Add(12);\r
- queue.DeleteMax();\r
- queue.DeleteMin();\r
- queue.AddAll<int>(new int[] { 4, 5, 6, 2 });\r
- Assert.AreEqual(17, events.Count);\r
- int[] vals = { 34, 0, 56, 0, 34, 0, 12, 0, 56, 0, 12, 0, 4, 5, 6, 2, 0 };\r
- Acts[] acts = { Acts.Add, Acts.Changed, Acts.Add, Acts.Changed, Acts.Add, Acts.Changed, Acts.Add, Acts.Changed, \r
- Acts.Remove, Acts.Changed, Acts.Remove, Acts.Changed, Acts.Add, Acts.Add, Acts.Add, Acts.Add, Acts.Changed };\r
- for (int i = 0; i < vals.Length; i++)\r
- {\r
- //Console.WriteLine("{0}", events[cell]);\r
- Assert.AreEqual(acts[i], events[i].Key, "Action " + i);\r
- Assert.AreEqual(vals[i], events[i].Value, "Value " + i);\r
- }\r
- queue.CollectionChanged -= cch;\r
- Assert.AreEqual(EventTypeEnum.Added | EventTypeEnum.Removed, queue.ActiveEvents);\r
- queue.ItemsAdded -= iah;\r
- Assert.AreEqual(EventTypeEnum.Removed, queue.ActiveEvents);\r
- queue.ItemsRemoved -= irh;\r
- Assert.AreEqual(EventTypeEnum.None, queue.ActiveEvents);\r
- }\r
-\r
- [Test]\r
- public void Guarded()\r
- {\r
- ICollectionValue<int> guarded = new GuardedCollectionValue<int>(queue);\r
- guarded.CollectionChanged += new CollectionChangedHandler<int>(queue_CollectionChanged);\r
- guarded.ItemsAdded += new ItemsAddedHandler<int>(queue_ItemAdded);\r
- guarded.ItemsRemoved += new ItemsRemovedHandler<int>(queue_ItemRemoved);\r
- queue.Add(34);\r
- queue.Add(56);\r
- queue.Add(34);\r
- queue.Add(12);\r
- queue.DeleteMax();\r
- queue.DeleteMin();\r
- queue.AddAll<int>(new int[] { 4, 5, 6, 2 });\r
- Assert.AreEqual(17, events.Count);\r
- int[] vals = { 34, 0, 56, 0, 34, 0, 12, 0, 56, 0, 12, 0, 4, 5, 6, 2, 0 };\r
- Acts[] acts = { Acts.Add, Acts.Changed, Acts.Add, Acts.Changed, Acts.Add, Acts.Changed, Acts.Add, Acts.Changed, \r
- Acts.Remove, Acts.Changed, Acts.Remove, Acts.Changed, Acts.Add, Acts.Add, Acts.Add, Acts.Add, Acts.Changed };\r
- for (int i = 0; i < vals.Length; i++)\r
- {\r
- //Console.WriteLine("{0}", events[cell]);\r
- Assert.AreEqual(vals[i], events[i].Value);\r
- Assert.AreEqual(acts[i], events[i].Key);\r
- }\r
- }\r
-\r
-\r
- void queue_CollectionChanged(object sender)\r
- {\r
- events.Add(new KeyValuePair<Acts, int>(Acts.Changed, 0));\r
- }\r
- void queue_ItemAdded(object sender, ItemCountEventArgs<int> e)\r
- {\r
- events.Add(new KeyValuePair<Acts, int>(Acts.Add, e.Item));\r
- }\r
- void queue_ItemRemoved(object sender, ItemCountEventArgs<int> e)\r
- {\r
- events.Add(new KeyValuePair<Acts, int>(Acts.Remove, e.Item));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- IntervalHeap<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = new IntervalHeap<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{ }", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("{ -4, 65530, 28, 129 }", coll.ToString());\r
- Assert.AreEqual("{ -4, FFFA, 1C, 81 }", coll.ToString(null, rad16));\r
- Assert.AreEqual("{ -4, 65530, ... }", coll.ToString("L14", null));\r
- Assert.AreEqual("{ -4, FFFA, ... }", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class IntervalHeapTests\r
- {\r
- IPriorityQueue<int> queue;\r
-\r
-\r
- [SetUp]\r
- public void Init() { queue = new IntervalHeap<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { queue = null; }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new IntervalHeap<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor2()\r
- {\r
- new IntervalHeap<int>(5, null);\r
- }\r
-\r
- [Test]\r
- public void Handles()\r
- {\r
- IPriorityQueueHandle<int>[] handles = new IPriorityQueueHandle<int>[10];\r
-\r
- queue.Add(ref handles[0], 7);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[1], 72);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[2], 27);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[3], 17);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[4], 70);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[5], 1);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[6], 2);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[7], 7);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[8], 8);\r
- Assert.IsTrue(queue.Check());\r
- queue.Add(ref handles[9], 9);\r
- Assert.IsTrue(queue.Check());\r
- queue.Delete(handles[2]);\r
- Assert.IsTrue(queue.Check());\r
- queue.Delete(handles[0]);\r
- Assert.IsTrue(queue.Check());\r
- queue.Delete(handles[8]);\r
- Assert.IsTrue(queue.Check());\r
- queue.Delete(handles[4]);\r
- Assert.IsTrue(queue.Check());\r
- queue.Delete(handles[6]);\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(5, queue.Count);\r
- }\r
-\r
- [Test]\r
- public void Replace()\r
- {\r
- IPriorityQueueHandle<int> handle = null;\r
- queue.Add(6);\r
- queue.Add(10);\r
- queue.Add(ref handle, 7);\r
- queue.Add(21);\r
- Assert.AreEqual(7, queue.Replace(handle, 12));\r
- Assert.AreEqual(21, queue.FindMax());\r
- Assert.AreEqual(12, queue.Replace(handle, 34));\r
- Assert.AreEqual(34, queue.FindMax());\r
- Assert.IsTrue(queue.Check());\r
- //replace max\r
- Assert.AreEqual(34, queue.Replace(handle, 60));\r
- Assert.AreEqual(60, queue.FindMax());\r
- Assert.AreEqual(60, queue.Replace(handle, queue[handle] + 80));\r
- Assert.AreEqual(140, queue.FindMax());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- [Test]\r
- public void Replace2()\r
- {\r
- IPriorityQueueHandle<int> handle = null;\r
- queue.Add(6);\r
- queue.Add(10);\r
- queue.Add(ref handle, 7);\r
- //Replace last item in queue with something large\r
- Assert.AreEqual(7, queue.Replace(handle, 12));\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- [Test]\r
- public void ReuseHandle()\r
- {\r
- IPriorityQueueHandle<int> handle = null;\r
- queue.Add(ref handle, 7);\r
- queue.Delete(handle);\r
- queue.Add(ref handle, 8);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidPriorityQueueHandleException))]\r
- public void ErrorAddValidHandle()\r
- {\r
- IPriorityQueueHandle<int> handle = null;\r
- queue.Add(ref handle, 7);\r
- queue.Add(ref handle, 8);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidPriorityQueueHandleException))]\r
- public void ErrorDeleteInvalidHandle()\r
- {\r
- IPriorityQueueHandle<int> handle = null;\r
- queue.Add(ref handle, 7);\r
- queue.Delete(handle);\r
- queue.Delete(handle);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidPriorityQueueHandleException))]\r
- public void ErrorReplaceInvalidHandle()\r
- {\r
- IPriorityQueueHandle<int> handle = null;\r
- queue.Add(ref handle, 7);\r
- queue.Delete(handle);\r
- queue.Replace(handle, 13);\r
- }\r
-\r
- [Test]\r
- public void Simple()\r
- {\r
- Assert.IsTrue(queue.AllowsDuplicates);\r
- Assert.AreEqual(0, queue.Count);\r
- queue.Add(8); queue.Add(18); queue.Add(8); queue.Add(3);\r
- Assert.AreEqual(4, queue.Count);\r
- Assert.AreEqual(18, queue.DeleteMax());\r
- Assert.AreEqual(3, queue.Count);\r
- Assert.AreEqual(3, queue.DeleteMin());\r
- Assert.AreEqual(2, queue.Count);\r
- Assert.AreEqual(8, queue.FindMax());\r
- Assert.AreEqual(8, queue.DeleteMax());\r
- Assert.AreEqual(8, queue.FindMax());\r
- queue.Add(15);\r
- Assert.AreEqual(15, queue.FindMax());\r
- Assert.AreEqual(8, queue.FindMin());\r
- Assert.IsTrue(queue.Comparer.Compare(2, 3) < 0);\r
- Assert.IsTrue(queue.Comparer.Compare(4, 3) > 0);\r
- Assert.IsTrue(queue.Comparer.Compare(3, 3) == 0);\r
-\r
- }\r
-\r
-\r
- [Test]\r
- public void Enumerate()\r
- {\r
- int[] a = new int[4];\r
- int siz = 0;\r
- foreach (int i in queue)\r
- siz++;\r
- Assert.AreEqual(0, siz);\r
-\r
- queue.Add(8); queue.Add(18); queue.Add(8); queue.Add(3);\r
-\r
- foreach (int i in queue)\r
- a[siz++] = i;\r
- Assert.AreEqual(4, siz);\r
- Array.Sort(a, 0, siz);\r
- Assert.AreEqual(3, a[0]);\r
- Assert.AreEqual(8, a[1]);\r
- Assert.AreEqual(8, a[2]);\r
- Assert.AreEqual(18, a[3]);\r
-\r
- siz = 0;\r
- Assert.AreEqual(18, queue.DeleteMax());\r
- foreach (int i in queue)\r
- a[siz++] = i;\r
- Assert.AreEqual(3, siz);\r
- Array.Sort(a, 0, siz);\r
- Assert.AreEqual(3, a[0]);\r
- Assert.AreEqual(8, a[1]);\r
- Assert.AreEqual(8, a[2]);\r
-\r
- siz = 0;\r
- Assert.AreEqual(8, queue.DeleteMax());\r
- foreach (int i in queue)\r
- a[siz++] = i;\r
- Assert.AreEqual(2, siz);\r
- Array.Sort(a, 0, siz);\r
- Assert.AreEqual(3, a[0]);\r
- Assert.AreEqual(8, a[1]);\r
-\r
- siz = 0;\r
- Assert.AreEqual(8, queue.DeleteMax());\r
- foreach (int i in queue)\r
- a[siz++] = i;\r
- Assert.AreEqual(1, siz);\r
- Assert.AreEqual(3, a[0]);\r
- }\r
-\r
- [Test]\r
- public void Random()\r
- {\r
- int length = 1000;\r
- int[] a = new int[length];\r
- Random ran = new Random(6754);\r
-\r
- for (int i = 0; i < length; i++)\r
- queue.Add(a[i] = ran.Next());\r
-\r
- Assert.IsTrue(queue.Check());\r
- Array.Sort(a);\r
- for (int i = 0; i < length / 2; i++)\r
- {\r
- Assert.AreEqual(a[length - i - 1], queue.DeleteMax());\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(a[i], queue.DeleteMin());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.IsEmpty);\r
- }\r
-\r
- [Test]\r
- public void RandomWithHandles()\r
- {\r
- int length = 1000;\r
- int[] a = new int[length];\r
- Random ran = new Random(6754);\r
-\r
- for (int i = 0; i < length; i++)\r
- {\r
- IPriorityQueueHandle<int> h = null;\r
- queue.Add(ref h, a[i] = ran.Next());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.Check());\r
- Array.Sort(a);\r
- for (int i = 0; i < length / 2; i++)\r
- {\r
- Assert.AreEqual(a[length - i - 1], queue.DeleteMax());\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(a[i], queue.DeleteMin());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.IsEmpty);\r
- }\r
-\r
- [Test]\r
- public void RandomWithDeleteHandles()\r
- {\r
- Random ran = new Random(6754);\r
- int length = 1000;\r
- int[] a = new int[length];\r
- ArrayList<int> shuffle = new ArrayList<int>(length);\r
- IPriorityQueueHandle<int>[] h = new IPriorityQueueHandle<int>[length];\r
-\r
- for (int i = 0; i < length; i++)\r
- {\r
- shuffle.Add(i);\r
- queue.Add(ref h[i], a[i] = ran.Next());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.Check());\r
- shuffle.Shuffle(ran);\r
- for (int i = 0; i < length; i++)\r
- {\r
- int j = shuffle[i];\r
- Assert.AreEqual(a[j], queue.Delete(h[j]));\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.IsEmpty);\r
- }\r
-\r
- [Test]\r
- public void RandomIndexing()\r
- {\r
- Random ran = new Random(6754);\r
- int length = 1000;\r
- int[] a = new int[length];\r
- int[] b = new int[length];\r
- ArrayList<int> shuffle = new ArrayList<int>(length);\r
- IPriorityQueueHandle<int>[] h = new IPriorityQueueHandle<int>[length];\r
-\r
- for (int i = 0; i < length; i++)\r
- {\r
- shuffle.Add(i);\r
- queue.Add(ref h[i], a[i] = ran.Next());\r
- b[i] = ran.Next();\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.Check());\r
- shuffle.Shuffle(ran);\r
- for (int i = 0; i < length; i++)\r
- {\r
- int j = shuffle[i];\r
- Assert.AreEqual(a[j], queue[h[j]]);\r
- queue[h[j]] = b[j];\r
- Assert.AreEqual(b[j], queue[h[j]]);\r
- Assert.IsTrue(queue.Check());\r
- }\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void RandomDuplicates()\r
- {\r
- int length = 1000;\r
- int s;\r
- int[] a = new int[length];\r
- Random ran = new Random(6754);\r
-\r
- for (int i = 0; i < length; i++)\r
- queue.Add(a[i] = ran.Next(3, 13));\r
- Assert.IsTrue(queue.Check());\r
-\r
- Array.Sort(a);\r
-\r
- for (int i = 0; i < length / 2; i++)\r
- {\r
- Assert.AreEqual(a[i], queue.DeleteMin());\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(a[length - i - 1], s = queue.DeleteMax());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.IsEmpty);\r
- }\r
-\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- int length = 1000;\r
- int[] a = new int[length];\r
- Random ran = new Random(6754);\r
-\r
- LinkedList<int> lst = new LinkedList<int>();\r
- for (int i = 0; i < length; i++)\r
- lst.Add(a[i] = ran.Next());\r
-\r
- queue.AddAll(lst);\r
- Assert.IsTrue(queue.Check());\r
- Array.Sort(a);\r
- for (int i = 0; i < length / 2; i++)\r
- {\r
- Assert.AreEqual(a[length - i - 1], queue.DeleteMax());\r
- Assert.IsTrue(queue.Check());\r
- Assert.AreEqual(a[i], queue.DeleteMin());\r
- Assert.IsTrue(queue.Check());\r
- }\r
-\r
- Assert.IsTrue(queue.IsEmpty);\r
- }\r
-\r
- }\r
-\r
-\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests.linkedlists.hashed\r
-{\r
- using CollectionOfInt = HashedLinkedList<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.ListTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Clone.ViewTester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.ViewTester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new HashedLinkedList<T>(); }\r
- }\r
-\r
-\r
- namespace Enumerable\r
- {\r
- [TestFixture]\r
- public class Multiops\r
- {\r
- private HashedLinkedList<int> list;\r
-\r
- private Fun<int, bool> always, never, even;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedLinkedList<int>();\r
- always = delegate { return true; };\r
- never = delegate { return false; };\r
- even = delegate(int i) { return i % 2 == 0; };\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsTrue(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsFalse(list.All(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsTrue(list.Exists(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- int sum = 0;\r
- Act<int> a = delegate(int i) { sum = i + 10 * sum; };\r
-\r
- list.Apply(a);\r
- Assert.AreEqual(0, sum);\r
- sum = 0;\r
- list.Add(5); list.Add(8); list.Add(7); list.Add(5);\r
- list.Apply(a);\r
- Assert.AreEqual(587, sum);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class GetEnumerator\r
- {\r
- private HashedLinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedLinkedList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Empty()\r
- {\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
- list.Add(5);\r
- list.Add(10);\r
- list.Add(1);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(8, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(10, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(1, e.Current);\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void DoDispose()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- e.MoveNext();\r
- e.Dispose();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- list.Add(99);\r
- e.MoveNext();\r
- }\r
-\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
- namespace CollectionOrSink\r
- {\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("[ ]", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("[ -4, 28, 129, 65530 ]", coll.ToString());\r
- Assert.AreEqual("[ -4, 1C, 81, FFFA ]", coll.ToString(null, rad16));\r
- Assert.AreEqual("[ -4, 28, 129... ]", coll.ToString("L14", null));\r
- Assert.AreEqual("[ -4, 1C, 81... ]", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class CollectionOrSink\r
- {\r
- private HashedLinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedLinkedList<int>(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new HashedLinkedList<int>(null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- list.Add(7);\r
- Assert.AreEqual(7, list.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- list.Choose();\r
- }\r
-\r
-\r
- [Test]\r
- public void CountEtAl()\r
- {\r
- Assert.AreEqual(0, list.Count);\r
- Assert.IsTrue(list.IsEmpty);\r
- Assert.IsFalse(list.AllowsDuplicates);\r
- Assert.IsTrue(list.Add(5));\r
- Assert.AreEqual(1, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- Assert.IsFalse(list.Add(5));\r
- Assert.AreEqual(1, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- Assert.IsTrue(list.Add(8));\r
- Assert.AreEqual(2, list.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- list.Add(3); list.Add(4); list.Add(5);\r
-\r
- HashedLinkedList<int> list2 = new HashedLinkedList<int>();\r
-\r
- list2.AddAll(list);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- list.AddAll(list2);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- Assert.IsTrue(IC.eq(list, 3, 4, 5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private HashedLinkedList<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedLinkedList<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- [Test]\r
- public void FindLast()\r
- {\r
- int i;\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.FindLast(pred, out i));\r
- Assert.AreEqual(675, i);\r
- }\r
-\r
- [Test]\r
- public void FindIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(4, list.FindIndex(pred));\r
- }\r
-\r
- [Test]\r
- public void FindLastIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(6, list.FindLastIndex(pred));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private HashedLinkedList<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedLinkedList<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 1, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private HashedLinkedList<int> list;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedLinkedList<int>();\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray()));\r
- list.Add(7);\r
- list.Add(8);\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray(), 7, 8));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- list.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(6);\r
- list.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(4);\r
- list.Add(5);\r
- list.Add(9);\r
- list.CopyTo(a, 4);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 5, 9, 1008, 1009));\r
- list.Clear();\r
- list.Add(7);\r
- list.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 5, 9, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- list.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- list.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- list.Add(3);\r
- list.Add(4);\r
- list.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Sync\r
- {\r
- private HashedLinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedLinkedList<int>();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- [Test]\r
- public void Get()\r
- {\r
- Assert.IsNotNull(list.SyncRoot);\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace EditableCollection\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private HashedLinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new HashedLinkedList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsFalse(list.Contains(5));\r
- list.Add(5);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- list.Add(8);\r
- list.Add(10);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsTrue(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- list.Remove(8);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsFalse(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- }\r
-\r
- [Test]\r
- public void BadAdd()\r
- {\r
- Assert.IsTrue(list.Add(5));\r
- Assert.IsTrue(list.Add(8));\r
- Assert.IsFalse(list.Add(5));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsCount()\r
- {\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- list.Add(5);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- list.Add(8);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- Assert.AreEqual(1, list.ContainsCount(8));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- list.Add(5); list.Add(7);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.RemoveAllCopies(5);\r
- Assert.IsTrue(list.Check());\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.Add(5); list.Add(8);\r
- list.RemoveAllCopies(8);\r
- Assert.IsTrue(IC.eq(list, 7, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindAll()\r
- {\r
- Fun<int, bool> f = delegate(int i) { return i % 2 == 0; };\r
-\r
- Assert.IsTrue(list.FindAll(f).IsEmpty);\r
- list.Add(5); list.Add(8); list.Add(10);\r
- Assert.IsTrue(((HashedLinkedList<int>)list.FindAll(f)).Check());\r
- Assert.IsTrue(IC.eq(list.FindAll(f), 8, 10));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- HashedLinkedList<int> list2 = new HashedLinkedList<int>();\r
-\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(list.ContainsAll(list2));\r
- list.Add(4);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list.Add(5);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- HashedLinkedList<int> list2 = new HashedLinkedList<int>();\r
-\r
- list.Add(4); list.Add(5); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(5); list2.Add(5); list2.Add(6);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 6));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- HashedLinkedList<int> list2 = new HashedLinkedList<int>();\r
-\r
- list.Add(4); list.Add(5); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 6));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(6); list2.Add(5);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- list.Add(4); list.Add(5); list.Add(6);\r
- Assert.IsFalse(list.Remove(2));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(list.Remove(4));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 6));\r
- Assert.AreEqual(6, list.RemoveLast());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5));\r
- list.Add(7);\r
- Assert.AreEqual(5, list.RemoveFirst());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- list.Add(7); list.Add(6);\r
- list.Clear();\r
- Assert.IsTrue(list.IsEmpty);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace IIndexed\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void IndexOf()\r
- {\r
- Assert.AreEqual(~0, dit.IndexOf(6));\r
- dit.Add(7);\r
- Assert.AreEqual(~1, dit.IndexOf(6));\r
- Assert.AreEqual(~1, dit.LastIndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- dit.Add(5); dit.Add(7); dit.Add(8); dit.Add(7);\r
- Assert.AreEqual(~3, dit.IndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- Assert.AreEqual(0, dit.LastIndexOf(7));\r
- Assert.AreEqual(2, dit.IndexOf(8));\r
- Assert.AreEqual(1, dit.LastIndexOf(5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Removing\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- dit.Add(5); dit.Add(7); dit.Add(9); dit.Add(1); dit.Add(2);\r
- Assert.AreEqual(7, dit.RemoveAt(1));\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 5, 9, 1, 2));\r
- Assert.AreEqual(5, dit.RemoveAt(0));\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1, 2));\r
- Assert.AreEqual(2, dit.RemoveAt(2));\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad0()\r
- {\r
- dit.RemoveAt(0);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBadM1()\r
- {\r
- dit.RemoveAt(-1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad1()\r
- {\r
- dit.Add(8);\r
- dit.RemoveAt(1);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- dit.RemoveInterval(0, 0);\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(3, 0);\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 40, 50, 60));\r
- dit.RemoveInterval(3, 1);\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 50, 60));\r
- dit.RemoveInterval(1, 3);\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 60));\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit));\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40, 50, 60));\r
- dit.RemoveInterval(2, 2);\r
- Assert.IsTrue(((HashedLinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace IList_\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedLinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void FirstBad()\r
- {\r
- int f = lst.First;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void LastBad()\r
- {\r
- int f = lst.Last;\r
- }\r
-\r
-\r
- [Test]\r
- public void FirstLast()\r
- {\r
- lst.Add(19);\r
- Assert.AreEqual(19, lst.First);\r
- Assert.AreEqual(19, lst.Last);\r
- lst.Add(34); lst.InsertFirst(12);\r
- Assert.AreEqual(12, lst.First);\r
- Assert.AreEqual(34, lst.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void This()\r
- {\r
- lst.Add(34);\r
- Assert.AreEqual(34, lst[0]);\r
- lst[0] = 56;\r
- Assert.AreEqual(56, lst.First);\r
- lst.Add(7); lst.Add(77); lst.Add(777); lst.Add(7777);\r
- lst[0] = 45; lst[2] = 78; lst[4] = 101;\r
- Assert.IsTrue(IC.eq(lst, 45, 7, 78, 777, 101));\r
- }\r
-\r
- [Test]\r
- public void ThisWithUpdates()\r
- {\r
- HashedLinkedList<KeyValuePair<int, int>> pairlist = new HashedLinkedList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- pairlist.Add(new KeyValuePair<int, int>(10, 50));\r
- pairlist.Add(new KeyValuePair<int, int>(11, 51));\r
- pairlist.Add(new KeyValuePair<int, int>(12, 52));\r
- pairlist.Add(new KeyValuePair<int, int>(13, 53));\r
- pairlist[2] = new KeyValuePair<int, int>(12, 102);\r
- Assert.IsTrue(pairlist.Check());\r
- Assert.AreEqual(new KeyValuePair<int, int>(12, 102), pairlist[2]);\r
- pairlist[2] = new KeyValuePair<int, int>(22, 202);\r
- Assert.IsTrue(pairlist.Check());\r
- Assert.AreEqual(new KeyValuePair<int, int>(22, 202), pairlist[2]);\r
- pairlist[1] = new KeyValuePair<int, int>(12, 303);\r
- Assert.IsTrue(pairlist.Check());\r
- Assert.AreEqual(new KeyValuePair<int, int>(12, 303), pairlist[1]);\r
- Assert.AreEqual(new KeyValuePair<int, int>(22, 202), pairlist[2]);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentException))]\r
- public void ThisWithUpdatesBad()\r
- {\r
- HashedLinkedList<KeyValuePair<int, int>> pairlist = new HashedLinkedList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- pairlist.Add(new KeyValuePair<int, int>(10, 50));\r
- pairlist.Add(new KeyValuePair<int, int>(11, 51));\r
- pairlist.Add(new KeyValuePair<int, int>(12, 52));\r
- pairlist.Add(new KeyValuePair<int, int>(13, 53));\r
- pairlist[2] = new KeyValuePair<int, int>(11, 102);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptyGet()\r
- {\r
- int f = lst[0];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowGet()\r
- {\r
- lst.Add(7);\r
-\r
- int f = lst[-1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiGet()\r
- {\r
- lst.Add(6);\r
-\r
- int f = lst[1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptySet()\r
- {\r
- lst[0] = 4;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowSet()\r
- {\r
- lst.Add(7);\r
- lst[-1] = 9;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiSet()\r
- {\r
- lst.Add(6);\r
- lst[1] = 11;\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private IList<KeyValuePair<int, int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new HashedLinkedList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int, int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- Assert.AreEqual(4, lst[3].Key);\r
- Assert.AreEqual(34, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Inserting\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedLinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 4);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5));\r
- lst.Insert(3, 2);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5, 2));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(DuplicateNotAllowedException))]\r
- public void InsertDuplicate()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 5);\r
- }\r
-\r
- [Test]\r
- public void InsertAllDuplicate1()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- try\r
- {\r
- lst.InsertAll<int>(1, new int[] { 1, 2, 3, 4 });\r
- }\r
- catch (DuplicateNotAllowedException)\r
- {\r
- }\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 1, 2, 3));\r
- }\r
-\r
- [Test]\r
- public void InsertAllDuplicate2()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- try\r
- {\r
- lst.InsertAll<int>(1, new int[] { 5, 6, 5, 8 });\r
- }\r
- catch (DuplicateNotAllowedException)\r
- {\r
- }\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 5, 6, 3));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertLow()\r
- {\r
- lst.Add(7);\r
- lst.Insert(-1, 9);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertHi()\r
- {\r
- lst.Add(6);\r
- lst.Insert(2, 11);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- for (int i = 0; i < 7; i++)\r
- lst.Add(2 * i);\r
-\r
- Assert.IsTrue(lst.FIFO);\r
- Assert.AreEqual(0, lst.Remove());\r
- Assert.AreEqual(2, lst.Remove());\r
- lst.FIFO = false;\r
- Assert.AreEqual(12, lst.Remove());\r
- Assert.AreEqual(10, lst.Remove());\r
- lst.FIFO = true;\r
- Assert.AreEqual(4, lst.Remove());\r
- Assert.AreEqual(6, lst.Remove());\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- lst.InsertFirst(4);\r
- lst.InsertLast(5);\r
- lst.InsertFirst(14);\r
- lst.InsertLast(15);\r
- lst.InsertFirst(24);\r
- lst.InsertLast(25);\r
- lst.InsertFirst(34);\r
- lst.InsertLast(55);\r
- Assert.IsTrue(IC.eq(lst, 34, 24, 14, 4, 5, 15, 25, 55));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirst()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- lst.Add(5);\r
- lst.ViewOf(2).InsertFirst(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 3, 4, 5));\r
- lst.ViewOf(3).InsertFirst(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 4, 5));\r
- lst.ViewOf(5).InsertFirst(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 4, 9, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void BadViewOf()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- Assert.IsNull(lst.ViewOf(4));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAfter()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- lst.Add(5);\r
- lst.LastViewOf(2).InsertLast(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 7, 3, 4, 5));\r
- lst.LastViewOf(1).InsertLast(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 7, 3, 4, 5));\r
- lst.LastViewOf(5).InsertLast(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 7, 3, 4, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void BadInsertAfter()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(6);\r
- lst.Add(5);\r
- Assert.IsNull(lst.ViewOf(4));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
-\r
- IList<int> lst2 = new HashedLinkedList<int>();\r
-\r
- lst2.Add(7); lst2.Add(8); lst2.Add(9);\r
- lst.InsertAll(0, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 3, 4));\r
- lst.RemoveAll(lst2);\r
- lst.InsertAll(4, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 3, 4, 7, 8, 9));\r
- lst.RemoveAll(lst2);\r
- lst.InsertAll(2, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 7, 8, 9, 3, 4));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(DuplicateNotAllowedException))]\r
- public void InsertAllBad()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
-\r
- IList<int> lst2 = new HashedLinkedList<int>();\r
-\r
- lst2.Add(5); lst2.Add(2); lst2.Add(9);\r
- lst.InsertAll(0, lst2);\r
- }\r
-\r
-\r
- [Test]\r
- public void Map()\r
- {\r
- Fun<int, string> m = delegate(int i) { return "<<" + i + ">>"; };\r
- IList<string> r = lst.Map(m);\r
-\r
- Assert.IsTrue(((HashedLinkedList<string>)r).Check());\r
- Assert.IsTrue(r.IsEmpty);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- r = lst.Map(m);\r
- Assert.IsTrue(((HashedLinkedList<string>)r).Check());\r
- Assert.AreEqual(4, r.Count);\r
- for (int i = 0; i < 4; i++)\r
- Assert.AreEqual("<<" + (i + 1) + ">>", r[i]);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapper()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapperView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAllView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemove() { lst.Remove(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveFirst() { lst.RemoveFirst(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveLast() { lst.RemoveLast(); }\r
-\r
-\r
- [Test]\r
- public void RemoveFirstLast()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- Assert.AreEqual(1, lst.RemoveFirst());\r
- Assert.AreEqual(4, lst.RemoveLast());\r
- Assert.AreEqual(2, lst.RemoveFirst());\r
- Assert.AreEqual(3, lst.RemoveLast());\r
- Assert.IsTrue(lst.IsEmpty);\r
- }\r
-\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(0, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 0).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- lst.View(5, 1).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void BadReverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.View(8, 3).Reverse();\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class SortingTest\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedLinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- lst.Add(5); lst.Add(6); lst.Add(55); lst.Add(7); lst.Add(3);\r
- Assert.IsFalse(lst.IsSorted(new IC()));\r
- lst.Sort(new IC());\r
- Assert.IsTrue(lst.Check(), "Check ");\r
- Assert.IsTrue(lst.IsSorted());\r
- Assert.IsTrue(lst.IsSorted(new IC()));\r
- Assert.IsTrue(IC.eq(lst, 3, 5, 6, 7, 55));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ShuffleTests\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedLinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Shuffle()\r
- {\r
- lst.Add(5); lst.Add(6); lst.Add(5); lst.Add(7); lst.Add(3);\r
- for (int i = 0; i < 100; i++)\r
- {\r
- lst.Shuffle(new C5Random(i + 1));\r
- Assert.IsTrue(lst.Check(), "Check " + i);\r
- int[] lst2 = lst.ToArray();\r
- Sorting.IntroSort<int>(lst2);\r
- Assert.IsTrue(IC.eq(lst2, 3, 5, 6, 7), "Contents " + i);\r
- }\r
- }\r
- }\r
- }\r
-\r
- namespace Range\r
- {\r
- [TestFixture]\r
- public class Range\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new HashedLinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void GetRange()\r
- {\r
- //Assert.IsTrue(IC.eq(lst[0, 0)));\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst[0, 3], 0, 1, 2));\r
- Assert.IsTrue(IC.eq(lst[3, 3], 3, 4, 5));\r
- Assert.IsTrue(IC.eq(lst[6, 3], 6, 7, 8));\r
- Assert.IsTrue(IC.eq(lst[6, 4], 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void Backwards()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst.Backwards(), 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[0, 3].Backwards(), 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[3, 3].Backwards(), 5, 4, 3));\r
- Assert.IsTrue(IC.eq(lst[6, 4].Backwards(), 9, 8, 7, 6));\r
- }\r
-\r
-\r
- [Test]\r
- public void DirectionAndCount()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst.Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst[3, 7].Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst[3, 7].Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst.Backwards().Direction);\r
- Assert.AreEqual(4, lst[3, 4].Count);\r
- Assert.AreEqual(4, lst[3, 4].Backwards().Count);\r
- Assert.AreEqual(10, lst.Backwards().Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- foreach (int i in lst)\r
- {\r
- lst.Add(45 + i);\r
- }\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace View\r
- {\r
- [TestFixture]\r
- public class Simple\r
- {\r
- HashedLinkedList<int> list;\r
- HashedLinkedList<int> view;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedLinkedList<int>();\r
- list.Add(0); list.Add(1); list.Add(2); list.Add(3);\r
- view = (HashedLinkedList<int>)list.View(1, 2);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = null;\r
- view = null;\r
- }\r
-\r
-\r
- void check()\r
- {\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(view.Check());\r
- }\r
-\r
- [Test]\r
- public void InsertPointer()\r
- {\r
- IList<int> view2 = list.View(2, 0);\r
- list.Insert(view2, 7);\r
- check();\r
- list.Insert(list, 8);\r
- check();\r
- view.Insert(view2, 9);\r
- check();\r
- view.Insert(list.View(3, 2), 10);\r
- check();\r
- view.Insert(list.ViewOf(0), 11);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 11, 1, 9, 7, 2, 10, 3, 8));\r
- Assert.IsTrue(IC.eq(view, 11, 1, 9, 7, 2, 10));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad1()\r
- {\r
- view.Insert(list.View(0, 0), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad2()\r
- {\r
- view.Insert(list, 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad3()\r
- {\r
- list.Insert(new ArrayList<int>(), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad4()\r
- {\r
- list.Insert(new ArrayList<int>().View(0, 0), 7);\r
- }\r
-\r
- [Test]\r
- public void Span()\r
- {\r
- IList<int> span = list.View(1, 0).Span(list.View(2, 0));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(1, span.Offset);\r
- Assert.AreEqual(1, span.Count);\r
- span = list.View(0, 2).Span(list.View(2, 2));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(0, span.Offset);\r
- Assert.AreEqual(4, span.Count);\r
- span = list.View(3, 1).Span(list.View(1, 1));\r
- Assert.IsNull(span);\r
- }\r
-\r
- [Test]\r
- public void ViewOf()\r
- {\r
- for (int i = 0; i < 4; i++)\r
- list.Add(i);\r
- IList<int> v = view.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.LastViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- }\r
-\r
- [Test]\r
- public void BadViewOf()\r
- {\r
- Assert.IsNull(view.ViewOf(5));\r
- Assert.IsNull(view.LastViewOf(5));\r
- Assert.IsNull(view.ViewOf(3));\r
- Assert.IsNull(view.LastViewOf(3));\r
- Assert.IsNull(view.ViewOf(0));\r
- Assert.IsNull(view.LastViewOf(0));\r
- }\r
-\r
-\r
- [Test]\r
- public void ArrayStuff()\r
- {\r
- Assert.IsTrue(IC.eq(view.ToArray(), 1, 2));\r
- int[] extarray = new int[5];\r
- view.CopyTo(extarray, 2);\r
- Assert.IsTrue(IC.eq(extarray, 0, 0, 1, 2, 0));\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2));\r
- view.InsertFirst(10);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 10, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 10, 1, 2));\r
- view.Clear();\r
- Assert.IsFalse(view.IsReadOnly);\r
- Assert.IsFalse(view.AllowsDuplicates);\r
- Assert.IsTrue(view.IsEmpty);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 3));\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(8);\r
- Assert.IsFalse(view.IsEmpty);\r
- Assert.IsFalse(view.AllowsDuplicates);\r
- Assert.IsFalse(view.IsReadOnly);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 3));\r
- Assert.IsTrue(IC.eq(view, 8));\r
- view.Add(12);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12));\r
- view./*ViewOf(12).*/InsertLast(15);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12, 15));\r
- view.ViewOf(12).InsertFirst(18);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15));\r
-\r
- HashedLinkedList<int> lst2 = new HashedLinkedList<int>();\r
-\r
- lst2.Add(90); lst2.Add(92);\r
- view.AddAll(lst2);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92));\r
- view.InsertLast(66);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 66, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92, 66));\r
- }\r
-\r
-\r
- [Test]\r
- public void Bxxx()\r
- {\r
- Assert.IsTrue(IC.eq(view.Backwards(), 2, 1));\r
- Assert.AreSame(list, view.Underlying);\r
- Assert.IsNull(list.Underlying);\r
- Assert.AreEqual(EnumerationDirection.Forwards, view.Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, view.Backwards().Direction);\r
- Assert.AreEqual(0, list.Offset);\r
- Assert.AreEqual(1, view.Offset);\r
- }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsTrue(view.Contains(1));\r
- Assert.IsFalse(view.Contains(0));\r
-\r
- HashedLinkedList<int> lst2 = new HashedLinkedList<int>();\r
-\r
- lst2.Add(2);\r
- Assert.IsTrue(view.ContainsAll(lst2));\r
- lst2.Add(3);\r
- Assert.IsFalse(view.ContainsAll(lst2));\r
- Assert.AreEqual(Speed.Constant, view.ContainsSpeed);\r
- Assert.AreEqual(2, view.Count);\r
- view.Add(1);\r
- Assert.AreEqual(1, view.ContainsCount(2));\r
- Assert.AreEqual(1, view.ContainsCount(1));\r
- Assert.AreEqual(2, view.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void CreateView()\r
- {\r
- HashedLinkedList<int> view2 = (HashedLinkedList<int>)view.View(1, 0);\r
-\r
- Assert.AreSame(list, view2.Underlying);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- Assert.IsTrue(view.FIFO);\r
- view.Add(23); view.Add(24); view.Add(25);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 23, 24, 25));\r
- Assert.AreEqual(1, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24, 25));\r
- view.FIFO = false;\r
- Assert.IsFalse(view.FIFO);\r
- Assert.AreEqual(25, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24));\r
- }\r
-\r
-\r
- [Test]\r
- public void MapEtc()\r
- {\r
- HashedLinkedList<double> dbl = (HashedLinkedList<double>)view.Map(new Fun<int, double>(delegate(int i) { return i / 10.0; }));\r
-\r
- Assert.IsTrue(dbl.Check());\r
- Assert.AreEqual(0.1, dbl[0]);\r
- Assert.AreEqual(0.2, dbl[1]);\r
- for (int i = 0; i < 10; i++) view.Add(i);\r
-\r
- HashedLinkedList<int> list2 = (HashedLinkedList<int>)view.FindAll(new Fun<int, bool>(delegate(int i) { return i % 4 == 1; }));\r
-\r
- Assert.IsTrue(list2.Check());\r
- Assert.IsTrue(IC.eq(list2, 1, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void FL()\r
- {\r
- Assert.AreEqual(1, view.First);\r
- Assert.AreEqual(2, view.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void Indexing()\r
- {\r
- list.Clear();\r
- for (int i = 0; i < 20; i++) list.Add(i);\r
-\r
- view = (HashedLinkedList<int>)list.View(5, 7);\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i + 5, view[i]);\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.IndexOf(i + 5));\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.LastIndexOf(i + 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- view.Insert(0, 34);\r
- view.Insert(1, 35);\r
- view.Insert(4, 36);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 2, 36));\r
-\r
- IList<int> list2 = new HashedLinkedList<int>();\r
-\r
- list2.Add(40); list2.Add(41);\r
- view.InsertAll(3, list2);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 40, 41, 2, 36));\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- view.Add(45); view.Add(47); view.Add(46); view.Add(48);\r
- Assert.IsFalse(view.IsSorted(new IC()));\r
- view.Sort(new IC());\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 45, 46, 47, 48, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2, 45, 46, 47, 48));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- Assert.IsFalse(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- Assert.IsFalse(view.Remove(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- view.RemoveAllCopies(3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5));\r
- Assert.IsTrue(IC.eq(list, 0, 2, 5, 3));\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 2, 5, 1));\r
-\r
- HashedLinkedList<int> l2 = new HashedLinkedList<int>();\r
-\r
- l2.Add(1); l2.Add(2); l2.Add(2); l2.Add(3); l2.Add(1);\r
- view.RemoveAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 5));\r
- view.RetainAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(2); view.Add(4); view.Add(5);\r
- Assert.AreEqual(2, view.RemoveAt(0));\r
- Assert.AreEqual(5, view.RemoveAt(1));\r
- Assert.AreEqual(4, view.RemoveAt(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(8); view.Add(6); view.Add(78);\r
- Assert.AreEqual(8, view.RemoveFirst());\r
- Assert.AreEqual(78, view.RemoveLast());\r
- view.Add(2); view.Add(5); view.Add(3); view.Add(1);\r
- view.RemoveInterval(1, 2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 6, 1));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- view.Clear();\r
- for (int i = 0; i < 10; i++) view.Add(10 + i);\r
-\r
- view.View(3, 4).Reverse();\r
- check();\r
- Assert.IsTrue(IC.eq(view, 10, 11, 12, 16, 15, 14, 13, 17, 18, 19));\r
- view.Reverse();\r
- Assert.IsTrue(IC.eq(view, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10));\r
- Assert.IsTrue(IC.eq(list, 0, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10, 3));\r
- }\r
-\r
-\r
- [Test]\r
- public void Slide()\r
- {\r
- view.Slide(1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 3));\r
- view.Slide(-2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1));\r
- view.Slide(0, 3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1, 2));\r
- view.Slide(2, 1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2));\r
- view.Slide(-1, 0);\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(28);\r
- Assert.IsTrue(IC.eq(list, 0, 28, 1, 2, 3));\r
- }\r
- [Test]\r
- public void Iterate()\r
- {\r
- list.Clear();\r
- check();\r
- view = null;\r
- foreach (int i in new int[] { 2, 4, 8, 13, 6, 1, 10, 11 }) list.Add(i);\r
-\r
- view = (HashedLinkedList<int>)list.View(list.Count - 2, 2);\r
- int j = 666;\r
- while (true)\r
- {\r
- check();\r
- //Console.WriteLine("View: {0}: {1} --> {2}", view.Count, view.First, view.Last);\r
- if ((view.Last - view.First) % 2 == 1)\r
- view.Insert(1, j++);\r
- check();\r
- if (view.Offset == 0)\r
- break;\r
- else\r
- view.Slide(-1, 2);\r
- }\r
- //foreach (int cell in list) Console.Write(" " + cell);\r
- //Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 2, 4, 8, 668, 13, 6, 1, 667, 10, 666, 11));\r
- }\r
-\r
-\r
- [Test]\r
- public void SyncRoot()\r
- {\r
- Assert.AreSame(view.SyncRoot, list.SyncRoot);\r
- }\r
- }\r
- [TestFixture]\r
- public class MulipleViews\r
- {\r
- IList<int> list;\r
- IList<int>[][] views;\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new HashedLinkedList<int>();\r
- for (int i = 0; i < 6; i++)\r
- list.Add(i);\r
- views = new IList<int>[7][];\r
- for (int i = 0; i < 7; i++)\r
- {\r
- views[i] = new IList<int>[7 - i];\r
- for (int j = 0; j < 7 - i; j++)\r
- views[i][j] = list.View(i, j);\r
- }\r
- }\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = null;\r
- views = null;\r
- }\r
- [Test]\r
- public void Insert()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(3, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(3);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 3 && i + j > 3 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveInterval(3, 2);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i <= 5 ? 3 : i - 2, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j == 0 ? 0 : i <= 3 && i + j > 4 ? j - 2 : i > 4 || i + j <= 3 ? j : j - 1, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void InsertAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.InsertLast(777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(5);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 5 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 5 && i + j > 5 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void InsertAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(0, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 && j == 0 ? 0 : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(0);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i == 0 && j > 0 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void Clear()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before clear");\r
- //for (int i = 0; i < 7; i++)\r
- //for (int j = 0; j < 7 - i; j++)\r
- //Console.WriteLine("// view[{0}][{1}] : {2}", i, j, ((HashedLinkedList<int>) views[i][j]).GetHashCode());\r
- views[2][3].Clear();\r
- Assert.IsTrue(list.Check(), "list check after clear");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 2 ? i : i < 6 ? 2 : i - 3, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(s(i, j), views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- private int s(int i, int j)\r
- {\r
- if (j == 0) return 0;\r
- int k = i + j - 1; //end\r
- if (i > 4 || k <= 1) return j;\r
- if (i >= 2) return k > 4 ? k - 4 : 0;\r
- if (i <= 2) return k >= 4 ? j - 3 : 2 - i;\r
- return -1;\r
- }\r
- [Test]\r
- public void InsertAll()\r
- {\r
- IList<int> list2 = new HashedLinkedList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before insertAll");\r
- list.InsertAll(3, list2);\r
- Assert.IsTrue(list.Check(), "list check after insertAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- IList<int> list2 = new HashedLinkedList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before AddAll");\r
- list.View(1, 2).AddAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after AddAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new HashedLinkedList<int>();\r
- for (int k = 0; k < 6; k++) list.Add(k);\r
- HashedLinkedList<int> v = (HashedLinkedList<int>)list.View(i, j);\r
- list.Remove(3);\r
- Assert.IsTrue(list.Check(), "list check after Remove, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
- [Test]\r
- public void RemoveAll1()\r
- {\r
- IList<int> list2 = new HashedLinkedList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
-\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new HashedLinkedList<int>();\r
- for (int k = 0; k < 6; k++) list.Add(k);\r
- HashedLinkedList<int> v = (HashedLinkedList<int>)list.View(i, j);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
- [Test]\r
- public void RemoveAll2()\r
- {\r
- IList<int> list2 = new HashedLinkedList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
- Assert.IsTrue(list.Check(), "list check before RemoveAll");\r
- list.RemoveAll(list2);\r
-\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(1, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(1, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(1, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(1, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(1, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(1, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(1, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(1, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(1, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(1, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(1, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(2, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(2, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(2, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(2, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(2, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(2, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(2, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(1, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(1, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(2, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(2, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(1, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(2, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(1, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(2, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(0, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(1, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(0, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(1, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll");\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- IList<int> list2 = new HashedLinkedList<int>();\r
- list2.Add(2); list2.Add(4); list2.Add(5);\r
- Assert.IsTrue(list.Check(), "list check before RetainAll");\r
- list.RetainAll(list2);\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(0, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(0, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(0, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(0, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(0, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(0, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(0, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(0, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(0, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(0, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(0, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(1, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(1, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(1, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(1, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(1, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(1, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(1, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(0, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(0, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(1, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(1, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(2, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(3, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(2, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(3, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(1, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(2, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(1, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(2, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
-\r
- Assert.IsTrue(list.Check(), "list check after RetainAll");\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- IList<int> list2 = new HashedLinkedList<int>();\r
- list2.Add(0); list2.Add(2); list2.Add(82); list2.Add(92); list2.Add(5); list2.Add(2); list2.Add(1);\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new HashedLinkedList<int>();\r
- list.AddAll(list2);\r
- HashedLinkedList<int> v = (HashedLinkedList<int>)list.View(i, j);\r
- list.RemoveAllCopies(2);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAllCopies, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
-\r
- private void checkDisposed(bool reverse, int start, int count)\r
- {\r
- int k = 0;\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- if (i + j <= start || i >= start + count || (i <= start && i + j >= start + count) || (reverse && start <= i && start + count >= i + j))\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- }\r
- catch (ViewDisposedException)\r
- {\r
- Assert.Fail("view[" + i + "][" + j + "] threw");\r
- }\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] size");\r
- if (reverse && ((j > 0 && start <= i && start + count >= i + j) || (j == 0 && start < i && start + count > i)))\r
- Assert.AreEqual(start + (start + count - i - j), views[i][j].Offset, "view[" + i + "][" + j + "] offset (mirrored)");\r
- else\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- }\r
- else\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- Assert.Fail("view[" + i + "][" + j + "] no throw");\r
- }\r
- catch (ViewDisposedException) { }\r
- }\r
- }\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Reverse");\r
- list2.Reverse();\r
- Assert.IsTrue(list.Check(), "list check after Reverse");\r
- checkDisposed(true, start, count);\r
- }\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Sort");\r
- list2.Sort();\r
- Assert.IsTrue(list.Check(), "list check after Sort");\r
- checkDisposed(false, start, count);\r
- }\r
- [Test]\r
- public void Shuffle()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Shuffle");\r
- list2.Shuffle();\r
- Assert.IsTrue(list.Check(), "list check after Shuffle");\r
- checkDisposed(false, start, count);\r
- }\r
-\r
-\r
- }\r
-\r
- }\r
-\r
- namespace HashingAndEquals\r
- {\r
- [TestFixture]\r
- public class ISequenced\r
- {\r
- private ISequenced<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- dat = new HashedLinkedList<int>();\r
- dut = new HashedLinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- }\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.sequencedhashcode(), dit.GetSequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dit.GetSequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(3, 7), dit.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.sequencedhashcode(), dut.GetSequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(7), dut.GetSequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(7, 3), dut.GetSequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(0); dit.Add(31);\r
- dat.Add(1); dat.Add(0);\r
- Assert.AreEqual(dit.GetSequencedHashCode(), dat.GetSequencedHashCode());\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dat.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dut));\r
- Assert.IsTrue(dut.SequencedEquals(dit));\r
- dit.Add(7);\r
- ((HashedLinkedList<int>)dut).InsertFirst(7);\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- Assert.IsFalse(dut.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- dat = new HashedLinkedList<int>();\r
- dut = new HashedLinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(-1657792980); dit.Add(-1570288808);\r
- dat.Add(1862883298); dat.Add(-272461342);\r
- Assert.AreEqual(dit.GetUnsequencedHashCode(), dat.GetUnsequencedHashCode());\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnorderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ICollection<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- dat = new HashedLinkedList<int>();\r
- dut = new HashedLinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new HashedLinkedList<ICollection<int>>();\r
- Dat = new HashedLinkedList<ICollection<int>>();\r
- Dut = new HashedLinkedList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dat));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ISequenced<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- dat = new HashedLinkedList<int>();\r
- dut = new HashedLinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new HashedLinkedList<ICollection<int>>();\r
- Dat = new HashedLinkedList<ICollection<int>>();\r
- Dut = new HashedLinkedList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dit); Dut.Add(dut); Dut.Add(dat);\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ICollection<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- dat = new HashedLinkedList<int>();\r
- dut = new HashedLinkedList<int>();\r
- dot = new HashedLinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- dot.Add(2); dot.Add(1);\r
- Dit = new HashedLinkedList<ISequenced<int>>();\r
- Dat = new HashedLinkedList<ISequenced<int>>();\r
- Dut = new HashedLinkedList<ISequenced<int>>();\r
- Dot = new HashedLinkedList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dut));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dat));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ISequenced<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new HashedLinkedList<int>();\r
- dat = new HashedLinkedList<int>();\r
- dut = new HashedLinkedList<int>();\r
- dot = new HashedLinkedList<int>();\r
- dit.Add(2); dit.Add(1); //{2,1}\r
- dat.Add(1); dat.Add(2); //{1,2}\r
- dut.Add(3); //{3}\r
- dot.Add(2); dot.Add(1); //{2,1}\r
- Dit = new HashedLinkedList<ISequenced<int>>();\r
- Dat = new HashedLinkedList<ISequenced<int>>();\r
- Dut = new HashedLinkedList<ISequenced<int>>();\r
- Dot = new HashedLinkedList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit); // {{2,1},{3}}\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat); // {{3},{2,1},{1,2}}\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit); // {{2,1},{3}}\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut); // {{2,1},{3}}\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests.linkedlists.plain\r
-{\r
- using CollectionOfInt = LinkedList<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
-\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.ListTester<CollectionOfInt>().Test(factory);\r
- new C5UnitTests.Templates.Events.QueueTester<CollectionOfInt>().Test(factory);\r
- new C5UnitTests.Templates.Events.StackTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Clone.ViewTester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.ViewTester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new LinkedList<T>(); }\r
- }\r
-\r
- namespace Enumerable\r
- {\r
- [TestFixture]\r
- public class Multiops\r
- {\r
- private LinkedList<int> list;\r
-\r
- private Fun<int, bool> always, never, even;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new LinkedList<int>();\r
- always = delegate { return true; };\r
- never = delegate { return false; };\r
- even = delegate(int i) { return i % 2 == 0; };\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsTrue(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsTrue(list.All(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.All(always));\r
- Assert.IsFalse(list.All(never));\r
- Assert.IsFalse(list.All(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(5);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsFalse(list.Exists(even));\r
- list.Add(8);\r
- Assert.IsTrue(list.Exists(always));\r
- Assert.IsFalse(list.Exists(never));\r
- Assert.IsTrue(list.Exists(even));\r
- }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- int sum = 0;\r
- Act<int> a = delegate(int i) { sum = i + 10 * sum; };\r
-\r
- list.Apply(a);\r
- Assert.AreEqual(0, sum);\r
- sum = 0;\r
- list.Add(5); list.Add(8); list.Add(7); list.Add(5);\r
- list.Apply(a);\r
- Assert.AreEqual(5875, sum);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class GetEnumerator\r
- {\r
- private LinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new LinkedList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Empty()\r
- {\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
- list.Add(5);\r
- list.Add(10);\r
- list.Add(1);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(8, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(5, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(10, e.Current);\r
- Assert.IsTrue(e.MoveNext());\r
- Assert.AreEqual(1, e.Current);\r
- Assert.IsFalse(e.MoveNext());\r
- }\r
-\r
-\r
- [Test]\r
- public void DoDispose()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- e.MoveNext();\r
- e.Dispose();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- list.Add(5);\r
- list.Add(8);\r
- list.Add(5);\r
-\r
- SCG.IEnumerator<int> e = list.GetEnumerator();\r
-\r
- e.MoveNext();\r
- list.Add(99);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
- namespace CollectionOrExtensible\r
- {\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("[ ]", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("[ -4, 28, 129, 65530 ]", coll.ToString());\r
- Assert.AreEqual("[ -4, 1C, 81, FFFA ]", coll.ToString(null, rad16));\r
- Assert.AreEqual("[ -4, 28, 129... ]", coll.ToString("L14", null));\r
- Assert.AreEqual("[ -4, 1C, 81... ]", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class CollectionOrSink\r
- {\r
- private LinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new LinkedList<int>(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new LinkedList<int>(null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- list.Add(7);\r
- Assert.AreEqual(7, list.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- list.Choose();\r
- }\r
-\r
-\r
- [Test]\r
- public void CountEtAl()\r
- {\r
- Assert.AreEqual(0, list.Count);\r
- Assert.IsTrue(list.IsEmpty);\r
- Assert.IsTrue(list.AllowsDuplicates);\r
- list.Add(5);\r
- Assert.AreEqual(1, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- list.Add(5);\r
- Assert.AreEqual(2, list.Count);\r
- Assert.IsFalse(list.IsEmpty);\r
- list.Add(8);\r
- Assert.AreEqual(3, list.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- list.Add(3); list.Add(4); list.Add(5);\r
-\r
- LinkedList<int> list2 = new LinkedList<int>();\r
-\r
- list2.AddAll(list);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- list.AddAll(list2);\r
- Assert.IsTrue(IC.eq(list2, 3, 4, 5));\r
- Assert.IsTrue(IC.eq(list, 3, 4, 5, 3, 4, 5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private LinkedList<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new LinkedList<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- [Test]\r
- public void FindLast()\r
- {\r
- int i;\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.FindLast(pred, out i));\r
- Assert.AreEqual(675, i);\r
- }\r
-\r
- [Test]\r
- public void FindIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(4, list.FindIndex(pred));\r
- }\r
-\r
- [Test]\r
- public void FindLastIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(6, list.FindLastIndex(pred));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private LinkedList<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new LinkedList<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 2, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private LinkedList<int> list;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new LinkedList<int>();\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray()));\r
- list.Add(7);\r
- list.Add(7);\r
- Assert.AreEqual("Alles klar", aeq(list.ToArray(), 7, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- list.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(6);\r
- list.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- list.Add(4);\r
- list.Add(4);\r
- list.Add(9);\r
- list.CopyTo(a, 4);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 4, 9, 1008, 1009));\r
- list.Clear();\r
- list.Add(7);\r
- list.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 6, 4, 4, 9, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- list.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- list.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- list.Add(3);\r
- list.Add(3);\r
- list.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Sync\r
- {\r
- private LinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new LinkedList<int>();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
-\r
- [Test]\r
- public void Get()\r
- {\r
- Assert.IsNotNull(list.SyncRoot);\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace EditableCollection\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private LinkedList<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new LinkedList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsFalse(list.Contains(5));\r
- list.Add(5);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- list.Add(8);\r
- list.Add(10);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsTrue(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- list.Remove(8);\r
- Assert.IsTrue(list.Contains(5));\r
- Assert.IsFalse(list.Contains(7));\r
- Assert.IsFalse(list.Contains(8));\r
- Assert.IsTrue(list.Contains(10));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsCount()\r
- {\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- list.Add(5);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- list.Add(8);\r
- Assert.AreEqual(1, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- Assert.AreEqual(1, list.ContainsCount(8));\r
- list.Add(5);\r
- Assert.AreEqual(2, list.ContainsCount(5));\r
- Assert.AreEqual(0, list.ContainsCount(7));\r
- Assert.AreEqual(1, list.ContainsCount(8));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- list.Add(5); list.Add(7); list.Add(5);\r
- Assert.AreEqual(2, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.RemoveAllCopies(5);\r
- Assert.AreEqual(0, list.ContainsCount(5));\r
- Assert.AreEqual(1, list.ContainsCount(7));\r
- list.Add(5); list.Add(8); list.Add(5);\r
- list.RemoveAllCopies(8);\r
- Assert.IsTrue(IC.eq(list, 7, 5, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindAll()\r
- {\r
- Fun<int, bool> f = delegate(int i) { return i % 2 == 0; };\r
-\r
- Assert.IsTrue(list.FindAll(f).IsEmpty);\r
- list.Add(5); list.Add(8); list.Add(5); list.Add(10); list.Add(8);\r
- Assert.IsTrue(((LinkedList<int>)list.FindAll(f)).Check());\r
- Assert.IsTrue(IC.eq(list.FindAll(f), 8, 10, 8));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
-\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(list.ContainsAll(list2));\r
- list.Add(4);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list.Add(5);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- list2.Add(4);\r
- Assert.IsFalse(list.ContainsAll(list2));\r
- list.Add(4);\r
- Assert.IsTrue(list.ContainsAll(list2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
-\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7); list2.Add(7); list2.Add(4);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4, 5));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(5); list2.Add(5); list2.Add(6);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 5, 6));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RetainAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
-\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- list2.Add(5); list2.Add(4); list2.Add(7); list2.Add(7); list2.Add(4);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 6));\r
- list.Add(5); list.Add(4); list.Add(6);\r
- list2.Clear();\r
- list2.Add(6); list2.Add(5); list2.Add(5); list2.Add(6);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4));\r
- list2.Clear();\r
- list2.Add(7); list2.Add(8); list2.Add(9);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
-\r
- Assert.IsTrue(list.FIFO);\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- Assert.IsFalse(list.Remove(2));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(list.Remove(4));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5, 4, 6));\r
- Assert.AreEqual(6, list.RemoveLast());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5, 4));\r
- list.Add(7);\r
- Assert.AreEqual(4, list.RemoveFirst());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 5, 4, 7));\r
-\r
- list.FIFO = false;\r
- list.Clear();\r
- list.Add(4); list.Add(4); list.Add(5); list.Add(4); list.Add(6);\r
- Assert.IsFalse(list.Remove(2));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(list.Remove(4));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4, 5, 6));\r
- Assert.AreEqual(6, list.RemoveLast());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 4, 5));\r
- list.Add(7);\r
- Assert.AreEqual(4, list.RemoveFirst());\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 4, 5, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- list.Add(7); list.Add(7);\r
- list.Clear();\r
- Assert.IsTrue(list.IsEmpty);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace IIndexed\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void IndexOf()\r
- {\r
- Assert.AreEqual(~0, dit.IndexOf(6));\r
- dit.Add(7);\r
- Assert.AreEqual(~1, dit.IndexOf(6));\r
- Assert.AreEqual(~1, dit.LastIndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- dit.Add(5); dit.Add(7); dit.Add(8); dit.Add(7);\r
- Assert.AreEqual(~5, dit.IndexOf(6));\r
- Assert.AreEqual(0, dit.IndexOf(7));\r
- Assert.AreEqual(4, dit.LastIndexOf(7));\r
- Assert.AreEqual(3, dit.IndexOf(8));\r
- Assert.AreEqual(1, dit.LastIndexOf(5));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Removing\r
- {\r
- private IIndexed<int> dit;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- dit.Add(5); dit.Add(7); dit.Add(9); dit.Add(1); dit.Add(2);\r
- Assert.AreEqual(7, dit.RemoveAt(1));\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 5, 9, 1, 2));\r
- Assert.AreEqual(5, dit.RemoveAt(0));\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1, 2));\r
- Assert.AreEqual(2, dit.RemoveAt(2));\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 9, 1));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad0()\r
- {\r
- dit.RemoveAt(0);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBadM1()\r
- {\r
- dit.RemoveAt(-1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void RemoveAtBad1()\r
- {\r
- dit.Add(8);\r
- dit.RemoveAt(1);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- dit.RemoveInterval(0, 0);\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(3, 0);\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 40, 50, 60));\r
- dit.RemoveInterval(3, 1);\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 20, 30, 50, 60));\r
- dit.RemoveInterval(1, 3);\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 10, 60));\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit));\r
- dit.Add(10); dit.Add(20); dit.Add(30); dit.Add(40); dit.Add(50); dit.Add(60);\r
- dit.RemoveInterval(0, 2);\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40, 50, 60));\r
- dit.RemoveInterval(2, 2);\r
- Assert.IsTrue(((LinkedList<int>)dit).Check());\r
- Assert.IsTrue(IC.eq(dit, 30, 40));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace IList_\r
- {\r
- [TestFixture]\r
- public class Searching\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new LinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void FirstBad()\r
- {\r
- int f = lst.First;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void LastBad()\r
- {\r
- int f = lst.Last;\r
- }\r
-\r
-\r
- [Test]\r
- public void FirstLast()\r
- {\r
- lst.Add(19);\r
- Assert.AreEqual(19, lst.First);\r
- Assert.AreEqual(19, lst.Last);\r
- lst.Add(34); lst.InsertFirst(12);\r
- Assert.AreEqual(12, lst.First);\r
- Assert.AreEqual(34, lst.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void This()\r
- {\r
- lst.Add(34);\r
- Assert.AreEqual(34, lst[0]);\r
- lst[0] = 56;\r
- Assert.AreEqual(56, lst.First);\r
- lst.Add(7); lst.Add(7); lst.Add(7); lst.Add(7);\r
- lst[0] = 45; lst[2] = 78; lst[4] = 101;\r
- Assert.IsTrue(IC.eq(lst, 45, 7, 78, 7, 101));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptyGet()\r
- {\r
- int f = lst[0];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowGet()\r
- {\r
- lst.Add(7);\r
-\r
- int f = lst[-1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiGet()\r
- {\r
- lst.Add(6);\r
-\r
- int f = lst[1];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadEmptySet()\r
- {\r
- lst[0] = 4;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadLowSet()\r
- {\r
- lst.Add(7);\r
- lst[-1] = 9;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void ThisBadHiSet()\r
- {\r
- lst.Add(6);\r
- lst[1] = 11;\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private IList<KeyValuePair<int, int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new LinkedList<KeyValuePair<int, int>>(new KeyValuePairEqualityComparer<int, int>());\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int, int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- Assert.AreEqual(4, lst[3].Key);\r
- Assert.AreEqual(34, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Inserting\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new LinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 4);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5));\r
- lst.Insert(3, 2);\r
- Assert.IsTrue(IC.eq(lst, 7, 4, 5, 2));\r
- }\r
-\r
- [Test]\r
- public void InsertDuplicate()\r
- {\r
- lst.Insert(0, 5);\r
- Assert.IsTrue(IC.eq(lst, 5));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 5));\r
- lst.Insert(1, 5);\r
- Assert.IsTrue(IC.eq(lst, 7, 5, 5));\r
- }\r
-\r
- [Test]\r
- public void InsertAllDuplicate1()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- lst.InsertAll<int>(1, new int[] { 1, 2, 3, 4 });\r
- Assert.IsTrue(IC.eq(lst, 7, 1, 2, 3, 4, 3));\r
- Assert.IsTrue(lst.Check());\r
- }\r
- [Test]\r
- public void InsertAllDuplicate2()\r
- {\r
- lst.Insert(0, 3);\r
- Assert.IsTrue(IC.eq(lst, 3));\r
- lst.Insert(0, 7);\r
- Assert.IsTrue(IC.eq(lst, 7, 3));\r
- lst.InsertAll<int>(1, new int[] { 5, 6, 5, 8 });\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 5, 6, 5, 8, 3));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertLow()\r
- {\r
- lst.Add(7);\r
- lst.Insert(-1, 9);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void BadInsertHi()\r
- {\r
- lst.Add(6);\r
- lst.Insert(2, 11);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- for (int i = 0; i < 7; i++)\r
- lst.Add(2 * i);\r
-\r
- Assert.IsTrue(lst.FIFO);\r
- Assert.AreEqual(0, lst.Remove());\r
- Assert.AreEqual(2, lst.Remove());\r
- lst.FIFO = false;\r
- Assert.AreEqual(12, lst.Remove());\r
- Assert.AreEqual(10, lst.Remove());\r
- lst.FIFO = true;\r
- Assert.AreEqual(4, lst.Remove());\r
- Assert.AreEqual(6, lst.Remove());\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- lst.InsertFirst(4);\r
- lst.InsertLast(5);\r
- lst.InsertFirst(14);\r
- lst.InsertLast(15);\r
- lst.InsertFirst(24);\r
- lst.InsertLast(25);\r
- lst.InsertFirst(34);\r
- lst.InsertLast(55);\r
- Assert.IsTrue(IC.eq(lst, 34, 24, 14, 4, 5, 15, 25, 55));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertFirst()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- lst.ViewOf(2).InsertFirst(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 3, 2, 5));\r
- lst.ViewOf(3).InsertFirst(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 2, 5));\r
- lst.ViewOf(5).InsertFirst(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 2, 8, 3, 2, 9, 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void BadInsertFirst()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- Assert.IsNull(lst.ViewOf(4));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAfter()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- lst.LastViewOf(2).InsertLast(7);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 2, 3, 2, 7, 5));\r
- lst.LastViewOf(1).InsertLast(8);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 3, 2, 7, 5));\r
- lst.LastViewOf(5).InsertLast(9);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 1, 8, 2, 3, 2, 7, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void BadInsertAfter()\r
- {\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(2);\r
- lst.Add(5);\r
- Assert.IsNull(lst.ViewOf(4));\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
-\r
- IList<int> lst2 = new LinkedList<int>();\r
-\r
- lst2.Add(7); lst2.Add(8); lst2.Add(9);\r
- lst.InsertAll(0, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 3, 4));\r
- lst.InsertAll(7, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 3, 4, 7, 8, 9));\r
- lst.InsertAll(5, lst2);\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 1, 2, 7, 8, 9, 3, 4, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void Map()\r
- {\r
- Fun<int, string> m = delegate(int i) { return "<<" + i + ">>"; };\r
- IList<string> r = lst.Map(m);\r
-\r
- Assert.IsTrue(r.Check());\r
- Assert.IsTrue(r.IsEmpty);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- r = lst.Map(m);\r
- Assert.IsTrue(r.Check());\r
- Assert.AreEqual(4, r.Count);\r
- for (int i = 0; i < 4; i++)\r
- Assert.AreEqual("<<" + (i + 1) + ">>", r[i]);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapper()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAll()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void BadMapperView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.Map(m);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void ModifyingFindAllView()\r
- {\r
- lst = lst.View(0, 0);\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- Fun<int, bool> m = delegate(int i) { if (i == 2) lst.Add(7); return true; };\r
- lst.FindAll(m);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemove() { lst.Remove(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveFirst() { lst.RemoveFirst(); }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadRemoveLast() { lst.RemoveLast(); }\r
-\r
-\r
- [Test]\r
- public void RemoveFirstLast()\r
- {\r
- lst.Add(1);\r
- lst.Add(2);\r
- lst.Add(3);\r
- lst.Add(4);\r
- Assert.AreEqual(1, lst.RemoveFirst());\r
- Assert.AreEqual(4, lst.RemoveLast());\r
- Assert.AreEqual(2, lst.RemoveFirst());\r
- Assert.AreEqual(3, lst.RemoveLast());\r
- Assert.IsTrue(lst.IsEmpty);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void RemoveFirstEmpty()\r
- {\r
- lst.RemoveFirst();\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void RemoveLastEmpty()\r
- {\r
- lst.RemoveLast();\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(0, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 0).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 2, 1, 0));\r
- lst.View(7, 3).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- lst.View(5, 1).Reverse();\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(IC.eq(lst, 7, 8, 9, 6, 5, 4, 3, 0, 1, 2));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void BadReverse()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(i);\r
-\r
- lst.View(8, 3).Reverse();\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class SortingTests\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new LinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- lst.Add(5); lst.Add(6); lst.Add(5); lst.Add(7); lst.Add(3);\r
- Assert.IsFalse(lst.IsSorted(new IC()));\r
- lst.Sort(new IC());\r
- Assert.IsTrue(lst.Check());\r
- Assert.IsTrue(lst.IsSorted());\r
- Assert.IsTrue(lst.IsSorted(new IC()));\r
- Assert.IsTrue(IC.eq(lst, 3, 5, 5, 6, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void Stability()\r
- {\r
- IList<KeyValuePair<int, string>> lst2 = new LinkedList<KeyValuePair<int, string>>();\r
- SCG.IComparer<KeyValuePair<int, string>> c = new KeyValuePairComparer<int, string>(new IC());\r
-\r
- lst2.Add(new KeyValuePair<int, string>(5, "a"));\r
- lst2.Add(new KeyValuePair<int, string>(5, "b"));\r
- lst2.Add(new KeyValuePair<int, string>(6, "c"));\r
- lst2.Add(new KeyValuePair<int, string>(4, "d"));\r
- lst2.Add(new KeyValuePair<int, string>(3, "e"));\r
- lst2.Add(new KeyValuePair<int, string>(4, "f"));\r
- lst2.Add(new KeyValuePair<int, string>(5, "handle"));\r
- Assert.IsFalse(lst2.IsSorted(c));\r
- lst2.Sort(c);\r
- Assert.IsTrue(lst2.IsSorted(c));\r
-\r
- KeyValuePair<int, string> p = lst2.RemoveFirst();\r
-\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual("e", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(4, p.Key);\r
- Assert.AreEqual("d", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(4, p.Key);\r
- Assert.AreEqual("f", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(5, p.Key);\r
- Assert.AreEqual("a", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(5, p.Key);\r
- Assert.AreEqual("b", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(5, p.Key);\r
- Assert.AreEqual("handle", p.Value);\r
- p = lst2.RemoveFirst();\r
- Assert.AreEqual(6, p.Key);\r
- Assert.AreEqual("c", p.Value);\r
- Assert.IsTrue(lst2.IsEmpty);\r
- }\r
- }\r
- [TestFixture]\r
- public class ShuffleTests\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new LinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Shuffle()\r
- {\r
- lst.Add(5); lst.Add(6); lst.Add(5); lst.Add(7); lst.Add(3);\r
- for (int i = 0; i < 100; i++)\r
- {\r
- lst.Shuffle(new C5Random(i + 1));\r
- Assert.IsTrue(lst.Check(), "Check " + i);\r
- int[] lst2 = lst.ToArray();\r
- Sorting.IntroSort<int>(lst2);\r
- Assert.IsTrue(IC.eq(lst2, 3, 5, 5, 6, 7), "Contents " + i);\r
- }\r
- }\r
- }\r
- }\r
-\r
-\r
- namespace IStackQueue\r
- {\r
- [TestFixture]\r
- public class Stack\r
- {\r
- private IStack<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new LinkedList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Push(7);\r
- list.Push(5);\r
- list.Push(7);\r
- list.Push(8);\r
- list.Push(9);\r
- Assert.AreEqual(9, list.Pop());\r
- Assert.AreEqual(8, list.Pop());\r
- Assert.AreEqual(7, list.Pop());\r
- Assert.AreEqual(5, list.Pop());\r
- Assert.AreEqual(7, list.Pop());\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PopEmpty()\r
- {\r
- list.Push(5);\r
- Assert.AreEqual(5, list.Pop());\r
- list.Pop();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- [TestFixture]\r
- public class Queue\r
- {\r
- private IQueue<int> list;\r
-\r
-\r
- [SetUp]\r
- public void Init() { list = new LinkedList<int>(); }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- list.Enqueue(7);\r
- list.Enqueue(5);\r
- list.Enqueue(7);\r
- list.Enqueue(8);\r
- list.Enqueue(9);\r
- Assert.AreEqual(7, list.Dequeue());\r
- Assert.AreEqual(5, list.Dequeue());\r
- Assert.AreEqual(7, list.Dequeue());\r
- Assert.AreEqual(8, list.Dequeue());\r
- Assert.AreEqual(9, list.Dequeue());\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void DeQueueEmpty()\r
- {\r
- list.Enqueue(5);\r
- Assert.AreEqual(5, list.Dequeue());\r
- list.Dequeue();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
- }\r
- }\r
-\r
-\r
- namespace Range\r
- {\r
- [TestFixture]\r
- public class Range\r
- {\r
- private IList<int> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init() { lst = new LinkedList<int>(); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void GetRange()\r
- {\r
- //Assert.IsTrue(IC.eq(lst[0, 0)));\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst[0, 3], 0, 1, 2));\r
- Assert.IsTrue(IC.eq(lst[3, 4], 3, 4, 5, 6));\r
- Assert.IsTrue(IC.eq(lst[6, 4], 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void BadGetRange()\r
- {\r
- object foo = lst[0, 11];\r
- }\r
-\r
-\r
- [Test]\r
- public void Backwards()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.IsTrue(IC.eq(lst.Backwards(), 9, 8, 7, 6, 5, 4, 3, 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[0, 4].Backwards(), 3, 2, 1, 0));\r
- Assert.IsTrue(IC.eq(lst[3, 4].Backwards(), 6, 5, 4, 3));\r
- Assert.IsTrue(IC.eq(lst[6, 4].Backwards(), 9, 8, 7, 6));\r
- }\r
-\r
-\r
- [Test]\r
- public void DirectionAndCount()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst.Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, lst[3, 7].Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst[3, 7].Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, lst.Backwards().Direction);\r
- Assert.AreEqual(4, lst[3, 4].Count);\r
- Assert.AreEqual(4, lst[3, 4].Backwards().Count);\r
- Assert.AreEqual(10, lst.Backwards().Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterUpdate()\r
- {\r
- for (int i = 0; i < 10; i++) lst.Add(i);\r
-\r
- foreach (int i in lst)\r
- {\r
- lst.Add(45 + i);\r
- }\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace View\r
- {\r
- [TestFixture]\r
- public class Simple\r
- {\r
- LinkedList<int> list, view;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new LinkedList<int>();\r
- list.Add(0); list.Add(1); list.Add(2); list.Add(3);\r
- view = (LinkedList<int>)list.View(1, 2);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = view = null;\r
- }\r
-\r
-\r
- void check()\r
- {\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(view.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertPointer()\r
- {\r
- IList<int> view2 = list.View(2, 0);\r
- list.Insert(view2, 7);\r
- check();\r
- list.Insert(list, 8);\r
- check();\r
- view.Insert(view2, 9);\r
- check();\r
- view.Insert(list.View(3, 2), 10);\r
- check();\r
- view.Insert(list.ViewOf(0), 11);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 11, 1, 9, 7, 2, 10, 3, 8));\r
- Assert.IsTrue(IC.eq(view, 11, 1, 9, 7, 2, 10));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad1()\r
- {\r
- view.Insert(list.View(0, 0), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void InsertPointerBad2()\r
- {\r
- view.Insert(list, 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad3()\r
- {\r
- list.Insert(new ArrayList<int>(), 7);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(IncompatibleViewException))]\r
- public void InsertPointerBad4()\r
- {\r
- list.Insert(new ArrayList<int>().View(0, 0), 7);\r
- }\r
-\r
- [Test]\r
- public void Span()\r
- {\r
- IList<int> span = list.View(1, 0).Span(list.View(2, 0));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(1, span.Offset);\r
- Assert.AreEqual(1, span.Count);\r
- span = list.View(0, 2).Span(list.View(2, 2));\r
- Assert.IsTrue(span.Check());\r
- Assert.AreEqual(0, span.Offset);\r
- Assert.AreEqual(4, span.Count);\r
- span = list.View(3, 1).Span(list.View(1, 1));\r
- Assert.IsNull(span);\r
- }\r
-\r
- [Test]\r
- public void ViewOf()\r
- {\r
- for (int i = 0; i < 4; i++)\r
- list.Add(i);\r
- IList<int> v = view.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.ViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(2, v.Offset);\r
- v = list.LastViewOf(2);\r
- Assert.IsTrue(v.Check());\r
- Assert.IsTrue(IC.eq(v, 2));\r
- Assert.AreEqual(6, v.Offset);\r
- }\r
-\r
- [Test]\r
- public void BadViewOf()\r
- {\r
- Assert.IsNull(view.ViewOf(5));\r
- Assert.IsNull(view.LastViewOf(5));\r
- Assert.IsNull(view.ViewOf(3));\r
- Assert.IsNull(view.LastViewOf(3));\r
- Assert.IsNull(view.ViewOf(0));\r
- Assert.IsNull(view.LastViewOf(0));\r
- }\r
-\r
- [Test]\r
- public void ArrayStuff()\r
- {\r
- Assert.IsTrue(IC.eq(view.ToArray(), 1, 2));\r
- int[] extarray = new int[5];\r
- view.CopyTo(extarray, 2);\r
- Assert.IsTrue(IC.eq(extarray, 0, 0, 1, 2, 0));\r
- }\r
-\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2));\r
- view.InsertFirst(10);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 10, 1, 2, 3));\r
- Assert.IsTrue(IC.eq(view, 10, 1, 2));\r
- view.Clear();\r
- Assert.IsFalse(view.IsReadOnly);\r
- Assert.IsTrue(view.AllowsDuplicates);\r
- Assert.IsTrue(view.IsEmpty);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 3));\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(8);\r
- Assert.IsFalse(view.IsEmpty);\r
- Assert.IsTrue(view.AllowsDuplicates);\r
- Assert.IsFalse(view.IsReadOnly);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 3));\r
- Assert.IsTrue(IC.eq(view, 8));\r
- view.Add(12);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12));\r
- view./*ViewOf(12).*/InsertLast(15);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 12, 15));\r
- view.ViewOf(12).InsertFirst(18);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15));\r
-\r
- LinkedList<int> lst2 = new LinkedList<int>();\r
-\r
- lst2.Add(90); lst2.Add(92);\r
- view.AddAll(lst2);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92));\r
- view.InsertLast(66);\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 8, 18, 12, 15, 90, 92, 66, 3));\r
- Assert.IsTrue(IC.eq(view, 8, 18, 12, 15, 90, 92, 66));\r
- }\r
-\r
-\r
- [Test]\r
- public void Bxxx()\r
- {\r
- Assert.IsTrue(IC.eq(view.Backwards(), 2, 1));\r
- Assert.AreSame(list, view.Underlying);\r
- Assert.IsNull(list.Underlying);\r
- Assert.AreEqual(EnumerationDirection.Forwards, view.Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, view.Backwards().Direction);\r
- Assert.AreEqual(0, list.Offset);\r
- Assert.AreEqual(1, view.Offset);\r
- }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsTrue(view.Contains(1));\r
- Assert.IsFalse(view.Contains(0));\r
-\r
- LinkedList<int> lst2 = new LinkedList<int>();\r
-\r
- lst2.Add(2);\r
- Assert.IsTrue(view.ContainsAll(lst2));\r
- lst2.Add(3);\r
- Assert.IsFalse(view.ContainsAll(lst2));\r
- Assert.AreEqual(Speed.Linear, view.ContainsSpeed);\r
- Assert.AreEqual(2, view.Count);\r
- view.Add(1);\r
- Assert.AreEqual(1, view.ContainsCount(2));\r
- Assert.AreEqual(2, view.ContainsCount(1));\r
- Assert.AreEqual(3, view.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void CreateView()\r
- {\r
- LinkedList<int> view2 = (LinkedList<int>)view.View(1, 0);\r
-\r
- Assert.AreSame(list, view2.Underlying);\r
- }\r
-\r
-\r
- [Test]\r
- public void FIFO()\r
- {\r
- Assert.IsTrue(view.FIFO);\r
- view.Add(23); view.Add(24); view.Add(25);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 23, 24, 25));\r
- Assert.AreEqual(1, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24, 25));\r
- view.FIFO = false;\r
- Assert.IsFalse(view.FIFO);\r
- Assert.AreEqual(25, view.Remove());\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 23, 24));\r
- }\r
-\r
-\r
- [Test]\r
- public void MapEtc()\r
- {\r
- LinkedList<double> dbl = (LinkedList<double>)view.Map(new Fun<int, double>(delegate(int i) { return i / 10.0; }));\r
-\r
- Assert.IsTrue(dbl.Check());\r
- Assert.AreEqual(0.1, dbl[0]);\r
- Assert.AreEqual(0.2, dbl[1]);\r
- for (int i = 0; i < 10; i++) view.Add(i);\r
-\r
- list = (LinkedList<int>)view.FindAll(new Fun<int, bool>(delegate(int i) { return i % 4 == 1; }));\r
- Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 1, 1, 5, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void FL()\r
- {\r
- Assert.AreEqual(1, view.First);\r
- Assert.AreEqual(2, view.Last);\r
- }\r
-\r
-\r
- [Test]\r
- public void Indexing()\r
- {\r
- list.Clear();\r
- for (int i = 0; i < 20; i++) list.Add(i);\r
-\r
- view = (LinkedList<int>)list.View(5, 7);\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i + 5, view[i]);\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.IndexOf(i + 5));\r
-\r
- for (int i = 0; i < 7; i++) Assert.AreEqual(i, view.LastIndexOf(i + 5));\r
- }\r
-\r
-\r
- [Test]\r
- public void INsert()\r
- {\r
- view.Insert(0, 34);\r
- view.Insert(1, 35);\r
- view.Insert(4, 36);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 2, 36));\r
-\r
- IList<int> list2 = new LinkedList<int>();\r
-\r
- list2.AddAll(view);\r
- view.InsertAll(3, list2);\r
- Assert.IsTrue(view.Check());\r
- Assert.IsTrue(IC.eq(view, 34, 35, 1, 34, 35, 1, 2, 36, 2, 36));\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- view.Add(45); view.Add(47); view.Add(46); view.Add(48);\r
- Assert.IsFalse(view.IsSorted(new IC()));\r
- view.Sort(new IC());\r
- check();\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 45, 46, 47, 48, 3));\r
- Assert.IsTrue(IC.eq(view, 1, 2, 45, 46, 47, 48));\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- view.FIFO = false;\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 1, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 1, 5, 3, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5, 3, 3, 0));\r
- Assert.IsTrue(view.Remove(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5, 3, 3));\r
- view.RemoveAllCopies(3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5));\r
- Assert.IsTrue(IC.eq(list, 0, 1, 2, 5, 3));\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 5, 1, 5, 3, 1, 3, 0));\r
-\r
- view.FIFO = true;\r
- view.Clear(); view.Add(1); view.Add(2);\r
-\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 1, 2, 1, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 1, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5, 3, 1, 3, 0));\r
- Assert.IsTrue(view.Remove(0));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5, 3, 1, 3));\r
- view.RemoveAllCopies(3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 5, 1));\r
- Assert.IsTrue(IC.eq(list, 0, 2, 5, 1, 3));\r
- view.Add(1); view.Add(5); view.Add(3); view.Add(1); view.Add(3); view.Add(0);\r
- Assert.IsTrue(IC.eq(view, 2, 5, 1, 1, 5, 3, 1, 3, 0));\r
-\r
- LinkedList<int> l2 = new LinkedList<int>();\r
-\r
- l2.Add(1); l2.Add(2); l2.Add(2); l2.Add(3); l2.Add(1);\r
- view.RemoveAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 5, 5, 1, 3, 0));\r
- view.RetainAll(l2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 1, 3));\r
- view.Add(2); view.Add(4); view.Add(5);\r
- Assert.AreEqual(1, view.RemoveAt(0));\r
- Assert.AreEqual(5, view.RemoveAt(3));\r
- Assert.AreEqual(2, view.RemoveAt(1));\r
- check();\r
- Assert.IsTrue(IC.eq(view, 3, 4));\r
- view.Add(8);\r
- Assert.AreEqual(3, view.RemoveFirst());\r
- Assert.AreEqual(8, view.RemoveLast());\r
- view.Add(2); view.Add(5); view.Add(3); view.Add(1);\r
- view.RemoveInterval(1, 2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 4, 3, 1));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- view.Clear();\r
- for (int i = 0; i < 10; i++) view.Add(10 + i);\r
-\r
- view.View(3, 4).Reverse();\r
- check();\r
- Assert.IsTrue(IC.eq(view, 10, 11, 12, 16, 15, 14, 13, 17, 18, 19));\r
- view.Reverse();\r
- Assert.IsTrue(IC.eq(view, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10));\r
- Assert.IsTrue(IC.eq(list, 0, 19, 18, 17, 13, 14, 15, 16, 12, 11, 10, 3));\r
- }\r
-\r
-\r
- [Test]\r
- public void Slide()\r
- {\r
- view.Slide(1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2, 3));\r
- view.Slide(-2);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1));\r
- view.Slide(0, 3);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 0, 1, 2));\r
- view.Slide(2, 1);\r
- check();\r
- Assert.IsTrue(IC.eq(view, 2));\r
- Assert.AreEqual(view, view.Slide(-1, 0));\r
- check();\r
- Assert.IsTrue(IC.eq(view));\r
- view.Add(28);\r
- Assert.IsTrue(IC.eq(list, 0, 28, 1, 2, 3));\r
- }\r
- [Test]\r
- public void Iterate()\r
- {\r
- list.Clear();\r
- view = null;\r
- foreach (int i in new int[] { 2, 4, 8, 13, 6, 1, 2, 7 }) list.Add(i);\r
-\r
- view = (LinkedList<int>)list.View(list.Count - 2, 2);\r
- while (true)\r
- {\r
- //Console.WriteLine("View: {0}: {1} --> {2}", view.Count, view.First, view.Last);\r
- if ((view.Last - view.First) % 2 == 1)\r
- view.Insert(1, 666);\r
- check();\r
- if (view.Offset == 0)\r
- break;\r
- else\r
- view.Slide(-1, 2);\r
- }\r
- //foreach (int cell in list) Console.Write(" " + cell);\r
- //Assert.IsTrue(list.Check());\r
- Assert.IsTrue(IC.eq(list, 2, 4, 8, 666, 13, 6, 1, 666, 2, 666, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void SyncRoot()\r
- {\r
- Assert.AreSame(view.SyncRoot, list.SyncRoot);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class MulipleViews\r
- {\r
- IList<int> list;\r
- IList<int>[][] views;\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new LinkedList<int>();\r
- for (int i = 0; i < 6; i++)\r
- list.Add(i);\r
- views = new IList<int>[7][];\r
- for (int i = 0; i < 7; i++)\r
- {\r
- views[i] = new IList<int>[7 - i];\r
- for (int j = 0; j < 7 - i; j++)\r
- views[i][j] = list.View(i, j);\r
- }\r
- }\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = null;\r
- views = null;\r
- }\r
- [Test]\r
- public void Insert()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(3, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(3);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 3 && i + j > 3 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveInterval(3, 2);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 3 ? i : i <= 5 ? 3 : i - 2, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j == 0 ? 0 : i <= 3 && i + j > 4 ? j - 2 : i > 4 || i + j <= 3 ? j : j - 1, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void InsertAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.InsertLast(777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtEnd()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(5);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i <= 5 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i <= 5 && i + j > 5 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void InsertAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before insert");\r
- list.Insert(0, 777);\r
- Assert.IsTrue(list.Check(), "list check after insert");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 && j == 0 ? 0 : i + 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void RemoveAtStart()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before remove");\r
- list.RemoveAt(0);\r
- Assert.IsTrue(list.Check(), "list check after remove");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i == 0 ? i : i - 1, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i == 0 && j > 0 ? j - 1 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
- [Test]\r
- public void Clear()\r
- {\r
- Assert.IsTrue(list.Check(), "list check before clear");\r
- views[2][3].Clear();\r
- Assert.IsTrue(list.Check(), "list check after clear");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 2 ? i : i < 6 ? 2 : i - 3, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(s(i, j), views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- private int s(int i, int j)\r
- {\r
- if (j == 0) return 0;\r
- int k = i + j - 1; //end\r
- if (i > 4 || k <= 1) return j;\r
- if (i >= 2) return k > 4 ? k - 4 : 0;\r
- if (i <= 2) return k >= 4 ? j - 3 : 2 - i;\r
- return -1;\r
- }\r
- [Test]\r
- public void InsertAll()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before insertAll");\r
- list.InsertAll(3, list2);\r
- Assert.IsTrue(list.Check(), "list check after insertAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
- for (int i = 0; i < 5; i++) { list2.Add(100 + i); }\r
- Assert.IsTrue(list.Check(), "list check before AddAll");\r
- list.View(1, 2).AddAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after AddAll");\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- Assert.AreEqual(i < 3 || (i == 3 && j == 0) ? i : i + 5, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- Assert.AreEqual(i < 3 && i + j > 3 ? j + 5 : j, views[i][j].Count, "view[" + i + "][" + j + "] count");\r
- }\r
- }\r
-\r
- [Test]\r
- public void RemoveAll1()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
-\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new LinkedList<int>();\r
- for (int k = 0; k < 6; k++) list.Add(k);\r
- LinkedList<int> v = (LinkedList<int>)list.View(i, j);\r
- list.RemoveAll(list2);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
- [Test]\r
- public void RemoveAll2()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
- list2.Add(1); list2.Add(3); list2.Add(4);\r
- Assert.IsTrue(list.Check(), "list check before RemoveAll");\r
- list.RemoveAll(list2);\r
-\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(1, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(1, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(1, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(1, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(1, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(1, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(1, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(1, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(1, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(1, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(1, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(2, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(2, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(2, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(2, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(2, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(2, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(2, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(1, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(1, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(2, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(2, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(1, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(2, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(1, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(2, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(0, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(1, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(0, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(1, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
- Assert.IsTrue(list.Check(), "list check after RemoveAll");\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
- list2.Add(2); list2.Add(4); list2.Add(5);\r
- Assert.IsTrue(list.Check(), "list check before RetainAll");\r
- list.RetainAll(list2);\r
- Assert.AreEqual(0, views[0][0].Offset, "view [0][0] offset");\r
- Assert.AreEqual(0, views[0][1].Offset, "view [0][1] offset");\r
- Assert.AreEqual(0, views[0][2].Offset, "view [0][2] offset");\r
- Assert.AreEqual(0, views[0][3].Offset, "view [0][3] offset");\r
- Assert.AreEqual(0, views[0][4].Offset, "view [0][4] offset");\r
- Assert.AreEqual(0, views[0][5].Offset, "view [0][5] offset");\r
- Assert.AreEqual(0, views[0][6].Offset, "view [0][6] offset");\r
- Assert.AreEqual(0, views[1][0].Offset, "view [1][0] offset");\r
- Assert.AreEqual(0, views[1][1].Offset, "view [1][1] offset");\r
- Assert.AreEqual(0, views[1][2].Offset, "view [1][2] offset");\r
- Assert.AreEqual(0, views[1][3].Offset, "view [1][3] offset");\r
- Assert.AreEqual(0, views[1][4].Offset, "view [1][4] offset");\r
- Assert.AreEqual(0, views[1][5].Offset, "view [1][5] offset");\r
- Assert.AreEqual(0, views[2][0].Offset, "view [2][0] offset");\r
- Assert.AreEqual(0, views[2][1].Offset, "view [2][1] offset");\r
- Assert.AreEqual(0, views[2][2].Offset, "view [2][2] offset");\r
- Assert.AreEqual(0, views[2][3].Offset, "view [2][3] offset");\r
- Assert.AreEqual(0, views[2][4].Offset, "view [2][4] offset");\r
- Assert.AreEqual(1, views[3][0].Offset, "view [3][0] offset");\r
- Assert.AreEqual(1, views[3][1].Offset, "view [3][1] offset");\r
- Assert.AreEqual(1, views[3][2].Offset, "view [3][2] offset");\r
- Assert.AreEqual(1, views[3][3].Offset, "view [3][3] offset");\r
- Assert.AreEqual(1, views[4][0].Offset, "view [4][0] offset");\r
- Assert.AreEqual(1, views[4][1].Offset, "view [4][1] offset");\r
- Assert.AreEqual(1, views[4][2].Offset, "view [4][2] offset");\r
- Assert.AreEqual(2, views[5][0].Offset, "view [5][0] offset");\r
- Assert.AreEqual(2, views[5][1].Offset, "view [5][1] offset");\r
- Assert.AreEqual(3, views[6][0].Offset, "view [6][0] offset");\r
-\r
- Assert.AreEqual(0, views[0][0].Count, "view [0][0] count");\r
- Assert.AreEqual(0, views[0][1].Count, "view [0][1] count");\r
- Assert.AreEqual(0, views[0][2].Count, "view [0][2] count");\r
- Assert.AreEqual(1, views[0][3].Count, "view [0][3] count");\r
- Assert.AreEqual(1, views[0][4].Count, "view [0][4] count");\r
- Assert.AreEqual(2, views[0][5].Count, "view [0][5] count");\r
- Assert.AreEqual(3, views[0][6].Count, "view [0][6] count");\r
- Assert.AreEqual(0, views[1][0].Count, "view [1][0] count");\r
- Assert.AreEqual(0, views[1][1].Count, "view [1][1] count");\r
- Assert.AreEqual(1, views[1][2].Count, "view [1][2] count");\r
- Assert.AreEqual(1, views[1][3].Count, "view [1][3] count");\r
- Assert.AreEqual(2, views[1][4].Count, "view [1][4] count");\r
- Assert.AreEqual(3, views[1][5].Count, "view [1][5] count");\r
- Assert.AreEqual(0, views[2][0].Count, "view [2][0] count");\r
- Assert.AreEqual(1, views[2][1].Count, "view [2][1] count");\r
- Assert.AreEqual(1, views[2][2].Count, "view [2][2] count");\r
- Assert.AreEqual(2, views[2][3].Count, "view [2][3] count");\r
- Assert.AreEqual(3, views[2][4].Count, "view [2][4] count");\r
- Assert.AreEqual(0, views[3][0].Count, "view [3][0] count");\r
- Assert.AreEqual(0, views[3][1].Count, "view [3][1] count");\r
- Assert.AreEqual(1, views[3][2].Count, "view [3][2] count");\r
- Assert.AreEqual(2, views[3][3].Count, "view [3][3] count");\r
- Assert.AreEqual(0, views[4][0].Count, "view [4][0] count");\r
- Assert.AreEqual(1, views[4][1].Count, "view [4][1] count");\r
- Assert.AreEqual(2, views[4][2].Count, "view [4][2] count");\r
- Assert.AreEqual(0, views[5][0].Count, "view [5][0] count");\r
- Assert.AreEqual(1, views[5][1].Count, "view [5][1] count");\r
- Assert.AreEqual(0, views[6][0].Count, "view [6][0] count");\r
-\r
-\r
- Assert.IsTrue(list.Check(), "list check after RetainAll");\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- LinkedList<int> list2 = new LinkedList<int>();\r
- list2.Add(0); list2.Add(2); list2.Add(2); list2.Add(2); list2.Add(5); list2.Add(2); list2.Add(1);\r
- for (int i = 0; i < 7; i++)\r
- {\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- list = new LinkedList<int>();\r
- list.AddAll(list2);\r
- LinkedList<int> v = (LinkedList<int>)list.View(i, j);\r
- list.RemoveAllCopies(2);\r
- Assert.AreEqual(i == 0 ? 0 : i <= 4 ? 1 : i <= 6 ? 2 : 3, v.Offset, "v.Offset, i=" + i + ", j=" + j);\r
- Assert.AreEqual((i == 0 && j > 0 ? 1 : 0) + (i <= 4 && i + j > 4 ? 1 : 0) + (i <= 6 && i + j > 6 ? 1 : 0), v.Count, "v.Count, i=" + i + ", j=" + j);\r
- Assert.IsTrue(list.Check(), "list check after RemoveAllCopies, i=" + i + ", j=" + j);\r
- }\r
- }\r
- }\r
-\r
- private void checkDisposed(bool reverse, int start, int count)\r
- {\r
- int k = 0;\r
- for (int i = 0; i < 7; i++)\r
- for (int j = 0; j < 7 - i; j++)\r
- {\r
- if (i + j <= start || i >= start + count || (i <= start && i + j >= start + count) || (reverse && start <= i && start + count >= i + j))\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- }\r
- catch (ViewDisposedException)\r
- {\r
- Assert.Fail("view[" + i + "][" + j + "] threw");\r
- }\r
- Assert.AreEqual(j, views[i][j].Count, "view[" + i + "][" + j + "] size");\r
- if (reverse && ((j > 0 && start <= i && start + count >= i + j) || (j == 0 && start < i && start + count > i)))\r
- Assert.AreEqual(start + (start + count - i - j), views[i][j].Offset, "view[" + i + "][" + j + "] offset (mirrored)");\r
- else\r
- Assert.AreEqual(i, views[i][j].Offset, "view[" + i + "][" + j + "] offset");\r
- }\r
- else\r
- {\r
- try\r
- {\r
- k = views[i][j].Count;\r
- Assert.Fail("view[" + i + "][" + j + "] no throw");\r
- }\r
- catch (ViewDisposedException) { }\r
- }\r
- }\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Reverse");\r
- list2.Reverse();\r
- Assert.IsTrue(list.Check(), "list check after Reverse");\r
- checkDisposed(true, start, count);\r
- }\r
- [Test]\r
- public void Sort()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Sort");\r
- list2.Sort();\r
- Assert.IsTrue(list.Check(), "list check after Sort");\r
- checkDisposed(false, start, count);\r
- }\r
- [Test]\r
- public void Shuffle()\r
- {\r
- int start = 2, count = 3;\r
- IList<int> list2 = list.View(start, count);\r
- Assert.IsTrue(list.Check(), "list check before Shuffle");\r
- list2.Shuffle();\r
- Assert.IsTrue(list.Check(), "list check after Shuffle");\r
- checkDisposed(false, start, count);\r
- }\r
-\r
-\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Validity\r
- {\r
- IList<int> list;\r
- IList<int> view;\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new LinkedList<int>();\r
- for (int i = 0; i < 6; i++)\r
- list.Add(i);\r
- view = list.View(2, 3);\r
- view.Dispose();\r
- }\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- list = null;\r
- view = null;\r
- }\r
-\r
- //Properties\r
-\r
- //\r
- /*ActiveEvents,\r
-AllowsDuplicates,\r
-ContainsSpeed,\r
-Count,\r
-CountSpeed,\r
-Direction,\r
-DuplicatesByCounting,\r
-FIFO,\r
-First,\r
-EqualityComparer,\r
-IsEmpty,\r
-IsReadOnly,\r
-this[int index],\r
-this[int start, int count],\r
-Last,\r
-Offset,\r
-SyncRoot,\r
-Underlying\r
-*/\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Add()\r
- {\r
- view.Add(5);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void AddAll_int_()\r
- {\r
- view.AddAll<int>(new int[] { });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void AddAll()\r
- {\r
- view.AddAll<int>(new int[] { });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void All()\r
- {\r
- view.All(delegate(int i) { return false; });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Apply()\r
- {\r
- view.Apply(delegate(int i) { });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Backwards()\r
- {\r
- view.Backwards();\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Choose()\r
- {\r
- view.Choose();\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Contains()\r
- {\r
- view.Contains(0);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Clear()\r
- {\r
- view.Clear();\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void ContainsAll()\r
- {\r
- view.ContainsAll<int>(new int[] { });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void ContainsCount()\r
- {\r
- view.ContainsCount(0);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void CopyTo()\r
- {\r
- view.CopyTo(new int[1], 0);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Dequeue()\r
- {\r
- ((LinkedList<int>)view).Dequeue();\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Enqueue()\r
- {\r
- ((LinkedList<int>)view).Enqueue(0);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Exists()\r
- {\r
- view.Exists(delegate(int i) { return false; });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Filter()\r
- {\r
- view.Filter(delegate(int i) { return true; });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void Find()\r
- {\r
- int i = 0;\r
- view.Find(ref i);\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void FindAll()\r
- {\r
- view.FindAll(delegate(int i) { return false; });\r
- }\r
- [Test]\r
- [ExpectedException(typeof(ViewDisposedException))]\r
- public void FindOrAdd()\r
- {\r
- int i = 0;\r
- view.FindOrAdd(ref i);\r
- }\r
-\r
- //TODO: wonder if it is allright to wait with the exception till the enumerator is actually used?\r
- /* [Test]\r
- [ExpectedException(typeof(ListDisposedException))]\r
- public void GetEnumerator()\r
- {\r
- view.GetEnumerator();\r
- }\r
- */\r
- /*Method overview\r
- Check(),\r
- checkRange(int start, int count),\r
- Dispose(),\r
- Equals(object obj),\r
- Finalize(),\r
- fireBagItemsAdded(T item, int count),\r
- fireBagItemsRemoved(T item, int count),\r
- fireCollectionChanged(),\r
- fireCollectionCleared(int start, int count),\r
- fireItemAdded(T item),\r
- fireItemInserted(T item, int index),\r
- fireItemRemoved(T item),\r
- fireItemRemovedAt(T item, int index),\r
- GetEnumerator(),\r
- GetHashCode(),\r
- GetSequencedHashCode(),\r
- GetType(),\r
- GetUnsequencedHashCode(),\r
- IndexOf(T item),\r
- Insert(int i, T item),\r
- ViewOf().InsertLast(T item, T target),\r
- InsertAll(int i, IEnumerable<T> items),\r
- ViewOf().InsertFirst(T item, T target),\r
- InsertFirst(T item),\r
- InsertLast(T item),\r
- IsSorted(SCG.IComparer<T> c),\r
- LastIndexOf(T item),\r
- LastViewOf(T item),\r
- Map<V>(Fun<T,V> mapper),\r
- Map<V>(Fun<T,V> mapper, SCG.IEqualityComparer<V> equalityComparer),\r
- MemberwiseClone(),\r
- modifycheck(int stamp),\r
- Pop(),\r
- Push(T item),\r
- Remove(),\r
- Remove(T item),\r
- Remove(T item, out T removeditem),\r
- RemoveAll(IEnumerable<T> items),\r
- RemoveAllCopies(T item),\r
- RemoveAt(int i),\r
- RemoveFirst(),\r
- RemoveInterval(int start, int count),\r
- RemoveLast(),\r
- RetainAll(IEnumerable<T> items),\r
- Reverse(),\r
- Reverse(int start, int count),\r
- SequencedEquals(ISequenced<T> that),\r
- Shuffle(),\r
- Shuffle(System.Random rnd),\r
- Slide(int offset),\r
- Slide(int offset, int size),\r
- Sort(),\r
- Sort(SCG.IComparer<T> c),\r
- ToArray(),\r
- ToString(),\r
- UnsequencedEquals(ICollection<T> that),\r
- Update(T item),\r
- Update(T item, out T olditem),\r
- updatecheck(),\r
- UpdateOrAdd(T item),\r
- UpdateOrAdd(T item, out T olditem),\r
- View(int start, int count),\r
- ViewOf(T item)\r
- */\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace LinkedListOfTreesORLists\r
- {\r
- [TestFixture]\r
- public class MultiLevelUnorderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ICollection<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new LinkedList<ICollection<int>>();\r
- Dat = new LinkedList<ICollection<int>>();\r
- Dut = new LinkedList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dat));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ISequenced<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new LinkedList<ICollection<int>>();\r
- Dat = new LinkedList<ICollection<int>>();\r
- Dut = new LinkedList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dit); Dut.Add(dut); Dut.Add(dat);\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ICollection<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- dot = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(2); dat.Add(1);\r
- dut.Add(3);\r
- dot.Add(1); dot.Add(2);\r
- Dit = new LinkedList<ISequenced<int>>();\r
- Dat = new LinkedList<ISequenced<int>>();\r
- Dut = new LinkedList<ISequenced<int>>();\r
- Dot = new LinkedList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dut));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dat));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ISequenced<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- dot = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(2); dat.Add(1);\r
- dut.Add(3);\r
- dot.Add(1); dot.Add(2);\r
- Dit = new LinkedList<ISequenced<int>>();\r
- Dat = new LinkedList<ISequenced<int>>();\r
- Dut = new LinkedList<ISequenced<int>>();\r
- Dot = new LinkedList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsFalse(Dit.SequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace HashingAndEquals\r
- {\r
- [TestFixture]\r
- public class ISequenced\r
- {\r
- private ISequenced<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- }\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.sequencedhashcode(), dit.GetSequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dit.GetSequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(3, 7), dit.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.sequencedhashcode(), dut.GetSequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(7), dut.GetSequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(7, 3), dut.GetSequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(0); dit.Add(31);\r
- dat.Add(1); dat.Add(0);\r
- Assert.AreEqual(dit.GetSequencedHashCode(), dat.GetSequencedHashCode());\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dat.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dut));\r
- Assert.IsTrue(dut.SequencedEquals(dit));\r
- dit.Add(7);\r
- ((LinkedList<int>)dut).InsertFirst(7);\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- Assert.IsFalse(dut.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void EqualHashButDifferent()\r
- {\r
- dit.Add(-1657792980); dit.Add(-1570288808);\r
- dat.Add(1862883298); dat.Add(-272461342);\r
- Assert.AreEqual(dit.GetUnsequencedHashCode(), dat.GetUnsequencedHashCode());\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnorderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ICollection<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new LinkedList<ICollection<int>>();\r
- Dat = new LinkedList<ICollection<int>>();\r
- Dut = new LinkedList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dat));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfUnOrdered\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
- private ISequenced<ICollection<int>> Dit, Dat, Dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- Dit = new LinkedList<ICollection<int>>();\r
- Dat = new LinkedList<ICollection<int>>();\r
- Dut = new LinkedList<ICollection<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dit.UnsequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dit); Dut.Add(dut); Dut.Add(dat);\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = null;\r
- Dit = Dat = Dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelUnOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ICollection<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- dot = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- dot.Add(2); dot.Add(1);\r
- Dit = new LinkedList<ISequenced<int>>();\r
- Dat = new LinkedList<ISequenced<int>>();\r
- Dut = new LinkedList<ISequenced<int>>();\r
- Dot = new LinkedList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dut));\r
- Assert.IsFalse(Dit.UnsequencedEquals(Dat));\r
- Assert.IsTrue(Dit.UnsequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class MultiLevelOrderedOfOrdered\r
- {\r
- private ISequenced<int> dit, dat, dut, dot;\r
-\r
- private ISequenced<ISequenced<int>> Dit, Dat, Dut, Dot;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new LinkedList<int>();\r
- dat = new LinkedList<int>();\r
- dut = new LinkedList<int>();\r
- dot = new LinkedList<int>();\r
- dit.Add(2); dit.Add(1);\r
- dat.Add(1); dat.Add(2);\r
- dut.Add(3);\r
- dot.Add(2); dot.Add(1);\r
- Dit = new LinkedList<ISequenced<int>>();\r
- Dat = new LinkedList<ISequenced<int>>();\r
- Dut = new LinkedList<ISequenced<int>>();\r
- Dot = new LinkedList<ISequenced<int>>();\r
- }\r
-\r
-\r
- [Test]\r
- public void Check()\r
- {\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dit.SequencedEquals(dot));\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- }\r
-\r
-\r
- [Test]\r
- public void Multi()\r
- {\r
- Dit.Add(dit); Dit.Add(dut); Dit.Add(dit);\r
- Dat.Add(dut); Dat.Add(dit); Dat.Add(dat);\r
- Dut.Add(dot); Dut.Add(dut); Dut.Add(dit);\r
- Dot.Add(dit); Dot.Add(dit); Dot.Add(dut);\r
- Assert.IsTrue(Dit.SequencedEquals(Dut));\r
- Assert.IsFalse(Dit.SequencedEquals(Dat));\r
- Assert.IsFalse(Dit.SequencedEquals(Dot));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = dat = dut = dot = null;\r
- Dit = Dat = Dut = Dot = null;\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
- <ProductVersion>8.0.50727</ProductVersion>\r
- <SchemaVersion>2.0</SchemaVersion>\r
- <ProjectGuid>{08CBFDEB-A2E2-4F0E-A4E1-B996B05569DE}</ProjectGuid>\r
- <OutputType>Library</OutputType>\r
- <StartupObject>\r
- </StartupObject>\r
- <RootNamespace>nunit</RootNamespace>\r
- <NoStandardLibraries>false</NoStandardLibraries>\r
- <AssemblyName>nunit</AssemblyName>\r
- <FileUpgradeFlags>\r
- </FileUpgradeFlags>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">\r
- <DebugSymbols>true</DebugSymbols>\r
- <Optimize>false</Optimize>\r
- <OutputPath>.\bin\Debug\</OutputPath>\r
- <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>\r
- <DefineConstants>DEBUG;TRACE</DefineConstants>\r
- <WarningLevel>4</WarningLevel>\r
- <IncrementalBuild>false</IncrementalBuild>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">\r
- <DebugSymbols>false</DebugSymbols>\r
- <Optimize>true</Optimize>\r
- <OutputPath>.\bin\Release\</OutputPath>\r
- <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>\r
- <DefineConstants>TRACE</DefineConstants>\r
- <WarningLevel>4</WarningLevel>\r
- <IncrementalBuild>false</IncrementalBuild>\r
- </PropertyGroup>\r
- <ItemGroup>\r
- <ProjectReference Include="..\C5\C5.csproj">\r
- <Project>{D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}</Project>\r
- <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>\r
- <Name>C5</Name>\r
- </ProjectReference>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Compile Include="arrays\CircularQueueTest.cs" />\r
- <Compile Include="AssemblyInfo.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="BasesTest.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="Records.cs" />\r
- <Compile Include="Sorting.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="SupportClasses.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="arrays\ArrayListTest.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="arrays\HashedArrayListTest.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="arrays\SortedArrayTests.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="hashing\HashBagTests.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="hashing\HashDictionaryTests.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="hashing\HashTableTests.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="heaps\HeapTests.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="linkedlists\HashedLinkedListTest.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="linkedlists\LinkedListTest.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="templates\Clone.cs" />\r
- <Compile Include="templates\Events.cs" />\r
- <Compile Include="templates\GenericCollectionTester.cs" />\r
- <Compile Include="templates\List.cs" />\r
- <Compile Include="trees\Bag.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="trees\Dictionary.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="trees\RedBlackTreeSetTests.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="WrappersTest.cs" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <AppDesigner Include="Properties\" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Reference Include="nunit.framework, Version=2.2.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Folder Include="Properties\" />\r
- </ItemGroup>\r
- <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />\r
- <PropertyGroup>\r
- <PreBuildEvent>\r
- </PreBuildEvent>\r
- <PostBuildEvent>\r
- </PostBuildEvent>\r
- </PropertyGroup>\r
- <ProjectExtensions>\r
- <VisualStudio>\r
- </VisualStudio>\r
- </ProjectExtensions>\r
-</Project>
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.Templates.Extensible\r
-{\r
- class Clone\r
- {\r
- public static void Tester<U>() where U : class, IExtensible<int>, new()\r
- {\r
- U extensible = new U();\r
- RealTester<U>(extensible);\r
- extensible.Add(12);\r
- extensible.Add(23);\r
- extensible.Add(56);\r
- RealTester<U>(extensible);\r
- }\r
-\r
- public static void ViewTester<U>() where U : class, IList<int>, new()\r
- {\r
- U baselist = new U();\r
- baselist.Add(12);\r
- baselist.Add(23);\r
- baselist.Add(56);\r
- baselist.Add(112);\r
- baselist.Add(123);\r
- baselist.Add(156);\r
- U view = (U)baselist.View(2, 2);\r
- RealTester<U>(view);\r
- }\r
-\r
- public static void RealTester<U>(U extensible) where U : class, IExtensible<int>, new()\r
- {\r
- object clone = extensible.Clone();\r
- Assert.IsNotNull(clone);\r
- Assert.AreEqual(typeof(U), clone.GetType(),\r
- String.Format("Wrong type '{0}' of clone of '{1}'", clone.GetType(), typeof(U)));\r
- U theClone = clone as U;\r
- Assert.IsTrue(theClone.Check(), "Clone does not pass Check()");\r
- if (typeof(ICollection<int>).IsAssignableFrom(typeof(U)))\r
- Assert.IsTrue(EqualityComparer<U>.Default.Equals(extensible, theClone), "Clone has wrong contents");\r
- else //merely extensible\r
- Assert.IsTrue(IC.eq(theClone, extensible.ToArray()), "Clone has wrong contents");\r
- }\r
- }\r
-\r
- class Serialization\r
- {\r
- public static void Tester<U>() where U : class, IExtensible<int>, new()\r
- {\r
- U extensible = new U();\r
- realtester<U>(extensible);\r
- extensible.Add(12);\r
- extensible.Add(23);\r
- extensible.Add(56);\r
- realtester<U>(extensible);\r
- }\r
-\r
- public static void ViewTester<U>() where U : class, IList<int>, new()\r
- {\r
- U baselist = new U();\r
- baselist.Add(12);\r
- baselist.Add(23);\r
- baselist.Add(56);\r
- baselist.Add(112);\r
- baselist.Add(123);\r
- baselist.Add(156);\r
- U view = (U)baselist.View(2, 2);\r
- realtester<U>(view);\r
- }\r
-\r
- private static void realtester<U>(U extensible) where U : class, IExtensible<int>, new()\r
- {\r
- System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter =\r
- new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();\r
- System.IO.Stream stream = new System.IO.MemoryStream();\r
- formatter.Serialize(stream, extensible);\r
- stream.Flush();\r
- stream.Seek(0L, System.IO.SeekOrigin.Begin);\r
- object clone = formatter.Deserialize(stream);\r
-\r
- Assert.IsNotNull(clone);\r
- Assert.AreEqual(typeof(U), clone.GetType(),\r
- String.Format("Wrong type '{0}' of clone of '{1}'", clone.GetType(), typeof(U)));\r
- U theClone = clone as U;\r
- Assert.IsTrue(theClone.Check(), "Clone does not pass Check()");\r
- if (typeof(ICollection<int>).IsAssignableFrom(typeof(U)))\r
- Assert.IsTrue(EqualityComparer<U>.Default.Equals(extensible, theClone), "Clone has wrong contents");\r
- else //merely extensible\r
- Assert.IsTrue(IC.eq(theClone, extensible.ToArray()), "Clone has wrong contents");\r
- }\r
- }\r
-\r
-}\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-using System.Reflection;\r
-\r
-namespace C5UnitTests.Templates.Events\r
-{\r
- public abstract class CollectionValueTester<TCollection, TItem> : GenericCollectionTester<TCollection, EventTypeEnum>\r
- where TCollection : ICollectionValue<TItem>\r
- {\r
- protected TCollection collection;\r
- protected CollectionEventList<TItem> seen;\r
- protected EventTypeEnum listenTo;\r
- protected void listen() { seen.Listen(collection, listenTo); }\r
-\r
- public override void SetUp(TCollection list, EventTypeEnum testSpec)\r
- {\r
- this.collection = list;\r
- listenTo = testSpec;\r
- seen = new CollectionEventList<TItem>(EqualityComparer<TItem>.Default);\r
- }\r
-\r
- public SCG.IEnumerable<EventTypeEnum> SpecsBasic\r
- {\r
- get\r
- {\r
- CircularQueue<EventTypeEnum> specs = new CircularQueue<EventTypeEnum>();\r
- //foreach (EventTypeEnum listenTo in Enum.GetValues(typeof(EventTypeEnum)))\r
- // if ((listenTo & ~EventTypeEnum.Basic) == 0)\r
- // specs.Enqueue(listenTo);\r
- //specs.Enqueue(EventTypeEnum.Added | EventTypeEnum.Removed);\r
- for (int spec = 0; spec <= (int)EventTypeEnum.Basic; spec++)\r
- specs.Enqueue((EventTypeEnum)spec);\r
- return specs;\r
- }\r
- }\r
- public SCG.IEnumerable<EventTypeEnum> SpecsAll\r
- {\r
- get\r
- {\r
- CircularQueue<EventTypeEnum> specs = new CircularQueue<EventTypeEnum>();\r
- //foreach (EventTypeEnum listenTo in Enum.GetValues(typeof(EventTypeEnum)))\r
- // specs.Enqueue(listenTo);\r
- //specs.Enqueue(EventTypeEnum.Added | EventTypeEnum.Removed);\r
-\r
- for (int spec = 0; spec <= (int)EventTypeEnum.All; spec++)\r
- specs.Enqueue((EventTypeEnum)spec);\r
- return specs;\r
- }\r
- }\r
- }\r
- public abstract class CollectionValueTester<U> : CollectionValueTester<U, int> where U : ICollectionValue<int>\r
- {\r
- }\r
-\r
- public class ExtensibleTester<U> : CollectionValueTester<U> where U : IExtensible<int>\r
- {\r
- public override SCG.IEnumerable<EventTypeEnum> GetSpecs()\r
- {\r
- return SpecsBasic;\r
- }\r
- [Test]\r
- public virtual void Listenable()\r
- {\r
- Assert.AreEqual(EventTypeEnum.Basic, collection.ListenableEvents);\r
- Assert.AreEqual(EventTypeEnum.None, collection.ActiveEvents);\r
- listen();\r
- Assert.AreEqual(listenTo, collection.ActiveEvents);\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- collection.Add(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
- [Test]\r
- public void AddAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- collection.Add(10 * i + 5);\r
- }\r
- listen();\r
- collection.AddAll<int>(new int[] { 45, 200, 56, 67 });\r
- seen.Check(collection.AllowsDuplicates ?\r
- collection.DuplicatesByCounting ?\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(200, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(55, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(65, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}\r
- :\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(200, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}\r
- :\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(200, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.AddAll<int>(new int[] { });\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- }\r
-\r
- public class CollectionTester<U> : ExtensibleTester<U> where U : ICollection<int>\r
- {\r
- [Test]\r
- public void Update()\r
- {\r
- collection.Add(4); collection.Add(54); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection.Update(53);\r
- seen.Check(\r
- collection.AllowsDuplicates ?\r
- collection.DuplicatesByCounting ?\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(54, 2), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 2), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- }\r
- : new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(54, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- }\r
- : new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(54, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.Update(67);\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- int val = 53;\r
- collection.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] { });\r
- val = 67;\r
- collection.FindOrAdd(ref val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- }\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- int val = 53;\r
- collection.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(53, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- val = 67;\r
- collection.UpdateOrAdd(val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.UpdateOrAdd(51, out val);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(53, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(51, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- val = 67;\r
- collection.UpdateOrAdd(81, out val);\r
- seen.Check(new CollectionEvent<int>[] { \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(81, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- }\r
-\r
- [Test]\r
- public void RemoveItem()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.Remove(53);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Remove(11);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- collection.Add(10 * i + 5);\r
- }\r
- listen();\r
- collection.RemoveAll<int>(new int[] { 32, 187, 45 });\r
- //TODO: the order depends on internals of the HashSet\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(35, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(45, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.RemoveAll<int>(new int[] { 200, 300 });\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- collection.Add(10 * i + 5);\r
- }\r
- listen();\r
- collection.RetainAll<int>(new int[] { 32, 187, 45, 62, 75, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(15, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(25, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(55, 1), collection),\r
- //new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(75, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.RetainAll<int>(new int[] { 32, 187, 45, 62, 75, 82, 95, 2 });\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public void RemoveAllCopies()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- {\r
- collection.Add(3 * i + 5);\r
- }\r
- listen();\r
- collection.RemoveAllCopies(14);\r
- seen.Check(\r
- collection.AllowsDuplicates ?\r
- collection.DuplicatesByCounting ?\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 3), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}\r
- :\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(14, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(17, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}\r
- :\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(11, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.RemoveAllCopies(14);\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public virtual void Clear()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection.Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedEventArgs(true, collection.AllowsDuplicates ? 3 : 2), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.Clear();\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- }\r
-\r
- public class IndexedTester<U> : CollectionTester<U> where U : IIndexed<int>\r
- {\r
- [Test]\r
- public void RemoveAt()\r
- {\r
- collection.Add(4); collection.Add(16); collection.Add(28);\r
- listen();\r
- collection.RemoveAt(1);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(16,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(16, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.RemoveInterval(1, 2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- collection is IList<int> ?\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,2,1), collection):\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedEventArgs(false,2), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.RemoveInterval(1, 0);\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
- }\r
-\r
- public class SortedIndexedTester<U> : IndexedTester<U> where U : IIndexedSorted<int>\r
- {\r
- [Test]\r
- public void DeleteMinMax()\r
- {\r
- collection.Add(34);\r
- collection.Add(56);\r
- collection.Add(34);\r
- collection.Add(12);\r
- listen();\r
- collection.DeleteMax();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.DeleteMin();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(12, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- }\r
-\r
- [Test]\r
- public void AddSorted()\r
- {\r
- listen();\r
- collection.AddSorted(collection.AllowsDuplicates ? new int[] { 31, 62, 63, 93 } : new int[] { 31, 62, 93 });\r
- seen.Check(collection.AllowsDuplicates ?\r
- collection.DuplicatesByCounting ?\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(31, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(93, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}\r
- :\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(31, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(63, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(93, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)}\r
- :\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(31, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(62, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(93, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.AddSorted(new int[] { });\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public void RemoveRange()\r
- {\r
- for (int i = 0; i < 20; i++)\r
- collection.Add(i * 10 + 5);\r
- listen();\r
- collection.RemoveRangeFrom(173);\r
- //TODO: fix order to remove in:\r
- seen.Check(\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(195, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(185, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(175, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.RemoveRangeFromTo(83, 113);\r
- seen.Check(\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(105, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(95, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(85, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.RemoveRangeTo(33);\r
- seen.Check(\r
- new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(5, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(15, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(25, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.RemoveRangeFrom(173);\r
- seen.Check(new CollectionEvent<int>[] { });\r
- collection.RemoveRangeFromTo(83, 113);\r
- seen.Check(new CollectionEvent<int>[] { });\r
- collection.RemoveRangeTo(33);\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
- }\r
-\r
- public class ListTester<U> : IndexedTester<U> where U : IList<int>\r
- {\r
- public override SCG.IEnumerable<EventTypeEnum> GetSpecs()\r
- {\r
- return SpecsAll;\r
- }\r
-\r
- [Test]\r
- public override void Listenable()\r
- {\r
- Assert.AreEqual(EventTypeEnum.All, collection.ListenableEvents);\r
- Assert.AreEqual(EventTypeEnum.None, collection.ActiveEvents);\r
- listen();\r
- Assert.AreEqual(listenTo, collection.ActiveEvents);\r
- }\r
- [Test]\r
- public void SetThis()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection[1] = 45;\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(56,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Insert()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection.Insert(1, 45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- }\r
-\r
- [Test]\r
- public void InsertAll()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection.InsertAll<int>(1, new int[] { 666, 777, 888 });\r
- //seen.Print(Console.Error);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(666,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(666, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(777,2), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(777, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(888,3), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(888, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.InsertAll<int>(1, new int[] { });\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public void InsertFirstLast()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.InsertFirst(45);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(45,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(45, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.InsertLast(88);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(88,4), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(88, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- }\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- collection.FIFO = false;\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.Remove();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.FIFO = true;\r
- collection.Remove();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(4, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
- [Test]\r
- public void RemoveFirst()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.RemoveFirst();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(4,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(4, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
- [Test]\r
- public void RemoveLast()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.RemoveLast();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(18,2), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(18, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
- [Test]\r
- public void Reverse()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection.Reverse();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.View(1, 0).Reverse();\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
-\r
- [Test]\r
- public void Sort()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection.Sort();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.View(1, 0).Sort();\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public void Shuffle()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(8);\r
- listen();\r
- collection.Shuffle();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.View(1, 0).Shuffle();\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public override void Clear()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.View(1, 1).Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(false,1,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.Clear();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,2,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.Clear();\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- [Test]\r
- public void ListDispose()\r
- {\r
- collection.Add(4); collection.Add(56); collection.Add(18);\r
- listen();\r
- collection.View(1, 1).Dispose();\r
- seen.Check(new CollectionEvent<int>[] { });\r
- collection.Dispose();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Cleared, new ClearedRangeEventArgs(true,3,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- collection.Dispose();\r
- seen.Check(new CollectionEvent<int>[] { });\r
- }\r
-\r
- /* \r
- \r
- * /\r
- //[TearDown]\r
- //public void Dispose() { list = null; seen = null; }\r
- /*\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewChanged()\r
- {\r
- IList<int> w = collection.View(0, 0);\r
- w.CollectionChanged += new CollectionChangedHandler<int>(w_CollectionChanged);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewCleared()\r
- {\r
- IList<int> w = collection.View(0, 0);\r
- w.CollectionCleared += new CollectionClearedHandler<int>(w_CollectionCleared);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewAdded()\r
- {\r
- IList<int> w = collection.View(0, 0);\r
- w.ItemsAdded += new ItemsAddedHandler<int>(w_ItemAdded);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewInserted()\r
- {\r
- IList<int> w = collection.View(0, 0);\r
- w.ItemInserted += new ItemInsertedHandler<int>(w_ItemInserted);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewRemoved()\r
- {\r
- IList<int> w = collection.View(0, 0);\r
- w.ItemsRemoved += new ItemsRemovedHandler<int>(w_ItemRemoved);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(UnlistenableEventException))]\r
- public void ViewRemovedAt()\r
- {\r
- IList<int> w = collection.View(0, 0);\r
- w.ItemRemovedAt += new ItemRemovedAtHandler<int>(w_ItemRemovedAt);\r
- }\r
-\r
- void w_CollectionChanged(object sender)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_CollectionCleared(object sender, ClearedEventArgs eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemAdded(object sender, ItemCountEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemInserted(object sender, ItemAtEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemRemoved(object sender, ItemCountEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }\r
-\r
- void w_ItemRemovedAt(object sender, ItemAtEventArgs<int> eventArgs)\r
- {\r
- throw new NotImplementedException();\r
- }*/\r
- }\r
-\r
- public class StackTester<U> : CollectionValueTester<U> where U : IStack<int>\r
- {\r
- public override SCG.IEnumerable<EventTypeEnum> GetSpecs()\r
- {\r
- return SpecsBasic;\r
- }\r
-\r
- [Test]\r
- public void PushPop()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<int>[0]);\r
- collection.Push(23);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(23,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(23, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Push(-12);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(-12,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(-12, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(-12,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(-12, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Pop();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(23,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(23, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
- }\r
-\r
- public class QueueTester<U> : CollectionValueTester<U> where U : IQueue<int>\r
- {\r
- public override SCG.IEnumerable<EventTypeEnum> GetSpecs()\r
- {\r
- return SpecsBasic;\r
- }\r
-\r
- [Test]\r
- public void EnqueueDequeue()\r
- {\r
- listen();\r
- collection.Enqueue(67);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(67,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(67, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Enqueue(2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Inserted, new ItemAtEventArgs<int>(2,1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(2, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(67,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(67, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Dequeue();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.RemovedAt, new ItemAtEventArgs<int>(2,0), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(2, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
- }\r
-\r
- public class PriorityQueueTester<U> : ExtensibleTester<U> where U : IPriorityQueue<int>\r
- {\r
- public override System.Collections.Generic.IEnumerable<EventTypeEnum> GetSpecs()\r
- {\r
- return SpecsBasic;\r
- }\r
-\r
- [Test]\r
- public void Direct()\r
- {\r
- listen();\r
- collection.Add(34);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.Add(56);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.AddAll<int>(new int[] { });\r
- seen.Check(new CollectionEvent<int>[] {\r
- });\r
- collection.Add(34);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.Add(12);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(12, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.DeleteMax();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.DeleteMin();\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(12, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.AddAll<int>(new int[] { 4, 5, 6, 2 });\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(4, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(5, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(6, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(2, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection)\r
- });\r
- }\r
-\r
- [Test]\r
- public void WithHandles()\r
- {\r
- listen();\r
- IPriorityQueueHandle<int> handle = null, handle2;\r
- collection.Add(34);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.Add(56);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(56, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.Add(ref handle, 34);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(34, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.Add(12);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(12, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.DeleteMax(out handle2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(56, 1), collection),\r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- collection.DeleteMin(out handle2);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(12, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
-\r
- collection.Replace(handle, 117);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(34, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Added, new ItemCountEventArgs<int>(117, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
-\r
- collection.Delete(handle);\r
- seen.Check(new CollectionEvent<int>[] {\r
- new CollectionEvent<int>(EventTypeEnum.Removed, new ItemCountEventArgs<int>(117, 1), collection), \r
- new CollectionEvent<int>(EventTypeEnum.Changed, new EventArgs(), collection), \r
- });\r
- }\r
- }\r
-\r
- public class DictionaryTester<U> : CollectionValueTester<U, KeyValuePair<int, int>> where U : IDictionary<int, int>\r
- {\r
- public override SCG.IEnumerable<EventTypeEnum> GetSpecs()\r
- {\r
- return SpecsBasic;\r
- }\r
-\r
- [Test]\r
- public virtual void Listenable()\r
- {\r
- Assert.AreEqual(EventTypeEnum.Basic, collection.ListenableEvents);\r
- Assert.AreEqual(EventTypeEnum.None, collection.ActiveEvents);\r
- listen();\r
- Assert.AreEqual(listenTo, collection.ActiveEvents);\r
- }\r
-\r
- [Test]\r
- public void AddAndREmove()\r
- {\r
- listen();\r
- seen.Check(new CollectionEvent<KeyValuePair<int, int>>[0]);\r
- collection.Add(23, 45);\r
- seen.Check(new CollectionEvent<KeyValuePair<int,int>>[] {\r
- new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Added, new ItemCountEventArgs<KeyValuePair<int,int>>(new KeyValuePair<int,int>(23,45), 1), collection),\r
- new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- collection.Remove(25);\r
- seen.Check(new CollectionEvent<KeyValuePair<int, int>>[] {\r
- new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Removed, new ItemCountEventArgs<KeyValuePair<int,int>>(new KeyValuePair<int,int>(23,45), 1), collection),\r
- new CollectionEvent<KeyValuePair<int,int>>(EventTypeEnum.Changed, new EventArgs(), collection)});\r
- }\r
-\r
-\r
-\r
- }\r
-\r
-}\r
-\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-using System.Reflection;\r
-\r
-namespace C5UnitTests.Templates\r
-{\r
- public abstract class GenericCollectionTester<U, W>\r
- {\r
- protected CircularQueue<MethodInfo> testMethods;\r
- public GenericCollectionTester()\r
- {\r
- testMethods = new CircularQueue<MethodInfo>();\r
- foreach (MethodInfo minfo in this.GetType().GetMethods())\r
- {\r
- if (minfo.GetParameters().Length == 0 &&\r
- minfo.GetCustomAttributes(typeof(TestAttribute), false).Length > 0)\r
- testMethods.Enqueue(minfo);\r
- }\r
- }\r
-\r
- public virtual void Test(Fun<U> factory)\r
- {\r
- foreach (MethodInfo minfo in testMethods)\r
- {\r
- foreach (W testSpec in GetSpecs())\r
- {\r
- SetUp(factory(), testSpec);\r
- //Console.WriteLine("Testing {0}, with method {1} and testSpec {{{2}}}", typeof(U), minfo.Name, testSpec);\r
- try\r
- {\r
- minfo.Invoke(this, null);\r
- }\r
- catch (TargetInvocationException)\r
- {\r
- //if (e.InnerException is ExpectedExceptionAttribute)\r
- //{\r
- //}\r
- //else\r
- throw;\r
- }\r
- //tearDown\r
- }\r
- }\r
- }\r
-\r
- public abstract void SetUp(U collection, W testSpec);\r
- public abstract SCG.IEnumerable<W> GetSpecs();\r
- }\r
-\r
- public abstract class GenericCollectionTester<U> : GenericCollectionTester<U, int>\r
- {\r
- public override System.Collections.Generic.IEnumerable<int> GetSpecs()\r
- {\r
- return new int[] { 0 };\r
- }\r
-\r
- public override void SetUp(U collection, int testSpec)\r
- {\r
- SetUp(collection);\r
- }\r
-\r
- public abstract void SetUp(object collection);\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.Templates.List\r
-{\r
- class Foo\r
- {\r
- public static void Tester<U>() where U : class, IList<int>, new()\r
- {\r
- U extensible = new U();\r
- extensible.Add(12);\r
- extensible.Add(23);\r
- extensible.Add(56);\r
- }\r
- }\r
-}\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests.trees.TreeBag\r
-{\r
- using CollectionOfInt = TreeBag<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.SortedIndexedTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new TreeBag<T>(); }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{{ }}", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530, -4, 28 });\r
- Assert.AreEqual("{{ -4(*2), 28(*2), 129(*1), 65530(*1) }}", coll.ToString());\r
- Assert.AreEqual("{{ -4(*2), 1C(*2), 81(*1), FFFA(*1) }}", coll.ToString(null, rad16));\r
- Assert.AreEqual("{{ -4(*2), 28(*2)... }}", coll.ToString("L18", null));\r
- Assert.AreEqual("{{ -4(*2), 1C(*2)... }}", coll.ToString("L18", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private IIndexedSorted<KeyValuePair<int, int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new TreeBag<KeyValuePair<int, int>>(new KeyValuePairComparer<int, int>(new IC()));\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int, int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(13, lst[11].Key);\r
- Assert.AreEqual(79, lst[11].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int, int> p = new KeyValuePair<int, int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- Assert.AreEqual(4, lst[3].Key);\r
- Assert.AreEqual(34, lst[3].Value);\r
- p = new KeyValuePair<int, int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Simple\r
- {\r
- private TreeBag<string> bag;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- bag = new TreeBag<string>(new SC());\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- bag = null;\r
- }\r
-\r
- [Test]\r
- public void Initial()\r
- {\r
- bool res;\r
-\r
- Assert.IsFalse(bag.IsReadOnly);\r
- Assert.AreEqual(0, bag.Count, "new bag should be empty");\r
- Assert.AreEqual(0, bag.ContainsCount("A"));\r
- Assert.AreEqual(0, bag.ContainsCount("B"));\r
- Assert.AreEqual(0, bag.ContainsCount("C"));\r
- Assert.IsFalse(bag.Contains("A"));\r
- Assert.IsFalse(bag.Contains("B"));\r
- Assert.IsFalse(bag.Contains("C"));\r
- bag.Add("A");\r
- Assert.AreEqual(1, bag.Count);\r
- Assert.AreEqual(1, bag.ContainsCount("A"));\r
- Assert.AreEqual(0, bag.ContainsCount("B"));\r
- Assert.AreEqual(0, bag.ContainsCount("C"));\r
- Assert.IsTrue(bag.Contains("A"));\r
- Assert.IsFalse(bag.Contains("B"));\r
- Assert.IsFalse(bag.Contains("C"));\r
- bag.Add("C");\r
- Assert.AreEqual(2, bag.Count);\r
- Assert.AreEqual(1, bag.ContainsCount("A"));\r
- Assert.AreEqual(0, bag.ContainsCount("B"));\r
- Assert.AreEqual(1, bag.ContainsCount("C"));\r
- Assert.IsTrue(bag.Contains("A"));\r
- Assert.IsFalse(bag.Contains("B"));\r
- Assert.IsTrue(bag.Contains("C"));\r
- bag.Add("C");\r
- Assert.AreEqual(3, bag.Count);\r
- Assert.AreEqual(1, bag.ContainsCount("A"));\r
- Assert.AreEqual(0, bag.ContainsCount("B"));\r
- Assert.AreEqual(2, bag.ContainsCount("C"));\r
- Assert.IsTrue(bag.Contains("A"));\r
- Assert.IsFalse(bag.Contains("B"));\r
- Assert.IsTrue(bag.Contains("C"));\r
- bag.Add("B");\r
- bag.Add("C");\r
- Assert.AreEqual(5, bag.Count);\r
- Assert.AreEqual(1, bag.ContainsCount("A"));\r
- Assert.AreEqual(1, bag.ContainsCount("B"));\r
- Assert.AreEqual(3, bag.ContainsCount("C"));\r
- Assert.IsTrue(bag.Contains("A"));\r
- Assert.IsTrue(bag.Contains("B"));\r
- Assert.IsTrue(bag.Contains("C"));\r
- res = bag.Remove("C");\r
- Assert.AreEqual(4, bag.Count);\r
- Assert.AreEqual(1, bag.ContainsCount("A"));\r
- Assert.AreEqual(1, bag.ContainsCount("B"));\r
- Assert.AreEqual(2, bag.ContainsCount("C"));\r
- Assert.IsTrue(bag.Contains("A"));\r
- Assert.IsTrue(bag.Contains("B"));\r
- Assert.IsTrue(bag.Contains("C"));\r
- res = bag.Remove("A");\r
- Assert.AreEqual(3, bag.Count);\r
- Assert.AreEqual(0, bag.ContainsCount("A"));\r
- Assert.AreEqual(1, bag.ContainsCount("B"));\r
- Assert.AreEqual(2, bag.ContainsCount("C"));\r
- Assert.IsFalse(bag.Contains("A"));\r
- Assert.IsTrue(bag.Contains("B"));\r
- Assert.IsTrue(bag.Contains("C"));\r
- bag.RemoveAllCopies("C");\r
- Assert.AreEqual(1, bag.Count);\r
- Assert.AreEqual(0, bag.ContainsCount("A"));\r
- Assert.AreEqual(1, bag.ContainsCount("B"));\r
- Assert.AreEqual(0, bag.ContainsCount("C"));\r
- Assert.IsFalse(bag.Contains("A"));\r
- Assert.IsTrue(bag.Contains("B"));\r
- Assert.IsFalse(bag.Contains("C"));\r
- Assert.IsFalse(bag.Contains("Z"));\r
- Assert.IsFalse(bag.Remove("Z"));\r
- bag.RemoveAllCopies("Z");\r
- Assert.AreEqual(1, bag.Count);\r
- Assert.AreEqual(0, bag.ContainsCount("A"));\r
- Assert.AreEqual(1, bag.ContainsCount("B"));\r
- Assert.AreEqual(0, bag.ContainsCount("C"));\r
- Assert.IsFalse(bag.Contains("A"));\r
- Assert.IsTrue(bag.Contains("B"));\r
- Assert.IsFalse(bag.Contains("C"));\r
- Assert.IsFalse(bag.Contains("Z"));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class FindOrAdd\r
- {\r
- private TreeBag<KeyValuePair<int, string>> bag;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- bag = new TreeBag<KeyValuePair<int, string>>(new KeyValuePairComparer<int, string>(new IC()));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- bag = null;\r
- }\r
-\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- KeyValuePair<int, string> p = new KeyValuePair<int, string>(3, "tre");\r
- Assert.IsFalse(bag.FindOrAdd(ref p));\r
- p.Value = "drei";\r
- Assert.IsTrue(bag.FindOrAdd(ref p));\r
- Assert.AreEqual("tre", p.Value);\r
- p.Value = "three";\r
- Assert.AreEqual(2, bag.ContainsCount(p));\r
- Assert.AreEqual("tre", bag[0].Value);\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Enumerators\r
- {\r
- private TreeBag<string> bag;\r
-\r
- private SCG.IEnumerator<string> bagenum;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- bag = new TreeBag<string>(new SC());\r
- foreach (string s in new string[] { "A", "B", "A", "A", "B", "C", "D", "B" })\r
- bag.Add(s);\r
-\r
- bagenum = bag.GetEnumerator();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- bagenum = null;\r
- bag = null;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextOnModified()\r
- {\r
- //TODO: also problem before first MoveNext!!!!!!!!!!\r
- bagenum.MoveNext();\r
- bag.Add("T");\r
- bagenum.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- public void NormalUse()\r
- {\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "A");\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "A");\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "A");\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "B");\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "B");\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "B");\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "C");\r
- Assert.IsTrue(bagenum.MoveNext());\r
- Assert.AreEqual(bagenum.Current, "D");\r
- Assert.IsFalse(bagenum.MoveNext());\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Ranges\r
- {\r
- private TreeBag<int> tree;\r
-\r
- private SCG.IComparer<int> c;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- c = new IC();\r
- tree = new TreeBag<int>(c);\r
- for (int i = 1; i <= 10; i++)\r
- {\r
- tree.Add(i * 2); tree.Add(i);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Enumerator()\r
- {\r
- SCG.IEnumerator<int> e = tree.RangeFromTo(5, 17).GetEnumerator();\r
- int i = 0;\r
- int[] all = new int[] { 5, 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16 };\r
- while (e.MoveNext())\r
- {\r
- Assert.AreEqual(all[i++], e.Current);\r
- }\r
-\r
- Assert.AreEqual(12, i);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidOperationException))]\r
- public void Enumerator2()\r
- {\r
- SCG.IEnumerator<int> e = tree.RangeFromTo(5, 17).GetEnumerator();\r
- int i = e.Current;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidOperationException))]\r
- public void Enumerator3()\r
- {\r
- SCG.IEnumerator<int> e = tree.RangeFromTo(5, 17).GetEnumerator();\r
-\r
- while (e.MoveNext()) ;\r
-\r
- int i = e.Current;\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- int[] all = new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16, 18, 20 };\r
-\r
- tree.RemoveRangeFrom(18);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16 }));\r
- tree.RemoveRangeFrom(28);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16 }));\r
- tree.RemoveRangeFrom(1);\r
- Assert.IsTrue(IC.eq(tree));\r
- foreach (int i in all) tree.Add(i);\r
-\r
- tree.RemoveRangeTo(10);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 10, 10, 12, 14, 16, 18, 20 }));\r
- tree.RemoveRangeTo(2);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 10, 10, 12, 14, 16, 18, 20 }));\r
- tree.RemoveRangeTo(21);\r
- Assert.IsTrue(IC.eq(tree));\r
- foreach (int i in all) tree.Add(i);\r
-\r
- tree.RemoveRangeFromTo(4, 8);\r
- Assert.IsTrue(IC.eq(tree, 1, 2, 2, 3, 8, 8, 9, 10, 10, 12, 14, 16, 18, 20));\r
- tree.RemoveRangeFromTo(14, 28);\r
- Assert.IsTrue(IC.eq(tree, 1, 2, 2, 3, 8, 8, 9, 10, 10, 12));\r
- tree.RemoveRangeFromTo(0, 9);\r
- Assert.IsTrue(IC.eq(tree, 9, 10, 10, 12));\r
- tree.RemoveRangeFromTo(0, 81);\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- int[] all = new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16, 18, 20 };\r
-\r
- Assert.IsTrue(IC.eq(tree, all));\r
- Assert.IsTrue(IC.eq(tree.RangeAll(), all));\r
- Assert.AreEqual(20, tree.RangeAll().Count);\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(11), new int[] { 12, 14, 16, 18, 20 }));\r
- Assert.AreEqual(5, tree.RangeFrom(11).Count);\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(12), new int[] { 12, 14, 16, 18, 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(1), all));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(0), all));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(21), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(20), new int[] { 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(8), new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(7), new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6 }));\r
- Assert.AreEqual(9, tree.RangeTo(7).Count);\r
- Assert.IsTrue(IC.eq(tree.RangeTo(1), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(0), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(3), new int[] { 1, 2, 2 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(20), new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16, 18 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(21), all));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(7, 12), new int[] { 7, 8, 8, 9, 10, 10 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 11), new int[] { 6, 6, 7, 8, 8, 9, 10, 10 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(1, 12), new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10 }));\r
- Assert.AreEqual(15, tree.RangeFromTo(1, 12).Count);\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(2, 12), new int[] { 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 21), new int[] { 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16, 18, 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 20), new int[] { 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16, 18 }));\r
- }\r
-\r
-\r
- [Test]\r
- public void Backwards()\r
- {\r
- int[] all = new int[] { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 12, 14, 16, 18, 20 };\r
- int[] lla = new int[] { 20, 18, 16, 14, 12, 10, 10, 9, 8, 8, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1 };\r
-\r
- Assert.IsTrue(IC.eq(tree, all));\r
- Assert.IsTrue(IC.eq(tree.RangeAll().Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(11).Backwards(), new int[] { 20, 18, 16, 14, 12 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(12).Backwards(), new int[] { 20, 18, 16, 14, 12 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(1).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(0).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(21).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(20).Backwards(), new int[] { 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(8).Backwards(), new int[] { 7, 6, 6, 5, 4, 4, 3, 2, 2, 1 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(7).Backwards(), new int[] { 6, 6, 5, 4, 4, 3, 2, 2, 1 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(1).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(0).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(3).Backwards(), new int[] { 2, 2, 1 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(20).Backwards(), new int[] { 18, 16, 14, 12, 10, 10, 9, 8, 8, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(21).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(7, 12).Backwards(), new int[] { 10, 10, 9, 8, 8, 7 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 11).Backwards(), new int[] { 10, 10, 9, 8, 8, 7, 6, 6 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(0, 12).Backwards(), new int[] { 10, 10, 9, 8, 8, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(1, 12).Backwards(), new int[] { 10, 10, 9, 8, 8, 7, 6, 6, 5, 4, 4, 3, 2, 2, 1 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 21).Backwards(), new int[] { 20, 18, 16, 14, 12, 10, 10, 9, 8, 8, 7, 6, 6 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 20).Backwards(), new int[] { 18, 16, 14, 12, 10, 10, 9, 8, 8, 7, 6, 6 }));\r
- }\r
-\r
-\r
- [Test]\r
- public void Direction()\r
- {\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeFrom(20).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeTo(7).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeFromTo(1, 12).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeAll().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeFrom(20).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeTo(7).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeFromTo(1, 12).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeAll().Backwards().Direction);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- c = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class BagItf\r
- {\r
- private TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 5);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Both()\r
- {\r
- Assert.AreEqual(0, tree.ContainsCount(7));\r
- Assert.AreEqual(1, tree.ContainsCount(10));\r
- Assert.AreEqual(2, tree.ContainsCount(17));\r
- tree.RemoveAllCopies(17);\r
- Assert.AreEqual(0, tree.ContainsCount(17));\r
- tree.RemoveAllCopies(7);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Div\r
- {\r
- private TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 5);\r
- }\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new TreeBag<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor3()\r
- {\r
- new TreeBag<int>(null, EqualityComparer<int>.Default);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor4()\r
- {\r
- new TreeBag<int>(Comparer<int>.Default, null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor5()\r
- {\r
- new TreeBag<int>(null, null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- tree.Add(7);\r
- Assert.AreEqual(7, tree.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- tree.Choose();\r
- }\r
-\r
-\r
- [Test]\r
- public void NoDuplicates()\r
- {\r
- Assert.IsTrue(tree.AllowsDuplicates);\r
- loadup();\r
- Assert.IsTrue(tree.AllowsDuplicates);\r
- }\r
-\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- Assert.IsTrue(tree.Add(17));\r
- Assert.IsTrue(tree.Add(17));\r
- Assert.IsTrue(tree.Add(18));\r
- Assert.IsTrue(tree.Add(18));\r
- Assert.AreEqual(4, tree.Count);\r
- Assert.IsTrue(IC.eq(tree, 17, 17, 18, 18));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private TreeBag<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new TreeBag<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- [Test]\r
- public void FindLast()\r
- {\r
- int i;\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.FindLast(pred, out i));\r
- Assert.AreEqual(675, i);\r
- }\r
-\r
- [Test]\r
- public void FindIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(3, list.FindIndex(pred));\r
- }\r
-\r
- [Test]\r
- public void FindLastIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(7, list.FindLastIndex(pred));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private TreeBag<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new TreeBag<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 2, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private TreeBag<int> tree;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(tree.ToArray()));\r
- tree.Add(4);\r
- tree.Add(7);\r
- tree.Add(4);\r
- Assert.AreEqual("Alles klar", aeq(tree.ToArray(), 4, 4, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- tree.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- tree.Add(6);\r
- tree.Add(6);\r
- tree.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 6, 1004, 1005, 1006, 1007, 1008, 1009));\r
- tree.Add(4);\r
- tree.Add(9);\r
- tree.CopyTo(a, 4);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 6, 4, 6, 6, 9, 1008, 1009));\r
- tree.Clear();\r
- tree.Add(7);\r
- tree.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 6, 4, 6, 6, 9, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- tree.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- tree.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- tree.Add(3);\r
- tree.Add(4);\r
- tree.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Remove\r
- {\r
- private TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 5);\r
- }\r
- //10,11,12,13,14,15,15,16,16,17,17,18,18,19,19,20,21,22,23,24\r
- }\r
-\r
-\r
- [Test]\r
- public void SmallTrees()\r
- {\r
- tree.Clear();\r
- tree.Add(9);\r
- tree.Add(7);\r
- tree.Add(9);\r
- Assert.IsTrue(tree.Remove(7));\r
- Assert.IsTrue(tree.Check(""));\r
- }\r
-\r
-\r
- [Test]\r
- public void ByIndex()\r
- {\r
- //Remove root!\r
- int n = tree.Count;\r
- int i = tree[10];\r
-\r
- Assert.AreEqual(17, tree.RemoveAt(10));\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsTrue(tree.Contains(i));\r
- Assert.AreEqual(n - 1, tree.Count);\r
- Assert.AreEqual(17, tree.RemoveAt(9));\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 2, tree.Count);\r
-\r
- //Low end\r
- i = tree.FindMin();\r
- tree.RemoveAt(0);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 3, tree.Count);\r
-\r
- //high end\r
- i = tree.FindMax();\r
- tree.RemoveAt(tree.Count - 1);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 4, tree.Count);\r
-\r
- //Some leaf\r
- //tree.dump();\r
- i = 18;\r
- Assert.AreEqual(i, tree.RemoveAt(9));\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.AreEqual(i, tree.RemoveAt(8));\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 6, tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AlmostEmpty()\r
- {\r
- //Almost empty\r
- tree.Clear();\r
- tree.Add(3);\r
- tree.RemoveAt(0);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(3));\r
- Assert.AreEqual(0, tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void Empty()\r
- {\r
- tree.Clear();\r
- tree.RemoveAt(0);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void HighIndex()\r
- {\r
- tree.RemoveAt(tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void LowIndex()\r
- {\r
- tree.RemoveAt(-1);\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- //Note: ids does not match for bag\r
- Assert.IsFalse(tree.Remove(-20));\r
-\r
- //1b\r
- Assert.IsTrue(tree.Remove(20));\r
- Assert.IsTrue(tree.Check("T1"));\r
- Assert.IsFalse(tree.Remove(20));\r
-\r
- //1b\r
- Assert.IsTrue(tree.Remove(10));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //case 1c\r
- Assert.IsTrue(tree.Remove(24));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //1a (terminating)\r
- Assert.IsTrue(tree.Remove(16));\r
- Assert.IsTrue(tree.Remove(16));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //2\r
- Assert.IsTrue(tree.Remove(18));\r
- Assert.IsTrue(tree.Remove(17));\r
- Assert.IsTrue(tree.Remove(18));\r
- Assert.IsTrue(tree.Remove(17));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //2+1b\r
- Assert.IsTrue(tree.Remove(15));\r
- Assert.IsTrue(tree.Remove(15));\r
- for (int i = 0; i < 5; i++) tree.Add(17 + i);\r
- Assert.IsTrue(tree.Remove(23));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //1a+1b\r
- Assert.IsTrue(tree.Remove(11));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //2+1c\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(50 - 2 * i);\r
-\r
- Assert.IsTrue(tree.Remove(42));\r
- Assert.IsTrue(tree.Remove(38));\r
- Assert.IsTrue(tree.Remove(22));\r
- Assert.IsTrue(tree.Remove(40));\r
-\r
- //\r
- for (int i = 0; i < 48; i++)\r
- tree.Remove(i);\r
-\r
- //Almost empty tree:*\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Remove(48));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //Empty tree:*\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class PredecessorStructure\r
- {\r
- private TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- for (int i = 0; i < 20; i++)\r
- tree.Add(2 * i);\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(4 * i);\r
- }\r
-\r
-\r
- [Test]\r
- public void Predecessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.Predecessor(7));\r
- Assert.AreEqual(6, tree.Predecessor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.Predecessor(1));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.Predecessor(39));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PredecessorTooLow1()\r
- {\r
- tree.Predecessor(-2);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PredecessorTooLow2()\r
- {\r
- tree.Predecessor(0);\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakPredecessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.WeakPredecessor(7));\r
- Assert.AreEqual(8, tree.WeakPredecessor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.WeakPredecessor(1));\r
- Assert.AreEqual(0, tree.WeakPredecessor(0));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.WeakPredecessor(39));\r
- Assert.AreEqual(38, tree.WeakPredecessor(38));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void WeakPredecessorTooLow1()\r
- {\r
- tree.WeakPredecessor(-2);\r
- }\r
-\r
-\r
- [Test]\r
- public void Successor()\r
- {\r
- loadup();\r
- Assert.AreEqual(8, tree.Successor(7));\r
- Assert.AreEqual(10, tree.Successor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(2, tree.Successor(0));\r
- Assert.AreEqual(0, tree.Successor(-1));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.Successor(37));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void SuccessorTooHigh1()\r
- {\r
- tree.Successor(38);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void SuccessorTooHigh2()\r
- {\r
- tree.Successor(39);\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakSuccessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.WeakSuccessor(6));\r
- Assert.AreEqual(8, tree.WeakSuccessor(7));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.WeakSuccessor(-1));\r
- Assert.AreEqual(0, tree.WeakSuccessor(0));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.WeakSuccessor(37));\r
- Assert.AreEqual(38, tree.WeakSuccessor(38));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void WeakSuccessorTooHigh1()\r
- {\r
- tree.WeakSuccessor(39);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class PriorityQueue\r
- {\r
- private TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- foreach (int i in new int[] { 1, 2, 3, 4 })\r
- tree.Add(i);\r
- tree.Add(1);\r
- tree.Add(3);\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- loadup();\r
- Assert.AreEqual(1, tree.FindMin());\r
- Assert.AreEqual(4, tree.FindMax());\r
- Assert.AreEqual(1, tree.DeleteMin());\r
- Assert.AreEqual(4, tree.DeleteMax());\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.AreEqual(1, tree.FindMin());\r
- Assert.AreEqual(3, tree.FindMax());\r
- Assert.AreEqual(1, tree.DeleteMin());\r
- Assert.AreEqual(3, tree.DeleteMax());\r
- Assert.IsTrue(tree.Check("Normal test 2"), "Bad tree");\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty1()\r
- {\r
- tree.FindMin();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty2()\r
- {\r
- tree.FindMax();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty3()\r
- {\r
- tree.DeleteMin();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty4()\r
- {\r
- tree.DeleteMax();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IndexingAndCounting\r
- {\r
- private TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- }\r
-\r
-\r
- private void populate()\r
- {\r
- tree.Add(30);\r
- tree.Add(30);\r
- tree.Add(50);\r
- tree.Add(10);\r
- tree.Add(70);\r
- tree.Add(70);\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- populate();\r
-\r
- int[] a = tree.ToArray();\r
-\r
- Assert.AreEqual(6, a.Length);\r
- Assert.AreEqual(10, a[0]);\r
- Assert.AreEqual(30, a[1]);\r
- Assert.AreEqual(30, a[2]);\r
- Assert.AreEqual(50, a[3]);\r
- Assert.AreEqual(70, a[4]);\r
- Assert.AreEqual(70, a[5]);\r
- }\r
-\r
-\r
- [Test]\r
- public void GoodIndex()\r
- {\r
- Assert.AreEqual(-1, tree.IndexOf(20));\r
- Assert.AreEqual(-1, tree.LastIndexOf(20));\r
- populate();\r
- Assert.AreEqual(10, tree[0]);\r
- Assert.AreEqual(30, tree[1]);\r
- Assert.AreEqual(30, tree[2]);\r
- Assert.AreEqual(50, tree[3]);\r
- Assert.AreEqual(70, tree[4]);\r
- Assert.AreEqual(70, tree[5]);\r
- Assert.AreEqual(0, tree.IndexOf(10));\r
- Assert.AreEqual(1, tree.IndexOf(30));\r
- Assert.AreEqual(3, tree.IndexOf(50));\r
- Assert.AreEqual(4, tree.IndexOf(70));\r
- Assert.AreEqual(~1, tree.IndexOf(20));\r
- Assert.AreEqual(~0, tree.IndexOf(0));\r
- Assert.AreEqual(~6, tree.IndexOf(90));\r
- Assert.AreEqual(0, tree.LastIndexOf(10));\r
- Assert.AreEqual(2, tree.LastIndexOf(30));\r
- Assert.AreEqual(3, tree.LastIndexOf(50));\r
- Assert.AreEqual(5, tree.LastIndexOf(70));\r
- Assert.AreEqual(~1, tree.LastIndexOf(20));\r
- Assert.AreEqual(~0, tree.LastIndexOf(0));\r
- Assert.AreEqual(~6, tree.LastIndexOf(90));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void IndexTooLarge()\r
- {\r
- populate();\r
- Console.WriteLine(tree[6]);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void IndexTooSmall()\r
- {\r
- populate();\r
- Console.WriteLine(tree[-1]);\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeOutsideInput()\r
- {\r
- populate();\r
- Assert.AreEqual(0, tree.CountFrom(90));\r
- Assert.AreEqual(0, tree.CountFromTo(-20, 0));\r
- Assert.AreEqual(0, tree.CountFromTo(80, 100));\r
- Assert.AreEqual(0, tree.CountTo(0));\r
- Assert.AreEqual(6, tree.CountTo(90));\r
- Assert.AreEqual(6, tree.CountFromTo(-20, 90));\r
- Assert.AreEqual(6, tree.CountFrom(0));\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeIntermediateInput()\r
- {\r
- populate();\r
- Assert.AreEqual(5, tree.CountFrom(20));\r
- Assert.AreEqual(2, tree.CountFromTo(20, 40));\r
- Assert.AreEqual(3, tree.CountTo(40));\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeMatchingInput()\r
- {\r
- populate();\r
- Assert.AreEqual(5, tree.CountFrom(30));\r
- Assert.AreEqual(3, tree.CountFromTo(30, 70));\r
- Assert.AreEqual(0, tree.CountFromTo(50, 30));\r
- Assert.AreEqual(0, tree.CountFromTo(50, 50));\r
- Assert.AreEqual(0, tree.CountTo(10));\r
- Assert.AreEqual(3, tree.CountTo(50));\r
- }\r
-\r
-\r
- [Test]\r
- public void CountEmptyTree()\r
- {\r
- Assert.AreEqual(0, tree.CountFrom(20));\r
- Assert.AreEqual(0, tree.CountFromTo(20, 40));\r
- Assert.AreEqual(0, tree.CountTo(40));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace ModificationCheck\r
- {\r
- [TestFixture]\r
- public class Enumerator\r
- {\r
- private TreeBag<int> tree;\r
-\r
- private SCG.IEnumerator<int> e;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
- tree.Add(3);\r
- tree.Add(7);\r
- e = tree.GetEnumerator();\r
- }\r
-\r
-\r
- [Test]\r
- public void CurrentAfterModification()\r
- {\r
- e.MoveNext();\r
- tree.Add(34);\r
- Assert.AreEqual(0, e.Current);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterAdd()\r
- {\r
- tree.Add(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterRemove()\r
- {\r
- tree.Remove(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterClear()\r
- {\r
- tree.Clear();\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- e = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class RangeEnumerator\r
- {\r
- private TreeBag<int> tree;\r
-\r
- private SCG.IEnumerator<int> e;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- e = tree.RangeFromTo(3, 7).GetEnumerator();\r
- }\r
-\r
-\r
- [Test]\r
- public void CurrentAfterModification()\r
- {\r
- e.MoveNext();\r
- tree.Add(34);\r
- Assert.AreEqual(3, e.Current);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterAdd()\r
- {\r
- tree.Add(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterRemove()\r
- {\r
- tree.Remove(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterClear()\r
- {\r
- tree.Clear();\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- e = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace PathcopyPersistence\r
- {\r
- [TestFixture]\r
- public class Navigation\r
- {\r
- private TreeBag<int> tree, snap;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeBag<int>(ic);\r
- for (int i = 0; i <= 20; i++)\r
- tree.Add(2 * i + 1);\r
- tree.Add(13);\r
- snap = (TreeBag<int>)tree.Snapshot();\r
- for (int i = 0; i <= 10; i++)\r
- tree.Remove(4 * i + 1);\r
- }\r
-\r
-\r
- private bool twomodeleven(int i)\r
- {\r
- return i % 11 == 2;\r
- }\r
-\r
-\r
- [Test]\r
- public void InternalEnum()\r
- {\r
- Assert.IsTrue(IC.eq(snap.FindAll(new Fun<int, bool>(twomodeleven)), 13, 13, 35));\r
- }\r
-\r
-\r
- public void MoreCut()\r
- {\r
- //TODO: Assert.Fail("more tests of Cut needed");\r
- }\r
-\r
-\r
- [Test]\r
- public void Cut()\r
- {\r
- int lo, hi;\r
- bool lv, hv;\r
-\r
- Assert.IsFalse(snap.Cut(new HigherOrder.CubeRoot(64), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(5, hi);\r
- Assert.AreEqual(3, lo);\r
- Assert.IsTrue(snap.Cut(new HigherOrder.CubeRoot(125), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(7, hi);\r
- Assert.AreEqual(3, lo);\r
- Assert.IsFalse(snap.Cut(new HigherOrder.CubeRoot(125000), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && !hv);\r
- Assert.AreEqual(41, lo);\r
- Assert.IsFalse(snap.Cut(new HigherOrder.CubeRoot(-27), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(!lv && hv);\r
- Assert.AreEqual(1, hi);\r
- }\r
-\r
-\r
- [Test]\r
- public void Range()\r
- {\r
- Assert.IsTrue(IC.eq(snap.RangeFromTo(5, 16), 5, 7, 9, 11, 13, 13, 15));\r
- Assert.IsTrue(IC.eq(snap.RangeFromTo(5, 17), 5, 7, 9, 11, 13, 13, 15));\r
- Assert.IsTrue(IC.eq(snap.RangeFromTo(6, 16), 7, 9, 11, 13, 13, 15));\r
- }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsTrue(snap.Contains(5));\r
- Assert.IsTrue(snap.Contains(13));\r
- Assert.AreEqual(1, snap.ContainsCount(5));\r
- Assert.AreEqual(2, snap.ContainsCount(13));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindMin()\r
- {\r
- Assert.AreEqual(1, snap.FindMin());\r
- }\r
-\r
-\r
- [Test]\r
- public void FindMax()\r
- {\r
- Assert.AreEqual(41, snap.FindMax());\r
- }\r
-\r
-\r
- [Test]\r
- public void Predecessor()\r
- {\r
- Assert.AreEqual(13, snap.Predecessor(15));\r
- Assert.AreEqual(15, snap.Predecessor(16));\r
- Assert.AreEqual(15, snap.Predecessor(17));\r
- Assert.AreEqual(17, snap.Predecessor(18));\r
- }\r
-\r
-\r
- [Test]\r
- public void Successor()\r
- {\r
- Assert.AreEqual(17, snap.Successor(15));\r
- Assert.AreEqual(17, snap.Successor(16));\r
- Assert.AreEqual(19, snap.Successor(17));\r
- Assert.AreEqual(19, snap.Successor(18));\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakPredecessor()\r
- {\r
- Assert.AreEqual(15, snap.WeakPredecessor(15));\r
- Assert.AreEqual(15, snap.WeakPredecessor(16));\r
- Assert.AreEqual(17, snap.WeakPredecessor(17));\r
- Assert.AreEqual(17, snap.WeakPredecessor(18));\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakSuccessor()\r
- {\r
- Assert.AreEqual(15, snap.WeakSuccessor(15));\r
- Assert.AreEqual(17, snap.WeakSuccessor(16));\r
- Assert.AreEqual(17, snap.WeakSuccessor(17));\r
- Assert.AreEqual(19, snap.WeakSuccessor(18));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NotSupportedException), "Indexing not supported for snapshots")]\r
- public void CountTo()\r
- {\r
- int j = snap.CountTo(15);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NotSupportedException), "Indexing not supported for snapshots")]\r
- public void Indexing()\r
- {\r
- int j = snap[4];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NotSupportedException), "Indexing not supported for snapshots")]\r
- public void Indexing2()\r
- {\r
- int j = snap.IndexOf(5);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- ic = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Single\r
- {\r
- private TreeBag<int> tree;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeBag<int>(ic);\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i + 1);\r
- }\r
-\r
-\r
- [Test]\r
- public void EnumerationWithAdd()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- int i = 0;\r
- TreeBag<int> snap = (TreeBag<int>)tree.Snapshot();\r
-\r
- foreach (int j in snap)\r
- {\r
- Assert.AreEqual(1 + 2 * i++, j);\r
- tree.Add(21 - j);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- TreeBag<int> snap = (TreeBag<int>)tree.Snapshot();\r
-\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- tree.Remove(19);\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveNormal()\r
- {\r
- tree.Clear();\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 10);\r
- }\r
- tree.Add(15);\r
-\r
- int[] orig = new int[] { 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 };\r
- TreeBag<int> snap = (TreeBag<int>)tree.Snapshot();\r
-\r
- Assert.IsFalse(tree.Remove(-20));\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
-\r
- //decrease items case\r
- Assert.IsTrue(tree.Remove(15));\r
- Assert.IsTrue(tree.Check("T1"));\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- //snap.dump();\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //No demote case, with move_item\r
- Assert.IsTrue(tree.Remove(20));\r
- Assert.IsTrue(tree.Check("T1"));\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsFalse(tree.Remove(20));\r
-\r
- //plain case 2\r
- tree.Snapshot();\r
- Assert.IsTrue(tree.Remove(14));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //case 1b\r
- Assert.IsTrue(tree.Remove(25));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //case 1c\r
- Assert.IsTrue(tree.Remove(29));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //1a (terminating)\r
- Assert.IsTrue(tree.Remove(10));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //2+1b\r
- Assert.IsTrue(tree.Remove(12));\r
- tree.Snapshot();\r
- Assert.IsTrue(tree.Remove(11));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //1a+1b\r
- Assert.IsTrue(tree.Remove(18));\r
- Assert.IsTrue(tree.Remove(13));\r
- Assert.IsTrue(tree.Remove(15));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //2+1c\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(50 - 2 * i);\r
-\r
- Assert.IsTrue(tree.Remove(42));\r
- Assert.IsTrue(tree.Remove(38));\r
- Assert.IsTrue(tree.Remove(28));\r
- Assert.IsTrue(tree.Remove(40));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //\r
- Assert.IsTrue(tree.Remove(16));\r
- Assert.IsTrue(tree.Remove(23));\r
- Assert.IsTrue(tree.Remove(17));\r
- Assert.IsTrue(tree.Remove(19));\r
- Assert.IsTrue(tree.Remove(50));\r
- Assert.IsTrue(tree.Remove(26));\r
- Assert.IsTrue(tree.Remove(21));\r
- Assert.IsTrue(tree.Remove(22));\r
- Assert.IsTrue(tree.Remove(24));\r
- for (int i = 0; i < 48; i++)\r
- tree.Remove(i);\r
-\r
- //Almost empty tree:\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Remove(48));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //Empty tree:\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- }\r
-\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- TreeBag<int> snap = (TreeBag<int>)tree.Snapshot();\r
-\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- tree.Add(10);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- tree.Add(16);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
-\r
- tree.Add(9);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //Promote+zigzig\r
- tree.Add(40);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- for (int i = 1; i < 4; i++)\r
- tree.Add(40 - 2 * i);\r
-\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
-\r
- //Zigzag:\r
- tree.Add(32);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- }\r
-\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- TreeBag<int> snap = (TreeBag<int>)tree.Snapshot();\r
-\r
- tree.Clear();\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.AreEqual(0, tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidOperationException), "Cannot snapshot a snapshot")]\r
- public void SnapSnap()\r
- {\r
- TreeBag<int> snap = (TreeBag<int>)tree.Snapshot();\r
-\r
- snap.Snapshot();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- ic = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Multiple\r
- {\r
- private TreeBag<int> tree;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- private bool eq(SCG.IEnumerable<int> me, int[] that)\r
- {\r
- int i = 0, maxind = that.Length - 1;\r
-\r
- foreach (int item in me)\r
- if (i > maxind || ic.Compare(item, that[i++]) != 0)\r
- return false;\r
-\r
- return true;\r
- }\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeBag<int>(ic);\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i + 1);\r
- }\r
-\r
-\r
- [Test]\r
- public void First()\r
- {\r
- TreeBag<int>[] snaps = new TreeBag<int>[10];\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- snaps[i] = (TreeBag<int>)(tree.Snapshot());\r
- tree.Add(2 * i);\r
- }\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- Assert.AreEqual(i + 10, snaps[i].Count);\r
- }\r
-\r
- snaps[5] = null;\r
- snaps[9] = null;\r
- GC.Collect();\r
- snaps[8].Dispose();\r
- tree.Remove(14);\r
-\r
- int[] res = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19 };\r
- int[] snap7 = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19 };\r
- int[] snap3 = new int[] { 0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19 };\r
-\r
- Assert.IsTrue(IC.eq(snaps[3], snap3), "Snap 3 was changed!");\r
- Assert.IsTrue(IC.eq(snaps[7], snap7), "Snap 7 was changed!");\r
- Assert.IsTrue(IC.eq(tree, res));\r
- Assert.IsTrue(tree.Check("B"));\r
- Assert.IsTrue(snaps[3].Check("B"));\r
- Assert.IsTrue(snaps[7].Check("B"));\r
- }\r
-\r
-\r
- [Test]\r
- public void CollectingTheMaster()\r
- {\r
- TreeBag<int>[] snaps = new TreeBag<int>[10];\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- snaps[i] = (TreeBag<int>)(tree.Snapshot());\r
- tree.Add(2 * i);\r
- }\r
-\r
- tree = null;\r
- GC.Collect();\r
- for (int i = 0; i < 10; i++)\r
- {\r
- Assert.AreEqual(i + 10, snaps[i].Count);\r
- }\r
-\r
- snaps[5] = null;\r
- snaps[9] = null;\r
- GC.Collect();\r
- snaps[8].Dispose();\r
-\r
- int[] snap7 = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19 };\r
- int[] snap3 = new int[] { 0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19 };\r
-\r
- Assert.IsTrue(IC.eq(snaps[3], snap3), "Snap 3 was changed!");\r
- Assert.IsTrue(IC.eq(snaps[7], snap7), "Snap 7 was changed!");\r
- Assert.IsTrue(snaps[3].Check("B"));\r
- Assert.IsTrue(snaps[7].Check("B"));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- ic = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace HigherOrder\r
- {\r
- internal class CubeRoot : IComparable<int>\r
- {\r
- private int c;\r
-\r
-\r
- internal CubeRoot(int c) { this.c = c; }\r
-\r
-\r
- public int CompareTo(int that) { return c - that * that * that; }\r
- public bool Equals(int that) { return c == that * that * that; }\r
- }\r
-\r
-\r
-\r
- class Interval : IComparable<int>\r
- {\r
- private int b, t;\r
-\r
-\r
- internal Interval(int b, int t) { this.b = b; this.t = t; }\r
-\r
-\r
- public int CompareTo(int that) { return that < b ? 1 : that > t ? -1 : 0; }\r
- public bool Equals(int that) { return that >= b && that <= t; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Simple\r
- {\r
- private TreeBag<int> tree;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeBag<int>(ic);\r
- }\r
-\r
-\r
- private bool never(int i) { return false; }\r
-\r
-\r
- private bool always(int i) { return true; }\r
-\r
-\r
- private bool even(int i) { return i % 2 == 0; }\r
-\r
-\r
- private string themap(int i) { return String.Format("AA {0,4} BB", i); }\r
-\r
-\r
- private string badmap(int i) { return String.Format("AA {0} BB", i); }\r
-\r
-\r
- private int appfield1;\r
-\r
- private int appfield2;\r
-\r
-\r
- private void apply(int i) { appfield1++; appfield2 += i * i; }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- Simple simple1 = new Simple();\r
-\r
- tree.Apply(new Act<int>(simple1.apply));\r
- Assert.AreEqual(0, simple1.appfield1);\r
- Assert.AreEqual(0, simple1.appfield2);\r
-\r
- Simple simple2 = new Simple();\r
-\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
- tree.Add(2);\r
-\r
- tree.Apply(new Act<int>(simple2.apply));\r
- Assert.AreEqual(11, simple2.appfield1);\r
- Assert.AreEqual(289, simple2.appfield2);\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2);\r
-\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2 + 1);\r
-\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(always)));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2);\r
-\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2 + 1);\r
-\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(always)));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindAll()\r
- {\r
- Assert.AreEqual(0, tree.FindAll(new Fun<int, bool>(never)).Count);\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
- tree.Add(2);\r
-\r
- Assert.AreEqual(0, tree.FindAll(new Fun<int, bool>(never)).Count);\r
- Assert.AreEqual(11, tree.FindAll(new Fun<int, bool>(always)).Count);\r
- Assert.AreEqual(6, tree.FindAll(new Fun<int, bool>(even)).Count);\r
- Assert.IsTrue(((TreeBag<int>)tree.FindAll(new Fun<int, bool>(even))).Check("R"));\r
- }\r
-\r
-\r
- [Test]\r
- public void Map()\r
- {\r
- Assert.AreEqual(0, tree.Map(new Fun<int, string>(themap), new SC()).Count);\r
- for (int i = 0; i < 14; i++)\r
- tree.Add(i * i * i);\r
- tree.Add(1);\r
-\r
- IIndexedSorted<string> res = tree.Map(new Fun<int, string>(themap), new SC());\r
-\r
- Assert.IsTrue(((TreeBag<string>)res).Check("R"));\r
- Assert.AreEqual(15, res.Count);\r
- Assert.AreEqual("AA 0 BB", res[0]);\r
- Assert.AreEqual("AA 1 BB", res[1]);\r
- Assert.AreEqual("AA 1 BB", res[2]);\r
- Assert.AreEqual("AA 8 BB", res[3]);\r
- Assert.AreEqual("AA 27 BB", res[4]);\r
- Assert.AreEqual("AA 125 BB", res[6]);\r
- Assert.AreEqual("AA 1000 BB", res[11]);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentException), "mapper not monotonic")]\r
- public void BadMap()\r
- {\r
- for (int i = 0; i < 11; i++)\r
- tree.Add(i * i * i);\r
-\r
- ISorted<string> res = tree.Map(new Fun<int, string>(badmap), new SC());\r
- }\r
-\r
-\r
- [Test]\r
- public void Cut()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
- tree.Add(3);\r
-\r
- int low, high;\r
- bool lval, hval;\r
-\r
- Assert.IsTrue(tree.Cut(new CubeRoot(27), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(2, low);\r
- Assert.IsFalse(tree.Cut(new CubeRoot(30), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(3, low);\r
- }\r
-\r
-\r
- [Test]\r
- public void CutInt()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i);\r
-\r
- int low, high;\r
- bool lval, hval;\r
-\r
- Assert.IsFalse(tree.Cut(new IC(3), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(2, low);\r
- Assert.IsTrue(tree.Cut(new IC(6), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(8, high);\r
- Assert.AreEqual(4, low);\r
- }\r
-\r
-\r
- [Test]\r
- public void CutInterval()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i);\r
-\r
- int lo, hi;\r
- bool lv, hv;\r
-\r
- Assert.IsTrue(tree.Cut(new Interval(5, 9), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(10, hi);\r
- Assert.AreEqual(4, lo);\r
- Assert.IsTrue(tree.Cut(new Interval(6, 10), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(12, hi);\r
- Assert.AreEqual(4, lo);\r
- for (int i = 0; i < 100; i++)\r
- tree.Add(2 * i);\r
-\r
- tree.Cut(new Interval(77, 105), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(106, hi);\r
- Assert.AreEqual(76, lo);\r
- tree.Cut(new Interval(5, 7), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(8, hi);\r
- Assert.AreEqual(4, lo);\r
- tree.Cut(new Interval(80, 110), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(112, hi);\r
- Assert.AreEqual(78, lo);\r
- }\r
-\r
-\r
- [Test]\r
- public void UpperCut()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- int l, h;\r
- bool lv, hv;\r
-\r
- Assert.IsFalse(tree.Cut(new CubeRoot(1000), out l, out lv, out h, out hv));\r
- Assert.IsTrue(lv && !hv);\r
- Assert.AreEqual(9, l);\r
- Assert.IsFalse(tree.Cut(new CubeRoot(-50), out l, out lv, out h, out hv));\r
- Assert.IsTrue(!lv && hv);\r
- Assert.AreEqual(0, h);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { ic = null; tree = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace MultiOps\r
- {\r
- [TestFixture]\r
- public class AddAll\r
- {\r
- private int sqr(int i) { return i * i; }\r
-\r
-\r
- TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init() { tree = new TreeBag<int>(new IC()); }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- tree.AddAll(new FunEnumerable(0, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeEmpty()\r
- {\r
- for (int i = 4; i < 9; i++) tree.Add(i);\r
-\r
- tree.AddAll(new FunEnumerable(0, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(5, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptySome()\r
- {\r
- tree.AddAll(new FunEnumerable(4, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(4, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(0, tree[0]);\r
- Assert.AreEqual(1, tree[1]);\r
- Assert.AreEqual(4, tree[2]);\r
- Assert.AreEqual(9, tree[3]);\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeSome()\r
- {\r
- for (int i = 5; i < 9; i++) tree.Add(i);\r
- tree.Add(1);\r
-\r
- tree.AddAll(new FunEnumerable(4, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(9, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 1, 4, 5, 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class AddSorted\r
- {\r
- private int sqr(int i) { return i * i; }\r
-\r
- private int step(int i) { return i / 3; }\r
-\r
-\r
- private int bad(int i) { return i * (5 - i); }\r
-\r
-\r
- TreeBag<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init() { tree = new TreeBag<int>(new IC()); }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- tree.AddSorted(new FunEnumerable(0, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeEmpty()\r
- {\r
- for (int i = 4; i < 9; i++) tree.Add(i);\r
-\r
- tree.AddSorted(new FunEnumerable(0, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(5, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptySome()\r
- {\r
- tree.AddSorted(new FunEnumerable(4, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(4, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(0, tree[0]);\r
- Assert.AreEqual(1, tree[1]);\r
- Assert.AreEqual(4, tree[2]);\r
- Assert.AreEqual(9, tree[3]);\r
- }\r
-\r
- [Test]\r
- public void EmptySome2()\r
- {\r
- tree.AddSorted(new FunEnumerable(4, new Fun<int, int>(step)));\r
- //tree.dump();\r
- Assert.AreEqual(4, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(0, tree[0]);\r
- Assert.AreEqual(0, tree[1]);\r
- Assert.AreEqual(0, tree[2]);\r
- Assert.AreEqual(1, tree[3]);\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeSome()\r
- {\r
- for (int i = 5; i < 9; i++) tree.Add(i);\r
- tree.Add(1);\r
-\r
- tree.AddSorted(new FunEnumerable(4, new Fun<int, int>(sqr)));\r
- Assert.AreEqual(9, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 1, 4, 5, 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentException), "Argument not sorted")]\r
- public void EmptyBad()\r
- {\r
- tree.AddSorted(new FunEnumerable(9, new Fun<int, int>(bad)));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Rest\r
- {\r
- TreeBag<int> tree, tree2;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeBag<int>(new IC());\r
- tree2 = new TreeBag<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
- tree.Add(4);\r
-\r
- for (int i = 0; i < 10; i++)\r
- tree2.Add(2 * i);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- tree.RemoveAll(tree2.RangeFromTo(3, 7));\r
- Assert.AreEqual(9, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 4, 5, 7, 8, 9));\r
- tree.RemoveAll(tree2.RangeFromTo(3, 7));\r
- Assert.AreEqual(8, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 5, 7, 8, 9));\r
- tree.RemoveAll(tree2.RangeFromTo(13, 17));\r
- Assert.AreEqual(8, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 5, 7, 8, 9));\r
- tree.RemoveAll(tree2.RangeFromTo(3, 17));\r
- Assert.AreEqual(7, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 5, 7, 9));\r
- for (int i = 0; i < 10; i++) tree2.Add(i);\r
-\r
- tree.RemoveAll(tree2.RangeFromTo(-1, 10));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
- private void pint<T>(SCG.IEnumerable<T> e)\r
- {\r
- foreach (T i in e)\r
- Console.Write("{0} ", i);\r
-\r
- Console.WriteLine();\r
- }\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- tree.Add(8); tree2.Add(6);\r
- //pint<int>(tree);\r
- //pint<int>(tree2);\r
- tree.RetainAll(tree2.RangeFromTo(3, 17));\r
- Assert.AreEqual(3, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 4, 6, 8));\r
- tree.RetainAll(tree2.RangeFromTo(1, 17));\r
- Assert.AreEqual(3, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 4, 6, 8));\r
- tree.RetainAll(tree2.RangeFromTo(3, 5));\r
- Assert.AreEqual(1, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 4));\r
- tree.RetainAll(tree2.RangeFromTo(7, 17));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- tree.RetainAll(tree2.RangeFromTo(5, 5));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- tree.RetainAll(tree2.RangeFromTo(15, 25));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- Assert.IsFalse(tree.ContainsAll(tree2));\r
- Assert.IsTrue(tree.ContainsAll(tree));\r
- tree2.Clear();\r
- Assert.IsTrue(tree.ContainsAll(tree2));\r
- tree.Clear();\r
- Assert.IsTrue(tree.ContainsAll(tree2));\r
- tree2.Add(8);\r
- Assert.IsFalse(tree.ContainsAll(tree2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- tree.RemoveInterval(3, 4);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(7, tree.Count);\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 6, 7, 8, 9));\r
- tree.RemoveInterval(2, 3);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(4, tree.Count);\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 8, 9));\r
- tree.RemoveInterval(0, 4);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad1()\r
- {\r
- tree.RemoveInterval(-3, 8);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad2()\r
- {\r
- tree.RemoveInterval(3, -8);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad3()\r
- {\r
- tree.RemoveInterval(3, 9);\r
- }\r
-\r
-\r
- [Test]\r
- public void GetRange()\r
- {\r
- Assert.IsTrue(IC.eq(tree[3, 3]));\r
- Assert.IsTrue(IC.eq(tree[3, 4], 3));\r
- Assert.IsTrue(IC.eq(tree[3, 5], 3, 4));\r
- Assert.IsTrue(IC.eq(tree[3, 6], 3, 4, 4));\r
- Assert.IsTrue(IC.eq(tree[3, 7], 3, 4, 4, 5));\r
- Assert.IsTrue(IC.eq(tree[4, 4]));\r
- Assert.IsTrue(IC.eq(tree[4, 5], 4));\r
- Assert.IsTrue(IC.eq(tree[4, 6], 4, 4));\r
- Assert.IsTrue(IC.eq(tree[4, 7], 4, 4, 5));\r
- Assert.IsTrue(IC.eq(tree[4, 8], 4, 4, 5, 6));\r
- Assert.IsTrue(IC.eq(tree[5, 5]));\r
- Assert.IsTrue(IC.eq(tree[5, 6], 4));\r
- Assert.IsTrue(IC.eq(tree[5, 7], 4, 5));\r
- Assert.IsTrue(IC.eq(tree[5, 8], 4, 5, 6));\r
- Assert.IsTrue(IC.eq(tree[5, 9], 4, 5, 6, 7));\r
- Assert.IsTrue(IC.eq(tree[5, 11], 4, 5, 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [Test]\r
- public void GetRangeBackwards()\r
- {\r
- Assert.IsTrue(IC.eq(tree[3, 3].Backwards()));\r
- Assert.IsTrue(IC.eq(tree[3, 4].Backwards(), 3));\r
- Assert.IsTrue(IC.eq(tree[3, 5].Backwards(), 4, 3));\r
- Assert.IsTrue(IC.eq(tree[3, 6].Backwards(), 4, 4, 3));\r
- Assert.IsTrue(IC.eq(tree[3, 7].Backwards(), 5, 4, 4, 3));\r
- Assert.IsTrue(IC.eq(tree[4, 4].Backwards()));\r
- Assert.IsTrue(IC.eq(tree[4, 5].Backwards(), 4));\r
- Assert.IsTrue(IC.eq(tree[4, 6].Backwards(), 4, 4));\r
- Assert.IsTrue(IC.eq(tree[4, 7].Backwards(), 5, 4, 4));\r
- Assert.IsTrue(IC.eq(tree[4, 8].Backwards(), 6, 5, 4, 4));\r
- Assert.IsTrue(IC.eq(tree[5, 5].Backwards()));\r
- Assert.IsTrue(IC.eq(tree[5, 6].Backwards(), 4));\r
- Assert.IsTrue(IC.eq(tree[5, 7].Backwards(), 5, 4));\r
- Assert.IsTrue(IC.eq(tree[5, 8].Backwards(), 6, 5, 4));\r
- Assert.IsTrue(IC.eq(tree[5, 9].Backwards(), 7, 6, 5, 4));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad1()\r
- {\r
- object foo = tree[-3, 0];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad2()\r
- {\r
- object foo = tree[3, 2];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad3()\r
- {\r
- object foo = tree[3, 12];\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; tree2 = null; }\r
- }\r
- }\r
-\r
-\r
- namespace Hashing\r
- {\r
- [TestFixture]\r
- public class ISequenced\r
- {\r
- private ISequenced<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeBag<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new TreeBag<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new TreeBag<int>(new RevIC(), EqualityComparer<int>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- }\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.sequencedhashcode(), dit.GetSequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dit.GetSequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(3, 7), dit.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.sequencedhashcode(), dut.GetSequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dut.GetSequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(7, 3), dut.GetSequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dat.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dut));\r
- Assert.IsTrue(dut.SequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- Assert.IsFalse(dut.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeBag<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new TreeBag<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new TreeBag<int>(new RevIC(), EqualityComparer<int>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG=System.Collections.Generic;\r
-\r
-\r
-namespace C5UnitTests.trees.RBDictionary\r
-{\r
- static class Factory\r
- {\r
- public static IDictionary<K,V> New<K,V>() { return new TreeDictionary<K,V>(); }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- IDictionary<int,int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int,int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("[ ]", coll.ToString());\r
- coll.Add(23, 67); coll.Add(45, 89);\r
- Assert.AreEqual("[ 23 => 67, 45 => 89 ]", coll.ToString());\r
- Assert.AreEqual("[ 17 => 43, 2D => 59 ]", coll.ToString(null, rad16));\r
- Assert.AreEqual("[ 23 => 67, ... ]", coll.ToString("L14", null));\r
- Assert.AreEqual("[ 17 => 43, ... ]", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class RBDict\r
- {\r
- private TreeDictionary<string,string> dict;\r
-\r
-\r
- [SetUp]\r
- public void Init() { dict = new TreeDictionary<string,string>(new SC()); }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { dict = null; }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new TreeDictionary<int,int>(null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- dict.Add("YES","NO");\r
- Assert.AreEqual(new KeyValuePair<string,string>("YES","NO"), dict.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- dict.Choose();\r
- }\r
-\r
- [Test]\r
- public void Pred()\r
- {\r
- dict.Add("A", "1");\r
- dict.Add("C", "2");\r
- dict.Add("E", "3");\r
- Assert.AreEqual("1", dict.Predecessor("B").Value);\r
- Assert.AreEqual("1", dict.Predecessor("C").Value);\r
- Assert.AreEqual("1", dict.WeakPredecessor("B").Value);\r
- Assert.AreEqual("2", dict.WeakPredecessor("C").Value);\r
- Assert.AreEqual("2", dict.Successor("B").Value);\r
- Assert.AreEqual("3", dict.Successor("C").Value);\r
- Assert.AreEqual("2", dict.WeakSuccessor("B").Value);\r
- Assert.AreEqual("2", dict.WeakSuccessor("C").Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Initial()\r
- {\r
- bool res;\r
- Assert.IsFalse(dict.IsReadOnly);\r
-\r
- Assert.AreEqual(dict.Count, 0, "new dict should be empty");\r
- dict.Add("A", "B");\r
- Assert.AreEqual(dict.Count, 1, "bad count");\r
- Assert.AreEqual(dict["A"], "B", "Wrong value for dict[A]");\r
- dict.Add("C", "D");\r
- Assert.AreEqual(dict.Count, 2, "bad count");\r
- Assert.AreEqual(dict["A"], "B", "Wrong value");\r
- Assert.AreEqual(dict["C"], "D", "Wrong value");\r
- res = dict.Remove("A");\r
- Assert.IsTrue(res, "bad return value from Remove(A)");\r
- Assert.IsTrue(dict.Check());\r
- Assert.AreEqual(dict.Count, 1, "bad count");\r
- Assert.AreEqual(dict["C"], "D", "Wrong value of dict[C]");\r
- res = dict.Remove("Z");\r
- Assert.IsFalse(res, "bad return value from Remove(Z)");\r
- Assert.AreEqual(dict.Count, 1, "bad count");\r
- Assert.AreEqual(dict["C"], "D", "Wrong value of dict[C] (2)");\r
- dict.Clear();\r
- Assert.AreEqual(dict.Count, 0, "dict should be empty");\r
- }\r
- [Test]\r
- public void Contains()\r
- {\r
- dict.Add("C", "D");\r
- Assert.IsTrue(dict.Contains("C"));\r
- Assert.IsFalse(dict.Contains("D"));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(DuplicateNotAllowedException), "Key being added: 'A'")]\r
- public void IllegalAdd()\r
- {\r
- dict.Add("A", "B");\r
- dict.Add("A", "B");\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void GettingNonExisting()\r
- {\r
- Console.WriteLine(dict["R"]);\r
- }\r
-\r
-\r
- [Test]\r
- public void Setter()\r
- {\r
- dict["R"] = "UYGUY";\r
- Assert.AreEqual(dict["R"], "UYGUY");\r
- dict["R"] = "UIII";\r
- Assert.AreEqual(dict["R"], "UIII");\r
- dict["S"] = "VVV";\r
- Assert.AreEqual(dict["R"], "UIII");\r
- Assert.AreEqual(dict["S"], "VVV");\r
- //dict.dump();\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Enumerators\r
- {\r
- private TreeDictionary<string,string> dict;\r
-\r
- private SCG.IEnumerator<KeyValuePair<string,string>> dictenum;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dict = new TreeDictionary<string,string>(new SC());\r
- dict["S"] = "A";\r
- dict["T"] = "B";\r
- dict["R"] = "C";\r
- dictenum = dict.GetEnumerator();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dictenum = null;\r
- dict = null;\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void Keys()\r
- {\r
- SCG.IEnumerator<string> keys = dict.Keys.GetEnumerator();\r
- Assert.AreEqual(3, dict.Keys.Count);\r
- Assert.IsTrue(keys.MoveNext());\r
- Assert.AreEqual("R",keys.Current);\r
- Assert.IsTrue(keys.MoveNext());\r
- Assert.AreEqual("S",keys.Current);\r
- Assert.IsTrue(keys.MoveNext());\r
- Assert.AreEqual("T",keys.Current);\r
- Assert.IsFalse(keys.MoveNext());\r
- }\r
-\r
- [Test]\r
- public void Values()\r
- {\r
- SCG.IEnumerator<string> values = dict.Values.GetEnumerator();\r
- Assert.AreEqual(3, dict.Values.Count);\r
- Assert.IsTrue(values.MoveNext());\r
- Assert.AreEqual("C",values.Current);\r
- Assert.IsTrue(values.MoveNext());\r
- Assert.AreEqual("A",values.Current);\r
- Assert.IsTrue(values.MoveNext());\r
- Assert.AreEqual("B",values.Current);\r
- Assert.IsFalse(values.MoveNext());\r
- }\r
-\r
- [Test]\r
- public void Fun()\r
- {\r
- Assert.AreEqual("B", dict.Fun("T"));\r
- }\r
-\r
-\r
- [Test]\r
- public void NormalUse()\r
- {\r
- Assert.IsTrue(dictenum.MoveNext());\r
- Assert.AreEqual(dictenum.Current, new KeyValuePair<string,string>("R", "C"));\r
- Assert.IsTrue(dictenum.MoveNext());\r
- Assert.AreEqual(dictenum.Current, new KeyValuePair<string,string>("S", "A"));\r
- Assert.IsTrue(dictenum.MoveNext());\r
- Assert.AreEqual(dictenum.Current, new KeyValuePair<string,string>("T", "B"));\r
- Assert.IsFalse(dictenum.MoveNext());\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace PathCopyPersistence\r
- {\r
- [TestFixture]\r
- public class Simple\r
- {\r
- private TreeDictionary<string,string> dict;\r
-\r
- private TreeDictionary<string,string> snap;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dict = new TreeDictionary<string,string>(new SC());\r
- dict["S"] = "A";\r
- dict["T"] = "B";\r
- dict["R"] = "C";\r
- dict["V"] = "G";\r
- snap = (TreeDictionary<string,string>)dict.Snapshot();\r
- }\r
-\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- dict["SS"] = "D";\r
- Assert.AreEqual(5, dict.Count);\r
- Assert.AreEqual(4, snap.Count);\r
- dict["T"] = "bb";\r
- Assert.AreEqual(5, dict.Count);\r
- Assert.AreEqual(4, snap.Count);\r
- Assert.AreEqual("B", snap["T"]);\r
- Assert.AreEqual("bb", dict["T"]);\r
- Assert.IsFalse(dict.IsReadOnly);\r
- Assert.IsTrue(snap.IsReadOnly);\r
- //Finally, update of root node:\r
- TreeDictionary<string,string> snap2 = (TreeDictionary<string,string>)dict.Snapshot();\r
- dict["S"] = "abe";\r
- Assert.AreEqual("abe", dict["S"]);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ReadOnlyCollectionException))]\r
- public void UpdateSnap()\r
- {\r
- snap["Y"] = "J";\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dict = null;\r
- snap = null;\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using C5;\r
-using NUnit.Framework;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace C5UnitTests.trees.TreeSet\r
-{\r
- using CollectionOfInt = TreeSet<int>;\r
-\r
- [TestFixture]\r
- public class GenericTesters\r
- {\r
- [Test]\r
- public void TestEvents()\r
- {\r
- Fun<CollectionOfInt> factory = delegate() { return new CollectionOfInt(TenEqualityComparer.Default); };\r
- new C5UnitTests.Templates.Events.SortedIndexedTester<CollectionOfInt>().Test(factory);\r
- }\r
-\r
- [Test]\r
- public void Extensible()\r
- {\r
- C5UnitTests.Templates.Extensible.Clone.Tester<CollectionOfInt>();\r
- C5UnitTests.Templates.Extensible.Serialization.Tester<CollectionOfInt>();\r
- }\r
- }\r
-\r
- static class Factory\r
- {\r
- public static ICollection<T> New<T>() { return new TreeSet<T>(); }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Formatting\r
- {\r
- ICollection<int> coll;\r
- IFormatProvider rad16;\r
- [SetUp]\r
- public void Init() { coll = Factory.New<int>(); rad16 = new RadixFormatProvider(16); }\r
- [TearDown]\r
- public void Dispose() { coll = null; rad16 = null; }\r
- [Test]\r
- public void Format()\r
- {\r
- Assert.AreEqual("{ }", coll.ToString());\r
- coll.AddAll<int>(new int[] { -4, 28, 129, 65530 });\r
- Assert.AreEqual("{ -4, 28, 129, 65530 }", coll.ToString());\r
- Assert.AreEqual("{ -4, 1C, 81, FFFA }", coll.ToString(null, rad16));\r
- Assert.AreEqual("{ -4, 28, 129... }", coll.ToString("L14", null));\r
- Assert.AreEqual("{ -4, 1C, 81... }", coll.ToString("L14", rad16));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class Combined\r
- {\r
- private IIndexedSorted<KeyValuePair<int,int>> lst;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- lst = new TreeSet<KeyValuePair<int,int>>(new KeyValuePairComparer<int,int>(new IC()));\r
- for (int i = 0; i < 10; i++)\r
- lst.Add(new KeyValuePair<int,int>(i, i + 30));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { lst = null; }\r
-\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Find(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Find(ref p));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindOrAdd()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- p = new KeyValuePair<int,int>(13, 79);\r
- Assert.IsFalse(lst.FindOrAdd(ref p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void Update()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Update(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Update(p));\r
- }\r
-\r
-\r
- [Test]\r
- public void UpdateOrAdd()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(3, lst[3].Key);\r
- Assert.AreEqual(78, lst[3].Value);\r
- p = new KeyValuePair<int,int>(13, 79);\r
- Assert.IsFalse(lst.UpdateOrAdd(p));\r
- Assert.AreEqual(13, lst[10].Key);\r
- Assert.AreEqual(79, lst[10].Value);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveWithReturn()\r
- {\r
- KeyValuePair<int,int> p = new KeyValuePair<int,int>(3, 78);\r
-\r
- Assert.IsTrue(lst.Remove(p, out p));\r
- Assert.AreEqual(3, p.Key);\r
- Assert.AreEqual(33, p.Value);\r
- Assert.AreEqual(4, lst[3].Key);\r
- Assert.AreEqual(34, lst[3].Value);\r
- p = new KeyValuePair<int,int>(13, 78);\r
- Assert.IsFalse(lst.Remove(p, out p));\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Ranges\r
- {\r
- private TreeSet<int> tree;\r
-\r
- private SCG.IComparer<int> c;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- c = new IC();\r
- tree = new TreeSet<int>(c);\r
- for (int i = 1; i <= 10; i++)\r
- {\r
- tree.Add(i * 2);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Enumerator()\r
- {\r
- SCG.IEnumerator<int> e = tree.RangeFromTo(5, 17).GetEnumerator();\r
- int i = 3;\r
-\r
- while (e.MoveNext())\r
- {\r
- Assert.AreEqual(2 * i++, e.Current);\r
- }\r
-\r
- Assert.AreEqual(9, i);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidOperationException))]\r
- public void Enumerator2()\r
- {\r
- SCG.IEnumerator<int> e = tree.RangeFromTo(5, 17).GetEnumerator();\r
- int i = e.Current;\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidOperationException))]\r
- public void Enumerator3()\r
- {\r
- SCG.IEnumerator<int> e = tree.RangeFromTo(5, 17).GetEnumerator();\r
-\r
- while (e.MoveNext());\r
-\r
- int i = e.Current;\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- int[] all = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };\r
-\r
- tree.RemoveRangeFrom(18);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 2, 4, 6, 8, 10, 12, 14, 16 }));\r
- tree.RemoveRangeFrom(28);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 2, 4, 6, 8, 10, 12, 14, 16 }));\r
- tree.RemoveRangeFrom(2);\r
- Assert.IsTrue(IC.eq(tree));\r
- foreach (int i in all) tree.Add(i);\r
-\r
- tree.RemoveRangeTo(10);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 10, 12, 14, 16, 18, 20 }));\r
- tree.RemoveRangeTo(2);\r
- Assert.IsTrue(IC.eq(tree, new int[] { 10, 12, 14, 16, 18, 20 }));\r
- tree.RemoveRangeTo(21);\r
- Assert.IsTrue(IC.eq(tree));\r
- foreach (int i in all) tree.Add(i);\r
-\r
- tree.RemoveRangeFromTo(4, 8);\r
- Assert.IsTrue(IC.eq(tree, 2, 8, 10, 12, 14, 16, 18, 20));\r
- tree.RemoveRangeFromTo(14, 28);\r
- Assert.IsTrue(IC.eq(tree, 2, 8, 10, 12));\r
- tree.RemoveRangeFromTo(0, 9);\r
- Assert.IsTrue(IC.eq(tree, 10, 12));\r
- tree.RemoveRangeFromTo(0, 81);\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- int[] all = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };\r
-\r
- Assert.IsTrue(IC.eq(tree, all));\r
- Assert.IsTrue(IC.eq(tree.RangeAll(), all));\r
- Assert.AreEqual(10, tree.RangeAll().Count);\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(11), new int[] { 12, 14, 16, 18, 20 }));\r
- Assert.AreEqual(5, tree.RangeFrom(11).Count);\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(12), new int[] { 12, 14, 16, 18, 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(2), all));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(1), all));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(21), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(20), new int[] { 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(8), new int[] { 2, 4, 6 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(7), new int[] { 2, 4, 6 }));\r
- Assert.AreEqual(3, tree.RangeTo(7).Count);\r
- Assert.IsTrue(IC.eq(tree.RangeTo(2), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(1), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(3), new int[] { 2 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(20), new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(21), all));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(7, 12), new int[] { 8, 10 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 11), new int[] { 6, 8, 10 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(1, 12), new int[] { 2, 4, 6, 8, 10 }));\r
- Assert.AreEqual(5, tree.RangeFromTo(1, 12).Count);\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(2, 12), new int[] { 2, 4, 6, 8, 10 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 21), new int[] { 6, 8, 10, 12, 14, 16, 18, 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 20), new int[] { 6, 8, 10, 12, 14, 16, 18 }));\r
- }\r
-\r
-\r
- [Test]\r
- public void Backwards()\r
- {\r
- int[] all = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };\r
- int[] lla = new int[] { 20, 18, 16, 14, 12, 10, 8, 6, 4, 2 };\r
-\r
- Assert.IsTrue(IC.eq(tree, all));\r
- Assert.IsTrue(IC.eq(tree.RangeAll().Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(11).Backwards(), new int[] { 20, 18, 16, 14, 12 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(12).Backwards(), new int[] { 20, 18, 16, 14, 12 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(2).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(1).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(21).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeFrom(20).Backwards(), new int[] { 20 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(8).Backwards(), new int[] { 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(7).Backwards(), new int[] { 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(2).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(1).Backwards(), new int[] { }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(3).Backwards(), new int[] { 2 }));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(20).Backwards(), new int[] { 18, 16, 14, 12, 10, 8, 6, 4, 2}));\r
- Assert.IsTrue(IC.eq(tree.RangeTo(21).Backwards(), lla));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(7, 12).Backwards(), new int[] { 10, 8 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 11).Backwards(), new int[] { 10, 8, 6 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(1, 12).Backwards(), new int[] { 10, 8, 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(2, 12).Backwards(), new int[] { 10, 8, 6, 4, 2 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 21).Backwards(), new int[] { 20, 18, 16, 14, 12, 10, 8, 6 }));\r
- Assert.IsTrue(IC.eq(tree.RangeFromTo(6, 20).Backwards(), new int[] { 18, 16, 14, 12, 10, 8, 6 }));\r
- }\r
-\r
- [Test]\r
- public void Direction()\r
- {\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeFrom(20).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeTo(7).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeFromTo(1, 12).Direction);\r
- Assert.AreEqual(EnumerationDirection.Forwards, tree.RangeAll().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeFrom(20).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeTo(7).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeFromTo(1, 12).Backwards().Direction);\r
- Assert.AreEqual(EnumerationDirection.Backwards, tree.RangeAll().Backwards().Direction);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- c = null;\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class BagItf\r
- {\r
- private TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 10);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Both()\r
- {\r
- Assert.AreEqual(0, tree.ContainsCount(7));\r
- Assert.AreEqual(1, tree.ContainsCount(10));\r
- tree.RemoveAllCopies(10);\r
- Assert.AreEqual(0, tree.ContainsCount(10));\r
- tree.RemoveAllCopies(7);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class Div\r
- {\r
- private TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 10);\r
- }\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor1()\r
- {\r
- new TreeSet<int>(null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor3()\r
- {\r
- new TreeSet<int>(null, EqualityComparer<int>.Default);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor4()\r
- {\r
- new TreeSet<int>(Comparer<int>.Default, null);\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NullReferenceException))]\r
- public void NullEqualityComparerinConstructor5()\r
- {\r
- new TreeSet<int>(null, null);\r
- }\r
-\r
- [Test]\r
- public void Choose()\r
- {\r
- tree.Add(7);\r
- Assert.AreEqual(7, tree.Choose());\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void BadChoose()\r
- {\r
- tree.Choose();\r
- }\r
-\r
-\r
- [Test]\r
- public void NoDuplicates()\r
- {\r
- Assert.IsFalse(tree.AllowsDuplicates);\r
- loadup();\r
- Assert.IsFalse(tree.AllowsDuplicates);\r
- }\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- Assert.IsTrue(tree.Add(17));\r
- Assert.IsFalse(tree.Add(17));\r
- Assert.IsTrue(tree.Add(18));\r
- Assert.IsFalse(tree.Add(18));\r
- Assert.AreEqual(2, tree.Count);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
- [TestFixture]\r
- public class FindOrAdd\r
- {\r
- private TreeSet<KeyValuePair<int,string>> bag;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- bag = new TreeSet<KeyValuePair<int,string>>(new KeyValuePairComparer<int,string>(new IC()));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- bag = null;\r
- }\r
-\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- KeyValuePair<int,string> p = new KeyValuePair<int,string>(3, "tre");\r
-\r
- Assert.IsFalse(bag.FindOrAdd(ref p));\r
- p.Value = "drei";\r
- Assert.IsTrue(bag.FindOrAdd(ref p));\r
- Assert.AreEqual("tre", p.Value);\r
- p.Value = "three";\r
- Assert.AreEqual(1, bag.ContainsCount(p));\r
- Assert.AreEqual("tre", bag[0].Value);\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class FindPredicate\r
- {\r
- private TreeSet<int> list;\r
- Fun<int, bool> pred;\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- list = new TreeSet<int>(TenEqualityComparer.Default);\r
- pred = delegate(int i) { return i % 5 == 0; };\r
- }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Find()\r
- {\r
- int i;\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.Find(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.Find(pred, out i));\r
- Assert.AreEqual(45, i);\r
- }\r
-\r
- [Test]\r
- public void FindLast()\r
- {\r
- int i;\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(list.FindLast(pred, out i));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.IsTrue(list.FindLast(pred, out i));\r
- Assert.AreEqual(675, i);\r
- }\r
-\r
- [Test]\r
- public void FindIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(3, list.FindIndex(pred));\r
- }\r
-\r
- [Test]\r
- public void FindLastIndex()\r
- {\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 4, 22, 67, 37 });\r
- Assert.IsFalse(0 <= list.FindLastIndex(pred));\r
- list.AddAll<int>(new int[] { 45, 122, 675, 137 });\r
- Assert.AreEqual(7, list.FindLastIndex(pred));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class UniqueItems\r
- {\r
- private TreeSet<int> list;\r
-\r
- [SetUp]\r
- public void Init() { list = new TreeSet<int>(); }\r
-\r
- [TearDown]\r
- public void Dispose() { list = null; }\r
-\r
- [Test]\r
- public void Test()\r
- {\r
- Assert.IsTrue(IC.seteq(list.UniqueItems()));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities()));\r
- list.AddAll<int>(new int[] { 7, 9, 7 });\r
- Assert.IsTrue(IC.seteq(list.UniqueItems(), 7, 9));\r
- Assert.IsTrue(IC.seteq(list.ItemMultiplicities(), 7, 1, 9, 1));\r
- }\r
- }\r
-\r
- [TestFixture]\r
- public class ArrayTest\r
- {\r
- private TreeSet<int> tree;\r
-\r
- int[] a;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- a = new int[10];\r
- for (int i = 0; i < 10; i++)\r
- a[i] = 1000 + i;\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
-\r
-\r
- private string aeq(int[] a, params int[] b)\r
- {\r
- if (a.Length != b.Length)\r
- return "Lengths differ: " + a.Length + " != " + b.Length;\r
-\r
- for (int i = 0; i < a.Length; i++)\r
- if (a[i] != b[i])\r
- return String.Format("{0}'th elements differ: {1} != {2}", i, a[i], b[i]);\r
-\r
- return "Alles klar";\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- Assert.AreEqual("Alles klar", aeq(tree.ToArray()));\r
- tree.Add(7);\r
- tree.Add(4);\r
- Assert.AreEqual("Alles klar", aeq(tree.ToArray(), 4, 7));\r
- }\r
-\r
-\r
- [Test]\r
- public void CopyTo()\r
- {\r
- tree.CopyTo(a, 1);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- tree.Add(6);\r
- tree.CopyTo(a, 2);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 1004, 1005, 1006, 1007, 1008, 1009));\r
- tree.Add(4);\r
- tree.Add(9);\r
- tree.CopyTo(a, 4);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 4, 6, 9, 1007, 1008, 1009));\r
- tree.Clear();\r
- tree.Add(7);\r
- tree.CopyTo(a, 9);\r
- Assert.AreEqual("Alles klar", aeq(a, 1000, 1001, 6, 1003, 4, 6, 9, 1007, 1008, 7));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad()\r
- {\r
- tree.CopyTo(a, 11);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToBad2()\r
- {\r
- tree.CopyTo(a, -1);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void CopyToTooFar()\r
- {\r
- tree.Add(3);\r
- tree.Add(4);\r
- tree.CopyTo(a, 9);\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Remove\r
- {\r
- private TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 10);\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void SmallTrees()\r
- {\r
- tree.Clear();\r
- tree.Add(7);\r
- tree.Add(9);\r
- Assert.IsTrue(tree.Remove(7));\r
- Assert.IsTrue(tree.Check(""));\r
- }\r
-\r
-\r
- [Test]\r
- public void ByIndex()\r
- {\r
- //Remove root!\r
- int n = tree.Count;\r
- int i = tree[10];\r
-\r
- tree.RemoveAt(10);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 1, tree.Count);\r
-\r
- //Low end\r
- i = tree.FindMin();\r
- tree.RemoveAt(0);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 2, tree.Count);\r
-\r
- //high end\r
- i = tree.FindMax();\r
- tree.RemoveAt(tree.Count - 1);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 3, tree.Count);\r
-\r
- //Some leaf\r
- i = 18;\r
- tree.RemoveAt(7);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(i));\r
- Assert.AreEqual(n - 4, tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- public void AlmostEmpty()\r
- {\r
- //Almost empty\r
- tree.Clear();\r
- tree.Add(3);\r
- tree.RemoveAt(0);\r
- Assert.IsTrue(tree.Check(""));\r
- Assert.IsFalse(tree.Contains(3));\r
- Assert.AreEqual(0, tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void Empty()\r
- {\r
- tree.Clear();\r
- tree.RemoveAt(0);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void HighIndex()\r
- {\r
- tree.RemoveAt(tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException), "Index out of range for sequenced collectionvalue")]\r
- public void LowIndex()\r
- {\r
- tree.RemoveAt(-1);\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- Assert.IsFalse(tree.Remove(-20));\r
-\r
- //No demote case, with move_item\r
- Assert.IsTrue(tree.Remove(20));\r
- Assert.IsTrue(tree.Check("T1"));\r
- Assert.IsFalse(tree.Remove(20));\r
-\r
- //plain case 2\r
- Assert.IsTrue(tree.Remove(14));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //case 1b\r
- Assert.IsTrue(tree.Remove(25));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //case 1c\r
- Assert.IsTrue(tree.Remove(29));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //1a (terminating)\r
- Assert.IsTrue(tree.Remove(10));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //2+1b\r
- Assert.IsTrue(tree.Remove(12));\r
- Assert.IsTrue(tree.Remove(11));\r
-\r
- //1a+1b\r
- Assert.IsTrue(tree.Remove(18));\r
- Assert.IsTrue(tree.Remove(13));\r
- Assert.IsTrue(tree.Remove(15));\r
-\r
- //2+1c\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(50 - 2 * i);\r
-\r
- Assert.IsTrue(tree.Remove(42));\r
- Assert.IsTrue(tree.Remove(38));\r
- Assert.IsTrue(tree.Remove(28));\r
- Assert.IsTrue(tree.Remove(40));\r
-\r
- //\r
- Assert.IsTrue(tree.Remove(16));\r
- Assert.IsTrue(tree.Remove(23));\r
- Assert.IsTrue(tree.Remove(17));\r
- Assert.IsTrue(tree.Remove(19));\r
- Assert.IsTrue(tree.Remove(50));\r
- Assert.IsTrue(tree.Remove(26));\r
- Assert.IsTrue(tree.Remove(21));\r
- Assert.IsTrue(tree.Remove(22));\r
- Assert.IsTrue(tree.Remove(24));\r
- for (int i = 0; i < 48; i++)\r
- tree.Remove(i);\r
-\r
- //Almost empty tree:\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Remove(48));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
-\r
- //Empty tree:\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class PredecessorStructure\r
- {\r
- private TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- for (int i = 0; i < 20; i++)\r
- tree.Add(2 * i);\r
- }\r
-\r
-\r
- [Test]\r
- public void Predecessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.Predecessor(7));\r
- Assert.AreEqual(6, tree.Predecessor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.Predecessor(1));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.Predecessor(39));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PredecessorTooLow1()\r
- {\r
- tree.Predecessor(-2);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void PredecessorTooLow2()\r
- {\r
- tree.Predecessor(0);\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakPredecessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.WeakPredecessor(7));\r
- Assert.AreEqual(8, tree.WeakPredecessor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.WeakPredecessor(1));\r
- Assert.AreEqual(0, tree.WeakPredecessor(0));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.WeakPredecessor(39));\r
- Assert.AreEqual(38, tree.WeakPredecessor(38));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void WeakPredecessorTooLow1()\r
- {\r
- tree.WeakPredecessor(-2);\r
- }\r
-\r
-\r
- [Test]\r
- public void Successor()\r
- {\r
- loadup();\r
- Assert.AreEqual(8, tree.Successor(7));\r
- Assert.AreEqual(10, tree.Successor(8));\r
-\r
- //The bottom\r
- Assert.AreEqual(2, tree.Successor(0));\r
- Assert.AreEqual(0, tree.Successor(-1));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.Successor(37));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void SuccessorTooHigh1()\r
- {\r
- tree.Successor(38);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void SuccessorTooHigh2()\r
- {\r
- tree.Successor(39);\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakSuccessor()\r
- {\r
- loadup();\r
- Assert.AreEqual(6, tree.WeakSuccessor(6));\r
- Assert.AreEqual(8, tree.WeakSuccessor(7));\r
-\r
- //The bottom\r
- Assert.AreEqual(0, tree.WeakSuccessor(-1));\r
- Assert.AreEqual(0, tree.WeakSuccessor(0));\r
-\r
- //The top\r
- Assert.AreEqual(38, tree.WeakSuccessor(37));\r
- Assert.AreEqual(38, tree.WeakSuccessor(38));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void WeakSuccessorTooHigh1()\r
- {\r
- tree.WeakSuccessor(39);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class PriorityQueue\r
- {\r
- private TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- }\r
-\r
-\r
- private void loadup()\r
- {\r
- foreach (int i in new int[] { 1, 2, 3, 4 })\r
- tree.Add(i);\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- loadup();\r
- Assert.AreEqual(1, tree.FindMin());\r
- Assert.AreEqual(4, tree.FindMax());\r
- Assert.AreEqual(1, tree.DeleteMin());\r
- Assert.AreEqual(4, tree.DeleteMax());\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.AreEqual(2, tree.FindMin());\r
- Assert.AreEqual(3, tree.FindMax());\r
- Assert.AreEqual(2, tree.DeleteMin());\r
- Assert.AreEqual(3, tree.DeleteMax());\r
- Assert.IsTrue(tree.Check("Normal test 2"), "Bad tree");\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty1()\r
- {\r
- tree.FindMin();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty2()\r
- {\r
- tree.FindMax();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty3()\r
- {\r
- tree.DeleteMin();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NoSuchItemException))]\r
- public void Empty4()\r
- {\r
- tree.DeleteMax();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IndexingAndCounting\r
- {\r
- private TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- }\r
-\r
-\r
- private void populate()\r
- {\r
- tree.Add(30);\r
- tree.Add(50);\r
- tree.Add(10);\r
- tree.Add(70);\r
- }\r
-\r
-\r
- [Test]\r
- public void ToArray()\r
- {\r
- populate();\r
-\r
- int[] a = tree.ToArray();\r
-\r
- Assert.AreEqual(4, a.Length);\r
- Assert.AreEqual(10, a[0]);\r
- Assert.AreEqual(30, a[1]);\r
- Assert.AreEqual(50, a[2]);\r
- Assert.AreEqual(70, a[3]);\r
- }\r
-\r
-\r
- [Test]\r
- public void GoodIndex()\r
- {\r
- Assert.AreEqual(-1, tree.IndexOf(20));\r
- Assert.AreEqual(-1, tree.LastIndexOf(20));\r
- populate();\r
- Assert.AreEqual(10, tree[0]);\r
- Assert.AreEqual(30, tree[1]);\r
- Assert.AreEqual(50, tree[2]);\r
- Assert.AreEqual(70, tree[3]);\r
- Assert.AreEqual(0, tree.IndexOf(10));\r
- Assert.AreEqual(1, tree.IndexOf(30));\r
- Assert.AreEqual(2, tree.IndexOf(50));\r
- Assert.AreEqual(3, tree.IndexOf(70));\r
- Assert.AreEqual(~1, tree.IndexOf(20));\r
- Assert.AreEqual(~0, tree.IndexOf(0));\r
- Assert.AreEqual(~4, tree.IndexOf(90));\r
- Assert.AreEqual(0, tree.LastIndexOf(10));\r
- Assert.AreEqual(1, tree.LastIndexOf(30));\r
- Assert.AreEqual(2, tree.LastIndexOf(50));\r
- Assert.AreEqual(3, tree.LastIndexOf(70));\r
- Assert.AreEqual(~1, tree.LastIndexOf(20));\r
- Assert.AreEqual(~0, tree.LastIndexOf(0));\r
- Assert.AreEqual(~4, tree.LastIndexOf(90));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void IndexTooLarge()\r
- {\r
- populate();\r
- Console.WriteLine(tree[4]);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(IndexOutOfRangeException))]\r
- public void IndexTooSmall()\r
- {\r
- populate();\r
- Console.WriteLine(tree[-1]);\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeOutsideInput()\r
- {\r
- populate();\r
- Assert.AreEqual(0, tree.CountFrom(90));\r
- Assert.AreEqual(0, tree.CountFromTo(-20, 0));\r
- Assert.AreEqual(0, tree.CountFromTo(80, 100));\r
- Assert.AreEqual(0, tree.CountTo(0));\r
- Assert.AreEqual(4, tree.CountTo(90));\r
- Assert.AreEqual(4, tree.CountFromTo(-20, 90));\r
- Assert.AreEqual(4, tree.CountFrom(0));\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeIntermediateInput()\r
- {\r
- populate();\r
- Assert.AreEqual(3, tree.CountFrom(20));\r
- Assert.AreEqual(1, tree.CountFromTo(20, 40));\r
- Assert.AreEqual(2, tree.CountTo(40));\r
- }\r
-\r
-\r
- [Test]\r
- public void FilledTreeMatchingInput()\r
- {\r
- populate();\r
- Assert.AreEqual(3, tree.CountFrom(30));\r
- Assert.AreEqual(2, tree.CountFromTo(30, 70));\r
- Assert.AreEqual(0, tree.CountFromTo(50, 30));\r
- Assert.AreEqual(0, tree.CountFromTo(50, 50));\r
- Assert.AreEqual(0, tree.CountTo(10));\r
- Assert.AreEqual(2, tree.CountTo(50));\r
- }\r
-\r
-\r
- [Test]\r
- public void CountEmptyTree()\r
- {\r
- Assert.AreEqual(0, tree.CountFrom(20));\r
- Assert.AreEqual(0, tree.CountFromTo(20, 40));\r
- Assert.AreEqual(0, tree.CountTo(40));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace ModificationCheck\r
- {\r
- [TestFixture]\r
- public class Enumerator\r
- {\r
- private TreeSet<int> tree;\r
-\r
- private SCG.IEnumerator<int> e;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- e = tree.GetEnumerator();\r
- }\r
-\r
-\r
- [Test]\r
- public void CurrentAfterModification()\r
- {\r
- e.MoveNext();\r
- tree.Add(34);\r
- Assert.AreEqual(0, e.Current);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterAdd()\r
- {\r
- tree.Add(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterRemove()\r
- {\r
- tree.Remove(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterClear()\r
- {\r
- tree.Clear();\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- e = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class RangeEnumerator\r
- {\r
- private TreeSet<int> tree;\r
-\r
- private SCG.IEnumerator<int> e;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- e = tree.RangeFromTo(3, 7).GetEnumerator();\r
- }\r
-\r
-\r
- [Test]\r
- public void CurrentAfterModification()\r
- {\r
- e.MoveNext();\r
- tree.Add(34);\r
- Assert.AreEqual(3, e.Current);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterAdd()\r
- {\r
- tree.Add(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterRemove()\r
- {\r
- tree.Remove(34);\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(CollectionModifiedException))]\r
- public void MoveNextAfterClear()\r
- {\r
- tree.Clear();\r
- e.MoveNext();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- e = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace PathcopyPersistence\r
- {\r
- [TestFixture]\r
- public class Navigation\r
- {\r
- private TreeSet<int> tree, snap;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeSet<int>(ic);\r
- for (int i = 0; i <= 20; i++)\r
- tree.Add(2 * i + 1);\r
-\r
- snap = (TreeSet<int>)tree.Snapshot();\r
- for (int i = 0; i <= 10; i++)\r
- tree.Remove(4 * i + 1);\r
- }\r
-\r
-\r
- private bool twomodeleven(int i)\r
- {\r
- return i % 11 == 2;\r
- }\r
-\r
-\r
- [Test]\r
- public void InternalEnum()\r
- {\r
- Assert.IsTrue(IC.eq(snap.FindAll(new Fun<int, bool>(twomodeleven)), 13, 35));\r
- }\r
-\r
- \r
- public void MoreCut() { }\r
-\r
- [Test]\r
- public void Cut()\r
- {\r
- int lo, hi;\r
- bool lv, hv;\r
-\r
- Assert.IsFalse(snap.Cut(new HigherOrder.CubeRoot(64), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(5, hi);\r
- Assert.AreEqual(3, lo);\r
- Assert.IsTrue(snap.Cut(new HigherOrder.CubeRoot(125), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(7, hi);\r
- Assert.AreEqual(3, lo);\r
- Assert.IsFalse(snap.Cut(new HigherOrder.CubeRoot(125000), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && !hv);\r
- Assert.AreEqual(41, lo);\r
- Assert.IsFalse(snap.Cut(new HigherOrder.CubeRoot(-27), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(!lv && hv);\r
- Assert.AreEqual(1, hi);\r
- }\r
-\r
-\r
- [Test]\r
- public void Range()\r
- {\r
- Assert.IsTrue(IC.eq(snap.RangeFromTo(5, 16), 5, 7, 9, 11, 13, 15));\r
- Assert.IsTrue(IC.eq(snap.RangeFromTo(5, 17), 5, 7, 9, 11, 13, 15));\r
- Assert.IsTrue(IC.eq(snap.RangeFromTo(6, 16), 7, 9, 11, 13, 15));\r
- //Assert.AreEqual(snap.RangeFromTo(6, 16).Count, 5);\r
- }\r
-\r
-\r
- [Test]\r
- public void Contains()\r
- {\r
- Assert.IsTrue(snap.Contains(5));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindMin()\r
- {\r
- Assert.AreEqual(1, snap.FindMin());\r
- }\r
-\r
-\r
- [Test]\r
- public void FindMax()\r
- {\r
- Assert.AreEqual(41, snap.FindMax());\r
- }\r
-\r
-\r
- [Test]\r
- public void Predecessor()\r
- {\r
- Assert.AreEqual(13, snap.Predecessor(15));\r
- Assert.AreEqual(15, snap.Predecessor(16));\r
- Assert.AreEqual(15, snap.Predecessor(17));\r
- Assert.AreEqual(17, snap.Predecessor(18));\r
- }\r
-\r
-\r
- [Test]\r
- public void Successor()\r
- {\r
- Assert.AreEqual(17, snap.Successor(15));\r
- Assert.AreEqual(17, snap.Successor(16));\r
- Assert.AreEqual(19, snap.Successor(17));\r
- Assert.AreEqual(19, snap.Successor(18));\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakPredecessor()\r
- {\r
- Assert.AreEqual(15, snap.WeakPredecessor(15));\r
- Assert.AreEqual(15, snap.WeakPredecessor(16));\r
- Assert.AreEqual(17, snap.WeakPredecessor(17));\r
- Assert.AreEqual(17, snap.WeakPredecessor(18));\r
- }\r
-\r
-\r
- [Test]\r
- public void WeakSuccessor()\r
- {\r
- Assert.AreEqual(15, snap.WeakSuccessor(15));\r
- Assert.AreEqual(17, snap.WeakSuccessor(16));\r
- Assert.AreEqual(17, snap.WeakSuccessor(17));\r
- Assert.AreEqual(19, snap.WeakSuccessor(18));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NotSupportedException), "Indexing not supported for snapshots")]\r
- public void CountTo()\r
- {\r
- int j = snap.CountTo(15);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NotSupportedException), "Indexing not supported for snapshots")]\r
- public void Indexing()\r
- {\r
- int j = snap[4];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(NotSupportedException), "Indexing not supported for snapshots")]\r
- public void Indexing2()\r
- {\r
- int j = snap.IndexOf(5);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- ic = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Single\r
- {\r
- private TreeSet<int> tree;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeSet<int>(ic);\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i + 1);\r
- }\r
-\r
-\r
- [Test]\r
- public void EnumerationWithAdd()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- int i = 0;\r
- TreeSet<int> snap = (TreeSet<int>)tree.Snapshot();\r
-\r
- foreach (int j in snap)\r
- {\r
- Assert.AreEqual(1 + 2 * i++, j);\r
- tree.Add(21 - j);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- }\r
- }\r
-\r
-\r
- [Test]\r
- public void Remove()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- TreeSet<int> snap = (TreeSet<int>)tree.Snapshot();\r
-\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- tree.Remove(19);\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveNormal()\r
- {\r
- tree.Clear();\r
- for (int i = 10; i < 20; i++)\r
- {\r
- tree.Add(i);\r
- tree.Add(i + 10);\r
- }\r
-\r
- int[] orig = new int[] { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 };\r
- TreeSet<int> snap = (TreeSet<int>)tree.Snapshot();\r
-\r
- Assert.IsFalse(tree.Remove(-20));\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //No demote case, with move_item\r
- Assert.IsTrue(tree.Remove(20));\r
- Assert.IsTrue(tree.Check("T1"));\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsFalse(tree.Remove(20));\r
-\r
- //plain case 2\r
- tree.Snapshot();\r
- Assert.IsTrue(tree.Remove(14));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //case 1b\r
- Assert.IsTrue(tree.Remove(25));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //case 1c\r
- Assert.IsTrue(tree.Remove(29));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //1a (terminating)\r
- Assert.IsTrue(tree.Remove(10));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //2+1b\r
- Assert.IsTrue(tree.Remove(12));\r
- tree.Snapshot();\r
- Assert.IsTrue(tree.Remove(11));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //1a+1b\r
- Assert.IsTrue(tree.Remove(18));\r
- Assert.IsTrue(tree.Remove(13));\r
- Assert.IsTrue(tree.Remove(15));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //2+1c\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(50 - 2 * i);\r
-\r
- Assert.IsTrue(tree.Remove(42));\r
- Assert.IsTrue(tree.Remove(38));\r
- Assert.IsTrue(tree.Remove(28));\r
- Assert.IsTrue(tree.Remove(40));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //\r
- Assert.IsTrue(tree.Remove(16));\r
- Assert.IsTrue(tree.Remove(23));\r
- Assert.IsTrue(tree.Remove(17));\r
- Assert.IsTrue(tree.Remove(19));\r
- Assert.IsTrue(tree.Remove(50));\r
- Assert.IsTrue(tree.Remove(26));\r
- Assert.IsTrue(tree.Remove(21));\r
- Assert.IsTrue(tree.Remove(22));\r
- Assert.IsTrue(tree.Remove(24));\r
- for (int i = 0; i < 48; i++)\r
- tree.Remove(i);\r
-\r
- //Almost empty tree:\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Remove(48));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
-\r
- //Empty tree:\r
- Assert.IsFalse(tree.Remove(26));\r
- Assert.IsTrue(tree.Check("Normal test 1"), "Bad tree");\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- }\r
-\r
-\r
- [Test]\r
- public void Add()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- TreeSet<int> snap = (TreeSet<int>)tree.Snapshot();\r
-\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- tree.Add(10);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- tree.Add(16);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
-\r
- //Promote+zigzig\r
- tree.Add(40);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- for (int i = 1; i < 4; i++)\r
- tree.Add(40 - 2 * i);\r
-\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
-\r
- //Zigzag:\r
- tree.Add(32);\r
- Assert.IsTrue(snap.Check("M"), "Bad snap!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- }\r
-\r
-\r
- [Test]\r
- public void Clear()\r
- {\r
- int[] orig = new int[] { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };\r
- TreeSet<int> snap = (TreeSet<int>)tree.Snapshot();\r
-\r
- tree.Clear();\r
- Assert.IsTrue(snap.Check("Snap"), "Bad snap!");\r
- Assert.IsTrue(tree.Check("Tree"), "Bad tree!");\r
- Assert.IsTrue(IC.eq(snap, orig), "Snap was changed!");\r
- Assert.AreEqual(0, tree.Count);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(InvalidOperationException), "Cannot snapshot a snapshot")]\r
- public void SnapSnap()\r
- {\r
- TreeSet<int> snap = (TreeSet<int>)tree.Snapshot();\r
-\r
- snap.Snapshot();\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- ic = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Multiple\r
- {\r
- private TreeSet<int> tree;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- private bool eq(SCG.IEnumerable<int> me, int[] that)\r
- {\r
- int i = 0, maxind = that.Length - 1;\r
-\r
- foreach (int item in me)\r
- if (i > maxind || ic.Compare(item, that[i++]) != 0)\r
- return false;\r
-\r
- return true;\r
- }\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeSet<int>(ic);\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i + 1);\r
- }\r
-\r
-\r
- [Test]\r
- public void First()\r
- {\r
- TreeSet<int>[] snaps = new TreeSet<int>[10];\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- snaps[i] = (TreeSet<int>)(tree.Snapshot());\r
- tree.Add(2 * i);\r
- }\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- Assert.AreEqual(i + 10, snaps[i].Count);\r
- }\r
-\r
- snaps[5] = null;\r
- snaps[9] = null;\r
- GC.Collect();\r
- snaps[8].Dispose();\r
- tree.Remove(14);\r
-\r
- int[] res = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19 };\r
- int[] snap7 = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19 };\r
- int[] snap3 = new int[] { 0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19 };\r
-\r
- Assert.IsTrue(IC.eq(snaps[3], snap3), "Snap 3 was changed!");\r
- Assert.IsTrue(IC.eq(snaps[7], snap7), "Snap 7 was changed!");\r
- Assert.IsTrue(IC.eq(tree, res));\r
- Assert.IsTrue(tree.Check("B"));\r
- Assert.IsTrue(snaps[3].Check("B"));\r
- Assert.IsTrue(snaps[7].Check("B"));\r
- }\r
-\r
-\r
- [Test]\r
- public void CollectingTheMaster()\r
- {\r
- TreeSet<int>[] snaps = new TreeSet<int>[10];\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- snaps[i] = (TreeSet<int>)(tree.Snapshot());\r
- tree.Add(2 * i);\r
- }\r
-\r
- tree = null;\r
- GC.Collect();\r
- for (int i = 0; i < 10; i++)\r
- {\r
- Assert.AreEqual(i + 10, snaps[i].Count);\r
- }\r
-\r
- snaps[5] = null;\r
- snaps[9] = null;\r
- GC.Collect();\r
- snaps[8].Dispose();\r
-\r
- int[] snap7 = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19 };\r
- int[] snap3 = new int[] { 0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19 };\r
-\r
- Assert.IsTrue(IC.eq(snaps[3], snap3), "Snap 3 was changed!");\r
- Assert.IsTrue(IC.eq(snaps[7], snap7), "Snap 7 was changed!");\r
- Assert.IsTrue(snaps[3].Check("B"));\r
- Assert.IsTrue(snaps[7].Check("B"));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- tree = null;\r
- ic = null;\r
- }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace HigherOrder\r
- {\r
- internal class CubeRoot: IComparable<int>\r
- {\r
- private int c;\r
-\r
-\r
- internal CubeRoot(int c) { this.c = c; }\r
-\r
-\r
- public int CompareTo(int that) { return c - that * that * that; }\r
- public bool Equals(int that) { return c == that * that * that; }\r
- }\r
-\r
-\r
-\r
- class Interval: IComparable<int>\r
- {\r
- private int b, t;\r
-\r
-\r
- internal Interval(int b, int t) { this.b = b; this.t = t; }\r
-\r
-\r
- public int CompareTo(int that) { return that < b ? 1 : that > t ? -1 : 0; }\r
- public bool Equals(int that) { return that >= b && that <= t; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class Simple\r
- {\r
- private TreeSet<int> tree;\r
-\r
- private SCG.IComparer<int> ic;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- ic = new IC();\r
- tree = new TreeSet<int>(ic);\r
- }\r
-\r
-\r
- private bool never(int i) { return false; }\r
-\r
-\r
- private bool always(int i) { return true; }\r
-\r
-\r
- private bool even(int i) { return i % 2 == 0; }\r
-\r
-\r
- private string themap(int i) { return String.Format("AA {0,4} BB", i); }\r
-\r
-\r
- private string badmap(int i) { return String.Format("AA {0} BB", i); }\r
-\r
-\r
- private int appfield1;\r
-\r
- private int appfield2;\r
-\r
-\r
- private void apply(int i) { appfield1++; appfield2 += i * i; }\r
-\r
-\r
- [Test]\r
- public void Apply()\r
- {\r
- Simple simple1 = new Simple();\r
-\r
- tree.Apply(new Act<int>(simple1.apply));\r
- Assert.AreEqual(0, simple1.appfield1);\r
- Assert.AreEqual(0, simple1.appfield2);\r
-\r
- Simple simple2 = new Simple();\r
-\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- tree.Apply(new Act<int>(simple2.apply));\r
- Assert.AreEqual(10, simple2.appfield1);\r
- Assert.AreEqual(285, simple2.appfield2);\r
- }\r
-\r
-\r
- [Test]\r
- public void All()\r
- {\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2);\r
-\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2 + 1);\r
-\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.All(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.All(new Fun<int, bool>(always)));\r
- }\r
-\r
-\r
- [Test]\r
- public void Exists()\r
- {\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(always)));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2);\r
-\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(always)));\r
- tree.Clear();\r
- for (int i = 0; i < 10; i++) tree.Add(i * 2 + 1);\r
-\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(never)));\r
- Assert.IsFalse(tree.Exists(new Fun<int, bool>(even)));\r
- Assert.IsTrue(tree.Exists(new Fun<int, bool>(always)));\r
- }\r
-\r
-\r
- [Test]\r
- public void FindAll()\r
- {\r
- Assert.AreEqual(0, tree.FindAll(new Fun<int, bool>(never)).Count);\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- Assert.AreEqual(0, tree.FindAll(new Fun<int, bool>(never)).Count);\r
- Assert.AreEqual(10, tree.FindAll(new Fun<int, bool>(always)).Count);\r
- Assert.AreEqual(5, tree.FindAll(new Fun<int, bool>(even)).Count);\r
- Assert.IsTrue(((TreeSet<int>)tree.FindAll(new Fun<int, bool>(even))).Check("R"));\r
- }\r
-\r
-\r
- [Test]\r
- public void Map()\r
- {\r
- Assert.AreEqual(0, tree.Map(new Fun<int,string>(themap), new SC()).Count);\r
- for (int i = 0; i < 11; i++)\r
- tree.Add(i * i * i);\r
-\r
- IIndexedSorted<string> res = tree.Map(new Fun<int,string>(themap), new SC());\r
-\r
- Assert.IsTrue(((TreeSet<string>)res).Check("R"));\r
- Assert.AreEqual(11, res.Count);\r
- Assert.AreEqual("AA 0 BB", res[0]);\r
- Assert.AreEqual("AA 27 BB", res[3]);\r
- Assert.AreEqual("AA 125 BB", res[5]);\r
- Assert.AreEqual("AA 1000 BB", res[10]);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentException), "mapper not monotonic")]\r
- public void BadMap()\r
- {\r
- for (int i = 0; i < 11; i++)\r
- tree.Add(i * i * i);\r
-\r
- ISorted<string> res = tree.Map(new Fun<int,string>(badmap), new SC());\r
- }\r
-\r
-\r
- [Test]\r
- public void Cut()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- int low, high;\r
- bool lval, hval;\r
-\r
- Assert.IsTrue(tree.Cut(new CubeRoot(27), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(2, low);\r
- Assert.IsFalse(tree.Cut(new CubeRoot(30), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(3, low);\r
- }\r
-\r
-\r
- [Test]\r
- public void CutInt()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i);\r
-\r
- int low, high;\r
- bool lval, hval;\r
-\r
- Assert.IsFalse(tree.Cut(new IC(3), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(4, high);\r
- Assert.AreEqual(2, low);\r
- Assert.IsTrue(tree.Cut(new IC(6), out low, out lval, out high, out hval));\r
- Assert.IsTrue(lval && hval);\r
- Assert.AreEqual(8, high);\r
- Assert.AreEqual(4, low);\r
- }\r
-\r
-\r
- [Test]\r
- public void CutInterval()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(2 * i);\r
-\r
- int lo, hi;\r
- bool lv, hv;\r
-\r
- Assert.IsTrue(tree.Cut(new Interval(5, 9), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(10, hi);\r
- Assert.AreEqual(4, lo);\r
- Assert.IsTrue(tree.Cut(new Interval(6, 10), out lo, out lv, out hi, out hv));\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(12, hi);\r
- Assert.AreEqual(4, lo);\r
- for (int i = 0; i < 100; i++)\r
- tree.Add(2 * i);\r
-\r
- tree.Cut(new Interval(77, 105), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(106, hi);\r
- Assert.AreEqual(76, lo);\r
- tree.Cut(new Interval(5, 7), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(8, hi);\r
- Assert.AreEqual(4, lo);\r
- tree.Cut(new Interval(80, 110), out lo, out lv, out hi, out hv);\r
- Assert.IsTrue(lv && hv);\r
- Assert.AreEqual(112, hi);\r
- Assert.AreEqual(78, lo);\r
- }\r
-\r
-\r
- [Test]\r
- public void UpperCut()\r
- {\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- int l, h;\r
- bool lv, hv;\r
-\r
- Assert.IsFalse(tree.Cut(new CubeRoot(1000), out l, out lv, out h, out hv));\r
- Assert.IsTrue(lv && !hv);\r
- Assert.AreEqual(9, l);\r
- Assert.IsFalse(tree.Cut(new CubeRoot(-50), out l, out lv, out h, out hv));\r
- Assert.IsTrue(!lv && hv);\r
- Assert.AreEqual(0, h);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { ic = null; tree = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace MultiOps\r
- {\r
- [TestFixture]\r
- public class AddAll\r
- {\r
- private int sqr(int i) { return i * i; }\r
-\r
-\r
- TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init() { tree = new TreeSet<int>(new IC()); }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- tree.AddAll(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeEmpty()\r
- {\r
- for (int i = 4; i < 9; i++) tree.Add(i);\r
-\r
- tree.AddAll(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(5, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptySome()\r
- {\r
- tree.AddAll(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(4, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(0, tree[0]);\r
- Assert.AreEqual(1, tree[1]);\r
- Assert.AreEqual(4, tree[2]);\r
- Assert.AreEqual(9, tree[3]);\r
- }\r
-\r
-\r
- [Test]\r
- public void SomeSome()\r
- {\r
- for (int i = 5; i < 9; i++) tree.Add(i);\r
-\r
- tree.AddAll(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(8, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 4, 5, 6, 7, 8, 9));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class AddSorted\r
- {\r
- private int sqr(int i) { return i * i; }\r
-\r
-\r
- private int bad(int i) { return i * (5 - i); }\r
-\r
-\r
- TreeSet<int> tree;\r
-\r
-\r
- [SetUp]\r
- public void Init() { tree = new TreeSet<int>(new IC()); }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- tree.AddSorted(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void SomeEmpty()\r
- {\r
- for (int i = 4; i < 9; i++) tree.Add(i);\r
-\r
- tree.AddSorted(new FunEnumerable(0, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(5, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void EmptySome()\r
- {\r
- tree.AddSorted(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(4, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(0, tree[0]);\r
- Assert.AreEqual(1, tree[1]);\r
- Assert.AreEqual(4, tree[2]);\r
- Assert.AreEqual(9, tree[3]);\r
- }\r
-\r
-\r
-\r
- [Test]\r
- public void SomeSome()\r
- {\r
- for (int i = 5; i < 9; i++) tree.Add(i);\r
-\r
- tree.AddSorted(new FunEnumerable(4, new Fun<int,int>(sqr)));\r
- Assert.AreEqual(8, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 4, 5, 6, 7, 8, 9));\r
- }\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentException), "Argument not sorted")]\r
- public void EmptyBad()\r
- {\r
- tree.AddSorted(new FunEnumerable(9, new Fun<int,int>(bad)));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
-\r
- [TestFixture]\r
- public class Rest\r
- {\r
- TreeSet<int> tree, tree2;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- tree2 = new TreeSet<int>(new IC());\r
- for (int i = 0; i < 10; i++)\r
- tree.Add(i);\r
-\r
- for (int i = 0; i < 10; i++)\r
- tree2.Add(2 * i);\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveAll()\r
- {\r
- tree.RemoveAll(tree2.RangeFromTo(3, 7));\r
- Assert.AreEqual(8, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 5, 7, 8, 9));\r
- tree.RemoveAll(tree2.RangeFromTo(3, 7));\r
- Assert.AreEqual(8, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 5, 7, 8, 9));\r
- tree.RemoveAll(tree2.RangeFromTo(13, 17));\r
- Assert.AreEqual(8, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 5, 7, 8, 9));\r
- tree.RemoveAll(tree2.RangeFromTo(3, 17));\r
- Assert.AreEqual(7, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 3, 5, 7, 9));\r
- for (int i = 0; i < 10; i++) tree2.Add(i);\r
-\r
- tree.RemoveAll(tree2.RangeFromTo(-1, 10));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
-\r
- [Test]\r
- public void RetainAll()\r
- {\r
- tree.RetainAll(tree2.RangeFromTo(3, 17));\r
- Assert.AreEqual(3, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 4, 6, 8));\r
- tree.RetainAll(tree2.RangeFromTo(1, 17));\r
- Assert.AreEqual(3, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 4, 6, 8));\r
- tree.RetainAll(tree2.RangeFromTo(3, 5));\r
- Assert.AreEqual(1, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree, 4));\r
- tree.RetainAll(tree2.RangeFromTo(7, 17));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- tree.RetainAll(tree2.RangeFromTo(5, 5));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- for (int i = 0; i < 10; i++) tree.Add(i);\r
-\r
- tree.RetainAll(tree2.RangeFromTo(15, 25));\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
-\r
- [Test]\r
- public void ContainsAll()\r
- {\r
- Assert.IsFalse(tree.ContainsAll(tree2));\r
- Assert.IsTrue(tree.ContainsAll(tree));\r
- tree2.Clear();\r
- Assert.IsTrue(tree.ContainsAll(tree2));\r
- tree.Clear();\r
- Assert.IsTrue(tree.ContainsAll(tree2));\r
- tree2.Add(8);\r
- Assert.IsFalse(tree.ContainsAll(tree2));\r
- }\r
-\r
-\r
- [Test]\r
- public void RemoveInterval()\r
- {\r
- tree.RemoveInterval(3, 4);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(6, tree.Count);\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 2, 7, 8, 9));\r
- tree.RemoveInterval(2, 3);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(3, tree.Count);\r
- Assert.IsTrue(IC.eq(tree, 0, 1, 9));\r
- tree.RemoveInterval(0, 3);\r
- Assert.IsTrue(tree.Check());\r
- Assert.AreEqual(0, tree.Count);\r
- Assert.IsTrue(IC.eq(tree));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad1()\r
- {\r
- tree.RemoveInterval(-3, 8);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad2()\r
- {\r
- tree.RemoveInterval(3, -8);\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void RemoveRangeBad3()\r
- {\r
- tree.RemoveInterval(3, 8);\r
- }\r
-\r
-\r
- [Test]\r
- public void GetRange()\r
- {\r
- SCG.IEnumerable<int> e = tree[3, 6];\r
-\r
- Assert.IsTrue(IC.eq(e, 3, 4, 5));\r
- e = tree[3, 3];\r
- Assert.IsTrue(IC.eq(e));\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad1()\r
- {\r
- object foo = tree[-3, 0];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad2()\r
- {\r
- object foo = tree[3, 2];\r
- }\r
-\r
-\r
- [Test]\r
- [ExpectedException(typeof(ArgumentOutOfRangeException))]\r
- public void GetRangeBad3()\r
- {\r
- object foo = tree[3, 11];\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; tree2 = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace Sync\r
- {\r
- [TestFixture]\r
- public class SyncRoot\r
- {\r
- private TreeSet<int> tree;\r
-\r
- int sz = 5000;\r
-\r
-\r
- [Test]\r
- public void Safe()\r
- {\r
- System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(safe1));\r
- System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(safe2));\r
-\r
- t1.Start();\r
- t2.Start();\r
- t1.Join();\r
- t2.Join();\r
- Assert.AreEqual(2 * sz + 1, tree.Count);\r
- Assert.IsTrue(tree.Check());\r
- }\r
-\r
-\r
- //[Test]\r
- public void UnSafe()\r
- {\r
- bool bad = false;\r
-\r
- for (int i = 0; i < 10; i++)\r
- {\r
- System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe1));\r
- System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe2));\r
-\r
- t1.Start();\r
- t2.Start();\r
- t1.Join();\r
- t2.Join();\r
- if (bad = 2 * sz + 1 != tree.Count)\r
- {\r
- Console.WriteLine("{0}::Unsafe(): bad at {1}", GetType(), i);\r
- break;\r
- }\r
- }\r
-\r
- Assert.IsTrue(bad, "No sync problems!");\r
- }\r
-\r
-\r
- [Test]\r
- public void SafeUnSafe()\r
- {\r
- System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe1));\r
- System.Threading.Thread t2 = new System.Threading.Thread(new System.Threading.ThreadStart(unsafe2));\r
-\r
- t1.Start();\r
- t1.Join();\r
- t2.Start();\r
- t2.Join();\r
- Assert.AreEqual(2 * sz + 1, tree.Count);\r
- }\r
-\r
-\r
- [SetUp]\r
- public void Init() { tree = new TreeSet<int>(new IC()); }\r
-\r
-\r
- private void unsafe1()\r
- {\r
- for (int i = 0; i < 2 * sz; i++)\r
- tree.Add(i * 2);\r
-\r
- for (int i = 1; i < sz; i++)\r
- tree.Remove(i * 4);\r
- }\r
-\r
-\r
- private void safe1()\r
- {\r
- for (int i = 0; i < 2 * sz; i++)\r
- lock (tree.SyncRoot)\r
- tree.Add(i * 2);\r
-\r
- for (int i = 1; i < sz; i++)\r
- lock (tree.SyncRoot)\r
- tree.Remove(i * 4);\r
- }\r
-\r
-\r
- private void unsafe2()\r
- {\r
- for (int i = 2 * sz; i > 0; i--)\r
- tree.Add(i * 2 + 1);\r
-\r
- for (int i = sz; i > 0; i--)\r
- tree.Remove(i * 4 + 1);\r
- }\r
-\r
-\r
- private void safe2()\r
- {\r
- for (int i = 2 * sz; i > 0; i--)\r
- lock (tree.SyncRoot)\r
- tree.Add(i * 2 + 1);\r
-\r
- for (int i = sz; i > 0; i--)\r
- lock (tree.SyncRoot)\r
- tree.Remove(i * 4 + 1);\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
-\r
-\r
-\r
- //[TestFixture]\r
- public class ConcurrentQueries\r
- {\r
- private TreeSet<int> tree;\r
-\r
- int sz = 500000;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- tree = new TreeSet<int>(new IC());\r
- for (int i = 0; i < sz; i++)\r
- {\r
- tree.Add(i);\r
- }\r
- }\r
-\r
-\r
-\r
- class A\r
- {\r
- public int count = 0;\r
-\r
- TreeSet<int> t;\r
-\r
-\r
- public A(TreeSet<int> t) { this.t = t; }\r
-\r
-\r
- public void a(int i) { count++; }\r
-\r
-\r
- public void traverse() { t.Apply(new Act<int>(a)); }\r
- }\r
-\r
-\r
-\r
-\r
- [Test]\r
- public void Safe()\r
- {\r
- A a = new A(tree);\r
-\r
- a.traverse();\r
- Assert.AreEqual(sz, a.count);\r
- }\r
-\r
-\r
- [Test]\r
- public void RegrettablyUnsafe()\r
- {\r
- System.Threading.Thread[] t = new System.Threading.Thread[10];\r
- A[] a = new A[10];\r
- for (int i = 0; i < 10; i++)\r
- {\r
- a[i] = new A(tree);\r
- t[i] = new System.Threading.Thread(new System.Threading.ThreadStart(a[i].traverse));\r
- }\r
-\r
- for (int i = 0; i < 10; i++)\r
- t[i].Start();\r
- for (int i = 0; i < 10; i++)\r
- t[i].Join();\r
- for (int i = 0; i < 10; i++)\r
- Assert.AreEqual(sz,a[i].count);\r
-\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose() { tree = null; }\r
- }\r
- }\r
-\r
-\r
-\r
-\r
- namespace Hashing\r
- {\r
- [TestFixture]\r
- public class ISequenced\r
- {\r
- private ISequenced<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new TreeSet<int>(new RevIC(), EqualityComparer<int>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- }\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.sequencedhashcode(), dit.GetSequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dit.GetSequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(3, 7), dit.GetSequencedHashCode());\r
- Assert.AreEqual(CHC.sequencedhashcode(), dut.GetSequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.sequencedhashcode(3), dut.GetSequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.sequencedhashcode(7, 3), dut.GetSequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.SequencedEquals(dat));\r
- Assert.IsFalse(dat.SequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dat));\r
- Assert.IsTrue(dat.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dut));\r
- Assert.IsTrue(dut.SequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsFalse(dit.SequencedEquals(dut));\r
- Assert.IsFalse(dut.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.SequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
-\r
-\r
- [TestFixture]\r
- public class IEditableCollection\r
- {\r
- private ICollection<int> dit, dat, dut;\r
-\r
-\r
- [SetUp]\r
- public void Init()\r
- {\r
- dit = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dat = new TreeSet<int>(Comparer<int>.Default, EqualityComparer<int>.Default);\r
- dut = new TreeSet<int>(new RevIC(), EqualityComparer<int>.Default);\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyEmpty()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- }\r
-\r
-\r
- [Test]\r
- public void EmptyNonEmpty()\r
- {\r
- dit.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void HashVal()\r
- {\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dit.GetUnsequencedHashCode());\r
- dit.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dit.GetUnsequencedHashCode());\r
- dit.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3, 7), dit.GetUnsequencedHashCode());\r
- Assert.AreEqual(CHC.unsequencedhashcode(), dut.GetUnsequencedHashCode());\r
- dut.Add(3);\r
- Assert.AreEqual(CHC.unsequencedhashcode(3), dut.GetUnsequencedHashCode());\r
- dut.Add(7);\r
- Assert.AreEqual(CHC.unsequencedhashcode(7, 3), dut.GetUnsequencedHashCode());\r
- }\r
-\r
-\r
- [Test]\r
- public void Normal()\r
- {\r
- dit.Add(3);\r
- dit.Add(7);\r
- dat.Add(3);\r
- Assert.IsFalse(dit.UnsequencedEquals(dat));\r
- Assert.IsFalse(dat.UnsequencedEquals(dit));\r
- dat.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dat));\r
- Assert.IsTrue(dat.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void WrongOrder()\r
- {\r
- dit.Add(3);\r
- dut.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- dut.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dut));\r
- Assert.IsTrue(dut.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [Test]\r
- public void Reflexive()\r
- {\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(3);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- dit.Add(7);\r
- Assert.IsTrue(dit.UnsequencedEquals(dit));\r
- }\r
-\r
-\r
- [TearDown]\r
- public void Dispose()\r
- {\r
- dit = null;\r
- dat = null;\r
- dut = null;\r
- }\r
- }\r
-\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: anagrams 2004-08-08, 2004-11-16\r
-\r
-// Compile with \r
-// csc /r:C5.dll AnagramHashBag.cs \r
-\r
-using System;\r
-using System.IO; // StreamReader, TextReader\r
-using System.Text; // Encoding\r
-using System.Text.RegularExpressions; // Regex\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace AnagramHashBag\r
-{\r
- class MyTest\r
- {\r
- public static void Main(String[] args)\r
- {\r
- Console.OutputEncoding = Encoding.GetEncoding("iso-8859-1");\r
- SCG.IEnumerable<String> ss;\r
- if (args.Length == 2)\r
- ss = ReadFileWords(args[0], int.Parse(args[1]));\r
- else\r
- ss = args;\r
- // foreach (String s in FirstAnagramOnly(ss)) \r
- // Console.WriteLine(s);\r
- // Console.WriteLine("===");\r
- Timer t = new Timer();\r
- SCG.IEnumerable<SCG.IEnumerable<String>> classes = AnagramClasses(ss);\r
- int count = 0;\r
- foreach (SCG.IEnumerable<String> anagramClass in classes)\r
- {\r
- count++;\r
- foreach (String s in anagramClass) \r
- Console.Write(s + " ");\r
- Console.WriteLine();\r
- }\r
- Console.WriteLine("{0} non-trivial anagram classes", count);\r
- Console.WriteLine(t.Check());\r
- }\r
-\r
- // Read words at most n words from a file\r
-\r
- public static SCG.IEnumerable<String> ReadFileWords(String filename, int n)\r
- {\r
- Regex delim = new Regex("[^a-zæøåA-ZÆØÅ0-9-]+");\r
- Encoding enc = Encoding.GetEncoding("iso-8859-1");\r
- using (TextReader rd = new StreamReader(filename, enc))\r
- {\r
- for (String line = rd.ReadLine(); line != null; line = rd.ReadLine()) {\r
- foreach (String s in delim.Split(line))\r
- if (s != "")\r
- yield return s.ToLower();\r
- if (--n == 0)\r
- yield break;\r
- }\r
- }\r
- }\r
-\r
- // From an anagram point of view, a word is just a bag of\r
- // characters. So an anagram class is represented as HashBag<char>\r
- // which permits fast equality comparison -- we shall use them as\r
- // elements of hash sets or keys in hash maps.\r
-\r
- public static HashBag<char> AnagramClass(String s) {\r
- HashBag<char> anagram = new HashBag<char>();\r
- foreach (char c in s)\r
- anagram.Add(c);\r
- return anagram;\r
- }\r
-\r
- // Given a sequence of strings, return only the first member of each\r
- // anagram class.\r
-\r
- public static SCG.IEnumerable<String> FirstAnagramOnly(SCG.IEnumerable<String> ss)\r
- {\r
- HashSet<HashBag<char>> anagrams = new HashSet<HashBag<char>>();\r
- foreach (String s in ss) {\r
- HashBag<char> anagram = AnagramClass(s);\r
- if (!anagrams.Contains(anagram)) {\r
- anagrams.Add(anagram);\r
- yield return s;\r
- }\r
- }\r
- }\r
-\r
- // Given a sequence of strings, return all non-trivial anagram\r
- // classes. \r
-\r
- // Using HashBag<char> and an unsequenced equalityComparer, this performs as\r
- // follows on 1600 MHz Mobile P4 and .Net 2.0 beta 1 (wall-clock\r
- // time):\r
- // 50 000 words 2 822 classes 2.0 sec\r
- // 100 000 words 5 593 classes 4.3 sec\r
- // 200 000 words 11 705 classes 8.8 sec\r
- // 300 000 words 20 396 classes 52.0 sec includes swapping\r
- // 347 165 words 24 428 classes 146.0 sec includes swapping\r
-\r
- // The maximal memory consumption is less than 180 MB.\r
-\r
- public static SCG.IEnumerable<SCG.IEnumerable<String>>\r
- AnagramClasses(SCG.IEnumerable<String> ss)\r
- {\r
- IDictionary<HashBag<char>, TreeSet<String>> classes\r
- = new HashDictionary<HashBag<char>, TreeSet<String>>();\r
- foreach (String s in ss) {\r
- HashBag<char> anagram = AnagramClass(s);\r
- TreeSet<String> anagramClass;\r
- if (!classes.Find(anagram, out anagramClass))\r
- classes[anagram] = anagramClass = new TreeSet<String>();\r
- anagramClass.Add(s);\r
- }\r
- foreach (TreeSet<String> anagramClass in classes.Values)\r
- if (anagramClass.Count > 1)\r
- yield return anagramClass;\r
- }\r
- }\r
-\r
-// Crude timing utility ----------------------------------------\r
-\r
- public class Timer\r
- {\r
- private DateTime start;\r
-\r
- public Timer()\r
- {\r
- start = DateTime.Now;\r
- }\r
-\r
- public double Check()\r
- {\r
- TimeSpan dur = DateTime.Now - start;\r
- return dur.TotalSeconds;\r
- }\r
- }\r
-\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: anagrams represented as sorted strings 2004-08-26\r
-\r
-// To represent an anagram class, use a string containing the sorted\r
-// characters of a word. \r
-\r
-// This is faster than a TreeBag<char> because the words and hence\r
-// bags are small. Takes 15 CPU seconds and 138 MB RAM to find the\r
-// 26,058 anagram classes among 347,000 distinct words.\r
-\r
-// Compile with \r
-// csc /r:C5.dll Anagrams.cs \r
-\r
-using System;\r
-using System.IO; // StreamReader, TextReader\r
-using System.Text; // Encoding\r
-using System.Text.RegularExpressions; // Regex\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace AnagramStrings\r
-{\r
- class MyTest\r
- {\r
- public static void Main(String[] args)\r
- {\r
- Console.OutputEncoding = Encoding.GetEncoding("iso-8859-1");\r
- SCG.IEnumerable<String> ss;\r
- if (args.Length == 1)\r
- ss = ReadFileWords(args[0]);\r
- else\r
- ss = args;\r
-\r
- Timer t = new Timer();\r
- SCG.IEnumerable<SCG.IEnumerable<String>> classes = AnagramClasses(ss);\r
- int count = 0;\r
- foreach (SCG.IEnumerable<String> anagramClass in classes)\r
- {\r
- count++;\r
- // foreach (String s in anagramClass) \r
- // Console.Write(s + " ");\r
- // Console.WriteLine();\r
- }\r
- Console.WriteLine("{0} anagram classes", count);\r
- Console.WriteLine(t.Check());\r
- }\r
-\r
- // Read words from a file\r
-\r
- public static SCG.IEnumerable<String> ReadFileWords(String filename)\r
- {\r
- Regex delim = new Regex("[^a-zæøåA-ZÆØÅ0-9-]+");\r
- using (TextReader rd = new StreamReader(filename, Encoding.GetEncoding("iso-8859-1")))\r
- {\r
- for (String line = rd.ReadLine(); line != null; line = rd.ReadLine())\r
- foreach (String s in delim.Split(line))\r
- if (s != "")\r
- yield return s.ToLower();\r
- }\r
- }\r
-\r
- // From an anagram point of view, a word is just a bag of characters.\r
-\r
- public static CharBag AnagramClass(String s)\r
- {\r
- return new CharBag(s);\r
- }\r
-\r
- // Given a sequence of strings, return all non-trivial anagram classes \r
-\r
- public static SCG.IEnumerable<SCG.IEnumerable<String>> AnagramClasses(SCG.IEnumerable<String> ss)\r
- {\r
- IDictionary<CharBag, HashSet<String>> classes\r
- = new TreeDictionary<CharBag, HashSet<String>>();\r
- foreach (String s in ss)\r
- {\r
- CharBag anagram = AnagramClass(s);\r
- HashSet<String> anagramClass;\r
- if (!classes.Find(anagram, out anagramClass))\r
- classes[anagram] = anagramClass = new HashSet<String>();\r
- anagramClass.Add(s);\r
- }\r
- foreach (HashSet<String> anagramClass in classes.Values)\r
- if (anagramClass.Count > 1\r
- ) // && anagramClass.Exists(delegate(String s) { return !s.EndsWith("s"); }))\r
- yield return anagramClass;\r
- }\r
- }\r
-\r
-// A bag of characters is represented as a sorted string of the\r
-// characters, with multiplicity. Since natural language words are\r
-// short, the bags are small, so this is vastly better than\r
-// representing character bags using HashBag<char> or TreeBag<char>\r
-\r
- class CharBag : IComparable<CharBag>\r
- {\r
- private readonly String contents; // The bag's characters, sorted, with multiplicity\r
-\r
- public CharBag(String s)\r
- {\r
- char[] chars = s.ToCharArray();\r
- Array.Sort(chars);\r
- this.contents = new String(chars);\r
- }\r
-\r
- public override int GetHashCode()\r
- {\r
- return contents.GetHashCode();\r
- }\r
-\r
- public bool Equals(CharBag that)\r
- {\r
- return this.contents.Equals(that.contents);\r
- }\r
-\r
- public int CompareTo(CharBag that)\r
- {\r
- return this.contents.CompareTo(that.contents);\r
- }\r
- }\r
-\r
-// Crude timing utility ----------------------------------------\r
-\r
- public class Timer\r
- {\r
- private DateTime start;\r
-\r
- public Timer()\r
- {\r
- start = DateTime.Now;\r
- }\r
-\r
- public double Check()\r
- {\r
- TimeSpan dur = DateTime.Now - start;\r
- return dur.TotalSeconds;\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: anagrams 2004-08-08, 2004-11-16\r
-\r
-// Compile with \r
-// csc /r:C5.dll AnagramTreeBag.cs \r
-\r
-using System;\r
-using System.IO; // StreamReader, TextReader\r
-using System.Text; // Encoding\r
-using System.Text.RegularExpressions; // Regex\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace AnagramTreeBag\r
-{\r
- class MyTest\r
- {\r
- public static void Main(String[] args)\r
- {\r
- Console.OutputEncoding = Encoding.GetEncoding("iso-8859-1");\r
- SCG.IEnumerable<String> ss;\r
- if (args.Length == 2)\r
- ss = ReadFileWords(args[0], int.Parse(args[1]));\r
- else\r
- ss = args;\r
- // foreach (String s in FirstAnagramOnly(ss)) \r
- // Console.WriteLine(s);\r
- // Console.WriteLine("===");\r
- Timer t = new Timer();\r
- SCG.IEnumerable<SCG.IEnumerable<String>> classes = AnagramClasses(ss);\r
- int count = 0;\r
- foreach (SCG.IEnumerable<String> anagramClass in classes)\r
- {\r
- count++;\r
- // foreach (String s in anagramClass)\r
- // Console.Write(s + " ");\r
- // Console.WriteLine();\r
- }\r
- Console.WriteLine("{0} non-trivial anagram classes", count);\r
- Console.WriteLine(t.Check());\r
- }\r
-\r
- // Read words at most n words from a file\r
-\r
- public static SCG.IEnumerable<String> ReadFileWords(String filename, int n)\r
- {\r
- Regex delim = new Regex("[^a-zæøåA-ZÆØÅ0-9-]+");\r
- Encoding enc = Encoding.GetEncoding("iso-8859-1");\r
- using (TextReader rd = new StreamReader(filename, enc))\r
- {\r
- for (String line = rd.ReadLine(); line != null; line = rd.ReadLine())\r
- {\r
- foreach (String s in delim.Split(line))\r
- if (s != "")\r
- yield return s.ToLower();\r
- if (--n == 0)\r
- yield break;\r
- }\r
- }\r
- }\r
-\r
- // From an anagram point of view, a word is just a bag of\r
- // characters. So an anagram class is represented as TreeBag<char>\r
- // which permits fast equality comparison -- we shall use them as\r
- // elements of hash sets or keys in hash maps.\r
-\r
- public static TreeBag<char> AnagramClass(String s)\r
- {\r
- TreeBag<char> anagram = new TreeBag<char>(Comparer<char>.Default, EqualityComparer<char>.Default);\r
- foreach (char c in s)\r
- anagram.Add(c);\r
- return anagram;\r
- }\r
-\r
- // Given a sequence of strings, return only the first member of each\r
- // anagram class.\r
-\r
- public static SCG.IEnumerable<String> FirstAnagramOnly(SCG.IEnumerable<String> ss)\r
- {\r
- HashSet<TreeBag<char>> anagrams = new HashSet<TreeBag<char>>();\r
- foreach (String s in ss)\r
- {\r
- TreeBag<char> anagram = AnagramClass(s);\r
- if (!anagrams.Contains(anagram))\r
- {\r
- anagrams.Add(anagram);\r
- yield return s;\r
- }\r
- }\r
- }\r
-\r
- // Given a sequence of strings, return all non-trivial anagram\r
- // classes. \r
-\r
- // Using TreeBag<char> and an unsequenced equalityComparer, this performs as\r
- // follows on 1600 MHz Mobile P4 and .Net 2.0 beta 1 (wall-clock\r
- // time; number of distinct words):\r
-\r
- // 50 000 words 2 822 classes 2.4 sec\r
- // 100 000 words 5 593 classes 4.6 sec\r
- // 200 000 words 11 705 classes 9.6 sec\r
- // 300 000 words 20 396 classes 88.2 sec (includes swapping)\r
- // 347 165 words 24 428 classes 121.3 sec (includes swapping)\r
-\r
- // The maximal memory consumption is around 180 MB.\r
-\r
- public static SCG.IEnumerable<SCG.IEnumerable<String>>\r
- AnagramClasses(SCG.IEnumerable<String> ss)\r
- {\r
- IDictionary<TreeBag<char>, TreeSet<String>> classes;\r
- classes = new HashDictionary<TreeBag<char>, TreeSet<String>>();\r
- foreach (String s in ss)\r
- {\r
- TreeBag<char> anagram = AnagramClass(s);\r
- TreeSet<String> anagramClass;\r
- if (!classes.Find(anagram, out anagramClass))\r
- classes[anagram] = anagramClass = new TreeSet<String>();\r
- anagramClass.Add(s);\r
- }\r
- foreach (TreeSet<String> anagramClass in classes.Values)\r
- if (anagramClass.Count > 1)\r
- yield return anagramClass;\r
- }\r
- }\r
-\r
-// Crude timing utility ----------------------------------------\r
-\r
- public class Timer\r
- {\r
- private DateTime start;\r
-\r
- public Timer()\r
- {\r
- start = DateTime.Now;\r
- }\r
-\r
- public double Check()\r
- {\r
- TimeSpan dur = DateTime.Now - start;\r
- return dur.TotalSeconds;\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: anagrams 2004-08-08, 2004-11-16\r
-\r
-// Compile with \r
-// csc /r:C5.dll Anagrams.cs \r
-\r
-using System;\r
-using System.IO; // StreamReader, TextReader\r
-using System.Text; // Encoding\r
-using System.Text.RegularExpressions; // Regex\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace Anagrams\r
-{\r
- class MyTest\r
- {\r
- public static void Main(String[] args)\r
- {\r
- Console.OutputEncoding = Encoding.GetEncoding("iso-8859-1");\r
- SCG.IEnumerable<String> ss;\r
- if (args.Length == 2)\r
- ss = ReadFileWords(args[0], int.Parse(args[1]));\r
- else\r
- ss = args;\r
- // foreach (String s in FirstAnagramOnly(ss)) \r
- // Console.WriteLine(s);\r
- // Console.WriteLine("===");\r
- Timer t = new Timer();\r
- SCG.IEnumerable<SCG.IEnumerable<String>> classes = AnagramClasses(ss);\r
- int count = 0;\r
- foreach (SCG.IEnumerable<String> anagramClass in classes)\r
- {\r
- count++;\r
- // foreach (String s in anagramClass) \r
- // Console.Write(s + " ");\r
- // Console.WriteLine();\r
- }\r
- Console.WriteLine("{0} non-trivial anagram classes", count);\r
- Console.WriteLine(t.Check());\r
- }\r
-\r
- // Read words at most n words from a file\r
-\r
- public static SCG.IEnumerable<String> ReadFileWords(String filename, int n)\r
- {\r
- Regex delim = new Regex("[^a-zæøåA-ZÆØÅ0-9-]+");\r
- Encoding enc = Encoding.GetEncoding("iso-8859-1");\r
- using (TextReader rd = new StreamReader(filename, enc))\r
- {\r
- for (String line = rd.ReadLine(); line != null; line = rd.ReadLine())\r
- {\r
- foreach (String s in delim.Split(line))\r
- if (s != "")\r
- yield return s.ToLower();\r
- if (--n == 0)\r
- yield break;\r
- }\r
- }\r
- }\r
-\r
- // From an anagram point of view, a word is just a bag of\r
- // characters. So an anagram class is represented as TreeBag<char>\r
- // which permits fast equality comparison -- we shall use them as\r
- // elements of hash sets or keys in hash maps.\r
-\r
- public static TreeBag<char> AnagramClass(String s)\r
- {\r
- TreeBag<char> anagram = new TreeBag<char>(Comparer<char>.Default, EqualityComparer<char>.Default);\r
- foreach (char c in s)\r
- anagram.Add(c);\r
- return anagram;\r
- }\r
-\r
- // Given a sequence of strings, return only the first member of each\r
- // anagram class.\r
-\r
- public static SCG.IEnumerable<String> FirstAnagramOnly(SCG.IEnumerable<String> ss)\r
- {\r
- SCG.IEqualityComparer<TreeBag<char>> tbh\r
- = UnsequencedCollectionEqualityComparer<TreeBag<char>, char>.Default;\r
- HashSet<TreeBag<char>> anagrams = new HashSet<TreeBag<char>>(tbh);\r
- foreach (String s in ss)\r
- {\r
- TreeBag<char> anagram = AnagramClass(s);\r
- if (!anagrams.Contains(anagram))\r
- {\r
- anagrams.Add(anagram);\r
- yield return s;\r
- }\r
- }\r
- }\r
-\r
- // Given a sequence of strings, return all non-trivial anagram\r
- // classes. Should use a *sequenced* equalityComparer on a TreeBag<char>,\r
- // obviously: after all, characters can be sorted by ASCII code. On\r
- // 347 000 distinct Danish words this takes 70 cpu seconds, 180 MB\r
- // memory, and 263 wall-clock seconds (due to swapping).\r
-\r
- // Using a TreeBag<char> and a sequenced equalityComparer takes 82 cpu seconds\r
- // and 180 MB RAM to find the 26,058 anagram classes among 347,000\r
- // distinct words.\r
-\r
- // Using an unsequenced equalityComparer on TreeBag<char> or HashBag<char>\r
- // makes it criminally slow: at least 1200 cpu seconds. This must\r
- // be because many bags get the same hash code, so that there are\r
- // many collisions. But exactly how the unsequenced equalityComparer works is\r
- // not clear ... or is it because unsequenced equality is slow?\r
-\r
- public static SCG.IEnumerable<SCG.IEnumerable<String>> AnagramClasses(SCG.IEnumerable<String> ss)\r
- {\r
- bool unseq = true;\r
- IDictionary<TreeBag<char>, TreeSet<String>> classes;\r
- if (unseq)\r
- {\r
- SCG.IEqualityComparer<TreeBag<char>> unsequencedTreeBagEqualityComparer\r
- = UnsequencedCollectionEqualityComparer<TreeBag<char>, char>.Default;\r
- classes = new HashDictionary<TreeBag<char>, TreeSet<String>>(unsequencedTreeBagEqualityComparer);\r
- }\r
- else\r
- {\r
- SCG.IEqualityComparer<TreeBag<char>> sequencedTreeBagEqualityComparer\r
- = SequencedCollectionEqualityComparer<TreeBag<char>, char>.Default;\r
- classes = new HashDictionary<TreeBag<char>, TreeSet<String>>(sequencedTreeBagEqualityComparer);\r
- }\r
- foreach (String s in ss)\r
- {\r
- TreeBag<char> anagram = AnagramClass(s);\r
- TreeSet<String> anagramClass;\r
- if (!classes.Find(anagram, out anagramClass))\r
- classes[anagram] = anagramClass = new TreeSet<String>();\r
- anagramClass.Add(s);\r
- }\r
- foreach (TreeSet<String> anagramClass in classes.Values)\r
- if (anagramClass.Count > 1)\r
- yield return anagramClass;\r
- }\r
- }\r
-\r
-// Crude timing utility ----------------------------------------\r
-\r
- public class Timer\r
- {\r
- private DateTime start;\r
-\r
- public Timer()\r
- {\r
- start = DateTime.Now;\r
- }\r
-\r
- public double Check()\r
- {\r
- TimeSpan dur = DateTime.Now - start;\r
- return dur.TotalSeconds;\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: Antipatterns 2004-12-29\r
-\r
-// Compile with \r
-// csc /r:C5.dll Antipatterns.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace Antipatterns {\r
- class Antipatterns {\r
- public static void Main(String[] args) {\r
- ModifyInner();\r
- DontModifyInner();\r
- }\r
-\r
- // Anti-pattern: modifying an inner collection while it is a\r
- // member of an outer one may cause it to be lost from the outer\r
- // collection.\r
- \r
- private static void ModifyInner() {\r
- Console.WriteLine("\nAnti-pattern: Add to outer, modify, lose");\r
- ICollection<ISequenced<int>> outer = new HashSet<ISequenced<int>>();\r
- for (int i=0; i<100; i++) {\r
- ISequenced<int> inner = new TreeSet<int>();\r
- inner.Add(i); inner.Add(i+1);\r
- outer.Add(inner);\r
- }\r
- ISequenced<int> \r
- inner1 = new TreeSet<int>(), \r
- inner2 = new TreeSet<int>(),\r
- inner3 = new TreeSet<int>(); \r
- inner1.AddAll<int>(new int[] { 2, 3, 5, 7, 11 });\r
- inner2.AddAll(inner1); inner2.Add(13);\r
- inner3.AddAll(inner1); \r
- outer.Add(inner1);\r
- Console.WriteLine("inner1 in outer: {0}", outer.Contains(inner1));\r
- Console.WriteLine("inner2 in outer: {0}", outer.Contains(inner2));\r
- Console.WriteLine("inner3 in outer: {0}", outer.Contains(inner3));\r
- inner1.Add(13);\r
- Console.WriteLine("inner1 equals inner2: {0}", \r
- outer.EqualityComparer.Equals(inner1, inner2));\r
- Console.WriteLine("inner1 equals inner3: {0}", \r
- outer.EqualityComparer.Equals(inner1, inner3));\r
- Console.WriteLine("inner1 in outer: {0}", outer.Contains(inner1));\r
- Console.WriteLine("inner2 in outer: {0}", outer.Contains(inner2));\r
- Console.WriteLine("inner3 in outer: {0}", outer.Contains(inner3));\r
- Console.WriteLine("outer.Count: {0}", outer.Count);\r
- }\r
-\r
- private static void DontModifyInner() {\r
- Console.WriteLine("\nMake a snapshot and add it to outer");\r
- ICollection<ISequenced<int>> outer = new HashSet<ISequenced<int>>();\r
- for (int i=0; i<100; i++) {\r
- ISequenced<int> inner = new TreeSet<int>();\r
- inner.Add(i); inner.Add(i+1);\r
- outer.Add(inner);\r
- }\r
- IPersistentSorted<int> \r
- inner1 = new TreeSet<int>(), \r
- inner2 = new TreeSet<int>(),\r
- inner3 = new TreeSet<int>(); \r
- inner1.AddAll<int>(new int[] { 2, 3, 5, 7, 11 });\r
- inner2.AddAll(inner1); inner2.Add(13);\r
- inner3.AddAll(inner1); \r
- // Take a snapshot and add it to outer:\r
- outer.Add(inner1.Snapshot());\r
- Console.WriteLine("inner1 in outer: {0}", outer.Contains(inner1));\r
- Console.WriteLine("inner2 in outer: {0}", outer.Contains(inner2));\r
- Console.WriteLine("inner3 in outer: {0}", outer.Contains(inner3));\r
- inner1.Add(13);\r
- Console.WriteLine("inner1 equals inner2: {0}", \r
- outer.EqualityComparer.Equals(inner1, inner2));\r
- Console.WriteLine("inner1 equals inner3: {0}", \r
- outer.EqualityComparer.Equals(inner1, inner3));\r
- Console.WriteLine("inner1 in outer: {0}", outer.Contains(inner1));\r
- Console.WriteLine("inner2 in outer: {0}", outer.Contains(inner2));\r
- Console.WriteLine("inner3 in outer: {0}", outer.Contains(inner3));\r
- Console.WriteLine("outer.Count: {0}", outer.Count);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: anagrams 2004-12-\r
-\r
-// Compile with \r
-// csc /r:C5.dll Cloning.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace MyCloningTest {\r
- class MyTest {\r
- public static void Main(String[] args) {\r
- IList<int> lst = new ArrayList<int>();\r
- lst.AddAll(new int[] { 2, 3, 5, 7, 11, 13 });\r
- Console.WriteLine(lst);\r
- IList<int> v1 = lst.ViewOf(7);\r
- Console.WriteLine(v1);\r
- IList<int> v2 = (IList<int>)v1.Clone();\r
- v2.Slide(1);\r
- Console.WriteLine(v1);\r
- Console.WriteLine(v2);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: collections of collections 2004-11-16\r
-\r
-// Compile with \r
-// csc /r:C5.dll CollectionCollection.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace CollectionCollection\r
-{\r
- class MyTest\r
- {\r
- private static IList<int> col1 = new LinkedList<int>(),\r
- col2 = new LinkedList<int>(), col3 = new LinkedList<int>();\r
-\r
- public static void Main(String[] args) {\r
- ListEqualityComparers();\r
- IntSetSet();\r
- CharBagSet();\r
- }\r
- \r
- public static void ListEqualityComparers() {\r
- col1.AddAll<int>(new int[] { 7, 9, 13 });\r
- col2.AddAll<int>(new int[] { 7, 9, 13 });\r
- col3.AddAll<int>(new int[] { 9, 7, 13 });\r
-\r
- // Default equality and hasher == sequenced equality and hasher\r
- HashSet<IList<int>> hs1 = new HashSet<IList<int>>();\r
- Equalities("Default equality (sequenced equality)", hs1.EqualityComparer);\r
- hs1.Add(col1); hs1.Add(col2); hs1.Add(col3);\r
- Console.WriteLine("hs1.Count = {0}", hs1.Count);\r
-\r
- // Sequenced equality and hasher \r
- SCG.IEqualityComparer<IList<int>> seqEqualityComparer\r
- = SequencedCollectionEqualityComparer<IList<int>, int>.Default;\r
- HashSet<IList<int>> hs2 = new HashSet<IList<int>>(seqEqualityComparer);\r
- Equalities("Sequenced equality", hs2.EqualityComparer);\r
- hs2.Add(col1); hs2.Add(col2); hs2.Add(col3);\r
- Console.WriteLine("hs2.Count = {0}", hs2.Count);\r
-\r
- // Unsequenced equality and hasher\r
- SCG.IEqualityComparer<IList<int>> unseqEqualityComparer\r
- = UnsequencedCollectionEqualityComparer<IList<int>, int>.Default;\r
- HashSet<IList<int>> hs3 = new HashSet<IList<int>>(unseqEqualityComparer);\r
- Equalities("Unsequenced equality", hs3.EqualityComparer);\r
- hs3.Add(col1); hs3.Add(col2); hs3.Add(col3);\r
- Console.WriteLine("hs3.Count = {0}", hs3.Count);\r
-\r
- // Reference equality and hasher\r
- SCG.IEqualityComparer<IList<int>> refEqEqualityComparer \r
- = ReferenceEqualityComparer<IList<int>>.Default;\r
- HashSet<IList<int>> hs4 = new HashSet<IList<int>>(refEqEqualityComparer);\r
- Equalities("Reference equality", hs4.EqualityComparer);\r
- hs4.Add(col1); hs4.Add(col2); hs4.Add(col3);\r
- Console.WriteLine("hs4.Count = {0}", hs4.Count);\r
- }\r
-\r
- public static void Equalities(String msg, SCG.IEqualityComparer<IList<int>> equalityComparer)\r
- {\r
- Console.WriteLine("\n{0}:", msg);\r
- Console.Write("Equals(col1,col2)={0,-5}; ", equalityComparer.Equals(col1, col2));\r
- Console.Write("Equals(col1,col3)={0,-5}; ", equalityComparer.Equals(col1, col3));\r
- Console.WriteLine("Equals(col2,col3)={0,-5}", equalityComparer.Equals(col2, col3));\r
- }\r
-\r
- public static void IntSetSet() {\r
- ICollection<ISequenced<int>> outer = new HashSet<ISequenced<int>>();\r
- int[] ss = { 2, 3, 5, 7 };\r
- TreeSet<int> inner = new TreeSet<int>();\r
- outer.Add(inner.Snapshot());\r
- foreach (int i in ss) { \r
- inner.Add(i);\r
- outer.Add(inner.Snapshot());\r
- }\r
- foreach (ISequenced<int> s in outer) {\r
- int sum = 0;\r
- s.Apply(delegate(int x) { sum += x; });\r
- Console.WriteLine("Set has {0} elements and sum {1}", s.Count, sum);\r
- }\r
- }\r
-\r
- public static void CharBagSet() { \r
- String text = \r
- @"three sorted streams aligned by leading masters are stored \r
- there; an integral triangle ends, and stable tables keep;\r
- being alert, they later reread the logarithm, peek at the\r
- recent center, then begin to send their reader algorithm.";\r
- String[] words = text.Split(' ', '\n', '\r', ';', ',', '.');\r
- ICollection<ICollection<char>> anagrams \r
- = new HashSet<ICollection<char>>();\r
- int count = 0;\r
- foreach (String word in words) {\r
- if (word != "") {\r
- count++;\r
- HashBag<char> anagram = new HashBag<char>();\r
- anagram.AddAll<char>(word.ToCharArray());\r
- anagrams.Add(anagram);\r
- }\r
- }\r
- Console.WriteLine("Found {0} anagrams", count - anagrams.Count);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: anagrams 2004-12-08\r
-\r
-// Compile with \r
-// csc /r:C5.dll CollectionSanity.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace CollectionSanity {\r
- class CollectionSanity {\r
- public static void Main(String[] args) {\r
- IList<int> col1 = new LinkedList<int>(),\r
- col2 = new LinkedList<int>(), col3 = new LinkedList<int>();\r
- col1.AddAll<int>(new int[] { 7, 9, 13 });\r
- col2.AddAll<int>(new int[] { 7, 9, 13 });\r
- col3.AddAll<int>(new int[] { 9, 7, 13 });\r
-\r
- HashSet<IList<int>> hs1 = new HashSet<IList<int>>();\r
- hs1.Add(col1); hs1.Add(col2); hs1.Add(col3);\r
- Console.WriteLine("hs1 is sane: {0}", EqualityComparerSanity<int,IList<int>>(hs1));\r
- }\r
- \r
- // When colls is a collection of collections, this method checks\r
- // that all `inner' collections use the exact same equalityComparer. Note\r
- // that two equalityComparer objects may be functionally (extensionally)\r
- // identical, yet be distinct objects. However, if the equalityComparers\r
- // were obtained from EqualityComparer<T>.Default, there will be at most one\r
- // equalityComparer for each type T.\r
-\r
- public static bool EqualityComparerSanity<T,U>(ICollectionValue<U> colls) \r
- where U : IExtensible<T>\r
- {\r
- SCG.IEqualityComparer<T> equalityComparer = null;\r
- foreach (IExtensible<T> coll in colls) {\r
- if (equalityComparer == null) \r
- equalityComparer = coll.EqualityComparer;\r
- if (equalityComparer != coll.EqualityComparer) \r
- return false;\r
- }\r
- return true;\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: EventPatterns.cs for pattern chapter\r
-\r
-// Compile with \r
-// csc /r:C5.dll EventPatterns.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace EventPatterns {\r
- class EventPatterns {\r
- public static void Main(String[] args) {\r
- UnindexedCollectionEvents();\r
- Console.WriteLine("--------------------");\r
- IndexedCollectionEvents();\r
- Console.WriteLine("--------------------");\r
- UpdateEvent();\r
- }\r
-\r
- public static void UnindexedCollectionEvents() {\r
- ICollection<int> coll = new ArrayList<int>();\r
- ICollection<int> bag1 = new HashBag<int>();\r
- bag1.AddAll(new int[] { 3, 2, 5, 5, 7, 7, 5, 3, 7, 7 });\r
- // Add change handler\r
- coll.CollectionChanged \r
- += delegate(Object c) { \r
- Console.WriteLine("Collection changed"); \r
- };\r
- // Add cleared handler\r
- coll.CollectionCleared \r
- += delegate(Object c, ClearedEventArgs args) { \r
- Console.WriteLine("Collection cleared"); \r
- };\r
- // Add added handler\r
- coll.ItemsAdded \r
- += delegate(Object c, ItemCountEventArgs<int> args) { \r
- Console.WriteLine("Item {0} added", args.Item); \r
- };\r
- // Add item count handler\r
- AddItemsAddedCounter(coll);\r
- AddItemsRemovedCounter(coll);\r
- coll.AddAll(bag1);\r
- coll.RemoveAll(new int[] { 2, 5, 6, 3, 7, 2 });\r
- coll.Clear();\r
- ICollection<int> bag2 = new HashBag<int>();\r
- // Add added handler with multiplicity\r
- bag2.ItemsAdded \r
- += delegate(Object c, ItemCountEventArgs<int> args) { \r
- Console.WriteLine("{0} copies of {1} added", \r
- args.Count, args.Item);\r
- };\r
- bag2.AddAll(bag1);\r
- // Add removed handler with multiplicity\r
- bag2.ItemsRemoved \r
- += delegate(Object c, ItemCountEventArgs<int> args) { \r
- Console.WriteLine("{0} copies of {1} removed", \r
- args.Count, args.Item);\r
- };\r
- bag2.RemoveAllCopies(7);\r
- }\r
-\r
- // This works for all kinds of collections, also those with bag\r
- // semantics and representing duplicates by counting:\r
-\r
- private static void AddItemsAddedCounter<T>(ICollection<T> coll) {\r
- int addedCount = 0;\r
- coll.ItemsAdded \r
- += delegate(Object c, ItemCountEventArgs<T> args) { \r
- addedCount += args.Count; \r
- };\r
- coll.CollectionChanged \r
- += delegate(Object c) { \r
- if (addedCount > 0)\r
- Console.WriteLine("{0} items were added", addedCount);\r
- addedCount = 0;\r
- };\r
- }\r
-\r
- // This works for all kinds of collections, also those with bag\r
- // semantics and representing duplicates by counting:\r
-\r
- private static void AddItemsRemovedCounter<T>(ICollection<T> coll) {\r
- int removedCount = 0;\r
- coll.ItemsRemoved \r
- += delegate(Object c, ItemCountEventArgs<T> args) { \r
- removedCount += args.Count; \r
- };\r
- coll.CollectionChanged \r
- += delegate(Object c) { \r
- if (removedCount > 0)\r
- Console.WriteLine("{0} items were removed", removedCount);\r
- removedCount = 0;\r
- };\r
- }\r
-\r
- // Event patterns on indexed collections\r
-\r
- public static void IndexedCollectionEvents() {\r
- IList<int> coll = new ArrayList<int>();\r
- ICollection<int> bag = new HashBag<int>();\r
- bag.AddAll(new int[] { 3, 2, 5, 5, 7, 7, 5, 3, 7, 7 });\r
- // Add item inserted handler\r
- coll.ItemInserted \r
- += delegate(Object c, ItemAtEventArgs<int> args) { \r
- Console.WriteLine("Item {0} inserted at {1}", \r
- args.Item, args.Index); \r
- };\r
- coll.InsertAll(0, bag);\r
- // Add item removed-at handler\r
- coll.ItemRemovedAt \r
- += delegate(Object c, ItemAtEventArgs<int> args) { \r
- Console.WriteLine("Item {0} removed at {1}", \r
- args.Item, args.Index); \r
- };\r
- coll.RemoveLast();\r
- coll.RemoveFirst();\r
- coll.RemoveAt(1);\r
- }\r
-\r
- // Recognizing Update event as a Removed-Added-Changed sequence\r
-\r
- private enum State { Before, Removed, Updated };\r
-\r
- private static void AddItemUpdatedHandler<T>(ICollection<T> coll) {\r
- State state = State.Before;\r
- T removed = default(T), added = default(T);\r
- coll.ItemsRemoved \r
- += delegate(Object c, ItemCountEventArgs<T> args) { \r
- if (state==State.Before) {\r
- state = State.Removed; \r
- removed = args.Item;\r
- } else \r
- state = State.Before;\r
- };\r
- coll.ItemsAdded \r
- += delegate(Object c, ItemCountEventArgs<T> args) { \r
- if (state==State.Removed) { \r
- state = State.Updated; \r
- added = args.Item; \r
- } else \r
- state = State.Before;\r
- };\r
- coll.CollectionChanged \r
- += delegate(Object c) { \r
- if (state==State.Updated) \r
- Console.WriteLine("Item {0} was updated to {1}", \r
- removed, added);\r
- state = State.Before;\r
- };\r
- }\r
-\r
- public static void UpdateEvent() {\r
- ICollection<Teacher> coll = new HashSet<Teacher>();\r
- AddItemUpdatedHandler(coll);\r
- Teacher kristian = new Teacher("Kristian", "physics");\r
- coll.Add(kristian);\r
- coll.Add(new Teacher("Poul Einer", "mathematics"));\r
- // This should be caught by the update handler:\r
- coll.Update(new Teacher("Thomas", "mathematics"));\r
- // This should not be caught by the update handler:\r
- coll.Remove(kristian);\r
- coll.Add(new Teacher("Jens", "physics"));\r
- // The update handler is activated also by indexed updates\r
- IList<int> list = new ArrayList<int>();\r
- list.AddAll(new int[] { 7, 11, 13 });\r
- AddItemUpdatedHandler(list);\r
- list[1] = 9;\r
- }\r
- }\r
-\r
- // Example class where objects may be equal yet display differently\r
-\r
- class Teacher : IEquatable<Teacher> { \r
- private readonly String name, subject;\r
-\r
- public Teacher(String name, String subject) { \r
- this.name = name; this.subject = subject;\r
- }\r
-\r
- public bool Equals(Teacher that) {\r
- return this.subject.Equals(that.subject);\r
- }\r
-\r
- public override int GetHashCode() {\r
- return subject.GetHashCode();\r
- }\r
-\r
- public override String ToString() {\r
- return name + "[" + subject + "]";\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: File index: read a text file, build and print a list of\r
-// words and the line numbers (without duplicates) on which they occur.\r
-\r
-// Compile with \r
-// csc /r:C5.dll Fileindex.cs \r
-\r
-using System; // Console\r
-using System.IO; // StreamReader, TextReader\r
-using System.Text.RegularExpressions; // Regex\r
-using C5; // IDictionary, TreeDictionary, TreeSet\r
-\r
-namespace FileIndex\r
-{\r
- class Fileindex\r
- {\r
- static void Main(String[] args)\r
- {\r
- if (args.Length != 1)\r
- Console.WriteLine("Usage: Fileindex <filename>\n");\r
- else\r
- {\r
- IDictionary<String, TreeSet<int>> index = IndexFile(args[0]);\r
- PrintIndex(index);\r
- }\r
- }\r
-\r
- static IDictionary<String, TreeSet<int>> IndexFile(String filename)\r
- {\r
- IDictionary<String, TreeSet<int>> index = new TreeDictionary<String, TreeSet<int>>();\r
- Regex delim = new Regex("[^a-zA-Z0-9]+");\r
- using (TextReader rd = new StreamReader(filename))\r
- {\r
- int lineno = 0;\r
- for (String line = rd.ReadLine(); line != null; line = rd.ReadLine())\r
- {\r
- String[] res = delim.Split(line);\r
- lineno++;\r
- foreach (String s in res)\r
- if (s != "")\r
- {\r
- if (!index.Contains(s))\r
- index[s] = new TreeSet<int>();\r
- index[s].Add(lineno);\r
- }\r
- }\r
- }\r
- return index;\r
- }\r
-\r
- static void PrintIndex(IDictionary<String, TreeSet<int>> index)\r
- {\r
- foreach (String word in index.Keys)\r
- {\r
- Console.Write("{0}: ", word);\r
- foreach (int ln in index[word])\r
- Console.Write("{0} ", ln);\r
- Console.WriteLine();\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Drawing;\r
-using System.Collections;\r
-using System.ComponentModel;\r
-using System.Windows.Forms;\r
-using System.Diagnostics;\r
-using C5;\r
-\r
-namespace GConvexHull\r
-{\r
- /// <summary>\r
- /// Summary description for Form1.\r
- /// </summary>\r
- public class TesterForm : System.Windows.Forms.Form\r
- {\r
- //My data\r
-\r
- //My GUI stuff\r
- private System.Windows.Forms.Panel drawarea;\r
-\r
- private Graphics drawg;\r
-\r
- //Std stuff\r
- private System.Windows.Forms.Button runButton;\r
- private TextBox pointCount;\r
-\r
- /// <summary>\r
- /// Required designer variable.\r
- /// </summary>\r
- private System.ComponentModel.Container components = null;\r
-\r
-\r
- public TesterForm()\r
- {\r
- //\r
- // Required for Windows Form Designer support\r
- //\r
- InitializeComponent();\r
-\r
- //\r
- // TODO: Add any constructor code after InitializeComponent call\r
- //\r
- drawg = drawarea.CreateGraphics();\r
- reset();\r
- }\r
-\r
-\r
- /// <summary>\r
- /// Clean up any resources being used.\r
- /// </summary>\r
- protected override void Dispose(bool disposing)\r
- {\r
- if (disposing)\r
- {\r
- if (components != null)\r
- {\r
- components.Dispose();\r
- }\r
- }\r
-\r
- base.Dispose(disposing);\r
- }\r
-\r
- #region Windows Form Designer generated code\r
- /// <summary>\r
- /// Required method for Designer support - do not modify\r
- /// the contents of this method with the code editor.\r
- /// </summary>\r
- private void InitializeComponent()\r
- {\r
- this.drawarea = new System.Windows.Forms.Panel();\r
- this.runButton = new System.Windows.Forms.Button();\r
- this.pointCount = new System.Windows.Forms.TextBox();\r
- this.SuspendLayout();\r
- // \r
- // drawarea\r
- // \r
- this.drawarea.BackColor = System.Drawing.Color.White;\r
- this.drawarea.Location = new System.Drawing.Point(8, 9);\r
- this.drawarea.Name = "drawarea";\r
- this.drawarea.Size = new System.Drawing.Size(500, 500);\r
- this.drawarea.TabIndex = 0;\r
- this.drawarea.Paint += new System.Windows.Forms.PaintEventHandler(this.drawarea_Paint);\r
- this.drawarea.Invalidated += new System.Windows.Forms.InvalidateEventHandler(this.drawarea_Invalidated);\r
- this.drawarea.MouseMove += new System.Windows.Forms.MouseEventHandler(this.drawarea_MouseMove);\r
- this.drawarea.MouseClick += new System.Windows.Forms.MouseEventHandler(this.drawarea_MouseClick);\r
- // \r
- // runButton\r
- // \r
- this.runButton.Location = new System.Drawing.Point(8, 516);\r
- this.runButton.Name = "runButton";\r
- this.runButton.Size = new System.Drawing.Size(42, 20);\r
- this.runButton.TabIndex = 1;\r
- this.runButton.Text = "Run";\r
- this.runButton.Click += new System.EventHandler(this.runButton_Click);\r
- // \r
- // pointCount\r
- // \r
- this.pointCount.Location = new System.Drawing.Point(97, 517);\r
- this.pointCount.Name = "pointCount";\r
- this.pointCount.Size = new System.Drawing.Size(55, 20);\r
- this.pointCount.TabIndex = 5;\r
- // \r
- // TesterForm\r
- // \r
- this.ClientSize = new System.Drawing.Size(524, 550);\r
- this.Controls.Add(this.pointCount);\r
- this.Controls.Add(this.runButton);\r
- this.Controls.Add(this.drawarea);\r
- this.Name = "TesterForm";\r
- this.Text = "C5 Tester";\r
- this.Load += new System.EventHandler(this.TesterForm_Load);\r
- this.ResumeLayout(false);\r
- this.PerformLayout();\r
-\r
- }\r
- #endregion\r
-\r
- /// <summary>\r
- /// The main entry point for the application.\r
- /// </summary>\r
- [STAThread]\r
- static void Main()\r
- {\r
- Application.EnableVisualStyles();\r
- Application.Run(new TesterForm());\r
- }\r
-\r
- Point[] pts;\r
- Point[] chpts;\r
-\r
- private void runButton_Click(object sender, System.EventArgs e)\r
- {\r
- int N = int.Parse(pointCount.Text);\r
- pts = new Point[N];\r
- for (int i = 0; i < N; i++)\r
- pts[i] = Point.Random(500, 500);\r
- chpts = Convexhull.ConvexHull(pts);\r
-\r
- drawarea.Invalidate();\r
- }\r
-\r
-\r
- private void drawarea_Paint(object sender, System.Windows.Forms.PaintEventArgs e)\r
- {\r
- mydraw();\r
- }\r
-\r
-\r
- private void resetButton_Click(object sender, System.EventArgs e)\r
- {\r
- reset();\r
- }\r
-\r
-\r
- private void reset()\r
- {\r
- drawarea.Invalidate();//(new Rectangle(0, 0, 40, 40));\r
- }\r
-\r
-\r
-\r
- public void mydraw()\r
- {\r
- if (pts == null)\r
- {\r
- return;\r
- }\r
- for (int i = 0; i < pts.Length; i++)\r
- {\r
- Point p = pts[i];\r
- drawg.DrawEllipse(new Pen(Color.Red), transx(p.x) - 2, transy(p.y) - 2, 4, 4);\r
- }\r
- for (int i = 0; i < chpts.Length; i++)\r
- {\r
- int j = i + 1 < chpts.Length ? i + 1 : 0;\r
- drawg.DrawEllipse(new Pen(Color.Blue), transx(chpts[i].x) - 2, transy(chpts[i].y) - 2, 4, 4);\r
- drawg.DrawLine(new Pen(Color.LawnGreen), transx(chpts[i].x), transx(chpts[i].y), transx(chpts[j].x), transx(chpts[j].y));\r
- }\r
- }\r
-\r
-\r
-\r
- private int transx(double x)\r
- {\r
- return (int)x;\r
- }\r
-\r
-\r
- private int transy(double y)\r
- {\r
- return (int)y;\r
- }\r
-\r
-\r
- private void dumpButton_Click(object sender, System.EventArgs e)\r
- {\r
- Debug.WriteLine("###############");\r
- Debug.WriteLine("###############");\r
- }\r
-\r
-\r
- private void graphTypeControlArray_Click(object sender, System.EventArgs e)\r
- {\r
- Debug.WriteLine(e.GetType());\r
- Debug.WriteLine(sender.GetType());\r
- drawarea.Invalidate();\r
- }\r
-\r
-\r
- private void drawarea_MouseMove(object sender, MouseEventArgs e)\r
- {\r
- }\r
-\r
-\r
- private void drawarea_MouseClick(object sender, MouseEventArgs e)\r
- {\r
- //double x = untransx(e.X), y = untransy(e.Y);\r
-\r
- }\r
-\r
-\r
- private void drawarea_Invalidated(object sender, InvalidateEventArgs e)\r
- {\r
- //msg.Text = e.InvalidRect + "";\r
- //mydraw();\r
- }\r
-\r
-\r
- private void preparedFigureSelection_SelectedIndexChanged(object sender, System.EventArgs e)\r
- {\r
- }\r
-\r
- private void voronoiButton_CheckedChanged(object sender, EventArgs e)\r
- {\r
- graphTypeControlArray_Click(sender, e);\r
- }\r
-\r
- private void delaunayButton_CheckedChanged(object sender, EventArgs e)\r
- {\r
- graphTypeControlArray_Click(sender, e);\r
- }\r
-\r
- private void TesterForm_Load(object sender, EventArgs e)\r
- {\r
-\r
- }\r
-\r
- }\r
-}\r
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>\r
-<root>\r
- <!-- \r
- Microsoft ResX Schema \r
- \r
- Version 2.0\r
- \r
- The primary goals of this format is to allow a simple XML format \r
- that is mostly human readable. The generation and parsing of the \r
- various data types are done through the TypeConverter classes \r
- associated with the data types.\r
- \r
- Example:\r
- \r
- ... ado.net/XML headers & schema ...\r
- <resheader name="resmimetype">text/microsoft-resx</resheader>\r
- <resheader name="version">2.0</resheader>\r
- <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\r
- <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\r
- <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>\r
- <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>\r
- <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">\r
- <value>[base64 mime encoded serialized .NET Framework object]</value>\r
- </data>\r
- <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">\r
- <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\r
- <comment>This is a comment</comment>\r
- </data>\r
- \r
- There are any number of "resheader" rows that contain simple \r
- name/value pairs.\r
- \r
- Each data row contains a name, and value. The row also contains a \r
- type or mimetype. Type corresponds to a .NET class that support \r
- text/value conversion through the TypeConverter architecture. \r
- Classes that don't support this are serialized and stored with the \r
- mimetype set.\r
- \r
- The mimetype is used for serialized objects, and tells the \r
- ResXResourceReader how to depersist the object. This is currently not \r
- extensible. For a given mimetype the value must be set accordingly:\r
- \r
- Note - application/x-microsoft.net.object.binary.base64 is the format \r
- that the ResXResourceWriter will generate, however the reader can \r
- read any of the formats listed below.\r
- \r
- mimetype: application/x-microsoft.net.object.binary.base64\r
- value : The object must be serialized with \r
- : System.Serialization.Formatters.Binary.BinaryFormatter\r
- : and then encoded with base64 encoding.\r
- \r
- mimetype: application/x-microsoft.net.object.soap.base64\r
- value : The object must be serialized with \r
- : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\r
- : and then encoded with base64 encoding.\r
-\r
- mimetype: application/x-microsoft.net.object.bytearray.base64\r
- value : The object must be serialized into a byte array \r
- : using a System.ComponentModel.TypeConverter\r
- : and then encoded with base64 encoding.\r
- -->\r
- <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">\r
- <xsd:element name="root" msdata:IsDataSet="true">\r
- <xsd:complexType>\r
- <xsd:choice maxOccurs="unbounded">\r
- <xsd:element name="metadata">\r
- <xsd:complexType>\r
- <xsd:sequence>\r
- <xsd:element name="value" type="xsd:string" minOccurs="0" />\r
- </xsd:sequence>\r
- <xsd:attribute name="name" type="xsd:string" />\r
- <xsd:attribute name="type" type="xsd:string" />\r
- <xsd:attribute name="mimetype" type="xsd:string" />\r
- </xsd:complexType>\r
- </xsd:element>\r
- <xsd:element name="assembly">\r
- <xsd:complexType>\r
- <xsd:attribute name="alias" type="xsd:string" />\r
- <xsd:attribute name="name" type="xsd:string" />\r
- </xsd:complexType>\r
- </xsd:element>\r
- <xsd:element name="data">\r
- <xsd:complexType>\r
- <xsd:sequence>\r
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
- <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />\r
- </xsd:sequence>\r
- <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />\r
- <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />\r
- <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />\r
- </xsd:complexType>\r
- </xsd:element>\r
- <xsd:element name="resheader">\r
- <xsd:complexType>\r
- <xsd:sequence>\r
- <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />\r
- </xsd:sequence>\r
- <xsd:attribute name="name" type="xsd:string" use="required" />\r
- </xsd:complexType>\r
- </xsd:element>\r
- </xsd:choice>\r
- </xsd:complexType>\r
- </xsd:element>\r
- </xsd:schema>\r
- <resheader name="resmimetype">\r
- <value>text/microsoft-resx</value>\r
- </resheader>\r
- <resheader name="version">\r
- <value>2.0</value>\r
- </resheader>\r
- <resheader name="reader">\r
- <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
- </resheader>\r
- <resheader name="writer">\r
- <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\r
- </resheader>\r
- <metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">\r
- <value>25</value>\r
- </metadata>\r
-</root>
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// Compile with \r
-// csc /r:C5.dll GConvexHull.cs\r
-\r
-using System;\r
-using C5;\r
-\r
-namespace GConvexHull\r
-{\r
-// Find the convex hull of a point set in the plane\r
-\r
-// An implementation of Graham's (1972) point elimination algorithm,\r
-// as modified by Andrew (1979) to find lower and upper hull separately.\r
-\r
-// This implementation correctly handle duplicate points, and\r
-// multiple points with the same x-coordinate.\r
-\r
-// 1. Sort the points lexicographically by increasing (x,y), thus \r
-// finding also a leftmost point L and a rightmost point R.\r
-// 2. Partition the point set into two lists, upper and lower, according as \r
-// point is above or below the segment LR. The upper list begins with \r
-// L and ends with R; the lower list begins with R and ends with L.\r
-// 3. Traverse the point lists clockwise, eliminating all but the extreme\r
-// points (thus eliminating also duplicate points).\r
-// 4. Join the point lists (in clockwise order) in an array, \r
-// leaving out L from lower and R from upper.\r
-\r
- public class Convexhull\r
- {\r
- public static Point[] ConvexHull(Point[] pts)\r
- {\r
- // 1. Sort points lexicographically by increasing (x, y)\r
- int N = pts.Length;\r
- Array.Sort(pts);\r
- Point left = pts[0], right = pts[N - 1];\r
- // 2. Partition into lower hull and upper hull\r
- IList<Point> lower = new LinkedList<Point>(),\r
- upper = new LinkedList<Point>();\r
- lower.InsertFirst(left); upper.InsertLast(left);\r
- for (int i = 0; i < N; i++)\r
- {\r
- double det = Point.Area2(left, right, pts[i]);\r
- if (det < 0)\r
- lower.InsertFirst(pts[i]);\r
- else if (det > 0)\r
- upper.InsertLast(pts[i]);\r
- }\r
- lower.InsertFirst(right);\r
- upper.InsertLast(right);\r
- // 3. Eliminate points not on the hull\r
- Eliminate(lower);\r
- Eliminate(upper);\r
- // 4. Join the lower and upper hull, leaving out lower.Last and upper.Last\r
- Point[] res = new Point[lower.Count + upper.Count - 2];\r
- lower[0, lower.Count - 1].CopyTo(res, 0);\r
- upper[0, upper.Count - 1].CopyTo(res, lower.Count - 1);\r
- return res;\r
- }\r
-\r
- // Graham's scan\r
- public static void Eliminate(IList<Point> lst)\r
- {\r
- IList<Point> view = lst.View(0, 0);\r
- int slide = 0;\r
- while (view.TrySlide(slide, 3))\r
- if (Point.Area2(view[0], view[1], view[2]) < 0) // right turn\r
- slide = 1;\r
- else\r
- { // left or straight\r
- view.RemoveAt(1);\r
- slide = view.Offset != 0 ? -1 : 0;\r
- }\r
- }\r
- }\r
-\r
-// ------------------------------------------------------------\r
-\r
-// Points in the plane\r
-\r
- public class Point : IComparable<Point>\r
- {\r
- private static readonly C5Random rnd = new C5Random(42);\r
-\r
- public readonly double x, y;\r
-\r
- public Point(double x, double y)\r
- {\r
- this.x = x; this.y = y;\r
- }\r
-\r
- public override string ToString()\r
- {\r
- return "(" + x + ", " + y + ")";\r
- }\r
-\r
- public static Point Random(int w, int h)\r
- {\r
- return new Point(rnd.Next(w), rnd.Next(h));\r
- }\r
-\r
- public bool Equals(Point p2)\r
- {\r
- return x == p2.x && y == p2.y;\r
- }\r
-\r
- public int CompareTo(Point p2)\r
- {\r
- int major = x.CompareTo(p2.x);\r
- return major != 0 ? major : y.CompareTo(p2.y);\r
- }\r
-\r
- // Twice the signed area of the triangle (p0, p1, p2)\r
- public static double Area2(Point p0, Point p1, Point p2)\r
- {\r
- return p0.x * (p1.y - p2.y) + p1.x * (p2.y - p0.y) + p2.x * (p0.y - p1.y);\r
- }\r
- }\r
-\r
-// ------------------------------------------------------------\r
-\r
- class GConvexHull\r
- {\r
- static void Main(String[] args)\r
- {\r
- if (args.Length == 1)\r
- {\r
- string arg = args[0];\r
- int N = int.Parse(arg);\r
- Point[] pts = new Point[N];\r
- for (int i = 0; i < N; i++)\r
- pts[i] = Point.Random(500, 500);\r
- Point[] chpts = Convexhull.ConvexHull(pts);\r
- Console.WriteLine("Area is " + Area(chpts));\r
- Print(chpts);\r
- }\r
- else\r
- Console.WriteLine("Usage: GConvexHull <pointcount>\n");\r
- }\r
-\r
- // The area of a polygon (represented by an array of ordered vertices)\r
- public static double Area(Point[] pts)\r
- {\r
- int N = pts.Length;\r
- Point origo = new Point(0, 0);\r
- double area2 = 0;\r
- for (int i = 0; i < N; i++)\r
- area2 += Point.Area2(origo, pts[i], pts[(i + 1) % N]);\r
- return Math.Abs(area2 / 2);\r
- }\r
-\r
- public static void Print(Point[] pts)\r
- {\r
- int N = pts.Length;\r
- for (int i = 0; i < N; i++)\r
- Console.WriteLine(pts[i]);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// Compile with \r
-// csc /r:C5.dll GNfaToDfa.cs\r
-\r
-// C5 examples: RegExp -> NFA -> DFA -> Graph\r
-// Java 2000-10-07, GC# 2001-10-23, C# 2.0 2003-09-03, C# 2.0+C5 2004-08-08\r
-\r
-// This file contains, in order:\r
-// * Helper class Set<T> defined in terms of C5 classes.\r
-// * A class Nfa for representing an NFA (a nondeterministic finite \r
-// automaton), and for converting it to a DFA (a deterministic \r
-// finite automaton). Most complexity is in this class.\r
-// * A class Dfa for representing a DFA, a deterministic finite \r
-// automaton, and for writing a dot input file representing the DFA.\r
-// * Classes for representing regular expressions, and for building an \r
-// NFA from a regular expression\r
-// * A test class that creates an NFA, a DFA, and a dot input file \r
-// for a number of small regular expressions. The DFAs are \r
-// not minimized.\r
-\r
-using System;\r
-using System.Text;\r
-using System.IO;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace GNfaToDfa\r
-{\r
-\r
- public class Set<T> : HashSet<T> {\r
- public Set(SCG.IEnumerable<T> enm) : base() {\r
- AddAll(enm);\r
- }\r
-\r
- public Set(params T[] elems) : this((SCG.IEnumerable<T>)elems) { }\r
-\r
- // Set union (+), difference (-), and intersection (*):\r
-\r
- public static Set<T> operator +(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set+Set");\r
- else {\r
- Set<T> res = new Set<T>(s1);\r
- res.AddAll(s2);\r
- return res;\r
- }\r
- }\r
-\r
- public static Set<T> operator -(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set-Set");\r
- else {\r
- Set<T> res = new Set<T>(s1);\r
- res.RemoveAll(s2);\r
- return res;\r
- }\r
- }\r
-\r
- public static Set<T> operator *(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set*Set");\r
- else {\r
- Set<T> res = new Set<T>(s1);\r
- res.RetainAll(s2);\r
- return res;\r
- }\r
- }\r
-\r
- // Equality of sets; take care to avoid infinite loops\r
-\r
- public static bool operator ==(Set<T> s1, Set<T> s2) {\r
- return EqualityComparer<Set<T>>.Default.Equals(s1, s2);\r
- }\r
-\r
- public static bool operator !=(Set<T> s1, Set<T> s2) {\r
- return !(s1 == s2);\r
- }\r
-\r
- public override bool Equals(Object that) {\r
- return this == (that as Set<T>);\r
- }\r
-\r
- public override int GetHashCode() {\r
- return EqualityComparer<Set<T>>.Default.GetHashCode(this);\r
- }\r
-\r
- // Subset (<=) and superset (>=) relation:\r
-\r
- public static bool operator <=(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set<=Set");\r
- else\r
- return s1.ContainsAll(s2);\r
- }\r
-\r
- public static bool operator >=(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set>=Set");\r
- else\r
- return s2.ContainsAll(s1);\r
- }\r
- \r
- public override String ToString() {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("{");\r
- bool first = true;\r
- foreach (T x in this) {\r
- if (!first)\r
- sb.Append(",");\r
- sb.Append(x);\r
- first = false;\r
- }\r
- sb.Append("}");\r
- return sb.ToString();\r
- }\r
- }\r
-\r
-// ----------------------------------------------------------------------\r
-\r
-// Regular expressions, NFAs, DFAs, and dot graphs\r
-// sestoft@dina.kvl.dk * \r
-// Java 2001-07-10 * C# 2001-10-22 * Gen C# 2001-10-23, 2003-09-03\r
-\r
-// In the Generic C# 2.0 version we \r
-// use Queue<int> and Queue<Set<int>> for worklists\r
-// use Set<int> for pre-DFA states\r
-// use ArrayList<Transition> for NFA transition relations\r
-// use HashDictionary<Set<int>, HashDictionary<String, Set<int>>>\r
-// and HashDictionary<int, HashDictionary<String, int>> for DFA transition relations\r
-\r
-/* Class Nfa and conversion from NFA to DFA ---------------------------\r
-\r
- A nondeterministic finite automaton (NFA) is represented as a\r
- dictionary mapping a state number (int) to an arraylist of\r
- Transitions, a Transition being a pair of a label lab (a string,\r
- null meaning epsilon) and a target state (an int).\r
-\r
- A DFA is created from an NFA in two steps:\r
-\r
- (1) Construct a DFA whose each of whose states is composite,\r
- namely a set of NFA states (Set of int). This is done by\r
- methods CompositeDfaTrans and EpsilonClose.\r
-\r
- (2) Replace composite states (Set of int) by simple states\r
- (int). This is done by methods Rename and MkRenamer.\r
-\r
- Method CompositeDfaTrans works as follows: \r
-\r
- Create the epsilon-closure S0 (a Set of ints) of the start state\r
- s0, and put it in a worklist (a Queue). Create an empty DFA\r
- transition relation, which is a dictionary mapping a composite\r
- state (an epsilon-closed set of ints) to a dictionary mapping a\r
- label (a non-null string) to a composite state.\r
-\r
- Repeatedly choose a composite state S from the worklist. If it is\r
- not already in the keyset of the DFA transition relation, compute\r
- for every non-epsilon label lab the set T of states reachable by\r
- that label from some state s in S. Compute the epsilon-closure\r
- Tclose of every such state T and put it on the worklist. Then add\r
- the transition S -lab-> Tclose to the DFA transition relation, for\r
- every lab.\r
-\r
- Method EpsilonClose works as follows: \r
-\r
- Given a set S of states. Put the states of S in a worklist.\r
- Repeatedly choose a state s from the worklist, and consider all\r
- epsilon-transitions s -eps-> s' from s. If s' is in S already,\r
- then do nothing; otherwise add s' to S and the worklist. When the\r
- worklist is empty, S is epsilon-closed; return S.\r
-\r
- Method MkRenamer works as follows: \r
-\r
- Given a dictionary mapping a set of int to something, create an\r
- injective dictionary mapping from set of int to int, by choosing a\r
- fresh int for every key in the given dictionary.\r
-\r
- Method Rename works as follows:\r
-\r
- Given a dictionary mapping a set of int to a dictionary mapping a\r
- string to set of int, use the result of MkRenamer to replace all\r
- sets of ints by ints.\r
-\r
-*/\r
-\r
- class Nfa {\r
- private readonly int startState;\r
- private readonly int exitState; // This is the unique accept state\r
- private readonly IDictionary<int, ArrayList<Transition>> trans;\r
-\r
- public Nfa(int startState, int exitState) {\r
- this.startState = startState; this.exitState = exitState;\r
- trans = new HashDictionary<int, ArrayList<Transition>>();\r
- if (!startState.Equals(exitState))\r
- trans.Add(exitState, new ArrayList<Transition>());\r
- }\r
-\r
- public int Start { get { return startState; } }\r
-\r
- public int Exit { get { return exitState; } }\r
-\r
- public IDictionary<int, ArrayList<Transition>> Trans {\r
- get { return trans; }\r
- }\r
-\r
- public void AddTrans(int s1, String lab, int s2) {\r
- ArrayList<Transition> s1Trans;\r
- if (trans.Contains(s1))\r
- s1Trans = trans[s1];\r
- else {\r
- s1Trans = new ArrayList<Transition>();\r
- trans.Add(s1, s1Trans);\r
- }\r
- s1Trans.Add(new Transition(lab, s2));\r
- }\r
-\r
- public void AddTrans(KeyValuePair<int, ArrayList<Transition>> tr) {\r
- // Assumption: if tr is in trans, it maps to an empty list (end state)\r
- trans.Remove(tr.Key);\r
- trans.Add(tr.Key, tr.Value);\r
- }\r
-\r
- public override String ToString() {\r
- return "NFA start=" + startState + " exit=" + exitState;\r
- }\r
-\r
- // Construct the transition relation of a composite-state DFA from\r
- // an NFA with start state s0 and transition relation trans (a\r
- // dictionary mapping int to arraylist of Transition). The start\r
- // state of the constructed DFA is the epsilon closure of s0, and\r
- // its transition relation is a dictionary mapping a composite state\r
- // (a set of ints) to a dictionary mapping a label (a string) to a\r
- // composite state (a set of ints).\r
-\r
- static IDictionary<Set<int>, IDictionary<String, Set<int>>>\r
- CompositeDfaTrans(int s0, IDictionary<int, ArrayList<Transition>> trans) {\r
- Set<int> S0 = EpsilonClose(new Set<int>(s0), trans);\r
- IQueue<Set<int>> worklist = new CircularQueue<Set<int>>();\r
- worklist.Enqueue(S0);\r
- // The transition relation of the DFA\r
- IDictionary<Set<int>, IDictionary<String, Set<int>>> res =\r
- new HashDictionary<Set<int>, IDictionary<String, Set<int>>>();\r
- while (!worklist.IsEmpty) {\r
- Set<int> S = worklist.Dequeue();\r
- if (!res.Contains(S)) {\r
- // The S -lab-> T transition relation being constructed for a given S\r
- IDictionary<String, Set<int>> STrans =\r
- new HashDictionary<String, Set<int>>();\r
- // For all s in S, consider all transitions s -lab-> t\r
- foreach (int s in S) {\r
- // For all non-epsilon transitions s -lab-> t, add t to T\r
- foreach (Transition tr in trans[s]) {\r
- if (tr.lab != null) { // Non-epsilon transition\r
- Set<int> toState;\r
- if (STrans.Contains(tr.lab)) // Already a transition on lab\r
- toState = STrans[tr.lab];\r
- else { // No transitions on lab yet\r
- toState = new Set<int>();\r
- STrans.Add(tr.lab, toState);\r
- }\r
- toState.Add(tr.target);\r
- }\r
- }\r
- }\r
- // Epsilon-close all T such that S -lab-> T, and put on worklist\r
- IDictionary<String, Set<int>> STransClosed =\r
- new HashDictionary<String, Set<int>>();\r
- foreach (KeyValuePair<String, Set<int>> entry in STrans) {\r
- Set<int> Tclose = EpsilonClose(entry.Value, trans);\r
- STransClosed.Add(entry.Key, Tclose);\r
- worklist.Enqueue(Tclose);\r
- }\r
- res.Add(S, STransClosed);\r
- }\r
- }\r
- return res;\r
- }\r
-\r
- // Compute epsilon-closure of state set S in transition relation trans. \r
-\r
- static Set<int>\r
- EpsilonClose(Set<int> S, IDictionary<int, ArrayList<Transition>> trans) {\r
- // The worklist initially contains all S members\r
- IQueue<int> worklist = new CircularQueue<int>();\r
- S.Apply(worklist.Enqueue);\r
- Set<int> res = new Set<int>(S);\r
- while (!worklist.IsEmpty) {\r
- int s = worklist.Dequeue();\r
- foreach (Transition tr in trans[s]) {\r
- if (tr.lab == null && !res.Contains(tr.target)) {\r
- res.Add(tr.target);\r
- worklist.Enqueue(tr.target);\r
- }\r
- }\r
- }\r
- return res;\r
- }\r
-\r
- // Compute a renamer, which is a dictionary mapping set of int to int\r
-\r
- static IDictionary<Set<int>, int> MkRenamer(ICollectionValue<Set<int>> states)\r
- {\r
- IDictionary<Set<int>, int> renamer = new HashDictionary<Set<int>, int>();\r
- int count = 0;\r
- foreach (Set<int> k in states)\r
- renamer.Add(k, count++);\r
- return renamer;\r
- }\r
-\r
- // Using a renamer (a dictionary mapping set of int to int), replace\r
- // composite (set of int) states with simple (int) states in the\r
- // transition relation trans, which is a dictionary mapping set of\r
- // int to a dictionary mapping from string to set of int. The\r
- // result is a dictionary mapping from int to a dictionary mapping\r
- // from string to int.\r
-\r
- static IDictionary<int, IDictionary<String, int>>\r
- Rename(IDictionary<Set<int>, int> renamer,\r
- IDictionary<Set<int>, IDictionary<String, Set<int>>> trans)\r
- {\r
- IDictionary<int, IDictionary<String, int>> newtrans =\r
- new HashDictionary<int, IDictionary<String, int>>();\r
- foreach (KeyValuePair<Set<int>, IDictionary<String, Set<int>>> entry\r
- in trans) {\r
- Set<int> k = entry.Key;\r
- IDictionary<String, int> newktrans = new HashDictionary<String, int>();\r
- foreach (KeyValuePair<String, Set<int>> tr in entry.Value)\r
- newktrans.Add(tr.Key, renamer[tr.Value]);\r
- newtrans.Add(renamer[k], newktrans);\r
- }\r
- return newtrans;\r
- }\r
-\r
- static Set<int> AcceptStates(ICollectionValue<Set<int>> states,\r
- IDictionary<Set<int>, int> renamer,\r
- int exit)\r
- {\r
- Set<int> acceptStates = new Set<int>();\r
- foreach (Set<int> state in states)\r
- if (state.Contains(exit))\r
- acceptStates.Add(renamer[state]);\r
- return acceptStates;\r
- }\r
-\r
- public Dfa ToDfa() {\r
- IDictionary<Set<int>, IDictionary<String, Set<int>>>\r
- cDfaTrans = CompositeDfaTrans(startState, trans);\r
- Set<int> cDfaStart = EpsilonClose(new Set<int>(startState), trans);\r
- ICollectionValue<Set<int>> cDfaStates = cDfaTrans.Keys;\r
- IDictionary<Set<int>, int> renamer = MkRenamer(cDfaStates);\r
- IDictionary<int, IDictionary<String, int>> simpleDfaTrans =\r
- Rename(renamer, cDfaTrans);\r
- int simpleDfaStart = renamer[cDfaStart];\r
- Set<int> simpleDfaAccept = AcceptStates(cDfaStates, renamer, exitState);\r
- return new Dfa(simpleDfaStart, simpleDfaAccept, simpleDfaTrans);\r
- }\r
-\r
- // Nested class for creating distinctly named states when constructing NFAs\r
-\r
- public class NameSource {\r
- private static int nextName = 0;\r
-\r
- public int next() {\r
- return nextName++;\r
- }\r
- }\r
-\r
- // Write an input file for the dot program. You can find dot at\r
- // http://www.research.att.com/sw/tools/graphviz/\r
-\r
- public void WriteDot(String filename) {\r
- TextWriter wr =\r
- new StreamWriter(new FileStream(filename, FileMode.Create,\r
- FileAccess.Write));\r
- wr.WriteLine("// Format this file as a Postscript file with ");\r
- wr.WriteLine("// dot " + filename + " -Tps -o out.ps\n");\r
- wr.WriteLine("digraph nfa {");\r
- wr.WriteLine("size=\"11,8.25\";");\r
- wr.WriteLine("rotate=90;");\r
- wr.WriteLine("rankdir=LR;");\r
- wr.WriteLine("start [style=invis];"); // Invisible start node\r
- wr.WriteLine("start -> d" + startState); // Edge into start state\r
-\r
- // The accept state has a double circle\r
- wr.WriteLine("d" + exitState + " [peripheries=2];");\r
-\r
- // The transitions \r
- foreach (KeyValuePair<int, ArrayList<Transition>> entry in trans) {\r
- int s1 = entry.Key;\r
- foreach (Transition s1Trans in entry.Value) {\r
- String lab = s1Trans.lab ?? "eps";\r
- int s2 = s1Trans.target;\r
- wr.WriteLine("d" + s1 + " -> d" + s2 + " [label=\"" + lab + "\"];");\r
- }\r
- }\r
- wr.WriteLine("}");\r
- wr.Close();\r
- }\r
- }\r
-\r
-// Class Transition, a transition from one state to another ----------\r
-\r
- public class Transition {\r
- public readonly String lab;\r
- public readonly int target;\r
-\r
- public Transition(String lab, int target) {\r
- this.lab = lab; this.target = target;\r
- }\r
-\r
- public override String ToString() {\r
- return "-" + lab + "-> " + target;\r
- }\r
- }\r
-\r
-// Class Dfa, deterministic finite automata --------------------------\r
-\r
-/*\r
- A deterministic finite automaton (DFA) is represented as a\r
- dictionary mapping state number (int) to a dictionary mapping label\r
- (a non-null string) to a target state (an int).\r
-*/\r
-\r
- class Dfa {\r
- private readonly int startState;\r
- private readonly Set<int> acceptStates;\r
- private readonly IDictionary<int, IDictionary<String, int>> trans;\r
-\r
- public Dfa(int startState, Set<int> acceptStates,\r
- IDictionary<int, IDictionary<String, int>> trans)\r
- {\r
- this.startState = startState;\r
- this.acceptStates = acceptStates;\r
- this.trans = trans;\r
- }\r
-\r
- public int Start { get { return startState; } }\r
-\r
- public Set<int> Accept { get { return acceptStates; } }\r
-\r
- public IDictionary<int, IDictionary<String, int>> Trans {\r
- get { return trans; }\r
- }\r
-\r
- public override String ToString() {\r
- return "DFA start=" + startState + "\naccept=" + acceptStates;\r
- }\r
-\r
- // Write an input file for the dot program. You can find dot at\r
- // http://www.research.att.com/sw/tools/graphviz/\r
-\r
- public void WriteDot(String filename) {\r
- TextWriter wr =\r
- new StreamWriter(new FileStream(filename, FileMode.Create,\r
- FileAccess.Write));\r
- wr.WriteLine("// Format this file as a Postscript file with ");\r
- wr.WriteLine("// dot " + filename + " -Tps -o out.ps\n");\r
- wr.WriteLine("digraph dfa {");\r
- wr.WriteLine("size=\"11,8.25\";");\r
- wr.WriteLine("rotate=90;");\r
- wr.WriteLine("rankdir=LR;");\r
- wr.WriteLine("start [style=invis];"); // Invisible start node\r
- wr.WriteLine("start -> d" + startState); // Edge into start state\r
-\r
- // Accept states are double circles\r
- foreach (int state in trans.Keys)\r
- if (acceptStates.Contains(state))\r
- wr.WriteLine("d" + state + " [peripheries=2];");\r
-\r
- // The transitions \r
- foreach (KeyValuePair<int, IDictionary<String, int>> entry in trans) {\r
- int s1 = entry.Key;\r
- foreach (KeyValuePair<String, int> s1Trans in entry.Value) {\r
- String lab = s1Trans.Key;\r
- int s2 = s1Trans.Value;\r
- wr.WriteLine("d" + s1 + " -> d" + s2 + " [label=\"" + lab + "\"];");\r
- }\r
- }\r
- wr.WriteLine("}");\r
- wr.Close();\r
- }\r
- }\r
-\r
-// Regular expressions ----------------------------------------------\r
-//\r
-// Abstract syntax of regular expressions\r
-// r ::= A | r1 r2 | (r1|r2) | r*\r
-//\r
-\r
- abstract class Regex {\r
- abstract public Nfa MkNfa(Nfa.NameSource names);\r
- }\r
-\r
- class Eps : Regex {\r
- // The resulting nfa0 has form s0s -eps-> s0e\r
-\r
- public override Nfa MkNfa(Nfa.NameSource names) {\r
- int s0s = names.next();\r
- int s0e = names.next();\r
- Nfa nfa0 = new Nfa(s0s, s0e);\r
- nfa0.AddTrans(s0s, null, s0e);\r
- return nfa0;\r
- }\r
- }\r
-\r
- class Sym : Regex {\r
- String sym;\r
-\r
- public Sym(String sym) {\r
- this.sym = sym;\r
- }\r
-\r
- // The resulting nfa0 has form s0s -sym-> s0e\r
-\r
- public override Nfa MkNfa(Nfa.NameSource names) {\r
- int s0s = names.next();\r
- int s0e = names.next();\r
- Nfa nfa0 = new Nfa(s0s, s0e);\r
- nfa0.AddTrans(s0s, sym, s0e);\r
- return nfa0;\r
- }\r
- }\r
-\r
- class Seq : Regex {\r
- Regex r1, r2;\r
-\r
- public Seq(Regex r1, Regex r2) {\r
- this.r1 = r1; this.r2 = r2;\r
- }\r
-\r
- // If nfa1 has form s1s ----> s1e \r
- // and nfa2 has form s2s ----> s2e \r
- // then nfa0 has form s1s ----> s1e -eps-> s2s ----> s2e\r
-\r
- public override Nfa MkNfa(Nfa.NameSource names) {\r
- Nfa nfa1 = r1.MkNfa(names);\r
- Nfa nfa2 = r2.MkNfa(names);\r
- Nfa nfa0 = new Nfa(nfa1.Start, nfa2.Exit);\r
- foreach (KeyValuePair<int, ArrayList<Transition>> entry in nfa1.Trans)\r
- nfa0.AddTrans(entry);\r
- foreach (KeyValuePair<int, ArrayList<Transition>> entry in nfa2.Trans)\r
- nfa0.AddTrans(entry);\r
- nfa0.AddTrans(nfa1.Exit, null, nfa2.Start);\r
- return nfa0;\r
- }\r
- }\r
-\r
- class Alt : Regex {\r
- Regex r1, r2;\r
-\r
- public Alt(Regex r1, Regex r2) {\r
- this.r1 = r1; this.r2 = r2;\r
- }\r
-\r
- // If nfa1 has form s1s ----> s1e \r
- // and nfa2 has form s2s ----> s2e \r
- // then nfa0 has form s0s -eps-> s1s ----> s1e -eps-> s0e\r
- // s0s -eps-> s2s ----> s2e -eps-> s0e\r
-\r
- public override Nfa MkNfa(Nfa.NameSource names) {\r
- Nfa nfa1 = r1.MkNfa(names);\r
- Nfa nfa2 = r2.MkNfa(names);\r
- int s0s = names.next();\r
- int s0e = names.next();\r
- Nfa nfa0 = new Nfa(s0s, s0e);\r
- foreach (KeyValuePair<int, ArrayList<Transition>> entry in nfa1.Trans)\r
- nfa0.AddTrans(entry);\r
- foreach (KeyValuePair<int, ArrayList<Transition>> entry in nfa2.Trans)\r
- nfa0.AddTrans(entry);\r
- nfa0.AddTrans(s0s, null, nfa1.Start);\r
- nfa0.AddTrans(s0s, null, nfa2.Start);\r
- nfa0.AddTrans(nfa1.Exit, null, s0e);\r
- nfa0.AddTrans(nfa2.Exit, null, s0e);\r
- return nfa0;\r
- }\r
- }\r
-\r
- class Star : Regex {\r
- Regex r;\r
-\r
- public Star(Regex r) {\r
- this.r = r;\r
- }\r
-\r
- // If nfa1 has form s1s ----> s1e \r
- // then nfa0 has form s0s ----> s0s\r
- // s0s -eps-> s1s\r
- // s1e -eps-> s0s\r
-\r
- public override Nfa MkNfa(Nfa.NameSource names) {\r
- Nfa nfa1 = r.MkNfa(names);\r
- int s0s = names.next();\r
- Nfa nfa0 = new Nfa(s0s, s0s);\r
- foreach (KeyValuePair<int, ArrayList<Transition>> entry in nfa1.Trans)\r
- nfa0.AddTrans(entry);\r
- nfa0.AddTrans(s0s, null, nfa1.Start);\r
- nfa0.AddTrans(nfa1.Exit, null, s0s);\r
- return nfa0;\r
- }\r
- }\r
-\r
-// Trying the RE->NFA->DFA translation on three regular expressions\r
-\r
- class TestNFA {\r
- public static void Main(String[] args) {\r
- Regex a = new Sym("A");\r
- Regex b = new Sym("B");\r
- Regex c = new Sym("C");\r
- Regex abStar = new Star(new Alt(a, b));\r
- Regex bb = new Seq(b, b);\r
- Regex r = new Seq(abStar, new Seq(a, b));\r
- // The regular expression (a|b)*ab\r
- BuildAndShow("ex1", r);\r
- // The regular expression ((a|b)*ab)*\r
- BuildAndShow("ex2", new Star(r));\r
- // The regular expression ((a|b)*ab)((a|b)*ab)\r
- BuildAndShow("ex3", new Seq(r, r));\r
- // The regular expression (a|b)*abb, from ASU 1986 p 136\r
- BuildAndShow("ex4", new Seq(abStar, new Seq(a, bb)));\r
- // SML reals: sign?((digit+(\.digit+)?))([eE]sign?digit+)?\r
- Regex d = new Sym("digit");\r
- Regex dPlus = new Seq(d, new Star(d));\r
- Regex s = new Sym("sign");\r
- Regex sOpt = new Alt(s, new Eps());\r
- Regex dot = new Sym(".");\r
- Regex dotDigOpt = new Alt(new Eps(), new Seq(dot, dPlus));\r
- Regex mant = new Seq(sOpt, new Seq(dPlus, dotDigOpt));\r
- Regex e = new Sym("e");\r
- Regex exp = new Alt(new Eps(), new Seq(e, new Seq(sOpt, dPlus)));\r
- Regex smlReal = new Seq(mant, exp);\r
- BuildAndShow("ex5", smlReal);\r
- }\r
-\r
- public static void BuildAndShow(String fileprefix, Regex r) {\r
- Nfa nfa = r.MkNfa(new Nfa.NameSource());\r
- Console.WriteLine(nfa);\r
- Console.WriteLine("Writing NFA graph to file");\r
- nfa.WriteDot(fileprefix + "nfa.dot");\r
- Console.WriteLine("---");\r
- Dfa dfa = nfa.ToDfa();\r
- Console.WriteLine(dfa);\r
- Console.WriteLine("Writing DFA graph to file");\r
- dfa.WriteDot(fileprefix + "dfa.dot");\r
- Console.WriteLine();\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: GettingStarted 2005-01-18\r
-\r
-// Compile with \r
-// csc /r:C5.dll GettingStarted.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace GettingStarted {\r
- class GettingStarted {\r
- public static void Main(String[] args) {\r
- IList<String> names = new ArrayList<String>();\r
- names.AddAll(new String[] { "Hoover", "Roosevelt", \r
- "Truman", "Eisenhower", "Kennedy" });\r
- // Print list:\r
- Console.WriteLine(names);\r
- // Print item 1 ("Roosevelt") in the list:\r
- Console.WriteLine(names[1]);\r
- // Create a list view comprising post-WW2 presidents:\r
- IList<String> postWWII = names.View(2, 3);\r
- // Print item 2 ("Kennedy") in the view:\r
- Console.WriteLine(postWWII[2]);\r
- // Enumerate and print the list view in reverse chronological order:\r
- foreach (String name in postWWII.Backwards()) \r
- Console.WriteLine(name);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: Graph representation with basic algorithms using C5 \r
-\r
-\r
-// Compile with \r
-// csc /r:C5.dll Graph.cs \r
-\r
-\r
-// The code is structured as a rudimentary Graph library, with an interface\r
-// for (edge)weighted graphs and a single implementation based on an\r
-// adjacency list representation using hash dictionaries. \r
-\r
-\r
-// The algorithms implemented include:\r
-//\r
-// Breadth-First-Search and Depth-First-Search, with an interface based on actions\r
-// to be taken as edges are traversed. Applications are checking for connectedness,\r
-// counting components\r
-//\r
-// Priority-First-Search, where edges are traversed according to either weight or \r
-// accumulated weight from the start of the search.\r
-// An application of the non-accumulating version is the construction of a minimal\r
-// spanning tree and therefore the following approximation algorithm. \r
-// Applications of the accumulating version are the construction of a shortest path\r
-// and the computation of the distance from one vertex to another one.\r
-//\r
-// An approximation algorithm for Travelling Salesman Problems, \r
-// where the weights satisfies the triangle inequality. \r
-\r
-\r
-// Pervasive generic parameters:\r
-// V: The type of a vertex in a graph. Vertices are identified\r
-// by the Equals method inherited from object (or overridden).\r
-// E: The type of additional data associated with edges in a graph.\r
-// W: The type of values of weights on edges in a weighted graph, \r
-// in practise usually int or double. Must be comparable and \r
-// there must be given a compatible way to add values.\r
- \r
-// Interfaces:\r
-// IGraph<V,E,W>: The interface for a graph implementation with\r
-// vertex type V, edge dat type E and weight values of type W. \r
-// IWeight<E,W>: The interface of a weight function \r
-\r
-// Classes:\r
-// HashGraph<V,E,W>: An implementation of IWeightedGraph<V,E,W> based on \r
-// adjacency lists represented as hash dictionaries.\r
-// HashGraph<V,E,W>.EdgesValue: A helper class for the Edges() method\r
-// CountWeight<E>: A \r
-// IntWeight:\r
-// DoubleWeight:\r
-\r
-// Value Types:\r
-// Edge<V,E>: \r
-// EdgeAction<V,E,U>:\r
-\r
-// Some notes:\r
-// The code only supports "natural" equality of vertices.\r
-\r
-using C5;\r
-using System;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace Graph\r
-{\r
- /// <summary>\r
- /// (Duer ikke)\r
- /// </summary>\r
- /// <typeparam name="V"></typeparam>\r
- /// <typeparam name="E"></typeparam>\r
- interface IGraphVertex<V, E,W> where W : IComparable<W>\r
- {\r
- V Value { get;}\r
- IGraph<V, E, W> Graph { get;}\r
- ICollectionValue<KeyValuePair<V, E>> Adjacent { get;}\r
-\r
- }\r
-\r
- class Vertex<V>\r
- {\r
- //V v;\r
- }\r
-/// <summary>\r
-/// \r
-/// </summary>\r
-/// <typeparam name="V"></typeparam>\r
-/// <typeparam name="E"></typeparam>\r
-/// <typeparam name="W"></typeparam>\r
- interface IGraph<V, E, W> where W : IComparable<W>\r
- {\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The weight object for this graph</value>\r
- IWeight<E, W> Weight { get;}\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of vertices in this graph</value>\r
- int VertexCount { get;}\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of edges in this graph</value>\r
- int EdgeCount { get;}\r
-\r
- /// <summary>\r
- /// The collection of vertices of this graph.\r
- /// The return value is a snapshot, not a live view onto the graph.\r
- /// </summary>\r
- /// <returns></returns>\r
- ICollectionValue<V> Vertices();\r
-\r
- /// <summary>\r
- /// The collection of edges incident to a particular vertex.\r
- /// The return value is a snapshot og (endvertex, edgedata) pairs.\r
- /// </summary>\r
- /// <param name="vertex"></param>\r
- /// <returns></returns>\r
- ICollectionValue<KeyValuePair<V, E>> Adjacent(V vertex);\r
-\r
- /// <summary>\r
- /// The collection of all edges in the graph. The return value is a snapshot\r
- /// of Edge values. Each edge is present once for an undefined direction.\r
- /// </summary>\r
- /// <returns></returns>\r
- ICollectionValue<Edge<V, E>> Edges();\r
-\r
- /// <summary>\r
- /// Add a(n isolated) vertex to the graph Ignore if vertex is already in the graph.\r
- /// </summary>\r
- /// <param name="vertex"></param>\r
- /// <returns>True if the vertex was added.</returns>\r
- bool AddVertex(V vertex);\r
-\r
- /// <summary>\r
- /// Add an edge to the graph. If the edge is already in the graph, update the \r
- /// edge data. Add vertices as needed.\r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="end"></param>\r
- /// <param name="edgedata"></param>\r
- /// <returns>True if the edge was added</returns>\r
- bool AddEdge(V start, V end, E edgedata);\r
-\r
- /// <summary>\r
- /// Remove a vertex and all its incident edges from the graph.\r
- /// </summary>\r
- /// <returns>True if the vertex was already in the graph and hence was removed</returns>\r
- bool RemoveVertex(V vertex);\r
-\r
- /// <summary>\r
- /// Remove an edge from the graph. Do not remove the vertices if they become isolated.\r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="end"></param>\r
- /// <param name="edgedata">On output, the edge data associated with the removed edge.</param>\r
- /// <returns>True if </returns>\r
- bool RemoveEdge(V start, V end, out E edgedata);\r
-\r
- /// <summary>\r
- /// Is there an edge from start to end in this graph, and if so, what is \r
- /// the data on that edge.\r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="end"></param>\r
- /// <param name="edge"></param>\r
- /// <returns></returns>\r
- bool FindEdge(V start, V end, out E edge);\r
-\r
- /// <summary>\r
- /// Construct the subgraph corresponding to a set of vertices.\r
- /// </summary>\r
- /// <param name="vs"></param>\r
- /// <returns></returns>\r
- IGraph<V, E, W> SubGraph(ICollectionValue<V> vs);\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>True if graph is connected</value>\r
- bool IsConnected { get; }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <value>The number of connected components of this graph</value>\r
- int ComponentCount { get;}\r
-\r
- /// <summary>\r
- /// Compute the connnected components of this graph. \r
- /// </summary>\r
- /// <returns>A collection of (vertex,component) pairs, where the first part of the\r
- /// pair is some vertex in the component.</returns>\r
- ICollectionValue<KeyValuePair<V, IGraph<V, E, W>>> Components();\r
-\r
- /// <summary>\r
- /// Traverse the connected component containing the <code>start</code> vertex, \r
- /// in either BFS or DFS order, beginning at <code>start</code> and performing the action \r
- /// <code>act</code> on each edge part of the constructed tree.\r
- /// </summary>\r
- /// <param name="bfs">True if BFS, false if DFS</param>\r
- /// <param name="start">The vertex to start at</param>\r
- /// <param name="act">The action to perform at each node</param>\r
- void TraverseVertices(bool bfs, V start, Action<Edge<V, E>> act);\r
-\r
- /// <summary>\r
- /// Traverse an undirected graph in either BFS or DFS order, performing the action \r
- /// <code>act</code> on each vertex. \r
- /// The start vertex of each component of the graph is undefinded. \r
- /// </summary>\r
- /// <param name="bfs">True if BFS, false if DFS</param>\r
- /// <param name="act"></param>\r
- void TraverseVertices(bool bfs, Action<V> act);\r
-\r
- /// <summary>\r
- /// Traverse an undirected graph in either BFS or DFS order, performing the action \r
- /// <code>act</code> on each edge in the traversal and beforecomponent/aftercomponent \r
- /// at the start and end of each component (with argument: the start vertex of the component).\r
- /// </summary>\r
- /// <param name="bfs">True if BFS, false if DFS</param>\r
- /// <param name="act"></param>\r
- /// <param name="beforecomponent"></param>\r
- /// <param name="aftercomponent"></param>\r
- void TraverseVertices(bool bfs, Action<Edge<V, E>> act, Action<V> beforecomponent, Action<V> aftercomponent);\r
-\r
- /// <summary>\r
- /// A more advanced Depth First Search traversal.\r
- /// </summary>\r
- /// <param name="start">The vertex to start the search at</param>\r
- /// <param name="beforevertex">Action to perform when a vertex is first encountered.</param>\r
- /// <param name="aftervertex">Action to perform when all edges out of a vertex has been handles.</param>\r
- /// <param name="onfollow">Action to perform as an edge is traversed.</param>\r
- /// <param name="onfollowed">Action to perform when an edge is travesed back.</param>\r
- /// <param name="onnotfollowed">Action to perform when an edge (a backedge)is seen, but not followed.</param>\r
- void DepthFirstSearch(V start, Action<V> beforevertex, Action<V> aftervertex,\r
- Action<Edge<V, E>> onfollow, Action<Edge<V, E>> onfollowed, Action<Edge<V, E>> onnotfollowed);\r
-\r
- //TODO: perhaps we should avoid exporting this?\r
- /// <summary>\r
- /// Traverse the part of the graph reachable from start in order of least distance \r
- /// from start according to the weight function. Perform act on the edges of the \r
- /// traversal as they are recognised.\r
- /// </summary>\r
- /// <typeparam name="W"></typeparam>\r
- /// <param name="weight"></param>\r
- /// <param name="start"></param>\r
- /// <param name="act"></param>\r
- void PriorityFirstTraverse(bool accumulating, V start, EdgeAction<V, E, W> act);\r
-\r
- /// <summary>\r
- /// Compute the (a) shortest path from start to end. THrow an exception if end cannot be reached rom start.\r
- /// </summary>\r
- /// <param name="weight"></param>\r
- /// <param name="start"></param>\r
- /// <param name="end"></param>\r
- /// <returns></returns>\r
- ICollectionValue<Edge<V, E>> ShortestPath(V start, V end);\r
-\r
- /// <summary>\r
- /// Compute the Distance from start to end, i.e. the total weight of a shortest path from start to end. \r
- /// Throw an exception if end cannot be reached rom start.\r
- /// </summary>\r
- /// <param name="start"></param>\r
- /// <param name="end"></param>\r
- /// <returns></returns>\r
- W Distance(V start, V end);\r
-\r
- /// <summary>\r
- /// Compute a minimum spanning tree for the graph.\r
- /// Throw an exception if this graph is not connected.\r
- /// </summary>\r
- /// <param name="root">(The starting point of the PFS, to be removed)</param>\r
- /// <returns></returns>\r
- IGraph<V, E, W> MinimumSpanningTree(out V root);\r
-\r
- /// <summary>\r
- /// Compute a factor 2 approximation to a Minimum Weight\r
- /// Perfect Matching in a graph using NNs\r
- /// </summary>\r
- /// <returns></returns>\r
- ICollectionValue<Edge<V, E>> ApproximateMWPM();\r
-\r
- /// <summary>\r
- /// Construct a closed Euler tour of this graph if one exists, i.e. if \r
- /// the graph is connected and all vertices have even degrees. Throw an\r
- /// ArgumentException if no closed Euler tour exists.\r
- /// </summary>\r
- /// <returns>A list of vertices in an Euler tour of this graph.</returns>\r
- IList<V> EulerTour();\r
-\r
- /// <summary>\r
- /// This is intended for implementations of the very simple factor 2 approximation\r
- /// algorithms for the travelling salesman problem for Euclidic weight/distance \r
- /// functions, i.e. distances that satisfy the triangle inequality. (We do not do 3/2)\r
- /// </summary>\r
- /// <returns></returns>\r
- IDirectedCollectionValue<V> ApproximateTSP();\r
-\r
- /// <summary>\r
- /// Pretty-print the graph to the console (for debugging purposes).\r
- /// </summary>\r
- void Print(System.IO.TextWriter output);\r
- }\r
-\r
-/// <summary>\r
-/// The type of an edge in a graph. An edge is identified by its pair of \r
-/// vertices. The pair is considered ordered, and so an Edge really describes\r
-/// an edge of the graph in a particular traversal direction.\r
-/// </summary>\r
-/// <typeparam name="V">The type of a vertex.</typeparam>\r
-/// <typeparam name="E">The type of data asociated with edges.</typeparam>\r
- struct Edge<V, E>\r
- {\r
- static SCG.IEqualityComparer<V> vequalityComparer = EqualityComparer<V>.Default;\r
- public readonly V start, end;\r
- public readonly E edgedata;\r
- public Edge(V start, V end, E edgedata)\r
- {\r
- if (vequalityComparer.Equals(start, end))\r
- throw new ArgumentException("Illegal: start and end are equal");\r
- this.start = start; this.end = end; this.edgedata = edgedata;\r
- }\r
-\r
- public Edge<V, E> Reverse()\r
- {\r
- return new Edge<V, E>(end, start, edgedata);\r
- }\r
-\r
- public override string ToString()\r
- {\r
- return String.Format("(start='{0}', end='{1}', edgedata='{2}')", start, end, edgedata); ;\r
- }\r
-\r
- public override bool Equals(object obj)\r
- {\r
- if (obj is Edge<V, E>)\r
- {\r
- Edge<V, E> other = (Edge<V, E>)obj;\r
- return vequalityComparer.Equals(start, other.start) && vequalityComparer.Equals(end, other.end);\r
- }\r
- return false;\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public override int GetHashCode()\r
- {\r
- //TODO: should we use xor? Or a random factor?\r
- return start.GetHashCode() + 148712671 * end.GetHashCode();\r
- }\r
-\r
- /// <summary>\r
- /// The unordered equalityComparer compares edges independent of the order of the vertices.\r
- /// </summary>\r
- public class UnorderedEqualityComparer : SCG.IEqualityComparer<Edge<V, E>>\r
- {\r
- /// <summary>\r
- /// Check if two edges have the same vertices irrespective of order.\r
- /// </summary>\r
- /// <param name="i1"></param>\r
- /// <param name="i2"></param>\r
- /// <returns></returns>\r
- public bool Equals(Edge<V, E> i1, Edge<V, E> i2)\r
- {\r
- return (vequalityComparer.Equals(i1.start, i2.start) && vequalityComparer.Equals(i1.end, i2.end)) ||\r
- (vequalityComparer.Equals(i1.end, i2.start) && vequalityComparer.Equals(i1.start, i2.end));\r
- }\r
-\r
- /// <summary>\r
- /// Return a hash code compatible with the unordered equals.\r
- /// </summary>\r
- /// <param name="item"></param>\r
- /// <returns></returns>\r
- public int GetHashCode(Edge<V, E> item)\r
- {\r
- return item.start.GetHashCode() ^ item.end.GetHashCode();\r
- }\r
- }\r
- }\r
-\r
-/// <summary>\r
-/// The type of the weight object of a graph. This consists of a function mapping\r
-/// edge data values to weight values, and an operation to add two weight values.\r
-/// It is required that weight values are comparable.\r
-/// \r
-/// The user must assure that the add operation is commutative and fulfills \r
-/// Add(w1,w2) ≤ w1 for all w1 and w2 that can appear as weights or sums of\r
-/// weights. In practise, W will be int or double, all weight values will be \r
-/// non-negative and the addition will be the natural addition on W.\r
-/// </summary>\r
-/// <typeparam name="E"></typeparam>\r
-/// <typeparam name="W"></typeparam>\r
- interface IWeight<E, W> where W : IComparable<W>\r
- {\r
- /// <summary>\r
- /// Compute the weight value corresponding to specific edge data.\r
- /// </summary>\r
- /// <param name="edgedata"></param>\r
- /// <returns></returns>\r
- W Weight(E edgedata);\r
-\r
- /// <summary>\r
- /// Add two weight values.\r
- /// </summary>\r
- /// <param name="w1"></param>\r
- /// <param name="w2"></param>\r
- /// <returns></returns>\r
- W Add(W w1, W w2);\r
- }\r
-\r
-/// <summary>\r
-/// An action to perform when an edge is encountered during a traversal of the graph.\r
-/// The "extra" parameter is for additional information supplied by the traversal \r
-/// algorithm. \r
-/// The intention of the bool return value is that returning false is a signal to the\r
-/// traversal algorithm to abandon the traversl because the user has already found\r
-/// what he was looking for.\r
-/// </summary>\r
-/// <typeparam name="V"></typeparam>\r
-/// <typeparam name="E"></typeparam>\r
-/// <typeparam name="U"></typeparam>\r
-/// <param name="edge"></param>\r
-/// <param name="extra"></param>\r
-/// <returns></returns>\r
- delegate bool EdgeAction<V, E, U>(Edge<V, E> edge, U extra);\r
-\r
-\r
-/*\r
- For a dense graph, we would use data fields:\r
-\r
- E'[,] or E'[][] for the matrix. Possibly E'[][] for a triangular one!\r
- Here E' = struct{E edgedata, bool present} or class{E edgedata}, or if E is a class just E.\r
- Thus E' is E! for value types. Or we could have two matrices: E[][] and bool[][]. \r
-\r
- HashDictionary<V,int> to map vertex ids to indices.\r
- ArrayList<V> for the map the other way.\r
- Or simply a HashedArrayList<V> to get both?\r
-\r
- PresentList<int>, FreeList<int> or similar, if we do not want to compact the indices in the matrix on each delete.\r
- If we compact, we always do a delete on the vertex<->index map by a replace and a removelast:\r
- vimap[ind]=vimap[vimap.Count]; vimap.RemoveLast(); //also reorder matrix!\r
- \r
-\r
-*/\r
-\r
-/// <summary>\r
-/// An implementation of IGraph≤V,E,W≥ based on an adjacency list representation using hash dictionaries.\r
-/// As a consequence, this will be most efficient for sparse graphs.\r
-/// </summary>\r
-/// <typeparam name="V"></typeparam>\r
-/// <typeparam name="E"></typeparam>\r
-/// <typeparam name="W"></typeparam>\r
- class HashGraph<V, E, W> : IGraph<V, E, W> where W : IComparable<W>\r
- {\r
- int edgecount;\r
-\r
- HashDictionary<V, HashDictionary<V, E>> graph;\r
-\r
- IWeight<E, W> weight;\r
-\r
- public IWeight<E, W> Weight { get { return weight; } }\r
-\r
-\r
- /// <summary>\r
- /// Create an initially empty graph.\r
- /// </summary>\r
- /// <param name="weight"></param>\r
- [UsedBy("testTSP")]\r
- public HashGraph(IWeight<E, W> weight)\r
- {\r
- this.weight = weight;\r
- edgecount = 0;\r
- graph = new HashDictionary<V, HashDictionary<V, E>>();\r
- }\r
-\r
- /// <summary>\r
- /// Constructing a graph with no isolated vertices given a collection of edges.\r
- /// </summary>\r
- /// <param name="edges"></param>\r
- [UsedBy()]\r
- public HashGraph(IWeight<E, W> weight, SCG.IEnumerable<Edge<V, E>> edges) : this(weight)\r
- {\r
- foreach (Edge<V, E> edge in edges)\r
- {\r
- if (edge.start.Equals(edge.end))\r
- throw new ApplicationException("Edge has equal start and end");\r
- {\r
- HashDictionary<V, E> edgeset;\r
- //TODO: utilize upcoming FindOrAddSome operation\r
- if (!graph.Find(edge.start, out edgeset))\r
- graph.Add(edge.start, edgeset = new HashDictionary<V, E>());\r
- if (!edgeset.UpdateOrAdd(edge.end, edge.edgedata))\r
- edgecount++;\r
- if (!graph.Find(edge.end, out edgeset))\r
- graph.Add(edge.end, edgeset = new HashDictionary<V, E>());\r
- edgeset.UpdateOrAdd(edge.start, edge.edgedata);\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// This constructs a graph with a given set of vertices.\r
- /// Will only allow these vertices.\r
- /// Duplicate edges are allowed.\r
- /// </summary>\r
- /// <param name="vertices"></param>\r
- /// <param name="edges"></param>\r
- public HashGraph(IWeight<E, W> weight, SCG.IEnumerable<V> vertices, SCG.IEnumerable<Edge<V, E>> edges) : this(weight)\r
- {\r
- foreach (V v in vertices)\r
- graph.Add(v, new HashDictionary<V, E>());\r
- foreach (Edge<V, E> edge in edges)\r
- {\r
- HashDictionary<V, E> edgeset;\r
- if (edge.start.Equals(edge.end))\r
- throw new ApplicationException("Edge has equal start and end");\r
- if (!graph.Find(edge.start, out edgeset))\r
- throw new ApplicationException("Edge has unknown start");\r
- if (!edgeset.UpdateOrAdd(edge.end, edge.edgedata))\r
- edgecount++;\r
- if (!graph.Find(edge.end, out edgeset))\r
- throw new ApplicationException("Edge has unknown end");\r
- edgeset.UpdateOrAdd(edge.start, edge.edgedata);\r
- }\r
- }\r
-\r
- [UsedBy("testCOMP")]\r
- public int VertexCount { get { return graph.Count; } }\r
-\r
- [UsedBy("testCOMP")]\r
- public int EdgeCount { get { return edgecount; } }\r
-\r
- public ICollectionValue<V> Vertices()\r
- {\r
- return new GuardedCollectionValue<V>(graph.Keys);\r
- }\r
-\r
- public ICollectionValue<KeyValuePair<V, E>> Adjacent(V vertex)\r
- {\r
- return new GuardedCollectionValue<KeyValuePair<V, E>>(graph[vertex]);\r
- }\r
-\r
- class EdgesValue : CollectionValueBase<Edge<V, E>>\r
- {\r
- HashGraph<V, E, W> graph;\r
- internal EdgesValue(HashGraph<V, E, W> g) { graph = g; }\r
-\r
- public override bool IsEmpty { get { return graph.edgecount == 0; } }\r
-\r
- public override int Count { get { return graph.edgecount; } }\r
-\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
-\r
-\r
- public override Edge<V, E> Choose()\r
- {\r
- KeyValuePair<V, HashDictionary<V, E>> adjacent = graph.graph.Choose();\r
- KeyValuePair<V, E> otherend = graph.graph[adjacent.Key].Choose();\r
- return new Edge<V, E>(adjacent.Key, otherend.Key, otherend.Value);\r
- }\r
-\r
- public override SCG.IEnumerator<Edge<V, E>> GetEnumerator()\r
- {\r
- HashSet<Edge<V, E>> seen = new HashSet<Edge<V, E>>(new Edge<V, E>.UnorderedEqualityComparer());\r
- foreach (V v in graph.graph.Keys)\r
- foreach (KeyValuePair<V, E> p in graph.graph[v])\r
- {\r
- Edge<V, E> edge = new Edge<V, E>(v, p.Key, p.Value);\r
- if (!seen.FindOrAdd(ref edge))\r
- yield return edge;\r
- }\r
- }\r
- }\r
-\r
- public ICollectionValue<Edge<V, E>> Edges()\r
- {\r
- return new EdgesValue(this);\r
- }\r
-\r
- public bool AddVertex(V v)\r
- {\r
- if (graph.Contains(v))\r
- return false;\r
- graph.Add(v, new HashDictionary<V, E>());\r
- return true;\r
- }\r
-\r
- //Note: no warning on update of edgedata!\r
- //TODO: Shouldn´t Update or Add return the old value?\r
- //Then it would be easy to check for updates \r
- public bool AddEdge(V start, V end, E edgedata)\r
- {\r
- bool retval = false;\r
- HashDictionary<V, E> edgeset;\r
- if (graph.Find(start, out edgeset))\r
- retval = !edgeset.UpdateOrAdd(end, edgedata);\r
- else\r
- {\r
- graph[start] = edgeset = new HashDictionary<V, E>();\r
- edgeset[end] = edgedata;\r
- retval = true;\r
- }\r
- if (graph.Find(end, out edgeset))\r
- edgeset.UpdateOrAdd(start, edgedata);\r
- else\r
- {\r
- graph[end] = edgeset = new HashDictionary<V, E>();\r
- edgeset[start] = edgedata;\r
- }\r
- if (retval)\r
- edgecount++;\r
- return retval;\r
- }\r
-\r
- public bool RemoveVertex(V vertex)\r
- {\r
- HashDictionary<V, E> edgeset;\r
- if (!graph.Find(vertex, out edgeset))\r
- return false;\r
- foreach (V othervertex in edgeset.Keys)\r
- graph[othervertex].Remove(vertex); //Assert retval==true\r
- edgecount -= edgeset.Count;\r
- graph.Remove(vertex);\r
- return true;\r
- }\r
-\r
- public bool RemoveEdge(V start, V end, out E edgedata)\r
- {\r
- HashDictionary<V, E> edgeset;\r
- if (!graph.Find(start, out edgeset))\r
- {\r
- edgedata = default(E);\r
- return false;\r
- }\r
- if (!edgeset.Remove(end, out edgedata))\r
- return false;\r
- graph[end].Remove(start);\r
- edgecount--;\r
- return true;\r
- }\r
-\r
- public bool FindEdge(V start, V end, out E edgedata)\r
- {\r
- HashDictionary<V, E> edges;\r
- if (!graph.Find(start, out edges))\r
- {\r
- edgedata = default(E);\r
- return false;\r
- }\r
- return edges.Find(end, out edgedata);\r
- }\r
-\r
- public IGraph<V, E, W> SubGraph(ICollectionValue<V> vs)\r
- {\r
- HashSet<V> vertexset = vs as HashSet<V>;\r
- if (vertexset == null)\r
- {\r
- vertexset = new HashSet<V>();\r
- vertexset.AddAll(vs);\r
- }\r
-\r
- return new HashGraph<V, E, W>(weight,\r
- vs,\r
- Edges().Filter(delegate(Edge<V, E> e) { return vertexset.Contains(e.start) && vertexset.Contains(e.end); }));\r
- }\r
-\r
- public bool IsConnected\r
- {\r
- //TODO: optimize: needs to change Action<Edge<V,E>> to EdgeAction to be able to break out\r
- get { return ComponentCount <= 1; }\r
- }\r
-\r
- public int ComponentCount\r
- {\r
- get\r
- {\r
- int components = 0;\r
- TraverseVertices(false, null, delegate(V v) { components++; }, null);\r
- return components;\r
- }\r
- }\r
-\r
- public ICollectionValue<KeyValuePair<V, IGraph<V, E, W>>> Components()\r
- {\r
- ArrayList<KeyValuePair<V, IGraph<V, E, W>>> retval = new ArrayList<KeyValuePair<V, IGraph<V, E, W>>>();\r
- HashGraph<V, E, W> component;\r
- ArrayList<V> vertices = null;\r
- Action<Edge<V, E>> edgeaction = delegate(Edge<V, E> e)\r
- {\r
- vertices.Add(e.end);\r
- };\r
- Action<V> beforecomponent = delegate(V v)\r
- {\r
- vertices = new ArrayList<V>();\r
- vertices.Add(v);\r
- };\r
- Action<V> aftercomponent = delegate(V v)\r
- {\r
- //component = SubGraph(vertices);\r
- component = new HashGraph<V, E, W>(weight);\r
- foreach (V start in vertices)\r
- {\r
- //component.graph[start] = graph[start].Clone();\r
- HashDictionary<V, E> edgeset = component.graph[start] = new HashDictionary<V, E>();\r
- foreach (KeyValuePair<V, E> adjacent in graph[start])\r
- edgeset[adjacent.Key] = adjacent.Value;\r
- }\r
- retval.Add(new KeyValuePair<V, IGraph<V, E, W>>(v, component));\r
- };\r
- TraverseVertices(false, edgeaction, beforecomponent, aftercomponent);\r
- return retval;\r
- }\r
-\r
- [UsedBy("test1")]\r
- public void TraverseVertices(bool bfs, V start, Action<Edge<V, E>> act)\r
- {\r
- if (!graph.Contains(start))\r
- throw new ArgumentException("start Vertex not in graph");\r
- IList<Edge<V, E>> todo = new LinkedList<Edge<V, E>>();\r
- todo.FIFO = bfs;\r
- HashSet<V> seen = new HashSet<V>();\r
- V v;\r
- while (!todo.IsEmpty || seen.Count == 0)\r
- {\r
- if (seen.Count > 1)\r
- {\r
- Edge<V, E> e = todo.Remove();\r
- if (act != null)\r
- act(e);\r
- v = e.end;\r
- }\r
- else\r
- {\r
- seen.Add(start);\r
- v = start;\r
- }\r
-\r
- HashDictionary<V, E> adjacent;\r
- if (graph.Find(v, out adjacent))\r
- {\r
- foreach (KeyValuePair<V, E> p in adjacent)\r
- {\r
- V end = p.Key;\r
- if (!seen.FindOrAdd(ref end))\r
- todo.Add(new Edge<V, E>(v, end, p.Value));\r
- }\r
- }\r
- }\r
- }\r
-\r
- public void TraverseVertices(bool bfs, Action<V> act)\r
- {\r
- TraverseVertices(bfs, delegate(Edge<V, E> e) { act(e.end); }, act, null);\r
- }\r
-\r
- //TODO: merge the hash set here with the intra omponent one?\r
- public void TraverseVertices(bool bfs, Action<Edge<V, E>> act, Action<V> beforecomponent, Action<V> aftercomponent)\r
- {\r
- HashSet<V> missing = new HashSet<V>();\r
- missing.AddAll(Vertices());\r
- Action<Edge<V, E>> myact = act + delegate(Edge<V, E> e) { missing.Remove(e.end); };\r
- Action<V> mybeforecomponent = beforecomponent + delegate(V v) { missing.Remove(v); };\r
- while (!missing.IsEmpty)\r
- {\r
- V start = default(V);\r
- foreach (V v in missing)\r
- { start = v; break; }\r
- mybeforecomponent(start);\r
- TraverseVertices(bfs, start, myact);\r
- if (aftercomponent != null)\r
- aftercomponent(start);\r
- }\r
- }\r
-\r
- delegate void Visitor(V v, V parent, bool atRoot);\r
-\r
- //TODO: allow actions to be null\r
- [UsedBy("testDFS")]\r
- public void DepthFirstSearch(V start, Action<V> before, Action<V> after,\r
- Action<Edge<V, E>> onfollow, Action<Edge<V, E>> onfollowed, Action<Edge<V, E>> onnotfollowed)\r
- {\r
- HashSet<V> seen = new HashSet<V>();\r
- seen.Add(start);\r
- //If we do not first set visit = null, the compiler will complain at visit(end)\r
- //that visit is uninitialized\r
- Visitor visit = null;\r
- visit = delegate(V v, V parent, bool atRoot)\r
- {\r
- before(v);\r
- HashDictionary<V, E> adjacent;\r
- if (graph.Find(v, out adjacent))\r
- foreach (KeyValuePair<V, E> p in adjacent)\r
- {\r
- V end = p.Key;\r
- Edge<V, E> e = new Edge<V, E>(v, end, p.Value);\r
- if (!seen.FindOrAdd(ref end))\r
- {\r
- onfollow(e);\r
- visit(end, v, false);\r
- onfollowed(e);\r
- }\r
- else\r
- {\r
- if (!atRoot && !parent.Equals(end))\r
- onnotfollowed(e);\r
- }\r
- }\r
- after(v);\r
- };\r
- visit(start, default(V), true);\r
- }\r
-\r
- public void PriorityFirstTraverse(bool accumulated, V start, EdgeAction<V, E, W> act)\r
- {\r
- if (!graph.Contains(start))\r
- throw new ArgumentException("Graph does not contain start");\r
- IPriorityQueue<W> fringe = new IntervalHeap<W>();\r
- HashDictionary<V, IPriorityQueueHandle<W>> seen = new HashDictionary<V, IPriorityQueueHandle<W>>();\r
- HashDictionary<IPriorityQueueHandle<W>, Edge<V, E>> bestedge = new HashDictionary<IPriorityQueueHandle<W>, Edge<V, E>>();\r
-\r
- IPriorityQueueHandle<W> h = null;\r
- V current;\r
- W currentdist;\r
- while (!fringe.IsEmpty || seen.Count == 0)\r
- {\r
- if (seen.Count == 0)\r
- {\r
- seen.Add(start, h);\r
- current = start;\r
- currentdist = default(W);\r
- }\r
- else\r
- {\r
- currentdist = fringe.DeleteMin(out h);\r
- Edge<V, E> e = bestedge[h];\r
- if (!act(e, currentdist))\r
- break;\r
- bestedge.Remove(h);\r
- current = e.end;\r
- }\r
- HashDictionary<V, E> adjacentnodes;\r
- if (graph.Find(current, out adjacentnodes))\r
- foreach (KeyValuePair<V, E> adjacent in adjacentnodes)\r
- {\r
- V end = adjacent.Key;\r
- E edgedata = adjacent.Value;\r
- W dist = weight.Weight(edgedata), olddist;\r
- if (accumulated && !current.Equals(start)) dist = weight.Add(currentdist, weight.Weight(edgedata));\r
- if (!seen.Find(end, out h))\r
- {\r
- h = null;\r
- fringe.Add(ref h, dist);\r
- seen[end] = h;\r
- bestedge[h] = new Edge<V, E>(current, end, edgedata);\r
- }\r
- else if (fringe.Find(h, out olddist) && dist.CompareTo(olddist) < 0)\r
- {\r
- fringe[h] = dist;\r
- bestedge[h] = new Edge<V, E>(current, end, edgedata);\r
- }\r
- }\r
- }\r
- }\r
-\r
- public W Distance(V start, V end)\r
- {\r
- W dist = default(W);\r
- bool found = false;\r
- PriorityFirstTraverse(true, start, delegate(Edge<V, E> e, W w)\r
- {\r
- if (end.Equals(e.end)) { dist = w; found = true; return false; }\r
- else return true;\r
- });\r
- if (found)\r
- return dist;\r
- throw new ArgumentException(String.Format("No path from {0} to {1}", start, end));\r
- }\r
-\r
-\r
- public ICollectionValue<Edge<V, E>> ShortestPath(V start, V end)\r
- {\r
- HashDictionary<V, Edge<V, E>> backtrack = new HashDictionary<V, Edge<V, E>>();\r
- PriorityFirstTraverse(true, start, delegate(Edge<V, E> e, W w) { backtrack[e.end] = e; return !end.Equals(e.end); });\r
- ArrayList<Edge<V, E>> path = new ArrayList<Edge<V, E>>();\r
- Edge<V, E> edge;\r
- V v = end;\r
- while (backtrack.Find(v, out edge))\r
- {\r
- path.Add(edge);\r
- v = edge.start;\r
- }\r
- if (path.IsEmpty)\r
- throw new ArgumentException(String.Format("No path from {0} to {1}", start, end));\r
- path.Reverse();\r
- return path;\r
- }\r
-\r
- /// <summary>\r
- /// NB: assume connected, throw exception if not\r
- /// </summary>\r
- /// <typeparam name="W"></typeparam>\r
- /// <param name="edgeWeight"></param>\r
- /// <returns></returns>\r
- public IGraph<V, E, W> MinimumSpanningTree(out V start)\r
- {\r
- ArrayList<Edge<V, E>> edges = new ArrayList<Edge<V, E>>();\r
- start = default(V);\r
- foreach (V v in graph.Keys)\r
- { start = v; break; }\r
- PriorityFirstTraverse(false, start, delegate(Edge<V, E> e, W w) { edges.Add(e); return true; });\r
- if (edges.Count != graph.Count - 1)\r
- throw new ArgumentException("Graph not connected");\r
- return new HashGraph<V, E, W>(weight, edges);\r
- }\r
-\r
- public ICollectionValue<Edge<V, E>> ApproximateMWPM()\r
- {\r
- //Assume graph complete and even number of vertices\r
- HashGraph<V, E, W> clone = new HashGraph<V, E, W>(weight, Edges());\r
- ArrayList<Edge<V, E>> evenpath = new ArrayList<Edge<V, E>>();\r
- ArrayList<Edge<V, E>> oddpath = new ArrayList<Edge<V, E>>();\r
- V start = default(V);\r
- foreach (V v in clone.Vertices()) { start = v; break; }\r
- V current = start;\r
- W evenweight, oddweight;\r
- evenweight = oddweight = default(W);\r
- bool even = true;\r
- while (clone.VertexCount > 0)\r
- {\r
- V bestvertex = default(V);\r
- E bestedge = default(E);\r
- W bestweight = default(W);\r
- if (clone.VertexCount == 1)\r
- {\r
- bestvertex = start;\r
- bestedge = graph[current][start];\r
- bestweight = weight.Weight(bestedge);\r
- }\r
- else\r
- {\r
- bool first = true;\r
- foreach (KeyValuePair<V, E> p in clone.graph[current])\r
- {\r
- W thisweight = weight.Weight(p.Value);\r
- if (first || bestweight.CompareTo(thisweight) > 0)\r
- {\r
- bestvertex = p.Key;\r
- bestweight = thisweight;\r
- bestedge = p.Value;\r
- }\r
- first = false;\r
- }\r
- }\r
- clone.RemoveVertex(current);\r
- //Console.WriteLine("-* {0} / {1} / {2}", bestvertex, bestweight, tour.Count);\r
- if (even)\r
- {\r
- evenweight = evenpath.Count < 1 ? bestweight : weight.Add(evenweight, bestweight);\r
- evenpath.Add(new Edge<V, E>(current, bestvertex, bestedge));\r
- }\r
- else\r
- {\r
- oddweight = oddpath.Count < 1 ? bestweight : weight.Add(oddweight, bestweight);\r
- oddpath.Add(new Edge<V, E>(current, bestvertex, bestedge));\r
- }\r
- current = bestvertex;\r
- even = !even;\r
- }\r
- //Console.WriteLine("Totalweights: even: {0} and odd: {1}", evenweight, oddweight);\r
- return evenweight.CompareTo(oddweight) < 0 ? evenpath : oddpath;\r
- }\r
-\r
- /// <summary>\r
- /// The construction is performed as follows: \r
- /// Start at some vertex. Greedily construct a path starting there by \r
- /// following edges at random until no more unused edges are available\r
- /// from the current node, which must be the start node. Then follow \r
- /// the path constructed so far and whenever we meet a vertex with \r
- /// unused edges, construct a path from there greedily as above, \r
- /// inserting into the path in front of us.\r
- /// \r
- /// The algorithm will use constant time for each vertex added \r
- /// to the path and \r
- /// \r
- /// Illustrates use of views as a safe version of listnode pointers \r
- /// and hashed linked lists for choosing some item in constant time combined \r
- /// with (expected) constant time remove.\r
- /// </summary>\r
- /// <returns></returns>\r
- public IList<V> EulerTour()\r
- {\r
- bool debug = false;\r
- //Assert connected and all degrees even. (Connected is checked at the end)\r
- string fmt = "Graph does not have a closed Euler tour: vertex {0} has odd degree {1}";\r
- foreach (KeyValuePair<V, HashDictionary<V, E>> adj in graph)\r
- if (adj.Value.Count % 2 != 0)\r
- throw new ArgumentException(String.Format(fmt, adj.Key, adj.Value.Count));\r
-\r
- LinkedList<V> path = new LinkedList<V>();\r
- //Clone the graph data to keep track of used edges.\r
- HashDictionary<V, HashedArrayList<V>> edges = new HashDictionary<V, HashedArrayList<V>>();\r
- V start = default(V);\r
- HashedArrayList<V> adjacent = null;\r
- foreach (KeyValuePair<V, HashDictionary<V, E>> p in graph)\r
- {\r
- adjacent = new HashedArrayList<V>();\r
- adjacent.AddAll(p.Value.Keys);\r
- start = p.Key;\r
- edges.Add(start, adjacent);\r
- }\r
-\r
- path.Add(start);\r
- IList<V> view = path.View(0, 1);\r
- while (adjacent.Count > 0)\r
- {\r
- V current = view[0];\r
- if (debug) Console.WriteLine("==> {0}", current);\r
- //Augment the path (randomly) until we return here and all edges\r
- while (adjacent.Count > 0)\r
- {\r
- if (debug) Console.WriteLine(" => {0}, {1}", current, path.Count);\r
- V next = adjacent.RemoveFirst();\r
- view.Add(next);\r
- if (debug) Console.WriteLine("EDGE: " + current + "->" + next);\r
- if (!edges[next].Remove(current))\r
- Console.WriteLine("Bad");\r
- current = next;\r
- adjacent = edges[current];\r
- }\r
- //When we get here, the view contains a closed path, i.e.\r
- //view[view.Count-1] == view[0] and we have followed all edges from view[0]\r
- //We slide forward along the rest of the path constructed so far and stop at the\r
- //first vertex with still unfollwed edges.\r
- while (view.Offset < path.Count - 1 && adjacent.Count == 0)\r
- {\r
- view.Slide(1, 1);\r
- if (debug) Console.WriteLine(" -> {0}, {1}", view[0], path.Count);\r
- adjacent = edges[view[0]];\r
- }\r
- }\r
- if (path.Count <= edges.Count)\r
- throw new ArgumentException("Graph was not connected");\r
- return path;\r
- }\r
-\r
- /// <summary>\r
- /// The purpose of this struct is to be able to create and add new,\r
- /// synthetic vertices to a graph. \r
- /// </summary>\r
- struct Vplus : IEquatable<Vplus>\r
- {\r
- internal readonly V vertex; internal readonly int id;\r
- static SCG.IEqualityComparer<V> vequalityComparer = EqualityComparer<V>.Default;\r
- internal Vplus(V v) { vertex = v; id = 0; }\r
- internal Vplus(int i) { vertex = default(V); id = i; }\r
- //We should override Equals and GetHashCode\r
-\r
- public override string ToString()\r
- { return id == 0 ? String.Format("real({0})", vertex) : String.Format("fake({0})", id); }\r
-\r
- public override bool Equals(object obj) { throw new NotImplementedException(); }\r
-\r
- public bool Equals(Vplus other) { return vequalityComparer.Equals(vertex, other.vertex) && id == other.id; }\r
-\r
- public override int GetHashCode() { return vequalityComparer.GetHashCode(vertex) + id; }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- /// <returns></returns>\r
- public IDirectedCollectionValue<V> ApproximateTSP2()\r
- {\r
- /* Construct a minimum spanning tree for the graph */\r
- V root;\r
- IGraph<V, E, W> tree = MinimumSpanningTree(out root);\r
-\r
- //Console.WriteLine("========= Matching of odd vertices of mst =========");\r
- ArrayList<V> oddvertices = new ArrayList<V>();\r
- foreach (V v in tree.Vertices())\r
- if (tree.Adjacent(v).Count % 2 != 0)\r
- oddvertices.Add(v);\r
-\r
- ICollectionValue<Edge<V, E>> matching = SubGraph(oddvertices).ApproximateMWPM();\r
-\r
- //Console.WriteLine("========= Fuse matching and tree =========");\r
- //We must split the edges of the matching with fake temporary vertices\r
- //since the matching and the tree may have common edges\r
-\r
- HashGraph<Vplus, E, W> fused = new HashGraph<Vplus, E, W>(weight);\r
- foreach (Edge<V, E> e in tree.Edges())\r
- fused.AddEdge(new Vplus(e.start), new Vplus(e.end), e.edgedata);\r
- int fakeid = 1;\r
- foreach (Edge<V, E> e in matching)\r
- {\r
- Vplus fakevertex = new Vplus(fakeid++);\r
- fused.AddEdge(new Vplus(e.start), fakevertex, e.edgedata);\r
- fused.AddEdge(fakevertex, new Vplus(e.end), e.edgedata);\r
- }\r
- fused.Print(Console.Out);\r
-\r
- //Console.WriteLine("========= Remove fake vertices and perform shortcuts =========");\r
- IList<Vplus> fusedtour = fused.EulerTour();\r
- HashSet<V> seen = new HashSet<V>();\r
- IList<V> tour = new ArrayList<V>();\r
-\r
- foreach (Vplus vplus in fused.EulerTour())\r
- {\r
- V v = vplus.vertex;\r
- if (vplus.id == 0 && !seen.FindOrAdd(ref v))\r
- tour.Add(v);\r
- }\r
- return tour;\r
- }\r
-\r
- /// <summary>\r
- /// (Refer to the litterature, Vazirani)\r
- /// \r
- /// (Describe: MST+Euler+shortcuts)\r
- /// </summary>\r
- /// <returns></returns>\r
- [UsedBy("testTSP")]\r
- public IDirectedCollectionValue<V> ApproximateTSP()\r
- {\r
- /* Construct a minimum spanning tree for the graph */\r
- V root;\r
- IGraph<V, E, W> tree = MinimumSpanningTree(out root);\r
-\r
- /* (Virtually) double all edges of MST and construct an Euler tour of the vertices*/\r
- LinkedList<V> tour = new LinkedList<V>();\r
- tour.Add(root);\r
- tour.Add(root);\r
- IList<V> view = tour.View(1, 1);\r
-\r
- Action<Edge<V, E>> onfollow = delegate(Edge<V, E> e)\r
- {\r
- //slide the view until it points to the last copy of e.start\r
- while (!view[0].Equals(e.start))\r
- view.Slide(1);\r
- //then insert two copies of e.end and slide the view one backwards\r
- view.InsertFirst(e.end);\r
- view.InsertFirst(e.end);\r
- view.Slide(1, 1);\r
- };\r
-\r
- tree.TraverseVertices(false, root, onfollow);\r
-\r
- /* Finally, slide along the Euler tour and shortcut by removing vertices already seen*/\r
- HashSet<V> seen = new HashSet<V>();\r
- view = tour.View(0, tour.Count);\r
- while (view.Offset < tour.Count - 1)\r
- {\r
- V v = view[0];\r
- if (seen.FindOrAdd(ref v))\r
- view.RemoveFirst();\r
- else\r
- view.Slide(1, view.Count - 1);\r
- }\r
- return tour;\r
- }\r
-\r
- public void Print(System.IO.TextWriter output)\r
- {\r
- output.WriteLine("Graph has {0} vertices, {1} edges, {2} components", graph.Count, edgecount, ComponentCount);\r
- foreach (KeyValuePair<V, HashDictionary<V, E>> p in graph)\r
- {\r
- output.Write(" {0} -> ", p.Key);\r
- foreach (KeyValuePair<V, E> p2 in p.Value)\r
- output.Write("{1} (data {2}), ", p.Key, p2.Key, p2.Value);\r
- output.WriteLine();\r
- }\r
- }\r
- }\r
-\r
-/// <summary>\r
-/// A weight on a graph that assigns the weight 1 to every edge.\r
-/// </summary>\r
-/// <typeparam name="E">(Ignored) type of edgedata</typeparam>\r
- class CountWeight<E> : IWeight<E, int>\r
- {\r
- public int Weight(E edgedata) { return 1; }\r
-\r
- public int Add(int w1, int w2) { return w1 + w2; }\r
- }\r
-\r
-/// <summary>\r
-/// A weight on an IGraph<V,int> that uses the value of the edgedata as the weight value.\r
-/// </summary>\r
- class IntWeight : IWeight<int, int>\r
- {\r
-\r
- public int Weight(int edgedata) { return edgedata; }\r
-\r
- public int Add(int w1, int w2) { return w1 + w2; }\r
-\r
- }\r
-\r
-/// <summary>\r
-/// A weight on an IGraph<V,double> that uses the value of the edgedata as the weight value.\r
-/// </summary>\r
- class DoubleWeight : IWeight<double, double>\r
- {\r
-\r
- public double Weight(double edgedata) { return edgedata; }\r
-\r
- public double Add(double w1, double w2) { return w1 + w2; }\r
-\r
- }\r
-\r
-/// <summary>\r
-/// Attribute used for marking which examples use a particuler graph method\r
-/// </summary>\r
- class UsedByAttribute : Attribute\r
- {\r
- string[] tests;\r
- internal UsedByAttribute(params string[] tests) { this.tests = tests; }\r
-\r
- public override string ToString()\r
- {\r
- System.Text.StringBuilder sb = new System.Text.StringBuilder();\r
- for (int i = 0; i < tests.Length; i++)\r
- {\r
- if (i > 0)\r
- sb.Append(", ");\r
- sb.Append(tests[i]);\r
- }\r
- return sb.ToString();\r
- }\r
- }\r
-\r
-/// <summary>\r
-/// Attribute for marking example methods with a description\r
-/// </summary>\r
- class ExampleDescriptionAttribute : Attribute\r
- {\r
- string text;\r
- internal ExampleDescriptionAttribute(string text) { this.text = text; }\r
-\r
- public override string ToString() { return text; }\r
- }\r
-\r
-/// <summary>\r
-/// A selection of test cases\r
-/// </summary>\r
- class Test\r
- {\r
- static SCG.IEnumerable<Edge<int, int>> Grid(int n)\r
- {\r
- Random ran = new Random(1717);\r
- for (int i = 1; i <= n; i++)\r
- {\r
- for (int j = 1; j <= n; j++)\r
- {\r
- yield return new Edge<int, int>(1000 * i + j, 1000 * (i + 1) + j, ran.Next(1, 100));\r
- yield return new Edge<int, int>(1000 * i + j, 1000 * i + j + 1, ran.Next(1, 100));\r
- }\r
- }\r
- }\r
-\r
- static SCG.IEnumerable<Edge<string, int>> Snake(int n)\r
- {\r
- for (int i = 1; i <= n; i++)\r
- {\r
- yield return new Edge<string, int>("U" + i, "L" + i, 1);\r
- yield return new Edge<string, int>("U" + i, "U" + (i + 1), i % 2 == 0 ? 1 : 10);\r
- yield return new Edge<string, int>("L" + i, "L" + (i + 1), i % 2 == 0 ? 10 : 1);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Create the edges of a forest of complete binary trees.\r
- /// </summary>\r
- /// <param name="treeCount">Number of trees</param>\r
- /// <param name="height">Height of trees</param>\r
- /// <returns></returns>\r
- static SCG.IEnumerable<Edge<string, int>> Forest(int treeCount, int height)\r
- {\r
- for (int i = 0; i < treeCount; i++)\r
- {\r
- IList<string> q = new ArrayList<string>();\r
- string root = String.Format("[{0}]", i);\r
- int lmax = height + root.Length;\r
- q.Add(root);\r
- while (!q.IsEmpty)\r
- {\r
- string s = q.Remove();\r
- string s2 = s + "L";\r
- if (s2.Length < lmax)\r
- q.Add(s2);\r
- yield return new Edge<string, int>(s, s2, 0);\r
- s2 = s + "R";\r
- if (s2.Length < lmax)\r
- q.Add(s2);\r
- yield return new Edge<string, int>(s, s2, 0);\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Create edges of a graph correspondingto a "wheel" shape: the ecnter and equidistant \r
- /// points around the perimeter. The edgedata and edge weights are the euclidean distances.\r
- /// </summary>\r
- /// <param name="complete">True means the graph will be complete, false that the graph\r
- /// will have edges for the spokes and between neighboring perimeter vetices.</param>\r
- /// <param name="n">The number of perimeter vertices, must be at least 3.</param>\r
- /// <returns>An enumerable with the edges</returns>\r
- static SCG.IEnumerable<Edge<string, double>> Wheel(bool complete, int n)\r
- {\r
- if (n < 3)\r
- throw new ArgumentOutOfRangeException("n must be at least 3");\r
- string center = "C";\r
- string[] perimeter = new string[n];\r
- for (int i = 0; i < n; i++)\r
- {\r
- perimeter[i] = "P" + i;\r
- yield return new Edge<string, double>(perimeter[i], center, 1);\r
- }\r
- if (complete)\r
- for (int i = 0; i < n - 1; i++)\r
- for (int j = i + 1; j < n; j++)\r
- yield return new Edge<string, double>(perimeter[i], perimeter[j], 2 * Math.Sin((j - i) * Math.PI / n));\r
- else\r
- {\r
- for (int i = 0; i < n - 1; i++)\r
- yield return new Edge<string, double>(perimeter[i], perimeter[i + 1], 2 * Math.Sin(Math.PI / n));\r
- yield return new Edge<string, double>(perimeter[n - 1], perimeter[0], 2 * Math.Sin(Math.PI / n));\r
- }\r
- }\r
-\r
-\r
- /// <summary>\r
- /// []\r
- /// </summary>\r
- [ExampleDescription("Basic BFS and DFS using TraverseVertices method")]\r
- static void test1()\r
- {\r
- IGraph<int, int, int> g = new HashGraph<int, int, int>(new CountWeight<int>(), Grid(3));\r
- Console.WriteLine("Edge count: {0}", g.Edges().Count);\r
- Console.WriteLine("BFS:");\r
- g.TraverseVertices(true, 1001, delegate(Edge<int, int> e) { Console.WriteLine(e); });\r
- Console.WriteLine("DFS:");\r
- g.TraverseVertices(false, 1001, delegate(Edge<int, int> e) { Console.WriteLine(e); });\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- [ExampleDescription("Component methods")]\r
- static void testCOMP()\r
- {\r
- IGraph<string, int, int> g = new HashGraph<string, int, int>(new CountWeight<int>(), Forest(2, 2));\r
- Console.WriteLine("Forest has: Vertices: {0}, Edges: {1}, Components: {2}", g.VertexCount, g.EdgeCount, g.ComponentCount);\r
- //g.Print(Console.Out);\r
- foreach (KeyValuePair<string, IGraph<string, int, int>> comp in g.Components())\r
- {\r
- Console.WriteLine("Component of {0}:", comp.Key);\r
- comp.Value.Print(Console.Out);\r
- }\r
- }\r
-\r
- //TODO: remove?\r
- static void test3()\r
- {\r
- HashGraph<int, int, int> g = new HashGraph<int, int, int>(new CountWeight<int>(), Grid(5));\r
- g.Print(Console.Out);\r
- //EdgeWeight<int, IntWeight> weight = delegate(int i) { return i; };\r
- Console.WriteLine("========= PFS accum =========");\r
- g.PriorityFirstTraverse(\r
- true,\r
- 2002,\r
- delegate(Edge<int, int> e, int d) { Console.WriteLine("Edge: {0}, at distance {1}", e, d); return true; });\r
- Console.WriteLine("========= PFS not accum =========");\r
- g.PriorityFirstTraverse(\r
- false,\r
- 2002,\r
- delegate(Edge<int, int> e, int d) { Console.WriteLine("Edge: {0}, at distance {1}", e, d); return true; });\r
- Console.WriteLine("========= MST =========");\r
- int root;\r
- g.MinimumSpanningTree(out root).Print(Console.Out);\r
- Console.WriteLine("========= SP =========");\r
- foreach (Edge<int, int> edge in g.ShortestPath(1001, 5005))\r
- Console.WriteLine(edge);\r
- }\r
-\r
- static void test4()\r
- {\r
- IGraph<string, int, int> g = new HashGraph<string, int, int>(new IntWeight(), Snake(5));\r
- Console.WriteLine("Edge count: {0}", g.Edges().Count);\r
- Console.WriteLine("========= PFS =========");\r
- g.PriorityFirstTraverse(false,\r
- "U3",\r
- delegate(Edge<string, int> e, int d) { Console.WriteLine("Edge: {0}, at distance {1}", e, d); return true; });\r
- Console.WriteLine("========= MST =========");\r
- string root;\r
- IGraph<string, int, int> mst = g.MinimumSpanningTree(out root);\r
- mst.Print(Console.Out);\r
- Console.WriteLine("DFS:");\r
- mst.TraverseVertices(false, root, delegate(Edge<string, int> e) { Console.WriteLine(e); });\r
- Console.WriteLine("ATSP:");\r
- int first = 0;\r
- foreach (string s in g.ApproximateTSP())\r
- {\r
- Console.Write((first++ == 0 ? "" : " -> ") + s);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// This example examines the two variants of a priority-first search:\r
- /// with accumulated weights, leading to shortest paths from start;\r
- /// with non-acumulated weights, leading to a minimum spanning tree.\r
- /// </summary>\r
- [ExampleDescription("Priority-first-search with and without accumulated weights")]\r
- static void testPFS()\r
- {\r
- IGraph<string, double, double> g = new HashGraph<string, double, double>(new DoubleWeight(), Wheel(false, 10));\r
- g.Print(Console.Out);\r
- Console.WriteLine("========= PFS non-accumulated weights (-> MST) =========");\r
- g.PriorityFirstTraverse(false,\r
- "P0",\r
- delegate(Edge<string, double> e, double d) { Console.WriteLine("Edge: {0}, at distance {1}", e, d); return true; });\r
- Console.WriteLine("========= PFS accumulated weights (-> Shortst paths from start) =========");\r
- g.PriorityFirstTraverse(true,\r
- "P0",\r
- delegate(Edge<string, double> e, double d) { Console.WriteLine("Edge: {0}, at distance {1}", e, d); return true; });\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// \r
- /// (Refer to Vazirani, or do that where ApproximateTSP is implemented)\r
- /// \r
- /// Note that the tour created is not optimal. [Describe why]\r
- /// </summary>\r
- [ExampleDescription("Approximate TSP")]\r
- static void testTSP()\r
- {\r
- IGraph<string, double, double> g = new HashGraph<string, double, double>(new DoubleWeight(), Wheel(true, 10));\r
- //g.Print(Console.Out);\r
- Console.WriteLine("========= MST =========");\r
- string root;\r
- IGraph<string, double, double> mst = g.MinimumSpanningTree(out root);\r
- mst.TraverseVertices(false,\r
- root,\r
- delegate(Edge<string, double> e) { Console.WriteLine("Edge: {0} -> {1}", e.start, e.end); });\r
- Console.WriteLine("========= Approximate TSP =========");\r
- int first = 0;\r
- foreach (string s in g.ApproximateTSP())\r
- {\r
- Console.Write((first++ == 0 ? "" : " -> ") + s);\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// \r
- /// (Refer to Vazirani, or do that where ApproximateTSP is implemented)\r
- /// \r
- /// Note that the tour created is not optimal. [Describe why]\r
- /// </summary>\r
- [ExampleDescription("Approximate TSP2")]\r
- static void testTSP2()\r
- {\r
- HashGraph<string, double, double> g = new HashGraph<string, double, double>(new DoubleWeight(), Wheel(true, 20));\r
-\r
- foreach (string s in g.ApproximateTSP2())\r
- Console.WriteLine("# " + s);\r
- //g.Print(Console.Out);\r
- /*\r
- Console.WriteLine("========= MST =========");\r
- string root;\r
- IGraph<string, double, double> mst = g.MinimumSpanningTree(out root);\r
- mst.TraverseVertices(false,\r
- root,\r
- delegate(Edge<string, double> e) { Console.WriteLine("Edge: {0} -> {1}", e.start, e.end); });\r
- ArrayList<string> oddvertices = new ArrayList<string>();\r
- foreach (string v in mst.Vertices())\r
- if (mst.Adjacent(v).Count % 2 != 0)\r
- oddvertices.Add(v);\r
-\r
- Console.WriteLine("========= Matching of odd vertices of mst =========");\r
- ICollectionValue<Edge<string, double>> matching = g.SubGraph(oddvertices).ApproximateMWPM();\r
-\r
- Console.WriteLine("========= Add matching to mst =========");\r
- //We must split the edges of the matchin with fake temporary vertices\r
- //(For a general vertex type, we would have to augment it to Pair<V,int> \r
- int fake = 0;\r
- foreach (Edge<string, double> e in matching)\r
- {\r
- string fakevertex = "_" + (fake++);\r
- mst.AddEdge(e.start, fakevertex, 0);\r
- mst.AddEdge(fakevertex, e.end, e.edgedata);\r
- }\r
- //mst.Print(Console.Out);\r
-\r
- IList<string> tour = mst.EulerTour(), view = tour.View(1, tour.Count - 1);\r
-\r
- //Remove fake vertices\r
- while (view.Count > 0)\r
- if (view[0].StartsWith("_"))\r
- view.RemoveFirst();\r
- else\r
- view.Slide(1, view.Count - 1);\r
-\r
- Console.WriteLine("========= Approximate TSP 2 =========");\r
- //Short cut\r
- view = tour.View(1, tour.Count - 1);\r
- HashSet<string> seen = new HashSet<string>();\r
-\r
- while (view.Count > 0)\r
- {\r
- string s = view[0];\r
- if (seen.FindOrAdd(ref s))\r
- view.RemoveFirst();\r
- else\r
- view.Slide(1, view.Count - 1);\r
- }\r
-\r
- foreach (string s in tour)\r
- Console.WriteLine(". " + s);*/\r
- }\r
-\r
- /// <summary>\r
- /// \r
- /// </summary>\r
- static void testEuler()\r
- {\r
- HashGraph<string, double, double> g = new HashGraph<string, double, double>(new DoubleWeight(), Wheel(true, 6));\r
- foreach (string s in g.EulerTour())\r
- Console.Write(s + " ");\r
- Console.WriteLine();\r
- }\r
-\r
- /// <summary>\r
- /// An articulation point in a graph is a vertex, whose removal will \r
- /// disconnect the graph (or its component). This example uses the \r
- /// extended DepthFirstSearch method to compute articulation points\r
- /// of a graph.\r
- /// \r
- /// (Refer to Sedgewick. )\r
- /// \r
- /// Each vertex is given an index in traversal order. \r
- /// For each vertex, we compute the least index reachable by going downwards\r
- /// in the DFS tree and then following a single non-dfs edge. \r
- /// \r
- /// Since we cannot store the DFS indices in the vertices without changing the \r
- /// (assumed given) vertex type, V, we remember the indices in a V->int \r
- /// hash dictionary, index. The "least reachable" values are then stored in an \r
- /// array keyed by the index.\r
- /// \r
- /// The root of the search is an articulation point if it has more than one\r
- /// outgoing DFS edges. Other articulation points are non-root vertices, va,\r
- /// with an outgoing DFS edge, where the the least reachable index of the other \r
- /// vertex is greater or equal to the index of va. \r
- /// </summary>\r
- [ExampleDescription("Using the advanced DFS to compute articulation points")]\r
- static void testDFS()\r
- {\r
- HashGraph<string, int, int> g = new HashGraph<string, int, int>(new IntWeight());\r
- g.AddEdge("A", "B", 0);\r
- g.AddEdge("A", "E", 0);\r
- g.AddEdge("B", "E", 0);\r
- g.AddEdge("B", "C", 0);\r
- g.AddEdge("B", "H", 0);\r
- g.AddEdge("H", "I", 0);\r
- g.AddEdge("B", "D", 0);\r
- g.AddEdge("C", "D", 0);\r
- g.AddEdge("C", "F", 0);\r
- g.AddEdge("C", "G", 0);\r
- g.AddEdge("F", "G", 0);\r
-\r
- HashDictionary<string, int> index = new HashDictionary<string, int>();\r
- int[] leastIndexReachableFrom = new int[g.VertexCount];\r
- int nextindex = 0;\r
- int outgoingFromRoot = 0;\r
- Action<string> beforevertex = delegate(string v)\r
- {\r
- int i = (index[v] = nextindex++);\r
- leastIndexReachableFrom[i] = i;\r
- };\r
- Action<string> aftervertex = delegate(string v)\r
- {\r
- int i = index[v];\r
- if (i == 0 && outgoingFromRoot > 1)\r
- Console.WriteLine("Articulation point: {0} ({1}>1 outgoing DFS edges from start)",\r
- v, outgoingFromRoot);\r
- };\r
- Action<Edge<string, int>> onfollow = delegate(Edge<string, int> e)\r
- {\r
- };\r
- Action<Edge<string, int>> onfollowed = delegate(Edge<string, int> e)\r
- {\r
- int startind = index[e.start], endind = index[e.end];\r
- if (startind == 0)\r
- outgoingFromRoot++;\r
- else\r
- {\r
- int leastIndexReachable = leastIndexReachableFrom[endind];\r
- if (leastIndexReachable >= startind)\r
- Console.WriteLine("Articulation point: {0} (least index reachable via {3} is {1} >= this index {2})",\r
- e.start, leastIndexReachable, startind, e);\r
- if (leastIndexReachableFrom[startind] > leastIndexReachable)\r
- leastIndexReachableFrom[startind] = leastIndexReachable;\r
- }\r
- };\r
- Action<Edge<string, int>> onnotfollowed = delegate(Edge<string, int> e)\r
- {\r
- int startind = index[e.start], endind = index[e.end];\r
- if (leastIndexReachableFrom[startind] > endind)\r
- leastIndexReachableFrom[startind] = endind;\r
- };\r
-\r
- string root = "C";\r
- g.DepthFirstSearch(root, beforevertex, aftervertex, onfollow, onfollowed, onnotfollowed);\r
- Console.WriteLine("Edges:");\r
- foreach (Edge<string, int> e in g.Edges())\r
- Console.WriteLine("/ {0}", e);\r
- }\r
-\r
- static void Main(String[] args)\r
- {\r
- if (args.Length != 1)\r
- {\r
- Console.WriteLine("Usage: Graph.exe testno");\r
- System.Reflection.MethodInfo[] mis = typeof(Test).GetMethods(\r
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);\r
- foreach (System.Reflection.MethodInfo mi in mis)\r
- {\r
- if (mi.GetParameters().Length == 0 && mi.ReturnType == typeof(void) && mi.Name.StartsWith("test"))\r
- {\r
- object[] attrs = mi.GetCustomAttributes(typeof(ExampleDescriptionAttribute), false);\r
- Console.WriteLine(" {0} : {1}", mi.Name.Substring(4), attrs.Length > 0 ? attrs[0] : "");\r
- }\r
- }\r
- }\r
- else\r
- {\r
- string testMethodName = String.Format("test{0}", args[0]);\r
-\r
- System.Reflection.MethodInfo mi = typeof(Test).GetMethod(testMethodName,\r
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);\r
-\r
- if (mi == null)\r
- Console.WriteLine("No such testmethod, {0}", testMethodName);\r
- else\r
- {\r
- object[] attrs = mi.GetCustomAttributes(typeof(ExampleDescriptionAttribute), false);\r
- Console.WriteLine("============================== {0}() ==================================", testMethodName);\r
- Console.WriteLine("Description: {0}", attrs.Length > 0 ? attrs[0] : "None");\r
- Console.WriteLine("===========================================================================");\r
- mi.Invoke(null, null);\r
- }\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: hash codes, good and bad 2005-02-28\r
-\r
-// Compile with \r
-// csc /r:C5.dll HashCodes.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace MyHashCodesTest {\r
- class MyTest {\r
- public static void Main(String[] args) {\r
- int count = int.Parse(args[0]); \r
- {\r
- Console.Write("Good hash function: ");\r
- Timer t = new Timer();\r
- HashSet<int> good \r
- = MakeRandom(count, new GoodIntegerEqualityComparer());\r
- Console.WriteLine("({0} sec, {1} items)", t.Check(), good.Count);\r
- ISortedDictionary<int,int> bcd = good.BucketCostDistribution();\r
- foreach (KeyValuePair<int,int> entry in bcd) \r
- Console.WriteLine("{0,7} bucket(s) with cost {1,5}", \r
- entry.Value, entry.Key);\r
- }\r
- {\r
- Console.Write("Bad hash function: ");\r
- Timer t = new Timer();\r
- HashSet<int> bad = MakeRandom(count, new BadIntegerEqualityComparer());\r
- Console.WriteLine("({0} sec, {1} items)", t.Check(), bad.Count);\r
- ISortedDictionary<int,int> bcd = bad.BucketCostDistribution();\r
- foreach (KeyValuePair<int,int> entry in bcd) \r
- Console.WriteLine("{0,7} bucket(s) with cost {1,5}", \r
- entry.Value, entry.Key);\r
- }\r
- }\r
-\r
- private static readonly C5Random rnd = new C5Random();\r
- \r
- public static HashSet<int> MakeRandom(int count, \r
- SCG.IEqualityComparer<int> eqc) {\r
- HashSet<int> res;\r
- if (eqc == null) \r
- res = new HashSet<int>();\r
- else\r
- res = new HashSet<int>(eqc);\r
- for (int i=0; i<count; i++)\r
- res.Add(rnd.Next(1000000)); \r
- return res;\r
- }\r
-\r
- private class BadIntegerEqualityComparer : SCG.IEqualityComparer<int> {\r
- public bool Equals(int i1, int i2) {\r
- return i1 == i2;\r
- }\r
- public int GetHashCode(int i) {\r
- return i % 7;\r
- }\r
- }\r
-\r
- private class GoodIntegerEqualityComparer : SCG.IEqualityComparer<int> {\r
- public bool Equals(int i1, int i2) {\r
- return i1 == i2;\r
- }\r
- public int GetHashCode(int i) {\r
- return i;\r
- }\r
- }\r
- }\r
-\r
- // Crude timing utility\r
- \r
- public class Timer {\r
- private DateTime start;\r
- \r
- public Timer() {\r
- start = DateTime.Now;\r
- }\r
- \r
- public double Check() {\r
- TimeSpan dur = DateTime.Now - start;\r
- return dur.TotalSeconds;\r
- }\r
- }\r
-}\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: job queue 2004-11-22\r
-\r
-// Compile with \r
-// csc /r:C5.dll Anagrams.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-class MyJobQueueTest {\r
- public static void Main(String[] args) {\r
- JobQueue jq = new JobQueue();\r
- // One user submits three jobs at time=27\r
- Rid rid1 = jq.Submit(new Ip("62.150.83.11"), 27),\r
- rid2 = jq.Submit(new Ip("62.150.83.11"), 27),\r
- rid3 = jq.Submit(new Ip("62.150.83.11"), 27);\r
- // One job is executed\r
- jq.ExecuteOne();\r
- // Another user submits two jobs at time=55\r
- Rid rid4 = jq.Submit(new Ip("130.225.17.5"), 55),\r
- rid5 = jq.Submit(new Ip("130.225.17.5"), 55);\r
- // One more job is executed\r
- jq.ExecuteOne();\r
- // The first user tries to cancel his first and last job\r
- jq.Cancel(rid1);\r
- jq.Cancel(rid3);\r
- // The remaining jobs are executed\r
- while (jq.ExecuteOne() != null) { } \r
- }\r
-}\r
-\r
-class JobQueue {\r
- private readonly IPriorityQueue<Job> jobQueue;\r
- private readonly IDictionary<Rid,IPriorityQueueHandle<Job>> jobs;\r
- private readonly HashBag<Ip> userJobs;\r
-\r
- public JobQueue() {\r
- this.jobQueue = new IntervalHeap<Job>();\r
- this.jobs = new HashDictionary<Rid,IPriorityQueueHandle<Job>>();\r
- this.userJobs = new HashBag<Ip>();\r
- }\r
-\r
- public Rid Submit(Ip ip, int time) {\r
- int jobCount = userJobs.ContainsCount(ip);\r
- Rid rid = new Rid();\r
- Job job = new Job(rid, ip, time + 60 * jobCount);\r
- IPriorityQueueHandle<Job> h = null;\r
- jobQueue.Add(ref h, job);\r
- userJobs.Add(ip);\r
- jobs.Add(rid, h);\r
- Console.WriteLine("Submitted {0}", job); \r
- return rid;\r
- }\r
-\r
- public Job ExecuteOne() {\r
- if (!jobQueue.IsEmpty) {\r
- Job job = jobQueue.DeleteMin();\r
- userJobs.Remove(job.ip);\r
- jobs.Remove(job.rid);\r
- Console.WriteLine("Executed {0}", job); \r
- return job;\r
- } else\r
- return null;\r
- }\r
-\r
- public void Cancel(Rid rid) {\r
- IPriorityQueueHandle<Job> h;\r
- if (jobs.Remove(rid, out h)) {\r
- Job job = jobQueue.Delete(h);\r
- userJobs.Remove(job.ip);\r
- Console.WriteLine("Cancelled {0}", job);\r
- }\r
- }\r
-}\r
-\r
-class Job : IComparable<Job> {\r
- public readonly Rid rid;\r
- public readonly Ip ip;\r
- public readonly int time;\r
-\r
- public Job(Rid rid, Ip ip, int time) {\r
- this.rid = rid;\r
- this.ip = ip;\r
- this.time = time;\r
- }\r
-\r
- public int CompareTo(Job that) {\r
- return this.time - that.time;\r
- }\r
-\r
- public override String ToString() {\r
- return rid.ToString();\r
- }\r
-}\r
-\r
-class Rid { \r
- private readonly int ridNumber;\r
- private static int nextRid = 1;\r
- public Rid() {\r
- ridNumber = nextRid++;\r
- }\r
- public override String ToString() {\r
- return "rid=" + ridNumber;\r
- }\r
-}\r
-\r
-class Ip { \r
- public readonly String ipString;\r
-\r
- public Ip(String ipString) {\r
- this.ipString = ipString;\r
- }\r
-\r
- public override int GetHashCode() {\r
- return ipString.GetHashCode();\r
- }\r
-\r
- public override bool Equals(Object that) {\r
- return \r
- that != null \r
- && that is Ip \r
- && this.ipString.Equals(((Ip)that).ipString);\r
- }\r
-}\r
- \r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: Keyword recognition 2004-12-20\r
-\r
-// Compile with \r
-// csc /r:C5.dll KeywordRecognition.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace KeywordRecognition {\r
-\r
-class KeywordRecognition {\r
- // Array of 77 keywords:\r
-\r
- static readonly String[] keywordArray = \r
- { "abstract", "as", "base", "bool", "break", "byte", "case", "catch",\r
- "char", "checked", "class", "const", "continue", "decimal", "default",\r
- "delegate", "do", "double", "else", "enum", "event", "explicit",\r
- "extern", "false", "finally", "fixed", "float", "for", "foreach",\r
- "goto", "if", "implicit", "in", "int", "interface", "internal", "is",\r
- "lock", "long", "namespace", "new", "null", "object", "operator",\r
- "out", "override", "params", "private", "protected", "public",\r
- "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof",\r
- "stackalloc", "static", "string", "struct", "switch", "this", "throw",\r
- "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe",\r
- "ushort", "using", "virtual", "void", "volatile", "while" };\r
- \r
- private static readonly ICollection<String> kw1;\r
-\r
- private static readonly ICollection<String> kw2;\r
-\r
- private static readonly ICollection<String> kw3;\r
-\r
- private static readonly SCG.IDictionary<String,bool> kw4 = \r
- new SCG.Dictionary<String,bool>();\r
-\r
-\r
- class SC : SCG.IComparer<string>\r
- {\r
- public int Compare(string a, string b)\r
- {\r
- return StringComparer.InvariantCulture.Compare(a,b);\r
- }\r
- }\r
-\r
- class SH : SCG.IEqualityComparer<string>\r
- {\r
- public int GetHashCode(string item)\r
- {\r
- return item.GetHashCode();\r
- }\r
-\r
- public bool Equals(string i1, string i2)\r
- {\r
- return i1 == null ? i2 == null : i1.Equals(i2,StringComparison.InvariantCulture);\r
- }\r
- }\r
-\r
- static KeywordRecognition() { \r
- kw1 = new HashSet<String>();\r
- kw1.AddAll<string>(keywordArray); \r
- kw2 = new TreeSet<String>(new SC());\r
- kw2.AddAll<string>(keywordArray);\r
- kw3 = new SortedArray<String>(new SC());\r
- kw3.AddAll<string>(keywordArray);\r
- kw4 = new SCG.Dictionary<String,bool>();\r
- foreach (String keyword in keywordArray) \r
- kw4.Add(keyword, false);\r
- }\r
-\r
- public static bool IsKeyword1(String s) {\r
- return kw1.Contains(s);\r
- }\r
-\r
- public static bool IsKeyword2(String s) {\r
- return kw2.Contains(s);\r
- }\r
-\r
- public static bool IsKeyword3(String s) {\r
- return kw3.Contains(s);\r
- }\r
-\r
- public static bool IsKeyword4(String s) { \r
- return kw4.ContainsKey(s); \r
- }\r
-\r
- public static bool IsKeyword5(String s) { \r
- return Array.BinarySearch(keywordArray, s) >= 0; \r
- }\r
-\r
- public static void Main(String[] args) {\r
- if (args.Length != 2) \r
- Console.WriteLine("Usage: KeywordRecognition <iterations> <word>\n");\r
- else {\r
- int count = int.Parse(args[0]);\r
- String id = args[1];\r
-\r
- {\r
- Console.Write("HashSet.Contains ");\r
- Timer t = new Timer();\r
- for (int i=0; i<count; i++)\r
- IsKeyword1(id);\r
- Console.WriteLine(t.Check()); \r
- }\r
-\r
- {\r
- Console.Write("TreeSet.Contains ");\r
- Timer t = new Timer();\r
- for (int i=0; i<count; i++)\r
- IsKeyword2(id);\r
- Console.WriteLine(t.Check()); \r
- }\r
-\r
- {\r
- Console.Write("SortedArray.Contains ");\r
- Timer t = new Timer();\r
- for (int i=0; i<count; i++)\r
- IsKeyword3(id);\r
- Console.WriteLine(t.Check()); \r
- }\r
-\r
- {\r
- Console.Write("SCG.Dictionary.ContainsKey ");\r
- Timer t = new Timer();\r
- for (int i=0; i<count; i++)\r
- IsKeyword4(id);\r
- Console.WriteLine(t.Check()); \r
- }\r
-\r
- {\r
- Console.Write("Array.BinarySearch ");\r
- Timer t = new Timer();\r
- for (int i=0; i<count; i++)\r
- IsKeyword5(id);\r
- Console.WriteLine(t.Check()); \r
- }\r
- }\r
- }\r
-}\r
-\r
-// Crude timing utility ----------------------------------------\r
- \r
-public class Timer {\r
- private DateTime start;\r
-\r
- public Timer() {\r
- start = DateTime.Now;\r
- }\r
-\r
- public double Check() {\r
- TimeSpan dur = DateTime.Now - start;\r
- return dur.TotalSeconds;\r
- }\r
-}\r
-\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: ListPatterns.cs for pattern chapter\r
-\r
-// Compile with \r
-// csc /r:C5.dll ListPatterns.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace ListPatterns {\r
- class ListPatterns {\r
- public static void Main(String[] args) {\r
- IList<int> list = new ArrayList<int>();\r
- list.AddAll(new int[] { 23, 29, 31, 37, 41, 43, 47, 53 });\r
- // Reversing and swapping\r
- Console.WriteLine(list);\r
- list.Reverse();\r
- Console.WriteLine(list);\r
- ReverseInterval(list, 2, 3);\r
- Console.WriteLine(list);\r
- SwapInitialFinal(list, 2);\r
- Console.WriteLine(list);\r
- // Clearing all or part of list\r
- list.CollectionCleared \r
- += delegate(Object c, ClearedEventArgs eargs) {\r
- ClearedRangeEventArgs ceargs = eargs as ClearedRangeEventArgs;\r
- if (ceargs != null) \r
- Console.WriteLine("Cleared [{0}..{1}]", \r
- ceargs.Start, ceargs.Start+ceargs.Count-1);\r
- };\r
- RemoveSublist1(list, 1, 2);\r
- Console.WriteLine(list);\r
- RemoveSublist2(list, 1, 2);\r
- Console.WriteLine(list);\r
- RemoveTail1(list, 3);\r
- Console.WriteLine(list);\r
- RemoveTail2(list, 2);\r
- Console.WriteLine(list);\r
- }\r
-\r
- // Reverse list[i..i+n-1]\r
-\r
- public static void ReverseInterval<T>(IList<T> list, int i, int n) {\r
- list.View(i,n).Reverse();\r
- }\r
-\r
- // Swap list[0..i-1] with list[i..Count-1]\r
-\r
- public static void SwapInitialFinal<T>(IList<T> list, int i) {\r
- list.View(0,i).Reverse();\r
- list.View(i,list.Count-i).Reverse();\r
- list.Reverse();\r
- }\r
-\r
- // Remove sublist of a list\r
-\r
- public static void RemoveSublist1<T>(IList<T> list, int i, int n) {\r
- list.RemoveInterval(i, n);\r
- }\r
-\r
- public static void RemoveSublist2<T>(IList<T> list, int i, int n) {\r
- list.View(i, n). Clear();\r
- }\r
-\r
-\r
- // Remove tail of a list\r
-\r
- public static void RemoveTail1<T>(IList<T> list, int i) {\r
- list.RemoveInterval(i, list.Count-i);\r
- }\r
-\r
- public static void RemoveTail2<T>(IList<T> list, int i) {\r
- list.View(i, list.Count-i).Clear();\r
- }\r
-\r
- // Pattern for finding and using first (leftmost) x in list\r
-\r
- private static void PatFirst<T>(IList<T> list, T x) { \r
- int j = list.IndexOf(x);\r
- if (j >= 0) { \r
- // x is a position j in list\r
- } else {\r
- // x is not in list\r
- }\r
- }\r
-\r
- // Pattern for finding and using last (rightmost) x in list\r
-\r
- private static void PatLast<T>(IList<T> list, T x) { \r
- int j = list.LastIndexOf(x);\r
- if (j >= 0) { \r
- // x is at position j in list\r
- } else {\r
- // x is not in list\r
- }\r
- }\r
-\r
- // Pattern for finding and using first (leftmost) x in list[i..i+n-1]\r
-\r
- private static void PatFirstSublist<T>(IList<T> list, T x, int i, int n) { \r
- int j = list.View(i,n).IndexOf(x);\r
- if (j >= 0) { \r
- // x is at position j+i in list\r
- } else {\r
- // x is not in list[i..i+n-1]\r
- }\r
- }\r
-\r
- // Pattern for finding and using last (rightmost) x in list[i..i+n-1]\r
-\r
- private static void PatLastSublist<T>(IList<T> list, T x, int i, int n) { \r
- int j = list.View(i,n).LastIndexOf(x);\r
- if (j >= 0) { \r
- // x is at position j+i in list\r
- } else {\r
- // x is not in list[i..i+n-1]\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-// C5 example: locking 2005-11-07\r
-\r
-// Compile with \r
-// csc /r:C5.dll Locking.cs \r
-\r
-using System;\r
-using System.Threading;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace Locking {\r
- class Locking {\r
- static ArrayList<int> coll = new ArrayList<int>();\r
- // static SCG.List<int> coll = new SCG.List<int>();\r
- static readonly int count = 1000;\r
-\r
- public static void Main(String[] args) {\r
- Console.WriteLine("Adding and removing without locking:");\r
- RunTwoThreads(delegate { AddAndRemove(15000); });\r
- Console.WriteLine("coll has {0} items, should be 0", coll.Count);\r
-\r
- coll = new ArrayList<int>();\r
- Console.WriteLine("Adding and removing with locking:");\r
- RunTwoThreads(delegate { SafeAddAndRemove(15000); });\r
- Console.WriteLine("coll has {0} items, should be 0", coll.Count);\r
-\r
- Console.WriteLine("Moving items without locking:");\r
- ArrayList<int> from, to;\r
- from = new ArrayList<int>();\r
- to = new ArrayList<int>();\r
- for (int i=0; i<count; i++) \r
- from.Add(i);\r
- RunTwoThreads(delegate { while (!from.IsEmpty) Move(from, to); });\r
- Console.WriteLine("coll has {0} items, should be {1}", to.Count, count);\r
-\r
- Console.WriteLine("Moving items with locking:");\r
- from = new ArrayList<int>();\r
- to = new ArrayList<int>();\r
- for (int i=0; i<count; i++) \r
- from.Add(i);\r
- RunTwoThreads(delegate { while (!from.IsEmpty) SafeMove(from, to); });\r
- Console.WriteLine("coll has {0} items, should be {1}", to.Count, count);\r
- }\r
-\r
- public static void RunTwoThreads(Act run) {\r
- Thread t1 = new Thread(new ThreadStart(run)),\r
- t2 = new Thread(new ThreadStart(run));\r
- t1.Start(); t2.Start();\r
- t1.Join(); t2.Join();\r
- }\r
-\r
- // Concurrently adding to and removing from an arraylist\r
-\r
- public static void AddAndRemove(int count) {\r
- for (int i=0; i<count; i++) \r
- coll.Add(i);\r
- for (int i=0; i<count; i++)\r
- coll.Remove(i);\r
- }\r
-\r
- private static readonly Object sync = new Object();\r
-\r
- public static void SafeAddAndRemove(int count) {\r
- for (int i=0; i<count; i++) \r
- lock (sync)\r
- coll.Add(i);\r
- for (int i=0; i<count; i++)\r
- lock (sync)\r
- coll.Remove(i);\r
- }\r
-\r
- public static void SafeAdd<T>(IExtensible<T> coll, T x) { \r
- lock (sync) {\r
- coll.Add(x);\r
- }\r
- }\r
-\r
- public static void Move<T>(ICollection<T> from, ICollection<T> to) { \r
- if (!from.IsEmpty) { \r
- T x = from.Choose();\r
- Thread.Sleep(0); // yield processor to other threads\r
- from.Remove(x);\r
- to.Add(x);\r
- }\r
- }\r
- \r
- public static void SafeMove<T>(ICollection<T> from, ICollection<T> to) { \r
- lock (sync) \r
- if (!from.IsEmpty) { \r
- T x = from.Choose();\r
- Thread.Sleep(0); // yield processor to other threads\r
- from.Remove(x);\r
- to.Add(x);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-# Makefile for C5 book examples\r
-\r
-USERGUIDEFILES= Anagrams.cs Antipatterns.cs CollectionSanity.cs EventPatterns.cs \\r
- Fileindex.cs GConvexHull.cs GNfaToDfa.cs GettingStarted.cs \\r
- Graph.cs Graphcopy.cs HashCodes.cs Jobqueue.cs \\r
- KeywordRecognition.cs ListPatterns.cs ListPatterns.cs \\r
- Locking.cs MultiDictionary.cs PointLocation.cs \\r
- RandomSelection.cs ReadOnlyPatterns.cs Sets.cs \\r
- SortedIterationPatterns.cs SortedIterationPatterns.cs \\r
- SortingPermutation.cs Toposort.cs ViewPatterns.cs WrappedArray.cs\r
-\r
-all: c5examples.zip\r
-\r
-c5examples.zip: ${USERGUIDEFILES}\r
- rm -f C5.examples.zip\r
- zip C5.examples.zip ${USERGUIDEFILES}\r
-\r
-clean:\r
- rm -f C5.examples.zip\r
- rm -f *.dot\r
- rm -f *.exe\r
- rm -f *.ps\r
- rm -f *.eps\r
-\r
-.SUFFIXES :\r
-.SUFFIXES : .cs\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace MultiCollection\r
-{\r
- class BasicCollectionValue<T> : CollectionValueBase<T>, ICollectionValue<T>\r
- {\r
- SCG.IEnumerable<T> enumerable;\r
- Fun<T> chooser;\r
- int count;\r
- //TODO: add delegate for checking validity!\r
-\r
- public BasicCollectionValue(SCG.IEnumerable<T> e, Fun<T> chooser, int c) { enumerable = e; count = c; this.chooser = chooser; }\r
-\r
- public override int Count { get { return count; } }\r
-\r
- public override Speed CountSpeed { get { return Speed.Constant; } }\r
-\r
- public override bool IsEmpty { get { return count == 0; } }\r
-\r
- public override T Choose() { return chooser(); }\r
-\r
- public override System.Collections.Generic.IEnumerator<T> GetEnumerator()\r
- {\r
- return enumerable.GetEnumerator();\r
- }\r
- }\r
-\r
- interface IMultiCollection<K, V>\r
- {\r
- SCG.IEqualityComparer<K> KeyEqualityComparer { get;}\r
- SCG.IEqualityComparer<V> ValueEqualityComparer { get;}\r
- bool Add(K k, V v);\r
- bool Remove(K k, V v);\r
- ICollectionValue<V> this[K k] { get;}\r
- ICollectionValue<K> Keys { get;}\r
- SCG.IEnumerable<V> Values { get;}\r
-\r
- }\r
-\r
- class BasicMultiCollection<K, V, W, U> : IMultiCollection<K, V>//: IDictionary<K, W>\r
- where W : ICollection<V>, new()\r
- where U : IDictionary<K, W>, new()\r
- {\r
- U dict = new U();\r
-\r
- public SCG.IEqualityComparer<K> KeyEqualityComparer { get { return EqualityComparer<K>.Default; } }\r
-\r
- public SCG.IEqualityComparer<V> ValueEqualityComparer { get { return EqualityComparer<V>.Default; } } //TODO: depends on W!\r
-\r
- public bool Add(K k, V v)\r
- {\r
- W w;\r
- if (!dict.Find(k, out w)) \r
- dict.Add(k,w = new W());\r
- return w.Add(v);\r
- }\r
-\r
- public bool Remove(K k, V v)\r
- {\r
- W w;\r
- if (dict.Find(k, out w) && w.Remove(v))\r
- {\r
- if (w.Count == 0)\r
- dict.Remove(k);\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- public ICollectionValue<V> this[K k] { get { return dict[k]; } }\r
-\r
- public ICollectionValue<K> Keys { get { return dict.Keys; } }\r
-\r
- public SCG.IEnumerable<V> Values\r
- {\r
- get\r
- {\r
- foreach (W w in dict.Values)\r
- foreach (V v in w)\r
- yield return v;\r
- }\r
- }\r
- }\r
-\r
- class WordIndex : BasicMultiCollection<string,int,HashSet<int>,HashDictionary<string,HashSet<int>>>\r
- {\r
- }\r
-\r
- class MyTest\r
- {\r
- public static void Main(String[] args)\r
- {\r
- WordIndex wi = new WordIndex();\r
- wi.Add("ja", 2);\r
- wi.Add("nej", 4);\r
- wi.Add("ja", 7);\r
- foreach (string s in wi.Keys)\r
- {\r
- Console.WriteLine(s + " -->");\r
- foreach (int line in wi[s])\r
- {\r
- Console.WriteLine(" " + line);\r
- }\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
-\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: 2006-01-29\r
-\r
-// Compile with \r
-// csc /r:C5.dll MultiDictionary.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace MultiDictionaries {\r
-\r
- using MultiDictionary2;\r
-\r
- class MyTest {\r
- public static void Main(String[] args) {\r
- MultiHashDictionary<int,String> mdict = new MultiHashDictionary<int,String>();\r
- mdict.Add(2, "to");\r
- mdict.Add(2, "deux");\r
- mdict.Add(2, "two");\r
- mdict.Add(20, "tyve");\r
- mdict.Add(20, "twenty");\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- Console.WriteLine("mdict.Count (keys) is {0}", \r
- ((IDictionary<int,ICollection<String>>)mdict).Count);\r
- Console.WriteLine("mdict[2].Count is {0}", mdict[2].Count);\r
- mdict.Remove(20, "tyve");\r
- mdict.Remove(20, "twenty");\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- ICollection<String> zwei = new HashSet<String>();\r
- zwei.Add("zwei");\r
- mdict[2] = zwei;\r
- mdict[-2] = zwei;\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- zwei.Add("kaksi");\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- ICollection<String> empty = new HashSet<String>();\r
- mdict[0] = empty;\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- Console.WriteLine("mdict contains key 0: {0}", mdict.Contains(0));\r
- mdict.Remove(-2);\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- zwei.Remove("kaksi");\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- zwei.Clear();\r
- Console.WriteLine(mdict);\r
- Console.WriteLine("mdict.Count is {0}", mdict.Count);\r
- }\r
- }\r
-}\r
-\r
-namespace MultiDictionary1 {\r
- // Here we implement a multivalued dictionary as a hash dictionary\r
- // from keys to value collections. The value collections may have set\r
- // or bag semantics.\r
- \r
- // The value collections are externally modifiable (as in Peter\r
- // Golde's PowerCollections library), and therefore:\r
- //\r
- // * A value collection associated with a key may be null or\r
- // non-empty. Hence for correct semantics, the Contains(k) method\r
- // must check that the value collection associated with a key is\r
- // non-null and non-empty.\r
- // \r
- // * A value collection may be shared between two or more keys.\r
- //\r
-\r
- // A C5 hash dictionary each of whose keys map to a collection of values.\r
-\r
- public class MultiHashDictionary<K,V> : HashDictionary<K, ICollection<V>> {\r
-\r
- // Return total count of values associated with keys. This basic\r
- // implementation simply sums over all value collections, and so\r
- // is a linear-time operation in the total number of values. \r
-\r
- public new virtual int Count { \r
- get { \r
- int count = 0;\r
- foreach (KeyValuePair<K,ICollection<V>> entry in this) \r
- if (entry.Value != null)\r
- count += entry.Value.Count;\r
- return count;\r
- }\r
- }\r
-\r
- public override Speed CountSpeed {\r
- get { return Speed.Linear; }\r
- }\r
-\r
- // Add a (key,value) pair\r
-\r
- public virtual void Add(K k, V v) {\r
- ICollection<V> values;\r
- if (!base.Find(k, out values) || values == null) {\r
- values = new HashSet<V>();\r
- Add(k, values);\r
- } \r
- values.Add(v);\r
- }\r
-\r
- // Remove a single (key,value) pair, if present; return true if\r
- // anything was removed, else false\r
-\r
- public virtual bool Remove(K k, V v) {\r
- ICollection<V> values;\r
- if (base.Find(k, out values) && values != null) {\r
- if (values.Remove(v)) {\r
- if (values.IsEmpty)\r
- base.Remove(k);\r
- return true;\r
- } \r
- }\r
- return false;\r
- }\r
- \r
- // Determine whether key k is associated with a value\r
-\r
- public override bool Contains(K k) { \r
- ICollection<V> values;\r
- return Find(k, out values) && values != null && !values.IsEmpty;\r
- }\r
-\r
- // Determine whether each key in ks is associated with a value\r
-\r
- public override bool ContainsAll<U>(SCG.IEnumerable<U> ks) { \r
- foreach (K k in ks) \r
- if (!Contains(k))\r
- return false;\r
- return true;\r
- }\r
-\r
- // Get or set the value collection associated with key k\r
-\r
- public override ICollection<V> this[K k] {\r
- get {\r
- ICollection<V> values;\r
- return base.Find(k, out values) && values != null ? values : new HashSet<V>();\r
- }\r
- set {\r
- base[k] = value;\r
- }\r
- }\r
-\r
- // Inherited from base class HashDictionary<K,ICollection<V>>:\r
-\r
- // Add(K k, ICollection<V> values) \r
- // AddAll(IEnumerable<KeyValuePair<K,ICollection<V>>> kvs) \r
- // Clear\r
- // Clone\r
- // Find(K k, out ICollection<V> values)\r
- // Find(ref K k, out ICollection<V> values)\r
- // FindOrAdd(K k, ref ICollection<V> values) \r
- // Remove(K k) \r
- // Remove(K k, out ICollection<V> values) \r
- // Update(K k, ICollection<V> values)\r
- // Update(K k, ICollection<V> values, out ICollection<V> oldValues)\r
- // UpdateOrAdd(K k, ICollection<V> values)\r
- // UpdateOrAdd(K k, ICollection<V> values, out ICollection<V> oldValues)\r
- }\r
-}\r
-\r
-\r
-namespace MultiDictionary2 {\r
- // Here we implement a multivalued dictionary as a hash dictionary\r
- // from keys to value collections. The value collections may have\r
- // set or bag semantics. This version uses event listeners to make\r
- // the Count operation constant time.\r
- \r
- // * To avoid recomputing the total number of values for the Count\r
- // property, one may cache it and then use event listeners on the\r
- // value collections to keep the cached count updated. In turn, this\r
- // requires such event listeners on the dictionary also.\r
- \r
- // A C5 hash dictionary each of whose keys map to a collection of values.\r
-\r
- public class MultiHashDictionary<K,V> : HashDictionary<K, ICollection<V>> {\r
- private int count = 0; // Cached value count, updated by events only\r
-\r
- private void IncrementCount(Object sender, ItemCountEventArgs<V> args) {\r
- count += args.Count;\r
- }\r
-\r
- private void DecrementCount(Object sender, ItemCountEventArgs<V> args) {\r
- count -= args.Count;\r
- }\r
-\r
- private void ClearedCount(Object sender, ClearedEventArgs args) {\r
- count -= args.Count;\r
- }\r
-\r
- public MultiHashDictionary() {\r
- ItemsAdded += \r
- delegate(Object sender, ItemCountEventArgs<KeyValuePair<K,ICollection<V>>> args) {\r
- ICollection<V> values = args.Item.Value;\r
- if (values != null) {\r
- count += values.Count;\r
- values.ItemsAdded += IncrementCount;\r
- values.ItemsRemoved += DecrementCount;\r
- values.CollectionCleared += ClearedCount;\r
- }\r
- };\r
- ItemsRemoved += \r
- delegate(Object sender, ItemCountEventArgs<KeyValuePair<K,ICollection<V>>> args) {\r
- ICollection<V> values = args.Item.Value;\r
- if (values != null) {\r
- count -= values.Count;\r
- values.ItemsAdded -= IncrementCount;\r
- values.ItemsRemoved -= DecrementCount;\r
- values.CollectionCleared -= ClearedCount;\r
- }\r
- };\r
- }\r
-\r
- // Return total count of values associated with keys. \r
-\r
- public new virtual int Count { \r
- get { \r
- return count;\r
- }\r
- }\r
-\r
- public override Speed CountSpeed {\r
- get { return Speed.Constant; }\r
- }\r
-\r
- // Add a (key,value) pair\r
-\r
- public virtual void Add(K k, V v) {\r
- ICollection<V> values;\r
- if (!base.Find(k, out values) || values == null) {\r
- values = new HashSet<V>();\r
- Add(k, values);\r
- } \r
- values.Add(v);\r
- }\r
-\r
- // Remove a single (key,value) pair, if present; return true if\r
- // anything was removed, else false\r
-\r
- public virtual bool Remove(K k, V v) {\r
- ICollection<V> values;\r
- if (base.Find(k, out values) && values != null) {\r
- if (values.Remove(v)) {\r
- if (values.IsEmpty)\r
- base.Remove(k);\r
- return true;\r
- } \r
- }\r
- return false;\r
- }\r
- \r
- // Determine whether key k is associated with a value\r
-\r
- public override bool Contains(K k) { \r
- ICollection<V> values;\r
- return Find(k, out values) && values != null && !values.IsEmpty;\r
- }\r
-\r
- // Determine whether each key in ks is associated with a value\r
-\r
- public override bool ContainsAll<U>(SCG.IEnumerable<U> ks) { \r
- foreach (K k in ks) \r
- if (!Contains(k))\r
- return false;\r
- return true;\r
- }\r
-\r
- // Get or set the value collection associated with key k\r
-\r
- public override ICollection<V> this[K k] {\r
- get {\r
- ICollection<V> values;\r
- return base.Find(k, out values) && values != null ? values : new HashSet<V>();\r
- }\r
- set {\r
- base[k] = value;\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.Diagnostics;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace PointLocation\r
-{\r
- //public enum Site { Cell,Edge,Outside}\r
- /// <summary>\r
- /// A line segment with associated data of type T for the cell \r
- /// to its right respectively left.\r
- /// </summary>\r
- public struct Edge<T>\r
- {\r
- public double xs, ys, xe, ye;\r
- \r
- public T right, left;\r
- \r
- public Edge(double xs, double ys, double xe, double ye, T right, T left)\r
- {\r
- this.xs = xs;\r
- this.ys = ys;\r
- this.xe = xe;\r
- this.ye = ye;\r
- this.right = right;\r
- this.left = left;\r
- }\r
- \r
- \r
- public T Cell(bool upper)\r
- {\r
- return (DoubleComparer.StaticCompare(xs, xe) < 0) == upper ? left : right;\r
- }\r
- \r
- \r
- public override string ToString()\r
- {\r
- return String.Format("[({0:G5};{1:G5})->({2:G5};{3:G5})/R:{4} L:{5}]", xs, ys, xe, ye, right, left);\r
- }\r
- }\r
- \r
- \r
- \r
- /// <summary>\r
- /// A data structure for point location in a plane divided into\r
- /// cells by edges. This is the classical use of persistent trees\r
- /// by Sarnak and Tarjan [?]. See de Berg et al for alternatives.\r
- /// \r
- /// The internal data is an outer sorted dictionary that maps each\r
- /// x coordinate of an endpoint of some edge to an inner sorted set\r
- /// of the edges crossing or touching the vertical line at that x\r
- /// coordinate, the edges being ordered by their y coordinates\r
- /// to the immediate right of x. Lookup of a point (x,y) is done by\r
- /// finding the predecessor of x cell the outer dictionary and then locating\r
- /// the edges above and below (x,y) by searching in the inner sorted set.\r
- /// \r
- /// The creation of the inner sorted sets is done by maintaining a\r
- /// (persistent) tree of edges, inserting and deleting edges according\r
- /// to a horzontal sweep of the edges while saving a snapshot of the\r
- /// inner tree in the outer dictionary at each new x coordinate.\r
- ///\r
- /// If there are n edges, there will be 2n updates to the inner tree,\r
- /// and in the worst case, the inner tree will have size Omega(n) for\r
- /// Omega(n) snapshots. We will use O(n*logn) time and O(n) space for\r
- /// sorting the endpoints. If we use a nodecopying persistent inner tree,\r
- /// we will use O(n) space and time for building the data structure proper.\r
- /// If we use a pathcopy persistent tree, we will use O(n*logn) time and\r
- /// space for the data struicture. Finally, if we use a non-persistent\r
- /// tree with a full copy for snapshot, we may use up to O(n^2) space and\r
- /// time for building the datastructure.\r
- ///\r
- /// Lookup will take O(logn) time in any case, but taking the memory\r
- /// hierarchy into consideration, a low space use is very beneficial\r
- /// for large problems.\r
- ///\r
- /// The code assumes that the given set of edges is correct, in particular\r
- /// that they do not touch at interior points (e.g. cross or coincide). \r
- /// </summary>\r
- \r
- public class PointLocator<T>\r
- {\r
- private TreeDictionary<double,ISorted<Edge<T>>> htree;\r
- \r
- private EdgeComparer<T> lc = new EdgeComparer<T>();\r
- \r
- private SCG.IComparer<EndPoint> epc = new EndPoint(0, 0, true, 0);\r
- \r
- private DoubleComparer dc = new DoubleComparer();\r
- \r
- private TreeDictionary<EndPoint,Edge<T>> endpoints;\r
- \r
- private int count;\r
- \r
- private bool built = false;\r
- \r
- public PointLocator()\r
- {\r
- //htree = new TreeDictionary<double,TreeSet<Edge<T>>>(dc);\r
- endpoints = new TreeDictionary<EndPoint,Edge<T>>(epc);\r
- }\r
- \r
- public PointLocator(SCG.IEnumerable<Edge<T>> edges)\r
- {\r
- //htree = new TreeDictionary<double,TreeSet<Edge<T>>>(dc);\r
- endpoints = new TreeDictionary<EndPoint,Edge<T>>(epc);\r
- foreach (Edge<T> edge in edges)\r
- add(edge);\r
- }\r
- \r
- private void add(Edge<T> edge)\r
- {\r
- int c = DoubleComparer.StaticCompare(edge.xs, edge.xe);\r
- \r
- if (c == 0)\r
- return;\r
- \r
- endpoints.Add(new EndPoint(edge.xs, edge.ys, c < 0, count), edge);\r
- endpoints.Add(new EndPoint(edge.xe, edge.ye, c > 0, count++), edge);\r
- }\r
-\r
- public void Add(Edge<T> edge)\r
- {\r
- if (built)\r
- throw new InvalidOperationException("PointLocator static when built");\r
- add(edge);\r
- }\r
- \r
- public void AddAll(SCG.IEnumerable<Edge<T>> edges)\r
- {\r
- if (built)\r
- throw new InvalidOperationException("PointLocator static when built");\r
- \r
- foreach (Edge<T> edge in edges)\r
- add(edge);\r
- }\r
- \r
- public void Build()\r
- {\r
- //htree.Clear();\r
- htree = new TreeDictionary<double,ISorted<Edge<T>>>(dc);\r
- \r
- TreeSet<Edge<T>> vtree = new TreeSet<Edge<T>>(lc);\r
- double lastx = Double.NegativeInfinity;\r
- \r
- foreach (KeyValuePair<EndPoint,Edge<T>> p in endpoints)\r
- {\r
- if (dc.Compare(p.Key.x,lastx)>0)\r
- {\r
- //Put an empty snapshot at -infinity!\r
- htree[lastx] = (ISorted<Edge<T>>)(vtree.Snapshot());\r
- lc.X = lastx = p.Key.x;\r
- lc.compareToRight = false;\r
- }\r
- \r
- if (p.Key.start)\r
- {\r
- if (!lc.compareToRight)\r
- lc.compareToRight = true;\r
- Debug.Assert(vtree.Check());\r
- bool chk = vtree.Add(p.Value);\r
- Debug.Assert(vtree.Check());\r
- \r
- Debug.Assert(chk,"edge was not added!",""+p.Value);\r
- }\r
- else\r
- {\r
- Debug.Assert(!lc.compareToRight);\r
- \r
- Debug.Assert(vtree.Check("C"));\r
- \r
- bool chk = vtree.Remove(p.Value);\r
- Debug.Assert(vtree.Check("D"));\r
- \r
- Debug.Assert(chk,"edge was not removed!",""+p.Value);\r
- }\r
- }\r
- lc.compareToRight = true;\r
- \r
- htree[lastx] = (TreeSet<Edge<T>>)(vtree.Snapshot());\r
- built = true;\r
- }\r
- \r
- \r
- /*public void Clear()\r
- {\r
- endpoints.Clear();\r
- htree.Clear();\r
- }*/\r
- /// <summary>\r
- /// Find the cell, if any, containing (x,y).\r
- /// </summary>\r
- /// <param name="x">x coordinate of point</param>\r
- /// <param name="y">y coordinate of point</param>\r
- /// <param name="below">Associate data of cell according to edge below</param>\r
- /// <param name="above">Associate data of cell according to edge above</param>\r
- /// <returns>True if point is inside some cell</returns>\r
- public bool Place(double x, double y, out T cell)\r
- {\r
- if (!built)\r
- throw new InvalidOperationException("PointLocator must be built first");\r
- \r
- KeyValuePair<double,ISorted<Edge<T>>> p = htree.WeakPredecessor(x);\r
- \r
- //if (DoubleComparer.StaticCompare(cell.key,x)==0)\r
- //Just note it, we have thrown away the vertical edges!\r
- Edge<T> low, high;\r
- bool lval, hval;\r
- PointComparer<T> c = new PointComparer<T>(x, y);\r
- \r
- //Return value true here means we are at an edge.\r
- //But note that if x is in htree.Keys, we may be at a\r
- //vertical edge even if the return value is false here.\r
- //Therefore we do not attempt to sort out completely the case\r
- //where (x,y) is on an edge or even on several edges,\r
- //and just deliver some cell it is in.\r
- p.Value.Cut(c, out low, out lval, out high, out hval);\r
- if (!lval || !hval)\r
- {\r
- cell = default(T);\r
- return false;\r
- }\r
- else\r
- {\r
- cell = low.Cell(true);//high.Cell(false);\r
- return true;\r
- }\r
- }\r
- \r
- public void Place(double x, double y, out T upper, out bool hval, out T lower, out bool lval)\r
- {\r
- if (!built)\r
- throw new InvalidOperationException("PointLocator must be built first");\r
- \r
- KeyValuePair<double,ISorted<Edge<T>>> p = htree.WeakPredecessor(x);\r
- \r
- //if (DoubleComparer.StaticCompare(cell.key,x)==0)\r
- //Just note it, we have thrown away the vertical edges!\r
- Edge<T> low, high;\r
- PointComparer<T> c = new PointComparer<T>(x, y);\r
- \r
- //Return value true here means we are at an edge.\r
- //But note that if x is in htree.Keys, we may be at a\r
- //vertical edge even if the return value is false here.\r
- //Therefore we do not attempt to sort out completely the case\r
- //where (x,y) is on an edge or even on several edges,\r
- //and just deliver some cell it is in.\r
- p.Value.Cut(c, out low, out lval, out high, out hval);\r
- upper = hval ? high.Cell(false) : default(T);\r
- lower = lval ? low.Cell(true) : default(T);\r
- return; \r
- }\r
- \r
- public void Test(double x, double y)\r
- {\r
- T cell;\r
- \r
- if (Place(x, y, out cell))\r
- Console.WriteLine("({0}; {1}): <- {2} ", x, y, cell);\r
- else\r
- Console.WriteLine("({0}; {1}): -", x, y);\r
- }\r
- \r
- /// <summary>\r
- /// Endpoint of an edge with ordering/comparison according to x\r
- /// coordinates with arbitration by the id field. \r
- /// The client is assumed to keep the ids unique.\r
- /// </summary>\r
- public /*private*/ struct EndPoint: SCG.IComparer<EndPoint>\r
- {\r
- public double x, y;\r
- \r
- public bool start;\r
- \r
- private int id;\r
- \r
- \r
- public EndPoint(double x, double y, bool left, int id)\r
- {\r
- this.x = x;this.y = y;this.start = left;this.id = id;\r
- }\r
- \r
- \r
- public int Compare(EndPoint a, EndPoint b)\r
- {\r
- int c = DoubleComparer.StaticCompare(a.x, b.x);\r
- \r
- return c != 0 ? c : (a.start && !b.start) ? 1 : (!a.start && b.start) ? -1 : a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\r
- }\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Compare two doubles with tolerance. \r
- /// </summary>\r
- class DoubleComparer: SCG.IComparer<double>\r
- {\r
- private const double eps = 1E-10;\r
- \r
- public int Compare(double a, double b)\r
- {\r
- return a > b + eps ? 1 : a < b - eps ? -1 : 0;\r
- }\r
-\r
- public static int StaticCompare(double a, double b)\r
- {\r
- return a > b + eps ? 1 : a < b - eps ? -1 : 0;\r
- }\r
- }\r
-\r
- /// <summary>\r
- /// Compare a given point (x,y) to edges: is the point above, at or below\r
- /// the edge. Assumes edges not vertical. \r
- /// </summary>\r
- class PointComparer<T>: IComparable<Edge<T>>\r
- {\r
- private double x, y;\r
- \r
- public PointComparer(double x, double y)\r
- {\r
- this.x = x; this.y = y;\r
- }\r
- \r
- public int CompareTo(Edge<T> a)\r
- {\r
- double ya = (a.ye - a.ys) / (a.xe - a.xs) * (x - a.xs) + a.ys;\r
- \r
- return DoubleComparer.StaticCompare(y, ya);\r
- }\r
- \r
- public bool Equals(Edge<T> a) { return CompareTo(a) == 0; }\r
- }\r
-\r
- /// <summary>\r
- /// Compare two edges at a given x coordinate:\r
- /// Compares the y-coordinate to the immediate right of x of the two edges.\r
- /// Assumes edges to be compared are not vertical.\r
- /// </summary>\r
- class EdgeComparer<T>: SCG.IComparer<Edge<T>>\r
- {\r
- private double x;\r
- \r
- public bool compareToRight = true;\r
- \r
- public double X { get { return x; } set { x = value; } }\r
- \r
- public int Compare(Edge<T> line1, Edge<T> line2)\r
- {\r
- double a1 = (line1.ye - line1.ys) / (line1.xe - line1.xs);\r
- double a2 = (line2.ye - line2.ys) / (line2.xe - line2.xs);\r
- double ya = a1 * (x - line1.xs) + line1.ys;\r
- double yb = a2 * (x - line2.xs) + line2.ys;\r
- int c = DoubleComparer.StaticCompare(ya, yb);\r
- \r
- return c != 0 ? c : (compareToRight ? 1 : -1) * DoubleComparer.StaticCompare(a1, a2);\r
- }\r
- }\r
-\r
- namespace Test\r
- {\r
- public class Ugly : EnumerableBase<Edge<int>>, SCG.IEnumerable<Edge<int>>, SCG.IEnumerator<Edge<int>>\r
- {\r
- private int level = -1, maxlevel;\r
- \r
- private bool leftend = false;\r
- \r
- public Ugly(int maxlevel)\r
- {\r
- this.maxlevel = maxlevel;\r
- }\r
- \r
- public override SCG.IEnumerator<Edge<int>> GetEnumerator()\r
- {\r
- return (SCG.IEnumerator<Edge<int>>)MemberwiseClone();\r
- }\r
- \r
- public void Reset()\r
- {\r
- level = -1;\r
- leftend = false;\r
- }\r
- \r
- public bool MoveNext()\r
- {\r
- if (level > maxlevel)\r
- throw new InvalidOperationException();\r
- \r
- if (leftend)\r
- {\r
- leftend = false;\r
- return true;\r
- }\r
- else\r
- {\r
- leftend = true;\r
- return ++level <= maxlevel;\r
- }\r
- }\r
- \r
- public Edge<int> Current\r
- {\r
- get\r
- {\r
- if (level < 0 || level > maxlevel)\r
- throw new InvalidOperationException();\r
- \r
- double y = (level * 37) % maxlevel;\r
- double deltax = leftend ? 1 : maxlevel;\r
- \r
- if (leftend)\r
- return new Edge<int>(0, y, level, y - 0.5, 0, 0);\r
- else\r
- return new Edge<int>(level, y - 0.5, level, y, 0, 0);\r
- }\r
- }\r
- \r
- \r
- public void Dispose() { }\r
- \r
-#region IEnumerable Members\r
-\r
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
-\r
-#endregion\r
- \r
-#region IEnumerator Members\r
- \r
- object System.Collections.IEnumerator.Current\r
- {\r
- get { throw new Exception("The method or operation is not implemented."); }\r
- }\r
- \r
- void System.Collections.IEnumerator.Reset()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
- \r
-#endregion\r
- }\r
-\r
- public class TestUgly\r
- {\r
- private Ugly ugly;\r
- \r
- private int d;\r
- \r
- private PointLocator<int> pointlocator;\r
- \r
- \r
- public TestUgly(int d)\r
- {\r
- this.d = d;\r
- ugly = new Ugly(d);\r
- }\r
- \r
- \r
- public double Traverse()\r
- {\r
- double xsum = 0;\r
- \r
- foreach (Edge<int> e in ugly) xsum += e.xe;\r
- \r
- return xsum;\r
- }\r
- \r
- public bool LookUp(int count, int seed)\r
- {\r
- Random random = new Random(seed);\r
- bool res = false;\r
- \r
- for (int i = 0; i < count; i++)\r
- {\r
- int cell;\r
- \r
- res ^= pointlocator.Place(random.NextDouble() * d, random.NextDouble() * d, out cell);\r
- }\r
- \r
- return res;\r
- }\r
-\r
- public static void Run(string[] args)\r
- {\r
- int d = args.Length >= 2 ? int.Parse(args[1]) : 400;//00;\r
- int repeats = args.Length >= 3 ? int.Parse(args[2]) : 10;\r
- int lookups = args.Length >= 4 ? int.Parse(args[3]) : 500;//00;\r
- \r
- new TestUgly(d).run(lookups);\r
- }\r
- \r
- \r
- public void run(int lookups)\r
- {\r
- double s = 0;\r
- \r
- s += Traverse();\r
- \r
- pointlocator = new PointLocator<int>(ugly);\r
- pointlocator.Build();\r
- \r
- LookUp(lookups, 567);\r
- }\r
- }\r
- \r
- public class Lattice : EnumerableBase<Edge<string>>, SCG.IEnumerable<Edge<string>>, SCG.IEnumerator<Edge<string>>, System.Collections.IEnumerator\r
- {\r
- private int currenti = -1, currentj = 0, currentid = 0;\r
- \r
- private bool currenthoriz = true;\r
- \r
- private int maxi, maxj;\r
- \r
- private double a11 = 1, a21 = -1, a12 = 1, a22 = 1;\r
- \r
- public Lattice(int maxi, int maxj, double a11, double a21, double a12, double a22)\r
- {\r
- this.maxi = maxi;\r
- this.maxj = maxj;\r
- this.a11 = a11;\r
- this.a12 = a12;\r
- this.a21 = a21;\r
- this.a22 = a22;\r
- }\r
-\r
- public Lattice(int maxi, int maxj)\r
- {\r
- this.maxi = maxi;\r
- this.maxj = maxj;\r
- }\r
- \r
- public override SCG.IEnumerator<Edge<string>> GetEnumerator()\r
- {\r
- return (SCG.IEnumerator<Edge<string>>)MemberwiseClone();\r
- }\r
- \r
- public void Reset()\r
- {\r
- currenti = -1;\r
- currentj = 0;\r
- currentid = -1;\r
- currenthoriz = true;\r
- }\r
- \r
- public bool MoveNext()\r
- {\r
- currentid++;\r
- if (currenthoriz)\r
- {\r
- if (++currenti >= maxi)\r
- {\r
- if (currentj >= maxj)\r
- return false;\r
- \r
- currenti = 0;\r
- currenthoriz = false;\r
- }\r
- \r
- return true;\r
- }\r
- else\r
- {\r
- if (++currenti > maxi)\r
- {\r
- currenti = 0;\r
- currenthoriz = true;\r
- if (++currentj > maxj)\r
- return false;\r
- }\r
- \r
- return true;\r
- }\r
- }\r
- \r
- \r
- private string i2l(int i)\r
- {\r
- int ls = 0, j = i;\r
- \r
- do { ls++; j = j / 26 - 1; } while (j >= 0);\r
- \r
- char[] res = new char[ls];\r
- \r
- while (ls > 0) { res[--ls] = (char)(65 + i % 26); i = i / 26 - 1; }\r
- \r
- //res[0]--;\r
- return new String(res);\r
- }\r
- \r
- \r
- private string fmtid(int i, int j)\r
- {\r
- return "";//cell + ";" + cell;\r
- /*if (cell < 0 || cell < 0 || cell >= maxi || cell >= maxj)\r
- return "Outside";\r
- \r
- return String.Format("{0}{1}", i2l(cell), cell);*/\r
- }\r
- \r
- \r
- public Edge<string> Current\r
- {\r
- get\r
- {\r
- if (currenti >= maxi && currentj >= maxj)\r
- throw new InvalidOperationException();\r
- \r
- double xs = currenti * a11 + currentj * a12;\r
- double ys = currenti * a21 + currentj * a22;\r
- double deltax = currenthoriz ? a11 : a12;\r
- double deltay = currenthoriz ? a21 : a22;\r
- string r = fmtid(currenti, currenthoriz ? currentj - 1 : currentj);\r
- string l = fmtid(currenthoriz ? currenti : currenti - 1, currentj);\r
- \r
- return new Edge<string>(xs, ys, xs + deltax, ys + deltay, r, l);\r
- }\r
- }\r
- \r
- \r
- public void Dispose() { }\r
- \r
-#region IEnumerable Members\r
- \r
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
- \r
-#endregion\r
- \r
-#region IEnumerator Members\r
- \r
- object System.Collections.IEnumerator.Current\r
- {\r
- get { throw new Exception("The method or operation is not implemented."); }\r
- }\r
- \r
- bool System.Collections.IEnumerator.MoveNext()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
- \r
- void System.Collections.IEnumerator.Reset()\r
- {\r
- throw new Exception("The method or operation is not implemented.");\r
- }\r
- \r
-#endregion\r
- }\r
- \r
- public class TestLattice\r
- {\r
- private Lattice lattice;\r
- \r
- private int d;\r
- \r
- private PointLocator<string> pointlocator;\r
- \r
- \r
- public TestLattice(int d)\r
- {\r
- this.d = d;\r
- lattice = new Lattice(d, d, 1, 0, 0, 1);\r
- }\r
-\r
- public TestLattice(int d, double shear)\r
- {\r
- this.d = d;\r
- lattice = new Lattice(d, d, 1, 0, shear, 1);\r
- }\r
-\r
- public double Traverse()\r
- {\r
- double xsum = 0;\r
- \r
- foreach (Edge<string> e in lattice) xsum += e.xe;\r
- \r
- return xsum;\r
- }\r
- \r
- \r
- public bool LookUp(int count, int seed)\r
- {\r
- Random random = new Random(seed);\r
- bool res = false;\r
- \r
- for (int i = 0; i < count; i++)\r
- {\r
- string cell;\r
- \r
- res ^= pointlocator.Place(random.NextDouble() * d, random.NextDouble() * d, out cell);\r
- }\r
- \r
- return res;\r
- }\r
- \r
- \r
- public static void Run()\r
- {\r
- int d = 200;\r
- int repeats = 2;\r
- int lookups = 50000;\r
- TestLattice tl = null;\r
- \r
- Console.WriteLine("TestLattice Run({0}), means over {1} repeats:", d, repeats);\r
- tl = new TestLattice(d, 0.000001);\r
-\r
- tl.Traverse();\r
- \r
- tl.pointlocator = new PointLocator<string>();\r
- \r
- tl.pointlocator.AddAll(tl.lattice);\r
- \r
- tl.pointlocator.Build();\r
- \r
- tl.LookUp(lookups, 567);\r
- }\r
- \r
- \r
- public void BasicRun()\r
- {\r
- pointlocator.Test(-0.5, -0.5);\r
- pointlocator.Test(-0.5, 0.5);\r
- pointlocator.Test(-0.5, 1.5);\r
- pointlocator.Test(0.5, -0.5);\r
- pointlocator.Test(0.5, 0.5);\r
- pointlocator.Test(0.5, 1.5);\r
- pointlocator.Test(1.5, -0.5);\r
- pointlocator.Test(1.5, 0.5);\r
- pointlocator.Test(1.5, 1.5);\r
- pointlocator.Test(1.5, 4.99);\r
- pointlocator.Test(1.5, 5);\r
- pointlocator.Test(1.5, 5.01);\r
- pointlocator.Test(1.99, 4.99);\r
- pointlocator.Test(1.99, 5);\r
- pointlocator.Test(1.99, 5.01);\r
- pointlocator.Test(2, 4.99);\r
- pointlocator.Test(2, 5);\r
- pointlocator.Test(2, 5.01);\r
- pointlocator.Test(2.01, 4.99);\r
- pointlocator.Test(2.01, 5);\r
- pointlocator.Test(2.01, 5.01);\r
- }\r
- }\r
- }\r
-\r
- public class TestPointLocation {\r
- public static void Main(String[] args) {\r
- Test.TestUgly.Run(new String[0]);\r
- }\r
- }\r
-}\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: RandomSelection.cs for pattern chapter\r
-\r
-// Compile with \r
-// csc /r:C5.dll RandomSelection.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace RandomSelection {\r
- class RandomSelection {\r
- public static void Main(String[] args) {\r
- ArrayList<int> list = new ArrayList<int>(), copy1, copy2;\r
- list.AddAll(new int[] { 2, 3, 5, 7, 11, 13, 17, 19 });\r
- copy1 = (ArrayList<int>)list.Clone();\r
- copy2 = (ArrayList<int>)list.Clone();\r
- const int N = 7;\r
- Console.WriteLine("-- With replacement:");\r
- foreach (int x in RandomWith(list, N))\r
- Console.Write("{0} ", x);\r
- Console.WriteLine("\n-- Without replacement:");\r
- foreach (int x in RandomWithout1(copy1, N))\r
- Console.Write("{0} ", x);\r
- Console.WriteLine("\n-- Without replacement:");\r
- foreach (int x in RandomWithout2(copy2, N))\r
- Console.Write("{0} ", x);\r
- Console.WriteLine();\r
- }\r
-\r
- private static readonly C5Random rnd = new C5Random();\r
-\r
- // Select N random items from coll, with replacement.\r
- // Does not modify the given list.\r
-\r
- public static SCG.IEnumerable<T> RandomWith<T>(IIndexed<T> coll, int N) {\r
- for (int i=N; i>0; i--) { \r
- T x = coll[rnd.Next(coll.Count)];\r
- yield return x;\r
- }\r
- }\r
-\r
- // Select N random items from list, without replacement.\r
- // Modifies the given list.\r
-\r
- public static SCG.IEnumerable<T> RandomWithout1<T>(IList<T> list, int N) {\r
- list.Shuffle(rnd); \r
- foreach (T x in list.View(0, N)) \r
- yield return x;\r
- }\r
-\r
- // Select N random items from list, without replacement.\r
- // Faster when list is efficiently indexable and modifiable.\r
- // Modifies the given list.\r
-\r
- public static SCG.IEnumerable<T> RandomWithout2<T>(ArrayList<T> list, int N) {\r
- for (int i=N; i>0; i--) { \r
- int j = rnd.Next(list.Count);\r
- T x = list[j], replacement = list.RemoveLast();\r
- if (j < list.Count) \r
- list[j] = replacement;\r
- yield return x;\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: ReadOnlyPatterns.cs for pattern chapter\r
-\r
-// Compile with \r
-// csc /r:C5.dll ReadOnlyPatterns.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace ReadOnlyPatterns {\r
- class ReadOnlyPatterns {\r
- public static void Main(String[] args) {\r
- GuardHashSet<int>();\r
- GuardTreeSet<int>();\r
- GuardList<int>();\r
- GuardHashDictionary<int,int>();\r
- GuardSortedDictionary<int,int>();\r
- }\r
-\r
- // Read-only access to a hash-based collection\r
- \r
- static void GuardHashSet<T>() {\r
- ICollection<T> coll = new HashSet<T>();\r
- DoWork(new GuardedCollection<T>(coll));\r
- }\r
-\r
- static void DoWork<T>(ICollection<T> gcoll) { \r
- // Use gcoll ... \r
- }\r
-\r
- // Read-only access to an indexed sorted collection\r
-\r
- static void GuardTreeSet<T>() {\r
- IIndexedSorted<T> coll = new TreeSet<T>(); \r
- DoWork(new GuardedIndexedSorted<T>(coll));\r
- }\r
- \r
- static void DoWork<T>(IIndexedSorted<T> gcoll) { \r
- // Use gcoll ...\r
- }\r
-\r
- // Read-only access to a list\r
-\r
- static void GuardList<T>() {\r
- IList<T> coll = new ArrayList<T>(); \r
- DoWork(new GuardedList<T>(coll));\r
- }\r
- \r
- static void DoWork<T>(IList<T> gcoll) { \r
- // Use gcoll ...\r
- }\r
-\r
- // Read-only access to a dictionary\r
-\r
- static void GuardHashDictionary<K,V>() {\r
- IDictionary<K,V> dict = new HashDictionary<K,V>(); \r
- DoWork(new GuardedDictionary<K,V>(dict));\r
- }\r
- \r
- static void DoWork<K,V>(IDictionary<K,V> gdict) { \r
- // Use gdict ...\r
- }\r
-\r
- // Read-only access to a sorted dictionary\r
-\r
- static void GuardSortedDictionary<K,V>() {\r
- ISortedDictionary<K,V> dict = new TreeDictionary<K,V>(); \r
- DoWork(new GuardedSortedDictionary<K,V>(dict));\r
- }\r
- \r
- static void DoWork<K,V>(ISortedDictionary<K,V> gdict) { \r
- // Use gdict ...\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: functional sets 2004-12-21\r
-\r
-// Compile with \r
-// csc /r:C5.dll Sets.cs \r
-\r
-using System;\r
-using System.Text;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace Sets {\r
- // The class of sets with item type T, implemented as a subclass of\r
- // HashSet<T> but with functional infix operators * + - that compute\r
- // intersection, union and difference functionally. That is, they\r
- // create a new set object instead of modifying an existing one.\r
- // The hasher is automatically created so that it is appropriate for\r
- // T. In particular, this is true when T has the form Set<W> for\r
- // some W, since Set<W> implements ICollectionValue<W>.\r
-\r
- public class Set<T> : HashSet<T> {\r
- public Set(SCG.IEnumerable<T> enm) : base() {\r
- AddAll(enm);\r
- }\r
-\r
- public Set(params T[] elems) : this((SCG.IEnumerable<T>)elems) { }\r
-\r
- // Set union (+), difference (-), and intersection (*):\r
-\r
- public static Set<T> operator +(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set+Set");\r
- else {\r
- Set<T> res = new Set<T>(s1);\r
- res.AddAll(s2);\r
- return res;\r
- }\r
- }\r
-\r
- public static Set<T> operator -(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set-Set");\r
- else {\r
- Set<T> res = new Set<T>(s1);\r
- res.RemoveAll(s2);\r
- return res;\r
- }\r
- }\r
-\r
- public static Set<T> operator *(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set*Set");\r
- else {\r
- Set<T> res = new Set<T>(s1);\r
- res.RetainAll(s2);\r
- return res;\r
- }\r
- }\r
-\r
- // Equality of sets; take care to avoid infinite loops\r
-\r
- public static bool operator ==(Set<T> s1, Set<T> s2) {\r
- return EqualityComparer<Set<T>>.Default.Equals(s1, s2);\r
- }\r
-\r
- public static bool operator !=(Set<T> s1, Set<T> s2) {\r
- return !(s1 == s2);\r
- }\r
-\r
- public override bool Equals(Object that) {\r
- return this == (that as Set<T>);\r
- }\r
-\r
- public override int GetHashCode() {\r
- return EqualityComparer<Set<T>>.Default.GetHashCode(this);\r
- }\r
-\r
- // Subset (<=) and superset (>=) relation:\r
-\r
- public static bool operator <=(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set<=Set");\r
- else\r
- return s1.ContainsAll(s2);\r
- }\r
-\r
- public static bool operator >=(Set<T> s1, Set<T> s2) {\r
- if (s1 == null || s2 == null) \r
- throw new ArgumentNullException("Set>=Set");\r
- else\r
- return s2.ContainsAll(s1);\r
- }\r
- \r
- public override String ToString() {\r
- StringBuilder sb = new StringBuilder();\r
- sb.Append("{");\r
- bool first = true;\r
- foreach (T x in this) {\r
- if (!first)\r
- sb.Append(",");\r
- sb.Append(x);\r
- first = false;\r
- }\r
- sb.Append("}");\r
- return sb.ToString();\r
- }\r
- }\r
-\r
- class MyTest {\r
- public static void Main(String[] args) {\r
- Set<int> s1 = new Set<int>(2, 3, 5, 7, 11);\r
- Set<int> s2 = new Set<int>(2, 4, 6, 8, 10);\r
- Console.WriteLine("s1 + s2 = {0}", s1 + s2);\r
- Console.WriteLine("s1 * s2 = {0}", s1 * s2);\r
- Console.WriteLine("s1 - s2 = {0}", s1 - s2);\r
- Console.WriteLine("s1 - s1 = {0}", s1 - s1);\r
- Console.WriteLine("s1 + s1 == s1 is {0}", s1 + s1 == s1);\r
- Console.WriteLine("s1 * s1 == s1 is {0}", s1 * s1 == s1);\r
- Set<Set<int>> ss1 = new Set<Set<int>>(s1, s2, s1 + s2);\r
- Console.WriteLine("ss1 = {0}", ss1);\r
- Console.WriteLine("IntersectionClose(ss1) = {0}", IntersectionClose(ss1));\r
- Set<Set<int>> ss2 =\r
- new Set<Set<int>>(new Set<int>(2, 3), new Set<int>(1, 3), new Set<int>(1, 2));\r
- Console.WriteLine("ss2 = {0}", ss2);\r
- Console.WriteLine("IntersectionClose(ss2) = {0}", IntersectionClose(ss2));\r
- }\r
-\r
- // Given a set SS of sets of Integers, compute its intersection\r
- // closure, that is, the least set TT such that SS is a subset of TT\r
- // and such that for any two sets t1 and t2 in TT, their\r
- // intersection is also in TT. \r
-\r
- // For instance, if SS is {{2,3}, {1,3}, {1,2}}, \r
- // then TT is {{2,3}, {1,3}, {1,2}, {3}, {2}, {1}, {}}.\r
-\r
- // Both the argument and the result is a Set<Set<int>>\r
-\r
- static Set<Set<T>> IntersectionClose<T>(Set<Set<T>> ss) {\r
- IQueue<Set<T>> worklist = new CircularQueue<Set<T>>();\r
- foreach (Set<T> s in ss)\r
- worklist.Enqueue(s);\r
- HashSet<Set<T>> tt = new HashSet<Set<T>>();\r
- while (worklist.Count != 0) {\r
- Set<T> s = worklist.Dequeue();\r
- foreach (Set<T> t in tt) {\r
- Set<T> ts = t * s;\r
- if (!tt.Contains(ts))\r
- worklist.Enqueue(ts);\r
- }\r
- tt.Add(s);\r
- }\r
- return new Set<Set<T>>((SCG.IEnumerable<Set<T>>)tt);\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: SortedIterationPatterns.cs for pattern chapter\r
-\r
-// Compile with \r
-// csc /r:C5.dll SortedIterationPatterns.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace SortedIterationPatterns {\r
- class SortedIterationPatterns {\r
- public static void Main(String[] args) {\r
- ISorted<int> sorted = new TreeSet<int>();\r
- sorted.AddAll(new int[] { 23, 29, 31, 37, 41, 43, 47, 53 });\r
- Console.WriteLine(sorted);\r
- if (args.Length == 1) { \r
- int n = int.Parse(args[0]);\r
- int res;\r
- if (Predecessor(sorted, n, out res))\r
- Console.WriteLine("{0} has predecessor {1}", n, res);\r
- if (WeakPredecessor(sorted, n, out res))\r
- Console.WriteLine("{0} has weak predecessor {1}", n, res);\r
- if (Successor(sorted, n, out res))\r
- Console.WriteLine("{0} has successor {1}", n, res);\r
- if (WeakSuccessor(sorted, n, out res))\r
- Console.WriteLine("{0} has weak successor {1}", n, res);\r
- }\r
- IterBeginEnd(sorted);\r
- IterBeginEndBackwards(sorted);\r
- IterIncExc(sorted, 29, 47);\r
- IterIncExcBackwards(sorted, 29, 47);\r
- IterIncEnd(sorted, 29);\r
- IterBeginExc(sorted, 47);\r
- IterIncInc(sorted, 29, 47);\r
- IterBeginInc(sorted, 47);\r
- IterExcExc(sorted, 29, 47);\r
- IterExcEnd(sorted, 29);\r
- IterExcInc(sorted, 29, 47);\r
- }\r
-\r
- // --- Predecessor and successor patterns --------------------\r
-\r
- // Find weak successor of y in coll, or return false\r
-\r
- public static bool WeakSuccessor<T>(ISorted<T> coll, T y, out T ySucc) \r
- where T : IComparable<T>\r
- {\r
- T yPred;\r
- bool hasPred, hasSucc, \r
- hasY = coll.Cut(y, out yPred, out hasPred, out ySucc, out hasSucc);\r
- if (hasY)\r
- ySucc = y;\r
- return hasY || hasSucc;\r
- }\r
-\r
- // Find weak predecessor of y in coll, or return false\r
-\r
- public static bool WeakPredecessor<T>(ISorted<T> coll, T y, out T yPred) \r
- where T : IComparable<T>\r
- {\r
- T ySucc;\r
- bool hasPred, hasSucc, \r
- hasY = coll.Cut(y, out yPred, out hasPred, out ySucc, out hasSucc);\r
- if (hasY) \r
- yPred = y;\r
- return hasY || hasPred;\r
- }\r
-\r
- // Find (strict) successor of y in coll, or return false\r
-\r
- public static bool Successor<T>(ISorted<T> coll, T y, out T ySucc) \r
- where T : IComparable<T>\r
- {\r
- bool hasPred, hasSucc;\r
- T yPred;\r
- coll.Cut(y, out yPred, out hasPred, out ySucc, out hasSucc);\r
- return hasSucc;\r
- }\r
-\r
- // Find (strict) predecessor of y in coll, or return false\r
-\r
- public static bool Predecessor<T>(ISorted<T> coll, T y, out T yPred) \r
- where T : IComparable<T>\r
- {\r
- bool hasPred, hasSucc;\r
- T ySucc;\r
- coll.Cut(y, out yPred, out hasPred, out ySucc, out hasSucc);\r
- return hasPred;\r
- }\r
-\r
- // --- Sorted iteration patterns -----------------------------\r
-\r
- // Iterate over all items\r
- \r
- public static void IterBeginEnd<T>(ISorted<T> coll) {\r
- foreach (T x in coll) { \r
- Console.Write("{0} ", x);\r
- }\r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over all items, backwards\r
- \r
- public static void IterBeginEndBackwards<T>(ISorted<T> coll) {\r
- foreach (T x in coll.Backwards()) { \r
- Console.Write("{0} ", x);\r
- }\r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over [x1,x2[\r
- \r
- public static void IterIncExc<T>(ISorted<T> coll, T x1, T x2) {\r
- foreach (T x in coll.RangeFromTo(x1, x2)) { \r
- Console.Write("{0} ", x);\r
- }\r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over [x1,x2[, backwards\r
- \r
- public static void IterIncExcBackwards<T>(ISorted<T> coll, T x1, T x2) {\r
- foreach (T x in coll.RangeFromTo(x1, x2).Backwards()) { \r
- Console.Write("{0} ", x);\r
- }\r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over [x1...]\r
- \r
- public static void IterIncEnd<T>(ISorted<T> coll, T x1) {\r
- foreach (T x in coll.RangeFrom(x1)) { \r
- Console.Write("{0} ", x);\r
- }\r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over [...x2[\r
- \r
- public static void IterBeginExc<T>(ISorted<T> coll, T x2) {\r
- foreach (T x in coll.RangeTo(x2)) { \r
- Console.Write("{0} ", x);\r
- }\r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over [x1...x2]\r
- \r
- public static void IterIncInc<T>(ISorted<T> coll, T x1, T x2) \r
- where T : IComparable<T>\r
- {\r
- T x2Succ; \r
- bool x2HasSucc = Successor(coll, x2, out x2Succ);\r
- IDirectedEnumerable<T> range = \r
- x2HasSucc ? coll.RangeFromTo(x1, x2Succ) : coll.RangeFrom(x1);\r
- foreach (T x in range) {\r
- Console.Write("{0} ", x);\r
- } \r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over [...x2]\r
- \r
- public static void IterBeginInc<T>(ISorted<T> coll, T x2) \r
- where T : IComparable<T>\r
- {\r
- T x2Succ; \r
- bool x2HasSucc = Successor(coll, x2, out x2Succ);\r
- IDirectedEnumerable<T> range = \r
- x2HasSucc ? coll.RangeTo(x2Succ) : coll.RangeAll();\r
- foreach (T x in range) {\r
- Console.Write("{0} ", x);\r
- } \r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over ]x1...x2[\r
- \r
- public static void IterExcExc<T>(ISorted<T> coll, T x1, T x2)\r
- where T : IComparable<T>\r
- {\r
- T x1Succ;\r
- bool x1HasSucc = Successor(coll, x1, out x1Succ);\r
- IDirectedEnumerable<T> range = \r
- x1HasSucc ? coll.RangeFromTo(x1Succ, x2) : new ArrayList<T>();\r
- foreach (T x in range) {\r
- Console.Write("{0} ", x);\r
- } \r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over ]x1...]\r
- \r
- public static void IterExcEnd<T>(ISorted<T> coll, T x1) \r
- where T : IComparable<T>\r
- {\r
- T x1Succ;\r
- bool x1HasSucc = Successor(coll, x1, out x1Succ);\r
- IDirectedEnumerable<T> range = \r
- x1HasSucc ? coll.RangeFrom(x1Succ) : new ArrayList<T>();\r
- foreach (T x in range) {\r
- Console.Write("{0} ", x);\r
- } \r
- Console.WriteLine();\r
- }\r
-\r
- // Iterate over ]x1...x2]\r
- \r
- public static void IterExcInc<T>(ISorted<T> coll, T x1, T x2) \r
- where T : IComparable<T>\r
- {\r
- T x1Succ, x2Succ;\r
- bool x1HasSucc = Successor(coll, x1, out x1Succ),\r
- x2HasSucc = Successor(coll, x2, out x2Succ);\r
- IDirectedEnumerable<T> range = \r
- x1HasSucc ? (x2HasSucc ? coll.RangeFromTo(x1Succ, x2Succ) \r
- : coll.RangeFrom(x1Succ))\r
- : new ArrayList<T>();\r
- foreach (T x in range) {\r
- Console.Write("{0} ", x);\r
- } \r
- Console.WriteLine();\r
- }\r
-\r
- }\r
-}\r
+++ /dev/null
-// C5 example\r
-// 2004-11\r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace SortingPermutation\r
-{\r
- class MyTest\r
- {\r
- public static void Main(String[] args)\r
- {\r
- String[] cities = \r
- { "Tokyo", "Beijing", "Hangzhou", "Kyoto", "Beijing", "Copenhagen", "Seattle" };\r
- IList<String> alst = new ArrayList<String>();\r
- alst.AddAll<String>(cities);\r
- foreach (int i in MySort.GetPermutation1(alst))\r
- Console.Write("{0} ", i);\r
- Console.WriteLine();\r
- IList<String> llst = new LinkedList<String>();\r
- llst.AddAll<String>(cities);\r
- foreach (int i in MySort.GetPermutation2(llst))\r
- Console.Write("{0} ", i);\r
- Console.WriteLine();\r
- Console.WriteLine("The rank of the cities:");\r
- ArrayList<int> res = MySort.GetPermutation1(MySort.GetPermutation2(llst));\r
- foreach (int i in res)\r
- Console.Write("{0} ", i);\r
- Console.WriteLine();\r
- }\r
- }\r
-\r
- class MySort\r
- {\r
- // Fast for array lists and similar, but not stable; slow for linked lists\r
-\r
- public static ArrayList<int> GetPermutation1<T>(IList<T> lst)\r
- where T : IComparable<T>\r
- {\r
- ArrayList<int> res = new ArrayList<int>(lst.Count);\r
- for (int i = 0; i < lst.Count; i++)\r
- res.Add(i);\r
- res.Sort(new DelegateComparer<int>\r
- (delegate(int i, int j) { return lst[i].CompareTo(lst[j]); }));\r
- return res;\r
- }\r
-\r
- // Stable and fairly fast both for array lists and linked lists, \r
- // but does copy the collection's items. \r
-\r
- public static ArrayList<int> GetPermutation2<T>(IList<T> lst)\r
- where T : IComparable<T>\r
- {\r
- int i = 0;\r
- IList<KeyValuePair<T, int>> zipList =\r
- lst.Map<KeyValuePair<T, int>>\r
- (delegate(T x) { return new KeyValuePair<T, int>(x, i++); });\r
- zipList.Sort(new KeyValueComparer<T>(lst));\r
- ArrayList<int> res = new ArrayList<int>(lst.Count);\r
- foreach (KeyValuePair<T, int> p in zipList)\r
- res.Add(p.Value);\r
- return res;\r
- }\r
-\r
- private class KeyValueComparer<T> : SCG.IComparer<KeyValuePair<T, int>>\r
- where T : IComparable<T>\r
- {\r
- private readonly IList<T> lst;\r
- public KeyValueComparer(IList<T> lst)\r
- {\r
- this.lst = lst;\r
- }\r
- public int Compare(KeyValuePair<T, int> p1, KeyValuePair<T, int> p2)\r
- {\r
- return p1.Key.CompareTo(p2.Key);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: anagrams 2004-12-08\r
-\r
-// Compile with \r
-// csc /r:C5.dll TestSortedArray.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace TestSortedArray {\r
- class TestSortedArray {\r
- public static void Main(String[] args) {\r
- SortedArray<Object> sarr = new SortedArray<Object>();\r
- }\r
- }\r
-}\r
+++ /dev/null
-// Experiment: implicit conversion of indexer to function\r
-// sestoft@dina.kvl.dk * 2005-11-08\r
-\r
-using System;\r
-using C5;\r
-\r
-class MyFunTest {\r
- public static void Main(String[] args) {\r
- FooBar fb = new FooBar();\r
- IList<int> list = new LinkedList<int>();\r
- list.AddAll(new int[] { 2, 3, 5, 7, 11 });\r
- list.Map<double>(fb).Apply(Console.WriteLine);\r
- list.Apply(fb);\r
- }\r
-}\r
-\r
-class FooBar {\r
- public double this[int x] { \r
- get { \r
- Console.WriteLine(x); \r
- return x + 1.5; \r
- } \r
- }\r
-\r
- public Fun<int,double> Fun {\r
- get { \r
- return delegate(int x) { return this[x]; };\r
- }\r
- }\r
-\r
- public Act<int> Act {\r
- get { \r
- return delegate(int x) { double junk = this[x]; };\r
- }\r
- }\r
- \r
- public static implicit operator Fun<int,double>(FooBar fb) {\r
- return delegate(int x) { return fb[x]; };\r
- } \r
-\r
- public static implicit operator Act<int>(FooBar fb) {\r
- return delegate(int x) { double junk = fb[x]; };\r
- } \r
-}\r
-\r
-\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: topological sorting 2005-09-09\r
-\r
-// Compile with \r
-// csc /r:C5.dll Toposort.cs \r
-\r
-using System;\r
-using System.Text;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-using SDD = System.Diagnostics.Debug;\r
-\r
-namespace Toposort {\r
- class TestToposort {\r
- public static void Main(String[] args) {\r
- Node<String> \r
- d = new Node<String>("d"), \r
- e = new Node<String>("e"),\r
- c = new Node<String>("c", d, e),\r
- b = new Node<String>("b", d),\r
- a = new Node<String>("a", d, b, c);\r
- foreach (Node<String> n in Toposort0(a))\r
- Console.WriteLine(n);\r
- Console.WriteLine();\r
- foreach (Node<String> n in Toposort1(a))\r
- Console.WriteLine(n);\r
- Console.WriteLine();\r
- foreach (Node<String> n in Toposort2(a))\r
- Console.WriteLine(n);\r
- }\r
-\r
- // Toposort 0, adding each node when finished, after its descendants.\r
- // Classic depth-first search. Does not terminate on cyclic graphs.\r
- \r
- public static IList<Node<T>> Toposort0<T>(params Node<T>[] starts) {\r
- HashedLinkedList<Node<T>> sorted = new HashedLinkedList<Node<T>>();\r
- foreach (Node<T> start in starts) \r
- if (!sorted.Contains(start)) \r
- AddNode0(sorted, start);\r
- return sorted; \r
- }\r
-\r
- private static void AddNode0<T>(IList<Node<T>> sorted, Node<T> node) {\r
- SDD.Assert(!sorted.Contains(node));\r
- foreach (Node<T> child in node.children) \r
- if (!sorted.Contains(child)) \r
- AddNode0(sorted, child);\r
- sorted.InsertLast(node);\r
- }\r
-\r
- // Toposort 1, using hash index to add each node before its descendants.\r
- // Terminates also on cyclic graphs.\r
- \r
- public static IList<Node<T>> Toposort1<T>(params Node<T>[] starts) {\r
- HashedLinkedList<Node<T>> sorted = new HashedLinkedList<Node<T>>();\r
- foreach (Node<T> start in starts) \r
- if (!sorted.Contains(start)) {\r
- sorted.InsertLast(start);\r
- AddNode1(sorted, start);\r
- }\r
- return sorted; \r
- }\r
-\r
- private static void AddNode1<T>(IList<Node<T>> sorted, Node<T> node) {\r
- SDD.Assert(sorted.Contains(node));\r
- foreach (Node<T> child in node.children) \r
- if (!sorted.Contains(child)) {\r
- sorted.ViewOf(node).InsertFirst(child);\r
- AddNode1(sorted, child);\r
- }\r
- }\r
-\r
- // Toposort 2, node rescanning using a view.\r
- // Uses no method call stack and no extra data structures, but slower.\r
-\r
- public static IList<Node<T>> Toposort2<T>(params Node<T>[] starts) {\r
- HashedLinkedList<Node<T>> sorted = new HashedLinkedList<Node<T>>();\r
- foreach (Node<T> start in starts) \r
- if (!sorted.Contains(start)) {\r
- sorted.InsertLast(start);\r
- using (IList<Node<T>> cursor = sorted.View(sorted.Count-1,1)) {\r
- do { \r
- Node<T> child;\r
- while (null != (child = PendingChild(sorted, cursor.First))) {\r
- cursor.InsertFirst(child);\r
- cursor.Slide(0,1);\r
- }\r
- } while (cursor.TrySlide(+1));\r
- }\r
- }\r
- return sorted; \r
- }\r
-\r
- static Node<T> PendingChild<T>(IList<Node<T>> sorted, Node<T> node) {\r
- foreach (Node<T> child in node.children) \r
- if (!sorted.Contains(child))\r
- return child;\r
- return null;\r
- }\r
- }\r
-\r
- class Node<T> { \r
- public readonly T id;\r
- public readonly Node<T>[] children;\r
-\r
- public Node(T id, params Node<T>[] children) { \r
- this.id = id; this.children = children;\r
- }\r
-\r
- public override String ToString() { \r
- return id.ToString();\r
- }\r
-\r
- public Node<T> this[int i] {\r
- set { children[i] = value; }\r
- get { return children[i]; }\r
- }\r
- }\r
-}\r
+++ /dev/null
-// C5 example\r
-// 2004-11-09\r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace TreeTraversal\r
-{\r
- class MyTest\r
- {\r
- public static void Main(String[] args)\r
- {\r
- Tree<int> t = MakeTree(1, 15);\r
- Act<int> act = delegate(int val) { Console.Write("{0} ", val); };\r
- Console.WriteLine("Depth-first:");\r
- Tree<int>.DepthFirst(t, act);\r
- Console.WriteLine("\nBreadth-first:");\r
- Tree<int>.BreadthFirst(t, act);\r
- Console.WriteLine("\nDepth-first:");\r
- Tree<int>.Traverse(t, act, new ArrayList<Tree<int>>());\r
- Console.WriteLine("\nBreadth-first:");\r
- Tree<int>.Traverse(t, act, new LinkedList<Tree<int>>());\r
- Console.WriteLine();\r
- }\r
-\r
- // Build n-node tree with root numbered b and other nodes numbered b+1..b+n\r
- public static Tree<int> MakeTree(int b, int n)\r
- {\r
- if (n == 0)\r
- return null;\r
- else\r
- {\r
- int k = n / 2;\r
- Tree<int> t1 = MakeTree(b + 1, k), t2 = MakeTree(b + k + 1, n - 1 - k);\r
- return new Tree<int>(b, t1, t2);\r
- }\r
- }\r
- }\r
-\r
- class Tree<T>\r
- {\r
- private T val;\r
- private Tree<T> t1, t2;\r
- public Tree(T val) : this(val, null, null) { }\r
- public Tree(T val, Tree<T> t1, Tree<T> t2)\r
- {\r
- this.val = val; this.t1 = t1; this.t2 = t2;\r
- }\r
-\r
- public static void DepthFirst(Tree<T> t, Act<T> act)\r
- {\r
- IStack<Tree<T>> work = new ArrayList<Tree<T>>();\r
- work.Push(t);\r
- while (!work.IsEmpty)\r
- {\r
- Tree<T> cur = work.Pop();\r
- if (cur != null)\r
- {\r
- work.Push(cur.t2);\r
- work.Push(cur.t1);\r
- act(cur.val);\r
- }\r
- }\r
- }\r
-\r
- public static void BreadthFirst(Tree<T> t, Act<T> act)\r
- {\r
- IQueue<Tree<T>> work = new CircularQueue<Tree<T>>();\r
- work.Enqueue(t);\r
- while (!work.IsEmpty)\r
- {\r
- Tree<T> cur = work.Dequeue();\r
- if (cur != null)\r
- {\r
- work.Enqueue(cur.t1);\r
- work.Enqueue(cur.t2);\r
- act(cur.val);\r
- }\r
- }\r
- }\r
-\r
- public static void Traverse(Tree<T> t, Act<T> act, IList<Tree<T>> work)\r
- {\r
- work.Clear();\r
- work.Add(t);\r
- while (!work.IsEmpty)\r
- {\r
- Tree<T> cur = work.Remove();\r
- if (cur != null)\r
- {\r
- if (work.FIFO)\r
- {\r
- work.Add(cur.t1);\r
- work.Add(cur.t2);\r
- }\r
- else\r
- {\r
- work.Add(cur.t2);\r
- work.Add(cur.t1);\r
- }\r
- act(cur.val);\r
- }\r
- }\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: various tests 2005-01-01\r
-\r
-// Compile with \r
-// csc /r:C5.dll Try.cs \r
-\r
-using System;\r
-using System.Text;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace Try\r
-{\r
- class MyTest\r
- {\r
- public static void Main()\r
- {\r
- IList<bool> list = new ArrayList<bool>();\r
- list.AddAll(new bool[] { false, false, true, true, false });\r
- list.CollectionCleared \r
- += delegate(Object coll, ClearedEventArgs args) {\r
- ClearedRangeEventArgs crargs = args as ClearedRangeEventArgs;\r
- if (crargs != null) {\r
- Console.WriteLine("Cleared {0} to {1}", \r
- crargs.Start, crargs.Start+crargs.Count-1);\r
- } else {\r
- Console.WriteLine("Cleared {0} items", args.Count);\r
- }\r
- };\r
- list.RemoveInterval(2, 2);\r
- HashSet<int> hash = new HashSet<int>();\r
- hash.ItemsRemoved \r
- += delegate {\r
- Console.WriteLine("Item was removed");\r
- };\r
- hash.ItemsAdded \r
- += delegate {\r
- Console.WriteLine("Item was added");\r
- };\r
- hash.UpdateOrAdd(2);\r
- hash.UpdateOrAdd(2);\r
- }\r
- }\r
-}\r
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
- <ProductVersion>8.0.50727</ProductVersion>\r
- <SchemaVersion>2.0</SchemaVersion>\r
- <ProjectGuid>{B2A29FF2-A5C5-4F07-8CE7-FF5D744D7562}</ProjectGuid>\r
- <OutputType>Library</OutputType>\r
- <RootNamespace>UserGuideExamples</RootNamespace>\r
- <AssemblyName>UserGuideExamples</AssemblyName>\r
- <WarningLevel>4</WarningLevel>\r
- <StartupObject>\r
- </StartupObject>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
- <DebugSymbols>true</DebugSymbols>\r
- <DebugType>full</DebugType>\r
- <Optimize>false</Optimize>\r
- <OutputPath>.\bin\Debug\</OutputPath>\r
- <DefineConstants>DEBUG;TRACE</DefineConstants>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
- <DebugSymbols>false</DebugSymbols>\r
- <Optimize>true</Optimize>\r
- <OutputPath>.\bin\Release\</OutputPath>\r
- <DefineConstants>TRACE</DefineConstants>\r
- </PropertyGroup>\r
- <ItemGroup>\r
- <Compile Include="AnagramHashBag.cs" />\r
- <Compile Include="Anagrams.cs" />\r
- <Compile Include="AnagramStrings.cs" />\r
- <Compile Include="AnagramTreeBag.cs" />\r
- <Compile Include="Antipatterns.cs" />\r
- <Compile Include="Cloning.cs" />\r
- <Compile Include="CollectionCollection.cs" />\r
- <Compile Include="CollectionSanity.cs" />\r
- <Compile Include="EventPatterns.cs" />\r
- <Compile Include="GettingStarted.cs" />\r
- <Compile Include="Graph.cs" />\r
- <Compile Include="Fileindex.cs" />\r
- <Compile Include="GCHForm.cs">\r
- <SubType>Form</SubType>\r
- </Compile>\r
- <Compile Include="GConvexHull.cs" />\r
- <Compile Include="GNfaToDfa.cs" />\r
- <Compile Include="HashCodes.cs" />\r
- <Compile Include="Jobqueue.cs" />\r
- <Compile Include="KeywordRecognition.cs" />\r
- <Compile Include="ListPatterns.cs" />\r
- <Compile Include="Locking.cs" />\r
- <Compile Include="MultiCollection.cs" />\r
- <Compile Include="MultiDictionary.cs" />\r
- <Compile Include="PointLocation.cs" />\r
- <Compile Include="RandomSelection.cs" />\r
- <Compile Include="ReadOnlyPatterns.cs" />\r
- <Compile Include="Sets.cs" />\r
- <Compile Include="SortedIterationPatterns.cs" />\r
- <Compile Include="SortingPermutation.cs" />\r
- <Compile Include="TestSortedArray.cs" />\r
- <Compile Include="ThisFun.cs" />\r
- <Compile Include="Toposort.cs" />\r
- <Compile Include="TreeTraversal.cs" />\r
- <Compile Include="Try.cs" />\r
- <Compile Include="ViewPatterns.cs" />\r
- <Compile Include="Views.cs" />\r
- <Compile Include="WrappedArray.cs" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <EmbeddedResource Include="GCHForm.resx">\r
- <DependentUpon>GCHForm.cs</DependentUpon>\r
- </EmbeddedResource>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <ProjectReference Include="..\C5\C5.csproj">\r
- <Project>{D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}</Project>\r
- <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>\r
- <Name>C5</Name>\r
- </ProjectReference>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <None Include="Makefile" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Reference Include="System" />\r
- <Reference Include="System.Drawing" />\r
- <Reference Include="System.Windows.Forms" />\r
- </ItemGroup>\r
- <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />\r
-</Project>
\ No newline at end of file
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: ViewPatterns 2005-07-22\r
-\r
-// Compile with \r
-// csc /r:C5.dll ViewPatterns.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace ViewPatterns {\r
- class Views {\r
- public static void Main(String[] args) {\r
- IList<char> lst = new ArrayList<char>();\r
- lst.AddAll<char>(new char[] { 'a', 'b', 'c', 'd' });\r
- IList<char> v1 = lst.View(1, 1);\r
- Console.WriteLine("v1 = {0}", v1);\r
- InsertBeforeFirst(v1, '<', 'b');\r
- InsertAfterFirst(v1, '>', 'b');\r
- Console.WriteLine("v1 = {0}", v1);\r
- char x; \r
- if (SequencePredecessor(v1, 'b', out x)) \r
- Console.WriteLine("Predecessor of b is " + x);\r
- if (SequenceSuccessor(v1, 'b', out x)) \r
- Console.WriteLine("Successor of b is " + x);\r
- if (!SequencePredecessor(v1, 'c', out x)) \r
- Console.WriteLine("c has no predecessor");\r
- if (!SequenceSuccessor(v1, 'a', out x)) \r
- Console.WriteLine("a has no successor");\r
- IList<char> lst2 = new ArrayList<char>();\r
- lst2.AddAll<char>(new char[] { 'a', 'b', 'c', 'A', 'a', 'd', 'a' });\r
- foreach (int i in IndexesOf(lst2, 'a')) \r
- Console.Write("{0} ", i);\r
- Console.WriteLine();\r
- foreach (int i in ReverseIndexesOf(lst2, 'a')) \r
- Console.Write("{0} ", i);\r
- Console.WriteLine();\r
- Console.WriteLine(lst2);\r
- IList<char> view = lst2.View(2,0);\r
- InsertAtView(lst2, view, 'y');\r
- Console.WriteLine(lst2);\r
- InsertIntoView(view, 'x');\r
- Console.WriteLine(lst2);\r
- }\r
-\r
- // --- Patterns for zero-item views -----------------------------\r
-\r
- // Number of items before zero-item view\r
- \r
- public static int ItemsBefore<T>(IList<T> view) {\r
- return view.Offset;\r
- }\r
-\r
- // Number of items after zero-item view\r
- \r
- public static int ItemsAfter<T>(IList<T> view) {\r
- return view.Underlying.Count - view.Offset;\r
- }\r
-\r
- // Move (zero-item) view one item to the left\r
- \r
- public static void MoveLeft<T>(IList<T> view) {\r
- // One of these:\r
- view.Slide(-1);\r
- view.TrySlide(-1);\r
- }\r
-\r
- // Move (zero-item) view one item to the right\r
- \r
- public static void MoveRight<T>(IList<T> view) {\r
- // One of these:\r
- view.Slide(+1);\r
- view.TrySlide(+1);\r
- }\r
-\r
- // Test whether (zero-item) view is at beginning of list\r
- \r
- public static bool AtBeginning<T>(IList<T> view) {\r
- return view.Offset == 0;\r
- }\r
-\r
- // Test whether (zero-item) view is at end of list\r
- \r
- public static bool AtEnd<T>(IList<T> view) {\r
- return view.Offset == view.Underlying.Count;\r
- }\r
-\r
- // Insert x into zero-item view and into underlying list\r
- \r
- public static void InsertIntoView<T>(IList<T> view, T x) {\r
- view.Add(x);\r
- }\r
-\r
- // Insert x into list at zero-item view \r
- \r
- public static void InsertAtView<T>(IList<T> list, IList<T> view, T x) {\r
- list.Insert(view, x);\r
- }\r
-\r
- // Delete the item before zero-item view \r
- \r
- public static void DeleteBefore<T>(IList<T> view) {\r
- view.Slide(-1,1).RemoveFirst();\r
- }\r
-\r
- // Delete the item after zero-item view \r
- \r
- public static void DeleteAfter<T>(IList<T> view) {\r
- view.Slide(0,1).RemoveFirst();\r
- }\r
-\r
- // Get the zero-item view at left endpoint. Succeeds on all lists\r
- // and valid views.\r
-\r
- public static IList<T> LeftEndView<T>(IList<T> list) {\r
- return list.View(0,0);\r
- }\r
-\r
- // Get the zero-item view at right endpoint. Succeeds on all\r
- // lists and valid views.\r
-\r
- public static IList<T> RightEndView<T>(IList<T> list) {\r
- return list.View(list.Count,0);\r
- }\r
-\r
-\r
- // --- Patterns for one-item views ------------------------------\r
-\r
- // Find the sequence predecessor x of y; or throw exception\r
-\r
- public static T SequencePredecessor<T>(IList<T> list, T y) {\r
- return list.ViewOf(y).Slide(-1)[0];\r
- } \r
- \r
- // Find the sequence predecessor x of y; or return false \r
-\r
- public static bool SequencePredecessor<T>(IList<T> list, T y, out T x) {\r
- IList<T> view = list.ViewOf(y);\r
- bool ok = view != null && view.TrySlide(-1);\r
- x = ok ? view[0] : default(T);\r
- return ok;\r
- } \r
-\r
- // Find the sequence successor x of y; or throw exception\r
-\r
- public static T SequenceSuccessor<T>(IList<T> list, T y) {\r
- return list.ViewOf(y).Slide(+1)[0];\r
- } \r
-\r
- // Find the sequence successor x of y; or return false\r
-\r
- public static bool SequenceSuccessor<T>(IList<T> list, T y, out T x) {\r
- IList<T> view = list.ViewOf(y);\r
- bool ok = view != null && view.TrySlide(+1);\r
- x = ok ? view[0] : default(T);\r
- return ok;\r
- } \r
-\r
- // Insert x into list after first occurrence of y (or throw\r
- // NullReferenceException).\r
- \r
- public static void InsertAfterFirst<T>(IList<T> list, T x, T y) {\r
- list.Insert(list.ViewOf(y), x);\r
- }\r
-\r
- // Insert x into list before first occurrence of y (or throw\r
- // NullReferenceException)\r
- \r
- public static void InsertBeforeFirst<T>(IList<T> list, T x, T y) {\r
- list.Insert(list.ViewOf(y).Slide(0, 0), x);\r
- }\r
-\r
- // Insert x into list after last occurrence of y (or throw\r
- // NullReferenceException).\r
- \r
- public static void InsertAfterLast<T>(IList<T> list, T x, T y) {\r
- list.Insert(list.LastViewOf(y), x);\r
- }\r
-\r
- // Insert x into list before last occurrence of y (or throw\r
- // NullReferenceException)\r
- \r
- public static void InsertBeforeLast<T>(IList<T> list, T x, T y) {\r
- list.Insert(list.LastViewOf(y).Slide(0, 0), x);\r
- }\r
-\r
- // Same meaning as InsertBeforeFirst on a proper list, but not on\r
- // a view\r
-\r
- public static void InsertBeforeFirstAlt<T>(IList<T> list, T x, T y) {\r
- list.ViewOf(y).InsertFirst(x);\r
- }\r
-\r
- // Delete the sequence predecessor of first y; or throw exception\r
-\r
- public static T RemovePredecessorOfFirst<T>(IList<T> list, T y) {\r
- return list.ViewOf(y).Slide(-1).Remove();\r
- }\r
-\r
- // Delete the sequence successor of first y; or throw exception\r
-\r
- public static T RemoveSuccessorOfFirst<T>(IList<T> list, T y) {\r
- return list.ViewOf(y).Slide(+1).Remove();\r
- }\r
-\r
- // --- Other view patterns --------------------------------------\r
-\r
- // Replace the first occurrence of each x from xs by y in list:\r
- \r
- public static void ReplaceXsByY<T>(HashedLinkedList<T> list, T[] xs, T y) {\r
- foreach (T x in xs) {\r
- using (IList<T> view = list.ViewOf(x)) {\r
- if (view != null) { \r
- view.Remove();\r
- view.Add(y);\r
- }\r
- }\r
- }\r
- }\r
-\r
- // Get index in underlying list of view's left end\r
- \r
- public static int LeftEndIndex<T>(IList<T> view) { \r
- return view.Offset;\r
- }\r
-\r
- // Get index in underlying list of view's right end\r
-\r
- public static int RightEndIndex<T>(IList<T> view) { \r
- return view.Offset + view.Count;\r
- }\r
-\r
- // Test whether views overlap \r
-\r
- public static bool Overlap<T>(IList<T> u, IList<T> w) { \r
- if (u.Underlying == null || u.Underlying != w.Underlying) \r
- throw new ArgumentException("views must have same underlying list");\r
- else\r
- return u.Offset < w.Offset+w.Count && w.Offset < u.Offset+u.Count;\r
- }\r
-\r
- // Find the length of the overlap between two views\r
-\r
- public static int OverlapLength<T>(IList<T> u, IList<T> w) { \r
- if (Overlap(u, w))\r
- return Math.Min(u.Offset+u.Count, w.Offset+w.Count) \r
- - Math.Max(u.Offset, w.Offset);\r
- else\r
- return -1; // No overlap\r
- }\r
-\r
- // Test whether view u contains view v \r
-\r
- public static bool ContainsView<T>(IList<T> u, IList<T> w) { \r
- if (u.Underlying == null || u.Underlying != w.Underlying) \r
- throw new ArgumentException("views must have same underlying list");\r
- else\r
- if (w.Count > 0)\r
- return u.Offset <= w.Offset && w.Offset+w.Count <= u.Offset+u.Count;\r
- else\r
- return u.Offset < w.Offset && w.Offset < u.Offset+u.Count;\r
- }\r
-\r
- // Test whether views u and v have (or are) the same underlying list\r
-\r
- public static bool SameUnderlying<T>(IList<T> u, IList<T> w) { \r
- return (u.Underlying ?? u) == (w.Underlying ?? w);\r
- }\r
-\r
- // Find the index of the first item that satisfies p\r
-\r
- public static int FindFirstIndex<T>(IList<T> list, Fun<T,bool> p) {\r
- using (IList<T> view = list.View(0, 0)) {\r
- while (view.TrySlide(0, 1)) {\r
- if (p(view.First)) \r
- return view.Offset;\r
- view.Slide(+1, 0);\r
- }\r
- }\r
- return -1;\r
- }\r
-\r
- // Find the index of the last item that satisfies p\r
- \r
- public static int FindLastIndex<T>(IList<T> list, Fun<T,bool> p) {\r
- using (IList<T> view = list.View(list.Count, 0)) {\r
- while (view.TrySlide(-1, 1)) {\r
- if (p(view.First)) \r
- return view.Offset;\r
- }\r
- }\r
- return -1;\r
- }\r
-\r
- // Yield indexes of all items equal to x, in list order:\r
-\r
- public static SCG.IEnumerable<int> IndexesOf<T>(IList<T> list, T x) { \r
- IList<T> tail = list.View(0, list.Count);\r
- tail = tail.ViewOf(x);\r
- while (tail != null) {\r
- yield return tail.Offset;\r
- tail = tail.Slide(+1,0).Span(list);\r
- tail = tail.ViewOf(x); \r
- }\r
- }\r
-\r
- // Yield indexes of items equal to x, in reverse list order.\r
-\r
- public static SCG.IEnumerable<int> ReverseIndexesOf<T>(IList<T> list, T x) {\r
- IList<T> head = list.View(0, list.Count);\r
- head = head.LastViewOf(x);\r
- while (head != null) {\r
- yield return head.Offset;\r
- head = list.Span(head.Slide(0,0));\r
- head = head.LastViewOf(x);\r
- }\r
- }\r
-\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: Views 2004-12-29 OBSOLETE\r
-\r
-// Compile with \r
-// csc /r:C5.dll Views.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace Views {\r
- class Views {\r
- public static void Main(String[] args) {\r
- IList<char> lst = new LinkedList<char>();\r
- lst.AddAll<char>(new char[] { 'a', 'b', 'c', 'd' });\r
- IList<char> \r
- A = lst.View(0, 2),\r
- B = lst.View(2, 0),\r
- C = lst.View(2, 1),\r
- D = lst.View(3, 1),\r
- E = lst.View(4, 0),\r
- F = lst.View(1, 2),\r
- G = lst.View(0, 4);\r
- IList<char>[] views = { A, B, C, D, E, F, G };\r
- Console.WriteLine("ABCDEFG overlaps with:");\r
- foreach (IList<char> u in views) {\r
- foreach (IList<char> w in views) \r
- Console.Write(Overlap(u, w) ? '+' : '-');\r
- Console.WriteLine();\r
- } \r
- Console.WriteLine("ABCDEFG overlap length:");\r
- foreach (IList<char> u in views) {\r
- foreach (IList<char> w in views) {\r
- int len = OverlapLength(u, w);\r
- Console.Write(len >= 0 ? String.Format("{0}", len) : " ");\r
- }\r
- Console.WriteLine();\r
- } \r
- Console.WriteLine("ABCDEFG contained in:");\r
- foreach (IList<char> u in views) {\r
- foreach (IList<char> w in views) \r
- Console.Write(ContainsView(u, w) ? '+' : '-');\r
- Console.WriteLine();\r
- } \r
- }\r
- \r
- public static int LeftEndIndex<T>(IList<T> u) { \r
- return u.Offset;\r
- }\r
-\r
- public static int RightEndIndex<T>(IList<T> u) { \r
- return u.Offset+u.Count;\r
- }\r
-\r
- public static bool Overlap<T>(IList<T> u, IList<T> w) { \r
- if (u.Underlying == null || u.Underlying != w.Underlying) \r
- throw new ArgumentException("views must have same underlying list");\r
- else\r
- return u.Offset < w.Offset+w.Count && w.Offset < u.Offset+u.Count;\r
- }\r
-\r
- public static int OverlapLength<T>(IList<T> u, IList<T> w) { \r
- if (Overlap(u, w))\r
- return Math.Min(u.Offset+u.Count, w.Offset+w.Count) \r
- - Math.Max(u.Offset, w.Offset);\r
- else\r
- return -1; // No overlap\r
- }\r
-\r
- public static bool ContainsView<T>(IList<T> u, IList<T> w) { \r
- if (u.Underlying == null || u.Underlying != w.Underlying) \r
- throw new ArgumentException("views must have same underlying list");\r
- else\r
- if (w.Count > 0)\r
- return u.Offset <= w.Offset && w.Offset+w.Count <= u.Offset+u.Count;\r
- else\r
- return u.Offset < w.Offset && w.Offset < u.Offset+u.Count;\r
- }\r
-\r
- public static bool SameUnderlying<T>(IList<T> u, IList<T> w) { \r
- return (u.Underlying ?? u) == (w.Underlying ?? w);\r
- }\r
-\r
- // Replace the first occurrence of each x from xs by y in list:\r
- \r
- public static void ReplaceXsByY<T>(HashedLinkedList<T> list, T[] xs, T y) {\r
- foreach (T x in xs) {\r
- using (IList<T> view = list.ViewOf(x)) {\r
- if (view != null) { \r
- view.Remove();\r
- view.Add(y);\r
- }\r
- }\r
- }\r
- }\r
-\r
- // Find first item that satisfies p\r
-\r
- public static bool Find<T>(IList<T> list, Fun<T,bool> p, out T res) {\r
- IList<T> view = list.View(0, 0);\r
- while (view.Offset < list.Count) {\r
- view.Slide(+1, 1);\r
- if (p(view.First)) {\r
- res = view.First;\r
- return true;\r
- }\r
- }\r
- res = default(T);\r
- return false;\r
- }\r
-\r
- // Or, using that the list is enumerable:\r
-\r
- public static bool Find1<T>(IList<T> list, Fun<T,bool> p, out T res) {\r
- foreach (T x in list) { \r
- if (p(x)) {\r
- res = x;\r
- return true;\r
- }\r
- }\r
- res = default(T);\r
- return false;\r
- }\r
-\r
- // Find last item that satisfies p\r
-\r
- public static bool FindLast<T>(IList<T> list, Fun<T,bool> p, out T res) {\r
- IList<T> view = list.View(list.Count, 0);\r
- while (view.Offset > 0) {\r
- view.Slide(-1, 1);\r
- if (p(view.First)) {\r
- res = view.First;\r
- return true;\r
- }\r
- }\r
- res = default(T);\r
- return false;\r
- }\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// C5 example: WrappedArray 2005-07-21\r
-\r
-// Compile with \r
-// csc /r:C5.dll WrappedArray.cs \r
-\r
-using System;\r
-using C5;\r
-using SCG = System.Collections.Generic;\r
-\r
-namespace WrappedArray {\r
- class WrappedArray {\r
- public static void Main(String[] args) {\r
- }\r
-\r
-\r
- // System.Array.Exists\r
-\r
- public static bool Exists<T>(T[] arr, Fun<T,bool> p) {\r
- return new WrappedArray<T>(arr).Exists(p);\r
- } \r
-\r
- // System.Array.TrueForAll\r
-\r
- public static bool TrueForAll<T>(T[] arr, Fun<T,bool> p) {\r
- return new WrappedArray<T>(arr).All(p);\r
- } \r
-\r
- // System.Array.Find(T[], Predicate)\r
- // This loses the valuable bool returned by C5 Find.\r
-\r
- public static T Find<T>(T[] arr, Fun<T,bool> p) {\r
- T res; \r
- new WrappedArray<T>(arr).Find(p, out res);\r
- return res;\r
- } \r
-\r
- // System.Array.FindAll(T[], Predicate)\r
-\r
- public static T[] FindAll<T>(T[] arr, Fun<T,bool> p) {\r
- return new WrappedArray<T>(arr).FindAll(p).ToArray();\r
- } \r
-\r
- // System.Array.FindIndex(T[], Predicate)\r
-\r
- public static int FindIndex<T>(T[] arr, Fun<T,bool> p) {\r
- return new WrappedArray<T>(arr).FindIndex(p);\r
- } \r
-\r
- // System.Array.FindIndex(T[], int, Predicate)\r
-\r
- public static int FindIndex<T>(T[] arr, int i, Fun<T,bool> p) {\r
- int j = new WrappedArray<T>(arr).View(i,arr.Length-i).FindIndex(p);\r
- return j < 0 ? j : j+i;\r
- } \r
-\r
- // System.Array.FindIndex(T[], int, int, Predicate)\r
-\r
- public static int FindIndex<T>(T[] arr, int i, int n, Fun<T,bool> p) {\r
- int j = new WrappedArray<T>(arr).View(i,n).FindIndex(p);\r
- return j < 0 ? j : j+i;\r
- } \r
-\r
- // System.Array.FindLast(T[], Predicate)\r
- // This loses the valuable bool returned by C5 Find.\r
-\r
- public static T FindLast<T>(T[] arr, Fun<T,bool> p) {\r
- T res; \r
- new WrappedArray<T>(arr).FindLast(p, out res);\r
- return res;\r
- } \r
-\r
- // System.Array.FindLastIndex(T[], Predicate)\r
-\r
- public static int FindLastIndex<T>(T[] arr, Fun<T,bool> p) {\r
- return new WrappedArray<T>(arr).FindIndex(p);\r
- } \r
-\r
- // System.Array.FindLastIndex(T[], int, Predicate)\r
-\r
- public static int FindLastIndex<T>(T[] arr, int i, Fun<T,bool> p) {\r
- int j = new WrappedArray<T>(arr).View(i,arr.Length-i).FindIndex(p);\r
- return j < 0 ? j : j+i;\r
- } \r
-\r
- // System.Array.FindLastIndex(T[], int, int, Predicate)\r
-\r
- public static int FindLastIndex<T>(T[] arr, int i, int n, Fun<T,bool> p) {\r
- int j = new WrappedArray<T>(arr).View(i,n).FindIndex(p);\r
- return j < 0 ? j : j+i;\r
- } \r
- \r
- // System.Array.ForEach(T[], Action)\r
-\r
- public static void ForEach<T>(T[] arr, Act<T> act) {\r
- new WrappedArray<T>(arr).Apply(act);\r
- } \r
-\r
- // System.Array.IndexOf(T[], T)\r
-\r
- public static int IndexOf<T>(T[] arr, T x) {\r
- int j = new WrappedArray<T>(arr).IndexOf(x);\r
- return j < 0 ? -1 : j;\r
- } \r
- \r
- // System.Array.IndexOf(T[], T, int)\r
-\r
- public static int IndexOf<T>(T[] arr, T x, int i) {\r
- int j = new WrappedArray<T>(arr).View(i, arr.Length-i).IndexOf(x);\r
- return j < 0 ? -1 : j+i;\r
- } \r
- \r
- // System.Array.IndexOf(T[], T, int, int)\r
-\r
- public static int IndexOf<T>(T[] arr, T x, int i, int n) {\r
- int j = new WrappedArray<T>(arr).View(i, n).IndexOf(x);\r
- return j < 0 ? -1 : j+i;\r
- } \r
-\r
- // System.Array.LastIndexOf(T[], T)\r
-\r
- public static int LastIndexOf<T>(T[] arr, T x) {\r
- int j = new WrappedArray<T>(arr).LastIndexOf(x);\r
- return j < 0 ? -1 : j;\r
- } \r
- \r
- // System.Array.LastIndexOf(T[], T, int)\r
-\r
- public static int LastIndexOf<T>(T[] arr, T x, int i) {\r
- int j = new WrappedArray<T>(arr).View(i, arr.Length-i).LastIndexOf(x);\r
- return j < 0 ? -1 : j+i;\r
- } \r
- \r
- // System.Array.LastIndexOf(T[], T, int, int)\r
-\r
- public static int LastIndexOf<T>(T[] arr, T x, int i, int n) {\r
- int j = new WrappedArray<T>(arr).View(i, n).LastIndexOf(x);\r
- return j < 0 ? -1 : j+i;\r
- } \r
-\r
- // System.Array.Sort(T[])\r
-\r
- public static void Sort<T>(T[] arr) {\r
- new WrappedArray<T>(arr).Sort();\r
- } \r
-\r
- // System.Array.Sort(T[], int, int)\r
-\r
- public static void Sort<T>(T[] arr, int i, int n) {\r
- new WrappedArray<T>(arr).View(i, n).Sort();\r
- } \r
-\r
- // System.Array.Sort(T[], SCG.IComparer<T>)\r
-\r
- public static void Sort<T>(T[] arr, SCG.IComparer<T> cmp) {\r
- new WrappedArray<T>(arr).Sort(cmp);\r
- } \r
- \r
- // System.Array.Sort(T[], int, int, SCG.IComparer<T>)\r
-\r
- public static void Sort<T>(T[] arr, int i, int n, SCG.IComparer<T> cmp) {\r
- new WrappedArray<T>(arr).View(i, n).Sort(cmp);\r
- } \r
- \r
- // System.Array.Sort(T[], Comparison)\r
-\r
- public static void Sort<T>(T[] arr, Comparison<T> csn) {\r
- new WrappedArray<T>(arr).Sort(new DelegateComparer<T>(csn));\r
- } \r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System.Reflection;\r
-using System.Runtime.CompilerServices;\r
-\r
-//\r
-// General Information about an assembly is controlled through the following \r
-// set of attributes. Change these attribute values to modify the information\r
-// associated with an assembly.\r
-//\r
-[assembly: AssemblyTitle("")]\r
-[assembly: AssemblyDescription("")]\r
-[assembly: AssemblyConfiguration("")]\r
-[assembly: AssemblyCompany("")]\r
-[assembly: AssemblyProduct("")]\r
-[assembly: AssemblyCopyright("")]\r
-[assembly: AssemblyTrademark("")]\r
-[assembly: AssemblyCulture("")]\r
-\r
-//\r
-// Version information for an assembly consists of the following four values:\r
-//\r
-// Major Version\r
-// Minor Version \r
-// Build Number\r
-// Revision\r
-//\r
-// You can specify all the values or you can default the Revision and Build Numbers \r
-// by using the '*' as shown below:\r
-\r
-[assembly: AssemblyVersion("1.0.*")]\r
-\r
-//\r
-// In order to sign your assembly you must specify a key to use. Refer to the \r
-// Microsoft .NET Framework documentation for more information on assembly signing.\r
-//\r
-// Use the attributes below to control which key is used for signing. \r
-//\r
-// Notes: \r
-// (*) If no key is specified, the assembly is not signed.\r
-// (*) KeyName refers to a key that has been installed in the Crypto Service\r
-// Provider (CSP) on your machine. KeyFile refers to a file which contains\r
-// a key.\r
-// (*) If the KeyFile and the KeyName values are both specified, the \r
-// following processing occurs:\r
-// (1) If the KeyName can be found in the CSP, that key is used.\r
-// (2) If the KeyName does not exist and the KeyFile does exist, the key \r
-// in the KeyFile is installed into the CSP and used.\r
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.\r
-// When specifying the KeyFile, the location of the KeyFile should be\r
-// relative to the project output directory which is\r
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is\r
-// located in the project directory, you would specify the AssemblyKeyFile \r
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]\r
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework\r
-// documentation for more information on this.\r
-//\r
-[assembly: AssemblyDelaySign(false)]\r
-[assembly: AssemblyKeyFile("")]\r
-[assembly: AssemblyKeyName("")]\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using MSG = System.Collections.Generic;\r
-\r
-namespace Try\r
-{\r
-/*\r
- /// <summary>\r
- /// Affenpinscher \r
- /// </summary>\r
- public class SSS<T,U>\r
- {\r
- /// <summary>\r
- /// GGGGGGG <cell>tidlig <seealso cref="T:Try.Foo!3"/> <b alk="foo">bonny</b> namse</cell> efter\r
- /// </summary>\r
- /// <param name="u">zeU</param>\r
- /// <param name="cell">zeI</param>\r
- /// <param name="t">zeT</param>\r
- /// <returns>zeReturn</returns>\r
- public static T g(out U u, ref int cell, T t) { u = default(U); return default(T); }\r
- \r
- /// <summary>\r
- /// Nested klasse\r
- /// </summary>\r
- public class Inner<K>\r
- {\r
- /// <summary>\r
- /// IIIIIIIIII\r
- /// </summary>\r
- /// <param name="t">TTTTTTTTTT</param>\r
- /// <param name="k">KKKKKKK</param>\r
- /// <returns>RRRRRRRRRRR</returns>\r
- public U indre(T t, K k) { return default(U); }\r
- }\r
- /// <summary>\r
- /// Jaj ja\r
- /// </summary>\r
- public class NongenNested\r
- {\r
- /// <summary>\r
- /// Det er et y\r
- /// </summary>\r
- public int y;\r
- }\r
- /// <summary>\r
- /// Lolololola\r
- /// </summary>\r
- public U lefield;\r
- /// <summary>\r
- /// Cococococola\r
- /// </summary>\r
- public static Foo<T,U,U> gramse;\r
- /// <summary>\r
- /// zesum\r
- /// </summary>\r
- /// <value>zeval</value>\r
- public SSS<T,T> leprop { get { return default(SSS<T,T>); } }\r
- /// <summary>\r
- /// Sju\r
- /// </summary>\r
- /// <param name="f">ffffffff</param>\r
- /// <param name="johndoe">ffffffff</param>\r
- public string s<V,X,Y,Z>(Foo<T,Y,SSS<Z,T>> f, int johndoe) { return "7"; }\r
- /// <summary>\r
- /// intuism\r
- /// </summary>\r
- /// <param name="tudse">froe</param>\r
- /// <param name="frank">sin</param>\r
- public SSS(T[] tudse, double frank) { }\r
- }\r
-\r
- /// <summary>\r
- /// ooh \r
- /// </summary>\r
-\r
- public class HHH\r
- {\r
- /// <summary>\r
- /// MusseKom\r
- /// </summary>\r
- public class Musse { }\r
- }\r
-\r
-\r
-\r
- /// <summary>\r
- /// Hejsa \r
- /// </summary>\r
- public class Foo<K,L,M> { }\r
-\r
-*/\r
- /// <summary>\r
- /// Hejsa\r
- /// </summary>\r
- public delegate void Mapper<T,U>(T t);\r
-\r
-\r
-\r
- /// <summary>\r
- /// Los accoutables\r
- /// </summary>\r
- public interface IEnumerable<T>\r
- {\r
- // <summary>\r
- // getegetegeteg\r
- // </summary>\r
- // <returns>leturn</returns>\r
- //MSG.IEnumerator<T> GetEnumerator();\r
-\r
-\r
- /// <summary>\r
- /// Apply a delegate to all items of this collection.\r
- /// </summary>\r
- /// <param name="a">The delegate to apply</param>\r
- void Map<U>(Mapper<T,U> a);\r
- }\r
-}\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-using System;\r
-using System.IO;\r
-using System.Reflection;\r
-using System.Xml;\r
-using System.Diagnostics;\r
-\r
-namespace DocNet\r
-{\r
- class Timer\r
- {\r
- static System.Diagnostics.Process p;\r
-\r
- static long sws;\r
-\r
- static long svm;\r
-\r
- static double stt;\r
-\r
- static DateTime swc;\r
-\r
- public long ws;\r
-\r
- public long vm;\r
-\r
- public double tt;\r
-\r
- public DateTime wc;\r
-\r
- public double deltat;\r
-\r
- public double deltac;\r
-\r
-\r
- public Timer()\r
- {\r
- if (p == null)\r
- {\r
- p = System.Diagnostics.Process.GetCurrentProcess();\r
- stt = p.TotalProcessorTime.TotalMilliseconds;\r
- sws = p.WorkingSet64;\r
- svm = p.VirtualMemorySize64;\r
- swc = DateTime.Now;\r
- }\r
- }\r
-\r
-\r
- public double snap()\r
- {\r
- double oldt = tt;\r
- DateTime oldc = wc; p.Refresh();\r
- tt = p.TotalProcessorTime.TotalMilliseconds - stt;\r
- deltat = tt - oldt;\r
- ws = p.WorkingSet64 - sws;\r
- vm = p.VirtualMemorySize64 - svm;\r
- wc = DateTime.Now;\r
-\r
- TimeSpan x = oldc.Subtract(wc);\r
-\r
- deltac = -x.TotalMilliseconds;\r
- return deltac;\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <PropertyGroup>\r
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
- <ProductVersion>8.0.40607</ProductVersion>\r
- <SchemaVersion>2.0</SchemaVersion>\r
- <ProjectGuid>{42811A81-6A99-4C7A-A6DA-DF104C767B72}</ProjectGuid>\r
- <OutputType>Exe</OutputType>\r
- <StartupObject>\r
- </StartupObject>\r
- <RootNamespace>docNet</RootNamespace>\r
- <NoStandardLibraries>false</NoStandardLibraries>\r
- <AssemblyName>docNet</AssemblyName>\r
- <FileUpgradeFlags>\r
- </FileUpgradeFlags>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">\r
- <DebugSymbols>true</DebugSymbols>\r
- <Optimize>false</Optimize>\r
- <OutputPath>.\bin\Debug\</OutputPath>\r
- <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>\r
- <DefineConstants>DEBUG</DefineConstants>\r
- <WarningLevel>4</WarningLevel>\r
- <IncrementalBuild>false</IncrementalBuild>\r
- <DocumentationFile>docnet.xml</DocumentationFile>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">\r
- <DebugSymbols>false</DebugSymbols>\r
- <Optimize>true</Optimize>\r
- <OutputPath>.\bin\Release\</OutputPath>\r
- <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>\r
- <DefineConstants>TRACE</DefineConstants>\r
- <WarningLevel>4</WarningLevel>\r
- <IncrementalBuild>false</IncrementalBuild>\r
- </PropertyGroup>\r
- <ItemGroup>\r
- <Reference Include="System" />\r
- <Reference Include="System.Xml">\r
- <HintPath>..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.2.30703\System.XML.dll</HintPath>\r
- <Name>System.XML</Name>\r
- </Reference>\r
- <ProjectReference Include="..\C5\C5.csproj">\r
- <Project>{D70489CD-ABDA-48FF-BD1E-BE3F7495BE71}</Project>\r
- <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package>\r
- <Name>C5</Name>\r
- </ProjectReference>\r
- </ItemGroup>\r
- <ItemGroup>\r
- <Compile Include="AssemblyInfo.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="docnet.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Content Include="docbuild\banner.htm" />\r
- <Content Include="docbuild\docnet.css" />\r
- <Content Include="docbuild\frames.htm" />\r
- <Content Include="docbuild\litterature.htm" />\r
- <Content Include="docbuild\userguide.htm" />\r
- <Content Include="overview.xslt" />\r
- <Compile Include="Test.cs">\r
- <SubType>Code</SubType>\r
- </Compile>\r
- <Compile Include="Timer.cs" />\r
- <Content Include="trans.xslt" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <None Include="dodoc.cmd" />\r
- <None Include="mkcurrent.cmd" />\r
- </ItemGroup>\r
- <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />\r
- <PropertyGroup>\r
- <PreBuildEvent>\r
- </PreBuildEvent>\r
- <PostBuildEvent>\r
- </PostBuildEvent>\r
- <ApplicationIcon>\r
- </ApplicationIcon>\r
- </PropertyGroup>\r
- <ProjectExtensions>\r
- <VisualStudio>\r
- </VisualStudio>\r
- </ProjectExtensions>\r
-</Project>
\ No newline at end of file
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
-<html >\r
-<head>\r
- <link rel="stylesheet" type="text/css" href="docnet.css">\r
-</head>\r
-<body>\r
- <p>\r
- <font size="6"><b>C5 documentation</b></font> Legend: <code class="greenbg">A</code>:\r
- abstract, <code class="greenbg">F</code>: final, <code class="greenbg">N</code>:\r
- non-virtual, <code class="greenbg">P</code>: protected, <code class="greenbg">S</code>:\r
- static. <a href="userguide.htm" target="_blank">User's Guide</a></p>\r
-</body>\r
-</html>\r
+++ /dev/null
-BODY\r
-{\r
- FONT-FAMILY: "Verdana", sans-serif;\r
- FONT-SIZE: x-small;\r
-}\r
-CODE \r
-{\r
- FONT-SIZE: x-small;\r
-}\r
-A:link\r
-{\r
- COLOR: #4e4887\r
-}\r
-A:visited\r
-{\r
- COLOR: #8080c8\r
-}\r
-A:active\r
-{\r
- COLOR: #f16043\r
-}\r
-A:hover\r
-{\r
- COLOR: #f16043\r
-}\r
-P\r
-{\r
- MARGIN-BOTTOM: 0.5em;\r
- MARGIN-TOP: 0.5em\r
-}\r
-.greenbg\r
-{\r
- BACKGROUND-COLOR: #00ff00;\r
- font-weight:bold\r
-}\r
-TABLE\r
-{\r
- BORDER-BOTTOM: medium none;\r
- BORDER-LEFT: medium none;\r
- BORDER-RIGHT: medium none;\r
- BORDER-TOP: medium none;\r
-}\r
-TD\r
-{\r
- BACKGROUND-COLOR: #bedfff;\r
- BORDER-BOTTOM: medium none;\r
- BORDER-LEFT: medium none;\r
- BORDER-RIGHT: medium none;\r
- BORDER-TOP: medium none;\r
- FONT-SIZE:x-small;\r
- MARGIN: 2px;\r
- PADDING-BOTTOM: 2px;\r
- PADDING-LEFT: 2px;\r
- PADDING-RIGHT: 2px;\r
- PADDING-TOP: 2px;\r
- TEXT-ALIGN: left\r
-}\r
-TH\r
-{\r
- BACKGROUND-COLOR: #ffdfbe;\r
- BORDER-BOTTOM: medium none;\r
- BORDER-LEFT: medium none;\r
- BORDER-RIGHT: medium none;\r
- BORDER-TOP: medium none;\r
- FONT-SIZE: x-small;\r
- MARGIN: 2px;\r
- PADDING-BOTTOM: 2px;\r
- PADDING-LEFT: 2px;\r
- PADDING-RIGHT: 2px;\r
- PADDING-TOP: 2px;\r
- TEXT-ALIGN: left\r
-}\r
-TH\r
-{\r
- BACKGROUND-COLOR: #ffaa57\r
-}\r
-UL\r
-{\r
- MARGIN-TOP: 0.5em\r
-}\r
-OL\r
-{\r
- MARGIN-TOP: 0.5em\r
-}\r
-H1\r
-{\r
- COLOR: #336699;\r
- FONT-SIZE: x-large;\r
- MARGIN-BOTTOM: 0.5em;\r
- MARGIN-TOP: 1em;\r
- PADDING-LEFT: 4px\r
-}\r
-H2\r
-{\r
- BORDER-LEFT: #4e4887 8px solid;\r
- BORDER-TOP: #4e4887 1px solid;\r
- COLOR: #4e4887;\r
- FONT-SIZE: medium;\r
- MARGIN-BOTTOM: 0.5em;\r
- MARGIN-TOP: 1em;\r
- PADDING-LEFT: 4px\r
-}\r
-H3\r
-{\r
- BORDER-LEFT: #4e4887 4px solid;\r
- BORDER-TOP: #4e4887 1px solid;\r
- COLOR: #4e4887;\r
- FONT-SIZE: small;\r
- MARGIN-BOTTOM: 0.5em;\r
- MARGIN-TOP: 1em;\r
- PADDING-LEFT: 4px\r
-}\r
-H4\r
-{\r
- COLOR: #4e4887;\r
- FONT-SIZE: small;\r
- MARGIN-BOTTOM: 0.5em\r
-}\r
-H5\r
-{\r
- COLOR: #4e4887;\r
- FONT-SIZE: x-small;\r
- MARGIN-BOTTOM: 0.5em\r
-}\r
-H6\r
-{\r
- COLOR: #4e4887;\r
- FONT-SIZE: x-small;\r
- FONT-STYLE: italic;\r
- MARGIN-BOTTOM: 0.5em\r
-}\r
+++ /dev/null
-<html>\r
-<frameset rows="84,*">\r
- <frame name="banner" scrolling="no" noresize src="banner.htm">\r
- <frameset cols="200,*">\r
- <frame name="contents" src="contents.htm">\r
- <frame name="main" >\r
- </frameset>\r
- <noframes>\r
- <p>This page requires frames, but your browser does not support them.</p>\r
- </noframes>\r
-</frameset>\r
-</html>\r
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
-<html>\r
-<head>\r
-<title>C5 collection classes - litterature references</title>\r
-<meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0">\r
-<meta name=ProgId content=VisualStudio.HTML>\r
-<meta name=Originator content="Microsoft Visual Studio.NET 7.0">\r
-</head>\r
-<body>\r
-<h1>C5 collection classes - litterature references</h1>\r
-<table border="1" cellspacing="0">\r
- <tr>\r
- <td>\r
- <a name="CLRS">CLRS</a></td>\r
- <td>Cormen, Leiserson, Rivest, Shamir: ...</td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name="DSST">DSST</a></td>\r
- <td>D, Sarnak, Sleator, Tarjan, ...</td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name="Tarjan1">Tarjan1</a>Tarjan: (the booklet)</td>\r
- <td></td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name=""></a></td>\r
- <td></td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name=""></a></td>\r
- <td></td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name=""></a></td>\r
- <td></td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name=""></a></td>\r
- <td></td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name=""></a></td>\r
- <td></td>\r
- </tr>\r
- <tr>\r
- <td>\r
- <a name=""></a></td>\r
- <td></td>\r
- </tr>\r
-</table>\r
-\r
-\r
-</body>\r
-</html>\r
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\r
-<html>\r
-<head>\r
- <title>C5 User's Guide</title>\r
- <style>\r
-<!--\r
-.revvid { color: #FFFFFF; background-color: #00AA00; font-weight: bold }\r
--->\r
- </style>\r
-</head>\r
-<body>\r
-<h1><a class="mozTocH1" name="mozTocId905770"></a>C5 User's guide for\r
-prerelease version 0.5</h1>\r
-<h2><a class="mozTocH2" name="mozTocId507311"></a>Table of contents</h2>\r
-<ul class="readonly" id="mozToc">\r
-<!--mozToc h1 1 h2 2 h3 3 h4 4 h5 5 h6 6--><li><a href="#mozTocId905770">C5\r
-User's guide for prerelease version 0.5</a>\r
- <ul>\r
- <li><a href="#mozTocId507311">Table of contents</a></li>\r
- </ul>\r
- </li>\r
- <li><a href="#mozTocId564527">Overview</a></li>\r
- <li><a href="#mozTocId86956">Interfaces</a>\r
- <ul>\r
- <li><a href="#mozTocId21725">"Proper" collection interfaces</a></li>\r
- <li><a href="#mozTocId721827">Dictionary interfaces</a></li>\r
- <li><a href="#mozTocId908053">Query result interfaces</a></li>\r
- </ul>\r
- </li>\r
- <li><a href="#mozTocId110895">To construct a collection</a>\r
- <ul>\r
- <li><a href="#mozTocId850165">To use an external equalityComparer</a></li>\r
- <li><a href="#mozTocId162938">To use an external comparer</a></li>\r
- <li><a href="#mozTocId957374">To make collections of collections</a></li>\r
- </ul>\r
- </li>\r
- <li><a href="#mozTocId486186">Special topics</a>\r
- <ul>\r
- <li><a href="#mozTocId48263">To choose a set or bag collection</a></li>\r
- <li><a href="#mozTocId929755">To work on part of a list: list\r
-views</a></li>\r
- <li><a href="#mozTocId650306">To work with persistent red-black\r
-trees</a></li>\r
- <li><a href="#mozTocId553609">To implement new collection classes\r
-or subclass an existing one</a></li>\r
- <li><a href="#mozTocId753674">To present a read only view of a\r
-collection</a></li>\r
- </ul>\r
- </li>\r
- <li><a href="#mozTocId6619">Collection classes by data structure/class</a></li>\r
- <li><a href="#mozTocId393559">Planned architecture or interface\r
-changes for first release</a></li>\r
- <li><a href="#mozTocId336849">Performance details for proper\r
-collection classes</a></li>\r
- <li><a href="#mozTocId712409">Performance details for dictionary\r
-classes</a></li>\r
-</ul>\r
-<h1><a class="mozTocH1" name="mozTocId564527"></a>Overview<br>\r
-</h1>\r
-<p>C5 is a comprehensive library of collection classes for the <a\r
- href="http://www.ecma-international.org/publications/standards/Ecma-335.htm">Common\r
-Language Infrastructure</a> (CLI). This guide describes prerelease\r
-version 0.5 of C5. <br>\r
-</p>\r
-<p>C5 is a\r
-refactoring and extension of the <a\r
- href="http://www.dina.kvl.dk/%7Esestoft/gcsharp/index.html#collection">generic\r
-collection classes</a> developed by Peter Sestoft while visiting\r
-Microsoft\r
-Research in Cambridge.</p>\r
-<p> Unless stated otherwise types mentioned below will belong to the\r
-"C5"\r
-namespace; and all code examples assume a "using C5;" clause (and no\r
-"using System.Collection.Generics;" clause).. </p>\r
-<p>The goals in the development of the library has been</p>\r
-<ul>\r
- <li>\r
- <p class="MsoNormal"><span style="" lang="EN-US">To create a\r
-library of collection classes for the CLI that can assist expert and\r
-non-expert programmers on the platform to develop correct and efficient\r
-applications.</span> </p>\r
- </li>\r
- <li>\r
- <p class="MsoNormal"><span style="" lang="EN-US">The library should\r
-at least fill the gaps in the standard “System.Collections.Generics”\r
-namespace compared to standard collection class libraries for related\r
-object oriented languages like Java, and utilize the new facilities for\r
-generic </span><span style="" lang="EN-US">programming. Microsoft\r
-recently (mid 2004) seems to have changed their minds and ntend to\r
-bridge that gap in the beta2 version of VS 2005 due at the end of 2004.</span>\r
- </p>\r
- </li>\r
-</ul>\r
-<p>In order to fulfill the efficiency goal, the library utilizes\r
-first-class <a href="#datastructures">data structures</a>\r
-inside its collection classes. The library has been constructed with\r
-the modern\r
-object oriented programming principle of "<a href="#Interfaces">code\r
-to interfaces, not to implementations</a>" in mind, while the interface\r
-architecture has been carefully crafted to reflect the efficient data\r
-structures\r
-actually existence.</p>\r
-<p>A collection in the sense of this library is a plain "collection of\r
-items of a single type". A collection does not impose any other logical\r
-structure on its items than perhaps uniqueness or sequence ordering.</p>\r
-<p>The main division line among the collection classes of this library\r
-is the\r
-distinction between <a href="#Proper%20collection%20interfaces">"proper"\r
-collections</a> and <a href="#Dictionary%20interfaces">dictionaries</a>.\r
-A\r
-dictionary is a class that defines a partial function (or map) from one\r
-item\r
-type (the keys) to another one (the values). A dictionary can be viewed\r
-as a\r
-collection of (key,value) pairs having the property of defining a\r
-partial\r
-function.</p>\r
-<p>The item type for the collection classes are always given by generic\r
-parameters. For a proper collection, there will be a single parameter,\r
-customarily called T, as in HashSet<T>. For a dictionary there\r
-will be two - the key and value types -\r
-as in HashDictionary<K,V>.</p>\r
-<p>A collection class, or rather the data structure inside, can be\r
-either\r
-equality based or comparison based. An equality based collection will\r
-have an\r
-associated so-called equalityComparer of type <a href="main.htm#T:C5.IEqualityComparer%601">IEqualityComparer<T></a>,\r
-where T is the item type of the collection. A comparison based\r
-collection has an\r
-associated comparer of type <a href="main.htm#T:C5.IComparer%601">IComparer<T></a>.\r
-The section below on <a href="#Constructing">creation</a> of\r
-collection classes\r
-explains how the equalityComparers and comparers are chosen. NB: this design will\r
-be modified soon, cf. <a href="#planned">Planned changes</a>.<br>\r
-</p>\r
-<p>Collection classes in the library have either set or bag semantics.\r
-A set\r
-collection can at most contain one copy of an item, while bag\r
-collections may\r
-contain several. One can programmatically see at runtime if an editable\r
-collection class has set or bag semantics by checking the <a\r
- href="main.htm#P:C5.IExtensible%601.AllowsDuplicates">\r
-AllowsDuplicates</a>\r
-property. At compile time, refer to the <a href="#set%20or%20bag">set\r
-or bag table</a>\r
-below for an overview. <br>\r
-</p>\r
-<h1><a class="mozTocH1" name="mozTocId86956"></a><a name="Interfaces">Interfaces</a></h1>\r
-<p>The C5 library is designed to make it easy to program to interfaces\r
-instead\r
-of implementations. In particular, all public properties and methods of\r
-the\r
-collection classes belong to their implemented interfaces (except for\r
-the odd\r
-special diagnostic method and the odd mistake to be weeded out before\r
-release). The typical programming style\r
-would be</p>\r
-<blockquote>\r
- <p><code>IList<int> lst = new LinkedList<int>();<br>\r
-lst.Add(7);</code></p>\r
-</blockquote>\r
-<p>instead of </p>\r
-<blockquote>\r
- <p><code> LinkedList<int> lst = new LinkedList<int>();<br>\r
-lst.Add(7);</code></p>\r
-</blockquote>\r
-<p>Note that with this programming style, the Add call will be compiled\r
-to an\r
-interface call instead of a (virtual) method call, but interface calls\r
-on the\r
-CLR (at least the Microsoft implementation) are at most very slightly\r
-slower\r
-than virtual calls, so one should not shun the interface style for\r
-performance\r
-reasons.</p>\r
-<p>We will discuss the collection classes available in C5 structured\r
-according\r
-to the main functional interfaces of the <a\r
- href="#Proper%20collection%20interfaces">proper\r
-collections</a>, the <a href="#Dictionary%20interfaces">dictionaries</a>\r
-and the\r
-interfaces of <a href="#Query%20result%20interfaces">query results</a>.</p>\r
-<h2><a class="mozTocH2" name="mozTocId21725"></a><a\r
- name="Proper collection interfaces">"Proper" collection interfaces</a></h2>\r
-<p>The following diagam shows the type hierarchy of the proper\r
-collection classes:</p>\r
-<p><img alt="Interface hierarchy" src="ClsdiagWork.png"\r
- style="width: 757px; height: 498px;"><br>\r
-The most important interfaces - those that are directly\r
-implemented by\r
-collection classes - are listed to the left in this table with a short\r
-description in the middle and all implementing classes to the\r
-right. </p>\r
-<p>Please see also the <a href="#PerformanceProper">complete\r
-complexity table</a>\r
-for more comprehensive guidance.</p>\r
-<p>To identify which classes are equalityComparer or comparer based and which\r
-classes\r
-implement set or bag we use the following symbols:</p>\r
-<table border="1" width="471">\r
- <tbody>\r
- <tr>\r
- <td width="116">set: <code class="revvid">S</code> </td>\r
- <td width="117"> bag: <code class="revvid">B</code> </td>\r
- <td width="117"> equalityComparer: <code class="revvid">H</code> </td>\r
- <td width="117"> comparer: <code class="revvid">C</code> </td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<table border="1" width="100%">\r
- <tbody>\r
- <tr>\r
- <th width="19%">Interface</th>\r
- <th width="52%">Short description</th>\r
- <th width="29%">Implementing classes</th>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="19%"><a\r
- href="main.htm#T:C5.ICollection%601">ICollection<T></a> </td>\r
- <td valign="top" width="52%">This is the fundamental type\r
-of updateable collections. It has operations for searching for\r
-items, for adding, updating and removing one or a bunch of items, for\r
-clearing the collection and transforming the collection to an\r
-array. \r
- <p>If one only needs these operations, the hash set and hash bag\r
-classes are fastest for if we have a equalityComparer for the items and the\r
-red-black tree classes are fastest if we must use a comparer.</p>\r
- </td>\r
- <td valign="top" width="29%"><code class="revvid">SH</code> <a\r
- href="main.htm#T:C5.HashSet%601">HashSet<T></a><br>\r
- <code class="revvid">BH</code> <a\r
- href="main.htm#T:C5.HashBag%601">HashBag<T></a><br>\r
- <code class="revvid">BH</code> <a\r
- href="main.htm#T:C5.LinkedList%601">LinkedList<T></a><br>\r
- <code class="revvid">SH</code> <a\r
- href="main.htm#T:C5.HashedLinkedList%601">HashedLinkedList<T></a><br>\r
- <code class="revvid">BH</code> <a\r
- href="main.htm#T:C5.ArrayList%601">ArrayList<T></a><br>\r
- <code class="revvid">SH</code> <a\r
- href="main.htm#T:C5.HashedArrayList%601"> HashedArrayList<T><br>\r
- </a> <code class="revvid">SC</code> <a\r
- href="main.htm#T:C5.SortedArray%601"> SortedArray<T></a><br>\r
- <code class="revvid">SC</code> <a\r
- href="main.htm#T:C5.TreeSet%601"> TreeSet<T></a><br>\r
- <code class="revvid">BC</code> <a\r
- href="main.htm#T:C5.TreeBag%601"> TreeBag<T></a></td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="19%"><a\r
- href="main.htm#T:C5.IPriorityQueue%601">IPriorityQueue<T></a> </td>\r
- <td valign="top" width="52%">This is a special case in the\r
-library, being the only type of updateable collection interface that\r
-does not implement IEditableCollection<T>. The reason for its\r
-presence is the specialized "heap" data structures for priority queues\r
-that only support these operations.\r
- <p>If one only needs these the priority queue operations and is\r
-satisfied with bag semantics, then IntervalHeap<P> is the\r
-fastest choice. </p>\r
- </td>\r
- <td valign="top" width="29%"> <code class="revvid">BC</code> <a\r
- href="main.htm#T:C5.IntervalHeap%601">IntervalHeap<T></a><br>\r
- <code class="revvid">SC</code> <a\r
- href="main.htm#T:C5.TreeSet%601"> TreeSet<T></a><br>\r
- <code class="revvid">BC</code> <a\r
- href="main.htm#T:C5.TreeBag%601"> TreeBag<T></a></td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="19%"><a href="main.htm#T:C5.IList%601">IList<T></a> </td>\r
- <td valign="top" width="52%">This is an updateable collection\r
-with sequence order imposed on the items by the user at insertion time\r
-or by later rearrangements. \r
- <p>There are two main base data structures: dynamic arrays and\r
-doubly linked lists with very different complexity profile. The\r
-plain linked list is fast for operations at the end points only, while\r
-the plain array list have very fast lookups by index, but update\r
-operations are only fast at the right end point. </p>\r
- <p>The Hashed- variants employ an index based on a hash table.\r
-This speeds up lookups by item considerably and for the linked list\r
-variant also insertions before or after specific items. The index\r
-changes the classes from bags to sets. </p>\r
- <p>The hashed variants more than double the time of otherwise\r
-fast update operations, and should only be used when really\r
-needed. </p>\r
- </td>\r
- <td valign="top" width="29%"> <code class="revvid">BH</code> <a\r
- href="main.htm#T:C5.LinkedList%601"> LinkedList<T></a><br>\r
- <code class="revvid">SH</code> <a\r
- href="main.htm#T:C5.HashedLinkedList%601"> HashedLinkedList<T></a><br>\r
- <code class="revvid">BH</code> <a\r
- href="main.htm#T:C5.ArrayList%601"> ArrayList<T></a><br>\r
- <code class="revvid">SH</code> <a\r
- href="main.htm#T:C5.HashedArrayList%601"> HashedArrayList<T></a></td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="19%"><a\r
- href="main.htm#T:C5.IIndexedSorted%601">IIndexedSorted<T></a> </td>\r
- <td valign="top" width="52%">This is an updateable collection\r
-with sequence order given by a comparer. \r
- <p>There are two main data structures inside the implementations:\r
-red-black search trees and a dynamic array kept sorted at all times.</p>\r
- <p>The differences are chiefly that the trees have much faster\r
-update operations, while the sorted array is somewhat faster at index\r
-lookups. In fact, the sorted array should only be used for static\r
-operation, where the collection is created and populated and then not\r
-changed again. </p>\r
- </td>\r
- <td valign="top" width="29%"> <code class="revvid">SC</code> <a\r
- href="main.htm#T:C5.SortedArray%601"> SortedArray<T></a><br>\r
- <code class="revvid">SC</code> <a\r
- href="main.htm#T:C5.TreeSet%601"> TreeSet<T></a><br>\r
- <code class="revvid">BC</code> <a\r
- href="main.htm#T:C5.TreeBag%601"> TreeBag<T></a></td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="19%"><a\r
- href="main.htm#T:C5.IPersistentSorted%601">IPersistentSorted<T></a> </td>\r
- <td valign="top" width="52%">This is a sorted collection that\r
-support very fast clones that themselves are sorted. The only\r
-implementation is the tree implementation with set and bag variants. </td>\r
- <td valign="top" width="29%"> <code class="revvid">SC</code> <a\r
- href="main.htm#T:C5.TreeSet%601"> TreeSet<T></a><br>\r
- <code class="revvid">BC</code> <a\r
- href="main.htm#T:C5.TreeBag%601"> TreeBag<T></a></td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<h2><a class="mozTocH2" name="mozTocId721827"></a><a\r
- name="Dictionary interfaces">Dictionary interfaces</a></h2>\r
-<p>There are two dictionary interfaces:</p>\r
-<table border="1" width="100%">\r
- <tbody>\r
- <tr>\r
- <th valign="top" width="19%">Interface</th>\r
- <th width="56%">Short description</th>\r
- <th width="25%">Implementing classes</th>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="19%"><a\r
- href="main.htm#T:C5.IDictionary%602">IDictionary<K,V></a> </td>\r
- <td width="56%">This is the base dictionary interface. \r
- <p>The choice is that one should use the hash dictionary unless\r
-one only has a comparer for the items, in which case the tree\r
-dictionary can be used. </p>\r
- </td>\r
- <td width="25%"><a href="main.htm#T:C5.HashDictionary%602">HashDictionary<K,V></a><br>\r
- <a href="main.htm#T:C5.TreeDictionary%602">TreeDictionary<K,V></a></td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="19%"><a\r
- href="main.htm#T:C5.ISortedDictionary%602">ISortedDictionary<K,V></a>\r
- </td>\r
- <td width="56%">This is a dictionary based on a comparer for the\r
-keys. There is only the tree implementation. </td>\r
- <td width="25%"><a href="main.htm#T:C5.TreeDictionary%602">TreeDictionary<K,V></a></td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<h2><a class="mozTocH2" name="mozTocId908053"></a><a\r
- name="Query result interfaces">Query result interfaces</a></h2>\r
-<p>Some of the most basic collection interfaces have an important usage\r
-as the\r
-types of results of queries to collections, although these interfaces\r
-also\r
-appear at the base of the other collection interfaces and even as the\r
-types of\r
-synthetic collections. The interfaces in question are the standard\r
-System.Collections.Generics.IEnumerable<T>,\r
-<a href="main.htm#T:C5.ICollectionValue%601">ICollectionValue<T></a>,\r
-<a href="main.htm#T:C5.IDirectedEnumerable%601">IDirectedEnumerable<T></a>\r
-and <a href="main.htm#T:C5.IDirectedCollectionValue%601">IDirectedCollectionValue<T></a>.</p>\r
-<p>The differences between the "Enumerable" and "Collection"\r
-variants are that the "Enumerable" variant only knows how to\r
-enumerate through its items, the "Collection" variants also knows how\r
-many items it has (without having to walk through an enumeration). The\r
-"Directed" variants are used for results of queries to sequenced\r
-collections (implementing <a href="main.htm#T:C5.ISequenced%601">ISequenced<T></a>)\r
-and therefore have a non-implementation dependent enumeration order.\r
-The\r
-"Directed" variants supports two operations, <a\r
- href="main.htm#M:C5.IDirectedCollectionValue%601.Backwards">Backwards()</a>\r
-to enable enumeration in the opposite direction and <a\r
- href="main.htm#P:C5.IDirectedEnumerable%601.Direction">Direction</a>\r
-to tell if the enumeration order is forwards or backwards with respect\r
-to the\r
-original collection.</p>\r
-<p>Note: operations on an enumerator created by the GetEnumerator()\r
-method on System.Collections.Generics.IEnumerable<T> cannot be\r
-interleaved with update\r
-operations on\r
-the underlying collection.</p>\r
-<p>Note: for all enumerators in the library the operations have O(1)\r
-amortized\r
-complexity.</p>\r
-<h1><a class="mozTocH1" name="mozTocId110895"></a>To <a\r
- name="Constructing">construct</a> a collection</h1>\r
-<p>All collections classes in C5 have (zero parameter) default\r
-constructors. So\r
-if we want to make a linked list of items of some type, <code>TheType</code>,\r
-and add an item to the list we will do</p>\r
-<p><code> IList<TheType> lst = new\r
-LinkedList<TheType>();<br>\r
- TheType t = ...;<br>\r
- lst.Add(t);</code></p>\r
-<p>The collection classes have no constructors that will take an array\r
-or a\r
-collection as parameter for prepopulating the collection, use the <a\r
- href="file:///C:/home/kokholm/c5/vs/C5/main.htm#M:C5.ISink%601.AddAll%28C5.IEnumerable%7B%210%7D%29">\r
-AddAll</a> method\r
-instead. NB: in the released version, expect constructors with an\r
-enumerable as argument and constructors with a variable number of\r
-arguments ("params") for the initialization of the collection, see the <a\r
- href="#planned">planned changes</a> section.<br>\r
-</p>\r
-<p>Some collection classes are governed by internal parameters that one\r
-can give\r
-non-default values at creation time (<code>fill</code> in <a\r
- href="main.htm#T:C5.HashSet%601">HashSet<T></a>, \r
-<a href="main.htm#T:C5.HashBag%601">HashBag<T></a>, <a\r
- href="main.htm#T:C5.HashDictionary%602">HashDictionary<K,V></a>)\r
-or use internal tables that one can expand in advance if one has\r
-expectations of\r
-how large the collection will grow (HashSet<T>, \r
-HashBag<T>, HashDictionary<K,V>, <a\r
- href="main.htm#T:C5.ArrayList%601">ArrayList<T></a>,\r
-<a href="main.htm#T:C5.HashedArrayList%601"> HashedArrayList<T></a>,\r
-<a href="main.htm#T:C5.SortedArray%601">SortedArray<T></a>,\r
-<a href="main.htm#T:C5.IntervalHeap%601">IntervalHeap<T></a>).</p>\r
-<p>For equality-based collection classes, these constructors will use a\r
-default\r
-equalityComparer to define equality of items according to the following table:</p>\r
-<table border="1">\r
- <tbody>\r
- <tr>\r
- <th>T</th>\r
- <th>default equalityComparer (implements IEqualityComparer<T>)</th>\r
- <th>Equality and hash code by</th>\r
- </tr>\r
- <tr>\r
- <td>int</td>\r
- <td><a href="main.htm#T:C5.IntEqualityComparer">IntEqualityComparer</a></td>\r
- <td>Equals and hash code of integer</td>\r
- </tr>\r
- <tr>\r
- <td>other value type</td>\r
- <td><a href="main.htm#T:C5.DefaultValueTypeEqualityComparer%601">DefaultValueTypeEqualityComparer<T></a></td>\r
- <td>methods inherited from object</td>\r
- </tr>\r
- <tr>\r
- <td>IEditableCollection<S></td>\r
- <td><a href="main.htm#T:C5.EqualityComparerBuilder.UnsequencedEqualityComparer%602">EqualityComparerBuilder.UnsequencedEqualityComparer<S,IEditableCollection<S>></a></td>\r
- <td>contents without regards to sequence</td>\r
- </tr>\r
- <tr>\r
- <td>ISequenced<S></td>\r
- <td><a href="main.htm#T:C5.EqualityComparerBuilder.SequencedEqualityComparer%602">EqualityComparerBuilder.SequencedEqualityComparer<S,IEditableCollection<S>></a></td>\r
- <td>contents with regards to sequence</td>\r
- </tr>\r
- <tr>\r
- <td>other reference type</td>\r
- <td><a href="main.htm#T:C5.DefaultReferenceTypeEqualityComparer%601">DefaultReferenceTypeEqualityComparer<T></a></td>\r
- <td>methods inherited from object</td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<p>For comparison-based collection classes, these constructors will use\r
-a\r
-default comparer:</p>\r
-<table border="1">\r
- <tbody>\r
- <tr>\r
- <th>T</th>\r
- <th>default comparer <br>\r
-(implements IComparer<T>)</th>\r
- <th>Comparison by</th>\r
- </tr>\r
- <tr>\r
- <td>int</td>\r
- <td>IC</td>\r
- <td>Standard integer comparison</td>\r
- </tr>\r
- <tr>\r
- <td>implementing IComparable<T></td>\r
- <td><a href="main.htm#T:C5.NaturalComparer%601">NaturalComparer<T></a></td>\r
- <td>The CompareTo(T o) instance method</td>\r
- </tr>\r
- <tr>\r
- <td>other implementing System.IComparable</td>\r
- <td><a href="main.htm#T:C5.NaturalComparerO%601">NaturalComparerO<T></a></td>\r
- <td>The CompareTo(object o) instance method</td>\r
- </tr>\r
- <tr>\r
- <td>other</td>\r
- <td>-</td>\r
- <td><i>collection class constructor throws an exception</i></td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<p>Sometimes, the default equalityComparer or comparer is not the right one for\r
-the\r
-problem at hand. In that case one must get hold on a equalityComparer or comparer\r
-of the\r
-right kind and supply it to one of the constructors of the collection\r
-classes\r
-that supports such a parameter. The procedure is demonstrated in the\r
-sections\r
-below on <a href="#external%20equalityComparer">external equalityComparers</a>, <a\r
- href="#external%20comparer">external\r
-comparers</a> and <a href="#collections%20of%20collections">collections\r
-as items</a>.<br>\r
-</p>\r
-<p>NB: in the released version, expect the equalityComparers and comparers to be\r
-of the System.Collections.Generics.IComparer<T> type, see the <a\r
- href="userguide.htm#planned">planned changes</a> section.</p>\r
-<h2><a class="mozTocH2" name="mozTocId850165"></a>To use an <a\r
- name="external equalityComparer"> external equalityComparer</a></h2>\r
-<p>In addition to the helper classes referenced above, the library has\r
-the\r
-helper class <a href="main.htm#T:C5.KeyValuePairEqualityComparer%602">KeyValuePairEqualityComparer<K,V></a>\r
-to construct a equalityComparer for pairs of the type <a\r
- href="main.htm#T:C5.KeyValuePair%602">KeyValuePair<K,V></a>,\r
-the type of entry of a K to V dictionary. The constructed equalityComparer will\r
-only take\r
-the first component of the pair into account. We can use these classes\r
-in the\r
-following way to make a linked list (with hash index) of pairs of\r
-strings\r
-identified by their first components using some custom equalityComparer on\r
-strings:</p>\r
-<blockquote>\r
- <p><code>IEqualityComparer<string> csh = ...;<br>\r
-IEqualityComparer<KeyValuePair<string,string>> cph = <br>\r
- \r
-new KeyValuePairEqualityComparer<string,string>(csh);<br>\r
-IList<KeyValuePair<string,string>> lst =<br>\r
- </code> <code>\r
-new HashedLinkedList<KeyValuePair<string,string>>(cph);<br>\r
-lst.Add(new KeyValuePair<string,string>("abe","kat"));</code></p>\r
-</blockquote>\r
-<p>One may, of course, program a equalityComparer oneself. This one should always\r
-do if\r
-the item type is defined as a struct (value type) that does not\r
-override the\r
-Equals and GetHashCode methods of object, since in that case the\r
-default equalityComparer\r
-will use the slow default versions of those methods supplied by the\r
-runtime via\r
-reflection. </p>\r
-<h2><a class="mozTocH2" name="mozTocId162938"></a>To use an <a\r
- name="external comparer"> external comparer</a></h2>\r
-<p>There is a helper class for comparer of pairs: <a\r
- href="main.htm#T:C5.KeyValuePairEqualityComparer%602">KeyValuePairComparer<K,V></a>.\r
-We will show an example of a custom comparer. Imagine wanting to\r
-compare double\r
-precision floating point numbers with a tolerance. The following code\r
-snippet\r
-shows how one could make a tree set out of such numbers:</p>\r
-<blockquote>\r
- <p><code>class DC : IComparer<double> {<br>\r
- const double eps = 1E-10;<br>\r
- int Compare(double a, double b) <br>\r
- {return a > b + eps ? 1 : a < b -\r
-eps ? -1 : 0;}<br>\r
-}<br>\r
- <br>\r
-void dowork() {<br>\r
- IComparer<double> dc = new DC();<br>\r
- ISorted<double> tree = new TreeSet<double>(dc);<br>\r
- tree.Add(3.45);<br>\r
- ...<br>\r
-}</code></p>\r
-</blockquote>\r
-<p>In this particular case, one would have to make sure, that two\r
-different\r
-floating point numbers are only identified by the comparer if they\r
-really should\r
-represent the same value and not by coincidence.</p>\r
-<h2><a class="mozTocH2" name="mozTocId957374"></a>To make <a\r
- name="collections of collections"> collections of collections</a></h2>\r
-<p>When one wants to use a collection whose items itself are of\r
-collection type,\r
-one usually wants the interior collections to be identified by contents\r
-- either\r
-according to or irrespective of sequence order. An example could be\r
-transformations of <a\r
- href="http://www.dina.kvl.dk/%7Esestoft/gcsharp/index.html#regexp">Finite\r
-Automatons</a>. The default equalityComparers and the EqualityComparerBuilder classes\r
-mentioned\r
-above may help to construct such collections of collections as in the\r
-examples\r
-that follow:</p>\r
-<p>To make an array list of sequenced collections identified by\r
-contents in\r
-sequenced fashion one would simply do:</p>\r
-<blockquote>\r
- <p><code>ArrayList<ISequenced<int>> lst = new\r
-ArrayList<ISequenced<int>>();</code></p>\r
-</blockquote>\r
-<p>To make a linked list of linked lists identified by contents\r
-unsequenced, explicitly\r
-construct the collection equalityComparer:</p>\r
-<blockquote>\r
- <p><code>IEqualityComparer<LinkedList<int>> lsth =<br>\r
- </code> <code>new\r
-EqualityComparerBuilder.UnsequencedEqualityComparer<int,LinkedList<int>>();<br>\r
-LinkedList<LinkedList<int>> lst =<br>\r
- new LinkedList<LinkedList<int>>(lsth);</code></p>\r
-</blockquote>\r
-<p>If for some strange reason one would like to make a hash set of\r
-linked lists\r
-with the lists identified by reference equality one would simply do:</p>\r
-<blockquote>\r
- <p><code>HashSet<LinkedList<int>> lst = new\r
-HashSet<LinkedList<int>>();</code></p>\r
-</blockquote>\r
-<p>If for even stranger reasons one would make a hash set of\r
-ISequenced<int> collections with the collections identified by\r
-reference\r
-equality one would do like this:</p>\r
-<blockquote>\r
- <p><code>IEqualityComparer<</code><code>ISequenced</code><code><int>>\r
-lsth =<br>\r
- </code> <code>new\r
-DefaultReferenceTypeEqualityComparer<</code><code>ISequenced</code><code><int>>();<br>\r
-HashSet<</code><code>ISequenced</code><code><int>> lst =<br>\r
- new HashSet<</code><code>ISequenced</code><code><int>>(lsth);</code></p>\r
-</blockquote>\r
-<h1><a class="mozTocH1" name="mozTocId486186"></a>Special topics</h1>\r
-<h2><a class="mozTocH2" name="mozTocId48263"></a>To choose a <a\r
- name="set or bag"> set or bag</a> collection</h2>\r
-<p>The following table shows which of the collection classes have set\r
-semantics\r
-and which have bag semantics. All the implemented classes have fixed,\r
-compiled in semantics. <br>\r
-</p>\r
-<p>Note: when in a set collection, methods with an Add in the name will\r
-ignore\r
-attempts to add an item already there or flag the failed attempt by a\r
-Boolean return value; methods with an Insert in the name (only in\r
-lists) will throw an\r
-exception.</p>\r
-<table border="1" width="38%">\r
- <tbody>\r
- <tr>\r
- <td valign="top" width="6%"><a href="main.htm#T:C5.HashSet%601">HashSet<T></a></td>\r
- <td valign="top" width="5%">set</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a href="main.htm#T:C5.HashBag%601">HashBag<T></a></td>\r
- <td valign="top" width="5%">bag</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a\r
- href="main.htm#T:C5.LinkedList%601"> LinkedList<T></a></td>\r
- <td valign="top" width="5%">bag</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a\r
- href="main.htm#T:C5.HashedLinkedList%601"> HashedLinkedList<T></a></td>\r
- <td valign="top" width="5%">set</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a\r
- href="main.htm#T:C5.ArrayList%601"> ArrayList<T></a></td>\r
- <td valign="top" width="5%">bag</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a\r
- href="main.htm#T:C5.HashedArrayList%601"> HashedArrayList<T> </a>\r
- </td>\r
- <td valign="top" width="5%">set</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a\r
- href="main.htm#T:C5.SortedArray%601"> SortedArray<T></a></td>\r
- <td valign="top" width="5%">set</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a href="main.htm#T:C5.TreeSet%601">TreeSet<T></a></td>\r
- <td valign="top" width="5%">set</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"> <a href="main.htm#T:C5.TreeBag%601">TreeBag<T></a></td>\r
- <td valign="top" width="5%">bag</td>\r
- </tr>\r
- <tr>\r
- <td valign="top" width="6%"><a\r
- href="main.htm#T:C5.IntervalHeap%601">IntervalHeap<T></a></td>\r
- <td valign="top" width="5%">bag</td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<h2><a class="mozTocH2" name="mozTocId929755"></a>To work on part of a\r
-list: list views</h2>\r
-<p>The IList<T> interface supports via the <a\r
- href="main.htm#M:C5.IList%601.View%28System.Int32,System.Int32%29">\r
-View</a>\r
-method the functionality that one can zoom in on part of a list and use\r
-it as an\r
-IList<T> in its own right while having updates to the view passed\r
-through\r
-to the base (original) IList<T>. Using the <a\r
- href="main.htm#M:C5.IList%601.Slide%28System.Int32%29">Slide</a>\r
-method calls, one may move the view around the base list. Using Slide\r
-repeatedly\r
-one can implement safe ways to iterate over a list while updating it.\r
-The\r
-IList<T> interface also has properties <a\r
- href="main.htm#P:C5.IList%601.Underlying">Underlying</a>\r
-and <a href="main.htm#P:C5.IList%601.Offset">Offset</a> showing the\r
-base list of a\r
-view and the current site of a view.</p>\r
-<p>One can create a view on a view, but the new view will have the\r
-original base\r
-list as base. A view will be invalidated if an update operation is\r
-performed on\r
-the base list by any other means than through this particular view.</p>\r
-<p>The following code snippet shows a silly example of iterating over a\r
-list,\r
-doing an insertion each time certain combination of items are seen (the\r
-example\r
-iterates right to left and inserts 666 whenever two consecutive items\r
-have an\r
-odd difference):</p>\r
-<blockquote>\r
- <p><code>IList<int> lst = ...;<br>\r
-IList<int> view = lst.CreateView(lst.Count-2, 2);<br>\r
-while (true) {<br>\r
- if ((view.Last - view.First) % 2 == 1)<br>\r
- view.Insert(1, 666);<br>\r
- if (view.Offset == 0)<br>\r
- break;<br>\r
- else<br>\r
- view.Slide(-1,2);<br>\r
-}</code></p>\r
-</blockquote>\r
-<h2><a class="mozTocH2" name="mozTocId650306"></a>To work with\r
-persistent red-black trees</h2>\r
-<p>The search tree implementation in the library is based on node copy\r
-persistent red-black trees. The persistence is exposed in the <a\r
- href="main.htm#M:C5.IPersistentSorted%601.Snapshot">Snapshot</a>\r
-method that can be considered a very fast and space-saving way of\r
-making a\r
-read-only clone of the tree. When using persistence, the space use of a\r
-red-black tree in this implementation is linear in the number of\r
-operations\r
-since the creation of the tree.</p>\r
-<p>One use of persistence could be to safely enumerate a tree\r
-interleaved with\r
-updates:</p>\r
-<blockquote>\r
- <p><code>IPersistentSorted<int> tree = new TreeSet<int>();<br>\r
-tree.Add(5);<br>\r
-...<br>\r
-ISorted<int> snap = tree.Snapshot();<br>\r
-foreach (int i in snap)<br>\r
- tree.Add(i+7);</code></p>\r
-</blockquote>\r
-<p>The GUITester project of the complete library source code contains\r
-an\r
-interesting (standard) usage of persistent search trees to the\r
-geometric problem\r
-of constructing an efficient data structure for point location in a\r
-division of\r
-the plane given by a list of line segments.</p>\r
-<h2><a class="mozTocH2" name="mozTocId553609"></a>To implement new\r
-collection classes or subclass an existing one</h2>\r
-<p>All interface methods and properties of the collection classes\r
-implemented in\r
-the library are virtual and so it should be safe to subclass these\r
-classes. Some\r
-classes may have protected members if they are subclassed in the\r
-library itself.\r
-We refer to the detailed reference manuals and the library source for\r
-information on the protected members and their role in subclassing.</p>\r
-<p>There is a sequence of helper classes designed to be used as base\r
-classes of\r
-collection classes: <a href="main.htm#T:C5.EnumerableBase%601">EnumerableBase<T></a>,\r
-<a href="main.htm#T:C5.CollectionValueBase%601">CollectionValueBase<T></a>,\r
-<a href="main.htm#T:C5.CollectionBase%601">CollectionBase<T></a>,\r
-<a href="main.htm#T:C5.SequencedBase%601">SequencedBase<T></a>\r
-and <a href="main.htm#T:C5.ArrayBase%601">ArrayBase<T></a>.\r
-Please see the reference manual and the library source code for\r
-documentation\r
-and examples.</p>\r
-<p>As for dictionaries, the DictionaryBase<K,V> class will\r
-construct a\r
-class implementing IDictionary<K,V> by simply plugging in a set\r
-implementation.</p>\r
-<h2><a class="mozTocH2" name="mozTocId753674"></a>To present a read\r
-only view of a collection</h2>\r
-<p>The library contains a long list of wrapper classes all with name\r
-starting\r
-with Guarded having the purpose of creating a read-only view of an\r
-existing\r
-collection. The wrapping is done by the constructors of the classes. If\r
-we want\r
-to give some code access to only lookup operations on a, say, list we\r
-can do as\r
-follows:</p>\r
-<blockquote>\r
- <p><code>IList<int> lst;<br>\r
-...<br>\r
-IList<int> rolst = new GList<int>(lst);<br>\r
-OtherObject.dowork(rolst);</code></p>\r
-</blockquote>\r
-<p>Please see the reference manual for details on available wrapper\r
-classes.</p>\r
-<h1><a class="mozTocH1" name="mozTocId6619"></a><a name="datastructures">Collection\r
-classes by data structure/class</a></h1>\r
-<p>The following table shows the underlying data structure of the\r
-various collection classes.</p>\r
-<table border="1">\r
- <tbody>\r
- <tr>\r
- <th>Data structure</th>\r
- <th>Classes</th>\r
- <th>Primary Interfaces</th>\r
- </tr>\r
- <tr>\r
- <td>hash table</td>\r
- <td>HashSet<T></td>\r
- <td> ICollection<T></td>\r
- </tr>\r
- <tr>\r
- <td>hash table</td>\r
- <td>HashBag<T></td>\r
- <td> ICollection<T></td>\r
- </tr>\r
- <tr>\r
- <td>hash table</td>\r
- <td>HashDictionary<K,V></td>\r
- <td>IDictionary<K,V></td>\r
- </tr>\r
- <tr>\r
- <td>linked list</td>\r
- <td>LinkedList<T></td>\r
- <td>IList<T></td>\r
- </tr>\r
- <tr>\r
- <td>linked list with hash index</td>\r
- <td>HashedLinkedList<T></td>\r
- <td>IList<T></td>\r
- </tr>\r
- <tr>\r
- <td>dynamic array</td>\r
- <td>ArrayList<T></td>\r
- <td>IList<T></td>\r
- </tr>\r
- <tr>\r
- <td>dynamic array with hash index</td>\r
- <td>HashedArrayList<T></td>\r
- <td>IList<T></td>\r
- </tr>\r
- <tr>\r
- <td>sorted dynamic array</td>\r
- <td>SortedArray<T></td>\r
- <td>IIndexedSorted<T></td>\r
- </tr>\r
- <tr>\r
- <td>heap</td>\r
- <td>IntervalHeap<T></td>\r
- <td>IPriorityQueue<T></td>\r
- </tr>\r
- <tr>\r
- <td>red-black search tree</td>\r
- <td>TreeSet<T></td>\r
- <td>IIndexedSorted<T>, IPersistentSorted<T></td>\r
- </tr>\r
- <tr>\r
- <td>red-black search tree</td>\r
- <td>TreeBag<T></td>\r
- <td>IIndexedSorted<T>, IPersistentSorted<T></td>\r
- </tr>\r
- <tr>\r
- <td>red-black search tree</td>\r
- <td>TreeDictionary<K,V></td>\r
- <td>ISortedDictionary<K,V></td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<br>\r
-<h1><a class="mozTocH1" name="mozTocId393559"></a><><a\r
- name="planned"></a>Planned<span style="font-weight: bold;"> </span>architecture\r
-or interface changes\r
-for first release<br>\r
-</h1>\r
-<ol>\r
- <li>Eliminate the use of our own generic equality/comparator types,\r
-C5.IComparer<T> and C5.IEqualityComparer<T> and use the new design of\r
-VS 2005 beta1 in the form of the combined\r
-System.Collections.Generic.IComparer<T>.</li>\r
- <li>Vararg (params) constructors? (And IEnum do.)</li>\r
- <li>Possibly extended use of "wildcard style" operations like\r
-AddAll<U>(IEnumerable<U> items)?</li>\r
- <li>Make all collection classes clonable and serializable.</li>\r
-</ol>\r
-<h1><a class="mozTocH1" name="mozTocId336849"></a><a\r
- name="PerformanceProper">Performance</a> details for proper collection\r
-classes</h1>\r
-<p>This section overviews the complexities of cc public methods and\r
-property\r
-accesses.</p>\r
-<p>In the table below, for lack of space we use the following numbers\r
-to\r
-identify collection classes:</p>\r
-<table border="1">\r
- <tbody>\r
- <tr>\r
- <th>Class</th>\r
- <th>Column</th>\r
- </tr>\r
- <tr>\r
- <td>HashSet<T></td>\r
- <td>HS</td>\r
- </tr>\r
- <tr>\r
- <td>HashBag<T></td>\r
- <td>HB</td>\r
- </tr>\r
- <tr>\r
- <td>ArrayList<T></td>\r
- <td>AL</td>\r
- </tr>\r
- <tr>\r
- <td>LinkedList<T></td>\r
- <td>LL</td>\r
- </tr>\r
- <tr>\r
- <td>HashedArrayList<T></td>\r
- <td>HAL</td>\r
- </tr>\r
- <tr>\r
- <td>HashedLinkedList<T></td>\r
- <td>HLL</td>\r
- </tr>\r
- <tr>\r
- <td>TreeSet<T></td>\r
- <td>RBTS</td>\r
- </tr>\r
- <tr>\r
- <td>TreeBag<T></td>\r
- <td>RBTB</td>\r
- </tr>\r
- <tr>\r
- <td>SortedArray<T></td>\r
- <td>SA</td>\r
- </tr>\r
- <tr>\r
- <td>IntervalHeap<T></td>\r
- <td>IH</td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<p>And the following special symbols: </p>\r
-<p>\r
-n size of collection, <br>\r
-m size of argument if collection-: not supported<br>\r
-*: means: suboptimal complexity (library is in error)<br>\r
-$: special at end: the operation is much faster at the start and/or end\r
-(end for\r
-array list, both for linked list)\r
-</p>\r
-<p>Note: we do not show return type or parameters for methods,\r
-just mark\r
-with ()<br>\r
-Note: we ignore time for reclaiming of internal array space (e.g. Clear)<br>\r
-User supplied operations like comparers or equalityComparers are assumed to be\r
-O(1)</p>\r
-<table border="1" height="2893" width="100%">\r
- <tbody>\r
- <tr>\r
- <th height="23" width="9%">Member</th>\r
- <th height="23" width="8%">HS</th>\r
- <th height="23" width="8%">HB</th>\r
- <th height="23" width="8%">AL</th>\r
- <th height="23" width="8%">LL</th>\r
- <th height="23" width="8%">HAL</th>\r
- <th height="23" width="8%">HLL</th>\r
- <th height="23" width="8%">RBTS</th>\r
- <th height="23" width="8%">RBTB</th>\r
- <th height="23" width="9%">SA</th>\r
- <th height="23" width="9%">IH</th>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2"> IEnumerable<T></font></i></td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="8%"> </td>\r
- <td height="22" width="9%"> </td>\r
- <td height="22" width="9%"> </td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">GetEnumerator()</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">IDirectedEnumerable<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="18%"><font size="2">Direction</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="18%"><font size="2">Backwards()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">ICollectionValue<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Count</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="18%"><font size="2">CopyTo</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">ToArray</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Apply()</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Exists()</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">All()</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">IDirectedCollectionValue<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="18%"><font size="2">Backwards()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="13%"><i><font color="#808080" size="2">IExtensible<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">AllowsDuplicates</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">SyncRoot</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">IsEmpty</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Add</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">AddAll</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(mlog n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(mlog n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(mlog n)</font></td>\r
- <td height="22" width="9%"><font size="2">??</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">ICollection<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">IsReadOnly</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">ContainsSpeed</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">GetHashCode</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Equals</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Contains</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">ContainsCount</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">ContainsAll</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(mn)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(mn)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="9%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Find</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">FindOrAdd</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Update</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">UpdateOrAdd</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Remove</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveWithReturn</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveAllCopies</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveAll</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(mn)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(mn)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(m+n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="9%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Clear</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RetainAll</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)?</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(mn)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(mn)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(m+n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="9%"><font size="2">O(m logn)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">ISequenced<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">GetHashCode</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Equals</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">IIndexed<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">this[i]</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">this[start,end]</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">IndexOf()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">LastIndexOf()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveAt</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveInterval</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n log n)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(n log n)*</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">IList<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HB</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">AL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">LL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HAL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">HLL</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTS</font></i></td>\r
- <td align="center" height="22" width="8%"><i><font color="#808080"\r
- size="2">RBTB</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">SA</font></i></td>\r
- <td align="center" height="22" width="9%"><i><font color="#808080"\r
- size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">First</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Last</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">FIFO</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">this[i]</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Base</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Offset</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Map()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Insert()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">InsertFirst()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">InsertLast()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">InsertBefore()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">InsertAfter()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">InsertAll()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(m+n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m+n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m+n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(m+n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">FindAll()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Remove()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)$</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveFirst()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveLast()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">View()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Slide() (amount: d)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(d)</font></td>\r
- <td height="22" width="8%"><font size="2">O(d)</font></td>\r
- <td height="22" width="8%"><font size="2">O(d)</font></td>\r
- <td height="22" width="8%"><font size="2">O(d)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Reverse()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">IsSorted()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Sort()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n log n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Shuffle()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">IPriorityQueue<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HB</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">AL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">LL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HAL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HLL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTB</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">SA</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">FindMin()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">DeleteMin()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">FindMax()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="30" width="9%"><font size="2">DeleteMax()</font></td>\r
- <td height="30" width="8%"><font size="2">-</font></td>\r
- <td height="30" width="8%"><font size="2">-</font></td>\r
- <td height="30" width="8%"><font size="2">-</font></td>\r
- <td height="30" width="8%"><font size="2">-</font></td>\r
- <td height="30" width="8%"><font size="2">-</font></td>\r
- <td height="30" width="8%"><font size="2">-</font></td>\r
- <td height="30" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="30" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="30" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="30" width="9%"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="30" width="9%"> <font size="2">Comparer</font></td>\r
- <td height="30" width="8%"> <font size="2">-</font></td>\r
- <td height="30" width="8%"> <font size="2">-</font></td>\r
- <td height="30" width="8%"> <font size="2">-</font></td>\r
- <td height="30" width="8%"> <font size="2">-</font></td>\r
- <td height="30" width="8%"> <font size="2">-</font></td>\r
- <td height="30" width="8%"> <font size="2">-</font></td>\r
- <td height="30" width="8%"> <font size="2">O(1)</font></td>\r
- <td height="30" width="8%"> <font size="2">O(1)</font></td>\r
- <td height="30" width="9%"> <font size="2">O(1)</font></td>\r
- <td height="30" width="9%"> <font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">ISorted<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HB</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">AL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">LL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HAL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HLL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTB</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">SA</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Predecessor</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Successor</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">WeakPredecessor</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">WeakSuccessor</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Cut</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RangeFrom</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RangeFromTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RangeTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RangeAll</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">AddSorted</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">?</font></td>\r
- <td height="22" width="8%"><font size="2">?</font></td>\r
- <td height="22" width="9%"><font size="2">?</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveRangeFrom</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(nlog n)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(nlog n)*</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveRangeFromTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(nlog n)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(nlog n)*</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RemoveRangeTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(nlog n)*</font></td>\r
- <td height="22" width="8%"><font size="2">O(nlog n)*</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">IIndexedSorted<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HB</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">AL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">LL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HAL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HLL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTB</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">SA</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Map</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">CountFrom</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">CountFromTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">CountTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RangeFrom</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RangeFromTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">RangeTo</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(log n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">FindAll</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="8%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">O(n)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="14%"><i><font color="#808080" size="2">IPersistentSorted<T></font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HB</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">AL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">LL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HAL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">HLL</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTS</font></i></td>\r
- <td height="22" width="8%"><i><font color="#808080" size="2">RBTB</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">SA</font></i></td>\r
- <td height="22" width="9%"><i><font color="#808080" size="2">IH</font></i></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="9%"><font size="2">Snapshot()</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">-</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="8%"><font size="2">O(1)</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- <td height="22" width="9%"><font size="2">-</font></td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-<h1><a class="mozTocH1" name="mozTocId712409"></a><a\r
- name="PerformanceDict">Performance</a> details for dictionary classes</h1>\r
-<table border="1" width="467">\r
- <tbody>\r
- <tr>\r
- <th width="302">Member</th>\r
- <th width="79">HashDictionary<K,V></th>\r
- <th width="64">TreeDictionary<K,V></th>\r
- </tr>\r
- <tr>\r
- <td width="302"><i><font color="#808080" size="2">IEnumerable<KeyValuePair<K,V>></font></i></td>\r
- <td width="79"><font color="#808080"> </font></td>\r
- <td width="64"> </td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">GetEnumerator()</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td width="64"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><i><font color="#808080" size="2">IDictionary<K,V></font></i></td>\r
- <td width="79"><font color="#808080"> </font></td>\r
- <td width="64"> </td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">this[key]</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Count</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td width="64"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">IsReadOnly</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td width="64"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">SyncRoot</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td width="64"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Keys</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td width="64"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Values</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td width="64"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Add()</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Remove()</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Clear()</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(1)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Contains()</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Find()</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">Update()</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">FindOrAdd</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><font size="2">UpdateOrAdd</font></td>\r
- <td width="79"><font size="2">O(1)</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td width="302"><i><font color="#808080" size="2">ISortedDictionary<K,V></font></i></td>\r
- <td width="79"><font color="#808080"> </font></td>\r
- <td width="64"> </td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="302"><font size="2">Predecessor</font></td>\r
- <td width="79"><font size="2">-</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="302"><font size="2">Successor</font></td>\r
- <td width="79"><font size="2">-</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="302"><font size="2">WeakPredecessor</font></td>\r
- <td width="79"><font size="2">-</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- <tr>\r
- <td height="22" width="302"><font size="2">WeakSuccessor</font></td>\r
- <td width="79"><font size="2">-</font></td>\r
- <td height="22" width="64"><font size="2">O(log n)</font></td>\r
- </tr>\r
- </tbody>\r
-</table>\r
-</body>\r
-</html>\r
+++ /dev/null
-/*\r
- Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft\r
- Permission is hereby granted, free of charge, to any person obtaining a copy\r
- of this software and associated documentation files (the "Software"), to deal\r
- in the Software without restriction, including without limitation the rights\r
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
- copies of the Software, and to permit persons to whom the Software is\r
- furnished to do so, subject to the following conditions:\r
- \r
- The above copyright notice and this permission notice shall be included in\r
- all copies or substantial portions of the Software.\r
- \r
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- SOFTWARE.\r
-*/\r
-\r
-// DocNet.cs\r
-// Author: Antonio Cisternino\r
-// Version: 0.1\r
-// Last update: 5/12/2001\r
-// Modified Jan 2004 by kokholm@itu.dk\r
-\r
-using System;\r
-using System.IO;\r
-using System.Reflection;\r
-using System.Xml;\r
-using System.Text;\r
-using System.Diagnostics;\r
-\r
-namespace DocNet\r
-{\r
- class DocNet\r
- {\r
- private Assembly assembly;\r
-\r
- //private XmlDocument xml;\r
-\r
- private string defaultNamespace;\r
-\r
- private string assemblyName;\r
-\r
- private static C5.HashDictionary<string, string> longtype2short;\r
-\r
- private static C5.HashDictionary<string, XmlNode> cachedDocComments;\r
-\r
- static DocNet()\r
- {\r
- longtype2short = new C5.HashDictionary<string, string>();\r
- cachedDocComments = new C5.HashDictionary<string, XmlNode>();\r
- longtype2short.Add("System.Boolean", "bool");\r
- longtype2short.Add("System.Byte", "byte");\r
- longtype2short.Add("System.Int32", "int");\r
- longtype2short.Add("System.Double", "double");\r
- longtype2short.Add("System.Void", "void");\r
- longtype2short.Add("System.Object", "object");\r
- longtype2short.Add("System.String", "string");\r
- longtype2short.Add("System.Collections.Generic.IEnumerable{T}", "IEnumerable{T}");\r
- longtype2short.Add("System.Collections.Generic.IEnumerable{U}", "IEnumerable{U}");\r
- //longtype2short.Add("", "");\r
- }\r
-\r
-\r
- DocNet(string a, string x, string defaultNamespace)\r
- {\r
- this.defaultNamespace = defaultNamespace;\r
- assembly = Assembly.LoadFrom(a, null);\r
- XmlDocument xml = new XmlDocument();\r
- xml.Load(x);\r
- assemblyName = xml.SelectSingleNode("doc/assembly/name").InnerXml;\r
-\r
- if (!assembly.FullName.StartsWith(assemblyName + ","))\r
- throw new Exception("Wrong assembly specified!\n>> " + assembly.FullName + "\n>> " + assemblyName);\r
-\r
- foreach (XmlNode node in xml.SelectNodes("doc/members/member"))\r
- cachedDocComments.Add(node.SelectNodes("@name").Item(0).Value, node);\r
- }\r
-\r
-\r
- private void CopyCodeDoc(XmlElement p, string xpath, XmlDocument ret)\r
- {\r
- XmlNode n;\r
- //xml.SelectSingleNode(xpath);\r
-\r
- if (cachedDocComments.Find(xpath, out n))\r
- {\r
- foreach (XmlNode child in n.ChildNodes)\r
- p.AppendChild(ret.ImportNode(child, true));\r
- }\r
- //else\r
- // Console.Error.WriteLine("docNet: {0} not found", xpath);\r
- }\r
-\r
- string xmlClean(string s)\r
- {\r
-// return s.Replace("&", "&").Replace("{", "<").Replace("}", ">").Replace("<", "<").Replace(">", ">");\r
- return s.Replace("{", "<").Replace("}", ">");\r
- }\r
-\r
- private void AddSignature(XmlElement p, string signtext, XmlDocument ret)\r
- {\r
- XmlElement sign = CreateElement(ret, "Signature");\r
-\r
- try\r
- {\r
- sign.InnerXml = signtext.Replace("&", "&").Replace("{", "<").Replace("}", ">").Replace("<", "<").Replace(">", ">");\r
- }\r
- catch (XmlException)\r
- {\r
- Console.Error.WriteLine(signtext);\r
- }\r
- p.AppendChild(sign);\r
- }\r
-\r
- private void addImplements(XmlElement p, Type t, XmlDocument ret)\r
- {\r
- foreach (Type ty in t.GetInterfaces())\r
- {\r
- XmlElement impl = CreateElement(ret, "Implements");\r
-\r
- if (ty.Assembly == assembly)\r
- {\r
- impl.SetAttribute("refid", "T:" + canonicalTypeName(ty, null));\r
- impl.SetAttribute("C5", "");\r
- }\r
- AddSignature(impl, prettyTypeName(ty), ret);\r
- p.AppendChild(impl);\r
- }\r
- }\r
-\r
- private void addBases(XmlElement p, Type t, XmlDocument ret)\r
- {\r
- Type ty = t.BaseType;\r
-\r
- while (ty != null)\r
- {\r
- XmlElement @base = CreateElement(ret, "Bases");\r
-\r
- if (ty.Assembly == assembly)\r
- {\r
- @base.SetAttribute("refid", "T:" + canonicalTypeName(ty, null));\r
- @base.SetAttribute("C5", "");\r
- }\r
-\r
- AddSignature(@base, prettyTypeName(ty), ret);\r
- p.PrependChild(@base);\r
- ty = ty.BaseType;\r
- }\r
- }\r
-\r
-\r
-\r
- private XmlElement CreateElement(XmlDocument ret, string name)\r
- {\r
- return ret.CreateElement(null, name, null);\r
- }\r
-\r
- private void VisitField(bool inherited, FieldInfo f, XmlElement type, XmlDocument refman)\r
- {\r
- if (f.Name.Equals("value__"))\r
- return;\r
- string refid = "F:" + canonicalTypeName(f.DeclaringType, null) + "." + f.Name;\r
- //string xpath = "doc/members/member[@name = \"" + refid + "\"]";\r
- XmlElement el = CreateElement(refman, "Field");\r
-\r
- el.SetAttribute("Name", f.Name);\r
- el.SetAttribute("refid", refid);\r
- el.SetAttribute("Static", f.IsStatic.ToString());\r
- el.SetAttribute("Declared", xmlClean(prettyTypeName(f.DeclaringType)));\r
- el.SetAttribute("CDeclared", canonicalTypeName(f.DeclaringType, null));\r
- el.SetAttribute("Type", xmlClean(prettyTypeName(f.FieldType)));\r
- el.SetAttribute("Access", f.IsPublic ? "public" : (f.IsPrivate || f.IsAssembly ? "private" : "protected"));\r
- if (f.DeclaringType.Assembly == assembly)\r
- el.SetAttribute("C5", "");\r
-\r
- if (inherited)\r
- el.SetAttribute("Inherited", "");\r
-\r
- AddSignature(el, /*prettyTypeName(f.FieldType) + " " +*/ f.Name, refman);\r
- CopyCodeDoc(el, refid, refman);\r
- //AddSummary(el, xpath + "/summary", ret, doc);\r
- type.AppendChild(el);\r
- }\r
-\r
- private void VisitEvent(bool inherited, EventInfo e, XmlElement type, XmlDocument ret)\r
- {\r
- string refid = "E:" + canonicalTypeName(e.DeclaringType, null) + "." + e.Name;\r
- //string xpath = "doc/members/member[@name = \"" + refid + "\"]";\r
- XmlElement el = CreateElement(ret, "Event");\r
-\r
- el.SetAttribute("Name", e.Name);\r
- el.SetAttribute("refid", refid);\r
- //el.SetAttribute("Static", f.IsStatic.ToString());\r
- //TODO: check virtual and final values on adders/removers\r
- //el.SetAttribute("Virtual", e..IsVirtual.ToString());\r
- //el.SetAttribute("Final", e.IsFinal.ToString());\r
- el.SetAttribute("Declared", xmlClean(prettyTypeName(e.DeclaringType)));\r
- el.SetAttribute("CDeclared", canonicalTypeName(e.DeclaringType, null));\r
- el.SetAttribute("Type", xmlClean(prettyTypeName(e.EventHandlerType)));\r
- MethodInfo addMethod = e.GetAddMethod(true);\r
- el.SetAttribute("Access", addMethod.IsPublic ? "public" : addMethod.IsFamily ? "protected" : "private");//NBNBNB! e.IsPublic ? "public" : (e.IsPrivate || e.IsAssembly ? "private" : "protected"));\r
- if (e.DeclaringType.Assembly == assembly)\r
- el.SetAttribute("C5", "");\r
-\r
- if (inherited)\r
- el.SetAttribute("Inherited", "");\r
-\r
- AddSignature(el, /*prettyTypeName(e.EventHandlerType) + " " +*/ e.Name, ret);\r
- CopyCodeDoc(el, refid, ret);\r
- //AddSummary(el, xpath + "/summary", ret, doc);\r
- type.AppendChild(el);\r
- }\r
-\r
-\r
- private void VisitProperty(bool inherited, PropertyInfo p, XmlElement type, XmlDocument ret)\r
- {\r
- string refid = "P:" + canonicalPropertyName(p);\r
- string xpath = "doc/members/member[@name = \"" + refid + "\"]";\r
- XmlElement el = CreateElement(ret, "Property");\r
-\r
- el.SetAttribute("Name", p.Name);\r
- el.SetAttribute("refid", refid);\r
- el.SetAttribute("Access", "public");//TODO: check if reasonable\r
- MethodInfo m = p.CanRead ? p.GetGetMethod() : p.GetSetMethod();\r
- if (m != null)\r
- {\r
- el.SetAttribute("Static", m.IsStatic.ToString());\r
- el.SetAttribute("Abstract", m.IsAbstract.ToString());\r
- el.SetAttribute("Virtual", m.IsVirtual.ToString());\r
- el.SetAttribute("Final", m.IsFinal.ToString());\r
- }\r
- //else\r
- //Console.Error.WriteLine("%%%%% {0} | {1}", p, p.DeclaringType);\r
- el.SetAttribute("Declared", xmlClean(prettyTypeName(p.DeclaringType)));\r
- el.SetAttribute("CDeclared", canonicalTypeName(p.DeclaringType, null));\r
- el.SetAttribute("Get", p.CanRead.ToString());\r
- el.SetAttribute("Set", p.CanWrite.ToString());\r
- el.SetAttribute("Type", xmlClean(prettyTypeName(p.PropertyType)));\r
-\r
- if (p.DeclaringType.Assembly == assembly)\r
- el.SetAttribute("C5", "");\r
-\r
- if (inherited)\r
- el.SetAttribute("Inherited", "");\r
-\r
- if (p.Name.Equals("Item"))\r
- AddSignature(el, prettyIndexerSignature(p), ret);\r
- else\r
- AddSignature(el, /*prettyTypeName(p.PropertyType) + " " +*/ p.Name, ret);\r
-\r
- //AddSummary(el, xpath + "/summary", ret, doc);\r
- CopyCodeDoc(el, refid, ret);\r
- //AddValue(el, xpath + "/value", ret, doc);\r
- VisitParameters(p.GetIndexParameters(), el, ret, xpath);\r
- type.AppendChild(el);\r
- }\r
-\r
-\r
- private void VisitParameters(ParameterInfo[] pars, XmlElement n, XmlDocument ret, string xpath)\r
- {\r
- foreach (ParameterInfo p in pars)\r
- {\r
- XmlElement el = CreateElement(ret, "Parameter");\r
-\r
- el.SetAttribute("Name", p.Name);\r
- el.SetAttribute("Type", prettyTypeName(p.ParameterType));\r
- //AddSummary(el, xpath + "/param[@name = \"" + p.Name + "\"]", ret, doc);\r
- CopyCodeDoc(el, xpath + "/param[@name = \"" + p.Name + "\"]", ret);\r
-\r
- n.AppendChild(el);\r
- }\r
- }\r
-\r
-\r
- private void VisitConstructor(Type t, ConstructorInfo c, XmlElement type, XmlDocument ret)\r
- {\r
- Type declaringType = c.DeclaringType;\r
- string refid = "M:" + canonicalTypeName(c.DeclaringType, null) + "." + "#ctor";\r
-\r
- refid += canonicalParameters(c.GetParameters(), new string[]{});\r
-\r
- string xpath = "doc/members/member[@name = \"" + refid + "\"]";\r
- XmlElement el = CreateElement(ret, "Constructor");\r
- el.SetAttribute("Foo", c.IsConstructor ? "Con" : "San");\r
- el.SetAttribute("refid", refid);\r
- el.SetAttribute("Declared", prettyTypeName(declaringType));\r
- el.SetAttribute("CDeclared", canonicalTypeName(declaringType, null));\r
- el.SetAttribute("Access", c.IsPublic ? "public" : (c.IsPrivate ? "private" : "protected"));\r
- //el.SetAttribute("Access", c.IsPublic ? "public" : (c.IsPrivate || c.IsAssembly ? "private" : "protected"));\r
- if (declaringType.Assembly == assembly)\r
- el.SetAttribute("C5", "");\r
- if (declaringType != t)\r
- el.SetAttribute("Inherited", "");\r
- AddSignature(el, prettyConstructorSignature(c), ret);\r
- CopyCodeDoc(el, refid, ret);\r
- //AddSummary(el, xpath + "/summary", ret, doc);\r
- VisitParameters(c.GetParameters(), el, ret, xpath);\r
- type.AppendChild(el);\r
- }\r
-\r
-\r
- private void VisitMethod(bool inherited, MethodInfo m, XmlElement type, XmlDocument ret)\r
- {\r
- if (m.Name.StartsWith("get_") || m.Name.StartsWith("set_") || m.Name.StartsWith("add_") || m.Name.StartsWith("remove_"))\r
- return;\r
- bool isOperator = m.Name.StartsWith("op_");\r
-\r
- string refid = "M:" + canonicalMethodName(m);\r
-\r
- string xpath = "doc/members/member[@name = \"" + refid + "\"]";\r
- XmlElement el = CreateElement(ret, isOperator ? "Operator" : "Method");\r
-\r
- string mangledName = m.Name;\r
- if (isOperator)\r
- {\r
- switch (mangledName)\r
- {\r
- case "op_Equality": mangledName = "operator =="; break;\r
- case "op_Inequality": mangledName = "operator !="; break;\r
- default: throw new ApplicationException("unknown operatorname, " + mangledName);\r
- }\r
- }\r
- el.SetAttribute("Name", mangledName);\r
- el.SetAttribute("refid", refid);\r
- el.SetAttribute("Static", m.IsStatic.ToString());\r
- el.SetAttribute("Abstract", m.IsAbstract.ToString());\r
- el.SetAttribute("Virtual", m.IsVirtual.ToString());\r
- el.SetAttribute("Final", m.IsFinal.ToString());\r
- el.SetAttribute("Declared", xmlClean(prettyTypeName(m.DeclaringType)));\r
- el.SetAttribute("CDeclared", canonicalTypeName(m.DeclaringType, null));\r
- el.SetAttribute("ReturnType", xmlClean(prettyTypeName(m.ReturnType)));\r
- if (m.DeclaringType.Assembly == assembly)\r
- el.SetAttribute("C5", "");\r
- if (inherited)\r
- el.SetAttribute("Inherited", "");\r
- el.SetAttribute("Access", m.IsPublic ? "public" : (m.IsPrivate || m.IsAssembly ? "private" : "protected"));\r
- el.SetAttribute("Sealed", m.IsFinal.ToString());\r
- AddSignature(el, prettyMethodSignature(mangledName, m), ret);\r
- CopyCodeDoc(el, refid, ret);\r
- VisitParameters(m.GetParameters(), el, ret, xpath);\r
-\r
- foreach (Type gp in m.GetGenericArguments())\r
- foreach (Type gc in gp.GetGenericParameterConstraints())\r
- if (gc != typeof(object))\r
- {\r
- XmlElement constraint = CreateElement(ret, "constraint");\r
- constraint.SetAttribute("Value", prettyTypeName(gp) + " : " + xmlClean(prettyTypeName(gc)));\r
- el.AppendChild(constraint);\r
- }\r
- type.AppendChild(el);\r
- }\r
-\r
- public XmlDocument GenerateDoc()\r
- {\r
- BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic;\r
-\r
- XmlDocument ret = new XmlDocument();\r
- XmlElement root = CreateElement(ret, "Assembly");\r
-\r
- root.SetAttribute("Name", assemblyName);\r
-\r
- ret.AppendChild(root);\r
-\r
- XmlElement type = null;\r
- //string xpath = null;\r
-\r
- foreach (Type t in assembly.GetTypes())\r
- {\r
- if (t.Name.StartsWith("DocNet"))\r
- continue;\r
-\r
- if (t.IsInterface)\r
- {\r
- type = CreateElement(ret, "Interface");\r
- foreach (EventInfo e in t.GetEvents(flags))\r
- VisitEvent(e.DeclaringType != t, e, type, ret);\r
-\r
- foreach (PropertyInfo p in t.GetProperties(flags))\r
- VisitProperty(false, p, type, ret);\r
-\r
- foreach (MethodInfo m in t.GetMethods(flags))\r
- VisitMethod(false, m, type, ret);\r
- }\r
- else if (t.IsValueType)\r
- {\r
- type = CreateElement(ret, "Struct");\r
- foreach (FieldInfo f in t.GetFields(flags))\r
- VisitField(f.DeclaringType != t, f, type, ret);\r
-\r
- foreach (EventInfo e in t.GetEvents(flags))\r
- VisitEvent(e.DeclaringType != t, e, type, ret);\r
-\r
- foreach (PropertyInfo p in t.GetProperties(flags))\r
- VisitProperty(p.DeclaringType != t, p, type, ret);\r
-\r
- foreach (ConstructorInfo c in t.GetConstructors(flags))\r
- VisitConstructor(t, c, type, ret);\r
-\r
- foreach (MethodInfo m in t.GetMethods(flags))\r
- VisitMethod(m.DeclaringType != t, m, type, ret);\r
- }\r
- else if (t.IsSubclassOf(typeof(Delegate)))\r
- {\r
- type = CreateElement(ret, "Delegate");\r
- VisitMethod(false, t.GetMethod("Invoke"), type, ret);\r
- }\r
- else\r
- { // Class\r
- type = CreateElement(ret, "Class");\r
- foreach (FieldInfo f in t.GetFields(flags))\r
- VisitField(f.DeclaringType != t, f, type, ret);\r
-\r
- foreach (EventInfo e in t.GetEvents(flags))\r
- VisitEvent(e.DeclaringType != t, e, type, ret);\r
-\r
- foreach (PropertyInfo p in t.GetProperties(flags))\r
- VisitProperty(p.DeclaringType != t, p, type, ret);\r
-\r
- foreach (ConstructorInfo c in t.GetConstructors(flags))\r
- VisitConstructor(t, c, type, ret);\r
-\r
- foreach (MethodInfo m in t.GetMethods(flags))\r
- VisitMethod(m.DeclaringType != t, m, type, ret);\r
- }\r
-\r
- type.SetAttribute("Name", xmlClean(prettyTypeName(t)));\r
- type.SetAttribute("Access", t.IsPublic || t.IsNestedPublic ? "public" : t.IsNestedFamily ? "protected" : "private");\r
-\r
- string refid = "T:" + canonicalTypeName(t, null);\r
-\r
- type.SetAttribute("refid", refid);\r
- type.SetAttribute("C5", "");\r
- AddSignature(type, prettyTypeName(t), ret);\r
- addImplements(type, t, ret);\r
- addBases(type, t, ret);\r
-\r
- foreach (Type gp in t.GetGenericArguments())\r
- {\r
- if (gp.GenericParameterAttributes != GenericParameterAttributes.None)\r
- {\r
- XmlElement constraint = CreateElement(ret, "constraint");\r
- string constraintText = null;\r
- switch (gp.GenericParameterAttributes)\r
- {\r
- case GenericParameterAttributes.Contravariant:\r
- break;\r
- case GenericParameterAttributes.Covariant:\r
- break;\r
- case GenericParameterAttributes.DefaultConstructorConstraint:\r
- constraintText = "new()";\r
- break;\r
- case GenericParameterAttributes.None:\r
- break;\r
- case GenericParameterAttributes.ReferenceTypeConstraint:\r
- constraintText = "class";\r
- break;\r
- case GenericParameterAttributes.SpecialConstraintMask:\r
- break;\r
- case GenericParameterAttributes.NotNullableValueTypeConstraint:\r
- constraintText = "struct";\r
- break;\r
- case GenericParameterAttributes.VarianceMask:\r
- break;\r
- }\r
- constraint.SetAttribute("Value", String.Format("{0} : {1}", gp, constraintText));\r
- type.AppendChild(constraint);\r
- }\r
- foreach (Type gc in gp.GetGenericParameterConstraints())\r
- {\r
- if (gc != typeof(object))\r
- {\r
- XmlElement constraint = CreateElement(ret, "constraint");\r
- constraint.SetAttribute("Value", String.Format("{0} : {1}", prettyTypeName(gp), xmlClean(prettyTypeName(gc))));\r
- type.AppendChild(constraint);\r
- }\r
- }\r
- }\r
-\r
- CopyCodeDoc(type, refid, ret);\r
- root.AppendChild(type);\r
- }\r
-\r
- return ret;\r
- }\r
-\r
- C5.HashDictionary<Type, string> t2ptn = new C5.HashDictionary<Type, string>();\r
- private string prettyTypeName(Type t)\r
- {\r
- string retval;\r
- //if (!t2ptn.Find(t, out retval))\r
- //{\r
- int consumed = 0;\r
- retval = prettyTypeName(t, ref consumed);\r
- // t2ptn.Add(t, retval);\r
- //}\r
- return retval;\r
- }\r
-\r
- private string prettyTypeName(Type t, ref int consumed)\r
- {\r
- StringBuilder ret = new StringBuilder();\r
-\r
- if (t.IsGenericParameter)\r
- ret.Append(t.Name);\r
- else if (t.IsArray)\r
- ret.Append(prettyTypeName(t.GetElementType()) + "[]");\r
- else if (t.IsByRef)\r
- ret.Append("ref ").Append(prettyTypeName(t.GetElementType()));\r
- else if (!t.IsGenericType)\r
- ret.Append(t.IsNested ? prettyTypeName(t.DeclaringType, ref consumed) + "." + t.Name : t.FullName);\r
- else\r
- {\r
- bool first = true;\r
- StringBuilder gps = new StringBuilder();\r
- Type[] gp = t.GetGenericArguments();\r
-\r
- ret.Append(t.IsNested ? prettyTypeName(t.DeclaringType, ref consumed) : t.Namespace).Append(".").Append(t.Name);\r
- if (consumed < gp.Length)\r
- {\r
- //TODO: fix this ugly hack to remove `n \r
- ret.Remove(ret.Length - 2, 2);\r
- //ret = ret.Substring(0, ret.Length - 2);\r
- for (int i = consumed, length = gp.Length; i < length; i++)\r
- {\r
- Type ty = gp[i];\r
-\r
- if (first) first = false;\r
- else\r
- gps.Append(",");\r
-\r
- gps.Append(prettyTypeName(ty));\r
- }\r
-\r
- consumed = gp.Length;\r
- ret.Append("{").Append(gps.ToString()).Append("}");\r
- }\r
- }\r
-\r
- string retval = ret.ToString();\r
-\r
- if (retval.StartsWith(defaultNamespace + "."))\r
- retval = retval.Substring(defaultNamespace.Length + 1);\r
-\r
- if (longtype2short.Contains(retval))\r
- retval = longtype2short[retval];\r
-\r
- return retval;\r
- }\r
-\r
- private string prettyParameters(ParameterInfo[] pars)\r
- {\r
- string ret = "";\r
- bool first = true;\r
-\r
- foreach (ParameterInfo p in pars)\r
- {\r
- if (first) first = false;\r
- else\r
- ret += ", ";\r
- Type pt = p.ParameterType;\r
- if (p.IsOut)\r
- {\r
- ret += "out ";\r
- pt = pt.GetElementType();\r
- }\r
-\r
- ret += prettyTypeName(pt) + " " + p.Name;\r
- }\r
-\r
- return ret;\r
- }\r
-\r
- private string prettyMethodSignature(string name, MethodInfo m)\r
- {\r
- string gp = "";\r
- if (m.IsGenericMethod)\r
- {\r
- Type[] gps = m.GetGenericArguments();\r
- gp = "<";\r
-\r
- for (int i = 0; i < gps.Length; i++)\r
- gp += (i == 0 ? "" : ",") + gps[i].Name;\r
-\r
- gp += ">";\r
- }\r
-\r
- return name + gp + "(" + prettyParameters(m.GetParameters()) + ")";\r
- }\r
-\r
- private string prettyConstructorSignature(ConstructorInfo c)\r
- {\r
- Type t = c.DeclaringType;\r
-\r
- return prettyTypeName(t) + "(" + prettyParameters(c.GetParameters()) + ")";\r
- }\r
-\r
- private string prettyIndexerSignature(PropertyInfo p)\r
- {\r
- return /*prettyTypeName(p.PropertyType) + " " + */ "this[" + prettyParameters(p.GetIndexParameters()) + "]";\r
- }\r
-\r
-\r
- private string simpleTypeName(Type t)\r
- {\r
- return (t.IsNested ? simpleTypeName(t.DeclaringType) : t.Namespace) + "." + t.Name;\r
- }\r
-\r
-\r
- private string canonicalTypeName(Type t, string[] mgps)\r
- {\r
- string ret;\r
-\r
- if (t.IsGenericParameter)\r
- ret = "`" + t.GenericParameterPosition;\r
- else if (t.IsArray)\r
- ret = canonicalTypeName(t.GetElementType(), mgps) + "[]";\r
- else if (t.IsByRef)\r
- ret = canonicalTypeName(t.GetElementType(), mgps) + "@";\r
- else\r
- {\r
- ret = simpleTypeName(t);\r
- if (!t.IsGenericType)\r
- ret += "";\r
- else if (mgps == null)\r
- ret += "";//"`" + t.GetGenericArguments().Length;\r
- else\r
- {\r
- //TODO: fix this ugly hack to remove `n \r
- ret = ret.Substring(0, ret.Length - 2);\r
-\r
- bool first = true;\r
- string gps = "";\r
- Type[] gp = t.GetGenericArguments();\r
-\r
- foreach (Type ty in gp)\r
- {\r
- if (first) first = false;\r
- else\r
- gps += ",";\r
-\r
- if (ty.IsGenericParameter)\r
- {\r
- bool ismgp = false;\r
-\r
- foreach (string s in mgps) if (s.Equals(ty.Name)) ismgp = true;\r
-\r
- gps += (ismgp ? "``" : "`") + ty.GenericParameterPosition;\r
- }\r
- else\r
- gps += canonicalTypeName(ty, mgps);\r
- }\r
-\r
- ret += "{" + gps + "}";\r
- }\r
- }\r
-\r
- return ret;\r
- }\r
-\r
- private string canonicalMethodName(MethodInfo m)\r
- {\r
- string ret = canonicalTypeName(m.DeclaringType, null) + "." + m.Name;\r
-\r
- string[] gmps;\r
-\r
- if (m.IsGenericMethod)\r
- {\r
- Type[] gps = m.GetGenericArguments();\r
-\r
- ret += "``" + gps.Length;\r
- gmps = new string[gps.Length];\r
- for (int i = 0; i < gps.Length; i++)\r
- gmps[i] = gps[i].Name;\r
- }\r
- else\r
- gmps = new string[]{};\r
-\r
- ret += canonicalParameters(m.GetParameters(), gmps);\r
- return ret;\r
- }\r
-\r
- private string canonicalPropertyName(PropertyInfo p)\r
- {\r
- string pname = canonicalTypeName(p.DeclaringType, null) + "." + p.Name;\r
- ParameterInfo[] pars = p.GetIndexParameters();\r
-\r
- if (pars.Length > 0)\r
- pname += canonicalParameters(pars, new string[]{});\r
-\r
- return pname;\r
- }\r
-\r
- private string canonicalParameters(ParameterInfo[] pars, string[] gmps)\r
- {\r
- if (pars.Length == 0) return "";\r
-\r
- string ret = "";\r
- bool first = true;\r
-\r
- foreach (ParameterInfo p in pars)\r
- {\r
- if (first) first = false;\r
- else\r
- ret += ",";\r
-\r
- ret += canonicalTypeName(p.ParameterType, gmps); ;\r
- }\r
-\r
- return "(" + ret + ")";\r
- }\r
-\r
-\r
-\r
- static void Main(string[] args)\r
- {\r
- if (args.Length != 2)\r
- {\r
- args = new string[] { @"C5.dll", @"C5.xml" };\r
-\r
- }\r
- {\r
- Timer timer = new Timer();\r
- timer.snap();\r
- DocNet doc = new DocNet(args[0], args[1], "C5");\r
- XmlDocument merged = doc.GenerateDoc();\r
- Console.Error.WriteLine("Time merge: {0} ms", timer.snap());\r
-\r
- System.Xml.Xsl.XslCompiledTransform overview = new System.Xml.Xsl.XslCompiledTransform();\r
- overview.Load(@"overview.xslt");\r
- overview.Transform(merged, new XmlTextWriter(new StreamWriter(@"docbuild\contents.htm")));\r
- Console.Error.WriteLine("Time, overview: {0} ms", timer.snap());\r
-\r
- StringBuilder megaDoc = new StringBuilder();\r
- using (XmlWriter writer = XmlWriter.Create(megaDoc))\r
- {\r
- writer.WriteStartElement("hack");\r
- System.Xml.Xsl.XslCompiledTransform trans = new System.Xml.Xsl.XslCompiledTransform();\r
- trans.Load(@"trans.xslt");\r
- trans.Transform(merged, writer);\r
- writer.WriteEndElement();\r
- writer.Close();\r
- }\r
- Console.Error.WriteLine("Time trans: {0} ms", timer.snap());\r
- System.Xml.XPath.XPathDocument megaXml =\r
- new System.Xml.XPath.XPathDocument(XmlReader.Create(new StringReader(megaDoc.ToString())));\r
- System.Xml.XPath.XPathNodeIterator nodes = megaXml.CreateNavigator().Select("/hack/*");\r
- string docfn = null;\r
- foreach (System.Xml.XPath.XPathNavigator var in nodes)\r
- {\r
- if (var.Name == "filestart")\r
- docfn = var.GetAttribute("name", "");\r
- if (var.Name == "html")\r
- {\r
- Console.Error.Write(".");\r
- XmlWriter w = new XmlTextWriter(new StreamWriter(@"docbuild\types\" + docfn));\r
- var.WriteSubtree(w);\r
- w.Close();\r
- }\r
- }\r
- Console.Error.WriteLine();\r
- Console.Error.WriteLine("Time split: {0} ms", timer.snap());\r
- }\r
- Console.Write("? ");\r
- Console.Read();\r
- }\r
- }\r
-}\r
-\r
+++ /dev/null
-del docbuild\types\*.htm\r
-bin\Debug\docNet.exe ..\C5\bin\Debug\C5.dll ..\C5\c5.xml\r
+++ /dev/null
-cd c:\src\c5\src\C5\docNet\docbuild\r
-\r
-copy ..\..\C5\bin\Debug\C5.dll W:\research\c5\current\r
-copy ..\..\C5\bin\Debug\C5.pdb W:\research\c5\current\r
-\r
-rem del "W:\research\c5\current\types\*.htm"\r
-\r
-xcopy /Q *.htm W:\research\c5\current /S/Y\r
-copy docnet.css W:\research\c5\current\r
-pause\r
+++ /dev/null
-<?xml version="1.0" ?>\r
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\r
-<xsl:output encoding = "ISO-8859-1"/>\r
- <xsl:template match="/">\r
- <html>\r
- <head>\r
- <title>\r
- <xsl:text>DocNet documentation for</xsl:text>\r
- <xsl:value-of select="Assembly/@Name" /></title>\r
- <link rel="stylesheet" type="text/css" href="docnet.css" />\r
- </head>\r
- <body>\r
- <h3>Interfaces overview</h3>\r
- <xsl:for-each select="/Assembly/Interface[@Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">,<br/> </xsl:if>\r
- </xsl:for-each>\r
- <h3>Classes overview</h3>\r
- <xsl:for-each select="/Assembly/Class[@Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">,<br/> </xsl:if>\r
- </xsl:for-each>\r
- <h3>Value Types overview</h3>\r
- <xsl:for-each select="/Assembly/Struct[@Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">,<br/> </xsl:if>\r
- </xsl:for-each>\r
- <h3>Delegates overview</h3>\r
- <xsl:for-each select="/Assembly/Delegate[@Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">,<br/> </xsl:if>\r
- </xsl:for-each>\r
- </body>\r
- </html>\r
- </xsl:template>\r
- <xsl:template match="Signature">\r
- <code>\r
- <xsl:value-of select="." />\r
- </code>\r
- </xsl:template>\r
- <xsl:template name="htmllink">\r
- <xsl:choose>\r
- <xsl:when test="@refid">\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <!--xsl:text>main.htm#</xsl:text>\r
- <xsl:value-of select="@refid" /-->\r
- <xsl:text>types/</xsl:text><xsl:value-of select="substring(@refid,3)" /><xsl:text>.htm</xsl:text>\r
- </xsl:attribute>\r
- <xsl:attribute name="target">\r
- <xsl:text>main</xsl:text>\r
- </xsl:attribute>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
-</xsl:stylesheet>\r
+++ /dev/null
-<?xml version="1.0" ?>\r
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\r
- <xsl:output encoding = "ISO-8859-1" omit-xml-declaration="yes" indent="no"/>\r
- <xsl:strip-space elements="*"/>\r
- <xsl:template match="table">\r
- <xsl:text>\begin{tabular}{lc|*{15}{c}}\hline\hline </xsl:text>\r
- <xsl:apply-templates></xsl:apply-templates>\r
- <xsl:text>\hline\hline \end{tabular} </xsl:text>\r
- </xsl:template>\r
- <xsl:template match="tr">\r
- <xsl:choose>\r
- <xsl:when test="td/i">\r
- <xsl:text>\hline %</xsl:text><xsl:value-of select="td/i/font"/><xsl:text> </xsl:text>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:for-each select="th">\r
- <xsl:if test="position()!=1">\turned{</xsl:if>\r
- <xsl:apply-templates/>\r
- <xsl:if test="position()!=1">}</xsl:if>\r
- <xsl:if test="position()!=last()"><xsl:text disable-output-escaping="yes" > & </xsl:text></xsl:if>\r
- </xsl:for-each>\r
- <xsl:for-each select="td">\r
- <xsl:if test="position()=1">\texttt{</xsl:if>\r
- <xsl:if test="position()!=1">$</xsl:if>\r
- <xsl:apply-templates/>\r
- <xsl:if test="position()=1">}</xsl:if>\r
- <xsl:if test="position()!=1">$</xsl:if>\r
- <xsl:if test="position()!=last()"><xsl:text disable-output-escaping="yes" > & </xsl:text></xsl:if>\r
- </xsl:for-each>\r
- <!---->\\ <!---->\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <xsl:template match ="th">\r
- <xsl:apply-templates/>\r
- </xsl:template>\r
- <xsl:template match ="td">\r
- <xsl:apply-templates/>\r
- </xsl:template>\r
- <xsl:template match="font">\r
- <xsl:apply-templates/>\r
- </xsl:template>\r
-</xsl:stylesheet>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" ?>\r
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\r
- <xsl:output encoding = "ISO-8859-1"/>\r
- <xsl:template match="/">\r
- <xsl:apply-templates select="/Assembly/Interface" />\r
- <xsl:apply-templates select="/Assembly/Class" />\r
- <xsl:apply-templates select="/Assembly/Struct" />\r
- <xsl:apply-templates select="/Assembly/Delegate" />\r
- </xsl:template>\r
- <xsl:template match="/Assembly/Interface">\r
- <xsl:call-template name="file"/>\r
- </xsl:template>\r
- <xsl:template match="/Assembly/Class">\r
- <xsl:call-template name="file"/>\r
- </xsl:template>\r
- <xsl:template match="/Assembly/Struct">\r
- <xsl:call-template name="file"/>\r
- </xsl:template>\r
- <xsl:template match="/Assembly/Delegate">\r
- <xsl:call-template name="file"/>\r
- </xsl:template>\r
- <xsl:template name="file">\r
- <xsl:if test="@Access[.!='private']">\r
- <xsl:text> </xsl:text>\r
- <xsl:element name="filestart">\r
- <xsl:attribute name="name">\r
- <xsl:value-of select="substring(@refid,3)"/>\r
- <xsl:text>.htm</xsl:text>\r
- </xsl:attribute>\r
- </xsl:element>\r
- <xsl:text> </xsl:text>\r
- <html >\r
- <head>\r
- <title>\r
- <xsl:text>C5 doc: </xsl:text>\r
- <xsl:value-of select="@Name" />\r
- </title>\r
- <link rel="stylesheet" type="text/css" href="../docnet.css" />\r
- </head>\r
- <xsl:element name="body">\r
- <xsl:attribute name="onLoad">\r
- <xsl:text>parent.document.title ='C5 doc: </xsl:text>\r
- <xsl:value-of select="@Name" />\r
- <xsl:text>'</xsl:text>\r
- </xsl:attribute>\r
- <h2>\r
- <xsl:value-of select="name()"/>\r
- <xsl:text> </xsl:text>\r
- <xsl:call-template name="htmlname" />\r
- </h2>\r
- <xsl:apply-templates select="summary" />\r
- <xsl:call-template name="typeparams" />\r
- <xsl:call-template name="implements" />\r
- <xsl:call-template name="implementedby" />\r
- <xsl:call-template name="super" />\r
- <xsl:apply-templates select="Bases" />\r
- <xsl:call-template name="baseof" />\r
- <xsl:call-template name="foverview" />\r
- <xsl:call-template name="eoverview" />\r
- <xsl:call-template name="poverview" />\r
- <xsl:call-template name="coverview" />\r
- <xsl:call-template name="moverview" />\r
- <xsl:call-template name="ooverview" />\r
- <xsl:call-template name="ftable" />\r
- <xsl:call-template name="etable" />\r
- <xsl:call-template name="ptable" />\r
- <xsl:call-template name="ctable" />\r
- <xsl:call-template name="mtable" />\r
- <xsl:call-template name="otable" />\r
- </xsl:element>\r
- </html>\r
- </xsl:if>\r
- </xsl:template>\r
- <xsl:template name="implements">\r
- <xsl:for-each select="Implements">\r
- <xsl:sort select="@refid" />\r
- <xsl:if test="position()=1">\r
- <h3>Implements</h3>\r
- </xsl:if>\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">, </xsl:if>\r
- </xsl:for-each>\r
- </xsl:template>\r
- <xsl:template name="super">\r
- <xsl:variable name="leRefid" select="@refid" />\r
- <xsl:for-each select="/Assembly/Interface[Implements[@refid = $leRefid ] and @Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:if test="position()=1">\r
- <h3>Super</h3>\r
- </xsl:if>\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">, </xsl:if>\r
- </xsl:for-each>\r
- </xsl:template>\r
- <xsl:template name="implementedby">\r
- <xsl:variable name="leRefid" select="@refid" />\r
- <xsl:for-each select="/Assembly/Class[Implements[@refid = $leRefid ] and @Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:if test="position()=1">\r
- <h3>Implemented by</h3>\r
- </xsl:if>\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">, </xsl:if>\r
- </xsl:for-each>\r
- </xsl:template>\r
- <xsl:template match="Bases">\r
- <xsl:if test="position()=1">\r
- <h3>Bases</h3>\r
- </xsl:if>\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">, </xsl:if>\r
- </xsl:template>\r
- <xsl:template name="baseof">\r
- <xsl:variable name="leRefid" select="@refid" />\r
- <xsl:for-each select="/Assembly/Class[Bases[@refid = $leRefid ] and @Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:if test="position()=1">\r
- <h3>Base of</h3>\r
- </xsl:if>\r
- <xsl:call-template name="htmllink" />\r
- <xsl:if test="position()!=last()">, </xsl:if>\r
- </xsl:for-each>\r
- </xsl:template>\r
- <xsl:template match="param">\r
- <tr>\r
- <td valign="top">\r
- <!--code-->\r
- <xsl:value-of select="@name" />\r
- <!--/code-->\r
- <xsl:text>:</xsl:text>\r
- </td>\r
- <td valign="top">\r
- <xsl:apply-templates/>\r
- </td>\r
- </tr>\r
- </xsl:template>\r
- <xsl:template match="returns">\r
- <xsl:if test="current()[../@ReturnType!='void']">\r
- <tr>\r
- <td valign="top">\r
- <b>Returns:</b>\r
- </td>\r
- <td valign="top">\r
- <xsl:apply-templates/>\r
- </td>\r
- </tr>\r
- </xsl:if>\r
- </xsl:template>\r
- <xsl:template match="Signature">\r
- <code>\r
- <xsl:value-of select="." />\r
- </code>\r
- </xsl:template>\r
- <xsl:template match="summary">\r
- <xsl:apply-templates />\r
- </xsl:template>\r
- <xsl:template match="value">\r
- <p>\r
- <b>Value:</b>\r
- <xsl:apply-templates />\r
- </p>\r
- </xsl:template>\r
- <!-- templates for VS 2005 doc tags-->\r
- <xsl:template match="exception">\r
- <xsl:choose>\r
- <xsl:when test="current()[name(..)='summary']">\r
- <b>/Throws</b>\r
- <xsl:value-of select="substring(@cref,3)" />\r
- <xsl:apply-templates />\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <tr>\r
- <td valign="top">\r
- <xsl:variable name="leRefid" select="@cref" />\r
- <xsl:variable name="leExcNode" select="/Assembly/Class[@refid = $leRefid and @Access != 'private']"/>\r
- <xsl:choose>\r
- <xsl:when test="$leExcNode">\r
- <xsl:for-each select="$leExcNode">\r
- <xsl:call-template name="htmllink" />\r
- </xsl:for-each>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:value-of select="substring(@cref,3)" />\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </td>\r
- <td valign="top">\r
- <xsl:apply-templates />\r
- </td>\r
- </tr>\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <!--xsl:template match="code">\r
- <code>\r
- <xsl:apply-templates select="@* | node()" />\r
- </code>\r
- </xsl:template-->\r
- <xsl:template match="item">\r
- <li>\r
- <xsl:apply-templates select="@* | node()" />\r
- </li>\r
- </xsl:template>\r
- <!-- also do description and term tags, and other list types?-->\r
- <xsl:template match="list">\r
- <xsl:choose>\r
- <xsl:when test="@type='ordered'">\r
- <ol>\r
- <xsl:apply-templates select="@* | node()" />\r
- </ol>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <ul>\r
- <xsl:apply-templates select="@* | node()" />\r
- </ul>\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <xsl:template match="para">\r
- <p>\r
- <xsl:apply-templates select="@* | node()" />\r
- </p>\r
- </xsl:template>\r
- <xsl:template match="seealso">\r
- <xsl:text>See also</xsl:text>\r
- <xsl:variable name="leRefid" select="@cref" />\r
- <xsl:variable name="leNode" select="//*[@refid=$leRefid]" />\r
- <xsl:variable name="leFile" select="substring(ancestor::*[@refid and not(@Declared)]/@refid,3)" />\r
- <xsl:choose>\r
- <xsl:when test ="substring(@cref,1,2) = 'T:'">\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <xsl:value-of select="substring(@cref,3)" />\r
- <xsl:text>.htm</xsl:text>\r
- </xsl:attribute>\r
- <xsl:value-of select="$leNode/Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:when test="$leNode/@CDeclared=$leFile">\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- #<xsl:value-of select="@cref" />\r
- </xsl:attribute>\r
- <xsl:value-of select="$leNode/Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <xsl:value-of select="$leNode/@CDeclared" />.htm#<xsl:value-of select="@cref" />\r
- </xsl:attribute>\r
- <xsl:value-of select="$leNode/@Declared" />.<xsl:value-of select="$leNode/Signature" />\r
- </xsl:element>\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <xsl:template match="see">\r
- <!--xsl:text>See </xsl:text-->\r
- <xsl:variable name="leRefid" select="@cref" />\r
- <xsl:variable name="leNode" select="//*[@refid=$leRefid]" />\r
- <xsl:variable name="leFile" select="substring(ancestor::*[@refid and not(@Declared)]/@refid,3)" />\r
- <xsl:choose>\r
- <xsl:when test ="substring(@cref,1,2) = 'T:'">\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <xsl:value-of select="substring(@cref,3)" />\r
- <xsl:text>.htm</xsl:text>\r
- </xsl:attribute>\r
- <xsl:value-of select="$leNode/Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:when test="$leNode/@CDeclared=$leFile">\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <xsl:text>#</xsl:text>\r
- <xsl:value-of select="@cref" />\r
- </xsl:attribute>\r
- <xsl:value-of select="$leNode/Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <xsl:value-of select="$leNode/@CDeclared" />.htm#<xsl:value-of select="@cref" />\r
- </xsl:attribute>\r
- <xsl:value-of select="$leNode/@Declared" />.<xsl:value-of select="$leNode/Signature" />\r
- </xsl:element>\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <xsl:template match="typeparam">\r
- <tr>\r
- <td valign="top">\r
- <xsl:value-of select="@name" />\r
- </td>\r
- <td valign="top">\r
- <xsl:apply-templates />\r
- </td>\r
- </tr>\r
- </xsl:template>\r
- <xsl:template match="constraint">\r
- <tr>\r
- <td valign="top"></td>\r
- <td valign="top">\r
- <xsl:value-of select="@Value" />\r
- </td>\r
- </tr>\r
- </xsl:template>\r
- <xsl:template match="@* | node()">\r
- <xsl:copy>\r
- <xsl:apply-templates select="@* | node()" />\r
- </xsl:copy>\r
- </xsl:template>\r
- <!-- end templates for VS 2005 doc tags -->\r
- <xsl:template name="typeparams">\r
- <xsl:if test="typeparam">\r
- <table>\r
- <tr>\r
- <td>\r
- <b>Type parameters:</b>\r
- </td>\r
- <td></td>\r
- </tr>\r
- <xsl:apply-templates select="typeparam"/>\r
- <xsl:if test="constraint">\r
- <tr>\r
- <td>\r
- <b>Constraints:</b>\r
- </td>\r
- <td></td>\r
- </tr>\r
- <xsl:apply-templates select="constraint"/>\r
- </xsl:if>\r
- </table>\r
- </xsl:if>\r
- </xsl:template>\r
- <xsl:template name="htmllink">\r
- <xsl:choose>\r
- <xsl:when test="@C5">\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <xsl:choose>\r
- <xsl:when test ="substring(@refid,1,2) = 'T:'">\r
- <xsl:value-of select="substring(@refid,3)" />\r
- <xsl:text>.htm</xsl:text>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:value-of select="@CDeclared"/>.htm#<xsl:value-of select="@refid" />\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:attribute>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <xsl:template name="locallink">\r
- <xsl:choose>\r
- <xsl:when test="@refid">\r
- <xsl:element name="a">\r
- <xsl:attribute name="href">\r
- <xsl:text>#</xsl:text>\r
- <xsl:value-of select="concat(../@refid , '|',@refid)" />\r
- </xsl:attribute>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <xsl:template name="htmlname">\r
- <xsl:choose>\r
- <xsl:when test="@refid">\r
- <xsl:choose>\r
- <xsl:when test ="not(@Declared)">\r
- <!-- i.e. a type -->\r
- <xsl:element name="a">\r
- <xsl:attribute name="name">\r
- <xsl:value-of select="@refid" />\r
- </xsl:attribute>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:element>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <!-- i.e. a member -->\r
- <xsl:element name="a">\r
- <xsl:attribute name="name">\r
- <xsl:value-of select="concat(../@refid , '|',@refid)" />\r
- </xsl:attribute>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:element>\r
- <xsl:if test ="not(@Inherited)">\r
- <!-- the canonical description -->\r
- <xsl:element name="a">\r
- <xsl:attribute name="name">\r
- <xsl:value-of select="@refid" />\r
- </xsl:attribute>\r
- </xsl:element>\r
- </xsl:if>\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:apply-templates select="Signature" />\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- </xsl:template>\r
- <xsl:template name="ftable">\r
- <xsl:call-template name="table">\r
- <xsl:with-param name="type">Field</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="etable">\r
- <xsl:call-template name="table">\r
- <xsl:with-param name="type">Event</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="ptable">\r
- <xsl:call-template name="table">\r
- <xsl:with-param name="type">Property</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="ctable">\r
- <xsl:call-template name="table">\r
- <xsl:with-param name="type">Constructor</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="mtable">\r
- <xsl:call-template name="table">\r
- <xsl:with-param name="type" select="'Method'"/>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="otable">\r
- <xsl:call-template name="table">\r
- <xsl:with-param name="type" select="'Operator'"/>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="table">\r
- <xsl:param name="type" />\r
- <xsl:param name="protection" />\r
- <xsl:variable name="thenodes" select="*[name() = $type and @Access != 'private' and not(@Inherited)]" />\r
- <xsl:if test="$thenodes">\r
- <h3>\r
- <xsl:value-of select="$type" />\r
- <xsl:text> details</xsl:text>\r
- </h3>\r
- <table border="1">\r
- <xsl:for-each select="$thenodes">\r
- <xsl:sort select="@Name" />\r
- <tr>\r
- <td valign="top">\r
- <xsl:if test="current()[@Virtual != 'True' and @Static != 'True']">\r
- <code class="greenbg">N</code>\r
- </xsl:if>\r
- <xsl:if test="current()[@Final = 'True' and @Static != 'True']">\r
- <code class="greenbg">F</code>\r
- </xsl:if>\r
- <xsl:if test="current()[@Abstract = 'True']">\r
- <code class="greenbg">A</code>\r
- </xsl:if>\r
- <xsl:if test="current()[@Static = 'True']">\r
- <code class="greenbg">S</code>\r
- </xsl:if>\r
- <xsl:if test="current()[@Access = 'protected']">\r
- <code class="greenbg">P</code>\r
- </xsl:if>\r
- <code>\r
- <xsl:text> </xsl:text>\r
- <xsl:choose>\r
- <xsl:when test="@ReturnType">\r
- <xsl:value-of select="@ReturnType"/>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:value-of select="@Type"/>\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- <xsl:text> </xsl:text>\r
- </code>\r
- <xsl:call-template name="htmlname" />\r
- </td>\r
- <td>\r
- <!--xsl:if test="@Inherited">\r
- <xsl:text>Inherited from </xsl:text>\r
- <xsl:value-of select="@Declared"/>\r
- <xsl:text>: </xsl:text>\r
- <xsl:call-template name="htmllink" />\r
- </xsl:if-->\r
- <xsl:if test="not(@Inherited)">\r
- <xsl:if test="@Get">\r
- <b>Access: </b>\r
- <xsl:if test="@Get='True' and @Set='True'">Read-Write</xsl:if>\r
- <xsl:if test="@Get='True' and @Set='False'">Read-Only</xsl:if>\r
- <xsl:if test="@Get='False' and @Set='True'">Write-Only</xsl:if>\r
- <br/>\r
- </xsl:if>\r
- <xsl:apply-templates select="value" />\r
- <xsl:apply-templates select="summary" />\r
- <xsl:if test="exception">\r
- <table>\r
- <tr>\r
- <td>\r
- <b>Throws</b>\r
- </td>\r
- <td></td>\r
- </tr>\r
- <xsl:apply-templates select="exception" />\r
- </table>\r
- </xsl:if>\r
- <xsl:call-template name="typeparams"/>\r
- <xsl:if test="current()[@ReturnType != 'void'] or param">\r
- <table>\r
- <xsl:apply-templates select="returns" />\r
- <xsl:if test="param">\r
- <tr>\r
- <td>\r
- <b>Parameters:</b>\r
- </td>\r
- </tr>\r
- <xsl:apply-templates select="param" />\r
- </xsl:if>\r
- </table>\r
- </xsl:if>\r
- </xsl:if>\r
- </td>\r
- </tr>\r
- </xsl:for-each>\r
- </table>\r
- </xsl:if>\r
- </xsl:template>\r
- <xsl:template name="foverview">\r
- <xsl:call-template name="overview">\r
- <xsl:with-param name="type">Field</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="eoverview">\r
- <xsl:call-template name="overview">\r
- <xsl:with-param name="type">Event</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="poverview">\r
- <xsl:call-template name="overview">\r
- <xsl:with-param name="type">Property</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="coverview">\r
- <xsl:call-template name="overview">\r
- <xsl:with-param name="type">Constructor</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="moverview">\r
- <xsl:call-template name="overview">\r
- <xsl:with-param name="type">Method</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="ooverview">\r
- <xsl:call-template name="overview">\r
- <xsl:with-param name="type">Operator</xsl:with-param>\r
- </xsl:call-template>\r
- </xsl:template>\r
- <xsl:template name="overview">\r
- <xsl:param name="type" select="'[Unknown Locale]'" />\r
- <xsl:for-each select="*[name() = $type and @Access != 'private']">\r
- <xsl:sort select="@Name" />\r
- <xsl:if test="position() = 1">\r
- <h3>\r
- <xsl:value-of select="$type" />\r
- <xsl:text> overview</xsl:text>\r
- </h3>\r
- </xsl:if>\r
- <xsl:choose>\r
- <xsl:when test="@Inherited">\r
- <xsl:call-template name="htmllink" />\r
- <xsl:text>, </xsl:text>\r
- <xsl:text>Inherited from </xsl:text>\r
- <xsl:value-of select="@Declared"/>\r
- </xsl:when>\r
- <xsl:otherwise>\r
- <xsl:call-template name="locallink" />\r
- </xsl:otherwise>\r
- </xsl:choose>\r
- <xsl:if test="position()!=last()">\r
- ,<br/>\r
- </xsl:if>\r
- </xsl:for-each>\r
- </xsl:template>\r
-</xsl:stylesheet>\r