1 // Copyright (c) 2003 Daniel Wallin and Arvid Norberg 2 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: 9 10 // The above copyright notice and this permission notice shall be included 11 // in all copies or substantial portions of the Software. 12 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. 22 23 24 #ifndef LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED 25 #define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED 26 27 #include <luabind/config.hpp> 28 #include <luabind/detail/policy.hpp> 29 30 namespace luabind { namespace detail 31 { 32 // makes A dependent on B, meaning B will outlive A. 33 // internally A stores a reference to B 34 template<int A, int B> 35 struct dependency_policy 36 { postcallluabind::detail::dependency_policy37 static void postcall(lua_State* L, const index_map& indices) 38 { 39 int nurse_index = indices[A]; 40 int patient = indices[B]; 41 42 object_rep* nurse = static_cast<object_rep*>(lua_touserdata(L, nurse_index)); 43 44 // If the nurse isn't an object_rep, just make this a nop. 45 if (nurse == 0) 46 return; 47 48 nurse->add_dependency(L, patient); 49 } 50 }; 51 52 }} 53 54 #if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) 55 56 namespace luabind 57 { 58 // most absurd workaround of all time? 59 namespace detail 60 { 61 template<int N> 62 struct size_char_array 63 { 64 char storage[N + 2]; 65 }; 66 67 template<int N> 68 size_char_array<N> deduce_size(LUABIND_PLACEHOLDER_ARG(N)); 69 70 template<class T> 71 struct get_index_workaround 72 { 73 static T t; 74 BOOST_STATIC_CONSTANT(int, value = sizeof(deduce_size(t)) - 2); 75 }; 76 } 77 78 template<class A, class B> 79 detail::policy_cons<detail::dependency_policy<detail::get_index_workaround<A>::value dependency(A,B)80 , detail::get_index_workaround<B>::value>, detail::null_type> dependency(A,B) 81 { 82 return detail::policy_cons<detail::dependency_policy< 83 detail::get_index_workaround<A>::value, detail::get_index_workaround<B>::value> 84 , detail::null_type>(); 85 } 86 87 template<class A> 88 detail::policy_cons<detail::dependency_policy<0 89 , detail::get_index_workaround<A>::value>, detail::null_type> return_internal_reference(A)90 return_internal_reference(A) 91 { 92 return detail::policy_cons<detail::dependency_policy<0 93 , detail::get_index_workaround<A>::value>, detail::null_type>(); 94 } 95 } 96 97 #else 98 99 namespace luabind 100 { 101 template<int A, int B> 102 detail::policy_cons<detail::dependency_policy<A, B>, detail::null_type> dependency(LUABIND_PLACEHOLDER_ARG (A),LUABIND_PLACEHOLDER_ARG (B))103 dependency(LUABIND_PLACEHOLDER_ARG(A), LUABIND_PLACEHOLDER_ARG(B)) 104 { 105 return detail::policy_cons<detail::dependency_policy<A, B>, detail::null_type>(); 106 } 107 108 template<int A> 109 detail::policy_cons<detail::dependency_policy<0, A>, detail::null_type> return_internal_reference(LUABIND_PLACEHOLDER_ARG (A))110 return_internal_reference(LUABIND_PLACEHOLDER_ARG(A)) 111 { 112 return detail::policy_cons<detail::dependency_policy<0, A>, detail::null_type>(); 113 } 114 } 115 116 #endif 117 118 #endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED 119 120