Covellite++  Version: 2.3.0 Revision: ??? Platform: x64 Build: 23:13 04.01.2025
Кроссплатформенный фреймворк для разработки приложений на С++
Загрузка...
Поиск...
Не найдено
Component.inl
1
2#pragma once
3#include <Covellite/Api/Component.hpp>
4#include <boost/core/ignore_unused.hpp>
5#include <alicorn/std.memory.hpp>
6
7namespace covellite
8{
9
10namespace api
11{
12
29inline /*static*/ auto Component::Make(const SourceParams_t & _Params) -> ComponentPtr_t
30{
31 Params_t Params;
32
33 for (const auto & Param : _Params)
34 {
35 auto & Value = Params[GetHash(Param.first)];
36 Value.hType = Param.second.type().hash_code();
37 Value.Value = Param.second;
38 }
39
40 using Pool_t = ::alicorn::extension::std::pool<>;
41
42 return Pool_t::make_unique<Component>(Params, ConstructorTag{});
43}
44
55inline /*static*/ size_t Component::GetHash(const Name_t & _Value)
56{
57 static const Hasher_t Hasher;
58 return Hasher(_Value);
59}
60
74inline Component::Component(const Params_t & _Params, ConstructorTag _Tag) :
75 m_Params(_Params),
76 Id((*this)[GetHashId()].Default(uT("Unknown"))),
77 Type((*this)[GetHashType()].Default(uT("Unknown"))),
78 Kind((*this)[GetHashKind()].Default(uT("Unknown")))
79{
80 ::boost::ignore_unused(_Tag);
81}
82
92template<class T>
93inline bool Component::Param::IsType(void) const
94{
95 static const auto hTType = typeid(T).hash_code();
96 return (this->hType == hTType);
97}
98
107template<class T>
108inline Component::Param & Component::Param::Default(const T & _Value)
109{
110 if (!::covellite::has_value(this->Value)) Set(_Value);
111 return *this;
112}
113
114template<typename S, typename T>
115class is_streamable
116{
117 template<typename SS, typename TT>
118 static auto test(int) -> decltype(
119 ::std::declval<SS &>() << ::std::declval<TT>(), ::std::true_type());
120
121 template<typename, typename>
122 static auto test(...) -> ::std::false_type;
123
124public:
125 static const bool value = decltype(test<S, T>(0))::value;
126};
127
128template<bool>
129class Component::Convertor
130{
131public:
132 template<class T>
133 static T To(const String_t &)
134 {
135 // Функция никогда не вызывается, потребовалась исключительно из-за того,
136 // что ::boost::lexical_cast<T>() не компилируется для указателей и
137 // не streamable'ных типов.
138 throw 0;
139 }
140};
141
142template<>
143class Component::Convertor<true>
144{
145public:
146 template<class T>
147 inline static T To(const String_t & _Value)
148 {
149 return ::boost::lexical_cast<T>(_Value);
150 }
151};
152
168template<class T>
169Component::Param::operator T & (void)
170{
171 try
172 {
173 return ::covellite::any_cast<T &>(this->Value);
174 }
175 catch (const ::std::exception &)
176 {
177 // значение еще не было присвоено или параметр содержит значение другого типа
178 }
179
180 if (IsType<String_t>())
181 {
182 using TType_t = typename ::std::remove_const<T>::type;
183
184 constexpr auto IsConvertable =
185 !::std::is_pointer<T>::value &&
186 !::std::is_reference<T>::value &&
187 is_streamable<::std::iostream, TType_t>::value;
188
189 Set(Convertor<IsConvertable>::template To<TType_t>(
190 ::covellite::any_cast<const String_t &>(this->Value)));
191 }
192
193 return ::covellite::any_cast<T &>(this->Value);
194}
195
196template<class T>
197Component::Param::operator const T & (void) const
198{
199 return ::covellite::any_cast<const T &>(this->Value);
200}
201
214template<class T>
215Component::Param & Component::Param::operator= (const T & _Value)
216{
217 try
218 {
219 // 09 Октябрь 2020 10:43 (unicornum.verum@gmail.com)
220 TODO("Убрать оптимизацию присваивания по ссылке для std::any");
221 // Оптимизация присваивания по ссылке была сделана из-за того, что
222 // boost::any создавал новый объект (оператором new!) КАЖДЫЙ раз при
223 // присваивании нового значения, для std::any это не так.
224
225 ::covellite::any_cast<T &>(this->Value) = _Value;
226 return *this;
227 }
228 catch (const ::std::exception &)
229 {
230 // значение еще не было присвоено или параметр содержит значение другого типа
231 }
232
233 Set(_Value);
234 return *this;
235}
236
237template<class T>
238inline void Component::Param::Set(const T & _Value)
239{
240 static const auto hTType = typeid(T).hash_code();
241
242 this->Value = _Value;
243 this->hType = hTType;
244}
245
253inline Component::Param & Component::operator[] (const Name_t & _Name)
254{
255 return (*this)[GetHash(_Name)];
256}
257
265inline Component::Param & Component::operator[] (const size_t & _Hash)
266{
267 return m_Params[_Hash];
268}
269
280inline const Component::Param & Component::operator[] (const Name_t & _Name) const
281{
282 return (*this)[GetHash(_Name)];
283}
284
295inline const Component::Param & Component::operator[] (const size_t & _Hash) const
296{
297 const auto itParam = m_Params.find(_Hash);
298 if (itParam == ::std::end(m_Params))
299 {
300 throw STD_EXCEPTION << "Unknown parameter: " << _Hash;
301 }
302
303 return itParam->second;
304}
305
306inline /*static*/ size_t Component::GetHashId(void)
307{
308 static const size_t Hash = GetHash(uT("id"));
309 return Hash;
310}
311
312inline /*static*/ size_t Component::GetHashType(void)
313{
314 static const size_t Hash = GetHash(uT("type"));
315 return Hash;
316}
317
318inline /*static*/ size_t Component::GetHashKind(void)
319{
320 static const size_t Hash = GetHash(uT("kind"));
321 return Hash;
322}
323
324} // namespace api
325
326} // namespace covellite
Component(const Params_t &, ConstructorTag)
Конструктор класса.
Definition Component.inl:74
Param & operator[](const Name_t &)
Оператор получения временной переменной для доступа к параметру компонента.
Definition Component.inl:253
static ComponentPtr_t Make(const SourceParams_t &)
Функция создания объектов компонентов.
Definition Component.inl:29
static size_t GetHash(const Name_t &)
Функция получения хеша для имени параметра.
Definition Component.inl:55