File: lsAny.h

package info (click to toggle)
asymptote 3.02%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 33,400 kB
  • sloc: cpp: 172,516; ansic: 69,728; python: 14,967; sh: 5,599; javascript: 4,866; lisp: 1,507; perl: 1,417; makefile: 1,028; yacc: 610; lex: 449; xml: 182; asm: 8
file content (158 lines) | stat: -rw-r--r-- 3,697 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#pragma once

#include "LibLsp/JsonRpc/serializer.h"
#include <string>
#include "LibLsp/JsonRpc/message.h"
namespace lsp
{
struct Any
{
    //! Type of JSON value
    enum Type
    {
        kUnKnown = -1,
        kNullType = 0, //!< null
        kFalseType = 1, //!< false
        kTrueType = 2, //!< true
        kObjectType = 3, //!< object
        kArrayType = 4, //!< array
        kStringType = 5, //!< string
        kNumberType = 6 //!< number
    };

    template<typename T>
    bool Get(T& value);

    template<typename T>
    void Set(T& value);

    int GuessType();
    int GetType();

    void Set(std::unique_ptr<LspMessage> value);

    void SetJsonString(std::string&& _data, Type _type);

    void SetJsonString(std::string const& _data, Type _type);

    std::string const& Data() const
    {
        return data;
    }

    void swap(Any& arg) noexcept;

    /*
                 *Example for GetFromMap
                        struct A{
                                std::string  visitor;
                                bool   verbose;
                        }
                        REFLECT_MAP_TO_STRUCT(A,visitor,verbose)

                        std::string data = "{\"visitor\":\"default\",\"verbose\":\"true\"};
                        lsp:Any any;
                        any.SetJsonString(data, static_cast<lsp::Any::Type>(-1));
                        A a_object;
                        any.GetFromMap(a_object);
                */
    template<typename T>
    bool GetFromMap(T& value);

    template<typename T>
    bool GetForMapHelper(T& value);
    bool GetForMapHelper(std::string& value);
    bool GetForMapHelper(optional<std::string>& value);

private:
    std::unique_ptr<Reader> GetReader();
    std::unique_ptr<Writer> GetWriter() const;
    void SetData(std::unique_ptr<Writer>&);

    std::string data;
    int jsonType = kUnKnown;
};

}; // namespace lsp

extern void Reflect(Reader& visitor, lsp::Any& value);
extern void Reflect(Writer& visitor, lsp::Any& value);

template<typename T>
void ReflectMember(std::map<std::string, lsp::Any>& visitor, char const* name, T& value)
{

    auto it = visitor.find(name);
    if (it != visitor.end())
    {
        it->second.GetForMapHelper(value);
    }
}
template<typename T>
void ReflectMember(std::map<std::string, std::string>& visitor, char const* name, T& value)
{

    auto it = visitor.find(name);
    if (it != visitor.end())
    {
        lsp::Any any;
        any.SetJsonString(it->second, static_cast<lsp::Any::Type>(-1));
        any.Get(value);
    }
}

#define REFLECT_MAP_TO_STRUCT(type, ...) \
    template<typename TVisitor> \
    void ReflectMap(TVisitor& visitor, type& value) \
    { \
        MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
    }

namespace lsp
{
template<typename T>
bool Any::Get(T& value)
{
    auto const visitor = GetReader();
    Reflect(*visitor, value);
    return true;
}

template<typename T>
void Any::Set(T& value)
{
    auto visitor = GetWriter();
    Reflect(*visitor, value);
    SetData(visitor);
}

template<typename T>
bool Any::GetFromMap(T& value)
{
    auto const visitor = GetReader();
    std::map<std::string, lsp::Any> _temp;
    Reflect(*visitor, _temp);
    ReflectMap(_temp, value);
    return true;
}

template<typename T>
bool Any::GetForMapHelper(T& value)
{
    jsonType = GetType();
    if (jsonType == kStringType)
    {
        auto copy = data;
        copy.erase(copy.find_last_not_of('"') + 1);
        copy.erase(0, copy.find_first_not_of('"'));
        lsp::Any any;
        any.SetJsonString(copy, kUnKnown);
        any.Get(value);
    }
    else
    {
        Get(value);
    }
    return true;
}
} // namespace lsp