<md>

# Miscellaneous Features

## Opaque Classes

When implementing the interaction between your Jancy script and the host C/C++ application you will often need to hide the details of C++ implementation of classes exported to the Jancy namespace. Jancy simplifies the job by providing <i>opaque classes</i>. 

<div class='new_frame snippet'>
<code name="jancy">
opaque class Serial
{
	uint_t autoget property m_baudRate;
	SerialFlowControl autoget property m_flowControl;
	uint_t autoget property m_dataBits; // typically 5..8
	SerialStopBits autoget property m_stopBits;
	SerialParity autoget property m_parity;

	// ...

	Serial* operator new ();
}

</code>
</div>
<br>

The corresponding C++ implementation class would look somewhat like this:

<div class='new_frame snippet'>
<code name="jancy">

class Serial: public jnc::IfaceHdr
{
public:
	JNC_BEGIN_CLASS ("io.Serial", ApiSlot_Serial)
		JNC_AUTOGET_PROPERTY ("m_baudRate",    &Serial::setBaudRate)
		JNC_AUTOGET_PROPERTY ("m_flowControl", &Serial::setFlowControl)
		JNC_AUTOGET_PROPERTY ("m_dataBits",    &Serial::setDataBits)
		JNC_AUTOGET_PROPERTY ("m_stopBits",    &Serial::setStopBits)
		JNC_AUTOGET_PROPERTY ("m_parity",      &Serial::setParity)

		// ...

		JNC_OPERATOR_NEW (&Serial::operatorNew)
	JNC_API_END_CLASS ()

	uint_t m_baudRate;
	axl::io::SerialFlowControl m_flowControl;
	uint_t m_dataBits;
	axl::io::SerialStopBits m_stopBits;
	axl::io::SerialParity m_parity;

	// ...

protected:
	// hidden implementation

	axl::io::Serial m_serial;
	mt::Lock m_ioLock;
	uint_t m_ioFlags;
	IoThread m_ioThread;

};

</code>
</div>
<br>

Opaque classes can be neither derived from nor allocated statically, on stack, or as a class field member. This is because the Jancy compiler has no information about their full layout -- they are <i>opaque</i> after all.

Opaque classes can only be allocated on the heap and only if their declaration includes 'operator new'. The developer can choose which opaque classes should be creatable and which ones should be exposed as non-creatable host interfaces.

## Expression Aliases

Jancy provides convenient syntax for creating expression aliases. These behave much like macros of C/C++ except they belong to the namespace they were declared at, plus they must reference the complete expression. 

Besides the obvious use as a safe alternative to macros, aliases are irreplaceable when you need to share an on-change event between multiple properties.

<div class='new_frame snippet'>
<code name="jancy">
opaque class ComboBox
{
	// ...

	property m_currentIndex
	{	
		size_t autoget m_value;
		set (size_t value);
		alias bindable event m_onPropChanged () = m_onChanged;
	}

	property m_currentText
	{		
		char const* get ();
		alias bindable event m_onPropChanged () = m_onChanged;
	}

	property m_currentData
	{		
		object* get ();
		alias bindable event m_onPropChanged () = m_onChanged;
	}

	event m_onChanged ();

	// ...
}

</code>
</div>

## Scopes in Switch

Jancy encloses all the case blocks in switch statements into implicitly created scopes. This means you are free to create and use local variables in switch statements:

<div class='new_frame snippet'>
<code name="jancy">

foo (int x)
{
	switch (x)
	{
	case 0:
		int i = 10;
		break;

	case 1:
		int i = 20; // no problem: we are in different scope
	
	case 2:
		int i = 30; // no problem even when we fall-through from previous case label
		break;

	default:
		int i = 40; // still ok. you've got the idea
	}
}

</code>
</div>

## Once

Jancy provides an elegant syntax for lazy initialization. 
Prefix the necessary piece of code with 'once' and the compiler will generate a thread-safe wrapper. The latter will ensure that this code executes once per each program run.

<div class='new_frame snippet'>
<code name="jancy">

