#include <CORBA.h>
#include <string.h>
#include <iostream.h>
#include <mico/impl.h>
#include <mico/util.h>
#include "types.h"

/*
 * general rule for what is passed to StaticAny constructor,
 * StaticTypeInfo::marshal, StaticTypeInfo::demarshal as the
 * second argument:
 *
 * - base types: pointer to the base type;
 *   e.g. CORBA::Long *
 * - string, wstring: pointer to pointer to first char;
 *   e.g. char **
 * - interfaces (including Object, Context, Principal, TypeCode):
 *   pointer to *_ptr;
 *   e.g. Object_ptr *
 * - any: pointer to any; i.e. CORBA::Any *
 * - enum: pointer to enum;
 *   e.g. for enum foo { ... }: foo *
 * - struct: pointer to struct;
 *   e.g. for struct foo { ... }: foo *
 * - exception: pointer to exception;
 *   e.g. for exception foo { ... }: foo *
 * - union: pointer to union;
 *   e.g. for union foo switch (...) { ... }: foo *
 * - fixed: pointer to fixed;
 *   e.g. for typedef fixed<4,2> foo: foo *
 * - array: pointer to first array element;
 *   e.g. for typedef long foo[5]: long *
 * - sequence: pointer to sequence;
 *   e.g. for typedef sequence<long> foo: foo *
 *
 * take care when elements of constructed types are _var types. since
 * the second arg of StaticAny is of type void * the compiler
 * will *not* convert the _var to the containing type. instead you
 * have to explicitely convert the _var type to its containig type.
 * E.g., the IDL struct
 *   struct Foo {
 *       string s;
 *   };
 * will result in the C++ struct
 *   struct Foo {
 *       CORBA::String_var s;
 *   };
 * when passing Foo::s to one of the above mentioned methods, you have to
 * explicitely convert the String_var into a char* and take the address of
 * it to get the required char **:
 *   Foo f;
 *   StaticAny (_stc_Foo, &(char *&)f.s);
 * An better way would be to use the inout() method, because this works
 * for all kinds of _var types, whereas in the above example the cast
 * depends on the exact type of the _var:
 *   Foo f;
 *   StaticAny (_stc_Foo, &f.s.inout());
 */

class TCEnum : public CORBA::StaticTypeInfo {
    typedef Enum T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T; }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (*(T *)v); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = *(T *)s; }
    void free (StaticValueType v) const
    { delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	CORBA::ULong ul;
	if (!dc.enumeration (ul))
	    return FALSE;
	*(T *)v = (T)ul;
	return TRUE;
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	ec.enumeration ((CORBA::ULong)*(T *)v);
    }
};

CORBA::StaticTypeInfo *_stc_Enum = new TCEnum;


//--------------------


class TCStruct : public CORBA::StaticTypeInfo {
    typedef Struct T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T; }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (*(T *)v); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = *(T *)s; }
    void free (StaticValueType v) const
    { delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	return
	    dc.struct_begin() &&
	    CORBA::_stc_long->demarshal (dc, &((T *)v)->l) &&
	    CORBA::_stc_string->demarshal (dc, &((T *)v)->s.inout()) &&
	    dc.struct_end();
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	ec.struct_begin();
	CORBA::_stc_long->marshal (ec, &((T *)v)->l);
	CORBA::_stc_string->marshal (ec, &((T *)v)->s.inout());
	ec.struct_end();
    }
};

CORBA::StaticTypeInfo *_stc_Struct = new TCStruct;


//--------------------


/*
 * the _encode() method of the generated exception should look like this:
 *
 * void Except::_encode (CORBA::DataEncoder &ec)
 * {
 *     _stc_Except->marshal (ec, this);
 * }
 */
