There are 5 class types:
The Xc++ language allows for reflecting classes and structs using $class and $struct.
For example
$struct+ X
{
$int32 x;
};
The public modifier (+
) means that X
is public - so it is:
ReflectedClass
instance is registered in the
ReflectedClass registry)
X
is defined in a Windows dynamic link library then the symbols are exported
to allow for using X
from other libraries and executables)
The public modifier (+
) cannot be used on a generic type such as a $mixin
, or else Xcpp gives the error
'+' modifier not permitted on $mixin
The public modifier (+
) also cannot be used on nested classes or structs.
Here's a more complicated example:
$class+ C <<dc>> isa ceda::IObject :
Base1, public Base2, private Base3
model SomeModel
mixin [Mixin1 Mixin2] Base4, protected Base5 : [1,2,3,foo(x)]
{
};
dc
is a directive which determines whether a default constructor is defined.
A class or struct can declare it implements an interface using isa
. For example:
$class X isa IObject
{
};
A class can reference a base model by name.
In the following example class X
references its base model M
by name:
$model M {};
$class X : model M {};
Note that M
must be a pure model
(a class with an embedded model is not sufficient to be referenced in this manner).
A class can define any number of anonymous models in its mixin chain. For example:
$class X : mixin
[
model
{
int32 x;
float64 y;
}
]
This model is called an anonymous model mixin.
Models can be free standing
$model Point
{
int32 x;
int32 y;
};
They can be inherited in a $class
$class X :
model
{
int32 x;
}
{
};
They can be embedded directly
$class X
{
model
{
int32 x;
}
};
$class X {};
$class X { $model{} };
$model M {};
$class X : mixin[M1 M2] {};
$mixin X {};
$mixin X<typename T> {};
$mixin X { $model{} };
$class X : model {} {};
$class X : model M {};
$mixin X : model {} {};
$mixin X<typename T,int N> : model {} {};
$mixin X : model M {};
$class X : mixin [M] {};
$mixin [model{}] {};
$mixin X : mixin [M] {};
$class X : mixin [model{}] {};
$class X isa ceda::IObject {};
$class X isa ceda::IPersistable {};
$class X : model{} mixin [model{}] {};
$class X : model{} mixin [model{}model{}] {};
$class X isa ceda::IObject : model{} mixin [model{}model{}] {};
example | |
---|---|
pure model | $model M {}; |
base model | $class X : model {} {}; |
referenced base model | $class X : model M {}; |
nested model | $class X { $model{} }; |
embedded mixin model | $class X : mixin [model{}] {}; |
referenced mixin model | $class X : mixin [M] {}; |
Xcpp imposes the use of platform independent types in certain cases. If a class is reflected then its members must have platform independent types. We call this a strict class.
A pure model is quite restricted:
struct
not a class
isa
cannot be specified to indicate that it implements an interface. It cannot even implement IObject
$dep
, $indep
member variables or $cache
functions$evict
cannot be used inside a pure modelFor each field in a model a half open interval [r1,r2) of integer release numbers represents the set of release numbers for which the field exists in the schema.
We use r2 = -1 to indicate that the field hasn't been dropped in the latest release.
If there is no $schema {...} section then for each model field we have r1 = 0 and r2 = -1. This represents "added but not dropped".
During the parsing of the $schema {...} section we assume the following
After parsing the $schema section, it should never be the case that r1 = -1. However it possible for r2 to be -1 to indicate that the field hasn't been dropped in the latest release.