OSDN Git Service

build moflib1.0 on cmake-base system
[moflib/moflib.git] / extlib / luabind-0.8 / luabind / iterator_policy.hpp
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)
4
5 #ifndef LUABIND_ITERATOR_POLICY__071111_HPP
6 # define LUABIND_ITERATOR_POLICY__071111_HPP
7
8 # include <luabind/config.hpp>
9 # include <luabind/detail/policy.hpp>
10 # include <luabind/detail/convert_to_lua.hpp>
11
12 namespace luabind { namespace detail {
13
14 template <class Iterator>
15 struct iterator
16 {
17     static int next(lua_State* L)
18     {
19         iterator* self = static_cast<iterator*>(
20             lua_touserdata(L, lua_upvalueindex(1)));
21
22         if (self->first != self->last)
23         {
24             convert_to_lua(L, *self->first);
25             ++self->first;
26         }
27         else
28         {
29             lua_pushnil(L);
30         }
31
32         return 1;
33     }
34
35     static int destroy(lua_State* L)
36     {
37         iterator* self = static_cast<iterator*>(
38             lua_touserdata(L, lua_upvalueindex(1)));
39         self->~iterator();
40         return 0;
41     }
42
43     iterator(Iterator first, Iterator last)
44       : first(first)
45       , last(last)
46     {}
47
48     Iterator first;
49     Iterator last;
50 };
51
52 template <class Iterator>
53 int make_range(lua_State* L, Iterator first, Iterator last)
54 {
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;
63 }
64
65 template <class Container>
66 int make_range(lua_State* L, Container& container)
67 {
68     return make_range(L, container.begin(), container.end());
69 }
70
71 struct iterator_converter
72 {
73     typedef iterator_converter type;
74
75     template <class Container>
76     void apply(lua_State* L, Container& container)
77     {
78         make_range(L, container);
79     }
80
81     template <class Container>
82     void apply(lua_State* L, Container const& container)
83     {
84         make_range(L, container);
85     }
86 };
87
88 struct iterator_policy : conversion_policy<0>
89 {
90     static void precall(lua_State*, index_map const&)
91     {}
92
93     static void postcall(lua_State*, index_map const&)
94     {}
95
96     template <class T, class Direction>
97     struct apply
98     {
99         typedef iterator_converter type;
100     };
101 };
102
103 }} // namespace luabind::detail
104
105 namespace luabind { namespace {
106
107 LUABIND_ANONYMOUS_FIX detail::policy_cons<
108     detail::iterator_policy, detail::null_type> return_stl_iterator;
109
110 }} // namespace luabind::unnamed
111
112 #endif // LUABIND_ITERATOR_POLICY__071111_HPP
113