11using System ;
22using System . Collections ;
33using System . Collections . Generic ;
4+ #if NET6_0_OR_GREATER
5+ using System . ComponentModel ;
6+ using System . Diagnostics ;
7+ using System . Globalization ;
8+ #endif
49using System . Runtime . CompilerServices ;
510
611namespace StringBuilderArray
@@ -31,7 +36,6 @@ private StringBuilderArray()
3136
3237 public int Length
3338 {
34- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
3539 get
3640 {
3741 var result = 0 ;
@@ -50,7 +54,6 @@ public int Length
5054 }
5155 }
5256
53- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
5457 public StringBuilderArray Append ( string str )
5558 {
5659 if ( _size == _buffer . Length )
@@ -127,7 +130,11 @@ public StringBuilderArray AppendLine(string str)
127130 return Append ( Environment . NewLine ) ;
128131 }
129132
130- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
133+ public StringBuilderArray AppendLine ( )
134+ {
135+ return Append ( Environment . NewLine ) ;
136+ }
137+
131138 public StringBuilderArray Append ( IList < string > strings )
132139 {
133140 foreach ( var str in strings )
@@ -499,5 +506,157 @@ public void Reset()
499506 }
500507
501508 #endregion
509+
510+ #if NET6_0_OR_GREATER
511+
512+ public StringBuilderArray Append ( [ InterpolatedStringHandlerArgument ( "" ) ] ref StringBuilderArrayStringHandler handler ) => this ;
513+
514+ public StringBuilderArray Append ( IFormatProvider provider , [ InterpolatedStringHandlerArgument ( "" , "provider" ) ] ref StringBuilderArrayStringHandler handler ) => this ;
515+
516+ public StringBuilderArray AppendLine ( [ InterpolatedStringHandlerArgument ( "" ) ] ref StringBuilderArrayStringHandler handler ) => AppendLine ( ) ;
517+
518+ public StringBuilderArray AppendLine ( IFormatProvider provider , [ InterpolatedStringHandlerArgument ( "" , "provider" ) ] ref StringBuilderArrayStringHandler handler ) => AppendLine ( ) ;
519+
520+ [ EditorBrowsable ( EditorBrowsableState . Never ) ]
521+ [ InterpolatedStringHandler ]
522+ public struct StringBuilderArrayStringHandler
523+ {
524+ private static readonly string _whitespace = " " ;
525+
526+ private readonly StringBuilderArray _stringBuilder ;
527+ private readonly IFormatProvider _provider ;
528+ private readonly bool _hasCustomFormatter ;
529+
530+ public StringBuilderArrayStringHandler ( int literalLength , int formattedCount , StringBuilderArray stringBuilder )
531+ {
532+ _stringBuilder = stringBuilder ;
533+ _provider = null ;
534+ _hasCustomFormatter = false ;
535+ }
536+
537+ public StringBuilderArrayStringHandler ( int literalLength , int formattedCount , StringBuilderArray stringBuilder , IFormatProvider provider )
538+ {
539+ _stringBuilder = stringBuilder ;
540+ _provider = provider ;
541+ _hasCustomFormatter = provider is not null && HasCustomFormatter ( provider ) ;
542+ }
543+
544+ public void AppendLiteral ( string value ) => _stringBuilder . Append ( value ) ;
545+
546+ #region AppendFormatted
547+
548+ #region AppendFormatted T
549+ public void AppendFormatted < T > ( T value )
550+ {
551+ if ( _hasCustomFormatter )
552+ {
553+ AppendCustomFormatter ( value , format : null ) ;
554+ }
555+ else if ( value is IFormattable )
556+ {
557+ _stringBuilder . Append ( ( ( IFormattable ) value ) . ToString ( format : null , _provider ) ) ;
558+ }
559+ else if ( value is not null )
560+ {
561+ _stringBuilder . Append ( value . ToString ( ) ) ;
562+ }
563+ }
564+
565+ public void AppendFormatted < T > ( T value , string format )
566+ {
567+ if ( _hasCustomFormatter )
568+ {
569+ AppendCustomFormatter ( value , format ) ;
570+ }
571+ else if ( value is IFormattable )
572+ {
573+ _stringBuilder . Append ( ( ( IFormattable ) value ) . ToString ( format , _provider ) ) ;
574+ }
575+ else if ( value is not null )
576+ {
577+ _stringBuilder . Append ( value . ToString ( ) ) ;
578+ }
579+ }
580+
581+ public void AppendFormatted < T > ( T value , int alignment ) => AppendFormatted ( value , alignment , format : null ) ;
582+
583+ public void AppendFormatted < T > ( T value , int alignment , string format )
584+ {
585+ if ( alignment == 0 )
586+ {
587+ AppendFormatted ( value , format ) ;
588+ }
589+ else if ( alignment < 0 )
590+ {
591+ int start = _stringBuilder . Length ;
592+ AppendFormatted ( value , format ) ;
593+ int paddingRequired = - alignment - ( _stringBuilder . Length - start ) ;
594+ if ( paddingRequired > 0 )
595+ {
596+ for ( int i = 0 ; i < paddingRequired ; i ++ )
597+ {
598+ _stringBuilder . Append ( _whitespace ) ;
599+ }
600+ }
601+ }
602+ else
603+ {
604+ for ( int i = 0 ; i < alignment ; i ++ )
605+ {
606+ _stringBuilder . Append ( _whitespace ) ;
607+ }
608+ AppendFormatted ( value , format ) ;
609+ }
610+ }
611+ #endregion
612+
613+ #region AppendFormatted string
614+ public void AppendFormatted ( string value )
615+ {
616+ if ( ! _hasCustomFormatter )
617+ {
618+ _stringBuilder . Append ( value ) ;
619+ }
620+ else
621+ {
622+ AppendFormatted < string > ( value ) ;
623+ }
624+ }
625+
626+ public void AppendFormatted ( string value , int alignment = 0 , string format = null ) => AppendFormatted < string > ( value , alignment , format ) ;
627+ #endregion
628+
629+ #region AppendFormatted object
630+ public void AppendFormatted ( object value , int alignment = 0 , string format = null ) => AppendFormatted < object > ( value , alignment , format ) ;
631+ #endregion
632+
633+ #endregion
634+
635+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
636+ private void AppendCustomFormatter < T > ( T value , string format )
637+ {
638+ Debug . Assert ( _hasCustomFormatter ) ;
639+ Debug . Assert ( _provider != null ) ;
640+
641+ ICustomFormatter formatter = ( ICustomFormatter ) _provider . GetFormat ( typeof ( ICustomFormatter ) ) ;
642+ Debug . Assert ( formatter != null , "An incorrectly written provider said it implemented ICustomFormatter, and then didn't" ) ;
643+
644+ if ( formatter is not null )
645+ {
646+ _stringBuilder . Append ( formatter . Format ( format , value , _provider ) ) ;
647+ }
648+ }
649+
650+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
651+ internal static bool HasCustomFormatter ( IFormatProvider provider )
652+ {
653+ Debug . Assert ( provider is not null ) ;
654+ Debug . Assert ( provider is not CultureInfo || provider . GetFormat ( typeof ( ICustomFormatter ) ) is null , "Expected CultureInfo to not provide a custom formatter" ) ;
655+ return
656+ provider . GetType ( ) != typeof ( CultureInfo ) &&
657+ provider . GetFormat ( typeof ( ICustomFormatter ) ) != null ;
658+ }
659+ }
660+ #endif
502661 }
503662}
0 commit comments