2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 04:42:28 +00:00

Compare commits

..

8 Commits

Author SHA1 Message Date
Dave Abrahams
480aaf6400 gcc-3.0.x needs to use typeid(x).name() instead of type_info directly for cross-shared-lib RTTI.
[SVN r12126]
2001-12-19 22:23:39 +00:00
Dave Abrahams
26b15fe373 initial checkin
[SVN r12123]
2001-12-19 16:06:31 +00:00
Dave Abrahams
eadcc79089 workaround for missing 'C' standard headers
[SVN r12104]
2001-12-18 14:10:06 +00:00
Dave Abrahams
35fd3dfaa1 Integrated Scott Snyder's nested class patch
[SVN r12080]
2001-12-17 05:49:24 +00:00
Dave Abrahams
3505ac2516 initial checkin
[SVN r12077]
2001-12-16 18:38:05 +00:00
Dave Abrahams
946ed17ae1 initial checkin
[SVN r12075]
2001-12-16 18:18:58 +00:00
Dave Abrahams
a4747eb10a *** empty log message ***
[SVN r12074]
2001-12-16 18:09:42 +00:00
nobody
4d6772dac2 This commit was manufactured by cvs2svn to create branch 'newbpl'.
[SVN r8341]
2000-11-27 08:04:06 +00:00
785 changed files with 4899 additions and 64045 deletions

View File

@@ -1,229 +0,0 @@
# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel, Jonathan Helmus, Kyle Kastner, and Alex Willmer
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
$MINICONDA_URL = "http://repo.continuum.io/miniconda/"
$BASE_URL = "https://www.python.org/ftp/python/"
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"
$PYTHON_PRERELEASE_REGEX = @"
(?x)
(?<major>\d+)
\.
(?<minor>\d+)
\.
(?<micro>\d+)
(?<prerelease>[a-z]{1,2}\d+)
"@
function Download ($filename, $url) {
$webclient = New-Object System.Net.WebClient
$basedir = $pwd.Path + "\"
$filepath = $basedir + $filename
if (Test-Path $filename) {
Write-Host "Reusing" $filepath
return $filepath
}
# Download and retry up to 3 times in case of network transient errors.
Write-Host "Downloading" $filename "from" $url
$retry_attempts = 2
for ($i = 0; $i -lt $retry_attempts; $i++) {
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}
return $filepath
}
function ParsePythonVersion ($python_version) {
if ($python_version -match $PYTHON_PRERELEASE_REGEX) {
return ([int]$matches.major, [int]$matches.minor, [int]$matches.micro,
$matches.prerelease)
}
$version_obj = [version]$python_version
return ($version_obj.major, $version_obj.minor, $version_obj.build, "")
}
function DownloadPython ($python_version, $platform_suffix) {
$major, $minor, $micro, $prerelease = ParsePythonVersion $python_version
if (($major -le 2 -and $micro -eq 0) `
-or ($major -eq 3 -and $minor -le 2 -and $micro -eq 0) `
) {
$dir = "$major.$minor"
$python_version = "$major.$minor$prerelease"
} else {
$dir = "$major.$minor.$micro"
}
if ($prerelease) {
if (($major -le 2) `
-or ($major -eq 3 -and $minor -eq 1) `
-or ($major -eq 3 -and $minor -eq 2) `
-or ($major -eq 3 -and $minor -eq 3) `
) {
$dir = "$dir/prev"
}
}
if (($major -le 2) -or ($major -le 3 -and $minor -le 4)) {
$ext = "msi"
if ($platform_suffix) {
$platform_suffix = ".$platform_suffix"
}
} else {
$ext = "exe"
if ($platform_suffix) {
$platform_suffix = "-$platform_suffix"
}
}
$filename = "python-$python_version$platform_suffix.$ext"
$url = "$BASE_URL$dir/$filename"
$filepath = Download $filename $url
return $filepath
}
function InstallPython ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = ""
} else {
$platform_suffix = "amd64"
}
$installer_path = DownloadPython $python_version $platform_suffix
$installer_ext = [System.IO.Path]::GetExtension($installer_path)
Write-Host "Installing $installer_path to $python_home"
$install_log = $python_home + ".log"
if ($installer_ext -eq '.msi') {
InstallPythonMSI $installer_path $python_home $install_log
} else {
InstallPythonEXE $installer_path $python_home $install_log
}
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function InstallPythonEXE ($exepath, $python_home, $install_log) {
$install_args = "/quiet InstallAllUsers=1 TargetDir=$python_home"
RunCommand $exepath $install_args
}
function InstallPythonMSI ($msipath, $python_home, $install_log) {
$install_args = "/qn /log $install_log /i $msipath TARGETDIR=$python_home"
$uninstall_args = "/qn /x $msipath"
RunCommand "msiexec.exe" $install_args
if (-not(Test-Path $python_home)) {
Write-Host "Python seems to be installed else-where, reinstalling."
RunCommand "msiexec.exe" $uninstall_args
RunCommand "msiexec.exe" $install_args
}
}
function RunCommand ($command, $command_args) {
Write-Host $command $command_args
Start-Process -FilePath $command -ArgumentList $command_args -Wait -Passthru
}
function InstallPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$python_path = $python_home + "\python.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
Write-Host "Executing:" $python_path $GET_PIP_PATH
& $python_path $GET_PIP_PATH
} else {
Write-Host "pip already installed."
}
}
function DownloadMiniconda ($python_version, $platform_suffix) {
if ($python_version -eq "3.4") {
$filename = "Miniconda3-3.5.5-Windows-" + $platform_suffix + ".exe"
} else {
$filename = "Miniconda-3.5.5-Windows-" + $platform_suffix + ".exe"
}
$url = $MINICONDA_URL + $filename
$filepath = Download $filename $url
return $filepath
}
function InstallMiniconda ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = "x86"
} else {
$platform_suffix = "x86_64"
}
$filepath = DownloadMiniconda $python_version $platform_suffix
Write-Host "Installing" $filepath "to" $python_home
$install_log = $python_home + ".log"
$args = "/S /D=$python_home"
Write-Host $filepath $args
Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}
function InstallMinicondaPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$conda_path = $python_home + "\Scripts\conda.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$args = "install --yes pip"
Write-Host $conda_path $args
Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru
} else {
Write-Host "pip already installed."
}
}
function main () {
InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
InstallPip $env:PYTHON
}
main

View File

@@ -1,88 +0,0 @@
:: To build extensions for 64 bit Python 3, we need to configure environment
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
::
:: To build extensions for 64 bit Python 2, we need to configure environment
:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
::
:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
:: environment configurations.
::
:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
:: cmd interpreter, at least for (SDK v7.0)
::
:: More details at:
:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
:: http://stackoverflow.com/a/13751649/163740
::
:: Author: Olivier Grisel
:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
::
:: Notes about batch files for Python people:
::
:: Quotes in values are literally part of the values:
:: SET FOO="bar"
:: FOO is now five characters long: " b a r "
:: If you don't want quotes, don't include them on the right-hand side.
::
:: The CALL lines at the end of this file look redundant, but if you move them
:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
:: case, I don't know why.
@ECHO OFF
SET COMMAND_TO_RUN=%*
SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf
:: Extract the major and minor versions, and allow for the minor version to be
:: more than 9. This requires the version number to have two dots in it.
SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
IF "%PYTHON_VERSION:~3,1%" == "." (
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
) ELSE (
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
)
:: Based on the Python version, determine what SDK version to use, and whether
:: to set the SDK for 64-bit.
IF %MAJOR_PYTHON_VERSION% == 2 (
SET WINDOWS_SDK_VERSION="v7.0"
SET SET_SDK_64=Y
) ELSE (
IF %MAJOR_PYTHON_VERSION% == 3 (
SET WINDOWS_SDK_VERSION="v7.1"
IF %MINOR_PYTHON_VERSION% LEQ 4 (
SET SET_SDK_64=Y
) ELSE (
SET SET_SDK_64=N
IF EXIST "%WIN_WDK%" (
:: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
REN "%WIN_WDK%" 0wdf
)
)
) ELSE (
ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
EXIT 1
)
)
IF %PYTHON_ARCH% == 64 (
IF %SET_SDK_64% == Y (
ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
SET DISTUTILS_USE_SDK=1
SET MSSdk=1
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
) ELSE (
ECHO Using default MSVC build environment for 64 bit architecture
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
)
) ELSE (
ECHO Using default MSVC build environment for 32 bit architecture
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
)

View File

@@ -1,58 +0,0 @@
#!/bin/bash
set -e # Exit with nonzero exit code if anything fails
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 -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
# 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
git init
git config user.name "Travis CI"
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.
git commit -m "Deploy to GitHub Pages: ${SHA}"
# Now that we're all set up, we can push.
git push -q upstream HEAD:gh-pages

4
.gitignore vendored
View File

@@ -1,4 +0,0 @@
bin.SCons
*.pyc
*~
\#*\#

View File

@@ -1,99 +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)
sudo: required
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
# clang generates an 'illegal instruction' error in the NumPy check.
# Perhaps we need to upgrade clang to a newer version ?
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++98 OPTIONS=--no-numpy
- compiler: clang
env: CXX=clang++ PYTHON=python3 CXXFLAGS=-std=c++11 OPTIONS=--no-numpy
- env: PYTHON=python DOC=1
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- scons
- gcc-4.8
- g++-4.8
- clang
- 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")
install:
# Install our own version of Boost (the subset we need) as the system version is
# too old (for C++11 support).
- rm -rf $HOME/Boost
- |
set -e
if [ ! -d $HOME/Boost ]; then
echo "rebuilding Boost prerequisites"
wget https://sourceforge.net/projects/boost/files/boost/1.61.0/boost_1_61_0.tar.gz/download
tar xf download
pushd boost_1_61_0
./bootstrap.sh
./b2 tools/bcp
mkdir -p $HOME/Boost
dist/bin/bcp python tools/boostbook tools/quickbook $HOME/Boost &> /dev/null
popd
fi
before_script:
- scons --version
script:
- scons config --python=$PYTHON --boost-include=$HOME/Boost $OPTIONS
- if [ "$DOC" ]; then scons doc; else scons && scons test; fi
after_success:
# Upload docs only when building upstream.
- |
if [ "$DOC" -a \
"$TRAVIS_REPO_SLUG" = "boostorg/python" -a \
"$TRAVIS_PULL_REQUEST" = "false" ]; then
export GH_TOKEN
.ci/upload_docs.sh
fi

57
Jamfile Normal file
View File

@@ -0,0 +1,57 @@
subproject libs/python ;
# bring in the rules for python
SEARCH on <module@>python.jam = $(BOOST_BUILD_PATH) ;
include <module@>python.jam ;
PYTHON_PROPERTIES
+= <metrowerks><*><cxxflags>"-inline deferred"
<cxx><*><include>$(BOOST_ROOT)/boost/compatibility/cpp_c_headers
;
local export-bpl ;
if $(NT)
{
# Stick this in the property set to deal with gcc
export-bpl = export-bpl-logic ;
rule export-bpl-logic ( toolset variant : properties * )
{
if $(toolset) != gcc
{
properties += <define>BOOST_PYTHON_EXPORT=__declspec(dllexport) ;
}
else
{
properties += <define>BOOST_PYTHON_EXPORT= ;
}
return $(properties) ;
}
}
dll bpl
:
src/converter/body.cpp
src/converter/handle.cpp
src/converter/registry.cpp
src/converter/wrapper.cpp
src/converter/unwrap.cpp
src/converter/unwrapper.cpp
src/converter/type_id.cpp
src/object/class.cpp
src/object/function.cpp
:
$(PYTHON_PROPERTIES)
$(export-bpl)
# <define>BOOST_PYTHON_TRACE
;
extension m1 : test/m1.cpp <lib>bpl # <define>BOOST_PYTHON_TRACE
: <gcc><*><define>BOOST_PYTHON_EXPORT=
: debug-python ;
extension m2 : test/m2.cpp <lib>bpl # <define>BOOST_PYTHON_TRACE
: <gcc><*><define>BOOST_PYTHON_EXPORT=
: debug-python ;
boost-python-runtest try : test/newtest.py <lib>m1 <lib>m2 : : debug-python ;

View File

@@ -1,23 +0,0 @@
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.

View File

@@ -1,70 +0,0 @@
![logo](https://raw.githubusercontent.com/boostorg/python/develop/doc/images/bpl.png)
# Synopsis
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
* Globally Registered Type Coercions
* Automatic Cross-Module Type Conversions
* Efficient Function Overloading
* C++ to Python Exception Translation
* Default Arguments
* Keyword Arguments
* Manipulating Python objects in C++
* Exporting C++ Iterators as Python Iterators
* Documentation Strings
See the [Boost.Python](http://boostorg.github.io/python) documentation for details.
**Hint :** Check out the [development version](http://boostorg.github.io/python/develop) of the documentation to see work in progress.
# Building ![Build Status](https://travis-ci.org/boostorg/python.svg?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.
## Prerequisites
* [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.
## Build
Run
```
scons
```
to build the library.
## Test
Run
```
scons test
```
to run the tests.
## Build docs
Run
```
scons doc
```
to build the documentation.

View File

@@ -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', 'sphinx4scons'],
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(env)
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') })

View File

@@ -1,98 +0,0 @@
environment:
global:
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
# /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
matrix:
# Pre-installed Python versions, which Appveyor may upgrade to
# a later point release.
# See: http://www.appveyor.com/docs/installed-software#python
- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.x" # currently 2.7.9
PYTHON_ARCH: "32"
ARCH: "x86"
#- PYTHON: "C:\\Python27-x64"
# PYTHON_VERSION: "2.7.x" # currently 2.7.9
# PYTHON_ARCH: "64"
# 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"
install:
# If there is a newer build queued for the same PR, cancel this one.
# The AppVeyor 'rollout builds' option is supposed to serve the same
# purpose but it is problematic because it tends to cancel builds pushed
# directly to master instead of just PR builds (or the converse).
# credits: JuliaLang developers.
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
- ECHO "Filesystem root:"
- ps: "ls \"C:/\""
- ECHO "Installed libraries:"
- ps: "ls \"C:/Libraries/\""
- 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.
- ps: if (-not(Test-Path($env:PYTHON))) { & .ci\install.ps1 }
# Prepend newly installed Python to the PATH of this build (this cannot be
# done from inside the powershell script as it would require to restart
# the parent CMD process).
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
# Check that we have the expected version and architecture for Python
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""
# Upgrade to the latest version of pip to avoid it displaying warnings
# about it being out of date.
- "pip install --disable-pip-version-check --user --upgrade pip"
# Install the build dependencies of the project. If some dependencies contain
# 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"
build_script:
# Build the compiled extension
#- "%CMD_IN_ENV% python setup.py build"
- scons config arch=%ARCH% --boost-include=%BOOST_PREFIX%
- scons arch=%ARCH%
test_script:
# Run the project tests
#- "%CMD_IN_ENV% python setup.py nosetests"
- scons test arch=%ARCH% --verbose
after_test:
# If tests are successful, create binary packages for the project.
#- "%CMD_IN_ENV% python setup.py bdist_wheel"
#- "%CMD_IN_ENV% python setup.py bdist_wininst"
#- "%CMD_IN_ENV% python setup.py bdist_msi"
#- ps: "ls dist"
#artifacts:
# Archive the generated packages in the ci.appveyor.com build report.
#- path: dist\*
#on_success:
# - TODO: upload the content of dist/*.whl to a public wheelhouse
#

View File

@@ -1,175 +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
;
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) ]
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).python-tag
: # default build
<link>shared
: # usage requirements
<link>static:<define>BOOST_PYTHON_STATIC_LIB
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
rule lib_boost_numpy ( is-py3 ? )
{
numpy-include = [ python.numpy-include ] ;
lib [ cond $(is-py3) : boost_numpy3 : boost_numpy ]
: # sources
numpy/dtype.cpp
numpy/matrix.cpp
numpy/ndarray.cpp
numpy/numpy.cpp
numpy/scalars.cpp
numpy/ufunc.cpp
: # requirements
[ 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
[ cond $(is-py3) : <python>$(py3-version) ]
-<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).python-tag
: # default build
<link>shared
: # usage requirements
<python-debugging>on:<define>BOOST_DEBUG_PYTHON
;
}
libraries = boost_python ;
libraries3 = boost_python3 ;
if [ python.numpy ]
{
libraries += boost_numpy ;
libraries3 += boost_numpy3 ;
}
lib_boost_python ;
lib_boost_numpy ;
if $(py3-version)
{
lib_boost_python yes ;
lib_boost_numpy yes ;
libraries += $(libraries3) ;
}
boost-install $(libraries) ;

View File

@@ -1,140 +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 numpy
from . import boost
def add_options(vars):
ui.add_option('-V', '--verbose', dest='verbose', action='store_true', help='verbose mode: print full commands.')
ui.add_option('--no-numpy', dest='numpy', action='store_false', help='do not attempt to build NumPy bindings.')
python.add_options(vars)
numpy.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')
vars.Add('NUMPY')
vars.Add('NUMPY_CPPPATH', converter=lambda v:v.split())
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(env):
checks = OrderedDict()
checks['cxx'] = cxx.check
checks['python'] = python.check
if env.GetOption('numpy') is not False:
checks['numpy'] = numpy.check
else:
env['NUMPY'] = False
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

View File

@@ -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

View File

@@ -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

View File

@@ -1,86 +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
from contextlib import contextmanager
@contextmanager
def saved(context):
save_cpppath = context.env.get('CPPPATH', [])
save_libs = context.env.get('LIBS', [])
yield context
context.env.Replace(LIBS=save_libs)
context.env.Replace(CPPPATH=save_cpppath)
def add_options(vars):
pass
def check(context):
numpy_source_file = r"""
// If defined, enforces linking againg PythonXXd.lib, which
// is usually not included in Python environments.
#undef _DEBUG
#include "Python.h"
#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;
}
"""
import platform
import subprocess
import re, os
def check_python(cmd):
try:
return True, subprocess.check_output([python, '-c', cmd]).strip()
except subprocess.CalledProcessError as e:
return False, e
context.Message('Checking for NumPy...')
with saved(context):
python = context.env['PYTHON']
result, numpy_incpath = check_python('import numpy; print(numpy.get_include())')
if result:
context.env.AppendUnique(CPPPATH=numpy_incpath)
context.env.AppendUnique(LIBS=context.env['PYTHONLIBS'])
result, output = context.TryRun(numpy_source_file,'.cpp')
if not result:
context.Result(0)
return False
context.env['NUMPY'] = True
context.env['NUMPY_CPPPATH'] = numpy_incpath
context.Result(1)
return True

View File

@@ -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

View File

@@ -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

View File

@@ -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")

View File

@@ -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")

View File

@@ -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)

View File

@@ -1,75 +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 BoostSphinx(env, target, source):
env.Sphinx(target, source)
def exists(env):
return True
def generate(env):
env.AddMethod(QuickBook)
env.AddMethod(BoostBook)
env.AddMethod(BoostHTML)
env.AddMethod(BoostRST)
env.AddMethod(BoostSphinx)

