Module ddsl.xtypes

Datatypes in Lua.

Uses the ddsl core primitives to implement datatypes (a.k.a. xtypes) as defined by the OMG X-Types specification in Lua.

The datatypes are equivalent to those described by the X-Types specification. Thus, this module can serve as an alternative for defining types in Lua, instead of in IDL or XML.

A datatype is a blueprint for a data structure. Any number of data-objects or instances (a.k.a. xinstance) can be created from a datatype. Each instance is backed by the underlying datatype from which it was created. The datatype constraints are enforced on the instances---for example a struct instance can only have the fields defined in the struct datatype; sequence and array bounds are enforced. Furthermore, if the datatype structure changes, those changes are propagated to all the instances.

Operators to manipulate datatypes (i.e. structure) are also provided. Thus, for a struct datatype, new members can be added, existing ones can be removed or modified. Since every instance is backed by a datatype, any instance can be used as a handle to manipulate the underlying datatype. Changes are propagated to all the other instances, to ensure consistency.

Since every instance is backed by a datatype, a new instance can be created from any instance using new_instance. A datatype constructor returns a template instance (a.k.a. xtemplate) that can be used as cannonical instance to refer to the datatype.

Each field in the template instance is initialized to a flattened out accessor string that can be used retrive that field's value in some storage system. For example, the accessor strings can be directly used for data access in Lua scripts used with the RTI Connext DDS Prototyper (see Section 8.4, Data Access API in the RTI Connext DDS Prototyper Getting Started Guide).

General Syntax

Since ddsl does not impose any specific syntax on how datatypes are expressed in Lua, this module defines the syntax. The general syntax and patterns common to all datatypes are illsurated below.

local xtypes = require 'ddsl.xtypes'

-- create a datatype of kind 'kind' with the name 'MyType'
-- NOTE: mytype is the template instance for MyType (i.e. xtemplate)
local mytype = xtypes.<kind>{
   MyType = { <definition_syntax_for_kind> }
}


-- create an instance to use in user application code
local myinstance = xtypes.new_instance(mytype)

-- print the datatype underlying an instance
print(tostring(myinstance)) -- or simply
print(myinstance)


-- get the template instance
assert(xtypes.template(myinstance) == mytype)


-- print the kind of a datatype
-- NOTE: the kind is immutable, i.e. cannot be changed after creation
print(mytype[xtypes.KIND]())


-- get the name of a datatype
print(mytype[xtypes.NAME])

-- set the name of a datatype
mytype[xtypes.NAME] = 'MyTypeNewName'


-- get the enclosing namespace of a datatype
print(mytype[xtypes.NS])

-- set the enclosing namespace of a datatype
mytype[xtypes.NS] = YourType -- defined elsewhere; maybe nil


-- get the qualifiers associated with a datatype
print(mytype[xtypes.QUALIFIERS])

-- set the qualifiers associated with a datatype
mytype[xtypes.QUALIFIERS] = {
  xtypes.Nested,
  xtypes.Extensibility{'FINAL_EXTENSIBILITY'},
}

