Custom policies

View: New views
6 Messages — Rating Filter:   Alert me  

Custom policies

by Dan Posluns-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hi there,

 

I’d like to write a policy class for performing a reinterpret_cast on a specified parameter. I’m not a complete stranger to generic programming so I would hope it would be within my means, but there doesn’t appear to be any documentation (inline or otherwise) on how the various policy classes were written, though, and I’m finding myself pretty overwhelmed trying to understand them.

 

Is there a good source of reference material on them? Alternatively, is there anyone willing and able to walk me through the creation of such a policy class? (I can imagine there being other similar policy types I would want to create in the future.)

Thanks,

Dan.


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
luabind-user mailing list
luabind-user@...
https://lists.sourceforge.net/lists/listinfo/luabind-user

Re: Custom policies

by Dan Posluns-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

As I investigate the problem I think I can effectively provide some further details…

 

Basically I have a situation where I want to add a function to Lua:

 

void foo(int w, SomeCrazyType x);

 

For reasons I won’t get into, SomeCrazyType is not easily constructible from a Lua value. I of course have the option of creating a wrapper function:

 

void wrapper(int w, SomeNormalButCompatibleType y)
{

foo(w, reinterpret_cast<SomeCrazyType>(y));
}

 

… but this is something I need to do an awful lot of. What would be far more practical and elegant is to have a Luabind policy that changes the function signature within Luabind from:

                void (*)(int, SomeCrazyType)

to…

                void (*)(int, SomeNormalButCompatibleType)

… and then performs that reinterpret_cast<> on calling.

 

Looking at the various policies in existence the necessary ingredients seem to all be there, more-or-less, but I’m still having trouble parsing the existing policies and figuring out the best way to go about this.

 

Again, any help is appreciated!

 

Thanks,

Dan.

 

 

From: luabind-user-bounces@... [mailto:luabind-user-bounces@...] On Behalf Of Dan Posluns
Sent: Friday, April 25, 2008 3:10 PM
To: luabind-user@...
Subject: [luabind] Custom policies

 

Hi there,

 

I’d like to write a policy class for performing a reinterpret_cast on a specified parameter. I’m not a complete stranger to generic programming so I would hope it would be within my means, but there doesn’t appear to be any documentation (inline or otherwise) on how the various policy classes were written, though, and I’m finding myself pretty overwhelmed trying to understand them.

 

Is there a good source of reference material on them? Alternatively, is there anyone willing and able to walk me through the creation of such a policy class? (I can imagine there being other similar policy types I would want to create in the future.)

Thanks,

Dan.


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
luabind-user mailing list
luabind-user@...
https://lists.sourceforge.net/lists/listinfo/luabind-user

Re: Custom policies [1/2]

by Dan Posluns-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

I sent this response more than a week ago, but it got delayed because of the size and apparently there’s nobody checking the queue. Here it is again, broken into two separate messages so it can fit:

 

Well, nobody seems to have any suggestions for me… but that’s okay because in the end I was ultimately able to create the class, more-or-less. Only problem is that it only works for pass-by-value. When used with pointer or reference types Luabind currently asserts… if anyone is bold enough to assist me in making the necessary modifications, I think this class would ultimately be a very useful addition to the repository.

 

Here’s an example of when/how you might use it. Say you have the following class you want to make accessible to Lua:

 

class MyClass

{

public:

      enum Flags

      {

            FLAG_ONE,

            FLAG_TWO,

            FLAG_THREE,

 

            FLAG_COUNT

      };

 

      void doSomething(std::bitset<FLAG_COUNT> flags);

};

 

Because std::bitset is templated you don’t really want to redefine the class for all possible template instantiations. Furthermore you don’t even really want to expose the complication and functionality of std::bitset<> to the Lua user; you’d just as soon have them mash the flags together to produce a result.

 

You can achieve this by doing a raw (C-style) cast from “int” to “std::bitset<FLAG_COUNT>” using the “cast” policy as follows:

 

module(L)

[

      class_<MyClass>("MyClass")

            .def(constructor<>())

            .enum_("Flags")[

                  value("FLAG_ONE", 1 << MyClass::FLAG_ONE),

                  value("FLAG_TWO", 1 << MyClass::FLAG_TWO),

                  value("FLAG_THREE", 1 << MyClass::FLAG_THREE)]

            .def("doSomething", &MyClass::DoSomething, cast<int, raw_c>(_1))

];

 

