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

Convert to Qt QVariant #2216

Closed
pylvain opened this issue Jun 24, 2020 · 5 comments
Closed

Convert to Qt QVariant #2216

pylvain opened this issue Jun 24, 2020 · 5 comments

Comments

@pylvain
Copy link

pylvain commented Jun 24, 2020

Hi, i'm currently working with JSON in Qt/Qml. Because of Qt poor support for JSON, i'm using this library. So, i have to convert this library's default type, which is using stl types, to a QVariant/QJsonValue, which is using Qt types, and vice versa. It's ok, but it feels like a waste of computer power and memory. Just out of curiosity, is it possible to work something out by modifying this definition :

template<template<typename U, typename V, typename... Args> class ObjectType =
         std::map,
         template<typename U, typename... Args> class ArrayType = std::vector,
         class StringType = std::string, class BooleanType = bool,
         class NumberIntegerType = std::int64_t,
         class NumberUnsignedType = std::uint64_t,
         class NumberFloatType = double,
         template<typename U> class AllocatorType = std::allocator,
         template<typename T, typename SFINAE = void> class JSONSerializer =
         adl_serializer,
         class BinaryType = std::vector<std::uint8_t>>
class basic_json;

with something like

class ObjectType = QJsonValue::Object
class StringType = QJsonValue::String 
etc ...

I'm no C++ expert, and i cannot make this work on my own, this is a bit too advanced for me.

Thanks

@ArtemSarmini
Copy link
Contributor

ArtemSarmini commented Jun 24, 2020

Make your own alias like
using qt_json = basic_json<QMap, QVector, QString, ...>;
Do not try to edit library files.

@pylvain
Copy link
Author

pylvain commented Jun 24, 2020

Thanks, simply that seems to work :

using myjson = basic_json<QMap,QVector,QString,bool,int,unsigned int,double>;

Silly me was trying to use QJSonValue:: thinking it was refering to types, but that was just an enum. Thank you !

@sandroandrade
Copy link

Thanks, simply that seems to work :

using myjson = basic_json<QMap,QVector,QString,bool,int,unsigned int,double>;

Silly me was trying to use QJSonValue:: thinking it was refering to types, but that was just an enum. Thank you !

Is this currently working? Using QVector as array type yelds the following error:

/usr/include/nlohmann/json.hpp:560:11: error: wrong number of template arguments (2, should be 1)
  560 |     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
      |           ^~~~~~~

Probably because QVector doesn't support passing the allocator as template parameter. Any hint? Similar errors occur for QMap type.

Thanks in advance,

@nlohmann
Copy link
Owner

nlohmann commented Nov 9, 2021

You could define a wrapper type that just consumes the AllocatorType argument. Something like

template<typename T, typename AllocatorType>
class q_vector_wrapper<T, AllocatorType> : public QVector<T>
{};

@Dariusz1989
Copy link

Dariusz1989 commented Aug 3, 2023

Can this be elaborated a bit? I want to support QVector etc etc but I'm hitting walls left and right.
Any hints? how to declare/how to use? etc?
Tried with :

namespace nlohmann {
    template<>
    struct adl_serializer<QString> {
        static void to_json(json &j, const QString &s) {
            j = s.toStdString();
        }

        static void from_json(const json &j, QString &s) {
            s = QString::fromStdString(j.get<std::string>());
        }
    };

    template<typename T>
    struct adl_serializer<QVector<T>> {
        static void to_json(json &j, const QVector<T> &data) {
            for (const auto &element: data) {
                j.push_back(element);
            }
        }

        static void from_json(const json &j, QVector<T> &data) {
            for (const auto &element: j) {
                data.push_back(element.get<T>());
            }
        }
    };
}

but lots of errors

error C2908: explicit specialization; 'nlohmann::json_abi_v3_11_2::adl_serializer<T,void>' has already been instantiated
        with
        [
            T=QString
        ]
        error C2766: explicit specialization; 'nlohmann::json_abi_v3_11_2::adl_serializer<T,void>' has already been defined
        with
        [
            T=QString
        ]
        : note: see previous definition of 'adl_serializer<QString,void>'
        ```
        etc etc
        

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

No branches or pull requests

5 participants