class TCExcept : public CORBA::StaticTypeInfo {
    typedef Except T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T; }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (*(T *)v); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = *(T *)s; }
    void free (StaticValueType v) const
    { delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	string repoid;
	return
	    dc.except_begin (repoid) &&
	    CORBA::_stc_long->demarshal (dc, &((T *)v)->l) &&
	    CORBA::_stc_string->demarshal (dc, &((T *)v)->s.inout()) &&
	    dc.except_end();
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	ec.except_begin ("IDL:Except:1.0");
	CORBA::_stc_long->marshal (ec, &((T *)v)->l);
	CORBA::_stc_string->marshal (ec, &((T *)v)->s.inout());
	ec.except_end();
    }
};

CORBA::StaticTypeInfo *_stc_Except = new TCExcept;


//--------------------


class TCImplicitUnion : public CORBA::StaticTypeInfo {
    typedef ImplicitUnion T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T; }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (*(T *)v); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = *(T *)s; }
    void free (StaticValueType v) const
    { delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	if (!dc.union_begin())
	    return FALSE;
	if (!CORBA::_stc_long->demarshal (dc, &((T *)v)->_discriminator))
	    return FALSE;
	switch (((T *)v)->_discriminator) {
	case 1:
	    if (!CORBA::_stc_long->demarshal (dc, &((T *)v)->_m.l))
		return FALSE;
	    break;
	case 2:
	    if (!CORBA::_stc_string->demarshal (dc, &((T *)v)->_m.s.inout()))
		return FALSE;
	    break;
	}
	return dc.union_end();
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	ec.union_begin();
	CORBA::_stc_long->marshal (ec, &((T *)v)->_discriminator);
	switch (((T *)v)->_discriminator) {
	case 1:
	    CORBA::_stc_long->marshal (ec, &((T *)v)->_m.l);
	    break;
	case 2:
	    CORBA::_stc_string->marshal (ec, &((T *)v)->_m.s.inout());
	    break;
	}
	ec.union_end();
    }
};

CORBA::StaticTypeInfo *_stc_ImplicitUnion = new TCImplicitUnion;


//--------------------


class TCExplicitUnion : public CORBA::StaticTypeInfo {
    typedef ExplicitUnion T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T; }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (*(T *)v); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = *(T *)s; }
    void free (StaticValueType v) const
    { delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	if (!dc.union_begin())
	    return FALSE;
	if (!CORBA::_stc_long->demarshal (dc, &((T *)v)->_discriminator))
	    return FALSE;
	switch (((T *)v)->_discriminator) {
	case 1:
	    if (!CORBA::_stc_long->demarshal (dc, &((T *)v)->_m.l))
		return FALSE;
	    break;
	case 2:
	    if (!CORBA::_stc_string->demarshal (dc, &((T *)v)->_m.s.inout()))
		return FALSE;
	    break;
	default:
	    CORBA::Boolean b;
	    if (!CORBA::_stc_boolean->demarshal (dc, &((T *)v)->_m.b))
		return FALSE;
	    break;
	}
	return dc.union_end();
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	ec.union_begin();
	CORBA::_stc_long->marshal (ec, &((T *)v)->_discriminator);
	switch (((T *)v)->_discriminator) {
	case 1:
	    CORBA::_stc_long->marshal (ec, &((T *)v)->_m.l);
	    break;
	case 2:
	    CORBA::_stc_string->marshal (ec, &((T *)v)->_m.s.inout());
	    break;
	default:
	    CORBA::_stc_boolean->marshal (ec, &((T *)v)->_m.b);
	    break;
	}
	ec.union_end();
    }
};

CORBA::StaticTypeInfo *_stc_ExplicitUnion = new TCExplicitUnion;


//--------------------


class TCInterface : public CORBA::StaticTypeInfo {
    typedef Interface *T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T (0); }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (Interface::_duplicate (*(T *)v)); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = Interface::_duplicate (*(T *)s); }
    void free (StaticValueType v) const
    { CORBA::release (*(T *)v); delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	CORBA::Object_ptr obj;
	if (!CORBA::_stc_Object->demarshal (dc, &obj))
	    return FALSE;
	*(T *)v = Interface::_narrow (obj);
	CORBA::release (obj);
	return TRUE;
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	CORBA::Object_ptr obj = *(T *)v;
	CORBA::_stc_Object->marshal (ec, &obj); 
    }
};