View File

@@ -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")

View File

@@ -1,592 +0,0 @@
"""SCons.Tool.spinx4scons
Tool-specific initialization for the Sphinx document build system.
There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.
It should be placed in e.g. ~/site_scons/site_tools/sphinx4scons/
directory. Then it may be loaded by placing
sphinx = Tool('sphinx4scons')
sphinx(env)
in your SConstruct file.
For further details, please see the SCons documentation on how to
install and enable custom tools.
"""
#
# This package is provided under the Expat license
#
# Copyright (c) 2012 Orlando Wingbrant
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# 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 AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
__author__ = "Orlando Wingbrant"
__email__ = "orlando@widesite.org"
__url__ = "https://bitbucket.org/wingbrant/sphinx4scons"
__license__ = "Expat license"
import SCons.Action
import SCons.Builder
import SCons.Defaults
import SCons.Util
import SCons.Node.FS
import os
from sphinx.util.matching import patfilter, compile_matchers
from sphinx.util.osutil import make_filename
class ToolSphinxWarning(SCons.Warnings.Warning):
pass
class SphinxBuilderNotFound(ToolSphinxWarning):
pass
SCons.Warnings.enableWarningClass(ToolSphinxWarning)
def exists(env):
return _detect(env)
def _detect(env):
"""Try to detect the sphinx-build script."""
try:
return env['SPHINXBUILD']
except KeyError:
pass
sphinx = env.WhereIs('sphinx-build')
if sphinx:
return sphinx
raise SCons.Errors.StopError(
SphinxBuilderNotFound,
"Could not detect sphinx-build script")
return None
def generate(env):
"""Add Builders and construction variables to the Environment."""
env['SPHINXBUILD'] = _detect(env)
sphinx = _create_sphinx_builder(env)
env.SetDefault(
# Additional command-line flags
SPHINXFLAGS = '',
# Tag definitions, each entry will appear on the command line preceded by -t
SPHINXTAGS = [],
# Directory for doctrees
SPHINXDOCTREE = '',
# Path to sphinx configuration file
SPHINXCONFIG = '',
# Config file override settings, each entry will be preceded by -D
SPHINXSETTINGS = {},
# Default sphinx builder,
SPHINXBUILDER = 'html',
# Sphinx command
SPHINXCOM = "$SPHINXBUILD $_SPHINXOPTIONS ${SOURCE.attributes.root} ${TARGET.attributes.root}",
# Alternate console output when building sphinx documents
SPHINXCOMSTR = ""
)
try:
env.AddMethod(Sphinx, "Sphinx")
except AttributeError:
# Looks like we use a pre-0.98 version of SCons...
from SCons.Script.SConscript import SConsEnvironment
SConsEnvironment.Sphinx = Sphinx
def Sphinx(env, target, source, **kw):
"""A pseudo-builder wrapper for the sphinx builder."""
builder = env['BUILDERS']['Sphinx4Scons']
env_kw = env.Override(kw)
options = _get_sphinxoptions(env_kw, target, source)
output = builder(env, target, source, _SPHINXOPTIONS=options, **kw)
return output
def _get_sphinxoptions(env, target, source):
"""Concatenates all the options for the sphinx command line."""
options = []
builder = _get_sphinxbuilder(env)
options.append("-b %s" % env.subst(builder, target=target, source=source))
flags = env.get('options', env.get('SPHINXFLAGS', ''))
options.append(env.subst(flags, target=target, source=source))
tags = env.get('tags', env.get('SPHINXTAGS', None))
if tags is not None:
if not SCons.SCons.Util.is_List(tags):
tags = [tags]
for tag in tags:
if tag != '':
tag = env.subst(tag, target=target, source=source)
options.append("-t %s" % tag)
settings = env.get('settings', env.get('SPHINXSETTINGS', None))
if settings is not None:
if not SCons.SCons.Util.is_Dict(settings):
raise TypeError('SPHINXSETTINGS and/or settings argument must be a dictionary')
for key, value in settings.iteritems():
if value != '':
value = env.subst(value, target=target, source=source)
options.append('-D "%s=%s"' % (key, value))
doctree = env.get('doctree', env.get("SPHINXDOCTREE", None))
if isinstance(doctree, SCons.Node.FS.Dir):
options.append("-d %s" % doctree.get_abspath())
elif doctree is not None and doctree != '':
doctree = env.subst(doctree, target=target, source=source)
options.append("-d %s" % env.Dir(doctree).get_abspath())
config = _get_sphinxconfig_path(env, None)
if config is not None and config != '':
config = env.subst(config, target=target, source=source)
options.append("-c %s" % env.Dir(config).File('conf.py').rfile().dir.get_abspath())
return " ".join(options)
def _create_sphinx_builder(env):
try:
sphinx = env['BUILDERS']['Sphinx4Scons']
except KeyError:
fs = SCons.Node.FS.get_default_fs()
sphinx_com = SCons.Action.Action('$SPHINXCOM', '$SPHINXCOMSTR')
sphinx = SCons.Builder.Builder(action=sphinx_com,
emitter=sphinx_emitter,
target_factory=fs.Dir,
source_factory=fs.Dir
)
env['BUILDERS']['Sphinx4Scons'] = sphinx
return sphinx
def sphinx_emitter(target, source, env):
target[0].must_be_same(SCons.Node.FS.Dir)
targetnode = target[0]
source[0].must_be_same(SCons.Node.FS.Dir)
srcnode = source[0]
configdir = _get_sphinxconfig_path(env, None)
if not configdir:
confignode = srcnode
else:
confignode = env.Dir(configdir)
srcinfo = SourceInfo(srcnode, confignode, env)
targets, sources = _get_emissions(env, target, srcinfo)
env.Clean(targets, target[0])
return targets, sources
def sphinx_path(os_path):
"""Create sphinx-style path from os-style path."""
return os_path.replace(os.sep, "/")
def os_path(sphinx_path):
"""Create os-style path from sphinx-style path."""
return sphinx_path.replace("/", os.sep)
class SourceInfo(object):
"""
Data container for all different kinds of source files used in
a sphinx project.
"""
def __init__(self, srcnode, confignode, env):
self.confignode = confignode
self.config = self._get_config(self.confignode, env)
self.templates = self._get_templates(self.confignode, self.config)
self.statics = self._get_statics(self.confignode, self.config)
self.srcnode = srcnode
self.sources = self._get_sources(self.srcnode, self.config)
self.srcroot = srcnode
if not srcnode.duplicate:
self.srcroot = srcnode.srcnode().rdir()
def _get_config(self, confignode, env):
config = {}
execfile(confignode.File('conf.py').rfile().get_abspath(), config)
return config
def _get_templates(self, confignode, config):
"""Returns template files defined in the project."""
templates = []
for path in config.get('templates_path', []):
# Check if path is dir or file.
# We can't use FS.Entry since that will create nodes, and
# these nodes don't know about the source tree and will
# get disambiguated to files even if they are directories in the
# source tree.
p = confignode.File('conf.py').rfile().dir.srcnode().get_abspath()
p = os.path.join(p, os_path(path))
if os.path.isfile(p):
templates.append(confignode.File(path))
elif os.path.isdir(p):
node = confignode.Dir(path)
for root, dirs, files in os.walk(p):
mydir = node.Dir(os.path.relpath(root, p))
templates += [mydir.File(f) for f in files]
return templates
def _get_statics(self, confignode, config):
"""Returns static files, filtered through exclude_patterns."""
statics = []
matchers = compile_matchers(config.get('exclude_patterns', []))
for path in config.get('html_static_path', []):
# Check _get_templates() why we use this construction.
p = confignode.File('conf.py').rfile().dir.srcnode().get_abspath()
p = os.path.join(p, os_path(path))
if os.path.isfile(p):
statics.append(confignode.File(path))
elif os.path.isdir(p):
node = confignode.Dir(path)
for root, dirs, files in os.walk(p):
relpath = os.path.relpath(root, p)
for entry in [d for d in dirs if
self._anymatch(matchers,
sphinx_path(os.path.join(relpath, d)))]:
dirs.remove(entry)
statics += [node.File(os_path(f)) for f in
self._exclude(matchers,
[sphinx_path(os.path.join(relpath, name))
for name in files])]
return statics
def _get_sources(self, srcnode, config):
"""Returns all source files in the project filtered through exclude_patterns."""
suffix = config.get('source_suffix', '.rst')
matchers = compile_matchers(config.get('exclude_patterns', []))
srcfiles = []
scannode = srcnode.srcnode().rdir()
for root, dirs, files in os.walk(scannode.get_abspath()):
relpath = os.path.relpath(root, scannode.get_abspath())
for entry in [d for d in dirs if
self._anymatch(matchers,
sphinx_path(os.path.join(relpath, d)))]:
dirs.remove(entry)
srcfiles += [srcnode.File(os_path(f)) for f in
self._exclude(matchers,
[sphinx_path(os.path.join(relpath, name))
for name in files if name.endswith(suffix)])]
return srcfiles
def _exclude(self, matchers, items):
result = items
for matcher in matchers:
result = filter(lambda x: not matcher(x), result)
return result
def _anymatch(self, matchers, item):
for matcher in matchers:
if matcher(item):
return True
return False
def _get_sphinxconfig_path(env, default):
path = env.get('config', env.get('SPHINXCONFIG', None))
if path is None or path == '':
path = default
return path
def _get_emissions(env, target, srcinfo):
targets = []
sources = []
builder = _get_sphinxbuilder(env)
if builder == 'changes':
targets, sources = _get_changes_emissions(env, target, srcinfo)
if builder == 'devhelp':
targets, sources = _get_help_emissions(env, target, srcinfo,
['.devhelp.gz'])
elif builder == 'dirhtml':
targets, sources = _get_dirhtml_emissions(env, target, srcinfo)
elif builder == 'doctest':
targets, sources = _get_doctest_emissions(env, target, srcinfo)
elif builder == 'epub':
targets, sources = _get_epub_emissions(env, target, srcinfo)
elif builder == 'html':
targets, sources = _get_serialize_emissions(env, target, srcinfo)
elif builder == 'htmlhelp':
targets, sources = _get_help_emissions(env, target, srcinfo,
['.hhp'], 'htmlhelp_basename')
elif builder == 'gettext':
targets, sources = _get_gettext_emissions(env, target, srcinfo)
elif builder == 'json':
targets, sources = _get_serialize_emissions(env, target, srcinfo,
'.fjson',
['globalcontext.json',
'searchindex.json',
'self.environment.pickle'])
elif builder == 'latex':
targets, sources = _get_latex_emissions(env, target, srcinfo)
elif builder == 'linkcheck':
targets, sources = _get_linkcheck_emissions(env, target, srcinfo)
elif builder == 'man':
targets, sources = _get_man_emissions(env, target, srcinfo)
elif builder == 'pickle':
targets, sources = _get_serialize_emissions(env, target, srcinfo,
'.fpickle',
['globalcontext.pickle',
'searchindex.pickle',
'environment.pickle'])
elif builder == 'qthelp':
targets, sources = _get_help_emissions(env, target, srcinfo,
['.qhp', '.qhcp'])
elif builder == 'singlehtml':
targets, sources = _get_singlehtml_emissions(env, target, srcinfo)
elif builder == 'texinfo':
targets, sources = _get_texinfo_emissions(env, target, srcinfo)
elif builder == 'text':
targets, sources = _get_text_emissions(env, target, srcinfo)
sources.append(srcinfo.confignode.File('conf.py'))
for s in sources:
s.attributes.root = srcinfo.srcroot
for t in targets:
t.attributes.root = target[0]
return targets, sources
def _get_sphinxbuilder(env):
builder = env.get('builder', env["SPHINXBUILDER"])
if builder is None or builder == '':
raise SCons.Errors.UserError(("Missing construction variable " +
"SPHINXBUILDER or variable is empty."))
return builder
def _get_changes_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [target[0].File("changes.html")]
return targets, sources
def _get_dirhtml_emissions(env, target, srcinfo):
suffix = srcinfo.config.get('html_file_suffix', ".html")
def get_outfilename(pagename):
pagename = os.path.splitext(pagename)[0]
#Special treatment of files named "index". Don't create directory.
if pagename == 'index' or pagename.endswith(os.sep + 'index'):
outfilename = pagename + suffix
else:
outfilename = os.path.join(pagename, 'index' + suffix)
return outfilename
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
targets = []
for s in srcinfo.sources:
t = os.path.relpath(str(s), str(srcinfo.srcroot))
targets.append(target[0].File(get_outfilename(t)))
for key in srcinfo.config.get('html_additional_pages', {}):
t = target[0].File(get_outfilename(key))
targets.append(t)
return targets, sources
def _get_doctest_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [target[0].File("output.txt")]
return targets, sources
def _get_epub_emissions(env, target, srcinfo):
epubPreFiles = srcinfo.config.get('epub_pre_files', [])
epubPostFiles = srcinfo.config.get('epub_post_files', [])
epubCover = srcinfo.config.get('epub_cover', (None, None))
sources = []
sources.extend(srcinfo.sources)
sources.extend([srcinfo.srcroot.File(os_path(f[0])) for f in epubPreFiles])
sources.extend([srcinfo.srcroot.File(os_path(f[0])) for f in epubPostFiles])
if not (epubCover[0] is None or epubCover[0] == ''):
sources.append(srcinfo.srcroot.File(os_path(epubCover[0])))
if not (epubCover[1] is None or epubCover[1] == ''):
sources.append(srcinfo.srcroot.File(os_path(epubCover[1])))
t = srcinfo.config.get('epub_basename',
srcinfo.config.get('project',
'Python'))
targets = [target[0].File("%s.epub" % make_filename(t))]
return targets, sources
def _get_gettext_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [os.path.relpath(str(s), str(srcinfo.srcroot)) for s in sources]
targets = [os.path.splitext(t)[0] for t in targets]
targets = set([t.split(os.sep)[0] for t in targets])
targets = [target[0].File(t + ".pot") for t in targets]
return targets, sources
def _get_help_emissions(env, target, srcinfo, suffixes, basenameConfigKey='project'):
basename = make_filename(
srcinfo.config.get(basenameConfigKey, srcinfo.config['project']))
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
targets = [target[0].File(basename + s) for s in suffixes]
return targets, sources
def _get_latex_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = map(lambda x: target[0].File(os_path(x[1])),
srcinfo.config.get('latex_documents'))
return targets, sources
def _get_linkcheck_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = [target[0].File("output.txt")]
return targets, sources
def _get_man_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = map(lambda x: target[0].File(os_path("%s.%s" % (x[1], x[4]))),
srcinfo.config.get('man_pages'))
return targets, sources
def _get_serialize_emissions(env, target, srcinfo, suffix=None, extrafiles=[]):
if suffix is None:
suffix = srcinfo.config.get('html_file_suffix', '.html')
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
targets = []
for s in srcinfo.sources:
t = os.path.splitext(str(s))[0] + suffix
t = os.path.relpath(t, str(srcinfo.srcroot))
targets.append(t)
for key in srcinfo.config.get('html_additional_pages', {}):
targets.append(os_path("%s%s" % (key, suffix)))
targets.extend(extrafiles)
targets = [target[0].File(t) for t in targets]
return targets, sources
def _get_singlehtml_emissions(env, target, srcinfo):
suffix = srcinfo.config.get('html_file_suffix', ".html")
sources = []
sources.extend(srcinfo.sources)
sources.extend(srcinfo.templates)
sources.extend(srcinfo.statics)
t = os.path.relpath(srcinfo.config['master_doc'] + suffix,
str(srcinfo.srcroot))
targets = [target[0].File(t)]
return targets, sources
def _get_texinfo_emissions(env, target, srcinfo):
suffix = srcinfo.config.get('source_suffix', '.rst')
sources = []
sources.extend(srcinfo.sources)
sources.extend(map(lambda x: source[0].File(os_path(x + suffix)),
srcinfo.config.get('texinfo_appendices', [])))
targets = map(lambda x: target[0].File(os_path("%s.texi" % x[1])),
srcinfo.config.get('texinfo_documents'))
return targets, sources
def _get_text_emissions(env, target, srcinfo):
sources = []
sources.extend(srcinfo.sources)
targets = []
for s in sources:
t = os.path.relpath(str(s), str(srcinfo.srcroot))
t = os.path.splitext(t)[0] + ".txt"
targets.append(target[0].File(t))
return targets, sources

View File

@@ -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)

View File

@@ -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)

View File

@@ -1,66 +0,0 @@
# Copyright (c) 2006 Joel de Guzman
# Copyright (c) 2015 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)
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
<format>html:<xsl:param>boost.defaults=none
<format>html:<xsl:param>toc.max.depth=3
<format>html:<xsl:param>toc.section.depth=2
<format>html:<xsl:param>chunk.section.depth=1
;
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
<format>html:<xsl:param>generate.toc="library nop; chapter toc; section toc;"
<format>html:<xsl:param>html.stylesheet=boostbook.css
<format>html:<xsl:param>boost.image.src=images/boost.png
<format>html:<xsl:param>boost.graphics.root=images/
;
boostbook tutorial : tutorial.qbk
: <format>html:<name>$(here)/html/tutorial
<format>html:<xsl:param>html.stylesheet=../boostbook.css
<format>html:<xsl:param>boost.image.src=../images/boost.png
<format>html:<xsl:param>boost.graphics.root=../images/
;
boostbook reference : reference.qbk
: <format>html:<name>$(here)/html/reference
<format>html:<xsl:param>html.stylesheet=../boostbook.css
<format>html:<xsl:param>boost.image.src=../images/boost.png
<format>html:<xsl:param>boost.graphics.root=../images/
;
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 ;

View File

@@ -1,52 +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'])
if env['NUMPY']:
env.BoostSphinx('html/numpy', 'numpy/')

View File