foo ()
{
	once initialize ();

	// ...
}

</code>
</div>
<br>

If your lazy initialization requires more than a single statement, enclose the entire block of your initialization code in a compound statement:

<div class='new_frame snippet'>
<code name="jancy">

foo ()
{
	once 
	{
		initializeTables ();
		initializeMaps ();
		initializeIo ();

		// ...
	}

	// ...
}

</code>
</div>
<br>

Jancy also provides a way to run the lazy initialization once per thread.
Use 'thread once' to achieve this:

<div class='new_frame snippet'>
<code name="jancy">

foo ()
{
	thread once initializeThread (); 

	// ...
}

</code>
</div>

## Module Constructors/Destructors

Jancy provides module constructors/destructors as a convenient way to write 
initialization/cleanup code for compilation units:

<div class='new_frame snippet'>
<code name="jancy">


class C1
{
	construct ()
	{
		printf ("C1.construct ()\n");
	}

	destruct ()
	{
		printf ("C1.destruct ()\n");
	}
}

C1 g_c; // global static variable with constructor & destructor

int g_x = foo (); // global static variable with initializer

int foo ()
{
	printf ("foo ()\n");
	return 100;
}

// module constructor will be called after all global static variables have been initialized

construct ()
{
	printf ("module.construct ()\n");
}

// module destructor will be called before global static variables have been destructed

destruct ()
{
	printf ("module.destruct ()\n");
}

</code>
</div>

## Extension Namespaces

Jancy offers a way to extend the functionality of existing classes with extension namespaces. An extension namespace declares additional methods which have access to all the members of the class that they extend. There are certain limitations imposed on the extension methods. These ensure that if your code runs without extension namespaces, then it runs exactly the same with the introduction of any extension namespace(s):

<div class='new_frame snippet'>
<code name="jancy">
class C1
{
	protected int m_x;

	construct (int x)
	{
		printf ("C1.construct (%d)\n", x);
		m_x = x;
	}

	foo ()
	{
		printf ("C1.foo () { m_x = %d }\n", m_x);
	}
}

extension ExtC1: C1
{
	bar ()
	{
		// extension method has access to protected data
		printf ("C1 (extend).bar () { m_x = %d }\n", m_x); 
	}

	static baz ()
	{
		printf ("C1 (extend).baz ()\n");
	}

	// construct (double x);    // <-- error: constructors cannot be part of extension namespace
	// int operator += (int x); // <-- error: operator methods cannot be part of extension namespace
	// virtual baz ();          // <-- error: virtual methods cannot be part of extension namespace
}

// entry point

int main ()
{
	C1 c construct (100);
	c.foo ();
	
	
	
	c.bar ();  // bar () is extension method

	C1.baz (); // baz () is static extension method

	return 0;
}

</code>
</div>

## Curly Initializers

Jancy supports a convenient method of assigning aggregate values with curly initializers:

Classic C-style curly-intializers:

<div class='new_frame snippet'>
<code name="jancy">

int a [] = { 1, 2, 3 };	 

</code>
</div>
<br>

It's OK to skip elements leaving them zero-initialized:

<div class='new_frame snippet'>
<code name="jancy">

int b [10] = { ,, 3, 4,,, 7 }; 

</code>
</div>
<br>

You can use both index- and name-based addressing:

<div class='new_frame snippet'>
<code name="jancy">

struct Point
{
	int m_x;
	int m_y;
	int m_z;
}
	
Point point = { 10, m_z = 30 };  

</code>
</div>
<br>

You can also use curly-initializers in assignment operator after declaration:

<div class='new_frame snippet'>
<code name="jancy">
	
point = { , 200, 300 }; 

</code>
</div>
<br>

...or in a new operator:

<div class='new_frame snippet'>
<code name="jancy">
	
Point* point2 = new Point { m_y = 2000, m_z = 3000 }; 

</code>
</div>

---
Proceed to Jancy [compiler overview](/jancy/compiler_architecture.html)
</md>
