public static RCValue InvokeSequential(RCClosure closure, string name, RCVectorBase right) { RCActivator.OverloadKey key = new RCActivator.OverloadKey(name, typeof(object), null, right.ScalarType); Overload overload; if (!_overloads.TryGetValue(key, out overload)) { throw RCException.Overload(closure, name, right); } object array = overload.Invoke(right.Array); return(RCVectorBase.FromArray(array)); }
static VectorMath() { foreach (MethodInfo method in typeof(ScalarMath).GetMethods()) { object[] attributes = method.GetCustomAttributes(typeof(Primitive), false); for (int i = 0; i < attributes.Length; ++i) { Primitive verb = (Primitive)attributes[i]; ParameterInfo[] parameters = method.GetParameters(); if (verb.Profile == Profile.Monadic) { Type rtype = parameters[0].ParameterType; Type otype = method.ReturnType; RCActivator.OverloadKey key = new RCActivator.OverloadKey(verb.Name, typeof(object), null, rtype); Type vectoroptype = typeof(VectorMath).GetNestedType("VectorOp`2"). MakeGenericType(rtype, otype); // Why do I have to do the backtick thingy on GetNestedType but not on // GetMethod? MethodInfo vectoropMethod = typeof(VectorMath).GetMethod("MonadicOp"). MakeGenericMethod(rtype, otype); Delegate vectorop = Delegate.CreateDelegate(vectoroptype, vectoropMethod); Type primoptype = typeof(VectorMath).GetNestedType("ScalarOp`2"). MakeGenericType(rtype, otype); Delegate primop = Delegate.CreateDelegate(primoptype, method); if (_overloads.ContainsKey(key)) { throw new Exception("dispatch table already contains the key:" + key); } _overloads.Add(key, new Overload(vectorop, primop)); } else if (verb.Profile == Profile.Dyadic) { Type ltype = parameters[0].ParameterType; Type rtype = parameters[1].ParameterType; Type otype = method.ReturnType; RCActivator.OverloadKey key = new RCActivator.OverloadKey(verb.Name, typeof(object), ltype, rtype); Type vectoroptype = typeof(VectorMath).GetNestedType("VectorOp`3"). MakeGenericType(ltype, rtype, otype); // Why do I have to do the backtick thingy on GetNestedType but not on // GetMethod? MethodInfo vectoropMethod = typeof(VectorMath).GetMethod("DyadicOp"). MakeGenericMethod(ltype, rtype, otype); Delegate vectorop = Delegate.CreateDelegate(vectoroptype, vectoropMethod); Type primoptype = typeof(VectorMath).GetNestedType("ScalarOp`3"). MakeGenericType(ltype, rtype, otype); Delegate primop = Delegate.CreateDelegate(primoptype, method); if (_overloads.ContainsKey(key)) { throw new Exception("dispatch table already contains the key:" + key); } _overloads.Add(key, new Overload(vectorop, primop)); } else if (verb.Profile == Profile.Cumulative) { // The parameter is a ref parameter which is actually a different type than // the type which is being referenced. GetElementType () gives you the // referenced type which is what we want when constructing generic methods. Type stype = parameters[0].ParameterType.GetElementType(); Type rtype = parameters[1].ParameterType; Type otype = method.ReturnType; // The stype is not a parameter to the operator so it is not included in the // key. RCActivator.OverloadKey key = new RCActivator.OverloadKey(verb.Name, typeof(object), null, rtype); Type cumoptype = typeof(VectorMath).GetNestedType("CumVectorOp`2"). MakeGenericType(stype, rtype); MethodInfo cumopMethod = typeof(VectorMath).GetMethod("CumulativeOp"). MakeGenericMethod(stype, rtype); Type primoptype = typeof(VectorMath).GetNestedType("SeqScalarOp`3"). MakeGenericType(stype, rtype, otype); Delegate cumop = Delegate.CreateDelegate(cumoptype, cumopMethod); Delegate primop = Delegate.CreateDelegate(primoptype, method); if (_overloads.ContainsKey(key)) { throw new Exception("dispatch table already contains the key:" + key); } _overloads.Add(key, new Overload(cumop, primop)); } else if (verb.Profile == Profile.Sequential) { // The parameter is a ref parameter which is actually a different type than // the type which is being referenced. GetElementType () gives you the // referenced type which is what we want when constructing generic methods. Type stype = parameters[0].ParameterType.GetElementType(); Type rtype = parameters[1].ParameterType; Type otype = method.ReturnType; // The stype is not a parameter so it is not included in the key. RCActivator.OverloadKey key = new RCActivator.OverloadKey(verb.Name, typeof(object), null, rtype); Type vectoroptype = typeof(VectorMath).GetNestedType("SeqVectorOp`3"). MakeGenericType(stype, rtype, otype); // Why do I have to do the backtick thingy on GetNestedType but not on // GetMethod? MethodInfo vectoropMethod = typeof(VectorMath).GetMethod("SequentialOp"). MakeGenericMethod(stype, rtype, otype); Delegate vectorop = Delegate.CreateDelegate(vectoroptype, vectoropMethod); Type primoptype = typeof(VectorMath).GetNestedType("SeqScalarOp`3"). MakeGenericType(stype, rtype, otype); Delegate primop = Delegate.CreateDelegate(primoptype, method); if (_overloads.ContainsKey(key)) { throw new Exception("dispatch table already contains the key:" + key); } _overloads.Add(key, new Overload(vectorop, primop)); } else if (verb.Profile == Profile.Contextual) { // The parameter is a ref parameter which is actually a different type than // the type which is being referenced. GetElementType () gives you the // referenced type which is what we want when constructing generic methods. Type ctype = parameters[0].ParameterType; Type ltype = ctype.GetGenericArguments()[0]; Type rtype = parameters[1].ParameterType; Type otype = method.ReturnType; // The stype is not a parameter to the operator so it is not included in the // key. RCActivator.OverloadKey key = new RCActivator.OverloadKey(verb.Name, typeof(object), ltype, rtype); Type vectoroptype = typeof(VectorMath).GetNestedType("ConVectorOp`4"). MakeGenericType(ctype, ltype, rtype, otype); // Why do I have to do the backtick thingy on GetNestedType but not on // GetMethod? MethodInfo vectoropMethod = typeof(VectorMath).GetMethod("ContextualOp"). MakeGenericMethod(ctype, ltype, rtype, otype); Delegate vectorop = Delegate.CreateDelegate(vectoroptype, vectoropMethod); Type primoptype = typeof(VectorMath).GetNestedType("ConScalarOp`4"). MakeGenericType(ctype, ltype, rtype, otype); Delegate primop = Delegate.CreateDelegate(primoptype, method); if (_overloads.ContainsKey(key)) { throw new Exception("dispatch table already contains the key:" + key); } _overloads.Add(key, new Overload(vectorop, primop)); } } } }