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

Make XML great again. #847

Closed
sfinktah opened this issue Nov 30, 2017 · 2 comments
Closed

Make XML great again. #847

sfinktah opened this issue Nov 30, 2017 · 2 comments
Labels
solution: wontfix the issue will not be fixed (either it is impossible or deemed out of scope)

Comments

@sfinktah
Copy link

sfinktah commented Nov 30, 2017

Firstly, sincere apologies, this is not an issue with your excellent JSON library, and should probably be tagged "Wishful Thinking" or some-such.

However, I will post it anyway, and if I knew how, but regrettably can't cross-post it to the zenxml where it probably belong, since they're on sourceforge. (ikr).

tl;dr - in your (no doubt) abundance of free time, would you consider "fixing" xen::xml (which I thought was the XML equiv. of your lovely library) to actually be as good as your library.

    // Example struct
    struct S {
        float get_value()        { return externalFunctionGet(); }
        void  set_value(float _) { externalFunctionSet(_);       }

        // MSVC prototype extension
        __declspec(property(get = get_value, put = set_value)) float value;
    } s;

    // JSON - lovely, works perfectly, of course.

    json j;               // empty XML document
    j["value"] = s.value; // write property
    s.value = j["value"]; // read  property


    // zen::Xml

    zen::XmlDoc doc;       //empty XML document
    zen::XmlOut out(doc);  // data output proxy
    out["value"](s.value); // so far so good, thought not very attractive syntax
    
    zen::XmlIn in(doc);    // data input proxy
    in["value"])(s.value); // **fails** because it requires a reference.

At this point, you can probably see how zen::xml is at a major disadvantage, not having the (pretty magical) ability of nlohmann::json to automatically determine and convert types via assignment.

The problem wouldn't be insurmountable, if the struct just returned member values, one could simply change the getter and setter to use references.

Technically, this can actually be done anyway, but only in MSVC (love that standards compliance).

    // shoddy "fix" - make functions return references (which will be temporary, though MSVC allows it)
    // unknown whether it will actually function correctly, but it does compile.

    struct S2 {
        float& get_value()        { return externalFunctionGet(); }
        void  set_value(float& _) { externalFunctionSet(_);       }

        // MSVC prototype extension
        __declspec(property(get = get_value, put = set_value)) float value;
    } s2;

    // zen::Xml example works fine

    // JSON, not so much.

    j["value"] = s2.value; // write property
    s2.value = j["value"]; // **fails** (can't convert basic_json to float&)

Note: this is not a complaint that JSON fails in this instance... I don't think it's the fault of your library -
it's more likely to be a quirk of MSVC's property implemention - since it handles this fine:

    auto fn = []() -> float& { static float f = 1.0f;  return f;  };
    s2.value = fn();

Anyway, if any other readers have any suggestions for a solution, or perhaps any XML library that would accept something like this example from zen::Xml

//write a value into one deeply nested XML element - note the different types used seamlessly: char[], wchar_t[], char, wchar_t, int
zen::XmlOut out(doc);
out["elemento1"][L"элемент2"][L"要素3"][L"στοιχείο4"]["elem5"][L"元素6"][L'']['z'](-1234);```

Which is very nice, but wholly unusable because it requires the same &argument....

... well any ideas at all would be appreciated.

And again, I apologise.

@sfinktah
Copy link
Author

and I guess I should probably add the only solution I did find, though I am dubious that anyone well end up here, looking for a solution to XML issues. But you never can tell.

template<typename T>
struct refwrap {
    std::function<T(void)> getter;
    std::function<void(T)> setter;
    T tmp = {};

    refwrap(
        std::function<T(void)> getter = nullptr,
        std::function<void(T)> setter = nullptr
    ) : getter(getter), setter(setter) { }

    T& ref_getter() { if (getter) tmp = getter(); return tmp; }
    void ref_setter(T& _) { if (setter) setter(_); }

    __declspec(property(get = ref_getter, put = ref_setter)) T &value;
};
#define PROP(type, name) \
    (refwrap<type>([&]() { return .name; }, [&](type _) { name = _; })).value

in["value"](PROP(float, s.value));

@nlohmann
Copy link
Owner

nlohmann commented Dec 4, 2017

I am sorry to disappoint you, but I currently hardly find the time to cope with this library...

@nlohmann nlohmann added the solution: wontfix the issue will not be fixed (either it is impossible or deemed out of scope) label Dec 6, 2017
@nlohmann nlohmann closed this as completed Dec 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
solution: wontfix the issue will not be fixed (either it is impossible or deemed out of scope)
Projects
None yet
Development

No branches or pull requests

2 participants