fixed access violation
[luabind.git] / luabind / class.hpp
blob2f524e65bf3eec219bf39bcf14837cd5c80c954a
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_c<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_c<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
683 public:
685 // public 'cause of enum_maker, FIX
686 void add_static_constant(const char* name, int val)
688 m_static_constants[name] = val;
691 protected:
693 mutable std::vector<detail::scoped_object*> m_children;
695 void init(LUABIND_TYPE_INFO type
696 , LUABIND_TYPE_INFO holder_type
697 , void*(*extractor)(void*)
698 , const void*(*const_extractor)(void*)
699 , void(*const_converter)(void*,void*)
700 , void(*holder_constructor)(void*,void*)
701 , void(*const_holder_constructor)(void*,void*)
702 , void(*destructor)(void*)
703 , void(*const_holder_destructor)(void*)
704 , int holder_size
705 , int holder_alignment)
707 m_type = type;
708 m_holder_type = holder_type;
709 m_extractor = extractor;
710 m_const_extractor = const_extractor;
711 m_const_converter = const_converter;
712 m_construct_holder = holder_constructor;
713 m_construct_const_holder = const_holder_constructor;
714 m_destructor = destructor;
715 m_const_holder_destructor = const_holder_destructor;
716 m_holder_size = holder_size;
717 m_holder_alignment = holder_alignment;
720 template<class T>
721 void set_const_holder_type(T*)
723 m_const_holder_type = LUABIND_TYPEID(T);
726 inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
728 detail::class_rep::callback c;
729 c.func = g;
730 c.pointer_offset = 0;
731 #ifndef LUABIND_DONT_COPY_STRINGS
732 m_strings.push_back(detail::dup_string(name));
733 m_getters[m_strings.back()] = c;
734 #else
735 m_getters[name] = c;
736 #endif
739 inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
741 detail::class_rep::callback c;
742 c.func = s;
743 c.pointer_offset = 0;
744 #ifndef LUABIND_DONT_COPY_STRINGS
745 m_strings.push_back(detail::dup_string(name));
746 m_setters[m_strings.back()] = c;
747 #else
748 m_setters[name] = c;
749 #endif
752 void add_base(const base_desc& b)
754 m_bases.push_back(b);
757 public:
759 void add_constructor(const detail::construct_rep::overload_t& o)
761 m_constructor.overloads.push_back(o);
764 void add_method(const char* name, const detail::overload_rep& o)
766 #ifdef LUABIND_DONT_COPY_STRINGS
767 detail::method_rep& method = m_methods[name];
768 method.name = name;
769 #else
770 m_strings.push_back(detail::dup_string(name));
771 detail::method_rep& method = m_methods[m_strings.back()];
772 method.name = m_strings.back();
773 #endif
774 method.add_overload(o);
775 method.crep = 0;
778 #ifndef LUABIND_NO_ERROR_CHECKING
779 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
780 #else
781 inline void add_operator(int op_id, int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
782 #endif
784 detail::class_rep::operator_callback o;
785 o.set_fun(func);
786 o.set_match_fun(matcher);
787 o.set_arity(arity);
789 #ifndef LUABIND_NO_ERROR_CHECKING
791 o.set_sig_fun(sig);
793 #endif
794 m_operators[op_id].push_back(o);
803 const char* name() const { return m_name; }
805 class_base(const char* name)
807 #ifndef LUABIND_DONT_COPY_STRINGS
808 m_strings.push_back(detail::dup_string(name));
809 m_name = m_strings.back();
810 #else
811 m_name = name;
812 #endif
814 #ifndef NDEBUG
815 m_cloned = false;
816 #endif
819 virtual ~class_base()
821 for (std::vector<detail::scoped_object*>::iterator
822 i = m_children.begin(); i != m_children.end(); ++i)
823 delete *i;
825 // if we are copying strings, we have to destroy them too
826 #ifndef LUABIND_DONT_COPY_STRINGS
827 for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
828 delete[] *i;
829 #endif
832 // pushes the class_rep on the lua stack
833 virtual void commit(lua_State* L)
835 assert(!m_cloned && "class already commited");
837 detail::getref(L, scope_stack::top(L));
838 lua_pushstring(L, m_name);
840 detail::class_rep* crep;
842 detail::class_registry* r = detail::class_registry::get_registry(L);
843 // create a class_rep structure for this class.
844 // allocate it within lua to let lua collect it on
845 // lua_close(). This is better than allocating it
846 // as a static, since it will then be destructed
847 // when the program exits instead.
848 // warning: we assume that lua will not
849 // move the userdata memory.
850 lua_newuserdata(L, sizeof(detail::class_rep));
851 crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
853 new(crep) detail::class_rep( m_type
854 , m_name
856 , m_destructor
857 , m_const_holder_destructor
858 , m_holder_type
859 , m_const_holder_type
860 , m_extractor
861 , m_const_extractor
862 , m_const_converter
863 , m_construct_holder
864 , m_construct_const_holder
865 , m_holder_size
866 , m_holder_alignment);
868 // register this new type in the class registry
869 r->add_class(m_type, crep);
870 if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type, LUABIND_INVALID_TYPE_INFO)))
872 // if we have a held type
873 // we have to register it in the class-table
874 // but only for the base class, if it already
875 // exists, we don't have to register it
876 detail::class_rep* c = r->find_class(m_holder_type);
877 if (c == 0)
879 r->add_class(m_holder_type, crep);
880 r->add_class(m_const_holder_type, crep);
884 // add methods
885 for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i = m_methods.begin();
886 i != m_methods.end();
887 ++i)
889 crep->add_method(L, i->first, i->second);
890 i->second.crep = crep;
892 crep->m_methods.swap(m_methods);
894 // constructors
895 m_constructor.swap(crep->m_constructor);
897 #ifndef LUABIND_DONT_COPY_STRINGS
898 assert(crep->m_strings.empty() && "Internal error");
899 std::swap(crep->m_strings, m_strings);
900 #endif
902 std::swap(crep->m_getters, m_getters);
903 std::swap(crep->m_setters, m_setters);
905 for(int i = 0; i < detail::number_of_operators; ++i)
906 std::swap(crep->m_operators[i], m_operators[i]);
908 std::swap(crep->m_static_constants, m_static_constants);
910 for (std::vector<base_desc>::iterator i = m_bases.begin();
911 i != m_bases.end();
912 ++i)
914 detail::class_registry* r = detail::class_registry::get_registry(L);
916 // the baseclass' class_rep structure
917 detail::class_rep* bcrep = r->find_class(i->type);
919 detail::class_rep::base_info base;
920 base.pointer_offset = i->ptr_offset;
921 base.base = bcrep;
923 crep->add_base_class(base);
926 lua_settable(L, -3);
927 lua_pop(L, 1);
931 // destructive copy
932 virtual luabind::detail::scoped_object* clone()
934 assert(m_cloned == false);
936 #ifndef NDEBUG
937 m_cloned = true;
938 #endif
940 class_base* ret = new class_base(m_name);
942 std::swap(ret->m_getters, m_getters);
943 std::swap(ret->m_setters, m_setters);
945 for(int i = 0; i < detail::number_of_operators; ++i)
946 std::swap(ret->m_operators[i], m_operators[i]);
948 std::swap(ret->m_static_constants, m_static_constants);
950 ret->init(m_type
951 , m_holder_type
952 , m_extractor
953 , m_const_extractor
954 , m_const_converter
955 , m_construct_holder
956 , m_construct_const_holder
957 , m_destructor
958 , m_const_holder_destructor
959 , m_holder_size
960 , m_holder_alignment);
962 ret->m_const_holder_type = m_const_holder_type;
964 ret->m_bases.swap(m_bases);
965 ret->m_methods.swap(m_methods);
966 m_constructor.swap(ret->m_constructor);
968 ret->m_name = m_name;
970 #ifndef LUABIND_DONT_COPY_STRINGS
971 std::swap(ret->m_strings, m_strings);
972 #endif
974 m_children.swap(ret->m_children);
976 return ret;
990 // registers a class in the lua environment
991 template<class T, class X1, class X2, class X3>
992 struct class_: class_base
994 typedef class_<T, X1, X2, X3> self_t;
996 lua_State* m_L;
998 private:
1000 template<class A, class B, class C, class D>
1001 class_(const class_<A,B,C,D>&);
1003 public:
1005 // WrappedType MUST inherit from T
1006 typedef typename detail::extract_parameter<
1007 boost::mpl::vector3<X1,X2,X3>
1008 , boost::is_base_and_derived<T, boost::mpl::_>
1009 /* , boost::mpl::not_<
1010 boost::mpl::or_<
1011 detail::is_bases<boost::mpl::_>
1012 , boost::is_base_and_derived<boost::mpl::_, T>
1015 , detail::null_type
1016 >::type WrappedType;
1018 typedef typename detail::extract_parameter<
1019 boost::mpl::list3<X1,X2,X3>
1020 , boost::mpl::not_<
1021 boost::mpl::or_<
1022 boost::mpl::or_<
1023 detail::is_bases<boost::mpl::_>
1024 , boost::is_base_and_derived<boost::mpl::_, T>
1026 , boost::is_base_and_derived<T, boost::mpl::_>
1029 , detail::null_type
1030 >::type HeldType;
1032 // this function generates conversion information
1033 // in the given class_rep structure. It will be able
1034 // to implicitly cast to the given template type
1035 template<class To>
1036 void gen_base_info(detail::type<To>)
1038 // fist, make sure the given base class is registered.
1039 // if it's not registered we can't push it's lua table onto
1040 // the stack because it doesn't have a table
1042 // try to cast this type to the base type and remember
1043 // the pointer offset. For multiple inheritance the pointer
1044 // may change when casting. Since we need to be able to
1045 // cast we need this pointer offset.
1046 // store the information in this class' base class-vector
1047 base_desc base;
1048 base.type = LUABIND_TYPEID(To);
1049 base.ptr_offset = detail::ptr_offset(detail::type<T>(), detail::type<To>());
1050 add_base(base);
1053 void gen_base_info(detail::type<detail::null_type>)
1056 #define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type<B##n>());
1058 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, class B)>
1059 void generate_baseclass_list(detail::type<bases<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_BASES, B)> >)
1061 BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _)
1064 #undef LUABIND_GEN_BASE_INFO
1066 // this is the internal version of def() it is run from both overloads
1067 // of def. It has two versions, one where a contstructor is registered
1068 // and one where a function is registered
1069 template<class Policies>
1070 struct internal_def_s
1072 template<class F>
1073 static void apply(const char* name, F f, class_base* c)
1075 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1077 detail::overload_rep o(f, static_cast<Policies*>(0));
1079 typedef LUABIND_MSVC_TYPENAME detail::function_callback_s<HeldType,T,F,Policies>::type call_t;
1081 o.set_match_fun(&detail::match_function_callback_s<T,F,Policies>::apply);
1082 o.call_fun = boost::bind<int>(call_t(f), _1, _2);
1084 #ifndef LUABIND_NO_ERROR_CHECKING
1086 o.set_sig_fun(&detail::get_member_signature<F>::apply);
1088 #endif
1090 c->add_method(name, o);
1093 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1094 static void apply(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>, class_base* c)
1096 // std::cout << "HeldType2: " << typeid(HeldType).name() << "\n";
1098 detail::construct_rep::overload_t o;
1100 o.set_constructor(
1101 &detail::construct_class<
1103 ,Policies
1104 ,constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1105 >::apply
1108 // if we have a WrappedType, we have to register it's constructor
1109 // but if it's null_type (no WrappedType) we should not register it
1110 detail::register_wrapped_type<WrappedType>::apply(o,
1111 static_cast<const constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>*>(0),
1112 static_cast<const Policies*>(0));
1115 o.set_match_fun(
1116 &detail::constructor_match<
1117 constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)>
1119 ,Policies
1120 >::apply);
1122 #ifndef LUABIND_NO_ERROR_CHECKING
1124 o.set_sig_fun(&detail::get_signature<constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> >::apply);
1126 #endif
1128 typedef constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> con_t;
1130 o.set_arity(detail::calc_arity<con_t::arity>::apply(con_t(), static_cast<Policies*>(0)));
1132 c->add_constructor(o);
1136 class_(lua_State* L, const char* name): class_base(name), m_L(L) { init(); }
1137 class_(const char* name): class_base(name), m_L(0) { init(); }
1139 ~class_()
1141 if (m_L != 0)
1143 scope::init(m_L);
1144 lua_pushvalue(m_L, LUA_GLOBALSINDEX);
1145 scope_stack::push(m_L);
1146 commit(m_L);
1147 scope_stack::pop(m_L);
1151 template<class F>
1152 class_& def(const char* name, F f)
1154 internal_def_s<detail::null_type>::apply(name, f, this);
1155 return *this;
1158 template<class F, class Policies>
1159 class_& def(const char* name, F f, const Policies&)
1161 internal_def_s<Policies>::apply(name, f, this);
1162 return *this;
1165 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A)>
1166 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig)
1168 internal_def_s<detail::null_type>::apply(sig, this);
1169 return *this;
1172 template<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, class A), class Policies>
1173 class_& def(constructor<BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A)> sig, const Policies& policies)
1175 internal_def_s<Policies>::apply(sig, this);
1176 return *this;
1179 template<class Getter>
1180 class_& property(const char* name, Getter g)
1182 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, detail::null_type>(), _1, _2, g));
1183 return *this;
1186 template<class Getter, class MaybeSetter>
1187 class_& property(const char* name, Getter g, MaybeSetter s)
1189 return property_impl(name, g, s, boost::mpl::bool_<detail::is_policy_cons<MaybeSetter>::value>());
1192 template<class Getter, class Setter, class GetPolicies>
1193 class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies)
1195 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1196 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, detail::null_type>(), _1, _2, s));
1197 return *this;
1200 template<class Getter, class Setter, class GetPolicies, class SetPolicies>
1201 class_& property(const char* name
1202 , Getter g, Setter s
1203 , const GetPolicies& get_policies
1204 , const SetPolicies& set_policies)
1206 add_getter(name, boost::bind<int>(detail::get_caller<T, Getter, GetPolicies>(get_policies), _1, _2, g));
1207 add_setter(name, boost::bind<int>(detail::set_caller<T, Setter, GetPolicies>(set_policies), _1, _2, s));
1208 return *this;
1211 template<class D>
1212 class_& def_readonly(const char* name, D T::*member_ptr)
1214 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1215 return *this;
1218 template<class D, class Policies>
1219 class_& def_readonly(const char* name, D T::*member_ptr, const Policies& policies)
1221 add_getter(name, boost::bind<int>(detail::auto_get<T,D,Policies>(policies), _1, _2, member_ptr));
1222 return *this;
1225 template<class D>
1226 class_& def_readwrite(const char* name, D T::*member_ptr)
1228 add_getter(name, boost::bind<int>(detail::auto_get<T,D,detail::null_type>(), _1, _2, member_ptr));
1229 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1230 return *this;
1233 template<class D, class GetPolicies>
1234 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies)
1236 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1237 add_setter(name, boost::bind<int>(detail::auto_set<T,D,detail::null_type>(), _1, _2, member_ptr));
1238 return *this;
1241 template<class D, class GetPolicies, class SetPolicies>
1242 class_& def_readwrite(const char* name, D T::*member_ptr, const GetPolicies& get_policies, const SetPolicies& set_policies)
1244 add_getter(name, boost::bind<int>(detail::auto_get<T,D,GetPolicies>(get_policies), _1, _2, member_ptr));
1245 add_setter(name, boost::bind<int>(detail::auto_set<T,D,SetPolicies>(set_policies), _1, _2, member_ptr));
1246 return *this;
1249 template<class op_id, class Left, class Right, class Policies>
1250 class_& def(detail::operator_<op_id, Left, Right>, const Policies& policies)
1252 typedef typename detail::operator_unwrapper<Policies, op_id, T, Left, Right> op_type;
1253 #ifndef LUABIND_NO_ERROR_CHECKING
1254 add_operator(op_type::get_id()
1255 , &op_type::execute
1256 , &op_type::match
1257 , &detail::get_signature<constructor<typename op_type::left_t, typename op_type::right_t> >::apply
1258 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1259 #else
1260 add_operator(op_type::get_id()
1261 , &op_type::execute
1262 , &op_type::match
1263 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1264 #endif
1265 return *this;
1268 template<class op_id, class Left, class Right>
1269 class_& def(detail::operator_<op_id, Left, Right>)
1271 typedef typename detail::operator_unwrapper<detail::null_type, op_id, T, Left, Right> op_type;
1273 #ifndef LUABIND_NO_ERROR_CHECKING
1274 add_operator(op_type::get_id()
1275 , &op_type::execute
1276 , &op_type::match
1277 , &detail::get_signature<constructor<LUABIND_MSVC_TYPENAME op_type::left_t, LUABIND_MSVC_TYPENAME op_type::right_t> >::apply
1278 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1279 #else
1280 add_operator(op_type::get_id()
1281 , &op_type::execute
1282 , &op_type::match
1283 , detail::is_unary(op_type::get_id()) ? 1 : 2);
1284 #endif
1285 return *this;
1288 template<class Signature, bool Constant>
1289 class_& def(detail::application_operator<Signature, Constant>*)
1291 typedef detail::application_operator<Signature, Constant, detail::null_type> op_t;
1293 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<detail::null_type*>(0));
1295 #ifndef LUABIND_NO_ERROR_CHECKING
1296 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1297 #else
1298 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1299 #endif
1301 return *this;
1304 template<class Signature, bool Constant, class Policies>
1305 class_& def(detail::application_operator<Signature, Constant>*, const Policies& policies)
1307 typedef detail::application_operator<Signature, Constant, Policies> op_t;
1309 int arity = detail::calc_arity<Signature::arity>::apply(Signature(), static_cast<Policies*>(0));
1311 #ifndef LUABIND_NO_ERROR_CHECKING
1312 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, &detail::get_signature<Signature>::apply, arity + 1);
1313 #else
1314 add_operator(detail::op_call, &op_t::template apply<T>::execute, &op_t::match, arity + 1);
1315 #endif
1317 return *this;
1320 detail::enum_maker<self_t> enum_(const char*)
1322 return detail::enum_maker<self_t>(*this);
1325 class_& operator[](const detail::scoped_object& x)
1327 detail::scoped_object* ptr = &const_cast<detail::scoped_object&>(x);
1328 m_children.push_back(ptr->clone());
1329 return *this;
1332 private:
1334 void init()
1336 typedef typename detail::extract_parameter<
1337 boost::mpl::list3<X1,X2,X3>
1338 , boost::mpl::or_<
1339 detail::is_bases<boost::mpl::_>
1340 , boost::is_base_and_derived<boost::mpl::_, T>
1342 , no_bases
1343 >::type bases_t;
1345 typedef typename
1346 boost::mpl::if_<detail::is_bases<bases_t>
1347 , bases_t
1348 , bases<bases_t>
1349 >::type Base;
1351 HeldType* crap = 0;
1353 class_base::init(LUABIND_TYPEID(T)
1354 , detail::internal_holder_type<HeldType>::apply()
1355 , detail::internal_holder_extractor<HeldType>::apply(detail::type<T>())
1356 , detail::internal_const_holder_extractor<HeldType>::apply(detail::type<T>())
1357 , detail::const_converter<HeldType>::apply(luabind::get_const_holder(crap))
1358 , detail::holder_constructor<HeldType>::apply(detail::type<T>())
1359 , detail::const_holder_constructor<HeldType>::apply(detail::type<T>())
1360 , detail::internal_holder_destructor<HeldType>::apply(detail::type<T>())
1361 , detail::internal_const_holder_destructor<HeldType>::apply(detail::type<T>())
1362 , detail::internal_holder_size<HeldType>::apply()
1363 , detail::get_holder_alignment<HeldType>::apply());
1365 set_const_holder_type(luabind::get_const_holder(static_cast<HeldType*>(0)));
1367 generate_baseclass_list(detail::type<Base>());
1370 template<class Getter, class GetPolicies>
1371 class_& property_impl(const char* name,
1372 Getter g,
1373 GetPolicies policies,
1374 boost::mpl::bool_<true>)
1376 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,GetPolicies>(policies), _1, _2, g));
1377 return *this;
1380 template<class Getter, class Setter>
1381 class_& property_impl(const char* name,
1382 Getter g,
1383 Setter s,
1384 boost::mpl::bool_<false>)
1386 add_getter(name, boost::bind<int>(detail::get_caller<T,Getter,detail::null_type>(), _1, _2, g));
1387 add_setter(name, boost::bind<int>(detail::set_caller<T,Setter,detail::null_type>(), _1, _2, s));
1388 return *this;
1394 #endif // LUABIND_CLASS_HPP_INCLUDED