@@ -1,947 +0,0 @@
+++++++++++++++++++++++++++++++++++++++++++
Building Hybrid Systems with Boost.Python
+++++++++++++++++++++++++++++++++++++++++++
:Author: David Abrahams
:Contact: dave@boost-consulting.com
:organization: `Boost Consulting`_
:date: 2003-05-14
:Author: Ralf W. Grosse-Kunstleve
:copyright: Copyright David Abrahams and Ralf W. Grosse-Kunstleve 2003. All rights reserved
.. contents:: Table of Contents
.. _`Boost Consulting`: http://www.boost-consulting.com
==========
Abstract
==========
Boost.Python is an open source C++ library which provides a concise
IDL-like interface for binding C++ classes and functions to
Python. Leveraging the full power of C++ compile-time introspection
and of recently developed metaprogramming techniques, this is achieved
entirely in pure C++, without introducing a new syntax.
Boost.Python's rich set of features and high-level interface make it
possible to engineer packages from the ground up as hybrid systems,
giving programmers easy and coherent access to both the efficient
compile-time polymorphism of C++ and the extremely convenient run-time
polymorphism of Python.
==============
Introduction
==============
Python and C++ are in many ways as different as two languages could
be: while C++ is usually compiled to machine-code, Python is
interpreted. Python's dynamic type system is often cited as the
foundation of its flexibility, while in C++ static typing is the
cornerstone of its efficiency. C++ has an intricate and difficult
compile-time meta-language, while in Python, practically everything
happens at runtime.
Yet for many programmers, these very differences mean that Python and
C++ complement one another perfectly. Performance bottlenecks in
Python programs can be rewritten in C++ for maximal speed, and
authors of powerful C++ libraries choose Python as a middleware
language for its flexible system integration capabilities.
Furthermore, the surface differences mask some strong similarities:
* 'C'-family control structures (if, while, for...)
* Support for object-orientation, functional programming, and generic
programming (these are both *multi-paradigm* programming languages.)
* Comprehensive operator overloading facilities, recognizing the
importance of syntactic variability for readability and
expressivity.
* High-level concepts such as collections and iterators.
* High-level encapsulation facilities (C++: namespaces, Python: modules)
to support the design of re-usable libraries.
* Exception-handling for effective management of error conditions.
* C++ idioms in common use, such as handle/body classes and
reference-counted smart pointers mirror Python reference semantics.
Given Python's rich 'C' interoperability API, it should in principle
be possible to expose C++ type and function interfaces to Python with
an analogous interface to their C++ counterparts. However, the
facilities provided by Python alone for integration with C++ are
relatively meager. Compared to C++ and Python, 'C' has only very
rudimentary abstraction facilities, and support for exception-handling
is completely missing. 'C' extension module writers are required to
manually manage Python reference counts, which is both annoyingly
tedious and extremely error-prone. Traditional extension modules also
tend to contain a great deal of boilerplate code repetition which
makes them difficult to maintain, especially when wrapping an evolving
API.
These limitations have lead to the development of a variety of wrapping
systems. SWIG_ is probably the most popular package for the
integration of C/C++ and Python. A more recent development is SIP_,
which was specifically designed for interfacing Python with the Qt_
graphical user interface library. Both SWIG and SIP introduce their
own specialized languages for customizing inter-language bindings.
This has certain advantages, but having to deal with three different
languages (Python, C/C++ and the interface language) also introduces
practical and mental difficulties. The CXX_ package demonstrates an
interesting alternative. It shows that at least some parts of
Python's 'C' API can be wrapped and presented through a much more
user-friendly C++ interface. However, unlike SWIG and SIP, CXX does
not include support for wrapping C++ classes as new Python types.
The features and goals of Boost.Python_ overlap significantly with
many of these other systems. That said, Boost.Python attempts to
maximize convenience and flexibility without introducing a separate
wrapping language. Instead, it presents the user with a high-level
C++ interface for wrapping C++ classes and functions, managing much of
the complexity behind-the-scenes with static metaprogramming.
Boost.Python also goes beyond the scope of earlier systems by
providing:
* Support for C++ virtual functions that can be overridden in Python.
* Comprehensive lifetime management facilities for low-level C++
pointers and references.
* Support for organizing extensions as Python packages,
with a central registry for inter-language type conversions.
* A safe and convenient mechanism for tying into Python's powerful
serialization engine (pickle).
* Coherence with the rules for handling C++ lvalues and rvalues that
can only come from a deep understanding of both the Python and C++
type systems.
The key insight that sparked the development of Boost.Python is that
much of the boilerplate code in traditional extension modules could be
eliminated using C++ compile-time introspection. Each argument of a
wrapped C++ function must be extracted from a Python object using a
procedure that depends on the argument type. Similarly the function's
return type determines how the return value will be converted from C++
to Python. Of course argument and return types are part of each
function's type, and this is exactly the source from which
Boost.Python deduces most of the information required.
This approach leads to *user guided wrapping*: as much information is
extracted directly from the source code to be wrapped as is possible
within the framework of pure C++, and some additional information is
supplied explicitly by the user. Mostly the guidance is mechanical
and little real intervention is required. Because the interface
specification is written in the same full-featured language as the
code being exposed, the user has unprecedented power available when
she does need to take control.
.. _Python: http://www.python.org/
.. _SWIG: http://www.swig.org/
.. _SIP: http://www.riverbankcomputing.co.uk/sip/index.php
.. _Qt: http://www.trolltech.com/
.. _CXX: http://cxx.sourceforge.net/
.. _Boost.Python: http://www.boost.org/libs/python/doc
===========================
Boost.Python Design Goals
===========================
The primary goal of Boost.Python is to allow users to expose C++
classes and functions to Python using nothing more than a C++
compiler. In broad strokes, the user experience should be one of
directly manipulating C++ objects from Python.
However, it's also important not to translate all interfaces *too*
literally: the idioms of each language must be respected. For
example, though C++ and Python both have an iterator concept, they are
expressed very differently. Boost.Python has to be able to bridge the
interface gap.
It must be possible to insulate Python users from crashes resulting
from trivial misuses of C++ interfaces, such as accessing
already-deleted objects. By the same token the library should
insulate C++ users from low-level Python 'C' API, replacing
error-prone 'C' interfaces like manual reference-count management and
raw ``PyObject`` pointers with more-robust alternatives.
Support for component-based development is crucial, so that C++ types
exposed in one extension module can be passed to functions exposed in
another without loss of crucial information like C++ inheritance
relationships.
Finally, all wrapping must be *non-intrusive*, without modifying or
even seeing the original C++ source code. Existing C++ libraries have
to be wrappable by third parties who only have access to header files
and binaries.
==========================
Hello Boost.Python World
==========================
And now for a preview of Boost.Python, and how it improves on the raw
facilities offered by Python. Here's a function we might want to
expose::
char const* greet(unsigned x)
{
static char const* const msgs[] = { "hello", "Boost.Python", "world!" };
if (x > 2)
throw std::range_error("greet: index out of range");
return msgs[x];
}
To wrap this function in standard C++ using the Python 'C' API, we'd
need something like this::
extern "C" // all Python interactions use 'C' linkage and calling convention
{
// Wrapper to handle argument/result conversion and checking
PyObject* greet_wrap(PyObject* args, PyObject * keywords)
{
int x;
if (PyArg_ParseTuple(args, "i", &x)) // extract/check arguments
{
char const* result = greet(x); // invoke wrapped function
return PyString_FromString(result); // convert result to Python
}
return 0; // error occurred
}
// Table of wrapped functions to be exposed by the module
static PyMethodDef methods[] = {
{ "greet", greet_wrap, METH_VARARGS, "return one of 3 parts of a greeting" }
, { NULL, NULL, 0, NULL } // sentinel
};
// module initialization function
DL_EXPORT init_hello()
{
(void) Py_InitModule("hello", methods); // add the methods to the module
}
}
Now here's the wrapping code we'd use to expose it with Boost.Python::
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(hello)
{
def("greet", greet, "return one of 3 parts of a greeting");
}
and here it is in action::
>>> import hello
>>> for x in range(3):
... print hello.greet(x)
...
hello
Boost.Python
world!
Aside from the fact that the 'C' API version is much more verbose,
it's worth noting a few things that it doesn't handle correctly:
* The original function accepts an unsigned integer, and the Python
'C' API only gives us a way of extracting signed integers. The
Boost.Python version will raise a Python exception if we try to pass
a negative number to ``hello.greet``, but the other one will proceed
to do whatever the C++ implementation does when converting an
negative integer to unsigned (usually wrapping to some very large
number), and pass the incorrect translation on to the wrapped
function.
* That brings us to the second problem: if the C++ ``greet()``
function is called with a number greater than 2, it will throw an
exception. Typically, if a C++ exception propagates across the
boundary with code generated by a 'C' compiler, it will cause a
crash. As you can see in the first version, there's no C++
scaffolding there to prevent this from happening. Functions wrapped
by Boost.Python automatically include an exception-handling layer
which protects Python users by translating unhandled C++ exceptions
into a corresponding Python exception.
* A slightly more-subtle limitation is that the argument conversion
used in the Python 'C' API case can only get that integer ``x`` in
*one way*. PyArg_ParseTuple can't convert Python ``long`` objects
(arbitrary-precision integers) which happen to fit in an ``unsigned
int`` but not in a ``signed long``, nor will it ever handle a
wrapped C++ class with a user-defined implicit ``operator unsigned
int()`` conversion. Boost.Python's dynamic type conversion
registry allows users to add arbitrary conversion methods.
==================
Library Overview
==================
This section outlines some of the library's major features. Except as
neccessary to avoid confusion, details of library implementation are
omitted.
------------------
Exposing Classes
------------------
C++ classes and structs are exposed with a similarly-terse interface.
Given::
struct World
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
The following code will expose it in our extension module::
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World")
.def("greet", &World::greet)
.def("set", &World::set)
;
}
Although this code has a certain pythonic familiarity, people
sometimes find the syntax bit confusing because it doesn't look like
most of the C++ code they're used to. All the same, this is just
standard C++. Because of their flexible syntax and operator
overloading, C++ and Python are great for defining domain-specific
(sub)languages
(DSLs), and that's what we've done in Boost.Python. To break it down::
class_<World>("World")
constructs an unnamed object of type ``class_<World>`` and passes
``"World"`` to its constructor. This creates a new-style Python class
called ``World`` in the extension module, and associates it with the
C++ type ``World`` in the Boost.Python type conversion registry. We
might have also written::
class_<World> w("World");
but that would've been more verbose, since we'd have to name ``w``
again to invoke its ``def()`` member function::
w.def("greet", &World::greet)
There's nothing special about the location of the dot for member
access in the original example: C++ allows any amount of whitespace on
either side of a token, and placing the dot at the beginning of each
line allows us to chain as many successive calls to member functions
as we like with a uniform syntax. The other key fact that allows
chaining is that ``class_<>`` member functions all return a reference
to ``*this``.
So the example is equivalent to::
class_<World> w("World");
w.def("greet", &World::greet);
w.def("set", &World::set);
It's occasionally useful to be able to break down the components of a
Boost.Python class wrapper in this way, but the rest of this article
will stick to the terse syntax.
For completeness, here's the wrapped class in use: ::
>>> import hello
>>> planet = hello.World()
>>> planet.set('howdy')
>>> planet.greet()
'howdy'
Constructors
============
Since our ``World`` class is just a plain ``struct``, it has an
implicit no-argument (nullary) constructor. Boost.Python exposes the
nullary constructor by default, which is why we were able to write: ::
>>> planet = hello.World()
However, well-designed classes in any language may require constructor
arguments in order to establish their invariants. Unlike Python,
where ``__init__`` is just a specially-named method, In C++
constructors cannot be handled like ordinary member functions. In
particular, we can't take their address: ``&World::World`` is an
error. The library provides a different interface for specifying
constructors. Given::
struct World
{
World(std::string msg); // added constructor
...
we can modify our wrapping code as follows::
class_<World>("World", init<std::string>())
...
of course, a C++ class may have additional constructors, and we can
expose those as well by passing more instances of ``init<...>`` to
``def()``::
class_<World>("World", init<std::string>())
.def(init<double, double>())
...
Boost.Python allows wrapped functions, member functions, and
constructors to be overloaded to mirror C++ overloading.
Data Members and Properties
===========================
Any publicly-accessible data members in a C++ class can be easily
exposed as either ``readonly`` or ``readwrite`` attributes::
class_<World>("World", init<std::string>())
.def_readonly("msg", &World::msg)
...
and can be used directly in Python: ::
>>> planet = hello.World('howdy')
>>> planet.msg
'howdy'
This does *not* result in adding attributes to the ``World`` instance
``__dict__``, which can result in substantial memory savings when
wrapping large data structures. In fact, no instance ``__dict__``
will be created at all unless attributes are explicitly added from
Python. Boost.Python owes this capability to the new Python 2.2 type
system, in particular the descriptor interface and ``property`` type.
In C++, publicly-accessible data members are considered a sign of poor
design because they break encapsulation, and style guides usually
dictate the use of "getter" and "setter" functions instead. In
Python, however, ``__getattr__``, ``__setattr__``, and since 2.2,
``property`` mean that attribute access is just one more
well-encapsulated syntactic tool at the programmer's disposal.
Boost.Python bridges this idiomatic gap by making Python ``property``
creation directly available to users. If ``msg`` were private, we
could still expose it as attribute in Python as follows::
class_<World>("World", init<std::string>())
.add_property("msg", &World::greet, &World::set)
...
The example above mirrors the familiar usage of properties in Python
2.2+: ::
>>> class World(object):
... __init__(self, msg):
... self.__msg = msg
... def greet(self):
... return self.__msg
... def set(self, msg):
... self.__msg = msg
... msg = property(greet, set)
Operator Overloading
====================
The ability to write arithmetic operators for user-defined types has
been a major factor in the success of both languages for numerical
computation, and the success of packages like NumPy_ attests to the
power of exposing operators in extension modules. Boost.Python
provides a concise mechanism for wrapping operator overloads. The
example below shows a fragment from a wrapper for the Boost rational
number library::
class_<rational<int> >("rational_int")
.def(init<int, int>()) // constructor, e.g. rational_int(3,4)
.def("numerator", &rational<int>::numerator)
.def("denominator", &rational<int>::denominator)
.def(-self) // __neg__ (unary minus)
.def(self + self) // __add__ (homogeneous)
.def(self * self) // __mul__
.def(self + int()) // __add__ (heterogenous)
.def(int() + self) // __radd__
...
The magic is performed using a simplified application of "expression
templates" [VELD1995]_, a technique originally developed for
optimization of high-performance matrix algebra expressions. The
essence is that instead of performing the computation immediately,
operators are overloaded to construct a type *representing* the
computation. In matrix algebra, dramatic optimizations are often
available when the structure of an entire expression can be taken into
account, rather than evaluating each operation "greedily".
Boost.Python uses the same technique to build an appropriate Python
method object based on expressions involving ``self``.
.. _NumPy: http://www.pfdubois.com/numpy/
Inheritance
===========
C++ inheritance relationships can be represented to Boost.Python by adding
an optional ``bases<...>`` argument to the ``class_<...>`` template
parameter list as follows::
class_<Derived, bases<Base1,Base2> >("Derived")
...
This has two effects:
1. When the ``class_<...>`` is created, Python type objects
corresponding to ``Base1`` and ``Base2`` are looked up in
Boost.Python's registry, and are used as bases for the new Python
``Derived`` type object, so methods exposed for the Python ``Base1``
and ``Base2`` types are automatically members of the ``Derived``
type. Because the registry is global, this works correctly even if
``Derived`` is exposed in a different module from either of its
bases.
2. C++ conversions from ``Derived`` to its bases are added to the
Boost.Python registry. Thus wrapped C++ methods expecting (a
pointer or reference to) an object of either base type can be
called with an object wrapping a ``Derived`` instance. Wrapped
member functions of class ``T`` are treated as though they have an
implicit first argument of ``T&``, so these conversions are
neccessary to allow the base class methods to be called for derived
objects.
Of course it's possible to derive new Python classes from wrapped C++
class instances. Because Boost.Python uses the new-style class
system, that works very much as for the Python built-in types. There
is one significant detail in which it differs: the built-in types
generally establish their invariants in their ``__new__`` function, so
that derived classes do not need to call ``__init__`` on the base
class before invoking its methods : ::
>>> class L(list):
... def __init__(self):
... pass
...
>>> L().reverse()
>>>
Because C++ object construction is a one-step operation, C++ instance
data cannot be constructed until the arguments are available, in the
``__init__`` function: ::
>>> class D(SomeBoostPythonClass):
... def __init__(self):
... pass
...
>>> D().some_boost_python_method()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: bad argument type for built-in operation
This happened because Boost.Python couldn't find instance data of type
``SomeBoostPythonClass`` within the ``D`` instance; ``D``'s ``__init__``
function masked construction of the base class. It could be corrected
by either removing ``D``'s ``__init__`` function or having it call
``SomeBoostPythonClass.__init__(...)`` explicitly.
Virtual Functions
=================
Deriving new types in Python from extension classes is not very
interesting unless they can be used polymorphically from C++. In
other words, Python method implementations should appear to override
the implementation of C++ virtual functions when called *through base
class pointers/references from C++*. Since the only way to alter the
behavior of a virtual function is to override it in a derived class,
the user must build a special derived class to dispatch a polymorphic
class' virtual functions::
//
// interface to wrap:
//
class Base
{
public:
virtual int f(std::string x) { return 42; }
virtual ~Base();
};
int calls_f(Base const& b, std::string x) { return b.f(x); }
//
// Wrapping Code
//
// Dispatcher class
struct BaseWrap : Base
{
// Store a pointer to the Python object
BaseWrap(PyObject* self_) : self(self_) {}
PyObject* self;
// Default implementation, for when f is not overridden
int f_default(std::string x) { return this->Base::f(x); }
// Dispatch implementation
int f(std::string x) { return call_method<int>(self, "f", x); }
};
...
def("calls_f", calls_f);
class_<Base, BaseWrap>("Base")
.def("f", &Base::f, &BaseWrap::f_default)
;
Now here's some Python code which demonstrates: ::
>>> class Derived(Base):
... def f(self, s):
... return len(s)
...
>>> calls_f(Base(), 'foo')
42
>>> calls_f(Derived(), 'forty-two')
9
Things to notice about the dispatcher class:
* The key element which allows overriding in Python is the
``call_method`` invocation, which uses the same global type
conversion registry as the C++ function wrapping does to convert its
arguments from C++ to Python and its return type from Python to C++.
* Any constructor signatures you wish to wrap must be replicated with
an initial ``PyObject*`` argument
* The dispatcher must store this argument so that it can be used to
invoke ``call_method``
* The ``f_default`` member function is needed when the function being
exposed is not pure virtual; there's no other way ``Base::f`` can be
called on an object of type ``BaseWrap``, since it overrides ``f``.
Deeper Reflection on the Horizon?
=================================
Admittedly, this formula is tedious to repeat, especially on a project
with many polymorphic classes. That it is neccessary reflects some
limitations in C++'s compile-time introspection capabilities: there's
no way to enumerate the members of a class and find out which are
virtual functions. At least one very promising project has been
started to write a front-end which can generate these dispatchers (and
other wrapping code) automatically from C++ headers.
Pyste_ is being developed by Bruno da Silva de Oliveira. It builds on
GCC_XML_, which generates an XML version of GCC's internal program
representation. Since GCC is a highly-conformant C++ compiler, this
ensures correct handling of the most-sophisticated template code and
full access to the underlying type system. In keeping with the
Boost.Python philosophy, a Pyste interface description is neither
intrusive on the code being wrapped, nor expressed in some unfamiliar
language: instead it is a 100% pure Python script. If Pyste is
successful it will mark a move away from wrapping everything directly
in C++ for many of our users. It will also allow us the choice to
shift some of the metaprogram code from C++ to Python. We expect that
soon, not only our users but the Boost.Python developers themselves
will be "thinking hybrid" about their own code.
.. _`GCC_XML`: http://www.gccxml.org/HTML/Index.html
.. _`Pyste`: http://www.boost.org/libs/python/pyste
---------------
Serialization
---------------
*Serialization* is the process of converting objects in memory to a
form that can be stored on disk or sent over a network connection. The
serialized object (most often a plain string) can be retrieved and
converted back to the original object. A good serialization system will
automatically convert entire object hierarchies. Python's standard
``pickle`` module is just such a system. It leverages the language's strong
runtime introspection facilities for serializing practically arbitrary
user-defined objects. With a few simple and unintrusive provisions this
powerful machinery can be extended to also work for wrapped C++ objects.
Here is an example::
#include <string>
struct World
{
World(std::string a_msg) : msg(a_msg) {}
std::string greet() const { return msg; }
std::string msg;
};
#include <boost/python.hpp>
using namespace boost::python;
struct World_picklers : pickle_suite
{
static tuple
getinitargs(World const& w) { return make_tuple(w.greet()); }
};
BOOST_PYTHON_MODULE(hello)
{
class_<World>("World", init<std::string>())
.def("greet", &World::greet)
.def_pickle(World_picklers())
;
}
Now let's create a ``World`` object and put it to rest on disk::
>>> import hello
>>> import pickle
>>> a_world = hello.World("howdy")
>>> pickle.dump(a_world, open("my_world", "w"))
In a potentially *different script* on a potentially *different
computer* with a potentially *different operating system*::
>>> import pickle
>>> resurrected_world = pickle.load(open("my_world", "r"))
>>> resurrected_world.greet()
'howdy'
Of course the ``cPickle`` module can also be used for faster
processing.
Boost.Python's ``pickle_suite`` fully supports the ``pickle`` protocol
defined in the standard Python documentation. Like a __getinitargs__
function in Python, the pickle_suite's getinitargs() is responsible for
creating the argument tuple that will be use to reconstruct the pickled
object. The other elements of the Python pickling protocol,
__getstate__ and __setstate__ can be optionally provided via C++
getstate and setstate functions. C++'s static type system allows the
library to ensure at compile-time that nonsensical combinations of
functions (e.g. getstate without setstate) are not used.
Enabling serialization of more complex C++ objects requires a little
more work than is shown in the example above. Fortunately the
``object`` interface (see next section) greatly helps in keeping the
code manageable.
------------------
Object interface
------------------
Experienced 'C' language extension module authors will be familiar
with the ubiquitous ``PyObject*``, manual reference-counting, and the
need to remember which API calls return "new" (owned) references or
"borrowed" (raw) references. These constraints are not just
cumbersome but also a major source of errors, especially in the
presence of exceptions.
Boost.Python provides a class ``object`` which automates reference
counting and provides conversion to Python from C++ objects of
arbitrary type. This significantly reduces the learning effort for
prospective extension module writers.
Creating an ``object`` from any other type is extremely simple::
object s("hello, world"); // s manages a Python string
``object`` has templated interactions with all other types, with
automatic to-python conversions. It happens so naturally that it's
easily overlooked::
object ten_Os = 10 * s[4]; // -> "oooooooooo"
In the example above, ``4`` and ``10`` are converted to Python objects
before the indexing and multiplication operations are invoked.
The ``extract<T>`` class template can be used to convert Python objects
to C++ types::
double x = extract<double>(o);
If a conversion in either direction cannot be performed, an
appropriate exception is thrown at runtime.
The ``object`` type is accompanied by a set of derived types
that mirror the Python built-in types such as ``list``, ``dict``,
``tuple``, etc. as much as possible. This enables convenient
manipulation of these high-level types from C++::
dict d;
d["some"] = "thing";
d["lucky_number"] = 13;
list l = d.keys();
This almost looks and works like regular Python code, but it is pure
C++. Of course we can wrap C++ functions which accept or return
``object`` instances.
=================
Thinking hybrid
=================
Because of the practical and mental difficulties of combining
programming languages, it is common to settle a single language at the
outset of any development effort. For many applications, performance
considerations dictate the use of a compiled language for the core
algorithms. Unfortunately, due to the complexity of the static type
system, the price we pay for runtime performance is often a
significant increase in development time. Experience shows that
writing maintainable C++ code usually takes longer and requires *far*
more hard-earned working experience than developing comparable Python
code. Even when developers are comfortable working exclusively in
compiled languages, they often augment their systems by some type of
ad hoc scripting layer for the benefit of their users without ever
availing themselves of the same advantages.
Boost.Python enables us to *think hybrid*. Python can be used for
rapidly prototyping a new application; its ease of use and the large
pool of standard libraries give us a head start on the way to a
working system. If necessary, the working code can be used to
discover rate-limiting hotspots. To maximize performance these can
be reimplemented in C++, together with the Boost.Python bindings
needed to tie them back into the existing higher-level procedure.
Of course, this *top-down* approach is less attractive if it is clear
from the start that many algorithms will eventually have to be
implemented in C++. Fortunately Boost.Python also enables us to
pursue a *bottom-up* approach. We have used this approach very
successfully in the development of a toolbox for scientific
applications. The toolbox started out mainly as a library of C++
classes with Boost.Python bindings, and for a while the growth was
mainly concentrated on the C++ parts. However, as the toolbox is
becoming more complete, more and more newly added functionality can be
implemented in Python.
.. image:: images/python_cpp_mix.png
This figure shows the estimated ratio of newly added C++ and Python
code over time as new algorithms are implemented. We expect this
ratio to level out near 70% Python. Being able to solve new problems
mostly in Python rather than a more difficult statically typed
language is the return on our investment in Boost.Python. The ability
to access all of our code from Python allows a broader group of
developers to use it in the rapid development of new applications.
=====================
Development history
=====================
The first version of Boost.Python was developed in 2000 by Dave
Abrahams at Dragon Systems, where he was privileged to have Tim Peters
as a guide to "The Zen of Python". One of Dave's jobs was to develop
a Python-based natural language processing system. Since it was
eventually going to be targeting embedded hardware, it was always
assumed that the compute-intensive core would be rewritten in C++ to
optimize speed and memory footprint [#proto]_. The project also wanted to
test all of its C++ code using Python test scripts [#test]_. The only
tool we knew of for binding C++ and Python was SWIG_, and at the time
its handling of C++ was weak. It would be false to claim any deep
insight into the possible advantages of Boost.Python's approach at
this point. Dave's interest and expertise in fancy C++ template
tricks had just reached the point where he could do some real damage,
and Boost.Python emerged as it did because it filled a need and
because it seemed like a cool thing to try.
This early version was aimed at many of the same basic goals we've
described in this paper, differing most-noticeably by having a
slightly more cumbersome syntax and by lack of special support for
operator overloading, pickling, and component-based development.
These last three features were quickly added by Ullrich Koethe and
Ralf Grosse-Kunstleve [#feature]_, and other enthusiastic contributors arrived
on the scene to contribute enhancements like support for nested
modules and static member functions.
By early 2001 development had stabilized and few new features were
being added, however a disturbing new fact came to light: Ralf had
begun testing Boost.Python on pre-release versions of a compiler using
the EDG_ front-end, and the mechanism at the core of Boost.Python
responsible for handling conversions between Python and C++ types was
failing to compile. As it turned out, we had been exploiting a very
common bug in the implementation of all the C++ compilers we had
tested. We knew that as C++ compilers rapidly became more
standards-compliant, the library would begin failing on more
platforms. Unfortunately, because the mechanism was so central to the
functioning of the library, fixing the problem looked very difficult.
Fortunately, later that year Lawrence Berkeley and later Lawrence
Livermore National labs contracted with `Boost Consulting`_ for support
and development of Boost.Python, and there was a new opportunity to
address fundamental issues and ensure a future for the library. A
redesign effort began with the low level type conversion architecture,
building in standards-compliance and support for component-based
development (in contrast to version 1 where conversions had to be
explicitly imported and exported across module boundaries). A new
analysis of the relationship between the Python and C++ objects was
done, resulting in more intuitive handling for C++ lvalues and
rvalues.
The emergence of a powerful new type system in Python 2.2 made the
choice of whether to maintain compatibility with Python 1.5.2 easy:
the opportunity to throw away a great deal of elaborate code for
emulating classic Python classes alone was too good to pass up. In
addition, Python iterators and descriptors provided crucial and
elegant tools for representing similar C++ constructs. The
development of the generalized ``object`` interface allowed us to
further shield C++ programmers from the dangers and syntactic burdens
of the Python 'C' API. A great number of other features including C++
exception translation, improved support for overloaded functions, and
most significantly, CallPolicies for handling pointers and
references, were added during this period.
In October 2002, version 2 of Boost.Python was released. Development
since then has concentrated on improved support for C++ runtime
polymorphism and smart pointers. Peter Dimov's ingenious
``boost::shared_ptr`` design in particular has allowed us to give the
hybrid developer a consistent interface for moving objects back and
forth across the language barrier without loss of information. At
first, we were concerned that the sophistication and complexity of the
Boost.Python v2 implementation might discourage contributors, but the
emergence of Pyste_ and several other significant feature
contributions have laid those fears to rest. Daily questions on the
Python C++-sig and a backlog of desired improvements show that the
library is getting used. To us, the future looks bright.
.. _`EDG`: http://www.edg.com
=============
Conclusions
=============
Boost.Python achieves seamless interoperability between two rich and
complimentary language environments. Because it leverages template
metaprogramming to introspect about types and functions, the user
never has to learn a third syntax: the interface definitions are
written in concise and maintainable C++. Also, the wrapping system
doesn't have to parse C++ headers or represent the type system: the
compiler does that work for us.
Computationally intensive tasks play to the strengths of C++ and are
often impossible to implement efficiently in pure Python, while jobs
like serialization that are trivial in Python can be very difficult in
pure C++. Given the luxury of building a hybrid software system from
the ground up, we can approach design with new confidence and power.
===========
Citations
===========
.. [VELD1995] T. Veldhuizen, "Expression Templates," C++ Report,
Vol. 7 No. 5 June 1995, pp. 26-31.
http://osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
===========
Footnotes
===========
.. [#proto] In retrospect, it seems that "thinking hybrid" from the
ground up might have been better for the NLP system: the
natural component boundaries defined by the pure python
prototype turned out to be inappropriate for getting the
desired performance and memory footprint out of the C++ core,
which eventually caused some redesign overhead on the Python
side when the core was moved to C++.
.. [#test] We also have some reservations about driving all C++
testing through a Python interface, unless that's the only way
it will be ultimately used. Any transition across language
boundaries with such different object models can inevitably
mask bugs.
.. [#feature] These features were expressed very differently in v1 of
Boost.Python

View File

@@ -1,716 +0,0 @@
/*=============================================================================
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 */

View File

@@ -1,566 +0,0 @@
[chapter Building and Testing
[quickbook 1.7]
[authors [Abrahams, David]]
[copyright 2002 - 2015 David Abrahams, Stefan Seefeld]
[id building]
]
[/ 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)
/]
[section Requirements]
Boost.Python requires [@http://www.python.org/2.2 Python 2.2]
[footnote Note that although we tested earlier versions of Boost.Python
with Python 2.2, and we don't *think* we've done anything to break
compatibility, this release of Boost.Python may not have been tested
with versions of Python earlier than 2.4, so we're not 100% sure that
python 2.2 and 2.3 are supported.] *or* [@http://www.python.org newer].
[endsect]
[section Background]
There are two basic models for combining C++ and Python:
* [@http://www.python.org/doc/current/ext/intro.html extending],
in which the end-user launches the Python interpreter
executable and imports Python “extension modules” written in C++.
Think of taking a library written in C++ and giving it a Python
interface so Python programmers can use it. From Python, these
modules look just like regular Python modules.
* [@http://www.python.org/doc/current/ext/embedding.html embedding],
in which the end-user launches a program written
in C++ that in turn invokes the Python interpreter as a library
subroutine. Think of adding scriptability to an existing
application.
The key distinction between extending and embedding is the location
of the C++ `main()` function: in the Python interpreter executable,
or in some other program, respectively. Note that even when
embedding Python in another program, [@http://www.python.org/doc/current/ext/extending-with-embedding.html extension modules are often
the best way to make C/C++ functionality accessible to Python
code], so the use of extension modules is really at the heart of
both models.
Except in rare cases, extension modules are built as
dynamically-loaded libraries with a single entry point, which means
you can change them without rebuilding either the other extension
modules or the executable containing `main()`.
[endsect]
[section No-Install Quickstart]
There is no need to “install Boost” in order to get started using
Boost.Python. These instructions use _bb_ projects,
which will build those binaries as soon as they're needed. Your
first tests may take a little longer while you wait for
Boost.Python to build, but doing things this way will save you from
worrying about build intricacies like which library binaries to use
for a specific compiler configuration and figuring out the right
compiler options to use yourself.
[note Of course it's possible to use other build systems to
build Boost.Python and its extensions, but they are not
officially supported by Boost. Moreover *99% of all “I can't
build Boost.Python” problems come from trying to use another
build system* without first following these instructions.
If you want to use another system anyway, we suggest that you
follow these instructions, and then invoke `bjam` with the
`-a -o`\ /filename/
options to dump the build commands it executes to a file, so
you can see what your alternate build system needs to do.]
[section Basic Procedure]
1. Get Boost; see sections 1 and 2 of the _gsg_.
2. Get the `bjam` build driver. See section 5 of the _gsg_.
3. cd into the `example/quickstart/` directory of your
Boost.Python installation, which contains a small example project.
4. Invoke `bjam`. Replace the “\ `stage`\ “ argument from the
example invocation from section 5 of the _gsg_ with “\ `test`\ ,“ to
build all the test targets. Also add the argument “\ `--verbose-test`\ ”
to see the output generated by the tests when they are run.
On Windows, your `bjam` invocation might look something like:
``
C:\\...\\quickstart> bjam toolset=msvc --verbose-test test
``
and on Unix variants, perhaps,
``
.../quickstart$ bjam toolset=gcc --verbose-test test
``
[note For the sake of concision, the rest of this guide will use
unix-style forward slashes in pathnames instead of the
backslashes with which Windows users may be more familiar. The forward
slashes should work everywhere except in
[@http://www.boost.org/more/getting_started/windows.html#command-prompt
Command Prompt] windows, where you should use backslashes.]
If you followed this procedure successfully, you will have built an
extension module called `extending` and tested it by running a
Python script called `test_extending.py`. You will also have
built and run a simple application called `embedding` that embeds
python.
[endsect]
[section In Case of Trouble]
If you're seeing lots of compiler and/or linker error messages,
it's probably because Boost.Build is having trouble finding your
Python installation. You might want to pass the
`--debug-configuration` option to `bjam` the first few times
you invoke it, to make sure that Boost.Build is correctly locating
all the parts of your Python installation. If it isn't, consider
[link building.configuring_boost_build Configuring Boost.Build]
as detailed below.
If you're still having trouble, Someone on one of the following
mailing lists may be able to help:
* The _bb_list_ for issues related to Boost.Build
* The _bp_list_ for issues specifically related to Boost.Python
[endsect]
[section In Case Everything Seemed to Work]
Rejoice! If you're new to Boost.Python, at this point it might be
a good idea to ignore build issues for a while and concentrate on
learning the library by going through the _tutorial_ and perhaps
some of the _reference_, trying out what you've
learned about the API by modifying the quickstart project.
[endsect]
[section Modifying the Example Project]
If you're content to keep your extension module forever in one
source file called `extending.cpp`, inside your Boost.Python
distribution, and import it forever as `extending`, then you can
stop here. However, it's likely that you will want to make a few
changes. There are a few things you can do without having to learn
_bb_ in depth.
The project you just built is specified in two files in the current
directory: `boost-build.jam`, which tells `bjam` where it can
find the interpreted code of the Boost build system, and
`Jamroot`, which describes the targets you just built. These
files are heavily commented, so they should be easy to modify.
Take care, however, to preserve whitespace. Punctuation such as
`;` will not be recognized as intended by `bjam` if it is not
surrounded by whitespace.
[section Relocate the Project]
You'll probably want to copy this project elsewhere so you can
change it without modifying your Boost distribution. To do that,
simply
a. copy the entire `example/quickstart/` directory
into a new directory.
b. In the new copies of `boost-build.jam` and `Jamroot`, locate
the relative path near the top of the file that is clearly
marked by a comment, and edit that path so that it refers to the
same directory your Boost distribution as it referred to when
the file was in its original location in the
`example/quickstart/` directory.
For example, if you moved the project from
`/home/dave/boost_1_34_0/libs/python/example/quickstart` to
`/home/dave/my-project`, you could change the first path in
`boost-build.jam` from
``
../../../../tools/build/src
``
to
``
/home/dave/boost_1_34_0/tools/build/src
``
and change the first path in `Jamroot` from
``
../../../..
``
to
``
/home/dave/boost_1_34_0
``
[endsect]
[section Add New or Change Names of Existing Source Files]
The names of additional source files involved in building your
extension module or embedding application can be listed in
`Jamroot` right alongside `extending.cpp` or `embedding.cpp`
respectively. Just be sure to leave whitespace around each
filename:
``
… file1.cpp file2.cpp file3.cpp …
``
Naturally, if you want to change the name of a source file you can
tell Boost.Build about it by editing the name in `Jamroot`.
[endsect]
[section Change the Name of your Extension Module]
The name of the extension module is determined by two things:
# the name in `Jamroot` immediately following `python-extension`, and
# the name passed to `BOOST_PYTHON_MODULE` in `extending.cpp`.
To change the name of the extension module from `extending` to
`hello`, you'd edit `Jamroot`, changing
``
python-extension extending : extending.cpp ;
``
to
``
python-extension hello : extending.cpp ;
``
and you'd edit extending.cpp, changing
``
BOOST_PYTHON_MODULE(extending)
``
to
``
BOOST_PYTHON_MODULE(hello)
``
[endsect]
[endsect]
[endsect]
[section Installing Boost.Python on your System]
Since Boost.Python is a separately-compiled (as opposed to
`header-only`) library, its user relies on the services of a
Boost.Python library binary.
If you need a regular installation of the Boost.Python library
binaries on your system, the _gsg_ will
walk you through the steps of creating one. If building binaries
from source, you might want to supply the `--with-python`
argument to `bjam` (or the `--with-libraries=python` argument
to `configure`), so only the Boost.Python binary will be built,
rather than all the Boost binaries.
[endsect]
[section Configuring Boost.Build]
As described in the [@http://www.boost.org/build/doc/html/bbv2/overview/configuration.html Boost.Build Reference Manual], a file called
`user-config.jam` in your home directory is used to
specify the tools and libraries available to the build system. You
may need to create or edit `user-config.jam` to tell Boost.Build
how to invoke Python, `#include` its headers, and link with its
libraries.
[note If you are using a unix-variant OS and you ran Boost's
`configure` script, it may have generated a
`user-config.jam` for you. [footnote `configure` overwrites the existing
`user-config.jam` in your home directory (if any) after making a backup of
the old version.] If your `configure`\ /\ `make` sequence was successful and
Boost.Python binaries were built, your `user-config.jam` file is probably already
correct.]
If you have one fairly “standard” python installation for your
platform, you might not need to do anything special to describe it. If
you haven't configured python in `user-config.jam` (and you don't
specify `--without-python` on the Boost.Build command line),
Boost.Build will automatically execute the equivalent of
``
import toolset : using ;
using python ;
``
which automatically looks for Python in the most likely places.
However, that only happens when using the Boost.Python project file
(e.g. when referred to by another project as in the quickstart
method). If instead you are linking against separately-compiled
Boost.Python binaries, you should set up a `user-config.jam` file
with at least the minimal incantation above.
[section Python Configuration Parameters]
If you have several versions of Python installed, or Python is
installed in an unusual way, you may want to supply any or all of
the following optional parameters to `using python`.
[variablelist
[[version]
[the version of Python to use. Should be in Major.Minor
format, for example, `2.3`. Do not include the subminor
version (i.e. *not* `2.5.1`). If you have multiple Python
versions installed, the version will usually be the only
configuration argument required.]]
[[cmd-or-prefix]
[preferably, a command that invokes a Python interpreter.
Alternatively, the installation prefix for Python libraries and
header files. Only use the alternative formulation if there is
no appropriate Python executable available.]]
[[*includes*]
[the `#include` paths for Python headers. Normally the correct
path(s) will be automatically deduced from `version` and/or
`cmd-or-prefix`.]]
[[*libraries*]
[the path to Python library binaries. On MacOS/Darwin,
you can also pass the path of the Python framework. Normally the
correct path(s) will be automatically deduced from `version`
and/or `cmd-or-prefix`.]]
[[*condition*]
[if specified, should be a set of Boost.Build
properties that are matched against the build configuration when
Boost.Build selects a Python configuration to use. See examples
below for details.]]
[[*extension-suffix*]
[A string to append to the name of extension
modules before the true filename extension. You almost certainly
don't need to use this. Usually this suffix is only used when
targeting a Windows debug build of Python, and will be set
automatically for you based on the value of the
[link building.python_debugging_builds <python-debugging>] feature.
However, at least one Linux distribution (Ubuntu Feisty Fawn) has
a specially configured [@https://wiki.ubuntu.com/PyDbgBuilds <python-dbg>]
package that claims to use such a suffix.]]
]
[endsect]
[section Examples]
Note that in the examples below, case and *especially whitespace* are
significant.
* If you have both python 2.5 and python 2.4 installed,
`user-config.jam` might contain
``
using python : 2.5 ; # Make both versions of Python available
using python : 2.4 ; # To build with python 2.4, add python=2.4
# to your command line.
``
The first version configured (2.5) becomes the default. To build
against python 2.4, add `python=2.4` to the `bjam` command line.
* If you have python installed in an unusual location, you might
supply the path to the interpreter in the `cmd-or-prefix`
parameter:
``
using python : : /usr/local/python-2.6-beta/bin/python ;
``
* If you have a separate build of Python for use with a particular
toolset, you might supply that toolset in the `condition`
parameter:
``
using python ; # use for most toolsets
# Use with Intel C++ toolset
using python
: # version
: c:\\Devel\\Python-2.5-IntelBuild\\PCBuild\\python # cmd-or-prefix
: # includes
: # libraries
: <toolset>intel # condition
;
``
* If you have downloaded the Python sources and built both the
normal and the [link building.python_debugging_builds "python debugging"]
builds from source on Windows, you might see:
``
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python ;
using python : 2.5 : C:\\src\\Python-2.5\\PCBuild\\python_d
: # includes
: # libs
: <python-debugging>on ;
``
* You can set up your user-config.jam so a bjam built under Windows
can build/test both Windows and Cygwin_ python extensions. Just pass
`<target-os>cygwin` in the `condition` parameter
for the cygwin python installation:
``
# windows installation
using python ;
# cygwin installation
using python : : c:\\cygwin\\bin\\python2.5 : : : <target-os>cygwin ;
``
when you put target-os=cygwin in your build request, it should build
with the cygwin version of python: [#flavor]_
``
bjam target-os=cygwin toolset=gcc
``
This is supposed to work the other way, too (targeting windows
python with a [@http://cygwin.com Cygwin] bjam) but it seems as though the support in
Boost.Build's toolsets for building that way is broken at the
time of this writing.
* Note that because of [@http://zigzag.cs.msu.su/boost.build/wiki/AlternativeSelection
the way Boost.Build currently selects target alternatives], you might have be very
explicit in your build requests. For example, given:
``
using python : 2.5 ; # a regular windows build
using python : 2.4 : : : : <target-os>cygwin ;
``
building with
``
bjam target-os=cygwin
``
will yield an error. Instead, you'll need to write
``
bjam target-os=cygwin/python=2.4
``
[endsect]
[endsect]
[section Choosing a Boost.Python Library Binary]
If—instead of letting Boost.Build construct and link with the right
libraries automatically—you choose to use a pre-built Boost.Python
library, you'll need to think about which one to link with. The
Boost.Python binary comes in both static and dynamic flavors. Take
care to choose the right flavor for your application. [footnote
Information about how to identify the static and dynamic builds of Boost.Python on
[@http://boost.org/more/getting_started/windows.html#library-naming Windows] /
[@http://boost.org/more/getting_started/unix-variants.html#library-naming Unix variants]]
[section The Dynamic Binary]
The dynamic library is the safest and most-versatile choice:
* A single copy of the library code is used by all extension
modules built with a given toolset. [footnote Because of the way most \*nix platforms
share symbols among dynamically-loaded objects, I'm not certain
that extension modules built with different compiler toolsets
will always use different copies of the Boost.Python library
when loaded into the same Python instance. Not using different
libraries could be a good thing if the compilers have compatible
ABIs, because extension modules built with the two libraries
would be interoperable. Otherwise, it could spell disaster,
since an extension module and the Boost.Python library would
have different ideas of such things as class layout. I would
appreciate someone doing the experiment to find out what
happens.]
* The library contains a type conversion registry. Because one
registry is shared among all extension modules, instances of a
class exposed to Python in one dynamically-loaded extension
module can be passed to functions exposed in another such module.
[endsect]
[section The Static Binary]
It might be appropriate to use the static Boost.Python library in
any of the following cases:
* You are _extending_ python and the types exposed in your
dynamically-loaded extension module don't need to be used by any
other Boost.Python extension modules, and you don't care if the
core library code is duplicated among them.
* You are _embedding_ python in your application and either:
* You are targeting a Unix variant OS other than MacOS or AIX,
where the dynamically-loaded extension modules can “see” the
Boost.Python library symbols that are part of the executable.
* Or, you have statically linked some Boost.Python extension
modules into your application and you don't care if any
dynamically-loaded Boost.Python extension modules are able to
use the types exposed by your statically-linked extension
modules (and vice-versa).
[endsect]
[endsect]
[section `#include` Issues]
1. If you should ever have occasion to `#include "python.h"`
directly in a translation unit of a program using Boost.Python,
use `#include "boost/python/detail/wrap_python.hpp"` instead.
It handles several issues necessary for use with Boost.Python,
one of which is mentioned in the next section.
2. Be sure not to `#include` any system headers before
`wrap_python.hpp`. This restriction is actually imposed by
Python, or more properly, by Python's interaction with your
operating system. See
[@http://docs.python.org/ext/simpleExample.html] for details.
[endsect]
[section Python Debugging Builds]
Python can be built in a special “python debugging” configuration
that adds extra checks and instrumentation that can be very useful
for developers of extension modules. The data structures used by
the debugging configuration contain additional members, so *a
Python executable built with python debugging enabled cannot be
used with an extension module or library compiled without it, and
vice-versa.*
Since pre-built “python debugging” versions of the Python
executable and libraries are not supplied with most distributions
of Python, [footnote On Unix and similar platforms, a debugging python and associated libraries are built by adding --with-pydebug when configuring the Python build. On Windows, the debugging version of Python is generated by the "Win32 Debug" target of the Visual Studio project in the PCBuild subdirectory of a full Python source code distribution.] and we didn't want to force our users
to build them, Boost.Build does not automatically enable python
debugging in its `debug` build variant (which is the default).
Instead there is a special build property called
`python-debugging` that, when used as a build property, will
define the right preprocessor symbols and select the right
libraries to link with.
On unix-variant platforms, the debugging versions of Python's data
structures will only be used if the symbol `Py_DEBUG` is defined.
On many windows compilers, when extension modules are built with
the preprocessor symbol `_DEBUG`, Python defaults to force
linking with a special debugging version of the Python DLL. Since
that symbol is very commonly used even when Python is not present,
Boost.Python temporarily undefines `_DEBUG` when `Python.h`
is #included from `boost/python/detail/wrap_python.hpp` - unless
`BOOST_DEBUG_PYTHON` is defined. The upshot is that if you want
“python debugging”and you aren't using Boost.Build, you should make
sure `BOOST_DEBUG_PYTHON` is defined, or python debugging will be
suppressed.
[endsect]
[section Testing Boost.Python]
To run the full test suite for Boost.Python, invoke `bjam` in the
`test` subdirectory of your Boost.Python distribution.
[endsect]
[section Notes for MinGW (and Cygwin with -mno-cygwin) GCC Users]
If you are using a version of Python prior to 2.4.1 with a MinGW
prior to 3.0.0 (with binutils-2.13.90-20030111-1), you will need to
create a MinGW-compatible version of the Python library; the one
shipped with Python will only work with a Microsoft-compatible
linker. Follow the instructions in the “Non-Microsoft” section of
the “Building Extensions: Tips And Tricks” chapter in
[@https://docs.python.org/2/install/index.html Installing Python Modules]
to create `libpythonXX.a`, where `XX` corresponds to the major and minor
version numbers of your Python installation.
[endsect]

View File

@@ -1,83 +0,0 @@
[chapter Configuration
[quickbook 1.7]
[authors [Abrahams, David]]
[copyright 2002 - 2015 David Abrahams, Stefan Seefeld]
[id configuration]
]
[section Configuration]
[section Introduction]
[*Boost.Python] uses several configuration macros in `<boost/config.hpp>`, as well as configuration macros meant to be supplied by the application. These macros are documented here.
[endsect]
[section Application Defined Macros]
These are the macros that may be defined by an application using Boost.Python. Note that if you extend a strict interpretation of the C++ standard to cover dynamic libraries, using different values of these macros when compiling different libraries (including extension modules and the Boost.Python library itself) is a violation of the [link odr ODR]. However, we know of no C++ implementations on which this particular violation is detectable or causes any problems.
[table
[[Macro][Default][Meaning]]
[[BOOST_PYTHON_MAX_ARITY]
[15]
[The maximum arity of any function, member function,
or constructor to be wrapped, invocation of a
Boost.Python function wich is specified as taking
arguments x1, x2,...Xn. This includes, in particular,
callback mechanisms such as object::operator()(...) or call_method<R>(... ).]]
[[BOOST_PYTHON_MAX_BASES][10]
[The maximum number of template arguments to the
`bases<...>` class template, which is used to specify
the bases of a wrapped C++ class..]]
[[BOOST_PYTHON_STATIC_MODULE]
[ /not defined/ ]
[If defined, prevents your module initialization
function from being treated as an exported symbol
on platforms which support that distinction in-code]]
[[BOOST_PYTHON_ENABLE_CDECL]
[ /not defined/ ]
[If defined, allows functions using the `__cdecl`
calling convention to be wrapped.]]
[[BOOST_PYTHON_ENABLE_STDCALL]
[ /not defined/ ]
[If defined, allows functions using the `__stdcall`
calling convention to be wrapped.]]
[[BOOST_PYTHON_ENABLE_FASTCALL]
[ /not defined/ ]
[If defined, allows functions using the `__fastcall`
calling convention to be wrapped.]]
]
[endsect]
[section Library Defined Defined Macros]
These macros are defined by *Boost.Python* and are implementation details of interest only to implementors and those porting to new platforms.
[table
[[Macro][Default][Meaning]]
[[BOOST_PYTHON_TYPE_ID_NAME][ /not defined/ ]
[If defined, this indicates that the type_info comparison across
shared library boundaries does not work on this platform.
In other words, if shared-lib-1 passes `typeid(T)` to a function
in shared-lib-2 which compares it to `typeid(T)`, that comparison
may return `false`. If this macro is #defined, Boost.Python uses
and compares `typeid(T).name()` instead of using and comparing
the `std::type_info` objects directly.]]
[[BOOST_PYTHON_NO_PY_SIGNATURES][ /not defined/ ]
[If defined for a module no pythonic signatures are generated for
the docstrings of the module functions, and no python type is
associated with any of the converters registered by the module.
This also reduces the binary size of the module by about 14%
(gcc compiled).
If defined for the boost_python runtime library, the default for
the `docstring_options.enable_py_signatures()` is set to `false`.]]
[[BOOST_PYTHON_SUPPORTS_PY_SIGNATURES]
[ /defined/ if `BOOST_PYTHON_NO_PY_SIGNATURES` is /undefined/ ]
[This macro is defined to enable a smooth transition from older
Boost.Python versions which do not support pythonic signatures.
For example usage see here.]]
[[BOOST_PYTHON_PY_SIGNATURES_PROPER_INIT_SELF_TYPE][ /not defined/ ]
[If defined the python type of `__init__` method "self" parameters
is properly generated, otherwise object is used. It is undefined by
default because it increases the binary size of the module by about
14% (gcc compiled).]]
]
[endsect]
[endsect]

View File

@@ -1,736 +0,0 @@
[chapter Frequently Asked Questions (FAQs)
[quickbook 1.7]
[id faq]
]
[section How can I wrap a function which takes a function pointer as an argument?]
If what you're trying to do is something like this:
``
typedef boost::function<void (string s) > funcptr;
void foo(funcptr fp)
{
fp("hello,world!");
}
BOOST_PYTHON_MODULE(test)
{
def("foo",foo);
}
``
And then:
``
>>> def hello(s):
... print s
...
>>> foo(hello)
hello, world!
``
The short answer is: "you can't". This is not a
Boost.Python limitation so much as a limitation of C++. The
problem is that a Python function is actually data, and the only
way of associating data with a C++ function pointer is to store it
in a static variable of the function. The problem with that is
that you can only associate one piece of data with every C++
function, and we have no way of compiling a new C++ function
on-the-fly for every Python function you decide to pass
to `foo`. In other words, this could work if the C++
function is always going to invoke the /same/ Python
function, but you probably don't want that.
If you have the luxury of changing the C++ code you're
wrapping, pass it an `object` instead and call that;
the overloaded function call operator will invoke the Python
function you pass it behind the `object`.
[endsect]
[section I'm getting the "attempt to return dangling reference" error.
What am I doing wrong?]
That exception is protecting you from causing a nasty crash. It usually
happens in response to some code like this:
``
period const &get_floating_frequency() const
{
return boost::python::call_method<period const &>(
m_self,"get_floating_frequency");
}
``
And you get:
``
ReferenceError: Attempt to return dangling reference to object of type:
class period
``
In this case, the Python method invoked by `call_method`
constructs a new Python object. You're trying to return a reference to a
C++ object (an instance of `class period`) contained within
and owned by that Python object. Because the called method handed back a
brand new object, the only reference to it is held for the duration of
`get_floating_frequency()` above. When the function returns,
the Python object will be destroyed, destroying the instance of
`class period`, and leaving the returned reference dangling.
That's already undefined behavior, and if you try to do anything with
that reference you're likely to cause a crash. Boost.Python detects this
situation at runtime and helpfully throws an exception instead of letting
you do that.
[endsect]
[section Is `return_internal_reference` efficient?]
[*Q:] /I have an object composed of 12 doubles. A `const&` to
this object is returned by a member function of another class. From the
viewpoint of using the returned object in Python I do not care if I get
a copy or a reference to the returned object. In Boost.Python I have the
choice of using `copy_const_reference` or `return_internal_reference`.
Are there considerations that would lead me to prefer one over the other,
such as size of generated code or memory overhead?/
[*A:] `copy_const_reference` will make an instance with storage
for one of your objects, `size = base_size + 12 * sizeof(double)`.
`return_internal_reference` will make an instance with storage for a
pointer to one of your objects, `size = base_size + sizeof(void*)`.
However, it will also create a weak reference object which goes in the
source object's weakreflist and a special callback object to manage the
lifetime of the internally-referenced object. My guess?
`copy_const_reference` is your friend here, resulting in less overall
memory use and less fragmentation, also probably fewer total
cycles.
[endsect]
[section How can I wrap functions which take C++ containers as arguments?]
Ralf W. Grosse-Kunstleve provides these notes:
# Using the regular `class_<>` wrapper:
``
class_<std::vector<double> >("std_vector_double")
.def(...)
...
;
``
This can be moved to a template so that several types (`double`, `int`,
`long`, etc.) can be wrapped with the same code. This technique is used
in the file `scitbx/include/scitbx/array_family/boost_python/flex_wrapper.h`
in the "scitbx" package. The file could easily be modified for
wrapping `std::vector<>` instantiations.
This type of C++/Python binding is most suitable for containers
that may contain a large number of elements (>10000).
# Using custom rvalue converters. Boost.Python "rvalue converters"
match function signatures such as:
``
void foo(std::vector<double> const &array); // pass by const-reference
void foo(std::vector<double> array); // pass by value
``
Some custom rvalue converters are implemented in the file
`scitbx/include/scitbx/boost_python/container_conversions.h`
This code can be used to convert from C++ container types such as
`std::vector<>` or `std::list<>` to Python tuples and vice
versa. A few simple examples can be found in the file
`scitbx/array_family/boost_python/regression_test_module.cpp`
Automatic C++ container <-> Python tuple conversions are most
suitable for containers of moderate size. These converters generate
significantly less object code compared to alternative 1 above.
A disadvantage of using alternative 2 is that operators such as
arithmetic +,-,*,/,% are not available. It would be useful to have custom
rvalue converters that convert to a "math_array" type instead of tuples.
This is currently not implemented but is possible within the framework of
Boost.Python V2 as it will be released in the next couple of weeks. [ed.:
this was posted on 2002/03/10]
It would also be useful to also have "custom lvalue converters" such
as `std::vector<>` <-> Python list. These converters would
support the modification of the Python list from C++. For example:
C++:
``
void foo(std::vector<double> &array)
{
for(std::size_t i=0;i&lt;array.size();i++) {
array[i] *= 2;
}
}
``
Python: [python]
``
>>> l = [1, 2, 3]
>>> foo(l)
>>> print l
[2, 4, 6]
``
Custom lvalue converters require changes to the Boost.Python core library
and are currently not available.
P.S.:
The "scitbx" files referenced above are available via anonymous
CVS:
``
cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx login
cvs -d:pserver:anonymous@cvs.cctbx.sourceforge.net:/cvsroot/cctbx co scitbx
``
[endsect]
[section fatal error C1204:Compiler limit:internal structure overflow]
[*Q:] /I get this error message when compiling a large source file. What can I do?/
[*A:] You have two choices:
# Upgrade your compiler (preferred)
# Break your source file up into multiple translation units.
`my_module.cpp`: [c++]
``
...
void more_of_my_module();
BOOST_PYTHON_MODULE(my_module)
{
def("foo", foo);
def("bar", bar);
...
more_of_my_module();
}
``
`more_of_my_module.cpp`:
``
void more_of_my_module()
{
def("baz", baz);
...
}
``
If you find that a `class_<...>` declaration
can't fit in a single source file without triggering the error, you
can always pass a reference to the `class_` object to a
function in another source file, and call some of its member
functions (e.g. `.def(...)`) in the auxilliary source
file:
`more_of_my_class.cpp`:
``
void more_of_my_class(class&lt;my_class&gt;&amp; x)
{
x
.def("baz", baz)
.add_property("xx", &my_class::get_xx, &my_class::set_xx)
;
...
}
``
[endsect]
[section How do I debug my Python extensions?]
Greg Burley gives the following answer for Unix GCC users:
[:Once you have created a boost python extension for your c++ library or
class, you may need to debug the code. Afterall this is one of the
reasons for wrapping the library in python. An expected side-effect or
benefit of using BPL is that debugging should be isolated to the c++
library that is under test, given that python code is minimal and
boost::python either works or it doesn't. (ie. While errors can occur
when the wrapping method is invalid, most errors are caught by the
compiler ;-).
The basic steps required to initiate a gdb session to debug a c++
library via python are shown here. Note, however that you should start
the gdb session in the directory that contains your BPL my_ext.so
module.
``
(gdb) target exec python
(gdb) run
>>> from my_ext import *
>>> [C-c]
(gdb) break MyClass::MyBuggyFunction
(gdb) cont
>>> pyobj = MyClass()
>>> pyobj.MyBuggyFunction()
Breakpoint 1, MyClass::MyBuggyFunction ...
Current language: auto; currently c++
(gdb) do debugging stuff
``
]
Greg's approach works even better using Emacs' "gdb"
command, since it will show you each line of source as you step through it.
On *Windows*, my favorite debugging solution is the debugger that
comes with Microsoft Visual C++ 7. This debugger seems to work with code
generated by all versions of Microsoft and Metrowerks toolsets; it's rock
solid and "just works" without requiring any special tricks from the
user.
Raoul Gough has provided the following for gdb on Windows:
[:gdb support for Windows DLLs has improved lately, so it is
now possible to debug Python extensions using a few
tricks. Firstly, you will need an up-to-date gdb with support
for minimal symbol extraction from a DLL. Any gdb from version 6
onwards, or Cygwin gdb-20030214-1 and onwards should do. A
suitable release will have a section in the gdb.info file under
Configuration - Native - Cygwin Native -
Non-debug DLL symbols. Refer to that info section for more
details of the procedures outlined here.
Secondly, it seems necessary to set a breakpoint in the
Python interpreter, rather than using ^C to break execution. A
good place to set this breakpoint is PyOS_Readline, which will
stop execution immediately before reading each interactive
Python command. You have to let Python start once under the
debugger, so that it loads its own DLL, before you can set the
breakpoint:
``
$ gdb python
GNU gdb 2003-09-02-cvs (cygwin-special)
[...]
(gdb) run
Starting program: /cygdrive/c/Python22/python.exe
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> ^Z
Program exited normally.
(gdb) break *&PyOS_Readline
Breakpoint 1 at 0x1e04eff0
(gdb) run
Starting program: /cygdrive/c/Python22/python.exe
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
from /cygdrive/c/WINNT/system32/python22.dll
(gdb) cont
Continuing.
>>> from my_ext import *
Breakpoint 1, 0x1e04eff0 in python22!PyOS_Readline ()
from /cygdrive/c/WINNT/system32/python22.dll
(gdb) # my_ext now loaded (with any debugging symbols it contains)
``
]
[h2 Debugging extensions through Boost.Build]
If you are launching your extension module tests with _bb_ using the
`boost-python-runtest` rule, you can ask it to launch your
debugger for you by adding "--debugger=/debugger/" to your bjam
command-line:
``
bjam -sTOOLS=vc7.1 "--debugger=devenv /debugexe" test
bjam -sTOOLS=gcc -sPYTHON_LAUNCH=gdb test
``
It can also be extremely useful to add the `-d+2` option when
you run your test, because Boost.Build will then show you the exact
commands it uses to invoke it. This will invariably involve setting up
PYTHONPATH and other important environment variables such as
LD_LIBRARY_PATH which may be needed by your debugger in order to get
things to work right.
[endsect]
[section Why doesn't my `*=` operator work?]
[*Q:] ['I have exported my class to python, with many overloaded
operators. it works fine for me except the `*=`
operator. It always tells me "can't multiply sequence with non int
type". If I use `p1.__imul__(p2)` instead of
`p1 *= p2`, it successfully executes my code. What's
wrong with me?]
[*A:] There's nothing wrong with you. This is a bug in Python
2.2. You can see the same effect in Pure Python (you can learn a lot
about what's happening in Boost.Python by playing with new-style
classes in Pure Python).
``
>>> class X(object):
... def __imul__(self, x):
... print 'imul'
...
>>> x = X()
>>> x *= 1
``
To cure this problem, all you need to do is upgrade your Python to
version 2.2.1 or later.
[endsect]
[section Does Boost.Python work with Mac OS X?]
It is known to work under 10.2.8 and 10.3 using
Apple's gcc 3.3 compiler:
``gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1493)``
Under 10.2.8 get the August 2003 gcc update (free at [@http://connect.apple.com]).
Under 10.3 get the Xcode Tools v1.0 (also free).
Python 2.3 is required. The Python that ships with 10.3 is
fine. Under 10.2.8 use these commands to install Python
as a framework:
``./configure --enable-framework
make
make frameworkinstall``
The last command requires root privileges because the target
directory is `/Library/Frameworks/Python.framework/Versions/2.3`.
However, the installation does not interfere with the Python
version that ships with 10.2.8.
It is also crucial to increase the `stacksize` before
starting compilations, e.g.:
``limit stacksize 8192k``
If the `stacksize` is too small the build might crash with
internal compiler errors.
Sometimes Apple's compiler exhibits a bug by printing an error
like the following while compiling a
`boost::python::class_<your_type>`
template instantiation:
``
.../inheritance.hpp:44: error: cannot
dynamic_cast `p' (of type `struct cctbx::boost_python::<unnamed>::add_pair*
') to type `void*' (source type is not polymorphic)
``
We do not know a general workaround, but if the definition of
`your_type` can be modified the following was found
to work in all cases encountered so far:
``
struct your_type
{
// before defining any member data
#if defined(__MACH__) &amp;&amp; defined(__APPLE_CC__) &amp;&amp; __APPLE_CC__ == 1493
bool dummy_;
#endif
// now your member data, e.g.
double x;
int j;
// etc.
};
``
[endsect]
[section How can I find the existing PyObject that holds a C++ object?]
[: "I am wrapping a function that always returns a pointer to an
already-held C++ object."]
One way to do that is to hijack the mechanisms used for wrapping a class
with virtual functions. If you make a wrapper class with an initial
PyObject* constructor argument and store that PyObject* as "self", you
can get back to it by casting down to that wrapper type in a thin wrapper
function. For example:
``
class X { X(int); virtual ~X(); ... };
X* f(); // known to return Xs that are managed by Python objects
// wrapping code
struct X_wrap : X
{
X_wrap(PyObject* self, int v) : self(self), X(v) {}
PyObject* self;
};
handle<> f_wrap()
{
X_wrap* xw = dynamic_cast<X_wrap*>(f());
assert(xw != 0);
return handle<>(borrowed(xw->self));
}
...
def("f", f_wrap());
class_<X,X_wrap,boost::noncopyable>("X", init<int>())
...
;
``
Of course, if X has no virtual functions you'll have to use
`static_cast` instead of `dynamic_cast` with no
runtime check that it's valid. This approach also only works if the
`X` object was constructed from Python, because
`X`\ s constructed from C++ are of course never
`X_wrap` objects.
Another approach to this requires you to change your C++ code a bit;
if that's an option for you it might be a better way to go. work we've
been meaning to get to anyway. When a `shared_ptr<X>` is
converted from Python, the shared_ptr actually manages a reference to the
containing Python object. When a shared_ptr<X> is converted back to
Python, the library checks to see if it's one of those "Python object
managers" and if so just returns the original Python object. So you could
just write `object(p)` to get the Python object back. To
exploit this you'd have to be able to change the C++ code you're wrapping
so that it deals with shared_ptr instead of raw pointers.
There are other approaches too. The functions that receive the Python
object that you eventually want to return could be wrapped with a thin
wrapper that records the correspondence between the object address and
its containing Python object, and you could have your f_wrap function
look in that mapping to get the Python object out.
[endsect]
[section How can I wrap a function which needs to take ownership of a raw pointer?]
[*Q:] Part of an API that I'm wrapping goes something like this:
``
struct A {}; struct B { void add( A* ); }
where B::add() takes ownership of the pointer passed to it.
``
However:
``
a = mod.A()
b = mod.B()
b.add( a )
del a
del b
# python interpreter crashes
# later due to memory corruption.
``
Even binding the lifetime of a to b via `with_custodian_and_ward` doesn't prevent
the python object a from ultimately trying to delete the object it's pointing to.
Is there a way to accomplish a 'transfer-of-ownership' of a wrapped C++ object?
--Bruce Lowery
Yes: Make sure the C++ object is held by auto_ptr:
``
class_<A, std::auto_ptr<A> >("A")
...
;
``
Then make a thin wrapper function which takes an auto_ptr parameter:
``
void b_insert(B &b, std::auto_ptr<A> a)
{
b.insert(a.get());
a.release();
}
``
Wrap that as B.add. Note that pointers returned via `manage_new_object`
will also be held by `auto_ptr`, so this transfer-of-ownership
will also work correctly.
[endsect]
[section Compilation takes too much time and eats too much memory!
What can I do to make it faster?]
Please refer to the `Reducing Compiling Time` section in the _tutorial_.
[endsect]
[section How do I create sub-packages using Boost.Python?]
Please refer to the `Creating Packages` section in the _tutorial_.
[endsect]
[section error C2064: term does not evaluate to a function taking 2 arguments]
/Niall Douglas provides these notes:/
If you see Microsoft Visual C++ 7.1 (MS Visual Studio .NET 2003) issue
an error message like the following it is most likely due to a bug
in the compiler:
``
boost\boost\python\detail\invoke.hpp(76):
error C2064: term does not evaluate to a function taking 2 arguments"
``
This message is triggered by code like the following:
``
#include <boost/python.hpp>
using namespace boost::python;
class FXThread
{
public:
bool setAutoDelete(bool doso) throw();
};
void Export_FXThread()
{
class_< FXThread >("FXThread")
.def("setAutoDelete", &amp;FXThread::setAutoDelete)
;
}
``
The bug is related to the `throw()` modifier.
As a workaround cast off the modifier. E.g.:
``
.def("setAutoDelete", (bool (FXThread::*)(bool)) &FXThread::setAutoDelete)
``
(The bug has been reported to Microsoft.)
[endsect]
[section How can I automatically convert my custom string type to and from a Python string?]
/Ralf W. Grosse-Kunstleve provides these notes:/
Below is a small, self-contained demo extension module that shows
how to do this. Here is the corresponding trivial test:
``
import custom_string
assert custom_string.hello() == "Hello world."
assert custom_string.size("california") == 10
``
If you look at the code you will find:
* A custom `to_python` converter (easy):
`custom_string_to_python_str`
*A custom lvalue converter (needs more code):
`custom_string_from_python_str`
The custom converters are registered in the global Boost.Python
registry near the top of the module initialization function. Once
flow control has passed through the registration code the automatic
conversions from and to Python strings will work in any module
imported in the same process.
``
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/to_python_converter.hpp>
namespace sandbox { namespace {
class custom_string
{
public:
custom_string() {}
custom_string(std::string const &value) : value_(value) {}
std::string const &value() const { return value_; }
private:
std::string value_;
};
struct custom_string_to_python_str
{
static PyObject* convert(custom_string const &s)
{
return boost::python::incref(boost::python::object(s.value()).ptr());
}
};
struct custom_string_from_python_str
{
custom_string_from_python_str()
{
boost::python::converter::registry::push_back(
&convertible,
&construct,
boost::python::type_id<custom_string>());
}
static void* convertible(PyObject* obj_ptr)
{
if (!PyString_Check(obj_ptr)) return 0;
return obj_ptr;
}
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
const char* value = PyString_AsString(obj_ptr);
if (value == 0) boost::python::throw_error_already_set();
void* storage = (
(boost::python::converter::rvalue_from_python_storage<custom_string>*)
data)->storage.bytes;
new (storage) custom_string(value);
data->convertible = storage;
}
};
custom_string hello() { return custom_string("Hello world."); }
std::size_t size(custom_string const &s) { return s.value().size(); }
void init_module()
{
using namespace boost::python;
boost::python::to_python_converter<
custom_string,
custom_string_to_python_str>();
custom_string_from_python_str();
def("hello", hello);
def("size", size);
}
}} // namespace sandbox::<anonymous>
BOOST_PYTHON_MODULE(custom_string)
{
sandbox::init_module();
}
``
[endsect]
[section Why is my automatic to-python conversion not being found?]
/Niall Douglas provides these notes:/
If you define custom converters similar to the ones
shown above the `def_readonly()` and `def_readwrite()`
member functions provided by `boost::python::class_` for
direct access to your member data will not work as expected.
This is because `def_readonly("bar",&foo::bar)` is
equivalent to:
``
.add_property("bar", make_getter(&foo::bar, return_internal_reference()))
``
Similarly, `def_readwrite("bar",&foo::bar)` is
equivalent to:
``
.add_property("bar", make_getter(&foo::bar, return_internal_reference()),
make_setter(&foo::bar, return_internal_reference())
``
In order to define return value policies compatible with the
custom conversions replace `def_readonly()` and
`def_readwrite()` by `add_property()`. E.g.:
``
.add_property("bar", make_getter(&foo::bar, return_value_policy<return_by_value>()),
make_setter(&foo::bar, return_value_policy<return_by_value>()))
``
[endsect]
[section Is Boost.Python thread-aware/compatible with multiple interpreters?]
/Niall Douglas provides these notes:/
The quick answer to this is: no.
The longer answer is that it can be patched to be so, but it's
complex. You will need to add custom lock/unlock wrapping of every
time your code enters Boost.Python (particularly every virtual
function override) plus heavily modify
`boost/python/detail/invoke.hpp` with custom unlock/lock
wrapping of every time Boost.Python enters your code. You must
furthermore take care to /not/ unlock/lock when Boost.Python
is invoking iterator changes via `invoke.hpp`.
There is a patched `invoke.hpp` posted on the C++-SIG
mailing list archives and you can find a real implementation of all
the machinery necessary to fully implement this in the TnFOX
project at [@http://sourceforge.net/projects/tnfox/ this]
SourceForge project location.
[endsect]

View File

@@ -1,38 +0,0 @@
[chapter Glossary
[quickbook 1.7]
[id glossary]
]
[variablelist
[[arity [#arity]]
[The number of argumnts accepted by a function or member function.
Unless otherwise specified, the hidden `this` argument to member
functions is not counted when specifying arity.]]
[[ntbs [#ntbs]]
[Null-Terminated Byte String, or 'C'-string. C++ string literals are *ntbs*\ es.
An *ntbs* must never be null.]]
[[raise [#raise]]
[Exceptions in Python are "raised", not "thrown", as they are in C++.
When this documentation says that some Python exception is "raised" in
the context of C++ code, it means that the corresponding Python exception
is set via the [@http://www.python.org/doc/current/api/exceptionHandling.html Python/'C' API],
and `throw_error_already_set()` is called.]]
[[POD [#pod]]
[A technical term from the C++ standard. Short for "Plain Ol'Data":
A POD-struct is an aggregate class that has no non-static data members
of type pointer to member, non-POD-struct, non-POD-union (or array of such
types) or reference, and has no user-defined copy assign- ment operator and
no user-defined destructor. Similarly, a POD-union is an aggregate union that
has no non-static data members of type pointer to member, non-POD-struct,
non-POD-union (or array of such types) or reference, and has no
user-defined copy assignment operator and no user-defined destructor. A
POD class is a class that is either a POD-struct or a POD-union. An
aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions
(10.3).]]
[[ODR [#odr]]
[The "One Definition Rule", which says that any entity in a C++ program must have
the same definition in all translation units (object files) which make up a program.]]
]

View File

@@ -1,66 +0,0 @@
/*=============================================================================
Copyright 2002 William E. Kempf
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)
=============================================================================*/
H1
{
FONT-SIZE: 200%;
COLOR: #00008B;
}
H2
{
FONT-SIZE: 150%;
}
H3
{
FONT-SIZE: 125%;
}
H4
{
FONT-SIZE: 108%;
}
BODY
{
FONT-SIZE: 100%;
BACKGROUND-COLOR: #ffffff;
COLOR: #000000;
}
PRE
{
MARGIN-LEFT: 2em;
FONT-FAMILY: Courier,
monospace;
}
CODE
{
FONT-FAMILY: Courier,
monospace;
}
CODE.as_pre
{
white-space: pre;
}
.index
{
TEXT-ALIGN: left;
}
.page-index
{
TEXT-ALIGN: left;
}
.definition
{
TEXT-ALIGN: left;
}
.footnote
{
FONT-SIZE: 66%;
VERTICAL-ALIGN: super;
TEXT-DECORATION: none;
}
.function-semantics
{
CLEAR: left;
}

View File

@@ -1,700 +0,0 @@
/*=============================================================================
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;
}
/*=============================================================================
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 */

View File

@@ -1,275 +0,0 @@
/*
:Author: David Goodger
:Contact: goodger@python.org
:Date: $Date$
:Revision: $Revision$
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin-left: 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left {
clear: left }
img.align-right {
clear: right }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M10.428,10.411h0.56c3.78,0,4.788-1.96,4.872-3.444h3.22v19.88h-3.92V13.154h-4.732V10.411z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 485 B

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.815,10.758h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.04h-3.36V13.11H3.815V10.758z"/>
<path style="fill:#FFFFFF;" d="M22.175,7.806c4.009,0,5.904,2.76,5.904,8.736c0,5.975-1.896,8.76-5.904,8.76
c-4.008,0-5.904-2.785-5.904-8.76C16.271,10.566,18.167,7.806,22.175,7.806z M22.175,22.613c1.921,0,2.448-1.68,2.448-6.071
c0-4.393-0.527-6.049-2.448-6.049c-1.92,0-2.448,1.656-2.448,6.049C19.727,20.934,20.255,22.613,22.175,22.613z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 B

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M5.209,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H5.209V10.412z"/>
<path style="fill:#FFFFFF;" d="M18.553,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.359V12.764h-4.056V10.412z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 827 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M4.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H4.813V10.412z"/>
<path style="fill:#FFFFFF;" d="M17.316,13.484c0-5.545,4.056-6.024,5.568-6.024c3.265,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.553,5.544c-2.256,1.584-3.432,2.353-3.815,3.145h7.392V24.5h-11.64c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.353-2.424c-2.352,0-2.423,1.944-2.447,3.192H17.316z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 509 B

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H3.813V10.412z"/>
<path style="fill:#FFFFFF;" d="M20.611,14.636h0.529c1.008,0,2.855-0.096,2.855-2.304c0-0.624-0.288-2.185-2.137-2.185
c-2.303,0-2.303,2.185-2.303,2.784h-3.12c0-3.191,1.8-5.472,5.64-5.472c2.279,0,5.279,1.152,5.279,4.752
c0,1.728-1.08,2.808-2.039,3.24V15.5c0.6,0.168,2.568,1.056,2.568,3.96c0,3.216-2.377,5.496-5.809,5.496
c-1.607,0-5.928-0.36-5.928-5.688h3.288l-0.024,0.024c0,0.912,0.24,2.976,2.496,2.976c1.344,0,2.52-0.911,2.52-2.808
c0-2.328-2.256-2.424-3.816-2.424V14.636z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M4.146,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H4.146V10.412z"/>
<path style="fill:#FFFFFF;" d="M28.457,20.732h-1.896V24.5h-3.36v-3.768h-6.72v-2.904L22.746,7.46h3.815v10.656h1.896V20.732z
M23.201,18.116c0-4.128,0.072-6.792,0.072-7.32h-0.048l-4.272,7.32H23.201z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.479,11.079h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.04h-3.36V13.43H3.479V11.079z"/>
<path style="fill:#FFFFFF;" d="M19.342,14.943c0.625-0.433,1.392-0.937,3.048-0.937c2.279,0,5.16,1.584,5.16,5.496
c0,2.328-1.176,6.121-6.192,6.121c-2.664,0-5.376-1.584-5.544-5.016h3.36c0.144,1.391,0.888,2.326,2.376,2.326
c1.607,0,2.544-1.367,2.544-3.191c0-1.512-0.72-3.047-2.496-3.047c-0.456,0-1.608,0.023-2.256,1.223l-3-0.143l1.176-9.361h9.36
v2.832h-6.937L19.342,14.943z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H3.813V10.412z"/>
<path style="fill:#FFFFFF;" d="M24.309,11.78c-0.097-0.96-0.721-1.633-1.969-1.633c-2.184,0-2.688,2.496-2.808,4.704L19.58,14.9
c0.456-0.624,1.296-1.416,3.191-1.416c3.529,0,5.209,2.712,5.209,5.256c0,3.72-2.28,6.216-5.568,6.216
c-5.16,0-6.168-4.32-6.168-8.568c0-3.24,0.432-8.928,6.336-8.928c0.695,0,2.641,0.264,3.48,1.104
c0.936,0.912,1.271,1.416,1.584,3.217H24.309z M22.172,16.172c-1.271,0-2.568,0.792-2.568,2.928c0,1.849,1.056,3.168,2.664,3.168
c1.225,0,2.353-0.936,2.353-3.239C24.62,16.868,23.229,16.172,22.172,16.172z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.479,11.079h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.04h-3.36V13.43H3.479V11.079z"/>
<path style="fill:#FFFFFF;" d="M27.838,11.006c-1.631,1.776-5.807,6.816-6.215,14.16h-3.457c0.36-6.816,4.632-12.24,6.072-13.776
h-8.472l0.072-2.976h12V11.006z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 866 B

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M4.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H4.813V10.412z"/>
<path style="fill:#FFFFFF;" d="M23.172,24.956c-4.392,0-5.904-2.856-5.904-5.185c0-0.863,0-3.119,2.592-4.319
c-1.344-0.672-2.064-1.752-2.064-3.336c0-2.904,2.328-4.656,5.304-4.656c3.528,0,5.4,2.088,5.4,4.44
c0,1.464-0.6,2.712-1.968,3.432c1.632,0.815,2.544,1.896,2.544,4.104C29.076,21.596,27.684,24.956,23.172,24.956z M23.124,16.916
c-1.224,0-2.4,0.792-2.4,2.64c0,1.632,0.936,2.712,2.472,2.712c1.752,0,2.424-1.512,2.424-2.688
C25.62,18.38,24.996,16.916,23.124,16.916z M25.284,12.26c0-1.296-0.888-2.112-1.968-2.112c-1.512,0-2.305,0.864-2.305,2.112
c0,1.008,0.744,2.112,2.185,2.112C24.516,14.372,25.284,13.484,25.284,12.26z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M4.146,10.746h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.041h-3.36V13.097H4.146V10.746z"/>
<path style="fill:#FFFFFF;" d="M20.225,20.898v0.023c0.192,1.176,0.936,1.68,1.968,1.68c1.392,0,2.783-1.176,2.808-4.752
l-0.048-0.049c-0.768,1.152-2.088,1.441-3.24,1.441c-3.264,0-5.16-2.473-5.16-5.329c0-4.176,2.472-6.12,5.808-6.12
c5.904,0,6,6.36,6,8.76c0,6.601-3.12,8.736-6.192,8.736c-2.904,0-4.992-1.68-5.28-4.391H20.225z M22.434,16.553
c1.176,0,2.472-0.84,2.472-2.855c0-1.944-0.841-3.145-2.568-3.145c-0.864,0-2.424,0.433-2.424,2.88
C19.913,16.001,21.161,16.553,22.434,16.553z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M9.668,12.328c0-6.469,4.732-7.028,6.496-7.028c3.808,0,6.833,2.24,6.833,6.271
c0,3.416-2.213,5.152-4.145,6.469c-2.632,1.848-4.004,2.744-4.452,3.668h8.624v3.472H9.444c0.14-2.324,0.308-4.76,4.62-7.896
c3.584-2.604,5.012-3.612,5.012-5.853c0-1.315-0.84-2.828-2.744-2.828c-2.744,0-2.828,2.269-2.856,3.725H9.668z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 926 B

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M23.172,7.46c4.008,0,5.904,2.76,5.904,8.736c0,5.976-1.896,8.76-5.904,8.76
s-5.904-2.784-5.904-8.76C17.268,10.22,19.164,7.46,23.172,7.46z M23.172,22.268c1.92,0,2.448-1.68,2.448-6.071
c0-4.393-0.528-6.049-2.448-6.049s-2.448,1.656-2.448,6.049C20.724,20.588,21.252,22.268,23.172,22.268z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M5.306,13.151c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392v2.976H5.114c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H5.306z"/>
<path style="fill:#FFFFFF;" d="M19.49,10.079h0.48c3.239,0,4.104-1.681,4.176-2.952h2.761v17.04h-3.361V12.431H19.49V10.079z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M17.316,13.484c0-5.545,4.056-6.024,5.568-6.024c3.265,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.553,5.544c-2.256,1.584-3.432,2.353-3.815,3.145h7.392V24.5h-11.64c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.353-2.424c-2.352,0-2.423,1.944-2.447,3.192H17.316z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M21.612,14.636h0.528c1.008,0,2.855-0.096,2.855-2.304c0-0.624-0.287-2.185-2.136-2.185
c-2.304,0-2.304,2.185-2.304,2.784h-3.12c0-3.191,1.8-5.472,5.64-5.472c2.28,0,5.28,1.152,5.28,4.752
c0,1.728-1.08,2.808-2.04,3.24V15.5c0.6,0.168,2.568,1.056,2.568,3.96c0,3.216-2.377,5.496-5.809,5.496
c-1.607,0-5.928-0.36-5.928-5.688h3.288l-0.024,0.024c0,0.912,0.24,2.976,2.496,2.976c1.344,0,2.521-0.911,2.521-2.808
c0-2.328-2.257-2.424-3.816-2.424V14.636z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M4.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H4.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H4.972z"/>
<path style="fill:#FFFFFF;" d="M30.124,20.732h-1.896V24.5h-3.36v-3.768h-6.72v-2.904L24.412,7.46h3.816v10.656h1.896V20.732z
M24.868,18.116c0-4.128,0.071-6.792,0.071-7.32h-0.047l-4.272,7.32H24.868z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M20.676,14.276c0.624-0.433,1.393-0.937,3.049-0.937c2.279,0,5.16,1.584,5.16,5.496
c0,2.328-1.177,6.12-6.193,6.12c-2.664,0-5.375-1.584-5.543-5.016h3.36c0.144,1.392,0.889,2.327,2.376,2.327
c1.608,0,2.544-1.367,2.544-3.191c0-1.513-0.72-3.048-2.496-3.048c-0.455,0-1.607,0.023-2.256,1.224l-3-0.144l1.176-9.36h9.36
v2.832h-6.937L20.676,14.276z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M25.309,11.78c-0.097-0.96-0.721-1.633-1.969-1.633c-2.184,0-2.688,2.496-2.808,4.704L20.58,14.9
c0.456-0.624,1.296-1.416,3.191-1.416c3.529,0,5.209,2.712,5.209,5.256c0,3.72-2.28,6.216-5.568,6.216
c-5.16,0-6.168-4.32-6.168-8.568c0-3.24,0.432-8.928,6.336-8.928c0.695,0,2.641,0.264,3.48,1.104
c0.936,0.912,1.271,1.416,1.584,3.217H25.309z M23.172,16.172c-1.271,0-2.568,0.792-2.568,2.928c0,1.849,1.056,3.168,2.664,3.168
c1.225,0,2.353-0.936,2.353-3.239C25.62,16.868,24.229,16.172,23.172,16.172z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M29.172,10.34c-1.632,1.776-5.808,6.816-6.216,14.16H19.5c0.36-6.816,4.632-12.24,6.072-13.776
H17.1l0.072-2.976h12V10.34z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M23.172,24.956c-4.392,0-5.904-2.856-5.904-5.185c0-0.863,0-3.119,2.592-4.319
c-1.344-0.672-2.064-1.752-2.064-3.336c0-2.904,2.328-4.656,5.304-4.656c3.528,0,5.4,2.088,5.4,4.44
c0,1.464-0.6,2.712-1.968,3.432c1.632,0.815,2.544,1.896,2.544,4.104C29.076,21.596,27.684,24.956,23.172,24.956z M23.124,16.916
c-1.224,0-2.4,0.792-2.4,2.64c0,1.632,0.936,2.712,2.472,2.712c1.752,0,2.424-1.512,2.424-2.688
C25.62,18.38,24.996,16.916,23.124,16.916z M25.284,12.26c0-1.296-0.888-2.112-1.968-2.112c-1.512,0-2.305,0.864-2.305,2.112
c0,1.008,0.744,2.112,2.185,2.112C24.516,14.372,25.284,13.484,25.284,12.26z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
<path style="fill:#FFFFFF;" d="M20.893,20.564v0.023c0.191,1.176,0.936,1.68,1.967,1.68c1.393,0,2.785-1.176,2.809-4.752
l-0.048-0.048c-0.769,1.152-2.088,1.44-3.24,1.44c-3.264,0-5.16-2.473-5.16-5.328c0-4.176,2.472-6.12,5.807-6.12
c5.904,0,6.001,6.36,6.001,8.76c0,6.601-3.12,8.736-6.192,8.736c-2.904,0-4.992-1.68-5.28-4.392H20.893z M23.1,16.22
c1.176,0,2.473-0.84,2.473-2.855c0-1.944-0.84-3.145-2.568-3.145c-0.863,0-2.424,0.433-2.424,2.88
C20.58,15.668,21.828,16.22,23.1,16.22z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M15.127,14.005h0.616c1.176,0,3.332-0.112,3.332-2.688c0-0.728-0.336-2.548-2.492-2.548
c-2.688,0-2.688,2.548-2.688,3.248h-3.64c0-3.724,2.1-6.384,6.58-6.384c2.66,0,6.16,1.344,6.16,5.544
c0,2.016-1.261,3.276-2.38,3.78v0.056c0.699,0.196,2.996,1.232,2.996,4.62c0,3.752-2.772,6.412-6.776,6.412
c-1.876,0-6.916-0.42-6.916-6.636h3.836l-0.028,0.027c0,1.064,0.28,3.473,2.912,3.473c1.568,0,2.94-1.064,2.94-3.276
c0-2.716-2.632-2.828-4.452-2.828V14.005z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M8.268,14.636h0.528c1.008,0,2.856-0.096,2.856-2.304c0-0.624-0.288-2.185-2.136-2.185
c-2.304,0-2.304,2.185-2.304,2.784h-3.12c0-3.191,1.8-5.472,5.64-5.472c2.28,0,5.28,1.152,5.28,4.752
c0,1.728-1.08,2.808-2.04,3.24V15.5c0.6,0.168,2.568,1.056,2.568,3.96c0,3.216-2.376,5.496-5.808,5.496
c-1.608,0-5.928-0.36-5.928-5.688h3.288l-0.024,0.024c0,0.912,0.24,2.976,2.496,2.976c1.344,0,2.52-0.911,2.52-2.808
c0-2.328-2.256-2.424-3.816-2.424V14.636z"/>
<path style="fill:#FFFFFF;" d="M23.172,7.46c4.008,0,5.904,2.76,5.904,8.736c0,5.976-1.896,8.76-5.904,8.76
s-5.904-2.784-5.904-8.76C17.268,10.22,19.164,7.46,23.172,7.46z M23.172,22.268c1.92,0,2.448-1.68,2.448-6.071
c0-4.393-0.528-6.049-2.448-6.049s-2.448,1.656-2.448,6.049C20.724,20.588,21.252,22.268,23.172,22.268z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M21.891,20.784h-2.212v4.396h-3.92v-4.396h-7.84v-3.389L15.227,5.3h4.452v12.432h2.212V20.784z
M15.759,17.731c0-4.815,0.084-7.924,0.084-8.54h-0.056l-4.984,8.54H15.759z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 423 B

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M14.035,14.252c0.728-0.504,1.624-1.092,3.556-1.092c2.66,0,6.02,1.848,6.02,6.411
c0,2.717-1.372,7.141-7.224,7.141c-3.108,0-6.272-1.849-6.468-5.853h3.92c0.168,1.624,1.036,2.717,2.772,2.717
c1.876,0,2.968-1.597,2.968-3.725c0-1.764-0.839-3.556-2.912-3.556c-0.532,0-1.876,0.028-2.632,1.428l-3.5-0.168l1.372-10.92
h10.919v3.304h-8.092L14.035,14.252z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 967 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M19.106,10.673c-0.112-1.12-0.84-1.904-2.296-1.904c-2.548,0-3.136,2.912-3.276,5.488l0.056,0.056
c0.532-0.728,1.512-1.651,3.724-1.651c4.116,0,6.077,3.164,6.077,6.131c0,4.34-2.66,7.252-6.497,7.252
c-6.02,0-7.196-5.039-7.196-9.996c0-3.78,0.504-10.416,7.392-10.416c0.812,0,3.08,0.308,4.061,1.288
c1.092,1.063,1.483,1.652,1.848,3.752H19.106z M16.614,15.797c-1.484,0-2.996,0.924-2.996,3.416c0,2.156,1.232,3.697,3.108,3.697
c1.428,0,2.745-1.094,2.745-3.781C19.471,16.609,17.846,15.797,16.614,15.797z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M24.28,9.66c-1.904,2.071-6.776,7.951-7.252,16.52h-4.032c0.42-7.952,5.404-14.28,7.084-16.072
h-9.884l0.084-3.472h14V9.66z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 738 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M16.28,26.712c-5.124,0-6.888-3.332-6.888-6.048c0-1.009,0-3.641,3.024-5.04
c-1.568-0.784-2.408-2.044-2.408-3.893c0-3.388,2.716-5.432,6.188-5.432c4.116,0,6.3,2.436,6.3,5.18
c0,1.708-0.7,3.164-2.296,4.004c1.903,0.952,2.968,2.212,2.968,4.788C23.168,22.792,21.544,26.712,16.28,26.712z M16.224,17.332
c-1.428,0-2.8,0.924-2.8,3.08c0,1.903,1.092,3.164,2.884,3.164c2.043,0,2.829-1.765,2.829-3.137
C19.137,19.04,18.408,17.332,16.224,17.332z M18.744,11.899c0-1.512-1.036-2.464-2.296-2.464c-1.764,0-2.688,1.008-2.688,2.464
c0,1.177,0.868,2.464,2.548,2.464C17.848,14.363,18.744,13.328,18.744,11.899z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
<!DOCTYPE svg [
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
<g>
<g style="enable-background:new ;">
<path style="fill:#FFFFFF;" d="M13.953,21.921v0.027c0.224,1.372,1.092,1.961,2.296,1.961c1.624,0,3.248-1.372,3.276-5.545
l-0.057-0.056c-0.896,1.344-2.436,1.68-3.78,1.68c-3.808,0-6.02-2.884-6.02-6.216c0-4.872,2.884-7.14,6.776-7.14
c6.888,0,7,7.42,7,10.22c0,7.7-3.641,10.192-7.224,10.192c-3.388,0-5.824-1.96-6.16-5.124H13.953z M16.529,16.853
c1.372,0,2.884-0.979,2.884-3.332c0-2.268-0.98-3.668-2.996-3.668c-1.008,0-2.828,0.504-2.828,3.36
C13.589,16.209,15.045,16.853,16.529,16.853z"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,68 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) --><svg height="120.648" id="Layer_1" inkscape:version="0.42" sodipodi:docbase="F:\openclip\svg da inviare" sodipodi:docname="Attenzione.svg" sodipodi:version="0.32" space="preserve" style="overflow:visible;enable-background:new 0 0 133.878 120.648;" version="1.1" viewBox="0 0 133.878 120.648" width="133.878" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
<metadata>
<rdf:RDF xmlns:cc="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<cc:Work rdf:about="">
<dc:title>Attenzione</dc:title>
<dc:description></dc:description>
<dc:subject>
<rdf:Bag>
<rdf:li>pulsante</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:publisher>
<cc:Agent rdf:about="http://www.openclipart.org/">
<dc:title>Open Clip Art Library</dc:title>
</cc:Agent>
</dc:publisher>
<dc:creator>
<cc:Agent>
<dc:title>Architetto Francesco Rollandin</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>Architetto Francesco Rollandin</dc:title>
</cc:Agent>
</dc:rights>
<dc:date></dc:date>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<cc:license rdf:resource="http://web.resource.org/cc/PublicDomain"/>
<dc:language>en</dc:language>
</cc:Work>
<cc:License rdf:about="http://web.resource.org/cc/PublicDomain">
<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
<cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
</cc:License>
</rdf:RDF>
</metadata>
<defs id="defs43"/>
<sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:current-layer="Layer_1" inkscape:cx="66.939003" inkscape:cy="60.324001" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="510" inkscape:window-width="787" inkscape:window-x="44" inkscape:window-y="58" inkscape:zoom="2.9838869" pagecolor="#ffffff"/>
<g id="g3">
<linearGradient gradientTransform="matrix(56.9977 90.4964 90.4964 -56.9977 -27343.9609 47971.0547)" gradientUnits="userSpaceOnUse" id="XMLID_4_" x1="-244.5732" x2="-242.8169" y1="455.4199" y2="455.4199">
<stop id="stop6" offset="0" style="stop-color:#FFFA5F"/>
<stop id="stop8" offset="1" style="stop-color:#9F3300"/>
</linearGradient>
<path d="M51.333,8.834C34.985,37.343,18.638,65.854,2.289,94.363 c-7.081,12.352,3.352,26.285,16.453,26.285c6.708,0,13.418,0,20.128,0c22.109,0,44.217,0,66.327,0c3.644,0,7.286,0,10.931,0 c13.293,0,20.963-14.273,16.452-26.031c-4.114-10.729-11.861-20.99-17.542-30.922c-8.81-15.403-17.618-30.809-26.429-46.212 c-1.813-3.167-3.622-6.333-5.434-9.5C76.601-3.516,57.616-2.03,51.333,8.834 M53.973,9.064" id="path10" style="fill:url(#XMLID_4_);"/>
<path d="M55.474,12.388c-8.247,14.279-16.492,28.559-24.739,42.839 c-5.526,9.567-11.05,19.137-16.577,28.707c-2.732,4.73-7.323,10.456-8.284,16c-3.799,21.9,34.927,15.743,46.734,15.743 c20.073,0,40.144,0,60.215,0c13.716,0,18.636-11.963,12.229-23.063c-6.462-11.195-12.927-22.388-19.389-33.582 c-7.249-12.557-14.499-25.113-21.75-37.671c-1.682-2.916-3.364-5.829-5.049-8.745C73.767,3.785,60.676,3.364,55.474,12.388" id="path12" style="fill-rule:evenodd;clip-rule:evenodd;fill:#FFF200;"/>
<path d="M55.474,12.388c-8.247,14.279-16.492,28.559-24.739,42.839c-5.526,9.567-11.05,19.137-16.577,28.707 c-2.732,4.73-7.323,10.456-8.284,16c-3.799,21.9,34.927,15.743,46.734,15.743c20.073,0,40.144,0,60.215,0 c13.716,0,18.636-11.963,12.229-23.063c-6.462-11.195-12.927-22.388-19.389-33.582c-7.249-12.557-14.499-25.113-21.75-37.671 c-1.682-2.916-3.364-5.829-5.049-8.745C73.767,3.785,60.676,3.364,55.474,12.388" id="path14" style="fill:#FFCE00;"/>
<path d="M126.731,95.522c-8.733-15.127-17.468-30.253-26.201-45.379 c-5.537-9.595-11.078-19.188-16.616-28.781c-3.938-6.821-7.459-15.689-16.813-15.689c1.013,0,5.901,10.225,6.469,11.196 c5.451,9.314,10.902,18.63,16.352,27.947c9.217,15.749,18.433,31.498,27.646,47.249c2.302,3.933,5.356,10.555,1.308,14.397 c-3.148,2.987-7.99,3.196-12.099,3.196c-7.225,0-14.448,0-21.674,0c-22.125,0-44.251,0-66.377,0c-3.598,0-7.197,0-10.794,0 c5.285,7.909,16.341,6.02,24.546,6.02c13.009,0,26.017,0,39.023,0c11.979,0,23.958,0,35.937,0c2.516,0,5.032,0,7.547,0 C125.136,115.678,131.878,104.435,126.731,95.522" id="path16" style="fill:#FFB600;"/>
<path d="M14.615,112.457c-4.483-7.751,1.908-16.103,5.793-22.834 c4.698-8.138,9.398-16.276,14.097-24.414C44.54,47.83,54.574,30.448,64.61,13.069c0.789-1.367,3.725-4.568,2.594-5.539 c-3.913-3.353-10.287,1.936-12.107,5.087c-3.129,5.417-6.258,10.835-9.386,16.252c-11.105,19.226-22.209,38.453-33.313,57.68 c-1.649,2.854-3.299,5.713-4.95,8.569c-4.771,8.265-0.075,19.162,9.658,20.446C16.124,114.65,15.294,113.615,14.615,112.457" id="path18" style="fill-rule:evenodd;clip-rule:evenodd;fill:#FFE600;"/>
<path d="M77.076,34.654c0,10.183-1.788,20.758-3.439,30.772 c-0.369,2.239-4.03,23.609-7.796,14.179c-4.247-10.632-4.832-23.419-5.958-34.696c-0.363-3.638-1.538-8.425-0.563-12.06 C61.667,24.099,77.076,25.199,77.076,34.654" id="path20" style="fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFE1;"/>
<path d="M77.076,34.654c-2.018,0.995-1.521,8.717-1.797,11.395c-0.685,6.643-1.505,13.282-2.614,19.869 c-0.79,4.701-1.301,10.862-3.954,14.981c-1.642,2.567-3.405-5.958-3.634-6.932c-2.948-12.443-4.464-25.664-5.09-38.43 c-0.272-5.52,5.164-8.854,10.277-7.622c3.87,0.933,5.217,7.36,7.688,6.738c0.009-11.451-19.755-11.453-19.746,0 c0.017,11.956,2.087,24.599,4.423,36.294c0.501,2.507,1.642,12.376,5.449,12.376c4.059-0.021,5.285-11.432,5.79-14.137 c1.261-6.765,2.139-13.605,2.887-20.444C77.084,45.722,79.281,35.942,77.076,34.654" id="path22" style="fill:#FFFFFF;"/>
<linearGradient gradientTransform="matrix(68.2284 33.0019 33.0019 -68.2284 1613.9791 39385.6641)" gradientUnits="userSpaceOnUse" id="XMLID_5_" x1="-246.981" x2="-245.2275" y1="458.29" y2="458.29">
<stop id="stop25" offset="0" style="stop-color:#FFFA5F"/>
<stop id="stop27" offset="1" style="stop-color:#9F3300"/>
</linearGradient>
<path d="M57.957,34.654c0,10.053,1.632,20.54,3.242,30.431 c0.479,2.936,4.912,26.502,9.99,15.164c4.987-11.134,5.351-25.201,6.386-37.184c0.273-3.169,1.153-7.045,0.421-10.221 C75.628,22.587,57.957,23.788,57.957,34.654 M60.207,34.654c0-8.061,13.138-9.015,15.459-1.792c1.156,3.597-0.13,8.748-0.508,12.38 c-1.135,10.904-2.052,22.602-5.501,33.069c-2.816,8.545-5.546-10.187-5.934-12.522C62.039,55.63,60.207,44.985,60.207,34.654" id="path29" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#XMLID_5_);"/>
<path d="M77.076,96.788c0,11.964-18.555,11.964-18.555,0 C58.521,84.822,77.076,84.822,77.076,96.788" id="path31" style="fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFE1;"/>
<path d="M77.076,96.788c-2.605,1.661-2.157,6.757-7.044,8.101c-6.178,1.7-12.033-4.159-10.336-10.335 c1.439-5.23,7.657-7.767,12.341-5.021c2.91,1.704,3.164,7.913,5.915,7.256c0-14.267-22.698-12.238-20.143,1.826 c0.987,5.444,6.375,9.15,11.814,8.162C72.417,106.271,81.44,98.19,77.076,96.788" id="path33" style="fill:#FFFFFF;"/>
<linearGradient gradientTransform="matrix(68.2241 32.9998 32.9998 -68.2241 1604.682 39402.625)" gradientUnits="userSpaceOnUse" id="XMLID_6_" x1="-246.998" x2="-245.2348" y1="458.0625" y2="458.0625">
<stop id="stop36" offset="0" style="stop-color:#FFFA5F"/>
<stop id="stop38" offset="1" style="stop-color:#9F3300"/>
</linearGradient>
<path d="M57.395,96.788c0,13.41,20.805,13.41,20.805,0 C78.2,83.376,57.395,83.375,57.395,96.788 M59.647,96.788c0-10.514,16.301-10.514,16.301,0 C75.948,107.3,59.647,107.3,59.647,96.788" id="path40" style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#XMLID_6_);"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 B

View File

@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
<!DOCTYPE svg [
<!ENTITY st0 "fill-rule:nonzero;clip-rule:nonzero;fill:#FFFFFF;stroke:#000000;stroke-miterlimit:4;">
<!ENTITY st1 "fill:none;stroke:none;">
<!ENTITY st2 "fill:#000000;">
<!ENTITY st3 "fill:none;stroke:#FFFFFF;stroke-width:6.3469;stroke-linejoin:round;">
<!ENTITY st4 "fill-rule:evenodd;clip-rule:evenodd;stroke:none;">
<!ENTITY st5 "fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
]>
<svg width="48pt" height="48pt" viewBox="0 0 48 48" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<g id="Layer_x0020_3" style="&st0;">
<g style="&st4;">
<path style="&st3;" d="M22.9,7.1L5.1,21.8l0,0c-0.3,0.3-0.5,0.8-0.5,1.2c0,0.2,0,0.4,0.1,0.6c0.3,0.6,0.9,1,1.6,1c0,0,1.1,0,2.2,0c0,2.4,0,14.2,0,14.2c0,1.1,0.8,1.9,1.8,1.9h27.4c1.1,0,1.9-0.9,1.9-2c0,0,0-11.8,0-14.2c1,0,2,0,2,0c0.8,0,1.4-0.5,1.7-1.2
c0.1-0.2,0.1-0.4,0.1-0.6c0-0.5-0.2-1-0.7-1.4c0,0-3.6-3-4.5-3.7c0-1.2,0-6.9,0-6.9c0-1.2-0.8-2-2-2h-4.8c-1,0-1.7,0.6-1.9,1.5c-1.9-1.6-4.1-3.5-4.1-3.5l0.1,0.1c-0.7-0.7-1.8-0.8-2.7-0.1z"/>
<path style="&st2;" d="M22.9,7.1L5.1,21.8l0,0c-0.3,0.3-0.5,0.8-0.5,1.2c0,0.2,0,0.4,0.1,0.6c0.3,0.6,0.9,1,1.6,1c0,0,1.1,0,2.2,0c0,2.4,0,14.2,0,14.2c0,1.1,0.8,1.9,1.8,1.9h27.4c1.1,0,1.9-0.9,1.9-2c0,0,0-11.8,0-14.2c1,0,2,0,2,0c0.8,0,1.4-0.5,1.7-1.2
c0.1-0.2,0.1-0.4,0.1-0.6c0-0.5-0.2-1-0.7-1.4c0,0-3.6-3-4.5-3.7c0-1.2,0-6.9,0-6.9c0-1.2-0.8-2-2-2h-4.8c-1,0-1.7,0.6-1.9,1.5c-1.9-1.6-4.1-3.5-4.1-3.5l0.1,0.1c-0.7-0.7-1.8-0.8-2.7-0.1z"/>
<path style="&st2;" d="M41.8,22.8l-5.1-4.2v-0.1L31,13.7v0l-6.5-5.5C24.2,8,24,8,23.8,8.2L6.2,22.9c-0.1,0.1-0.1,0.3,0.1,0.3h1.6H10h28.1h1.2h2.3c0.2,0,0.4-0.2,0.2-0.4z"/>
<path d="M35.8,16.8l0-5.1c0-0.2-0.1-0.4-0.3-0.4h-3.2c-0.2,0-0.3,0.1-0.3,0.3v2.2l3.9,2.9z"/>
<path d="M11.9,24.7V37c0,0.3,0.1,0.4,0.3,0.4h23.6c0.3,0,0.4-0.2,0.4-0.4V24.7H11.9z"/>
</g>
</g>
<g id="crop_x0020_marks" style="&st5;">
<path style="&st1;" d="M48,48H0V0h48v48z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
<!DOCTYPE svg [
<!ENTITY st0 "fill:#FFFFFF;stroke:none;">
<!ENTITY st1 "fill:#FFFFFF;stroke-width:6.6112;stroke-linecap:round;stroke-linejoin:round;">
<!ENTITY st2 "stroke:#FFFFFF;stroke-width:6.6112;">
<!ENTITY st3 "fill:none;stroke:none;">
<!ENTITY st4 "fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<!ENTITY st5 "stroke:none;">
]>
<svg width="48pt" height="48pt" viewBox="0 0 48 48" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<g id="Layer_x0020_3" style="&st4;">
<g>
<path style="&st2;" d="M41.7,35.3L26.6,9.4c-0.6-1-1.7-1.7-2.9-1.6c-1.2,0-2.3,0.7-2.9,1.7L6.3,35.4c-0.6,1-0.6,2.3,0,3.3c0.6,1,1.7,1.6,2.9,1.6h29.6c1.2,0,2.3-0.6,2.9-1.7c0.6-1,0.6-2.3,0-3.3z"/>
<path style="&st1;" d="M23.7,11L9.2,37h29.6L23.7,11z"/>
<path style="&st0;" d="M23.7,11.9L10.3,36.1h27.5l-14-24.1z"/>
<g>
<path style="&st5;" d="M24.1,34c-1.1,0-1.8-0.8-1.8-1.8c0-1.1,0.7-1.8,1.8-1.8c1.1,0,1.8,0.7,1.8,1.8c0,1-0.7,1.8-1.8,1.8h0z M22.9,29.3l-0.4-9.1h3.2l-0.4,9.1h-2.3z"/>
</g>
</g>
</g>
<g id="crop_x0020_marks" style="&st4;">
<path style="&st3;" d="M48,48H0V0h48v48z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 B

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
<!DOCTYPE svg [
<!ENTITY st0 "fill:none;stroke:none;">
<!ENTITY st1 "fill:#FFFFFF;stroke:#FFFFFF;stroke-width:7.5901;stroke-linejoin:round;">
<!ENTITY st2 "fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<!ENTITY st3 "stroke:none;">
]>
<svg width="48pt" height="48pt" viewBox="0 0 48 48" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<g id="Layer_x0020_3" style="&st2;">
<g>
<path style="&st1;" d="M22.4,41.1c0,0.3,0.3,0.3,0.5,0.2l16.6-16.9c0.5-0.5,0.4-0.7,0-1L22.9,6.7c-0.1-0.1-0.4-0.1-0.4,0.1v10H8.9c-0.3,0-0.5,0.2-0.5,0.4l0,13.3C8.4,30.9,8.6,31,9,31h13.5l-0.1,10.1z"/>
<path style="&st3;" d="M22.4,41.1c0,0.3,0.3,0.3,0.5,0.2l16.6-16.9c0.5-0.5,0.4-0.7,0-1L22.9,6.7c-0.1-0.1-0.4-0.1-0.4,0.1v10H8.9c-0.3,0-0.5,0.2-0.5,0.4l0,13.3C8.4,30.9,8.6,31,9,31h13.5l-0.1,10.1z"/>
</g>
</g>
<g id="crop_x0020_marks" style="&st2;">
<path style="&st0;" d="M48,48H0V0h48v48z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
<!DOCTYPE svg [
<!ENTITY st0 "fill:none;stroke:#FFFFFF;stroke-width:12.1438;stroke-linejoin:round;">
<!ENTITY st1 "fill:none;stroke-width:1.2429;">
<!ENTITY st2 "fill:#FFFFFF;stroke:none;">
<!ENTITY st3 "fill:none;stroke:#FFFFFF;stroke-width:12.7649;stroke-linejoin:round;">
<!ENTITY st4 "fill:#FFFFFF;stroke-width:6.3824;stroke-linejoin:round;">
<!ENTITY st5 "fill:none;stroke:none;">
<!ENTITY st6 "fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<!ENTITY st7 "fill:#FFFFFF;stroke:#FFFFFF;stroke-width:12.7649;stroke-linejoin:round;">
<!ENTITY st8 "stroke:none;">
<!ENTITY st9 "fill:none;stroke-width:4.9715;stroke-linejoin:round;">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="48pt" height="48pt" viewBox="0 0 48 48" xml:space="preserve">
<g id="Layer_x0020_1" style="&st6;">
<path style="&st0;" d="M35.7,19.8v18.9H11V8.8h13.9l10.8,11z"/>
<path style="&st3;" d="M38.7,30.4L25,16.7l-7.7-3l2.7,8.7l13.3,13.4l5.4-5.4z"/>
<path style="&st7;" d="M35.7,8.8H11v29.9h24.7V8.8z"/>
<path style="&st4;" d="M35.7,8.8H11v29.9h24.7V8.8z"/>
<path style="&st2;" d="M35.7,8.8H11v29.9h24.7V8.8z"/>
</g>
<g id="Layer_x0020_4" style="&st6;">
<path style="&st9;" d="M38.7,30.4L25,16.7l-7.7-3l2.7,8.7l13.3,13.4l5.4-5.4z"/>
<path style="&st8;" d="M38.7,30.4L25,16.7l-7.7-3l2.7,8.7l13.3,13.4l5.4-5.4z"/>
<path style="&st8;" d="M20.6,14.7l-2.5,2.5L17,13.4l3.6,1.3z"/>
<path style="&st1;" d="M19.6,22.2l3-0.3l2.4-2.4l0.4-2.8"/>
<path style="&st2;" d="M20.4,14.9L18.3,17l1.6,5.2l2.7-0.3l2.4-2.4l0.3-2.4l-5-2.2z"/>
</g>
<g id="crop" style="&st6;">
<path style="&st5;" d="M48,48H0V0h48v48z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
<!DOCTYPE svg [
<!ENTITY st0 "fill:none;stroke:none;">
<!ENTITY st1 "fill:#FFFFFF;stroke:#FFFFFF;stroke-width:7.5901;stroke-linejoin:round;">
<!ENTITY st2 "fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
<!ENTITY st3 "stroke:none;">
]>
<svg width="48pt" height="48pt" viewBox="0 0 48 48" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<g id="Layer_x0020_3" style="&st2;">
<g>
<path style="&st1;" d="M25.6,6.9c0-0.3-0.3-0.3-0.5-0.2L8.4,23.6c-0.5,0.5-0.4,0.7,0,1l16.6,16.6c0.1,0.1,0.4,0.1,0.4-0.1v-10h13.6c0.3,0,0.5-0.2,0.5-0.4l0-13.3c0-0.3-0.2-0.5-0.5-0.5H25.5l0.1-10.1z"/>
<path style="&st3;" d="M25.6,6.9c0-0.3-0.3-0.3-0.5-0.2L8.4,23.6c-0.5,0.5-0.4,0.7,0,1l16.6,16.6c0.1,0.1,0.4,0.1,0.4-0.1v-10h13.6c0.3,0,0.5-0.2,0.5-0.4l0-13.3c0-0.3-0.2-0.5-0.5-0.5H25.5l0.1-10.1z"/>
</g>
</g>
<g id="crop_x0020_marks" style="&st2;">
<path style="&st0;" d="M48,48H0V0h48v48z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More