CORBA::StaticTypeInfo *_stc_Interface = new TCInterface;


//--------------------


class TCFixedExample : public CORBA::StaticTypeInfo {
    typedef FixedExample T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T; }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (*(T *)v); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = *(T *)s; }
    void free (StaticValueType v) const
    { delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	FixedBase::FixedValue val;
	if (!dc.get_fixed (val, 4, 2))
	    return FALSE;
	((T *)v)->from_digits (val);
	return TRUE;
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	FixedBase::FixedValue_var val = ((T *)v)->to_digits();
	ec.put_fixed (val, 4, 2);
    }
};

CORBA::StaticTypeInfo *_stc_FixedExample = new TCFixedExample;


//--------------------


class TCBaseArray : public CORBA::StaticTypeInfo {
    typedef BaseArray_slice T;
public:
    StaticValueType create () const
    { return (StaticValueType)BaseArray_alloc(); }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)BaseArray_dup ((T *)v); }
    // need BaseArray_copy() ...
    void assign (StaticValueType d, const StaticValueType s) const
    {
	for (int i = 0; i < 5; ++i)
	    ((T *)d)[i] = ((T *)s)[i];
    }
    void free (StaticValueType v) const
    { BaseArray_free ((T *)v); }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	// this is much faster than iterating over the elements, but
	// is only supported for basic types
	return dc.get_longs ((T *)v, 5);
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	// this is much faster than iterating over the elements, but
	// is only supported for basic types
	ec.put_longs ((T *)v, 5);
    }
};

CORBA::StaticTypeInfo *_stc_BaseArray = new TCBaseArray;


//--------------------


class TCConstrArray : public CORBA::StaticTypeInfo {
    typedef ConstrArray_slice T;
public:
    StaticValueType create () const
    { return (StaticValueType)ConstrArray_alloc(); }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)ConstrArray_dup ((T *)v); }
    // need ConstrArray_copy() ...
    void assign (StaticValueType d, const StaticValueType s) const
    {
	for (int i = 0; i < 5; ++i)
	    ((T *)d)[i] = ((T *)s)[i];
    }
    void free (StaticValueType v) const
    { ConstrArray_free ((T *)v); }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	if (!dc.arr_begin())
	    return FALSE;
	for (CORBA::ULong i = 0; i < 5; ++i) {
	    if (!_stc_Struct->demarshal (dc, &((T *)v)[i]))
		return FALSE;
	}
	return dc.arr_end();
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	ec.arr_begin();
	for (CORBA::ULong i = 0; i < 5; ++i) {
	    _stc_Struct->marshal (ec, &((T *)v)[i]);
	}
	ec.arr_end();
    }
};

CORBA::StaticTypeInfo *_stc_ConstrArray = new TCConstrArray;


//--------------------


class TCConstrSeq : public CORBA::StaticTypeInfo {
    typedef ConstrSeq T;
public:
    StaticValueType create () const
    { return (StaticValueType)new T; }
    StaticValueType copy (const StaticValueType v) const
    { return (StaticValueType)new T (*(T *)v); }
    void assign (StaticValueType d, const StaticValueType s) const
    { *(T *)d = *(T *)s; }
    void free (StaticValueType v) const
    { delete (T *)v; }
    CORBA::Boolean demarshal (CORBA::DataDecoder &dc, StaticValueType v) const
    {
	CORBA::ULong len;
	if (!dc.seq_begin (len))
	    return FALSE;
	((T *)v)->length (len);
	for (CORBA::ULong i = 0; i < len; ++i) {
	    if (!_stc_Struct->demarshal (dc, &(*(T *)v)[i]))
		return FALSE;
	}
	return dc.seq_end();
    }
    void marshal (CORBA::DataEncoder &ec, StaticValueType v) const
    {
	CORBA::ULong len = ((T *)v)->length();
	ec.seq_begin (len);
	for (CORBA::ULong i = 0; i < len; ++i) {
	    _stc_Struct->marshal (ec, &(*(T *)v)[i]);
	}
	ec.seq_end();
    }
};

