GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
bootstrap_stl.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
15
16
17#ifndef CHAISCRIPT_BOOTSTRAP_STL_HPP_
18#define CHAISCRIPT_BOOTSTRAP_STL_HPP_
19
20#include <functional>
21#include <memory>
22#include <stdexcept>
23#include <typeinfo>
24#include <vector>
25
26#include "bootstrap.hpp"
27#include "boxed_value.hpp"
28#include "dispatchkit.hpp"
29#include "operators.hpp"
31#include "register_function.hpp"
32#include "type_info.hpp"
33
34namespace chaiscript
35{
36 namespace bootstrap
37 {
39 {
40
44 template<typename Container, typename IterType>
46 {
48
50 : m_begin(c.begin()), m_end(c.end())
51 {
52 }
53
54 bool empty() const
55 {
56 return m_begin == m_end;
57 }
58
59 void pop_front()
60 {
61 if (empty())
62 {
63 throw std::range_error("Range empty");
64 }
65 ++m_begin;
66 }
67
68 void pop_back()
69 {
70 if (empty())
71 {
72 throw std::range_error("Range empty");
73 }
74 --m_end;
75 }
76
77 decltype(auto) front() const
78 {
79 if (empty())
80 {
81 throw std::range_error("Range empty");
82 }
83 return (*m_begin);
84 }
85
86 decltype(auto) back() const
87 {
88 if (empty())
89 {
90 throw std::range_error("Range empty");
91 }
92 auto pos = m_end;
93 --pos;
94 return (*(pos));
95 }
96
97 IterType m_begin;
98 IterType m_end;
99 };
100
101 namespace detail {
102
103 template<typename T>
104 size_t count(const T &t_target, const typename T::key_type &t_key)
105 {
106 return t_target.count(t_key);
107 }
108
109 template<typename T>
110 void insert(T &t_target, const T &t_other)
111 {
112 t_target.insert(t_other.begin(), t_other.end());
113 }
114
115 template<typename T>
116 void insert_ref(T &t_target, const typename T::value_type &t_val)
117 {
118 t_target.insert(t_val);
119 }
120
121
122
124 template<typename Bidir_Type>
125 void input_range_type_impl(const std::string &type, Module& m)
126 {
127 m.add(user_type<Bidir_Type>(), type + "_Range");
128
129 copy_constructor<Bidir_Type>(type + "_Range", m);
130
131 m.add(constructor<Bidir_Type (typename Bidir_Type::container_type &)>(), "range_internal");
132
133 m.add(fun(&Bidir_Type::empty), "empty");
134 m.add(fun(&Bidir_Type::pop_front), "pop_front");
135 m.add(fun(&Bidir_Type::front), "front");
136 m.add(fun(&Bidir_Type::pop_back), "pop_back");
137 m.add(fun(&Bidir_Type::back), "back");
138 }
139
140
142 template<typename Type>
143 void insert_at(Type &container, int pos, const typename Type::value_type &v)
144 {
145 auto itr = container.begin();
146 auto end = container.end();
147
148 if (pos < 0 || std::distance(itr, end) < pos)
149 {
150 throw std::range_error("Cannot insert past end of range");
151 }
152
153 std::advance(itr, pos);
154 container.insert(itr, v);
155 }
156
157
159 template<typename Type>
160 void erase_at(Type &container, int pos)
161 {
162 auto itr = container.begin();
163 auto end = container.end();
164
165 if (pos < 0 || std::distance(itr, end) < (pos-1))
166 {
167 throw std::range_error("Cannot erase past end of range");
168 }
169
170 std::advance(itr, pos);
171 container.erase(itr);
172 }
173 }
174
175 template<typename ContainerType>
181 template<typename ContainerType>
182 ModulePtr input_range_type(const std::string &type)
183 {
184 auto m = std::make_shared<Module>();
186 return m;
187 }
188
189
192 template<typename ContainerType>
193 void random_access_container_type(const std::string &/*type*/, Module& m)
194 {
195 //In the interest of runtime safety for the m, we prefer the at() method for [] access,
196 //to throw an exception in an out of bounds condition.
197 m.add(
198 fun(
199 [](ContainerType &c, int index) -> typename ContainerType::reference {
202 return c.at(static_cast<typename ContainerType::size_type>(index));
203 }), "[]");
204
205 m.add(
206 fun(
207 [](const ContainerType &c, int index) -> typename ContainerType::const_reference {
210 return c.at(static_cast<typename ContainerType::size_type>(index));
211 }), "[]");
212 }
213 template<typename ContainerType>
215 {
216 auto m = std::make_shared<Module>();
218 return m;
219 }
220
221
222
225 template<typename ContainerType>
226 void assignable_type(const std::string &type, Module& m)
227 {
230 }
231 template<typename ContainerType>
232 ModulePtr assignable_type(const std::string &type)
233 {
234 auto m = std::make_shared<Module>();
236 return m;
237 }
238
239
242 template<typename ContainerType>
243 void resizable_type(const std::string &/*type*/, Module& m)
244 {
245 m.add(fun([](ContainerType *a, typename ContainerType::size_type n, const typename ContainerType::value_type& val) { return a->resize(n, val); } ), "resize");
246 m.add(fun([](ContainerType *a, typename ContainerType::size_type n) { return a->resize(n); } ), "resize");
247 }
248 template<typename ContainerType>
249 ModulePtr resizable_type(const std::string &type)
250 {
251 auto m = std::make_shared<Module>();
253 return m;
254 }
255
256
259 template<typename ContainerType>
260 void reservable_type(const std::string &/*type*/, Module& m)
261 {
262 m.add(fun([](ContainerType *a, typename ContainerType::size_type n) { return a->reserve(n); } ), "reserve");
263 m.add(fun([](const ContainerType *a) { return a->capacity(); } ), "capacity");
264 }
265 template<typename ContainerType>
266 ModulePtr reservable_type(const std::string &type)
267 {
268 auto m = std::make_shared<Module>();
270 return m;
271 }
272
273
276 template<typename ContainerType>
277 void container_type(const std::string &/*type*/, Module& m)
278 {
279 m.add(fun([](const ContainerType *a) { return a->size(); } ), "size");
280 m.add(fun([](const ContainerType *a) { return a->empty(); } ), "empty");
281 m.add(fun([](ContainerType *a) { a->clear(); } ), "clear");
282 }
283 template <typename ContainerType>
284 ModulePtr container_type(const std::string& type)
285 {
286 auto m = std::make_shared<Module>();
288 return m;
289 }
290
291
294 template<typename Type>
295 void default_constructible_type(const std::string &type, Module& m)
296 {
297 m.add(constructor<Type ()>(), type);
298 }
299 template <typename Type>
300 ModulePtr default_constructible_type(const std::string& type)
301 {
302 auto m = std::make_shared<Module>();
304 return m;
305 }
306
307
308
311 template<typename ContainerType>
312 void sequence_type(const std::string &/*type*/, Module& m)
313 {
315 []()->std::string{
316 if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
317 return "insert_ref_at";
318 } else {
319 return "insert_at";
320 }
321 }());
322
323 m.add(fun(&detail::erase_at<ContainerType>), "erase_at");
324 }
325 template <typename ContainerType>
326 ModulePtr sequence_type(const std::string &type)
327 {
328 auto m = std::make_shared<Module>();
330 return m;
331 }
332
335 template<typename ContainerType>
336 void back_insertion_sequence_type(const std::string &type, Module& m)
337 {
338 m.add(fun([](ContainerType &container)->decltype(auto){
339 if (container.empty()) {
340 throw std::range_error("Container empty");
341 } else {
342 return (container.back());
343 }
344 }
345 )
346 , "back");
347 m.add(fun([](const ContainerType &container)->decltype(auto){
348 if (container.empty()) {
349 throw std::range_error("Container empty");
350 } else {
351 return (container.back());
352 }
353 }
354 )
355 , "back");
356
357
358 typedef void (ContainerType::*push_back)(const typename ContainerType::value_type &);
359 m.add(fun(static_cast<push_back>(&ContainerType::push_back)),
360 [&]()->std::string{
361 if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
362 m.eval(
363 "# Pushes the second value onto the container while making a clone of the value\n"
364 "def push_back(" + type + " container, x)\n"
365 "{ \n"
366 " if (x.is_var_return_value()) {\n"
367 " x.reset_var_return_value() \n"
368 " container.push_back_ref(x) \n"
369 " } else { \n"
370 " container.push_back_ref(clone(x)); \n"
371 " }\n"
372 "} \n"
373 );
374
375 return "push_back_ref";
376 } else {
377 return "push_back";
378 }
379 }());
380
381 m.add(fun(&ContainerType::pop_back), "pop_back");
382 }
383 template<typename ContainerType>
385 {
386 auto m = std::make_shared<Module>();
388 return m;
389 }
390
391
392
395 template<typename ContainerType>
396 void front_insertion_sequence_type(const std::string &type, Module& m)
397 {
398 typedef void (ContainerType::*push_ptr)(typename ContainerType::const_reference);
399 typedef void (ContainerType::*pop_ptr)();
400
401 m.add(fun([](ContainerType &container)->decltype(auto){
402 if (container.empty()) {
403 throw std::range_error("Container empty");
404 } else {
405 return (container.front());
406 }
407 }
408 )
409 , "front");
410
411 m.add(fun([](const ContainerType &container)->decltype(auto){
412 if (container.empty()) {
413 throw std::range_error("Container empty");
414 } else {
415 return (container.front());
416 }
417 }
418 )
419 , "front");
420
421
422 m.add(fun(static_cast<push_ptr>(&ContainerType::push_front)),
423 [&]()->std::string{
424 if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) {
425 m.eval(
426 "# Pushes the second value onto the front of container while making a clone of the value\n"
427 "def push_front(" + type + " container, x)\n"
428 "{ \n"
429 " if (x.is_var_return_value()) {\n"
430 " x.reset_var_return_value() \n"
431 " container.push_front_ref(x) \n"
432 " } else { \n"
433 " container.push_front_ref(clone(x)); \n"
434 " }\n"
435 "} \n"
436 );
437 return "push_front_ref";
438 } else {
439 return "push_front";
440 }
441 }());
442
443 m.add(fun(static_cast<pop_ptr>(&ContainerType::pop_front)), "pop_front");
444 }
445 template<typename ContainerType>
447 {
448 auto m = std::make_shared<Module>();
450 return m;
451 }
452
453
456 template<typename PairType>
457 void pair_type(const std::string &type, Module& m)
458 {
459 m.add(user_type<PairType>(), type);
460
461 m.add(fun(&PairType::first), "first");
462 m.add(fun(&PairType::second), "second");
463
465 m.add(constructor<PairType (const typename PairType::first_type &, const typename PairType::second_type &)>(), type);
466 }
467 template<typename PairType>
468 ModulePtr pair_type(const std::string &type)
469 {
470 auto m = std::make_shared<Module>();
471 pair_type<PairType>(type, *m);
472 return m;
473 }
474
475
476
479
480 template<typename ContainerType>
481 void pair_associative_container_type(const std::string &type, Module& m)
482 {
484 }
485 template<typename ContainerType>
487 {
488 auto m = std::make_shared<Module>();
490 return m;
491 }
492
493
496 template<typename ContainerType>
497 void unique_associative_container_type(const std::string &/*type*/, Module& m)
498 {
500
501 typedef size_t (ContainerType::*erase_ptr)(const typename ContainerType::key_type &);
502
503 m.add(fun(static_cast<erase_ptr>(&ContainerType::erase)), "erase");
504
506
508 []()->std::string{
509 if (typeid(typename ContainerType::mapped_type) == typeid(Boxed_Value)) {
510 return "insert_ref";
511 } else {
512 return "insert";
513 }
514 }());
515 }
516 template<typename ContainerType>
518 {
519 auto m = std::make_shared<Module>();
521 return m;
522 }
523
524
527 template<typename MapType>
528 void map_type(const std::string &type, Module& m)
529 {
530 m.add(user_type<MapType>(), type);
531
532 typedef typename MapType::mapped_type &(MapType::*elem_access)(const typename MapType::key_type &);
533 typedef const typename MapType::mapped_type &(MapType::*const_elem_access)(const typename MapType::key_type &) const;
534
535 m.add(fun(static_cast<elem_access>(&MapType::operator[])), "[]");
536
537 m.add(fun(static_cast<elem_access>(&MapType::at)), "at");
538 m.add(fun(static_cast<const_elem_access>(&MapType::at)), "at");
539
540 if (typeid(MapType) == typeid(std::map<std::string, Boxed_Value>))
541 {
542 m.eval(R"(
543 def Map::`==`(Map rhs) {
544 if ( rhs.size() != this.size() ) {
545 return false;
546 } else {
547 auto r1 = range(this);
548 auto r2 = range(rhs);
549 while (!r1.empty())
550 {
551 if (!eq(r1.front().first, r2.front().first) || !eq(r1.front().second, r2.front().second))
552 {
553 return false;
555 r1.pop_front();
556 r2.pop_front();
557 }
558 true;
559 }
560 } )"
561 );
562 }
563
570 }
571 template<typename MapType>
572 ModulePtr map_type(const std::string &type)
573 {
574 auto m = std::make_shared<Module>();
575 map_type<MapType>(type, *m);
576 return m;
577 }
579
581 template<typename ListType>
582 void list_type(const std::string &type, Module& m)
583 {
584 m.add(user_type<ListType>(), type);
585
594 }
595 template<typename ListType>
596 ModulePtr list_type(const std::string &type)
597 {
598 auto m = std::make_shared<Module>();
599 list_type<ListType>(type, m);
600 return m;
601 }
602
603
606 template<typename VectorType>
607 void vector_type(const std::string &type, Module& m)
608 {
609 m.add(user_type<VectorType>(), type);
610
611 m.add(fun([](VectorType &container)->decltype(auto){
612 if (container.empty()) {
613 throw std::range_error("Container empty");
614 } else {
615 return (container.front());
616 }
617 }
618 )
619 , "front");
620
621 m.add(fun([](const VectorType &container)->decltype(auto){
622 if (container.empty()) {
623 throw std::range_error("Container empty");
624 } else {
625 return (container.front());
626 }
627 }
628 )
629 , "front");
630
631
632
644 if (typeid(VectorType) == typeid(std::vector<Boxed_Value>))
645 {
646 m.eval(R"(
647 def Vector::`==`(Vector rhs) {
648 if ( rhs.size() != this.size() ) {
649 return false;
650 } else {
651 auto r1 = range(this);
652 auto r2 = range(rhs);
653 while (!r1.empty())
654 {
655 if (!eq(r1.front(), r2.front()))
656 {
657 return false;
658 }
659 r1.pop_front();
660 r2.pop_front();
661 }
662 true;
663 }
664 } )"
665 );
666 }
667 }
668 template<typename VectorType>
669 ModulePtr vector_type(const std::string &type)
670 {
671 auto m = std::make_shared<Module>();
672 vector_type<VectorType>(type, *m);
673 return m;
674 }
675
678 template<typename String>
679 void string_type(const std::string &type, Module& m)
680 {
681 m.add(user_type<String>(), type);
686 sequence_type<String>(type, m);
688 // container_type<String>(type, m);
691
692 //Special case: add push_back to string (which doesn't support other back_insertion operations
693 m.add(fun(&String::push_back),
694 []()->std::string{
695 if (typeid(typename String::value_type) == typeid(Boxed_Value)) {
696 return "push_back_ref";
697 } else {
698 return "push_back";
699 }
700 }());
701
702
703 m.add(fun([](const String *s, const String &f, size_t pos) { return s->find(f, pos); } ), "find");
704 m.add(fun([](const String *s, const String &f, size_t pos) { return s->rfind(f, pos); } ), "rfind");
705 m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_of(f, pos); } ), "find_first_of");
706 m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_of(f, pos); } ), "find_last_of");
707 m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_last_not_of(f, pos); } ), "find_last_not_of");
708 m.add(fun([](const String *s, const String &f, size_t pos) { return s->find_first_not_of(f, pos); } ), "find_first_not_of");
709
710 m.add(fun([](String *s, typename String::value_type c) -> decltype(auto) { return (*s += c); } ), "+=");
711
712 m.add(fun([](String *s) { s->clear(); } ), "clear");
713 m.add(fun([](const String *s) { return s->empty(); } ), "empty");
714 m.add(fun([](const String *s) { return s->size(); } ), "size");
715
716 m.add(fun([](const String *s) { return s->c_str(); } ), "c_str");
717 m.add(fun([](const String *s) { return s->data(); } ), "data");
718 m.add(fun([](const String *s, size_t pos, size_t len) { return s->substr(pos, len); } ), "substr");
719 }
720 template<typename String>
721 ModulePtr string_type(const std::string &type)
722 {
723 auto m = std::make_shared<Module>();
724 string_type<String>(type, *m);
725 return m;
726 }
727
728
729
732 template<typename FutureType>
733 void future_type(const std::string &type, Module& m)
734 {
735 m.add(user_type<FutureType>(), type);
736
737 m.add(fun([](const FutureType &t) { return t.valid(); }), "valid");
738 m.add(fun([](FutureType &t) { return t.get(); }), "get");
739 m.add(fun(&FutureType::wait), "wait");
740 }
741 template<typename FutureType>
742 ModulePtr future_type(const std::string &type)
743 {
744 auto m = std::make_shared<Module>();
745 future_type<FutureType>(type, *m);
746 return m;
747 }
748 }
749 }
750}
751
752
753#endif
754
755
Type
Definition Database.hh:9
SM String(std::string s)
Definition Language.hh:977
Definition Containment.hh:34
A wrapper for holding any valid C++ type. All types in ChaiScript are Boxed_Value objects.
Definition boxed_value.hpp:28
Holds a collection of ChaiScript settings which can be applied to the ChaiScript runtime....
Definition dispatchkit.hpp:150
Module & add(Type_Info ti, std::string name)
Definition dispatchkit.hpp:152
Module & eval(const std::string &str)
Definition dispatchkit.hpp:183
void assign(Module &m)
Definition operators.hpp:24
void addition(Module &m)
Definition operators.hpp:144
void assign_sum(Module &m)
Definition operators.hpp:84
Definition bootstrap_stl.hpp:101
size_t count(const T &t_target, const typename T::key_type &t_key)
Definition bootstrap_stl.hpp:104
void insert_ref(T &t_target, const typename T::value_type &t_val)
Definition bootstrap_stl.hpp:116
void insert_at(Type &container, int pos, const typename Type::value_type &v)
Algorithm for inserting at a specific position into a container.
Definition bootstrap_stl.hpp:143
void input_range_type_impl(const std::string &type, Module &m)
Add Bidir_Range support for the given ContainerType.
Definition bootstrap_stl.hpp:125
void erase_at(Type &container, int pos)
Algorithm for erasing a specific position from a container.
Definition bootstrap_stl.hpp:160
void insert(T &t_target, const T &t_other)
Definition bootstrap_stl.hpp:110
Definition bootstrap_stl.hpp:39
void vector_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:589
void assignable_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:226
void map_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:528
void container_type(const std::string &, Module &m)
Definition bootstrap_stl.hpp:277
void list_type(const std::string &type, Module &m)
http://www.sgi.com/tech/stl/List.html
Definition bootstrap_stl.hpp:564
void input_range_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:176
void sequence_type(const std::string &, Module &m)
Definition bootstrap_stl.hpp:312
void back_insertion_sequence_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:336
void pair_associative_container_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:481
void random_access_container_type(const std::string &, Module &m)
Definition bootstrap_stl.hpp:193
void future_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:697
void reservable_type(const std::string &, Module &m)
Definition bootstrap_stl.hpp:260
void front_insertion_sequence_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:396
void resizable_type(const std::string &, Module &m)
Definition bootstrap_stl.hpp:243
void string_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:643
void unique_associative_container_type(const std::string &, Module &m)
Definition bootstrap_stl.hpp:497
void pair_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:457
void default_constructible_type(const std::string &type, Module &m)
Definition bootstrap_stl.hpp:295
Classes and functions useful for bootstrapping of ChaiScript and adding of new types.
Definition bootstrap.hpp:21
void copy_constructor(const std::string &type, Module &m)
Adds a copy constructor for the given type to the given Model.
Definition bootstrap.hpp:64
void opers_comparison(Module &m)
Add all comparison operators for the templated type. Used during bootstrap, also available to users.
Definition bootstrap.hpp:74
void basic_constructors(const std::string &type, Module &m)
Adds default and copy constructors for the given type.
Definition bootstrap.hpp:94
Namespace chaiscript contains every API call that the average user will be concerned with.
constexpr Type_Info user_type(const T &)
Creates a Type_Info object representing the type passed in.
Definition type_info.hpp:221
Proxy_Function constructor()
Generates a constructor function for use with ChaiScript.
Definition proxy_constructors.hpp:47
Proxy_Function fun(const T &t)
Creates a new Proxy_Function object from a free function, member function or data member.
Definition register_function.hpp:43
constexpr Type_Info user_type()
Creates a Type_Info object representing the templated type.
Definition type_info.hpp:236
std::shared_ptr< Module > ModulePtr
Convenience typedef for Module objects to be added to the ChaiScript runtime.
Definition dispatchkit.hpp:263
double f(const std::string &, double, bool) noexcept
Definition profile_cpp_calls_2.cpp:4
Definition GameApi.h:42
IterType m_begin
Definition bootstrap_stl.hpp:97
void pop_front()
Definition bootstrap_stl.hpp:59
void pop_back()
Definition bootstrap_stl.hpp:68
Bidir_Range(Container &c)
Definition bootstrap_stl.hpp:49
decltype(auto) front() const
Definition bootstrap_stl.hpp:77
bool empty() const
Definition bootstrap_stl.hpp:54
Container container_type
Definition bootstrap_stl.hpp:47
IterType m_end
Definition bootstrap_stl.hpp:98
decltype(auto) back() const
Definition bootstrap_stl.hpp:86