certi-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[certi-cvs] certi/libHLA CMakeLists.txt HLAtypesIEEE1516.hh...


From: certi-cvs
Subject: [certi-cvs] certi/libHLA CMakeLists.txt HLAtypesIEEE1516.hh...
Date: Sat, 02 Aug 2008 14:03:15 +0000

CVSROOT:        /sources/certi
Module name:    certi
Changes by:     Petr Gotthard <gotthardp>       08/08/02 14:03:15

Modified files:
        libHLA         : CMakeLists.txt HLAtypesIEEE1516.hh 
Added files:
        libHLA         : HLAbasicType.hh HLAbuffer.cc HLAbuffer.hh 
                         HLAenumeratedType.hh HLAfixedArray.hh 
                         HLAfixedRecord.hh HLAvariableArray.hh 
                         HLAvariantRecord.hh 
Removed files:
        libHLA         : HLAtypesIEEE1516.cc 

Log message:
        HLAtypesIEEE1516.hh separated into several files for better 
maintainability and extensibility.
        HLAbuffer.cc renamed due to "implicit include" mechanism of Sun's C++.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/CMakeLists.txt?cvsroot=certi&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAtypesIEEE1516.hh?cvsroot=certi&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAbasicType.hh?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAbuffer.cc?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAbuffer.hh?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAenumeratedType.hh?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAfixedArray.hh?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAfixedRecord.hh?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAvariableArray.hh?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAvariantRecord.hh?cvsroot=certi&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/certi/libHLA/HLAtypesIEEE1516.cc?cvsroot=certi&r1=1.1&r2=0

Patches:
Index: CMakeLists.txt
===================================================================
RCS file: /sources/certi/certi/libHLA/CMakeLists.txt,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- CMakeLists.txt      17 Jul 2008 16:03:53 -0000      1.2
+++ CMakeLists.txt      2 Aug 2008 14:03:14 -0000       1.3
@@ -1,6 +1,6 @@
 
 SET(CERTI_TYPES1516_SRCS
-    HLAtypesIEEE1516.hh HLAtypesIEEE1516.cc
+    HLAbuffer.hh HLAbuffer.cc
 )
  
 SOURCE_GROUP("Source Files\\Types1516" FILES ${CERTI_TYPES1516_SRCS})
