Skip to content

Instantly share code, notes, and snippets.

@ZacharyPatten
Created March 13, 2020 15:14
Show Gist options
  • Save ZacharyPatten/b9353e5a7b1930d16ef6128aa7a16246 to your computer and use it in GitHub Desktop.
Save ZacharyPatten/b9353e5a7b1930d16ef6128aa7a16246 to your computer and use it in GitHub Desktop.
An example of custom syntax for making sets of numbers.
using System;
using System.Collections;
using System.Collections.Generic;
using static SetSyntax;
class Program
{
static void Main()
{
var numbers = Set * 0..5 - 1..3 + 9..20 - 12..15 + 7 - 19;
foreach (int value in numbers)
{
Console.WriteLine(value);
}
}
}
public struct SetSyntax : IEnumerable<int>
{
public static SetSyntax Set => default;
internal HashSet<int> Numbers;
internal SetSyntax(HashSet<int> set) => Numbers = set;
public static SetSyntax operator +(SetSyntax a, int b) => new SetSyntax(a.Numbers.AddTo(b));
public static SetSyntax operator +(SetSyntax a, Range b) => new SetSyntax(a.Numbers.AddTo(b.Enumerate()));
public static SetSyntax operator -(SetSyntax a, int b) => new SetSyntax(a.Numbers.RemoveFrom(b));
public static SetSyntax operator -(SetSyntax a, Range b) => new SetSyntax(a.Numbers.RemoveFrom(b.Enumerate()));
public static SetSyntax operator *(SetSyntax a, int b) => new SetSyntax(new HashSet<int>(new[] { b }));
public static SetSyntax operator *(SetSyntax a, Range b) => new SetSyntax(new HashSet<int>(b.Enumerate()));
public IEnumerator<int> GetEnumerator() => Numbers.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Numbers.GetEnumerator();
}
public static class Extensions
{
internal static HashSet<T> AddTo<T>(this HashSet<T> set, T value)
{
set.Add(value);
return set;
}
internal static HashSet<T> RemoveFrom<T>(this HashSet<T> set, T value)
{
set.Remove(value);
return set;
}
internal static HashSet<T> AddTo<T>(this HashSet<T> set, IEnumerable<T> enumerable)
{
enumerable.ForEach(i => set.Add(i));
return set;
}
internal static HashSet<T> RemoveFrom<T>(this HashSet<T> set, IEnumerable<T> enumerable)
{
enumerable.ForEach(i => set.Remove(i));
return set;
}
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (T v in enumerable)
action(v);
}
public static IEnumerable<int> Enumerate(this Range range)
{
int length = range.End.Value - range.Start.Value;
for (int i = 0; i < length; i++)
yield return i + range.Start.Value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment