/// <summary>
 /// Gets or creates the value.
 /// </summary>
 /// <param name="key">The key.</param>
 /// <param name="valueCreator">The value creator.</param>
 /// <returns></returns>
 /// <remarks>
 /// This method should be used with statically allocated delegates.
 /// To this end, non-trivial delegates passed to this method should always be declared as
 /// a static method, to prevent accidental closures.
 /// </remarks>
 public TValue SynchronizedGetOrCreateValue(TKey key, ValueCreator valueCreator)
 {
     lock (this)
     {
         return(this.GetOrCreateValue(key, valueCreator));
     }
 }
        /// <summary>
        /// Gets or creates the value.
        /// </summary>
        /// <remarks>
        /// The purpose of the context argument is to enable statically allocated delegates.
        /// To this end, non-trivial delegates passed to this method should always be declared as
        /// a static method, to prevent accidental closures.
        /// </remarks>
        /// <typeparam name="TContext">The type of the context.</typeparam>
        /// <param name="key">The key.</param>
        /// <param name="context">The context.</param>
        /// <param name="valueCreator">The value creator.</param>
        /// <returns></returns>
        public TValue GetOrCreateValue <TContext>(TKey key, TContext context, ValueCreator <TContext> valueCreator)
        {
            Contract.Requires(key != null);
            TValue res;

            if (!this.TryGetValue(key, out res))
            {
                res = valueCreator(key, context);
                this.Insert(key, res, true);
            }
            return(res);
        }
        /// <summary>
        /// Gets or creates the value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="valueCreator">The value creator.</param>
        /// <returns></returns>
        /// <remarks>
        /// This method should be used with statically allocated delegates.
        /// To this end, non-trivial delegates passed to this method should always be declared as
        /// a static method, to prevent accidental closures.
        /// </remarks>
        public TValue GetOrCreateValue(TKey key, ValueCreator valueCreator)
        {
            Contract.Requires(key != null);
            // TODO: Profile and consider merging TryGetValue and Insert
            TValue res;

            if (!this.TryGetValue(key, out res))
            {
                res = valueCreator(key);
                this.Insert(key, res, true);
            }
            return(res);
        }
 /// <summary>
 /// Gets the value associated with the specified key. If it doesn't exist in the cache
 /// then it will be created with createValue() and added to the cache.
 /// </summary>
 public Value GetAndAddValue(Key key, ValueCreator createValue)
 {
     if (this.cache.ContainsKey(key) == false)
     {
         while (this.cache.Count >= this.maxCacheSize)
         {
             this.valueRemover.MoveNext();
         }
         this.cache[key] = new ValueWithReference(createValue());
     }
     this.cache[key].recentlyUsed = true;
     return(this.cache[key].value);
 }
Beispiel #5
0
        public void TestExpression(Dictionary <string, object> context, string expression, object expectedResult)
        {
            var questions = new List <Questionnaires.RunTime.Question>();

            foreach (var value in context)
            {
                questions.Add(ValueCreator.CreateQuestion(value.Key, (dynamic)value.Value));
            }

            var store = new QuestionStore(questions);

            var astFactory = new ASTBuilder(new Result());
            var AST        = astFactory.BuildExpression(expression);

            var evaluator = new Questionnaires.RunTime.ExpressionEvaluator(store);
            var result    = evaluator.Evaluate((IExpression)AST);

            Value.ValueTester.Test((dynamic)result, expectedResult);
        }
Beispiel #6
0
        /// <summary>
        ///     Parses the Expression starting at the specified Operator Precedence
        /// </summary>
        /// <param name="stopAt">Operator Precedence</param>
        /// <returns>Expression at the Specified Index</returns>
        public HlExpression ParseExpr(int stopAt)
        {
            if (stopAt == -1)
            {
                stopAt = m_OpCollection.Highest;
            }

            HlExpression node = ValueCreator.CreateValue(this, ( uint )stopAt);

            if (CurrentToken.Type == HlTokenType.OpSemicolon)
            {
                Eat(HlTokenType.OpSemicolon);

                return(node);
            }

            int end = Math.Min(stopAt, m_OpCollection.Highest);

            for (int i = 0; i <= end; i++)
            {
                if (!m_OpCollection.HasLevel(i))
                {
                    continue;
                }

                List <HlExpressionOperator> ops     = m_OpCollection.GetLevel(i);
                HlExpressionOperator        current = ops.FirstOrDefault(x => x.CanCreate(this, node));

                if (current != null)
                {
                    node = current.Create(this, node);
                }
            }

            return(node);
        }
 /// <summary>
 /// Gets or creates the value.
 /// </summary>
 /// <remarks>
 /// The purpose of the context argument is to enable statically allocated delegates.
 /// To this end, non-trivial delegates passed to this method should always be declared as
 /// a static method, to prevent accidental closures.
 /// </remarks>
 /// <typeparam name="TContext">The type of the context.</typeparam>
 /// <param name="key">The key.</param>
 /// <param name="context">The context.</param>
 /// <param name="valueCreator">The value creator.</param>
 /// <returns></returns>
 public TValue SynchronizedGetOrCreateValue <TContext>(TKey key, TContext context, ValueCreator <TContext> valueCreator)
 {
     Contract.Requires(key != null);
     lock (this)
     {
         return(this.GetOrCreateValue <TContext>(key, context, valueCreator));
     }
 }