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