-- Get the qualified name (i.e. scoped name) of a datatype:
print(xtypes.nsname(mytype)

-- Get the outermost enclosing scope of a datatype:
print(xtypes.nsroot(mytype)

The datatype constructors provide more usage examples, specific to each type.

Info:

  • Author: Rajive Joshi

Functions

nsname () ddsl.nsname: fully qualified name within the enclosing scope.
nsroot () ddsl.nsroot: outermost enclosing root namespace.
resolve () ddsl.resolve: resolve a typedef
template () ddsl.template: get the cannonical template instance (xtemplate)
new_instance () ddsl.new_instance: create a new instance (xinstance)
new_collection () ddsl.new_collection: create a new collection of instances (xinstances)
is_collection () ddsl.is_collection: is this a collection of instances (xinstances) ?

Tables

EMPTY ddsl.EMPTY: Empty datatype definition for use as initializer in datatype constructors.

Fields

log logger to log messages and get/set the verbosity levels

Datatype Kinds

ANNOTATION () Annotation kind.
ATOM () atom kind.
ENUM () enumeration kind.
STRUCT () struct kind.
UNION () union kind.
TYPEDEF () typedef kind.
CONST () constant kind.
MODULE () module kind.

Datatype Attributes

KIND () ddsl.KIND: Datatype kind.
NAME () ddsl.NAME: Datatype name.
NS () ddsl.NS: Datatype enclosing namespace (enclosing scope).
QUALIFIERS () ddsl.QUALIFIERS: Datatype qualifiers (annotations).
BASE () Datatype of the base struct (inheritance)
SWITCH () Datatype of a union discriminator (switch).

Datatype Qualifiers

annotation (decl) Create an annotation.
array (n, ...) Create an array qualifier with the specified dimensions.
sequence (n, ...) Create a sequence qualifier with the specified dimensions.

Datatypes

atom (decl) Create an atomic datatype.
enum (decl) Create an enum datatype.
struct (decl) Create a struct datatype.
union (decl) Create a union datatype.
typedef (decl) Create a typedef alias datatype.
const (decl) Create a constant.
module (decl) Create a module namespace.

Builtin Datatypes

boolean boolean.
octet octet.
char char.
wchar wide char.
float float.
double double.
long_double long double.
short short.
long long.
long_long long long.
unsigned_short unsigned short.
unsigned_long unsigned long.
unsigned_long_long unsigned long long.
string (n) string<n>: string of length n.
wstring (n) wstring<n>:wstring of length n.

Builtin Annotations

Key Datatype member is a key field.
ID Datatype member id.
Optional Datatype member is optional.
MustUnderstand Datatype member is required.
Shared Datatype member is shared.
BitBound enum datatype is bit-bound.
BitSet enum datatype is a bit-set.
Extensibility Datatype extensibility.
Nested Datatype is not top-level it is nexted.
top_level Datatype may (or may not) be top-level.


Functions

nsname ()
ddsl.nsname: fully qualified name within the enclosing scope.
nsroot ()
ddsl.nsroot: outermost enclosing root namespace.
resolve ()
ddsl.resolve: resolve a typedef
template ()
ddsl.template: get the cannonical template instance (xtemplate)
new_instance ()
ddsl.new_instance: create a new instance (xinstance)
new_collection ()
ddsl.new_collection: create a new collection of instances (xinstances)
is_collection ()
ddsl.is_collection: is this a collection of instances (xinstances) ?

Tables

EMPTY
ddsl.EMPTY: Empty datatype definition for use as initializer in datatype constructors.

Usage:

      local xtypes = require 'ddsl.xtypes'
    
      -- create an empty datatype of kind 'kind' with the name 'MyType'
      local mytype = xtypes.<kind>{
         MyType = EMPTY
      }

Fields

log
logger to log messages and get/set the verbosity levels

Datatype Kinds

Use these to get and set the corresponding datatype attribute.

Usage:

  -- get the kind of a datatype
  print(mytype[KIND]()) -- evaluate the kind to get the description

  -- use the kind of a datatype to make decisions
  if STRUCT == mytype[KIND] then
    ...
  else
    ...
  end
ANNOTATION ()
Annotation kind.

Returns:

    string 'annotation'
ATOM ()
atom kind.

Returns:

    string 'atom'
ENUM ()
enumeration kind.

Returns:

    string 'enum'
STRUCT ()
struct kind.

Returns:

    string 'struct'
UNION ()
union kind.

Returns:

    string 'union'
TYPEDEF ()
typedef kind.

Returns:

    string 'typedef'
CONST ()
constant kind.

Returns:

    string 'const'
MODULE ()
module kind.

Returns:

    string 'module'

Datatype Attributes

Use these to get and set the corresponding datatype attribute.

Usage:

  -- get the name of a datatype
  print(mytype[NAME])

  -- set the name of a datatype
  mytype[NAME] = 'MyTypeNewName' 
KIND ()
ddsl.KIND: Datatype kind.
NAME ()
ddsl.NAME: Datatype name.
NS ()
ddsl.NS: Datatype enclosing namespace (enclosing scope).
QUALIFIERS ()
ddsl.QUALIFIERS: Datatype qualifiers (annotations).
BASE ()
Datatype of the base struct (inheritance)

Returns:

    string ' : '
SWITCH ()
Datatype of a union discriminator (switch).

Returns:

    string 'switch'

Datatype Qualifiers

annotation (decl)
Create an annotation. Annotations qualify a datatype or a member of the datatype. Except for array and sequence qualifiers, annotation contents are opaque to DDSL; they are kept intact and may be interpreted in the user's context.

Parameters:

  • decl {[string]=...} a table containing an annotation name and definition, where ... are the optional default attributes of the annotation.

Returns:

    table an annotation datatype template (xtemplate)

Usage:

      -- Create user defined annotation @MyAnnotation(value1 = 42, value2 = 42.0)
      local MyAnnotation = xtypes.annotation{
         MyAnnotation = {value1 = 42, value2 = 9.0} -- default attributes
      }
    
      -- Use user defined annotation with custom attributes
      MyAnnotation{value1 = 942, value2 = 999.0}
    
      -- Print the annotation contents (value1, value2)
      for k, v in pairs(MyAnnotation) do
        print(k, v)
      end
    
      -- Use builtin annotation Key
      xtypes.Key
    
      -- Use builtin annotation Extensibility
      xtypes.Extensibility{'EXTENSIBLE_EXTENSIBILITY'}  
array (n, ...)
Create an array qualifier with the specified dimensions. Ensures that a valid set of dimension values is passed in. Returns the array datatype qualifier, initialized with the specified dimensions. An array qualifier is interpreted by DDSL as a collection qualifier.

Parameters:

  • n int the first dimension
  • ... the remaining dimensions

Returns:

    table the array qualifier instance (xtemplate)
sequence (n, ...)
Create a sequence qualifier with the specified dimensions. Ensures that a valid set of dimension values is passed in. Returns the sequence datatype qualifier, initialized with the specified dimensions. A sequence qualifier is interpreted by DDSL as a collection qualifier.

Parameters:

  • n int the first dimension
  • ... the remaining dimensions

Returns:

    table the sequence qualifier instance (xtemplate)

Datatypes

atom (decl)

Create an atomic datatype. There are two kinds of atomic types:

  • un-dimensioned
  • dimensioned, e.g. bounded size/length (e.g. string)

Parameters:

  • decl {[string]=EMPTY, {int} or const} a table containing an atom name mapped to and EMPTY initializer (for undimensioned atoms) or a a table containing an integral dimension (for dimensioned atoms). The dimension could also be an integral const datatype.

Returns:

    table an atom datatype template (xtemplate)

Usage:

      -- Create an un-dimensioned atomic datatype named 'MyAtom':
      local MyAtom = xtypes.atom{
        MyAtom = EMPTY
      }
    
      -- Create a dimensioned atomic type:
      local string10 = xtypes.atom{string={10}}        -- bounded length string
      local wstring10 = xtypes.atom{wstring={10}}      -- bounded length wstring
    
      -- Create a dimensioned atomic type, where 'MAXLEN' is a const:
      local StringMaxlen = xtypes.atom{string=MAXLEN} -- bounded length string
enum (decl)
Create an enum datatype.

Parameters:

  • decl {[string]={string,string,[string]=int,[string]=int,...}

    a table containing an enum name mapped to a table (which is an array of strings or a map of strings to ordinal values, or a mix of both). For example,

     { MyEnum = { { str1 = ord1 }, { str2 = ord2 }, ... } }
    

    or

     { MyEnum = { str1, str2, ... } }
    

    or a mix of the above

     { MyEnum = { strA, strB, { str1 = ord1 }, { str2 = ord2 }, ... } }
    

Returns:

    table an enum datatype template (xtemplate) The table is a map of enumerator strings to their ordinal values.

Usage:

      -- Create enum: declarative style
      local MyEnum = xtypes.enum{
        MyEnum = {
              { enumerator_1 = ordinal_1 },
              :
              { enumerator_M = ordinal_M },
    
              -- OR --
    
              enumerator_A,
              :
              enumerator_Z,
    
              -- OPTIONAL --
              annotation_x,
              :
              annotation_z,
        }
      }
    
      -- Create enum: imperative style (start with EMPTY)
      MyEnum = xtypes.enum{
        MyEnum = xtypes.EMPTY
      }
    
      -- Set the i-th member:
      MyEnum[i] = { enumerator_i = ordinal_i }
      -- OR --
      MyEnum[i] = enumerator_i -- default: ordinal_i = #MyEnum
    
      -- After setting the i-th member, the following post-conditions hold:
      MyEnum[enumerator_i]     == ordinal_i
      MyEnum(ordinal_i)        == enumerator_i
    
    
      -- Delete the i-th member:
      MyEnum[i] = nil
    
    
      -- Get the number of enumerators in the enum:
      print(#MyEnum)
    
    
      -- Get the i-th member:
      local enumerator, ordinal = next(MyEnum[i])
      print(enumerator, ordinal)
    
      -- Get the enumerator's ordinal value:
      print(MyEnum[enumerator])
    
    
      -- Iterate over the model definition (ordered):
      for i = 1, #MyEnum do print(next(MyEnum[i])) end
    
      -- Iterate over enum and ordinal values (unordered):
      for enumerator, ordinal in pairs(MyEnum) do print(enumerator, ordinal) end
    
      -- Lookup the enumerator name for an ordinal value:
      print(MyEnum(ordinal))
struct (decl)
Create a struct datatype.

Parameters:

  • decl {[string]={[string]={...},{[string]={...},...}

    a table containing a struct name mapped to a table (which is an array of strings mapped to member definitions). For example,

    { MyStruct = { { role1 = {...}, { role2 = {...} }, ... } }
    

    where the member definition for a role is,

    { role = { xtemplate, [array | sequence,] [annotation, ...] } }
    

Returns:

    table a struct datatype template (xtemplate).
    The table is a map of the role names to flattened out strings that represent the path from the enclosing top-level struct scope to the role. The string values may be be used to retrieve the field values from some storage system.

Usage:

      -- Create struct: declarative style
      local MyStruct = xtypes.struct{
        MyStruct = {
          [<optional base struct>], -- base struct must be the 1st item
    
          {role_1={xtemplate_1, [array_1|sequence_1,] [annotation_1,...]}},
            :
          {role_M={xtemplate_M, [array_M|sequence_M,] [annotation_M,...]}},
    
          -- OPTIONAL --
          annotation_x,
           :
          annotation_z,
        }
      }
    
      -- OR Create struct: imperative style (start with base struct or EMPTY)
      local MyStruct = xtypes.struct{
        MyStruct = { <optional base struct> } | xtypes.EMPTY
      }
    
      -- Set the i-th member:
      MyStruct[i] = { new_role = { new_xtemplate,
                                    [new_array | new_sequence,]
                                    [new_annotation, ...] } }
    
      -- After setting the i-th member, the following post-condition holds:
      -- NOTE: also holds for roles defined in the base struct datatype
      MyStruct[role] == 'prefix.enclosing.scope.path.to.role'
      MyStruct(role) == <the role definition>
    
    
      -- Delete the i-th member:
      MyStruct[i] = nil
    
    
      -- Set base class:
      MyStruct[xtypes.BASE] = YourStruct -- defined elsewhere
    
    
      -- Get the number of members in the struct (not including base struct):
      print(#MyStruct)
    
    
      -- Get the i-th member:
      -- {
      --   role = {template, [array|sequence,] [annotation1, annotation2, ...]
      -- }
      local member = MyStruct[i]
      local role, roledef = next(member)
      print(role, table.unpack(roledef))
    
      -- Get a member definition by role name. The return value is a table
      -- in the same format that is used to define a member role:
      --  { template, [array|sequence,] [annotation1, annotation2, ...] }
      local roledef = MyStruct(role)
      print(table.unpack(roledef))
    
    
      -- Get the member role's value
      print(MyStruct[role])   -- an accessor string into some storage system
    
    
      -- Get the base class:
      print(MyStruct[xtypes.BASE])
    
    
      -- Iterate over the model definition (ordered):
      -- NOTE: does NOT show the roles defined in the base struct datatype
      for i = 1, #MyStruct do
        local role, roledef = next(MyStruct[i])
        print(role, table.unpack(roledef))
      end
    
      -- Iterate over instance members and the indexes (unordered):
      -- NOTE: shows roles defined in the base struct datatype
      for role, value in pairs(MyStruct) do
        print(role, value, table.unpack(MyStruct(role)))
      end
union (decl)
Create a union datatype.

Parameters:

  • decl {[string]={xtemplate,{caseDisc1,...caseDiscN,string]={...}},...}} a table containing a union name mapped to a table as follows.

    {
      MyUnion = {
          xtemplate,
          { caseDisc11, ..., caseDisc1N, role1 = {...} },
          { caseDisc21, ..., caseDisc2N, role2 = {...} },
          ...
          { xtypes.EMPTY, [..., caseDiscN,]  role = {...} } -- default
      }
    }
    

    where the member definition for a role is,

    { role = { xtemplate, [array | sequence,] [annotation, ...] } }
    

    and xtypes.EMPTY is treated as the built-in default discriminator.

Returns:

    table an union datatype template (xtemplate). The table is a map of the role names to flattened out strings that represent the path from the enclosing top-level union scope to the role. The string values may be be used to retrieve the field values from some storage system.

Usage:

      -- Create union: declarative style
      local MyUnion = xtypes.union{
        MyUnion = {
          <discriminator atom or enum>,  -- must be the 1st item
    
          {  caseDiscriminator11, caseDiscriminator12, ... caseDiscriminator1N,
             role_1 = {xtemplate_1,[array_1|sequence_1,][annotation_1,...]}
          },
            :
          {  caseDiscriminatorM1, caseDiscriminatorM2, ... caseDiscriminatorMN,
             role_M = {xtemplate_M,[array_M|sequence_M,][annotation_M,...]}
          },
    
          { xtypes.EMPTY, [..., caseDiscriminatorN, ] -- default
            role = { xtemplate,[array|sequence,][annotation,...]}
    
          -- OPTIONAL --
          annotation_x,
           :
          annotation_z,
        }
      }
    
      -- OR Create union: imperative style (start with EMPTY)
      local MyUnion = xtypes.union{
        MyUnion = { <discriminator atom or enum> }
      }
    
      -- Set the i-th case:
      -- {
      --   caseDiscriminator1, caseDiscriminator2, ... caseDiscriminatorN,
      --   role = { template, [array|sequence,] [annotation1, annotation2, ...] }
      -- }
      MyUnion[i] = {
          caseDiscriminator1, ... caseDiscriminatorN,
          role = { xtemplate, [array | sequence,] [annotation, ...] }
      },
    
      -- After setting the i-th member, the following post-condition holds:
      MyUnion[role] == 'prefix.enclosing.scope.path.to.role'
      MyUnion(role) == <the role definition>
    
    
      -- Delete the i-th case:
      MyUnion[i] = nil
    
    
      -- Set the discriminator type definition:
       MyUnion[xtypes.SWITCH] = <discriminator atom or enum>
    
     -- After setting the discriminator, the following post-condition holds:
      MyUnion._d == '#'
    
    
     -- Get the number of cases in the union:
      print(#MyUnion)
    
    
      -- Get the i-th case:
      -- {
      --   caseDiscriminator1, caseDiscriminator2, ... caseDiscriminatorN,
      --   role = { template, [array|sequence,] [annotation1, annotation2, ...] }
      -- }
      local case = MyUnion[i]
      print(table.unpack(case))
      local role, roledef = next(case, #case)
      print('\t', role, table.unpack(roledef))
    
      -- Get a member definition by role name. The return value is a table
      -- in the same format that is used to define a member role:
      --  { template, [array|sequence,] [annotation1, annotation2, ...] }
      local roledef = MyUnion(role)
      print(table.unpack(roledef))
    
      -- Get the member role's value
      print(MyUnion[role])   -- an accessor string into some storage system
    
      -- Get the discriminator type definition:
       print(MyUnion[xtypes.SWITCH])
    
      -- Get the discriminator's value
      print(MyUnion._d)   -- an accessor string into some storage system
    
     -- Get the currectly selected member's value.
     -- i.e. the member selected by current discriminator value, MyUnion._d
     print(MyUnion()) -- may be nil, e.g. when there is no default discriminator
    
    
      -- Iterate over the model definition (ordered):
      for i = 1, #MyUnion do
        local case = MyUnion[i]
        local role, roledef = next(case, #case)
        print(role, table.unpack(roledef), ':', table.unpack(case))
      end
    
      -- Iterate over instance members and the indexes (unordered):
      for role, value in pairs(MyUnion) do
        print(role, value, table.unpack(MyUnion(role)))
      end
typedef (decl)
Create a typedef alias datatype. Typedefs are aliases for underlying datatypes.

Parameters:

  • decl {[string]={xtemplate,[array or sequence,][annotation,...]}} a table containing a typedef mapped to an array as follows.

    { MyTypedef = { xtemplate, [array | sequence,] [annotation, ...] } }
    

    where xtemplate is the underlying type definition, optionally followed by and array or sequence qualifiers to specify the multiplicity, optionally followed by annotations.

Returns:

    table an typedef datatype template (xtemplate).

Usage:

      -- Create a typedef datatype:
      local MyTypedef = xtypes.typedef{
        MyTypedef = { xtemplate, [array | sequence,] [annotation, ...] }
      }
    
      -- Retreive the typedef definition
      print(MyTypedef()) -- xtemplate, [array | sequence]
    
      -- Resolve a typedef to the underlying non-typedef datatype and a list
      -- of collection qualifiers
      print(xtypes.resolve(MyTypedef))
    
    
      -- Example: typedef sequence<MyStruct> MyStructSeq
      local MyStructSeq = xtypes.typedef{
        MyStructSeq = { xtypes.MyStruct, xtypes.sequence() }
      }
    
      print(MyStructSeq()) --     MyStruct     @sequence(10)
    
    
      -- Example: typedef MyStruct MyStructArray[10][20]
      local MyStructArray = xtypes.typedef{
        MyStructArray = { xtypes.MyStruct, xtypes.array(10, 20) }
      }
    
      print(MyStructArray()) --   MyStruct     @array(10, 20)
const (decl)
Create a constant.

Parameters:

  • decl {[string]={atom,value}} a table containing a constant name mapped to an array containing an atom and a value of the atom datatype. NOTE: this method will try to convert the value to the correct type, if not already so (for example, if the value is a string).

Returns:

    table a constant.

Usage:

      -- Create a constant datatype
      local MY_CONST = xtypes.const{
        MY_CONST = { atom, <const_value> }
      }
    
      -- Get the const value and the underlying atomic datatype
      print(MY_CONST()) --    value      atom
    
    
      -- Examples:
      local MAXLEN = xtypes.const{
        MAXLEN = { xtypes.short, 128 }
      }
      print(MAXLEN()) -- 128  short
    
      local PI = xtypes.const{
        PI = { xtypes.double, 3.14 }
      }
      print(PI()) -- 3.14  double
    
      local MY_STRING = xtypes.const{
        MY_STRING = { xtypes.string(128), "My String Constant" }
      }
      print(MY_STRING()) -- My String Constant      string<128>
    
    
      -- Use a const datatype
      local MyStringSeq =  xtypes.typedef{
        MyStringSeq = { xtypes.string, xtypes.sequence(MAXLEN) }
      }
module (decl)
Create a module namespace. A module is an name-space for holding (enclosing) datatypes.

Parameters:

Returns:

    table a module namespace. The table is a map of the datatype names to xtemplate canonical instances.

Usage:

        -- Create module: declarative style
        local MyModule = xtypes.module{
          MyModule = {
            xtypes.const{...},
            :
            xtypes.enum{...},
            :
            xtypes.struct{...},
            :
            xtypes.union{...},
            :
            xtypes.typedef{...},
            :
            xtypes.module{...}, -- nested module name-space
            :
          }
        }
    
      -- Create module: imperative style (start with EMPTY)
      local MyModule = xtypes.module{
        MyModule = xtypes.EMPTY
      }
    
      -- Get the i-th member:
      print(MyModule[i])
    
      -- Set the i-th member:
      MyModule[i] = xtemplate
    
      -- After setting the i-th member, the following post-condition holds:
      MyModule.name == xtemplate -- where: name = xtemplate[xtypes.NAME]
    
      -- Delete the i-th member:
      MyModule[i] = nil
    
    
     -- Get the number of members in the module:
      print(#MyModule)
    
      -- Iterate over the module definition (ordered):
      for i = 1, #MyModule do print(MyModule[i]) end
    
      -- Iterate over module namespace (unordered):
      for k, v in pairs(MyModule) do print(k, v) end

Builtin Datatypes

Builtin atomic datatypes.
boolean
boolean.
octet
octet.
char
char.
wchar
wide char.
float
float.
double
double.
long_double
long double.
short
short.
long
long.
long_long
long long.
unsigned_short
unsigned short.
unsigned_long
unsigned long.
unsigned_long_long
unsigned long long.
string (n)
string<n>: string of length n.

Parameters:

  • n int the maximum length of the string

Returns:

    xtemplate the string datatype
wstring (n)
wstring<n>:wstring of length n.

Parameters:

  • n int the maximum length of the wstring

Returns:

    xtemplate the wstring datatype

Builtin Annotations

Use these to qualify the datatype structure. Some apply to datatypes, while others apply to datatype members.
Key
Datatype member is a key field. @Key
ID
Datatype member id. @ID{n}
Optional
Datatype member is optional. @Optional
MustUnderstand
Datatype member is required. @MustUnderstand
Shared
Datatype member is shared. @Shared
BitBound
enum datatype is bit-bound. @BitBound{n}
BitSet
enum datatype is a bit-set. @BitSet
Extensibility
Datatype extensibility. @Extensibility{'EXTENSIBLE_EXTENSIBILITY'|'MUTABLE_EXTENSIBILITY'|'FINAL_EXTENSIBILITY}
Nested
Datatype is not top-level it is nexted. @Nested
top_level
Datatype may (or may not) be top-level. @top_level{false}
generated by LDoc 1.4.3 Last updated 2015-11-07 15:24:54