Пример #1
0
        protected override ICallable CreateCallable(Type I, Type O)
        {
            var fields = I.GetFields().OrderBy(f => f.Name).ToArray();

            IgnorableAssert.Assert(fields.Length == 2, $"Controlled must always accept two args: an array of control qubits and the operation normal input tuple. Got {I.FullName}");
            IgnorableAssert.Assert(O == typeof(QVoid), $"Controlled can only be applied to Operations that return void. Received: {O.FullName}");

            var baseArgsType = fields[1].FieldType;
            var op           = this.BaseOp.FindCallable(baseArgsType, O);
            var ctrlOp       = typeof(ControlledOperation <,>).MakeGenericType(MatchOperationTypes(baseArgsType, O, op.GetType()));
            var result       = (ICallable)Activator.CreateInstance(ctrlOp, op);

            return(result);
        }
Пример #2
0
 internal static A PopNextArgs <A>(Func <A[], A> build, int nrUndefined, Stack <A> args)
 {
     IgnorableAssert.Assert(args.Count != 0, "shape mismatch in partial tuple");
     if (nrUndefined != 1 || args.Count == 1)
     {
         return(args.Pop());
     }
     else
     {
         var content = new A[args.Count];
         for (var i = 0; i < content.Length; i++)
         {
             content[i] = args.Pop();
         }
         return(build(content));
     }
 }
Пример #3
0
        /// <summary>
        /// Because C# can't automatically cast from (IUnitary, long) to (ICallable, long), sigh...
        /// we do the work for it here...
        /// </summary>
        static public object CastTuple(Type targetType, object value)
        {
            if (targetType == typeof(QVoid))
            {
                return(QVoid.Instance);
            }

            if (value == null)
            {
                return(null);
            }

            var valueType = value.GetType();

            if (targetType.IsAssignableFrom(valueType))
            {
                return(value);
            }

            if (valueType.BaseType.IsQTuple())
            {
                return(CastTuple(targetType, valueType.BaseType.GetProperty("Data").GetValue(value)));
            }

            // See bug #779
            if (targetType == typeof(Double))
            {
                return(Double.Parse(value.ToString()));
            }
            else if (targetType == typeof(Int64))
            {
                return(Int64.Parse(value.ToString()));
            }
            else if (targetType.IsTuple() && valueType.IsTuple())
            {
                var targetFields = targetType.GetFields().OrderBy(f => f.Name).ToArray();
                var valueFields  = valueType.GetFields().OrderBy(f => f.Name).ToArray();
                var values       = new object[targetFields.Length];

                Debug.Assert(targetFields.Length == valueFields.Length, $"Trying to cast tuples of different length. Expected {targetFields.Length}, but got {valueFields.Length}");

                for (var i = 0; i < targetFields.Length; i++)
                {
                    values[i] = CastTuple(targetFields[i].FieldType, valueFields[i].GetValue(value));
                }

                return(Activator.CreateInstance(targetType, values));
            }
            else if (targetType.IsQArray() && valueType.IsQArray())
            {
                Debug.Assert(targetType.GenericTypeArguments[0].IsAssignableFrom(valueType.GenericTypeArguments[0]), "Trying to cast Arrays of different types.");
                return(Activator.CreateInstance(targetType, value));
            }
            else if (targetType.IsPartialMapper() && valueType.IsPartialMapper())
            {
                var tp = targetType.GenericTypeArguments[0];
                var ti = targetType.GenericTypeArguments[1];
                var vp = valueType.GenericTypeArguments[0];
                var vi = valueType.GenericTypeArguments[1];

                var gen = typeof(PartialMapper).GetMethod(nameof(CastPartialMapper), BindingFlags.NonPublic | BindingFlags.Static);
                var m   = gen.MakeGenericMethod(tp, ti, vp, vi);
                return(m.Invoke(null, new object[] { value }));
            }
            else
            {
                IgnorableAssert.Assert(targetType.IsInstanceOfType(value) || (value == null && targetType.IsValueType == false),
                                       $"Invalid resolved value. Expected {targetType} but got {valueType}");
                return(value);
            }
        }