Click here to Skip to main content
15,895,746 members
Articles / Programming Languages / C# 4.0

The List Trifecta, Part 2

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
7 Sep 2013LGPL310 min read 28.7K   317   12  
The BDictionary is like a Dictionary mashed up with List<T>. BList and BMultiMap also say hello.
//
// Math operation structures produced with the help of T4 (Maths.tt)
// NOTE: THIS CODE HAS NOT BEEN WELL-TESTED AND DOES NOT YET HAVE A TEST SUITE.
// 
<#@ template language="C#" #>
<#@ output extension="cs" #>
<#@ include file="NumTraits.ttinclude" #>
using System.Collections.Generic;

<# foreach(Traits T in _traits) { #>

namespace Loyc.Math
{
	using System;
	using T = <#=T.QualifiedName#>;

	public struct <#=T.MathType#> : <#=T.Interfaces#>
	{
		public static readonly <#=T.MathType#> Value = new <#=T.MathType#>();

		#region INumTraits

		public T MinValue           { get { return T.MinValue; } }
		public T MaxValue           { get { return T.MaxValue; } }
		public T Epsilon            { get { return <#=T.Epsilon#>; } }
		public T PositiveInfinity   { get { return <#=T.PositiveInfinity#>; } }
		public T NegativeInfinity   { get { <#=T.ReturnNegativeInfinity#>; } }
		public T NaN                { get { <#=T.ReturnNaN#>; } }
		public bool IsInfinity(T value)   { return <#=T.IsInfinity#>; }
		public bool IsNaN(T value)        { return <#=T.IsNaN#>; }
		public bool IsSigned        { get { return <#=T.IsSigned?"true":"false"#>; } }
		public bool IsFloatingPoint { get { return <#=T.IsFloat?"true":"false"#>; } }
		public bool IsInteger       { get { return <#=T.IsInt?"true":"false"#>; } }
		public bool IsOrdered       { get { return true; } }
		public int SignificantBits  { get { return <#=T.SignificantBits#>; } }
		public int MaxIntPowerOf2   { get { return <#=T.WholeBits#>; } }
		public ulong MaxInt { get { return (ulong)<#=T.MaxInt()#>; } }
		public long MinInt  { get { return (long)<#=T.MinInt()#>; } }
		public T Zero       { get { return <#=T.Zero()#>; } }
		public T One        { get { return <#=T.One()#>; } }

		#endregion

		#region <#= T.IsSigned ? "ISignedMath" : "IMath" #>

<#		if (T.IsFixed) { #>
		public T From(uint t)   { return T.FastCast(t); }
		public T From(int t)    { return T.FastCast(t); }
		public T From(ulong t)  { return T.FastCast((long)t); }
		public T From(long t)   { return T.FastCast(t); }
		public T From(double t) { return T.FastCast(t); }

		public T Clip(uint t)   { return new T(t); }
		public T Clip(int t)    { return new T(t); }
		public T Clip(ulong t)  { return new T(t); }
		public T Clip(long t)   { return new T(t); }
		public T Clip(double t) { return new T(t); }
<#		} else { #>
		public T From(uint t)   { return (T)t; }
		public T From(int t)    { return (T)t; }
		public T From(ulong t)  { return (T)t; }
		public T From(long t)   { return (T)t; }
		public T From(double t) { return (T)t; }

<#		if (T.IsFloat) { #>		
		public T Clip(uint t)   { return (T)t; }
		public T Clip(int t)    { return (T)t; }
		public T Clip(ulong t)  { return (T)t; }
		public T Clip(long t)   { return (T)t; }
		public T Clip(double t) { return (T)t; }
<#		} else { #>
		public T Clip(uint t)   { return<#if(T.WholeBits<32){#> t > (uint)T.MaxValue ? T.MaxValue : <#}#>(T)t; }
		public T Clip(ulong t)  { return<#if(T.WholeBits<64){#> t > (ulong)T.MaxValue ? T.MaxValue : <#}#>(T)t; }
		public T Clip(int t)    { return<#if(T.WholeBits<31){#> t > (int)T.MaxValue ? T.MaxValue : <#}#>
		                   <#if(!T.IsSigned||T.WholeBits<31){#> t < (int)T.MinValue ? T.MinValue : <#}#>(T)t; }
		public T Clip(long t)   { return<#if(T.WholeBits<63){#> t > (long)T.MaxValue ? T.MaxValue : <#}#>
		                   <#if(!T.IsSigned||T.WholeBits<63){#> t < (long)T.MinValue ? T.MinValue : <#}#>(T)t; }
		public T Clip(double t) { return (T)MathEx.InRange(t, (double)0, (double)T.MaxValue); }
<#		} #>
<#		} #>

		public bool IsLess(T a, T b)        { return a < b; }
		public bool IsLessOrEqual(T a, T b) { return a <= b; }
		public T Abs(T a)                   { return <#=T.Abs()#>; }
		public T Max(T a, T b)              { return a > b ? a : b; }
		public T Min(T a, T b)              { return a < b ? a : b; }
		public int Compare(T x, T y)        { return x.CompareTo(y); }
		public bool Equals(T x, T y)        { return x == y; }
		public int GetHashCode(T x)         { return x.GetHashCode(); }

		public T Incremented(T a)           { a++; return a; }
		public T Decremented(T a)           { a--; return a; }
<#		if (T.IsFloat) { #>
		public T NextHigher(T a)            { return MathEx.NextHigher(a); }
		public T NextLower(T a)             { return MathEx.NextLower(a); }
<#		} else { #>
		public T NextHigher(T a)            { a++; return a; }
		public T NextLower(T a)             { a--; return a; }
<#		} #>

		public T Add(T a, T b)              { return (T)(a + b); }
		public T Subtract(T a, T b)         { return (T)(a - b); }
		public T Multiply(T a, T b)         { return (T)(a * b); }
		public T Divide(T a, T b)           { return (T)(a / b); }
		public T MulDiv(T a, T mul, T div)  { return (T)<#=T.MulDiv("a", "mul", "div")#>; }

<#		if (!T.IsInt) { #>
		public T Reciprocal(T a) { return One / a; }
<#		} #>
<#		if (T.IsSigned) { #>
		public T Negate(T a) { return (T)(-a); }

<#		} #>
		public T ShiftLeft(T a, int amount)  { return <#=T.ShiftLeft()#>; }
		public T ShiftRight(T a, int amount) { return <#=T.ShiftRight()#>; }

		public T Sqrt(T a)   { return <#=T.Sqrt()#>; }
		public T Square(T a) { return (T)(a * a); }

		#endregion

<#		if (T.IsInt || T.IsFixed) { #>
		#region BinaryMath

		public T And(T a, T b) { return (T)(a & b); }
		public T Or(T a, T b)  { return (T)(a | b); }
		public T Xor(T a, T b) { return (T)(a ^ b); }
		public T Not(T a)      { return (T)~a; }

		public int CountOnes(T a)     { return <#=T.CountOnes()#>; }
		public int Log2Floor(T a)     { return <#=T.Log2Floor()#>; }

		#endregion
<#		} else if (T.IsFloat) { #>
		#region ITrigonometry & IExp Members

		public T Asin(T a) { return (T)Math.Asin(a); }
		public T Acos(T a) { return (T)Math.Acos(a); }
		public T Atan(T a) { return (T)Math.Atan(a); }
		public T Atan2(T y, T x) { return (T)Math.Atan2(y, x); }

		public T Sin(T a) { return (T)Math.Sin(a); }
		public T Cos(T a) { return (T)Math.Cos(a); }
		public T Tan(T a) { return (T)Math.Tan(a); }

		public T Exp(T a)                 { return (T)Math.Exp(a); }
		public T Pow(T @base, T exponent) { return (T)Math.Pow(@base, exponent); }
		public T Ln(T a)                  { return (T)Math.Log(a); }
		#if CompactFramework
		public T Log(T a, T @base)        { return (T)(Math.Log(a) / Math.Log(@base)); }
		#else
		public T Log(T a, T @base)        { return (T)Math.Log(a, @base); }
		#endif

		#endregion
<#		} #>
	}
}
<# } #>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Software Developer None
Canada Canada
Since I started programming when I was 11, I wrote the SNES emulator "SNEqr", the FastNav mapping component, the Enhanced C# programming language (in progress), the parser generator LLLPG, and LES, a syntax to help you start building programming languages, DSLs or build systems.

My overall focus is on the Language of your choice (Loyc) initiative, which is about investigating ways to improve interoperability between programming languages and putting more power in the hands of developers. I'm also seeking employment.

Comments and Discussions