GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
boxed_value.hpp
Go to the documentation of this file.
1// This file is distributed under the BSD License.
2// See "license.txt" for details.
3// Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com)
4// Copyright 2009-2017, Jason Turner (jason@emptycrate.com)
5// http://www.chaiscript.com
6
7// This is an open source non-commercial project. Dear PVS-Studio, please check it.
8// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
9
10
11#ifndef CHAISCRIPT_BOXED_VALUE_HPP_
12#define CHAISCRIPT_BOXED_VALUE_HPP_
13
14#include <map>
15#include <memory>
16#include <type_traits>
17
19#include "any.hpp"
20#include "type_info.hpp"
21
22namespace chaiscript
23{
24
28 {
29 public:
31 struct Void_Type
32 {
33 };
34
35 private:
38 struct Data
39 {
40 Data(const Type_Info &ti,
42 bool is_ref,
43 const void *t_void_ptr,
44 bool t_return_value)
45 : m_type_info(ti), m_obj(std::move(to)), m_data_ptr(ti.is_const()?nullptr:const_cast<void *>(t_void_ptr)), m_const_data_ptr(t_void_ptr),
46 m_is_ref(is_ref), m_return_value(t_return_value)
47 {
48 }
49
50 Data &operator=(const Data &rhs)
51 {
52 m_type_info = rhs.m_type_info;
53 m_obj = rhs.m_obj;
54 m_is_ref = rhs.m_is_ref;
55 m_data_ptr = rhs.m_data_ptr;
56 m_const_data_ptr = rhs.m_const_data_ptr;
57 m_return_value = rhs.m_return_value;
58
59 if (rhs.m_attrs)
60 {
61 m_attrs = std::make_unique<std::map<std::string, std::shared_ptr<Data>>>(*rhs.m_attrs);
62 }
63
64 return *this;
65 }
66
67 Data(const Data &) = delete;
68
69 Data(Data &&) = default;
70 Data &operator=(Data &&rhs) = default;
71
72
73 Type_Info m_type_info;
74 chaiscript::detail::Any m_obj;
75 void *m_data_ptr;
76 const void *m_const_data_ptr;
77 std::unique_ptr<std::map<std::string, std::shared_ptr<Data>>> m_attrs;
78 bool m_is_ref;
79 bool m_return_value;
80 };
81
82 struct Object_Data
83 {
84 static auto get(Boxed_Value::Void_Type, bool t_return_value)
85 {
86 return std::make_shared<Data>(
88 chaiscript::detail::Any(),
89 false,
90 nullptr,
91 t_return_value)
92 ;
93 }
94
95 template<typename T>
96 static auto get(const std::shared_ptr<T> *obj, bool t_return_value)
97 {
98 return get(*obj, t_return_value);
99 }
100
101 template<typename T>
102 static auto get(const std::shared_ptr<T> &obj, bool t_return_value)
103 {
104 return std::make_shared<Data>(
106 chaiscript::detail::Any(obj),
107 false,
108 obj.get(),
109 t_return_value
110 );
111 }
112
113 template<typename T>
114 static auto get(std::shared_ptr<T> &&obj, bool t_return_value)
115 {
116 auto ptr = obj.get();
117 return std::make_shared<Data>(
119 chaiscript::detail::Any(std::move(obj)),
120 false,
121 ptr,
122 t_return_value
123 );
124 }
125
126
127
128 template<typename T>
129 static auto get(T *t, bool t_return_value)
130 {
131 return get(std::ref(*t), t_return_value);
132 }
133
134 template<typename T>
135 static auto get(const T *t, bool t_return_value)
136 {
137 return get(std::cref(*t), t_return_value);
138 }
139
140
141 template<typename T>
142 static auto get(std::reference_wrapper<T> obj, bool t_return_value)
143 {
144 auto p = &obj.get();
145 return std::make_shared<Data>(
147 chaiscript::detail::Any(std::move(obj)),
148 true,
149 p,
150 t_return_value
151 );
152 }
153
154 template<typename T>
155 static auto get(std::unique_ptr<T> &&obj, bool t_return_value)
156 {
157 auto ptr = obj.get();
158 return std::make_shared<Data>(
160 chaiscript::detail::Any(std::make_shared<std::unique_ptr<T>>(std::move(obj))),
161 true,
162 ptr,
163 t_return_value
164 );
165 }
166
167 template<typename T>
168 static auto get(T t, bool t_return_value)
169 {
170 auto p = std::make_shared<T>(std::move(t));
171 auto ptr = p.get();
172 return std::make_shared<Data>(
174 chaiscript::detail::Any(std::move(p)),
175 false,
176 ptr,
177 t_return_value
178 );
179 }
180
181 static std::shared_ptr<Data> get()
182 {
183 return std::make_shared<Data>(
184 Type_Info(),
185 chaiscript::detail::Any(),
186 false,
187 nullptr,
188 false
189 );
190 }
191
192 };
193
194 public:
196 template<typename T,
197 typename = typename std::enable_if<!std::is_same<Boxed_Value, typename std::decay<T>::type>::value>::type>
198 explicit Boxed_Value(T &&t, bool t_return_value = false)
199 : m_data(Object_Data::get(std::forward<T>(t), t_return_value))
200 {
201 }
202
204 Boxed_Value() = default;
205
208 Boxed_Value(const Boxed_Value&) = default;
210
211 void swap(Boxed_Value &rhs)
212 {
213 std::swap(m_data, rhs.m_data);
214 }
215
219 {
220 (*m_data) = (*rhs.m_data);
221 return *this;
222 }
223
224 const Type_Info &get_type_info() const noexcept
225 {
226 return m_data->m_type_info;
227 }
228
230 bool is_undef() const noexcept
231 {
232 return m_data->m_type_info.is_undef();
233 }
234
235 bool is_const() const noexcept
236 {
237 return m_data->m_type_info.is_const();
238 }
239
240 bool is_type(const Type_Info &ti) const noexcept
241 {
242 return m_data->m_type_info.bare_equal(ti);
243 }
244
245
246 template<typename T>
247 auto pointer_sentinel(std::shared_ptr<T> &ptr) const
248 {
249 struct Sentinel {
250 Sentinel(std::shared_ptr<T> &t_ptr, Data &data)
251 : m_ptr(t_ptr), m_data(data)
252 {
253 }
254
255 ~Sentinel()
256 {
257 // save new pointer data
258 const auto ptr_ = m_ptr.get().get();
259 m_data.get().m_data_ptr = ptr_;
260 m_data.get().m_const_data_ptr = ptr_;
261 }
262
263 Sentinel& operator=(Sentinel&&s) = default;
264 Sentinel(Sentinel &&s) = default;
265
266 operator std::shared_ptr<T>&() const
267 {
268 return m_ptr.get();
269 }
270
271 Sentinel &operator=(const Sentinel &) = delete;
272 Sentinel(Sentinel&) = delete;
273
274 std::reference_wrapper<std::shared_ptr<T>> m_ptr;
275 std::reference_wrapper<Data> m_data;
276 };
277
278 return Sentinel(ptr, *(m_data.get()));
279 }
280
281 bool is_null() const noexcept
282 {
283 return (m_data->m_data_ptr == nullptr && m_data->m_const_data_ptr == nullptr);
284 }
285
286 const chaiscript::detail::Any & get() const noexcept
287 {
288 return m_data->m_obj;
289 }
290
291 bool is_ref() const noexcept
292 {
293 return m_data->m_is_ref;
294 }
295
296 bool is_return_value() const noexcept
297 {
298 return m_data->m_return_value;
299 }
300
301 void reset_return_value() const noexcept
302 {
303 m_data->m_return_value = false;
304 }
305
306 bool is_pointer() const noexcept
307 {
308 return !is_ref();
309 }
310
311 void *get_ptr() const noexcept
312 {
313 return m_data->m_data_ptr;
314 }
315
316 const void *get_const_ptr() const noexcept
317 {
318 return m_data->m_const_data_ptr;
319 }
320
321 Boxed_Value get_attr(const std::string &t_name)
322 {
323 if (!m_data->m_attrs)
324 {
325 m_data->m_attrs = std::make_unique<std::map<std::string, std::shared_ptr<Data>>>();
326 }
327
328 auto &attr = (*m_data->m_attrs)[t_name];
329 if (attr) {
330 return Boxed_Value(attr, Internal_Construction());
331 } else {
332 Boxed_Value bv; //default construct a new one
333 attr = bv.m_data;
334 return bv;
335 }
336 }
337
339 {
340 if (t_obj.m_data->m_attrs)
341 {
342 m_data->m_attrs = std::make_unique<std::map<std::string, std::shared_ptr<Data>>>(*t_obj.m_data->m_attrs);
343 }
344 return *this;
345 }
346
348 {
349 copy_attrs(t_obj);
351 return *this;
352 }
353
354
356 static bool type_match(const Boxed_Value &l, const Boxed_Value &r) noexcept
357 {
358 return l.get_type_info() == r.get_type_info();
359 }
360
361 private:
362 // necessary to avoid hitting the templated && constructor of Boxed_Value
363 struct Internal_Construction{};
364
365 Boxed_Value(std::shared_ptr<Data> t_data, Internal_Construction)
366 : m_data(std::move(t_data)) {
367 }
368
369 std::shared_ptr<Data> m_data = Object_Data::get();
370 };
371
386 template<typename T>
388 {
389 return Boxed_Value(std::forward<T>(t));
390 }
391
392 namespace detail {
397 template<typename T>
399 {
400 return Boxed_Value(std::make_shared<typename std::add_const<T>::type >(t));
401 }
402
408 template<typename T>
410 {
411 return Boxed_Value( const_cast<typename std::add_const<T>::type *>(t) );
412 }
413
419 template<typename T>
420 Boxed_Value const_var_impl(const std::shared_ptr<T> &t)
421 {
422 return Boxed_Value( std::const_pointer_cast<typename std::add_const<T>::type>(t) );
423 }
424
430 template<typename T>
431 Boxed_Value const_var_impl(const std::reference_wrapper<T> &t)
432 {
433 return Boxed_Value( std::cref(t.get()) );
434 }
435 }
436
460 template<typename T>
462 {
463 return detail::const_var_impl(t);
464 }
465
467 static const auto v = Boxed_Value(Boxed_Value::Void_Type());
468 return v;
469 }
470
471 inline Boxed_Value const_var(bool b) {
472 static const auto t = detail::const_var_impl(true);
473 static const auto f = detail::const_var_impl(false);
474
475 if (b) {
476 return t;
477 } else {
478 return f;
479 }
480 }
481
482}
483
484#endif
485
Definition Graph.hh:6965
A wrapper for holding any valid C++ type. All types in ChaiScript are Boxed_Value objects.
Definition boxed_value.hpp:28
Boxed_Value & operator=(const Boxed_Value &)=default
bool is_ref() const noexcept
Definition boxed_value.hpp:291
Boxed_Value(Boxed_Value &&)=default
bool is_pointer() const noexcept
Definition boxed_value.hpp:306
void * get_ptr() const noexcept
Definition boxed_value.hpp:311
Boxed_Value & operator=(Boxed_Value &&)=default
const void * get_const_ptr() const noexcept
Definition boxed_value.hpp:316
Boxed_Value(const Boxed_Value &)=default
Boxed_Value(T &&t, bool t_return_value=false)
Basic Boxed_Value constructor.
Definition boxed_value.hpp:198
Boxed_Value & clone_attrs(const Boxed_Value &t_obj)
Definition boxed_value.hpp:347
bool is_const() const noexcept
Definition boxed_value.hpp:235
Boxed_Value assign(const Boxed_Value &rhs)
Definition boxed_value.hpp:218
const chaiscript::detail::Any & get() const noexcept
Definition boxed_value.hpp:286
bool is_type(const Type_Info &ti) const noexcept
Definition boxed_value.hpp:240
bool is_null() const noexcept
Definition boxed_value.hpp:281
bool is_undef() const noexcept
return true if the object is uninitialized
Definition boxed_value.hpp:230
const Type_Info & get_type_info() const noexcept
Definition boxed_value.hpp:224
void swap(Boxed_Value &rhs)
Definition boxed_value.hpp:211
void reset_return_value() const noexcept
Definition boxed_value.hpp:301
static bool type_match(const Boxed_Value &l, const Boxed_Value &r) noexcept
Definition boxed_value.hpp:356
Boxed_Value & copy_attrs(const Boxed_Value &t_obj)
Definition boxed_value.hpp:338
bool is_return_value() const noexcept
Definition boxed_value.hpp:296
Boxed_Value()=default
Unknown-type constructor.
auto pointer_sentinel(std::shared_ptr< T > &ptr) const
Definition boxed_value.hpp:247
Boxed_Value get_attr(const std::string &t_name)
Definition boxed_value.hpp:321
Compile time deduced information about a type.
Definition type_info.hpp:34
Definition any.hpp:42
lazy data
Definition meshpage.php:1583
Boxed_Value const_var_impl(const T &t)
Takes a value, copies it and returns a Boxed_Value object that is immutable.
Definition boxed_value.hpp:398
Namespace chaiscript contains every API call that the average user will be concerned with.
Boxed_Value void_var()
Definition boxed_value.hpp:466
Boxed_Value var(T &&t)
Creates a Boxed_Value. If the object passed in is a value type, it is copied. If it is a pointer,...
Definition boxed_value.hpp:387
Boxed_Value const_var(const T &t)
Takes an object and returns an immutable Boxed_Value. If the object is a std::reference or pointer ty...
Definition boxed_value.hpp:461
STL namespace.
double f(const std::string &, double, bool) noexcept
Definition profile_cpp_calls_2.cpp:4
Definition GameApi.h:42
used for explicitly creating a "void" object
Definition boxed_value.hpp:32
static constexpr Type_Info get()
Definition type_info.hpp:138