bug fixes for gcc
[luabind.git] / luabind / class.hpp
blob0bc6ed744501cdfd57df785e9b1ae7e823cc2c2e
1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
24 #ifndef LUABIND_CLASS_HPP_INCLUDED
25 #define LUABIND_CLASS_HPP_INCLUDED
28 ISSUES:
29 ------------------------------------------------------
31 * solved for member functions, not application operator *
32 if we have a base class that defines a function a derived class must be able to
33 override that function (not just overload). Right now we just add the other overload
34 to the overloads list and will probably get an ambiguity. If we want to support this
35 each method_rep must include a vector of type_info pointers for each parameter.
36 Operators do not have this problem, since operators always have to have
37 it's own type as one of the arguments, no ambiguity can occur. Application
38 operator, on the other hand, would have this problem.
39 Properties cannot be overloaded, so they should always be overridden.
40 If this is to work for application operator, we really need to specify if an application
41 operator is const or not.
43 If one class registers two functions with the same name and the same
44 signature, there's currently no error. The last registered function will
45 be the one that's used.
46 How do we know which class registered the function? If the function was
47 defined by the base class, it is a legal operation, to override it.
48 we cannot look at the pointer offset, since it always will be zero for one of the bases.
52 TODO:
53 ------------------------------------------------------
55 scopes
56 classes with the same name in different scopes will have the same (fully qualified) name.
57 functions that are renamed will still have the same name in error-messages
59 finish smart pointer support
60 * make sure there are no bugs in the conversion from holder to const_holder
61 * the adopt policy should not be able to adopt pointers to held_types. This
62 must be prohibited.
63 * name_of_type must recognize holder_types and not return "custom"
65 support calling functions on lua threads (i.e. use lua_resume() instead of lua_pcall()).
67 document the new yield-policy more
69 cache finalizers in the class_rep. For lua classes
70 we currently do a lookup each time we need to know if a lua class
71 has a finalizer.
73 static functions, this could be implemented by letting classes contain
74 other declarations (classes or functions)
76 document custom policies, custom converters
78 store the instance object for policies.
80 support the __concat metamethod. This is a bit tricky, since it cannot be
81 treated as a normal operator. It is a binary operator but we want to use the
82 __tostring implementation for both arguments.
86 #include <luabind/config.hpp>
88 #include <string>
89 #include <map>
90 #include <vector>
91 #include <cassert>
93 #include <boost/static_assert.hpp>
94 #include <boost/type_traits.hpp>
95 #include <boost/bind.hpp>
96 #include <boost/function.hpp>
97 #include <boost/preprocessor/repetition/enum_params.hpp>
98 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
99 #include <boost/preprocessor/repetition/repeat.hpp>
100 #include <boost/type_traits/is_same.hpp>
101 #include <boost/mpl/list.hpp>
102 #include <boost/mpl/apply.hpp>
103 #include <boost/mpl/lambda.hpp>
104 #include <boost/mpl/logical.hpp>
105 #include <boost/mpl/find_if.hpp>
106 #include <boost/mpl/apply_if.hpp>
107 #include <boost/mpl/logical.hpp>
109 #include <luabind/config.hpp>
110 #include <luabind/scope.hpp>
111 #include <luabind/detail/constructor.hpp>
112 #include <luabind/detail/call.hpp>
113 #include <luabind/detail/signature_match.hpp>
114 #include <luabind/detail/primitives.hpp>
115 #include <luabind/detail/property.hpp>
116 #include <luabind/detail/typetraits.hpp>
117 #include <luabind/detail/class_rep.hpp>
118 #include <luabind/detail/method_rep.hpp>
119 #include <luabind/detail/construct_rep.hpp>
120 #include <luabind/detail/object_rep.hpp>
121 #include <luabind/detail/operators.hpp>
122 #include <luabind/detail/calc_arity.hpp>
123 #include <luabind/detail/call_member.hpp>
124 #include <luabind/detail/enum_maker.hpp>
125 #include <luabind/detail/get_signature.hpp>
126 #include <luabind/detail/implicit_cast.hpp>
127 #include <luabind/detail/operator_id.hpp>
129 namespace luabind
131 namespace detail
133 struct unspecified {};
136 using detail::type;
138 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
139 struct class_;
141 // TODO: this function will only be invoked if the user hasn't defined a correct overload
142 // maybe we should have a static assert in here?
143 inline detail::null_type* get_const_holder(...)
145 return 0;
148 namespace detail
150 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
151 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
153 #ifndef BOOST_MSVC
154 template<class T>
155 char is_bases_helper(const T&);
156 #else
157 char is_bases_helper(...);
158 #endif
160 template<class T>
161 struct is_bases
163 static const T& t;
165 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
166 typedef boost::mpl::bool_<value> type;
167 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
170 double is_not_unspecified_helper(const unspecified*);
171 char is_not_unspecified_helper(...);
173 template<class T>
174 struct is_not_unspecified
176 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
177 typedef boost::mpl::bool_<value> type;
178 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
181 template<class Predicate>
182 struct get_predicate
184 typedef typename boost::mpl::and_<
185 Predicate
186 , is_not_unspecified<boost::mpl::_1>
187 > type;
190 template<class Parameters, class Predicate, class DefaultValue>
191 struct extract_parameter
193 typedef typename get_predicate<Predicate>::type pred;
194 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
195 typedef typename boost::mpl::apply_if<boost::is_same<iterator, typename boost::mpl::end<Parameters>::type>
196 , boost::mpl::identity<DefaultValue>
197 , iterator
198 >::type type;
201 // TODO: is this detail::class_rep::function_dispatcher or detail::free_functions::function_dispatcher?
202 // LUABIND_API int function_dispatcher(lua_State* L);
204 // this should know about the smart pointer type.
205 // and should really do:
206 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
207 // to extract the held pointer.
208 template<class HeldType, class T, class F, class Policies>
209 struct function_callback_non_null : Policies
211 function_callback_non_null(F f_): f(f_) {}
212 inline int operator()(lua_State* L, void* obj_ptr)
214 HeldType& held_obj = *static_cast<HeldType*>(obj_ptr);
216 T* ptr = static_cast<T*>(luabind::get_pointer(held_obj));
218 return call(f, ptr, L, static_cast<Policies*>(this));
220 F f;
223 template<class T, class F, class Policies>
224 struct function_callback_null_type : Policies
226 function_callback_null_type(F f_): f(f_) {}
227 inline int operator()(lua_State* L, void* obj_ptr)
229 // std::cout << "HeldType: null_type\n";
230 T* ptr = static_cast<T*>(obj_ptr);
231 return call(f, ptr, L, static_cast<Policies*>(this));
233 F f;
236 template<class HeldType, class T, class F, class Policies>
237 struct function_callback_s
239 typedef typename
240 boost::mpl::if_<boost::is_same<HeldType,detail::null_type>
241 , function_callback_null_type<T,F,Policies>
242 , function_callback_non_null<HeldType,T,F,Policies>
243 >::type type;
246 template<class T, class F, class Policies>
247 struct match_function_callback_s
249 static inline int apply(lua_State* L)
251 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
252 F fptr = 0;
253 return match(fptr, L, obj->flags() & object_rep::constant, static_cast<Policies*>(0));
257 // prints the types of the values on the stack, in the
258 // range [start_index, lua_gettop()]
260 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
262 struct LUABIND_API create_class
264 static int stage1(lua_State* L);
265 static int stage2(lua_State* L);
268 template<class Type>
269 struct register_wrapped_type
271 template<class Signature, class Policies>
272 static void apply(detail::construct_rep::overload_t& o, const Signature*, const Policies*)
274 o.set_wrapped_constructor(
275 &detail::construct_wrapped_class<Type, Policies, Signature>::apply
280 template<>
281 struct register_wrapped_type<detail::null_type>
283 template<class Signature, class Policies>
284 static void apply(detail::construct_rep::overload_t&, const Signature*, const Policies*) {}
288 // if the class is held by a smart pointer, we need to be able to
289 // implicitly dereference the pointer when needed.
291 template<class UnderlyingT, class HeldT>
292 struct extract_underlying_type
294 static void* extract(void* ptr)
296 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
297 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
298 return underlying_ptr;
302 template<class UnderlyingT, class HeldT>
303 struct extract_underlying_const_type
305 static const void* extract(void* ptr)
307 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
308 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
309 return underlying_ptr;
313 template<class HeldType>
314 struct internal_holder_extractor
316 typedef void*(*extractor_fun)(void*);
318 template<class T>
319 static extractor_fun apply(detail::type<T>)
321 return &detail::extract_underlying_type<T, HeldType>::extract;
325 template<>
326 struct internal_holder_extractor<detail::null_type>
328 typedef void*(*extractor_fun)(void*);
330 template<class T>
331 static extractor_fun apply(detail::type<T>)
333 return 0;
338 template<class HeldType, class ConstHolderType>
339 struct convert_holder
341 static void apply(void* holder, void* target)
343 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
348 template<class HeldType>
349 struct const_converter
351 typedef void(*converter_fun)(void*, void*);
353 template<class ConstHolderType>
354 static converter_fun apply(ConstHolderType*)
356 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
360 template<>
361 struct const_converter<detail::null_type>
363 typedef void(*converter_fun)(void*, void*);
365 template<class T>
366 static converter_fun apply(T*)
368 return 0;
375 template<class HeldType>
376 struct internal_const_holder_extractor
378 typedef const void*(*extractor_fun)(void*);
380 template<class T>
381 static extractor_fun apply(detail::type<T>)
383 return get_extractor(detail::type<T>(), luabind::get_const_holder(static_cast<HeldType*>(0)));
385 private:
386 template<class T, class ConstHolderType>
387 static extractor_fun get_extractor(detail::type<T>, ConstHolderType*)
389 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
393 template<>
394 struct internal_const_holder_extractor<detail::null_type>
396 typedef const void*(*extractor_fun)(void*);
398 template<class T>
399 static extractor_fun apply(detail::type<T>)
401 return 0;
407 // this is simply a selector that returns the type_info
408 // of the held type, or invalid_type_info if we don't have
409 // a held_type
410 template<class HeldType>
411 struct internal_holder_type
413 static LUABIND_TYPE_INFO apply()
415 return LUABIND_TYPEID(HeldType);
419 template<>
420 struct internal_holder_type<detail::null_type>
422 static LUABIND_TYPE_INFO apply()
424 return LUABIND_INVALID_TYPE_INFO;
429 // this is the actual held_type constructor
430 template<class HeldType, class T>
431 struct internal_construct_holder
433 static void apply(void* target, void* raw_pointer)
435 new(target) HeldType(static_cast<T*>(raw_pointer));
439 // the following two functions are the ones that returns
440 // a pointer to a held_type_constructor, or 0 if there
441 // is no held_type
442 template<class HeldType>
443 struct holder_constructor
445 typedef void(*constructor)(void*,void*);
446 template<class T>
447 static constructor apply(detail::type<T>)
449 return &internal_construct_holder<HeldType, T>::apply;
453 template<>
454 struct holder_constructor<detail::null_type>
456 typedef void(*constructor)(void*,void*);
457 template<class T>
458 static constructor apply(detail::type<T>)
460 return 0;
464 // the following two functions are the ones that returns
465 // a pointer to a const_held_type_constructor, or 0 if there
466 // is no held_type
467 template<class HolderType>
468 struct const_holder_constructor
470 typedef void(*constructor)(void*,void*);
471 template<class T>
472 static constructor apply(detail::type<T>)
474 return get_const_holder_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
477 private:
479 template<class T, class ConstHolderType>
480 static constructor get_const_holder_constructor(detail::type<T>, ConstHolderType*)
482 return &internal_construct_holder<ConstHolderType, T>::apply;
486 template<>
487 struct const_holder_constructor<detail::null_type>
489 typedef void(*constructor)(void*,void*);
490 template<class T>
491 static constructor apply(detail::type<T>)
493 return 0;
499 // this is a selector that returns the size of the held_type
500 // or 0 if we don't have a held_type
501 template <class HolderType>
502 struct internal_holder_size
504 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType*>(0))); }
505 private:
506 template<class ConstHolderType>
507 static int get_internal_holder_size(ConstHolderType*)
509 return max<sizeof(HolderType), sizeof(ConstHolderType)>::value;
513 template <>
514 struct internal_holder_size<detail::null_type>
516 static int apply() { return 0; }
520 // if we have a held type, return the destructor to it
521 // note the difference. The held_type should only be destructed (not deleted)
522 // since it's constructed in the lua userdata
523 template<class HeldType>
524 struct internal_holder_destructor
526 typedef void(*destructor_t)(void*);
527 template<class T>
528 static destructor_t apply(detail::type<T>)
530 return &detail::destruct_only_s<HeldType>::apply;
534 // if we don't have a held type, return the destructor of the raw type
535 template<>
536 struct internal_holder_destructor<detail::null_type>
538 typedef void(*destructor_t)(void*);
539 template<class T>
540 static destructor_t apply(detail::type<T>)
542 return &detail::delete_s<T>::apply;
547 // if we have a held type, return the destructor to it's const version
548 template<class HolderType>
549 struct internal_const_holder_destructor
551 typedef void(*destructor_t)(void*);
552 template<class T>
553 static destructor_t apply(detail::type<T>)
555 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType*>(0)));
558 private:
560 template<class ConstHolderType>
561 static destructor_t const_holder_type_destructor(ConstHolderType*)
563 return &detail::destruct_only_s<ConstHolderType>::apply;
568 // if we don't have a held type, return the destructor of the raw type
569 template<>
570 struct internal_const_holder_destructor<detail::null_type>
572 typedef void(*destructor_t)(void*);
573 template<class T>
574 static destructor_t apply(detail::type<T>)
576 return 0;
583 template<class HolderType>
584 struct get_holder_alignment
586 static int apply()
588 return internal_alignment(luabind::get_const_holder(static_cast<HolderType*>(0)));
591 private:
593 template<class ConstHolderType>
594 static int internal_alignment(ConstHolderType*)
596 return detail::max<boost::alignment_of<HolderType>::value
597 , boost::alignment_of<ConstHolderType>::value>::value;
601 template<>
602 struct get_holder_alignment<detail::null_type>
604 static int apply()
606 return 1;
611 } // detail
626 struct class_base: detail::scoped_object
628 protected:
630 struct base_desc
632 LUABIND_TYPE_INFO type;
633 int ptr_offset;
636 private:
638 #ifndef NDEBUG
639 bool m_cloned;
640 #endif
642 const char* m_name;
644 std::map<const char*, detail::method_rep, detail::ltstr> m_methods;
646 // datamembers, some members may be readonly, and
647 // only have a getter function
648 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_getters;
649 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_setters;
651 // the operators in lua
652 std::vector<detail::class_rep::operator_callback> m_operators[detail::number_of_operators];
653 std::map<const char*, int, detail::ltstr> m_static_constants;
655 std::vector<base_desc> m_bases;
656 detail::construct_rep m_constructor;
658 void(*m_destructor)(void*);
659 void(*m_const_holder_destructor)(void*);
661 void*(*m_extractor)(void*);
662 const void*(*m_const_extractor)(void*);
664 void(*m_const_converter)(void*,void*);
666 void(*m_construct_holder)(void*, void*);
667 void(*m_construct_const_holder)(void*, void*);
669 int m_holder_size;
670 int m_holder_alignment;
672 LUABIND_TYPE_INFO m_type;
673 LUABIND_TYPE_INFO m_holder_type;
674 LUABIND_TYPE_INFO m_const_holder_type;
676 #ifndef LUABIND_DONT_COPY_STRINGS
677 // the maps that contains char pointers points into
678 // this vector of strings.
679 std::vector<char*> m_strings;
680 #endif
682 public:
684 // public 'cause of enum_maker, FIX
685 void add_static_constant(const char* name, int val)
687 m_static_constants[name] = val;
690 protected:
692 void init(LUABIND_TYPE_INFO type
693 , LUABIND_TYPE_INFO holder_type
694 , void*(*extractor)(void*)
695 , const void*(*const_extractor)(void*)
696 , void(*const_converter)(void*,void*)
697 , void(*holder_constructor)(void*,void*)
698 , void(*const_holder_constructor)(void*,void*)
699 , void(*destructor)(void*)
700 , void(*const_holder_destructor)(void*)
701 , int holder_size
702 , int holder_alignment)
704 m_type = type;
705 m_holder_type = holder_type;
706 m_extractor = extractor;
707 m_const_extractor = const_extractor;
708 m_const_converter = const_converter;
709 m_construct_holder = holder_constructor;
710 m_construct_const_holder = const_holder_constructor;
711 m_destructor = destructor;
712 m_const_holder_destructor = const_holder_destructor;
713 m_holder_size = holder_size;
714 m_holder_alignment = holder_alignment;
717 template<class T>
718 void set_const_holder_type(T*)
720 m_const_holder_type = LUABIND_TYPEID(T);
723 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
725 detail::class_rep::callback c;
726 c.func = g;
727 c.pointer_offset = 0;
728 #ifndef LUABIND_DONT_COPY_STRINGS
729 m_strings.push_back(detail::dup_string(name));
730 m_getters[m_strings.back()] = c;
731 #else
732 m_getters[name] = c;
733 #endif
736 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
738 detail::class_rep::callback c;
739 c.func = s;
740 c.pointer_offset = 0;
741 #ifndef LUABIND_DONT_COPY_STRINGS
742 m_strings.push_back(detail::dup_string(name));
743 m_setters[m_strings.back()] = c;
744 #else
745 m_setters[name] = c;
746 #endif
749 void add_base(const base_desc& b)
751 m_bases.push_back(b);
754 public:
756 void add_constructor(const detail::construct_rep::overload_t& o)
758 m_constructor.overloads.push_back(o);
761 void add_method(const char* name, const detail::overload_rep& o)
763 #ifdef LUABIND_DONT_COPY_STRINGS
764 detail::method_rep& method = m_methods[name];
765 method.name = name;
766 #else
767 m_strings.push_back(detail::dup_string(name));
768 detail::method_rep& method = m_methods[m_strings.back()];
769 method.name = m_strings.back();
770 #endif
771 method.add_overload(o);
772 method.crep = 0;
775 #ifndef LUABIND_NO_ERROR_CHECKING
776 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
777 #else
778 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
779 #endif
781 detail::class_rep::operator_callback o;
782 o.set_fun(func);
783 o.set_match_fun(matcher);
784 o.set_arity(arity);
786 #ifndef LUABIND_NO_ERROR_CHECKING
788 o.set_sig_fun(sig);
790 #endif
791 m_operators[op_id].push_back(o);
800 const char* name() const { return m_name; }
802 class_base(const char* name)
804 #ifndef LUABIND_DONT_COPY_STRINGS
805 m_strings.push_back(detail::dup_string(name));
806 m_name = m_strings.back();
807 #else
808 m_name = name;
809 #endif
811 #ifndef NDEBUG
812 m_cloned = false;
813 #endif
816 virtual ~class_base()
818 // if we are copying strings, we have to destroy them too
819 #ifndef LUABIND_DONT_COPY_STRINGS
820 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
821 delete[] *i;
822 #endif
825 // pushes the class_rep on the lua stack
826 virtual void commit(lua_State* L)
828 assert(!m_cloned && "class already commited");
830 detail::getref(L, scope_stack::top(L));
831 lua_pushstring(L, m_name);
833 detail::class_rep* crep;
835 detail::class_registry* r = detail::class_registry::get_registry(L);
836 // create a class_rep structure for this class.
837 // allocate it within lua to let lua collect it on
838 // lua_close(). This is better than allocating it
839 // as a static, since it will then be destructed
840 // when the program exits instead.
841 // warning: we assume that lua will not
842 // move the userdata memory.
843 lua_newuserdata(L, sizeof(detail::class_rep));
844 crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
846 new(crep) detail::class_rep( m_type
847 , m_name
849 , m_destructor
850 , m_const_holder_destructor
851 , m_holder_type
852 , m_const_holder_type
853 , m_extractor
854 , m_const_extractor
855 , m_const_converter
856 , m_construct_holder
857 , m_construct_const_holder
858 , m_holder_size
859 , m_holder_alignment);
861 // register this new type in the class registry
862 r->add_class(m_type, crep);
863 if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type, LUABIND_INVALID_TYPE_INFO)))
865 // if we have a held type
866 // we have to register it in the class-table
867 // but only for the base class, if it already
868 // exists, we don't have to register it
869 detail::class_rep* c = r->find_class(m_holder_type);
870 if (c == 0)
872 r->add_class(m_holder_type, crep);
873 r->add_class(m_const_holder_type, crep);
877 // add methods
878 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i = m_methods.begin();
879 i != m_methods.end();
880 ++i)
882 i->second.crep = crep;
884 std::swap(crep->m_methods, m_methods);
886 // constructors
887 m_constructor.swap(crep->m_constructor);
889 #ifndef LUABIND_DONT_COPY_STRINGS
890 assert(crep->m_strings.empty() && "Internal error");
891 std::swap(crep->m_strings, m_strings);
892 #endif
894 std::swap(crep->m_getters, m_getters);
895 std::swap(crep->m_setters, m_setters);
897 for(int i = 0; i < detail::number_of_operators; ++i)
898 std::swap(crep->m_operators[i], m_operators[i]);
900 std::swap(crep->m_static_constants, m_static_constants);
902 for (std::vector<base_desc>::iterator i = m_bases.begin();
903 i != m_bases.end();
904 ++i)
906 detail::class_registry* r = detail::class_registry::get_registry(L);
908 // the baseclass' class_rep structure
909 detail::class_rep* bcrep = r->find_class(i->type);
911 detail::class_rep::base_info base;
912 base.pointer_offset = i->ptr_offset;
913 base.base = bcrep;
915 crep->add_base_class(base);
918 lua_settable(L, -3);
919 lua_pop(L, 1);
923 // destructive copy
924 virtual luabind::detail::scoped_object* clone()
926 assert(m_cloned == false);
928 #ifndef NDEBUG
929 m_cloned = true;
930 #endif
932 class_base* ret = new class_base(m_name);
934 std::swap(ret->m_getters, m_getters);
935 std::swap(ret->m_setters, m_setters);
937 for(int i = 0; i < detail::number_of_operators; ++i)
938 std::swap(ret->m_operators[i], m_operators[i]);
940 std::swap(ret->m_static_constants, m_static_constants);
942 ret->init(m_type
943 , m_holder_type
944 , m_extractor
945 , m_const_extractor
946 , m_const_converter
947 , m_construct_holder
948 , m_construct_const_holder
949 , m_destructor
950 , m_const_holder_destructor
951 , m_holder_size
952 , m_holder_alignment);
954 ret->m_const_holder_type = m_const_holder_type;
956 std::swap(ret->m_bases, m_bases);
957 std::swap(ret->m_methods, m_methods);
958 m_constructor.swap(ret->m_constructor);
960 ret->m_name = m_name;
962 #ifndef LUABIND_DONT_COPY_STRINGS
963 std::swap(ret->m_strings, m_strings);
964 #endif
966 return ret;
981 // registers a class in the lua environment
982 template<class T, class X1, class X2, class X3>
983 struct class_: class_base
985 typedef class_<T, X1, X2, X3> self_t;
987 lua_State* m_L;
989 private:
991 template<class A, class B, class C, class D>
992 class_(const class_<A,B,C,D>&);
994 public:
996 // WrappedType MUST inherit from T
997 typedef typename detail::extract_parameter<
998 boost::mpl::vector3<X1,X2,X3>
999 , boost::is_base_and_derived<T, boost::mpl::_>
1000 /* , boost::mpl::not_<
1001 boost::mpl::or_<
1002 detail::is_bases<boost::mpl::_>
1003 , boost::is_base_and_derived<boost::mpl::_, T>
1006 , detail::null_type
1007 >::type WrappedType;
1009 typedef typename detail::extract_parameter<
1010 boost::mpl::list3<X1,X2,X3>
1011 , boost::mpl::not_<
1012 boost::mpl::or_<
1013 boost::mpl::or_<
1014 detail::is_bases<boost::mpl::_>
1015 , boost::is_base_and_derived<boost::mpl::_, T>
1017 , boost::is_base_and_derived<T, boost::mpl::_>
1020 , detail::null_type
1021 >::type HeldType;
1023 // this function generates conversion information
1024 // in the given class_rep structure. It will be able
1025 // to implicitly cast to the given template type
1026 template<class To>
1027 void gen_base_info(detail::type<To>)
1029 // fist, make sure the given base class is registered.
1030 // if it's not registered we can't push it's lua table onto
1031 // the stack because it doesn't have a table
1033 // try to cast this type to the base type and remember
1034 // the pointer offset. For multiple inheritance the pointer
1035 // may change when casting. Since we need to be able to
1036 // cast we need this pointer offset.
1037 // store the information in this class' base class-vector
1038 base_desc base;
1039 base.type = LUABIND_TYPEID(To);
1040 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
1041 add_base(base);
1044 void gen_base_info(detail::type<detail::null_type>)
1047 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
1049 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
1050 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
1052 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
1055 #undef LUABIND_GEN_BASE_INFO
1057 // this is the internal version of def() it is run from both overloads
1058 // of def. It has two versions, one where a contstructor is registered
1059 // and one where a function is registered
1060 template<class Policies>
1061 struct internal_def_s
1063 template<class F>
1064 static void apply(const char* name, F f, class_base* c)
1066 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1068 detail::overload_rep o(f, static_cast<Policies*>(0));
1070 typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
1072 o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
1073 o.call_fun = boost::bind<int>(call_t(f), _1, _2);
1075 #ifndef LUABIND_NO_ERROR_CHECKING
1077 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1079 #endif
1081 c->add_method(name, o);
1084 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1085 static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
1087 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1089 detail::construct_rep::overload_t o;
1091 o.set_constructor(
1092 &detail::construct_class<
1094 ,Policies
1095 ,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1096 >::apply
1099 // if we have a WrappedType, we have to register it's constructor
1100 // but if it's null_type (no WrappedType) we should not register it
1101 detail::register_wrapped_type<WrappedType>::apply(o,
1102 static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
1103 static_cast<const Policies*>(0));
1106 o.set_match_fun(
1107 &detail::constructor_match<
1108 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1110 ,Policies
1111 >::apply);
1113 #ifndef LUABIND_NO_ERROR_CHECKING
1115 o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
1117 #endif
1119 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
1121 o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
1123 c->add_constructor(o);
1127 class_(lua_State* L, const char* name): class_base(name), m_L(L) { init(); }
1128 class_(const char* name): class_base(name), m_L(0) { init(); }
1130 ~class_()
1132 if (m_L != 0)
1134 scope::init(m_L);
1135 lua_pushvalue(m_L, LUA_GLOBALSINDEX);
1136 scope_stack::push(m_L);
1137 commit(m_L);
1138 scope_stack::pop(m_L);
1142 template<class F>
1143 class_& def(const char* name, F f)
1145 internal_def_s<detail::null_type>::apply(name, f, this);
1146 return *this;
1149 template<class F, class Policies>
1150 class_& def(const char* name, F f, const Policies&)
1152 internal_def_s<Policies>::apply(name, f, this);
1153 return *this;
1156 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1157 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
1159 internal_def_s<detail::null_type>::apply(sig, this);
1160 return *this;
1163 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
1164 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
1166 internal_def_s<Policies>::apply(sig, this);
1167 return *this;
1170 template<class Getter>
1171 class_& property(const char* name, Getter g)
1173 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
1174 return *this;
1177 template<class Getter, class MaybeSetter>
1178 class_& property(const char* name, Getter g, MaybeSetter s)
1180 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
1183 template<class Getter, class Setter, class GetPolicies>
1184 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
1186 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1187 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
1188 return *this;
1191 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
1192 class_& property(const char* name
1193 , Getter g, Setter s
1194 , const GetPolicies& get_policies
1195 , const SetPolicies& set_policies)
1197 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1198 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
1199 return *this;
1202 template<class D>
1203 class_& def_readonly(const char* name, D T::*member_ptr)
1205 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1206 return *this;
1209 template<class D, class Policies>
1210 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
1212 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
1213 return *this;
1216 template<class D>
1217 class_& def_readwrite(const char* name, D T::*member_ptr)
1219 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1220 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1221 return *this;
1224 template<class D, class GetPolicies>
1225 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1227 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1228 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1229 return *this;
1232 template<class D, class GetPolicies, class SetPolicies>
1233 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1235 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1236 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1237 return *this;
1240 template<class op_id, class Left, class Right, class Policies>
1241 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1243 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1244 #ifndef LUABIND_NO_ERROR_CHECKING
1245 add_operator(op_type::get_id()
1246 , &op_type::execute
1247 , &op_type::match
1248 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1249 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1250 #else
1251 add_operator(op_type::get_id()
1252 , &op_type::execute
1253 , &op_type::match
1254 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1255 #endif
1256 return *this;
1259 template<class op_id, class Left, class Right>
1260 class_& def(detail::operator_<op_id, Left, Right>)
1262 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1264 #ifndef LUABIND_NO_ERROR_CHECKING
1265 add_operator(op_type::get_id()
1266 , &op_type::execute
1267 , &op_type::match
1268 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1269 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1270 #else
1271 add_operator(op_type::get_id()
1272 , &op_type::execute
1273 , &op_type::match
1274 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1275 #endif
1276 return *this;
1279 template<class Signature, bool Constant>
1280 class_& def(detail::application_operator<Signature, Constant>*)
1282 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1284 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
1286 #ifndef LUABIND_NO_ERROR_CHECKING
1287 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1288 #else
1289 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1290 #endif
1292 return *this;
1295 template<class Signature, bool Constant, class Policies>
1296 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1298 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1300 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1302 #ifndef LUABIND_NO_ERROR_CHECKING
1303 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1304 #else
1305 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1306 #endif
1308 return *this;
1311 detail::enum_maker<self_t> enum_(const char*)
1313 return detail::enum_maker<self_t>(*this);
1316 private:
1318 void init()
1320 typedef typename detail::extract_parameter<
1321 boost::mpl::list3<X1,X2,X3>
1322 , boost::mpl::or_<
1323 detail::is_bases<boost::mpl::_>
1324 , boost::is_base_and_derived<boost::mpl::_, T>
1326 , no_bases
1327 >::type bases_t;
1329 typedef typename
1330 boost::mpl::if_<detail::is_bases<bases_t>
1331 , bases_t
1332 , bases<bases_t>
1333 >::type Base;
1335 HeldType* crap = 0;
1337 class_base::init(LUABIND_TYPEID(T)
1338 , detail::internal_holder_type<HeldType>::apply()
1339 , detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
1340 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
1341 , detail::const_converter<HeldType>::apply(luabind::get_const_holder(crap))
1342 , detail::holder_constructor<HeldType>::apply(detail::type<T>())
1343 , detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
1344 , detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
1345 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
1346 , detail::internal_holder_size<HeldType>::apply()
1347 , detail::get_holder_alignment<HeldType>::apply());
1349 set_const_holder_type(luabind::get_const_holder(static_cast<HeldType*>(0)));
1351 generate_baseclass_list(detail::type<Base>());
1354 template<class Getter, class GetPolicies>
1355 class_& property_impl(const char* name,
1356 Getter g,
1357 GetPolicies policies,
1358 boost::mpl::bool_<true>)
1360 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1361 return *this;
1364 template<class Getter, class Setter>
1365 class_& property_impl(const char* name,
1366 Getter g,
1367 Setter s,
1368 boost::mpl::bool_<false>)
1370 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1371 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1372 return *this;
1378 #endif // LUABIND_CLASS_HPP_INCLUDED