CORBA::StaticTypeInfo *_stc_ConstrSeq = new TCConstrSeq;


//--------------------


class Interface_impl : virtual public Interface_skel {
};


inline int
operator== (const Struct &s1, const Struct &s2)
{
    if (s1.l != s2.l)
	return 0;
    if (!!s1.s.in() ^ !!s2.s.in())
	return 0;
    return !s1.s.in() || !strcmp (s1.s, s2.s);
}

inline int
operator== (const Except &s1, const Except &s2)
{
    if (s1.l != s2.l)
	return 0;
    if (!!s1.s.in() ^ !!s2.s.in())
	return 0;
    return !s1.s.in() || !strcmp (s1.s, s2.s);
}

inline int
operator== (const ExplicitUnion &s1, const ExplicitUnion &s2)
{
    return s1._d() == s2._d();
}

inline int
operator== (const ImplicitUnion &s1, const ImplicitUnion &s2)
{
    return s1._d() == s2._d();
}

template<class T>
struct StdCmp {
    int compare (const T &t1, const T &t2)
    {
	return t1 == t2;
    }
};

template<class T, int N>
struct ArrCmp {
    int compare (const T &a1, const T &a2)
    {
	for (int i = 0; i < N; ++i)
	    if (!(a1[i] == a2[i]))
		return 0;
	return 1;
    }
};

struct StrCmp {
    int compare (const char *t1, const char *t2)
    {
	return !strcmp (t1, t2);
    }
};

struct WStrCmp {
    int compare (const wchar_t *t1, const wchar_t *t2)
    {
	return !xwcscmp (t1, t2);
    }
};

struct ObjCmp {
    int compare (CORBA::Object_ptr obj1, CORBA::Object_ptr obj2)
    {
	return obj1->_is_equivalent (obj2);
    }
};

struct TCCmp {
    int compare (CORBA::TypeCode_ptr tc1, CORBA::TypeCode_ptr tc2)
    {
	return tc1->equal (tc2);
    }
};

template<class C, class T>
struct Checker {
    Checker (CORBA::StaticTypeInfo *ti, const T &val1)
    {
	MICO::CDREncoder ec;
	MICO::CDRDecoder dc (ec.buffer(), FALSE);

	CORBA::Boolean ret;

	T val2;

	CORBA::StaticAny any1 (ti, (void *)&val1);
	CORBA::StaticAny any2 (ti, (void *)&val2);

	any1.marshal (ec);
	ret = any2.demarshal (dc);
	assert (ret);

	C cmp;
	assert (cmp.compare (val1, val2));
    }
};

