bug fixed with overloads in inherited classes
[luabind.git] / luabind / class.hpp
blob18c9bd44eb7eab93079ea0f72c6bdd0998a619bd
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);
215 // T* ptr = static_cast<T*>(luabind::get_pointer(held_obj));
216 // is this correct?
217 T* ptr = static_cast<T*>(obj_ptr);
219 return call(f, ptr, L, static_cast<Policies*>(this));
221 F f;
224 template<class T, class F, class Policies>
225 struct function_callback_null_type : Policies
227 function_callback_null_type(F f_): f(f_) {}
228 inline int operator()(lua_State* L, void* obj_ptr)
230 // std::cout << "HeldType: null_type\n";
231 T* ptr = static_cast<T*>(obj_ptr);
232 return call(f, ptr, L, static_cast<Policies*>(this));
234 F f;
237 template<class HeldType, class T, class F, class Policies>
238 struct function_callback_s
240 typedef typename
241 boost::mpl::if_<boost::is_same<HeldType,detail::null_type>
242 , function_callback_null_type<T,F,Policies>
243 , function_callback_non_null<HeldType,T,F,Policies>
244 >::type type;
247 template<class T, class F, class Policies>
248 struct match_function_callback_s
250 static inline int apply(lua_State* L)
252 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
253 F fptr = 0;
254 return match(fptr, L, obj->flags() & object_rep::constant, static_cast<Policies*>(0));
258 // prints the types of the values on the stack, in the
259 // range [start_index, lua_gettop()]
261 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
263 struct LUABIND_API create_class
265 static int stage1(lua_State* L);
266 static int stage2(lua_State* L);
269 template<class Type>
270 struct register_wrapped_type
272 template<class Signature, class Policies>
273 static void apply(detail::construct_rep::overload_t& o, const Signature*, const Policies*)
275 o.set_wrapped_constructor(
276 &detail::construct_wrapped_class<Type, Policies, Signature>::apply
281 template<>
282 struct register_wrapped_type<detail::null_type>
284 template<class Signature, class Policies>
285 static void apply(detail::construct_rep::overload_t&, const Signature*, const Policies*) {}
289 // if the class is held by a smart pointer, we need to be able to
290 // implicitly dereference the pointer when needed.
292 template<class UnderlyingT, class HeldT>
293 struct extract_underlying_type
295 static void* extract(void* ptr)
297 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
298 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
299 return underlying_ptr;
303 template<class UnderlyingT, class HeldT>
304 struct extract_underlying_const_type
306 static const void* extract(void* ptr)
308 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
309 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
310 return underlying_ptr;
314 template<class HeldType>
315 struct internal_holder_extractor
317 typedef void*(*extractor_fun)(void*);
319 template<class T>
320 static extractor_fun apply(detail::type<T>)
322 return &detail::extract_underlying_type<T, HeldType>::extract;
326 template<>
327 struct internal_holder_extractor<detail::null_type>
329 typedef void*(*extractor_fun)(void*);
331 template<class T>
332 static extractor_fun apply(detail::type<T>)
334 return 0;
339 template<class HeldType, class ConstHolderType>
340 struct convert_holder
342 static void apply(void* holder, void* target)
344 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
349 template<class HeldType>
350 struct const_converter
352 typedef void(*converter_fun)(void*, void*);
354 template<class ConstHolderType>
355 static converter_fun apply(ConstHolderType*)
357 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
361 template<>
362 struct const_converter<detail::null_type>
364 typedef void(*converter_fun)(void*, void*);
366 template<class T>
367 static converter_fun apply(T*)
369 return 0;
376 template<class HeldType>
377 struct internal_const_holder_extractor
379 typedef const void*(*extractor_fun)(void*);
381 template<class T>
382 static extractor_fun apply(detail::type<T>)
384 return get_extractor(detail::type<T>(), luabind::get_const_holder(static_cast<HeldType*>(0)));
386 private:
387 template<class T, class ConstHolderType>
388 static extractor_fun get_extractor(detail::type<T>, ConstHolderType*)
390 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
394 template<>
395 struct internal_const_holder_extractor<detail::null_type>
397 typedef const void*(*extractor_fun)(void*);
399 template<class T>
400 static extractor_fun apply(detail::type<T>)
402 return 0;
408 // this is simply a selector that returns the type_info
409 // of the held type, or invalid_type_info if we don't have
410 // a held_type
411 template<class HeldType>
412 struct internal_holder_type
414 static LUABIND_TYPE_INFO apply()
416 return LUABIND_TYPEID(HeldType);
420 template<>
421 struct internal_holder_type<detail::null_type>
423 static LUABIND_TYPE_INFO apply()
425 return LUABIND_INVALID_TYPE_INFO;
430 // this is the actual held_type constructor
431 template<class HeldType, class T>
432 struct internal_construct_holder
434 static void apply(void* target, void* raw_pointer)
436 new(target) HeldType(static_cast<T*>(raw_pointer));
440 // the following two functions are the ones that returns
441 // a pointer to a held_type_constructor, or 0 if there
442 // is no held_type
443 template<class HeldType>
444 struct holder_constructor
446 typedef void(*constructor)(void*,void*);
447 template<class T>
448 static constructor apply(detail::type<T>)
450 return &internal_construct_holder<HeldType, T>::apply;
454 template<>
455 struct holder_constructor<detail::null_type>
457 typedef void(*constructor)(void*,void*);
458 template<class T>
459 static constructor apply(detail::type<T>)
461 return 0;
465 // the following two functions are the ones that returns
466 // a pointer to a const_held_type_constructor, or 0 if there
467 // is no held_type
468 template<class HolderType>
469 struct const_holder_constructor
471 typedef void(*constructor)(void*,void*);
472 template<class T>
473 static constructor apply(detail::type<T>)
475 return get_const_holder_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
478 private:
480 template<class T, class ConstHolderType>
481 static constructor get_const_holder_constructor(detail::type<T>, ConstHolderType*)
483 return &internal_construct_holder<ConstHolderType, T>::apply;
487 template<>
488 struct const_holder_constructor<detail::null_type>
490 typedef void(*constructor)(void*,void*);
491 template<class T>
492 static constructor apply(detail::type<T>)
494 return 0;
500 // this is a selector that returns the size of the held_type
501 // or 0 if we don't have a held_type
502 template <class HolderType>
503 struct internal_holder_size
505 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType*>(0))); }
506 private:
507 template<class ConstHolderType>
508 static int get_internal_holder_size(ConstHolderType*)
510 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
514 template <>
515 struct internal_holder_size<detail::null_type>
517 static int apply() { return 0; }
521 // if we have a held type, return the destructor to it
522 // note the difference. The held_type should only be destructed (not deleted)
523 // since it's constructed in the lua userdata
524 template<class HeldType>
525 struct internal_holder_destructor
527 typedef void(*destructor_t)(void*);
528 template<class T>
529 static destructor_t apply(detail::type<T>)
531 return &detail::destruct_only_s<HeldType>::apply;
535 // if we don't have a held type, return the destructor of the raw type
536 template<>
537 struct internal_holder_destructor<detail::null_type>
539 typedef void(*destructor_t)(void*);
540 template<class T>
541 static destructor_t apply(detail::type<T>)
543 return &detail::delete_s<T>::apply;
548 // if we have a held type, return the destructor to it's const version
549 template<class HolderType>
550 struct internal_const_holder_destructor
552 typedef void(*destructor_t)(void*);
553 template<class T>
554 static destructor_t apply(detail::type<T>)
556 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType*>(0)));
559 private:
561 template<class ConstHolderType>
562 static destructor_t const_holder_type_destructor(ConstHolderType*)
564 return &detail::destruct_only_s<ConstHolderType>::apply;
569 // if we don't have a held type, return the destructor of the raw type
570 template<>
571 struct internal_const_holder_destructor<detail::null_type>
573 typedef void(*destructor_t)(void*);
574 template<class T>
575 static destructor_t apply(detail::type<T>)
577 return 0;
584 template<class HolderType>
585 struct get_holder_alignment
587 static int apply()
589 return internal_alignment(luabind::get_const_holder(static_cast<HolderType*>(0)));
592 private:
594 template<class ConstHolderType>
595 static int internal_alignment(ConstHolderType*)
597 return detail::max_c<boost::alignment_of<HolderType>::value
598 , boost::alignment_of<ConstHolderType>::value>::value;
602 template<>
603 struct get_holder_alignment<detail::null_type>
605 static int apply()
607 return 1;
612 } // detail
627 struct class_base: detail::scoped_object
629 protected:
631 struct base_desc
633 LUABIND_TYPE_INFO type;
634 int ptr_offset;
637 private:
639 #ifndef NDEBUG
640 bool m_cloned;
641 #endif
643 const char* m_name;
645 std::map<const char*, detail::method_rep, detail::ltstr> m_methods;
647 // datamembers, some members may be readonly, and
648 // only have a getter function
649 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_getters;
650 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_setters;
652 // the operators in lua
653 std::vector<detail::class_rep::operator_callback> m_operators[detail::number_of_operators];
654 std::map<const char*, int, detail::ltstr> m_static_constants;
656 std::vector<base_desc> m_bases;
657 detail::construct_rep m_constructor;
659 void(*m_destructor)(void*);
660 void(*m_const_holder_destructor)(void*);
662 void*(*m_extractor)(void*);
663 const void*(*m_const_extractor)(void*);
665 void(*m_const_converter)(void*,void*);
667 void(*m_construct_holder)(void*, void*);
668 void(*m_construct_const_holder)(void*, void*);
670 int m_holder_size;
671 int m_holder_alignment;
673 LUABIND_TYPE_INFO m_type;
674 LUABIND_TYPE_INFO m_holder_type;
675 LUABIND_TYPE_INFO m_const_holder_type;
677 #ifndef LUABIND_DONT_COPY_STRINGS
678 // the maps that contains char pointers points into
679 // this vector of strings.
680 std::vector<char*> m_strings;
681 #endif
684 public:
686 // public 'cause of enum_maker, FIX
687 void add_static_constant(const char* name, int val)
689 m_static_constants[name] = val;
692 protected:
694 mutable std::vector<detail::scoped_object*> m_children;
696 void init(LUABIND_TYPE_INFO type
697 , LUABIND_TYPE_INFO holder_type
698 , void*(*extractor)(void*)
699 , const void*(*const_extractor)(void*)
700 , void(*const_converter)(void*,void*)
701 , void(*holder_constructor)(void*,void*)
702 , void(*const_holder_constructor)(void*,void*)
703 , void(*destructor)(void*)
704 , void(*const_holder_destructor)(void*)
705 , int holder_size
706 , int holder_alignment)
708 m_type = type;
709 m_holder_type = holder_type;
710 m_extractor = extractor;
711 m_const_extractor = const_extractor;
712 m_const_converter = const_converter;
713 m_construct_holder = holder_constructor;
714 m_construct_const_holder = const_holder_constructor;
715 m_destructor = destructor;
716 m_const_holder_destructor = const_holder_destructor;
717 m_holder_size = holder_size;
718 m_holder_alignment = holder_alignment;
721 template<class T>
722 void set_const_holder_type(T*)
724 m_const_holder_type = LUABIND_TYPEID(T);
727 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
729 detail::class_rep::callback c;
730 c.func = g;
731 c.pointer_offset = 0;
732 #ifndef LUABIND_DONT_COPY_STRINGS
733 m_strings.push_back(detail::dup_string(name));
734 m_getters[m_strings.back()] = c;
735 #else
736 m_getters[name] = c;
737 #endif
740 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
742 detail::class_rep::callback c;
743 c.func = s;
744 c.pointer_offset = 0;
745 #ifndef LUABIND_DONT_COPY_STRINGS
746 m_strings.push_back(detail::dup_string(name));
747 m_setters[m_strings.back()] = c;
748 #else
749 m_setters[name] = c;
750 #endif
753 void add_base(const base_desc& b)
755 m_bases.push_back(b);
758 public:
760 void add_constructor(const detail::construct_rep::overload_t& o)
762 m_constructor.overloads.push_back(o);
765 void add_method(const char* name, const detail::overload_rep& o)
767 #ifdef LUABIND_DONT_COPY_STRINGS
768 detail::method_rep& method = m_methods[name];
769 method.name = name;
770 #else
771 m_strings.push_back(detail::dup_string(name));
772 detail::method_rep& method = m_methods[m_strings.back()];
773 method.name = m_strings.back();
774 #endif
775 method.add_overload(o);
776 method.crep = 0;
779 #ifndef LUABIND_NO_ERROR_CHECKING
780 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
781 #else
782 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
783 #endif
785 detail::class_rep::operator_callback o;
786 o.set_fun(func);
787 o.set_match_fun(matcher);
788 o.set_arity(arity);
790 #ifndef LUABIND_NO_ERROR_CHECKING
792 o.set_sig_fun(sig);
794 #endif
795 m_operators[op_id].push_back(o);
804 const char* name() const { return m_name; }
806 class_base(const char* name)
808 #ifndef LUABIND_DONT_COPY_STRINGS
809 m_strings.push_back(detail::dup_string(name));
810 m_name = m_strings.back();
811 #else
812 m_name = name;
813 #endif
815 #ifndef NDEBUG
816 m_cloned = false;
817 #endif
820 virtual ~class_base()
822 for (std::vector<detail::scoped_object*>::iterator
823 i = m_children.begin(); i != m_children.end(); ++i)
824 delete *i;
826 // if we are copying strings, we have to destroy them too
827 #ifndef LUABIND_DONT_COPY_STRINGS
828 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
829 delete[] *i;
830 #endif
833 // pushes the class_rep on the lua stack
834 virtual void commit(lua_State* L)
836 assert(!m_cloned && "class already commited");
838 detail::getref(L, scope_stack::top(L));
839 lua_pushstring(L, m_name);
841 detail::class_rep* crep;
843 detail::class_registry* r = detail::class_registry::get_registry(L);
844 // create a class_rep structure for this class.
845 // allocate it within lua to let lua collect it on
846 // lua_close(). This is better than allocating it
847 // as a static, since it will then be destructed
848 // when the program exits instead.
849 // warning: we assume that lua will not
850 // move the userdata memory.
851 lua_newuserdata(L, sizeof(detail::class_rep));
852 crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
854 new(crep) detail::class_rep( m_type
855 , m_name
857 , m_destructor
858 , m_const_holder_destructor
859 , m_holder_type
860 , m_const_holder_type
861 , m_extractor
862 , m_const_extractor
863 , m_const_converter
864 , m_construct_holder
865 , m_construct_const_holder
866 , m_holder_size
867 , m_holder_alignment);
869 // register this new type in the class registry
870 r->add_class(m_type, crep);
871 if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type, LUABIND_INVALID_TYPE_INFO)))
873 // if we have a held type
874 // we have to register it in the class-table
875 // but only for the base class, if it already
876 // exists, we don't have to register it
877 detail::class_rep* c = r->find_class(m_holder_type);
878 if (c == 0)
880 r->add_class(m_holder_type, crep);
881 r->add_class(m_const_holder_type, crep);
885 // constructors
886 m_constructor.swap(crep->m_constructor);
888 #ifndef LUABIND_DONT_COPY_STRINGS
889 assert(crep->m_strings.empty() && "Internal error");
890 std::swap(crep->m_strings, m_strings);
891 #endif
893 std::swap(crep->m_getters, m_getters);
894 std::swap(crep->m_setters, m_setters);
896 for(int i = 0; i < detail::number_of_operators; ++i)
897 std::swap(crep->m_operators[i], m_operators[i]);
899 std::swap(crep->m_static_constants, m_static_constants);
901 for (std::vector<base_desc>::iterator i = m_bases.begin();
902 i != m_bases.end();
903 ++i)
905 detail::class_registry* r = detail::class_registry::get_registry(L);
907 // the baseclass' class_rep structure
908 detail::class_rep* bcrep = r->find_class(i->type);
910 detail::class_rep::base_info base;
911 base.pointer_offset = i->ptr_offset;
912 base.base = bcrep;
914 crep->add_base_class(base);
916 // copy base class table
917 detail::getref(L, crep->table_ref());
918 detail::getref(L, bcrep->table_ref());
919 lua_pushnil(L);
921 while (lua_next(L, -2))
923 lua_pushvalue(L, -2); // copy key
924 lua_insert(L, -2);
925 lua_settable(L, -5);
928 lua_pop(L, 2);
931 crep->m_methods = m_methods;
933 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i
934 = crep->m_methods.begin(); i != crep->m_methods.end(); ++i)
936 i->second.crep = crep;
939 // add methods
940 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i
941 = m_methods.begin(); i != m_methods.end(); ++i)
943 crep->add_method(L, i->first, crep->m_methods[i->first]);
944 i->second.crep = crep;
947 m_methods.clear();
949 lua_settable(L, -3);
950 lua_pop(L, 1);
954 // destructive copy
955 virtual luabind::detail::scoped_object* clone()
957 assert(m_cloned == false);
959 #ifndef NDEBUG
960 m_cloned = true;
961 #endif
963 class_base* ret = new class_base(m_name);
965 std::swap(ret->m_getters, m_getters);
966 std::swap(ret->m_setters, m_setters);
968 for(int i = 0; i < detail::number_of_operators; ++i)
969 std::swap(ret->m_operators[i], m_operators[i]);
971 std::swap(ret->m_static_constants, m_static_constants);
973 ret->init(m_type
974 , m_holder_type
975 , m_extractor
976 , m_const_extractor
977 , m_const_converter
978 , m_construct_holder
979 , m_construct_const_holder
980 , m_destructor
981 , m_const_holder_destructor
982 , m_holder_size
983 , m_holder_alignment);
985 ret->m_const_holder_type = m_const_holder_type;
987 ret->m_bases.swap(m_bases);
988 ret->m_methods.swap(m_methods);
989 m_constructor.swap(ret->m_constructor);
991 ret->m_name = m_name;
993 #ifndef LUABIND_DONT_COPY_STRINGS
994 std::swap(ret->m_strings, m_strings);
995 #endif
997 m_children.swap(ret->m_children);
999 return ret;
1013 // registers a class in the lua environment
1014 template<class T, class X1, class X2, class X3>
1015 struct class_: class_base
1017 typedef class_<T, X1, X2, X3> self_t;
1019 lua_State* m_L;
1021 private:
1023 template<class A, class B, class C, class D>
1024 class_(const class_<A,B,C,D>&);
1026 public:
1028 // WrappedType MUST inherit from T
1029 typedef typename detail::extract_parameter<
1030 boost::mpl::vector3<X1,X2,X3>
1031 , boost::is_base_and_derived<T, boost::mpl::_>
1032 /* , boost::mpl::not_<
1033 boost::mpl::or_<
1034 detail::is_bases<boost::mpl::_>
1035 , boost::is_base_and_derived<boost::mpl::_, T>
1038 , detail::null_type
1039 >::type WrappedType;
1041 typedef typename detail::extract_parameter<
1042 boost::mpl::list3<X1,X2,X3>
1043 , boost::mpl::not_<
1044 boost::mpl::or_<
1045 boost::mpl::or_<
1046 detail::is_bases<boost::mpl::_>
1047 , boost::is_base_and_derived<boost::mpl::_, T>
1049 , boost::is_base_and_derived<T, boost::mpl::_>
1052 , detail::null_type
1053 >::type HeldType;
1055 // this function generates conversion information
1056 // in the given class_rep structure. It will be able
1057 // to implicitly cast to the given template type
1058 template<class To>
1059 void gen_base_info(detail::type<To>)
1061 // fist, make sure the given base class is registered.
1062 // if it's not registered we can't push it's lua table onto
1063 // the stack because it doesn't have a table
1065 // try to cast this type to the base type and remember
1066 // the pointer offset. For multiple inheritance the pointer
1067 // may change when casting. Since we need to be able to
1068 // cast we need this pointer offset.
1069 // store the information in this class' base class-vector
1070 base_desc base;
1071 base.type = LUABIND_TYPEID(To);
1072 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
1073 add_base(base);
1076 void gen_base_info(detail::type<detail::null_type>)
1079 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
1081 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
1082 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
1084 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
1087 #undef LUABIND_GEN_BASE_INFO
1089 // this is the internal version of def() it is run from both overloads
1090 // of def. It has two versions, one where a contstructor is registered
1091 // and one where a function is registered
1092 template<class Policies>
1093 struct internal_def_s
1095 template<class F>
1096 static void apply(const char* name, F f, class_base* c)
1098 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1100 detail::overload_rep o(f, static_cast<Policies*>(0));
1102 typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
1104 o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
1105 o.call_fun = boost::bind<int>(call_t(f), _1, _2);
1107 #ifndef LUABIND_NO_ERROR_CHECKING
1109 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1111 #endif
1113 c->add_method(name, o);
1116 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1117 static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
1119 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1121 detail::construct_rep::overload_t o;
1123 o.set_constructor(
1124 &detail::construct_class<
1126 ,Policies
1127 ,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1128 >::apply
1131 // if we have a WrappedType, we have to register it's constructor
1132 // but if it's null_type (no WrappedType) we should not register it
1133 detail::register_wrapped_type<WrappedType>::apply(o,
1134 static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
1135 static_cast<const Policies*>(0));
1138 o.set_match_fun(
1139 &detail::constructor_match<
1140 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1142 ,Policies
1143 >::apply);
1145 #ifndef LUABIND_NO_ERROR_CHECKING
1147 o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
1149 #endif
1151 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
1153 o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
1155 c->add_constructor(o);
1159 class_(lua_State* L, const char* name): class_base(name), m_L(L) { init(); }
1160 class_(const char* name): class_base(name), m_L(0) { init(); }
1162 ~class_()
1164 if (m_L != 0)
1166 scope::init(m_L);
1167 lua_pushvalue(m_L, LUA_GLOBALSINDEX);
1168 scope_stack::push(m_L);
1169 commit(m_L);
1170 scope_stack::pop(m_L);
1174 template<class F>
1175 class_& def(const char* name, F f)
1177 internal_def_s<detail::null_type>::apply(name, f, this);
1178 return *this;
1181 template<class F, class Policies>
1182 class_& def(const char* name, F f, const Policies&)
1184 internal_def_s<Policies>::apply(name, f, this);
1185 return *this;
1188 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1189 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
1191 internal_def_s<detail::null_type>::apply(sig, this);
1192 return *this;
1195 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
1196 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
1198 internal_def_s<Policies>::apply(sig, this);
1199 return *this;
1202 template<class Getter>
1203 class_& property(const char* name, Getter g)
1205 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
1206 return *this;
1209 template<class Getter, class MaybeSetter>
1210 class_& property(const char* name, Getter g, MaybeSetter s)
1212 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
1215 template<class Getter, class Setter, class GetPolicies>
1216 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
1218 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1219 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
1220 return *this;
1223 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
1224 class_& property(const char* name
1225 , Getter g, Setter s
1226 , const GetPolicies& get_policies
1227 , const SetPolicies& set_policies)
1229 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1230 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
1231 return *this;
1234 template<class D>
1235 class_& def_readonly(const char* name, D T::*member_ptr)
1237 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1238 return *this;
1241 template<class D, class Policies>
1242 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
1244 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
1245 return *this;
1248 template<class D>
1249 class_& def_readwrite(const char* name, D T::*member_ptr)
1251 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1252 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1253 return *this;
1256 template<class D, class GetPolicies>
1257 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1259 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1260 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1261 return *this;
1264 template<class D, class GetPolicies, class SetPolicies>
1265 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1267 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1268 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1269 return *this;
1272 template<class op_id, class Left, class Right, class Policies>
1273 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1275 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1276 #ifndef LUABIND_NO_ERROR_CHECKING
1277 add_operator(op_type::get_id()
1278 , &op_type::execute
1279 , &op_type::match
1280 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1281 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1282 #else
1283 add_operator(op_type::get_id()
1284 , &op_type::execute
1285 , &op_type::match
1286 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1287 #endif
1288 return *this;
1291 template<class op_id, class Left, class Right>
1292 class_& def(detail::operator_<op_id, Left, Right>)
1294 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1296 #ifndef LUABIND_NO_ERROR_CHECKING
1297 add_operator(op_type::get_id()
1298 , &op_type::execute
1299 , &op_type::match
1300 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1301 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1302 #else
1303 add_operator(op_type::get_id()
1304 , &op_type::execute
1305 , &op_type::match
1306 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1307 #endif
1308 return *this;
1311 template<class Signature, bool Constant>
1312 class_& def(detail::application_operator<Signature, Constant>*)
1314 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1316 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
1318 #ifndef LUABIND_NO_ERROR_CHECKING
1319 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1320 #else
1321 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1322 #endif
1324 return *this;
1327 template<class Signature, bool Constant, class Policies>
1328 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1330 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1332 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1334 #ifndef LUABIND_NO_ERROR_CHECKING
1335 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1336 #else
1337 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1338 #endif
1340 return *this;
1343 detail::enum_maker<self_t> enum_(const char*)
1345 return detail::enum_maker<self_t>(*this);
1348 class_& operator[](const detail::scoped_object& x)
1350 detail::scoped_object* ptr = &const_cast<detail::scoped_object&>(x);
1351 m_children.push_back(ptr->clone());
1352 return *this;
1355 private:
1357 void init()
1359 typedef typename detail::extract_parameter<
1360 boost::mpl::list3<X1,X2,X3>
1361 , boost::mpl::or_<
1362 detail::is_bases<boost::mpl::_>
1363 , boost::is_base_and_derived<boost::mpl::_, T>
1365 , no_bases
1366 >::type bases_t;
1368 typedef typename
1369 boost::mpl::if_<detail::is_bases<bases_t>
1370 , bases_t
1371 , bases<bases_t>
1372 >::type Base;
1374 HeldType* crap = 0;
1376 class_base::init(LUABIND_TYPEID(T)
1377 , detail::internal_holder_type<HeldType>::apply()
1378 , detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
1379 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
1380 , detail::const_converter<HeldType>::apply(luabind::get_const_holder(crap))
1381 , detail::holder_constructor<HeldType>::apply(detail::type<T>())
1382 , detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
1383 , detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
1384 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
1385 , detail::internal_holder_size<HeldType>::apply()
1386 , detail::get_holder_alignment<HeldType>::apply());
1388 set_const_holder_type(luabind::get_const_holder(static_cast<HeldType*>(0)));
1390 generate_baseclass_list(detail::type<Base>());
1393 template<class Getter, class GetPolicies>
1394 class_& property_impl(const char* name,
1395 Getter g,
1396 GetPolicies policies,
1397 boost::mpl::bool_<true>)
1399 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1400 return *this;
1403 template<class Getter, class Setter>
1404 class_& property_impl(const char* name,
1405 Getter g,
1406 Setter s,
1407 boost::mpl::bool_<false>)
1409 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1410 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1411 return *this;
1417 #endif // LUABIND_CLASS_HPP_INCLUDED