Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to implement a variadic (const) compound type for List and Map #32

Open
CncGpp opened this issue Sep 20, 2021 · 0 comments
Open

How to implement a variadic (const) compound type for List and Map #32

CncGpp opened this issue Sep 20, 2021 · 0 comments

Comments

@CncGpp
Copy link

CncGpp commented Sep 20, 2021

Hi, I'm developing a scripting-capable utility. I now use successfully wren-lang with wrenbind17 but I would like to try QuickJS.

However, I was unable to define a generic (variadic) datatype that allows me to call C++ functions from JS with compound objects such as Lists/Arrays or Map. Is it possible to do such a thing?

namespace js {
    struct List {
        // ??? DATA
        template <typename T> T get(const size_t ix) const;
        size_t size() const;
    };

    struct Map {
        // ??? DATA
        template <typename K, typename V> V get(const K key) const;
        size_t size() const;       
    };


    using Variant = std::variant<std::nullptr_t, bool, int, double, std::string, js::List, js::Map>;
    struct any :  public Variant {
        using Variant::variant;
        using Variant::operator=;

        enum class Type : int {
            null_t = 0, bool_t, int_t, double_t, string_t, list_t, map_t
        };

        any(const Variant& p) : Variant(p) {}

        Type type() const { return (Type)this->index(); }

        template <class T> bool is() const {
            const Type t = type();

            if constexpr (std::is_same<T, std::nullptr_t>::value)
                return t == Type::null_t;

            if constexpr (std::is_same<T, bool>::value)
                return t == Type::bool_t;

            if constexpr (std::is_same<T, int>::value)
                return t == Type::int_t;

            if constexpr (std::is_same<T, double>::value)
                return t == Type::double_t;

            if constexpr (std::is_same<T, std::string>::value)
                return t == Type::string_t;

            if constexpr (std::is_same<T, js::List>::value)
                return t == Type::list_t;

            if constexpr (std::is_same<T, js::Map>::value)
                return t == Type::map_t;

            return false;
        }

        template <class T> T as() const { return std::get<T>(*this); }
    };
}

So js::List is just a list/array of js::any and js::Map is a map of <std::string, js::any> .

I'd like to do something like this:

/* C++ function definition*/
void f(std::string s, js::any a){
   if(a.is<js::Map>()){
       // Code for accessing map elements  for example convert to nlohmann_json
  } else if(a.is<js::List>()){
    auto v = a.as<js::list>().get(0);          //v is also a js::any.
  } else { ... }
}
/* JS function call*/
module.f("~/example.dat", {
     "parms" : {"hello":"HI!"},
     "array" : [false, "str1", true, "str2"],
     "id" : 38,
});

Is it possible to do this in quickjspp?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant