STLもどき

昨日の続きで実装を進めてみました。まずは、IArithmeticインタフェースですが、一応最終形id:ladybugさんのコメントを見て気が変わりました。(^^;

public interface IArithmetic<T> 
    where T : IComparable, IFormattable, IConvertible, IComparable<T>
{
    T Add(T x, T y);
    T Subtract(T x, T y);
    T Multiply(T x, T y);
    T Divide(T x, T y);
    T Modulus(T x, T y);
    T Negate(T x);
    T Zero { get;}
    T Unit { get;}
    T Value(int x);
    bool IsZero(T x);
    bool IsUnit(T x);
}

これくらい用意しておけば大丈夫かな。あと、byteやshortもサポートすることにしました。ただ、ushortとかuintなど負をサポートしない型でNegateを呼び出すと、NotSupportedExceptionを投げます。次に、functionalですが、ポインタやメンバ関数関連を実装する必要がないので項目は割とすくなめ。

public delegate R UnaryFunction<A, R>(A arg);
public delegate R BinaryFunction<A1, A2, R>(A1 arg1, A2 arg2);
  
public static class Functional
{
  // Methods
  public static UnaryFunction<A2, R> 
    Bind1st<A1, A2, R>(BinaryFunction<A1, A2, R> pr, A1 arg1);
  public static UnaryFunction<A1, R> 
    Bind2nd<A1, A2, R>(BinaryFunction<A1, A2, R> pr, A2 arg2);
  public static BinaryFunction<T, T, T> Divides<T, I>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T> 
    where I: IArithmetic<T>;
  public static BinaryFunction<T, T, bool> EqualTo<T>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T>;
  public static BinaryFunction<T, T, bool> Greater<T>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T>;
  public static BinaryFunction<T, T, bool> GreaterEqual<T>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T>;
  public static BinaryFunction<T, T, bool> Less<T>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T>;
  public static BinaryFunction<T, T, bool> LessEqual<T>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T>;
  public static BinaryFunction<bool, bool, bool> LogicalAnd();
  public static UnaryFunction<bool, bool> LogicalNot();
  public static BinaryFunction<bool, bool, bool> LogicalOr();
  public static BinaryFunction<T, T, T> Minus<T, I>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T> 
    where I: IArithmetic<T>;
  public static BinaryFunction<T, T, T> Modulus<T, I>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T> 
    where I: IArithmetic<T>;
  public static BinaryFunction<T, T, T> Multiplies<T, I>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T> 
    where I: IArithmetic<T>;
  public static UnaryFunction<T, bool> Not1<T>(UnaryFunction<T, bool> pr);
  public static BinaryFunction<T, T, bool> Not2<T>(BinaryFunction<T, T, bool> pr);
  public static BinaryFunction<T, T, bool> NotEqualTo<T>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T>;
  public static BinaryFunction<T, T, T> Plus<T, I>() 
    where T: IComparable, IFormattable, IConvertible, IComparable<T> 
    where I: IArithmetic<T>;
}

では、早速、こいつらを使ってテスト。

#region Using directives

using System;
using System.Collections.Generic;
using STL.Generic;
using Fn = STL.Generic.Functional;

#endregion

class Program
{
    static void Main(string[] args)
    {
        List<int> list = new List<int>();
        for (int i = 0; i < 10; ++i)
            list.Add(i);

        // 小なり
        BinaryFunction<int, int, bool> less = Fn.Less<int>();
        // 右項を7に固定
        UnaryFunction<int, bool> less7 = Fn.Bind2nd<int, int, bool>(less, 7);
        // リストから7より小さい要素を取得
        List<int> li = list.FindAll(new Predicate<int>(less7) );
        foreach (int n in li)
            Console.Write("{0} ", n);
        Console.WriteLine();
        // less7の否定
        UnaryFunction<int, bool> not_less7 = Fn.Not1<int>(less7);
        // リストから7以上の要素を取得
        li = list.FindAll(new Predicate<int>(not_less7));
        foreach (int n in li)
            Console.Write("{0} ", n);
        Console.WriteLine();

        Console.ReadLine();
    }
}
/* 結果
0 1 2 3 4 5 6
7 8 9
 */

STL.Genericが名前空間でFunctionalがstatic関数だけのクラスとなっています。勢いで作ってみましたが使いではあるのかしら?(^^;