uCalc API Version: 2.1.3-preview.2 Released: 6/17/2026

Warning

uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.

(Constructor)

Constructor

Product: 

Fast Math Parser

Class: 

uCalcBase

Creates a new uCalc instance, optionally cloning an existing one, or creating an empty placeholder.

Remarks

The uCalc constructor initializes a new evaluation engine. Depending on the overload used, the new instance may:

  • Clone the default engine
  • Clone a specific engine
  • Create an empty placeholder for later assignment

Each instance maintains its own isolated namespace of variables, functions, operators, tokens, transformers, and configuration settings.


Constructor Overloads

1. uCalc(bool setAsDefault = false, bool autoRelease = false)

Creates a new uCalc instance as a clone of the Default instance.

  • setAsDefault = true
    The new instance becomes the new Default instance.
    Equivalent to calling IsDefault(true) after construction.

  • autoRelease (C++ only)
    Marks the instance for automatic release when it goes out of scope.
    Equivalent to calling Owned().

Isolation:
The new instance is a deep clone. Changes to this instance do not affect the Default instance or any other instance.


2. uCalc(uCalc other) (C# only)

Creates a new instance as a clone of another uCalc instance.

  • Not supported in C++ (invokes the native copy constructor instead).
  • For cross‑language consistency, prefer Clone().

4. uCalc(uCalc::Empty)

Creates an empty placeholder instance.

  • Allocates only a minimal handle
  • No internal engine state
  • Can later be assigned a real instance (e.g., via Clone() or assignment)

Useful for deferred initialization.


Instance Lifetime & Scoping

uCalc instances behave differently depending on:

  • How they were created (constructor vs Clone())
  • Whether they are owned
  • Whether the language supports deterministic destruction

Below is the unified model.


Lifetime Rules (All Languages)

Instances created with Clone()

  • Always persist until explicitly released with Release()
  • Going out of scope does not release them
  • The variable holding the handle may be destroyed, but the engine remains alive

Therefore:
Always call Release() when you no longer need a cloned instance.


C# Lifetime Rules

Constructor-created instances

  • Are automatically released only when used with using
  • Without using, they behave like cloned instances and must be released manually

Clone() instances

  • Same rule: auto-release only when wrapped in using

Examples:

{     var u1 = new uCalc();     var u2 = uc.Clone();     // Neither u1 nor u2 auto-release  }{     using var u1 = new uCalc();     using var u2 = uc.Clone();     // Both auto-release  }

C++ Lifetime Rules

Constructor-created instances

  • Auto-release when the object goes out of scope

Clone() instances

  • Must be released manually unless wrapped in a stack‑allocated uCalc

Examples:

{     auto u1 = new uCalc();     auto u2 = uc.Clone();     // Must call Release() manually  }{     uCalc u1;     uCalc u2(uc.Clone());     uc1.Owned();   uc2.Owned();   // Auto-release on scope exit  }

MemoryIndex vs Handle

  • Handle
    Internal pointer-like value; unpredictable value; cannot be duplicated.

  • MemoryIndex
    Stable, predictable identifier for an instance.
    Useful for detecting whether an instance has been released.

Released instances are recycled.
If you create a new instance immediately after releasing another, it will typically reuse the same MemoryIndex.


Comparative Analysis — Why uCalc?

vs. Native C#/C++ Objects

  • uCalc instances encapsulate a full expression engine, not just data
  • Cloning produces isolated execution environments
  • Deterministic destruction is optional and configurable
  • MemoryIndex provides introspection not available in native objects

vs. Script Engines

  • uCalc instances are lightweight and fast to clone
  • Each instance maintains its own namespace
  • No global state unless explicitly shared

Examples

Quick Start
				
					using uCalcSoftware;

var uc = new uCalc();
// Create a new instance
using (var calc = new uCalc()) {
   
   // Evaluate an expression
   Console.WriteLine(calc.Eval("2 + 3"));
}
				
			
5
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   // Create a new instance
   {
      uCalc calc;
      calc.Owned(); // Causes calc to be released when it goes out of scope

      // Evaluate an expression
      cout << calc.Eval("2 + 3") << endl;
   }
}
				
			
5
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// Create a new instance
      Using calc As New uCalc()
         
         '// Evaluate an expression
         Console.WriteLine(calc.Eval("2 + 3"))
      End Using
   End Sub
End Module
				
			
5
Creating isolated evaluation contexts.
				
					using uCalcSoftware;

var uc = new uCalc();
var main = new uCalc();
main.DefineVariable("rate = 0.05");

var scenarioA = main.Clone();
var scenarioB = main.Clone();

scenarioA.DefineVariable("rate = 0.10");
scenarioB.DefineVariable("rate = 0.20");

Console.WriteLine($"A: {scenarioA.Eval("1000 * rate")}");
Console.WriteLine($"B: {scenarioB.Eval("1000 * rate")}");
Console.WriteLine($"Main: {main.Eval("1000 * rate")}");
main.Release();
scenarioA.Release();
scenarioB.Release();

				
			
A: 100
B: 200
Main: 50
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uCalc main;
   main.DefineVariable("rate = 0.05");

   auto scenarioA = main.Clone();
   auto scenarioB = main.Clone();

   scenarioA.DefineVariable("rate = 0.10");
   scenarioB.DefineVariable("rate = 0.20");

   cout << "A: " << scenarioA.Eval("1000 * rate") << endl;
   cout << "B: " << scenarioB.Eval("1000 * rate") << endl;
   cout << "Main: " << main.Eval("1000 * rate") << endl;
   main.Release();
   scenarioA.Release();
   scenarioB.Release();

}
				
			
A: 100
B: 200
Main: 50
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      Dim main As New uCalc()
      main.DefineVariable("rate = 0.05")
      
      Dim scenarioA = main.Clone()
      Dim scenarioB = main.Clone()
      
      scenarioA.DefineVariable("rate = 0.10")
      scenarioB.DefineVariable("rate = 0.20")
      
      Console.WriteLine($"A: {scenarioA.Eval("1000 * rate")}")
      Console.WriteLine($"B: {scenarioB.Eval("1000 * rate")}")
      Console.WriteLine($"Main: {main.Eval("1000 * rate")}")
      main.Release()
      scenarioA.Release()
      scenarioB.Release()
      
   End Sub
End Module
				
			
A: 100
B: 200
Main: 50
Creating uCalc instances
				
					using uCalcSoftware;

var uc = new uCalc();
uc.DefineVariable("x = 123");

var uc1 = new uCalc(); // Creates a new instance
Console.WriteLine(uc1.EvalStr("x")); // uc1 does not have a variable named x
uc1.Release(); // Releases uc1 if it is no longer needed

var uc2 = uc.Clone(); // Creates new instance that is a clone of uc
Console.WriteLine(uc2.EvalStr("x")); // starts with the value of x obtained from uc
uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc
Console.WriteLine(uc2.EvalStr("x"));
Console.WriteLine(uc.EvalStr("x")); // The original x in uc remains unchanged
uc2.Release();

// Language specific - auto-releasing uCalc object

{ // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
   var uCalc1 = new uCalc();
   var uCalc2 = uc.Clone();
   // Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
}

{ // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
   using var uCalc1 = new uCalc();
   using var uCalc2 = uc.Clone();

   // No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
}

				
			
Undefined identifier
123
456
123
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   uc.DefineVariable("x = 123");

   uCalc uc1; // Creates a new instance
   cout << uc1.EvalStr("x") << endl; // uc1 does not have a variable named x
   uc1.Release(); // Releases uc1 if it is no longer needed

   auto uc2 = uc.Clone(); // Creates new instance that is a clone of uc
   cout << uc2.EvalStr("x") << endl; // starts with the value of x obtained from uc
   uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc
   cout << uc2.EvalStr("x") << endl;
   cout << uc.EvalStr("x") << endl; // The original x in uc remains unchanged
   uc2.Release();

   // Language specific - auto-releasing uCalc object

   { // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
      auto uCalc1 = new uCalc();
      auto uCalc2 = uc.Clone();
      // Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
   }

   { // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
      
      uCalc uCalc1;
      uCalc uCalc2(uc.Clone());
      // No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
   }

}
				
			
Undefined identifier
123
456
123
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      uc.DefineVariable("x = 123")
      
      Dim uc1 As New uCalc() '// Creates a new instance
      Console.WriteLine(uc1.EvalStr("x")) '// uc1 does not have a variable named x
      uc1.Release() '// Releases uc1 if it is no longer needed
      
      Dim uc2 = uc.Clone() '// Creates new instance that is a clone of uc
      Console.WriteLine(uc2.EvalStr("x")) '// starts with the value of x obtained from uc
      uc2.Eval("x = 456") '// Changes the value of x in uc1 but not uc
      Console.WriteLine(uc2.EvalStr("x"))
      Console.WriteLine(uc.EvalStr("x")) '// The original x in uc remains unchanged
      uc2.Release()
      
      '// Language specific - auto-releasing uCalc object
      #If False
         { '// Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
         Dim uCalc1 = new uCalc()
         Dim uCalc2 = uc.Clone()
         '// Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
         }
         
         { '// The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
         
         
         '// No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
         }
         #End If
      End Sub
   End Module
				
			
Undefined identifier
123
456
123
Evaluating expressions
				
					using uCalcSoftware;

var uc = new uCalc();
// See EvalStr for more examples.

Console.WriteLine(uc.Eval("1+1"));
Console.WriteLine(uc.Eval("5*(3+9)^2"));
Console.WriteLine(uc.Eval("Length('This is a test')"));
				
			
2
720
14
				
					#include <iostream>
#include "uCalc.h"

using namespace std;
using namespace uCalcSoftware;

int main() {
   uCalc uc;
   // See EvalStr for more examples.

   cout << uc.Eval("1+1") << endl;
   cout << uc.Eval("5*(3+9)^2") << endl;
   cout << uc.Eval("Length('This is a test')") << endl;
}
				
			
2
720
14
				
					Imports System
Imports uCalcSoftware
Public Module Program
   Public Sub Main()
      Dim uc As New uCalc()
      '// See EvalStr for more examples.
      
      Console.WriteLine(uc.Eval("1+1"))
      Console.WriteLine(uc.Eval("5*(3+9)^2"))
      Console.WriteLine(uc.Eval("Length('This is a test')"))
   End Sub
End Module
				
			
2
720
14