My Project
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*>(lua_touserdata(L, 1));
38  self->~iterator();
39  return 0;
40  }
41 
42  iterator(Iterator first, Iterator last)
43  : first(first)
44  , last(last)
45  {}
46 
47  Iterator first;
48  Iterator last;
49 };
50 
51 template <class Iterator>
52 int make_range(lua_State* L, Iterator first, Iterator last)
53 {
54  void* storage = lua_newuserdata(L, sizeof(iterator<Iterator>));
55  lua_newtable(L);
56  lua_pushcclosure(L, iterator<Iterator>::destroy, 0);
57  lua_setfield(L, -2, "__gc");
58  lua_setmetatable(L, -2);
59  lua_pushcclosure(L, iterator<Iterator>::next, 1);
60  new (storage) iterator<Iterator>(first, last);
61  return 1;
62 }
63 
64 template <class Container>
65 int make_range(lua_State* L, Container& container)
66 {
67  return make_range(L, container.begin(), container.end());
68 }
69 
71 {
72  typedef iterator_converter type;
73 
74  template <class Container>
75  void apply(lua_State* L, Container& container)
76  {
77  make_range(L, container);
78  }
79 
80  template <class Container>
81  void apply(lua_State* L, Container const& container)
82  {
83  make_range(L, container);
84  }
85 };
86 
88 {
89  static void precall(lua_State*, index_map const&)
90  {}
91 
92  static void postcall(lua_State*, index_map const&)
93  {}
94 
95  template <class T, class Direction>
96  struct apply
97  {
98  typedef iterator_converter type;
99  };
100 };
101 
102 }} // namespace luabind::detail
103 
104 namespace luabind { namespace {
105 
106 LUABIND_ANONYMOUS_FIX detail::policy_cons<
107  detail::iterator_policy, detail::null_type> return_stl_iterator;
108 
109 }} // namespace luabind::unnamed
110 
111 #endif // LUABIND_ITERATOR_POLICY__071111_HPP
112 
Definition: policy.hpp:77
Definition: policy.hpp:83
Definition: minilua.c:461
Definition: PEtypes.h:507
Definition: iterator_policy.hpp:96
Definition: primitives.hpp:44
Definition: iterator_policy.hpp:87
Definition: iterator_policy.hpp:70
Definition: iterator_policy.hpp:15
Definition: policy.hpp:104