@@ -25,6 +25,13 @@
 
 INSTALL(FILES
     HLAtypesIEEE1516.hh
+    HLAbuffer.hh
+    HLAbasicType.hh
+    HLAenumeratedType.hh
+    HLAfixedArray.hh
+    HLAvariableArray.hh
+    HLAfixedRecord.hh
+    HLAvariantRecord.hh
     DESTINATION include)
 
 INSTALL(PROGRAMS

Index: HLAtypesIEEE1516.hh
===================================================================
RCS file: /sources/certi/certi/libHLA/HLAtypesIEEE1516.hh,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- HLAtypesIEEE1516.hh 2 Aug 2008 11:44:12 -0000       1.3
+++ HLAtypesIEEE1516.hh 2 Aug 2008 14:03:14 -0000       1.4
@@ -11,23 +11,12 @@
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
-// $Id: HLAtypesIEEE1516.hh,v 1.3 2008/08/02 11:44:12 gotthardp Exp $
+// $Id: HLAtypesIEEE1516.hh,v 1.4 2008/08/02 14:03:14 gotthardp Exp $
 // ----------------------------------------------------------------------------
 
 #ifndef _HLATYPES_IEEE1516_HH
 #define _HLATYPES_IEEE1516_HH
 
-#if defined(_WIN32)
-#pragma warning(disable:4503) // suppress warning C4503: decorated name length 
exceeded
-#endif
-
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-#include <iomanip>
-#include <map>
-#include <stdexcept>
-
 /* These templates implement efficient access functions that provide direct
  * access to IEEE 1516.2 compliant data buffers.
  * The data are manipulated "in situ", no temporary variables are created.
@@ -39,124 +28,10 @@
  * See http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s09.html
  */
 
-#ifdef _MSC_VER
-typedef unsigned __int64  uint64_t;
-typedef __int64           int64_t;
-typedef unsigned __int32  uint32_t;
-typedef __int32           int32_t;
-typedef unsigned __int16  uint16_t;
-typedef __int16           int16_t;
-typedef unsigned __int8   uint8_t;
-typedef __int8            int8_t;
-#else
-#include <stdint.h>
-#endif
+#include <HLAbuffer.hh>
 
 namespace libhla {
 
-std::ostream& __print_buffer(std::ostream& stream, const void *buffer, size_t 
length);
-
-/* Caution:
- * This implementation assumes that there are no compiler-generated data in
- * the heap memory allocated for the __HLAbuffer struct.
- * All structures must have no virtual functions and no non-static members.
- */
-
-class __HLAbuffer
-{
-private:
-    // static buffer for all instantiations of the HLAdata template
-    // indexed by pointers after the last element, the end() pointers
-    typedef std::map<char*,__HLAbuffer*> BufferList;
-    static BufferList gBuffers;
-
-public:
-    char *mBegin;
-    size_t mCapacity;
-    // no automatic free() and realloc() for user allocated memory
-    bool mUserAllocated;
-    // parameters used during dynamic resizing
-    const void* mShakeThat;
-    int mShakeValue;
-
-    __HLAbuffer(size_t capacity)
-     : mUserAllocated(false), mShakeThat(NULL)
-    {
-        // exponential growth: capacity *= 1.5
-        mCapacity = (size_t)(capacity*1.5);
-        mBegin = (char*)calloc(1, mCapacity);
-        // store "this" to a global table
-        gBuffers[mBegin + mCapacity] = this;
-    }
-
-    __HLAbuffer(void *begin, size_t capacity)
-      : mBegin((char*)begin), mCapacity(capacity), mUserAllocated(true), 
mShakeThat(NULL)
-    {
-        // store "this" to a global table
-        gBuffers[mBegin + mCapacity] = this;
-    }
-
-    virtual ~__HLAbuffer()
-    {
-        if (!mUserAllocated)
-            free(mBegin);
-        // remove "this" from the global table
-        gBuffers.erase(__buffer_iterator(mBegin));
-    }
-
-    void __exchange_buffers(__HLAbuffer& newBuffer)
-    {
-        char* oldBegin = mBegin;
-        size_t oldCapacity = mCapacity;
-
-        mBegin = newBuffer.mBegin;
-        mCapacity = newBuffer.mCapacity;
-        gBuffers[mBegin + mCapacity] = this; // update
-
-        newBuffer.mBegin = oldBegin;
-        newBuffer.mCapacity = oldCapacity;
-        gBuffers[oldBegin + oldCapacity] = &newBuffer; // update
-    }
-
-    static BufferList::iterator __buffer_iterator(const void* __this)
-    {
-        // find the first pointer not less than "this", what is the end() 
pointer
-        BufferList::iterator result = gBuffers.lower_bound((char*)__this);
-        if (result == gBuffers.end())
-            throw std::runtime_error("HLAdata: bad pointer");
-        return result;
-    }
-
-    static __HLAbuffer& __buffer(const void* __this)
-    { return *(__buffer_iterator(__this)->second); }
-
-#ifndef NDEBUG
-    static void __check_memory(const void* __this, size_t size)
-    {
-        const __HLAbuffer& buffer = __buffer(__this);
-        if ((char*)__this + size > (char*)buffer.mBegin + buffer.mCapacity)
-            throw std::length_error("HLAdata: data buffer overflow");
-    }
-#endif
-
-    virtual const size_t size() const = 0;
-    virtual void __shake(const void* __that, int value, long resize) = 0;
-
-    static void shake(const void* __that, int value, long resize)
-    { __buffer(__that).__shake(__that, value, resize); }
-
-    const char* data() const
-    { return mBegin; }
-
-    std::ostream& print(std::ostream& stream)
-    {
-#ifndef NDEBUG
-        __check_memory(mBegin, size());
-#endif
-        return __print_buffer(stream, mBegin, size());
-    }
-};
-
 template<class T>
 class HLAdata : public __HLAbuffer
 {
@@ -212,1178 +87,20 @@
     }
 };
 
-//! Swap <i> bytes of the <T> type
-/*! Template specializations are defined for each possible <i>.
- */
-template<class T, int i = sizeof(T)>
-struct __swap;
-
-//! Conversion to the Little Endian encoding
-template<class T>
-struct LittleEndian
-{
-    inline const T operator()(const T& x) const {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-        return x;
-#elif __BYTE_ORDER == __BIG_ENDIAN
-        return __swap<T>()( x );
-#else
-#error Undefined __BYTE_ORDER
-#endif
-    }
-};
-
-//! Conversion to the Big Endian encoding
-template<class T>
-struct BigEndian
-{
-    inline const T operator()(const T& x) const {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-        return __swap<T>()( x );
-#elif __BYTE_ORDER == __BIG_ENDIAN
-        return x;
-#endif
-    }
-};
-
-template<class T>
-struct __swap<T,1>
-{
-    inline const T operator()(const T& x) const {
-        return x;
-    }
-};
-
-template<class T>
-struct __swap<T,2>
-{
-    inline const T operator()(const T& x) const {
-        union {
-            uint16_t u16;
-            T x;
-        } result;
-        result.u16 =
-            (*(uint16_t*)&x<<8 | *(uint16_t*)&x>>8);
-        return result.x;
-    }
-};
-
-template<class T>
-struct __swap<T,4>
-{
-    inline const T operator()(const T& x) const {
-        union {
-            uint32_t u32;
-            T x;
-        } result;
-        result.u32 =
-            (*(uint32_t*)&x<<24 | *(uint32_t*)&x>>24 |
-            (*(uint32_t*)&x & 0x0000ff00UL)<<8 |
-            (*(uint32_t*)&x & 0x00ff0000UL)>>8);
-        return result.x;
-    }
-};
-
-template<class T>
-struct __swap<T,8>
-{
-    inline const T operator()(const T& x) const {
-        union {
-            uint64_t u64;
-            T x;
-        } result;
-        result.u64 =
-            (*(uint64_t*)&x<<56 | *(uint64_t*)&x>>56 |
-            (*(uint64_t*)&x & 0x000000000000ff00ULL)<<40 |
-            (*(uint64_t*)&x & 0x0000000000ff0000ULL)<<24 |
-            (*(uint64_t*)&x & 0x00000000ff000000ULL)<< 8 |
-            (*(uint64_t*)&x & 0x000000ff00000000ULL)>> 8 |
-            (*(uint64_t*)&x & 0x0000ff0000000000ULL)>>24 |
-            (*(uint64_t*)&x & 0x00ff000000000000ULL)>>40);
-        return result.x;
-    }
-};
-
-//! HLA basic type, represented by <T> type stored in <S> using <E> encoding.
-/*!
- * HLAbasicType<DATATYPE, STORAGE, ENCODING>
- * defines a user-convenient DATATYPE, stored in STORAGE using given ENCODING.
- *
- * The data are stored in a buffer of sizeof(STORAGE).
- *
- * The buffer is casted to a DATATYPE that provide data access operators. The
- * data can be accessed in an usual way.
- * The DATATYPE may have any sizeof(), but must have static-cast to STORAGE.
- *
- * For example:
- * typedef HLAbasicType<long, uint32_t, LittleEndian> HLAinteger32BE;
- * HLAdata<HLAinteger32BE> value;
- *
- * value = 42;
- */
-template<class T, class S, template<class T>class E>
-struct HLAbasicType
-{
-    HLAbasicType& operator = (const T& data)
-    {
-#ifndef NDEBUG
-        __HLAbuffer::__check_memory(this, __sizeof());
-#endif
-        *(S*)this = E<S>()(data);
-        return *this;
-    }
-
-    operator T() const
-    {
-#ifndef NDEBUG
-        __HLAbuffer::__check_memory(this, __sizeof());
-#endif
-        return E<S>()(*(S*)this);
-    }
-
-    static const size_t emptysizeof()
-    { return __sizeof(); }
-
-    static const size_t __sizeof()
-    { return sizeof(S); }
-
-    void copy(void* source)
-    {
-#ifndef NDEBUG
-        __HLAbuffer::__check_memory(this, __sizeof());
-#endif
-        memcpy((char*)this, source, __sizeof());
-    }
-
-    static const size_t m_octetBoundary = sizeof(S);
-    static const bool m_isVariable = false;
-};
-
-template<class T, class S, template<class T>class E>
-std::ostream& PrintBuffer(std::ostream& stream, HLAbasicType<T,S,E>& buffer)
-{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
-
-/* IEEE 1516.2, Table 23:
- * Basic data representation table
- */
-typedef HLAbasicType<short, int16_t, BigEndian> HLAinteger16BE;
-typedef HLAbasicType<long, int32_t, BigEndian> HLAinteger32BE;
-typedef HLAbasicType<long long, int64_t, BigEndian> HLAinteger64BE;
-typedef HLAbasicType<float, float, BigEndian> HLAfloat32BE;
-typedef HLAbasicType<double, double, BigEndian> HLAfloat64BE;
-typedef HLAbasicType<wchar_t, wchar_t, BigEndian> HLAoctetPairBE;
-
-typedef HLAbasicType<short, int16_t, LittleEndian> HLAinteger16LE;
-typedef HLAbasicType<long, int32_t, LittleEndian> HLAinteger32LE;
-typedef HLAbasicType<long long, int64_t, LittleEndian> HLAinteger64LE;
-typedef HLAbasicType<float, float, LittleEndian> HLAfloat32LE;
-typedef HLAbasicType<double, double, LittleEndian> HLAfloat64LE;
-typedef HLAbasicType<wchar_t, wchar_t, LittleEndian> HLAoctetPairLE;
-
-typedef HLAbasicType<char, char, BigEndian> HLAoctet;
-
-/* Additional datatypes used by RPR-FOM
- */
-typedef HLAbasicType<unsigned short, uint16_t, BigEndian> Unsignedinteger16BE;
-typedef HLAbasicType<unsigned long, uint32_t, BigEndian> Unsignedinteger32BE;
-typedef HLAbasicType<unsigned long, uint64_t, BigEndian> Unsignedinteger64BE;
-
-//! HLA enumerated type, enumeration <E> with representation <R>.
-/*!
- * HLAenumeratedType<ENUMERATION, REPRESENTATION>
- * defines an user-convenient ENUMERATION stored using given REPRESENTATION.
- *
- * The data can be accessed in an usual way.
- *
- * Some models may use one enumerated value in multiple enumerations. To avoid
- * name collisions it's recommended to put the ENUMERATION in an individual 
namespace.
- *
- * For example:
- * +------------+----------------+------------+--------+-----------+
- * | Name       | Representation | Enumerator | Values | Semantics |
- * +------------+----------------+------------+--------+-----------+
- * |            |                | HLAfalse   | 0      |           |
- * | HLAboolean | HLAinteger32BE +------------+--------+-----------+
- * |            |                | HLAfalse   | 1      |           |
- * +------------+----------------+------------+--------+-----------+
- * 
- * namespace __HLAboolean {
- * enum __enum {
- *   HLAfalse = 0,
- *   HLAtrue = 1
- * };
- * }
- * typedef HLAenumeratedType<__HLAboolean::__enum, HLAinteger32BE> HLAboolean;
- * HLAdata<HLAboolean> value;
- *
- * value = HLAtrue;
- */
-template<class E, class R>
-struct HLAenumeratedType
-{
-    HLAenumeratedType& operator = (const E& data)
-    {
-        *(R*)this = data;
-        return *this;
-    }
-
-    HLAenumeratedType& operator = (const int& data)
-    {
-        *(R*)this = data;
-        return *this;
-    }
-
-    operator E() const
-    {
-        int result = *(R*)this;
-        return (E)result;
-    }
-
-    operator int() const
-    { return *(R*)this; }
-
-    static const size_t emptysizeof()
-    { return R::emptysizeof(); }
-
-    static const size_t __sizeof()
-    { return R::__sizeof(); }
-
-    void copy(void* source)
-    { ((R*)this)->copy(source); }
-
-    static const size_t m_octetBoundary = R::m_octetBoundary;
-    static const bool m_isVariable = false;
-};
+} // namespace libhla
 
-#ifndef MAX
-#define MAX(a,b) (((a)>(b))?(a):(b))
+#if defined(_WIN32)
+#pragma warning(disable:4503) // suppress warning C4503: decorated name length 
exceeded
 #endif
 
-/* Calculate the smallest nonnegative value of P that satisfies the following
- * formula: (offset+size+P) mod boundary = 0
- */
-inline size_t __padding(size_t size, size_t boundary)
-{ return boundary - ((size-1)%boundary + 1); }
-
-//! Fixed array of <N> elements of type <M>
-/*!
- * HLAfixedArray<DATATYPE, NUMBER>
- * defines a fixed array of NUMBER elements of type DATATYPE.
- *
- * The data can be accessed in an usual way.
- *
- * For example:
- * +-------------+----------------+-------------+-----------------+-----------+
- * | Name        | Element type   | Cardinality | Encoding        | Semantics |
- * +-------------+----------------+-------------+-----------------+-----------+
- * | Coordinates | HLAinteger32BE | 3           | HLAfixedArray   |           |
- * +-------------+----------------+-------------+-----------------+-----------+
- *
- * typedef HLAfixedArray<HLAinteger32BE,3> Coordinates;
- * HLAdata<Coordinates> value;
- *
- * (*value)[0] = 100;
- * (*value)[1] = 200;
- */
-template<class M, int N, bool hasVariable = M::m_isVariable>
-struct HLAfixedArray;
-
-template<class M, int N, bool hasVariable>
-std::ostream& PrintBuffer(std::ostream& stream, 
HLAfixedArray<M,N,hasVariable>& buffer)
-{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
-
-// Fixed array optimized for fixed-size elements
-// note: this is the most efficient data type
-template<class M, int N>
-struct HLAfixedArray<M, N, false>
-{
-    static const size_t size()
-    { return N; }
-
-    static const size_t offset(long i)
-    { return i*(M::__sizeof() + __padding(M::__sizeof(), M::m_octetBoundary)); 
}
-
-    M& operator[](long i) const
-    {
-        if (i < 0 || i >= (long)size())
-            throw std::out_of_range("HLAfixedArray: index out of range");
-        return *(M*)((char*)this + offset(i));
-    }
-
-    static const size_t emptysizeof()
-    { return __sizeof(); }
-
-    // Padding shall not be added after the last element of the array.
-    static const size_t __sizeof()
-    { return offset(N-1) + M::__sizeof(); }
-
-    void copy(void* source)
-    {
-        size_t offs = 0;
-        // copy all elements of the structure
-        for (size_t i = 0; i < N; i++) {
-            ((M*)((char*)this + offs))->copy((char*)source + offs);
-            offs += M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary);
-        }
-    }
-
-    static const size_t m_octetBoundary = M::m_octetBoundary;
-    static const bool m_isVariable = false; // fixed-size array of fixed-size 
elements
-};
-
-// Generic fixed array, supports variable-size elements
-template<class M, int N>
-struct HLAfixedArray<M, N, true>
-{
-    static const size_t size()
-    { return N; }
-
-    const size_t offset(long i) const
-    {
-        size_t offs = 0;
-        // count every member, the elements may be variable-sized
-        for (long j=0; j<i; j++) {
-            offs += ((M*)((char*)this + offs))->__sizeof();
-            offs += __padding(offs, M::m_octetBoundary);
-        }
-        return offs;
-    }
-
-    M& operator[](long i) const
-    {
-        if (i >= size())
-            throw std::out_of_range("HLAfixedArray: index out of range");
-        return *(M*)((char*)this + offset(i));
-    }
-
-    static const size_t emptysizeof()
-    {
-        size_t size = N*M::emptysizeof();
-        // padding shall not be added after the last element of the array
-        if(N > 1)
-            size += (N-1)*__padding(M::emptysizeof(), M::m_octetBoundary);
-        return size;
-    }
-
-    const size_t __sizeof() const
-    {
-        size_t offs = offset(N-1);
-        return offs + ((M*)((char*)this + offs))->__sizeof();
-    }
-
-    void copy(void* source)
-    {
-        size_t offsD = 0;
-        size_t offsS = 0;
-        // copy all elements of the structure, the elements may be 
variable-sized
-        for (size_t i = 0; i < N; i++) {
-            ((M*)((char*)this + offsD))->copy((char*)source + offsS);
-
-            offsD += ((M*)((char*)this + offsD))->__sizeof(); // may differ 
from source size
-            offsD += __padding(offsD, M::m_octetBoundary);
-            offsS += ((M*)((char*)source + offsS))->__sizeof();
-            offsS += __padding(offsS, M::m_octetBoundary);
-        }
-    }
-
-    static const size_t m_octetBoundary = M::m_octetBoundary;
-    static const bool m_isVariable = true; // variable-sized elements
-};
-
-//! Variable array of type <M>
-/*!
- * HLAvariableArray<DATATYPE>
- * defines an array of a variable number of DATATYPE elements.
- *
- * The size() member must be set before accessing the data. No data are moved
- * when the size() is changed.
- *
- * For example:
- * +-------------+----------------+-------------+-----------------+-----------+
- * | Name        | Element type   | Cardinality | Encoding        | Semantics |
- * +-------------+----------------+-------------+-----------------+-----------+
- * | List        | HLAinteger32BE | Dynamic     | HLAvaribleArray |           |
- * +-------------+----------------+-------------+-----------------+-----------+
- *
- * typedef HLAvariableArray<HLAinteger32BE> List;
- * HLAdata<List> value;
- *
- * (*value).set_size(2);
- * (*value)[0] = 100;
- * (*value)[1] = 200;
- */
-template<class M, bool hasVariable = M::m_isVariable>
-struct HLAvariableArray;
-
-template<class M, bool hasVariable>
-std::ostream& PrintBuffer(std::ostream& stream, 
HLAvariableArray<M,hasVariable>& buffer)
-{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
-
-// Variable array optimized for fixed-size elements
-template<class M>
-struct HLAvariableArray<M, false>
-{
-    //! Get/Set array size, without memory management
-    /* This function assumes no data are stored in the buffer after this array.
-     * You may want to use set_size() instead.
-     */
-    HLAinteger32BE& size() const
-    { return (HLAinteger32BE&)*this; }
-
-    //! Set array size, with memory management
-    void set_size(long i)
-    {
-        if (i == size())
-            return; // no change
-
-        // as changing the array size may impact padding, the whole buffer 
needs to be reorganized
-        __HLAbuffer::shake(this, i,
-            (i-size())*(long)(M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary)));
-    }
-
-    static const size_t offset(long i)
-    { return emptysizeof() + i*(M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary)); }
-
-    M& operator[](long i) const
-    {
-        if (i >= size())
-            throw std::out_of_range("HLAvariableArray: index out of range");
-        return *(M*)((char*)this + offset(i));
-    }
-
-    static const size_t emptysizeof()
-    { return HLAinteger32BE::__sizeof() + 
__padding(HLAinteger32BE::__sizeof(), M::m_octetBoundary); }
-
-    // Padding shall not be added after the last element of the array.
-    const size_t __sizeof() const
-    {
-        if (size() > 0)
-            return offset(size()-1) + M::__sizeof();
-        else
-            return emptysizeof();
-    }
-
-    void copy(void* source)
-    {
-        int N = *(HLAinteger32BE*)source;
-        int toCopy;
-
-        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
-        if(source == buffer.mShakeThat) {
-            *(HLAinteger32BE*)this = buffer.mShakeValue;
-            toCopy = std::min(N, buffer.mShakeValue); // number of elements to 
copy
-        }
-        else {
-            *(HLAinteger32BE*)this = N;
-            toCopy = N; // copy all elements
-        }
-
-        size_t offs = emptysizeof();
-        // copy all elements of the structure, the elements may be 
variable-sized
-        for (int i = 0; i < toCopy; i++) {
-            ((M*)((char*)this + offs))->copy((char*)source + offs);
-            offs += M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary);
-        }
-    }
-
-    static const size_t m_octetBoundary =
-        MAX(HLAinteger32BE::m_octetBoundary, M::m_octetBoundary);
-    static const bool m_isVariable = true; // variable-sized array
-};
-
-// Generic variable array, supports variable-size elements
-// note: this is the less efficient data type
-template<class M>
-struct HLAvariableArray<M, true>
-{
-    //! Get/Set array size, without memory management
-    /* This function assumes no data are stored in the buffer after this array.
-     * You may want to use set_size() instead.
-     */
-    HLAinteger32BE& size() const
-    { return (HLAinteger32BE&)*this; }
-
-    //! Set array size, with memory management
-    void set_size(long i)
-    {
-        if (i == size())
-            return; // no change
-
-        // as changing the array size may impact padding, the whole buffer 
needs to be reorganized
-        __HLAbuffer::shake(this, i,
-            (i-size())*(long)(M::emptysizeof() + __padding(M::emptysizeof(), 
M::m_octetBoundary)));
-    }
-
-    const size_t offset(long i) const
-    {
-        size_t offs = emptysizeof();
-        // count every member, the elements may be variable-sized
-        for (long j=0; j<i; j++) {
-            offs += ((M*)((char*)this + offs))->__sizeof();
-            offs += __padding(offs, M::m_octetBoundary);
-        }
-        return offs;
-    }
-
-    M& operator[](long i) const
-    {
-        if (i >= size())
-            throw std::out_of_range("HLAvariableArray: index out of range");
-        return *(M*)((char*)this + offset(i));
-    }
-
-    static const size_t emptysizeof()
-    { return HLAinteger32BE::__sizeof() + 
__padding(HLAinteger32BE::__sizeof(), M::m_octetBoundary); }
-
-    // Padding shall not be added after the last element of the array.
-    const size_t __sizeof() const
-    {
-        if (size() > 0) {
-            size_t offs = offset(size()-1);
-            return offs + ((M*)((char*)this + offs))->__sizeof();
-        }
-        else
-            return emptysizeof();
-    }
-
-    void copy(void* source)
-    {
-        int N = *(HLAinteger32BE*)source;
-        int toCopy;
-
-        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
-        if(source == buffer.mShakeThat) {
-            *(HLAinteger32BE*)this = buffer.mShakeValue;
-            toCopy = std::min(N, buffer.mShakeValue); // number of elements to 
copy
-        }
-        else {
-            *(HLAinteger32BE*)this = N;
-            toCopy = N; // copy all elements
-        }
-
-        size_t offsD = emptysizeof();
-        size_t offsS = emptysizeof();
-        // copy all elements of the structure, the elements may be 
variable-sized
-        for (int i = 0; i < toCopy; i++) {
-            ((M*)((char*)this + offsD))->copy((char*)source + offsS);
-
-            offsD += ((M*)((char*)this + offsD))->__sizeof(); // may differ 
from source size
-            offsD += __padding(offsD, M::m_octetBoundary);
-            offsS += ((M*)((char*)source + offsS))->__sizeof();
-            offsS += __padding(offsS, M::m_octetBoundary);
-        }
-    }
-
-    static const size_t m_octetBoundary =
-        MAX(HLAinteger32BE::m_octetBoundary, M::m_octetBoundary);
-    static const bool m_isVariable = true; // variable-size array of 
variable-size elements
-};
-
-//! Fixed record of fields <R>
-/*!
- * HLAfixedRecord<
- *   HLAfixedField<INDEX1, DATATYPE1,
- *   HLAfixedField<INDEX2, DATATYPE2,
- *   ...
- *   > ... > TYPENAME;
- * defines an ordered sequence of DATATYPE entries.
- *
- * The data can be accessed using the field<INDEX>() function. The INDEX is a 
logical
- * identifier only. The data are stored in the declaration order.
- *
- * For example:
- * 
+-------------+------------------------------------+----------------+-----------+
- * |             | Field                              |                |       
    |
- * | Record name +---------+--------------+-----------+ Encoding       | 
Semantics |
- * |             | Name    | Type         | Semantics |                |       
    |
- * 
+-------------+---------+--------------+-----------+----------------+-----------+
- * |             | FIELD_X | HLAfloat32LE |           |                |       
    |
- * |             +---------+--------------+-----------+                |       
    |
- * | Coordinates | FIELD_X | HLAfloat32LE |           | HLAfixedRecord |       
    |
- * |             +---------+--------------+-----------+                |       
    |
- * |             | FIELD_X | HLAfloat32LE |           |                |       
    |
- * 
+-------------+---------+--------------+-----------+----------------+-----------+
- * 
- * enum {
- *   FIELD_X = 0,
- *   FIELD_Y,
- *   FIELD_Z
- * };
- * typedef HLAfixedRecord<
- *   HLAfixedField<FIELD_X, HLAfloat32LE,
- *   HLAfixedField<FIELD_Y, HLAfloat32LE,
- *   HLAfixedField<FIELD_Z, HLAfloat32LE
- *   > > > > Coordinates;
- * HLAdata<Coordinates> value;
- *
- * value->field<FIELD_X>() = 3.14;
- * value->field<FIELD_Y>() = 6.28;
- * value->field<FIELD_Z>() = 9.42;
- */
-template<class R, bool hasVariable = R::m_isVariable>
-struct HLAfixedRecord;
-
-template<class R, bool V>
-std::ostream& PrintBuffer(std::ostream& stream, HLAfixedRecord<R,V>& buffer)
-{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
-
-//! Returns <i>th field of the HLAfixedField <L>
-template<class R, int i> struct __FieldAt;
-
-// Fixed record optimized for fixed-size fields
-template<class R>
-struct HLAfixedRecord<R, false>
-{
-    template <int i>
-    typename __FieldAt<R,i>::Type& field() const
-    { return *(typename __FieldAt<R,i>::Type*)((char*)this + 
R::field_offsetof(i)); }
-
-    static const size_t emptysizeof()
-    { return R::emptysizeof(); }
-
-    static const size_t __sizeof()
-    { return R::__sizeof(); }
-
-    void copy(void* source)
-    { ((R*)this)->copy(source); }
-
-    static const size_t m_octetBoundary = R::m_octetBoundary;
-    static const bool m_isVariable = false; // fixed-sized fields
-};
-
-// Generic fixed record, supports variable-size fields
-template<class R>
-struct HLAfixedRecord<R, true>
-{
-    template <int i>
-    typename __FieldAt<R,i>::Type& field() const
-    { return *(typename __FieldAt<R,i>::Type*)((char*)this + 
((R*)this)->field_offsetof(i)); }
-
-    static const size_t emptysizeof()
-    { return R::emptysizeof(); }
-
-    const size_t __sizeof()
-    { return ((R*)this)->__sizeof(); }
-
-    void copy(void* source)
-    { ((R*)this)->copy(source); }
-
-    static const size_t m_octetBoundary = R::m_octetBoundary;
-    static const bool m_isVariable = true; // variable-sized fields
-};
-
-struct HLAfixedEnd;
-
-//! Record at index <E>, field of type <M>, followed by HLAfixedField <N>
-// note: <E> must be "int" to enable implicit conversion from/to enum types
-template<int E, class M, class N = HLAfixedEnd, bool hasVariable = 
M::m_isVariable || N::m_isVariable>
-struct HLAfixedField;
-
-// List of fixed-size fields
-template<int E, class M, class N>
-struct HLAfixedField<E, M, N, false>
-{
-    static const size_t field_offsetof(int d, size_t offs = 0)
-    {
-        if (d != E) {
-            size_t size = M::__sizeof();
-            size += __padding(offs+size, N::memberBoundary);
-            return N::field_offsetof(d, offs+size);
-        }
-        else
-            return offs;
-    }
-
-    static const size_t memberBoundary = M::m_octetBoundary;
-
-    static const size_t emptysizeof(size_t offs = 0)
-    { return __sizeof(offs); }
-
-    // Padding shall not be added after the last element of the array.
-    static const size_t __sizeof(size_t offs = 0)
-    {
-        size_t size = M::__sizeof();
-        // if not reached HLAvariantEnd
-        if (N::memberBoundary) {
-            size += __padding(offs+size, N::memberBoundary);
-            return N::__sizeof(offs+size);
-        }
-        else
-            return offs+size;
-    }
-
-    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
-    {
-        ((M*)this)->copy(source);
-        if (N::memberBoundary) {
-            offsD += M::__sizeof();
-            offsD += __padding(offsD, N::memberBoundary);
-            offsS += M::__sizeof();
-            offsS += __padding(offsS, N::memberBoundary);
-            ((N*)((char*)this + M::__sizeof()))->copy((char*)source + 
M::__sizeof(), offsD, offsS);
-        }
-    }
-
-    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
-    static const bool m_isVariable = false; // fixed-sized fields
-};
-
-// List containg variable-size fields
-template<int E, class M, class N>
-struct HLAfixedField<E, M, N, true>
-{
-    const size_t field_offsetof(int d, size_t offs = 0) const
-    {
-        if (d != E) {
-            size_t size = ((M*)this)->__sizeof();
-            size += __padding(offs+size, N::memberBoundary);
-            return ((N*)((char*)this + size))->field_offsetof(d, offs+size);
-        }
-        else
-            return offs;
-    }
-
-    static const size_t memberBoundary = M::m_octetBoundary;
-
-    static const size_t emptysizeof(size_t offs = 0)
-    {
-        size_t size = M::emptysizeof();
-        // if not reached HLAvariantEnd
-        if (N::memberBoundary) {
-            size += __padding(offs+size, N::memberBoundary);
-            return N::emptysizeof(offs+size);
-        }
-        else
-            return offs+size;
-    }
-
-    // Padding shall not be added after the last element of the array.
-    const size_t __sizeof(size_t offs = 0) const
-    {
-      size_t size = ((M*)this)->__sizeof();
-      // if not reached HLAvariantEnd
-      if (N::memberBoundary) {
-          size += __padding(offs+size, N::memberBoundary);
-          return ((N*)((char*)this + size))->__sizeof(offs+size);
-      }
-      else
-          return offs+size;
-    }
-
-    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
-    {
-        ((M*)this)->copy(source);
-        if (N::memberBoundary) {
-            size_t sizeD = ((M*)this)->__sizeof(); // may differ from source 
size
-            sizeD += __padding(offsD+sizeD, N::memberBoundary);
-            size_t sizeS = ((M*)source)->__sizeof();
-            sizeS += __padding(offsS+sizeS, N::memberBoundary);
-            ((N*)((char*)this + sizeD))->copy((char*)source + sizeS, 
offsD+sizeD, offsS+sizeS);
-        }
-    }
-
-    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
-    static const bool m_isVariable = true; // variable-sized fields
-};
-
-//! Defines a last field in the fixed record
-struct HLAfixedEnd
-{
-    static const size_t field_offsetof(int d, size_t offs = 0)
-    { return offs; }
-
-    static const size_t memberBoundary = 0;
-    static const size_t emptysizeof(size_t offs = 0)
-    { return offs; }
-    static const size_t __sizeof(size_t offs = 0)
-    { return offs; }
-    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
-    { /* nop */ }
-
-    static const size_t m_octetBoundary = 0;
-    static const bool m_isVariable = false;
-};
-
-template<bool C, class T, class E>
-struct __if
-{ typedef T X; };
-
-template<class T, class E>
-struct __if<false, T, E>
-{ typedef E X; };
-
-template<int E, class M, class N, bool V, int d>
-struct __FieldAt<HLAfixedField<E, M, N, V>, d>
-{ typedef typename __if<d==E, M, typename __FieldAt<N,d>::Type>::X Type; }; 
-
-// returned when no HLAfixedField has a given index(i)
-template<int d>
-struct __FieldAt<HLAfixedEnd, d>
-{ typedef HLAfixedEnd Type; };
-
-//! Variant record of discriminant <D> at index <E> and alternatives <R>
-/*!
- * HLAvariantRecord<
- *   INDEX, DATATYPE,
- *   HLAvariantField<ENUMERATORS1, INDEX1, DATATYPE1,
- *   HLAvariantField<ENUMERATORS2, INDEX2, DATATYPE2,
- *   ...
- *   > ... > TYPENAME;
- * defines an ordered sequence of DATATYPE entries.
- *
- * The data can be accessed using the field<INDEX>() function. The INDEX is a 
logical
- * identifier only. 
- * The first field is a discriminant. It is followed by an alternative whose
- * ENUMERATORS match the discriminant value.
- *
- * For example:
- * 
+-------------+-------------------------------+------------------------------------+------------------+-----------+
- * |             | Discriminant                  | Alternative                 
       |                  |           |
- * | Record name 
+------+-----------+------------+---------+--------------+-----------+ Encoding 
        | Semantics |
- * |             | Name | Type      | Enumerator | Name    | Type         | 
Semantics |                  |           |
- * 
+-------------+------+-----------+------------+---------+--------------+-----------+------------------+-----------+
- * |             |      |           | AXIS_X     | FIELD_X | HLAfloat32LE |    
       |                  |           |
- * | Coordinates | TYPE | TypesEnum 
+------------+---------+--------------+-----------+ HLAvariantRecord |          
 |
- * |             |      |           | AXIS_Y     | FIELD_Y | HLAfloat32LE |    
       |                  |           |
- * 
+-------------+------+-----------+------------+---------+--------------+-----------+------------------+-----------+
- * 
- * namespace __Fields {
- * enum __enum {
- *   TYPE = 0,
- *   FIELD_X = 101,
- *   FIELD_Y = 102
- * };
- * }
- * typedef HLAenumeratedType<__Fields::__enum, HLAinteger32BE> Fields;
- * typedef HLAvariantRecord<
- *   __Fields::TYPE, TypesEnum,
- *   HLAvariantField<HLAsetValue<AXIS_X>, __Fields::FIELD_X, HLAfloat32LE,
- *   HLAvariantField<HLAsetValue<AXIS_Y>, __Fields::FIELD_Y, HLAfloat32LE
- *   > > > Coordinates;
- * HLAdata<Coordinates> value;
- *
- * value->set_discriminant(AXIS_X);
- * value->field<__Fields::FIELD_X>() = 3.14;
- */
-template<int DE, class DM, class R, bool hasVariable = R::m_isVariable>
-struct HLAvariantRecord;
-
-template<int DE, class DM, class R, bool V>
-std::ostream& PrintBuffer(std::ostream& stream, HLAvariantRecord<DE,DM,R,V>& 
buffer)
-{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
-
-//! Returns the discriminant, or a <i>th field of the HLAvariantField <R>
-template<int DE, class DM, class R, int e>
-struct __DiscriminantOrFieldAt;
-
-// Variant record optimized for fixed-size fields
-template<int DE, class DM, class R>
-struct HLAvariantRecord<DE, DM, R, false>
-{
-    //! Get/Set the discriminant, without memory management
-    /* This function assumes no data are stored in the buffer after this array.
-     * You may want to use set_discriminant() instead.
-     */
-    DM& discriminant() const
-    { return *(DM*)this; }
-
-    //! Set the discriminant, with memory management
-    void set_discriminant(int d)
-    {
-        if (d == (int)discriminant())
-            return; // no change
-
-        // as changing the discriminant may impact padding, the whole buffer 
needs to be reorganized
-        __HLAbuffer::shake(this, d, (long)R::field_emptysizeof(d));
-    }
-
-    template <int e>
-    typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type& field() const
-    {
-        // return the discriminant
-        if (e == DE)
-            return *(typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type*)this;
-
-        if (e != R::get_field(discriminant()))
-            throw std::out_of_range("HLAvariantRecord: wrong discriminant");
-        // return one of the alternatives
-        return *(typename 
__DiscriminantOrFieldAt<DE,DM,R,e>::Type*)((char*)this + emptysizeof());
-    }
-
-    static const size_t emptysizeof()
-    { return DM::__sizeof() + __padding(DM::__sizeof(), R::m_octetBoundary); }
-
-    const size_t __sizeof() const
-    {
-        if (R::has_field(discriminant()))
-            return emptysizeof() + R::field_sizeof(discriminant());
-        else
-            return emptysizeof();
-    }
-
-    void copy(void* source)
-    {
-        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
-        if(source == buffer.mShakeThat) {
-            *(DM*)this = buffer.mShakeValue;
-            // switching variant: content is removed
-        }
-        else {
-            int d = *(DM*)source;
-            // not switching variant: copy the content
-            *(DM*)this = d;
-            ((R*)this)->copy(d, (char*)source + emptysizeof());
-        }
-    }
-
-    static const size_t m_octetBoundary = MAX(DM::m_octetBoundary, 
R::m_octetBoundary);
-    static const bool m_isVariable = true; // variant record of fixed-size 
fields
-};
-
-// Generic variant record, supports variable-size fields
-template<int DE, class DM, class R>
-struct HLAvariantRecord<DE, DM, R, true>
-{
-    //! Get/Set the discriminant, without memory management
-    /* This function assumes no data are stored in the buffer after this array.
-     * You may want to use set_discriminant() instead.
-     */
-    DM& discriminant() const
-    { return *(DM*)this; }
-
-    //! Set the discriminant, with memory management
-    void set_discriminant(int d)
-    {
-        if (d == (int)discriminant())
-            return; // no change
-
-        // as changing the discriminant may impact padding, the whole buffer 
needs to be reorganized
-        __HLAbuffer::shake(this, d, (long)R::field_emptysizeof(d));
-    }
-
-    template <int e>
-    typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type& field() const
-    {
-        // return the discriminant
-        if (e == DE)
-            return *(typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type*)this;
-
-        if (e != R::get_field(discriminant()))
-            throw std::out_of_range("HLAvariantRecord: wrong discriminant");
-        // return one of the alternatives
-        return *(typename 
__DiscriminantOrFieldAt<DE,DM,R,e>::Type*)((char*)this + emptysizeof());
-    }
-
-    static const size_t emptysizeof()
-    { return DM::__sizeof() + __padding(DM::__sizeof(), R::m_octetBoundary); }
-
-    const size_t __sizeof() const
-    {
-        if (R::has_field(discriminant()))
-            return emptysizeof() + ((R*)((char*)this + 
emptysizeof()))->field_sizeof(discriminant());
-        else
-            return emptysizeof();
-    }
-
-    void copy(void* source)
-    {
-        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
-        if(source == buffer.mShakeThat) {
-            *(DM*)this = buffer.mShakeValue;
-            // switching variant: content is removed
-        }
-        else {
-            int d = *(DM*)source;
-            // not switching variant: copy the content
-            *(DM*)this = d;
-            ((R*)this)->copy(d, (char*)source + emptysizeof());
-        }
-    }
-
-    static const size_t m_octetBoundary = MAX(DM::m_octetBoundary, 
R::m_octetBoundary);
-    static const bool m_isVariable = true; // variant record of variable-sized 
fields
-};
-
-struct HLAsetEnd;
-
-//! Defines a value in an enumerator list; to be used with HLAvariantField
-template<int e, class N = HLAsetEnd>
-struct HLAsetValue
-{
-    static int includes(int i)
-    {
-        if (i == e)
-            return 1;
-        else
-            return N::includes(i);
-    }
-};
-
-//! Defines a range in an enumerator list
-template<int e1, int e2, class N = HLAsetEnd>
-struct HLAsetRange
-{
-    static int includes(int i)
-    {
-        if (e1 <= i && i <= e2)
-            return 1;
-        else
-            return N::includes(i);
-    }
-};
-
-//! Defines the "HLAother" symbol in an enumerator list
-template<class N = HLAsetEnd>
-struct HLAsetOther
-{
-    static int includes(int i)
-    { return 1; }
-};
-
-//! Defines the end of an enumerator list
-struct HLAsetEnd
-{
-    static int includes(int i)
-    { return 0; }
-};
-
-struct HLAvariantEnd;
-
-//! Record at index <E>, field of type <M>, followed by HLAvariantField <N>
-// note: <E> must be "int" to enable implicit conversion from/to enum types
-template<class D, int E, class M, class N = HLAvariantEnd, bool hasVariable = 
M::m_isVariable || N::m_isVariable>
-struct HLAvariantField;
-
-// List of fixed-size fields
-template<class D, int E, class M, class N>
-struct HLAvariantField<D, E, M, N, false>
-{
-    static bool has_field(int d)
-    {
-        if (D::includes(d))
-          return true; // found
-        else
-          return N::has_field(d); // continue searching
-    }
-
-    static int get_field(int d)
-    {
-        if (D::includes(d))
-            return E;
-        else
-            return N::get_field(d);
-    }
-
-    static const size_t field_emptysizeof(int e)
-    {
-        if (e == E)
-            return M::emptysizeof();
-        else
-            return N::field_emptysizeof(e);
-    }
-
-    static const size_t field_sizeof(int e)
-    {
-        if (e == E)
-            return M::__sizeof();
-        else
-            return N::field_sizeof(e);
-    }
-
-    void copy(int e, void* source)
-    {
-        if (e == E)
-            return ((M*)this)->copy(source);
-        else
-            return ((N*)this)->copy(e, source);
-    }
-
-    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
-    static const bool m_isVariable = false; // fixed-sized fields
-};
-
-// List containg variable-size fields
-template<class D, int E, class M, class N>
-struct HLAvariantField<D, E, M, N, true>
-{
-    static bool has_field(int d)
-    {
-        if (D::includes(d))
-          return true; // found
-        else
-          return N::has_field(d); // continue searching
-    }
-
-    static int get_field(int d)
-    {
-        if (D::includes(d))
-            return E;
-        else
-            return N::get_field(d);
-    }
-
-    static const size_t field_emptysizeof(int e)
-    {
-        if (e == E)
-            return M::emptysizeof();
-        else
-            return N::field_emptysizeof(e);
-    }
-
-    const size_t field_sizeof(int e) const
-    {
-        if (e == E)
-            return ((M*)this)->__sizeof();
-        else
-            return ((N*)this)->field_sizeof(e);
-    }
-
-    void copy(int e, void* source)
-    {
-        if (e == E)
-            return ((M*)this)->copy(source);
-        else
-            return ((N*)this)->copy(e, source);
-    }
-
-    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
-    static const bool m_isVariable = true; // variable-sized fields
-};
-
-//! Defines a last field in the fixed record
-struct HLAvariantEnd
-{
-    static bool has_field(int d)
-    { return false; }
-    static int get_field(int d)
-    { throw std::out_of_range("HLAvariantRecord: unknown discriminant"); }
-    static const size_t field_emptysizeof(int e)
-    { return 0; }
-    static const size_t field_sizeof(int e)
-    { return 0; }
-    void copy(int e, void* source)
-    { /* nop */ }
-
-    static const size_t m_octetBoundary = 0;
-    static const bool m_isVariable = false;
-};
-
-template<int DE, class DM, class R, int e>
-struct __DiscriminantOrFieldAt
-{ typedef typename __if<e==DE, DM, typename __FieldAt<R,e>::Type>::X Type; }; 
-
-template<class D, int E, class M, class N, bool V, int e>
-struct __FieldAt<HLAvariantField<D,E,M,N,V>, e>
-{ typedef typename __if<e==E, M, typename __FieldAt<N,e>::Type>::X Type; }; 
-
-// returned when no HLAvariantField has a given index(i)
-template<int e>
-struct __FieldAt<HLAvariantEnd, e>
-{ typedef HLAvariantEnd Type; };
-
-} // namespace libhla
+#include <HLAbasicType.hh>
+#include <HLAenumeratedType.hh>
+#include <HLAfixedArray.hh>
+#include <HLAvariableArray.hh>
+#include <HLAfixedRecord.hh>
+#include <HLAvariantRecord.hh>
 
 #endif // _HLATYPES_IEEE1516_HH
 
-// $Id: HLAtypesIEEE1516.hh,v 1.3 2008/08/02 11:44:12 gotthardp Exp $
+// $Id: HLAtypesIEEE1516.hh,v 1.4 2008/08/02 14:03:14 gotthardp Exp $
 

Index: HLAbasicType.hh
===================================================================
RCS file: HLAbasicType.hh
diff -N HLAbasicType.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAbasicType.hh     2 Aug 2008 14:03:14 -0000       1.1
@@ -0,0 +1,205 @@
+// ----------------------------------------------------------------------------
+// HLAbasicType.hh - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAbasicType.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#ifndef _HLATYPES_BASICTYPE_HH
+#define _HLATYPES_BASICTYPE_HH
+
+#include <HLAbuffer.hh>
+
+namespace libhla {
+
+/* HLAbasicType<DATATYPE, STORAGE, ENCODING>
+ * defines a user-convenient DATATYPE, stored in STORAGE using given ENCODING.
+ *
+ * The data are stored in a buffer of sizeof(STORAGE).
+ *
+ * The buffer is casted to a DATATYPE that provide data access operators. The
+ * data can be accessed in an usual way.
+ * The DATATYPE may have any sizeof(), but must have static-cast to STORAGE.
+ *
+ * For example:
+ * typedef HLAbasicType<long, uint32_t, LittleEndian> HLAinteger32BE;
+ * HLAdata<HLAinteger32BE> value;
+ *
+ * value = 42;
+ */
+
+//! Swap <i> bytes of the <T> type
+/*! Template specializations are defined for each possible <i>.
+ */
+template<class T, int i = sizeof(T)>
+struct __swap;
+
+//! Conversion to the Little Endian encoding
+template<class T>
+struct LittleEndian
+{
+    inline const T operator()(const T& x) const {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+        return x;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+        return __swap<T>()( x );
+#else
+#error Undefined __BYTE_ORDER
+#endif
+    }
+};
+
+//! Conversion to the Big Endian encoding
+template<class T>
+struct BigEndian
+{
+    inline const T operator()(const T& x) const {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+        return __swap<T>()( x );
+#elif __BYTE_ORDER == __BIG_ENDIAN
+        return x;
+#endif
+    }
+};
+
+template<class T>
+struct __swap<T,1>
+{
+    inline const T operator()(const T& x) const {
+        return x;
+    }
+};
+
+template<class T>
+struct __swap<T,2>
+{
+    inline const T operator()(const T& x) const {
+        union {
+            uint16_t u16;
+            T x;
+        } result;
+        result.u16 =
+            (*(uint16_t*)&x<<8 | *(uint16_t*)&x>>8);
+        return result.x;
+    }
+};
+
+template<class T>
+struct __swap<T,4>
+{
+    inline const T operator()(const T& x) const {
+        union {
+            uint32_t u32;
+            T x;
+        } result;
+        result.u32 =
+            (*(uint32_t*)&x<<24 | *(uint32_t*)&x>>24 |
+            (*(uint32_t*)&x & 0x0000ff00UL)<<8 |
+            (*(uint32_t*)&x & 0x00ff0000UL)>>8);
+        return result.x;
+    }
+};
+
+template<class T>
+struct __swap<T,8>
+{
+    inline const T operator()(const T& x) const {
+        union {
+            uint64_t u64;
+            T x;
+        } result;
+        result.u64 =
+            (*(uint64_t*)&x<<56 | *(uint64_t*)&x>>56 |
+            (*(uint64_t*)&x & 0x000000000000ff00ULL)<<40 |
+            (*(uint64_t*)&x & 0x0000000000ff0000ULL)<<24 |
+            (*(uint64_t*)&x & 0x00000000ff000000ULL)<< 8 |
+            (*(uint64_t*)&x & 0x000000ff00000000ULL)>> 8 |
+            (*(uint64_t*)&x & 0x0000ff0000000000ULL)>>24 |
+            (*(uint64_t*)&x & 0x00ff000000000000ULL)>>40);
+        return result.x;
+    }
+};
+
+//! HLA basic type, represented by <T> type stored in <S> using <E> encoding.
+template<class T, class S, template<class T>class E>
+struct HLAbasicType
+{
+    HLAbasicType& operator = (const T& data)
+    {
+#ifndef NDEBUG
+        __HLAbuffer::__check_memory(this, __sizeof());
+#endif
+        *(S*)this = E<S>()(data);
+        return *this;
+    }
+
+    operator T() const
+    {
+#ifndef NDEBUG
+        __HLAbuffer::__check_memory(this, __sizeof());
+#endif
+        return E<S>()(*(S*)this);
+    }
+
+    static const size_t emptysizeof()
+    { return __sizeof(); }
+
+    static const size_t __sizeof()
+    { return sizeof(S); }
+
+    void copy(void* source)
+    {
+#ifndef NDEBUG
+        __HLAbuffer::__check_memory(this, __sizeof());
+#endif
+        memcpy((char*)this, source, __sizeof());
+    }
+
+    static const size_t m_octetBoundary = sizeof(S);
+    static const bool m_isVariable = false;
+};
+
+template<class T, class S, template<class T>class E>
+std::ostream& PrintBuffer(std::ostream& stream, HLAbasicType<T,S,E>& buffer)
+{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
+
+/* IEEE 1516.2, Table 23:
+ * Basic data representation table
+ */
+typedef HLAbasicType<short, int16_t, BigEndian> HLAinteger16BE;
+typedef HLAbasicType<long, int32_t, BigEndian> HLAinteger32BE;
+typedef HLAbasicType<long long, int64_t, BigEndian> HLAinteger64BE;
+typedef HLAbasicType<float, float, BigEndian> HLAfloat32BE;
+typedef HLAbasicType<double, double, BigEndian> HLAfloat64BE;
+typedef HLAbasicType<wchar_t, wchar_t, BigEndian> HLAoctetPairBE;
+
+typedef HLAbasicType<short, int16_t, LittleEndian> HLAinteger16LE;
+typedef HLAbasicType<long, int32_t, LittleEndian> HLAinteger32LE;
+typedef HLAbasicType<long long, int64_t, LittleEndian> HLAinteger64LE;
+typedef HLAbasicType<float, float, LittleEndian> HLAfloat32LE;
+typedef HLAbasicType<double, double, LittleEndian> HLAfloat64LE;
+typedef HLAbasicType<wchar_t, wchar_t, LittleEndian> HLAoctetPairLE;
+
+typedef HLAbasicType<char, char, BigEndian> HLAoctet;
+
+/* Additional datatypes used by RPR-FOM
+ */
+typedef HLAbasicType<unsigned short, uint16_t, BigEndian> Unsignedinteger16BE;
+typedef HLAbasicType<unsigned long, uint32_t, BigEndian> Unsignedinteger32BE;
+typedef HLAbasicType<unsigned long, uint64_t, BigEndian> Unsignedinteger64BE;
+
+} // namespace libhla
+
+#endif // _HLATYPES_BASICTYPE_HH
+
+// $Id: HLAbasicType.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+

Index: HLAbuffer.cc
===================================================================
RCS file: HLAbuffer.cc
diff -N HLAbuffer.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAbuffer.cc        2 Aug 2008 14:03:14 -0000       1.1
@@ -0,0 +1,66 @@
+// ----------------------------------------------------------------------------
+// HLAbuffer.cc - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAbuffer.cc,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#include "HLAbuffer.hh"
+
+#include <iomanip>
+
+// #define HLATYPES_IEEE1516_DISPLAYPRINTABLE
+
+namespace libhla {
+
+__HLAbuffer::BufferList __HLAbuffer::gBuffers;
+
+//! Print the physical data buffer (for debugging purposes only)
+std::ostream& __print_buffer(std::ostream& stream, const void *buffer, size_t 
length)
+{
+    static const size_t cBytesPerLine = 16;
+    size_t offset = 0;
+
+    while (length != 0) {
+        stream << std::hex << std::setfill('0') << std::setw(4) << 
(unsigned)offset << ": ";
+
+        size_t i = std::min(cBytesPerLine, length);
+        const unsigned char* p = (const unsigned char*)buffer;
+
+        for (size_t j = i; j > 0; j--)
+            stream << " " << std::hex << std::setfill('0') << std::setw(2) << 
(unsigned)*p++;
+
+#ifdef HLATYPES_IEEE1516_DISPLAYPRINTABLE
+        for(size_t j = cBytesPerLine - i; j > 0; j--)
+            stream << "   ";
+
+        stream << "   ";
+
+        p = (const unsigned char*)buffer;
+        for (size_t j = i; j > 0; j--) {
+            char ch = *p++;
+            stream << (isprint(ch) ? ch : ' ');
+        }
+#endif
+        stream << std::endl;
+        buffer = (const unsigned char*)buffer + i;
+        length -= i;
+        offset += i;
+    }
+
+    return stream;
+}
+
+} // namespace libhla
+
+// $Id: HLAbuffer.cc,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+

Index: HLAbuffer.hh
===================================================================
RCS file: HLAbuffer.hh
diff -N HLAbuffer.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAbuffer.hh        2 Aug 2008 14:03:14 -0000       1.1
@@ -0,0 +1,157 @@
+// ----------------------------------------------------------------------------
+// HLAbuffer.hh - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAbuffer.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#ifndef _HLATYPES_BUFFER_HH
+#define _HLATYPES_BUFFER_HH
+
+#include <iostream>
+#include <map>
+#include <stdexcept>
+
+#ifdef _MSC_VER
+typedef unsigned __int64  uint64_t;
+typedef __int64           int64_t;
+typedef unsigned __int32  uint32_t;
+typedef __int32           int32_t;
+typedef unsigned __int16  uint16_t;
+typedef __int16           int16_t;
+typedef unsigned __int8   uint8_t;
+typedef __int8            int8_t;
+#else
+#include <stdint.h>
+#endif
+
+namespace libhla {
+
+std::ostream& __print_buffer(std::ostream& stream, const void *buffer, size_t 
length);
+
+/* Caution:
+ * This implementation assumes that there are no compiler-generated data in
+ * the heap memory allocated for the __HLAbuffer struct.
+ * All structures must have no virtual functions and no non-static members.
+ */
+
+class __HLAbuffer
+{
+private:
+    // static buffer for all instantiations of the HLAdata template
+    // indexed by pointers after the last element, the end() pointers
+    typedef std::map<char*,__HLAbuffer*> BufferList;
+    static BufferList gBuffers;
+
+public:
+    char *mBegin;
+    size_t mCapacity;
+    // no automatic free() and realloc() for user allocated memory
+    bool mUserAllocated;
+    // parameters used during dynamic resizing
+    const void* mShakeThat;
+    int mShakeValue;
+
+    __HLAbuffer(size_t capacity)
+     : mUserAllocated(false), mShakeThat(NULL)
+    {
+        // exponential growth: capacity *= 1.5
+        mCapacity = (size_t)(capacity*1.5);
+        mBegin = (char*)calloc(1, mCapacity);
+        // store "this" to a global table
+        gBuffers[mBegin + mCapacity] = this;
+    }
+
+    __HLAbuffer(void *begin, size_t capacity)
+      : mBegin((char*)begin), mCapacity(capacity), mUserAllocated(true), 
mShakeThat(NULL)
+    {
+        // store "this" to a global table
+        gBuffers[mBegin + mCapacity] = this;
+    }
+
+    virtual ~__HLAbuffer()
+    {
+        if (!mUserAllocated)
+            free(mBegin);
+        // remove "this" from the global table
+        gBuffers.erase(__buffer_iterator(mBegin));
+    }
+
+    void __exchange_buffers(__HLAbuffer& newBuffer)
+    {
+        char* oldBegin = mBegin;
+        size_t oldCapacity = mCapacity;
+
+        mBegin = newBuffer.mBegin;
+        mCapacity = newBuffer.mCapacity;
+        gBuffers[mBegin + mCapacity] = this; // update
+
+        newBuffer.mBegin = oldBegin;
+        newBuffer.mCapacity = oldCapacity;
+        gBuffers[oldBegin + oldCapacity] = &newBuffer; // update
+    }
+
+    static BufferList::iterator __buffer_iterator(const void* __this)
+    {
+        // find the first pointer not less than "this", what is the end() 
pointer
+        BufferList::iterator result = gBuffers.lower_bound((char*)__this);
+        if (result == gBuffers.end())
+            throw std::runtime_error("HLAdata: bad pointer");
+        return result;
+    }
+
+    static __HLAbuffer& __buffer(const void* __this)
+    { return *(__buffer_iterator(__this)->second); }
+
+#ifndef NDEBUG
+    static void __check_memory(const void* __this, size_t size)
+    {
+        const __HLAbuffer& buffer = __buffer(__this);
+        if ((char*)__this + size > (char*)buffer.mBegin + buffer.mCapacity)
+            throw std::length_error("HLAdata: data buffer overflow");
+    }
+#endif
+
+    virtual const size_t size() const = 0;
+    virtual void __shake(const void* __that, int value, long resize) = 0;
+
+    static void shake(const void* __that, int value, long resize)
+    { __buffer(__that).__shake(__that, value, resize); }
+
+    const char* data() const
+    { return mBegin; }
+
+    std::ostream& print(std::ostream& stream)
+    {
+#ifndef NDEBUG
+        __check_memory(mBegin, size());
+#endif
+        return __print_buffer(stream, mBegin, size());
+    }
+};
+
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+/* Calculate the smallest nonnegative value of P that satisfies the following
+ * formula: (offset+size+P) mod boundary = 0
+ */
+inline size_t __padding(size_t size, size_t boundary)
+{ return boundary - ((size-1)%boundary + 1); }
+
+} // namespace libhla
+
+#endif // _HLATYPES_BUFFER_HH
+
+// $Id: HLAbuffer.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+

Index: HLAenumeratedType.hh
===================================================================
RCS file: HLAenumeratedType.hh
diff -N HLAenumeratedType.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAenumeratedType.hh        2 Aug 2008 14:03:14 -0000       1.1
@@ -0,0 +1,94 @@
+// ----------------------------------------------------------------------------
+// HLAenumeratedType.hh - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAenumeratedType.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#ifndef _HLATYPES_ENUMERATEDTYPE_HH
+#define _HLATYPES_ENUMERATEDTYPE_HH
+
+namespace libhla {
+
+/* HLAenumeratedType<ENUMERATION, REPRESENTATION>
+ * defines an user-convenient ENUMERATION stored using given REPRESENTATION.
+ *
+ * The data can be accessed in an usual way.
+ *
+ * Some models may use one enumerated value in multiple enumerations. To avoid
+ * name collisions it's recommended to put the ENUMERATION in an individual 
namespace.
+ *
+ * For example:
+ * +------------+----------------+------------+--------+-----------+
+ * | Name       | Representation | Enumerator | Values | Semantics |
+ * +------------+----------------+------------+--------+-----------+
+ * |            |                | HLAfalse   | 0      |           |
+ * | HLAboolean | HLAinteger32BE +------------+--------+-----------+
+ * |            |                | HLAfalse   | 1      |           |
+ * +------------+----------------+------------+--------+-----------+
+ * 
+ * namespace __HLAboolean {
+ * enum __enum {
+ *   HLAfalse = 0,
+ *   HLAtrue = 1
+ * };
+ * }
+ * typedef HLAenumeratedType<__HLAboolean::__enum, HLAinteger32BE> HLAboolean;
+ * HLAdata<HLAboolean> value;
+ *
+ * value = HLAtrue;
+ */
+
+//! HLA enumerated type, enumeration <E> with representation <R>.
+template<class E, class R>
+struct HLAenumeratedType
+{
+    HLAenumeratedType& operator = (const E& data)
+    {
+        *(R*)this = data;
+        return *this;
+    }
+
+    HLAenumeratedType& operator = (const int& data)
+    {
+        *(R*)this = data;
+        return *this;
+    }
+
+    operator E() const
+    {
+        int result = *(R*)this;
+        return (E)result;
+    }
+
+    operator int() const
+    { return *(R*)this; }
+
+    static const size_t emptysizeof()
+    { return R::emptysizeof(); }
+
+    static const size_t __sizeof()
+    { return R::__sizeof(); }
+
+    void copy(void* source)
+    { ((R*)this)->copy(source); }
+
+    static const size_t m_octetBoundary = R::m_octetBoundary;
+    static const bool m_isVariable = false;
+};
+
+} // namespace libhla
+
+#endif // _HLATYPES_ENUMERATEDTYPE_HH
+
+// $Id: HLAenumeratedType.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+

Index: HLAfixedArray.hh
===================================================================
RCS file: HLAfixedArray.hh
diff -N HLAfixedArray.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAfixedArray.hh    2 Aug 2008 14:03:14 -0000       1.1
@@ -0,0 +1,154 @@
+// ----------------------------------------------------------------------------
+// HLAfixedArray.hh - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAfixedArray.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#ifndef _HLATYPES_FIXEDARRAY_HH
+#define _HLATYPES_FIXEDARRAY_HH
+
+#include <stdexcept>
+
+namespace libhla {
+
+/* HLAfixedArray<DATATYPE, NUMBER>
+ * defines a fixed array of NUMBER elements of type DATATYPE.
+ *
+ * The data can be accessed in an usual way.
+ *
+ * For example:
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | Name        | Element type   | Cardinality | Encoding        | Semantics |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | Coordinates | HLAinteger32BE | 3           | HLAfixedArray   |           |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ *
+ * typedef HLAfixedArray<HLAinteger32BE,3> Coordinates;
+ * HLAdata<Coordinates> value;
+ *
+ * (*value)[0] = 100;
+ * (*value)[1] = 200;
+ */
+
+//! Fixed array of <N> elements of type <M>
+template<class M, int N, bool hasVariable = M::m_isVariable>
+struct HLAfixedArray;
+
+template<class M, int N, bool hasVariable>
+std::ostream& PrintBuffer(std::ostream& stream, 
HLAfixedArray<M,N,hasVariable>& buffer)
+{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
+
+// Fixed array optimized for fixed-size elements
+// note: this is the most efficient data type
+template<class M, int N>
+struct HLAfixedArray<M, N, false>
+{
+    static const size_t size()
+    { return N; }
+
+    static const size_t offset(long i)
+    { return i*(M::__sizeof() + __padding(M::__sizeof(), M::m_octetBoundary)); 
}
+
+    M& operator[](long i) const
+    {
+        if (i < 0 || i >= (long)size())
+            throw std::out_of_range("HLAfixedArray: index out of range");
+        return *(M*)((char*)this + offset(i));
+    }
+
+    static const size_t emptysizeof()
+    { return __sizeof(); }
+
+    // Padding shall not be added after the last element of the array.
+    static const size_t __sizeof()
+    { return offset(N-1) + M::__sizeof(); }
+
+    void copy(void* source)
+    {
+        size_t offs = 0;
+        // copy all elements of the structure
+        for (size_t i = 0; i < N; i++) {
+            ((M*)((char*)this + offs))->copy((char*)source + offs);
+            offs += M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary);
+        }
+    }
+
+    static const size_t m_octetBoundary = M::m_octetBoundary;
+    static const bool m_isVariable = false; // fixed-size array of fixed-size 
elements
+};
+
+// Generic fixed array, supports variable-size elements
+template<class M, int N>
+struct HLAfixedArray<M, N, true>
+{
+    static const size_t size()
+    { return N; }
+
+    const size_t offset(long i) const
+    {
+        size_t offs = 0;
+        // count every member, the elements may be variable-sized
+        for (long j=0; j<i; j++) {
+            offs += ((M*)((char*)this + offs))->__sizeof();
+            offs += __padding(offs, M::m_octetBoundary);
+        }
+        return offs;
+    }
+
+    M& operator[](long i) const
+    {
+        if (i >= size())
+            throw std::out_of_range("HLAfixedArray: index out of range");
+        return *(M*)((char*)this + offset(i));
+    }
+
+    static const size_t emptysizeof()
+    {
+        size_t size = N*M::emptysizeof();
+        // padding shall not be added after the last element of the array
+        if(N > 1)
+            size += (N-1)*__padding(M::emptysizeof(), M::m_octetBoundary);
+        return size;
+    }
+
+    const size_t __sizeof() const
+    {
+        size_t offs = offset(N-1);
+        return offs + ((M*)((char*)this + offs))->__sizeof();
+    }
+
+    void copy(void* source)
+    {
+        size_t offsD = 0;
+        size_t offsS = 0;
+        // copy all elements of the structure, the elements may be 
variable-sized
+        for (size_t i = 0; i < N; i++) {
+            ((M*)((char*)this + offsD))->copy((char*)source + offsS);
+
+            offsD += ((M*)((char*)this + offsD))->__sizeof(); // may differ 
from source size
+            offsD += __padding(offsD, M::m_octetBoundary);
+            offsS += ((M*)((char*)source + offsS))->__sizeof();
+            offsS += __padding(offsS, M::m_octetBoundary);
+        }
+    }
+
+    static const size_t m_octetBoundary = M::m_octetBoundary;
+    static const bool m_isVariable = true; // variable-sized elements
+};
+
+} // namespace libhla
+
+#endif // _HLATYPES_FIXEDARRAY_HH
+
+// $Id: HLAfixedArray.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+

Index: HLAfixedRecord.hh
===================================================================
RCS file: HLAfixedRecord.hh
diff -N HLAfixedRecord.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAfixedRecord.hh   2 Aug 2008 14:03:14 -0000       1.1
@@ -0,0 +1,271 @@
+// ----------------------------------------------------------------------------
+// HLAfixedRecord.hh - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAfixedRecord.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#ifndef _HLATYPES_FIXEDRECORD_HH
+#define _HLATYPES_FIXEDRECORD_HH
+
+#include <HLAbuffer.hh>
+
+namespace libhla {
+
+/* HLAfixedRecord<
+ *   HLAfixedField<INDEX1, DATATYPE1,
+ *   HLAfixedField<INDEX2, DATATYPE2,
+ *   ...
+ *   > ... > TYPENAME;
+ * defines an ordered sequence of DATATYPE entries.
+ *
+ * The data can be accessed using the field<INDEX>() function. The INDEX is a 
logical
+ * identifier only. The data are stored in the declaration order.
+ *
+ * For example:
+ * 
+-------------+------------------------------------+----------------+-----------+
+ * |             | Field                              |                |       
    |
+ * | Record name +---------+--------------+-----------+ Encoding       | 
Semantics |
+ * |             | Name    | Type         | Semantics |                |       
    |
+ * 
+-------------+---------+--------------+-----------+----------------+-----------+
+ * |             | FIELD_X | HLAfloat32LE |           |                |       
    |
+ * |             +---------+--------------+-----------+                |       
    |
+ * | Coordinates | FIELD_X | HLAfloat32LE |           | HLAfixedRecord |       
    |
+ * |             +---------+--------------+-----------+                |       
    |
+ * |             | FIELD_X | HLAfloat32LE |           |                |       
    |
+ * 
+-------------+---------+--------------+-----------+----------------+-----------+
+ * 
+ * enum {
+ *   FIELD_X = 0,
+ *   FIELD_Y,
+ *   FIELD_Z
+ * };
+ * typedef HLAfixedRecord<
+ *   HLAfixedField<FIELD_X, HLAfloat32LE,
+ *   HLAfixedField<FIELD_Y, HLAfloat32LE,
+ *   HLAfixedField<FIELD_Z, HLAfloat32LE
+ *   > > > > Coordinates;
+ * HLAdata<Coordinates> value;
+ *
+ * value->field<FIELD_X>() = 3.14;
+ * value->field<FIELD_Y>() = 6.28;
+ * value->field<FIELD_Z>() = 9.42;
+ */
+
+//! Fixed record of fields <R>
+template<class R, bool hasVariable = R::m_isVariable>
+struct HLAfixedRecord;
+
+template<class R, bool V>
+std::ostream& PrintBuffer(std::ostream& stream, HLAfixedRecord<R,V>& buffer)
+{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
+
+//! Returns <i>th field of the HLAfixedField <L>
+template<class R, int i> struct __FieldAt;
+
+// Fixed record optimized for fixed-size fields
+template<class R>
+struct HLAfixedRecord<R, false>
+{
+    template <int i>
+    typename __FieldAt<R,i>::Type& field() const
+    { return *(typename __FieldAt<R,i>::Type*)((char*)this + 
R::field_offsetof(i)); }
+
+    static const size_t emptysizeof()
+    { return R::emptysizeof(); }
+
+    static const size_t __sizeof()
+    { return R::__sizeof(); }
+
+    void copy(void* source)
+    { ((R*)this)->copy(source); }
+
+    static const size_t m_octetBoundary = R::m_octetBoundary;
+    static const bool m_isVariable = false; // fixed-sized fields
+};
+
+// Generic fixed record, supports variable-size fields
+template<class R>
+struct HLAfixedRecord<R, true>
+{
+    template <int i>
+    typename __FieldAt<R,i>::Type& field() const
+    { return *(typename __FieldAt<R,i>::Type*)((char*)this + 
((R*)this)->field_offsetof(i)); }
+
+    static const size_t emptysizeof()
+    { return R::emptysizeof(); }
+
+    const size_t __sizeof()
+    { return ((R*)this)->__sizeof(); }
+
+    void copy(void* source)
+    { ((R*)this)->copy(source); }
+
+    static const size_t m_octetBoundary = R::m_octetBoundary;
+    static const bool m_isVariable = true; // variable-sized fields
+};
+
+struct HLAfixedEnd;
+
+//! Record at index <E>, field of type <M>, followed by HLAfixedField <N>
+// note: <E> must be "int" to enable implicit conversion from/to enum types
+template<int E, class M, class N = HLAfixedEnd, bool hasVariable = 
M::m_isVariable || N::m_isVariable>
+struct HLAfixedField;
+
+// List of fixed-size fields
+template<int E, class M, class N>
+struct HLAfixedField<E, M, N, false>
+{
+    static const size_t field_offsetof(int d, size_t offs = 0)
+    {
+        if (d != E) {
+            size_t size = M::__sizeof();
+            size += __padding(offs+size, N::memberBoundary);
+            return N::field_offsetof(d, offs+size);
+        }
+        else
+            return offs;
+    }
+
+    static const size_t memberBoundary = M::m_octetBoundary;
+
+    static const size_t emptysizeof(size_t offs = 0)
+    { return __sizeof(offs); }
+
+    // Padding shall not be added after the last element of the array.
+    static const size_t __sizeof(size_t offs = 0)
+    {
+        size_t size = M::__sizeof();
+        // if not reached HLAvariantEnd
+        if (N::memberBoundary) {
+            size += __padding(offs+size, N::memberBoundary);
+            return N::__sizeof(offs+size);
+        }
+        else
+            return offs+size;
+    }
+
+    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
+    {
+        ((M*)this)->copy(source);
+        if (N::memberBoundary) {
+            offsD += M::__sizeof();
+            offsD += __padding(offsD, N::memberBoundary);
+            offsS += M::__sizeof();
+            offsS += __padding(offsS, N::memberBoundary);
+            ((N*)((char*)this + M::__sizeof()))->copy((char*)source + 
M::__sizeof(), offsD, offsS);
+        }
+    }
+
+    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
+    static const bool m_isVariable = false; // fixed-sized fields
+};
+
+// List containg variable-size fields
+template<int E, class M, class N>
+struct HLAfixedField<E, M, N, true>
+{
+    const size_t field_offsetof(int d, size_t offs = 0) const
+    {
+        if (d != E) {
+            size_t size = ((M*)this)->__sizeof();
+            size += __padding(offs+size, N::memberBoundary);
+            return ((N*)((char*)this + size))->field_offsetof(d, offs+size);
+        }
+        else
+            return offs;
+    }
+
+    static const size_t memberBoundary = M::m_octetBoundary;
+
+    static const size_t emptysizeof(size_t offs = 0)
+    {
+        size_t size = M::emptysizeof();
+        // if not reached HLAvariantEnd
+        if (N::memberBoundary) {
+            size += __padding(offs+size, N::memberBoundary);
+            return N::emptysizeof(offs+size);
+        }
+        else
+            return offs+size;
+    }
+
+    // Padding shall not be added after the last element of the array.
+    const size_t __sizeof(size_t offs = 0) const
+    {
+      size_t size = ((M*)this)->__sizeof();
+      // if not reached HLAvariantEnd
+      if (N::memberBoundary) {
+          size += __padding(offs+size, N::memberBoundary);
+          return ((N*)((char*)this + size))->__sizeof(offs+size);
+      }
+      else
+          return offs+size;
+    }
+
+    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
+    {
+        ((M*)this)->copy(source);
+        if (N::memberBoundary) {
+            size_t sizeD = ((M*)this)->__sizeof(); // may differ from source 
size
+            sizeD += __padding(offsD+sizeD, N::memberBoundary);
+            size_t sizeS = ((M*)source)->__sizeof();
+            sizeS += __padding(offsS+sizeS, N::memberBoundary);
+            ((N*)((char*)this + sizeD))->copy((char*)source + sizeS, 
offsD+sizeD, offsS+sizeS);
+        }
+    }
+
+    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
+    static const bool m_isVariable = true; // variable-sized fields
+};
+
+//! Defines a last field in the fixed record
+struct HLAfixedEnd
+{
+    static const size_t field_offsetof(int d, size_t offs = 0)
+    { return offs; }
+
+    static const size_t memberBoundary = 0;
+    static const size_t emptysizeof(size_t offs = 0)
+    { return offs; }
+    static const size_t __sizeof(size_t offs = 0)
+    { return offs; }
+    void copy(void* source, size_t offsD = 0, size_t offsS = 0)
+    { /* nop */ }
+
+    static const size_t m_octetBoundary = 0;
+    static const bool m_isVariable = false;
+};
+
+template<bool C, class Then, class Else>
+struct __fixedRecord_if
+{ typedef Then X; };
+
+template<class Then, class Else>
+struct __fixedRecord_if<false, Then, Else>
+{ typedef Else X; };
+
+template<int E, class M, class N, bool V, int d>
+struct __FieldAt<HLAfixedField<E, M, N, V>, d>
+{ typedef typename __fixedRecord_if<d==E, M, typename __FieldAt<N,d>::Type>::X 
Type; };
+
+// returned when no HLAfixedField has a given index(i)
+template<int d>
+struct __FieldAt<HLAfixedEnd, d>
+{ typedef HLAfixedEnd Type; };
+
+} // namespace libhla
+
+#endif // _HLATYPES_FIXEDRECORD_HH
+
+// $Id: HLAfixedRecord.hh,v 1.1 2008/08/02 14:03:14 gotthardp Exp $
+

Index: HLAvariableArray.hh
===================================================================
RCS file: HLAvariableArray.hh
diff -N HLAvariableArray.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAvariableArray.hh 2 Aug 2008 14:03:15 -0000       1.1
@@ -0,0 +1,219 @@
+// ----------------------------------------------------------------------------
+// HLAvariableArray.hh - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAvariableArray.hh,v 1.1 2008/08/02 14:03:15 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#ifndef _HLATYPES_VARIABLEARRAY_HH
+#define _HLATYPES_VARIABLEARRAY_HH
+
+#include <HLAbuffer.hh>
+#include <HLAbasicType.hh>
+
+namespace libhla {
+
+/* HLAvariableArray<DATATYPE>
+ * defines an array of a variable number of DATATYPE elements.
+ *
+ * The size() member must be set before accessing the data. No data are moved
+ * when the size() is changed.
+ *
+ * For example:
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | Name        | Element type   | Cardinality | Encoding        | Semantics |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ * | List        | HLAinteger32BE | Dynamic     | HLAvaribleArray |           |
+ * +-------------+----------------+-------------+-----------------+-----------+
+ *
+ * typedef HLAvariableArray<HLAinteger32BE> List;
+ * HLAdata<List> value;
+ *
+ * (*value).set_size(2);
+ * (*value)[0] = 100;
+ * (*value)[1] = 200;
+ */
+
+//! Variable array of type <M>
+template<class M, bool hasVariable = M::m_isVariable>
+struct HLAvariableArray;
+
+template<class M, bool hasVariable>
+std::ostream& PrintBuffer(std::ostream& stream, 
HLAvariableArray<M,hasVariable>& buffer)
+{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
+
+// Variable array optimized for fixed-size elements
+template<class M>
+struct HLAvariableArray<M, false>
+{
+    //! Get/Set array size, without memory management
+    /* This function assumes no data are stored in the buffer after this array.
+     * You may want to use set_size() instead.
+     */
+    HLAinteger32BE& size() const
+    { return (HLAinteger32BE&)*this; }
+
+    //! Set array size, with memory management
+    void set_size(long i)
+    {
+        if (i == size())
+            return; // no change
+
+        // as changing the array size may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, i,
+            (i-size())*(long)(M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary)));
+    }
+
+    static const size_t offset(long i)
+    { return emptysizeof() + i*(M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary)); }
+
+    M& operator[](long i) const
+    {
+        if (i >= size())
+            throw std::out_of_range("HLAvariableArray: index out of range");
+        return *(M*)((char*)this + offset(i));
+    }
+
+    static const size_t emptysizeof()
+    { return HLAinteger32BE::__sizeof() + 
__padding(HLAinteger32BE::__sizeof(), M::m_octetBoundary); }
+
+    // Padding shall not be added after the last element of the array.
+    const size_t __sizeof() const
+    {
+        if (size() > 0)
+            return offset(size()-1) + M::__sizeof();
+        else
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        int N = *(HLAinteger32BE*)source;
+        int toCopy;
+
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(HLAinteger32BE*)this = buffer.mShakeValue;
+            toCopy = std::min(N, buffer.mShakeValue); // number of elements to 
copy
+        }
+        else {
+            *(HLAinteger32BE*)this = N;
+            toCopy = N; // copy all elements
+        }
+
+        size_t offs = emptysizeof();
+        // copy all elements of the structure, the elements may be 
variable-sized
+        for (int i = 0; i < toCopy; i++) {
+            ((M*)((char*)this + offs))->copy((char*)source + offs);
+            offs += M::__sizeof() + __padding(M::__sizeof(), 
M::m_octetBoundary);
+        }
+    }
+
+    static const size_t m_octetBoundary =
+        MAX(HLAinteger32BE::m_octetBoundary, M::m_octetBoundary);
+    static const bool m_isVariable = true; // variable-sized array
+};
+
+// Generic variable array, supports variable-size elements
+// note: this is the less efficient data type
+template<class M>
+struct HLAvariableArray<M, true>
+{
+    //! Get/Set array size, without memory management
+    /* This function assumes no data are stored in the buffer after this array.
+     * You may want to use set_size() instead.
+     */
+    HLAinteger32BE& size() const
+    { return (HLAinteger32BE&)*this; }
+
+    //! Set array size, with memory management
+    void set_size(long i)
+    {
+        if (i == size())
+            return; // no change
+
+        // as changing the array size may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, i,
+            (i-size())*(long)(M::emptysizeof() + __padding(M::emptysizeof(), 
M::m_octetBoundary)));
+    }
+
+    const size_t offset(long i) const
+    {
+        size_t offs = emptysizeof();
+        // count every member, the elements may be variable-sized
+        for (long j=0; j<i; j++) {
+            offs += ((M*)((char*)this + offs))->__sizeof();
+            offs += __padding(offs, M::m_octetBoundary);
+        }
+        return offs;
+    }
+
+    M& operator[](long i) const
+    {
+        if (i >= size())
+            throw std::out_of_range("HLAvariableArray: index out of range");
+        return *(M*)((char*)this + offset(i));
+    }
+
+    static const size_t emptysizeof()
+    { return HLAinteger32BE::__sizeof() + 
__padding(HLAinteger32BE::__sizeof(), M::m_octetBoundary); }
+
+    // Padding shall not be added after the last element of the array.
+    const size_t __sizeof() const
+    {
+        if (size() > 0) {
+            size_t offs = offset(size()-1);
+            return offs + ((M*)((char*)this + offs))->__sizeof();
+        }
+        else
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        int N = *(HLAinteger32BE*)source;
+        int toCopy;
+
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(HLAinteger32BE*)this = buffer.mShakeValue;
+            toCopy = std::min(N, buffer.mShakeValue); // number of elements to 
copy
+        }
+        else {
+            *(HLAinteger32BE*)this = N;
+            toCopy = N; // copy all elements
+        }
+
+        size_t offsD = emptysizeof();
+        size_t offsS = emptysizeof();
+        // copy all elements of the structure, the elements may be 
variable-sized
+        for (int i = 0; i < toCopy; i++) {
+            ((M*)((char*)this + offsD))->copy((char*)source + offsS);
+
+            offsD += ((M*)((char*)this + offsD))->__sizeof(); // may differ 
from source size
+            offsD += __padding(offsD, M::m_octetBoundary);
+            offsS += ((M*)((char*)source + offsS))->__sizeof();
+            offsS += __padding(offsS, M::m_octetBoundary);
+        }
+    }
+
+    static const size_t m_octetBoundary =
+        MAX(HLAinteger32BE::m_octetBoundary, M::m_octetBoundary);
+    static const bool m_isVariable = true; // variable-size array of 
variable-size elements
+};
+
+} // namespace libhla
+
+#endif // _HLATYPES_VARIABLEARRAY_HH
+
+// $Id: HLAvariableArray.hh,v 1.1 2008/08/02 14:03:15 gotthardp Exp $
+

