*** empty log message ***
[luabind.git] / luabind / class.hpp
blob1f9d9dc1ebfbdbde91b23f56bc10e5ee64b8653f
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 //#include <boost/langbinding/inheritance.hpp>
131 namespace luabind
133 namespace detail
135 struct unspecified {};
138 using detail::type;
140 template<class T, class X1 = detail::unspecified, class X2 = detail::unspecified, class X3 = detail::unspecified>
141 struct class_;
143 // TODO: this function will only be invoked if the user hasn't defined a correct overload
144 // maybe we should have a static assert in here?
145 inline detail::null_type* get_const_holder(...)
147 return 0;
150 namespace detail
152 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class A)>
153 double is_bases_helper(const bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, A)>&);
155 #ifndef BOOST_MSVC
156 template<class T>
157 char is_bases_helper(const T&);
158 #else
159 char is_bases_helper(...);
160 #endif
162 template<class T>
163 struct is_bases
165 static const T& t;
167 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_bases_helper(t)) == sizeof(double));
168 typedef boost::mpl::bool_<value> type;
169 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_bases,(T))
172 double is_not_unspecified_helper(const unspecified*);
173 char is_not_unspecified_helper(...);
175 template<class T>
176 struct is_not_unspecified
178 BOOST_STATIC_CONSTANT(bool, value = sizeof(is_not_unspecified_helper(static_cast<T*>(0))) == sizeof(char));
179 typedef boost::mpl::bool_<value> type;
180 BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_not_unspecified,(T))
183 template<class Predicate>
184 struct get_predicate
186 typedef typename boost::mpl::and_<
187 Predicate
188 , is_not_unspecified<boost::mpl::_1>
189 > type;
192 template<class Parameters, class Predicate, class DefaultValue>
193 struct extract_parameter
195 typedef typename get_predicate<Predicate>::type pred;
196 typedef typename boost::mpl::find_if<Parameters, pred>::type iterator;
197 typedef typename boost::mpl::apply_if<boost::is_same<iterator, typename boost::mpl::end<Parameters>::type>
198 , boost::mpl::identity<DefaultValue>
199 , iterator
200 >::type type;
203 // TODO: is this detail::class_rep::function_dispatcher or detail::free_functions::function_dispatcher?
204 // LUABIND_API int function_dispatcher(lua_State* L);
206 // this should know about the smart pointer type.
207 // and should really do:
208 // get_pointer(*static_cast<SmartPointer*>(obj_ptr))
209 // to extract the held pointer.
210 template<class HeldType, class T, class F, class Policies>
211 struct function_callback_non_null : Policies
213 function_callback_non_null(F f_): f(f_) {}
214 inline int operator()(lua_State* L, void* obj_ptr)
216 // HeldType& held_obj = *static_cast<HeldType*>(obj_ptr);
217 // T* ptr = static_cast<T*>(luabind::get_pointer(held_obj));
218 // is this correct?
219 T* ptr = static_cast<T*>(obj_ptr);
221 return call(f, ptr, L, static_cast<Policies*>(this));
223 F f;
226 template<class T, class F, class Policies>
227 struct function_callback_null_type : Policies
229 function_callback_null_type(F f_): f(f_) {}
230 inline int operator()(lua_State* L, void* obj_ptr)
232 // std::cout << "HeldType: null_type\n";
233 T* ptr = static_cast<T*>(obj_ptr);
234 return call(f, ptr, L, static_cast<Policies*>(this));
236 F f;
239 template<class HeldType, class T, class F, class Policies>
240 struct function_callback_s
242 typedef typename
243 boost::mpl::if_<boost::is_same<HeldType,detail::null_type>
244 , function_callback_null_type<T,F,Policies>
245 , function_callback_non_null<HeldType,T,F,Policies>
246 >::type type;
249 template<class T, class F, class Policies>
250 struct match_function_callback_s
252 static inline int apply(lua_State* L)
254 object_rep* obj = static_cast<object_rep*>(lua_touserdata(L, 1));
255 F fptr = 0;
256 return match(fptr, L, obj->flags() & object_rep::constant, static_cast<Policies*>(0));
260 // prints the types of the values on the stack, in the
261 // range [start_index, lua_gettop()]
263 LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index);
265 struct LUABIND_API create_class
267 static int stage1(lua_State* L);
268 static int stage2(lua_State* L);
271 template<class Type>
272 struct register_wrapped_type
274 template<class Signature, class Policies>
275 static void apply(detail::construct_rep::overload_t& o, const Signature*, const Policies*)
277 o.set_wrapped_constructor(
278 &detail::construct_wrapped_class<Type, Policies, Signature>::apply
283 template<>
284 struct register_wrapped_type<detail::null_type>
286 template<class Signature, class Policies>
287 static void apply(detail::construct_rep::overload_t&, const Signature*, const Policies*) {}
291 // if the class is held by a smart pointer, we need to be able to
292 // implicitly dereference the pointer when needed.
294 template<class UnderlyingT, class HeldT>
295 struct extract_underlying_type
297 static void* extract(void* ptr)
299 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
300 UnderlyingT* underlying_ptr = static_cast<UnderlyingT*>(get_pointer(held_obj));
301 return underlying_ptr;
305 template<class UnderlyingT, class HeldT>
306 struct extract_underlying_const_type
308 static const void* extract(void* ptr)
310 HeldT& held_obj = *reinterpret_cast<HeldT*>(ptr);
311 const UnderlyingT* underlying_ptr = static_cast<const UnderlyingT*>(get_pointer(held_obj));
312 return underlying_ptr;
316 template<class HeldType>
317 struct internal_holder_extractor
319 typedef void*(*extractor_fun)(void*);
321 template<class T>
322 static extractor_fun apply(detail::type<T>)
324 return &detail::extract_underlying_type<T, HeldType>::extract;
328 template<>
329 struct internal_holder_extractor<detail::null_type>
331 typedef void*(*extractor_fun)(void*);
333 template<class T>
334 static extractor_fun apply(detail::type<T>)
336 return 0;
341 template<class HeldType, class ConstHolderType>
342 struct convert_holder
344 static void apply(void* holder, void* target)
346 new(target) ConstHolderType(*reinterpret_cast<HeldType*>(holder));
351 template<class HeldType>
352 struct const_converter
354 typedef void(*converter_fun)(void*, void*);
356 template<class ConstHolderType>
357 static converter_fun apply(ConstHolderType*)
359 return &detail::convert_holder<HeldType, ConstHolderType>::apply;
363 template<>
364 struct const_converter<detail::null_type>
366 typedef void(*converter_fun)(void*, void*);
368 template<class T>
369 static converter_fun apply(T*)
371 return 0;
378 template<class HeldType>
379 struct internal_const_holder_extractor
381 typedef const void*(*extractor_fun)(void*);
383 template<class T>
384 static extractor_fun apply(detail::type<T>)
386 return get_extractor(detail::type<T>(), luabind::get_const_holder(static_cast<HeldType*>(0)));
388 private:
389 template<class T, class ConstHolderType>
390 static extractor_fun get_extractor(detail::type<T>, ConstHolderType*)
392 return &detail::extract_underlying_const_type<T, ConstHolderType>::extract;
396 template<>
397 struct internal_const_holder_extractor<detail::null_type>
399 typedef const void*(*extractor_fun)(void*);
401 template<class T>
402 static extractor_fun apply(detail::type<T>)
404 return 0;
410 // this is simply a selector that returns the type_info
411 // of the held type, or invalid_type_info if we don't have
412 // a held_type
413 template<class HeldType>
414 struct internal_holder_type
416 static LUABIND_TYPE_INFO apply()
418 return LUABIND_TYPEID(HeldType);
422 template<>
423 struct internal_holder_type<detail::null_type>
425 static LUABIND_TYPE_INFO apply()
427 return LUABIND_INVALID_TYPE_INFO;
432 // this is the actual held_type constructor
433 template<class HeldType, class T>
434 struct internal_construct_holder
436 static void apply(void* target, void* raw_pointer)
438 new(target) HeldType(static_cast<T*>(raw_pointer));
442 // the following two functions are the ones that returns
443 // a pointer to a held_type_constructor, or 0 if there
444 // is no held_type
445 template<class HeldType>
446 struct holder_constructor
448 typedef void(*constructor)(void*,void*);
449 template<class T>
450 static constructor apply(detail::type<T>)
452 return &internal_construct_holder<HeldType, T>::apply;
456 template<>
457 struct holder_constructor<detail::null_type>
459 typedef void(*constructor)(void*,void*);
460 template<class T>
461 static constructor apply(detail::type<T>)
463 return 0;
467 // the following two functions are the ones that returns
468 // a pointer to a const_held_type_constructor, or 0 if there
469 // is no held_type
470 template<class HolderType>
471 struct const_holder_constructor
473 typedef void(*constructor)(void*,void*);
474 template<class T>
475 static constructor apply(detail::type<T>)
477 return get_const_holder_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
480 private:
482 template<class T, class ConstHolderType>
483 static constructor get_const_holder_constructor(detail::type<T>, ConstHolderType*)
485 return &internal_construct_holder<ConstHolderType, T>::apply;
489 template<>
490 struct const_holder_constructor<detail::null_type>
492 typedef void(*constructor)(void*,void*);
493 template<class T>
494 static constructor apply(detail::type<T>)
496 return 0;
502 // this is a selector that returns the size of the held_type
503 // or 0 if we don't have a held_type
504 template <class HolderType>
505 struct internal_holder_size
507 static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType*>(0))); }
508 private:
509 template<class ConstHolderType>
510 static int get_internal_holder_size(ConstHolderType*)
512 return max_c<sizeof(HolderType), sizeof(ConstHolderType)>::value;
516 template <>
517 struct internal_holder_size<detail::null_type>
519 static int apply() { return 0; }
523 // if we have a held type, return the destructor to it
524 // note the difference. The held_type should only be destructed (not deleted)
525 // since it's constructed in the lua userdata
526 template<class HeldType>
527 struct internal_holder_destructor
529 typedef void(*destructor_t)(void*);
530 template<class T>
531 static destructor_t apply(detail::type<T>)
533 return &detail::destruct_only_s<HeldType>::apply;
537 // if we don't have a held type, return the destructor of the raw type
538 template<>
539 struct internal_holder_destructor<detail::null_type>
541 typedef void(*destructor_t)(void*);
542 template<class T>
543 static destructor_t apply(detail::type<T>)
545 return &detail::delete_s<T>::apply;
550 // if we have a held type, return the destructor to it's const version
551 template<class HolderType>
552 struct internal_const_holder_destructor
554 typedef void(*destructor_t)(void*);
555 template<class T>
556 static destructor_t apply(detail::type<T>)
558 return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType*>(0)));
561 private:
563 template<class ConstHolderType>
564 static destructor_t const_holder_type_destructor(ConstHolderType*)
566 return &detail::destruct_only_s<ConstHolderType>::apply;
571 // if we don't have a held type, return the destructor of the raw type
572 template<>
573 struct internal_const_holder_destructor<detail::null_type>
575 typedef void(*destructor_t)(void*);
576 template<class T>
577 static destructor_t apply(detail::type<T>)
579 return 0;
586 template<class HolderType>
587 struct get_holder_alignment
589 static int apply()
591 return internal_alignment(luabind::get_const_holder(static_cast<HolderType*>(0)));
594 private:
596 template<class ConstHolderType>
597 static int internal_alignment(ConstHolderType*)
599 return detail::max_c<boost::alignment_of<HolderType>::value
600 , boost::alignment_of<ConstHolderType>::value>::value;
604 template<>
605 struct get_holder_alignment<detail::null_type>
607 static int apply()
609 return 1;
614 } // detail
629 struct class_base: detail::scoped_object
631 protected:
633 struct base_desc
635 LUABIND_TYPE_INFO type;
636 int ptr_offset;
639 private:
641 #ifndef NDEBUG
642 bool m_cloned;
643 #endif
645 const char* m_name;
647 std::map<const char*, detail::method_rep, detail::ltstr> m_methods;
649 // datamembers, some members may be readonly, and
650 // only have a getter function
651 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_getters;
652 std::map<const char*, detail::class_rep::callback, detail::ltstr> m_setters;
654 // the operators in lua
655 std::vector<detail::class_rep::operator_callback> m_operators[detail::number_of_operators];
656 std::map<const char*, int, detail::ltstr> m_static_constants;
658 std::vector<base_desc> m_bases;
659 detail::construct_rep m_constructor;
661 void(*m_destructor)(void*);
662 void(*m_const_holder_destructor)(void*);
664 void*(*m_extractor)(void*);
665 const void*(*m_const_extractor)(void*);
667 void(*m_const_converter)(void*,void*);
669 void(*m_construct_holder)(void*, void*);
670 void(*m_construct_const_holder)(void*, void*);
672 int m_holder_size;
673 int m_holder_alignment;
675 LUABIND_TYPE_INFO m_type;
676 LUABIND_TYPE_INFO m_holder_type;
677 LUABIND_TYPE_INFO m_const_holder_type;
679 #ifndef LUABIND_DONT_COPY_STRINGS
680 // the maps that contains char pointers points into
681 // this vector of strings.
682 std::vector<char*> m_strings;
683 #endif
686 public:
688 // public 'cause of enum_maker, FIX
689 void add_static_constant(const char* name, int val)
691 m_static_constants[name] = val;
694 protected:
696 mutable std::vector<detail::scoped_object*> m_children;
698 void init(LUABIND_TYPE_INFO type
699 , LUABIND_TYPE_INFO holder_type
700 , void*(*extractor)(void*)
701 , const void*(*const_extractor)(void*)
702 , void(*const_converter)(void*,void*)
703 , void(*holder_constructor)(void*,void*)
704 , void(*const_holder_constructor)(void*,void*)
705 , void(*destructor)(void*)
706 , void(*const_holder_destructor)(void*)
707 , int holder_size
708 , int holder_alignment)
710 m_type = type;
711 m_holder_type = holder_type;
712 m_extractor = extractor;
713 m_const_extractor = const_extractor;
714 m_const_converter = const_converter;
715 m_construct_holder = holder_constructor;
716 m_construct_const_holder = const_holder_constructor;
717 m_destructor = destructor;
718 m_const_holder_destructor = const_holder_destructor;
719 m_holder_size = holder_size;
720 m_holder_alignment = holder_alignment;
723 template<class T>
724 void set_const_holder_type(T*)
726 m_const_holder_type = LUABIND_TYPEID(T);
729 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
731 detail::class_rep::callback c;
732 c.func = g;
733 c.pointer_offset = 0;
734 #ifndef LUABIND_DONT_COPY_STRINGS
735 m_strings.push_back(detail::dup_string(name));
736 m_getters[m_strings.back()] = c;
737 #else
738 m_getters[name] = c;
739 #endif
742 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
744 detail::class_rep::callback c;
745 c.func = s;
746 c.pointer_offset = 0;
747 #ifndef LUABIND_DONT_COPY_STRINGS
748 m_strings.push_back(detail::dup_string(name));
749 m_setters[m_strings.back()] = c;
750 #else
751 m_setters[name] = c;
752 #endif
755 void add_base(const base_desc& b)
757 m_bases.push_back(b);
760 public:
762 void add_constructor(const detail::construct_rep::overload_t& o)
764 m_constructor.overloads.push_back(o);
767 void add_method(const char* name, const detail::overload_rep& o)
769 #ifdef LUABIND_DONT_COPY_STRINGS
770 detail::method_rep& method = m_methods[name];
771 method.name = name;
772 #else
773 m_strings.push_back(detail::dup_string(name));
774 detail::method_rep& method = m_methods[m_strings.back()];
775 method.name = m_strings.back();
776 #endif
777 method.add_overload(o);
778 method.crep = 0;
781 #ifndef LUABIND_NO_ERROR_CHECKING
782 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
783 #else
784 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
785 #endif
787 detail::class_rep::operator_callback o;
788 o.set_fun(func);
789 o.set_match_fun(matcher);
790 o.set_arity(arity);
792 #ifndef LUABIND_NO_ERROR_CHECKING
794 o.set_sig_fun(sig);
796 #endif
797 m_operators[op_id].push_back(o);
806 const char* name() const { return m_name; }
808 class_base(const char* name)
810 #ifndef LUABIND_DONT_COPY_STRINGS
811 m_strings.push_back(detail::dup_string(name));
812 m_name = m_strings.back();
813 #else
814 m_name = name;
815 #endif
817 #ifndef NDEBUG
818 m_cloned = false;
819 #endif
822 virtual ~class_base()
824 for (std::vector<detail::scoped_object*>::iterator
825 i = m_children.begin(); i != m_children.end(); ++i)
826 delete *i;
828 // if we are copying strings, we have to destroy them too
829 #ifndef LUABIND_DONT_COPY_STRINGS
830 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
831 delete[] *i;
832 #endif
835 // pushes the class_rep on the lua stack
836 virtual void commit(lua_State* L)
838 assert(!m_cloned && "class already commited");
840 detail::getref(L, scope_stack::top(L));
841 lua_pushstring(L, m_name);
843 detail::class_rep* crep;
845 detail::class_registry* r = detail::class_registry::get_registry(L);
846 // create a class_rep structure for this class.
847 // allocate it within lua to let lua collect it on
848 // lua_close(). This is better than allocating it
849 // as a static, since it will then be destructed
850 // when the program exits instead.
851 // warning: we assume that lua will not
852 // move the userdata memory.
853 lua_newuserdata(L, sizeof(detail::class_rep));
854 crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
856 new(crep) detail::class_rep( m_type
857 , m_name
859 , m_destructor
860 , m_const_holder_destructor
861 , m_holder_type
862 , m_const_holder_type
863 , m_extractor
864 , m_const_extractor
865 , m_const_converter
866 , m_construct_holder
867 , m_construct_const_holder
868 , m_holder_size
869 , m_holder_alignment);
871 // register this new type in the class registry
872 r->add_class(m_type, crep);
873 if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type, LUABIND_INVALID_TYPE_INFO)))
875 // if we have a held type
876 // we have to register it in the class-table
877 // but only for the base class, if it already
878 // exists, we don't have to register it
879 detail::class_rep* c = r->find_class(m_holder_type);
880 if (c == 0)
882 r->add_class(m_holder_type, crep);
883 r->add_class(m_const_holder_type, crep);
887 // constructors
888 m_constructor.swap(crep->m_constructor);
890 #ifndef LUABIND_DONT_COPY_STRINGS
891 assert(crep->m_strings.empty() && "Internal error");
892 std::swap(crep->m_strings, m_strings);
893 #endif
895 std::swap(crep->m_getters, m_getters);
896 std::swap(crep->m_setters, m_setters);
898 for(int i = 0; i < detail::number_of_operators; ++i)
899 std::swap(crep->m_operators[i], m_operators[i]);
901 std::swap(crep->m_static_constants, m_static_constants);
903 // here!
904 // crep->m_methods = m_methods;
906 for (std::vector<base_desc>::iterator i = m_bases.begin();
907 i != m_bases.end();
908 ++i)
910 detail::class_registry* r = detail::class_registry::get_registry(L);
912 // the baseclass' class_rep structure
913 detail::class_rep* bcrep = r->find_class(i->type);
915 detail::class_rep::base_info base;
916 base.pointer_offset = i->ptr_offset;
917 base.base = bcrep;
919 crep->add_base_class(base);
921 typedef std::map<const char*, detail::method_rep, detail::ltstr> methods_t;
923 for (methods_t::const_iterator i
924 = bcrep->m_methods.begin()
925 ; i != bcrep->m_methods.end()
926 ; ++i)
928 detail::method_rep& m = m_methods[i->first];
930 typedef std::vector<detail::overload_rep> overloads_t;
932 for (overloads_t::const_iterator j
933 = i->second.overloads().begin()
934 ; j != i->second.overloads().end()
935 ; ++j)
937 detail::overload_rep o = *j;
938 o.add_offset(base.pointer_offset);
939 m.add_overload(o);
943 // copy base class table
944 detail::getref(L, crep->table_ref());
945 detail::getref(L, bcrep->table_ref());
946 lua_pushnil(L);
948 while (lua_next(L, -2))
950 lua_pushvalue(L, -2); // copy key
951 lua_insert(L, -2);
952 lua_settable(L, -5);
955 lua_pop(L, 2);
958 crep->m_methods = m_methods;
960 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i
961 = crep->m_methods.begin(); i != crep->m_methods.end(); ++i)
963 i->second.crep = crep;
966 // add methods
967 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i
968 = m_methods.begin(); i != m_methods.end(); ++i)
970 detail::getref(L, crep->table_ref());
971 lua_pushstring(L, i->first);
972 lua_pushnil(L);
973 lua_settable(L, -3);
974 lua_pop(L, 1);
976 crep->add_method(L, i->first, crep->m_methods[i->first]);
977 i->second.crep = crep;
980 m_methods.clear();
982 lua_settable(L, -3);
983 lua_pop(L, 1);
987 // destructive copy
988 virtual luabind::detail::scoped_object* clone()
990 assert(m_cloned == false);
992 #ifndef NDEBUG
993 m_cloned = true;
994 #endif
996 class_base* ret = new class_base(m_name);
998 std::swap(ret->m_getters, m_getters);
999 std::swap(ret->m_setters, m_setters);
1001 for(int i = 0; i < detail::number_of_operators; ++i)
1002 std::swap(ret->m_operators[i], m_operators[i]);
1004 std::swap(ret->m_static_constants, m_static_constants);
1006 ret->init(m_type
1007 , m_holder_type
1008 , m_extractor
1009 , m_const_extractor
1010 , m_const_converter
1011 , m_construct_holder
1012 , m_construct_const_holder
1013 , m_destructor
1014 , m_const_holder_destructor
1015 , m_holder_size
1016 , m_holder_alignment);
1018 ret->m_const_holder_type = m_const_holder_type;
1020 ret->m_bases.swap(m_bases);
1021 ret->m_methods.swap(m_methods);
1022 m_constructor.swap(ret->m_constructor);
1024 ret->m_name = m_name;
1026 #ifndef LUABIND_DONT_COPY_STRINGS
1027 std::swap(ret->m_strings, m_strings);
1028 #endif
1030 m_children.swap(ret->m_children);
1032 return ret;
1046 // registers a class in the lua environment
1047 template<class T, class X1, class X2, class X3>
1048 struct class_: class_base
1050 typedef class_<T, X1, X2, X3> self_t;
1052 lua_State* m_L;
1054 private:
1056 template<class A, class B, class C, class D>
1057 class_(const class_<A,B,C,D>&);
1059 public:
1061 // WrappedType MUST inherit from T
1062 typedef typename detail::extract_parameter<
1063 boost::mpl::vector3<X1,X2,X3>
1064 , boost::is_base_and_derived<T, boost::mpl::_>
1065 /* , boost::mpl::not_<
1066 boost::mpl::or_<
1067 detail::is_bases<boost::mpl::_>
1068 , boost::is_base_and_derived<boost::mpl::_, T>
1071 , detail::null_type
1072 >::type WrappedType;
1074 typedef typename detail::extract_parameter<
1075 boost::mpl::list3<X1,X2,X3>
1076 , boost::mpl::not_<
1077 boost::mpl::or_<
1078 boost::mpl::or_<
1079 detail::is_bases<boost::mpl::_>
1080 , boost::is_base_and_derived<boost::mpl::_, T>
1082 , boost::is_base_and_derived<T, boost::mpl::_>
1085 , detail::null_type
1086 >::type HeldType;
1088 template<class To>
1089 void register_downcast(boost::mpl::true_, detail::type<To>* = 0)
1090 { boost::langbinding::register_conversion<To, T>(true); }
1092 template<class To>
1093 void register_downcast(boost::mpl::false_, detail::type<To>* = 0)
1096 // this function generates conversion information
1097 // in the given class_rep structure. It will be able
1098 // to implicitly cast to the given template type
1099 template<class To>
1100 void gen_base_info(detail::type<To>)
1102 // boost::langbinding::register_dynamic_id<To>();
1103 // boost::langbinding::register_conversion<T, To>(false);
1105 // register_downcast<To>(boost::mpl::bool_<boost::is_polymorphic<To>::value>());
1107 // fist, make sure the given base class is registered.
1108 // if it's not registered we can't push it's lua table onto
1109 // the stack because it doesn't have a table
1111 // try to cast this type to the base type and remember
1112 // the pointer offset. For multiple inheritance the pointer
1113 // may change when casting. Since we need to be able to
1114 // cast we need this pointer offset.
1115 // store the information in this class' base class-vector
1116 base_desc base;
1117 base.type = LUABIND_TYPEID(To);
1118 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
1119 add_base(base);
1122 void gen_base_info(detail::type<detail::null_type>)
1125 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
1127 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
1128 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
1130 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
1133 #undef LUABIND_GEN_BASE_INFO
1135 // this is the internal version of def() it is run from both overloads
1136 // of def. It has two versions, one where a contstructor is registered
1137 // and one where a function is registered
1138 template<class Policies>
1139 struct internal_def_s
1141 template<class F>
1142 static void apply(const char* name, F f, class_base* c)
1144 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1146 detail::overload_rep o(f, static_cast<Policies*>(0));
1148 typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
1150 o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
1151 o.call_fun = boost::bind<int>(call_t(f), _1, _2);
1153 #ifndef LUABIND_NO_ERROR_CHECKING
1155 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1157 #endif
1159 c->add_method(name, o);
1162 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1163 static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
1165 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1167 detail::construct_rep::overload_t o;
1169 o.set_constructor(
1170 &detail::construct_class<
1172 ,Policies
1173 ,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1174 >::apply
1177 // if we have a WrappedType, we have to register it's constructor
1178 // but if it's null_type (no WrappedType) we should not register it
1179 detail::register_wrapped_type<WrappedType>::apply(o,
1180 static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
1181 static_cast<const Policies*>(0));
1184 o.set_match_fun(
1185 &detail::constructor_match<
1186 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1188 ,Policies
1189 >::apply);
1191 #ifndef LUABIND_NO_ERROR_CHECKING
1193 o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
1195 #endif
1197 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
1199 o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
1201 c->add_constructor(o);
1205 class_(lua_State* L, const char* name): class_base(name), m_L(L) { init(); }
1206 class_(const char* name): class_base(name), m_L(0) { init(); }
1208 ~class_()
1210 if (m_L != 0)
1212 scope::init(m_L);
1213 lua_pushvalue(m_L, LUA_GLOBALSINDEX);
1214 scope_stack::push(m_L);
1215 commit(m_L);
1216 scope_stack::pop(m_L);
1220 template<class F>
1221 class_& def(const char* name, F f)
1223 internal_def_s<detail::null_type>::apply(name, f, this);
1224 return *this;
1227 template<class F, class Policies>
1228 class_& def(const char* name, F f, const Policies&)
1230 internal_def_s<Policies>::apply(name, f, this);
1231 return *this;
1234 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1235 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
1237 internal_def_s<detail::null_type>::apply(sig, this);
1238 return *this;
1241 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
1242 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
1244 internal_def_s<Policies>::apply(sig, this);
1245 return *this;
1248 template<class Getter>
1249 class_& property(const char* name, Getter g)
1251 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
1252 return *this;
1255 template<class Getter, class MaybeSetter>
1256 class_& property(const char* name, Getter g, MaybeSetter s)
1258 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
1261 template<class Getter, class Setter, class GetPolicies>
1262 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
1264 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1265 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
1266 return *this;
1269 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
1270 class_& property(const char* name
1271 , Getter g, Setter s
1272 , const GetPolicies& get_policies
1273 , const SetPolicies& set_policies)
1275 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1276 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
1277 return *this;
1280 template<class D>
1281 class_& def_readonly(const char* name, D T::*member_ptr)
1283 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1284 return *this;
1287 template<class D, class Policies>
1288 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
1290 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
1291 return *this;
1294 template<class D>
1295 class_& def_readwrite(const char* name, D T::*member_ptr)
1297 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1298 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1299 return *this;
1302 template<class D, class GetPolicies>
1303 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1305 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1306 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1307 return *this;
1310 template<class D, class GetPolicies, class SetPolicies>
1311 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1313 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1314 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1315 return *this;
1318 template<class op_id, class Left, class Right, class Policies>
1319 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1321 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1322 #ifndef LUABIND_NO_ERROR_CHECKING
1323 add_operator(op_type::get_id()
1324 , &op_type::execute
1325 , &op_type::match
1326 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1327 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1328 #else
1329 add_operator(op_type::get_id()
1330 , &op_type::execute
1331 , &op_type::match
1332 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1333 #endif
1334 return *this;
1337 template<class op_id, class Left, class Right>
1338 class_& def(detail::operator_<op_id, Left, Right>)
1340 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1342 #ifndef LUABIND_NO_ERROR_CHECKING
1343 add_operator(op_type::get_id()
1344 , &op_type::execute
1345 , &op_type::match
1346 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1347 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1348 #else
1349 add_operator(op_type::get_id()
1350 , &op_type::execute
1351 , &op_type::match
1352 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1353 #endif
1354 return *this;
1357 template<class Signature, bool Constant>
1358 class_& def(detail::application_operator<Signature, Constant>*)
1360 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1362 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
1364 #ifndef LUABIND_NO_ERROR_CHECKING
1365 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1366 #else
1367 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1368 #endif
1370 return *this;
1373 template<class Signature, bool Constant, class Policies>
1374 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1376 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1378 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1380 #ifndef LUABIND_NO_ERROR_CHECKING
1381 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1382 #else
1383 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1384 #endif
1386 return *this;
1389 detail::enum_maker<self_t> enum_(const char*)
1391 return detail::enum_maker<self_t>(*this);
1394 class_& operator[](const detail::scoped_object& x)
1396 detail::scoped_object* ptr = &const_cast<detail::scoped_object&>(x);
1397 m_children.push_back(ptr->clone());
1398 return *this;
1401 private:
1403 void init()
1405 typedef typename detail::extract_parameter<
1406 boost::mpl::list3<X1,X2,X3>
1407 , boost::mpl::or_<
1408 detail::is_bases<boost::mpl::_>
1409 , boost::is_base_and_derived<boost::mpl::_, T>
1411 , no_bases
1412 >::type bases_t;
1414 typedef typename
1415 boost::mpl::if_<detail::is_bases<bases_t>
1416 , bases_t
1417 , bases<bases_t>
1418 >::type Base;
1420 HeldType* crap = 0;
1422 // boost::langbinding::register_dynamic_id<T>();
1424 class_base::init(LUABIND_TYPEID(T)
1425 , detail::internal_holder_type<HeldType>::apply()
1426 , detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
1427 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
1428 , detail::const_converter<HeldType>::apply(luabind::get_const_holder(crap))
1429 , detail::holder_constructor<HeldType>::apply(detail::type<T>())
1430 , detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
1431 , detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
1432 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
1433 , detail::internal_holder_size<HeldType>::apply()
1434 , detail::get_holder_alignment<HeldType>::apply());
1436 set_const_holder_type(luabind::get_const_holder(static_cast<HeldType*>(0)));
1438 generate_baseclass_list(detail::type<Base>());
1441 template<class Getter, class GetPolicies>
1442 class_& property_impl(const char* name,
1443 Getter g,
1444 GetPolicies policies,
1445 boost::mpl::bool_<true>)
1447 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1448 return *this;
1451 template<class Getter, class Setter>
1452 class_& property_impl(const char* name,
1453 Getter g,
1454 Setter s,
1455 boost::mpl::bool_<false>)
1457 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1458 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1459 return *this;
1465 #endif // LUABIND_CLASS_HPP_INCLUDED