loom

Форк
0
/
Object.cpp 
196 строк · 5.1 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo/loom
7
*/
8

9
#include "simodo/variable/Variable.h"
10
#include "simodo/bormental/DrBormental.h"
11
#include "simodo/variable/FunctionWrapper.h"
12
#include "simodo/inout/format/fmt.h"
13

14
#include <algorithm>
15

16
namespace simodo::variable
17
{
18
    void Object::setFlag(ObjectFlag flag)
19
    {
20
        _flags.set(flag);
21
    }
22

23
    Object Object::copy() const
24
    {
25
        Object record;
26

27
        for(const Variable & member : _variables)
28
            record.add(member.copyVariable());
29

30
        return record;
31
    }
32

33
    void Object::swap(Object & other)
34
    {
35
        _variables.swap(other._variables);
36
    }
37

38
    bool Object::exists(const std::u16string & name) const
39
    {
40
        auto it = find_if(_variables.begin(), _variables.end(), [name](const Variable & v){
41
            return v.name() == name;
42
        });
43

44
        return it != _variables.end();
45
    }
46

47
    const Value & Object::find(const std::u16string & name) const
48
    {
49
        static const Value undef {};
50

51
        auto it = find_if(_variables.begin(), _variables.end(), [name](const Variable & v){
52
            return v.name() == name;
53
        });
54

55
        if (it == _variables.end())
56
            return undef;
57

58
        return it->value();  
59
    }
60

61
    Value & Object::find_mutable(const std::u16string & name)
62
    {
63
        static Value undef {};
64

65
        auto it = find_if(_variables.begin(), _variables.end(), [name](const Variable & v){
66
            return v.name() == name;
67
        });
68

69
        if (it == _variables.end())
70
            return undef;
71

72
        return it->value();
73
    }
74

75
    void Object::reserve(size_t capacity)
76
    {
77
        _variables.reserve(capacity);
78
    }
79

80
    void Object::add(const Variable & variable)
81
    {
82
        auto it = std::find_if(_variables.begin(), _variables.end(),
83
                [variable](const Variable & v){
84
                    return v.name() == variable.name();
85
                });
86

87
        if (it != _variables.end())
88
            throw bormental::DrBormental("Object::add", 
89
                                        inout::fmt("The element named '%1' already exists")
90
                                        .arg(variable.name()));
91

92
        _variables.push_back(variable);
93
    }
94

95
    void Object::set(const Variable & variable)
96
    {
97
        auto it = std::find_if(_variables.begin(), _variables.end(),
98
                [variable](const Variable & v){
99
                    return v.name() == variable.name();
100
                });
101

102
        if (it != _variables.end())
103
            it->setValue(variable.value());
104
        else
105
            _variables.push_back(variable);
106
    }
107

108
    void Object::remove(const std::u16string & name)
109
    {
110
        auto it = std::find_if(_variables.begin(), _variables.end(),
111
                [name](const variable::Variable & v)
112
                { 
113
                    return v.name() == name; 
114
                });
115

116
        if (it == _variables.end())
117
            _variables.erase(it);
118
    }
119

120
    const Variable & Object::getVariableByName(const std::u16string & name) const
121
    {
122
        static const Variable undef {};
123

124
        auto it = find_if(_variables.begin(), _variables.end(), [name](const Variable & v){
125
            return v.name() == name;
126
        });
127

128
        if (it == _variables.end())
129
            return undef;
130

131
        return *it;  
132
    }
133

134
    Variable & Object::getVariableByName_mutable(const std::u16string & name)
135
    {
136
        return const_cast<Variable &>(getVariableByName(name));
137
    }
138

139
    const Variable & Object::getVariableByIndex(index_t index) const 
140
    {
141
        if (index >= _variables.size())
142
            throw bormental::DrBormental("Object::getVariableByIndex", inout::fmt("Out of index"));
143

144
        return _variables[index];
145
    }
146

147
    Variable & Object::getVariableByIndex_mutable(index_t index) 
148
    {
149
        return const_cast<Variable &>(getVariableByIndex(index));
150
    }
151

152
    void Object::resetInternalParents(std::shared_ptr<Object> parent)
153
    {
154
        assert(parent.get() == this);
155

156
        for(Variable & v : _variables)
157
            if (v.type() == ValueType::Function)
158
                v.value().setInternalParent(parent);
159
    }
160

161
    std::shared_ptr<Object> Object::getInternalParent() const
162
    {
163
        assert(!_variables.empty());
164

165
        const variable::Variable & function_core = getVariableByIndex(0);
166

167
        assert(function_core.type() == variable::ValueType::IntFunction);
168

169
        return function_core.value().getInternalParent();
170
    }
171

172
    Value Object::invoke(const std::u16string & method_name, const VariableSet_t & arguments)
173
    {
174
        const Variable & function = getVariableByName(method_name);
175
        if (function.type() == variable::ValueType::Null) 
176
            return {};
177

178
        if (function.type() != variable::ValueType::Function) 
179
            return {};
180

181
        try
182
        {
183
            FunctionWrapper            func(function);
184
            VariableSet_t              args_mutable = arguments;
185
            VariableSetWrapper_mutable args(args_mutable);
186
            
187
            return func.invoke(args);
188
        }
189
        catch(const std::exception & e)
190
        {
191
        }
192
        
193
        return {};
194
    }
195

196
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.