Fix bug in cast graph cache

This patch fixes a bug in the cast graph cache in Luabind 0.9.1. The
problem did not manifest itself in earlier versions, but only became
apparent with Luabind commit 8e9bb9c7, which fixed a different cast
cache bug.

When a cast from a Lua value to a C++ object fails due to mismatching
types, e.g. upon function overload resolution, or explicit object_cast,
Luabind stores a bogus entry in the cast graph cache. A second cast to
the same C++ type will then erroneously yield a successful cast despite
the mismatching types. This results in e.g. ambiguous overload errors
for overloaded functions despite non-ambiguity, or segmentation faults
due to access of a C++ object through a pointer with the wrong type.

The bug has first been discovered and fixed by Eduard Mueller:

http://old.nabble.com/inheritance-cast_graph-cache-bug-fix-p29936577.html

The above patch switches the arguments to store a correct cache entry
with offset equal to cache::invalid. The distance value is irrelevant,
as it is discarded in cast_graph::impl::cast(). Presumably the above
patch changes it from -1 to 0 to account for the std::size_t type used
in the signature of cache::put.

The patch below takes a different approach, as already suggested by the
author of the above patch. We swap the offset and distance arguments of
cache::put to match the order of the cache entry pair. Further, we
change the distance type in the cache::put signature from std::size_t
to int, to be consistent with the cache entry type. This inconsistency
stems from the changes in Luabind commit cf37774.

Note that under GNU/Linux, the cast graph cache bug manifests itself
on the x86 platform, but does not seem to affect Luabind on x86_64.
Lua 5.2: replace lua_equal and lua_lessthan with lua_compare

http://www.lua.org/manual/5.2/manual.html#8.3

http://www.lua.org/manual/5.2/manual.html#lua_compare
Lua 5.2: replace occurrences of deprecated LUA_GLOBALSINDEX

Use lua_getglobal and lua_setglobal to retrieve and set globals.

Use lua_rawgeti with LUA_RIDX_GLOBALS to retrieve table of globals.

http://www.lua.org/manual/5.2/manual.html#8.3

http://www.lua.org/manual/5.2/manual.html#4.5

This commit drops support for Lua 5.0, since Luabind is incompatible
with Lua 5.0 anyway, e.g. commit 7dc37f9 requires lua_Integer added
in Lua 5.1.
Lua 5.2: replace lua_strlen with lua_rawlen

lua_strlen was a macro for lua_objlen, which is superseded by lua_rawlen.

http://www.lua.org/manual/5.2/manual.html#8.3

This commit drops support for Lua 5.0, since Luabind is incompatible
with Lua 5.0 anyway, e.g. commit 7dc37f9 requires lua_Integer added
in Lua 5.1.
Lua 5.2: replace lua_[gs]etfenv with lua_[gs]etuservalue

http://www.lua.org/manual/5.2/manual.html#8.1
Lua 5.2: pass extra parameter NULL to lua_resume

http://www.lua.org/manual/5.2/manual.html#8.3

This commit drops support for Lua 5.0, since Luabind is incompatible
with Lua 5.0 anyway, e.g. commit 7dc37f9 requires lua_Integer added
in Lua 5.1.
Lua 5.2: replace lua_open with luaL_newstate

This commit drops support for Lua 5.0, since Luabind is incompatible
with Lua 5.0 anyway, e.g. commit 7dc37f9 requires lua_Integer added
in Lua 5.1.
Lua 5.2: fix test_free_functions unit test

The line triggering the error is truncated at a different position.
Lua 5.2: use new macro lua_pushglobaltable

This macro is not mentioned in the Lua 5.2 manual.
Fix FTBFS with Boost 1.49.0

The implementation of BOOST_PP_ITERATION_FLAGS() changed in Boost 1.49.0,
which causes Luabind to fail to build with GCC (reproduced with GCC 4.4
and GCC 4.6).

https://svn.boost.org/trac/boost/ticket/6631

http://thread.gmane.org/gmane.comp.lib.boost.devel/228802

http://article.gmane.org/gmane.comp.lib.boost.devel/228836

The work-around is to replace the pattern

 #if !defined(MACRO)
     // A
 #elif MACRO()
     // B
 #endif

with

 #if !defined(MACRO)
     // A
 #else
     #if MACRO()
         // B
     #endif
 #endif
Fix aliasing warnings with GCC >= 4.

Apply the same fix as used in boost::make_shared.

https://svn.boost.org/trac/boost/changeset/69251

