/// <summary> /// Creates new conversion data object (an edge in a graph). /// </summary> /// <param name="source">Source vertex.</param> /// <param name="destination">Destination vertex.</param> /// <param name="convertFunc">Data conversion function.</param> /// <param name="forceSequential">Force conversion to execute sequentially.</param> /// <param name="createFunc">Destination image creation function.</param> /// <param name="cost">Conversion cost.</param> public ConversionData(T source, T destination, ConvertDataFunc convertFunc, bool forceSequential = false, CreateImageFunc createFunc = null, ConversionCost cost = ConversionCost.DataConvert) : base(source, destination) { this.CreateFunc = createFunc; this.ConvertFunc = convertFunc; this.ForceSequential = forceSequential; this.cost = cost; }
static bool IsAllowedCost(ConversionCost cost) => cost < ConversionCost.NoConversion;
public static ConversionCost Or(ConversionCost a, ConversionCost b) => a | b;
/// <summary> /// Gets maximal value of given operands. /// </summary> public static ConversionCost Max(ConversionCost a, ConversionCost b) => (a > b) ? a : b;
/// <summary> /// Gets minimal value of given operands. /// </summary> public static ConversionCost Min(ConversionCost a, ConversionCost b) => (a < b) ? a : b;
static bool IsAllowedCost(ConversionCost cost) => cost < ConversionCost.MissingArgs;
/// <summary> /// Creates expression that computes cost of the method call with given arguments. /// </summary> /// <param name="method">Method to calculate the cost.</param> /// <param name="args">Arguments provider.</param> /// <param name="costofargs">Indexes of parameters which costof() have to be calculated.</param> /// <param name="minCost">Gets minimal compile-time cost of conversion.</param> /// <returns>Expression getting cost of conversion.</returns> static Expression BindCostOf(MethodBase method, ArgumentsBinder args, BitArray costofargs, out ConversionCost minCost) { if (method == null || args == null) { throw new ArgumentNullException(); } var ps = method.GetParameters(); minCost = ConversionCost.Pass; // method( {implicit}, {mandatory}, {optional+params} ) var nimplicit = ImplicitParametersCount(ps); var nmandatory = MandatoryParametersCount(ps, nimplicit); var noptional = ps.Length - nimplicit - nmandatory; /* * var result = ConversionCost.Pass; // == 0 * * result = CostOf(argv[0], T1) | CostOf(argv[1], T2) | ... CostOf(argv[nmandatory - 1], TN) // ! BinaryOrCosts(...) * result |= (argc > expectedargs) ? TooManyArgs : Pass; * IF (noptional > 0) { ... } * * return result; */ var expr_argc = args.BindArgsCount(); int?argc_opt = (expr_argc is ConstantExpression) ? (int?)((ConstantExpression)expr_argc).Value : null; // parameters cost var block_cost = new List <Expression>(); var expr_costs = new List <Expression>(); bool hasparams = false; for (int im = 0; im < nmandatory + noptional; im++) { var p = ps[nimplicit + im]; if (noptional != 0 && p.Position == ps.Length - 1 && p.IsParamsParameter()) { hasparams = true; var element_type = p.ParameterType.GetElementType(); // for (int o = io + nmandatory; o < argc; o++) result |= CostOf(argv[o], p.ElementType) if (argc_opt.HasValue) { for (; im < argc_opt.Value; im++) { expr_costs.Add(args.BindCostOf(im, element_type, false, false)); } } else { // just return DefaultValue (which is greater than Warning), for performance reasons expr_costs.Add(Expression.Constant(ConversionCost.DefaultValue)); } break; } // expr_costs.Add(args.BindCostOf(im, p.ParameterType, im < nmandatory, costofargs[im] == false)); } if (hasparams == false) { // (argc > expectedargs) ? TooManyArgs : Pass expr_costs.Add(args.BindCostOfTooManyArgs(nmandatory + noptional)); } // collect known costs foreach (var cc in expr_costs.OfType <ConstantExpression>().Select(x => (ConversionCost)x.Value)) { minCost |= cc; } // return(CombineCosts(expr_costs)); }
public ConversionInfo(ConversionCost cost, IConversionRule rule) { Cost = cost; Rule = rule; }