ReflectedFunction.h

// ReflectedFunction.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2022

@import "IObject.h"
@import "ReflectedType.h"

namespace ceda
{
///////////////////////////////////////////////////////////////////////////////////////////////////
// ReflectedReturnType

$struct+ ReflectedReturnType
{
    const octet_t* byteCode;      // Specifies type and metadata
    ReflectedType rtype;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// ReflectedArg

$struct+ ReflectedArg <<os>>
{
    $ConstStringZ GetName() const { return name; }
    void Write(xostream& os) const;

    //////////////// State //////////////////

    ConstStringZ name;
    const octet_t* byteCode;       // Specifies type and metadata
    ReflectedType rtype;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// ReflectedFunction

$struct+ ReflectedFunction <<os>>
{
    $ConstStringZ GetName() const { return name; }
    $ssize_t GetNumArgs() const { return numArgs; }
    $const ReflectedArg& GetArg(ssize_t i) const { return args[i]; }
    void Write(xostream& os) const;

    ConstStringZ name;
    ReflectedReturnType returnType;
    const ReflectedArg* args;
    ssize_t numArgs;
    const octet_t* metaData;
};

///////////////////////////////////////////////////////////////////////////////////////////////////
// ReflectedFunctor

$struct+ ReflectedFunctor <<os>>
{
    $ConstStringZ GetName() const { return name; }
    $ssize_t GetNumArgs() const { return numArgs; }
    $const ReflectedArg& GetArg(ssize_t i) const { return args[i]; }
    bool operator<(const ReflectedFunctor& rhs) const { return this < &rhs; }
    bool operator==(const ReflectedFunctor& rhs) const { return this == &rhs; }
    void Write(xostream& os) const;

    @if (!CEDA_ENABLE_STRING_TABLES)
    {
        const octet_t* byteCode;
    }
    ConstStringZ name;
    ReflectedReturnType returnType;
    const ReflectedArg* args;
    ssize_t numArgs;
    const octet_t* metaData;
    ConstStringZ const* stringTable;
};

inline const ReflectedFunction& AsReflectedFunction(const ReflectedFunctor& rf)
{
    // Assumes that the ReflectedFunctor begins with all the members defined in ReflectedFunction
    return reinterpret_cast<const ReflectedFunction&>(rf);
}

///////////////////////////////////////////////////////////////////////////////////////////////////
// ReflectedGlobalFunction

$struct+ ReflectedGlobalFunction <<os>>
{
    $ConstStringZ GetName() const { return name; }
    $ssize_t GetNumArgs() const { return numArgs; }
    $const ReflectedArg& GetArg(ssize_t i) const { return args[i]; }
    bool operator<(const ReflectedGlobalFunction& rhs) const { return this < &rhs; }
    bool operator==(const ReflectedGlobalFunction& rhs) const { return this == &rhs; }
    void Write(xostream& os) const;

    ConstStringZ name;
    ReflectedReturnType returnType;
    const ReflectedArg* args;
    ssize_t numArgs;
    const octet_t* metaData;
    ConstStringZ const* stringTable;
    FunctionPointer address;
};

inline const ReflectedFunction& AsReflectedFunction(const ReflectedGlobalFunction& rgf)
{
    // Assumes that the ReflectedGlobalFunction begins with all the members defined in ReflectedFunction
    return reinterpret_cast<const ReflectedFunction&>(rgf);
}

template<typename T>
struct GetReflectedType_class<T, std::enable_if_t<!std::is_const<T>::value && !std::is_volatile<T>::value && IsReflectedFunctor<T>::value>>
{
    static inline ReflectedType get()
    {
        ReflectedType r;
        r.tag = EReflectedTypeTag::Functor;
        r.Functor = &GetReflectedFunctor<T>();
        return r;
    }
};
} // namespace ceda