Index: HLAvariantRecord.hh
===================================================================
RCS file: HLAvariantRecord.hh
diff -N HLAvariantRecord.hh
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ HLAvariantRecord.hh 2 Aug 2008 14:03:15 -0000       1.1
@@ -0,0 +1,400 @@
+// ----------------------------------------------------------------------------
+// HLAvariantRecord.hh - IEEE 1516.2 compliant datatypes
+// Copyright (C) 2008  Petr Gotthard <address@hidden>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License version 2.1, as published by the Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// $Id: HLAvariantRecord.hh,v 1.1 2008/08/02 14:03:15 gotthardp Exp $
+// ----------------------------------------------------------------------------
+
+#ifndef _HLATYPES_VARIANTRECORD_HH
+#define _HLATYPES_VARIANTRECORD_HH
+
+#include <HLAbuffer.hh>
+
+namespace libhla {
+
+/* HLAvariantRecord<
+ *   INDEX, DATATYPE,
+ *   HLAvariantField<ENUMERATORS1, INDEX1, DATATYPE1,
+ *   HLAvariantField<ENUMERATORS2, INDEX2, DATATYPE2,
+ *   ...
+ *   > ... > TYPENAME;
+ * defines an ordered sequence of DATATYPE entries.
+ *
+ * The data can be accessed using the field<INDEX>() function. The INDEX is a 
logical
+ * identifier only. 
+ * The first field is a discriminant. It is followed by an alternative whose
+ * ENUMERATORS match the discriminant value.
+ *
+ * For example:
+ * 
+-------------+-------------------------------+------------------------------------+------------------+-----------+
+ * |             | Discriminant                  | Alternative                 
       |                  |           |
+ * | Record name 
+------+-----------+------------+---------+--------------+-----------+ Encoding 
        | Semantics |
+ * |             | Name | Type      | Enumerator | Name    | Type         | 
Semantics |                  |           |
+ * 
+-------------+------+-----------+------------+---------+--------------+-----------+------------------+-----------+
+ * |             |      |           | AXIS_X     | FIELD_X | HLAfloat32LE |    
       |                  |           |
+ * | Coordinates | TYPE | TypesEnum 
+------------+---------+--------------+-----------+ HLAvariantRecord |          
 |
+ * |             |      |           | AXIS_Y     | FIELD_Y | HLAfloat32LE |    
       |                  |           |
+ * 
+-------------+------+-----------+------------+---------+--------------+-----------+------------------+-----------+
+ * 
+ * namespace __Fields {
+ * enum __enum {
+ *   TYPE = 0,
+ *   FIELD_X = 101,
+ *   FIELD_Y = 102
+ * };
+ * }
+ * typedef HLAenumeratedType<__Fields::__enum, HLAinteger32BE> Fields;
+ * typedef HLAvariantRecord<
+ *   __Fields::TYPE, TypesEnum,
+ *   HLAvariantField<HLAsetValue<AXIS_X>, __Fields::FIELD_X, HLAfloat32LE,
+ *   HLAvariantField<HLAsetValue<AXIS_Y>, __Fields::FIELD_Y, HLAfloat32LE
+ *   > > > Coordinates;
+ * HLAdata<Coordinates> value;
+ *
+ * value->set_discriminant(AXIS_X);
+ * value->field<__Fields::FIELD_X>() = 3.14;
+ */
+
+//! Variant record of discriminant <D> at index <E> and alternatives <R>
+template<int DE, class DM, class R, bool hasVariable = R::m_isVariable>
+struct HLAvariantRecord;
+
+template<int DE, class DM, class R, bool V>
+std::ostream& PrintBuffer(std::ostream& stream, HLAvariantRecord<DE,DM,R,V>& 
buffer)
+{ return __print_buffer(stream, (void*)&buffer, buffer.__sizeof()); }
+
+//! Returns <i>th field of the HLAfixedField <L>
+template<class R, int i> struct __FieldAt;
+
+//! Returns the discriminant, or a <i>th field of the HLAvariantField <R>
+template<int DE, class DM, class R, int e>
+struct __DiscriminantOrFieldAt;
+
+// Variant record optimized for fixed-size fields
+template<int DE, class DM, class R>
+struct HLAvariantRecord<DE, DM, R, false>
+{
+    //! Get/Set the discriminant, without memory management
+    /* This function assumes no data are stored in the buffer after this array.
+     * You may want to use set_discriminant() instead.
+     */
+    DM& discriminant() const
+    { return *(DM*)this; }
+
+    //! Set the discriminant, with memory management
+    void set_discriminant(int d)
+    {
+        if (d == (int)discriminant())
+            return; // no change
+
+        // as changing the discriminant may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, d, (long)R::field_emptysizeof(d));
+    }
+
+    template <int e>
+    typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type& field() const
+    {
+        // return the discriminant
+        if (e == DE)
+            return *(typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type*)this;
+
+        if (e != R::get_field(discriminant()))
+            throw std::out_of_range("HLAvariantRecord: wrong discriminant");
+        // return one of the alternatives
+        return *(typename 
__DiscriminantOrFieldAt<DE,DM,R,e>::Type*)((char*)this + emptysizeof());
+    }
+
+    static const size_t emptysizeof()
+    { return DM::__sizeof() + __padding(DM::__sizeof(), R::m_octetBoundary); }
+
+    const size_t __sizeof() const
+    {
+        if (R::has_field(discriminant()))
+            return emptysizeof() + R::field_sizeof(discriminant());
+        else
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(DM*)this = buffer.mShakeValue;
+            // switching variant: content is removed
+        }
+        else {
+            int d = *(DM*)source;
+            // not switching variant: copy the content
+            *(DM*)this = d;
+            ((R*)this)->copy(d, (char*)source + emptysizeof());
+        }
+    }
+
+    static const size_t m_octetBoundary = MAX(DM::m_octetBoundary, 
R::m_octetBoundary);
+    static const bool m_isVariable = true; // variant record of fixed-size 
fields
+};
+
+// Generic variant record, supports variable-size fields
+template<int DE, class DM, class R>
+struct HLAvariantRecord<DE, DM, R, true>
+{
+    //! Get/Set the discriminant, without memory management
+    /* This function assumes no data are stored in the buffer after this array.
+     * You may want to use set_discriminant() instead.
+     */
+    DM& discriminant() const
+    { return *(DM*)this; }
+
+    //! Set the discriminant, with memory management
+    void set_discriminant(int d)
+    {
+        if (d == (int)discriminant())
+            return; // no change
+
+        // as changing the discriminant may impact padding, the whole buffer 
needs to be reorganized
+        __HLAbuffer::shake(this, d, (long)R::field_emptysizeof(d));
+    }
+
+    template <int e>
+    typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type& field() const
+    {
+        // return the discriminant
+        if (e == DE)
+            return *(typename __DiscriminantOrFieldAt<DE,DM,R,e>::Type*)this;
+
+        if (e != R::get_field(discriminant()))
+            throw std::out_of_range("HLAvariantRecord: wrong discriminant");
+        // return one of the alternatives
+        return *(typename 
__DiscriminantOrFieldAt<DE,DM,R,e>::Type*)((char*)this + emptysizeof());
+    }
+
+    static const size_t emptysizeof()
+    { return DM::__sizeof() + __padding(DM::__sizeof(), R::m_octetBoundary); }
+
+    const size_t __sizeof() const
+    {
+        if (R::has_field(discriminant()))
+            return emptysizeof() + ((R*)((char*)this + 
emptysizeof()))->field_sizeof(discriminant());
+        else
+            return emptysizeof();
+    }
+
+    void copy(void* source)
+    {
+        __HLAbuffer& buffer = __HLAbuffer::__buffer(this);
+        if(source == buffer.mShakeThat) {
+            *(DM*)this = buffer.mShakeValue;
+            // switching variant: content is removed
+        }
+        else {
+            int d = *(DM*)source;
+            // not switching variant: copy the content
+            *(DM*)this = d;
+            ((R*)this)->copy(d, (char*)source + emptysizeof());
+        }
+    }
+
+    static const size_t m_octetBoundary = MAX(DM::m_octetBoundary, 
R::m_octetBoundary);
+    static const bool m_isVariable = true; // variant record of variable-sized 
fields
+};
+
+struct HLAsetEnd;
+
+//! Defines a value in an enumerator list; to be used with HLAvariantField
+template<int e, class N = HLAsetEnd>
+struct HLAsetValue
+{
+    static int includes(int i)
+    {
+        if (i == e)
+            return 1;
+        else
+            return N::includes(i);
+    }
+};
+
+//! Defines a range in an enumerator list
+template<int e1, int e2, class N = HLAsetEnd>
+struct HLAsetRange
+{
+    static int includes(int i)
+    {
+        if (e1 <= i && i <= e2)
+            return 1;
+        else
+            return N::includes(i);
+    }
+};
+
+//! Defines the "HLAother" symbol in an enumerator list
+template<class N = HLAsetEnd>
+struct HLAsetOther
+{
+    static int includes(int i)
+    { return 1; }
+};
+
+//! Defines the end of an enumerator list
+struct HLAsetEnd
+{
+    static int includes(int i)
+    { return 0; }
+};
+
+struct HLAvariantEnd;
+
+//! Record at index <E>, field of type <M>, followed by HLAvariantField <N>
+// note: <E> must be "int" to enable implicit conversion from/to enum types
+template<class D, int E, class M, class N = HLAvariantEnd, bool hasVariable = 
M::m_isVariable || N::m_isVariable>
+struct HLAvariantField;
+
+// List of fixed-size fields
+template<class D, int E, class M, class N>
+struct HLAvariantField<D, E, M, N, false>
+{
+    static bool has_field(int d)
+    {
+        if (D::includes(d))
+          return true; // found
+        else
+          return N::has_field(d); // continue searching
+    }
+
+    static int get_field(int d)
+    {
+        if (D::includes(d))
+            return E;
+        else
+            return N::get_field(d);
+    }
+
+    static const size_t field_emptysizeof(int e)
+    {
+        if (e == E)
+            return M::emptysizeof();
+        else
+            return N::field_emptysizeof(e);
+    }
+
+    static const size_t field_sizeof(int e)
+    {
+        if (e == E)
+            return M::__sizeof();
+        else
+            return N::field_sizeof(e);
+    }
+
+    void copy(int e, void* source)
+    {
+        if (e == E)
+            return ((M*)this)->copy(source);
+        else
+            return ((N*)this)->copy(e, source);
+    }
+
+    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
+    static const bool m_isVariable = false; // fixed-sized fields
+};
+
+// List containg variable-size fields
+template<class D, int E, class M, class N>
+struct HLAvariantField<D, E, M, N, true>
+{
+    static bool has_field(int d)
+    {
+        if (D::includes(d))
+          return true; // found
+        else
+          return N::has_field(d); // continue searching
+    }
+
+    static int get_field(int d)
+    {
+        if (D::includes(d))
+            return E;
+        else
+            return N::get_field(d);
+    }
+
+    static const size_t field_emptysizeof(int e)
+    {
+        if (e == E)
+            return M::emptysizeof();
+        else
+            return N::field_emptysizeof(e);
+    }
+
+    const size_t field_sizeof(int e) const
+    {
+        if (e == E)
+            return ((M*)this)->__sizeof();
+        else
+            return ((N*)this)->field_sizeof(e);
+    }
+
+    void copy(int e, void* source)
+    {
+        if (e == E)
+            return ((M*)this)->copy(source);
+        else
+            return ((N*)this)->copy(e, source);
+    }
+
+    static const size_t m_octetBoundary = MAX(M::m_octetBoundary, 
N::m_octetBoundary);
+    static const bool m_isVariable = true; // variable-sized fields
+};
+
+//! Defines a last field in the fixed record
+struct HLAvariantEnd
+{
+    static bool has_field(int d)
+    { return false; }
+    static int get_field(int d)
+    { throw std::out_of_range("HLAvariantRecord: unknown discriminant"); }
+    static const size_t field_emptysizeof(int e)
+    { return 0; }
+    static const size_t field_sizeof(int e)
+    { return 0; }
+    void copy(int e, void* source)
+    { /* nop */ }
+
+    static const size_t m_octetBoundary = 0;
+    static const bool m_isVariable = false;
+};
+
+template<bool C, class Then, class Else>
+struct __variantRecord_if
+{ typedef Then X; };
+
+template<class Then, class Else>
+struct __variantRecord_if<false, Then, Else>
+{ typedef Else X; };
+
+template<int DE, class DM, class R, int e>
+struct __DiscriminantOrFieldAt
+{ typedef typename __variantRecord_if<e==DE, DM, typename 
__FieldAt<R,e>::Type>::X Type; }; 
+
+template<class D, int E, class M, class N, bool V, int e>
+struct __FieldAt<HLAvariantField<D,E,M,N,V>, e>
+{ typedef typename __variantRecord_if<e==E, M, typename 
__FieldAt<N,e>::Type>::X Type; }; 
+
+// returned when no HLAvariantField has a given index(i)
+template<int e>
+struct __FieldAt<HLAvariantEnd, e>
+{ typedef HLAvariantEnd Type; };
+
+} // namespace libhla
+
+#endif // _HLATYPES_VARIANTRECORD_HH
+
+// $Id: HLAvariantRecord.hh,v 1.1 2008/08/02 14:03:15 gotthardp Exp $
+

