~yade-dev/yade/0.80

« back to all changes in this revision

Viewing changes to py/3rd-party/boost-python-indexing-suite-v2-noSymlinkHeaders/int_slice_helper.hpp

  • Committer: Anton Gladky
  • Date: 2012-05-02 21:50:42 UTC
  • Revision ID: gladky.anton@gmail.com-20120502215042-v1fa9r65usqe7kfk
0.80.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2003 Raoul M. Gough
 
2
//
 
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)
 
6
//
 
7
// Header file int_slice_helper.hpp
 
8
//
 
9
// History
 
10
// =======
 
11
// 2003/10/13   rmg     File creation
 
12
// 2008/12/08   Roman   Change indexing suite layout
 
13
//
 
14
// $Id: int_slice_helper.hpp,v 1.1.2.10 2004/02/08 18:57:42 raoulgough Exp $
 
15
//
 
16
 
 
17
#ifndef BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP
 
18
#define BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP
 
19
 
 
20
# include <boost/python/errors.hpp>
 
21
# include <indexing_suite/workaround.hpp>
 
22
 
 
23
namespace boost { namespace python { namespace indexing {
 
24
  template<typename Algorithms, typename SliceType>
 
25
  struct int_slice_helper
 
26
  {
 
27
    // Works with a SliceType that provides an int-like index_type
 
28
    // that is convertible to the algorithm's index_param
 
29
 
 
30
    typedef Algorithms algorithms_type;
 
31
    typedef SliceType slice_type;
 
32
 
 
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;
 
38
 
 
39
    int_slice_helper (container &c, slice_type const &);
 
40
 
 
41
    bool next();
 
42
 
 
43
    reference current () const;
 
44
    void write (value_param val);
 
45
    void erase_remaining () const;
 
46
 
 
47
  private:
 
48
    void assign (value_param val) const;
 
49
    void insert (value_param val);
 
50
 
 
51
  private:
 
52
    slice_type m_slice;
 
53
    container *m_ptr;
 
54
    index_type m_pos;
 
55
  };
 
56
 
 
57
  template<typename Algorithms, typename SliceType>
 
58
  int_slice_helper<Algorithms, SliceType>
 
59
  ::int_slice_helper (container &c, slice_type const &sl)
 
60
    : m_slice (sl),
 
61
    m_ptr (&c),
 
62
    m_pos (-1)
 
63
  {
 
64
  }
 
65
 
 
66
  template<typename Algorithms, typename SliceType>
 
67
  bool
 
68
  int_slice_helper<Algorithms, SliceType>::next()
 
69
  {
 
70
    bool result = false; // Assume the worst
 
71
 
 
72
    if (m_pos == -1)
 
73
      {
 
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);
 
77
      }
 
78
 
 
79
    else if (m_slice.in_range (m_pos))
 
80
      {
 
81
        // Subsequent calls - advance by the slice's stride
 
82
        m_pos += m_slice.step();
 
83
        result = m_slice.in_range (m_pos);
 
84
      }
 
85
 
 
86
    return result;
 
87
  }
 
88
 
 
89
  template<typename Algorithms, typename SliceType>
 
90
  typename int_slice_helper<Algorithms, SliceType>::reference
 
91
  int_slice_helper<Algorithms, SliceType>::current () const
 
92
  {
 
93
    return algorithms_type::get (*m_ptr, m_pos);
 
94
  }
 
95
 
 
96
  template<typename Algorithms, typename SliceType>
 
97
  void int_slice_helper<Algorithms, SliceType>::write (value_param val)
 
98
  {
 
99
    if (next())
 
100
      {
 
101
        assign (val);
 
102
      }
 
103
 
 
104
    else
 
105
      {
 
106
        insert (val);
 
107
      }
 
108
  }
 
109
 
 
110
  template<typename Algorithms, typename SliceType>
 
111
  void int_slice_helper<Algorithms, SliceType>::assign (value_param val) const
 
112
  {
 
113
    algorithms_type::assign (*m_ptr, m_pos, val);
 
114
  }
 
115
 
 
116
  namespace detail {
 
117
    template<bool doit> struct maybe_insert {
 
118
 
 
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 :-)
 
122
 
 
123
      template<class Algorithms>
 
124
      static void apply_(
 
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
 
130
          Algorithms *,
 
131
# endif
 
132
          typename Algorithms::container &,
 
133
          typename Algorithms::index_param,
 
134
          typename Algorithms::value_param)
 
135
      {
 
136
        PyErr_SetString(
 
137
            PyExc_TypeError,
 
138
            "container does not support insertion into slice");
 
139
 
 
140
        boost::python::throw_error_already_set ();
 
141
      }
 
142
    };
 
143
 
 
144
    template<> struct maybe_insert<true> {
 
145
      template<class Algorithms>
 
146
      static void apply_(
 
147
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
 
148
        && defined (BOOST_MSVC6_MEMBER_TEMPLATES)
 
149
          Algorithms *,
 
150
# endif
 
151
          typename Algorithms::container &c,
 
152
          typename Algorithms::index_param i,
 
153
          typename Algorithms::value_param v)
 
154
      {
 
155
        Algorithms::insert (c, i, v);
 
156
      }
 
157
    };
 
158
  }
 
159
 
 
160
  template<typename Algorithms, typename SliceType>
 
161
  void int_slice_helper<Algorithms, SliceType>::insert (value_param val)
 
162
  {
 
163
    if (m_slice.step() != 1)
 
164
      {
 
165
        PyErr_SetString(
 
166
            PyExc_ValueError, "attempt to insert via extended slice");
 
167
 
 
168
        boost::python::throw_error_already_set ();
 
169
      }
 
170
 
 
171
    else
 
172
      {
 
173
        detail::maybe_insert<
 
174
          detail::is_member<
 
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),
 
179
# else
 
180
          BOOST_NESTED_TEMPLATE apply_ <Algorithms>(
 
181
# endif
 
182
              *m_ptr, m_pos, val);
 
183
 
 
184
        ++m_pos;  // Advance for any subsequent inserts
 
185
      }
 
186
  }
 
187
 
 
188
  namespace detail {
 
189
    template<bool doit> struct maybe_erase {
 
190
      template<class Algorithms>
 
191
      static void apply_(
 
192
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
 
193
        && defined (BOOST_MSVC6_MEMBER_TEMPLATES)
 
194
          Algorithms *,
 
195
# endif
 
196
          typename Algorithms::container &,
 
197
          typename Algorithms::index_param,
 
198
          typename Algorithms::index_param)
 
199
      {
 
200
        PyErr_SetString(
 
201
            PyExc_TypeError, "container does not support item deletion");
 
202
 
 
203
        boost::python::throw_error_already_set ();
 
204
      }
 
205
    };
 
206
 
 
207
    template<> struct maybe_erase<true> {
 
208
      template<class Algorithms>
 
209
      static void apply_(
 
210
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
 
211
        && defined (BOOST_MSVC6_MEMBER_TEMPLATES)
 
212
          Algorithms *,
 
213
# endif
 
214
          typename Algorithms::container &c,
 
215
          typename Algorithms::index_param from,
 
216
          typename Algorithms::index_param to)
 
217
      {
 
218
        Algorithms::erase_range (c, from, to);
 
219
      }
 
220
    };
 
221
  }
 
222
 
 
223
  template<typename Algorithms, typename SliceType>
 
224
  void int_slice_helper<Algorithms, SliceType>::erase_remaining () const
 
225
  {
 
226
    if (m_slice.step() != 1)
 
227
      {
 
228
        PyErr_SetString(
 
229
            PyExc_ValueError, "attempt to delete via extended slice");
 
230
 
 
231
        boost::python::throw_error_already_set ();
 
232
      }
 
233
 
 
234
    else
 
235
      {
 
236
        detail::maybe_erase<
 
237
          detail::is_member<
 
238
            container_traits::supported_methods, method_delitem>::value>::
 
239
 
 
240
# if defined (BOOST_NO_MEMBER_TEMPLATES) \
 
241
  && defined (BOOST_MSVC6_MEMBER_TEMPLATES)
 
242
          apply_ (static_cast<Algorithms *>(0),
 
243
# else
 
244
          BOOST_NESTED_TEMPLATE apply_ <Algorithms>(
 
245
# endif
 
246
              *m_ptr, m_pos, m_slice.stop());
 
247
      }
 
248
  }
 
249
 
 
250
} } }
 
251
 
 
252
#endif // BOOST_PYTHON_INDEXING_INT_SLICE_HELPER_HPP