Here, the “cast” policy indicates that the first parameter should be treated on the Lua side as an int, and converted into a std::bitset<FLAG_COUNT> using a C-style cast. (In addition to raw_c, there is also static_c, dynamic_c and reinterpret_c for those kinds of casts.)

 

Now you can call the function from Lua as follows:

 

x = MyClass()

x:doSomething(MyClass.FLAG_ONE + MyClass.FLAG_THREE)

 

Again, this currently only works with functions that take their parameters by value, and not by pointer/reference. Sorry! If anyone wants to help me fix it then let me know.

 

*** continued in part two! ***


-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
luabind-user mailing list
luabind-user@...
https://lists.sourceforge.net/lists/listinfo/luabind-user

Re: Custom policies [2/2]

by Dan Posluns-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Here's the contents of the new file, cast_policy.hpp:

#ifndef LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED
#define LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED

#include <luabind/config.hpp>
#include <luabind/detail/policy.hpp>

namespace luabind { namespace detail {

      template<class CastFrom, class CastType, class Direction = lua_to_cpp>
      struct cast_to
      {
            template<class T>
            T apply(lua_State *L, by_value<T> data, int index)
            {
                  typedef typename find_conversion_policy<1, detail::null_type>::type converter_policy;
                  typename mpl::apply_wrap2<converter_policy, CastFrom, lua_to_cpp>::type converter;

                  return CastType::apply<CastFrom, T>(converter.apply(L, LUABIND_DECORATE_TYPE(CastFrom), index));
            }

            template<class T>
            static int match(lua_State* L, by_value<T>, int index)
            {
                  typedef typename find_conversion_policy<1, detail::null_type>::type converter_policy;
                  typename mpl::apply_wrap2<converter_policy, CastFrom, lua_to_cpp>::type converter;

                  return converter.match(L, LUABIND_DECORATE_TYPE(CastFrom), index);
            }

            template<class T>
            void converter_postcall(lua_State*, T, int) {}
      };

      template<int N, class CastFrom, class CastType>
      struct cast_policy : conversion_policy<N>
      {
            struct only_accepts_values {};
            struct only_converts_from_lua_to_cpp {};

            static void precall(lua_State*, const index_map&) {}
            static void postcall(lua_State*, const index_map&) {}

            template<class T, class Direction>
            struct apply
            {
                  //typedef reinterpret_cast_to<CastFrom, Direction> type;

                  typedef typename boost::mpl::if_<boost::is_same<Direction, lua_to_cpp>
                        , typename boost::mpl::if_<boost::is_pointer<T>
                              , only_accepts_values
                              , typename boost::mpl::if_<boost::is_reference<T>
                                    , only_accepts_values
                                    , cast_to<CastFrom, CastType, Direction> >::type>::type
                        , only_converts_from_lua_to_cpp>::type type;
            };
      };
}}

namespace luabind
{
      struct raw_c
      {
            template<class From, class To>
            static To apply(From data)
            {
                  return (To)data;
            }
      };

      struct static_c
      {
            template<class From, class To>
            static To apply(From data)
            {
                  return static_cast<To>(data);
            }
      };

      struct dynamic_c
      {
            template<class From, class To>
            static To apply(From data)
            {
                  return dynamic_cast<To>(data);
            }
      };

      struct reinterpret_c
      {
            template<class From, class To>
            static To apply(From data)
            {
                  return reinterpret_cast<To>(data);
            }
      };

      template<class CastFrom, class CastType, int N>
      detail::policy_cons<detail::cast_policy<N, CastFrom, CastType>, detail::null_type>
      cast(LUABIND_PLACEHOLDER_ARG(N))
      {
            return detail::policy_cons<detail::cast_policy<N, CastFrom, CastType>, detail::null_type>();
      }
}

#endif // LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED


Any comments/questions, let me know!

Dan.

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
luabind-user mailing list
luabind-user@...
https://lists.sourceforge.net/lists/listinfo/luabind-user

Re: Custom policies [2/2]

by Josh Green-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
Mate,
That looks fantastic, awesome work.
Sorry I don't have the change to play with the by value/reference stuff.. But I imagine it would either be a template specialisation thing, or you have this type in your conversion policy:
struct only_accepts_values {};

I assume that stops Luabind from using the class with references... What happens if you use something else or nothing in it's place?