Index: HLAtypesIEEE1516.cc
===================================================================
RCS file: HLAtypesIEEE1516.cc
diff -N HLAtypesIEEE1516.cc
--- HLAtypesIEEE1516.cc 15 Jul 2008 10:54:11 -0000      1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,64 +0,0 @@
-// ----------------------------------------------------------------------------
-// HLAtypesIEEE1516.cc - IEEE 1516.2 compliant datatypes
-// Copyright (C) 2008  Petr Gotthard <address@hidden>
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License version 2.1, as published by the Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// $Id: HLAtypesIEEE1516.cc,v 1.1 2008/07/15 10:54:11 gotthardp Exp $
-// ----------------------------------------------------------------------------
-
-#include "HLAtypesIEEE1516.hh"
-
-// #define HLATYPES_IEEE1516_DISPLAYPRINTABLE
-
-namespace libhla {
-
-__HLAbuffer::BufferList __HLAbuffer::gBuffers;
-
-//! Print the physical data buffer (for debugging purposes only)
-std::ostream& __print_buffer(std::ostream& stream, const void *buffer, size_t 
length)
-{
-    static const size_t cBytesPerLine = 16;
-    size_t offset = 0;
-
-    while (length != 0) {
-        stream << std::hex << std::setfill('0') << std::setw(4) << 
(unsigned)offset << ": ";
-
-        size_t i = std::min(cBytesPerLine, length);
-        const unsigned char* p = (const unsigned char*)buffer;
-
-        for (size_t j = i; j > 0; j--)
-            stream << " " << std::hex << std::setfill('0') << std::setw(2) << 
(unsigned)*p++;
-
-#ifdef HLATYPES_IEEE1516_DISPLAYPRINTABLE
-        for(size_t j = cBytesPerLine - i; j > 0; j--)
-            stream << "   ";
-
-        stream << "   ";
-
-        p = (const unsigned char*)buffer;
-        for (size_t j = i; j > 0; j--) {
-            char ch = *p++;
-            stream << (isprint(ch) ? ch : ' ');
-        }
-#endif
-        stream << std::endl;
-        buffer = (const unsigned char*)buffer + i;
-        length -= i;
-        offset += i;
-    }
-
-    return stream;
-}
-
-} // namespace libhla
-
-// $Id: HLAtypesIEEE1516.cc,v 1.1 2008/07/15 10:54:11 gotthardp Exp $
-




reply via email to

[Prev in Thread] Current Thread [Next in Thread]