Compare commits
255 Commits
boost-1.62
...
pr/fix-num
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c8b0dc215 | ||
|
|
fdc9ec760f | ||
|
|
0b0c0536d6 | ||
|
|
0d0cd711a7 | ||
|
|
72e254bf8b | ||
|
|
1f1b9b6aef | ||
|
|
6bd6d71850 | ||
|
|
4b01139720 | ||
|
|
65bfec2d97 | ||
|
|
4f6d547c0a | ||
|
|
b644946368 | ||
|
|
c7799aa44f | ||
|
|
02095af952 | ||
|
|
ed4776b59c | ||
|
|
ac62db1cf1 | ||
|
|
b4230e98f6 | ||
|
|
467a89eba7 | ||
|
|
28e2c6512c | ||
|
|
77ff0d6bbc | ||
|
|
24313709a7 | ||
|
|
ac9fa536c8 | ||
|
|
7352c9c0f7 | ||
|
|
26ac881b9d | ||
|
|
19f6c782aa | ||
|
|
f3df1bf912 | ||
|
|
d515eb82c8 | ||
|
|
0021720a46 | ||
|
|
61591f7ad2 | ||
|
|
6b8ab7a5a3 | ||
|
|
9039286937 | ||
|
|
429ac28c4a | ||
|
|
1db3871f50 | ||
|
|
66dad425aa | ||
|
|
ed3cbf8a60 | ||
|
|
2f6e728de5 | ||
|
|
65be0e0f0f | ||
|
|
d4d41d94ae | ||
|
|
660487c43f | ||
|
|
d6d54ce483 | ||
|
|
b9d0d97499 | ||
|
|
ebba009a9f | ||
|
|
9ad3313d1f | ||
|
|
bf9a03399b | ||
|
|
2d9871fc5a | ||
|
|
30c9eb1fb6 | ||
|
|
7c5e478432 | ||
|
|
2b7842a39f | ||
|
|
8d37630cc8 | ||
|
|
9d2903cd5e | ||
|
|
b09d80a93e | ||
|
|
135c025484 | ||
|
|
ecf05c4a90 | ||
|
|
00b7ed03a7 | ||
|
|
c2424bcc8f | ||
|
|
b3b67273b0 | ||
|
|
31c8b7f1b4 | ||
|
|
2d1f66fd19 | ||
|
|
69e38d2186 | ||
|
|
8536e97c67 | ||
|
|
142661dac8 | ||
|
|
d6554d6c65 | ||
|
|
90829714cc | ||
|
|
664d443df3 | ||
|
|
c4fe369d69 | ||
|
|
7cfc47008e | ||
|
|
1452dfe713 | ||
|
|
3613142839 | ||
|
|
b2f53e1acf | ||
|
|
3844c4fc5f | ||
|
|
df16e3e55e | ||
|
|
3066c73c09 | ||
|
|
edd890bd2b | ||
|
|
352792c90a | ||
|
|
47faef65ee | ||
|
|
5121fc11f9 | ||
|
|
471e6181b2 | ||
|
|
398e7f02b8 | ||
|
|
1e315242ce | ||
|
|
77ee91d5c5 | ||
|
|
e670de2795 | ||
|
|
367b793ac9 | ||
|
|
8c170d9193 | ||
|
|
bd7b8ecba5 | ||
|
|
0224f54ae0 | ||
|
|
d14b8cf411 | ||
|
|
4e0b96faa8 | ||
|
|
7178a70176 | ||
|
|
36bbdde2fe | ||
|
|
1df6d84b80 | ||
|
|
e968329174 | ||
|
|
07c8cbe652 | ||
|
|
163e469bc4 | ||
|
|
ac39d2ed69 | ||
|
|
264f6ae4b9 | ||
|
|
84c96447e2 | ||
|
|
dc8d68d3fc | ||
|
|
91512a971d | ||
|
|
080eb55be6 | ||
|
|
a3d8223b5d | ||
|
|
b9431cd326 | ||
|
|
2ccf54f091 | ||
|
|
4ce4821111 | ||
|
|
69ddfcae17 | ||
|
|
3ace4a0015 | ||
|
|
cbb3851488 | ||
|
|
127cc20a1d | ||
|
|
482219f20a | ||
|
|
061050c006 | ||
|
|
03adaee6d2 | ||
|
|
bc2f77a3db | ||
|
|
aaf0d220ae | ||
|
|
bb6f52dc35 | ||
|
|
d422058fb4 | ||
|
|
a60ab14b91 | ||
|
|
e0ee734161 | ||
|
|
444c948abe | ||
|
|
97e4b34a15 | ||
|
|
5029273ca8 | ||
|
|
26aaa5b62e | ||
|
|
f753f4bc30 | ||
|
|
9e53eb2c23 | ||
|
|
6c2e3fb487 | ||
|
|
fcbba59630 | ||
|
|
61a399e80a | ||
|
|
a0e849ed91 | ||
|
|
4dbb2784ee | ||
|
|
4d9ab505b0 | ||
|
|
3494381c01 | ||
|
|
bc13c4c600 | ||
|
|
73b8350e53 | ||
|
|
c509a3ab01 | ||
|
|
4c2070f39f | ||
|
|
e2c23fd5f9 | ||
|
|
7ff5465e7d | ||
|
|
e747cc9422 | ||
|
|
b46ccc4f51 | ||
|
|
be72aab254 | ||
|
|
5035f6e801 | ||
|
|
0b549aee88 | ||
|
|
bf73da1bce | ||
|
|
ca8ce585b7 | ||
|
|
81551cf6b6 | ||
|
|
e3bf3c6f51 | ||
|
|
c8798676f6 | ||
|
|
c9974daec2 | ||
|
|
b46dfd9064 | ||
|
|
956606ef0c | ||
|
|
0b59058fa2 | ||
|
|
2a41c80c58 | ||
|
|
42a57978ee | ||
|
|
4b99e6b83f | ||
|
|
49b536fbd3 | ||
|
|
2e47285fb5 | ||
|
|
45b588b85a | ||
|
|
cce7dfcf17 | ||
|
|
2f7742ffec | ||
|
|
46b959cceb | ||
|
|
ca3526c76a | ||
|
|
4ec94c676b | ||
|
|
a35cbd1af1 | ||
|
|
28a9fab278 | ||
|
|
ab2225bcbd | ||
|
|
dbe4903887 | ||
|
|
405f99cd3c | ||
|
|
313dcbb628 | ||
|
|
dca44829a6 | ||
|
|
46f6382fe4 | ||
|
|
99e6194620 | ||
|
|
4c2850cbfd | ||
|
|
029eb385ed | ||
|
|
77b89341d0 | ||
|
|
588027252b | ||
|
|
d61d41a786 | ||
|
|
1d3a535e53 | ||
|
|
65dc91f3da | ||
|
|
782ca7bf20 | ||
|
|
1a5a3e1701 | ||
|
|
00c61f4767 | ||
|
|
c20af50ae3 | ||
|
|
38e68fa2ae | ||
|
|
35a62fea52 | ||
|
|
b219376e24 | ||
|
|
1e66e33201 | ||
|
|
8f909d55ac | ||
|
|
05c21bcae1 | ||
|
|
0cb3bd7aa5 | ||
|
|
7a84a00673 | ||
|
|
9d7dfd8449 | ||
|
|
2a8823f745 | ||
|
|
beaa4b0e4d | ||
|
|
55c3b0569e | ||
|
|
2aca81bca9 | ||
|
|
32d2135462 | ||
|
|
7064cf3186 | ||
|
|
777e16e1d0 | ||
|
|
715e5cbc31 | ||
|
|
67b5b07976 | ||
|
|
7b088c9df2 | ||
|
|
3dda62f8b8 | ||
|
|
c33460c265 | ||
|
|
4c12b004ec | ||
|
|
5bed132ff8 | ||
|
|
3ffcf3335a | ||
|
|
c314274a56 | ||
|
|
437373456f | ||
|
|
7add755ae0 | ||
|
|
79182d7189 | ||
|
|
36e9e38373 | ||
|
|
45e52301e9 | ||
|
|
37a73f344b | ||
|
|
bbd9aad6e9 | ||
|
|
8fa1f9db9e | ||
|
|
9c56469358 | ||
|
|
196c9e653f | ||
|
|
c572b4db73 | ||
|
|
b2519a25a9 | ||
|
|
2979e4b062 | ||
|
|
88dd5330d0 | ||
|
|
fa51b58cd6 | ||
|
|
419b6ec973 | ||
|
|
085f574d6e | ||
|
|
69d9f34f3e | ||
|
|
36ee7d23f9 | ||
|
|
b269b4b124 | ||
|
|
20b68f2a2f | ||
|
|
2794a9bd15 | ||
|
|
0a76801936 | ||
|
|
daf466a697 | ||
|
|
718cfd468e | ||
|
|
3796825523 | ||
|
|
6904a166f7 | ||
|
|
39b9047190 | ||
|
|
930167e961 | ||
|
|
64b2c1697b | ||
|
|
f0345b2521 | ||
|
|
77ec571511 | ||
|
|
70c7fbd1d8 | ||
|
|
91a1119070 | ||
|
|
a300f7cdd0 | ||
|
|
65db10061f | ||
|
|
3d7f523384 | ||
|
|
252c3aa695 | ||
|
|
584df88fb2 | ||
|
|
ba1416fff0 | ||
|
|
42ca807c82 | ||
|
|
b988e8c45f | ||
|
|
c7db44f617 | ||
|
|
f3aecdf2f4 | ||
|
|
40bd0326f3 | ||
|
|
99d3a54ad5 | ||
|
|
c3d186e0bf | ||
|
|
e0fa8ec619 | ||
|
|
e2b2ebe862 | ||
|
|
eef2eef7dd | ||
|
|
189915bc8b |
@@ -4,7 +4,7 @@ environment:
|
||||
# /E:ON and /V:ON options are not enabled in the batch script intepreter
|
||||
# See: http://stackoverflow.com/a/13751649/163740
|
||||
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci\\run_with_env.cmd"
|
||||
BOOST_PREFIX: C:\Libraries\boost_1_60_0
|
||||
BOOST_PREFIX: C:\Libraries\boost_1_66_0
|
||||
|
||||
matrix:
|
||||
|
||||
@@ -15,20 +15,21 @@ environment:
|
||||
- PYTHON: "C:\\Python27"
|
||||
PYTHON_VERSION: "2.7.x" # currently 2.7.9
|
||||
PYTHON_ARCH: "32"
|
||||
ARCH: "x86"
|
||||
MSVC: "14.0"
|
||||
ARCH: x86
|
||||
|
||||
#- PYTHON: "C:\\Python27-x64"
|
||||
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
|
||||
# PYTHON_ARCH: "64"
|
||||
# ARCH: "x86_64"
|
||||
- PYTHON: "C:\\Python36-x64"
|
||||
PYTHON_VERSION: "3.6.x"
|
||||
PYTHON_ARCH: "64"
|
||||
MSVC: "12.0"
|
||||
ARCH: x86_64
|
||||
|
||||
#- PYTHON: "C:\\Python35"
|
||||
# PYTHON_VERSION: "3.5.x" # currently 3.4.3
|
||||
# PYTHON_ARCH: "32"
|
||||
|
||||
#- PYTHON: "C:\\Python35-x64"
|
||||
# PYTHON_VERSION: "3.5.x" # currently 3.4.3
|
||||
# PYTHON_ARCH: "64"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
PYTHON: "C:\\Python36-x64"
|
||||
PYTHON_VERSION: "3.6.x"
|
||||
PYTHON_ARCH: "64"
|
||||
MSVC: "14.13.26128"
|
||||
ARCH: x86_64
|
||||
|
||||
install:
|
||||
# If there is a newer build queued for the same PR, cancel this one.
|
||||
@@ -44,8 +45,9 @@ install:
|
||||
- ps: "ls \"C:/\""
|
||||
- ECHO "Installed libraries:"
|
||||
- ps: "ls \"C:/Libraries/\""
|
||||
- ECHO "Installed SDKs:"
|
||||
- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
|
||||
## This path doesn't exist with the VS 2017 worker images
|
||||
#- ECHO "Installed SDKs:"
|
||||
#- ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\""
|
||||
|
||||
# Install Python (from the official .msi of http://python.org) and pip when
|
||||
# not already installed.
|
||||
@@ -68,19 +70,22 @@ install:
|
||||
# compiled extensions and are not provided as pre-built wheel packages,
|
||||
# pip will build them from source using the MSVC compiler matching the
|
||||
# target Python version and architecture
|
||||
- easy_install scons
|
||||
#- "%CMD_IN_ENV% pip install -r dev-requirements.txt"
|
||||
- |
|
||||
curl -LfsS -o faber.tar.gz https://github.com/stefanseefeld/faber/archive/snapshot/2018-04-08.tar.gz
|
||||
tar xf faber.tar.gz
|
||||
CD faber-snapshot-2018-04-08
|
||||
python setup.py install
|
||||
CD ..
|
||||
# report the available MSVC compilers
|
||||
- faber --info=tools cxx
|
||||
- easy_install sphinx
|
||||
- pip install numpy
|
||||
|
||||
build_script:
|
||||
# Build the compiled extension
|
||||
#- "%CMD_IN_ENV% python setup.py build"
|
||||
- scons config arch=%ARCH% --boost-include=%BOOST_PREFIX%
|
||||
- scons arch=%ARCH%
|
||||
- faber --with-boost-include=%BOOST_PREFIX% target.arch=%ARCH% msvc.version=%MSVC%
|
||||
|
||||
test_script:
|
||||
# Run the project tests
|
||||
#- "%CMD_IN_ENV% python setup.py nosetests"
|
||||
- scons test arch=%ARCH% --verbose
|
||||
- faber --with-boost-include=%BOOST_PREFIX% test.report target.arch=%ARCH% msvc.version=%MSVC%
|
||||
|
||||
after_test:
|
||||
# If tests are successful, create binary packages for the project.
|
||||
@@ -95,4 +100,4 @@ after_test:
|
||||
|
||||
#on_success:
|
||||
# - TODO: upload the content of dist/*.whl to a public wheelhouse
|
||||
#
|
||||
#
|
||||
3
.ci/faber
Normal file
@@ -0,0 +1,3 @@
|
||||
from faber.tools.python import python
|
||||
|
||||
p = python(command='$PYTHON')
|
||||
@@ -5,34 +5,53 @@ SOURCE_BRANCH="master"
|
||||
TARGET_BRANCH="gh-pages"
|
||||
|
||||
# Pull requests and commits to other branches shouldn't try to deploy, just build to verify
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" != master -a "$TRAVIS_BRANCH" != develop ]; then
|
||||
if [ "$TRAVIS_PULL_REQUEST" != "false" ] || \
|
||||
[ "$TRAVIS_BRANCH" != master -a \
|
||||
"$TRAVIS_BRANCH" != develop -a \
|
||||
"$TRAVIS_BRANCH" != travis ]; then
|
||||
echo "No docs to upload."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -z "$GH_TOKEN" ]; then
|
||||
echo "Error: GH_TOKEN is undefined"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save some useful information
|
||||
REPO=`git config remote.origin.url`
|
||||
SHA=`git rev-parse --verify HEAD`
|
||||
|
||||
# bin.SCons happens to contain the "doc/html" tree that we want to push
|
||||
# build happens to contain the "doc/html" tree that we want to push
|
||||
# into the gh-pages branch. So we step into that directory, create a new repo,
|
||||
# set the remote appropriately, then commit and push.
|
||||
cd bin.SCons
|
||||
cd build
|
||||
git init
|
||||
git config user.name "Travis CI"
|
||||
git config user.email "$COMMIT_AUTHOR_EMAIL"
|
||||
git config user.email "travis-ci"
|
||||
|
||||
# Make sure 'GH_TOKEN' is set (as 'secure' variable) in .travis.yml
|
||||
git remote add upstream "https://$GH_TOKEN@github.com/boostorg/python.git"
|
||||
git fetch upstream
|
||||
git reset upstream/gh-pages
|
||||
|
||||
# Prepare version.
|
||||
if [ "$TRAVIS_BRANCH" = develop -o "$TRAVIS_BRANCH" = travis ]; then
|
||||
mkdir -p develop/doc/
|
||||
cp ../index.html develop/
|
||||
cp ../doc/index.html develop/doc/
|
||||
cp -a doc/html develop/doc/
|
||||
git add develop/index.html
|
||||
git add develop/doc/index.html
|
||||
git add -A develop/doc/html
|
||||
else
|
||||
cp ../index.html .
|
||||
cp ../doc/index.html doc/
|
||||
git add index.html
|
||||
git add doc/index.html
|
||||
git add -A doc/html
|
||||
fi
|
||||
# Commit the new version.
|
||||
cp ../index.html .
|
||||
cp ../doc/index.html doc/
|
||||
git add index.html
|
||||
git add doc/index.html
|
||||
git add -A doc/html
|
||||
git commit -m "Deploy to GitHub Pages: ${SHA}"
|
||||
|
||||
# Now that we're all set up, we can push.
|
||||
|
||||
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
bin.SCons
|
||||
*.pyc
|
||||
*~
|
||||
\#*\#
|
||||
105
.travis.yml
@@ -11,55 +11,108 @@ dist: trusty
|
||||
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: BRNUkxN3p8f+uYKWC3Hr0VPqZA0PxbWr1DJlcI4hbiZtzKhMCWjDmd9UW9CzzexqeOxpd+9s0G87qvOur+wMSVxugDxtTesZrh1czXHeSVxgQrYD783XJtQJ9aYypbChkiboRD6Xpmbq7itwMuHBJMFtCuDxMynpU1jWwkyTf2Y=
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++98
|
||||
- compiler: gcc
|
||||
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++11
|
||||
- compiler: gcc
|
||||
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++98
|
||||
- compiler: gcc
|
||||
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++11
|
||||
- compiler: clang
|
||||
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98
|
||||
- compiler: clang
|
||||
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11
|
||||
- env: PYTHON=python DOC=1
|
||||
global:
|
||||
- secure: mqoxglbUN/At/r8O7nLVccGldnB1jvhLHNyYjfCXrdOD0GNX+TY2TS1+kIEv9Deg/P6X/QvrBa/ZzbDNryn3mDXBfOSy400ebSIUHHP3HtGHJShOGDyXedY3hZ/dqmxdV3p9hIxv4lcx1HPyC96s4wpiR0S9F1JBzD6scIabezM=
|
||||
- os: linux
|
||||
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++98
|
||||
- os: linux
|
||||
env: CXX=g++ PYTHON=python CXXFLAGS=-std=c++11
|
||||
- os: linux
|
||||
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++98
|
||||
- os: linux
|
||||
env: CXX=g++ PYTHON=python3 CXXFLAGS=-std=c++11
|
||||
- os: linux
|
||||
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98
|
||||
- os: linux
|
||||
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11
|
||||
- os: osx
|
||||
env: CXX=clang++ PYTHON=python CXXFLAGS=-std=c++11
|
||||
- env: PYTHON=python DOC=1
|
||||
allow_failures:
|
||||
- os: osx
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- scons
|
||||
- gcc-4.8
|
||||
- g++-4.8
|
||||
- clang
|
||||
- python-dev python-pip
|
||||
- python-numpy
|
||||
- python-sphinx
|
||||
- python3-dev
|
||||
- python3-numpy
|
||||
- libboost-all-dev
|
||||
- xsltproc
|
||||
- docbook-xsl
|
||||
- python-docutils
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/Boost
|
||||
|
||||
before_install:
|
||||
# The Trusty image has several Python versions pre-installed compiled with
|
||||
# conflicting UCS2 and UCS4 unicode. Modify the PATH to skip the TravisCI python.
|
||||
# See https://github.com/travis-ci/travis-ci/issues/4948 for details.
|
||||
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
|
||||
- sudo pip install future
|
||||
# The Trusty image has several Python versions pre-installed compiled with
|
||||
# conflicting UCS2 and UCS4 unicode. Modify the PATH to skip the TravisCI python.
|
||||
# See https://github.com/travis-ci/travis-ci/issues/4948 for details.
|
||||
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
|
||||
|
||||
install:
|
||||
# Install our own version of Boost (the subset we need) as the system version is
|
||||
# too old (for C++11 support).
|
||||
- |
|
||||
if [ ! -d $HOME/Boost/tools/boostbook ]; then
|
||||
echo "rebuilding Boost prerequisites."
|
||||
wget https://sourceforge.net/projects/boost/files/boost/1.66.0/boost_1_66_0.tar.gz/download
|
||||
tar xf download
|
||||
pushd boost_1_66_0
|
||||
./bootstrap.sh
|
||||
./b2 tools/bcp
|
||||
mkdir -p $HOME/Boost
|
||||
# Install Boost.Python prerequisites, but not Boost.Python itself.
|
||||
dist/bin/bcp python tools/boostbook tools/quickbook $HOME/Boost &> /dev/null
|
||||
rm -rf $HOME/Boost/boost/python*
|
||||
popd
|
||||
else
|
||||
echo "using cached Boost prerequisites."
|
||||
fi
|
||||
# Install Faber, the build tool.
|
||||
date=2018-04-08
|
||||
wget https://github.com/stefanseefeld/faber/archive/snapshot/$date.tar.gz
|
||||
tar xf $date.tar.gz
|
||||
pushd faber-snapshot-$date
|
||||
#wget https://github.com/stefanseefeld/faber/archive/release/0.2.tar.gz
|
||||
#tar xf 0.2.tar.gz
|
||||
#pushd faber-release-0.2
|
||||
sudo python setup.py install
|
||||
popd
|
||||
|
||||
before_script:
|
||||
- scons --version
|
||||
- sed -e "s/\$PYTHON/$PYTHON/g" .ci/faber > ~/.faber
|
||||
- $PYTHON --version
|
||||
- faber -h
|
||||
- ls -l $HOME/Boost
|
||||
|
||||
script:
|
||||
- scons config --python=$PYTHON
|
||||
- if [ "$DOC" ]; then scons doc; else scons && scons test; fi
|
||||
- |
|
||||
if [ "$DOC" ]; then
|
||||
BOOST_ROOT=$HOME/Boost faber --builddir=build doc.html
|
||||
else
|
||||
faber --with-boost-include=$HOME/Boost --builddir=build test.report cxx.name=$CXX cxxflags=$CXXFLAGS
|
||||
fi
|
||||
|
||||
after_success:
|
||||
# Upload docs only when building upstream.
|
||||
- if [ "$DOC" -a "$TRAVIS_REPO_SLUG" = "boostorg/python" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then .ci/upload_docs.sh; fi
|
||||
- |
|
||||
if [ "$DOC" -a \
|
||||
"$TRAVIS_REPO_SLUG" = "boostorg/python" -a \
|
||||
"$TRAVIS_PULL_REQUEST" = "false" ]; then
|
||||
export GH_TOKEN
|
||||
.ci/upload_docs.sh
|
||||
fi
|
||||
|
||||
68
Jamfile
Normal file
@@ -0,0 +1,68 @@
|
||||
# Copyright (c) 2018 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import option ;
|
||||
import regex ;
|
||||
import python ;
|
||||
|
||||
#
|
||||
# The `version-suffix` rule really belongs into python.jam, and
|
||||
# should be moved there. `split-version` is only duplicated here
|
||||
# as a prerequisite. (See https://github.com/boostorg/build/pull/290)
|
||||
#
|
||||
|
||||
|
||||
# Validate the version string and extract the major/minor part we care about.
|
||||
#
|
||||
local rule split-version ( version )
|
||||
{
|
||||
local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)(.*)$" : $(version) : 1 2 3 ] ;
|
||||
if ! $(major-minor[2]) || $(major-minor[3])
|
||||
{
|
||||
ECHO "Warning: \"using python\" expects a two part (major, minor) version number; got" $(version) instead ;
|
||||
|
||||
# Add a zero to account for the missing digit if necessary.
|
||||
major-minor += 0 ;
|
||||
}
|
||||
|
||||
return $(major-minor[1]) $(major-minor[2]) ;
|
||||
}
|
||||
|
||||
# Define a version suffix for libraries depending on Python.
|
||||
# For example, Boost.Python built for Python 2.7 uses the suffix "27"
|
||||
rule version-suffix ( version )
|
||||
{
|
||||
local major-minor = [ split-version $(version) ] ;
|
||||
local suffix = $(major-minor:J="") ;
|
||||
return $(suffix) ;
|
||||
}
|
||||
|
||||
|
||||
# Python build id (for Python libraries only).
|
||||
python-id = [ option.get "python-buildid" ] ;
|
||||
if $(python-id)
|
||||
{
|
||||
PYTHON_ID = [ regex.replace $(python-id) "[*\\/:.\"\']" _ ] ;
|
||||
}
|
||||
|
||||
rule python-tag ( name : type ? : property-set )
|
||||
{
|
||||
local result = $(name) ;
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
|
||||
{
|
||||
local version = [ $(property-set).get <python> ] ;
|
||||
local lib-suffix = [ version-suffix $(version) ] ;
|
||||
result = $(result)$(lib-suffix) ;
|
||||
}
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB && $(PYTHON_ID)
|
||||
{
|
||||
result = $(result)-$(PYTHON_ID) ;
|
||||
}
|
||||
|
||||
# forward to the boost tagging rule
|
||||
return [ tag $(result) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
23
LICENSE_1_0.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
30
README.md
@@ -2,6 +2,8 @@
|
||||
|
||||
# Synopsis
|
||||
|
||||
[](https://gitter.im/boostorg/python?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Welcome to Boost.Python, a C++ library which enables seamless interoperability between C++ and the Python programming language. The library includes support for:
|
||||
|
||||
* References and Pointers
|
||||
@@ -17,7 +19,10 @@ Welcome to Boost.Python, a C++ library which enables seamless interoperability b
|
||||
|
||||
See the [Boost.Python](http://boostorg.github.io/python) documentation for details.
|
||||
|
||||
# Building 
|
||||
**Hint :** Check out the [development version](http://boostorg.github.io/python/develop) of the documentation to see work in progress.
|
||||
|
||||
# Building [](https://travis-ci.org/boostorg/python) [](https://ci.appveyor.com/project/stefanseefeld/python/branch/develop)
|
||||
|
||||
|
||||
While Boost.Python is part of the Boost C++ Libraries super-project, and thus can be compiled as part of Boost, it can also be compiled and installed stand-alone, i.e. against a pre-installed Boost package.
|
||||
|
||||
@@ -25,27 +30,14 @@ While Boost.Python is part of the Boost C++ Libraries super-project, and thus ca
|
||||
|
||||
* [Python](http://www.python.org)
|
||||
* [Boost](http://www.boost.org)
|
||||
* [SCons](http://www.scons.org)
|
||||
|
||||
## Configure
|
||||
|
||||
Simply run
|
||||
|
||||
```
|
||||
scons config [options]
|
||||
```
|
||||
to prepare a build. See `scons -h` for a description of the available options. For example
|
||||
```
|
||||
scons config --boost=/path/to/boost --python=/path/to/python
|
||||
```
|
||||
will configure Boost.Python to be built against the two specific versions of Boost and Python.
|
||||
* [Faber](https://stefanseefeld.github.io/faber)
|
||||
|
||||
## Build
|
||||
|
||||
Run
|
||||
|
||||
```
|
||||
scons
|
||||
faber
|
||||
```
|
||||
to build the library.
|
||||
|
||||
@@ -54,7 +46,7 @@ to build the library.
|
||||
Run
|
||||
|
||||
```
|
||||
scons test
|
||||
faber test.report
|
||||
```
|
||||
to run the tests.
|
||||
|
||||
@@ -63,6 +55,6 @@ to run the tests.
|
||||
Run
|
||||
|
||||
```
|
||||
scons doc
|
||||
faber doc.html
|
||||
```
|
||||
to build the documentation.
|
||||
to build the documentation.
|
||||
|
||||
34
SConscript
@@ -1,34 +0,0 @@
|
||||
# -*- python -*-
|
||||
|
||||
Import("env")
|
||||
|
||||
env.Append(CPPPATH = "#/include",CPPDEFINES = ["BOOST_ALL_NO_LIB=1"])
|
||||
|
||||
env.AppendUnique(CPPDEFINES = ["${LINK_DYNAMIC and 'BOOST_PYTHON_DYN_LINK=1' or []}"])
|
||||
for variant in env["variant"]:
|
||||
env["current_variant"] = variant
|
||||
env.SetProperty(profile = False)
|
||||
if variant == "release":
|
||||
env.SetProperty(optimize = "speed", debug = False)
|
||||
elif variant == "debug":
|
||||
env.SetProperty(optimize = "no", debug = True)
|
||||
elif variant == "profile":
|
||||
env.SetProperty(optimize = "speed", profile = True, debug = True)
|
||||
for linking in env["link"]:
|
||||
env["linking"] = linking
|
||||
if linking == "dynamic":
|
||||
env["LINK_DYNAMIC"] = True
|
||||
else:
|
||||
env["LINK_DYNAMIC"] = False
|
||||
for threading in env["threading"]:
|
||||
env["current_threading"] = threading
|
||||
env.SetProperty(threading = threading)
|
||||
variant_dir=env.subst("$BOOST_CURRENT_VARIANT_DIR")
|
||||
|
||||
env.SConscript("src/SConscript", variant_dir=variant_dir + '/src',
|
||||
exports = { "env" : env.Clone(BOOST_LIB = 'python') })
|
||||
if GetOption("test"):
|
||||
test_env = env.Clone(BOOST_LIB = 'python', BOOST_TEST = True)
|
||||
test_env.BoostUseLib('python')
|
||||
env.SConscript("test/SConscript", variant_dir=variant_dir + '/test',
|
||||
exports = { "env" : test_env })
|
||||
100
SConstruct
@@ -1,100 +0,0 @@
|
||||
# -*- python -*-
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import SCons.Script.Main
|
||||
import config
|
||||
import config.ui
|
||||
import platform
|
||||
import os
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
#
|
||||
# We try to mimic the typical autotools-workflow.
|
||||
#
|
||||
# * In a 'configure' step all the essential build parameters are established
|
||||
# (either by explicit command-line arguments or from configure checks)
|
||||
# * A subsequent build step can then simply read the cached variables, so
|
||||
# users don't have to memorize and re-issue the arguments on each subsequent
|
||||
# invocation, and neither do the config checks need to be re-run.
|
||||
#
|
||||
# The essential part here is to define a 'config' target, which removes any
|
||||
# caches that may still be lingering around, then runs the checks.
|
||||
|
||||
if 'config' in COMMAND_LINE_TARGETS:
|
||||
# Clear the cache
|
||||
try: os.remove('bin.SCons/config.py')
|
||||
except: pass
|
||||
if not os.path.exists('bin.SCons/'):
|
||||
os.mkdir('bin.SCons/')
|
||||
vars = Variables('bin.SCons/config.py', ARGUMENTS)
|
||||
config.add_options(vars)
|
||||
arch = ARGUMENTS.get('arch', platform.machine())
|
||||
env_vars = {}
|
||||
if 'CXX' in os.environ: env_vars['CXX'] = os.environ['CXX']
|
||||
if 'CXXFLAGS' in os.environ: env_vars['CXXFLAGS'] = os.environ['CXXFLAGS'].split()
|
||||
env = Environment(toolpath=['config/tools'],
|
||||
tools=['default', 'libs', 'tests', 'doc'],
|
||||
variables=vars,
|
||||
TARGET_ARCH=arch,
|
||||
**env_vars)
|
||||
if 'gcc' in env['TOOLS']:
|
||||
# Earlier SCons versions (~ 2.3.0) can't handle CXX=clang++.
|
||||
version = subprocess.check_output([env['CXX'], '--version'])
|
||||
match = re.search(r'[0-9]+(\.[0-9]+)+', version)
|
||||
if match:
|
||||
version = match.group(0)
|
||||
else:
|
||||
version = 'unknown'
|
||||
env['CXXVERSION'] = version
|
||||
|
||||
Help(config.ui.help(vars, env) + """
|
||||
Variables are saved in bin.SCons/config.py and persist between scons invocations.
|
||||
""")
|
||||
|
||||
if GetOption('help'):
|
||||
Return()
|
||||
|
||||
build_dir = config.prepare_build_dir(env)
|
||||
config_log = '{}/config.log'.format(build_dir)
|
||||
|
||||
# configure
|
||||
SConsignFile('{}/.sconsign'.format(build_dir))
|
||||
#env.Decider('MD5-timestamp')
|
||||
env.Decider('timestamp-newer')
|
||||
checks = config.get_checks()
|
||||
if 'config' in COMMAND_LINE_TARGETS:
|
||||
conf=env.Configure(custom_tests=checks, log_file=config_log, conf_dir=build_dir)
|
||||
if False in (getattr(conf, c)() for c in checks):
|
||||
Exit(1)
|
||||
env = conf.Finish()
|
||||
vars.Save('bin.SCons/config.py', env)
|
||||
|
||||
if not os.path.exists(config_log):
|
||||
print('Please run `scons config` first. (See `scons -h` for available options.)')
|
||||
Exit(1)
|
||||
|
||||
if not GetOption('verbose'):
|
||||
config.ui.pretty_output(env)
|
||||
|
||||
# build
|
||||
env['BPL_VERSION'] = '1.62'
|
||||
for e in config.variants(env):
|
||||
variant_dir=e.subst("$BOOST_CURRENT_VARIANT_DIR")
|
||||
e.SConscript('src/SConscript', variant_dir=variant_dir + '/src',
|
||||
exports = { 'env' : e.Clone(BOOST_LIB = 'python') })
|
||||
if 'test' in COMMAND_LINE_TARGETS:
|
||||
test_env = e.Clone(BOOST_LIB = 'python', BOOST_TEST = True)
|
||||
test_env.BoostUseLib('python')
|
||||
e.SConscript('test/SConscript', variant_dir=variant_dir + '/test',
|
||||
exports = { 'env' : test_env })
|
||||
|
||||
if 'doc' in COMMAND_LINE_TARGETS:
|
||||
env.SConscript('doc/SConscript', variant_dir='bin.SCons/doc',
|
||||
exports = { 'env' : e.Clone(BOOST_LIB = 'python') })
|
||||
167
build/Jamfile
Normal file
@@ -0,0 +1,167 @@
|
||||
# Copyright David Abrahams 2001-2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import os ;
|
||||
import indirect ;
|
||||
import modules ;
|
||||
import feature ;
|
||||
import property ;
|
||||
import python ;
|
||||
|
||||
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
|
||||
{
|
||||
# Attempt default configuration of python
|
||||
import toolset : using ;
|
||||
using python ;
|
||||
}
|
||||
|
||||
if [ python.configured ] || ( --without-python in [ modules.peek : ARGV ] )
|
||||
{
|
||||
alias config-warning ;
|
||||
}
|
||||
else
|
||||
{
|
||||
message config-warning
|
||||
: "warning: No python installation configured and autoconfiguration"
|
||||
: "note: failed. See http://www.boost.org/libs/python/doc/building.html"
|
||||
: "note: for configuration instructions or pass --without-python to"
|
||||
: "note: suppress this message and silently skip all Boost.Python targets"
|
||||
;
|
||||
}
|
||||
|
||||
project boost/python
|
||||
: source-location ../src
|
||||
;
|
||||
|
||||
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
local rule eq ( a : b ) { if $(a) = $(b) { return 1 ; } }
|
||||
|
||||
lib boost_python
|
||||
: # sources
|
||||
list.cpp
|
||||
long.cpp
|
||||
dict.cpp
|
||||
tuple.cpp
|
||||
str.cpp
|
||||
slice.cpp
|
||||
|
||||
converter/from_python.cpp
|
||||
converter/registry.cpp
|
||||
converter/type_id.cpp
|
||||
object/enum.cpp
|
||||
object/class.cpp
|
||||
object/function.cpp
|
||||
object/inheritance.cpp
|
||||
object/life_support.cpp
|
||||
object/pickle_support.cpp
|
||||
errors.cpp
|
||||
module.cpp
|
||||
converter/builtin_converters.cpp
|
||||
converter/arg_to_python_base.cpp
|
||||
object/iterator.cpp
|
||||
object/stl_iterator.cpp
|
||||
object_protocol.cpp
|
||||
object_operators.cpp
|
||||
wrapper.cpp
|
||||
import.cpp
|
||||
exec.cpp
|
||||
object/function_doc_signature.cpp
|
||||
: # requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
|
||||
# On Windows, all code using Python has to link to the Python
|
||||
# import library.
|
||||
#
|
||||
# On *nix we never link libboost_python to libpython. When
|
||||
# extending Python, all Python symbols are provided by the
|
||||
# Python interpreter executable. When embedding Python, the
|
||||
# client executable is expected to explicitly link to
|
||||
# /python//python (the target representing libpython) itself.
|
||||
#
|
||||
# python_for_extensions is a target defined by Boost.Build to
|
||||
# provide the Python include paths, and on Windows, the Python
|
||||
# import library, as usage requirements.
|
||||
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
|
||||
|
||||
# we prevent building when there is no python available
|
||||
# as it's not possible anyway, and to cause dependents to
|
||||
# fail to build
|
||||
[ unless [ python.configured ] : <build>no ]
|
||||
<dependency>config-warning
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
|
||||
<tag>@$(__name__).python-tag
|
||||
<conditional>@python.require-py
|
||||
|
||||
: # default build
|
||||
<link>shared
|
||||
: # usage requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
;
|
||||
|
||||
numpy-include = [ python.numpy-include ] ;
|
||||
lib boost_numpy
|
||||
: # sources
|
||||
numpy/dtype.cpp
|
||||
numpy/matrix.cpp
|
||||
numpy/ndarray.cpp
|
||||
numpy/numpy.cpp
|
||||
numpy/scalars.cpp
|
||||
numpy/ufunc.cpp
|
||||
: # requirements
|
||||
<link>static:<define>BOOST_NUMPY_STATIC_LIB
|
||||
<define>BOOST_NUMPY_SOURCE
|
||||
[ cond [ python.numpy ] : <library>/python//python_for_extensions ]
|
||||
[ unless [ python.numpy ] : <build>no ]
|
||||
<include>$(numpy-include)
|
||||
<library>boost_python
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
|
||||
<tag>@$(__name__).python-tag
|
||||
<conditional>@python.require-py
|
||||
|
||||
: # default build
|
||||
<link>shared
|
||||
: # usage requirements
|
||||
<link>static:<define>BOOST_NUMPY_STATIC_LIB
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
;
|
||||
|
||||
# boost-install creates `stage` and `install` targets
|
||||
#
|
||||
# `stage` stages (builds and copies into `stage/lib`) the given libraries
|
||||
# `boost_python` and `boost_numpy` and their dependencies and is similar
|
||||
# to issuing `b2 --with-python stage` from top level
|
||||
#
|
||||
# `install` installs the two libraries and their dependencies and is similar
|
||||
# to issuing `b2 --with-python install` from top level
|
||||
|
||||
if [ python.configured ]
|
||||
{
|
||||
if [ python.numpy ]
|
||||
{
|
||||
boost-install boost_python boost_numpy ;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost-install boost_python ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
# When Python isn't configured, the above `boost-install` is not executed,
|
||||
# so we create empty `stage` and `install` targets that do nothing but issue
|
||||
# a warning message unless `--without-python` is given
|
||||
|
||||
alias stage : config-warning ;
|
||||
explicit stage ;
|
||||
|
||||
alias install : config-warning ;
|
||||
explicit install ;
|
||||
|
||||
}
|
||||
151
build/Jamfile.v2
@@ -1,151 +0,0 @@
|
||||
# Copyright David Abrahams 2001-2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import os ;
|
||||
import indirect ;
|
||||
import modules ;
|
||||
import feature ;
|
||||
|
||||
import python ;
|
||||
|
||||
if ! [ python.configured ] && ! ( --without-python in [ modules.peek : ARGV ] )
|
||||
{
|
||||
# Attempt default configuration of python
|
||||
import toolset : using ;
|
||||
using python ;
|
||||
}
|
||||
|
||||
if [ python.configured ] || ( --without-python in [ modules.peek : ARGV ] )
|
||||
{
|
||||
alias config-warning ;
|
||||
}
|
||||
else
|
||||
{
|
||||
message config-warning
|
||||
: "warning: No python installation configured and autoconfiguration"
|
||||
: "note: failed. See http://www.boost.org/libs/python/doc/building.html"
|
||||
: "note: for configuration instructions or pass --without-python to"
|
||||
: "note: suppress this message and silently skip all Boost.Python targets"
|
||||
;
|
||||
}
|
||||
|
||||
rule find-py3-version
|
||||
{
|
||||
local versions = [ feature.values python ] ;
|
||||
local py3ver ;
|
||||
for local v in $(versions)
|
||||
{
|
||||
if $(v) >= 3.0
|
||||
{
|
||||
py3ver = $(v) ;
|
||||
}
|
||||
}
|
||||
return $(py3ver) ;
|
||||
}
|
||||
|
||||
py3-version = [ find-py3-version ] ;
|
||||
|
||||
project boost/python
|
||||
: source-location ../src
|
||||
: requirements
|
||||
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
|
||||
<tag>@$(__name__).tag
|
||||
;
|
||||
|
||||
rule tag ( name : type ? : property-set )
|
||||
{
|
||||
local result = $(name) ;
|
||||
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
|
||||
{
|
||||
if $(name) = boost_python && $(PYTHON_ID)
|
||||
{
|
||||
result = $(result)-$(PYTHON_ID) ;
|
||||
}
|
||||
}
|
||||
|
||||
# forward to the boost tagging rule
|
||||
return [ indirect.call $(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
|
||||
$(result) : $(type) : $(property-set) ] ;
|
||||
}
|
||||
|
||||
rule cond ( test ? : yes * : no * ) { if $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
rule unless ( test ? : yes * : no * ) { if ! $(test) { return $(yes) ; } else { return $(no) ; } }
|
||||
|
||||
rule lib_boost_python ( is-py3 ? )
|
||||
{
|
||||
|
||||
lib [ cond $(is-py3) : boost_python3 : boost_python ]
|
||||
: # sources
|
||||
numeric.cpp
|
||||
list.cpp
|
||||
long.cpp
|
||||
dict.cpp
|
||||
tuple.cpp
|
||||
str.cpp
|
||||
slice.cpp
|
||||
|
||||
converter/from_python.cpp
|
||||
converter/registry.cpp
|
||||
converter/type_id.cpp
|
||||
object/enum.cpp
|
||||
object/class.cpp
|
||||
object/function.cpp
|
||||
object/inheritance.cpp
|
||||
object/life_support.cpp
|
||||
object/pickle_support.cpp
|
||||
errors.cpp
|
||||
module.cpp
|
||||
converter/builtin_converters.cpp
|
||||
converter/arg_to_python_base.cpp
|
||||
object/iterator.cpp
|
||||
object/stl_iterator.cpp
|
||||
object_protocol.cpp
|
||||
object_operators.cpp
|
||||
wrapper.cpp
|
||||
import.cpp
|
||||
exec.cpp
|
||||
object/function_doc_signature.cpp
|
||||
: # requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<define>BOOST_PYTHON_SOURCE
|
||||
|
||||
# On Windows, all code using Python has to link to the Python
|
||||
# import library.
|
||||
#
|
||||
# On *nix we never link libboost_python to libpython. When
|
||||
# extending Python, all Python symbols are provided by the
|
||||
# Python interpreter executable. When embedding Python, the
|
||||
# client executable is expected to explicitly link to
|
||||
# /python//python (the target representing libpython) itself.
|
||||
#
|
||||
# python_for_extensions is a target defined by Boost.Build to
|
||||
# provide the Python include paths, and on Windows, the Python
|
||||
# import library, as usage requirements.
|
||||
[ cond [ python.configured ] : <library>/python//python_for_extensions ]
|
||||
|
||||
# we prevent building when there is no python available
|
||||
# as it's not possible anyway, and to cause dependents to
|
||||
# fail to build
|
||||
[ unless [ python.configured ] : <build>no ]
|
||||
<dependency>config-warning
|
||||
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
[ cond $(is-py3) : <python>$(py3-version) ]
|
||||
: # default build
|
||||
<link>shared
|
||||
: # usage requirements
|
||||
<link>static:<define>BOOST_PYTHON_STATIC_LIB
|
||||
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
lib_boost_python ;
|
||||
boost-install boost_python ;
|
||||
|
||||
if $(py3-version)
|
||||
{
|
||||
lib_boost_python yes ;
|
||||
boost-install boost_python3 ;
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from SCons.Variables import *
|
||||
from SCons.Script import AddOption
|
||||
from collections import OrderedDict
|
||||
import platform
|
||||
from . import ui
|
||||
from . import cxx
|
||||
from . import python
|
||||
from . import boost
|
||||
|
||||
def add_options(vars):
|
||||
ui.add_option('-V', '--verbose', dest='verbose', action='store_true', help='verbose mode: print full commands.')
|
||||
python.add_options(vars)
|
||||
boost.add_options(vars)
|
||||
|
||||
vars.Add('CXX')
|
||||
vars.Add('CPPPATH', converter=lambda v:v.split())
|
||||
vars.Add('CCFLAGS', converter=lambda v:v.split())
|
||||
vars.Add('CXXFLAGS', converter=lambda v:v.split())
|
||||
vars.Add('LIBPATH', converter=lambda v:v.split())
|
||||
vars.Add('LIBS', converter=lambda v:v.split())
|
||||
vars.Add('PYTHON')
|
||||
vars.Add('PYTHONLIBS')
|
||||
vars.Add('prefix')
|
||||
vars.Add('boostbook_prefix',
|
||||
vars.Add('CXX11'))
|
||||
|
||||
ui.add_variable(vars, ("arch", "target architeture", platform.machine()))
|
||||
ui.add_variable(vars, ("toolchain", "toolchain to use", 'gcc'))
|
||||
ui.add_variable(vars, ListVariable("variant", "Build configuration", "release", ["release", "debug", "profile"]))
|
||||
ui.add_variable(vars, ListVariable("link", "Library linking", "dynamic", ["static", "dynamic"]))
|
||||
ui.add_variable(vars, ListVariable("threading", "Multi-threading support", "multi", ["single", "multi"]))
|
||||
ui.add_variable(vars, EnumVariable("layout", "Layout of library names and header locations", "versioned", ["versioned", "system"]))
|
||||
ui.add_variable(vars, PathVariable("stagedir", "If --stage is passed install only compiled library files in this location", "stage", PathVariable.PathAccept))
|
||||
ui.add_variable(vars, PathVariable("prefix", "Install prefix", "/usr/local", PathVariable.PathAccept))
|
||||
|
||||
|
||||
def get_checks():
|
||||
checks = OrderedDict()
|
||||
checks['cxx'] = cxx.check
|
||||
checks['python'] = python.check
|
||||
checks['boost'] = boost.check
|
||||
return checks
|
||||
|
||||
|
||||
def set_property(env, **kw):
|
||||
|
||||
from toolchains.gcc import features as gcc_features
|
||||
from toolchains.msvc import features as msvc_features
|
||||
|
||||
if 'gcc' in env['TOOLS']: features = gcc_features
|
||||
elif 'msvc' in env['TOOLS']: features = msvc_features
|
||||
else: raise Error('unknown toolchain')
|
||||
features.init_once(env)
|
||||
for (prop,value) in kw.items():
|
||||
getattr(features, prop, lambda x, y : None)(env, value)
|
||||
env[prop.upper()] = value
|
||||
|
||||
|
||||
def boost_suffix(env):
|
||||
suffix = str()
|
||||
|
||||
if env["layout"] == "versioned":
|
||||
if "gcc" in env["TOOLS"]:
|
||||
if env['CXX'] in ('clang', 'clang++'):
|
||||
suffix += "-clang" + "".join(env["CXXVERSION"].split(".")[0:2])
|
||||
else: # assume g++
|
||||
suffix += "-gcc" + "".join(env["CXXVERSION"].split(".")[0:2])
|
||||
if env["THREADING"] == "multi":
|
||||
suffix += "-mt"
|
||||
if env["DEBUG"]:
|
||||
suffix += "-d"
|
||||
if env["layout"] == "versioned":
|
||||
suffix += "-" + "_".join(env["BPL_VERSION"].split("."))
|
||||
|
||||
return suffix
|
||||
|
||||
|
||||
def prepare_build_dir(env):
|
||||
|
||||
vars = {}
|
||||
env["boost_suffix"] = boost_suffix
|
||||
build_dir="bin.SCons"
|
||||
# FIXME: Support 'toolchain' variable properly.
|
||||
# For now, we simply check whether $CXX refers to clang or gcc.
|
||||
if "gcc" in env["TOOLS"]:
|
||||
if env['CXX'] in ('clang', 'clang++'):
|
||||
build_dir+="/clang-%s"%env["CXXVERSION"]
|
||||
else: # assume g++
|
||||
build_dir+="/gcc-%s"%env["CXXVERSION"]
|
||||
default_cxxflags = ['-ftemplate-depth-128', '-Wall', '-g', '-O2']
|
||||
vars['CXXFLAGS'] = env.get('CXXFLAGS', default_cxxflags)
|
||||
elif "msvc" in env["TOOLS"]:
|
||||
build_dir+="/msvc-%s"%env["MSVS_VERSION"]
|
||||
vars['BOOST_BUILD_DIR'] = build_dir
|
||||
vars['BOOST_SUFFIX'] = "${boost_suffix(__env__)}"
|
||||
env.Replace(**vars)
|
||||
return build_dir
|
||||
|
||||
|
||||
def variants(env):
|
||||
|
||||
env.Prepend(CPPPATH = "#/include", CPPDEFINES = ["BOOST_ALL_NO_LIB=1"])
|
||||
set_property(env, architecture = env['TARGET_ARCH'])
|
||||
for variant in env["variant"]:
|
||||
e = env.Clone()
|
||||
e["current_variant"] = variant
|
||||
set_property(env, profile = False)
|
||||
if variant == "release":
|
||||
set_property(e, optimize = "speed", debug = False)
|
||||
elif variant == "debug":
|
||||
set_property(e, optimize = "no", debug = True)
|
||||
elif variant == "profile":
|
||||
set_property(e, optimize = "speed", profile = True, debug = True)
|
||||
for linking in env["link"]:
|
||||
e["linking"] = linking
|
||||
if linking == "dynamic":
|
||||
e["LINK_DYNAMIC"] = True
|
||||
else:
|
||||
e["LINK_DYNAMIC"] = False
|
||||
for threading in e["threading"]:
|
||||
e["current_threading"] = threading
|
||||
set_property(e, threading = threading)
|
||||
yield e
|
||||
@@ -1,45 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from . import ui
|
||||
import os
|
||||
|
||||
def add_options(vars):
|
||||
|
||||
ui.add_option("--boost-prefix", dest="boost_prefix", type="string", nargs=1, action="store",
|
||||
metavar="DIR", default=os.environ.get("BOOST_DIR"),
|
||||
help="prefix for Boost libraries; should have 'include' and 'lib' subdirectories, 'boost' and 'stage\\lib' subdirectories on Windows")
|
||||
ui.add_option("--boost-include", dest="boost_include", type="string", nargs=1, action="store",
|
||||
metavar="DIR", help="location of Boost header files")
|
||||
ui.add_option("--boostbook-prefix", dest="boostbook_prefix", type="string",
|
||||
nargs=1, action="store",
|
||||
metavar="DIR", default="/usr/share/boostbook",
|
||||
help="prefix for BoostBook stylesheets")
|
||||
|
||||
def check(context):
|
||||
|
||||
boost_source_file = r"#include <boost/config.hpp>"
|
||||
|
||||
context.Message('Checking for Boost...')
|
||||
|
||||
boost_prefix = context.env.GetOption('boost_prefix')
|
||||
boost_include = context.env.GetOption('boost_include')
|
||||
boostbook_prefix = context.env.GetOption('boostbook_prefix')
|
||||
incpath=None
|
||||
if boost_include:
|
||||
incpath=boost_include
|
||||
elif boost_prefix:
|
||||
incpath=boost_prefix
|
||||
if incpath:
|
||||
context.env.AppendUnique(CPPPATH=[incpath])
|
||||
if not context.TryCompile(boost_source_file, '.cpp'):
|
||||
context.Result(0)
|
||||
return False
|
||||
context.env.AppendUnique(boostbook_prefix=boostbook_prefix)
|
||||
context.Result(1)
|
||||
return True
|
||||
@@ -1,30 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from . import ui
|
||||
import os
|
||||
|
||||
def add_options(vars):
|
||||
|
||||
pass
|
||||
|
||||
def check(context):
|
||||
|
||||
source = r"""#if __cplusplus < 201103L
|
||||
#error no C++11
|
||||
#endif"""
|
||||
|
||||
context.Message('Checking for C++11 support...')
|
||||
|
||||
if not context.TryCompile(source, '.cpp'):
|
||||
context.env['CXX11'] = False
|
||||
context.Result(0)
|
||||
else:
|
||||
context.env['CXX11'] = True
|
||||
context.Result(1)
|
||||
return True
|
||||
@@ -1,98 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from . import ui
|
||||
|
||||
def add_options(vars):
|
||||
|
||||
ui.add_option('--python', help='the python executable')
|
||||
|
||||
|
||||
def check(context):
|
||||
|
||||
python_source_file = r"""
|
||||
// If defined, enforces linking againg PythonXXd.lib, which
|
||||
// is usually not included in Python environments.
|
||||
#undef _DEBUG
|
||||
#include "Python.h"
|
||||
int main()
|
||||
{
|
||||
Py_Initialize();
|
||||
Py_Finalize();
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
|
||||
import platform
|
||||
import subprocess
|
||||
import re, os
|
||||
|
||||
def check_python(cmd):
|
||||
return subprocess.check_output([python, '-c', cmd]).strip()
|
||||
|
||||
def check_sysconfig(cmd):
|
||||
r = check_python('import distutils.sysconfig as c; print(c.%s)'%cmd)
|
||||
return r if r != 'None' else ''
|
||||
|
||||
context.Message('Checking for Python...')
|
||||
python = context.env.GetOption('python') or 'python'
|
||||
context.env['PYTHON'] = python
|
||||
incpath = check_sysconfig('get_python_inc()')
|
||||
context.env.AppendUnique(CPPPATH=[incpath])
|
||||
if platform.system() == 'Windows':
|
||||
version = check_python('import sys; print("%d%d"%sys.version_info[0:2])')
|
||||
prefix = check_python('import sys; print(sys.prefix)')
|
||||
libfile = os.path.join(prefix, 'libs', 'python%s.lib'%version)
|
||||
libpath = os.path.join(prefix, 'libs')
|
||||
lib = 'python%s'%version
|
||||
context.env.AppendUnique(LIBS=[lib])
|
||||
else:
|
||||
libpath = check_sysconfig('get_config_var("LIBDIR")')
|
||||
libfile = check_sysconfig('get_config_var("LIBRARY")')
|
||||
match = re.search('(python.*)\.(a|so|dylib)', libfile)
|
||||
lib = None
|
||||
if match:
|
||||
lib = match.group(1)
|
||||
context.env.AppendUnique(PYTHONLIBS=[lib])
|
||||
if match.group(2) == 'a':
|
||||
flags = check_sysconfig('get_config_var("LINKFORSHARED")')
|
||||
if flags is not None:
|
||||
context.env.AppendUnique(LINKFLAGS=flags.split())
|
||||
context.env.AppendUnique(LIBPATH=[libpath])
|
||||
oldlibs = context.AppendLIBS([lib])
|
||||
flags = check_sysconfig('get_config_var("MODLIBS")')
|
||||
flags += ' ' + check_sysconfig('get_config_var("SHLIBS")')
|
||||
flags = [f[2:] for f in flags.strip().split() if f.startswith('-l')]
|
||||
if flags:
|
||||
context.AppendLIBS([flags])
|
||||
result = context.TryLink(python_source_file,'.cpp')
|
||||
if not result and context.env['PLATFORM'] == 'darwin':
|
||||
# Sometimes we need some extra stuff on Mac OS
|
||||
frameworkDir = libpath # search up the libDir tree for the proper home for frameworks
|
||||
while frameworkDir and frameworkDir != "/":
|
||||
frameworkDir, d2 = os.path.split(frameworkDir)
|
||||
if d2 == "Python.framework":
|
||||
if not "Python" in os.listdir(os.path.join(frameworkDir, d2)):
|
||||
context.Result(0)
|
||||
print((
|
||||
"Expected to find Python in framework directory %s, but it isn't there"
|
||||
% frameworkDir))
|
||||
return False
|
||||
break
|
||||
context.env.AppendUnique(LINKFLAGS="-F%s" % frameworkDir)
|
||||
result = context.TryLink(python_source_file,'.cpp')
|
||||
if not result:
|
||||
context.Result(0)
|
||||
print("Cannot link program with Python.")
|
||||
return False
|
||||
if context.env['PLATFORM'] == 'darwin':
|
||||
context.env['LDMODULESUFFIX'] = '.so'
|
||||
context.Result(1)
|
||||
context.SetLIBS(oldlibs)
|
||||
context.env.AppendUnique(PYTHONLIBS=[lib] + flags)
|
||||
return True
|
||||
@@ -1,18 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import traceback
|
||||
|
||||
def append_feature_flag(env, **kw):
|
||||
stack = traceback.extract_stack(limit = 3)
|
||||
feature = stack[0][2].upper()
|
||||
for (key, val) in kw.items():
|
||||
feature_var = feature + "_" + key
|
||||
env.AppendUnique(**{ key : "$" + feature_var })
|
||||
env[feature_var] = val
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from . import append_feature_flag
|
||||
|
||||
class features:
|
||||
|
||||
@classmethod
|
||||
def init_once(cls, env):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def architecture(env, arch):
|
||||
if arch:
|
||||
flag = {'x86' : '-m32',
|
||||
'x86_64' : '-m64',}.get(arch)
|
||||
if flag:
|
||||
append_feature_flag(env, CCFLAGS = flag)
|
||||
|
||||
@staticmethod
|
||||
def optimize(env, optimize):
|
||||
if not optimize or optimize == "no":
|
||||
append_feature_flag(env, CCFLAGS = "-O0 -fno-inline")
|
||||
elif optimize == "speed":
|
||||
append_feature_flag(env, CCFLAGS = "-O3 -finline-functions -Wno-inline")
|
||||
elif optimize == "space":
|
||||
append_feature_flag(env, CCFLAGS = "-Os")
|
||||
else:
|
||||
append_feature_flag(env, CCFLAGS = "")
|
||||
|
||||
@staticmethod
|
||||
def profile(env, profile):
|
||||
if profile:
|
||||
append_feature_flag(env, CCFLAGS = "-pg", LINKFLAGS = "-pg")
|
||||
else:
|
||||
append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
|
||||
|
||||
@staticmethod
|
||||
def threading(env, threading):
|
||||
if threading == "multi":
|
||||
append_feature_flag(env, CCFLAGS = "-pthread", LINKFLAGS = "-pthread")
|
||||
else:
|
||||
append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
|
||||
|
||||
@staticmethod
|
||||
def debug(env, debug):
|
||||
if debug:
|
||||
append_feature_flag(env, CCFLAGS = "-g", CPPDEFINES = [])
|
||||
else:
|
||||
append_feature_flag(env, CCFLAGS = "", CPPDEFINES = "NDEBUG")
|
||||
@@ -1,57 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from . import append_feature_flag
|
||||
|
||||
class features:
|
||||
|
||||
@classmethod
|
||||
def init_once(cls, env):
|
||||
env.AppendUnique(CCFLAGS = ['-TP', '/Z7', '/W3' ,'/GR', '/MDd', '/Zc:forScope', '/Zc:wchar_t', '/wd4675', '/EHs'])
|
||||
env.AppendUnique(LINKFLAGS = ['/subsystem:console'])
|
||||
|
||||
@staticmethod
|
||||
def architecture(env, arch):
|
||||
if arch:
|
||||
flag = {'x86' : '/MACHINE:X86',
|
||||
'x86_64' : '/MACHINE:X64',}.get(arch)
|
||||
if flag:
|
||||
append_feature_flag(env, LINKFLAGS = flag)
|
||||
|
||||
@staticmethod
|
||||
def optimize(env, optimize):
|
||||
#if not optimize or optimize == "no":
|
||||
# append_feature_flag(env, CCFLAGS = "-O0 -fno-inline")
|
||||
#elif optimize == "speed":
|
||||
# append_feature_flag(env, CCFLAGS = "-O3 -finline-functions -Wno-inline")
|
||||
#elif optimize == "space":
|
||||
# append_feature_flag(env, CCFLAGS = "-Os")
|
||||
#else:
|
||||
append_feature_flag(env, CCFLAGS = "")
|
||||
|
||||
@staticmethod
|
||||
def profile(env, profile):
|
||||
#if profile:
|
||||
# append_feature_flag(env, CCFLAGS = "-pg", LINKFLAGS = "-pg")
|
||||
#else:
|
||||
append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
|
||||
|
||||
@staticmethod
|
||||
def threading(env, threading):
|
||||
#if threading == "multi":
|
||||
# append_feature_flag(env, CCFLAGS = "/MT")
|
||||
#else:
|
||||
# append_feature_flag(env, CCFLAGS = "", LINKFLAGS = "")
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def debug(env, debug):
|
||||
#if debug:
|
||||
# append_feature_flag(env, CCFLAGS = "-g", CPPDEFINES = [])
|
||||
#else:
|
||||
append_feature_flag(env, CCFLAGS = "", CPPDEFINES = "NDEBUG")
|
||||
@@ -1,44 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Based on SCons/Tool/gcc.py
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import SCons.Util
|
||||
import SCons.Tool.cc
|
||||
|
||||
compilers = ['clang']
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for clang to an Environment."""
|
||||
SCons.Tool.cc.generate(env)
|
||||
|
||||
env['CC'] = env.Detect(compilers) or 'clang'
|
||||
if env['PLATFORM'] in ['cygwin', 'win32']:
|
||||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
||||
else:
|
||||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
|
||||
# determine compiler version
|
||||
if env['CC']:
|
||||
#pipe = SCons.Action._subproc(env, [env['CC'], '-dumpversion'],
|
||||
pipe = SCons.Action._subproc(env, [env['CC'], '--version'],
|
||||
stdin = 'devnull',
|
||||
stderr = 'devnull',
|
||||
stdout = subprocess.PIPE)
|
||||
if pipe.wait() != 0: return
|
||||
# clang -dumpversion is of no use
|
||||
line = pipe.stdout.readline()
|
||||
match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line)
|
||||
if match:
|
||||
env['CCVERSION'] = match.group(1)
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
||||
@@ -1,70 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from SCons.Script import AddOption, Flatten
|
||||
from SCons.Script import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Defaults import Copy
|
||||
from SCons.Script import *
|
||||
from subprocess import check_output, STDOUT, CalledProcessError
|
||||
import sys
|
||||
import os
|
||||
|
||||
def QuickBook(env, target, source, dependencies=[]):
|
||||
"""Compile a QuickBook document to BoostBook."""
|
||||
|
||||
for d in dependencies:
|
||||
env.Depends(target, d)
|
||||
env.Command(target, source, 'quickbook --input-file=$SOURCE --output-file=$TARGET')
|
||||
|
||||
|
||||
def BoostBook(env, target, source, resources=[], args=[]):
|
||||
"""Compile a BoostBook document to DocBook."""
|
||||
|
||||
bb_prefix = env.GetOption('boostbook_prefix')
|
||||
stylesheet = bb_prefix + '/xsl/docbook.xsl'
|
||||
env.Command(target, source,
|
||||
'xsltproc {} -o $TARGET {} $SOURCE'.format(' '.join(args), stylesheet))
|
||||
|
||||
|
||||
def BoostHTML(env, target, source, resources=[], args=[]):
|
||||
"""Compile a DocBook document to HTML."""
|
||||
|
||||
bb_prefix = env.GetOption('boostbook_prefix')
|
||||
stylesheet = bb_prefix + '/xsl/html.xsl'
|
||||
env.Command(target, source,
|
||||
'xsltproc {} -o $TARGET/ {} $SOURCE'.format(' '.join(args), stylesheet))
|
||||
prefix=Dir('.').path
|
||||
for r in resources:
|
||||
r = File(r).path[len(prefix)+1:]
|
||||
env.Depends(target, target + r)
|
||||
env.Command(target + r, r, Copy('$TARGET', '$SOURCE'))
|
||||
|
||||
|
||||
def BoostRST(env, target, source, resources=[]):
|
||||
"""Compile an RST document to HTML."""
|
||||
|
||||
prefix=Dir('.').path
|
||||
for r in resources:
|
||||
r = File(r).path[len(prefix)+1:]
|
||||
env.Depends('html/' + r, r)
|
||||
env.Command('html/' + r, r, Copy('$TARGET', '$SOURCE'))
|
||||
env.Command(target, source,
|
||||
'rst2html --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript --stylesheet=rst.css $SOURCE $TARGET')
|
||||
|
||||
|
||||
def exists(env):
|
||||
return True
|
||||
|
||||
|
||||
def generate(env):
|
||||
|
||||
env.AddMethod(QuickBook)
|
||||
env.AddMethod(BoostBook)
|
||||
env.AddMethod(BoostHTML)
|
||||
env.AddMethod(BoostRST)
|
||||
@@ -1,85 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from SCons.Script import AddOption, COMMAND_LINE_TARGETS, BUILD_TARGETS
|
||||
import distutils.sysconfig
|
||||
import platform
|
||||
|
||||
|
||||
def BoostLibrary(env, lib, sources, make_aliases = True, **kw):
|
||||
if env["LINK_DYNAMIC"]:
|
||||
lib_node = env.SharedLibrary("boost_" + lib + env["BOOST_SUFFIX"], sources, **kw)
|
||||
else:
|
||||
lib_node = env.StaticLibrary("boost_" + lib + env["BOOST_SUFFIX"], sources, **kw)
|
||||
|
||||
if make_aliases:
|
||||
if env.GetOption("stage"):
|
||||
env.Alias(lib, env.Install(env.Dir("$stagedir", "#"), lib_node))
|
||||
env.Default(env.Alias(lib, lib_node))
|
||||
|
||||
if env.GetOption("install"):
|
||||
env.Alias(lib, env.Install("$prefix/lib", lib_node))
|
||||
env.Alias(lib, env.Install('$prefix/include/boost', '#/include/boost/python'))
|
||||
env.Alias(lib, env.Install('$prefix/include/boost', '#/include/boost/python.hpp'))
|
||||
return lib_node
|
||||
|
||||
|
||||
def BoostUseLib(env, lib):
|
||||
build_dir = env.Dir('$BOOST_CURRENT_VARIANT_DIR/src')
|
||||
env.AppendUnique(LIBPATH = [build_dir],
|
||||
LIBS = ["boost_" + lib + env["BOOST_SUFFIX"]])
|
||||
if env.get("BOOST_TEST"):
|
||||
env.AppendUnique(RPATH = [build_dir])
|
||||
if platform.system() == 'Windows':
|
||||
env.PrependENVPath('PATH', build_dir.abspath)
|
||||
else:
|
||||
env.PrependENVPath('LD_LIBRARY_PATH', build_dir.abspath)
|
||||
|
||||
|
||||
def PythonExtension(env, lib, sources, **kw):
|
||||
if env["LINK_DYNAMIC"]:
|
||||
ext = env.SharedLibrary(lib, sources, SHLIBPREFIX='', SHLIBSUFFIX=distutils.sysconfig.get_config_var("SO"), **kw)
|
||||
return ext
|
||||
|
||||
|
||||
def boost_copy_func(dest, source, env):
|
||||
import os, stat, shutil
|
||||
|
||||
if os.path.isdir(source):
|
||||
if os.path.exists(dest):
|
||||
if not os.path.isdir(dest):
|
||||
raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))
|
||||
else:
|
||||
os.makedirs(dest)
|
||||
for file in os.listdir(source):
|
||||
if file == ".svn": continue
|
||||
boost_copy_func(os.path.join(dest, file), os.path.join(source, file), env)
|
||||
else:
|
||||
shutil.copy2(source, dest)
|
||||
st = os.stat(source)
|
||||
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def exists(env):
|
||||
return True
|
||||
|
||||
|
||||
def generate(env):
|
||||
env.AddMethod(BoostLibrary)
|
||||
env.AddMethod(BoostUseLib)
|
||||
env.AddMethod(PythonExtension)
|
||||
|
||||
env.Replace(
|
||||
INSTALL = boost_copy_func,
|
||||
BOOST_CURRENT_VARIANT_DIR = "#/$BOOST_BUILD_DIR/$current_variant/$linking/threading-$current_threading"
|
||||
)
|
||||
|
||||
AddOption('--stage', dest='stage', action="store_true")
|
||||
AddOption('--install', dest='install', action="store_true")
|
||||
@@ -1,123 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from SCons.Script import AddOption, Flatten
|
||||
from SCons.Script import Builder
|
||||
from SCons.Action import Action
|
||||
from subprocess import check_output, STDOUT, CalledProcessError
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def BoostCompileTest(env, test, source = None, **kw):
|
||||
|
||||
def gen_result(target, source, env=env):
|
||||
target_file = target[0].abspath
|
||||
result_file = os.path.splitext(target_file)[0] + '.result'
|
||||
if sys.stdout.isatty():
|
||||
env['RESULT']='\033[92mPASS\033[0m'
|
||||
else:
|
||||
env['RESULT']='PASS'
|
||||
|
||||
with open(result_file, 'w+') as result:
|
||||
result.write('Result: {}\n'.format('pass'))
|
||||
|
||||
obj = env.Object(test, source if source is not None else test + '.cpp')
|
||||
env.AddPostAction(obj, Action(gen_result, cmdstr=None))
|
||||
env.AddPostAction(obj, Action('@echo $RESULT'))
|
||||
return obj
|
||||
|
||||
def BoostRun(env, prog, target, command = '$SOURCE'):
|
||||
|
||||
def call(target, source, env=env):
|
||||
cmd = env.subst(command, target=target, source=source)
|
||||
result_file = env.subst('$TARGET', target=target)
|
||||
output=''
|
||||
try:
|
||||
output=check_output(cmd, stderr=STDOUT, shell=True, env=env['ENV'])
|
||||
success=True
|
||||
except CalledProcessError as e:
|
||||
output=e.output
|
||||
success=False
|
||||
with open(result_file, 'w+') as result:
|
||||
result.write('Result: {}\n'.format(success and 'pass' or 'fail'))
|
||||
result.write('Output: {}\n'.format(output))
|
||||
if sys.stdout.isatty():
|
||||
env['RESULT']=success and '\033[92mPASS\033[0m' or '\033[91mFAIL\033[0m'
|
||||
else:
|
||||
env['RESULT']=success and 'PASS' or 'FAIL'
|
||||
|
||||
testcomstr = env.get('TESTCOMSTR')
|
||||
if testcomstr:
|
||||
run = env.Command(target, prog, Action(call, cmdstr=testcomstr))
|
||||
else:
|
||||
run = env.Command(target, prog, Action(call, cmdstr=command))
|
||||
env.AddPostAction(target, Action('@echo $RESULT'))
|
||||
return run
|
||||
|
||||
|
||||
def BoostRunPythonScript(env, script):
|
||||
return env.BoostRun(env.File(script), script.replace('.py', '.result'), '"${PYTHON}" $SOURCE')
|
||||
|
||||
|
||||
def BoostRunTest(env, test, source = None, command = '$SOURCE', command_sources = [], **kw):
|
||||
test_prog = env.Program(test, (source is None) and (test + ".cpp") or source, **kw)
|
||||
command += '> $TARGET'
|
||||
run = env.BoostRun([test_prog, command_sources], test + '.result', command)
|
||||
return run
|
||||
|
||||
|
||||
def BoostRunTests(env, tests, **kw):
|
||||
run = []
|
||||
for test in Flatten(tests):
|
||||
run += env.BoostRunTest(test, **kw)
|
||||
return run
|
||||
|
||||
def BoostCompileTests(env, tests, **kw):
|
||||
comp = []
|
||||
for test in Flatten(tests):
|
||||
comp += env.BoostCompileTest(test, **kw)
|
||||
return comp
|
||||
|
||||
|
||||
def BoostTestSummary(env, tests, **kw):
|
||||
|
||||
def print_summary(target, source, **kw):
|
||||
results = tests
|
||||
failures = [r for r in results
|
||||
if r.get_path().endswith('.result') and not 'Result: pass' in r.get_contents()]
|
||||
print('%s tests; %s pass; %s fails'%(len(results), len(results)-len(failures), len(failures)))
|
||||
if failures:
|
||||
print('For detailed failure reports, see:')
|
||||
for f in failures:
|
||||
print(f.get_path())
|
||||
|
||||
testsumcomstr = env.get('TESTSUMCOMSTR')
|
||||
if testsumcomstr:
|
||||
run = env.Command('summary', tests, Action(print_summary, cmdstr=testsumcomstr))
|
||||
else:
|
||||
run = env.Command('summary', tests, print_summary, cmdstr='')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def exists(env):
|
||||
return True
|
||||
|
||||
|
||||
def generate(env):
|
||||
AddOption('--test', dest='test', action="store_true")
|
||||
|
||||
env.AddMethod(BoostCompileTest)
|
||||
env.AddMethod(BoostRun)
|
||||
env.AddMethod(BoostRunPythonScript)
|
||||
env.AddMethod(BoostRunTest)
|
||||
env.AddMethod(BoostRunTests)
|
||||
env.AddMethod(BoostCompileTests)
|
||||
env.AddMethod(BoostTestSummary)
|
||||
96
config/ui.py
@@ -1,96 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from SCons.Script import AddOption
|
||||
import sys
|
||||
|
||||
variables=[] # remember 'public' variables
|
||||
options=[]
|
||||
|
||||
def add_option(*args, **kwds):
|
||||
"""Capture the help messages so we can produce a helpful usage text."""
|
||||
options.append('{:25} {}'.format(', '.join(args), kwds.get('help', '')))
|
||||
AddOption(*args, **kwds)
|
||||
|
||||
def add_variable(vars, var):
|
||||
variables.append(var[0])
|
||||
vars.Add(var)
|
||||
|
||||
|
||||
def options_help(env):
|
||||
|
||||
return '\n '.join(options)
|
||||
|
||||
|
||||
def variables_help(vars, env):
|
||||
"""This is cloned from SCons' Variables.GenerateHelpText, to only report 'public' variables."""
|
||||
|
||||
opts = [o for o in vars.options if o.key in variables]
|
||||
|
||||
def format(opt):
|
||||
if opt.key in env:
|
||||
actual = env.subst('${%s}' % opt.key)
|
||||
else:
|
||||
actual = None
|
||||
return vars.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
|
||||
text = ''.join([f for f in map(format, opts) if f])
|
||||
lines = [' %s'%l for l in text.split('\n')] # Add some indentation
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
|
||||
def help(vars, env):
|
||||
|
||||
return """Usage: scons [--option...] [variable=value...] [target...]
|
||||
|
||||
available options:
|
||||
|
||||
{}
|
||||
|
||||
available variables:
|
||||
{}
|
||||
""".format(options_help(env), variables_help(vars, env))
|
||||
|
||||
def pretty_output(env):
|
||||
|
||||
colors = {}
|
||||
colors['red'] = '\033[31m'
|
||||
colors['green'] = '\033[32m'
|
||||
colors['blue'] = '\033[34m'
|
||||
colors['yellow'] = '\033[93m'
|
||||
colors['Red'] = '\033[91m'
|
||||
colors['Green'] = '\033[92m'
|
||||
colors['Blue'] = '\033[94m'
|
||||
colors['Purple'] = '\033[95m'
|
||||
colors['Cyan'] = '\033[96m'
|
||||
colors['end'] = '\033[0m'
|
||||
|
||||
#If the output is not a terminal, remove the colors
|
||||
if not sys.stdout.isatty():
|
||||
for key, value in colors.iteritems():
|
||||
colors[key] = ''
|
||||
|
||||
compile_source_message = '{green}Compiling $TARGET{end}'.format(**colors)
|
||||
compile_shared_source_message = '{green}Compiling $TARGET{end}'.format(**colors)
|
||||
link_program_message = '{blue}Linking $TARGET{end}'.format(**colors)
|
||||
link_library_message = '{blue}Linking $TARGET{end}'.format(**colors)
|
||||
ranlib_library_message = '{blue}Ranlib $TARGET{end}'.format(**colors)
|
||||
link_shared_library_message = '{blue}Linking $TARGET{end}'.format(**colors)
|
||||
test_message = '{blue}Testing $SOURCE{end}'.format(**colors)
|
||||
testsum_message = '{Blue}Test Summary{end}'.format(**colors)
|
||||
|
||||
env.Replace(CXXCOMSTR = compile_source_message,
|
||||
CCCOMSTR = compile_source_message,
|
||||
SHCCCOMSTR = compile_shared_source_message,
|
||||
SHCXXCOMSTR = compile_shared_source_message,
|
||||
ARCOMSTR = link_library_message,
|
||||
RANLIBCOMSTR = ranlib_library_message,
|
||||
SHLINKCOMSTR = link_shared_library_message,
|
||||
LINKCOMSTR = link_program_message,
|
||||
TESTCOMSTR = test_message,
|
||||
TESTSUMCOMSTR = testsum_message)
|
||||
25
doc/Jamfile
@@ -4,10 +4,14 @@
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import boostbook ;
|
||||
import quickbook ;
|
||||
import docutils ;
|
||||
import os ;
|
||||
|
||||
path-constant here : . ;
|
||||
path-constant images : html/images ;
|
||||
|
||||
|
||||
project python/doc
|
||||
: requirements
|
||||
-<xsl:param>boost.defaults=Boost
|
||||
@@ -17,9 +21,16 @@ project python/doc
|
||||
<format>html:<xsl:param>chunk.section.depth=1
|
||||
;
|
||||
|
||||
import boostbook ;
|
||||
import quickbook ;
|
||||
import docutils ;
|
||||
make numpy : numpy/index.rst : @sphinx-build ;
|
||||
|
||||
if [ os.name ] = NT
|
||||
{
|
||||
actions sphinx-build { chdir "$(>:D)" && make clean && make html}
|
||||
}
|
||||
else
|
||||
{
|
||||
actions sphinx-build { make -C "$(>:D)" clean html}
|
||||
}
|
||||
|
||||
boostbook python : python.qbk
|
||||
: <format>html:<name>$(here)/html
|
||||
@@ -47,3 +58,9 @@ html article : article.rst
|
||||
: <location>html
|
||||
<docutils-html>"--link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript --stylesheet=rst.css"
|
||||
;
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease : python tutorial reference numpy article ;
|
||||
explicit boostrelease ;
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# -*- python -*-
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
Import('env')
|
||||
|
||||
env.QuickBook('python.bbk', 'python.qbk',
|
||||
['building.qbk',
|
||||
'configuration.qbk',
|
||||
'support.qbk',
|
||||
'faq.qbk',
|
||||
'glossary.qbk'])
|
||||
|
||||
env.QuickBook('tutorial.bbk', 'tutorial.qbk')
|
||||
env.QuickBook('reference.bbk', 'reference.qbk',
|
||||
Glob('reference/*.qbk'))
|
||||
|
||||
|
||||
env.BoostBook('python.dbk', 'python.bbk')
|
||||
env.BoostBook('tutorial.dbk', 'tutorial.bbk')
|
||||
env.BoostBook('reference.dbk', 'reference.bbk')
|
||||
|
||||
images = Glob('images/*.*') + Glob('images/callouts/*.*')
|
||||
|
||||
env.BoostHTML('html/', 'python.dbk',
|
||||
resources=['boostbook.css'] + images,
|
||||
args=['--stringparam', 'generate.toc', '"library nop; chapter toc; section toc;"',
|
||||
'--stringparam', 'html.stylesheet', 'boostbook.css',
|
||||
'--stringparam', 'boost.image.src', 'images/bpl.png',
|
||||
'--stringparam', 'boost.graphics.root', 'images/',
|
||||
'--stringparam', 'boost.defaults', 'none',
|
||||
'--param', 'toc.max.depth', '3',
|
||||
'--param', 'toc.section.depth' ,'2',
|
||||
'--param', 'chunk.section.depth', '1'])
|
||||
env.BoostHTML('html/tutorial/', 'tutorial.dbk',
|
||||
args=['--stringparam', 'html.stylesheet', '../boostbook.css',
|
||||
'--stringparam', 'boost.image.src', '../images/bpl.png',
|
||||
'--stringparam', 'boost.graphics.root', '../images/'])
|
||||
env.BoostHTML('html/reference/', 'reference.dbk',
|
||||
args=['--stringparam', 'html.stylesheet', '../boostbook.css',
|
||||
'--stringparam', 'boost.image.src', '../images/bpl.png',
|
||||
'--stringparam', 'boost.graphics.root', '../images/'])
|
||||
|
||||
env.BoostRST('html/article.html', 'article.rst', resources=['rst.css'])
|
||||
83
doc/fabscript
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- python -*-
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from faber.tools.xslt import xsltflags
|
||||
from faber.tools.boost import quickbook, boostbook
|
||||
from faber.artefacts import html
|
||||
from glob import glob as G
|
||||
from os import makedirs
|
||||
from os.path import relpath, dirname, exists
|
||||
from shutil import copyfile
|
||||
|
||||
|
||||
def glob(pattern):
|
||||
prefix = srcdir + '/'
|
||||
p = len(prefix)+1
|
||||
return [f[p:] for f in G(prefix + pattern)]
|
||||
|
||||
|
||||
class make_html(action):
|
||||
|
||||
def __init__(self):
|
||||
action.__init__(self, 'make_html', self.process)
|
||||
|
||||
def map(self, fs):
|
||||
return boostbook.html.map(fs)
|
||||
|
||||
def process(self, target, source):
|
||||
boostbook.html(target, source[0:1])
|
||||
for s in source[1:]:
|
||||
t = target[0]._filename + relpath(s._filename, srcdir)
|
||||
d = dirname(t)
|
||||
if not exists(d):
|
||||
makedirs(d)
|
||||
copyfile(s._filename, t)
|
||||
|
||||
|
||||
sphinx_build = action('sphinx-build', 'sphinx-build -b html $(>) $(<)')
|
||||
rst2html = action('rst2html', 'rst2html --trim-footnote-reference-space --footnote-references=superscript --stylesheet=$(>:D)/rst.css $(>) $(<)')
|
||||
|
||||
python_bbk = rule(quickbook.process, 'python.bbk', 'python.qbk',
|
||||
dependencies=['release_notes.qbk',
|
||||
'building.qbk',
|
||||
'configuration.qbk',
|
||||
'suport.qbk',
|
||||
'faq.qbk',
|
||||
'glossary.qbk'])
|
||||
tutorial_bbk = rule(quickbook.process, 'tutorial.bbk', 'tutorial.qbk')
|
||||
reference_bbk = rule(quickbook.process, 'reference.bbk', 'reference.qbk')
|
||||
|
||||
python_db = rule(boostbook.db, 'python.db', python_bbk)
|
||||
tutorial_db = rule(boostbook.db, 'tutorial.db', tutorial_bbk)
|
||||
reference_db = rule(boostbook.db, 'reference.db', reference_bbk)
|
||||
|
||||
python = html.dir(make_html(), 'html', [python_db, 'boostbook.css'] + glob('/images/*.*') + glob('/images/callouts/*.*'),
|
||||
features=xsltflags('--stringparam generate.toc "library nop; chaper toc; section toc;"',
|
||||
'--stringparam html.stylesheet boostbook.css',
|
||||
'--stringparam boost.image.src images/bpl.png',
|
||||
'--stringparam boost.graphics.root images/',
|
||||
'--stringparam boost.defaults none',
|
||||
'--param toc.max.depth 3',
|
||||
'--param toc.section.depth 2',
|
||||
'--param chunk.section.depth 1'))
|
||||
tutorial = html.dir(boostbook.html, 'html/tutorial', tutorial_db, dependencies=[python],
|
||||
features=xsltflags('--stringparam html.stylesheet ../boostbook.css',
|
||||
'--stringparam boost.image.src ../images/bpl.png',
|
||||
'--stringparam boost.graphics.root ../images/'))
|
||||
reference = html.dir(boostbook.html, 'html/reference', reference_db, dependencies=[python],
|
||||
features=xsltflags('--stringparam html.stylesheet ../boostbook.css',
|
||||
'--stringparam boost.image.src ../images/bpl.png',
|
||||
'--stringparam boost.graphics.root ../images/'))
|
||||
numpy = rule(sphinx_build, 'html/numpy', 'numpy', attrs=always, dependencies=[python])
|
||||
|
||||
article = rule(rst2html, 'html/article.html', 'article.rst')
|
||||
|
||||
html = alias('html', [python, tutorial, reference, numpy, article])
|
||||
|
||||
default = html
|
||||
0
doc/html/images/python_cpp_mix.png
Executable file → Normal file
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
BIN
doc/images/jam.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
0
doc/internals.html
Executable file → Normal file
0
doc/internals.rst
Executable file → Normal file
133
doc/numpy/Makefile
Normal file
@@ -0,0 +1,133 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
HTMLDIR = ../html/numpy
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
all: html
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(HTMLDIR)
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(HTMLDIR)."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/BoostNumPy.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/BoostNumPy.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/BoostNumPy"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/BoostNumPy"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
make -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
716
doc/numpy/_static/boost.css
Normal file
@@ -0,0 +1,716 @@
|
||||
|
||||
/*=============================================================================
|
||||
Copyright (c) 2004 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Copyright 2013 Niall Douglas additions for colors and alignment.
|
||||
Copyright 2013 Paul A. Bristow additions for more colors and alignments.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompany-
|
||||
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
/*=============================================================================
|
||||
Body defaults
|
||||
=============================================================================*/
|
||||
|
||||
body
|
||||
{
|
||||
margin: 1em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Paragraphs
|
||||
=============================================================================*/
|
||||
|
||||
p
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Program listings
|
||||
=============================================================================*/
|
||||
|
||||
/* Code on paragraphs */
|
||||
p tt.computeroutput
|
||||
{
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
pre.synopsis
|
||||
{
|
||||
font-size: 9pt;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
font-size: 9pt;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
/* Program listings in tables don't get borders */
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
margin: 0pc 0pc 0pc 0pc;
|
||||
padding: 0pc 0pc 0pc 0pc;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Headings
|
||||
=============================================================================*/
|
||||
|
||||
h1, h2, h3, h4, h5, h6
|
||||
{
|
||||
text-align: left;
|
||||
margin: 1em 0em 0.5em 0em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 { font-size: 140%; }
|
||||
h2 { font-weight: bold; font-size: 140%; }
|
||||
h3 { font-weight: bold; font-size: 130%; }
|
||||
h4 { font-weight: bold; font-size: 120%; }
|
||||
h5 { font-weight: normal; font-style: italic; font-size: 110%; }
|
||||
h6 { font-weight: normal; font-style: italic; font-size: 100%; }
|
||||
|
||||
/* Top page titles */
|
||||
title,
|
||||
h1.title,
|
||||
h2.title
|
||||
h3.title,
|
||||
h4.title,
|
||||
h5.title,
|
||||
h6.title,
|
||||
.refentrytitle
|
||||
{
|
||||
font-weight: bold;
|
||||
margin-bottom: 1pc;
|
||||
}
|
||||
|
||||
h1.title { font-size: 140% }
|
||||
h2.title { font-size: 140% }
|
||||
h3.title { font-size: 130% }
|
||||
h4.title { font-size: 120% }
|
||||
h5.title { font-size: 110% }
|
||||
h6.title { font-size: 100% }
|
||||
|
||||
.section h1
|
||||
{
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
font-size: 140%;
|
||||
}
|
||||
|
||||
.section h2 { font-size: 140% }
|
||||
.section h3 { font-size: 130% }
|
||||
.section h4 { font-size: 120% }
|
||||
.section h5 { font-size: 110% }
|
||||
.section h6 { font-size: 100% }
|
||||
|
||||
/* Code on titles */
|
||||
h1 tt.computeroutput { font-size: 140% }
|
||||
h2 tt.computeroutput { font-size: 140% }
|
||||
h3 tt.computeroutput { font-size: 130% }
|
||||
h4 tt.computeroutput { font-size: 130% }
|
||||
h5 tt.computeroutput { font-size: 130% }
|
||||
h6 tt.computeroutput { font-size: 130% }
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
Author
|
||||
=============================================================================*/
|
||||
|
||||
h3.author
|
||||
{
|
||||
font-size: 100%
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Lists
|
||||
=============================================================================*/
|
||||
|
||||
li
|
||||
{
|
||||
font-size: 10pt;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
/* Unordered lists */
|
||||
ul
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Ordered lists */
|
||||
ol
|
||||
{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Links
|
||||
=============================================================================*/
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration: none; /* no underline */
|
||||
}
|
||||
|
||||
a:hover
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Spirit style navigation
|
||||
=============================================================================*/
|
||||
|
||||
.spirit-nav
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.spirit-nav a
|
||||
{
|
||||
color: white;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.spirit-nav img
|
||||
{
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Copyright footer
|
||||
=============================================================================*/
|
||||
.copyright-footer
|
||||
{
|
||||
text-align: right;
|
||||
font-size: 70%;
|
||||
}
|
||||
|
||||
.copyright-footer p
|
||||
{
|
||||
text-align: right;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Table of contents
|
||||
=============================================================================*/
|
||||
|
||||
div.toc
|
||||
{
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.1pc 1pc 0.1pc 1pc;
|
||||
font-size: 80%;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.boost-toc
|
||||
{
|
||||
float: right;
|
||||
padding: 0.5pc;
|
||||
}
|
||||
|
||||
/* Code on toc */
|
||||
.toc .computeroutput { font-size: 120% }
|
||||
|
||||
/* No margin on nested menus */
|
||||
|
||||
.toc dl dl { margin: 0; }
|
||||
|
||||
/*=============================================================================
|
||||
Tables
|
||||
=============================================================================*/
|
||||
|
||||
.table-title,
|
||||
div.table p.title
|
||||
{
|
||||
margin-left: 4%;
|
||||
padding-right: 0.5em;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
|
||||
.informaltable table,
|
||||
.table table
|
||||
{
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
div.informaltable table,
|
||||
div.table table
|
||||
{
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Table Cells */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
padding: 0.5em;
|
||||
text-align: left;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
border: 1pt solid white;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
table.simplelist
|
||||
{
|
||||
width: auto !important;
|
||||
margin: 0em !important;
|
||||
padding: 0em !important;
|
||||
border: none !important;
|
||||
}
|
||||
table.simplelist td
|
||||
{
|
||||
margin: 0em !important;
|
||||
padding: 0em !important;
|
||||
text-align: left !important;
|
||||
font-size: 9pt !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Suppress margins in tables
|
||||
=============================================================================*/
|
||||
|
||||
table th > *:first-child,
|
||||
table td > *:first-child
|
||||
{
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
table th > *:last-child,
|
||||
table td > *:last-child
|
||||
{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Blurbs
|
||||
=============================================================================*/
|
||||
|
||||
div.note,
|
||||
div.tip,
|
||||
div.important,
|
||||
div.caution,
|
||||
div.warning,
|
||||
p.blurb
|
||||
{
|
||||
font-size: 9pt; /* A little bit smaller than the main text */
|
||||
line-height: 1.2;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
p.blurb img
|
||||
{
|
||||
padding: 1pt;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Variable Lists
|
||||
=============================================================================*/
|
||||
|
||||
div.variablelist
|
||||
{
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
/* Make the terms in definition lists bold */
|
||||
div.variablelist dl dt,
|
||||
span.term
|
||||
{
|
||||
font-weight: bold;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
div.variablelist table tbody tr td
|
||||
{
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
padding: 0em 2em 0em 0em;
|
||||
font-size: 10pt;
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.variablelist dl dt
|
||||
{
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
div.variablelist dl dd
|
||||
{
|
||||
margin: 0em 0em 0.5em 2em;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
div.variablelist table tbody tr td p,
|
||||
div.variablelist dl dd p
|
||||
{
|
||||
margin: 0em 0em 0.5em 0em;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Misc
|
||||
=============================================================================*/
|
||||
|
||||
/* Title of books and articles in bibliographies */
|
||||
span.title
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
span.underline
|
||||
{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
span.strikethrough
|
||||
{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* Copyright, Legal Notice */
|
||||
div div.legalnotice p
|
||||
{
|
||||
text-align: left
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Colors
|
||||
=============================================================================*/
|
||||
|
||||
@media screen
|
||||
{
|
||||
body {
|
||||
background-color: #FFFFFF;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* Syntax Highlighting */
|
||||
.keyword { color: #0000AA; }
|
||||
.identifier { color: #000000; }
|
||||
.special { color: #707070; }
|
||||
.preprocessor { color: #402080; }
|
||||
.char { color: teal; }
|
||||
.comment { color: #800000; }
|
||||
.string { color: teal; }
|
||||
.number { color: teal; }
|
||||
.white_bkd { background-color: #FFFFFF; }
|
||||
.dk_grey_bkd { background-color: #999999; }
|
||||
|
||||
/* Links */
|
||||
a, a .keyword, a .identifier, a .special, a .preprocessor
|
||||
a .char, a .comment, a .string, a .number
|
||||
{
|
||||
color: #005a9c;
|
||||
}
|
||||
|
||||
a:visited, a:visited .keyword, a:visited .identifier,
|
||||
a:visited .special, a:visited .preprocessor a:visited .char,
|
||||
a:visited .comment, a:visited .string, a:visited .number
|
||||
{
|
||||
color: #9c5a9c;
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
|
||||
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
|
||||
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
|
||||
{
|
||||
text-decoration: none; /* no underline */
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* Copyright, Legal Notice */
|
||||
.copyright
|
||||
{
|
||||
color: #666666;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div div.legalnotice p
|
||||
{
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
/* Program listing */
|
||||
pre.synopsis
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
border: 0px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Blurbs */
|
||||
div.note,
|
||||
div.tip,
|
||||
div.important,
|
||||
div.caution,
|
||||
div.warning,
|
||||
p.blurb
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
div.toc
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
background-color: #F0F0F0;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
.copyright-footer
|
||||
{
|
||||
color: #8F8F8F;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
span.highlight
|
||||
{
|
||||
color: #00A000;
|
||||
}
|
||||
}
|
||||
|
||||
@media print
|
||||
{
|
||||
/* Links */
|
||||
a
|
||||
{
|
||||
color: black;
|
||||
}
|
||||
|
||||
a:visited
|
||||
{
|
||||
color: black;
|
||||
}
|
||||
|
||||
.spirit-nav
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Program listing */
|
||||
pre.synopsis
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.programlisting,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
td .programlisting,
|
||||
td .screen
|
||||
{
|
||||
border: 0px solid #DCDCDC;
|
||||
}
|
||||
|
||||
/* Table of contents */
|
||||
div.toc
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.informaltable table,
|
||||
.table table
|
||||
{
|
||||
border: 1px solid gray;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
div.informaltable table tr td,
|
||||
div.table table tr td
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
div.informaltable table tr th,
|
||||
div.table table tr th
|
||||
{
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
table.simplelist tr td
|
||||
{
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
span.highlight
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
Images
|
||||
=============================================================================*/
|
||||
|
||||
span.inlinemediaobject img
|
||||
{
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
Super and Subscript: style so that line spacing isn't effected, see
|
||||
http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341
|
||||
==============================================================================*/
|
||||
|
||||
sup,
|
||||
sub {
|
||||
height: 0;
|
||||
line-height: 1;
|
||||
vertical-align: baseline;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
/* For internet explorer: */
|
||||
|
||||
* html sup,
|
||||
* html sub {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
sup {
|
||||
bottom: 1ex;
|
||||
}
|
||||
|
||||
sub {
|
||||
top: .5ex;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
Indexes: pretty much the same as the TOC.
|
||||
==============================================================================*/
|
||||
|
||||
.index
|
||||
{
|
||||
font-size: 80%;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.index ul
|
||||
{
|
||||
padding-left: 3em;
|
||||
}
|
||||
|
||||
.index p
|
||||
{
|
||||
padding: 2px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.index-entry-level-0
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.index em
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
Alignment and coloring use 'role' feature, available from Quickbook 1.6 up.
|
||||
Added from Niall Douglas for role color and alignment.
|
||||
http://article.gmane.org/gmane.comp.lib.boost.devel/243318
|
||||
*/
|
||||
|
||||
/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */
|
||||
span.aligncenter
|
||||
{
|
||||
display: inline-block; width: 100%; text-align: center;
|
||||
}
|
||||
span.alignright
|
||||
{
|
||||
display: inline-block; width: 100%; text-align: right;
|
||||
}
|
||||
/* alignleft is the default. */
|
||||
span.alignleft
|
||||
{
|
||||
display: inline-block; width: 100%; text-align: left;
|
||||
}
|
||||
|
||||
/* alignjustify stretches the word spacing so that each line has equal width
|
||||
within a chosen fraction of page width (here arbitrarily 20%).
|
||||
*Not* useful inside table items as the column width remains the total string width.
|
||||
Nor very useful, except to temporarily restrict the width.
|
||||
*/
|
||||
span.alignjustify
|
||||
{
|
||||
display: inline-block; width: 20%; text-align: justify;
|
||||
}
|
||||
|
||||
/* Text colors.
|
||||
Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords.
|
||||
Quickbook Usage: [role red Some red text]
|
||||
|
||||
*/
|
||||
span.red { inline-block; color: red; }
|
||||
span.green { color: green; }
|
||||
span.lime { color: #00FF00; }
|
||||
span.blue { color: blue; }
|
||||
span.navy { color: navy; }
|
||||
span.yellow { color: yellow; }
|
||||
span.magenta { color: magenta; }
|
||||
span.indigo { color: #4B0082; }
|
||||
span.cyan { color: cyan; }
|
||||
span.purple { color: purple; }
|
||||
span.gold { color: gold; }
|
||||
span.silver { color: silver; } /* lighter gray */
|
||||
span.gray { color: #808080; } /* light gray */
|
||||
BIN
doc/numpy/_static/boost.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
doc/numpy/_static/bpl.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
doc/numpy/_static/home.png
Normal file
|
After Width: | Height: | Size: 358 B |
BIN
doc/numpy/_static/next.png
Normal file
|
After Width: | Height: | Size: 336 B |
BIN
doc/numpy/_static/prev.png
Normal file
|
After Width: | Height: | Size: 334 B |
38
doc/numpy/_static/style.css
Normal file
@@ -0,0 +1,38 @@
|
||||
@import url(boost.css);
|
||||
|
||||
.header h1 a
|
||||
{
|
||||
color: #00507f;
|
||||
font-size: 200%;
|
||||
font-style: italic;
|
||||
}
|
||||
.header h3 { margin: 1px;}
|
||||
#contents
|
||||
{
|
||||
/* border-bottom: solid thin black;*/
|
||||
}
|
||||
|
||||
.highlight
|
||||
{
|
||||
border: 1px solid #dcdcdc;
|
||||
background-color: inherit;
|
||||
padding: 0 1em;
|
||||
margin: 0 5em;
|
||||
}
|
||||
#searchbox
|
||||
{
|
||||
float: right;
|
||||
width: auto;
|
||||
margin: 0 2em;
|
||||
}
|
||||
|
||||
.admonition-title { font-weight: bold;}
|
||||
.toctree-wrapper
|
||||
{
|
||||
border: 1px solid #dcdcdc;
|
||||
padding: 1em;
|
||||
margin: 0 2em;
|
||||
}
|
||||
.toctree-wrapper .caption,
|
||||
.toctree-wrapper .topic-title { font-weight: bold;}
|
||||
|
||||
BIN
doc/numpy/_static/up.png
Normal file
|
After Width: | Height: | Size: 370 B |
120
doc/numpy/_templates/layout.html
Normal file
@@ -0,0 +1,120 @@
|
||||
{%- macro navbar() %}
|
||||
<div class="navbar" style="text-align:right;">
|
||||
{#%- if parents|count > 0 %#}
|
||||
{#{ parents[1].title }#}
|
||||
{%- if prev %}
|
||||
<a class="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}"><img src="{{ pathto('_static/prev.png', 1) }}" alt="prev"/></a>
|
||||
{%- endif %}
|
||||
{%- if parents %}
|
||||
<a class="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}"><img src="{{ pathto('_static/up.png', 1) }}" alt="up"/></a>
|
||||
{%- endif %}
|
||||
{%- if next %}
|
||||
<a class="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}"><img src="{{ pathto('_static/next.png', 1) }}" alt="next"/></a>
|
||||
{%- endif %}
|
||||
{#%- endif %#}
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
{{ metatags }}
|
||||
{%- if builder != 'htmlhelp' %}
|
||||
{%- set titlesuffix = docstitle|e %}
|
||||
{%- set titlesuffix = " - " + titlesuffix %}
|
||||
{%- endif %}
|
||||
<title>{{ title|striptags }}{{ titlesuffix }}</title>
|
||||
{%- if builder == 'web' %}
|
||||
<link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
|
||||
if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
|
||||
{%- for link, type, title in page_links %}
|
||||
<link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
|
||||
<link rel="stylesheet" href="{{ pathto('_static/style.css', 1) }}" type="text/css" />
|
||||
|
||||
{%- endif %}
|
||||
{%- if builder != 'htmlhelp' %}
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '{{ pathto("", 1) }}',
|
||||
VERSION: '{{ release|e }}',
|
||||
COLLAPSE_MODINDEX: false,
|
||||
FILE_SUFFIX: '{{ file_suffix }}'
|
||||
};
|
||||
</script>
|
||||
{%- for scriptfile in script_files %}
|
||||
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
|
||||
{%- endfor %}
|
||||
{%- if use_opensearch %}
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
|
||||
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
|
||||
{%- endif %}
|
||||
{%- if favicon %}
|
||||
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- block linktags %}
|
||||
{%- if hasdoc('about') %}
|
||||
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
|
||||
{%- endif %}
|
||||
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
|
||||
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
|
||||
{%- if hasdoc('copyright') %}
|
||||
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
|
||||
{%- endif %}
|
||||
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
|
||||
{%- if parents %}
|
||||
<link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
|
||||
{%- endif %}
|
||||
{%- if next %}
|
||||
<link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
|
||||
{%- endif %}
|
||||
{%- if prev %}
|
||||
<link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
{%- block extrahead %} {% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
|
||||
"header">
|
||||
<tr>
|
||||
<td valign="top" width="300">
|
||||
<h3><a href="{{ pathto('index') }}"><img
|
||||
alt="C++ Boost" src="{{ pathto('_static/' + logo, 1) }}" border="0"></a></h3>
|
||||
</td>
|
||||
|
||||
<td >
|
||||
<h1 align="center"><a href="{{ pathto('index') }}">(NumPy)</a></h1>
|
||||
<!-- <h2 align="center">CallPolicies Concept</h2>-->
|
||||
</td>
|
||||
<td>
|
||||
{%- if pagename != "search" %}
|
||||
<div id="searchbox" style="display: none">
|
||||
<form class="search" action="{{ pathto('search') }}" method="get">
|
||||
<input type="text" name="q" size="18" />
|
||||
<input type="submit" value="{{ _('Search') }}" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
<script type="text/javascript">$('#searchbox').show(0);</script>
|
||||
{%- endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="content">
|
||||
{%- block top_navbar %}{{ navbar() }}{% endblock %}
|
||||
{% block body %} {% endblock %}
|
||||
{%- block bottom_navbar %}{{ navbar() }}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
219
doc/numpy/conf.py
Normal file
@@ -0,0 +1,219 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Boost.Python NumPy documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Oct 27 09:04:58 2011.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Boost.Python NumPy extension'
|
||||
copyright = u'2011, Stefan Seefeld'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'default'
|
||||
|
||||
highlight_language = 'c++'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = '_static/bpl.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'BoostPythonNumPydoc'
|
||||
|
||||
html_add_permalinks = False
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'BoostPythonNumPy.tex', u'Boost.Python NumPy Documentation',
|
||||
u'Stefan Seefeld', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'boostnumpy', u'Boost.Python NumPy Documentation',
|
||||
[u'Stefan Seefeld'], 1)
|
||||
]
|
||||
14
doc/numpy/index.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
.. Boost.Python NumPy extension documentation master file, created by
|
||||
sphinx-quickstart on Thu Oct 27 09:04:58 2011.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to the documentation of the Boost.Python NumPy extension!
|
||||
=================================================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
Tutorial <tutorial/index>
|
||||
Reference <reference/index>
|
||||
|
||||
171
doc/numpy/make.bat
Normal file
@@ -0,0 +1,171 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set HTMLDIR=../html/numpy
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %HTMLDIR%
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %HTMLDIR%.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\BoostNumPy.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\BoostNumPy.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
110
doc/numpy/reference/binary_ufunc.rst
Normal file
@@ -0,0 +1,110 @@
|
||||
binary_ufunc
|
||||
============
|
||||
|
||||
.. contents :: Table of Contents
|
||||
|
||||
A ``binary_ufunc`` is a struct used as an intermediate step to broadcast two arguments so that a C++ function can be converted to a ufunc like function
|
||||
|
||||
``<boost/python/numpy/ufunc.hpp>`` contains the ``binary_ufunc`` structure definitions
|
||||
|
||||
|
||||
synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
namespace numpy
|
||||
{
|
||||
|
||||
template <typename TBinaryFunctor,
|
||||
typename TArgument1=typename TBinaryFunctor::first_argument_type,
|
||||
typename TArgument2=typename TBinaryFunctor::second_argument_type,
|
||||
typename TResult=typename TBinaryFunctor::result_type>
|
||||
|
||||
struct binary_ufunc
|
||||
{
|
||||
|
||||
static object call(TBinaryFunctor & self,
|
||||
object const & input1,
|
||||
object const & input2,
|
||||
object const & output);
|
||||
|
||||
static object make();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
constructors
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
struct example_binary_ufunc
|
||||
{
|
||||
typedef any_valid first_argument_type;
|
||||
typedef any_valid second_argument_type;
|
||||
typedef any_valid result_type;
|
||||
};
|
||||
|
||||
:Requirements: The ``any_valid`` type must be defined using typedef as a valid C++ type in order to use the struct methods correctly
|
||||
|
||||
:Note: The struct must be exposed as a Python class, and an instance of the class must be created to use the ``call`` method corresponding to the ``__call__`` attribute of the Python object
|
||||
|
||||
accessors
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
template <typename TBinaryFunctor,
|
||||
typename TArgument1=typename TBinaryFunctor::first_argument_type,
|
||||
typename TArgument2=typename TBinaryFunctor::second_argument_type,
|
||||
typename TResult=typename TBinaryFunctor::result_type>
|
||||
static object call(TBinaryFunctor & self,
|
||||
object const & input,
|
||||
object const & output);
|
||||
|
||||
:Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type
|
||||
|
||||
:Effects: Passes a Python object to the underlying C++ functor after broadcasting its arguments
|
||||
|
||||
::
|
||||
|
||||
template <typename TBinaryFunctor,
|
||||
typename TArgument1=typename TBinaryFunctor::first_argument_type,
|
||||
typename TArgument2=typename TBinaryFunctor::second_argument_type,
|
||||
typename TResult=typename TBinaryFunctor::result_type>
|
||||
static object make();
|
||||
|
||||
:Requires: Typenames ``TBinaryFunctor`` and optionally ``TArgument1`` and ``TArgument2`` for argument type and ``TResult`` for result type
|
||||
|
||||
:Returns: A Python function object to call the overloaded () operator in the struct (in typical usage)
|
||||
|
||||
Example(s)
|
||||
----------
|
||||
|
||||
::
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
struct BinarySquare
|
||||
{
|
||||
typedef double first_argument_type;
|
||||
typedef double second_argument_type;
|
||||
typedef double result_type;
|
||||
|
||||
double operator()(double a,double b) const { return (a*a + b*b) ; }
|
||||
};
|
||||
|
||||
p::object ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare").def("__call__", np::binary_ufunc<BinarySquare>::make());
|
||||
p::object inst = ud();
|
||||
result_array = inst.attr("__call__")(demo_array,demo_array) ;
|
||||
std::cout << "Square of list with binary ufunc is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
|
||||
|
||||
92
doc/numpy/reference/dtype.rst
Normal file
@@ -0,0 +1,92 @@
|
||||
dtype
|
||||
=====
|
||||
|
||||
.. contents :: Table of Contents
|
||||
|
||||
A `dtype`_ is an object describing the type of the elements of an ndarray
|
||||
|
||||
.. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype
|
||||
|
||||
``<boost/python/numpy/dtype.hpp>`` contains the method calls necessary to generate a python object equivalent to a numpy.dtype from builtin C++ objects, as well as to create custom dtypes from user defined types
|
||||
|
||||
|
||||
synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
namespace numpy
|
||||
{
|
||||
|
||||
class dtype : public object
|
||||
{
|
||||
static python::detail::new_reference convert(object::object_cref arg, bool align);
|
||||
public:
|
||||
|
||||
// Convert an arbitrary Python object to a data-type descriptor object.
|
||||
template <typename T>
|
||||
explicit dtype(T arg, bool align=false);
|
||||
|
||||
// Get the built-in numpy dtype associated with the given scalar template type.
|
||||
template <typename T> static dtype get_builtin();
|
||||
|
||||
// Return the size of the data type in bytes.
|
||||
int get_itemsize() const;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructors
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
template <typename T>
|
||||
explicit dtype(T arg, bool align=false)
|
||||
|
||||
:Requirements: ``T`` must be either :
|
||||
|
||||
* a built-in C++ typename convertible to object
|
||||
* a valid python object or convertible to object
|
||||
|
||||
:Effects: Constructs an object from the supplied python object / convertible
|
||||
to object / builtin C++ data type
|
||||
|
||||
:Throws: Nothing
|
||||
|
||||
::
|
||||
|
||||
template <typename T> static dtype get_builtin();
|
||||
|
||||
:Requirements: The typename supplied, ``T`` must be a builtin C++ type also supported by numpy
|
||||
|
||||
:Returns: Numpy dtype corresponding to builtin C++ type
|
||||
|
||||
accessors
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
int get_itemsize() const;
|
||||
|
||||
:Returns: the size of the data type in bytes.
|
||||
|
||||
|
||||
Example(s)
|
||||
----------
|
||||
|
||||
::
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
np::dtype dtype = np::dtype::get_builtin<double>();
|
||||
p::tuple for_custom_dtype = p::make_tuple("ha",dtype);
|
||||
np::dtype custom_dtype = np::dtype(list_for_dtype);
|
||||
|
||||
12
doc/numpy/reference/index.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
Boost.Python NumPy extension Reference
|
||||
======================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
dtype
|
||||
ndarray
|
||||
unary_ufunc
|
||||
binary_ufunc
|
||||
multi_iter
|
||||
|
||||
94
doc/numpy/reference/multi_iter.rst
Normal file
@@ -0,0 +1,94 @@
|
||||
multi_iter
|
||||
==========
|
||||
|
||||
.. contents :: Table of Contents
|
||||
|
||||
A ``multi_iter`` is a Python object, intended to be used as an iterator It should generally only be used in loops.
|
||||
|
||||
``<boost/python/numpy/ufunc.hpp>`` contains the class definitions for ``multi_iter``
|
||||
|
||||
|
||||
synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
namespace numpy
|
||||
{
|
||||
|
||||
class multi_iter : public object
|
||||
{
|
||||
public:
|
||||
void next();
|
||||
bool not_done() const;
|
||||
char * get_data(int n) const;
|
||||
int const get_nd() const;
|
||||
Py_intptr_t const * get_shape() const;
|
||||
Py_intptr_t const shape(int n) const;
|
||||
};
|
||||
|
||||
|
||||
multi_iter make_multi_iter(object const & a1);
|
||||
multi_iter make_multi_iter(object const & a1, object const & a2);
|
||||
multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
constructors
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
multi_iter make_multi_iter(object const & a1);
|
||||
multi_iter make_multi_iter(object const & a1, object const & a2);
|
||||
multi_iter make_multi_iter(object const & a1, object const & a2, object const & a3);
|
||||
|
||||
:Returns: A Python iterator object broadcasting over one, two or three sequences as supplied
|
||||
|
||||
accessors
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
void next();
|
||||
|
||||
:Effects: Increments the iterator
|
||||
|
||||
::
|
||||
|
||||
bool not_done() const;
|
||||
|
||||
:Returns: boolean value indicating whether the iterator is at its end
|
||||
|
||||
::
|
||||
|
||||
char * get_data(int n) const;
|
||||
|
||||
:Returns: a pointer to the element of the nth broadcasted array.
|
||||
|
||||
::
|
||||
|
||||
int const get_nd() const;
|
||||
|
||||
:Returns: the number of dimensions of the broadcasted array expression
|
||||
|
||||
::
|
||||
|
||||
Py_intptr_t const * get_shape() const;
|
||||
|
||||
:Returns: the shape of the broadcasted array expression as an array of integers.
|
||||
|
||||
::
|
||||
|
||||
Py_intptr_t const shape(int n) const;
|
||||
|
||||
:Returns: the shape of the broadcasted array expression in the nth dimension.
|
||||
|
||||
|
||||
382
doc/numpy/reference/ndarray.rst
Normal file
@@ -0,0 +1,382 @@
|
||||
ndarray
|
||||
=======
|
||||
|
||||
.. contents :: Table of Contents
|
||||
|
||||
A `ndarray`_ is an N-dimensional array which contains items of the same type and size, where N is the number of dimensions and is specified in the form of a ``shape`` tuple. Optionally, the numpy ``dtype`` for the objects contained may also be specified.
|
||||
|
||||
.. _ndarray: http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html
|
||||
.. _dtype: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#data-type-objects-dtype
|
||||
|
||||
``<boost/python/numpy/ndarray.hpp>`` contains the structures and methods necessary to move raw data between C++ and Python and create ndarrays from the data
|
||||
|
||||
|
||||
|
||||
synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
namespace numpy
|
||||
{
|
||||
|
||||
class ndarray : public object
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
enum bitflag
|
||||
{
|
||||
NONE=0x0, C_CONTIGUOUS=0x1, F_CONTIGUOUS=0x2, V_CONTIGUOUS=0x1|0x2,
|
||||
ALIGNED=0x4, WRITEABLE=0x8, BEHAVED=0x4|0x8,
|
||||
CARRAY_RO=0x1|0x4, CARRAY=0x1|0x4|0x8, CARRAY_MIS=0x1|0x8,
|
||||
FARRAY_RO=0x2|0x4, FARRAY=0x2|0x4|0x8, FARRAY_MIS=0x2|0x8,
|
||||
UPDATE_ALL=0x1|0x2|0x4, VARRAY=0x1|0x2|0x8, ALL=0x1|0x2|0x4|0x8
|
||||
};
|
||||
|
||||
ndarray view(dtype const & dt) const;
|
||||
ndarray astype(dtype const & dt) const;
|
||||
ndarray copy() const;
|
||||
int const shape(int n) const;
|
||||
int const strides(int n) const;
|
||||
char * get_data() const;
|
||||
dtype get_dtype() const;
|
||||
python::object get_base() const;
|
||||
void set_base(object const & base);
|
||||
Py_intptr_t const * get_shape() const;
|
||||
Py_intptr_t const * get_strides() const;
|
||||
int const get_nd() const;
|
||||
|
||||
bitflag const get_flags() const;
|
||||
|
||||
ndarray transpose() const;
|
||||
ndarray squeeze() const;
|
||||
ndarray reshape(tuple const & shape) const;
|
||||
object scalarize() const;
|
||||
};
|
||||
|
||||
ndarray zeros(tuple const & shape, dtype const & dt);
|
||||
ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);
|
||||
|
||||
ndarray empty(tuple const & shape, dtype const & dt);
|
||||
ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);
|
||||
|
||||
ndarray array(object const & obj);
|
||||
ndarray array(object const & obj, dtype const & dt);
|
||||
|
||||
template <typename Container>
|
||||
ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner);
|
||||
template <typename Container>
|
||||
ndarray from_data(void const * data, dtype const & dt, Container shape, Container strides, object const & owner);
|
||||
|
||||
ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
|
||||
ndarray from_object(object const & obj, dtype const & dt,int nd, ndarray::bitflag flags=ndarray::NONE);
|
||||
ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE);
|
||||
ndarray from_object(object const & obj, int nd_min, int nd_max,ndarray::bitflag flags=ndarray::NONE);
|
||||
ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE);
|
||||
ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE)
|
||||
|
||||
ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b) ;
|
||||
ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b);
|
||||
|
||||
}
|
||||
|
||||
|
||||
constructors
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
ndarray view(dtype const & dt) const;
|
||||
|
||||
:Returns: new ndarray with old ndarray data cast as supplied dtype
|
||||
|
||||
::
|
||||
|
||||
ndarray astype(dtype const & dt) const;
|
||||
|
||||
:Returns: new ndarray with old ndarray data converted to supplied dtype
|
||||
|
||||
::
|
||||
|
||||
ndarray copy() const;
|
||||
|
||||
:Returns: Copy of calling ndarray object
|
||||
|
||||
::
|
||||
|
||||
ndarray transpose() const;
|
||||
|
||||
:Returns: An ndarray with the rows and columns interchanged
|
||||
|
||||
::
|
||||
|
||||
ndarray squeeze() const;
|
||||
|
||||
:Returns: An ndarray with all unit-shaped dimensions removed
|
||||
|
||||
::
|
||||
|
||||
ndarray reshape(tuple const & shape) const;
|
||||
|
||||
:Requirements: The new ``shape`` of the ndarray must be supplied as a tuple
|
||||
|
||||
:Returns: An ndarray with the same data but reshaped to the ``shape`` supplied
|
||||
|
||||
|
||||
::
|
||||
|
||||
object scalarize() const;
|
||||
|
||||
:Returns: A scalar if the ndarray has only one element, otherwise it returns the entire array
|
||||
|
||||
::
|
||||
|
||||
ndarray zeros(tuple const & shape, dtype const & dt);
|
||||
ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);
|
||||
|
||||
:Requirements: The following parameters must be supplied as required :
|
||||
|
||||
* the ``shape`` or the size of all dimensions, as a tuple
|
||||
* the ``dtype`` of the data
|
||||
* the ``nd`` size for a square shaped ndarray
|
||||
* the ``shape`` Py_intptr_t
|
||||
|
||||
:Returns: A new ndarray with the given shape and data type, with data initialized to zero.
|
||||
|
||||
::
|
||||
|
||||
ndarray empty(tuple const & shape, dtype const & dt);
|
||||
ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);
|
||||
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``shape`` or the size of all dimensions, as a tuple
|
||||
* the ``dtype`` of the data
|
||||
* the ``shape`` Py_intptr_t
|
||||
|
||||
:Returns: A new ndarray with the given shape and data type, with data left uninitialized.
|
||||
|
||||
::
|
||||
|
||||
ndarray array(object const & obj);
|
||||
ndarray array(object const & obj, dtype const & dt);
|
||||
|
||||
:Returns: A new ndarray from an arbitrary Python sequence, with dtype of each element specified optionally
|
||||
|
||||
::
|
||||
|
||||
template <typename Container>
|
||||
inline ndarray from_data(void * data,dtype const & dt,Container shape,Container strides,python::object const & owner)
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``data`` which is a generic C++ data container
|
||||
* the dtype ``dt`` of the data
|
||||
* the ``shape`` of the ndarray as Python object
|
||||
* the ``strides`` of each dimension of the array as a Python object
|
||||
* the ``owner`` of the data, in case it is not the ndarray itself
|
||||
|
||||
:Returns: ndarray with attributes and data supplied
|
||||
|
||||
:Note: The ``Container`` typename must be one that is convertible to a std::vector or python object type
|
||||
|
||||
::
|
||||
|
||||
ndarray from_object(object const & obj, dtype const & dt,int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``obj`` Python object to convert to ndarray
|
||||
* the dtype ``dt`` of the data
|
||||
* minimum number of dimensions ``nd_min`` of the ndarray as Python object
|
||||
* maximum number of dimensions ``nd_max`` of the ndarray as Python object
|
||||
* optional ``flags`` bitflags
|
||||
|
||||
:Returns: ndarray constructed with dimensions and data supplied as parameters
|
||||
|
||||
::
|
||||
|
||||
inline ndarray from_object(object const & obj, dtype const & dt, int nd, ndarray::bitflag flags=ndarray::NONE);
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``obj`` Python object to convert to ndarray
|
||||
* the dtype ``dt`` of the data
|
||||
* number of dimensions ``nd`` of the ndarray as Python object
|
||||
* optional ``flags`` bitflags
|
||||
|
||||
:Returns: ndarray with dimensions ``nd`` x ``nd`` and suplied parameters
|
||||
|
||||
::
|
||||
|
||||
inline ndarray from_object(object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE)
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``obj`` Python object to convert to ndarray
|
||||
* the dtype ``dt`` of the data
|
||||
* optional ``flags`` bitflags
|
||||
|
||||
:Returns: Supplied Python object as ndarray
|
||||
|
||||
::
|
||||
|
||||
ndarray from_object(object const & obj, int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``obj`` Python object to convert to ndarray
|
||||
* minimum number of dimensions ``nd_min`` of the ndarray as Python object
|
||||
* maximum number of dimensions ``nd_max`` of the ndarray as Python object
|
||||
* optional ``flags`` bitflags
|
||||
|
||||
:Returns: ndarray with supplied dimension limits and parameters
|
||||
|
||||
:Note: dtype need not be supplied here
|
||||
|
||||
::
|
||||
|
||||
inline ndarray from_object(object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE);
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``obj`` Python object to convert to ndarray
|
||||
* the dtype ``dt`` of the data
|
||||
* number of dimensions ``nd`` of the ndarray as Python object
|
||||
* optional ``flags`` bitflags
|
||||
|
||||
:Returns: ndarray of ``nd`` x ``nd`` dimensions constructed from the supplied object
|
||||
|
||||
::
|
||||
|
||||
inline ndarray from_object(object const & obj, ndarray::bitflag flags=ndarray::NONE)
|
||||
|
||||
:Requirements: The following parameters must be supplied :
|
||||
|
||||
* the ``obj`` Python object to convert to ndarray
|
||||
* optional ``flags`` bitflags
|
||||
|
||||
:Returns: ndarray of same dimensions and dtype as supplied Python object
|
||||
|
||||
|
||||
accessors
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
int const shape(int n) const;
|
||||
|
||||
:Returns: The size of the n-th dimension of the ndarray
|
||||
|
||||
::
|
||||
|
||||
int const strides(int n) const;
|
||||
|
||||
:Returns: The stride of the nth dimension.
|
||||
|
||||
::
|
||||
|
||||
char * get_data() const;
|
||||
|
||||
:Returns: Array's raw data pointer as a char
|
||||
|
||||
:Note: This returns char so stride math works properly on it.User will have to reinterpret_cast it.
|
||||
|
||||
::
|
||||
|
||||
dtype get_dtype() const;
|
||||
|
||||
:Returns: Array's data-type descriptor object (dtype)
|
||||
|
||||
|
||||
::
|
||||
|
||||
object get_base() const;
|
||||
|
||||
:Returns: Object that owns the array's data, or None if the array owns its own data.
|
||||
|
||||
|
||||
::
|
||||
|
||||
void set_base(object const & base);
|
||||
|
||||
:Returns: Set the object that owns the array's data. Exercise caution while using this
|
||||
|
||||
|
||||
::
|
||||
|
||||
Py_intptr_t const * get_shape() const;
|
||||
|
||||
:Returns: Shape of the array as an array of integers
|
||||
|
||||
|
||||
::
|
||||
|
||||
Py_intptr_t const * get_strides() const;
|
||||
|
||||
:Returns: Stride of the array as an array of integers
|
||||
|
||||
|
||||
::
|
||||
|
||||
int const get_nd() const;
|
||||
|
||||
:Returns: Number of array dimensions
|
||||
|
||||
|
||||
::
|
||||
|
||||
bitflag const get_flags() const;
|
||||
|
||||
:Returns: Array flags
|
||||
|
||||
::
|
||||
|
||||
inline ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b)
|
||||
|
||||
:Returns: bitflag logically OR-ed as (a | b)
|
||||
|
||||
::
|
||||
|
||||
inline ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b)
|
||||
|
||||
:Returns: bitflag logically AND-ed as (a & b)
|
||||
|
||||
|
||||
Example(s)
|
||||
----------
|
||||
|
||||
::
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
p::object tu = p::make_tuple('a','b','c') ;
|
||||
np::ndarray example_tuple = np::array (tu) ;
|
||||
|
||||
p::list l ;
|
||||
np::ndarray example_list = np::array (l) ;
|
||||
|
||||
np::dtype dt = np::dtype::get_builtin<int>();
|
||||
np::ndarray example_list1 = np::array (l,dt);
|
||||
|
||||
int data[] = {1,2,3,4} ;
|
||||
p::tuple shape = p::make_tuple(4) ;
|
||||
p::tuple stride = p::make_tuple(4) ;
|
||||
p::object own ;
|
||||
np::ndarray data_ex = np::from_data(data,dt,shape,stride,own);
|
||||
|
||||
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
|
||||
shape = p::make_tuple(3,2) ;
|
||||
stride = p::make_tuple(4,2) ;
|
||||
np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
|
||||
|
||||
np::ndarray mul_data_ex = np::from_data(mul_data,dt1, p::make_tuple(3,4),p::make_tuple(4,1),p::object());
|
||||
mul_data_ex = np::from_data(mul_data,dt1, shape,stride,p::object());
|
||||
|
||||
103
doc/numpy/reference/unary_ufunc.rst
Normal file
@@ -0,0 +1,103 @@
|
||||
unary_ufunc
|
||||
===========
|
||||
|
||||
.. contents :: Table of Contents
|
||||
|
||||
A ``unary_ufunc`` is a struct used as an intermediate step to broadcast a single argument so that a C++ function can be converted to a ufunc like function
|
||||
|
||||
``<boost/python/numpy/ufunc.hpp>`` contains the ``unary_ufunc`` structure definitions
|
||||
|
||||
|
||||
synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace python
|
||||
{
|
||||
namespace numpy
|
||||
{
|
||||
|
||||
template <typename TUnaryFunctor,
|
||||
typename TArgument=typename TUnaryFunctor::argument_type,
|
||||
typename TResult=typename TUnaryFunctor::result_type>
|
||||
struct unary_ufunc
|
||||
{
|
||||
|
||||
static object call(TUnaryFunctor & self,
|
||||
object const & input,
|
||||
object const & output) ;
|
||||
|
||||
static object make();
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
constructors
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
struct example_unary_ufunc
|
||||
{
|
||||
typedef any_valid_type argument_type;
|
||||
typedef any_valid_type result_type;
|
||||
};
|
||||
|
||||
:Requirements: The ``any_valid`` type must be defined using typedef as a valid C++ type in order to use the struct methods correctly
|
||||
|
||||
:Note: The struct must be exposed as a Python class, and an instance of the class must be created to use the ``call`` method corresponding to the ``__call__`` attribute of the Python object
|
||||
|
||||
accessors
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
template <typename TUnaryFunctor,
|
||||
typename TArgument=typename TUnaryFunctor::argument_type,
|
||||
typename TResult=typename TUnaryFunctor::result_type>
|
||||
static object call(TUnaryFunctor & self,
|
||||
object const & input,
|
||||
object const & output);
|
||||
|
||||
:Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type
|
||||
|
||||
:Effects: Passes a Python object to the underlying C++ functor after broadcasting its arguments
|
||||
|
||||
::
|
||||
|
||||
template <typename TUnaryFunctor,
|
||||
typename TArgument=typename TUnaryFunctor::argument_type,
|
||||
typename TResult=typename TUnaryFunctor::result_type>
|
||||
static object make();
|
||||
|
||||
:Requires: Typenames ``TUnaryFunctor`` and optionally ``TArgument`` for argument type and ``TResult`` for result type
|
||||
|
||||
:Returns: A Python function object to call the overloaded () operator in the struct (in typical usage)
|
||||
|
||||
|
||||
|
||||
Example(s)
|
||||
----------
|
||||
|
||||
::
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
struct UnarySquare
|
||||
{
|
||||
typedef double argument_type;
|
||||
typedef double result_type;
|
||||
double operator()(double r) const { return r * r;}
|
||||
};
|
||||
|
||||
p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare").def("__call__", np::unary_ufunc<UnarySquare>::make());
|
||||
p::object inst = ud();
|
||||
std::cout << "Square of unary scalar 1.0 is " << p::extract <char const * > (p::str(inst.attr("__call__")(1.0))) << std::endl ;
|
||||
|
||||
149
doc/numpy/rst.css
Normal file
@@ -0,0 +1,149 @@
|
||||
@import url("doc/src/boostbook.css");
|
||||
@import url("doc/src/docutils.css");
|
||||
/* Copyright David Abrahams 2006. Distributed under the Boost
|
||||
Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
dl.docutils dt {
|
||||
font-weight: bold }
|
||||
|
||||
img.boost-logo {
|
||||
border: none;
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
pre.literal-block span.concept {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.prevpage {
|
||||
padding-top: -5px;
|
||||
text-align: left;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.nextpage {
|
||||
padding-top: -20px;
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.small {
|
||||
font-size: smaller }
|
||||
|
||||
h2 a {
|
||||
font-size: 90%;
|
||||
}
|
||||
h3 a {
|
||||
font-size: 80%;
|
||||
}
|
||||
h4 a {
|
||||
font-size: 70%;
|
||||
}
|
||||
h5 a {
|
||||
font-size: 60%;
|
||||
}
|
||||
|
||||
dl,table
|
||||
{
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
Tables
|
||||
=============================================================================*/
|
||||
|
||||
/* The only clue docutils gives us that tables are logically tables,
|
||||
and not, e.g., footnotes, is that they have border="1". Therefore
|
||||
we're keying off of that. We used to manually patch docutils to
|
||||
add a "table" class to all logical tables, but that proved much too
|
||||
fragile.
|
||||
*/
|
||||
|
||||
table[border="1"]
|
||||
{
|
||||
width: 92%;
|
||||
margin-left: 4%;
|
||||
margin-right: 4%;
|
||||
}
|
||||
|
||||
table[border="1"]
|
||||
{
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
/* Table Cells */
|
||||
table[border="1"] tr td
|
||||
{
|
||||
padding: 0.5em;
|
||||
text-align: left;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
table[border="1"] tr th
|
||||
{
|
||||
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||
border: 1pt solid white;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
@media screen
|
||||
{
|
||||
|
||||
/* Tables */
|
||||
table[border="1"] tr td
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
table[border="1"] tr th
|
||||
{
|
||||
background-color: #F0F0F0;
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
pre,
|
||||
.screen
|
||||
{
|
||||
border: 1px solid #DCDCDC;
|
||||
}
|
||||
|
||||
td pre
|
||||
td .screen
|
||||
{
|
||||
border: 0px
|
||||
}
|
||||
|
||||
.sidebar pre
|
||||
{
|
||||
border: 0px
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pre,
|
||||
.screen
|
||||
{
|
||||
font-size: 9pt;
|
||||
display: block;
|
||||
margin: 1pc 4% 0pc 4%;
|
||||
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||
}
|
||||
|
||||
/* Program listings in tables don't get borders */
|
||||
td pre,
|
||||
td .screen
|
||||
{
|
||||
margin: 0pc 0pc 0pc 0pc;
|
||||
padding: 0pc 0pc 0pc 0pc;
|
||||
}
|
||||
|
||||
54
doc/numpy/tutorial/dtype.rst
Normal file
@@ -0,0 +1,54 @@
|
||||
How to use dtypes
|
||||
=================
|
||||
|
||||
Here is a brief tutorial to show how to create ndarrays with built-in python data types, and extract the types and values of member variables
|
||||
|
||||
Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module::
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Py_Initialize();
|
||||
np::initialize();
|
||||
|
||||
Next, we create the shape and dtype. We use the get_builtin method to get the numpy dtype corresponding to the builtin C++ dtype
|
||||
Here, we will create a 3x3 array passing a tuple with (3,3) for the size, and double as the data type ::
|
||||
|
||||
p::tuple shape = p::make_tuple(3, 3);
|
||||
np::dtype dtype = np::dtype::get_builtin<double>();
|
||||
np::ndarray a = np::zeros(shape, dtype);
|
||||
|
||||
Finally, we can print the array using the extract method in the python namespace.
|
||||
Here, we first convert the variable into a string, and then extract it as a C++ character array from the python string using the <char const \* > template ::
|
||||
|
||||
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
|
||||
We can also print the dtypes of the data members of the ndarray by using the get_dtype method for the ndarray ::
|
||||
|
||||
std::cout << "Datatype is:\n" << p::extract<char const *>(p::str(a.get_dtype())) << std::endl ;
|
||||
|
||||
We can also create custom dtypes and build ndarrays with the custom dtypes
|
||||
|
||||
We use the dtype constructor to create a custom dtype. This constructor takes a list as an argument.
|
||||
|
||||
The list should contain one or more tuples of the format (variable name, variable type)
|
||||
|
||||
So first create a tuple with a variable name and its dtype, double, to create a custom dtype ::
|
||||
|
||||
p::tuple for_custom_dtype = p::make_tuple("ha",dtype) ;
|
||||
|
||||
Next, create a list, and add this tuple to the list. Then use the list to create the custom dtype ::
|
||||
|
||||
p::list list_for_dtype ;
|
||||
list_for_dtype.append(for_custom_dtype) ;
|
||||
np::dtype custom_dtype = np::dtype(list_for_dtype) ;
|
||||
|
||||
We are now ready to create an ndarray with dimensions specified by \*shape\* and of custom dtpye ::
|
||||
|
||||
np::ndarray new_array = np::zeros(shape,custom_dtype);
|
||||
}
|
||||
56
doc/numpy/tutorial/fromdata.rst
Normal file
@@ -0,0 +1,56 @@
|
||||
How to access data using raw pointers
|
||||
=====================================
|
||||
|
||||
One of the advantages of the ndarray wrapper is that the same data can be used in both Python and C++ and changes can be made to reflect at both ends.
|
||||
The from_data method makes this possible.
|
||||
|
||||
Like before, first get the necessary headers, setup the namespaces and initialize the Python runtime and numpy module::
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Py_Initialize();
|
||||
np::initialize();
|
||||
|
||||
Create an array in C++ , and pass the pointer to it to the from_data method to create an ndarray::
|
||||
|
||||
int arr[] = {1,2,3,4,5};
|
||||
np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin<int>(),
|
||||
p::make_tuple(5),
|
||||
p::make_tuple(sizeof(int)),
|
||||
p::object());
|
||||
|
||||
Print the source C++ array, as well as the ndarray, to check if they are the same::
|
||||
|
||||
std::cout << "C++ array :" << std::endl;
|
||||
for (int j=0;j<4;j++)
|
||||
{
|
||||
std::cout << arr[j] << ' ';
|
||||
}
|
||||
std::cout << std::endl
|
||||
<< "Python ndarray :" << p::extract<char const *>(p::str(py_array)) << std::endl;
|
||||
|
||||
Now, change an element in the Python ndarray, and check if the value changed correspondingly in the source C++ array::
|
||||
|
||||
py_array[1] = 5 ;
|
||||
std::cout << "Is the change reflected in the C++ array used to create the ndarray ? " << std::endl;
|
||||
for (int j = 0; j < 5; j++)
|
||||
{
|
||||
std::cout << arr[j] << ' ';
|
||||
}
|
||||
|
||||
Next, change an element of the source C++ array and see if it is reflected in the Python ndarray::
|
||||
|
||||
arr[2] = 8;
|
||||
std::cout << std::endl
|
||||
<< "Is the change reflected in the Python ndarray ?" << std::endl
|
||||
<< p::extract<char const *>(p::str(py_array)) << std::endl;
|
||||
}
|
||||
|
||||
As we can see, the changes are reflected across the ends. This happens because the from_data method passes the C++ array by reference to create the ndarray, and thus uses the same locations for storing data.
|
||||
|
||||
12
doc/numpy/tutorial/index.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
Boost.Python NumPy extension Tutorial
|
||||
=====================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
simple
|
||||
dtype
|
||||
ndarray
|
||||
ufunc
|
||||
fromdata
|
||||
|
||||
99
doc/numpy/tutorial/ndarray.rst
Normal file
@@ -0,0 +1,99 @@
|
||||
Creating ndarrays
|
||||
=================
|
||||
|
||||
The Boost.Numpy library exposes quite a few methods to create ndarrays. ndarrays can be created in a variety of ways, include empty arrays and zero filled arrays.
|
||||
ndarrays can also be created from arbitrary python sequences as well as from data and dtypes.
|
||||
|
||||
This tutorial will introduce you to some of the ways in which you can create ndarrays. The methods covered here include creating ndarrays from arbitrary Python sequences, as well as from C++ containers, using both unit and non-unit strides
|
||||
|
||||
First, as before, initialise the necessary namepaces and runtimes ::
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Py_Initialize();
|
||||
np::initialize();
|
||||
|
||||
Let's now create an ndarray from a simple tuple. We first create a tuple object, and then pass it to the array method, to generate the necessary tuple ::
|
||||
|
||||
p::object tu = p::make_tuple('a','b','c');
|
||||
np::ndarray example_tuple = np::array(tu);
|
||||
|
||||
Let's now try the same with a list. We create an empty list, add an element using the append method, and as before, call the array method ::
|
||||
|
||||
p::list l;
|
||||
l.append('a');
|
||||
np::ndarray example_list = np::array (l);
|
||||
|
||||
Optionally, we can also specify a dtype for the array ::
|
||||
|
||||
np::dtype dt = np::dtype::get_builtin<int>();
|
||||
np::ndarray example_list1 = np::array (l,dt);
|
||||
|
||||
We can also create an array by supplying data arrays and a few other parameters.
|
||||
|
||||
First,create an integer array ::
|
||||
|
||||
int data[] = {1,2,3,4,5};
|
||||
|
||||
Create a shape, and strides, needed by the function ::
|
||||
|
||||
p::tuple shape = p::make_tuple(5);
|
||||
p::tuple stride = p::make_tuple(sizeof(int));
|
||||
|
||||
Here, shape is (4,) , and the stride is `sizeof(int)``.
|
||||
A stride is the number of bytes that must be traveled to get to the next desired element while constructing the ndarray.
|
||||
|
||||
The function also needs an owner, to keep track of the data array passed. Passing none is dangerous ::
|
||||
|
||||
p::object own;
|
||||
|
||||
The from_data function takes the data array, datatype,shape,stride and owner as arguments and returns an ndarray ::
|
||||
|
||||
np::ndarray data_ex1 = np::from_data(data,dt, shape,stride,own);
|
||||
|
||||
Now let's print the ndarray we created ::
|
||||
|
||||
std::cout << "Single dimensional array ::" << std::endl
|
||||
<< p::extract<char const *>(p::str(data_ex)) << std::endl;
|
||||
|
||||
Let's make it a little more interesting. Lets make an 3x2 ndarray from a multi-dimensional array using non-unit strides
|
||||
|
||||
First lets create a 3x4 array of 8-bit integers ::
|
||||
|
||||
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
|
||||
|
||||
Now let's create an array of 3x2 elements, picking the first and third elements from each row . For that, the shape will be 3x2.
|
||||
The strides will be 4x2 i.e. 4 bytes to go to the next desired row, and 2 bytes to go to the next desired column ::
|
||||
|
||||
shape = p::make_tuple(3,2);
|
||||
stride = p::make_tuple(sizeof(uint8_t)*2,sizeof(uint8_t));
|
||||
|
||||
Get the numpy dtype for the built-in 8-bit integer data type ::
|
||||
|
||||
np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
|
||||
|
||||
Now lets first create and print out the ndarray as is.
|
||||
Notice how we can pass the shape and strides in the function directly, as well as the owner. The last part can be done because we don't have any use to
|
||||
manipulate the "owner" object ::
|
||||
|
||||
np::ndarray mul_data_ex = np::from_data(mul_data, dt1,
|
||||
p::make_tuple(3,4),
|
||||
p::make_tuple(4,1),
|
||||
p::object());
|
||||
std::cout << "Original multi dimensional array :: " << std::endl
|
||||
<< p::extract<char const *>(p::str(mul_data_ex)) << std::endl;
|
||||
|
||||
Now create the new ndarray using the shape and strides and print out the array we created using non-unit strides ::
|
||||
|
||||
mul_data_ex = np::from_data(mul_data, dt1, shape, stride, p::object());
|
||||
std::cout << "Selective multidimensional array :: "<<std::endl
|
||||
<< p::extract<char const *>(p::str(mul_data_ex)) << std::endl ;
|
||||
}
|
||||
|
||||
.. note:: The from_data method will throw ``error_already_set`` if the number of elements dictated by the shape and the corresponding strides don't match.
|
||||
41
doc/numpy/tutorial/simple.rst
Normal file
@@ -0,0 +1,41 @@
|
||||
A simple tutorial on Arrays
|
||||
===========================
|
||||
|
||||
Let's start with a simple tutorial to create and modify arrays.
|
||||
|
||||
Get the necessary headers for numpy components and set up necessary namespaces::
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
Initialise the Python runtime, and the numpy module. Failure to call these results in segmentation errors::
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Py_Initialize();
|
||||
np::initialize();
|
||||
|
||||
|
||||
Zero filled n-dimensional arrays can be created using the shape and data-type of the array as a parameter. Here, the shape is 3x3 and the datatype is the built-in float type::
|
||||
|
||||
p::tuple shape = p::make_tuple(3, 3);
|
||||
np::dtype dtype = np::dtype::get_builtin<float>();
|
||||
np::ndarray a = np::zeros(shape, dtype);
|
||||
|
||||
You can also create an empty array like this ::
|
||||
|
||||
np::ndarray b = np::empty(shape,dtype);
|
||||
|
||||
Print the original and reshaped array. The array a which is a list is first converted to a string, and each value in the list is extracted using extract< >::
|
||||
|
||||
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
|
||||
// Reshape the array into a 1D array
|
||||
a = a.reshape(p::make_tuple(9));
|
||||
// Print it again.
|
||||
std::cout << "Reshaped array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
}
|
||||
|
||||
120
doc/numpy/tutorial/ufunc.rst
Normal file
@@ -0,0 +1,120 @@
|
||||
Ufuncs
|
||||
======
|
||||
|
||||
Ufuncs or universal functions operate on ndarrays element by element, and support array broadcasting, type casting, and other features.
|
||||
|
||||
Lets try and see how we can use the binary and unary ufunc methods
|
||||
|
||||
After the neccessary includes ::
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
Now we create the structs necessary to implement the ufuncs. The typedefs *must* be made as the ufunc generators take these typedefs as inputs and return an error otherwise ::
|
||||
|
||||
struct UnarySquare
|
||||
{
|
||||
typedef double argument_type;
|
||||
typedef double result_type;
|
||||
|
||||
double operator()(double r) const { return r * r;}
|
||||
};
|
||||
|
||||
struct BinarySquare
|
||||
{
|
||||
typedef double first_argument_type;
|
||||
typedef double second_argument_type;
|
||||
typedef double result_type;
|
||||
|
||||
double operator()(double a,double b) const { return (a*a + b*b) ; }
|
||||
};
|
||||
|
||||
Initialise the Python runtime and the numpy module ::
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Py_Initialize();
|
||||
np::initialize();
|
||||
|
||||
Now expose the struct UnarySquare to Python as a class, and let ud be the class object. ::
|
||||
|
||||
p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare");
|
||||
ud.def("__call__", np::unary_ufunc<UnarySquare>::make());
|
||||
|
||||
Let inst be an instance of the class ud ::
|
||||
|
||||
p::object inst = ud();
|
||||
|
||||
Use the "__call__" method to call the overloaded () operator and print the value ::
|
||||
|
||||
std::cout << "Square of unary scalar 1.0 is " << p::extract<char const *>(p::str(inst.attr("__call__")(1.0))) << std::endl;
|
||||
|
||||
Create an array in C++ ::
|
||||
|
||||
int arr[] = {1,2,3,4} ;
|
||||
|
||||
|
||||
..and use it to create the ndarray in Python ::
|
||||
|
||||
np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>(),
|
||||
p::make_tuple(4),
|
||||
p::make_tuple(4),
|
||||
p::object());
|
||||
|
||||
Print out the demo array ::
|
||||
|
||||
std::cout << "Demo array is " << p::extract<char const *>(p::str(demo_array)) << std::endl;
|
||||
|
||||
Call the "__call__" method to perform the operation and assign the value to result_array ::
|
||||
|
||||
p::object result_array = inst.attr("__call__")(demo_array);
|
||||
|
||||
Print the resultant array ::
|
||||
|
||||
std::cout << "Square of demo array is " << p::extract<char const *>(p::str(result_array)) << std::endl;
|
||||
|
||||
Lets try the same with a list ::
|
||||
|
||||
p::list li;
|
||||
li.append(3);
|
||||
li.append(7);
|
||||
|
||||
Print out the demo list ::
|
||||
|
||||
std::cout << "Demo list is " << p::extract<char const *>(p::str(li)) << std::endl;
|
||||
|
||||
Call the ufunc for the list ::
|
||||
|
||||
result_array = inst.attr("__call__")(li);
|
||||
|
||||
And print the list out ::
|
||||
|
||||
std::cout << "Square of demo list is " << p::extract<char const *>(p::str(result_array)) << std::endl;
|
||||
|
||||
Now lets try Binary ufuncs. Again, expose the struct BinarySquare to Python as a class, and let ud be the class object ::
|
||||
|
||||
ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare");
|
||||
ud.def("__call__", np::binary_ufunc<BinarySquare>::make());
|
||||
|
||||
And initialise ud ::
|
||||
|
||||
inst = ud();
|
||||
|
||||
Print the two input lists ::
|
||||
|
||||
std::cout << "The two input list for binary ufunc are " << std::endl
|
||||
<< p::extract<char const *>(p::str(demo_array)) << std::endl
|
||||
<< p::extract<char const *>(p::str(demo_array)) << std::endl;
|
||||
|
||||
Call the binary ufunc taking demo_array as both inputs ::
|
||||
|
||||
result_array = inst.attr("__call__")(demo_array,demo_array);
|
||||
|
||||
And print the output ::
|
||||
|
||||
std::cout << "Square of list with binary ufunc is " << p::extract<char const *>(p::str(result_array)) << std::endl;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ The development of these features was funded in part by grants to `Boost Consult
|
||||
|
||||
[section Contents]
|
||||
|
||||
* [link rn Release Notes]
|
||||
* _tutorial_
|
||||
* [link building Building and Testing]
|
||||
* _reference_
|
||||
@@ -50,6 +51,7 @@ The development of these features was funded in part by grants to `Boost Consult
|
||||
* [link glossary Glossary]
|
||||
* [link support Support Resources]
|
||||
* [link faq Frequently Asked Questions (FAQs)]
|
||||
* [@numpy/index.html NumPy Extension Documentation]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -57,6 +59,7 @@ The development of these features was funded in part by grants to `Boost Consult
|
||||
|
||||
[@article.html Building Hybrid Systems With Boost Python], by Dave Abrahams and Ralf W. Grosse-Kunstleve
|
||||
|
||||
[include release_notes.qbk]
|
||||
[include building.qbk]
|
||||
[include configuration.qbk]
|
||||
[include support.qbk]
|
||||
|
||||
@@ -38,7 +38,7 @@ The `indexing_suite` class is the base class for the management of C++ container
|
||||
[[__iter__(self)]
|
||||
[This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the container. For mappings, it should iterate over the keys of the container, and should also be made available as the method iterkeys().
|
||||
|
||||
Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see [@http://www.python.org/doc/current/lib/typeiter.html Iterator Types] in the [@http://www.python.org/doc/current/lib/lib.html Python Library Reference].]]
|
||||
Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see [@https://docs.python.org/3/library/stdtypes.html#iterator-types Iterator Types] in the [@https://docs.python.org/3/library/index.html Python Library Reference].]]
|
||||
|
||||
[[__contains__(self, item)]
|
||||
[Called to implement membership test operators. Should return true if item is in self, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs.]]
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
[section boost/python/numeric.hpp]
|
||||
[section Introduction]
|
||||
Exposes a [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] for the Python [@http://www.python.org/dev/doc/devel/lib/typesmapping.html array] type.
|
||||
[endsect]
|
||||
[section Class `array`]
|
||||
Provides access to the array types of [@http://www.pfdubois.com/numpy/ Numerical Python]\ 's [@http://www.pfdubois.com/numpy/#Numeric Numeric] and [@http://stsdas.stsci.edu/numarray/index.html NumArray] modules. With the exception of the functions documented below, the semantics of the constructors and member functions defined below can be fully understood by reading the [link concepts.objectwrapper.typewrapper_concept_requirements TypeWrapper] concept definition. Since array is publicly derived from object, the public object interface applies to array instances as well.
|
||||
|
||||
The default behavior is to use numarray.NDArray as the associated Python type if the numarray module is installed in the default location. Otherwise it falls back to use Numeric.ArrayType. If neither extension module is installed, overloads of wrapped C++ functions with numeric::array parameters will never be matched, and other attempted uses of numeric::array will raise an appropriate Python exception. The associated Python type can be set manually using the set_module_and_type(...) static function.
|
||||
``
|
||||
namespace boost { namespace python { namespace numeric
|
||||
{
|
||||
class array : public object
|
||||
{
|
||||
public:
|
||||
object astype();
|
||||
template <class Type>
|
||||
object astype(Type const& type_);
|
||||
|
||||
template <class Type>
|
||||
array new_(Type const& type_) const;
|
||||
|
||||
template <class Sequence>
|
||||
void resize(Sequence const& x);
|
||||
void resize(long x1);
|
||||
void resize(long x1, long x2);
|
||||
...
|
||||
void resize(long x1, long x2,...long xn);
|
||||
|
||||
template <class Sequence>
|
||||
void setshape(Sequence const& x);
|
||||
void setshape(long x1);
|
||||
void setshape(long x1, long x2);
|
||||
...
|
||||
void setshape(long x1, long x2,...long xn);
|
||||
|
||||
template <class Indices, class Values>
|
||||
void put(Indices const& indices, Values const& values);
|
||||
|
||||
template <class Sequence>
|
||||
object take(Sequence const& sequence, long axis = 0);
|
||||
|
||||
template <class File>
|
||||
void tofile(File const& f) const;
|
||||
|
||||
object factory();
|
||||
template <class Sequence>
|
||||
object factory(Sequence const&);
|
||||
template <class Sequence, class Typecode>
|
||||
object factory(Sequence const&, Typecode const&, bool copy = true, bool savespace = false);
|
||||
template <class Sequence, class Typecode, class Type>
|
||||
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&);
|
||||
template <class Sequence, class Typecode, class Type, class Shape>
|
||||
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&, Shape const&);
|
||||
|
||||
template <class T1>
|
||||
explicit array(T1 const& x1);
|
||||
template <class T1, class T2>
|
||||
explicit array(T1 const& x1, T2 const& x2);
|
||||
...
|
||||
template <class T1, class T2,...class Tn>
|
||||
explicit array(T1 const& x1, T2 const& x2,...Tn const& xn);
|
||||
|
||||
static void set_module_and_type();
|
||||
static void set_module_and_type(char const* package_path = 0, char const* type_name = 0);
|
||||
static void get_module_name();
|
||||
|
||||
object argmax(long axis=-1);
|
||||
|
||||
object argmin(long axis=-1);
|
||||
|
||||
object argsort(long axis=-1);
|
||||
|
||||
void byteswap();
|
||||
|
||||
object copy() const;
|
||||
|
||||
object diagonal(long offset = 0, long axis1 = 0, long axis2 = 1) const;
|
||||
|
||||
void info() const;
|
||||
|
||||
bool is_c_array() const;
|
||||
bool isbyteswapped() const;
|
||||
void sort();
|
||||
object trace(long offset = 0, long axis1 = 0, long axis2 = 1) const;
|
||||
object type() const;
|
||||
char typecode() const;
|
||||
|
||||
object getflat() const;
|
||||
long getrank() const;
|
||||
object getshape() const;
|
||||
bool isaligned() const;
|
||||
bool iscontiguous() const;
|
||||
long itemsize() const;
|
||||
long nelements() const;
|
||||
object nonzero() const;
|
||||
|
||||
void ravel();
|
||||
object repeat(object const& repeats, long axis=0);
|
||||
void setflat(object const& flat);
|
||||
void swapaxes(long axis1, long axis2);
|
||||
str tostring() const;
|
||||
void transpose(object const& axes = object());
|
||||
object view() const;
|
||||
};
|
||||
}}}
|
||||
``
|
||||
[endsect]
|
||||
[section Class `array` observer functions]
|
||||
``
|
||||
object factory();
|
||||
template <class Sequence>
|
||||
object factory(Sequence const&);
|
||||
template <class Sequence, class Typecode>
|
||||
object factory(Sequence const&, Typecode const&, bool copy = true, bool savespace = false);
|
||||
template <class Sequence, class Typecode, class Type>
|
||||
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&);
|
||||
template <class Sequence, class Typecode, class Type, class Shape>
|
||||
object factory(Sequence const&, Typecode const&, bool copy, bool savespace, Type const&, Shape const&);
|
||||
``
|
||||
These functions map to the underlying array type's array() function family. They are not called "array" because of the C++ limitation that you can't define a member function with the same name as its enclosing class.
|
||||
``
|
||||
template <class Type>
|
||||
array new_(Type const&) const;
|
||||
``
|
||||
This function maps to the underlying array type's new() function. It is not called "new" because that is a keyword in C++.
|
||||
[endsect]
|
||||
[section Class `array` static functions]
|
||||
``
|
||||
static void set_module_and_type(char const* package_path, char const* type_name);
|
||||
static void set_module_and_type();
|
||||
``
|
||||
[variablelist
|
||||
[[Requires][package_path and type_name, if supplied, is an [link ntbs].]]
|
||||
[[Effects][The first form sets the package path of the module that supplies the type named by type_name to package_path. The second form restores the default search behavior. The associated Python type will be searched for only the first time it is needed, and thereafter the first time it is needed after an invocation of set_module_and_type.]]
|
||||
]
|
||||
``static std::string get_module_name()``
|
||||
[variablelist
|
||||
[[Effects][Returns the name of the module containing the class that will be held by new `numeric::array` instances.]]
|
||||
]
|
||||
[endsect]
|
||||
[section Example]
|
||||
``
|
||||
#include <boost/python/numeric.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
|
||||
// sets the first element in a 2d numeric array
|
||||
void set_first_element(numeric::array& y, double value)
|
||||
{
|
||||
y[make_tuple(0,0)] = value;
|
||||
}
|
||||
``
|
||||
[endsect]
|
||||
[endsect]
|
||||
@@ -5,7 +5,6 @@
|
||||
[include dict.qbk]
|
||||
[include list.qbk]
|
||||
[include long.qbk]
|
||||
[include numeric.qbk]
|
||||
[include object.qbk]
|
||||
[include str.qbk]
|
||||
[include slice.qbk]
|
||||
|
||||
@@ -86,8 +86,8 @@ The column of Python Expressions illustrates the expressions that will be suppor
|
||||
[[C++ Expression][Python Method Name][C++ Implementation][Python Expression (primary, secondary)]]
|
||||
[[`self == r`][`__eq__`][`x == y`][`x == y`, `y == x`]]
|
||||
[[`l == self`][`__eq__`][`y == x`][`y == x`, `x == y`]]
|
||||
[[`self != r`][`__nq__`][`x != y`][`x != y`, `y != x`]]
|
||||
[[`l != self`][`__nq__`][`y != x`][`y != x`, `x != y`]]
|
||||
[[`self != r`][`__ne__`][`x != y`][`x != y`, `y != x`]]
|
||||
[[`l != self`][`__ne__`][`y != x`][`y != x`, `x != y`]]
|
||||
[[`self < r`][`__lt__`][`x < y`][`x < y`, `y > x`]]
|
||||
[[`l < self`][`__gt__`][`y < x`][`y > x`, `x < y`]]
|
||||
[[`self > r`][`__gt__`][`x > y`][`x > y`, `y < x`]]
|
||||
|
||||
@@ -4,7 +4,7 @@ Pickle is a Python module for object serialization, also known as persistence, m
|
||||
|
||||
It is often necessary to save and restore the contents of an object to a file. One approach to this problem is to write a pair of functions that read and write data from a file in a special format. A powerful alternative approach is to use Python's pickle module. Exploiting Python's ability for introspection, the pickle module recursively converts nearly arbitrary Python objects into a stream of bytes that can be written to a file.
|
||||
|
||||
The Boost Python Library supports the pickle module through the interface as described in detail in the [@http://www.python.org/doc/current/lib/module-pickle.html Python Library Reference for pickle]. This interface involves the special methods `__getinitargs__`, `__getstate__` and `__setstate__` as described in the following. Note that `Boost.Python` is also fully compatible with Python's cPickle module.
|
||||
The Boost Python Library supports the pickle module through the interface as described in detail in the [@https://docs.python.org/2/library/pickle.html Python Library Reference for pickle]. This interface involves the special methods `__getinitargs__`, `__getstate__` and `__setstate__` as described in the following. Note that `Boost.Python` is also fully compatible with Python's cPickle module.
|
||||
[endsect]
|
||||
[section The Pickle Interface]
|
||||
At the user level, the Boost.Python pickle interface involves three special methods:
|
||||
|
||||
@@ -105,14 +105,6 @@ list odd_elements(list l)
|
||||
return l[slice(_,_,2)];
|
||||
}
|
||||
|
||||
// Perform a multidimensional extended slice of a Numeric.array
|
||||
numeric::array even_columns(numeric::array arr)
|
||||
{
|
||||
// select every other column, starting with the second, of a 2-D array.
|
||||
// Equivalent to "return arr[:, 1::2]" in Python.
|
||||
return arr[make_tuple( slice(), slice(1,_,2))];
|
||||
}
|
||||
|
||||
// Perform a summation over a slice of a std::vector.
|
||||
double partial_sum(std::vector<double> const& Foo, const slice index)
|
||||
{
|
||||
|
||||
11
doc/release_notes.qbk
Normal file
@@ -0,0 +1,11 @@
|
||||
[chapter Release Notes
|
||||
[quickbook 1.7]
|
||||
[id rn]
|
||||
]
|
||||
|
||||
[section Version 1.67]
|
||||
|
||||
* The Boost.Python library names now contain the Python version suffix.
|
||||
A variant compiled with Python 2.7 will thus produce library names
|
||||
`boost_python27` and `boost_numpy27`, etc., making it possible to host
|
||||
variants for multiple Python versions next to each other.
|
||||
@@ -92,7 +92,7 @@ who had to use a different tool.
|
||||
|
||||
We will skip over the details. Our objective will be to simply create
|
||||
the hello world module and run it in Python. For a complete reference to
|
||||
building Boost.Python, check out: [@../../../building.html
|
||||
building Boost.Python, check out: [@../building.html
|
||||
building.html]. After this brief ['bjam] tutorial, we should have built
|
||||
the DLLs and run a python program using the extension.
|
||||
|
||||
@@ -121,7 +121,7 @@ __jam__
|
||||
file. Simply copy the file and tweak [^use-project boost] to where your
|
||||
boost root directory is and you're OK.
|
||||
|
||||
The comments contained in the Jamrules file above should be sufficient
|
||||
The comments contained in the Jamroot file above should be sufficient
|
||||
to get you going.
|
||||
|
||||
[h2 Running bjam]
|
||||
@@ -1417,6 +1417,8 @@ eval evaluates the given expression and returns the resulting value.
|
||||
exec executes the given code (typically a set of statements) returning the result,
|
||||
and exec_file executes the code contained in the given file.
|
||||
|
||||
There are also overloads taking `char const*` instead of str as the first argument.
|
||||
|
||||
The [^globals] and [^locals] parameters are Python dictionaries
|
||||
containing the globals and locals of the context in which to run the code.
|
||||
For most intents and purposes you can use the namespace dictionary of the
|
||||
@@ -1869,36 +1871,6 @@ This technique has several advantages:
|
||||
* Minimize the need to recompile
|
||||
* Rapid prototyping (you can move the code to C++ if required without changing the interface)
|
||||
|
||||
You can even add a little syntactic sugar with the use of metaclasses. Let's
|
||||
create a special metaclass that "injects" methods in other classes.
|
||||
|
||||
# The one Boost.Python uses for all wrapped classes.
|
||||
# You can use here any class exported by Boost instead of "point"
|
||||
BoostPythonMetaclass = point.__class__
|
||||
|
||||
class injector(object):
|
||||
class __metaclass__(BoostPythonMetaclass):
|
||||
def __init__(self, name, bases, dict):
|
||||
for b in bases:
|
||||
if type(b) not in (self, type):
|
||||
for k,v in dict.items():
|
||||
setattr(b,k,v)
|
||||
return type.__init__(self, name, bases, dict)
|
||||
|
||||
# inject some methods in the point foo
|
||||
class more_point(injector, point):
|
||||
def __repr__(self):
|
||||
return 'Point(x=%s, y=%s)' % (self.x, self.y)
|
||||
def foo(self):
|
||||
print 'foo!'
|
||||
|
||||
Now let's see how it got:
|
||||
|
||||
>>> print point()
|
||||
Point(x=10, y=10)
|
||||
>>> point().foo()
|
||||
foo!
|
||||
|
||||
Another useful idea is to replace constructors with factory functions:
|
||||
|
||||
_point = point
|
||||
|
||||
@@ -1,43 +1,35 @@
|
||||
# Copyright David Abrahams 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
# Copyright Stefan Seefeld 2016.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Specify the path to the Boost project. If you move this project,
|
||||
# adjust this path to refer to the Boost root directory.
|
||||
use-project boost
|
||||
: ../../.. ;
|
||||
import python ;
|
||||
|
||||
# Set up the project-wide requirements that everything uses the
|
||||
# boost_python library from the project whose global ID is
|
||||
# /boost/python.
|
||||
project
|
||||
: requirements <library>/boost/python//boost_python
|
||||
<implicit-dependency>/boost//headers
|
||||
: usage-requirements <implicit-dependency>/boost//headers
|
||||
;
|
||||
|
||||
# Declare the three extension modules. You can specify multiple
|
||||
# source files after the colon separated by spaces.
|
||||
python-extension getting_started1 : getting_started1.cpp ;
|
||||
python-extension getting_started2 : getting_started2.cpp ;
|
||||
python-extension std_pair_ext : std_pair.cpp ;
|
||||
|
||||
# A little "rule" (function) to clean up the syntax of declaring tests
|
||||
# of these extension modules.
|
||||
local rule run-test ( test-name : sources + )
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
import testing ;
|
||||
testing.make-test run-pyd : $(sources) : : $(test-name) ;
|
||||
ECHO "warning: no Python configured in user-config.jam" ;
|
||||
ECHO "warning: will use default configuration" ;
|
||||
using python ;
|
||||
}
|
||||
|
||||
# Declare test targets
|
||||
run-test test1 : getting_started1 test_getting_started1.py ;
|
||||
run-test test2 : getting_started2 test_getting_started2.py ;
|
||||
run-test test3 : std_pair_ext test_std_pair.py ;
|
||||
# Adjust the following if Boost.Python isn't installed in a default location
|
||||
lib boost_python ;
|
||||
|
||||
# A target that runs all the tests
|
||||
alias test : test1 test2 test3 ;
|
||||
project
|
||||
: requirements
|
||||
# <include>/path/to/boost/python
|
||||
<library>boost_python
|
||||
;
|
||||
|
||||
# Only run tests when explicitly requested
|
||||
explicit test test1 test2 test3 ;
|
||||
rule run-test ( test-name : sources + )
|
||||
{
|
||||
import testing ;
|
||||
testing.make-test run-pyd : $(sources) : : $(test-name) ;
|
||||
}
|
||||
|
||||
build-project quickstart ;
|
||||
build-project tutorial ;
|
||||
if [ python.numpy ]
|
||||
{
|
||||
build-project numpy ;
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
.. Copyright David Abrahams 2006. Distributed under the Boost
|
||||
.. Software License, Version 1.0. (See accompanying
|
||||
.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
To get started with the Boost Python Library, use the examples
|
||||
getting_started1.cpp and getting_started2.cpp. Invoking
|
||||
|
||||
bjam --toolset=your-toolset test
|
||||
|
||||
in this directory will build and run the examples. See
|
||||
http://www.boost.org/more/getting_started.html for details about the
|
||||
--toolset= option.
|
||||
|
||||
If you move this example from its place in the Boost development tree
|
||||
you'll need to edit the two lines indicated in Jamroot and
|
||||
boost-build.jam.
|
||||
11
example/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||

|
||||
|
||||
# Examples
|
||||
|
||||
This directory contains various examples using Boost.Python.
|
||||
You may compile these using the `bjam` command either in this directory
|
||||
or in any of the subdirectories.
|
||||
You may need to adjust the paths in the Jamroot file if Boost.Python
|
||||
is not installed in a default location.
|
||||
See http://boostorg.github.io/python/doc/html/building/no_install_quickstart.html
|
||||
for details.
|
||||
@@ -1,7 +0,0 @@
|
||||
# Copyright David Abrahams 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Edit this path to point at the tools/build/src subdirectory of your
|
||||
# Boost installation. Absolute paths work, too.
|
||||
boost-build ../../../tools/build/src ;
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A couple of simple C++ functions that we want to expose to Python.
|
||||
std::string greet() { return "hello, world"; }
|
||||
int square(int number) { return number * number; }
|
||||
}
|
||||
|
||||
namespace python = boost::python;
|
||||
|
||||
// Python requires an exported function called init<module-name> in every
|
||||
// extension module. This is where we build the module contents.
|
||||
BOOST_PYTHON_MODULE(getting_started1)
|
||||
{
|
||||
// Add regular functions to the module.
|
||||
python::def("greet", greet);
|
||||
python::def("square", square);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/class.hpp>
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// A friendly class.
|
||||
class hello
|
||||
{
|
||||
public:
|
||||
hello(const std::string& country) { this->country = country; }
|
||||
std::string greet() const { return "Hello from " + country; }
|
||||
private:
|
||||
std::string country;
|
||||
};
|
||||
|
||||
// A function taking a hello object as an argument.
|
||||
std::string invite(const hello& w) {
|
||||
return w.greet() + "! Please come soon!";
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(getting_started2)
|
||||
{
|
||||
using namespace boost::python;
|
||||
class_<hello>("hello", init<std::string>())
|
||||
// Add a regular member function.
|
||||
.def("greet", &hello::greet)
|
||||
// Add invite() as a member of hello!
|
||||
.def("invite", invite)
|
||||
;
|
||||
|
||||
// Also add invite() as a regular function to the module.
|
||||
def("invite", invite);
|
||||
}
|
||||
29
example/numpy/Jamfile
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright Stefan Seefeld 2016.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import python ;
|
||||
|
||||
# Adjust the following if Boost.Python isn't installed in a default location
|
||||
lib boost_numpy
|
||||
:
|
||||
: <search>/usr/local/Boost/lib
|
||||
<include>/usr/local/Boost/include
|
||||
;
|
||||
|
||||
project numpy
|
||||
: requirements
|
||||
<include>/usr/local/Boost/include
|
||||
<library>boost_numpy
|
||||
<location>.
|
||||
;
|
||||
|
||||
exe simple : simple.cpp boost_numpy /python//python ;
|
||||
exe dtype : dtype.cpp boost_numpy /python//python ;
|
||||
exe ndarray : ndarray.cpp /python//python ;
|
||||
exe fromdata : fromdata.cpp /python//python ;
|
||||
exe ufunc : ufunc.cpp /python//python ;
|
||||
exe wrap : wrap.cpp /python//python ;
|
||||
|
||||
python-extension gaussian : gaussian.cpp ;
|
||||
37
example/numpy/demo_gaussian.py
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright Jim Bosch 2010-2012.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import numpy
|
||||
import gaussian
|
||||
|
||||
mu = numpy.zeros(2, dtype=float)
|
||||
sigma = numpy.identity(2, dtype=float)
|
||||
sigma[0, 1] = 0.15
|
||||
sigma[1, 0] = 0.15
|
||||
|
||||
g = gaussian.bivariate_gaussian(mu, sigma)
|
||||
|
||||
r = numpy.linspace(-40, 40, 1001)
|
||||
x, y = numpy.meshgrid(r, r)
|
||||
|
||||
z = g(x, y)
|
||||
|
||||
s = z.sum() * (r[1] - r[0])**2
|
||||
print "sum (should be ~ 1):", s
|
||||
|
||||
xc = (z * x).sum() / z.sum()
|
||||
print "x centroid (should be ~ %f): %f" % (mu[0], xc)
|
||||
|
||||
yc = (z * y).sum() / z.sum()
|
||||
print "y centroid (should be ~ %f): %f" % (mu[1], yc)
|
||||
|
||||
xx = (z * (x - xc)**2).sum() / z.sum()
|
||||
print "xx moment (should be ~ %f): %f" % (sigma[0,0], xx)
|
||||
|
||||
yy = (z * (y - yc)**2).sum() / z.sum()
|
||||
print "yy moment (should be ~ %f): %f" % (sigma[1,1], yy)
|
||||
|
||||
xy = 0.5 * (z * (x - xc) * (y - yc)).sum() / z.sum()
|
||||
print "xy moment (should be ~ %f): %f" % (sigma[0,1], xy)
|
||||
49
example/numpy/dtype.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* @brief An example to show how to create ndarrays with built-in python data types, and extract
|
||||
* the types and values of member variables
|
||||
*
|
||||
* @todo Add an example to show type conversion.
|
||||
* Add an example to show use of user-defined types
|
||||
*
|
||||
*/
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create a 3x3 shape...
|
||||
p::tuple shape = p::make_tuple(3, 3);
|
||||
// ...as well as a type for C++ double
|
||||
np::dtype dtype = np::dtype::get_builtin<double>();
|
||||
// Construct an array with the above shape and type
|
||||
np::ndarray a = np::zeros(shape, dtype);
|
||||
// Print the array
|
||||
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
// Print the datatype of the elements
|
||||
std::cout << "Datatype is:\n" << p::extract<char const *>(p::str(a.get_dtype())) << std::endl ;
|
||||
// Using user defined dtypes to create dtype and an array of the custom dtype
|
||||
// First create a tuple with a variable name and its dtype, double, to create a custom dtype
|
||||
p::tuple for_custom_dtype = p::make_tuple("ha",dtype) ;
|
||||
// The list needs to be created, because the constructor to create the custom dtype
|
||||
// takes a list of (variable,variable_type) as an argument
|
||||
p::list list_for_dtype ;
|
||||
list_for_dtype.append(for_custom_dtype) ;
|
||||
// Create the custom dtype
|
||||
np::dtype custom_dtype = np::dtype(list_for_dtype) ;
|
||||
// Create an ndarray with the custom dtype
|
||||
np::ndarray new_array = np::zeros(shape,custom_dtype);
|
||||
|
||||
}
|
||||
48
example/numpy/fromdata.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* @brief An example to show how to access data using raw pointers. This shows that you can use and
|
||||
* manipulate data in either Python or C++ and have the changes reflected in both.
|
||||
*/
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create an array in C++
|
||||
int arr[] = {1,2,3,4} ;
|
||||
// Create the ndarray in Python
|
||||
np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
|
||||
// Print the ndarray that we just created, and the source C++ array
|
||||
std::cout << "C++ array :" << std::endl ;
|
||||
for (int j=0;j<4;j++)
|
||||
{
|
||||
std::cout << arr[j] << ' ' ;
|
||||
}
|
||||
std::cout << std::endl << "Python ndarray :" << p::extract<char const *>(p::str(py_array)) << std::endl;
|
||||
// Change an element in the python ndarray
|
||||
py_array[1] = 5 ;
|
||||
// And see if the C++ container is changed or not
|
||||
std::cout << "Is the change reflected in the C++ array used to create the ndarray ? " << std::endl ;
|
||||
for (int j = 0;j<4 ; j++)
|
||||
{
|
||||
std::cout << arr[j] << ' ' ;
|
||||
}
|
||||
// Conversely, change it in C++
|
||||
arr[2] = 8 ;
|
||||
// And see if the changes are reflected in the Python ndarray
|
||||
std::cout << std::endl << "Is the change reflected in the Python ndarray ?" << std::endl << p::extract<char const *>(p::str(py_array)) << std::endl;
|
||||
|
||||
}
|
||||
315
example/numpy/gaussian.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
// Copyright Jim Bosch 2010-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
#ifndef M_PI
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
const double M_PI = boost::math::constants::pi<double>();
|
||||
#endif
|
||||
|
||||
namespace bp = boost::python;
|
||||
namespace bn = boost::python::numpy;
|
||||
|
||||
/**
|
||||
* A 2x2 matrix class, purely for demonstration purposes.
|
||||
*
|
||||
* Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
|
||||
*/
|
||||
class matrix2 {
|
||||
public:
|
||||
|
||||
double & operator()(int i, int j) {
|
||||
return _data[i*2 + j];
|
||||
}
|
||||
|
||||
double const & operator()(int i, int j) const {
|
||||
return _data[i*2 + j];
|
||||
}
|
||||
|
||||
double const * data() const { return _data; }
|
||||
|
||||
private:
|
||||
double _data[4];
|
||||
};
|
||||
|
||||
/**
|
||||
* A 2-element vector class, purely for demonstration purposes.
|
||||
*
|
||||
* Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
|
||||
*/
|
||||
class vector2 {
|
||||
public:
|
||||
|
||||
double & operator[](int i) {
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
double const & operator[](int i) const {
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
double const * data() const { return _data; }
|
||||
|
||||
vector2 operator+(vector2 const & other) const {
|
||||
vector2 r;
|
||||
r[0] = _data[0] + other[0];
|
||||
r[1] = _data[1] + other[1];
|
||||
return r;
|
||||
}
|
||||
|
||||
vector2 operator-(vector2 const & other) const {
|
||||
vector2 r;
|
||||
r[0] = _data[0] - other[0];
|
||||
r[1] = _data[1] - other[1];
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
double _data[2];
|
||||
};
|
||||
|
||||
/**
|
||||
* Matrix-vector multiplication.
|
||||
*/
|
||||
vector2 operator*(matrix2 const & m, vector2 const & v) {
|
||||
vector2 r;
|
||||
r[0] = m(0, 0) * v[0] + m(0, 1) * v[1];
|
||||
r[1] = m(1, 0) * v[0] + m(1, 1) * v[1];
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vector inner product.
|
||||
*/
|
||||
double dot(vector2 const & v1, vector2 const & v2) {
|
||||
return v1[0] * v2[0] + v1[1] * v2[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents a simple 2-d Gaussian (Normal) distribution, defined by a
|
||||
* mean vector 'mu' and a covariance matrix 'sigma'.
|
||||
*/
|
||||
class bivariate_gaussian {
|
||||
public:
|
||||
|
||||
vector2 const & get_mu() const { return _mu; }
|
||||
|
||||
matrix2 const & get_sigma() const { return _sigma; }
|
||||
|
||||
/**
|
||||
* Evaluate the density of the distribution at a point defined by a two-element vector.
|
||||
*/
|
||||
double operator()(vector2 const & p) const {
|
||||
vector2 u = _cholesky * (p - _mu);
|
||||
return 0.5 * _cholesky(0, 0) * _cholesky(1, 1) * std::exp(-0.5 * dot(u, u)) / M_PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the density of the distribution at an (x, y) point.
|
||||
*/
|
||||
double operator()(double x, double y) const {
|
||||
vector2 p;
|
||||
p[0] = x;
|
||||
p[1] = y;
|
||||
return operator()(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct from a mean vector and covariance matrix.
|
||||
*/
|
||||
bivariate_gaussian(vector2 const & mu, matrix2 const & sigma)
|
||||
: _mu(mu), _sigma(sigma), _cholesky(compute_inverse_cholesky(sigma))
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* This evaluates the inverse of the Cholesky factorization of a 2x2 matrix;
|
||||
* it's just a shortcut in evaluating the density.
|
||||
*/
|
||||
static matrix2 compute_inverse_cholesky(matrix2 const & m) {
|
||||
matrix2 l;
|
||||
// First do cholesky factorization: l l^t = m
|
||||
l(0, 0) = std::sqrt(m(0, 0));
|
||||
l(0, 1) = m(0, 1) / l(0, 0);
|
||||
l(1, 1) = std::sqrt(m(1, 1) - l(0,1) * l(0,1));
|
||||
// Now do forward-substitution (in-place) to invert:
|
||||
l(0, 0) = 1.0 / l(0, 0);
|
||||
l(1, 0) = l(0, 1) = -l(0, 1) / l(1, 1);
|
||||
l(1, 1) = 1.0 / l(1, 1);
|
||||
return l;
|
||||
}
|
||||
|
||||
vector2 _mu;
|
||||
matrix2 _sigma;
|
||||
matrix2 _cholesky;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* We have a two options for wrapping get_mu and get_sigma into NumPy-returning Python methods:
|
||||
* - we could deep-copy the data, making totally new NumPy arrays;
|
||||
* - we could make NumPy arrays that point into the existing memory.
|
||||
* The latter is often preferable, especially if the arrays are large, but it's dangerous unless
|
||||
* the reference counting is correct: the returned NumPy array needs to hold a reference that
|
||||
* keeps the memory it points to from being deallocated as long as it is alive. This is what the
|
||||
* "owner" argument to from_data does - the NumPy array holds a reference to the owner, keeping it
|
||||
* from being destroyed.
|
||||
*
|
||||
* Note that this mechanism isn't completely safe for data members that can have their internal
|
||||
* storage reallocated. A std::vector, for instance, can be invalidated when it is resized,
|
||||
* so holding a Python reference to a C++ class that holds a std::vector may not be a guarantee
|
||||
* that the memory in the std::vector will remain valid.
|
||||
*/
|
||||
|
||||
/**
|
||||
* These two functions are custom wrappers for get_mu and get_sigma, providing the shallow-copy
|
||||
* conversion with reference counting described above.
|
||||
*
|
||||
* It's also worth noting that these return NumPy arrays that cannot be modified in Python;
|
||||
* the const overloads of vector::data() and matrix::data() return const references,
|
||||
* and passing a const pointer to from_data causes NumPy's 'writeable' flag to be set to false.
|
||||
*/
|
||||
static bn::ndarray py_get_mu(bp::object const & self) {
|
||||
vector2 const & mu = bp::extract<bivariate_gaussian const &>(self)().get_mu();
|
||||
return bn::from_data(
|
||||
mu.data(),
|
||||
bn::dtype::get_builtin<double>(),
|
||||
bp::make_tuple(2),
|
||||
bp::make_tuple(sizeof(double)),
|
||||
self
|
||||
);
|
||||
}
|
||||
static bn::ndarray py_get_sigma(bp::object const & self) {
|
||||
matrix2 const & sigma = bp::extract<bivariate_gaussian const &>(self)().get_sigma();
|
||||
return bn::from_data(
|
||||
sigma.data(),
|
||||
bn::dtype::get_builtin<double>(),
|
||||
bp::make_tuple(2, 2),
|
||||
bp::make_tuple(2 * sizeof(double), sizeof(double)),
|
||||
self
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* To allow the constructor to work, we need to define some from-Python converters from NumPy arrays
|
||||
* to the matrix/vector types. The rvalue-from-python functionality is not well-documented in Boost.Python
|
||||
* itself; you can learn more from boost/python/converter/rvalue_from_python_data.hpp.
|
||||
*/
|
||||
|
||||
/**
|
||||
* We start with two functions that just copy a NumPy array into matrix/vector objects. These will be used
|
||||
* in the templated converted below. The first just uses the operator[] overloads provided by
|
||||
* bp::object.
|
||||
*/
|
||||
static void copy_ndarray_to_mv2(bn::ndarray const & array, vector2 & vec) {
|
||||
vec[0] = bp::extract<double>(array[0]);
|
||||
vec[1] = bp::extract<double>(array[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Here, we'll take the alternate approach of using the strides to access the array's memory directly.
|
||||
* This can be much faster for large arrays.
|
||||
*/
|
||||
static void copy_ndarray_to_mv2(bn::ndarray const & array, matrix2 & mat) {
|
||||
// Unfortunately, get_strides() can't be inlined, so it's best to call it once up-front.
|
||||
Py_intptr_t const * strides = array.get_strides();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
mat(i, j) = *reinterpret_cast<double const *>(array.get_data() + i * strides[0] + j * strides[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Here's the actual converter. Because we've separated the differences into the above functions,
|
||||
* we can write a single template class that works for both matrix2 and vector2.
|
||||
*/
|
||||
template <typename T, int N>
|
||||
struct mv2_from_python {
|
||||
|
||||
/**
|
||||
* Register the converter.
|
||||
*/
|
||||
mv2_from_python() {
|
||||
bp::converter::registry::push_back(
|
||||
&convertible,
|
||||
&construct,
|
||||
bp::type_id< T >()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if we can convert this to the desired type; if not return zero.
|
||||
* If we can convert, returned pointer can be used by construct().
|
||||
*/
|
||||
static void * convertible(PyObject * p) {
|
||||
try {
|
||||
bp::object obj(bp::handle<>(bp::borrowed(p)));
|
||||
std::auto_ptr<bn::ndarray> array(
|
||||
new bn::ndarray(
|
||||
bn::from_object(obj, bn::dtype::get_builtin<double>(), N, N, bn::ndarray::V_CONTIGUOUS)
|
||||
)
|
||||
);
|
||||
if (array->shape(0) != 2) return 0;
|
||||
if (N == 2 && array->shape(1) != 2) return 0;
|
||||
return array.release();
|
||||
} catch (bp::error_already_set & err) {
|
||||
bp::handle_exception();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the conversion by initializing the C++ object into memory prepared by Boost.Python.
|
||||
*/
|
||||
static void construct(PyObject * obj, bp::converter::rvalue_from_python_stage1_data * data) {
|
||||
// Extract the array we passed out of the convertible() member function.
|
||||
std::auto_ptr<bn::ndarray> array(reinterpret_cast<bn::ndarray*>(data->convertible));
|
||||
// Find the memory block Boost.Python has prepared for the result.
|
||||
typedef bp::converter::rvalue_from_python_storage<T> storage_t;
|
||||
storage_t * storage = reinterpret_cast<storage_t*>(data);
|
||||
// Use placement new to initialize the result.
|
||||
T * m_or_v = new (storage->storage.bytes) T();
|
||||
// Fill the result with the values from the NumPy array.
|
||||
copy_ndarray_to_mv2(*array, *m_or_v);
|
||||
// Finish up.
|
||||
data->convertible = storage->storage.bytes;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(gaussian) {
|
||||
bn::initialize();
|
||||
|
||||
// Register the from-python converters
|
||||
mv2_from_python< vector2, 1 >();
|
||||
mv2_from_python< matrix2, 2 >();
|
||||
|
||||
typedef double (bivariate_gaussian::*call_vector)(vector2 const &) const;
|
||||
|
||||
bp::class_<bivariate_gaussian>("bivariate_gaussian", bp::init<bivariate_gaussian const &>())
|
||||
|
||||
// Declare the constructor (wouldn't work without the from-python converters).
|
||||
.def(bp::init< vector2 const &, matrix2 const & >())
|
||||
|
||||
// Use our custom reference-counting getters
|
||||
.add_property("mu", &py_get_mu)
|
||||
.add_property("sigma", &py_get_sigma)
|
||||
|
||||
// First overload accepts a two-element array argument
|
||||
.def("__call__", (call_vector)&bivariate_gaussian::operator())
|
||||
|
||||
// This overload works like a binary NumPy universal function: you can pass
|
||||
// in scalars or arrays, and the C++ function will automatically be called
|
||||
// on each element of an array argument.
|
||||
.def("__call__", bn::binary_ufunc<bivariate_gaussian,double,double,double>::make())
|
||||
;
|
||||
}
|
||||
71
example/numpy/ndarray.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* @brief An example to show how to create ndarrays using arbitrary Python sequences.
|
||||
*
|
||||
* The Python sequence could be any object whose __array__ method returns an array, or any
|
||||
* (nested) sequence. This example also shows how to create arrays using both unit and
|
||||
* non-unit strides.
|
||||
*/
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
#if _MSC_VER
|
||||
using boost::uint8_t;
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create an ndarray from a simple tuple
|
||||
p::object tu = p::make_tuple('a','b','c') ;
|
||||
np::ndarray example_tuple = np::array (tu) ;
|
||||
// and from a list
|
||||
p::list l ;
|
||||
np::ndarray example_list = np::array (l) ;
|
||||
// Optionally, you can also specify a dtype
|
||||
np::dtype dt = np::dtype::get_builtin<int>();
|
||||
np::ndarray example_list1 = np::array (l,dt);
|
||||
// You can also create an array by supplying data.First,create an integer array
|
||||
int data[] = {1,2,3,4} ;
|
||||
// Create a shape, and strides, needed by the function
|
||||
p::tuple shape = p::make_tuple(4) ;
|
||||
p::tuple stride = p::make_tuple(4) ;
|
||||
// The function also needs an owner, to keep track of the data array passed. Passing none is dangerous
|
||||
p::object own ;
|
||||
// The from_data function takes the data array, datatype,shape,stride and owner as arguments
|
||||
// and returns an ndarray
|
||||
np::ndarray data_ex = np::from_data(data,dt,shape,stride,own);
|
||||
// Print the ndarray we created
|
||||
std::cout << "Single dimensional array ::" << std::endl << p::extract < char const * > (p::str(data_ex)) << std::endl ;
|
||||
// Now lets make an 3x2 ndarray from a multi-dimensional array using non-unit strides
|
||||
// First lets create a 3x4 array of 8-bit integers
|
||||
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
|
||||
// Now let's create an array of 3x2 elements, picking the first and third elements from each row
|
||||
// For that, the shape will be 3x2
|
||||
shape = p::make_tuple(3,2) ;
|
||||
// The strides will be 4x2 i.e. 4 bytes to go to the next desired row, and 2 bytes to go to the next desired column
|
||||
stride = p::make_tuple(4,2) ;
|
||||
// Get the numpy dtype for the built-in 8-bit integer data type
|
||||
np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
|
||||
// First lets create and print out the ndarray as is
|
||||
np::ndarray mul_data_ex = np::from_data(mul_data,dt1, p::make_tuple(3,4),p::make_tuple(4,1),p::object());
|
||||
std::cout << "Original multi dimensional array :: " << std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
|
||||
// Now create the new ndarray using the shape and strides
|
||||
mul_data_ex = np::from_data(mul_data,dt1, shape,stride,p::object());
|
||||
// Print out the array we created using non-unit strides
|
||||
std::cout << "Selective multidimensional array :: "<<std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
32
example/numpy/simple.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2011 Stefan Seefeld.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create a 3x3 shape...
|
||||
p::tuple shape = p::make_tuple(3, 3);
|
||||
// ...as well as a type for C++ float
|
||||
np::dtype dtype = np::dtype::get_builtin<float>();
|
||||
// Construct an array with the above shape and type
|
||||
np::ndarray a = np::zeros(shape, dtype);
|
||||
// Construct an empty array with the above shape and dtype as well
|
||||
np::ndarray b = np::empty(shape,dtype);
|
||||
// Print the array
|
||||
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
// Reshape the array into a 1D array
|
||||
a = a.reshape(p::make_tuple(9));
|
||||
// Print it again.
|
||||
std::cout << "Reshaped array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
}
|
||||
86
example/numpy/ufunc.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* @brief An example to demonstrate use of universal functions or ufuncs
|
||||
*
|
||||
*
|
||||
* @todo Calling the overloaded () operator is in a roundabout manner, find a simpler way
|
||||
* None of the methods like np::add, np::multiply etc are supported as yet
|
||||
*/
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
|
||||
// Create the structs necessary to implement the ufuncs
|
||||
// The typedefs *must* be made
|
||||
|
||||
struct UnarySquare
|
||||
{
|
||||
typedef double argument_type;
|
||||
typedef double result_type;
|
||||
|
||||
double operator()(double r) const { return r * r;}
|
||||
};
|
||||
|
||||
struct BinarySquare
|
||||
{
|
||||
typedef double first_argument_type;
|
||||
typedef double second_argument_type;
|
||||
typedef double result_type;
|
||||
|
||||
double operator()(double a,double b) const { return (a*a + b*b) ; }
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Expose the struct UnarySquare to Python as a class, and let ud be the class object
|
||||
p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare")
|
||||
.def("__call__", np::unary_ufunc<UnarySquare>::make());
|
||||
// Let inst be an instance of the class ud
|
||||
p::object inst = ud();
|
||||
// Use the "__call__" method to call the overloaded () operator and print the value
|
||||
std::cout << "Square of unary scalar 1.0 is " << p::extract <char const * > (p::str(inst.attr("__call__")(1.0))) << std::endl ;
|
||||
// Create an array in C++
|
||||
int arr[] = {1,2,3,4} ;
|
||||
// ..and use it to create the ndarray in Python
|
||||
np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
|
||||
// Print out the demo array
|
||||
std::cout << "Demo array is " << p::extract <char const * > (p::str(demo_array)) << std::endl ;
|
||||
// Call the "__call__" method to perform the operation and assign the value to result_array
|
||||
p::object result_array = inst.attr("__call__")(demo_array) ;
|
||||
// Print the resultant array
|
||||
std::cout << "Square of demo array is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
|
||||
// Lets try the same with a list
|
||||
p::list li ;
|
||||
li.append(3);
|
||||
li.append(7);
|
||||
// Print out the demo list
|
||||
std::cout << "Demo list is " << p::extract <char const * > (p::str(li)) << std::endl ;
|
||||
// Call the ufunc for the list
|
||||
result_array = inst.attr("__call__")(li) ;
|
||||
// And print the list out
|
||||
std::cout << "Square of demo list is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
|
||||
// Now lets try Binary ufuncs
|
||||
// Expose the struct BinarySquare to Python as a class, and let ud be the class object
|
||||
ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare")
|
||||
.def("__call__", np::binary_ufunc<BinarySquare>::make());
|
||||
// Again initialise inst as an instance of the class ud
|
||||
inst = ud();
|
||||
// Print the two input listsPrint the two input lists
|
||||
std::cout << "The two input list for binary ufunc are " << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl ;
|
||||
// Call the binary ufunc taking demo_array as both inputs
|
||||
result_array = inst.attr("__call__")(demo_array,demo_array) ;
|
||||
std::cout << "Square of list with binary ufunc is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
|
||||
}
|
||||
|
||||
135
example/numpy/wrap.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
// Copyright Jim Bosch 2011-2012.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
/**
|
||||
* A simple example showing how to wrap a couple of C++ functions that
|
||||
* operate on 2-d arrays into Python functions that take NumPy arrays
|
||||
* as arguments.
|
||||
*
|
||||
* If you find have a lot of such functions to wrap, you may want to
|
||||
* create a C++ array type (or use one of the many existing C++ array
|
||||
* libraries) that maps well to NumPy arrays and create Boost.Python
|
||||
* converters. There's more work up front than the approach here,
|
||||
* but much less boilerplate per function. See the "Gaussian" example
|
||||
* included with Boost.NumPy for an example of custom converters, or
|
||||
* take a look at the "ndarray" project on GitHub for a more complete,
|
||||
* high-level solution.
|
||||
*
|
||||
* Note that we're using embedded Python here only to make a convenient
|
||||
* self-contained example; you could just as easily put the wrappers
|
||||
* in a regular C++-compiled module and imported them in regular
|
||||
* Python. Again, see the Gaussian demo for an example.
|
||||
*/
|
||||
|
||||
#include <boost/python/numpy.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::python::numpy;
|
||||
|
||||
// This is roughly the most efficient way to write a C/C++ function that operates
|
||||
// on a 2-d NumPy array - operate directly on the array by incrementing a pointer
|
||||
// with the strides.
|
||||
void fill1(double * array, int rows, int cols, int row_stride, int col_stride) {
|
||||
double * row_iter = array;
|
||||
double n = 0.0; // just a counter we'll fill the array with.
|
||||
for (int i = 0; i < rows; ++i, row_iter += row_stride) {
|
||||
double * col_iter = row_iter;
|
||||
for (int j = 0; j < cols; ++j, col_iter += col_stride) {
|
||||
*col_iter = ++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Here's a simple wrapper function for fill1. It requires that the passed
|
||||
// NumPy array be exactly what we're looking for - no conversion from nested
|
||||
// sequences or arrays with other data types, because we want to modify it
|
||||
// in-place.
|
||||
void wrap_fill1(np::ndarray const & array) {
|
||||
if (array.get_dtype() != np::dtype::get_builtin<double>()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
if (array.get_nd() != 2) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
fill1(reinterpret_cast<double*>(array.get_data()),
|
||||
array.shape(0), array.shape(1),
|
||||
array.strides(0) / sizeof(double), array.strides(1) / sizeof(double));
|
||||
}
|
||||
|
||||
// Another fill function that takes a double**. This is less efficient, because
|
||||
// it's not the native NumPy data layout, but it's common enough in C/C++ that
|
||||
// it's worth its own example. This time we don't pass the strides, and instead
|
||||
// in wrap_fill2 we'll require the C_CONTIGUOUS bitflag, which guarantees that
|
||||
// the column stride is 1 and the row stride is the number of columns. That
|
||||
// restricts the arrays that can be passed to fill2 (it won't work on most
|
||||
// subarray views or transposes, for instance).
|
||||
void fill2(double ** array, int rows, int cols) {
|
||||
double n = 0.0; // just a counter we'll fill the array with.
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
for (int j = 0; j < cols; ++j) {
|
||||
array[i][j] = ++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Here's the wrapper for fill2; it's a little more complicated because we need
|
||||
// to check the flags and create the array of pointers.
|
||||
void wrap_fill2(np::ndarray const & array) {
|
||||
if (array.get_dtype() != np::dtype::get_builtin<double>()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
if (array.get_nd() != 2) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
if (!(array.get_flags() & np::ndarray::C_CONTIGUOUS)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Array must be row-major contiguous");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
double * iter = reinterpret_cast<double*>(array.get_data());
|
||||
int rows = array.shape(0);
|
||||
int cols = array.shape(1);
|
||||
boost::scoped_array<double*> ptrs(new double*[rows]);
|
||||
for (int i = 0; i < rows; ++i, iter += cols) {
|
||||
ptrs[i] = iter;
|
||||
}
|
||||
fill2(ptrs.get(), array.shape(0), array.shape(1));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(example) {
|
||||
np::initialize(); // have to put this in any module that uses Boost.NumPy
|
||||
p::def("fill1", wrap_fill1);
|
||||
p::def("fill2", wrap_fill2);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// This line makes our module available to the embedded Python intepreter.
|
||||
# if PY_VERSION_HEX >= 0x03000000
|
||||
PyImport_AppendInittab("example", &PyInit_example);
|
||||
# else
|
||||
PyImport_AppendInittab("example", &initexample);
|
||||
# endif
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
|
||||
PyRun_SimpleString(
|
||||
"import example\n"
|
||||
"import numpy\n"
|
||||
"z1 = numpy.zeros((5,6), dtype=float)\n"
|
||||
"z2 = numpy.zeros((4,3), dtype=float)\n"
|
||||
"example.fill1(z1)\n"
|
||||
"example.fill2(z2)\n"
|
||||
"print z1\n"
|
||||
"print z2\n"
|
||||
);
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
# Copyright David Abrahams 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
# Copyright Stefan Seefeld 2016.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Specify the path to the Boost project. If you move this project,
|
||||
# adjust the path to refer to the Boost root directory.
|
||||
use-project boost
|
||||
: ../../../.. ;
|
||||
|
||||
# Set up the project-wide requirements that everything uses the
|
||||
# boost_python library defined in the project whose global ID is
|
||||
# /boost/python.
|
||||
project boost-python-quickstart
|
||||
: requirements <library>/boost/python//boost_python
|
||||
<implicit-dependency>/boost//headers
|
||||
: usage-requirements <implicit-dependency>/boost//headers
|
||||
;
|
||||
|
||||
# Make the definition of the python-extension rule available
|
||||
import python ;
|
||||
import testing ;
|
||||
|
||||
project quickstart
|
||||
: requirements
|
||||
<location>.
|
||||
;
|
||||
|
||||
# Declare a Python extension called hello.
|
||||
python-extension extending : extending.cpp ;
|
||||
@@ -25,8 +17,6 @@ python-extension extending : extending.cpp ;
|
||||
# Declare an executable called embedding that embeds Python
|
||||
exe embedding : embedding.cpp /python//python ;
|
||||
|
||||
import testing ;
|
||||
|
||||
# Declare a test of the extension module
|
||||
testing.make-test run-pyd : extending test_extending.py : : test_ext ;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Copyright David Abrahams 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
# Edit this path to point at the tools/build/src subdirectory of your
|
||||
# Boost installation. Absolute paths work, too.
|
||||
boost-build ../../../../tools/build/src ;
|
||||
@@ -1,6 +1,7 @@
|
||||
#! /usr/bin/env python
|
||||
# Copyright Stefan Seefeld 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
print 'Hello World !'
|
||||
print('Hello World !')
|
||||
number = 42
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright Ralf W. Grosse-Kunstleve 2002-2004. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/python/module.hpp>
|
||||
#include <boost/python/def.hpp>
|
||||
#include <boost/python/tuple.hpp>
|
||||
#include <boost/python/to_python_converter.hpp>
|
||||
|
||||
namespace { // Avoid cluttering the global namespace.
|
||||
|
||||
// Converts a std::pair instance to a Python tuple.
|
||||
template <typename T1, typename T2>
|
||||
struct std_pair_to_tuple
|
||||
{
|
||||
static PyObject* convert(std::pair<T1, T2> const& p)
|
||||
{
|
||||
return boost::python::incref(
|
||||
boost::python::make_tuple(p.first, p.second).ptr());
|
||||
}
|
||||
static PyTypeObject const *get_pytype () {return &PyTuple_Type; }
|
||||
};
|
||||
|
||||
// Helper for convenience.
|
||||
template <typename T1, typename T2>
|
||||
struct std_pair_to_python_converter
|
||||
{
|
||||
std_pair_to_python_converter()
|
||||
{
|
||||
boost::python::to_python_converter<
|
||||
std::pair<T1, T2>,
|
||||
std_pair_to_tuple<T1, T2>,
|
||||
true //std_pair_to_tuple has get_pytype
|
||||
>();
|
||||
}
|
||||
};
|
||||
|
||||
// Example function returning a std::pair.
|
||||
std::pair<int, int>
|
||||
foo() { return std::pair<int, int>(3, 5); }
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
BOOST_PYTHON_MODULE(std_pair_ext)
|
||||
{
|
||||
using namespace boost::python;
|
||||
std_pair_to_python_converter<int, int>();
|
||||
def("foo", foo);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
r'''>>> import getting_started1
|
||||
>>> print getting_started1.greet()
|
||||
hello, world
|
||||
>>> number = 11
|
||||
>>> print number, '*', number, '=', getting_started1.square(number)
|
||||
11 * 11 = 121
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started1
|
||||
return doctest.testmod(test_getting_started1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
@@ -1,34 +0,0 @@
|
||||
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
r'''>>> from getting_started2 import *
|
||||
>>> hi = hello('California')
|
||||
>>> hi.greet()
|
||||
'Hello from California'
|
||||
>>> invite(hi)
|
||||
'Hello from California! Please come soon!'
|
||||
>>> hi.invite()
|
||||
'Hello from California! Please come soon!'
|
||||
|
||||
>>> class wordy(hello):
|
||||
... def greet(self):
|
||||
... return hello.greet(self) + ', where the weather is fine'
|
||||
...
|
||||
>>> hi2 = wordy('Florida')
|
||||
>>> hi2.greet()
|
||||
'Hello from Florida, where the weather is fine'
|
||||
>>> invite(hi2)
|
||||
'Hello from Florida! Please come soon!'
|
||||
'''
|
||||
|
||||
def run(args = None):
|
||||
if args is not None:
|
||||
import sys
|
||||
sys.argv = args
|
||||
import doctest, test_getting_started2
|
||||
return doctest.testmod(test_getting_started2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
sys.exit(run()[0])
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# Copyright Ralf W. Grosse-Kunstleve 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
import std_pair_ext
|
||||
assert std_pair_ext.foo() == (3, 5)
|
||||
print "OK"
|
||||
19
example/tutorial/Jamfile
Normal file
@@ -0,0 +1,19 @@
|
||||
# Copyright Stefan Seefeld 2016.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import python ;
|
||||
|
||||
project tutorial
|
||||
: requirements
|
||||
<location>.
|
||||
;
|
||||
|
||||
python-extension hello_ext : hello.cpp ;
|
||||
|
||||
run-test hello : hello_ext hello.py ;
|
||||
|
||||
alias test : hello ;
|
||||
explicit test ;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# Copyright David Abrahams 2006. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import python ;
|
||||
|
||||
if ! [ python.configured ]
|
||||
{
|
||||
ECHO "notice: no Python configured in user-config.jam" ;
|
||||
ECHO "notice: will use default configuration" ;
|
||||
using python ;
|
||||
}
|
||||
|
||||
# Specify the path to the Boost project. If you move this project,
|
||||
# adjust this path to refer to the Boost root directory.
|
||||
use-project boost
|
||||
: ../../../.. ;
|
||||
|
||||
# Set up the project-wide requirements that everything uses the
|
||||
# boost_python library from the project whose global ID is
|
||||
# /boost/python.
|
||||
project
|
||||
: requirements <library>/boost/python//boost_python
|
||||
<implicit-dependency>/boost//headers
|
||||
: usage-requirements <implicit-dependency>/boost//headers
|
||||
;
|
||||
|
||||
# Declare the three extension modules. You can specify multiple
|
||||
# source files after the colon separated by spaces.
|
||||
python-extension hello_ext : hello.cpp ;
|
||||
|
||||
# Put the extension and Boost.Python DLL in the current directory, so
|
||||
# that running script by hand works.
|
||||
install convenient_copy
|
||||
: hello_ext
|
||||
: <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
|
||||
<location>.
|
||||
;
|
||||
|
||||
# A little "rule" (function) to clean up the syntax of declaring tests
|
||||
# of these extension modules.
|
||||
local rule run-test ( test-name : sources + )
|
||||
{
|
||||
import testing ;
|
||||
testing.make-test run-pyd : $(sources) : : $(test-name) ;
|
||||
}
|
||||
|
||||
# Declare test targets
|
||||
run-test hello : hello_ext hello.py ;
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#! /usr/bin/env python
|
||||
# Copyright Joel de Guzman 2002-2007. Distributed under the Boost
|
||||
# Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt
|
||||
# or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
# Hello World Example from the tutorial
|
||||
|
||||
import hello_ext
|
||||
print hello_ext.greet()
|
||||
print(hello_ext.greet())
|
||||
|
||||
82
fabscript
Normal file
@@ -0,0 +1,82 @@
|
||||
# -*- python -*-
|
||||
#
|
||||
# Copyright (c) 2016 Stefan Seefeld
|
||||
# All rights reserved.
|
||||
#
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
from faber.feature import set
|
||||
from faber.types import cxx
|
||||
from faber.tools.compiler import cxxflags, define, include
|
||||
from faber.tools.python import python
|
||||
from faber.config import report, cxx_checks
|
||||
from faber.config.try_run import try_run
|
||||
|
||||
features += include('include')
|
||||
features += define('BOOST_ALL_NO_LIB') # disable auto-linking
|
||||
boost_include = options.get_with('boost-include')
|
||||
if boost_include:
|
||||
features += include(boost_include)
|
||||
python = python.instance()
|
||||
py_suffix = '{}{}'.format(*python.version.split('.')[:2])
|
||||
features |= set(python.include, python.linkpath, python.libs)
|
||||
|
||||
class has_numpy(try_run):
|
||||
|
||||
src = r"""
|
||||
// If defined, enforces linking against PythonXXd.lib, which
|
||||
// is usually not included in Python environments.
|
||||
#undef _DEBUG
|
||||
#include "Python.h"
|
||||
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
|
||||
#include "numpy/arrayobject.h"
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
void *initialize() { import_array();}
|
||||
#else
|
||||
void initialize() { import_array();}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
int result = 0;
|
||||
Py_Initialize();
|
||||
initialize();
|
||||
if (PyErr_Occurred())
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
npy_intp dims = 2;
|
||||
PyObject * a = PyArray_SimpleNew(1, &dims, NPY_INT);
|
||||
if (!a) result = 1;
|
||||
Py_DECREF(a);
|
||||
}
|
||||
Py_Finalize();
|
||||
return result;
|
||||
}
|
||||
"""
|
||||
def __init__(self, features=()):
|
||||
|
||||
inc = ''
|
||||
try:
|
||||
inc = python.check_python('import numpy; print(numpy.get_include())')
|
||||
features |= include(inc)
|
||||
except Exception:
|
||||
# ignore errors, the check will fail during compilation...
|
||||
pass
|
||||
try_run.__init__(self, 'has_numpy', has_numpy.src, cxx, features,
|
||||
if_=(include(inc), define('HAS_NUMPY')))
|
||||
|
||||
checks = [cxx_checks.has_cxx11(features, define('HAS_CXX11')),
|
||||
has_numpy(features)]
|
||||
config = report('config', checks)
|
||||
|
||||
src = module('src', features=config.use)
|
||||
test = module('test', features=config.use)
|
||||
doc = module('doc', features=config.use)
|
||||
|
||||
default = src.default
|
||||
@@ -42,7 +42,6 @@
|
||||
# include <boost/python/make_function.hpp>
|
||||
# include <boost/python/manage_new_object.hpp>
|
||||
# include <boost/python/module.hpp>
|
||||
# include <boost/python/numeric.hpp>
|
||||
# include <boost/python/object.hpp>
|
||||
# include <boost/python/object_protocol.hpp>
|
||||
# include <boost/python/object_protocol_core.hpp>
|
||||
|
||||
6
include/boost/python/arg_from_python.hpp
Executable file → Normal file
@@ -9,7 +9,7 @@
|
||||
# include <boost/python/converter/arg_from_python.hpp>
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|
||||
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
# include <boost/python/detail/type_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace python {
|
||||
@@ -19,7 +19,7 @@ struct arg_from_python
|
||||
: converter::select_arg_from_python<
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|
||||
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
|
||||
typename boost::remove_cv<T>::type
|
||||
typename detail::remove_cv<T>::type
|
||||
# else
|
||||
T
|
||||
# endif
|
||||
@@ -28,7 +28,7 @@ struct arg_from_python
|
||||
typedef typename converter::select_arg_from_python<
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
|
||||
|| BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(800))
|
||||
typename boost::remove_cv<T>::type
|
||||
typename detail::remove_cv<T>::type
|
||||
# else
|
||||
T
|
||||
# endif
|
||||
|
||||
@@ -11,10 +11,7 @@
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/python/detail/preprocessor.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
|
||||
# include <boost/type_traits/is_reference.hpp>
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
||||
# include <boost/python/detail/type_traits.hpp>
|
||||
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
# include <boost/preprocessor/repeat.hpp>
|
||||
@@ -116,9 +113,9 @@ namespace detail
|
||||
template <class T>
|
||||
struct is_reference_to_keywords
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, is_ref = is_reference<T>::value);
|
||||
typedef typename remove_reference<T>::type deref;
|
||||
typedef typename remove_cv<deref>::type key_t;
|
||||
BOOST_STATIC_CONSTANT(bool, is_ref = detail::is_reference<T>::value);
|
||||
typedef typename detail::remove_reference<T>::type deref;
|
||||
typedef typename detail::remove_cv<deref>::type key_t;
|
||||
BOOST_STATIC_CONSTANT(bool, is_key = is_keywords<key_t>::value);
|
||||
BOOST_STATIC_CONSTANT(bool, value = (is_ref & is_key));
|
||||
|
||||
|
||||
0
include/boost/python/base_type_traits.hpp
Executable file → Normal file
@@ -6,8 +6,8 @@
|
||||
# define BASES_DWA2002321_HPP
|
||||
|
||||
# include <boost/python/detail/prefix.hpp>
|
||||
# include <boost/type_traits/object_traits.hpp>
|
||||
# include <boost/python/detail/type_list.hpp>
|
||||
# include <boost/python/detail/type_traits.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/preprocessor/enum_params_with_a_default.hpp>
|
||||
|
||||