Like I said, awesome work!

Josh


> Date: Thu, 8 May 2008 16:46:28 -0700

> From: dposluns@...
> To: luabind-user@...
> Subject: Re: [luabind] Custom policies [2/2]
>
> Here's the contents of the new file, cast_policy.hpp:
>
> #ifndef LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED
> #define LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED
>
> #include <luabind/config.hpp>
> #include <luabind/detail/policy.hpp>
>
> namespace luabind { namespace detail {
>
>       template<class CastFrom, class CastType, class Direction = lua_to_cpp>
>       struct cast_to
>       {
>             template<class T>
>             T apply(lua_State *L, by_value<T> data, int index)
>             {
>                   typedef typename find_conversion_policy<1, detail::null_type>::type converter_policy;
>                   typename mpl::apply_wrap2<converter_policy, CastFrom, lua_to_cpp>::type converter;
>
>                   return CastType::apply<CastFrom, T>(converter.apply(L, LUABIND_DECORATE_TYPE(CastFrom), index));
>             }
>
>             template<class T>
>             static int match(lua_State* L, by_value<T>, int index)
>             {
>                   typedef typename find_conversion_policy<1, detail::null_type>::type converter_policy;
>                   typename mpl::apply_wrap2<converter_policy, CastFrom, lua_to_cpp>::type converter;
>
>                   return converter.match(L, LUABIND_DECORATE_TYPE(CastFrom), index);
>             }
>
>             template<class T>
>             void converter_postcall(lua_State*, T, int) {}
>       };
>
>       template<int N, class CastFrom, class CastType>
>       struct cast_policy : conversion_policy<N>
>       {
>             struct only_accepts_values {};
>             struct only_converts_from_lua_to_cpp {};
>
>             static void precall(lua_State*, const index_map&) {}
>             static void postcall(lua_State*, const index_map&) {}
>
>             template<class T, class Direction>
>             struct apply
>             {
>                   //typedef reinterpret_cast_to<CastFrom, Direction> type;
>
>                   typedef typename boost::mpl::if_<boost::is_same<Direction, lua_to_cpp>
>                         , typename boost::mpl::if_<boost::is_pointer<T>
>                               , only_accepts_values
>                               , typename boost::mpl::if_<boost::is_reference<T>
>                                     , only_accepts_values
>                                     , cast_to<CastFrom, CastType, Direction> >::type>::type
>                         , only_converts_from_lua_to_cpp>::type type;
>             };
>       };
> }}
>
> namespace luabind
> {
>       struct raw_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return (To)data;
>             }
>       };
>
>       struct static_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return static_cast<To>(data);
>             }
>       };
>
>       struct dynamic_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return dynamic_cast<To>(data);
>             }
>       };
>
>       struct reinterpret_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return reinterpret_cast<To>(data);
>             }
>       };
>
>       template<class CastFrom, class CastType, int N>
>       detail::policy_cons<detail::cast_policy<N, CastFrom, CastType>, detail::null_type>
>       cast(LUABIND_PLACEHOLDER_ARG(N))
>       {
>             return detail::policy_cons<detail::cast_policy<N, CastFrom, CastType>, detail::null_type>();
>       }
> }
>
> #endif // LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED
>
>
> Any comments/questions, let me know!
>
> Dan.
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
> Don't miss this year's exciting event. There's still time to save $100.
> Use priority code J8TL2D2.
> http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
> _______________________________________________
> luabind-user mailing list
> luabind-user@...
> https://lists.sourceforge.net/lists/listinfo/luabind-user


Hotmail on your mobile. Never miss another e-mail with
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
luabind-user mailing list
luabind-user@...
https://lists.sourceforge.net/lists/listinfo/luabind-user

Re: Custom policies [2/2]

by Dan Posluns-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

The only_accepts_values structure was added by me to generate a compile-time error on incorrect use (the other Luabind policies do similar things when they are designed to only take a pointer or reference etc.).

 

Without it, the program would compile if you used a pointer/reference with the policy but Luabind would assert and halt when you tried to use it at run-time.

 

