Defining Custom Types

Interface through which type definitions are created and extended for use with pvxs::Value.

#include <pvxs/data.h>
namespace pvxs { ... }

The type system of the PVA protocol consists of a number of primitive and compound types, as well as arrays of either. The pvxs::TypeCode::code_t enum is an exhaustive list of all valid types, as well as Null.

Any valid type may be instantiate directly.

Value v = TypeDef{TypeCode::String}.create();
v = "works, but not very interesting";

In almost all cases, custom type definitions will be for Structures. When defining structures, the functions of the pvxs::members namespace can help to keep definitions concise.

namespace M = pvxs::members;

Value v = TypeDef(TypeCode::Struct, {
    M::Int32("ifield"),
    M::Float64("fval"),
    M::Struct("substruct", {
        M::String("desc"),
    }),
}).create();

It is also possible to extend definitions.

namespace M = pvxs::members;

TypeDef def(TypeCode::Struct, {
    M::Int32("ifield"),
    M::Struct("substruct", {
        M::String("desc"),
    }),
});

def += {M::Float64("fval")};
Value v(def.create());

This also applies to the ntapi allowing fields to be added. eg. adding a string field “display.notes”.

namespace M = pvxs::members;

TypeDef def = nt::NTScalar{TypeCode::UInt32, true}.build();

def += {M::Struct("display", {M::String("notes")})};
Value v(def.create());
struct TypeCode

Possible Field types.

eg. String is scalar string, StringA is array of strings.

Public Types

enum code_t

actual complete (scalar) type code.

Values:

enumerator Bool
enumerator BoolA
enumerator Int8
enumerator Int16
enumerator Int32
enumerator Int64
enumerator UInt8
enumerator UInt16
enumerator UInt32
enumerator UInt64
enumerator Int8A
enumerator Int16A
enumerator Int32A
enumerator Int64A
enumerator UInt8A
enumerator UInt16A
enumerator UInt32A
enumerator UInt64A
enumerator Float32
enumerator Float64
enumerator Float32A
enumerator Float64A
enumerator String
enumerator StringA
enumerator Struct
enumerator Union
enumerator Any
enumerator StructA
enumerator UnionA
enumerator AnyA
enumerator Null

Public Functions

inline uint8_t order() const

size()==1<<order()

inline uint8_t size() const

Size in bytes for simple kinds (Bool, Integer, Real)

inline bool isunsigned() const

For Integer kind.

inline bool isarray() const

For all.

inline constexpr TypeCode arrayOf() const

associated array of type

inline constexpr TypeCode scalarOf() const

associated not array of type

const char *name() const

name string. eg. “bool” or “uint8_t”

Public Members

code_t code

the actual type code. eg. for switch()

class TypeDef

Define a new type, either from scratch, or based on an existing Value

namespace M = pvxs::members;
auto def1 = TypeDef(TypeCode::Int32); // a single scalar field
auto def2 = TypeDef(TypeCode::Struct, {
    M::Int32("value"),
    M::Struct("alarm", "alarm_t", {
        M::Int32("severity"),
    }),
    def1.as("special"), // compose definitions
});

auto val = def2.create(); // instantiate a Value
});

Public Functions

TypeDef() = default

new, empty, definition

explicit TypeDef(const Value&)

pre-populate definition based on provided Value

template<typename Iterable>
inline TypeDef(TypeCode code, const std::string &id, const Iterable &children)

new definition with id and children. code must be TypeCode::Struct or TypeCode::Union

inline TypeDef(TypeCode code)

new definition for a single scalar field. code must not be TypeCode::Struct or TypeCode::Union

inline TypeDef(TypeCode code, std::initializer_list<Member> children)

new definition without id. code must be TypeCode::Struct or TypeCode::Union

Member as(const std::string &name) const

Use this definition as a member (eg. sub-structure) in another definition.

Member as(TypeCode code, const std::string &name) const

Use this definition as a member (eg. sub-structure) in another definition with a (limited) type change.

A Kind::Compound type (eg. Struct) may be changed to another Compound type (eg. StructA). However. changes between Compound and non-Compound are not allowed.

Since

1.1.0

template<typename Iterable>
inline TypeDef &operator+=(const Iterable &children)

append additional children. Only for TypeCode::Struct or TypeCode::Union

Value create() const

Instantiate this definition.

struct Member

Definition of a member of a Struct/Union for use with TypeDef.

Public Functions

inline Member()

Empty/invalid Member.

inline Member(TypeCode code, const std::string &name)

Member for non-Compound

Pre:

code.kind()!=Kind::Compound

inline Member(TypeCode code, const std::string &name, const std::string &id, std::initializer_list<Member> children)

Compound member with type ID.

inline Member(TypeCode code, const std::string &name, std::initializer_list<Member> children)

Compound member without type ID.

namespace members

Helper functions for building TypeDef.

Each of the TypeCode::code_t enums has an associated helper function of the same name which is a shorthand notation for a Member().

eg.

members::UInt32("blah") 
is equivalent to
Member(TypeCode::UInt32, "blah") 

enum class pvxs::Kind : uint8_t

Groups of related types.

Values:

enumerator Bool
enumerator Integer
enumerator Real
enumerator String
enumerator Compound
enumerator Null