mirror of
https://github.com/boostorg/python.git
synced 2026-01-20 16:52:15 +00:00
Compare commits
14 Commits
ft_fixes_c
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d6b042c4c | ||
|
|
55a7884912 | ||
|
|
2566e1dd3a | ||
|
|
9bca6982a4 | ||
|
|
c7e12ecf3d | ||
|
|
5031479fa2 | ||
|
|
fc9a6ac369 | ||
|
|
905074542e | ||
|
|
b7957da50a | ||
|
|
1b1620b62a | ||
|
|
0ed5af25a7 | ||
|
|
1dbcf12502 | ||
|
|
10c2fbd63a | ||
|
|
9b602d16b4 |
@@ -52,6 +52,13 @@ bpl_exa + "/tst_dvect2.py",
|
|||||||
bpl_exa + "/tst_ivect1.py",
|
bpl_exa + "/tst_ivect1.py",
|
||||||
bpl_exa + "/tst_ivect2.py",
|
bpl_exa + "/tst_ivect2.py",
|
||||||
bpl_exa + "/test_cross_module.py",
|
bpl_exa + "/test_cross_module.py",
|
||||||
|
bpl_exa + "/vector_wrapper.h",
|
||||||
|
bpl_exa + "/richcmp1.cpp",
|
||||||
|
bpl_exa + "/richcmp2.cpp",
|
||||||
|
bpl_exa + "/richcmp3.cpp",
|
||||||
|
bpl_exa + "/test_richcmp1.py",
|
||||||
|
bpl_exa + "/test_richcmp2.py",
|
||||||
|
bpl_exa + "/test_richcmp3.py",
|
||||||
)
|
)
|
||||||
|
|
||||||
defs = (
|
defs = (
|
||||||
@@ -68,6 +75,9 @@ defs = (
|
|||||||
"noncopyable_import",
|
"noncopyable_import",
|
||||||
"ivect",
|
"ivect",
|
||||||
"dvect",
|
"dvect",
|
||||||
|
"richcmp1",
|
||||||
|
"richcmp2",
|
||||||
|
"richcmp3",
|
||||||
)
|
)
|
||||||
|
|
||||||
if (__name__ == "__main__"):
|
if (__name__ == "__main__"):
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ BOOST=$(ROOT)/boost
|
|||||||
|
|
||||||
PYEXE=/usr/local/Python-1.5.2/bin/python
|
PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
#PYEXE=/usr/local/Python-2.1/bin/python
|
||||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
#PYINC=-I/usr/local/Python-2.1/include/python2.1
|
||||||
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
|
STLPORTINC=-I$(BOOST)/boost/compatibility/cpp_c_headers
|
||||||
|
|
||||||
STDOPTS=
|
STDOPTS=
|
||||||
@@ -46,7 +46,8 @@ DEPOBJ=$(OBJ) \
|
|||||||
do_it_yourself_converters.o \
|
do_it_yourself_converters.o \
|
||||||
pickle1.o pickle2.o pickle3.o \
|
pickle1.o pickle2.o pickle3.o \
|
||||||
noncopyable_export.o noncopyable_import.o \
|
noncopyable_export.o noncopyable_import.o \
|
||||||
ivect.o dvect.o
|
ivect.o dvect.o \
|
||||||
|
richcmp1.o richcmp2.o richcmp3.o
|
||||||
|
|
||||||
.SUFFIXES: .o .cpp
|
.SUFFIXES: .o .cpp
|
||||||
|
|
||||||
@@ -58,7 +59,8 @@ all: libboost_python.a \
|
|||||||
do_it_yourself_converters.so \
|
do_it_yourself_converters.so \
|
||||||
pickle1.so pickle2.so pickle3.so \
|
pickle1.so pickle2.so pickle3.so \
|
||||||
noncopyable_export.so noncopyable_import.so \
|
noncopyable_export.so noncopyable_import.so \
|
||||||
ivect.so dvect.so
|
ivect.so dvect.so \
|
||||||
|
richcmp1.so richcmp2.so richcmp3.so
|
||||||
|
|
||||||
libboost_python.a: $(OBJ)
|
libboost_python.a: $(OBJ)
|
||||||
rm -f libboost_python.a
|
rm -f libboost_python.a
|
||||||
@@ -105,6 +107,15 @@ ivect.so: $(OBJ) ivect.o
|
|||||||
dvect.so: $(OBJ) dvect.o
|
dvect.so: $(OBJ) dvect.o
|
||||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||||
|
|
||||||
|
richcmp1.so: $(OBJ) richcmp1.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so
|
||||||
|
|
||||||
|
richcmp2.so: $(OBJ) richcmp2.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so
|
||||||
|
|
||||||
|
richcmp3.so: $(OBJ) richcmp3.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so
|
||||||
|
|
||||||
.cpp.o:
|
.cpp.o:
|
||||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||||
|
|
||||||
@@ -119,6 +130,9 @@ test:
|
|||||||
$(PYEXE) test_pickle2.py
|
$(PYEXE) test_pickle2.py
|
||||||
$(PYEXE) test_pickle3.py
|
$(PYEXE) test_pickle3.py
|
||||||
$(PYEXE) test_cross_module.py
|
$(PYEXE) test_cross_module.py
|
||||||
|
$(PYEXE) test_richcmp1.py
|
||||||
|
$(PYEXE) test_richcmp2.py
|
||||||
|
$(PYEXE) test_richcmp3.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||||
@@ -135,6 +149,9 @@ clean:
|
|||||||
rm -f noncopyable_import.o noncopyable_import.so
|
rm -f noncopyable_import.o noncopyable_import.so
|
||||||
rm -f ivect.o ivect.so
|
rm -f ivect.o ivect.so
|
||||||
rm -f dvect.o dvect.so
|
rm -f dvect.o dvect.so
|
||||||
|
rm -f richcmp1.o richcmp1.so
|
||||||
|
rm -f richcmp2.o richcmp2.so
|
||||||
|
rm -f richcmp3.o richcmp3.so
|
||||||
rm -f so_locations *.pyc
|
rm -f so_locations *.pyc
|
||||||
rm -rf ii_files
|
rm -rf ii_files
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ PYEXE=PYTHONPATH=. /usr/bin/python
|
|||||||
PYINC=-I/usr/include/python1.5
|
PYINC=-I/usr/include/python1.5
|
||||||
#PYEXE=/usr/local/Python-1.5.2/bin/python
|
#PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||||
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
#PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
#PYEXE=/usr/local/Python-2.1/bin/python
|
||||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
#PYINC=-I/usr/local/Python-2.1/include/python2.1
|
||||||
|
|
||||||
STDOPTS=-fPIC -ftemplate-depth-21
|
STDOPTS=-fPIC -ftemplate-depth-21
|
||||||
WARNOPTS=
|
WARNOPTS=
|
||||||
@@ -47,7 +47,8 @@ DEPOBJ=$(OBJ) \
|
|||||||
do_it_yourself_converters.o \
|
do_it_yourself_converters.o \
|
||||||
pickle1.o pickle2.o pickle3.o \
|
pickle1.o pickle2.o pickle3.o \
|
||||||
noncopyable_export.o noncopyable_import.o \
|
noncopyable_export.o noncopyable_import.o \
|
||||||
ivect.o dvect.o
|
ivect.o dvect.o \
|
||||||
|
richcmp1.o richcmp2.o richcmp3.o
|
||||||
|
|
||||||
.SUFFIXES: .o .cpp
|
.SUFFIXES: .o .cpp
|
||||||
|
|
||||||
@@ -59,7 +60,8 @@ all: libboost_python.a \
|
|||||||
do_it_yourself_converters.so \
|
do_it_yourself_converters.so \
|
||||||
pickle1.so pickle2.so pickle3.so \
|
pickle1.so pickle2.so pickle3.so \
|
||||||
noncopyable_export.so noncopyable_import.so \
|
noncopyable_export.so noncopyable_import.so \
|
||||||
ivect.so dvect.so
|
ivect.so dvect.so \
|
||||||
|
richcmp1.so richcmp2.so richcmp3.so
|
||||||
|
|
||||||
libboost_python.a: $(OBJ)
|
libboost_python.a: $(OBJ)
|
||||||
rm -f libboost_python.a
|
rm -f libboost_python.a
|
||||||
@@ -106,6 +108,15 @@ ivect.so: $(OBJ) ivect.o
|
|||||||
dvect.so: $(OBJ) dvect.o
|
dvect.so: $(OBJ) dvect.o
|
||||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||||
|
|
||||||
|
richcmp1.so: $(OBJ) richcmp1.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so
|
||||||
|
|
||||||
|
richcmp2.so: $(OBJ) richcmp2.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so
|
||||||
|
|
||||||
|
richcmp3.so: $(OBJ) richcmp3.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so
|
||||||
|
|
||||||
.cpp.o:
|
.cpp.o:
|
||||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||||
|
|
||||||
@@ -120,6 +131,9 @@ test:
|
|||||||
$(PYEXE) test_pickle2.py
|
$(PYEXE) test_pickle2.py
|
||||||
$(PYEXE) test_pickle3.py
|
$(PYEXE) test_pickle3.py
|
||||||
$(PYEXE) test_cross_module.py
|
$(PYEXE) test_cross_module.py
|
||||||
|
$(PYEXE) test_richcmp1.py
|
||||||
|
$(PYEXE) test_richcmp2.py
|
||||||
|
$(PYEXE) test_richcmp3.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||||
@@ -136,6 +150,9 @@ clean:
|
|||||||
rm -f noncopyable_import.o noncopyable_import.so
|
rm -f noncopyable_import.o noncopyable_import.so
|
||||||
rm -f ivect.o ivect.so
|
rm -f ivect.o ivect.so
|
||||||
rm -f dvect.o dvect.so
|
rm -f dvect.o dvect.so
|
||||||
|
rm -f richcmp1.o richcmp1.so
|
||||||
|
rm -f richcmp2.o richcmp2.so
|
||||||
|
rm -f richcmp3.o richcmp3.so
|
||||||
rm -f so_locations *.pyc
|
rm -f so_locations *.pyc
|
||||||
|
|
||||||
softlinks:
|
softlinks:
|
||||||
|
|||||||
@@ -62,10 +62,11 @@ all: libboost_python.a \
|
|||||||
do_it_yourself_converters.pyd \
|
do_it_yourself_converters.pyd \
|
||||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||||
noncopyable_export.pyd noncopyable_import.pyd \
|
noncopyable_export.pyd noncopyable_import.pyd \
|
||||||
ivect.pyd dvect.pyd
|
ivect.pyd dvect.pyd \
|
||||||
|
richcmp1.pyd richcmp2.pyd richcmp3.pyd
|
||||||
|
|
||||||
libboost_python.a: $(OBJ)
|
libboost_python.a: $(OBJ)
|
||||||
del libboost_python.a
|
-del libboost_python.a
|
||||||
ar r libboost_python.a $(OBJ)
|
ar r libboost_python.a $(OBJ)
|
||||||
|
|
||||||
DLLWRAPOPTS=-s --driver-name g++ -s \
|
DLLWRAPOPTS=-s --driver-name g++ -s \
|
||||||
@@ -149,6 +150,24 @@ dvect.pyd: $(OBJ) dvect.o
|
|||||||
--def dvect.def \
|
--def dvect.def \
|
||||||
$(OBJ) dvect.o $(PYLIB)
|
$(OBJ) dvect.o $(PYLIB)
|
||||||
|
|
||||||
|
richcmp1.pyd: $(OBJ) richcmp1.o
|
||||||
|
dllwrap $(DLLWRAPOPTS) \
|
||||||
|
--dllname richcmp1.pyd \
|
||||||
|
--def richcmp1.def \
|
||||||
|
$(OBJ) richcmp1.o $(PYLIB)
|
||||||
|
|
||||||
|
richcmp2.pyd: $(OBJ) richcmp2.o
|
||||||
|
dllwrap $(DLLWRAPOPTS) \
|
||||||
|
--dllname richcmp2.pyd \
|
||||||
|
--def richcmp2.def \
|
||||||
|
$(OBJ) richcmp2.o $(PYLIB)
|
||||||
|
|
||||||
|
richcmp3.pyd: $(OBJ) richcmp3.o
|
||||||
|
dllwrap $(DLLWRAPOPTS) \
|
||||||
|
--dllname richcmp3.pyd \
|
||||||
|
--def richcmp3.def \
|
||||||
|
$(OBJ) richcmp3.o $(PYLIB)
|
||||||
|
|
||||||
.cpp.o:
|
.cpp.o:
|
||||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||||
|
|
||||||
@@ -163,12 +182,15 @@ test:
|
|||||||
$(PYEXE) test_pickle2.py
|
$(PYEXE) test_pickle2.py
|
||||||
$(PYEXE) test_pickle3.py
|
$(PYEXE) test_pickle3.py
|
||||||
$(PYEXE) test_cross_module.py
|
$(PYEXE) test_cross_module.py
|
||||||
|
$(PYEXE) test_richcmp1.py
|
||||||
|
$(PYEXE) test_richcmp2.py
|
||||||
|
$(PYEXE) test_richcmp3.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
del *.o
|
-del *.o
|
||||||
del *.a
|
-del *.a
|
||||||
del *.pyd
|
-del *.pyd
|
||||||
del *.pyc
|
-del *.pyc
|
||||||
|
|
||||||
softlinks:
|
softlinks:
|
||||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ BOOST=$(ROOT)/boost
|
|||||||
|
|
||||||
PYEXE=/usr/local/Python-1.5.2/bin/python
|
PYEXE=/usr/local/Python-1.5.2/bin/python
|
||||||
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
PYINC=-I/usr/local/Python-1.5.2/include/python1.5
|
||||||
#PYEXE=/usr/local/Python-2.0/bin/python
|
#PYEXE=/usr/local/Python-2.1/bin/python
|
||||||
#PYINC=-I/usr/local/Python-2.0/include/python2.0
|
#PYINC=-I/usr/local/Python-2.1/include/python2.1
|
||||||
#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport
|
#STLPORTINC=-I/usr/local/STLport-4.1b3/stlport
|
||||||
#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport
|
#STLPORTINC=-I/usr/local/STLport-4.1b4/stlport
|
||||||
#STLPORTOPTS= \
|
#STLPORTOPTS= \
|
||||||
@@ -57,7 +57,8 @@ DEPOBJ=$(OBJ) \
|
|||||||
do_it_yourself_converters.o \
|
do_it_yourself_converters.o \
|
||||||
pickle1.o pickle2.o pickle3.o \
|
pickle1.o pickle2.o pickle3.o \
|
||||||
noncopyable_export.o noncopyable_import.o \
|
noncopyable_export.o noncopyable_import.o \
|
||||||
ivect.o dvect.o
|
ivect.o dvect.o \
|
||||||
|
richcmp1.o richcmp2.o richcmp3.o
|
||||||
|
|
||||||
.SUFFIXES: .o .cpp
|
.SUFFIXES: .o .cpp
|
||||||
|
|
||||||
@@ -69,7 +70,8 @@ all: libboost_python.a \
|
|||||||
do_it_yourself_converters.so \
|
do_it_yourself_converters.so \
|
||||||
pickle1.so pickle2.so pickle3.so \
|
pickle1.so pickle2.so pickle3.so \
|
||||||
noncopyable_export.so noncopyable_import.so \
|
noncopyable_export.so noncopyable_import.so \
|
||||||
ivect.so dvect.so
|
ivect.so dvect.so \
|
||||||
|
richcmp1.so richcmp2.so richcmp3.so
|
||||||
|
|
||||||
libboost_python.a: $(OBJ)
|
libboost_python.a: $(OBJ)
|
||||||
rm -f libboost_python.a
|
rm -f libboost_python.a
|
||||||
@@ -120,6 +122,15 @@ ivect.so: $(OBJ) ivect.o
|
|||||||
dvect.so: $(OBJ) dvect.o
|
dvect.so: $(OBJ) dvect.o
|
||||||
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
$(LD) $(LDOPTS) $(OBJ) $(HIDDEN) dvect.o -o dvect.so
|
||||||
|
|
||||||
|
richcmp1.so: $(OBJ) richcmp1.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp1.o -o richcmp1.so
|
||||||
|
|
||||||
|
richcmp2.so: $(OBJ) richcmp2.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp2.o -o richcmp2.so
|
||||||
|
|
||||||
|
richcmp3.so: $(OBJ) richcmp3.o
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp3.o -o richcmp3.so
|
||||||
|
|
||||||
.cpp.o:
|
.cpp.o:
|
||||||
$(CPP) $(CPPOPTS) -c $*.cpp
|
$(CPP) $(CPPOPTS) -c $*.cpp
|
||||||
|
|
||||||
@@ -134,6 +145,9 @@ test:
|
|||||||
$(PYEXE) test_pickle2.py
|
$(PYEXE) test_pickle2.py
|
||||||
$(PYEXE) test_pickle3.py
|
$(PYEXE) test_pickle3.py
|
||||||
$(PYEXE) test_cross_module.py
|
$(PYEXE) test_cross_module.py
|
||||||
|
$(PYEXE) test_richcmp1.py
|
||||||
|
$(PYEXE) test_richcmp2.py
|
||||||
|
$(PYEXE) test_richcmp3.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
rm -f $(OBJ) libboost_python.a libboost_python.a.input
|
||||||
@@ -150,6 +164,9 @@ clean:
|
|||||||
rm -f noncopyable_import.o noncopyable_import.so
|
rm -f noncopyable_import.o noncopyable_import.so
|
||||||
rm -f ivect.o ivect.so
|
rm -f ivect.o ivect.so
|
||||||
rm -f dvect.o dvect.so
|
rm -f dvect.o dvect.so
|
||||||
|
rm -f richcmp1.o richcmp1.so
|
||||||
|
rm -f richcmp2.o richcmp2.so
|
||||||
|
rm -f richcmp3.o richcmp3.so
|
||||||
rm -f so_locations *.pyc
|
rm -f so_locations *.pyc
|
||||||
rm -rf cxx_repository
|
rm -rf cxx_repository
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ BOOST_UNIX=$(HOME)/boost
|
|||||||
PYEXE="C:\Program files\Python\python.exe"
|
PYEXE="C:\Program files\Python\python.exe"
|
||||||
PYINC=/I"C:\Program files\Python\include"
|
PYINC=/I"C:\Program files\Python\include"
|
||||||
PYLIB="C:\Program files\Python\libs\python15.lib"
|
PYLIB="C:\Program files\Python\libs\python15.lib"
|
||||||
|
#PYEXE="C:\Python21\python.exe"
|
||||||
|
#PYINC=/I"C:\Python21\include"
|
||||||
|
#PYLIB="C:\Python21\libs\python21.lib"
|
||||||
|
|
||||||
STDOPTS=/nologo /MD /GR /GX /Zm200
|
STDOPTS=/nologo /MD /GR /GX /Zm200
|
||||||
WARNOPTS=
|
WARNOPTS=
|
||||||
@@ -43,7 +46,8 @@ all: boost_python.lib \
|
|||||||
do_it_yourself_converters.pyd \
|
do_it_yourself_converters.pyd \
|
||||||
pickle1.pyd pickle2.pyd pickle3.pyd \
|
pickle1.pyd pickle2.pyd pickle3.pyd \
|
||||||
noncopyable_export.pyd noncopyable_import.pyd \
|
noncopyable_export.pyd noncopyable_import.pyd \
|
||||||
ivect.pyd dvect.pyd
|
ivect.pyd dvect.pyd \
|
||||||
|
richcmp1.pyd richcmp2.pyd richcmp3.pyd
|
||||||
|
|
||||||
boost_python.lib: $(OBJ)
|
boost_python.lib: $(OBJ)
|
||||||
$(LD) -lib /nologo /out:boost_python.lib $(OBJ)
|
$(LD) -lib /nologo /out:boost_python.lib $(OBJ)
|
||||||
@@ -87,6 +91,15 @@ ivect.pyd: $(OBJ) ivect.obj
|
|||||||
dvect.pyd: $(OBJ) dvect.obj
|
dvect.pyd: $(OBJ) dvect.obj
|
||||||
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd"
|
$(LD) $(LDOPTS) $(OBJ) dvect.obj $(PYLIB) /export:initdvect /out:"dvect.pyd"
|
||||||
|
|
||||||
|
richcmp1.pyd: $(OBJ) richcmp1.obj
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp1.obj $(PYLIB) /export:initrichcmp1 /out:"richcmp1.pyd"
|
||||||
|
|
||||||
|
richcmp2.pyd: $(OBJ) richcmp2.obj
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp2.obj $(PYLIB) /export:initrichcmp2 /out:"richcmp2.pyd"
|
||||||
|
|
||||||
|
richcmp3.pyd: $(OBJ) richcmp3.obj
|
||||||
|
$(LD) $(LDOPTS) $(OBJ) richcmp3.obj $(PYLIB) /export:initrichcmp3 /out:"richcmp3.pyd"
|
||||||
|
|
||||||
.cpp.obj:
|
.cpp.obj:
|
||||||
$(CPP) $(CPPOPTS) /c $*.cpp
|
$(CPP) $(CPPOPTS) /c $*.cpp
|
||||||
|
|
||||||
@@ -101,14 +114,17 @@ test:
|
|||||||
$(PYEXE) test_pickle2.py
|
$(PYEXE) test_pickle2.py
|
||||||
$(PYEXE) test_pickle3.py
|
$(PYEXE) test_pickle3.py
|
||||||
$(PYEXE) test_cross_module.py --broken-auto-ptr
|
$(PYEXE) test_cross_module.py --broken-auto-ptr
|
||||||
|
$(PYEXE) test_richcmp1.py
|
||||||
|
$(PYEXE) test_richcmp2.py
|
||||||
|
$(PYEXE) test_richcmp3.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
del *.obj
|
-del *.obj
|
||||||
del *.lib
|
-del *.lib
|
||||||
del *.exp
|
-del *.exp
|
||||||
del *.idb
|
-del *.idb
|
||||||
del *.pyd
|
-del *.pyd
|
||||||
del *.pyc
|
-del *.pyc
|
||||||
|
|
||||||
softlinks:
|
softlinks:
|
||||||
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
python $(BOOST_UNIX)/libs/python/build/filemgr.py $(BOOST_UNIX) softlinks
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ initialization. These bind the corresponding enum values to the appropriate
|
|||||||
names so they can be used from Python:
|
names so they can be used from Python:
|
||||||
|
|
||||||
<blockquote><pre>
|
<blockquote><pre>
|
||||||
mymodule.add(boost::python::to_python(enum_value_1), "enum_value_1");
|
mymodule.add(boost::python::make_ref(enum_value_1), "enum_value_1");
|
||||||
mymodule.add(boost::python::to_python(enum_value_2), "enum_value_2");
|
mymodule.add(boost::python::make_ref(enum_value_2), "enum_value_2");
|
||||||
...
|
...
|
||||||
</pre></blockquote>
|
</pre></blockquote>
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ code before the last Python reference to it disappears:
|
|||||||
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE // this is a gcc 2.95.2 bug workaround
|
||||||
PyObject* to_python(Foo* p)
|
PyObject* to_python(Foo* p)
|
||||||
{
|
{
|
||||||
return boost::python::python_extension_class_converters<Foo>::ptr_to_python(p);
|
return boost::python::python_extension_class_converters<Foo>::smart_ptr_to_python(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* to_python(const Foo* p)
|
PyObject* to_python(const Foo* p)
|
||||||
|
|||||||
106
doc/richcmp.html
Normal file
106
doc/richcmp.html
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
|
||||||
|
"http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||||
|
|
||||||
|
<title>Rich Comparisons</title>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<img src="../../../c++boost.gif"
|
||||||
|
alt="c++boost.gif (8819 bytes)"
|
||||||
|
align="center"
|
||||||
|
width="277" height="86">
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h1>Rich Comparisons</h1>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
In Python versions up to and including Python 2.0, support for
|
||||||
|
implementing comparisons on user-defined classes and extension types
|
||||||
|
was quite simple. Classes could implement a <tt>__cmp__</tt> method
|
||||||
|
that was given two instances of a class as arguments, and could only
|
||||||
|
return <tt>0</tt> if they were equal or <tt>+1</tt> or <tt>-1</tt> if
|
||||||
|
they were not. The method could not raise an exception or return
|
||||||
|
anything other than an integer value.
|
||||||
|
In Python 2.1, <b>Rich Comparisons</b> were added (see
|
||||||
|
<a href="http://python.sourceforge.net/peps/pep-0207.html">PEP 207</a>).
|
||||||
|
Python classes can now individually overload each of the <, <=,
|
||||||
|
>, >=, ==, and != operations.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
For more detailed information, search for "rich comparison"
|
||||||
|
<a href="http://www.python.org/doc/current/ref/customization.html"
|
||||||
|
>here</a>.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Boost.Python supports both automatic overloading and manual overloading
|
||||||
|
of the Rich Comparison operators. The <b>compile-time</b> support is
|
||||||
|
independent of the Python version that is used when compiling
|
||||||
|
Boost.Python extension modules. That is, <tt>op_lt</tt> for example can
|
||||||
|
always be used, and the C++ <tt>operator<</tt> will always be bound
|
||||||
|
to the Python method <tt>__lt__</tt>. However, the <b>run-time</b>
|
||||||
|
behavior will depend on the Python version.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
With Python versions before 2.1, the Rich Comparison operators will not
|
||||||
|
be called by Python when any of the six comparison operators
|
||||||
|
(<tt><</tt>, <tt><=</tt>, <tt>==</tt>, <tt>!=</tt>,
|
||||||
|
<tt>></tt>, <tt>>=</tt>) is used in an expression. The only way
|
||||||
|
to access the corresponding methods is to call them explicitly, e.g.
|
||||||
|
<tt>a.__lt__(b)</tt>. Only with Python versions 2.1 or higher will
|
||||||
|
expressions like <tt>a < b</tt> work as expected.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
To support Rich Comparisions, the Python C API was modified between
|
||||||
|
Python versions 2.0 and 2.1. A new slot was introduced in the
|
||||||
|
<tt>PyTypeObject</tt> structure: <tt>tp_richcompare</tt>. For backwards
|
||||||
|
compatibility, a flag (<tt>Py_TPFLAGS_HAVE_RICHCOMPARE</tt>) has to be
|
||||||
|
set to signal to the Python interpreter that Rich Comparisions are
|
||||||
|
supported by a particular type.
|
||||||
|
There is only one flag for all the six comparison operators.
|
||||||
|
When any of the six operators is wrapped automatically or
|
||||||
|
manually, Boost.Python will set this flag. Attempts to use comparison
|
||||||
|
operators at the Python level that are not defined at the C++ level
|
||||||
|
will then lead to an <tt>AttributeError</tt> when the Python 2.1
|
||||||
|
(or higher) interpreter tries, e.g., <tt>a.__lt__(b)</tt>. That
|
||||||
|
is, in general all six operators should be supplied. Automatically
|
||||||
|
wrapped operators and manually wrapped operators can be mixed. For
|
||||||
|
example:<pre>
|
||||||
|
boost::python::class_builder<code> py_code(this_module, "code");
|
||||||
|
|
||||||
|
py_code.def(boost::python::constructor<>());
|
||||||
|
py_code.def(boost::python::constructor<int>());
|
||||||
|
py_code.def(boost::python::operators<( boost::python::op_eq
|
||||||
|
| boost::python::op_ne)>());
|
||||||
|
py_code.def(NotImplemented, "__lt__");
|
||||||
|
py_code.def(NotImplemented, "__le__");
|
||||||
|
py_code.def(NotImplemented, "__gt__");
|
||||||
|
py_code.def(NotImplemented, "__ge__");
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<tt>NotImplemented</tt> is a simple free function that (currently) has
|
||||||
|
to be provided by the user. For example:<pre>
|
||||||
|
boost::python::ref
|
||||||
|
NotImplemented(const code&, const code&) {
|
||||||
|
return
|
||||||
|
boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count);
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
See also:
|
||||||
|
<ul>
|
||||||
|
<li><a href="../example/richcmp1.cpp"><tt>../example/richcmp1.cpp</tt></a>
|
||||||
|
<li><a href="../example/richcmp2.cpp"><tt>../example/richcmp2.cpp</tt></a>
|
||||||
|
<li><a href="../example/richcmp3.cpp"><tt>../example/richcmp3.cpp</tt></a>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
© Copyright Nicholas K. Sauter & Ralf W. Grosse-Kunstleve 2001.
|
||||||
|
Permission to copy, use, modify, sell and distribute this document is
|
||||||
|
granted provided this copyright notice appears in all copies. This
|
||||||
|
document is provided "as is" without express or implied warranty, and
|
||||||
|
with no claim as to its suitability for any purpose.
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Updated: July 2001
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -60,13 +60,27 @@
|
|||||||
<b><tt class='method'>__str__</tt></b>(<i>self</i>)
|
<b><tt class='method'>__str__</tt></b>(<i>self</i>)
|
||||||
<dd>
|
<dd>
|
||||||
Create a string representation which is suitable for printing.
|
Create a string representation which is suitable for printing.
|
||||||
|
<dt>
|
||||||
|
<b><tt class='method'>__lt__</tt></b>(<i>self, other</i>)
|
||||||
|
<dt>
|
||||||
|
<b><tt class='method'>__le__</tt></b>(<i>self, other</i>)
|
||||||
|
<dt>
|
||||||
|
<b><tt class='method'>__eq__</tt></b>(<i>self, other</i>)
|
||||||
|
<dt>
|
||||||
|
<b><tt class='method'>__ne__</tt></b>(<i>self, other</i>)
|
||||||
|
<dt>
|
||||||
|
<b><tt class='method'>__gt__</tt></b>(<i>self, other</i>)
|
||||||
|
<dt>
|
||||||
|
<b><tt class='method'>__ge__</tt></b>(<i>self, other</i>)
|
||||||
|
<dd>
|
||||||
|
Rich Comparison methods.
|
||||||
|
New in Python 2.1.
|
||||||
|
See <a href="richcmp.html">Rich Comparisons</a>.
|
||||||
<dt>
|
<dt>
|
||||||
<b><tt class='method'>__cmp__</tt></b>(<i>self, other</i>)
|
<b><tt class='method'>__cmp__</tt></b>(<i>self, other</i>)
|
||||||
<dd>
|
<dd>
|
||||||
Three-way compare function, used to implement comparison operators
|
Three-way compare function.
|
||||||
(< etc.) Should return a negative integer if <code> self < other
|
See <a href="richcmp.html">Rich Comparisons</a>.
|
||||||
</code> , zero if <code> self == other </code> , a positive integer if
|
|
||||||
<code> self > other </code>.
|
|
||||||
<dt>
|
<dt>
|
||||||
<b><tt class='method'>__hash__</tt></b>(<i>self</i>)
|
<b><tt class='method'>__hash__</tt></b>(<i>self</i>)
|
||||||
<dd>
|
<dd>
|
||||||
@@ -544,17 +558,42 @@ Note that "__rrpow__" is an extension not present in plain Python.
|
|||||||
<code>__cmp__, __rcmp__</code>
|
<code>__cmp__, __rcmp__</code>
|
||||||
<td>
|
<td>
|
||||||
<code>cmp(left, right)</code><br>
|
<code>cmp(left, right)</code><br>
|
||||||
<code>left < right</code><br>
|
<br>See <a href="richcmp.html">Rich Comparisons</a>.
|
||||||
<code>left <= right</code><br>
|
|
||||||
<code>left > right</code><br>
|
|
||||||
<code>left >= right</code><br>
|
|
||||||
<code>left == right</code><br>
|
|
||||||
<code>left != right</code>
|
|
||||||
<td>
|
<td>
|
||||||
<code>op_cmp</code>
|
<code>op_cmp</code>
|
||||||
<td>
|
<td>
|
||||||
<code>cpp_left < cpp_right </code>
|
<code>cpp_left < cpp_right </code>
|
||||||
<br><code>cpp_right < cpp_left</code>
|
<br><code>cpp_right < cpp_left</code>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<code>__lt__</code>
|
||||||
|
<br><code>__le__</code>
|
||||||
|
<br><code>__eq__</code>
|
||||||
|
<br><code>__ne__</code>
|
||||||
|
<br><code>__gt__</code>
|
||||||
|
<br><code>__ge__</code>
|
||||||
|
<td>
|
||||||
|
<code>left < right</code>
|
||||||
|
<br><code>left <= right</code>
|
||||||
|
<br><code>left == right</code>
|
||||||
|
<br><code>left != right</code>
|
||||||
|
<br><code>left > right</code>
|
||||||
|
<br><code>left >= right</code>
|
||||||
|
<br>See <a href="richcmp.html">Rich Comparisons</a>
|
||||||
|
<td>
|
||||||
|
<code>op_lt</code>
|
||||||
|
<br><code>op_le</code>
|
||||||
|
<br><code>op_eq</code>
|
||||||
|
<br><code>op_ne</code>
|
||||||
|
<br><code>op_gt</code>
|
||||||
|
<br><code>op_ge</code>
|
||||||
|
<td>
|
||||||
|
<code>cpp_left < cpp_right </code>
|
||||||
|
<br><code>cpp_left <= cpp_right </code>
|
||||||
|
<br><code>cpp_left == cpp_right </code>
|
||||||
|
<br><code>cpp_left != cpp_right </code>
|
||||||
|
<br><code>cpp_left > cpp_right </code>
|
||||||
|
<br><code>cpp_left >= cpp_right </code>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
template defines a whole raft of these conversions (for <code>T, T*,
|
template defines a whole raft of these conversions (for <code>T, T*,
|
||||||
T&, std::auto_ptr<T></code>, etc.), using the same inline
|
T&, std::auto_ptr<T></code>, etc.), using the same inline
|
||||||
friend function technique employed by <a href=
|
friend function technique employed by <a href=
|
||||||
"http://www.boost.org/libs/utility/operators.htm">the boost operators
|
"file:///c:/boost/site/libs/utility/operators.htm">the boost operators
|
||||||
library</a>.
|
library</a>.
|
||||||
<p>
|
<p>
|
||||||
Because the <code>to_python</code> and <code>from_python</code> functions
|
Because the <code>to_python</code> and <code>from_python</code> functions
|
||||||
|
|||||||
@@ -20,6 +20,16 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||||
|
# include <windows.h>
|
||||||
|
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
= _set_se_translator(structured_exception_translator);
|
||||||
|
# endif
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE_INIT(dvect)
|
BOOST_PYTHON_MODULE_INIT(dvect)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -43,3 +53,4 @@ BOOST_PYTHON_MODULE_INIT(dvect)
|
|||||||
python::handle_exception(); // Deal with the exception for Python
|
python::handle_exception(); // Deal with the exception for Python
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,16 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||||
|
# include <windows.h>
|
||||||
|
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
= _set_se_translator(structured_exception_translator);
|
||||||
|
# endif
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE_INIT(ivect)
|
BOOST_PYTHON_MODULE_INIT(ivect)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -43,3 +53,4 @@ BOOST_PYTHON_MODULE_INIT(ivect)
|
|||||||
python::handle_exception(); // Deal with the exception for Python
|
python::handle_exception(); // Deal with the exception for Python
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,16 @@ namespace python = boost::python;
|
|||||||
|
|
||||||
#include "noncopyable.h"
|
#include "noncopyable.h"
|
||||||
|
|
||||||
|
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||||
|
# include <windows.h>
|
||||||
|
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
= _set_se_translator(structured_exception_translator);
|
||||||
|
# endif
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE_INIT(noncopyable_export)
|
BOOST_PYTHON_MODULE_INIT(noncopyable_export)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -19,6 +19,16 @@ namespace { // Avoid cluttering the global namespace.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef BOOST_MSVC // fixes for JIT debugging
|
||||||
|
# include <windows.h>
|
||||||
|
extern "C" void structured_exception_translator(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
extern "C" void (*old_translator)(unsigned int, EXCEPTION_POINTERS*)
|
||||||
|
= _set_se_translator(structured_exception_translator);
|
||||||
|
# endif
|
||||||
|
|
||||||
BOOST_PYTHON_MODULE_INIT(noncopyable_import)
|
BOOST_PYTHON_MODULE_INIT(noncopyable_import)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
if(args.size() != 1 || keywords.size() != 0) {
|
if(args.size() != 1 || keywords.size() != 0) {
|
||||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||||
throw boost::python::argument_error();
|
throw boost::python::error_already_set();
|
||||||
}
|
}
|
||||||
const world& w = from_python(args[0].get(), type<const world&>());
|
const world& w = from_python(args[0].get(), type<const world&>());
|
||||||
ref mydict = getattr(args[0], "__dict__");
|
ref mydict = getattr(args[0], "__dict__");
|
||||||
@@ -122,7 +122,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
if(args.size() != 2 || keywords.size() != 0) {
|
if(args.size() != 2 || keywords.size() != 0) {
|
||||||
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
|
||||||
throw boost::python::argument_error();
|
throw boost::python::error_already_set();
|
||||||
}
|
}
|
||||||
world& w = from_python(args[0].get(), type<world&>());
|
world& w = from_python(args[0].get(), type<world&>());
|
||||||
ref mydict = getattr(args[0], "__dict__");
|
ref mydict = getattr(args[0], "__dict__");
|
||||||
|
|||||||
87
example/richcmp1.cpp
Normal file
87
example/richcmp1.cpp
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter
|
||||||
|
// This example shows how to use rich comparisons for a vector type.
|
||||||
|
// It also shows how to template the entire wrapping of a std::vector.
|
||||||
|
// See vector_wrapper.h.
|
||||||
|
|
||||||
|
#include <boost/python/class_builder.hpp>
|
||||||
|
#include "vector_wrapper.h"
|
||||||
|
|
||||||
|
namespace vects {
|
||||||
|
|
||||||
|
struct dvect : public std::vector<double>
|
||||||
|
{
|
||||||
|
dvect() : std::vector<double>() {}
|
||||||
|
dvect(size_t n) : std::vector<double>(n) {}
|
||||||
|
dvect(boost::python::tuple tuple) : std::vector<double>(tuple.size())
|
||||||
|
{
|
||||||
|
std::vector<double>::iterator v_it = begin();
|
||||||
|
for (std::size_t i = 0; i < tuple.size(); i++)
|
||||||
|
v_it[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(),
|
||||||
|
boost::python::type<double>());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::python::tuple as_tuple() const
|
||||||
|
{
|
||||||
|
boost::python::tuple t(size());
|
||||||
|
for (std::size_t i = 0; i < size(); i++)
|
||||||
|
t.set_item(i,
|
||||||
|
boost::python::ref(BOOST_PYTHON_CONVERSION::to_python((*this)[i])));
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
# define DVECT_BINARY_OPERATORS(oper) \
|
||||||
|
friend std::vector<bool> \
|
||||||
|
operator##oper(const dvect& lhs, const dvect& rhs) \
|
||||||
|
{ \
|
||||||
|
if (lhs.size() != rhs.size()) { \
|
||||||
|
PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \
|
||||||
|
throw boost::python::error_already_set(); \
|
||||||
|
} \
|
||||||
|
std::vector<bool> result(lhs.size()); \
|
||||||
|
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||||
|
result[i] = (lhs[i] ##oper rhs[i]); \
|
||||||
|
} \
|
||||||
|
return result; \
|
||||||
|
}
|
||||||
|
DVECT_BINARY_OPERATORS(<)
|
||||||
|
DVECT_BINARY_OPERATORS(<=)
|
||||||
|
DVECT_BINARY_OPERATORS(==)
|
||||||
|
DVECT_BINARY_OPERATORS(!=)
|
||||||
|
DVECT_BINARY_OPERATORS(>)
|
||||||
|
DVECT_BINARY_OPERATORS(>=)
|
||||||
|
# undef VECTOR_BINARY_OPERATORS
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace <anonymous>
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void init_module(boost::python::module_builder& this_module)
|
||||||
|
{
|
||||||
|
(void) example::wrap_vector(this_module, "vector_of_bool", bool());
|
||||||
|
|
||||||
|
boost::python::class_builder<vects::dvect> py_dvect(this_module, "dvect");
|
||||||
|
|
||||||
|
py_dvect.def(boost::python::constructor<boost::python::tuple>());
|
||||||
|
py_dvect.def(&vects::dvect::as_tuple, "as_tuple");
|
||||||
|
|
||||||
|
const long
|
||||||
|
comp_operators = ( boost::python::op_lt | boost::python::op_le
|
||||||
|
| boost::python::op_eq | boost::python::op_ne
|
||||||
|
| boost::python::op_gt | boost::python::op_ge);
|
||||||
|
py_dvect.def(boost::python::operators<comp_operators>());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace <anonymous>
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE_INIT(richcmp1)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
boost::python::module_builder this_module("richcmp1");
|
||||||
|
// The actual work is done in a separate function in order
|
||||||
|
// to suppress a bogus VC60 warning.
|
||||||
|
init_module(this_module);
|
||||||
|
}
|
||||||
|
catch (...) { boost::python::handle_exception(); }
|
||||||
|
}
|
||||||
65
example/richcmp2.cpp
Normal file
65
example/richcmp2.cpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
// Example by Ralf W. Grosse-Kunstleve
|
||||||
|
// This example shows how to use rich comparisons for a type that
|
||||||
|
// does not support all six operators (<, <=, ==, !=, >, >=).
|
||||||
|
// To keep the example simple, we are using a "code" type does
|
||||||
|
// not really require rich comparisons. __cmp__ would be sufficient.
|
||||||
|
// However, with a more complicated type the main point of this
|
||||||
|
// example would be in danger of getting lost.
|
||||||
|
|
||||||
|
#include <boost/python/class_builder.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// suppose operator< and operator> are not meaningful for code
|
||||||
|
class code {
|
||||||
|
public:
|
||||||
|
code(int c = 0) : m_code(c) {}
|
||||||
|
inline friend bool operator==(const code& lhs, const code& rhs) {
|
||||||
|
return lhs.m_code == rhs.m_code;
|
||||||
|
}
|
||||||
|
inline friend bool operator!=(const code& lhs, const code& rhs) {
|
||||||
|
return lhs.m_code != rhs.m_code;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int m_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if PYTHON_API_VERSION >= 1010
|
||||||
|
boost::python::ref
|
||||||
|
NotImplemented(const code&, const code&) {
|
||||||
|
return
|
||||||
|
boost::python::ref(Py_NotImplemented, boost::python::ref::increment_count);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void init_module(boost::python::module_builder& this_module)
|
||||||
|
{
|
||||||
|
boost::python::class_builder<code> py_code(this_module, "code");
|
||||||
|
|
||||||
|
py_code.def(boost::python::constructor<>());
|
||||||
|
py_code.def(boost::python::constructor<int>());
|
||||||
|
py_code.def(boost::python::operators<( boost::python::op_eq
|
||||||
|
| boost::python::op_ne)>());
|
||||||
|
#if PYTHON_API_VERSION >= 1010
|
||||||
|
py_code.def(NotImplemented, "__lt__");
|
||||||
|
py_code.def(NotImplemented, "__le__");
|
||||||
|
py_code.def(NotImplemented, "__gt__");
|
||||||
|
py_code.def(NotImplemented, "__ge__");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace <anonymous>
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE_INIT(richcmp2)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
boost::python::module_builder this_module("richcmp2");
|
||||||
|
// The actual work is done in a separate function in order
|
||||||
|
// to suppress a bogus VC60 warning.
|
||||||
|
init_module(this_module);
|
||||||
|
}
|
||||||
|
catch (...) { boost::python::handle_exception(); }
|
||||||
|
}
|
||||||
178
example/richcmp3.cpp
Normal file
178
example/richcmp3.cpp
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
// Example by Ralf W. Grosse-Kunstleve & Nicholas K. Sauter.
|
||||||
|
// Comprehensive operator overloading for two vector types and scalars.
|
||||||
|
|
||||||
|
#include <boost/python/class_builder.hpp>
|
||||||
|
#include "vector_wrapper.h"
|
||||||
|
#include "dvect.h"
|
||||||
|
#include "ivect.h"
|
||||||
|
|
||||||
|
#define VECT_VECT_OPERATORS(result_type, vect_type1, oper, vect_type2) \
|
||||||
|
namespace vects { \
|
||||||
|
result_type \
|
||||||
|
operator##oper (const vect_type1& lhs, const vect_type2& rhs) { \
|
||||||
|
if (lhs.size() != rhs.size()) { \
|
||||||
|
PyErr_SetString(PyExc_ValueError, "vectors have different sizes"); \
|
||||||
|
throw boost::python::error_already_set(); \
|
||||||
|
} \
|
||||||
|
result_type result(lhs.size()); \
|
||||||
|
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||||
|
result[i] = (lhs[i] ##oper rhs[i]); \
|
||||||
|
} \
|
||||||
|
return result; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define VECT_SCALAR_OPERATORS(result_type, vect_type, oper, scalar_type) \
|
||||||
|
namespace vects { \
|
||||||
|
result_type \
|
||||||
|
operator##oper (const vect_type& lhs, const scalar_type& rhs) { \
|
||||||
|
result_type result(lhs.size()); \
|
||||||
|
for (std::size_t i=0; i<lhs.size(); i++) { \
|
||||||
|
result[i] = (lhs[i] ##oper rhs ); \
|
||||||
|
} \
|
||||||
|
return result; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCALAR_VECT_OPERATORS(result_type, scalar_type, oper, vect_type) \
|
||||||
|
namespace vects { \
|
||||||
|
result_type \
|
||||||
|
operator##oper (const scalar_type& lhs, const vect_type& rhs) { \
|
||||||
|
result_type result(rhs.size()); \
|
||||||
|
for (std::size_t i=0; i<rhs.size(); i++) { \
|
||||||
|
result[i] = (lhs ##oper rhs[i]); \
|
||||||
|
} \
|
||||||
|
return result; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MATH_VECT_VECT_OPERATORS(result_type, vect_type1, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(result_type, vect_type1, +, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(result_type, vect_type1, -, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(result_type, vect_type1, *, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(result_type, vect_type1, /, vect_type2)
|
||||||
|
|
||||||
|
#define COMP_VECT_VECT_OPERATORS(vect_type1, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, <, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, <=, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, ==, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, !=, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, >, vect_type2) \
|
||||||
|
VECT_VECT_OPERATORS(std::vector<bool>, vect_type1, >=, vect_type2)
|
||||||
|
|
||||||
|
#define MATH_VECT_SCALAR_OPERATORS(result_type, vect_type, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(result_type, vect_type, +, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(result_type, vect_type, -, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(result_type, vect_type, *, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(result_type, vect_type, /, scalar_type)
|
||||||
|
|
||||||
|
#define COMP_VECT_SCALAR_OPERATORS(vect_type, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, <, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, <=, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, ==, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, !=, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, >, scalar_type) \
|
||||||
|
VECT_SCALAR_OPERATORS(std::vector<bool>, vect_type, >=, scalar_type)
|
||||||
|
|
||||||
|
#define MATH_SCALAR_VECT_OPERATORS(result_type, scalar_type, vect_type) \
|
||||||
|
SCALAR_VECT_OPERATORS(result_type, scalar_type, +, vect_type) \
|
||||||
|
SCALAR_VECT_OPERATORS(result_type, scalar_type, -, vect_type) \
|
||||||
|
SCALAR_VECT_OPERATORS(result_type, scalar_type, *, vect_type) \
|
||||||
|
SCALAR_VECT_OPERATORS(result_type, scalar_type, /, vect_type)
|
||||||
|
|
||||||
|
MATH_VECT_VECT_OPERATORS(dvect, dvect, dvect)
|
||||||
|
COMP_VECT_VECT_OPERATORS( dvect, dvect)
|
||||||
|
MATH_VECT_SCALAR_OPERATORS(dvect, dvect, double)
|
||||||
|
COMP_VECT_SCALAR_OPERATORS( dvect, double)
|
||||||
|
MATH_SCALAR_VECT_OPERATORS(dvect, double, dvect)
|
||||||
|
// comparison operators not needed since Python uses reflection
|
||||||
|
|
||||||
|
MATH_VECT_VECT_OPERATORS(ivect, ivect, ivect)
|
||||||
|
COMP_VECT_VECT_OPERATORS( ivect, ivect)
|
||||||
|
MATH_VECT_SCALAR_OPERATORS(ivect, ivect, int)
|
||||||
|
COMP_VECT_SCALAR_OPERATORS( ivect, int)
|
||||||
|
MATH_SCALAR_VECT_OPERATORS(ivect, int, ivect)
|
||||||
|
// comparison operators not needed since Python uses reflection
|
||||||
|
|
||||||
|
MATH_VECT_VECT_OPERATORS(dvect, dvect, ivect)
|
||||||
|
COMP_VECT_VECT_OPERATORS( dvect, ivect)
|
||||||
|
MATH_VECT_VECT_OPERATORS(dvect, ivect, dvect)
|
||||||
|
COMP_VECT_VECT_OPERATORS( ivect, dvect)
|
||||||
|
|
||||||
|
#undef VECT_VECT_OPERATORS
|
||||||
|
#undef SCALAR_VECT_OPERATORS
|
||||||
|
#undef VECT_SCALAR_OPERATORS
|
||||||
|
#undef MATH_VECT_VECT_OPERATORS
|
||||||
|
#undef COMP_VECT_VECT_OPERATORS
|
||||||
|
#undef MATH_VECT_SCALAR_OPERATORS
|
||||||
|
#undef COMP_VECT_SCALAR_OPERATORS
|
||||||
|
#undef MATH_SCALAR_VECT_OPERATORS
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void init_module(boost::python::module_builder& this_module)
|
||||||
|
{
|
||||||
|
(void) example::wrap_vector(this_module, "vector_of_bool", bool());
|
||||||
|
|
||||||
|
const long
|
||||||
|
math_operators ( boost::python::op_mul | boost::python::op_add
|
||||||
|
| boost::python::op_div | boost::python::op_sub);
|
||||||
|
const long
|
||||||
|
comp_operators = ( boost::python::op_lt | boost::python::op_le
|
||||||
|
| boost::python::op_eq | boost::python::op_ne
|
||||||
|
| boost::python::op_gt | boost::python::op_ge);
|
||||||
|
|
||||||
|
boost::python::class_builder<vects::dvect>
|
||||||
|
dvect_class(this_module, "dvect");
|
||||||
|
boost::python::class_builder<vects::ivect>
|
||||||
|
ivect_class(this_module, "ivect");
|
||||||
|
|
||||||
|
dvect_class.def(boost::python::constructor<boost::python::tuple>());
|
||||||
|
dvect_class.def(&vects::dvect::as_tuple,"as_tuple");
|
||||||
|
|
||||||
|
dvect_class.def(boost::python::operators<math_operators>());
|
||||||
|
dvect_class.def(boost::python::operators<math_operators>(),
|
||||||
|
boost::python::right_operand<double>() );
|
||||||
|
dvect_class.def(boost::python::operators<math_operators>(),
|
||||||
|
boost::python::left_operand<double>() );
|
||||||
|
dvect_class.def(boost::python::operators<math_operators>(),
|
||||||
|
boost::python::right_operand<vects::ivect>() );
|
||||||
|
|
||||||
|
dvect_class.def(boost::python::operators<comp_operators>());
|
||||||
|
dvect_class.def(boost::python::operators<comp_operators>(),
|
||||||
|
boost::python::right_operand<double>() );
|
||||||
|
// left_operand not needed since Python uses reflection
|
||||||
|
dvect_class.def(boost::python::operators<comp_operators>(),
|
||||||
|
boost::python::right_operand<vects::ivect>() );
|
||||||
|
|
||||||
|
ivect_class.def(boost::python::constructor<boost::python::tuple>());
|
||||||
|
ivect_class.def(&vects::ivect::as_tuple,"as_tuple");
|
||||||
|
|
||||||
|
ivect_class.def(boost::python::operators<math_operators>());
|
||||||
|
ivect_class.def(boost::python::operators<math_operators>(),
|
||||||
|
boost::python::right_operand<int>() );
|
||||||
|
ivect_class.def(boost::python::operators<math_operators>(),
|
||||||
|
boost::python::left_operand<int>() );
|
||||||
|
ivect_class.def(boost::python::operators<math_operators>(),
|
||||||
|
boost::python::right_operand<vects::dvect>() );
|
||||||
|
|
||||||
|
ivect_class.def(boost::python::operators<comp_operators>());
|
||||||
|
ivect_class.def(boost::python::operators<comp_operators>(),
|
||||||
|
boost::python::right_operand<int>() );
|
||||||
|
// left_operand not needed since Python uses reflection
|
||||||
|
ivect_class.def(boost::python::operators<comp_operators>(),
|
||||||
|
boost::python::right_operand<vects::dvect>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace <anonymous>
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE_INIT(richcmp3)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
boost::python::module_builder this_module("richcmp3");
|
||||||
|
// The actual work is done in a separate function in order
|
||||||
|
// to suppress a bogus VC60 warning.
|
||||||
|
init_module(this_module);
|
||||||
|
}
|
||||||
|
catch (...) { boost::python::handle_exception(); }
|
||||||
|
}
|
||||||
@@ -137,4 +137,4 @@ def run(args = None):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
sys.exit(run())
|
sys.exit(run()[0])
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ r'''>>> import pickle3
|
|||||||
... wd.z = 3. * number
|
... wd.z = 3. * number
|
||||||
... pstr = pickle.dumps(wd)
|
... pstr = pickle.dumps(wd)
|
||||||
... wl = pickle.loads(pstr)
|
... wl = pickle.loads(pstr)
|
||||||
... print wd.greet(), wd.get_secret_number(), wd.__dict__
|
... print wd.greet(), wd.get_secret_number(), wd.x, wd.y, wd.z
|
||||||
... print wl.greet(), wl.get_secret_number(), wl.__dict__
|
... print wl.greet(), wl.get_secret_number(), wl.x, wl.y, wl.z
|
||||||
Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'}
|
Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0
|
||||||
Hello from California! 24 {'z': 72.0, 'x': 48, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyy'}
|
Hello from California! 24 48 yyyyyyyyyyyyyyyyyyyyyyyy 72.0
|
||||||
Hello from California! 42 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'}
|
Hello from California! 42 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0
|
||||||
Hello from California! 0 {'z': 126.0, 'x': 84, 'y': 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'}
|
Hello from California! 0 84 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 126.0
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def run(args = None):
|
def run(args = None):
|
||||||
|
|||||||
40
example/test_richcmp1.py
Normal file
40
example/test_richcmp1.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
r'''>>> import richcmp1
|
||||||
|
>>> d1 = richcmp1.dvect((0, 1, 3, 3, 6, 7))
|
||||||
|
>>> d2 = richcmp1.dvect((1, 2, 3, 4, 5, 6))
|
||||||
|
>>> print d1.as_tuple()
|
||||||
|
(0.0, 1.0, 3.0, 3.0, 6.0, 7.0)
|
||||||
|
>>> print d2.as_tuple()
|
||||||
|
(1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
|
||||||
|
>>> print (d1 < d2).as_tuple()
|
||||||
|
(1, 1, 0, 1, 0, 0)
|
||||||
|
>>> print (d1 <= d2).as_tuple()
|
||||||
|
(1, 1, 1, 1, 0, 0)
|
||||||
|
>>> print (d1 == d2).as_tuple()
|
||||||
|
(0, 0, 1, 0, 0, 0)
|
||||||
|
>>> print (d1 != d2).as_tuple()
|
||||||
|
(1, 1, 0, 1, 1, 1)
|
||||||
|
>>> print (d1 > d2).as_tuple()
|
||||||
|
(0, 0, 0, 0, 1, 1)
|
||||||
|
>>> print (d1 >= d2).as_tuple()
|
||||||
|
(0, 0, 1, 0, 1, 1)
|
||||||
|
>>> try: d1 == richcmp1.dvect((1, 2, 3, 4, 5))
|
||||||
|
... except ValueError, e: print str(e)
|
||||||
|
...
|
||||||
|
vectors have different sizes
|
||||||
|
'''
|
||||||
|
|
||||||
|
def run(args = None):
|
||||||
|
if args is not None:
|
||||||
|
import sys
|
||||||
|
sys.argv = args
|
||||||
|
import doctest, test_richcmp1
|
||||||
|
return doctest.testmod(test_richcmp1)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
if ( hasattr(sys, 'version_info')
|
||||||
|
and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1)
|
||||||
|
or sys.version_info[0] > 2)):
|
||||||
|
sys.exit(run()[0])
|
||||||
|
else:
|
||||||
|
print "Python version 2.1 or higher required. Test skipped."
|
||||||
41
example/test_richcmp2.py
Normal file
41
example/test_richcmp2.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
r'''>>> import richcmp2
|
||||||
|
>>> c1 = richcmp2.code(1)
|
||||||
|
>>> c2 = richcmp2.code(2)
|
||||||
|
>>> c3 = richcmp2.code(2)
|
||||||
|
>>> print c1 == c2
|
||||||
|
0
|
||||||
|
>>> print c1 != c2
|
||||||
|
1
|
||||||
|
>>> print c2 == c3
|
||||||
|
1
|
||||||
|
>>> print c2 != c3
|
||||||
|
0
|
||||||
|
>>> print c1 < c2
|
||||||
|
1
|
||||||
|
>>> print c1 <= c2
|
||||||
|
1
|
||||||
|
>>> print c1 == c2
|
||||||
|
0
|
||||||
|
>>> print c1 != c2
|
||||||
|
1
|
||||||
|
>>> print c1 > c2
|
||||||
|
0
|
||||||
|
>>> print c1 >= c2
|
||||||
|
0
|
||||||
|
'''
|
||||||
|
|
||||||
|
def run(args = None):
|
||||||
|
if args is not None:
|
||||||
|
import sys
|
||||||
|
sys.argv = args
|
||||||
|
import doctest, test_richcmp1
|
||||||
|
return doctest.testmod(test_richcmp1)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
if ( hasattr(sys, 'version_info')
|
||||||
|
and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1)
|
||||||
|
or sys.version_info[0] > 2)):
|
||||||
|
sys.exit(run()[0])
|
||||||
|
else:
|
||||||
|
print "Python version 2.1 or higher required. Test skipped."
|
||||||
77
example/test_richcmp3.py
Normal file
77
example/test_richcmp3.py
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
r'''>>> import richcmp3
|
||||||
|
>>>
|
||||||
|
>>> iv = richcmp3.ivect((1,2,3,4,5))
|
||||||
|
>>> print iv.as_tuple()
|
||||||
|
(1, 2, 3, 4, 5)
|
||||||
|
>>> dv = richcmp3.dvect((2,-2,3,8,-5))
|
||||||
|
>>> print dv.as_tuple()
|
||||||
|
(2.0, -2.0, 3.0, 8.0, -5.0)
|
||||||
|
>>>
|
||||||
|
>>> print (iv+dv).as_tuple()
|
||||||
|
(3.0, 0.0, 6.0, 12.0, 0.0)
|
||||||
|
>>> print (iv+3).as_tuple()
|
||||||
|
(4, 5, 6, 7, 8)
|
||||||
|
>>> print (3+iv).as_tuple()
|
||||||
|
(4, 5, 6, 7, 8)
|
||||||
|
>>>
|
||||||
|
>>> print "vect vs. vect Comparisons:"
|
||||||
|
vect vs. vect Comparisons:
|
||||||
|
>>> print (iv < dv).as_tuple()
|
||||||
|
(1, 0, 0, 1, 0)
|
||||||
|
>>> print (iv <= dv).as_tuple()
|
||||||
|
(1, 0, 1, 1, 0)
|
||||||
|
>>> print (iv == dv).as_tuple()
|
||||||
|
(0, 0, 1, 0, 0)
|
||||||
|
>>> print (iv != dv).as_tuple()
|
||||||
|
(1, 1, 0, 1, 1)
|
||||||
|
>>> print (iv > dv).as_tuple()
|
||||||
|
(0, 1, 0, 0, 1)
|
||||||
|
>>> print (iv >= dv).as_tuple()
|
||||||
|
(0, 1, 1, 0, 1)
|
||||||
|
>>>
|
||||||
|
>>> print "vect vs. scalar Comparisons:"
|
||||||
|
vect vs. scalar Comparisons:
|
||||||
|
>>> print (iv < 3).as_tuple()
|
||||||
|
(1, 1, 0, 0, 0)
|
||||||
|
>>> print (iv <= 3).as_tuple()
|
||||||
|
(1, 1, 1, 0, 0)
|
||||||
|
>>> print (iv == 3).as_tuple()
|
||||||
|
(0, 0, 1, 0, 0)
|
||||||
|
>>> print (iv != 3).as_tuple()
|
||||||
|
(1, 1, 0, 1, 1)
|
||||||
|
>>> print (iv > 3).as_tuple()
|
||||||
|
(0, 0, 0, 1, 1)
|
||||||
|
>>> print (iv >= 3).as_tuple()
|
||||||
|
(0, 0, 1, 1, 1)
|
||||||
|
>>>
|
||||||
|
>>> print "scalar vs. vect Comparisons:"
|
||||||
|
scalar vs. vect Comparisons:
|
||||||
|
>>> print (3 < iv).as_tuple()
|
||||||
|
(0, 0, 0, 1, 1)
|
||||||
|
>>> print (3 <= iv).as_tuple()
|
||||||
|
(0, 0, 1, 1, 1)
|
||||||
|
>>> print (3 == iv).as_tuple()
|
||||||
|
(0, 0, 1, 0, 0)
|
||||||
|
>>> print (3 != iv).as_tuple()
|
||||||
|
(1, 1, 0, 1, 1)
|
||||||
|
>>> print (3 > iv).as_tuple()
|
||||||
|
(1, 1, 0, 0, 0)
|
||||||
|
>>> print (3 >= iv).as_tuple()
|
||||||
|
(1, 1, 1, 0, 0)
|
||||||
|
'''
|
||||||
|
|
||||||
|
def run(args = None):
|
||||||
|
if args is not None:
|
||||||
|
import sys
|
||||||
|
sys.argv = args
|
||||||
|
import doctest, test_richcmp3
|
||||||
|
return doctest.testmod(test_richcmp3)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
if ( hasattr(sys, 'version_info')
|
||||||
|
and ( (sys.version_info[0] == 2 and sys.version_info[1] >= 1)
|
||||||
|
or sys.version_info[0] > 2)):
|
||||||
|
sys.exit(run()[0])
|
||||||
|
else:
|
||||||
|
print "Python version 2.1 or higher required. Test skipped."
|
||||||
@@ -87,12 +87,18 @@ if (__name__ == "__main__"):
|
|||||||
import sys, string
|
import sys, string
|
||||||
broken_auto_ptr = 0
|
broken_auto_ptr = 0
|
||||||
n = 1
|
n = 1
|
||||||
if (len(sys.argv) > 1):
|
|
||||||
if (sys.argv[1] == "--broken-auto-ptr"):
|
if len(sys.argv) > 1:
|
||||||
broken_auto_ptr = 1
|
argv = []
|
||||||
if (len(sys.argv) > 2):
|
|
||||||
n = string.atoi(sys.argv[2])
|
for x in sys.argv:
|
||||||
else:
|
if x != '--broken-auto-ptr':
|
||||||
n = string.atoi(sys.argv[1])
|
argv.append(x)
|
||||||
|
broken_auto_ptr = argv != sys.argv
|
||||||
|
sys.argv = argv
|
||||||
|
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
n = string.atoi(sys.argv[1])
|
||||||
|
|
||||||
for i in xrange(n):
|
for i in xrange(n):
|
||||||
f(broken_auto_ptr)
|
f(broken_auto_ptr)
|
||||||
|
|||||||
@@ -87,12 +87,18 @@ if (__name__ == "__main__"):
|
|||||||
import sys, string
|
import sys, string
|
||||||
broken_auto_ptr = 0
|
broken_auto_ptr = 0
|
||||||
n = 1
|
n = 1
|
||||||
if (len(sys.argv) > 1):
|
|
||||||
if (sys.argv[1] == "--broken-auto-ptr"):
|
if len(sys.argv) > 1:
|
||||||
broken_auto_ptr = 1
|
argv = []
|
||||||
if (len(sys.argv) > 2):
|
|
||||||
n = string.atoi(sys.argv[2])
|
for x in sys.argv:
|
||||||
else:
|
if x != '--broken-auto-ptr':
|
||||||
n = string.atoi(sys.argv[1])
|
argv.append(x)
|
||||||
|
broken_auto_ptr = argv != sys.argv
|
||||||
|
sys.argv = argv
|
||||||
|
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
n = string.atoi(sys.argv[1])
|
||||||
|
|
||||||
for i in xrange(n):
|
for i in xrange(n):
|
||||||
f(broken_auto_ptr)
|
f(broken_auto_ptr)
|
||||||
|
|||||||
117
example/vector_wrapper.h
Normal file
117
example/vector_wrapper.h
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
// Based on wrapVector.hh by Mike Owen and Jeff Johnson.
|
||||||
|
// http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/spheral/src/src/BPLWraps/CXXWraps/
|
||||||
|
|
||||||
|
#ifndef BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H
|
||||||
|
#define BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H
|
||||||
|
|
||||||
|
#include <boost/python/class_builder.hpp>
|
||||||
|
|
||||||
|
namespace example {
|
||||||
|
|
||||||
|
// A wrapper is used to define additional constructors. This wrapper
|
||||||
|
// is templated on the template parameter for its corresponding vector.
|
||||||
|
template <typename T>
|
||||||
|
struct vector_wrapper: std::vector<T>
|
||||||
|
{
|
||||||
|
// Tell the compiler how to convert a base class object to
|
||||||
|
// this wrapper object.
|
||||||
|
vector_wrapper(PyObject*,
|
||||||
|
const std::vector<T>& vec):
|
||||||
|
std::vector<T>(vec) {}
|
||||||
|
|
||||||
|
vector_wrapper(PyObject* self):
|
||||||
|
std::vector<T>() {}
|
||||||
|
|
||||||
|
vector_wrapper(PyObject* self,
|
||||||
|
std::size_t n):
|
||||||
|
std::vector<T>(n) {}
|
||||||
|
|
||||||
|
vector_wrapper(PyObject* self,
|
||||||
|
boost::python::tuple tuple):
|
||||||
|
std::vector<T>(tuple.size())
|
||||||
|
{
|
||||||
|
std::vector<T>::iterator vec = begin();
|
||||||
|
for (std::size_t i = 0; i < tuple.size(); i++)
|
||||||
|
vec[i] = BOOST_PYTHON_CONVERSION::from_python(tuple[i].get(),
|
||||||
|
boost::python::type<T>());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void raise_vector_IndexError() {
|
||||||
|
PyErr_SetString(PyExc_IndexError, "vector index out of range");
|
||||||
|
throw boost::python::error_already_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct vector_access
|
||||||
|
{
|
||||||
|
static
|
||||||
|
T
|
||||||
|
getitem(const std::vector<T>& vec,
|
||||||
|
std::size_t key)
|
||||||
|
{
|
||||||
|
if (key >= vec.size()) raise_vector_IndexError();
|
||||||
|
return vec[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
setitem(std::vector<T>& vec,
|
||||||
|
std::size_t key,
|
||||||
|
const T &value)
|
||||||
|
{
|
||||||
|
if (key >= vec.size()) raise_vector_IndexError();
|
||||||
|
vec[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
delitem(std::vector<T>& vec,
|
||||||
|
std::size_t key)
|
||||||
|
{
|
||||||
|
if (key >= vec.size()) raise_vector_IndexError();
|
||||||
|
vec.erase(vec.begin() + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert vector<T> to a regular Python tuple.
|
||||||
|
static
|
||||||
|
boost::python::tuple
|
||||||
|
as_tuple(const std::vector<T>& vec)
|
||||||
|
{
|
||||||
|
// Create a python type of size vec.size().
|
||||||
|
boost::python::tuple t(vec.size());
|
||||||
|
for (std::size_t i = 0; i < vec.size(); i++) {
|
||||||
|
t.set_item(i,
|
||||||
|
boost::python::ref(BOOST_PYTHON_CONVERSION::to_python(vec[i])));
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This function will build a vector<T> and add it to the given
|
||||||
|
// module with the given name.
|
||||||
|
template <typename T>
|
||||||
|
boost::python::class_builder<std::vector<T>, vector_wrapper<T> >
|
||||||
|
wrap_vector(boost::python::module_builder& module,
|
||||||
|
const std::string& vector_name,
|
||||||
|
const T&)
|
||||||
|
{
|
||||||
|
// Add the vector<T> to the module.
|
||||||
|
boost::python::class_builder<std::vector<T>, vector_wrapper<T> >
|
||||||
|
py_vector(module, vector_name.c_str());
|
||||||
|
|
||||||
|
// Define constructors and methods for the vector<T>.
|
||||||
|
py_vector.def(boost::python::constructor<>());
|
||||||
|
py_vector.def(boost::python::constructor<std::size_t>());
|
||||||
|
py_vector.def(boost::python::constructor<boost::python::tuple>());
|
||||||
|
py_vector.def(&std::vector<T>::size, "__len__");
|
||||||
|
py_vector.def(&vector_access<T>::getitem, "__getitem__");
|
||||||
|
py_vector.def(&vector_access<T>::setitem, "__setitem__");
|
||||||
|
py_vector.def(&vector_access<T>::delitem, "__delitem__");
|
||||||
|
py_vector.def(&vector_access<T>::as_tuple, "as_tuple");
|
||||||
|
|
||||||
|
return py_vector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_PYTHON_EXAMPLE_VECTOR_WRAPPER_H
|
||||||
@@ -70,6 +70,14 @@ class instance
|
|||||||
PyObject* oct();
|
PyObject* oct();
|
||||||
PyObject* hex();
|
PyObject* hex();
|
||||||
|
|
||||||
|
// Rich comparisons
|
||||||
|
PyObject* lt(PyObject* other);
|
||||||
|
PyObject* le(PyObject* other);
|
||||||
|
PyObject* eq(PyObject* other);
|
||||||
|
PyObject* ne(PyObject* other);
|
||||||
|
PyObject* gt(PyObject* other);
|
||||||
|
PyObject* ge(PyObject* other);
|
||||||
|
|
||||||
private: // noncopyable, without the size bloat
|
private: // noncopyable, without the size bloat
|
||||||
instance(const instance&);
|
instance(const instance&);
|
||||||
void operator=(const instance&);
|
void operator=(const instance&);
|
||||||
@@ -169,6 +177,14 @@ class class_t
|
|||||||
PyObject* instance_number_float(PyObject*) const;
|
PyObject* instance_number_float(PyObject*) const;
|
||||||
PyObject* instance_number_oct(PyObject*) const;
|
PyObject* instance_number_oct(PyObject*) const;
|
||||||
PyObject* instance_number_hex(PyObject*) const;
|
PyObject* instance_number_hex(PyObject*) const;
|
||||||
|
|
||||||
|
private: // Implement rich comparisons
|
||||||
|
PyObject* instance_lt(PyObject*, PyObject*) const;
|
||||||
|
PyObject* instance_le(PyObject*, PyObject*) const;
|
||||||
|
PyObject* instance_eq(PyObject*, PyObject*) const;
|
||||||
|
PyObject* instance_ne(PyObject*, PyObject*) const;
|
||||||
|
PyObject* instance_gt(PyObject*, PyObject*) const;
|
||||||
|
PyObject* instance_ge(PyObject*, PyObject*) const;
|
||||||
|
|
||||||
private: // Miscellaneous "special" methods
|
private: // Miscellaneous "special" methods
|
||||||
PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const;
|
PyObject* instance_call(PyObject* obj, PyObject* args, PyObject* keywords) const;
|
||||||
@@ -477,6 +493,42 @@ PyObject* class_t<T>::instance_number_hex(PyObject* obj) const
|
|||||||
return downcast<T>(obj)->hex();
|
return downcast<T>(obj)->hex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PyObject* class_t<T>::instance_lt(PyObject* obj, PyObject* other) const
|
||||||
|
{
|
||||||
|
return downcast<T>(obj)->lt(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PyObject* class_t<T>::instance_le(PyObject* obj, PyObject* other) const
|
||||||
|
{
|
||||||
|
return downcast<T>(obj)->le(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PyObject* class_t<T>::instance_eq(PyObject* obj, PyObject* other) const
|
||||||
|
{
|
||||||
|
return downcast<T>(obj)->eq(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PyObject* class_t<T>::instance_ne(PyObject* obj, PyObject* other) const
|
||||||
|
{
|
||||||
|
return downcast<T>(obj)->ne(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PyObject* class_t<T>::instance_gt(PyObject* obj, PyObject* other) const
|
||||||
|
{
|
||||||
|
return downcast<T>(obj)->gt(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PyObject* class_t<T>::instance_ge(PyObject* obj, PyObject* other) const
|
||||||
|
{
|
||||||
|
return downcast<T>(obj)->ge(other);
|
||||||
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
inline dictionary& class_base::dict()
|
inline dictionary& class_base::dict()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ typedef base_object<PyTypeObject> python_type;
|
|||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// class_t template member function implementations
|
// base_object member function implementations
|
||||||
//
|
//
|
||||||
template <class python_type>
|
template <class python_type>
|
||||||
base_object<python_type>::base_object(PyTypeObject* type_obj)
|
base_object<python_type>::base_object(PyTypeObject* type_obj)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
# define BOOST_CSTD_ std
|
# define BOOST_CSTD_ std
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name()
|
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" __declspec(dllexport) void init##name()
|
||||||
#else
|
#else
|
||||||
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name()
|
# define BOOST_PYTHON_MODULE_INIT(name) extern "C" void init##name()
|
||||||
|
|||||||
@@ -616,6 +616,12 @@ class extension_class
|
|||||||
choose_op<(which & op_and)>::template args<Operand>::add(this);
|
choose_op<(which & op_and)>::template args<Operand>::add(this);
|
||||||
choose_op<(which & op_xor)>::template args<Operand>::add(this);
|
choose_op<(which & op_xor)>::template args<Operand>::add(this);
|
||||||
choose_op<(which & op_or)>::template args<Operand>::add(this);
|
choose_op<(which & op_or)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_gt)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_ge)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_lt)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_le)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_eq)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_ne)>::template args<Operand>::add(this);
|
||||||
choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
|
choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
|
||||||
choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
|
choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
|
||||||
choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
|
choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
|
||||||
@@ -645,6 +651,12 @@ class extension_class
|
|||||||
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
|
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
|
||||||
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
|
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
|
||||||
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
|
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_gt)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_ge)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_lt)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_le)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_eq)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_ne)>::template args<Left,Right>::add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <long which, class Left, class Right>
|
template <long which, class Left, class Right>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class type_object_base : public python_type
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum capability {
|
enum capability {
|
||||||
hash, call, str, getattr, setattr, compare, repr,
|
hash, call, str, getattr, setattr, compare, repr, richcompare,
|
||||||
|
|
||||||
mapping_length, mapping_subscript, mapping_ass_subscript,
|
mapping_length, mapping_subscript, mapping_ass_subscript,
|
||||||
|
|
||||||
@@ -115,6 +115,14 @@ class type_object_base : public python_type
|
|||||||
virtual PyObject* instance_number_float(PyObject*) const;
|
virtual PyObject* instance_number_float(PyObject*) const;
|
||||||
virtual PyObject* instance_number_oct(PyObject*) const;
|
virtual PyObject* instance_number_oct(PyObject*) const;
|
||||||
virtual PyObject* instance_number_hex(PyObject*) const;
|
virtual PyObject* instance_number_hex(PyObject*) const;
|
||||||
|
|
||||||
|
public: // Callbacks for rich comparisons
|
||||||
|
virtual PyObject* instance_lt(PyObject*, PyObject*) const;
|
||||||
|
virtual PyObject* instance_le(PyObject*, PyObject*) const;
|
||||||
|
virtual PyObject* instance_eq(PyObject*, PyObject*) const;
|
||||||
|
virtual PyObject* instance_ne(PyObject*, PyObject*) const;
|
||||||
|
virtual PyObject* instance_gt(PyObject*, PyObject*) const;
|
||||||
|
virtual PyObject* instance_ge(PyObject*, PyObject*) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|||||||
@@ -65,7 +65,13 @@ enum operator_id
|
|||||||
op_long = 0x20000,
|
op_long = 0x20000,
|
||||||
op_float = 0x40000,
|
op_float = 0x40000,
|
||||||
op_str = 0x80000,
|
op_str = 0x80000,
|
||||||
op_cmp = 0x100000
|
op_cmp = 0x100000,
|
||||||
|
op_gt = 0x200000,
|
||||||
|
op_ge = 0x400000,
|
||||||
|
op_lt = 0x800000,
|
||||||
|
op_le = 0x1000000,
|
||||||
|
op_eq = 0x2000000,
|
||||||
|
op_ne = 0x4000000
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wrap the operators given by "which". Usage:
|
// Wrap the operators given by "which". Usage:
|
||||||
@@ -301,6 +307,12 @@ namespace detail
|
|||||||
PY_DEFINE_BINARY_OPERATORS(and, &);
|
PY_DEFINE_BINARY_OPERATORS(and, &);
|
||||||
PY_DEFINE_BINARY_OPERATORS(xor, ^);
|
PY_DEFINE_BINARY_OPERATORS(xor, ^);
|
||||||
PY_DEFINE_BINARY_OPERATORS(or, |);
|
PY_DEFINE_BINARY_OPERATORS(or, |);
|
||||||
|
PY_DEFINE_BINARY_OPERATORS(gt, >);
|
||||||
|
PY_DEFINE_BINARY_OPERATORS(ge, >=);
|
||||||
|
PY_DEFINE_BINARY_OPERATORS(lt, <);
|
||||||
|
PY_DEFINE_BINARY_OPERATORS(le, <=);
|
||||||
|
PY_DEFINE_BINARY_OPERATORS(eq, ==);
|
||||||
|
PY_DEFINE_BINARY_OPERATORS(ne, !=);
|
||||||
|
|
||||||
PY_DEFINE_UNARY_OPERATORS(neg, -);
|
PY_DEFINE_UNARY_OPERATORS(neg, -);
|
||||||
PY_DEFINE_UNARY_OPERATORS(pos, +);
|
PY_DEFINE_UNARY_OPERATORS(pos, +);
|
||||||
|
|||||||
@@ -736,6 +736,36 @@ PyObject* instance::hex()
|
|||||||
return callback<PyObject*>::call_method(this, "__hex__");
|
return callback<PyObject*>::call_method(this, "__hex__");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* instance::lt(PyObject* other)
|
||||||
|
{
|
||||||
|
return callback<PyObject*>::call_method(this, "__lt__", other);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* instance::le(PyObject* other)
|
||||||
|
{
|
||||||
|
return callback<PyObject*>::call_method(this, "__le__", other);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* instance::eq(PyObject* other)
|
||||||
|
{
|
||||||
|
return callback<PyObject*>::call_method(this, "__eq__", other);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* instance::ne(PyObject* other)
|
||||||
|
{
|
||||||
|
return callback<PyObject*>::call_method(this, "__ne__", other);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* instance::gt(PyObject* other)
|
||||||
|
{
|
||||||
|
return callback<PyObject*>::call_method(this, "__gt__", other);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* instance::ge(PyObject* other)
|
||||||
|
{
|
||||||
|
return callback<PyObject*>::call_method(this, "__ge__", other);
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct named_capability
|
struct named_capability
|
||||||
{
|
{
|
||||||
@@ -747,6 +777,12 @@ namespace {
|
|||||||
{
|
{
|
||||||
{ "__hash__", detail::type_object_base::hash },
|
{ "__hash__", detail::type_object_base::hash },
|
||||||
{ "__cmp__", detail::type_object_base::compare },
|
{ "__cmp__", detail::type_object_base::compare },
|
||||||
|
{ "__gt__", detail::type_object_base::richcompare },
|
||||||
|
{ "__ge__", detail::type_object_base::richcompare },
|
||||||
|
{ "__lt__", detail::type_object_base::richcompare },
|
||||||
|
{ "__le__", detail::type_object_base::richcompare },
|
||||||
|
{ "__eq__", detail::type_object_base::richcompare },
|
||||||
|
{ "__ne__", detail::type_object_base::richcompare },
|
||||||
{ "__repr__", detail::type_object_base::repr },
|
{ "__repr__", detail::type_object_base::repr },
|
||||||
{ "__str__", detail::type_object_base::str },
|
{ "__str__", detail::type_object_base::str },
|
||||||
{ "__call__", detail::type_object_base::call },
|
{ "__call__", detail::type_object_base::call },
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ def gen_extclass(args):
|
|||||||
// gen_extclass.python
|
// gen_extclass.python
|
||||||
|
|
||||||
// Revision History:
|
// Revision History:
|
||||||
|
// 17 Apr 01 Comment added with reference to cross_module.hpp (R.W. Grosse-Kunstleve)
|
||||||
// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted
|
// 05 Mar 01 Fixed a bug which prevented auto_ptr values from being converted
|
||||||
// to_python (Dave Abrahams)
|
// to_python (Dave Abrahams)
|
||||||
|
|
||||||
@@ -171,6 +172,14 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
|
|||||||
// and U. T is the class the user really intends to wrap. U is a class derived
|
// and U. T is the class the user really intends to wrap. U is a class derived
|
||||||
// from T with some virtual function overriding boilerplate, or if there are no
|
// from T with some virtual function overriding boilerplate, or if there are no
|
||||||
// virtual functions, U = held_instance<T>.
|
// virtual functions, U = held_instance<T>.
|
||||||
|
//
|
||||||
|
// A look-alike of this class in root/boost/python/cross_module.hpp
|
||||||
|
// is used for the implementation of the cross-module support
|
||||||
|
// (export_converters and import_converters). If from_python
|
||||||
|
// and to_python converters are added or removed from the class
|
||||||
|
// below, the class python_import_extension_class_converters has
|
||||||
|
// to be modified accordingly.
|
||||||
|
//
|
||||||
template <class T, class U = boost::python::detail::held_instance<T> >
|
template <class T, class U = boost::python::detail::held_instance<T> >
|
||||||
class python_extension_class_converters
|
class python_extension_class_converters
|
||||||
{
|
{
|
||||||
@@ -607,6 +616,12 @@ class extension_class
|
|||||||
choose_op<(which & op_and)>::template args<Operand>::add(this);
|
choose_op<(which & op_and)>::template args<Operand>::add(this);
|
||||||
choose_op<(which & op_xor)>::template args<Operand>::add(this);
|
choose_op<(which & op_xor)>::template args<Operand>::add(this);
|
||||||
choose_op<(which & op_or)>::template args<Operand>::add(this);
|
choose_op<(which & op_or)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_gt)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_ge)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_lt)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_le)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_eq)>::template args<Operand>::add(this);
|
||||||
|
choose_op<(which & op_ne)>::template args<Operand>::add(this);
|
||||||
choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
|
choose_unary_op<(which & op_neg)>::template args<Operand>::add(this);
|
||||||
choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
|
choose_unary_op<(which & op_pos)>::template args<Operand>::add(this);
|
||||||
choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
|
choose_unary_op<(which & op_abs)>::template args<Operand>::add(this);
|
||||||
@@ -636,6 +651,12 @@ class extension_class
|
|||||||
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
|
choose_op<(which & op_xor)>::template args<Left,Right>::add(this);
|
||||||
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
|
choose_op<(which & op_or)>::template args<Left,Right>::add(this);
|
||||||
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
|
choose_op<(which & op_cmp)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_gt)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_ge)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_lt)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_le)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_eq)>::template args<Left,Right>::add(this);
|
||||||
|
choose_op<(which & op_ne)>::template args<Left,Right>::add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <long which, class Left, class Right>
|
template <long which, class Left, class Right>
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ namespace detail {
|
|||||||
struct parameter_traits
|
struct parameter_traits
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef const_ref_selector<boost::is_reference<T>::value> selector;
|
enum { is_ref = boost::is_reference<T>::value };
|
||||||
|
typedef const_ref_selector<is_ref> selector;
|
||||||
public:
|
public:
|
||||||
typedef typename selector::template const_ref<T>::type const_reference;
|
typedef typename selector::template const_ref<T>::type const_reference;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -159,6 +159,28 @@ static PyObject* do_instance_repr(PyObject* obj)
|
|||||||
return call(obj, &type_object_base::instance_repr);
|
return call(obj, &type_object_base::instance_repr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject* do_instance_richcompare(PyObject* obj, PyObject* other, int d)
|
||||||
|
{
|
||||||
|
#if PYTHON_API_VERSION >= 1010
|
||||||
|
switch(d)
|
||||||
|
{
|
||||||
|
case Py_LT:
|
||||||
|
return call(obj, &type_object_base::instance_lt, other);
|
||||||
|
case Py_LE:
|
||||||
|
return call(obj, &type_object_base::instance_le, other);
|
||||||
|
case Py_EQ:
|
||||||
|
return call(obj, &type_object_base::instance_eq, other);
|
||||||
|
case Py_NE:
|
||||||
|
return call(obj, &type_object_base::instance_ne, other);
|
||||||
|
case Py_GT:
|
||||||
|
return call(obj, &type_object_base::instance_gt, other);
|
||||||
|
case Py_GE:
|
||||||
|
return call(obj, &type_object_base::instance_ge, other);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_instance_compare(PyObject* obj, PyObject* other)
|
static int do_instance_compare(PyObject* obj, PyObject* other)
|
||||||
{
|
{
|
||||||
return call(obj, &type_object_base::instance_compare, other);
|
return call(obj, &type_object_base::instance_compare, other);
|
||||||
@@ -406,7 +428,7 @@ namespace
|
|||||||
bool add_capability_general(type_object_base::capability capability, PyTypeObject* dest)
|
bool add_capability_general(type_object_base::capability capability, PyTypeObject* dest)
|
||||||
{
|
{
|
||||||
assert(dest != 0);
|
assert(dest != 0);
|
||||||
|
|
||||||
switch(capability)
|
switch(capability)
|
||||||
{
|
{
|
||||||
ENABLE_GENERAL_CAPABILITY(hash);
|
ENABLE_GENERAL_CAPABILITY(hash);
|
||||||
@@ -435,6 +457,20 @@ void create_method_table_if_null(T*& table)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool add_capability_richcompare(type_object_base::capability capability, PyTypeObject* dest)
|
||||||
|
{
|
||||||
|
assert(dest != 0);
|
||||||
|
if (capability == type_object_base::richcompare) {
|
||||||
|
#if PYTHON_API_VERSION >= 1010
|
||||||
|
dest->tp_richcompare = &do_instance_richcompare;
|
||||||
|
dest->tp_flags |= Py_TPFLAGS_HAVE_RICHCOMPARE;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#define ENABLE_MAPPING_CAPABILITY(field) \
|
#define ENABLE_MAPPING_CAPABILITY(field) \
|
||||||
case type_object_base::mapping_##field: \
|
case type_object_base::mapping_##field: \
|
||||||
create_method_table_if_null(dest); \
|
create_method_table_if_null(dest); \
|
||||||
@@ -548,6 +584,8 @@ namespace detail {
|
|||||||
{
|
{
|
||||||
if(add_capability_general(capability, dest_))
|
if(add_capability_general(capability, dest_))
|
||||||
return;
|
return;
|
||||||
|
if(add_capability_richcompare(capability, dest_))
|
||||||
|
return;
|
||||||
if(add_capability_mapping(capability, dest_->tp_as_mapping))
|
if(add_capability_mapping(capability, dest_->tp_as_mapping))
|
||||||
return;
|
return;
|
||||||
if(add_capability_sequence(capability, dest_->tp_as_sequence))
|
if(add_capability_sequence(capability, dest_->tp_as_sequence))
|
||||||
@@ -975,6 +1013,36 @@ PyObject* type_object_base::instance_number_hex(PyObject*) const
|
|||||||
return unimplemented("instance_number_hex");
|
return unimplemented("instance_number_hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* type_object_base::instance_lt(PyObject*, PyObject*) const
|
||||||
|
{
|
||||||
|
return unimplemented("instance_lt");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* type_object_base::instance_le(PyObject*, PyObject*) const
|
||||||
|
{
|
||||||
|
return unimplemented("instance_le");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* type_object_base::instance_eq(PyObject*, PyObject*) const
|
||||||
|
{
|
||||||
|
return unimplemented("instance_eq");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* type_object_base::instance_ne(PyObject*, PyObject*) const
|
||||||
|
{
|
||||||
|
return unimplemented("instance_ne");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* type_object_base::instance_gt(PyObject*, PyObject*) const
|
||||||
|
{
|
||||||
|
return unimplemented("instance_gt");
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* type_object_base::instance_ge(PyObject*, PyObject*) const
|
||||||
|
{
|
||||||
|
return unimplemented("instance_ge");
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace boost::python
|
}} // namespace boost::python
|
||||||
|
|
||||||
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
#ifdef TYPE_OBJECT_BASE_STANDALONE_TEST
|
||||||
|
|||||||
@@ -19,10 +19,13 @@ Load up the extension module
|
|||||||
Automatic checking of the number and type of arguments. Foo's constructor takes
|
Automatic checking of the number and type of arguments. Foo's constructor takes
|
||||||
a single long parameter.
|
a single long parameter.
|
||||||
|
|
||||||
>>> ext = Foo()
|
>>> try:
|
||||||
Traceback (innermost last):
|
... ext = Foo()
|
||||||
File "<stdin>", line 1, in ?
|
... except TypeError, err:
|
||||||
TypeError: function requires exactly 1 argument; 0 given
|
... assert re.match(r'function .* exactly 1 argument;? \(?0 given\)?',
|
||||||
|
... str(err))
|
||||||
|
... else:
|
||||||
|
... print 'no exception'
|
||||||
|
|
||||||
>>> try: ext = Foo('foo')
|
>>> try: ext = Foo('foo')
|
||||||
... except TypeError, err:
|
... except TypeError, err:
|
||||||
@@ -419,7 +422,7 @@ Some simple overloading tests:
|
|||||||
>>> try: r = Range('yikes')
|
>>> try: r = Range('yikes')
|
||||||
... except TypeError, e:
|
... except TypeError, e:
|
||||||
... assert re.match(
|
... assert re.match(
|
||||||
... 'No overloaded functions match [(]Range, string[)]\. Candidates are:\n.*\n.*',
|
... 'No overloaded functions match [(]Range, str[a-z]*[)]\. Candidates are:\n.*\n.*',
|
||||||
... str(e))
|
... str(e))
|
||||||
... else: print 'no exception'
|
... else: print 'no exception'
|
||||||
|
|
||||||
@@ -629,7 +632,7 @@ Testing overloaded free functions
|
|||||||
15
|
15
|
||||||
>>> try: overloaded(1, 'foo')
|
>>> try: overloaded(1, 'foo')
|
||||||
... except TypeError, err:
|
... except TypeError, err:
|
||||||
... assert re.match("No overloaded functions match \(int, string\)\. Candidates are:",
|
... assert re.match("No overloaded functions match \(int, str[a-z]*\)\. Candidates are:",
|
||||||
... str(err))
|
... str(err))
|
||||||
... else:
|
... else:
|
||||||
... print 'no exception'
|
... print 'no exception'
|
||||||
@@ -659,7 +662,7 @@ Testing overloaded constructors
|
|||||||
5
|
5
|
||||||
>>> try: over = OverloadTest(1, 'foo')
|
>>> try: over = OverloadTest(1, 'foo')
|
||||||
... except TypeError, err:
|
... except TypeError, err:
|
||||||
... assert re.match("No overloaded functions match \(OverloadTest, int, string\)\. Candidates are:",
|
... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:",
|
||||||
... str(err))
|
... str(err))
|
||||||
... else:
|
... else:
|
||||||
... print 'no exception'
|
... print 'no exception'
|
||||||
@@ -681,7 +684,7 @@ Testing overloaded methods
|
|||||||
5
|
5
|
||||||
>>> try: over.overloaded(1,'foo')
|
>>> try: over.overloaded(1,'foo')
|
||||||
... except TypeError, err:
|
... except TypeError, err:
|
||||||
... assert re.match("No overloaded functions match \(OverloadTest, int, string\)\. Candidates are:",
|
... assert re.match("No overloaded functions match \(OverloadTest, int, str[a-z]*\)\. Candidates are:",
|
||||||
... str(err))
|
... str(err))
|
||||||
... else:
|
... else:
|
||||||
... print 'no exception'
|
... print 'no exception'
|
||||||
@@ -1014,9 +1017,12 @@ test inheritB2
|
|||||||
-2
|
-2
|
||||||
>>> str(i)
|
>>> str(i)
|
||||||
'2'
|
'2'
|
||||||
>>> j = i/i
|
>>> try: j = i/i
|
||||||
Traceback (innermost last):
|
... except TypeError, err:
|
||||||
TypeError: bad operand type(s) for /
|
... assert re.match(r'(bad|unsupported) operand type\(s\) for /',
|
||||||
|
... str(err))
|
||||||
|
... else: print 'no exception'
|
||||||
|
|
||||||
>>> j = abs(i)
|
>>> j = abs(i)
|
||||||
Traceback (innermost last):
|
Traceback (innermost last):
|
||||||
TypeError: bad operand type for abs()
|
TypeError: bad operand type for abs()
|
||||||
|
|||||||
Reference in New Issue
Block a user