gcc.compile.c++ test/bin/test_policies.test/gcc-4.7.0/release/link-static/test_policies.o
In file included from test/test_policies.cpp:25:0:
./luabind/out_value_policy.hpp: In instantiation of ‘void luabind::detail::pure_out_value_converter<Size, Policies>::converter_postcall(lua_State*, luabind::detail::by_pointer<T>, int) [with T = int; int Size = 4; Policies = luabind::detail::null_type; lua_State = lua_State]’:
/tmp/boost_1_49_0/boost/preprocessor/iteration/detail/local.hpp:40:1:   required from ‘int luabind::detail::invoke_member(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, mpl_::long_<3l>, mpl_::true_) [with F = void (policies_test_class::*)(int, int*); Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State; mpl_::true_ = mpl_::bool_<true>]’
./luabind/detail/call.hpp:78:5:   required from ‘int luabind::detail::invoke0(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, IsVoid, mpl_::true_) [with F = void (policies_test_class::*)(int, int*); Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>; IsVoid = boost::is_void<void>; lua_State = lua_State; mpl_::true_ = mpl_::bool_<true>]’
./luabind/detail/call.hpp:101:4:   required from ‘int luabind::detail::invoke(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&) [with F = void (policies_test_class::*)(int, int*); Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
./luabind/make_function.hpp:62:15:   required from ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = void (policies_test_class::*)(int, int*); Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
./luabind/make_function.hpp:35:28:   required from ‘luabind::detail::function_object_impl<F, Signature, Policies>::function_object_impl(F, const Policies&) [with F = void (policies_test_class::*)(int, int*); Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>]’
./luabind/make_function.hpp:110:5:   required from ‘luabind::adl::object luabind::make_function(lua_State*, F, Signature, Policies) [with F = void (policies_test_class::*)(int, int*); Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
./luabind/class.hpp:311:52:   required from ‘void luabind::detail::memfun_registration<Class, F, Policies>::register_(lua_State*) const [with Class = policies_test_class; F = void (policies_test_class::*)(int, int*); Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
test/test_policies.cpp:226:1:   required from here
./luabind/out_value_policy.hpp:219:4: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
./luabind/out_value_policy.hpp:220:4: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
./luabind/out_value_policy.hpp: In instantiation of ‘void luabind::detail::pure_out_value_converter<Size, Policies>::converter_postcall(lua_State*, luabind::detail::by_pointer<T>, int) [with T = float; int Size = 4; Policies = luabind::detail::null_type; lua_State = lua_State]’:
/tmp/boost_1_49_0/boost/preprocessor/iteration/detail/local.hpp:34:1:   required from ‘int luabind::detail::invoke_normal(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, mpl_::long_<1l>, mpl_::true_) [with F = void (*)(float*); Signature = boost::mpl::vector2<void, float*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State; mpl_::true_ = mpl_::bool_<true>]’
./luabind/detail/call.hpp:89:5:   required from ‘int luabind::detail::invoke0(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&, IsVoid, mpl_::false_) [with F = void (*)(float*); Signature = boost::mpl::vector2<void, float*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>; IsVoid = boost::is_void<void>; lua_State = lua_State; mpl_::false_ = mpl_::bool_<false>]’
./luabind/detail/call.hpp:101:4:   required from ‘int luabind::detail::invoke(lua_State*, const luabind::detail::function_object&, luabind::detail::invoke_context&, const F&, Signature, const Policies&) [with F = void (*)(float*); Signature = boost::mpl::vector2<void, float*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
./luabind/make_function.hpp:62:15:   required from ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = void (*)(float*); Signature = boost::mpl::vector2<void, float*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
./luabind/make_function.hpp:35:28:   required from ‘luabind::detail::function_object_impl<F, Signature, Policies>::function_object_impl(F, const Policies&) [with F = void (*)(float*); Signature = boost::mpl::vector2<void, float*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>]’
./luabind/make_function.hpp:110:5:   required from ‘luabind::adl::object luabind::make_function(lua_State*, F, Signature, Policies) [with F = void (*)(float*); Signature = boost::mpl::vector2<void, float*>; Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
./luabind/function.hpp:28:72:   required from ‘void luabind::detail::function_registration<F, Policies>::register_(lua_State*) const [with F = void (*)(float*); Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>; lua_State = lua_State]’
test/test_policies.cpp:226:1:   required from here
./luabind/out_value_policy.hpp:219:4: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
./luabind/out_value_policy.hpp:220:4: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Fix further aliasing warnings with GCC 4.4

In contrast to GCC 4.7, GCC 4.4 warns about placement new to type-punned pointer.

gcc.compile.c++ test/bin/test_policies.test/gcc-4.4.6/release/link-static/test_policies.o
In file included from ./luabind/function.hpp:8,
                 from ./luabind/class.hpp:94,
                 from ./luabind/luabind.hpp:28,
                 from test/test_policies.cpp:31:
./luabind/out_value_policy.hpp: In static member function ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = void (*)(float*), Signature = boost::mpl::vector2<void, float*>, Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>]’:
./luabind/out_value_policy.hpp:234: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules
./luabind/out_value_policy.hpp:234: note: initialized from here
./luabind/out_value_policy.hpp: In member function ‘int luabind::detail::function_object_impl<F, Signature, Policies>::call(lua_State*, luabind::detail::invoke_context&) const [with F = void (*)(float*), Signature = boost::mpl::vector2<void, float*>, Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<1, luabind::detail::null_type>, luabind::detail::null_type>]’:
./luabind/out_value_policy.hpp:234: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules
./luabind/out_value_policy.hpp:234: note: initialized from here
./luabind/out_value_policy.hpp: In static member function ‘static int luabind::detail::function_object_impl<F, Signature, Policies>::entry_point(lua_State*) [with F = void (policies_test_class::*)(int, int*), Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>, Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>]’:
./luabind/out_value_policy.hpp:234: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules
./luabind/out_value_policy.hpp:234: note: initialized from here
./luabind/out_value_policy.hpp: In member function ‘int luabind::detail::function_object_impl<F, Signature, Policies>::call(lua_State*, luabind::detail::invoke_context&) const [with F = void (policies_test_class::*)(int, int*), Signature = boost::mpl::vector4<void, policies_test_class&, int, int*>, Policies = luabind::detail::policy_cons<luabind::detail::pure_out_value_policy<3, luabind::detail::null_type>, luabind::detail::null_type>]’:
./luabind/out_value_policy.hpp:234: warning: dereferencing pointer ‘<anonymous>’ does break strict-aliasing rules
Fix unused variable warnings for self and const_self with GCC.

This warnings may be suppressed by declaring variables as const.

./luabind/operator.hpp:347: warning: ‘luabind::<unnamed>::self’ defined but not used

The explicit initialisation with default constructor is needed for GCC 4.4.

./luabind/operator.hpp:347: error: uninitialized const ‘luabind::<unnamed>::self’
./luabind/operator.hpp:348: error: uninitialized const ‘luabind::<unnamed>::const_self’
Add support for conversion between Lua and rvalue references.

With C++11, boost::make_shared and std::make_shared use rvalue
references to forward constructor arguments without copying.

If the macro BOOST_HAS_RVALUE_REFS is defined, let the type trait
is_nonconst_reference evaluate to true only for lvalue references.

Use value_converter for rvalue reference types. Add specialisations
for rvalue references of default_converter of number types, bool,
std::string and boost::shared_ptr.

Note that support of rvalue references requires Boost ≥ 1.44.0.
Fix use of Luabind classes across shared library boundary.

Classes registered with Luabind are only valid within that shared library,
but cause segmentation faults if used across shared library boundaries.

Compare types using typeid(T).name() instead of typeid(T)::operator=.

This fixes use of shared libraries with the GCC 3.0 C++ ABI and loaded
using Lua's require(), which does not pass RTLD_GLOBAL to dlopen.

http://gcc.gnu.org/faq.html#dso

The typeid problem has appeared in other C++ libraries, e.g. boost::any.

https://svn.boost.org/trac/boost/ticket/754
https://svn.boost.org/trac/boost/changeset/56168
Substitute boost::is_lvalue_reference with partial template specialisation.

This avoids a dependency on Boost ≥ 1.44.0.

Use the existing implementation of is_nonconst_reference for compilers
that do not support partial template specialisation, as we can assume
that the same compilers do not support rvalue references.
Fix position of const keyword for consumed_args methods.

luabind/detail/policy.hpp(600): warning #858: type qualifier on return type is meaningless
      int const consumed_args(...)
          ^
Avoid invalid dereference of NULL pointer in throw_error_policy.

This fixes a warning with icpc (ICC) 12.1.3 20120212.

luabind/object.hpp(1002): warning #327: NULL reference is not allowed
            return *(typename boost::remove_reference<T>::type*)0;
                   ^