00001
00002
00003
00004
00005
00006 #ifndef __CXX_Objects__h
00007 #define __CXX_Objects__h
00008
00009
00010 #if defined(_XOPEN_SOURCE)
00011 #undef _XOPEN_SOURCE
00012 #endif
00013
00014 #include "Python.h"
00015 #include "Version.hxx"
00016 #include "Config.hxx"
00017 #include "Exception.hxx"
00018
00019
00020 #include <iostream>
00021 #include STR_STREAM
00022 #include <string>
00023 #include <iterator>
00024 #include <utility>
00025 #include <typeinfo>
00026
00027 namespace Py
00028 {
00029 typedef int sequence_index_type;
00030
00031
00032 class Object;
00033 class Type;
00034 template<TEMPLATE_TYPENAME T> class SeqBase;
00035 class String;
00036 class List;
00037 template<TEMPLATE_TYPENAME T> class MapBase;
00038
00039
00040 inline PyObject* new_reference_to(PyObject* p)
00041 {
00042 Py::_XINCREF(p);
00043 return p;
00044 }
00045
00046
00047
00048 inline PyObject* Null()
00049 {
00050 return (static_cast<PyObject*>(0));
00051 }
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 class Object
00117 {
00118 private:
00119
00120
00121
00122
00123
00124 PyObject* p;
00125
00126 protected:
00127
00128 void set (PyObject* pyob, bool owned = false)
00129 {
00130 release();
00131 p = pyob;
00132 if (!owned)
00133 {
00134 Py::_XINCREF (p);
00135 }
00136 validate();
00137 }
00138
00139 void release ()
00140 {
00141 Py::_XDECREF (p);
00142 p = 0;
00143 }
00144
00145 void validate()
00146 {
00147
00148 if (! accepts (p))
00149 {
00150 release ();
00151 if(PyErr_Occurred())
00152 {
00153 throw Exception();
00154 }
00155
00156 #if defined( _CPPRTTI ) || defined(__GNUG__)
00157 std::string s("CXX : Error creating object of type ");
00158 s += (typeid (*this)).name();
00159 throw TypeError (s);
00160 #else
00161 throw TypeError ("CXX: type error.");
00162 #endif
00163 }
00164 }
00165
00166 public:
00167
00168 explicit Object (PyObject* pyob=Py::_None(), bool owned = false): p (pyob)
00169 {
00170 if(!owned)
00171 {
00172 Py::_XINCREF (p);
00173 }
00174 validate();
00175 }
00176
00177
00178 Object (const Object& ob): p(ob.p)
00179 {
00180 Py::_XINCREF (p);
00181 validate();
00182 }
00183
00184
00185 Object& operator= (const Object& rhs)
00186 {
00187 set(rhs.p);
00188 return *this;
00189 }
00190
00191 Object& operator= (PyObject* rhsp)
00192 {
00193 if(ptr() == rhsp) return *this;
00194 set (rhsp);
00195 return *this;
00196 }
00197
00198
00199 virtual ~Object ()
00200 {
00201 release ();
00202 }
00203
00204
00205 PyObject* operator* () const
00206 {
00207 return p;
00208 }
00209
00210
00211 void increment_reference_count()
00212 {
00213 Py::_XINCREF(p);
00214 }
00215
00216 void decrement_reference_count()
00217 {
00218
00219 if(reference_count() == 1)
00220 throw RuntimeError("Object::decrement_reference_count error.");
00221 Py::_XDECREF(p);
00222 }
00223
00224 PyObject* ptr () const
00225 {
00226 return p;
00227 }
00228
00229
00230
00231
00232
00233
00234 virtual bool accepts (PyObject *pyob) const
00235 {
00236 return (pyob != 0);
00237 }
00238
00239 int reference_count () const
00240 {
00241 return p ? p->ob_refcnt : 0;
00242 }
00243
00244 Type type () const;
00245
00246 String str () const;
00247
00248 std::string as_string() const;
00249
00250 String repr () const;
00251
00252 List dir () const;
00253
00254 bool hasAttr (const std::string& s) const
00255 {
00256 return PyObject_HasAttrString (p, const_cast<char*>(s.c_str())) ? true: false;
00257 }
00258
00259 Object getAttr (const std::string& s) const
00260 {
00261 return Object (PyObject_GetAttrString (p, const_cast<char*>(s.c_str())), true);
00262 }
00263
00264 Object getItem (const Object& key) const
00265 {
00266 return Object (PyObject_GetItem(p, *key), true);
00267 }
00268
00269 long hashValue () const
00270 {
00271 return PyObject_Hash (p);
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 bool is(PyObject *pother) const
00281 {
00282 return p == pother;
00283 }
00284
00285 bool is(const Object& other) const
00286 {
00287 return p == other.p;
00288 }
00289
00290 bool isCallable () const
00291 {
00292 return PyCallable_Check (p) != 0;
00293 }
00294
00295 bool isInstance () const
00296 {
00297 return PyInstance_Check (p) != 0;
00298 }
00299
00300 bool isDict () const
00301 {
00302 return Py::_Dict_Check (p);
00303 }
00304
00305 bool isList () const
00306 {
00307 return Py::_List_Check (p);
00308 }
00309
00310 bool isMapping () const
00311 {
00312 return PyMapping_Check (p) != 0;
00313 }
00314
00315 bool isNumeric () const
00316 {
00317 return PyNumber_Check (p) != 0;
00318 }
00319
00320 bool isSequence () const
00321 {
00322 return PySequence_Check (p) != 0;
00323 }
00324
00325 bool isTrue () const
00326 {
00327 return PyObject_IsTrue (p) != 0;
00328 }
00329
00330 bool isType (const Type& t) const;
00331
00332 bool isTuple() const
00333 {
00334 return Py::_Tuple_Check(p);
00335 }
00336
00337 bool isString() const
00338 {
00339 return Py::_String_Check(p) || Py::_Unicode_Check(p);
00340 }
00341
00342 bool isUnicode() const
00343 {
00344 return Py::_Unicode_Check(p);
00345 }
00346
00347
00348 void setAttr (const std::string& s, const Object& value)
00349 {
00350 if(PyObject_SetAttrString (p, const_cast<char*>(s.c_str()), *value) == -1)
00351 throw AttributeError ("getAttr failed.");
00352 }
00353
00354 void delAttr (const std::string& s)
00355 {
00356 if(PyObject_DelAttrString (p, const_cast<char*>(s.c_str())) == -1)
00357 throw AttributeError ("delAttr failed.");
00358 }
00359
00360
00361
00362
00363 void delItem (const Object& )
00364 {
00365
00366
00367 throw KeyError("delItem failed.");
00368 }
00369
00370
00371 bool operator==(const Object& o2) const
00372 {
00373 int k = PyObject_Compare (p, *o2);
00374 if (PyErr_Occurred()) throw Exception();
00375 return k == 0;
00376 }
00377
00378 bool operator!=(const Object& o2) const
00379 {
00380 int k = PyObject_Compare (p, *o2);
00381 if (PyErr_Occurred()) throw Exception();
00382 return k != 0;
00383
00384 }
00385
00386 bool operator>=(const Object& o2) const
00387 {
00388 int k = PyObject_Compare (p, *o2);
00389 if (PyErr_Occurred()) throw Exception();
00390 return k >= 0;
00391 }
00392
00393 bool operator<=(const Object& o2) const
00394 {
00395 int k = PyObject_Compare (p, *o2);
00396 if (PyErr_Occurred()) throw Exception();
00397 return k <= 0;
00398 }
00399
00400 bool operator<(const Object& o2) const
00401 {
00402 int k = PyObject_Compare (p, *o2);
00403 if (PyErr_Occurred()) throw Exception();
00404 return k < 0;
00405 }
00406
00407 bool operator>(const Object& o2) const
00408 {
00409 int k = PyObject_Compare (p, *o2);
00410 if (PyErr_Occurred()) throw Exception();
00411 return k > 0;
00412 }
00413 };
00414
00415 inline PyObject* new_reference_to(const Object& g)
00416 {
00417 PyObject* p = g.ptr();
00418 Py::_XINCREF(p);
00419 return p;
00420 }
00421
00422
00423
00424 inline Object Nothing()
00425 {
00426 return Object(Py::_None());
00427 }
00428
00429
00430 inline Object None()
00431 {
00432 return Object(Py::_None());
00433 }
00434
00435
00436 #ifndef CXX_NO_IOSTREAMS
00437 std::ostream& operator<< (std::ostream& os, const Object& ob);
00438 #endif
00439
00440
00441 class Type: public Object
00442 {
00443 public:
00444 explicit Type (PyObject* pyob, bool owned = false): Object(pyob, owned)
00445 {
00446 validate();
00447 }
00448
00449 Type (const Object& ob): Object(*ob)
00450 {
00451 validate();
00452 }
00453
00454 Type(const Type& t): Object(t)
00455 {
00456 validate();
00457 }
00458
00459 Type& operator= (const Object& rhs)
00460 {
00461 return (*this = *rhs);
00462 }
00463
00464 Type& operator= (PyObject* rhsp)
00465 {
00466 if(ptr() == rhsp) return *this;
00467 set (rhsp);
00468 return *this;
00469 }
00470 virtual bool accepts (PyObject *pyob) const
00471 {
00472 return pyob && Py::_Type_Check (pyob);
00473 }
00474 };
00475
00476
00477
00478
00479
00480 inline Object asObject (PyObject *p)
00481 {
00482 return Object(p, true);
00483 }
00484
00485
00486
00487
00488
00489
00490 class Int: public Object
00491 {
00492 public:
00493
00494 explicit Int (PyObject *pyob, bool owned = false): Object (pyob, owned)
00495 {
00496 validate();
00497 }
00498
00499 Int (const Int& ob): Object(*ob)
00500 {
00501 validate();
00502 }
00503
00504
00505 explicit Int (long v = 0L): Object(PyInt_FromLong(v), true)
00506 {
00507 validate();
00508 }
00509
00510
00511 explicit Int (int v)
00512 {
00513 long w = v;
00514 set(PyInt_FromLong(w), true);
00515 validate();
00516 }
00517
00518
00519 explicit Int (bool v)
00520 {
00521 long w = v ? 1 : 0;
00522 set(PyInt_FromLong(w), true);
00523 validate();
00524 }
00525
00526 explicit Int (const Object& ob)
00527 {
00528 set(PyNumber_Int(*ob), true);
00529 validate();
00530 }
00531
00532
00533
00534 Int& operator= (const Object& rhs)
00535 {
00536 return (*this = *rhs);
00537 }
00538
00539 Int& operator= (PyObject* rhsp)
00540 {
00541 if(ptr() == rhsp) return *this;
00542 set (PyNumber_Int(rhsp), true);
00543 return *this;
00544 }
00545
00546 virtual bool accepts (PyObject *pyob) const
00547 {
00548 return pyob && Py::_Int_Check (pyob);
00549 }
00550
00551 operator long() const
00552 {
00553 return PyInt_AsLong (ptr());
00554 }
00555
00556 Int& operator= (int v)
00557 {
00558 set (PyInt_FromLong (long(v)), true);
00559 return *this;
00560 }
00561
00562 Int& operator= (long v)
00563 {
00564 set (PyInt_FromLong (v), true);
00565 return *this;
00566 }
00567 };
00568
00569
00570
00571 class Long: public Object
00572 {
00573 public:
00574
00575 explicit Long (PyObject *pyob, bool owned = false): Object (pyob, owned)
00576 {
00577 validate();
00578 }
00579
00580 Long (const Long& ob): Object(ob.ptr())
00581 {
00582 validate();
00583 }
00584
00585
00586 explicit Long (long v = 0L)
00587 : Object(PyLong_FromLong(v), true)
00588 {
00589 validate();
00590 }
00591
00592 explicit Long (unsigned long v)
00593 : Object(PyLong_FromUnsignedLong(v), true)
00594 {
00595 validate();
00596 }
00597
00598 explicit Long (int v)
00599 : Object(PyLong_FromLong(static_cast<long>(v)), true)
00600 {
00601 validate();
00602 }
00603
00604
00605 Long (const Object& ob)
00606 : Object(PyNumber_Long(*ob), true)
00607 {
00608 validate();
00609 }
00610
00611
00612
00613 Long& operator= (const Object& rhs)
00614 {
00615 return (*this = *rhs);
00616 }
00617
00618 Long& operator= (PyObject* rhsp)
00619 {
00620 if(ptr() == rhsp) return *this;
00621 set (PyNumber_Long(rhsp), true);
00622 return *this;
00623 }
00624
00625 virtual bool accepts (PyObject *pyob) const
00626 {
00627 return pyob && Py::_Long_Check (pyob);
00628 }
00629
00630 operator long() const
00631 {
00632 return PyLong_AsLong (ptr());
00633 }
00634
00635 operator unsigned long() const
00636 {
00637 return PyLong_AsUnsignedLong (ptr());
00638 }
00639 operator double() const
00640 {
00641 return PyLong_AsDouble (ptr());
00642 }
00643
00644 Long& operator= (int v)
00645 {
00646 set(PyLong_FromLong (long(v)), true);
00647 return *this;
00648 }
00649
00650 Long& operator= (long v)
00651 {
00652 set(PyLong_FromLong (v), true);
00653 return *this;
00654 }
00655
00656 Long& operator= (unsigned long v)
00657 {
00658 set(PyLong_FromUnsignedLong (v), true);
00659 return *this;
00660 }
00661 };
00662
00663
00664
00665
00666 class Float: public Object
00667 {
00668 public:
00669
00670 explicit Float (PyObject *pyob, bool owned = false): Object(pyob, owned)
00671 {
00672 validate();
00673 }
00674
00675 Float (const Float& f): Object(f)
00676 {
00677 validate();
00678 }
00679
00680
00681 explicit Float (double v=0.0)
00682 : Object(PyFloat_FromDouble (v), true)
00683 {
00684 validate();
00685 }
00686
00687
00688 Float (const Object& ob)
00689 : Object(PyNumber_Float(*ob), true)
00690 {
00691 validate();
00692 }
00693
00694 Float& operator= (const Object& rhs)
00695 {
00696 return (*this = *rhs);
00697 }
00698
00699 Float& operator= (PyObject* rhsp)
00700 {
00701 if(ptr() == rhsp) return *this;
00702 set (PyNumber_Float(rhsp), true);
00703 return *this;
00704 }
00705
00706 virtual bool accepts (PyObject *pyob) const
00707 {
00708 return pyob && Py::_Float_Check (pyob);
00709 }
00710
00711 operator double () const
00712 {
00713 return PyFloat_AsDouble (ptr());
00714 }
00715
00716 Float& operator= (double v)
00717 {
00718 set(PyFloat_FromDouble (v), true);
00719 return *this;
00720 }
00721
00722 Float& operator= (int v)
00723 {
00724 set(PyFloat_FromDouble (double(v)), true);
00725 return *this;
00726 }
00727
00728 Float& operator= (long v)
00729 {
00730 set(PyFloat_FromDouble (double(v)), true);
00731 return *this;
00732 }
00733
00734 Float& operator= (const Int& iob)
00735 {
00736 set(PyFloat_FromDouble (double(long(iob))), true);
00737 return *this;
00738 }
00739 };
00740
00741
00742
00743 class Complex: public Object
00744 {
00745 public:
00746
00747 explicit Complex (PyObject *pyob, bool owned = false): Object(pyob, owned)
00748 {
00749 validate();
00750 }
00751
00752 Complex (const Complex& f): Object(f)
00753 {
00754 validate();
00755 }
00756
00757
00758 explicit Complex (double v=0.0, double w=0.0)
00759 :Object(PyComplex_FromDoubles (v, w), true)
00760 {
00761 validate();
00762 }
00763
00764 Complex& operator= (const Object& rhs)
00765 {
00766 return (*this = *rhs);
00767 }
00768
00769 Complex& operator= (PyObject* rhsp)
00770 {
00771 if(ptr() == rhsp) return *this;
00772 set (rhsp);
00773 return *this;
00774 }
00775
00776 virtual bool accepts (PyObject *pyob) const
00777 {
00778 return pyob && Py::_Complex_Check (pyob);
00779 }
00780
00781 operator Py_complex () const
00782 {
00783 return PyComplex_AsCComplex (ptr());
00784 }
00785
00786 Complex& operator= (const Py_complex& v)
00787 {
00788 set(PyComplex_FromCComplex (v), true);
00789 return *this;
00790 }
00791
00792 Complex& operator= (double v)
00793 {
00794 set(PyComplex_FromDoubles (v, 0.0), true);
00795 return *this;
00796 }
00797
00798 Complex& operator= (int v)
00799 {
00800 set(PyComplex_FromDoubles (double(v), 0.0), true);
00801 return *this;
00802 }
00803
00804 Complex& operator= (long v)
00805 {
00806 set(PyComplex_FromDoubles (double(v), 0.0), true);
00807 return *this;
00808 }
00809
00810 Complex& operator= (const Int& iob)
00811 {
00812 set(PyComplex_FromDoubles (double(long(iob)), 0.0), true);
00813 return *this;
00814 }
00815
00816 double real() const
00817 {
00818 return PyComplex_RealAsDouble(ptr());
00819 }
00820
00821 double imag() const
00822 {
00823 return PyComplex_ImagAsDouble(ptr());
00824 }
00825 };
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 template<TEMPLATE_TYPENAME T>
00850 class seqref
00851 {
00852 protected:
00853 SeqBase<T>& s;
00854 int offset;
00855 T the_item;
00856 public:
00857
00858 seqref (SeqBase<T>& seq, sequence_index_type j)
00859 : s(seq), offset(j), the_item (s.getItem(j))
00860 {}
00861
00862 seqref (const seqref<T>& range)
00863 : s(range.s), offset(range.offset), the_item(range.the_item)
00864 {}
00865
00866
00867 seqref (Object& obj)
00868 : s(dynamic_cast< SeqBase<T>&>(obj))
00869 , offset( NULL )
00870 , the_item(s.getItem(offset))
00871 {}
00872 ~seqref()
00873 {}
00874
00875 operator T() const
00876 {
00877 return the_item;
00878 }
00879
00880 seqref<T>& operator=(const seqref<T>& rhs)
00881 {
00882 the_item = rhs.the_item;
00883 s.setItem(offset, the_item);
00884 return *this;
00885 }
00886
00887 seqref<T>& operator=(const T& ob)
00888 {
00889 the_item = ob;
00890 s.setItem(offset, ob);
00891 return *this;
00892 }
00893
00894
00895 PyObject* ptr () const
00896 {
00897 return the_item.ptr();
00898 }
00899
00900 int reference_count () const
00901 {
00902 return the_item.reference_count();
00903 }
00904
00905 Type type () const
00906 {
00907 return the_item.type();
00908 }
00909
00910 String str () const;
00911
00912 String repr () const;
00913
00914 bool hasAttr (const std::string& attr_name) const
00915 {
00916 return the_item.hasAttr(attr_name);
00917 }
00918
00919 Object getAttr (const std::string& attr_name) const
00920 {
00921 return the_item.getAttr(attr_name);
00922 }
00923
00924 Object getItem (const Object& key) const
00925 {
00926 return the_item.getItem(key);
00927 }
00928
00929 long hashValue () const
00930 {
00931 return the_item.hashValue();
00932 }
00933
00934 bool isCallable () const
00935 {
00936 return the_item.isCallable();
00937 }
00938
00939 bool isDict () const
00940 {
00941 return the_item.isDict();
00942 }
00943
00944 bool isList () const
00945 {
00946 return the_item.isList();
00947 }
00948
00949 bool isMapping () const
00950 {
00951 return the_item.isMapping();
00952 }
00953
00954 bool isNumeric () const
00955 {
00956 return the_item.isNumeric();
00957 }
00958
00959 bool isSequence () const
00960 {
00961 return the_item.isSequence();
00962 }
00963
00964 bool isTrue () const
00965 {
00966 return the_item.isTrue();
00967 }
00968
00969 bool isType (const Type& t) const
00970 {
00971 return the_item.isType (t);
00972 }
00973
00974 bool isTuple() const
00975 {
00976 return the_item.isTuple();
00977 }
00978
00979 bool isString() const
00980 {
00981 return the_item.isString();
00982 }
00983
00984 void setAttr (const std::string& attr_name, const Object& value)
00985 {
00986 the_item.setAttr(attr_name, value);
00987 }
00988
00989 void delAttr (const std::string& attr_name)
00990 {
00991 the_item.delAttr(attr_name);
00992 }
00993
00994 void delItem (const Object& key)
00995 {
00996 the_item.delItem(key);
00997 }
00998
00999 bool operator==(const Object& o2) const
01000 {
01001 return the_item == o2;
01002 }
01003
01004 bool operator!=(const Object& o2) const
01005 {
01006 return the_item != o2;
01007 }
01008
01009 bool operator>=(const Object& o2) const
01010 {
01011 return the_item >= o2;
01012 }
01013
01014 bool operator<=(const Object& o2) const
01015 {
01016 return the_item <= o2;
01017 }
01018
01019 bool operator<(const Object& o2) const
01020 {
01021 return the_item < o2;
01022 }
01023
01024 bool operator>(const Object& o2) const
01025 {
01026 return the_item > o2;
01027 }
01028 };
01029
01030
01031
01032
01033
01034 template<TEMPLATE_TYPENAME T>
01035 class SeqBase: public Object
01036 {
01037 public:
01038
01039 typedef size_t size_type;
01040 typedef seqref<T> reference;
01041 typedef T const_reference;
01042 typedef seqref<T>* pointer;
01043 typedef int difference_type;
01044 typedef T value_type;
01045
01046 virtual size_type max_size() const
01047 {
01048 return std::string::npos;
01049 }
01050
01051 virtual size_type capacity() const
01052 {
01053 return size();
01054 }
01055
01056 virtual void swap(SeqBase<T>& c)
01057 {
01058 SeqBase<T> temp = c;
01059 c = ptr();
01060 set(temp.ptr());
01061 }
01062
01063 virtual size_type size () const
01064 {
01065 return PySequence_Length (ptr());
01066 }
01067
01068 explicit SeqBase<T> ()
01069 :Object(PyTuple_New(0), true)
01070 {
01071 validate();
01072 }
01073
01074 explicit SeqBase<T> (PyObject* pyob, bool owned=false)
01075 : Object(pyob, owned)
01076 {
01077 validate();
01078 }
01079
01080 SeqBase<T> (const Object& ob): Object(ob)
01081 {
01082 validate();
01083 }
01084
01085
01086
01087 SeqBase<T>& operator= (const Object& rhs)
01088 {
01089 return (*this = *rhs);
01090 }
01091
01092 SeqBase<T>& operator= (PyObject* rhsp)
01093 {
01094 if(ptr() == rhsp) return *this;
01095 set (rhsp);
01096 return *this;
01097 }
01098
01099 virtual bool accepts (PyObject *pyob) const
01100 {
01101 return pyob && PySequence_Check (pyob);
01102 }
01103
01104 size_type length () const
01105 {
01106 return PySequence_Length (ptr());
01107 }
01108
01109
01110 const T operator[](sequence_index_type index) const
01111 {
01112 return getItem(index);
01113 }
01114
01115 seqref<T> operator[](sequence_index_type index)
01116 {
01117 return seqref<T>(*this, index);
01118 }
01119
01120 virtual T getItem (sequence_index_type i) const
01121 {
01122 return T(asObject(PySequence_GetItem (ptr(), i)));
01123 }
01124
01125 virtual void setItem (sequence_index_type i, const T& ob)
01126 {
01127 if (PySequence_SetItem (ptr(), i, *ob) == -1)
01128 {
01129 throw Exception();
01130 }
01131 }
01132
01133 SeqBase<T> repeat (int count) const
01134 {
01135 return SeqBase<T> (PySequence_Repeat (ptr(), count), true);
01136 }
01137
01138 SeqBase<T> concat (const SeqBase<T>& other) const
01139 {
01140 return SeqBase<T> (PySequence_Concat(ptr(), *other), true);
01141 }
01142
01143
01144 const T front () const
01145 {
01146 return getItem(0);
01147 }
01148
01149 seqref<T> front()
01150 {
01151 return seqref<T>(this, 0);
01152 }
01153
01154 const T back () const
01155 {
01156 return getItem(size()-1);
01157 }
01158
01159 seqref<T> back()
01160 {
01161 return seqref<T>(this, size()-1);
01162 }
01163
01164 void verify_length(size_type required_size) const
01165 {
01166 if (size() != required_size)
01167 throw IndexError ("Unexpected SeqBase<T> length.");
01168 }
01169
01170 void verify_length(size_type min_size, size_type max_size) const
01171 {
01172 size_type n = size();
01173 if (n < min_size || n > max_size)
01174 throw IndexError ("Unexpected SeqBase<T> length.");
01175 }
01176
01177 class iterator
01178 : public random_access_iterator_parent(seqref<T>)
01179 {
01180 protected:
01181 friend class SeqBase<T>;
01182 SeqBase<T>* seq;
01183 int count;
01184
01185 public:
01186 ~iterator ()
01187 {}
01188
01189 iterator ()
01190 : seq( 0 )
01191 , count( 0 )
01192 {}
01193
01194 iterator (SeqBase<T>* s, int where)
01195 : seq( s )
01196 , count( where )
01197 {}
01198
01199 iterator (const iterator& other)
01200 : seq( other.seq )
01201 , count( other.count )
01202 {}
01203
01204 bool eql (const iterator& other) const
01205 {
01206 return (*seq == *other.seq) && (count == other.count);
01207 }
01208
01209 bool neq (const iterator& other) const
01210 {
01211 return (*seq != *other.seq) || (count != other.count);
01212 }
01213
01214 bool lss (const iterator& other) const
01215 {
01216 return (count < other.count);
01217 }
01218
01219 bool gtr (const iterator& other) const
01220 {
01221 return (count > other.count);
01222 }
01223
01224 bool leq (const iterator& other) const
01225 {
01226 return (count <= other.count);
01227 }
01228
01229 bool geq (const iterator& other) const
01230 {
01231 return (count >= other.count);
01232 }
01233
01234 seqref<T> operator*()
01235 {
01236 return seqref<T>(*seq, count);
01237 }
01238
01239 seqref<T> operator[] (sequence_index_type i)
01240 {
01241 return seqref<T>(*seq, count + i);
01242 }
01243
01244 iterator& operator=(const iterator& other)
01245 {
01246 if (this == &other) return *this;
01247 seq = other.seq;
01248 count = other.count;
01249 return *this;
01250 }
01251
01252 iterator operator+(int n) const
01253 {
01254 return iterator(seq, count + n);
01255 }
01256
01257 iterator operator-(int n) const
01258 {
01259 return iterator(seq, count - n);
01260 }
01261
01262 iterator& operator+=(int n)
01263 {
01264 count = count + n;
01265 return *this;
01266 }
01267
01268 iterator& operator-=(int n)
01269 {
01270 count = count - n;
01271 return *this;
01272 }
01273
01274 int operator-(const iterator& other) const
01275 {
01276 if (*seq != *other.seq)
01277 throw RuntimeError ("SeqBase<T>::iterator comparison error");
01278 return count - other.count;
01279 }
01280
01281
01282 iterator& operator++ ()
01283 { count++; return *this;}
01284
01285 iterator operator++ (int)
01286 { return iterator(seq, count++);}
01287
01288 iterator& operator-- ()
01289 { count--; return *this;}
01290
01291 iterator operator-- (int)
01292 { return iterator(seq, count--);}
01293
01294 std::string diagnose() const
01295 {
01296 std::OSTRSTREAM oss;
01297 oss << "iterator diagnosis " << seq << ", " << count << std::ends;
01298 return std::string(oss.str());
01299 }
01300 };
01301
01302 iterator begin ()
01303 {
01304 return iterator(this, 0);
01305 }
01306
01307 iterator end ()
01308 {
01309 return iterator(this, length());
01310 }
01311
01312 class const_iterator
01313 : public random_access_iterator_parent(const Object)
01314 {
01315 protected:
01316 friend class SeqBase<T>;
01317 const SeqBase<T>* seq;
01318 sequence_index_type count;
01319
01320 public:
01321 ~const_iterator ()
01322 {}
01323
01324 const_iterator ()
01325 : seq( 0 )
01326 , count( 0 )
01327 {}
01328
01329 const_iterator (const SeqBase<T>* s, int where)
01330 : seq( s )
01331 , count( where )
01332 {}
01333
01334 const_iterator(const const_iterator& other)
01335 : seq( other.seq )
01336 , count( other.count )
01337 {}
01338
01339 const T operator*() const
01340 {
01341 return seq->getItem(count);
01342 }
01343
01344 const T operator[] (sequence_index_type i) const
01345 {
01346 return seq->getItem(count + i);
01347 }
01348
01349 const_iterator& operator=(const const_iterator& other)
01350 {
01351 if (this == &other) return *this;
01352 seq = other.seq;
01353 count = other.count;
01354 return *this;
01355 }
01356
01357 const_iterator operator+(int n) const
01358 {
01359 return const_iterator(seq, count + n);
01360 }
01361
01362 bool eql (const const_iterator& other) const
01363 {
01364 return (*seq == *other.seq) && (count == other.count);
01365 }
01366
01367 bool neq (const const_iterator& other) const
01368 {
01369 return (*seq != *other.seq) || (count != other.count);
01370 }
01371
01372 bool lss (const const_iterator& other) const
01373 {
01374 return (count < other.count);
01375 }
01376
01377 bool gtr (const const_iterator& other) const
01378 {
01379 return (count > other.count);
01380 }
01381
01382 bool leq (const const_iterator& other) const
01383 {
01384 return (count <= other.count);
01385 }
01386
01387 bool geq (const const_iterator& other) const
01388 {
01389 return (count >= other.count);
01390 }
01391
01392 const_iterator operator-(int n)
01393 {
01394 return const_iterator(seq, count - n);
01395 }
01396
01397 const_iterator& operator+=(int n)
01398 {
01399 count = count + n;
01400 return *this;
01401 }
01402
01403 const_iterator& operator-=(int n)
01404 {
01405 count = count - n;
01406 return *this;
01407 }
01408
01409 int operator-(const const_iterator& other) const
01410 {
01411 if (*seq != *other.seq)
01412 throw RuntimeError ("SeqBase<T>::const_iterator::- error");
01413 return count - other.count;
01414 }
01415
01416 const_iterator& operator++ ()
01417 { count++; return *this;}
01418
01419 const_iterator operator++ (int)
01420 { return const_iterator(seq, count++);}
01421
01422 const_iterator& operator-- ()
01423 { count--; return *this;}
01424
01425 const_iterator operator-- (int)
01426 { return const_iterator(seq, count--);}
01427 };
01428
01429 const_iterator begin () const
01430 {
01431 return const_iterator(this, 0);
01432 }
01433
01434 const_iterator end () const
01435 {
01436 return const_iterator(this, length());
01437 }
01438 };
01439
01440
01441 typedef SeqBase<Object> Sequence;
01442
01443 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01444 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01445 template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01446 template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01447 template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01448 template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::iterator& right);
01449
01450 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01451 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01452 template <TEMPLATE_TYPENAME T> bool operator< (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01453 template <TEMPLATE_TYPENAME T> bool operator> (const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01454 template <TEMPLATE_TYPENAME T> bool operator<=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01455 template <TEMPLATE_TYPENAME T> bool operator>=(const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& left, const EXPLICIT_TYPENAME SeqBase<T>::const_iterator& right);
01456
01457
01458 extern bool operator==(const Sequence::iterator& left, const Sequence::iterator& right);
01459 extern bool operator!=(const Sequence::iterator& left, const Sequence::iterator& right);
01460 extern bool operator< (const Sequence::iterator& left, const Sequence::iterator& right);
01461 extern bool operator> (const Sequence::iterator& left, const Sequence::iterator& right);
01462 extern bool operator<=(const Sequence::iterator& left, const Sequence::iterator& right);
01463 extern bool operator>=(const Sequence::iterator& left, const Sequence::iterator& right);
01464
01465 extern bool operator==(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01466 extern bool operator!=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01467 extern bool operator< (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01468 extern bool operator> (const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01469 extern bool operator<=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01470 extern bool operator>=(const Sequence::const_iterator& left, const Sequence::const_iterator& right);
01471
01472
01473
01474
01475
01476
01477 typedef std::basic_string<Py_UNICODE> unicodestring;
01478 extern Py_UNICODE unicode_null_string[1];
01479
01480 class Char: public Object
01481 {
01482 public:
01483 explicit Char (PyObject *pyob, bool owned = false): Object(pyob, owned)
01484 {
01485 validate();
01486 }
01487
01488 Char (const Object& ob): Object(ob)
01489 {
01490 validate();
01491 }
01492
01493 Char (const std::string& v = "")
01494 :Object(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true)
01495 {
01496 validate();
01497 }
01498
01499 Char (char v)
01500 : Object(PyString_FromStringAndSize (&v, 1), true)
01501 {
01502 validate();
01503 }
01504
01505 Char (Py_UNICODE v)
01506 : Object(PyUnicode_FromUnicode (&v, 1), true)
01507 {
01508 validate();
01509 }
01510
01511 Char& operator= (const Object& rhs)
01512 {
01513 return (*this = *rhs);
01514 }
01515
01516 Char& operator= (PyObject* rhsp)
01517 {
01518 if(ptr() == rhsp) return *this;
01519 set (rhsp);
01520 return *this;
01521 }
01522
01523
01524 virtual bool accepts (PyObject *pyob) const
01525 {
01526 return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob)) && PySequence_Length (pyob) == 1;
01527 }
01528
01529
01530 Char& operator= (const std::string& v)
01531 {
01532 set(PyString_FromStringAndSize (const_cast<char*>(v.c_str()),1), true);
01533 return *this;
01534 }
01535
01536 Char& operator= (char v)
01537 {
01538 set(PyString_FromStringAndSize (&v, 1), true);
01539 return *this;
01540 }
01541
01542 Char& operator= (const unicodestring& v)
01543 {
01544 set(PyUnicode_FromUnicode (const_cast<Py_UNICODE*>(v.data()),1), true);
01545 return *this;
01546 }
01547
01548 Char& operator= (Py_UNICODE v)
01549 {
01550 set(PyUnicode_FromUnicode (&v, 1), true);
01551 return *this;
01552 }
01553
01554
01555 operator String() const;
01556
01557 operator std::string () const
01558 {
01559 return std::string(PyString_AsString (ptr()));
01560 }
01561 };
01562
01563 class String: public SeqBase<Char>
01564 {
01565 public:
01566 virtual size_type capacity() const
01567 {
01568 return max_size();
01569 }
01570
01571 explicit String (PyObject *pyob, bool owned = false): SeqBase<Char>(pyob, owned)
01572 {
01573 validate();
01574 }
01575
01576 String (const Object& ob): SeqBase<Char>(ob)
01577 {
01578 validate();
01579 }
01580
01581 String()
01582 : SeqBase<Char>( PyString_FromStringAndSize( "", 0 ), true )
01583 {
01584 validate();
01585 }
01586
01587 String( const std::string& v )
01588 : SeqBase<Char>( PyString_FromStringAndSize( const_cast<char*>(v.data()),
01589 static_cast<int>( v.length() ) ), true )
01590 {
01591 validate();
01592 }
01593
01594 String( const char *s, const char *encoding, const char *error="strict" )
01595 : SeqBase<Char>( PyUnicode_Decode( s, strlen( s ), encoding, error ), true )
01596 {
01597 validate();
01598 }
01599
01600 String( const char *s, int len, const char *encoding, const char *error="strict" )
01601 : SeqBase<Char>( PyUnicode_Decode( s, len, encoding, error ), true )
01602 {
01603 validate();
01604 }
01605
01606 String( const std::string &s, const char *encoding, const char *error="strict" )
01607 : SeqBase<Char>( PyUnicode_Decode( s.c_str(), s.length(), encoding, error ), true )
01608 {
01609 validate();
01610 }
01611
01612 String( const std::string& v, std::string::size_type vsize )
01613 : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v.data()),
01614 static_cast<int>( vsize ) ), true)
01615 {
01616 validate();
01617 }
01618
01619 String( const char *v, int vsize )
01620 : SeqBase<Char>(PyString_FromStringAndSize( const_cast<char*>(v), vsize ), true )
01621 {
01622 validate();
01623 }
01624
01625 String( const char* v )
01626 : SeqBase<Char>( PyString_FromString( v ), true )
01627 {
01628 validate();
01629 }
01630
01631
01632 String& operator= ( const Object& rhs )
01633 {
01634 return *this = *rhs;
01635 }
01636
01637 String& operator= (PyObject* rhsp)
01638 {
01639 if( ptr() == rhsp )
01640 return *this;
01641 set (rhsp);
01642 return *this;
01643 }
01644
01645 virtual bool accepts (PyObject *pyob) const
01646 {
01647 return pyob && (Py::_String_Check(pyob) || Py::_Unicode_Check(pyob));
01648 }
01649
01650
01651 String& operator= (const std::string& v)
01652 {
01653 set( PyString_FromStringAndSize( const_cast<char*>( v.data() ),
01654 static_cast<int>( v.length() ) ), true );
01655 return *this;
01656 }
01657 String& operator= (const unicodestring& v)
01658 {
01659 set( PyUnicode_FromUnicode( const_cast<Py_UNICODE*>( v.data() ),
01660 static_cast<int>( v.length() ) ), true );
01661 return *this;
01662 }
01663
01664
01665
01666 String encode( const char *encoding, const char *error="strict" )
01667 {
01668 if( isUnicode() )
01669 {
01670 return String( PyUnicode_AsEncodedString( ptr(), encoding, error ) );
01671 }
01672 else
01673 {
01674 return String( PyString_AsEncodedObject( ptr(), encoding, error ) );
01675 }
01676 }
01677
01678 String decode( const char *encoding, const char *error="strict" )
01679 {
01680 return Object( PyString_AsDecodedObject( ptr(), encoding, error ) );
01681 }
01682
01683
01684 virtual size_type size () const
01685 {
01686 if( isUnicode() )
01687 {
01688 return static_cast<size_type>( PyUnicode_GET_SIZE (ptr()) );
01689 }
01690 else
01691 {
01692 return static_cast<size_type>( PyString_Size (ptr()) );
01693 }
01694 }
01695
01696 operator std::string () const
01697 {
01698 return as_std_string();
01699 }
01700
01701 std::string as_std_string() const
01702 {
01703 if( isUnicode() )
01704 {
01705 throw TypeError("cannot return std::string from Unicode object");
01706 }
01707 else
01708 {
01709 return std::string( PyString_AsString( ptr() ), static_cast<size_type>( PyString_Size( ptr() ) ) );
01710 }
01711 }
01712
01713 unicodestring as_unicodestring() const
01714 {
01715 if( isUnicode() )
01716 {
01717 return unicodestring( PyUnicode_AS_UNICODE( ptr() ),
01718 static_cast<size_type>( PyUnicode_GET_SIZE( ptr() ) ) );
01719 }
01720 else
01721 {
01722 throw TypeError("can only return unicodestring from Unicode object");
01723 }
01724 }
01725 };
01726
01727
01728
01729 class Tuple: public Sequence
01730 {
01731 public:
01732 virtual void setItem (sequence_index_type offset, const Object&ob)
01733 {
01734
01735 if(PyTuple_SetItem (ptr(), offset, new_reference_to(ob)) == -1)
01736 {
01737 throw Exception();
01738 }
01739 }
01740
01741
01742 explicit Tuple (PyObject *pyob, bool owned = false): Sequence (pyob, owned)
01743 {
01744 validate();
01745 }
01746
01747 Tuple (const Object& ob): Sequence(ob)
01748 {
01749 validate();
01750 }
01751
01752
01753 explicit Tuple (int size = 0)
01754 {
01755 set(PyTuple_New (size), true);
01756 validate ();
01757 for (sequence_index_type i=0; i < size; i++)
01758 {
01759 if(PyTuple_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
01760 {
01761 throw Exception();
01762 }
01763 }
01764 }
01765
01766 explicit Tuple (const Sequence& s)
01767 {
01768 sequence_index_type limit( sequence_index_type( s.length() ) );
01769
01770 set(PyTuple_New (limit), true);
01771 validate();
01772
01773 for(sequence_index_type i=0; i < limit; i++)
01774 {
01775 if(PyTuple_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
01776 {
01777 throw Exception();
01778 }
01779 }
01780 }
01781
01782
01783 Tuple& operator= (const Object& rhs)
01784 {
01785 return (*this = *rhs);
01786 }
01787
01788 Tuple& operator= (PyObject* rhsp)
01789 {
01790 if(ptr() == rhsp) return *this;
01791 set (rhsp);
01792 return *this;
01793 }
01794
01795 virtual bool accepts (PyObject *pyob) const
01796 {
01797 return pyob && Py::_Tuple_Check (pyob);
01798 }
01799
01800 Tuple getSlice (int i, int j) const
01801 {
01802 return Tuple (PySequence_GetSlice (ptr(), i, j), true);
01803 }
01804
01805 };
01806
01807
01808
01809
01810 class List: public Sequence
01811 {
01812 public:
01813
01814 explicit List (PyObject *pyob, bool owned = false): Sequence(pyob, owned)
01815 {
01816 validate();
01817 }
01818 List (const Object& ob): Sequence(ob)
01819 {
01820 validate();
01821 }
01822
01823 List (int size = 0)
01824 {
01825 set(PyList_New (size), true);
01826 validate();
01827 for (sequence_index_type i=0; i < size; i++)
01828 {
01829 if(PyList_SetItem (ptr(), i, new_reference_to(Py::_None())) == -1)
01830 {
01831 throw Exception();
01832 }
01833 }
01834 }
01835
01836
01837 List (const Sequence& s): Sequence()
01838 {
01839 int n = s.length();
01840 set(PyList_New (n), true);
01841 validate();
01842 for (sequence_index_type i=0; i < n; i++)
01843 {
01844 if(PyList_SetItem (ptr(), i, new_reference_to(s[i])) == -1)
01845 {
01846 throw Exception();
01847 }
01848 }
01849 }
01850
01851 virtual size_type capacity() const
01852 {
01853 return max_size();
01854 }
01855
01856
01857 List& operator= (const Object& rhs)
01858 {
01859 return (*this = *rhs);
01860 }
01861
01862 List& operator= (PyObject* rhsp)
01863 {
01864 if(ptr() == rhsp) return *this;
01865 set (rhsp);
01866 return *this;
01867 }
01868
01869 virtual bool accepts (PyObject *pyob) const
01870 {
01871 return pyob && Py::_List_Check (pyob);
01872 }
01873
01874 List getSlice (int i, int j) const
01875 {
01876 return List (PyList_GetSlice (ptr(), i, j), true);
01877 }
01878
01879 void setSlice (int i, int j, const Object& v)
01880 {
01881 if(PyList_SetSlice (ptr(), i, j, *v) == -1)
01882 {
01883 throw Exception();
01884 }
01885 }
01886
01887 void append (const Object& ob)
01888 {
01889 if(PyList_Append (ptr(), *ob) == -1)
01890 {
01891 throw Exception();
01892 }
01893 }
01894
01895 void insert (int i, const Object& ob)
01896 {
01897 if(PyList_Insert (ptr(), i, *ob) == -1)
01898 {
01899 throw Exception();
01900 }
01901 }
01902
01903 void sort ()
01904 {
01905 if(PyList_Sort(ptr()) == -1)
01906 {
01907 throw Exception();
01908 }
01909 }
01910
01911 void reverse ()
01912 {
01913 if(PyList_Reverse(ptr()) == -1)
01914 {
01915 throw Exception();
01916 }
01917 }
01918 };
01919
01920
01921
01922
01923 template<TEMPLATE_TYPENAME T>
01924 class mapref
01925 {
01926 protected:
01927 MapBase<T>& s;
01928 Object key;
01929 T the_item;
01930
01931 public:
01932 mapref<T> (MapBase<T>& map, const std::string& k)
01933 : s(map), the_item()
01934 {
01935 key = String(k);
01936 if(map.hasKey(key)) the_item = map.getItem(key);
01937 };
01938
01939 mapref<T> (MapBase<T>& map, const Object& k)
01940 : s(map), key(k), the_item()
01941 {
01942 if(map.hasKey(key)) the_item = map.getItem(key);
01943 };
01944
01945
01946
01947
01948
01949
01950
01951
01952 mapref<T>& operator=(const mapref<T>& other)
01953 {
01954 if(this == &other) return *this;
01955 the_item = other.the_item;
01956 s.setItem(key, other.the_item);
01957 return *this;
01958 };
01959
01960 mapref<T>& operator= (const T& ob)
01961 {
01962 the_item = ob;
01963 s.setItem (key, ob);
01964 return *this;
01965 }
01966
01967
01968 operator T() const
01969 {
01970 return the_item;
01971 }
01972
01973
01974 PyObject* ptr () const
01975 {
01976 return the_item.ptr();
01977 }
01978
01979 int reference_count () const
01980 {
01981 return the_item.reference_count();
01982 }
01983
01984 Type type () const
01985 {
01986 return the_item.type();
01987 }
01988
01989 String str () const
01990 {
01991 return the_item.str();
01992 }
01993
01994 String repr () const
01995 {
01996 return the_item.repr();
01997 }
01998
01999 bool hasAttr (const std::string& attr_name) const
02000 {
02001 return the_item.hasAttr(attr_name);
02002 }
02003
02004 Object getAttr (const std::string& attr_name) const
02005 {
02006 return the_item.getAttr(attr_name);
02007 }
02008
02009 Object getItem (const Object& k) const
02010 {
02011 return the_item.getItem(k);
02012 }
02013
02014 long hashValue () const
02015 {
02016 return the_item.hashValue();
02017 }
02018
02019 bool isCallable () const
02020 {
02021 return the_item.isCallable();
02022 }
02023
02024 bool isList () const
02025 {
02026 return the_item.isList();
02027 }
02028
02029 bool isMapping () const
02030 {
02031 return the_item.isMapping();
02032 }
02033
02034 bool isNumeric () const
02035 {
02036 return the_item.isNumeric();
02037 }
02038
02039 bool isSequence () const
02040 {
02041 return the_item.isSequence();
02042 }
02043
02044 bool isTrue () const
02045 {
02046 return the_item.isTrue();
02047 }
02048
02049 bool isType (const Type& t) const
02050 {
02051 return the_item.isType (t);
02052 }
02053
02054 bool isTuple() const
02055 {
02056 return the_item.isTuple();
02057 }
02058
02059 bool isString() const
02060 {
02061 return the_item.isString();
02062 }
02063
02064
02065 void setAttr (const std::string& attr_name, const Object& value)
02066 {
02067 the_item.setAttr(attr_name, value);
02068 }
02069
02070 void delAttr (const std::string& attr_name)
02071 {
02072 the_item.delAttr(attr_name);
02073 }
02074
02075 void delItem (const Object& k)
02076 {
02077 the_item.delItem(k);
02078 }
02079 };
02080
02081
02082 template< class T >
02083 bool operator==(const mapref<T>& left, const mapref<T>& right)
02084 {
02085 return true;
02086 }
02087
02088 template< class T >
02089 bool operator!=(const mapref<T>& left, const mapref<T>& right)
02090 {
02091 return true;
02092 }
02093
02094 template<TEMPLATE_TYPENAME T>
02095 class MapBase: public Object
02096 {
02097 protected:
02098 explicit MapBase<T>()
02099 {}
02100 public:
02101
02102
02103
02104
02105
02106 typedef size_t size_type;
02107 typedef Object key_type;
02108 typedef mapref<T> data_type;
02109 typedef std::pair< const T, T > value_type;
02110 typedef std::pair< const T, mapref<T> > reference;
02111 typedef const std::pair< const T, const T > const_reference;
02112 typedef std::pair< const T, mapref<T> > pointer;
02113
02114
02115 explicit MapBase<T> (PyObject *pyob, bool owned = false): Object(pyob, owned)
02116 {
02117 validate();
02118 }
02119
02120
02121 MapBase<T> (const Object& ob): Object(ob)
02122 {
02123 validate();
02124 }
02125
02126
02127 MapBase<T>& operator= (const Object& rhs)
02128 {
02129 return (*this = *rhs);
02130 }
02131
02132 MapBase<T>& operator= (PyObject* rhsp)
02133 {
02134 if(ptr() == rhsp) return *this;
02135 set (rhsp);
02136 return *this;
02137 }
02138
02139 virtual bool accepts (PyObject *pyob) const
02140 {
02141 return pyob && PyMapping_Check(pyob);
02142 }
02143
02144
02145
02146
02147 void clear ()
02148 {
02149 List k = keys();
02150 for(List::iterator i = k.begin(); i != k.end(); i++)
02151 {
02152 delItem(*i);
02153 }
02154 }
02155
02156 virtual size_type size() const
02157 {
02158 return PyMapping_Length (ptr());
02159 }
02160
02161
02162 T operator[](const std::string& key) const
02163 {
02164 return getItem(key);
02165 }
02166
02167 T operator[](const Object& key) const
02168 {
02169 return getItem(key);
02170 }
02171
02172 mapref<T> operator[](const std::string& key)
02173 {
02174 return mapref<T>(*this, key);
02175 }
02176
02177 mapref<T> operator[](const Object& key)
02178 {
02179 return mapref<T>(*this, key);
02180 }
02181
02182 int length () const
02183 {
02184 return PyMapping_Length (ptr());
02185 }
02186
02187 bool hasKey (const std::string& s) const
02188 {
02189 return PyMapping_HasKeyString (ptr(),const_cast<char*>(s.c_str())) != 0;
02190 }
02191
02192 bool hasKey (const Object& s) const
02193 {
02194 return PyMapping_HasKey (ptr(), s.ptr()) != 0;
02195 }
02196
02197 T getItem (const std::string& s) const
02198 {
02199 return T(
02200 asObject(PyMapping_GetItemString (ptr(),const_cast<char*>(s.c_str())))
02201 );
02202 }
02203
02204 T getItem (const Object& s) const
02205 {
02206 return T(
02207 asObject(PyObject_GetItem (ptr(), s.ptr()))
02208 );
02209 }
02210
02211 virtual void setItem (const char *s, const Object& ob)
02212 {
02213 if (PyMapping_SetItemString (ptr(), const_cast<char*>(s), *ob) == -1)
02214 {
02215 throw Exception();
02216 }
02217 }
02218
02219 virtual void setItem (const std::string& s, const Object& ob)
02220 {
02221 if (PyMapping_SetItemString (ptr(), const_cast<char*>(s.c_str()), *ob) == -1)
02222 {
02223 throw Exception();
02224 }
02225 }
02226
02227 virtual void setItem (const Object& s, const Object& ob)
02228 {
02229 if (PyObject_SetItem (ptr(), s.ptr(), ob.ptr()) == -1)
02230 {
02231 throw Exception();
02232 }
02233 }
02234
02235 void delItem (const std::string& s)
02236 {
02237 if (PyMapping_DelItemString (ptr(), const_cast<char*>(s.c_str())) == -1)
02238 {
02239 throw Exception();
02240 }
02241 }
02242
02243 void delItem (const Object& s)
02244 {
02245 if (PyMapping_DelItem (ptr(), *s) == -1)
02246 {
02247 throw Exception();
02248 }
02249 }
02250
02251 List keys () const
02252 {
02253 return List(PyMapping_Keys(ptr()), true);
02254 }
02255
02256 List values () const
02257 {
02258 return List(PyMapping_Values(ptr()), true);
02259 }
02260
02261 List items () const
02262 {
02263 return List(PyMapping_Items(ptr()), true);
02264 }
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277 #if 0 // here is the test code with which I found the (still existing) bug
02278 typedef cxx::Dict d_t;
02279 d_t d;
02280 cxx::String s1("blah");
02281 cxx::String s2("gorf");
02282 d[ "one" ] = s1;
02283 d[ "two" ] = s1;
02284 d[ "three" ] = s2;
02285 d[ "four" ] = s2;
02286
02287 d_t::iterator it;
02288 it = d.begin();
02289
02290 for( ; it != d.end(); ++it )
02291 {
02292 d_t::value_type vt( *it );
02293 cxx::String rs = vt.second.repr();
02294 std::string ls = rs.operator std::string();
02295 fprintf( stderr, "%s\n", ls );
02296 }
02297 #endif // 0
02298
02299 class iterator
02300 {
02301
02302 protected:
02303 typedef std::forward_iterator_tag iterator_category;
02304 typedef std::pair< const T, T > value_type;
02305 typedef int difference_type;
02306 typedef std::pair< const T, mapref<T> > pointer;
02307 typedef std::pair< const T, mapref<T> > reference;
02308
02309 friend class MapBase<T>;
02310
02311 MapBase<T>* map;
02312 List keys;
02313 List::iterator pos;
02314
02315 public:
02316 ~iterator ()
02317 {}
02318
02319 iterator ()
02320 : map( 0 )
02321 , keys()
02322 , pos()
02323 {}
02324
02325 iterator (MapBase<T>* m, bool end = false )
02326 : map( m )
02327 , keys( m->keys() )
02328 , pos( end ? keys.end() : keys.begin() )
02329 {}
02330
02331 iterator (const iterator& other)
02332 : map( other.map )
02333 , keys( other.keys )
02334 , pos( other.pos )
02335 {}
02336
02337 reference operator*()
02338 {
02339 Object key = *pos;
02340 return std::make_pair(key, mapref<T>(*map,key));
02341 }
02342
02343 iterator& operator=(const iterator& other)
02344 {
02345 if (this == &other)
02346 return *this;
02347 map = other.map;
02348 keys = other.keys;
02349 pos = other.pos;
02350 return *this;
02351 }
02352
02353 bool eql(const iterator& right) const
02354 {
02355 return *map == *right.map && pos == right.pos;
02356 }
02357 bool neq( const iterator& right ) const
02358 {
02359 return *map != *right.map || pos != right.pos;
02360 }
02361
02362
02363
02364
02365
02366
02367 iterator& operator++ ()
02368 { pos++; return *this;}
02369
02370 iterator operator++ (int)
02371 { return iterator(map, keys, pos++);}
02372
02373 iterator& operator-- ()
02374 { pos--; return *this;}
02375
02376 iterator operator-- (int)
02377 { return iterator(map, keys, pos--);}
02378
02379 std::string diagnose() const
02380 {
02381 std::OSTRSTREAM oss;
02382 oss << "iterator diagnosis " << map << ", " << pos << std::ends;
02383 return std::string(oss.str());
02384 }
02385 };
02386
02387 iterator begin ()
02388 {
02389 return iterator(this);
02390 }
02391
02392 iterator end ()
02393 {
02394 return iterator(this, true);
02395 }
02396
02397 class const_iterator
02398 {
02399 protected:
02400 typedef std::forward_iterator_tag iterator_category;
02401 typedef const std::pair< const T, T > value_type;
02402 typedef int difference_type;
02403 typedef const std::pair< const T, T > pointer;
02404 typedef const std::pair< const T, T > reference;
02405
02406 friend class MapBase<T>;
02407 const MapBase<T>* map;
02408 List keys;
02409 List::iterator pos;
02410
02411 public:
02412 ~const_iterator ()
02413 {}
02414
02415 const_iterator ()
02416 : map( 0 )
02417 , keys()
02418 , pos()
02419 {}
02420
02421 const_iterator (const MapBase<T>* m, List k, List::iterator p )
02422 : map( m )
02423 , keys( k )
02424 , pos( p )
02425 {}
02426
02427 const_iterator(const const_iterator& other)
02428 : map( other.map )
02429 , keys( other.keys )
02430 , pos( other.pos )
02431 {}
02432
02433 bool eql(const const_iterator& right) const
02434 {
02435 return *map == *right.map && pos == right.pos;
02436 }
02437 bool neq( const const_iterator& right ) const
02438 {
02439 return *map != *right.map || pos != right.pos;
02440 }
02441
02442
02443
02444
02445
02446
02447
02448
02449 const_iterator& operator=(const const_iterator& other)
02450 {
02451 if (this == &other) return *this;
02452 map = other.map;
02453 keys = other.keys;
02454 pos = other.pos;
02455 return *this;
02456 }
02457
02458
02459 const_iterator& operator++ ()
02460 { pos++; return *this;}
02461
02462 const_iterator operator++ (int)
02463 { return const_iterator(map, keys, pos++);}
02464
02465 const_iterator& operator-- ()
02466 { pos--; return *this;}
02467
02468 const_iterator operator-- (int)
02469 { return const_iterator(map, keys, pos--);}
02470 };
02471
02472 const_iterator begin () const
02473 {
02474 return const_iterator(this, 0);
02475 }
02476
02477 const_iterator end () const
02478 {
02479 return const_iterator(this, length());
02480 }
02481
02482 };
02483
02484 typedef MapBase<Object> Mapping;
02485
02486 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
02487 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::iterator& left, const EXPLICIT_TYPENAME MapBase<T>::iterator& right);
02488 template <TEMPLATE_TYPENAME T> bool operator==(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_TYPENAME MapBase<T>::const_iterator& right);
02489 template <TEMPLATE_TYPENAME T> bool operator!=(const EXPLICIT_TYPENAME MapBase<T>::const_iterator& left, const EXPLICIT_TYPENAME MapBase<T>::const_iterator& right);
02490
02491 extern bool operator==(const Mapping::iterator& left, const Mapping::iterator& right);
02492 extern bool operator!=(const Mapping::iterator& left, const Mapping::iterator& right);
02493 extern bool operator==(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
02494 extern bool operator!=(const Mapping::const_iterator& left, const Mapping::const_iterator& right);
02495
02496
02497
02498
02499 class Dict: public Mapping
02500 {
02501 public:
02502
02503 explicit Dict (PyObject *pyob, bool owned=false): Mapping (pyob, owned)
02504 {
02505 validate();
02506 }
02507 Dict (const Dict& ob): Mapping(ob)
02508 {
02509 validate();
02510 }
02511
02512 Dict ()
02513 {
02514 set(PyDict_New (), true);
02515 validate();
02516 }
02517
02518
02519 Dict& operator= (const Object& rhs)
02520 {
02521 return (*this = *rhs);
02522 }
02523
02524 Dict& operator= (PyObject* rhsp)
02525 {
02526 if(ptr() == rhsp) return *this;
02527 set(rhsp);
02528 return *this;
02529 }
02530
02531 virtual bool accepts (PyObject *pyob) const
02532 {
02533 return pyob && Py::_Dict_Check (pyob);
02534 }
02535 };
02536
02537 class Callable: public Object
02538 {
02539 public:
02540
02541 explicit Callable (): Object() {}
02542 explicit Callable (PyObject *pyob, bool owned = false): Object (pyob, owned)
02543 {
02544 validate();
02545 }
02546
02547 Callable (const Object& ob): Object(ob)
02548 {
02549 validate();
02550 }
02551
02552
02553
02554 Callable& operator= (const Object& rhs)
02555 {
02556 return (*this = *rhs);
02557 }
02558
02559 Callable& operator= (PyObject* rhsp)
02560 {
02561 if(ptr() == rhsp) return *this;
02562 set (rhsp);
02563 return *this;
02564 }
02565
02566
02567 virtual bool accepts (PyObject *pyob) const
02568 {
02569 return pyob && PyCallable_Check (pyob);
02570 }
02571
02572
02573 Object apply(const Tuple& args) const
02574 {
02575 return asObject(PyObject_CallObject(ptr(), args.ptr()));
02576 }
02577
02578
02579 Object apply(const Tuple& args, const Dict& kw) const
02580 {
02581 return asObject( PyEval_CallObjectWithKeywords( ptr(), args.ptr(), kw.ptr() ) );
02582 }
02583
02584 Object apply(PyObject* pargs = 0) const
02585 {
02586 return apply (Tuple(pargs));
02587 }
02588 };
02589
02590 class Module: public Object
02591 {
02592 public:
02593 explicit Module (PyObject* pyob, bool owned = false): Object (pyob, owned)
02594 {
02595 validate();
02596 }
02597
02598
02599 explicit Module (const std::string&s): Object()
02600 {
02601 PyObject *m = PyImport_AddModule( const_cast<char *>(s.c_str()) );
02602 set( m, false );
02603 validate ();
02604 }
02605
02606
02607 Module (const Module& ob): Object(*ob)
02608 {
02609 validate();
02610 }
02611
02612 Module& operator= (const Object& rhs)
02613 {
02614 return (*this = *rhs);
02615 }
02616
02617 Module& operator= (PyObject* rhsp)
02618 {
02619 if(ptr() == rhsp) return *this;
02620 set(rhsp);
02621 return *this;
02622 }
02623
02624 Dict getDict()
02625 {
02626 return Dict(PyModule_GetDict(ptr()));
02627
02628 }
02629 };
02630
02631
02632 inline Object operator+ (const Object& a)
02633 {
02634 return asObject(PyNumber_Positive(*a));
02635 }
02636 inline Object operator- (const Object& a)
02637 {
02638 return asObject(PyNumber_Negative(*a));
02639 }
02640
02641 inline Object abs(const Object& a)
02642 {
02643 return asObject(PyNumber_Absolute(*a));
02644 }
02645
02646 inline std::pair<Object,Object> coerce(const Object& a, const Object& b)
02647 {
02648 PyObject *p1, *p2;
02649 p1 = *a;
02650 p2 = *b;
02651 if(PyNumber_Coerce(&p1,&p2) == -1)
02652 {
02653 throw Exception();
02654 }
02655 return std::pair<Object,Object>(asObject(p1), asObject(p2));
02656 }
02657
02658 inline Object operator+ (const Object& a, const Object& b)
02659 {
02660 return asObject(PyNumber_Add(*a, *b));
02661 }
02662 inline Object operator+ (const Object& a, int j)
02663 {
02664 return asObject(PyNumber_Add(*a, *Int(j)));
02665 }
02666 inline Object operator+ (const Object& a, double v)
02667 {
02668 return asObject(PyNumber_Add(*a, *Float(v)));
02669 }
02670 inline Object operator+ (int j, const Object& b)
02671 {
02672 return asObject(PyNumber_Add(*Int(j), *b));
02673 }
02674 inline Object operator+ (double v, const Object& b)
02675 {
02676 return asObject(PyNumber_Add(*Float(v), *b));
02677 }
02678
02679 inline Object operator- (const Object& a, const Object& b)
02680 {
02681 return asObject(PyNumber_Subtract(*a, *b));
02682 }
02683 inline Object operator- (const Object& a, int j)
02684 {
02685 return asObject(PyNumber_Subtract(*a, *Int(j)));
02686 }
02687 inline Object operator- (const Object& a, double v)
02688 {
02689 return asObject(PyNumber_Subtract(*a, *Float(v)));
02690 }
02691 inline Object operator- (int j, const Object& b)
02692 {
02693 return asObject(PyNumber_Subtract(*Int(j), *b));
02694 }
02695 inline Object operator- (double v, const Object& b)
02696 {
02697 return asObject(PyNumber_Subtract(*Float(v), *b));
02698 }
02699
02700 inline Object operator* (const Object& a, const Object& b)
02701 {
02702 return asObject(PyNumber_Multiply(*a, *b));
02703 }
02704 inline Object operator* (const Object& a, int j)
02705 {
02706 return asObject(PyNumber_Multiply(*a, *Int(j)));
02707 }
02708 inline Object operator* (const Object& a, double v)
02709 {
02710 return asObject(PyNumber_Multiply(*a, *Float(v)));
02711 }
02712 inline Object operator* (int j, const Object& b)
02713 {
02714 return asObject(PyNumber_Multiply(*Int(j), *b));
02715 }
02716 inline Object operator* (double v, const Object& b)
02717 {
02718 return asObject(PyNumber_Multiply(*Float(v), *b));
02719 }
02720
02721 inline Object operator/ (const Object& a, const Object& b)
02722 {
02723 return asObject(PyNumber_Divide(*a, *b));
02724 }
02725 inline Object operator/ (const Object& a, int j)
02726 {
02727 return asObject(PyNumber_Divide(*a, *Int(j)));
02728 }
02729 inline Object operator/ (const Object& a, double v)
02730 {
02731 return asObject(PyNumber_Divide(*a, *Float(v)));
02732 }
02733 inline Object operator/ (int j, const Object& b)
02734 {
02735 return asObject(PyNumber_Divide(*Int(j), *b));
02736 }
02737 inline Object operator/ (double v, const Object& b)
02738 {
02739 return asObject(PyNumber_Divide(*Float(v), *b));
02740 }
02741
02742 inline Object operator% (const Object& a, const Object& b)
02743 {
02744 return asObject(PyNumber_Remainder(*a, *b));
02745 }
02746 inline Object operator% (const Object& a, int j)
02747 {
02748 return asObject(PyNumber_Remainder(*a, *Int(j)));
02749 }
02750 inline Object operator% (const Object& a, double v)
02751 {
02752 return asObject(PyNumber_Remainder(*a, *Float(v)));
02753 }
02754 inline Object operator% (int j, const Object& b)
02755 {
02756 return asObject(PyNumber_Remainder(*Int(j), *b));
02757 }
02758 inline Object operator% (double v, const Object& b)
02759 {
02760 return asObject(PyNumber_Remainder(*Float(v), *b));
02761 }
02762
02763 inline Object type(const Exception&)
02764 {
02765 PyObject *ptype, *pvalue, *ptrace;
02766 PyErr_Fetch(&ptype, &pvalue, &ptrace);
02767 Object result(ptype);
02768 PyErr_Restore(ptype, pvalue, ptrace);
02769 return result;
02770 }
02771
02772 inline Object value(const Exception&)
02773 {
02774 PyObject *ptype, *pvalue, *ptrace;
02775 PyErr_Fetch(&ptype, &pvalue, &ptrace);
02776 Object result;
02777 if(pvalue) result = pvalue;
02778 PyErr_Restore(ptype, pvalue, ptrace);
02779 return result;
02780 }
02781
02782 inline Object trace(const Exception&)
02783 {
02784 PyObject *ptype, *pvalue, *ptrace;
02785 PyErr_Fetch(&ptype, &pvalue, &ptrace);
02786 Object result;
02787 if(ptrace) result = ptrace;
02788 PyErr_Restore(ptype, pvalue, ptrace);
02789 return result;
02790 }
02791
02792
02793
02794 template<TEMPLATE_TYPENAME T>
02795 String seqref<T>::str () const
02796 {
02797 return the_item.str();
02798 }
02799
02800 template<TEMPLATE_TYPENAME T>
02801 String seqref<T>::repr () const
02802 {
02803 return the_item.repr();
02804 }
02805
02806
02807 }
02808 #endif // __CXX_Objects__h