]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/python/include/boost/python/suite/indexing/vector_indexing_suite.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / python / include / boost / python / suite / indexing / vector_indexing_suite.hpp
1 // (C) Copyright Joel de Guzman 2003.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 #ifndef VECTOR_INDEXING_SUITE_JDG20036_HPP
7 # define VECTOR_INDEXING_SUITE_JDG20036_HPP
8
9 # include <boost/python/suite/indexing/indexing_suite.hpp>
10 # include <boost/python/suite/indexing/container_utils.hpp>
11 # include <boost/python/iterator.hpp>
12
13 namespace boost { namespace python {
14
15 // Forward declaration
16 template <class Container, bool NoProxy, class DerivedPolicies>
17 class vector_indexing_suite;
18
19 namespace detail
20 {
21 template <class Container, bool NoProxy>
22 class final_vector_derived_policies
23 : public vector_indexing_suite<Container,
24 NoProxy, final_vector_derived_policies<Container, NoProxy> > {};
25 }
26
27 // The vector_indexing_suite class is a predefined indexing_suite derived
28 // class for wrapping std::vector (and std::vector like) classes. It provides
29 // all the policies required by the indexing_suite (see indexing_suite).
30 // Example usage:
31 //
32 // class X {...};
33 //
34 // ...
35 //
36 // class_<std::vector<X> >("XVec")
37 // .def(vector_indexing_suite<std::vector<X> >())
38 // ;
39 //
40 // By default indexed elements are returned by proxy. This can be
41 // disabled by supplying *true* in the NoProxy template parameter.
42 //
43 template <
44 class Container,
45 bool NoProxy = false,
46 class DerivedPolicies
47 = detail::final_vector_derived_policies<Container, NoProxy> >
48 class vector_indexing_suite
49 : public indexing_suite<Container, DerivedPolicies, NoProxy>
50 {
51 public:
52
53 typedef typename Container::value_type data_type;
54 typedef typename Container::value_type key_type;
55 typedef typename Container::size_type index_type;
56 typedef typename Container::size_type size_type;
57 typedef typename Container::difference_type difference_type;
58
59 template <class Class>
60 static void
61 extension_def(Class& cl)
62 {
63 cl
64 .def("append", &base_append)
65 .def("extend", &base_extend)
66 ;
67 }
68
69 static
70 typename mpl::if_<
71 is_class<data_type>
72 , data_type&
73 , data_type
74 >::type
75 get_item(Container& container, index_type i)
76 {
77 return container[i];
78 }
79
80 static object
81 get_slice(Container& container, index_type from, index_type to)
82 {
83 if (from > to)
84 return object(Container());
85 return object(Container(container.begin()+from, container.begin()+to));
86 }
87
88 static void
89 set_item(Container& container, index_type i, data_type const& v)
90 {
91 container[i] = v;
92 }
93
94 static void
95 set_slice(Container& container, index_type from,
96 index_type to, data_type const& v)
97 {
98 if (from > to) {
99 return;
100 }
101 else {
102 container.erase(container.begin()+from, container.begin()+to);
103 container.insert(container.begin()+from, v);
104 }
105 }
106
107 template <class Iter>
108 static void
109 set_slice(Container& container, index_type from,
110 index_type to, Iter first, Iter last)
111 {
112 if (from > to) {
113 container.insert(container.begin()+from, first, last);
114 }
115 else {
116 container.erase(container.begin()+from, container.begin()+to);
117 container.insert(container.begin()+from, first, last);
118 }
119 }
120
121 static void
122 delete_item(Container& container, index_type i)
123 {
124 container.erase(container.begin()+i);
125 }
126
127 static void
128 delete_slice(Container& container, index_type from, index_type to)
129 {
130 if (from > to) {
131 // A null-op.
132 return;
133 }
134 container.erase(container.begin()+from, container.begin()+to);
135 }
136
137 static size_t
138 size(Container& container)
139 {
140 return container.size();
141 }
142
143 static bool
144 contains(Container& container, key_type const& key)
145 {
146 return std::find(container.begin(), container.end(), key)
147 != container.end();
148 }
149
150 static index_type
151 get_min_index(Container& /*container*/)
152 {
153 return 0;
154 }
155
156 static index_type
157 get_max_index(Container& container)
158 {
159 return container.size();
160 }
161
162 static bool
163 compare_index(Container& /*container*/, index_type a, index_type b)
164 {
165 return a < b;
166 }
167
168 static index_type
169 convert_index(Container& container, PyObject* i_)
170 {
171 extract<long> i(i_);
172 if (i.check())
173 {
174 long index = i();
175 if (index < 0)
176 index += DerivedPolicies::size(container);
177 if (index >= long(container.size()) || index < 0)
178 {
179 PyErr_SetString(PyExc_IndexError, "Index out of range");
180 throw_error_already_set();
181 }
182 return index;
183 }
184
185 PyErr_SetString(PyExc_TypeError, "Invalid index type");
186 throw_error_already_set();
187 return index_type();
188 }
189
190 static void
191 append(Container& container, data_type const& v)
192 {
193 container.push_back(v);
194 }
195
196 template <class Iter>
197 static void
198 extend(Container& container, Iter first, Iter last)
199 {
200 container.insert(container.end(), first, last);
201 }
202
203 private:
204
205 static void
206 base_append(Container& container, object v)
207 {
208 extract<data_type&> elem(v);
209 // try if elem is an exact Data
210 if (elem.check())
211 {
212 DerivedPolicies::append(container, elem());
213 }
214 else
215 {
216 // try to convert elem to data_type
217 extract<data_type> elem(v);
218 if (elem.check())
219 {
220 DerivedPolicies::append(container, elem());
221 }
222 else
223 {
224 PyErr_SetString(PyExc_TypeError,
225 "Attempting to append an invalid type");
226 throw_error_already_set();
227 }
228 }
229 }
230
231 static void
232 base_extend(Container& container, object v)
233 {
234 std::vector<data_type> temp;
235 container_utils::extend_container(temp, v);
236 DerivedPolicies::extend(container, temp.begin(), temp.end());
237 }
238 };
239
240 }} // namespace boost::python
241
242 #endif // VECTOR_INDEXING_SUITE_JDG20036_HPP