Crazy Eddie's GUI System  ${CEGUI_VERSION}
algorithms.hpp
1 // This file has been generated by Py++.
2 
3 // Header file algorithms.hpp
4 //
5 // Uniform interface layer for all containers.
6 //
7 // Copyright (c) 2003 Raoul M. Gough
8 //
9 // Use, modification and distribution is subject to the Boost Software
10 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
11 // at http://www.boost.org/LICENSE_1_0.txt)
12 //
13 // History
14 // =======
15 // 2003/ 9/11 rmg File creation from suite_utils.hpp
16 // 2003/10/28 rmg Split container-specific versions into separate headers
17 // 2006/10/25 Roman Adding keys function to assoc_algorithms class
18 // 2008/12/08 Roman Change indexing suite layout
19 //
20 // $Id: algorithms.hpp,v 1.1.2.15 2004/02/08 18:57:42 raoulgough Exp $
21 //
22 
23 #ifndef BOOST_PYTHON_INDEXING_ALGORITHMS_HPP
24 #define BOOST_PYTHON_INDEXING_ALGORITHMS_HPP
25 
26 #include <indexing_suite/suite_utils.hpp>
27 
28 #include <boost/type_traits.hpp>
29 #include <boost/python/errors.hpp>
30 #include <indexing_suite/int_slice_helper.hpp>
31 #include <indexing_suite/slice.hpp>
32 #include <boost/mpl/if.hpp>
33 #include <boost/limits.hpp>
34 #include <algorithm>
35 #include <functional>
36 #include <stdexcept>
37 #include <string>
38 #include <set>
39 
40 namespace boost { namespace python { namespace indexing {
41  template<typename ContainerTraits, typename Ovr = detail::no_override>
43  {
46  ::type most_derived;
47 
48  public:
49  typedef ContainerTraits container_traits;
50 
51  // Import typedefs from the container_traits for convenience
52  typedef typename ContainerTraits::container container;
53  typedef typename ContainerTraits::iterator iterator;
54  typedef typename ContainerTraits::reference reference;
55  typedef typename ContainerTraits::size_type size_type;
56  typedef typename ContainerTraits::value_type value_type;
57  typedef typename ContainerTraits::value_param value_param;
58  typedef typename ContainerTraits::index_param index_param;
59  typedef typename ContainerTraits::key_param key_param;
60 
61  // Defer selection of supported_methods to the ContainerTraits
62  // template argument. This makes sense because default_algorithms
63  // derives all of its other information from this argument, and
64  // can't decide which of the static member functions will
65  // instantiate successfully for the container. Obviously a
66  // custom-written Algorithms implementation could choose to
67  // provide the supported_methods directly.
68 
69  BOOST_STATIC_CONSTANT(
70  method_set_type,
71  supported_methods = ContainerTraits::supported_methods);
72 
73  static size_type size (container &);
74  static iterator find (container &, key_param);
75  static size_type get_index (container &, key_param);
76  static size_type count (container &, key_param);
77  static bool contains (container &, key_param);
78  static void reverse (container &);
79  static reference get (container &, index_param);
80  static void assign (container &, index_param, value_param);
81  static void insert (container &, index_param, value_param);
82  static void erase_one (container &, index_param);
83  static void erase_range(container &, index_param, index_param);
84  static void push_back (container &, value_param);
85  static void sort (container &);
86  // static void sort (container &, PyObject *);
87 
88  static iterator begin (container &c) { return c.begin(); }
89  static iterator end (container &c) { return c.end(); }
90 
91  // Reasonable defaults for slice handling
93 
94  static slice_helper make_slice_helper (container &c, slice const &);
95 
96  // Default visit_container_class
97  template<typename PythonClass, typename Policy>
98  static void visit_container_class(
99  PythonClass &pyClass, Policy const &policy)
100  {
101  container_traits::visit_container_class (pyClass, policy);
102  }
103 
104 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
105  // MSVC6 and 7.0 seem to complain about most_derived::bounds_check
106  // for an instantiation of list_algorithms.
107  public:
108 #else
109  private:
110 #endif
111  static size_type bounds_check(
112  container &, index_param, char const *msg,
113  bool one_past = false,
114  bool truncate = false);
115  // Throws std::out_of_range if necessary. If one_past is set, then
116  // indexes up to container.size() *inclusive* are allowed. If
117  // truncate is set, then out of bounds values are reset to the
118  // nearest in-bound value (and if none exists, throws an
119  // exception). If truncate is *not* set, then negative values index
120  // from the upper bound backwards and are bounds-checked.
121  };
122 
124  // Base class for associative containers
126 
127  template<typename ContainerTraits, typename Ovr = detail::no_override>
129  : public default_algorithms
130  <ContainerTraits,
131  BOOST_DEDUCED_TYPENAME detail::maybe_override
132  <assoc_algorithms<ContainerTraits, Ovr>, Ovr>
133  ::type>
134  {
137  ::type most_derived;
139 
140  public:
141  typedef typename Parent::iterator iterator;
142  typedef typename Parent::size_type size_type;
143  typedef typename Parent::container container;
144  typedef typename Parent::reference reference;
145  typedef typename Parent::key_param key_param;
146  typedef typename Parent::value_param value_param;
147  typedef typename Parent::index_param index_param;
148 
149  static reference get (container &, index_param);
150 
151  // Use member functions for the following (hiding base class versions)
152  static void erase_one (container &, key_param);
153  static iterator find (container &, key_param);
154  static size_type count (container &, key_param);
155  static bool contains (container &, key_param);
156 
157  // Default visit_container_class
158  template<typename PythonClass, typename Policy>
159  static void visit_container_class( PythonClass &pyClass, Policy const &policy)
160  {
161  ContainerTraits::visit_container_class (pyClass, policy);
162  }
163 
164 
165  protected:
166  static iterator find_or_throw (container &, index_param);
167  };
168 
170  // Get the size of a container
172 
173  template<typename ContainerTraits, typename Ovr>
174  BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
176  {
177  return c.size();
178  }
179 
181  // Range check an index and throw out_of_range if necessary
183 
184  template<typename ContainerTraits, typename Ovr>
185  BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
187  container &c,
188  index_param ix,
189  char const *msg,
190  bool one_past,
191  bool truncate)
192  {
193  size_type bound = most_derived::size(c) + (one_past ? 1 : 0);
194  size_type result;
195 
196  if (truncate)
197  {
198  if (ix < 0)
199  {
200  result = 0;
201  }
202 
203  else
204  {
205  result = ix;
206 
207  if ((result >= bound) && (bound > 0))
208  {
209  result = bound - 1;
210  }
211  }
212  }
213 
214  else if (ix < 0)
215  {
216  if (size_type(-ix) > bound)
217  {
218  throw std::out_of_range (msg);
219  }
220 
221  result = bound + ix;
222  }
223 
224  else
225  {
226  result = ix;
227  }
228 
229  if (result >= bound)
230  {
231  throw std::out_of_range (msg);
232  }
233 
234  return result;
235  }
236 
238  // Find an element in a container (std algorithm version)
240 
241  template<typename ContainerTraits, typename Ovr>
242  BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::iterator
244  container &c, key_param key)
245  {
246  typedef typename container_traits::value_traits_type vtraits;
247  typedef typename vtraits::equal_to comparison;
248 
249  return std::find_if(
250  most_derived::begin(c),
251  most_derived::end(c),
252  std::bind1st (comparison(), key));
253  }
254 
256  // Find an element and return its index (std algorithm version)
258 
259  template<typename ContainerTraits, typename Ovr>
260  BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
262  container &c, key_param key)
263  {
264  iterator found (most_derived::find (c, key));
265 
266  if (found == most_derived::end(c))
267  {
268  PyErr_SetString(
269  PyExc_ValueError, "get_index: element not found");
270 
271  boost::python::throw_error_already_set ();
272  }
273 
274  iterator start (most_derived::begin (c));
275  return std::distance (start, found);
276  }
277 
279  // Count occurances of an element in a container (std algorithm version)
281 
282  template<typename ContainerTraits, typename Ovr>
283  BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::size_type
285  container &c, key_param key)
286  {
287  typedef typename container_traits::value_traits_type vtraits;
288  typedef typename vtraits::equal_to comparison;
289 
290  return std::count_if(
291  most_derived::begin(c),
292  most_derived::end(c),
293  std::bind1st (comparison(), key));
294  }
295 
297  // Check whether a container contains the given element (std algo ver)
299 
300  template<typename ContainerTraits, typename Ovr>
301  bool
303  container &c, key_param key)
304  {
305  return most_derived::find (c, key) != most_derived::end(c);
306  }
307 
309  // Index into a container (generic version)
311 
312  template<typename ContainerTraits, typename Ovr>
313  BOOST_DEDUCED_TYPENAME default_algorithms<ContainerTraits, Ovr>::reference
315  container &c, index_param ix)
316  {
317  return c[most_derived::bounds_check (c, ix, "get")];
318  }
319 
321  // Assign a value at a particular index (generic version)
323 
324  template<typename ContainerTraits, typename Ovr>
325  void
327  container &c, index_param ix, value_param val)
328  {
329  c[most_derived::bounds_check (c, ix, "assign")] = val;
330  }
331 
333  // Insert at end of a container (generic version)
335 
336  template<typename ContainerTraits, typename Ovr>
337  void
339  container &c, value_param v)
340  {
341  c.push_back (v);
342  }
343 
345  // Insert at an index in the container (generic version)
347 
348  template<typename ContainerTraits, typename Ovr>
349  void
351  container &c, index_param i, value_param v)
352  {
353  iterator insert_pos (most_derived::begin(c));
354 
355  // Index may range up to c.size() inclusive to allow inserting at end
356  std::advance(
357  insert_pos, most_derived::bounds_check (c, i, "insert", true, true));
358 
359  c.insert (insert_pos, v);
360  }
361 
363  // Erase between given indexes in the container (generic version)
365 
366  template<typename ContainerTraits, typename Ovr>
367  void
369  container &c, index_param from, index_param to)
370  {
371  iterator start (most_derived::begin(c));
372  iterator finish (most_derived::begin(c));
373 
374  // Start index must be properly in bounds
375  std::advance
376  (start, most_derived::bounds_check (c, from, "erase_range (from)"));
377 
378  // End index is one-past-the-end, so may range up to c.size() inclusive
379  std::advance
380  (finish, most_derived::bounds_check (c, to, "erase_range (to)", true));
381 
382  c.erase (start, finish);
383  }
384 
386  // Erase one element at the given index in the container (generic version)
388 
389  template<typename ContainerTraits, typename Ovr>
390  void
392  container &c, index_param ix)
393  {
394  iterator iter (most_derived::begin(c));
395  std::advance (iter, most_derived::bounds_check (c, ix, "erase_one"));
396  c.erase (iter);
397  }
398 
400  // Reverse the contents of a container (std algorithm version)
402 
403  template<typename ContainerTraits, typename Ovr>
405  {
406  std::reverse (most_derived::begin(c), most_derived::end(c));
407  }
408 
410  // Sort the contents of a container (std algorithm version)
412 
413  template<typename ContainerTraits, typename Ovr>
415  {
416  typedef typename container_traits::value_traits_type vtraits;
417  typedef typename vtraits::less comparison;
418  std::sort (most_derived::begin(c), most_derived::end(c), comparison());
419  }
420 
422  // slice_helper factory function (default version)
424 
425  template<typename ContainerTraits, typename Ovr>
428  ::make_slice_helper (container &c, slice const &sl)
429  {
430  return slice_helper (c, integer_slice (sl, most_derived::size (c)));
431  }
432 
434  // Index into a container (associative version)
436 
437  template<typename ContainerTraits, typename Ovr>
438  BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::reference
439  assoc_algorithms<ContainerTraits, Ovr>::get (container &c, index_param ix)
440  {
441  return *most_derived::find_or_throw (c, ix);
442  }
443 
445  // Erase elements with the given key (associative version)
447 
448  template<typename ContainerTraits, typename Ovr>
449  void
451  container &c, key_param key)
452  {
453  if (c.erase (key) == 0)
454  {
455  PyErr_SetString(
456  PyExc_ValueError, "Container does not hold value to be erased");
457 
458  boost::python::throw_error_already_set ();
459  }
460  }
461 
463  // Find an element in an associative container
465 
466  template<typename ContainerTraits, typename Ovr>
467  BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::iterator
469  ::find (container &c, key_param key)
470  {
471  return c.find (key);
472  }
473 
475  // Find an element in an associative container
477 
478  template<typename ContainerTraits, typename Ovr>
479  bool
481  container &c, key_param key)
482  {
483  return most_derived::find (c, key) != most_derived::end(c);
484  }
485 
487  // Find an element in an associative container - throw an exception if
488  // not found
490 
491  template<typename ContainerTraits, typename Ovr>
492  BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::iterator
494  container &c, index_param ix)
495  {
496  iterator iter = most_derived::find (c, ix);
497 
498  if (iter == most_derived::end(c))
499  {
500  PyErr_SetString(
501  PyExc_ValueError, "associative container: key not found");
502 
503  boost::python::throw_error_already_set ();
504  }
505 
506  return iter;
507  }
508 
510  // Count occurances of an element in a container (associative version)
512 
513  template<typename ContainerTraits, typename Ovr>
514  BOOST_DEDUCED_TYPENAME assoc_algorithms<ContainerTraits, Ovr>::size_type
516  container &c, key_param key)
517  {
518  return c.count (key);
519  }
520 
522  // Some meta-information to select algorithms for const and
523  // non-const qualified containers. All algorithms_selector specializations
524  // include two publically accessible typedefs, called
525  // mutable_algorithms and const_algorithms. This saves having to
526  // have separate partial specializations of algorithms for
527  // const and non-const containers. Client code should probably
528  // specialize algorithms directly.
530 
531  namespace detail {
532  template<typename Container> class algorithms_selector
533 # if defined(BOOST_MPL_MSVC_ETI_BUG)
534  {
535  // Bogus types to prevent compile errors due to ETI
536  typedef algorithms_selector<Container> mutable_algorithms;
537  typedef algorithms_selector<Container> const_algorithms;
538  }
539 # endif
540  ;
541  }
542 
544  // Algorithms selection for mutable containers
546 
547  template<class Container>
548  struct algorithms
549  : public detail::algorithms_selector<Container>::mutable_algorithms
550  {
551  };
552 
553 # if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
554  // Algorithms selection for const-qualified containers
557 
558  template<class Container>
559  struct algorithms<Container const>
560  : public detail::algorithms_selector<Container>::const_algorithms
561  {
562  };
563 # endif
564 } } }
565 
566 #endif // BOOST_PYTHON_INDEXING_ALGORITHMS_HPP
567 
568 
569 
Definition: algorithms.hpp:42
Definition: algorithms.hpp:128
Definition: python_CEGUI.h:9
Definition: slice.hpp:31
Definition: algorithms.hpp:548
Definition: int_slice_helper.hpp:27