Variant.cpp
// Variant.cpp
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2011
@import "Store.h"
@import "Ceda/cxObject/PrintReflectedVariable.h"
#include "Ceda/cxUtils/ScopeWriter.h"
#include "Ceda/cxUtils/Environ.h"
namespace VariantEx
{
///////////////////////////////////////////////////////////////////////////////////////////////////
// Example with a variant containing a pref.
$variant+ MyVariant
{
default -1;
ceda::int32;
ceda::pref<ceda::IPersistable>;
};
$struct+ Y <<os>> isa ceda::IPersistable :
model
{
MyVariant V;
MyVariant W;
}
{
Y() {}
Y(MyVariant v, MyVariant w)
{
_model_.V = v;
_model_.W = w;
}
static void Write(ceda::xostream& os, const MyVariant& v)
{
if (v.is<ceda::int32>())
{
os << v.as<ceda::int32>();
}
else
{
ceda::pref<ceda::IPersistable> p = v.as<ceda::pref<ceda::IPersistable> >();
if (p)
{
Y* y = ceda::qccast<Y>(p.Get());
cxAssert(y);
y->Write(os);
}
else
{
os << "null";
}
}
}
void Write(ceda::xostream& os) const
{
os << '(';
Write(os,V);
os << ',';
Write(os,W);
os << ')';
}
};
/*
Generated output:
Variant with pref
{
root = (((10,20),30),-1)
root = (((10,20),30),(1,(2,null)))
}
*/
void VariantWithPref()
{
ceda::TraceGroup g("Variant with pref");
ceda::xstring path = ceda::GetCedaTestPath("VariantWithPref.ced");
{
Store store(path, ceda::OM_CREATE_ALWAYS);
Y* root = store.BootstrapRoot<Y>();
}
{
Store store(path);
Y* root = store.BootstrapRoot<Y>();
{
ceda::CSpaceTxn txn;
Y* child2 = $new Y(10,20);
Y* child = $new Y(MyVariant(child2), 30);
// These objects just created are not reachable from the persistent store yet so they
// don't have an OID yet
cxAssert(!GetOid(child2));
cxAssert(!GetOid(child));
cxAssert(!root->IsDirty());
root->V = MyVariant(child);
// The assignment to V marked root as dirty and allocated oids to the reachable objects.
cxAssert(root->IsDirty());
cxAssert(GetOid(child2));
cxAssert(GetOid(child));
}
}
{
Store store(path);
Y* root = store.BootstrapRoot<Y>();
{
ceda::CSpaceTxn txn;
Tracer() << "root = " << *root << '\n';
}
}
{
Store store(path);
Y* root = store.BootstrapRoot<Y>();
{
ceda::CSpaceTxn txn;
// todo : $new doesn't support nesting at the moment.
//root->W = MyVariant( $new Y(1, MyVariant($new Y(2,3))) );
Y* y = $new Y(2,ceda::pref<ceda::IPersistable>());
root->W = MyVariant( $new Y(1, MyVariant(y)) );
}
}
{
Store store(path);
Y* root = store.BootstrapRoot<Y>();
{
ceda::CSpaceTxn txn;
Tracer() << "root = " << *root << '\n';
}
}
}
void Run()
{
VariantWithPref();
}
};