public static int FindLastIndex <T>(this IIndexed <T> collection, Func <T, bool> predicate) { #region Code Contracts // Argument must be non-null Requires(collection != null, ArgumentMustBeNonNull); // Argument must be non-null Requires(predicate != null, ArgumentMustBeNonNull); // Result is a valid index Ensures(Result <int>() == (collection.Any(predicate) ? collection.Count - collection.Backwards().Count(predicate) - 1 : -1)); #endregion var index = collection.Count - 1; foreach (var item in collection.Backwards()) { if (predicate(item)) { return(index); } index--; } return(-1); }
private ObservableIndex <PathInfoLight, Ref <IHelperDescriptor <TOptions> >, IEqualityComparer <PathInfoLight> > CreateHelpersSubscription <TOptions>( IIndexed <string, IHelperDescriptor <TOptions> > source) where TOptions : struct, IHelperOptions { var equalityComparer = Compatibility.RelaxedHelperNaming ? PathInfoLight.PlainPathComparer : PathInfoLight.PlainPathWithPartsCountComparer; var existingHelpers = source.ToIndexed( o => (PathInfoLight)$"[{o.Key}]", o => new Ref <IHelperDescriptor <TOptions> >(o.Value), equalityComparer ); var target = new ObservableIndex <PathInfoLight, Ref <IHelperDescriptor <TOptions> >, IEqualityComparer <PathInfoLight> >(equalityComparer, existingHelpers); var helpersObserver = new ObserverBuilder <ObservableEvent <IHelperDescriptor <TOptions> > >() .OnEvent <DictionaryAddedObservableEvent <string, IHelperDescriptor <TOptions> > >( @event => { PathInfoLight key = $"[{@event.Key}]"; if (target.TryGetValue(key, out var @ref)) { @ref.Value = @event.Value; return; } target.AddOrReplace(key, new Ref <IHelperDescriptor <TOptions> >(@event.Value)); }) .Build(); source.As <ObservableIndex <string, IHelperDescriptor <TOptions>, StringEqualityComparer> >()?.Subscribe(helpersObserver); return(target); }
// Select N random items from coll, with replacement. // Does not modify the given list. public static SCG.IEnumerable <T> RandomWith <T>(IIndexed <T> coll, int N) { for (int i = N; i > 0; i--) { T x = coll[rnd.Next(coll.Count)]; yield return(x); } }
internal BlockHelperOptions( TemplateDelegate template, TemplateDelegate inverse, ChainSegment[] blockParamsValues, BindingContext frame ) { _extensions = frame.Bag; OriginalTemplate = template; OriginalInverse = inverse; Frame = frame; BlockVariables = blockParamsValues; }
/// <summary> /// Used to combine multiple systemCollections into one large dispatcher /// </summary> /// <param name="addedCollection"></param> /// <param name="collectionDependencies"></param> public void AddSystemCollection(SystemCollection addedCollection, params SystemCollection[] collectionDependencies) { //Register the new components foreach (KeyValuePair <Type, IIndexed <IComponent> > kvp in addedCollection.componentLUT) { IIndexed <IComponent> newStorage = (IIndexed <IComponent>)Activator.CreateInstance(kvp.Value.GetType()); if (componentLUT.ContainsKey(kvp.Key)) { componentLUT[kvp.Key] = (newStorage.density > componentLUT[kvp.Key].density) ? newStorage as IIndexed <IComponent> : componentLUT[kvp.Key]; } else { componentLUT.Add(kvp.Key, (IIndexed <IComponent>)Activator.CreateInstance(kvp.Value.GetType())); } } //Register the new resources foreach (KeyValuePair <Type, IComponent> kvp in addedCollection.resourceLUT) { if (!resourceLUT.ContainsKey(kvp.Key)) { resourceLUT.Add(kvp.Key, kvp.Value); } } //Register the new systems foreach (KeyValuePair <ISystem, SystemDependencies> kvp in addedCollection.systems) { List <ISystem> depends = new List <ISystem>(); foreach (SystemCollection SC in collectionDependencies) { foreach (ISystem SD in SC.systems.Keys) { depends.Add(SD); } } depends.AddRange(kvp.Value.dependencies); RegisterSystem(kvp.Key, depends.ToArray()); } //Combine startup events OnStart += addedCollection.OnStart; }
/// <summary> /// Formats several fixed width strings into columns of the specified widths, performing word wrapping and alignment as specified. /// </summary> /// <param name="indent">The indentation (number of white space characters) to use before the first column.</param> /// <param name="columnSpacing">The spacing to use in between columns.</param> /// <param name="columns">An array of the <see cref="ColumnInfo"/> objects representing the columns to use.</param> /// <returns>A single string that when printed will represent the original strings formatted as specified in each <see cref="ColumnInfo"/> /// object.</returns> /// <exception cref="ArgumentNullException">A <see cref="ColumnInfo.Content"/> for a column was a null reference (<b>Nothing</b> in Visual Basic)</exception> /// <exception cref="ArgumentOutOfRangeException">The specified <see cref="ColumnInfo.Width"/> for a column was less than, or equal to zero.</exception> /// <exception cref="ArgumentException"><paramref name="columnSpacing"/> was less than zero, or, <paramref name="indent"/> was less than /// zero, or, no columns were specified.</exception> public static string FormatInColumns(int indent, int columnSpacing, params ColumnInfo[] columns) { if (columnSpacing < 0) throw new ArgumentException("columnSpacing must not be less than zero", "columnSpacing"); if (indent < 0) throw new ArgumentException("indent must not be less than zero", "indent"); if (columns.Length == 0) return ""; IIndexed<string>[] strings = new IIndexed<string>[columns.Length]; int totalLineCount = 0; // Calculate the total number of lines that needs to be printed for (int i = 0; i < columns.Length; i++) { strings[i] = SplitAtLineBreaks(WordWrap(columns[i].Content, columns[i].Width, columns[i].WordWrappingMethod, columns[i].Alignment, ' '), false); totalLineCount = Math.Max(strings[i].Count, totalLineCount); } // Calculate the first line on which each column should start to print, based // on its vertical alignment. int[] startLine = new int[columns.Length]; for (int col = 0; col < columns.Length; col++) { switch (columns[col].VerticalAlignment) { case VerticalAlignment.Top: startLine[col] = 0; break; case VerticalAlignment.Bottom: startLine[col] = totalLineCount - strings[col].Count; break; case VerticalAlignment.Middle: startLine[col] = (totalLineCount - strings[col].Count) / 2; break; default: throw new InvalidOperationException(Resources.CommandLineStrings.InternalErrorUnimplementedVerticalAlignmentUsed); } } StringBuilder result = new StringBuilder(); for (int line = 0; line < totalLineCount; line++) { result.Append(' ', indent); for (int col = 0; col < columns.Length; col++) { if (line >= startLine[col] && line - startLine[col] < strings[col].Count) { result.Append(strings[col][line - startLine[col]]); } else { result.Append(' ', columns[col].Width); } if (col < columns.Length - 1) result.Append(' ', columnSpacing); } if (line != totalLineCount - 1) result.Append(Environment.NewLine); } return result.ToString(); }
/// <summary> /// Formats several fixed width strings into columns of the specified widths, performing word wrapping and alignment as specified. /// </summary> /// <param name="indent">The indentation (number of white space characters) to use before the first column.</param> /// <param name="columnSpacing">The spacing to use in between columns.</param> /// <param name="columns">An array of the <see cref="ColumnInfo"/> objects representing the columns to use.</param> /// <returns>A single string that when printed will represent the original strings formatted as specified in each <see cref="ColumnInfo"/> /// object.</returns> /// <exception cref="ArgumentNullException">A <see cref="ColumnInfo.Content"/> for a column was a null reference (<b>Nothing</b> in Visual Basic)</exception> /// <exception cref="ArgumentOutOfRangeException">The specified <see cref="ColumnInfo.Width"/> for a column was less than, or equal to zero.</exception> /// <exception cref="ArgumentException"><paramref name="columnSpacing"/> was less than zero, or, <paramref name="indent"/> was less than /// zero, or, no columns were specified.</exception> public static string FormatInColumns(int indent, int columnSpacing, params ColumnInfo[] columns) { if (columnSpacing < 0) { throw new ArgumentException("columnSpacing must not be less than zero", "columnSpacing"); } if (indent < 0) { throw new ArgumentException("indent must not be less than zero", "indent"); } if (columns.Length == 0) { return(""); } IIndexed <string>[] strings = new IIndexed <string> [columns.Length]; int totalLineCount = 0; // Calculate the total number of lines that needs to be printed for (int i = 0; i < columns.Length; i++) { strings[i] = SplitAtLineBreaks(WordWrap(columns[i].Content, columns[i].Width, columns[i].WordWrappingMethod, columns[i].Alignment, ' '), false); totalLineCount = Math.Max(strings[i].Count, totalLineCount); } // Calculate the first line on which each column should start to print, based // on its vertical alignment. int[] startLine = new int[columns.Length]; for (int col = 0; col < columns.Length; col++) { switch (columns[col].VerticalAlignment) { case VerticalAlignment.Top: startLine[col] = 0; break; case VerticalAlignment.Bottom: startLine[col] = totalLineCount - strings[col].Count; break; case VerticalAlignment.Middle: startLine[col] = (totalLineCount - strings[col].Count) / 2; break; default: throw new InvalidOperationException(Resources.CommandLineStrings.InternalErrorUnimplementedVerticalAlignmentUsed); } } StringBuilder result = new StringBuilder(); for (int line = 0; line < totalLineCount; line++) { result.Append(' ', indent); for (int col = 0; col < columns.Length; col++) { if (line >= startLine[col] && line - startLine[col] < strings[col].Count) { result.Append(strings[col][line - startLine[col]]); } else { result.Append(' ', columns[col].Width); } if (col < columns.Length - 1) { result.Append(' ', columnSpacing); } } if (line != totalLineCount - 1) { result.Append(Environment.NewLine); } } return(result.ToString()); }
/// <summary> /// Aligns the specified string within a field of the desired width, cropping it if it doesn't fit, and expanding it otherwise. /// </summary> /// <param name="str">The string to align.</param> /// <param name="width">The width of the field in characters in which the string should be fitted.</param> /// <param name="alignment">The aligmnent that will be used for fitting the string in the field in case it is shorter than the specified field width.</param> /// <param name="cropping">The method that will be used for cropping if the string is too wide to fit in the specified width.</param> /// <param name="ellipsis">A string that will be inserted at the cropped side(s) of the string to denote that the string has been cropped.</param> /// <param name="padCharacter">The character that will be used for padding the string in case it is shorter than the specified field width.</param> /// <returns> /// A string exactly <paramref name="width"/> characters wide, containing the specified string <paramref name="str"/> fitted /// according to the parameters specified. /// </returns> /// <remarks>If the string consists of several lines, each line will be aligned according to the specified parameters.</remarks> /// <exception cref="ArgumentNullException"><paramref name="str"/> was a null reference (<b>Nothing</b> in Visual Basic)</exception> /// <exception cref="ArgumentOutOfRangeException">The specified <paramref name="width"/> was less than, or equal to zero.</exception> /// <exception cref="ArgumentException"><paramref name="width"/> is less than the length of the specified <paramref name="ellipsis"/>, or, /// the cropping specified is <see cref="Cropping.Both"/> and <paramref name="width"/> was less than <i>twice</i> the /// length of the <paramref name="ellipsis"/></exception> public static string Align(string str, int width, Alignment alignment, Cropping cropping, string ellipsis, char padCharacter) { if (str == null) { throw new ArgumentNullException("str"); } if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (ellipsis != null) { if (cropping != Cropping.Both && width < ellipsis.Length) { throw new ArgumentException("width must not be less than the length of ellipsis"); } else if (cropping == Cropping.Both && width < ellipsis.Length * 2) { throw new ArgumentException("width must not be less than twice the length of the ellipsis when cropping is set to Both"); } } IIndexed <string> lines = SplitAtLineBreaks(str); StringBuilder result = new StringBuilder(); for (int j = 0; j < lines.Count; j++) { if (j != 0) { result.Append(Environment.NewLine); } string s = lines[j]; int length = s.Length; if (length <= width) { switch (alignment) { case Alignment.Left: result.Append(s); result.Append(padCharacter, width - length); continue; case Alignment.Right: result.Append(padCharacter, width - length); result.Append(s); continue; case Alignment.Center: result.Append(padCharacter, (width - length) / 2); result.Append(s); result.Append(padCharacter, (width - length) - ((width - length) / 2)); continue; case Alignment.Justified: string trimmed = s.Trim(); length = trimmed.Length; int spaceCount = GetWordCount(s) - 1; Debug.Assert(spaceCount >= 0); if (spaceCount == 0) // string only contain a single word { result.Append(trimmed); result.Append(padCharacter, width - length); } StringBuilder localResult = new StringBuilder(); int remainingSpace = width - length; bool readingWord = true; for (int i = 0; i < length; i++) { if (!char.IsWhiteSpace(trimmed[i])) { readingWord = true; localResult.Append(trimmed[i]); } else if (readingWord) { localResult.Append(trimmed[i]); int spacesToAdd = remainingSpace / spaceCount--; remainingSpace -= spacesToAdd; localResult.Append(padCharacter, spacesToAdd); readingWord = false; } } result.Append(localResult); continue; default: throw new InvalidOperationException("Internal error; Unimplemented Justification specified"); } } // The string is too long and need to be cropped switch (cropping) { case Cropping.Right: return(s.Substring(0, width - ellipsis.Length) + ellipsis); case Cropping.Left: return(ellipsis + s.Substring(length - width + ellipsis.Length)); case Cropping.Both: return(ellipsis + s.Substring(length / 2 - width / 2, width - ellipsis.Length * 2) + ellipsis); default: break; } } return(result.ToString()); }
public AttunementManager(IEnumerable <IAttunementSpecification> specifications, IIndexed <Type, IAttunement> attunementFactories) { this.specifications = specifications; this.attunements = attunementFactories; }
private void AssertErrorMessagesContainNameOfIndexedSetterNotHiddenMethod(IIndexed indexed) { SkipVerificationForThisTest(); Expect.Once.On(indexed).Set["Bill", "Gates"].To("Microsoft"); try { indexed["Steve", "Jobs"] = "Apple"; } catch (ExpectationException e) { Assert.IsTrue(e.Message.IndexOf("set_Item") < 0, "message should not contain set_Item"); Assert.IsTrue( e.Message.IndexOf("indexed[equal to \"Bill\", equal to \"Gates\"] = (equal to \"Microsoft\")") >= 0, "message should contain indexed[equal to \"Bill\", equal to \"Gates\"] = \"Microsoft\"\nWas: " + e.Message); Assert.IsTrue(e.Message.IndexOf("indexed[\"Steve\", \"Jobs\"] = \"Apple\"") >= 0, "message should contain indexed[\"Steve\", \"Jobs\"] = \"Apple\"\nWas: " + e.Message); } }
private void AssertErrorMessagesContainNameOfIndexedGetterNotHiddenMethod(IIndexed indexed) { SkipVerificationForThisTest(); Stub.On(indexed).Get["Bill", "Gates"].Will(Return.Value("Microsoft")); try { String.Intern(indexed["Steve", "Jobs"]); } catch (ExpectationException e) { Assert.IsTrue(e.Message.IndexOf("get_Item") < 0, "message should not contain get_Item"); Assert.IsTrue(e.Message.IndexOf("indexed[equal to \"Bill\", equal to \"Gates\"]") >= 0, "message should contain indexed[equal to \"Bill\", equal to \"Gates\"]\nWas: " + e.Message); Assert.IsTrue(e.Message.IndexOf("indexed[\"Steve\", \"Jobs\"]") >= 0, "message should contain indexed[\"Steve\", \"Jobs\"]\nWas: " + e.Message); } }
private void AssertCanExpectIndexedSetter(IIndexed indexed) { Expect.Once.On(indexed).Set["Bill", "Gates"].To("Microsoft"); indexed["Bill", "Gates"] = "Microsoft"; }
private void AssertCanExpectIndexedGetter(IIndexed indexed) { Stub.On(indexed).Get["Bill", "Gates"].Will(Return.Value("Microsoft")); Stub.On(indexed).Get["Steve", "Jobs"].Will(Return.Value("Apple")); Assert.AreEqual("Microsoft", indexed["Bill", "Gates"], "Bill, Gates"); Assert.AreEqual("Apple", indexed["Steve", "Jobs"], "Steve, Jobs"); }