Fixes #66. Adds support for __stdcall on MSVC.
[luabind.git] / luabind / iterator_policy.hpp
blobad43d2a699ba1c653dfc5100846de1bd48937144
1 // Copyright Daniel Wallin 2007. Use, modification and distribution is
2 // subject to the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 #ifndef LUABIND_ITERATOR_POLICY__071111_HPP
6 # define LUABIND_ITERATOR_POLICY__071111_HPP
8 # include <luabind/config.hpp>
9 # include <luabind/detail/policy.hpp>
10 # include <luabind/detail/convert_to_lua.hpp>
12 namespace luabind { namespace detail {
14 template <class Iterator>
15 struct iterator
17 static int next(lua_State* L)
19 iterator* self = static_cast<iterator*>(
20 lua_touserdata(L, lua_upvalueindex(1)));
22 if (self->first != self->last)
24 convert_to_lua(L, *self->first);
25 ++self->first;
27 else
29 lua_pushnil(L);
32 return 1;
35 static int destroy(lua_State* L)
37 iterator* self = static_cast<iterator*>(
38 lua_touserdata(L, lua_upvalueindex(1)));
39 self->~iterator();
40 return 0;
43 iterator(Iterator first, Iterator last)
44 : first(first)
45 , last(last)
48 Iterator first;
49 Iterator last;
52 template <class Iterator>
53 int make_range(lua_State* L, Iterator first, Iterator last)
55 void* storage = lua_newuserdata(L, sizeof(iterator<Iterator>));
56 lua_newtable(L);
57 lua_pushcclosure(L, iterator<Iterator>::destroy, 0);
58 lua_setfield(L, -2, "__gc");
59 lua_setmetatable(L, -2);
60 lua_pushcclosure(L, iterator<Iterator>::next, 1);
61 new (storage) iterator<Iterator>(first, last);
62 return 1;
65 template <class Container>
66 int make_range(lua_State* L, Container& container)
68 return make_range(L, container.begin(), container.end());
71 struct iterator_converter
73 typedef boost::mpl::bool_<false> is_value_converter;
74 typedef iterator_converter type;
76 template <class Container>
77 void apply(lua_State* L, Container& container)
79 make_range(L, container);
82 template <class Container>
83 void apply(lua_State* L, Container const& container)
85 make_range(L, container);
89 struct iterator_policy : conversion_policy<0>
91 static void precall(lua_State*, index_map const&)
94 static void postcall(lua_State*, index_map const&)
97 template <class T, class Direction>
98 struct apply
100 typedef iterator_converter type;
104 }} // namespace luabind::detail
106 namespace luabind { namespace {
108 LUABIND_ANONYMOUS_FIX detail::policy_cons<
109 detail::iterator_policy, detail::null_type> return_stl_iterator;
111 }} // namespace luabind::unnamed
113 #endif // LUABIND_ITERATOR_POLICY__071111_HPP