1
// Copyright (c) 2003 Raoul M. Gough
3
// Use, modification and distribution is subject to the Boost Software
4
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
5
// at http://www.boost.org/LICENSE_1_0.txt)
7
// Header file int_slice_helper.hpp
11
// 2003/10/13 rmg File creation
12
// 2008/12/08 Roman Change indexing suite layout
14
// $Id: int_slice_helper.hpp,v 1.1.2.10 2004/02/08 18:57:42 raoulgough Exp $
17
#ifndef BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP
18
#define BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP
20
# include <boost/python/errors.hpp>
21
# include <indexing_suite/workaround.hpp>
23
namespace boost { namespace python { namespace indexing {
24
template<typename Algorithms, typename SliceType>
25
struct int_slice_helper
27
// Works with a SliceType that provides an int-like index_type
28
// that is convertible to the algorithm's index_param
30
typedef Algorithms algorithms_type;
31
typedef SliceType slice_type;
33
typedef typename algorithms_type::container container;
34
typedef typename algorithms_type::reference reference;
35
typedef typename algorithms_type::value_param value_param;
36
typedef typename algorithms_type::container_traits container_traits;
37
typedef typename slice_type::index_type index_type;
39
int_slice_helper (container &c, slice_type const &);
43
reference current () const;
44
void write (value_param val);
45
void erase_remaining () const;
48
void assign (value_param val) const;
49
void insert (value_param val);
57
template<typename Algorithms, typename SliceType>
58
int_slice_helper<Algorithms, SliceType>
59
::int_slice_helper (container &c, slice_type const &sl)
66
template<typename Algorithms, typename SliceType>
68
int_slice_helper<Algorithms, SliceType>::next()
70
bool result = false; // Assume the worst
74
// First time call - get to start of the slice (if any)
75
m_pos = m_slice.start();
76
result = m_slice.in_range (m_pos);
79
else if (m_slice.in_range (m_pos))
81
// Subsequent calls - advance by the slice's stride
82
m_pos += m_slice.step();
83
result = m_slice.in_range (m_pos);
89
template<typename Algorithms, typename SliceType>
90
typename int_slice_helper<Algorithms, SliceType>::reference
91
int_slice_helper<Algorithms, SliceType>::current () const
93
return algorithms_type::get (*m_ptr, m_pos);
96
template<typename Algorithms, typename SliceType>
97
void int_slice_helper<Algorithms, SliceType>::write (value_param val)
110
template<typename Algorithms, typename SliceType>
111
void int_slice_helper<Algorithms, SliceType>::assign (value_param val) const
113
algorithms_type::assign (*m_ptr, m_pos, val);
117
template<bool doit> struct maybe_insert {
119
// NOTE: use the name "apply_" instead of "apply" to avoid
120
// weirdo compiler crash in mpl/aux_/apply.hpp on MSVC7. Don't
121
// even ask how I arrived at this fix :-)
123
template<class Algorithms>
125
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
126
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
127
// Can't explicitly instantiate member function - must let
128
// the compiler deduce the argument type from a dummy
129
// parameter. Same applies throughout
132
typename Algorithms::container &,
133
typename Algorithms::index_param,
134
typename Algorithms::value_param)
138
"container does not support insertion into slice");
140
boost::python::throw_error_already_set ();
144
template<> struct maybe_insert<true> {
145
template<class Algorithms>
147
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
148
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
151
typename Algorithms::container &c,
152
typename Algorithms::index_param i,
153
typename Algorithms::value_param v)
155
Algorithms::insert (c, i, v);
160
template<typename Algorithms, typename SliceType>
161
void int_slice_helper<Algorithms, SliceType>::insert (value_param val)
163
if (m_slice.step() != 1)
166
PyExc_ValueError, "attempt to insert via extended slice");
168
boost::python::throw_error_already_set ();
173
detail::maybe_insert<
175
container_traits::supported_methods, method_insert>::value>::
176
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
177
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
178
apply_ (static_cast<Algorithms *>(0),
180
BOOST_NESTED_TEMPLATE apply_ <Algorithms>(
184
++m_pos; // Advance for any subsequent inserts
189
template<bool doit> struct maybe_erase {
190
template<class Algorithms>
192
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
193
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
196
typename Algorithms::container &,
197
typename Algorithms::index_param,
198
typename Algorithms::index_param)
201
PyExc_TypeError, "container does not support item deletion");
203
boost::python::throw_error_already_set ();
207
template<> struct maybe_erase<true> {
208
template<class Algorithms>
210
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
211
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
214
typename Algorithms::container &c,
215
typename Algorithms::index_param from,
216
typename Algorithms::index_param to)
218
Algorithms::erase_range (c, from, to);
223
template<typename Algorithms, typename SliceType>
224
void int_slice_helper<Algorithms, SliceType>::erase_remaining () const
226
if (m_slice.step() != 1)
229
PyExc_ValueError, "attempt to delete via extended slice");
231
boost::python::throw_error_already_set ();
238
container_traits::supported_methods, method_delitem>::value>::
240
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
241
&& defined (BOOST_MSVC6_MEMBER_TEMPLATES)
242
apply_ (static_cast<Algorithms *>(0),
244
BOOST_NESTED_TEMPLATE apply_ <Algorithms>(
246
*m_ptr, m_pos, m_slice.stop());
252
#endif // BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP