Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:26:16

0001 //  (C) Copyright Joel de Guzman 2003.
0002 //  Distributed under the Boost Software License, Version 1.0. (See
0003 //  accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef VECTOR_INDEXING_SUITE_JDG20036_HPP
0007 # define VECTOR_INDEXING_SUITE_JDG20036_HPP
0008 
0009 # include <boost/python/suite/indexing/indexing_suite.hpp>
0010 # include <boost/python/suite/indexing/container_utils.hpp>
0011 # include <boost/python/iterator.hpp>
0012 
0013 namespace boost { namespace python {
0014             
0015     // Forward declaration
0016     template <class Container, bool NoProxy, class DerivedPolicies>
0017     class vector_indexing_suite;
0018     
0019     namespace detail
0020     {
0021         template <class Container, bool NoProxy>
0022         class final_vector_derived_policies 
0023             : public vector_indexing_suite<Container, 
0024                 NoProxy, final_vector_derived_policies<Container, NoProxy> > {};
0025     }
0026 
0027     // The vector_indexing_suite class is a predefined indexing_suite derived 
0028     // class for wrapping std::vector (and std::vector like) classes. It provides
0029     // all the policies required by the indexing_suite (see indexing_suite).
0030     // Example usage:
0031     //
0032     //  class X {...};
0033     //
0034     //  ...
0035     //
0036     //      class_<std::vector<X> >("XVec")
0037     //          .def(vector_indexing_suite<std::vector<X> >())
0038     //      ;
0039     //
0040     // By default indexed elements are returned by proxy. This can be
0041     // disabled by supplying *true* in the NoProxy template parameter.
0042     //
0043     template <
0044         class Container, 
0045         bool NoProxy = false,
0046         class DerivedPolicies 
0047             = detail::final_vector_derived_policies<Container, NoProxy> >
0048     class vector_indexing_suite 
0049         : public indexing_suite<Container, DerivedPolicies, NoProxy>
0050     {
0051     public:
0052     
0053         typedef typename Container::value_type data_type;
0054         typedef typename Container::value_type key_type;
0055         typedef typename Container::size_type index_type;
0056         typedef typename Container::size_type size_type;
0057         typedef typename Container::difference_type difference_type;
0058         
0059         template <class Class>
0060         static void 
0061         extension_def(Class& cl)
0062         {
0063             cl
0064                 .def("append", &base_append)
0065                 .def("extend", &base_extend)
0066             ;
0067         }
0068         
0069         static 
0070         typename mpl::if_<
0071             is_class<data_type>
0072           , data_type&
0073           , data_type
0074         >::type
0075         get_item(Container& container, index_type i)
0076         { 
0077             return container[i];
0078         }
0079 
0080         static object 
0081         get_slice(Container& container, index_type from, index_type to)
0082         { 
0083             if (from > to)
0084                 return object(Container());
0085             return object(Container(container.begin()+from, container.begin()+to));
0086         }
0087 
0088         static void 
0089         set_item(Container& container, index_type i, data_type const& v)
0090         { 
0091             container[i] = v;
0092         }
0093 
0094         static void 
0095         set_slice(Container& container, index_type from, 
0096             index_type to, data_type const& v)
0097         { 
0098             if (from > to) {
0099                 return;
0100             }
0101             else {
0102                 container.erase(container.begin()+from, container.begin()+to);
0103                 container.insert(container.begin()+from, v);
0104             }
0105         }
0106 
0107         template <class Iter>
0108         static void 
0109         set_slice(Container& container, index_type from, 
0110             index_type to, Iter first, Iter last)
0111         { 
0112             if (from > to) {
0113                 container.insert(container.begin()+from, first, last);
0114             }
0115             else {
0116                 container.erase(container.begin()+from, container.begin()+to);
0117                 container.insert(container.begin()+from, first, last);
0118             }
0119         }
0120 
0121         static void 
0122         delete_item(Container& container, index_type i)
0123         { 
0124             container.erase(container.begin()+i);
0125         }
0126         
0127         static void 
0128         delete_slice(Container& container, index_type from, index_type to)
0129         { 
0130             if (from > to) {
0131                 // A null-op.
0132                 return;
0133             }
0134             container.erase(container.begin()+from, container.begin()+to);
0135         }
0136         
0137         static size_t
0138         size(Container& container)
0139         {
0140             return container.size();
0141         }
0142         
0143         static bool
0144         contains(Container& container, key_type const& key)
0145         {
0146             return std::find(container.begin(), container.end(), key)
0147                 != container.end();
0148         }
0149         
0150         static index_type
0151         get_min_index(Container& /*container*/)
0152         { 
0153             return 0;
0154         }
0155 
0156         static index_type
0157         get_max_index(Container& container)
0158         { 
0159             return container.size();
0160         }
0161       
0162         static bool 
0163         compare_index(Container& /*container*/, index_type a, index_type b)
0164         {
0165             return a < b;
0166         }
0167         
0168         static index_type
0169         convert_index(Container& container, PyObject* i_)
0170         { 
0171             extract<long> i(i_);
0172             if (i.check())
0173             {
0174                 long index = i();
0175                 if (index < 0)
0176                     index += DerivedPolicies::size(container);
0177                 if (index >= long(container.size()) || index < 0)
0178                 {
0179                     PyErr_SetString(PyExc_IndexError, "Index out of range");
0180                     throw_error_already_set();
0181                 }
0182                 return index;
0183             }
0184             
0185             PyErr_SetString(PyExc_TypeError, "Invalid index type");
0186             throw_error_already_set();
0187             return index_type();
0188         }
0189       
0190         static void 
0191         append(Container& container, data_type const& v)
0192         { 
0193             container.push_back(v);
0194         }
0195         
0196         template <class Iter>
0197         static void 
0198         extend(Container& container, Iter first, Iter last)
0199         { 
0200             container.insert(container.end(), first, last);
0201         }
0202         
0203     private:
0204     
0205         static void
0206         base_append(Container& container, object v)
0207         {
0208             extract<data_type&> elem(v);
0209             // try if elem is an exact Data
0210             if (elem.check())
0211             {
0212                 DerivedPolicies::append(container, elem());
0213             }
0214             else
0215             {
0216                 //  try to convert elem to data_type
0217                 extract<data_type> elem(v);
0218                 if (elem.check())
0219                 {
0220                     DerivedPolicies::append(container, elem());
0221                 }
0222                 else
0223                 {
0224                     PyErr_SetString(PyExc_TypeError, 
0225                         "Attempting to append an invalid type");
0226                     throw_error_already_set();
0227                 }
0228             }
0229         }
0230         
0231         static void
0232         base_extend(Container& container, object v)
0233         {
0234             std::vector<data_type> temp;
0235             container_utils::extend_container(temp, v);
0236             DerivedPolicies::extend(container, temp.begin(), temp.end());
0237         }
0238     };
0239        
0240 }} // namespace boost::python 
0241 
0242 #endif // VECTOR_INDEXING_SUITE_JDG20036_HPP