void
do_tests ()
{
    // basic types
    Checker<StdCmp<CORBA::Short>, CORBA::Short>
	short_c (CORBA::_stc_short, 42);

    Checker<StdCmp<CORBA::UShort>, CORBA::UShort>
	ushort_c (CORBA::_stc_ushort, 42);

    Checker<StdCmp<CORBA::Long>, CORBA::Long>
	long_c (CORBA::_stc_long, 42);

    Checker<StdCmp<CORBA::ULong>, CORBA::ULong>
	ulong_c (CORBA::_stc_ulong, 42);

    Checker<StdCmp<CORBA::LongLong>, CORBA::LongLong>
	longlong_c (CORBA::_stc_longlong, 42);

    Checker<StdCmp<CORBA::ULongLong>, CORBA::ULongLong>
	ulonglong_c (CORBA::_stc_ulonglong, 42);

    Checker<StdCmp<CORBA::Float>, CORBA::Float>
	float_c (CORBA::_stc_float, 42);

    Checker<StdCmp<CORBA::Double>, CORBA::Double>
	double_c (CORBA::_stc_double, 42);

    Checker<StdCmp<CORBA::LongDouble>, CORBA::LongDouble>
	ldouble_c (CORBA::_stc_longdouble, 42);

    Checker<StdCmp<CORBA::Octet>, CORBA::Octet>
	octet_c (CORBA::_stc_octet, 42);

    Checker<StdCmp<CORBA::Boolean>, CORBA::Boolean>
	bool_c (CORBA::_stc_boolean, TRUE);

    Checker<StdCmp<CORBA::Char>, CORBA::Char>
	char_c (CORBA::_stc_char, 42);

    Checker<StdCmp<CORBA::WChar>, CORBA::WChar>
	wchar_c (CORBA::_stc_wchar, 42);

    // string, wstring
    char *string_i = "foo";
    Checker<StrCmp, char *> string_c (CORBA::_stc_string, string_i);

    wchar_t *wstring_i = L"foo";
    Checker<WStrCmp, wchar_t *> wstring_c (CORBA::_stc_wstring, wstring_i);

    // any
    CORBA::Any any_i;
    any_i <<= (CORBA::Long)42;
    Checker<StdCmp<CORBA::Any>, CORBA::Any> any_c (CORBA::_stc_any, any_i);

    // typecode
    Checker<TCCmp, CORBA::TypeCode_ptr> tc_c
	(CORBA::_stc_TypeCode, _tc_Struct);

    // context, princiapl

    // interface
    Interface_ptr iface_i = new Interface_impl;
    Checker<ObjCmp, Interface_ptr> iface_s (_stc_Interface, iface_i);

    // sequences of basic types
    SequenceTmpl<CORBA::Short> short_i;
    short_i.length (2);
    short_i[0] = 1;
    short_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::Short> >, SequenceTmpl<CORBA::Short> >
	short_s (CORBA::_stcseq_short, short_i);

    SequenceTmpl<CORBA::UShort> ushort_i;
    ushort_i.length (2);
    ushort_i[0] = 1;
    ushort_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::UShort> >, SequenceTmpl<CORBA::UShort> >
	ushort_s (CORBA::_stcseq_ushort, ushort_i);

    SequenceTmpl<CORBA::Long> long_i;
    long_i.length (2);
    long_i[0] = 1;
    long_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::Long> >, SequenceTmpl<CORBA::Long> >
	long_s (CORBA::_stcseq_long, long_i);

    SequenceTmpl<CORBA::ULong> ulong_i;
    ulong_i.length (2);
    ulong_i[0] = 1;
    ulong_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::ULong> >, SequenceTmpl<CORBA::ULong> >
	ulong_s (CORBA::_stcseq_ulong, ulong_i);

    SequenceTmpl<CORBA::LongLong> longlong_i;
    longlong_i.length (2);
    longlong_i[0] = 1;
    longlong_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::LongLong> >, SequenceTmpl<CORBA::LongLong> >
	longlong_s (CORBA::_stcseq_longlong, longlong_i);

    SequenceTmpl<CORBA::ULongLong> ulonglong_i;
    ulonglong_i.length (2);
    ulonglong_i[0] = 1;
    ulonglong_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::ULongLong> >, SequenceTmpl<CORBA::ULongLong> >
	ulonglong_s (CORBA::_stcseq_ulonglong, ulonglong_i);

    SequenceTmpl<CORBA::Float> float_i;
    float_i.length (2);
    float_i[0] = 1;
    float_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::Float> >, SequenceTmpl<CORBA::Float> >
	float_s (CORBA::_stcseq_float, float_i);

    SequenceTmpl<CORBA::Double> double_i;
    double_i.length (2);
    double_i[0] = 1;
    double_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::Double> >, SequenceTmpl<CORBA::Double> >
	double_s (CORBA::_stcseq_double, double_i);

    SequenceTmpl<CORBA::LongDouble> longdouble_i;
    longdouble_i.length (2);
    longdouble_i[0] = 1;
    longdouble_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::LongDouble> >, SequenceTmpl<CORBA::LongDouble> >
	ldouble_s (CORBA::_stcseq_longdouble, longdouble_i);

    SequenceTmpl<CORBA::OctetWrapper> octet_i;
    octet_i.length (2);
    octet_i[0] = 1;
    octet_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::OctetWrapper> >, SequenceTmpl<CORBA::OctetWrapper> >
	octet_s (CORBA::_stcseq_octet, octet_i);

    SequenceTmpl<CORBA::BooleanWrapper> bool_i;
    bool_i.length (2);
    bool_i[0] = TRUE;
    bool_i[1] = FALSE;
    Checker<StdCmp<SequenceTmpl<CORBA::BooleanWrapper> >, SequenceTmpl<CORBA::BooleanWrapper> >
	bool_s (CORBA::_stcseq_boolean, bool_i);

    SequenceTmpl<CORBA::CharWrapper> char_i;
    char_i.length (2);
    char_i[0] = 1;
    char_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::CharWrapper> >, SequenceTmpl<CORBA::CharWrapper> >
	char_s (CORBA::_stcseq_char, char_i);

    SequenceTmpl<CORBA::WChar> wchar_i;
    wchar_i.length (2);
    wchar_i[0] = 1;
    wchar_i[1] = 2;
    Checker<StdCmp<SequenceTmpl<CORBA::WChar> >, SequenceTmpl<CORBA::WChar> >
	wchar_s (CORBA::_stcseq_wchar, wchar_i);

    // enum
    Checker<StdCmp<Enum>, Enum> Enum_c (_stc_Enum, enum2);

    // struct
    Struct Struct_i;
    Struct_i.l = 42;
    Struct_i.s = (const char *)"foo";
    Checker<StdCmp<Struct>, Struct> Struct_c (_stc_Struct, Struct_i);

    // exception
    Except Except_i;
    Except_i.l = 42;
    Except_i.s = (const char *)"foo";
    Checker<StdCmp<Except>, Except> Except_c (_stc_Except, Except_i);

    // union with explicit default case
    ExplicitUnion ExUn_i;
    ExUn_i.b (TRUE);
    Checker<StdCmp<ExplicitUnion>, ExplicitUnion>
	ExUn_c (_stc_ExplicitUnion, ExUn_i);

    // union with implicit default case
    ImplicitUnion ImUn_i;
    ImUn_i.l (42);
    Checker<StdCmp<ImplicitUnion>, ImplicitUnion>
	ImUn_c (_stc_ImplicitUnion, ImUn_i);

    // fixed
    FixedExample Fixed_i ((CORBA::LongDouble)42.34);
    Checker<StdCmp<FixedExample>, FixedExample>
	Fixed_c (_stc_FixedExample, Fixed_i);

    // sequence of constructed type
    ConstrSeq CoSeq_i;
    CoSeq_i.length (5);
    CoSeq_i[0].l = 1;
    CoSeq_i[1].l = 2;
    CoSeq_i[2].l = 3;
    CoSeq_i[3].l = 4;
    CoSeq_i[4].l = 5;
    CoSeq_i[0].s = (const char *)"1";
    CoSeq_i[1].s = (const char *)"2";
    CoSeq_i[2].s = (const char *)"3";
    CoSeq_i[3].s = (const char *)"4";
    CoSeq_i[4].s = (const char *)"5";
    Checker<StdCmp<ConstrSeq>, ConstrSeq> CoSeq_c (_stc_ConstrSeq, CoSeq_i);

    // array of base type
    BaseArray BaseArr_i = { 1, 2, 3, 4, 5 };
    Checker<ArrCmp<BaseArray,5>, BaseArray>
	BaseArr_c (_stc_BaseArray, BaseArr_i);

    // array of constructed type
    ConstrArray CoArr_i;
    CoArr_i[0].l = 1;
    CoArr_i[1].l = 2;
    CoArr_i[2].l = 3;
    CoArr_i[3].l = 4;
    CoArr_i[4].l = 5;
    CoArr_i[0].s = (const char *)"1";
    CoArr_i[1].s = (const char *)"2";
    CoArr_i[2].s = (const char *)"3";
    CoArr_i[3].s = (const char *)"4";
    CoArr_i[4].s = (const char *)"5";
    Checker<ArrCmp<ConstrArray,5>, ConstrArray>
	CoArr_c (_stc_ConstrArray, CoArr_i);
}

int
main (int argc, char *argv)
{
    do_tests();
    return 0;
}