It’s a shame the code base is so arcane… I’d love to go and make more sophisticated improvements to it but 90% of the time I don’t even know where to begin. :(

 

Dan.

 

From: luabind-user-bounces@... [mailto:luabind-user-bounces@...] On Behalf Of Josh Green
Sent: Monday, May 12, 2008 5:26 PM
To: luabind-user@...
Subject: Re: [luabind] Custom policies [2/2]

 

Mate,
That looks fantastic, awesome work.
Sorry I don't have the change to play with the by value/reference stuff.. But I imagine it would either be a template specialisation thing, or you have this type in your conversion policy:
struct only_accepts_values {};

I assume that stops Luabind from using the class with references... What happens if you use something else or nothing in it's place?

Like I said, awesome work!

Josh


> Date: Thu, 8 May 2008 16:46:28 -0700
> From: dposluns@...
> To: luabind-user@...
> Subject: Re: [luabind] Custom policies [2/2]
>
> Here's the contents of the new file, cast_policy.hpp:
>
> #ifndef LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED
> #define LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED
>
> #include <luabind/config.hpp>
> #include <luabind/detail/policy.hpp>
>
> namespace luabind { namespace detail {
>
>       template<class CastFrom, class CastType, class Direction = lua_to_cpp>
>       struct cast_to
>       {
>             template<class T>
>             T apply(lua_State *L, by_value<T> data, int index)
>             {
>                   typedef typename find_conversion_policy<1, detail::null_type>::type converter_policy;
>                   typename mpl::apply_wrap2<converter_policy, CastFrom, lua_to_cpp>::type converter;
>
>                   return CastType::apply<CastFrom, T>(converter.apply(L, LUABIND_DECORATE_TYPE(CastFrom), index));
>             }
>
>             template<class T>
>             static int match(lua_State* L, by_value<T>, int index)
>             {
>                   typedef typename find_conversion_policy<1, detail::null_type>::type converter_policy;
>                   typename mpl::apply_wrap2<converter_policy, CastFrom, lua_to_cpp>::type converter;
>
>                   return converter.match(L, LUABIND_DECORATE_TYPE(CastFrom), index);
>             }
>
>             template<class T>
>             void converter_postcall(lua_State*, T, int) {}
>       };
>
>       template<int N, class CastFrom, class CastType>
>       struct cast_policy : conversion_policy<N>
>       {
>             struct only_accepts_values {};
>             struct only_converts_from_lua_to_cpp {};
>
>             static void precall(lua_State*, const index_map&) {}
>             static void postcall(lua_State*, const index_map&) {}
>
>             template<class T, class Direction>
>             struct apply
>             {
>                   //typedef reinterpret_cast_to<CastFrom, Direction> type;
>
>                   typedef typename boost::mpl::if_<boost::is_same<Direction, lua_to_cpp>
>                         , typename boost::mpl::if_<boost::is_pointer<T>
>                               , only_accepts_values
>                               , typename boost::mpl::if_<boost::is_reference<T>
>                                     , only_accepts_values
>                                     , cast_to<CastFrom, CastType, Direction> >::type>::type
>                         , only_converts_from_lua_to_cpp>::type type;
>             };
>       };
> }}
>
> namespace luabind
> {
>       struct raw_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return (To)data;
>             }
>       };
>
>       struct static_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return static_cast<To>(data);
>             }
>       };
>
>       struct dynamic_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return dynamic_cast<To>(data);
>             }
>       };
>
>       struct reinterpret_c
>       {
>             template<class From, class To>
>             static To apply(From data)
>             {
>                   return reinterpret_cast<To>(data);
>             }
>       };
>
>       template<class CastFrom, class CastType, int N>
>       detail::policy_cons<detail::cast_policy<N, CastFrom, CastType>, detail::null_type>
>       cast(LUABIND_PLACEHOLDER_ARG(N))
>       {
>             return detail::policy_cons<detail::cast_policy<N, CastFrom, CastType>, detail::null_type>();
>       }
> }
>
> #endif // LUABIND_REINTERPRET_CAST_POLICY_HPP_INCLUDED
>
>
> Any comments/questions, let me know!
>
> Dan.
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
> Don't miss this year's exciting event. There's still time to save $100.
> Use priority code J8TL2D2.
> http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
> _______________________________________________
> luabind-user mailing list
> luabind-user@...
> https://lists.sourceforge.net/lists/listinfo/luabind-user


Hotmail on your mobile. Never miss another e-mail with


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
luabind-user mailing list
luabind-user@...
https://lists.sourceforge.net/lists/listinfo/luabind-user
LightInTheBox - Buy quality products at wholesale price