update python control examples
This commit is contained in:
parent
0f9760ddf4
commit
faa3349525
@ -1,15 +1,30 @@
|
||||
cmake_minimum_required(VERSION 2.8.2)
|
||||
project(UnitreeMotorSDK_M80106)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3")
|
||||
cmake_minimum_required(VERSION 3.1.0)
|
||||
project(unitree_actuator_sdk)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||
|
||||
include_directories(include)
|
||||
link_directories(lib)
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "aarch64")
|
||||
set(EXTRA_LIBS libUnitreeMotorSDK_M80106_Arm64.so)
|
||||
set(EXTRA_LIBS libUnitreeMotorSDK_Arm64.so)
|
||||
else()
|
||||
set(EXTRA_LIBS libUnitreeMotorSDK_M80106_Linux64.so)
|
||||
set(EXTRA_LIBS libUnitreeMotorSDK_Linux64.so)
|
||||
endif()
|
||||
|
||||
add_executable(motorctrl example/main.cpp)
|
||||
target_link_libraries(motorctrl ${EXTRA_LIBS})
|
||||
#example
|
||||
add_executable(example_a1_motor example/example_a1_motor.cpp)
|
||||
target_link_libraries(example_a1_motor ${EXTRA_LIBS})
|
||||
|
||||
add_executable(example_b1_motor example/example_b1_motor.cpp)
|
||||
target_link_libraries(example_b1_motor ${EXTRA_LIBS})
|
||||
|
||||
add_executable(example_goM8010_6_motor example/example_goM8010_6_motor.cpp)
|
||||
target_link_libraries(example_goM8010_6_motor ${EXTRA_LIBS})
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH "../lib")
|
||||
add_subdirectory(thirdparty/pybind11)
|
||||
pybind11_add_module(unitree_actuator_sdk thirdparty/python_wrapper/wrapper.cpp)
|
||||
target_link_libraries(unitree_actuator_sdk PRIVATE ${EXTRA_LIBS})
|
||||
set_target_properties(unitree_actuator_sdk PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${LIBRARY_OUTPUT_PATH}")
|
21
README.md
21
README.md
@ -2,15 +2,13 @@
|
||||
|
||||
### Notice
|
||||
|
||||
support motor: GO-M8010-6 motor
|
||||
support motor: GO-M8010-6 motor、A1 motor、 B1 motor
|
||||
|
||||
not support motor: A1 motor、 B1 motor (Check A1B1 branch for support)
|
||||
gcc >= 5.4.0 (for x86 platform)
|
||||
|
||||
gcc >= 5.4.0 (for libUnitreeMotorSDK_M80106_Linux64.so)
|
||||
gcc >= 7.5.0 (for Arm platform)
|
||||
|
||||
gcc >= 8.3.0 (for libUnitreeMotorSDK_M80106_Arm64.so)
|
||||
|
||||
run gcc -v command to check your gcc version
|
||||
run gcc --version command to check your gcc version
|
||||
|
||||
### Build
|
||||
```bash
|
||||
@ -21,7 +19,12 @@ make
|
||||
```
|
||||
|
||||
### Run
|
||||
Run examples with 'sudo',e.g.
|
||||
If the compilation is successful, many C++ example executable files will be generated in the build folder. Then run the examples with 'sudo', for example:
|
||||
```bash
|
||||
sudo ./motorctrl
|
||||
```
|
||||
sudo ./example_a1_motor
|
||||
```
|
||||
|
||||
If you need to run the Python example, please enter the "python" folder. Then run the examples with 'sudo', for example:
|
||||
```python
|
||||
sudo python3 example_a1_motor.py
|
||||
```
|
||||
|
35
example/example_a1_motor.cpp
Normal file
35
example/example_a1_motor.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <unistd.h>
|
||||
#include "serialPort/SerialPort.h"
|
||||
#include "unitreeMotor/unitreeMotor.h"
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
SerialPort serial("/dev/ttyUSB0");
|
||||
MotorCmd cmd;
|
||||
MotorData data;
|
||||
|
||||
while(true)
|
||||
{
|
||||
cmd.motorType = MotorType::A1;
|
||||
data.motorType = MotorType::A1;
|
||||
cmd.mode = queryMotorMode(MotorType::A1,MotorMode::FOC);
|
||||
cmd.id = 0;
|
||||
cmd.kp = 0.0;
|
||||
cmd.kd = 2;
|
||||
cmd.q = 0.0;
|
||||
cmd.dq = -6.28*queryGearRatio(MotorType::A1);
|
||||
cmd.tau = 0.0;
|
||||
serial.sendRecv(&cmd,&data);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "motor.q: " << data.q << std::endl;
|
||||
std::cout << "motor.temp: " << data.temp << std::endl;
|
||||
std::cout << "motor.W: " << data.dq << std::endl;
|
||||
std::cout << "motor.merror: " << data.merror << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
usleep(200);
|
||||
}
|
||||
|
||||
}
|
35
example/example_b1_motor.cpp
Normal file
35
example/example_b1_motor.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <unistd.h>
|
||||
#include "serialPort/SerialPort.h"
|
||||
#include "unitreeMotor/unitreeMotor.h"
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
SerialPort serial("/dev/ttyUSB0");
|
||||
MotorCmd cmd;
|
||||
MotorData data;
|
||||
|
||||
while(true)
|
||||
{
|
||||
cmd.motorType = MotorType::B1;
|
||||
data.motorType = MotorType::B1;
|
||||
cmd.mode = queryMotorMode(MotorType::B1,MotorMode::FOC);
|
||||
cmd.id = 0;
|
||||
cmd.kp = 0.0;
|
||||
cmd.kd = 3;
|
||||
cmd.q = 0.0;
|
||||
cmd.dq = -6.28*queryGearRatio(MotorType::B1);
|
||||
cmd.tau = 0.0;
|
||||
serial.sendRecv(&cmd,&data);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "motor.q: " << data.q << std::endl;
|
||||
std::cout << "motor.temp: " << data.temp << std::endl;
|
||||
std::cout << "motor.W: " << data.dq << std::endl;
|
||||
std::cout << "motor.merror: " << data.merror << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
usleep(200);
|
||||
}
|
||||
|
||||
}
|
35
example/example_goM8010_6_motor.cpp
Normal file
35
example/example_goM8010_6_motor.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <unistd.h>
|
||||
#include "serialPort/SerialPort.h"
|
||||
#include "unitreeMotor/unitreeMotor.h"
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
SerialPort serial("/dev/ttyUSB0");
|
||||
MotorCmd cmd;
|
||||
MotorData data;
|
||||
|
||||
while(true)
|
||||
{
|
||||
cmd.motorType = MotorType::GO_M8010_6;
|
||||
data.motorType = MotorType::GO_M8010_6;
|
||||
cmd.mode = queryMotorMode(MotorType::GO_M8010_6,MotorMode::FOC);
|
||||
cmd.id = 0;
|
||||
cmd.kp = 0.0;
|
||||
cmd.kd = 0.01;
|
||||
cmd.q = 0.0;
|
||||
cmd.dq = -6.28*queryGearRatio(MotorType::GO_M8010_6);
|
||||
cmd.tau = 0.0;
|
||||
serial.sendRecv(&cmd,&data);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "motor.q: " << data.q << std::endl;
|
||||
std::cout << "motor.temp: " << data.temp << std::endl;
|
||||
std::cout << "motor.W: " << data.dq << std::endl;
|
||||
std::cout << "motor.merror: " << data.merror << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
usleep(200);
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
#include "serialPort/SerialPort.h"
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
|
||||
SerialPort serial("/dev/ttyUSB0");
|
||||
MotorCmd cmd;
|
||||
MotorData data;
|
||||
|
||||
while(true) {
|
||||
cmd.motorType = MotorType::GO_M8010_6;
|
||||
cmd.id = 0;
|
||||
cmd.mode = 1;
|
||||
cmd.K_P = 0.0;
|
||||
cmd.K_W = 0.05;
|
||||
cmd.Pos = 0.0;
|
||||
cmd.W = 6.28*6.33;
|
||||
cmd.T = 0.0;
|
||||
serial.sendRecv(&cmd,&data);
|
||||
|
||||
if(data.correct == true)
|
||||
{
|
||||
std::cout << std::endl;
|
||||
std::cout << "motor.Pos: " << data.Pos << " rad" << std::endl;
|
||||
std::cout << "motor.Temp: " << data.Temp << " ℃" << std::endl;
|
||||
std::cout << "motor.W: " << data.W << " rad/s"<<std::endl;
|
||||
std::cout << "motor.T: " << data.T << " N.m" << std::endl;
|
||||
std::cout << "motor.MError: " << data.MError << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
usleep(200);
|
||||
|
||||
}
|
||||
|
||||
}
|
33
include/crc/crc32.h
Executable file
33
include/crc/crc32.h
Executable file
@ -0,0 +1,33 @@
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
inline uint32_t crc32_core(uint32_t* ptr, uint32_t len){
|
||||
uint32_t xbit = 0;
|
||||
uint32_t data = 0;
|
||||
uint32_t CRC32 = 0xFFFFFFFF;
|
||||
const uint32_t dwPolynomial = 0x04c11db7;
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
{
|
||||
xbit = 1 << 31;
|
||||
data = ptr[i];
|
||||
for (uint32_t bits = 0; bits < 32; bits++)
|
||||
{
|
||||
if (CRC32 & 0x80000000)
|
||||
{
|
||||
CRC32 <<= 1;
|
||||
CRC32 ^= dwPolynomial;
|
||||
}
|
||||
else
|
||||
CRC32 <<= 1;
|
||||
if (data & xbit)
|
||||
CRC32 ^= dwPolynomial;
|
||||
|
||||
xbit >>= 1;
|
||||
}
|
||||
}
|
||||
return CRC32;
|
||||
}
|
||||
|
||||
#endif // CRC32_H
|
@ -73,7 +73,7 @@ public:
|
||||
bool sendRecv(uint8_t *sendMsg, uint8_t *recvMsg, size_t sendLength);
|
||||
bool sendRecv(MotorCmd* sendMsg, MotorData* recvMsg);
|
||||
bool sendRecv(std::vector<MotorCmd> &sendVec, std::vector<MotorData> &recvVec);
|
||||
|
||||
void test();
|
||||
private:
|
||||
void _open();
|
||||
void _set();
|
||||
|
162
include/unitreeMotor/include/motor_msg_A1B1.h
Executable file
162
include/unitreeMotor/include/motor_msg_A1B1.h
Executable file
@ -0,0 +1,162 @@
|
||||
#ifndef MOTOR_A1B1_MSG
|
||||
#define MOTOR_A1B1_MSG
|
||||
|
||||
#include <stdint.h>
|
||||
typedef int16_t q15_t;
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
// 发送用单个数据数据结构
|
||||
typedef union{
|
||||
int32_t L;
|
||||
uint8_t u8[4];
|
||||
uint16_t u16[2];
|
||||
uint32_t u32;
|
||||
float F;
|
||||
}COMData32;
|
||||
|
||||
typedef struct {
|
||||
// 定义 数据包头
|
||||
unsigned char start[2]; // 包头
|
||||
unsigned char motorID; // 电机ID 0,1,2,3 ... 0xBB 表示向所有电机广播(此时无返回)
|
||||
unsigned char reserved;
|
||||
}COMHead;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint8_t fan_d; // 关节上的散热风扇转速
|
||||
uint8_t Fmusic; // 电机发声频率 /64*1000 15.625f 频率分度
|
||||
uint8_t Hmusic; // 电机发声强度 推荐值4 声音强度 0.1 分度
|
||||
uint8_t reserved4;
|
||||
|
||||
uint8_t FRGB[4]; // 足端LED
|
||||
|
||||
}LowHzMotorCmd;
|
||||
|
||||
typedef struct { // 以 4个字节一组排列 ,不然编译器会凑整
|
||||
// 定义 数据
|
||||
uint8_t mode; // 关节模式选择
|
||||
uint8_t ModifyBit; // 电机控制参数修改位
|
||||
uint8_t ReadBit; // 电机控制参数发送位
|
||||
uint8_t reserved;
|
||||
|
||||
COMData32 Modify; // 电机参数修改 的数据
|
||||
//实际给FOC的指令力矩为:
|
||||
//K_P*delta_Pos + K_W*delta_W + T
|
||||
q15_t T; // 期望关节的输出力矩(电机本身的力矩)x256, 7 + 8 描述
|
||||
q15_t W; // 期望关节速度 (电机本身的速度) x128, 8 + 7描述
|
||||
int32_t Pos; // 期望关节位置 x 16384/6.2832, 14位编码器(主控0点修正,电机关节还是以编码器0点为准)
|
||||
|
||||
q15_t K_P; // 关节刚度系数 x2048 4+11 描述
|
||||
q15_t K_W; // 关节速度系数 x1024 5+10 描述
|
||||
|
||||
uint8_t LowHzMotorCmdIndex; // 电机低频率控制命令的索引, 0-7, 分别代表LowHzMotorCmd中的8个字节
|
||||
uint8_t LowHzMotorCmdByte; // 电机低频率控制命令的字节
|
||||
|
||||
COMData32 Res[1]; // 通讯 保留字节 用于实现别的一些通讯内容
|
||||
|
||||
}MasterComdV3; // 加上数据包的包头 和CRC 34字节
|
||||
|
||||
typedef struct {
|
||||
// 定义 电机控制命令数据包
|
||||
COMHead head;
|
||||
MasterComdV3 Mdata;
|
||||
COMData32 CRCdata;
|
||||
}MasterComdDataV3;//返回数据
|
||||
|
||||
// typedef struct {
|
||||
// // 定义 总得485 数据包
|
||||
|
||||
// MasterComdData M1;
|
||||
// MasterComdData M2;
|
||||
// MasterComdData M3;
|
||||
|
||||
// }DMA485TxDataV3;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct { // 以 4个字节一组排列 ,不然编译器会凑整
|
||||
// 定义 数据
|
||||
uint8_t mode; // 当前关节模式
|
||||
uint8_t ReadBit; // 电机控制参数修改 是否成功位
|
||||
int8_t Temp; // 电机当前平均温度
|
||||
uint8_t MError; // 电机错误 标识
|
||||
|
||||
COMData32 Read; // 读取的当前 电机 的控制数据
|
||||
int16_t T; // 当前实际电机输出力矩 7 + 8 描述
|
||||
|
||||
int16_t W; // 当前实际电机速度(高速) 8 + 7 描述
|
||||
float LW; // 当前实际电机速度(低速)
|
||||
|
||||
int16_t W2; // 当前实际关节速度(高速) 8 + 7 描述
|
||||
float LW2; // 当前实际关节速度(低速)
|
||||
|
||||
int16_t Acc; // 电机转子加速度 15+0 描述 惯量较小
|
||||
int16_t OutAcc; // 输出轴加速度 12+3 描述 惯量较大
|
||||
|
||||
int32_t Pos; // 当前电机位置(主控0点修正,电机关节还是以编码器0点为准)
|
||||
int32_t Pos2; // 关节编码器位置(输出编码器)
|
||||
|
||||
int16_t gyro[3]; // 电机驱动板6轴传感器数据
|
||||
int16_t acc[3];
|
||||
|
||||
// 力传感器的数据
|
||||
int16_t Fgyro[3]; //
|
||||
int16_t Facc[3];
|
||||
int16_t Fmag[3];
|
||||
uint8_t Ftemp; // 8位表示的温度 7位(-28~100度) 1位0.5度分辨率
|
||||
|
||||
int16_t Force16; // 力传感器高16位数据
|
||||
int8_t Force8; // 力传感器低8位数据
|
||||
|
||||
uint8_t FError; // 足端传感器错误标识
|
||||
|
||||
int8_t Res[1]; // 通讯 保留字节
|
||||
|
||||
}ServoComdV3; // 加上数据包的包头 和CRC 78字节(4+70+4)
|
||||
|
||||
typedef struct {
|
||||
// 定义 电机控制命令数据包
|
||||
COMHead head;
|
||||
ServoComdV3 Mdata;
|
||||
|
||||
COMData32 CRCdata;
|
||||
|
||||
}ServoComdDataV3; //发送数据
|
||||
|
||||
// typedef struct {
|
||||
// // 定义 总的485 接受数据包
|
||||
|
||||
// ServoComdDataV3 M[3];
|
||||
// // uint8_t nullbyte1;
|
||||
|
||||
// }DMA485RxDataV3;
|
||||
|
||||
|
||||
#pragma pack()
|
||||
|
||||
// 00 00 00 00 00
|
||||
// 00 00 00 00 00
|
||||
// 00 00 00 00 00
|
||||
// 00 00 00
|
||||
// 数据包默认初始化
|
||||
// 主机发送的数据包
|
||||
/*
|
||||
Tx485Data[_FR][i].head.start[0] = 0xFE ; Tx485Data[_FR][i].head.start[1] = 0xEE; // 数据包头
|
||||
Tx485Data[_FR][i].Mdata.ModifyBit = 0xFF; Tx485Data[_FR][i].Mdata.mode = 0; // 默认不修改数据 和 电机的默认工作模式
|
||||
Tx485Data[_FR][i].head.motorID = i; 0 // 目标电机标号
|
||||
Tx485Data[_FR][i].Mdata.T = 0.0f; // 默认目标关节输出力矩 motor1.Extra_Torque = motorRxData[1].Mdata.T*0.390625f; // N.M 转化为 N.CM IQ8描述
|
||||
Tx485Data[_FR][i].Mdata.Pos = 0x7FE95C80; // 默认目标关节位置 不启用位置环 14位分辨率
|
||||
Tx485Data[_FR][i].Mdata.W = 16000.0f; // 默认目标关节速度 不启用速度环 1+8+7描述 motor1.Target_Speed = motorRxData[1].Mdata.W*0.0078125f; // 单位 rad/s IQ7描述
|
||||
Tx485Data[_FR][i].Mdata.K_P = (q15_t)(0.6f*(1<<11)); // 默认关节刚度系数 4+11 描述 motor1.K_Pos = ((float)motorRxData[1].Mdata.K_P)/(1<<11); // 描述刚度的通讯数据格式 4+11
|
||||
Tx485Data[_FR][i].Mdata.K_W = (q15_t)(1.0f*(1<<10)); // 默认关节速度系数 5+10 描述 motor1.K_Speed = ((float)motorRxData[1].Mdata.K_W)/(1<<10); // 描述阻尼的通讯数据格式 5+10
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
#ifndef __MOTOR_MSG_H
|
||||
#define __MOTOR_MSG_H
|
||||
#ifndef __MOTOR_MSG_GO_M8010_6_H
|
||||
#define __MOTOR_MSG_GO_M8010_6_H
|
||||
|
||||
#include <stdint.h>
|
||||
#define CRC_SIZE 2
|
||||
@ -26,7 +26,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int16_t tor_des; // 期望关节输出扭矩 unit: N.m (q8)
|
||||
int16_t spd_des; // 期望关节输出速度 unit: rad/s (q8)
|
||||
int16_t spd_des; // 期望关节输出速度 unit: rad/s (q7)
|
||||
int32_t pos_des; // 期望关节输出位置 unit: rad (q15)
|
||||
uint16_t k_pos; // 期望关节刚度系数 unit: 0.0-1.0 (q15)
|
||||
uint16_t k_spd; // 期望关节阻尼系数 unit: 0.0-1.0 (q15)
|
||||
@ -40,9 +40,9 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int16_t torque; // 实际关节输出扭矩 unit: N.m (q8)
|
||||
int16_t speed; // 实际关节输出速度 unit: rad/s (q8)
|
||||
int16_t speed; // 实际关节输出速度 unit: rad/s (q7)
|
||||
int32_t pos; // 实际关节输出位置 unit: W (q15)
|
||||
int8_t temp; // 电机温度: -50~127°C 90°C时触发温度保护
|
||||
int8_t temp; // 电机温度: -128~127°C 90°C时触发温度保护
|
||||
uint8_t MError :3; // 电机错误标识: 0.正常 1.过热 2.过流 3.过压 4.编码器故障 5-7.保留
|
||||
uint16_t force :12; // 足端气压传感器数据 12bit (0-4095)
|
||||
uint8_t none :1; // 保留位
|
@ -1,54 +1,74 @@
|
||||
#ifndef __UNITREEMOTOR_H
|
||||
#define __UNITREEMOTOR_H
|
||||
|
||||
#include "unitreeMotor/include/motor_msg.h" // 电机通信协议
|
||||
#include "unitreeMotor/include/motor_msg_GO-M8010-6.h"
|
||||
#include "unitreeMotor/include/motor_msg_A1B1.h"
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
|
||||
enum class MotorType{
|
||||
GO_M8010_6,
|
||||
A1, // 4.8M baudrate
|
||||
B1, // 6.0M baudrate
|
||||
GO_M8010_6
|
||||
};
|
||||
|
||||
enum class MotorMode{
|
||||
BRAKE,
|
||||
FOC,
|
||||
CALIBRATE
|
||||
};
|
||||
|
||||
struct MotorCmd{
|
||||
// 定义 发送格式化数据
|
||||
public:
|
||||
MotorType motorType = MotorType::GO_M8010_6;
|
||||
int hex_len = 17;
|
||||
unsigned short id; // 电机ID 0~14 15:广播ID 此时电机无返回
|
||||
unsigned short mode; // 电机模式 0:刹车 1:FOC闭环 2:电机标定(发送后等待5sec,期间禁止给电机发送消息)
|
||||
float T; // 期望关节的输出力矩(电机转子转矩 N.m) 范围: ±127.99
|
||||
float W; // 期望关节速度(电机转子转速 rad/s) ±804.00
|
||||
float Pos; // 期望关节位置(电机转子位置 rad) ±411774
|
||||
float K_P; // 关节刚度系数 0~25.599
|
||||
float K_W; // 关节速度系数 0~25.599
|
||||
MotorCmd(){}
|
||||
MotorType motorType;
|
||||
int hex_len;
|
||||
unsigned short id;
|
||||
unsigned short mode;
|
||||
float tau;
|
||||
float dq;
|
||||
float q;
|
||||
float kp;
|
||||
float kd;
|
||||
|
||||
void modify_data(MotorCmd* motor_s);
|
||||
uint8_t* get_motor_send_data();
|
||||
|
||||
COMData32 Res;
|
||||
private:
|
||||
ControlData_t motor_send_data; //电机控制数据结构体,详见motor_msg.h
|
||||
ControlData_t GO_M8010_6_motor_send_data;
|
||||
MasterComdDataV3 A1B1_motor_send_data;
|
||||
};
|
||||
|
||||
struct MotorData{
|
||||
// 定义 接收数据
|
||||
public:
|
||||
MotorType motorType = MotorType::GO_M8010_6;
|
||||
int hex_len = 16; // 接收的命令长度: 16Byte
|
||||
bool correct = false; // 接收数据是否完整(true完整,false不完整或断联)
|
||||
unsigned char motor_id; // 电机ID 0~14 15:广播ID 此时电机无返回
|
||||
unsigned char mode; // 电机模式 0:刹车 1:FOC闭环 2:电机标定
|
||||
int Temp; // 温度 -50~127 ℃
|
||||
int MError; // 错误标志 0.正常 1.过热 2.过流 3.过压 4.编码器故障
|
||||
float T; // 关节的输出力矩(电机转子转矩 N.m) 范围: ±127.99
|
||||
float W; // 关节速度(电机转子转速 rad/s) ±804.00
|
||||
float Pos; // 关节位置(电机转子位置 rad) ±411774
|
||||
int footForce; // 足端气压传感器接口 ADC原始值
|
||||
MotorData(){}
|
||||
MotorType motorType;
|
||||
int hex_len;
|
||||
unsigned char motor_id;
|
||||
unsigned char mode;
|
||||
int temp;
|
||||
int merror;
|
||||
float tau;
|
||||
float dq;
|
||||
float q;
|
||||
|
||||
bool correct = false;
|
||||
bool extract_data(MotorData* motor_r);
|
||||
uint8_t* get_motor_recv_data();
|
||||
|
||||
int footForce;
|
||||
float LW;
|
||||
int Acc;
|
||||
|
||||
float gyro[3];
|
||||
float acc[3];
|
||||
private:
|
||||
MotorData_t motor_recv_data; //电机接收数据结构体,详见motor_msg.h
|
||||
|
||||
MotorData_t GO_M8010_6_motor_recv_data;
|
||||
ServoComdDataV3 A1B1_motor_recv_data;
|
||||
};
|
||||
|
||||
|
||||
// Utility Function
|
||||
int queryMotorMode(MotorType motortype,MotorMode motormode);
|
||||
float queryGearRatio(MotorType motortype);
|
||||
#endif // UNITREEMOTOR_H
|
BIN
lib/libUnitreeMotorSDK_Arm64.so
Executable file
BIN
lib/libUnitreeMotorSDK_Arm64.so
Executable file
Binary file not shown.
BIN
lib/libUnitreeMotorSDK_Linux64.so
Executable file
BIN
lib/libUnitreeMotorSDK_Linux64.so
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
29
python/example_a1_motor.py
Normal file
29
python/example_a1_motor.py
Normal file
@ -0,0 +1,29 @@
|
||||
import time
|
||||
import sys
|
||||
sys.path.append('../lib')
|
||||
from unitree_actuator_sdk import *
|
||||
|
||||
|
||||
serial = SerialPort('/dev/ttyUSB0')
|
||||
cmd = MotorCmd()
|
||||
data = MotorData()
|
||||
|
||||
while True:
|
||||
data.motorType = MotorType.A1
|
||||
cmd.motorType = MotorType.A1
|
||||
cmd.mode = queryMotorMode(MotorType.A1,MotorMode.FOC)
|
||||
cmd.id = 0
|
||||
cmd.q = 0.0
|
||||
cmd.dq = 6.28*queryGearRatio(MotorType.A1)
|
||||
cmd.kp = 0.0
|
||||
cmd.kd = 2
|
||||
cmd.tau = 0.0
|
||||
serial.sendRecv(cmd, data)
|
||||
print('\n')
|
||||
print("q: " + str(data.q))
|
||||
print("dq: " + str(data.dq))
|
||||
print("temp: " + str(data.temp))
|
||||
print("merror: " + str(data.merror))
|
||||
print('\n')
|
||||
time.sleep(0.0002) # 200 us
|
||||
|
29
python/example_b1_motor.py
Normal file
29
python/example_b1_motor.py
Normal file
@ -0,0 +1,29 @@
|
||||
import time
|
||||
import sys
|
||||
sys.path.append('../lib')
|
||||
from unitree_actuator_sdk import *
|
||||
|
||||
|
||||
serial = SerialPort('/dev/ttyUSB0')
|
||||
cmd = MotorCmd()
|
||||
data = MotorData()
|
||||
|
||||
while True:
|
||||
data.motorType = MotorType.B1
|
||||
cmd.motorType = MotorType.B1
|
||||
cmd.mode = queryMotorMode(MotorType.B1,MotorMode.FOC)
|
||||
cmd.id = 0
|
||||
cmd.q = 0.0
|
||||
cmd.dq = 6.28*queryGearRatio(MotorType.B1)
|
||||
cmd.kp = 0.0
|
||||
cmd.kd = 3
|
||||
cmd.tau = 0.0
|
||||
serial.sendRecv(cmd, data)
|
||||
print('\n')
|
||||
print("q: " + str(data.q))
|
||||
print("dq: " + str(data.dq))
|
||||
print("temp: " + str(data.temp))
|
||||
print("merror: " + str(data.merror))
|
||||
print('\n')
|
||||
time.sleep(0.0002) # 200 us
|
||||
|
29
python/example_goM8010_6_motor.py
Normal file
29
python/example_goM8010_6_motor.py
Normal file
@ -0,0 +1,29 @@
|
||||
import time
|
||||
import sys
|
||||
sys.path.append('../lib')
|
||||
from unitree_actuator_sdk import *
|
||||
|
||||
|
||||
serial = SerialPort('/dev/ttyUSB0')
|
||||
cmd = MotorCmd()
|
||||
data = MotorData()
|
||||
|
||||
while True:
|
||||
data.motorType = MotorType.GO_M8010_6
|
||||
cmd.motorType = MotorType.GO_M8010_6
|
||||
cmd.mode = queryMotorMode(MotorType.GO_M8010_6,MotorMode.FOC)
|
||||
cmd.id = 0
|
||||
cmd.q = 0.0
|
||||
cmd.dq = 6.28*queryGearRatio(MotorType.GO_M8010_6)
|
||||
cmd.kp = 0.0
|
||||
cmd.kd = 0.01
|
||||
cmd.tau = 0.0
|
||||
serial.sendRecv(cmd, data)
|
||||
print('\n')
|
||||
print("q: " + str(data.q))
|
||||
print("dq: " + str(data.dq))
|
||||
print("temp: " + str(data.temp))
|
||||
print("merror: " + str(data.merror))
|
||||
print('\n')
|
||||
time.sleep(0.0002) # 200 us
|
||||
|
35
thirdparty/pybind11/.appveyor.yml
vendored
Normal file
35
thirdparty/pybind11/.appveyor.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
version: 1.0.{build}
|
||||
image:
|
||||
- Visual Studio 2017
|
||||
test: off
|
||||
skip_branch_with_pr: true
|
||||
build:
|
||||
parallel: true
|
||||
platform:
|
||||
- x86
|
||||
environment:
|
||||
matrix:
|
||||
- PYTHON: 36
|
||||
CONFIG: Debug
|
||||
install:
|
||||
- ps: |
|
||||
$env:CMAKE_GENERATOR = "Visual Studio 15 2017"
|
||||
if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
|
||||
$env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
|
||||
python -W ignore -m pip install --upgrade pip wheel
|
||||
python -W ignore -m pip install pytest numpy --no-warn-script-location pytest-timeout
|
||||
- ps: |
|
||||
Start-FileDownload 'https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip'
|
||||
7z x eigen-3.3.7.zip -y > $null
|
||||
$env:CMAKE_INCLUDE_PATH = "eigen-3.3.7;$env:CMAKE_INCLUDE_PATH"
|
||||
build_script:
|
||||
- cmake -G "%CMAKE_GENERATOR%" -A "%CMAKE_ARCH%"
|
||||
-DCMAKE_CXX_STANDARD=14
|
||||
-DPYBIND11_WERROR=ON
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DCMAKE_SUPPRESS_REGENERATION=1
|
||||
.
|
||||
- set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
- cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger%
|
||||
- cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger%
|
||||
on_failure: if exist "tests\test_cmake_build" type tests\test_cmake_build\*.log*
|
38
thirdparty/pybind11/.clang-format
vendored
Normal file
38
thirdparty/pybind11/.clang-format
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
# See all possible options and defaults with:
|
||||
# clang-format --style=llvm --dump-config
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AllowShortLambdasOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
ColumnLimit: 99
|
||||
CommentPragmas: 'NOLINT:.*|^ IWYU pragma:'
|
||||
IncludeBlocks: Regroup
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: 4
|
||||
Language: Cpp
|
||||
SpaceAfterCStyleCast: true
|
||||
Standard: Cpp11
|
||||
StatementMacros: ['PyObject_HEAD']
|
||||
TabWidth: 4
|
||||
IncludeCategories:
|
||||
- Regex: '<pybind11/.*'
|
||||
Priority: -1
|
||||
- Regex: 'pybind11.h"$'
|
||||
Priority: 1
|
||||
- Regex: '^".*/?detail/'
|
||||
Priority: 1
|
||||
SortPriority: 2
|
||||
- Regex: '^"'
|
||||
Priority: 1
|
||||
SortPriority: 3
|
||||
- Regex: '<[[:alnum:]._]+>'
|
||||
Priority: 4
|
||||
- Regex: '.*'
|
||||
Priority: 5
|
||||
...
|
77
thirdparty/pybind11/.clang-tidy
vendored
Normal file
77
thirdparty/pybind11/.clang-tidy
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
FormatStyle: file
|
||||
|
||||
Checks: |
|
||||
*bugprone*,
|
||||
*performance*,
|
||||
clang-analyzer-optin.cplusplus.VirtualCall,
|
||||
clang-analyzer-optin.performance.Padding,
|
||||
cppcoreguidelines-init-variables,
|
||||
cppcoreguidelines-prefer-member-initializer,
|
||||
cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
cppcoreguidelines-slicing,
|
||||
google-explicit-constructor,
|
||||
llvm-namespace-comment,
|
||||
misc-definitions-in-headers,
|
||||
misc-misplaced-const,
|
||||
misc-non-copyable-objects,
|
||||
misc-static-assert,
|
||||
misc-throw-by-value-catch-by-reference,
|
||||
misc-uniqueptr-reset-release,
|
||||
misc-unused-parameters,
|
||||
modernize-avoid-bind,
|
||||
modernize-loop-convert,
|
||||
modernize-make-shared,
|
||||
modernize-redundant-void-arg,
|
||||
modernize-replace-auto-ptr,
|
||||
modernize-replace-disallow-copy-and-assign-macro,
|
||||
modernize-replace-random-shuffle,
|
||||
modernize-shrink-to-fit,
|
||||
modernize-use-auto,
|
||||
modernize-use-bool-literals,
|
||||
modernize-use-default-member-init,
|
||||
modernize-use-emplace,
|
||||
modernize-use-equals-default,
|
||||
modernize-use-equals-delete,
|
||||
modernize-use-noexcept,
|
||||
modernize-use-nullptr,
|
||||
modernize-use-override,
|
||||
modernize-use-using,
|
||||
readability-avoid-const-params-in-decls,
|
||||
readability-braces-around-statements,
|
||||
readability-const-return-type,
|
||||
readability-container-size-empty,
|
||||
readability-delete-null-pointer,
|
||||
readability-else-after-return,
|
||||
readability-implicit-bool-conversion,
|
||||
readability-inconsistent-declaration-parameter-name,
|
||||
readability-make-member-function-const,
|
||||
readability-misplaced-array-index,
|
||||
readability-non-const-parameter,
|
||||
readability-qualified-auto,
|
||||
readability-redundant-function-ptr-dereference,
|
||||
readability-redundant-smartptr-get,
|
||||
readability-redundant-string-cstr,
|
||||
readability-simplify-subscript-expr,
|
||||
readability-static-accessed-through-instance,
|
||||
readability-static-definition-in-anonymous-namespace,
|
||||
readability-string-compare,
|
||||
readability-suspicious-call-argument,
|
||||
readability-uniqueptr-delete-release,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-exception-escape,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-unused-raii,
|
||||
|
||||
CheckOptions:
|
||||
- key: modernize-use-equals-default.IgnoreMacros
|
||||
value: false
|
||||
- key: performance-for-range-copy.WarnOnAllAutoCopies
|
||||
value: true
|
||||
- key: performance-inefficient-string-concatenation.StrictMode
|
||||
value: true
|
||||
- key: performance-unnecessary-value-param.AllowedTypes
|
||||
value: 'exception_ptr$;'
|
||||
- key: readability-implicit-bool-conversion.AllowPointerConditions
|
||||
value: true
|
||||
|
||||
HeaderFilterRegex: 'pybind11/.*h'
|
73
thirdparty/pybind11/.cmake-format.yaml
vendored
Normal file
73
thirdparty/pybind11/.cmake-format.yaml
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
parse:
|
||||
additional_commands:
|
||||
pybind11_add_module:
|
||||
flags:
|
||||
- THIN_LTO
|
||||
- MODULE
|
||||
- SHARED
|
||||
- NO_EXTRAS
|
||||
- EXCLUDE_FROM_ALL
|
||||
- SYSTEM
|
||||
|
||||
format:
|
||||
line_width: 99
|
||||
tab_size: 2
|
||||
|
||||
# If an argument group contains more than this many sub-groups
|
||||
# (parg or kwarg groups) then force it to a vertical layout.
|
||||
max_subgroups_hwrap: 2
|
||||
|
||||
# If a positional argument group contains more than this many
|
||||
# arguments, then force it to a vertical layout.
|
||||
max_pargs_hwrap: 6
|
||||
|
||||
# If a cmdline positional group consumes more than this many
|
||||
# lines without nesting, then invalidate the layout (and nest)
|
||||
max_rows_cmdline: 2
|
||||
separate_ctrl_name_with_space: false
|
||||
separate_fn_name_with_space: false
|
||||
dangle_parens: false
|
||||
|
||||
# If the trailing parenthesis must be 'dangled' on its on
|
||||
# 'line, then align it to this reference: `prefix`: the start'
|
||||
# 'of the statement, `prefix-indent`: the start of the'
|
||||
# 'statement, plus one indentation level, `child`: align to'
|
||||
# the column of the arguments
|
||||
dangle_align: prefix
|
||||
# If the statement spelling length (including space and
|
||||
# parenthesis) is smaller than this amount, then force reject
|
||||
# nested layouts.
|
||||
min_prefix_chars: 4
|
||||
|
||||
# If the statement spelling length (including space and
|
||||
# parenthesis) is larger than the tab width by more than this
|
||||
# amount, then force reject un-nested layouts.
|
||||
max_prefix_chars: 10
|
||||
|
||||
# If a candidate layout is wrapped horizontally but it exceeds
|
||||
# this many lines, then reject the layout.
|
||||
max_lines_hwrap: 2
|
||||
|
||||
line_ending: unix
|
||||
|
||||
# Format command names consistently as 'lower' or 'upper' case
|
||||
command_case: canonical
|
||||
|
||||
# Format keywords consistently as 'lower' or 'upper' case
|
||||
# unchanged is valid too
|
||||
keyword_case: 'upper'
|
||||
|
||||
# A list of command names which should always be wrapped
|
||||
always_wrap: []
|
||||
|
||||
# If true, the argument lists which are known to be sortable
|
||||
# will be sorted lexicographically
|
||||
enable_sort: true
|
||||
|
||||
# If true, the parsers may infer whether or not an argument
|
||||
# list is sortable (without annotation).
|
||||
autosort: false
|
||||
|
||||
# Causes a few issues - can be solved later, possibly.
|
||||
markup:
|
||||
enable_markup: false
|
24
thirdparty/pybind11/.codespell-ignore-lines
vendored
Normal file
24
thirdparty/pybind11/.codespell-ignore-lines
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>
|
||||
template <typename ThisT>
|
||||
auto &this_ = static_cast<ThisT &>(*this);
|
||||
if (load_impl<ThisT>(temp, false)) {
|
||||
ssize_t nd = 0;
|
||||
auto trivial = broadcast(buffers, nd, shape);
|
||||
auto ndim = (size_t) nd;
|
||||
int nd;
|
||||
ssize_t ndim() const { return detail::array_proxy(m_ptr)->nd; }
|
||||
using op = op_impl<id, ot, Base, L_type, R_type>;
|
||||
template <op_id id, op_type ot, typename L, typename R>
|
||||
template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra>
|
||||
class_ &def(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {
|
||||
class_ &def_cast(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {
|
||||
@pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"])
|
||||
struct IntStruct {
|
||||
explicit IntStruct(int v) : value(v){};
|
||||
~IntStruct() { value = -value; }
|
||||
IntStruct(const IntStruct &) = default;
|
||||
IntStruct &operator=(const IntStruct &) = default;
|
||||
py::class_<IntStruct>(m, "IntStruct").def(py::init([](const int i) { return IntStruct(i); }));
|
||||
py::implicitly_convertible<int, IntStruct>();
|
||||
m.def("test", [](int expected, const IntStruct &in) {
|
||||
[](int expected, const IntStruct &in) {
|
1
thirdparty/pybind11/.gitattributes
vendored
Normal file
1
thirdparty/pybind11/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
docs/*.svg binary
|
9
thirdparty/pybind11/.github/CODEOWNERS
vendored
Normal file
9
thirdparty/pybind11/.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
*.cmake @henryiii
|
||||
CMakeLists.txt @henryiii
|
||||
*.yml @henryiii
|
||||
*.yaml @henryiii
|
||||
/tools/ @henryiii
|
||||
/pybind11/ @henryiii
|
||||
noxfile.py @henryiii
|
||||
.clang-format @henryiii
|
||||
.clang-tidy @henryiii
|
388
thirdparty/pybind11/.github/CONTRIBUTING.md
vendored
Normal file
388
thirdparty/pybind11/.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,388 @@
|
||||
Thank you for your interest in this project! Please refer to the following
|
||||
sections on how to contribute code and bug reports.
|
||||
|
||||
### Reporting bugs
|
||||
|
||||
Before submitting a question or bug report, please take a moment of your time
|
||||
and ensure that your issue isn't already discussed in the project documentation
|
||||
provided at [pybind11.readthedocs.org][] or in the [issue tracker][]. You can
|
||||
also check [gitter][] to see if it came up before.
|
||||
|
||||
Assuming that you have identified a previously unknown problem or an important
|
||||
question, it's essential that you submit a self-contained and minimal piece of
|
||||
code that reproduces the problem. In other words: no external dependencies,
|
||||
isolate the function(s) that cause breakage, submit matched and complete C++
|
||||
and Python snippets that can be easily compiled and run in isolation; or
|
||||
ideally make a small PR with a failing test case that can be used as a starting
|
||||
point.
|
||||
|
||||
## Pull requests
|
||||
|
||||
Contributions are submitted, reviewed, and accepted using GitHub pull requests.
|
||||
Please refer to [this article][using pull requests] for details and adhere to
|
||||
the following rules to make the process as smooth as possible:
|
||||
|
||||
* Make a new branch for every feature you're working on.
|
||||
* Make small and clean pull requests that are easy to review but make sure they
|
||||
do add value by themselves.
|
||||
* Add tests for any new functionality and run the test suite (`cmake --build
|
||||
build --target pytest`) to ensure that no existing features break.
|
||||
* Please run [`pre-commit`][pre-commit] to check your code matches the
|
||||
project style. (Note that `gawk` is required.) Use `pre-commit run
|
||||
--all-files` before committing (or use installed-mode, check pre-commit docs)
|
||||
to verify your code passes before pushing to save time.
|
||||
* This project has a strong focus on providing general solutions using a
|
||||
minimal amount of code, thus small pull requests are greatly preferred.
|
||||
|
||||
### Licensing of contributions
|
||||
|
||||
pybind11 is provided under a BSD-style license that can be found in the
|
||||
``LICENSE`` file. By using, distributing, or contributing to this project, you
|
||||
agree to the terms and conditions of this license.
|
||||
|
||||
You are under no obligation whatsoever to provide any bug fixes, patches, or
|
||||
upgrades to the features, functionality or performance of the source code
|
||||
("Enhancements") to anyone; however, if you choose to make your Enhancements
|
||||
available either publicly, or directly to the author of this software, without
|
||||
imposing a separate written license agreement for such Enhancements, then you
|
||||
hereby grant the following license: a non-exclusive, royalty-free perpetual
|
||||
license to install, use, modify, prepare derivative works, incorporate into
|
||||
other computer software, distribute, and sublicense such enhancements or
|
||||
derivative works thereof, in binary and source code form.
|
||||
|
||||
|
||||
## Development of pybind11
|
||||
|
||||
### Quick setup
|
||||
|
||||
To setup a quick development environment, use [`nox`](https://nox.thea.codes).
|
||||
This will allow you to do some common tasks with minimal setup effort, but will
|
||||
take more time to run and be less flexible than a full development environment.
|
||||
If you use [`pipx run nox`](https://pipx.pypa.io), you don't even need to
|
||||
install `nox`. Examples:
|
||||
|
||||
```bash
|
||||
# List all available sessions
|
||||
nox -l
|
||||
|
||||
# Run linters
|
||||
nox -s lint
|
||||
|
||||
# Run tests on Python 3.9
|
||||
nox -s tests-3.9
|
||||
|
||||
# Build and preview docs
|
||||
nox -s docs -- serve
|
||||
|
||||
# Build SDists and wheels
|
||||
nox -s build
|
||||
```
|
||||
|
||||
### Full setup
|
||||
|
||||
To setup an ideal development environment, run the following commands on a
|
||||
system with CMake 3.14+:
|
||||
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r tests/requirements.txt
|
||||
cmake -S . -B build -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON
|
||||
cmake --build build -j4
|
||||
```
|
||||
|
||||
Tips:
|
||||
|
||||
* You can use `virtualenv` (faster, from PyPI) instead of `venv`.
|
||||
* You can select any name for your environment folder; if it contains "env" it
|
||||
will be ignored by git.
|
||||
* If you don't have CMake 3.14+, just add "cmake" to the pip install command.
|
||||
* You can use `-DPYBIND11_FINDPYTHON=ON` to use FindPython on CMake 3.12+
|
||||
* In classic mode, you may need to set `-DPYTHON_EXECUTABLE=/path/to/python`.
|
||||
FindPython uses `-DPython_ROOT_DIR=/path/to` or
|
||||
`-DPython_EXECUTABLE=/path/to/python`.
|
||||
|
||||
### Configuration options
|
||||
|
||||
In CMake, configuration options are given with "-D". Options are stored in the
|
||||
build directory, in the `CMakeCache.txt` file, so they are remembered for each
|
||||
build directory. Two selections are special - the generator, given with `-G`,
|
||||
and the compiler, which is selected based on environment variables `CXX` and
|
||||
similar, or `-DCMAKE_CXX_COMPILER=`. Unlike the others, these cannot be changed
|
||||
after the initial run.
|
||||
|
||||
The valid options are:
|
||||
|
||||
* `-DCMAKE_BUILD_TYPE`: Release, Debug, MinSizeRel, RelWithDebInfo
|
||||
* `-DPYBIND11_FINDPYTHON=ON`: Use CMake 3.12+'s FindPython instead of the
|
||||
classic, deprecated, custom FindPythonLibs
|
||||
* `-DPYBIND11_NOPYTHON=ON`: Disable all Python searching (disables tests)
|
||||
* `-DBUILD_TESTING=ON`: Enable the tests
|
||||
* `-DDOWNLOAD_CATCH=ON`: Download catch to build the C++ tests
|
||||
* `-DDOWNLOAD_EIGEN=ON`: Download Eigen for the NumPy tests
|
||||
* `-DPYBIND11_INSTALL=ON/OFF`: Enable the install target (on by default for the
|
||||
master project)
|
||||
* `-DUSE_PYTHON_INSTALL_DIR=ON`: Try to install into the python dir
|
||||
|
||||
|
||||
<details><summary>A few standard CMake tricks: (click to expand)</summary><p>
|
||||
|
||||
* Use `cmake --build build -v` to see the commands used to build the files.
|
||||
* Use `cmake build -LH` to list the CMake options with help.
|
||||
* Use `ccmake` if available to see a curses (terminal) gui, or `cmake-gui` for
|
||||
a completely graphical interface (not present in the PyPI package).
|
||||
* Use `cmake --build build -j12` to build with 12 cores (for example).
|
||||
* Use `-G` and the name of a generator to use something different. `cmake
|
||||
--help` lists the generators available.
|
||||
- On Unix, setting `CMAKE_GENERATER=Ninja` in your environment will give
|
||||
you automatic multithreading on all your CMake projects!
|
||||
* Open the `CMakeLists.txt` with QtCreator to generate for that IDE.
|
||||
* You can use `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to generate the `.json` file
|
||||
that some tools expect.
|
||||
|
||||
</p></details>
|
||||
|
||||
|
||||
To run the tests, you can "build" the check target:
|
||||
|
||||
```bash
|
||||
cmake --build build --target check
|
||||
```
|
||||
|
||||
`--target` can be spelled `-t` in CMake 3.15+. You can also run individual
|
||||
tests with these targets:
|
||||
|
||||
* `pytest`: Python tests only, using the
|
||||
[pytest](https://docs.pytest.org/en/stable/) framework
|
||||
* `cpptest`: C++ tests only
|
||||
* `test_cmake_build`: Install / subdirectory tests
|
||||
|
||||
If you want to build just a subset of tests, use
|
||||
`-DPYBIND11_TEST_OVERRIDE="test_callbacks;test_pickling"`. If this is
|
||||
empty, all tests will be built. Tests are specified without an extension if they need both a .py and
|
||||
.cpp file.
|
||||
|
||||
You may also pass flags to the `pytest` target by editing `tests/pytest.ini` or
|
||||
by using the `PYTEST_ADDOPTS` environment variable
|
||||
(see [`pytest` docs](https://docs.pytest.org/en/2.7.3/customize.html#adding-default-options)). As an example:
|
||||
|
||||
```bash
|
||||
env PYTEST_ADDOPTS="--capture=no --exitfirst" \
|
||||
cmake --build build --target pytest
|
||||
# Or using abbreviated flags
|
||||
env PYTEST_ADDOPTS="-s -x" cmake --build build --target pytest
|
||||
```
|
||||
|
||||
### Formatting
|
||||
|
||||
All formatting is handled by pre-commit.
|
||||
|
||||
Install with brew (macOS) or pip (any OS):
|
||||
|
||||
```bash
|
||||
# Any OS
|
||||
python3 -m pip install pre-commit
|
||||
|
||||
# OR macOS with homebrew:
|
||||
brew install pre-commit
|
||||
```
|
||||
|
||||
Then, you can run it on the items you've added to your staging area, or all
|
||||
files:
|
||||
|
||||
```bash
|
||||
pre-commit run
|
||||
# OR
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
And, if you want to always use it, you can install it as a git hook (hence the
|
||||
name, pre-commit):
|
||||
|
||||
```bash
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
### Clang-Format
|
||||
|
||||
As of v2.6.2, pybind11 ships with a [`clang-format`][clang-format]
|
||||
configuration file at the top level of the repo (the filename is
|
||||
`.clang-format`). Currently, formatting is NOT applied automatically, but
|
||||
manually using `clang-format` for newly developed files is highly encouraged.
|
||||
To check if a file needs formatting:
|
||||
|
||||
```bash
|
||||
clang-format -style=file --dry-run some.cpp
|
||||
```
|
||||
|
||||
The output will show things to be fixed, if any. To actually format the file:
|
||||
|
||||
```bash
|
||||
clang-format -style=file -i some.cpp
|
||||
```
|
||||
|
||||
Note that the `-style-file` option searches the parent directories for the
|
||||
`.clang-format` file, i.e. the commands above can be run in any subdirectory
|
||||
of the pybind11 repo.
|
||||
|
||||
### Clang-Tidy
|
||||
|
||||
[`clang-tidy`][clang-tidy] performs deeper static code analyses and is
|
||||
more complex to run, compared to `clang-format`, but support for `clang-tidy`
|
||||
is built into the pybind11 CMake configuration. To run `clang-tidy`, the
|
||||
following recipe should work. Run the `docker` command from the top-level
|
||||
directory inside your pybind11 git clone. Files will be modified in place,
|
||||
so you can use git to monitor the changes.
|
||||
|
||||
```bash
|
||||
docker run --rm -v $PWD:/mounted_pybind11 -it silkeh/clang:15-bullseye
|
||||
apt-get update && apt-get install -y git python3-dev python3-pytest
|
||||
cmake -S /mounted_pybind11/ -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--use-color" -DDOWNLOAD_EIGEN=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_STANDARD=17
|
||||
cmake --build build -j 2
|
||||
```
|
||||
|
||||
You can add `--fix` to the options list if you want.
|
||||
|
||||
### Include what you use
|
||||
|
||||
To run include what you use, install (`brew install include-what-you-use` on
|
||||
macOS), then run:
|
||||
|
||||
```bash
|
||||
cmake -S . -B build-iwyu -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=$(which include-what-you-use)
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
The report is sent to stderr; you can pipe it into a file if you wish.
|
||||
|
||||
### Build recipes
|
||||
|
||||
This builds with the Intel compiler (assuming it is in your path, along with a
|
||||
recent CMake and Python):
|
||||
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
. venv/bin/activate
|
||||
pip install pytest
|
||||
cmake -S . -B build-intel -DCMAKE_CXX_COMPILER=$(which icpc) -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON -DPYBIND11_WERROR=ON
|
||||
```
|
||||
|
||||
This will test the PGI compilers:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v $PWD:/pybind11 nvcr.io/hpc/pgi-compilers:ce
|
||||
apt-get update && apt-get install -y python3-dev python3-pip python3-pytest
|
||||
wget -qO- "https://cmake.org/files/v3.18/cmake-3.18.2-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local
|
||||
cmake -S pybind11/ -B build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
### Explanation of the SDist/wheel building design
|
||||
|
||||
> These details below are _only_ for packaging the Python sources from git. The
|
||||
> SDists and wheels created do not have any extra requirements at all and are
|
||||
> completely normal.
|
||||
|
||||
The main objective of the packaging system is to create SDists (Python's source
|
||||
distribution packages) and wheels (Python's binary distribution packages) that
|
||||
include everything that is needed to work with pybind11, and which can be
|
||||
installed without any additional dependencies. This is more complex than it
|
||||
appears: in order to support CMake as a first class language even when using
|
||||
the PyPI package, they must include the _generated_ CMake files (so as not to
|
||||
require CMake when installing the `pybind11` package itself). They should also
|
||||
provide the option to install to the "standard" location
|
||||
(`<ENVROOT>/include/pybind11` and `<ENVROOT>/share/cmake/pybind11`) so they are
|
||||
easy to find with CMake, but this can cause problems if you are not an
|
||||
environment or using ``pyproject.toml`` requirements. This was solved by having
|
||||
two packages; the "nice" pybind11 package that stores the includes and CMake
|
||||
files inside the package, that you get access to via functions in the package,
|
||||
and a `pybind11-global` package that can be included via `pybind11[global]` if
|
||||
you want the more invasive but discoverable file locations.
|
||||
|
||||
If you want to install or package the GitHub source, it is best to have Pip 10
|
||||
or newer on Windows, macOS, or Linux (manylinux1 compatible, includes most
|
||||
distributions). You can then build the SDists, or run any procedure that makes
|
||||
SDists internally, like making wheels or installing.
|
||||
|
||||
|
||||
```bash
|
||||
# Editable development install example
|
||||
python3 -m pip install -e .
|
||||
```
|
||||
|
||||
Since Pip itself does not have an `sdist` command (it does have `wheel` and
|
||||
`install`), you may want to use the upcoming `build` package:
|
||||
|
||||
```bash
|
||||
python3 -m pip install build
|
||||
|
||||
# Normal package
|
||||
python3 -m build -s .
|
||||
|
||||
# Global extra
|
||||
PYBIND11_GLOBAL_SDIST=1 python3 -m build -s .
|
||||
```
|
||||
|
||||
If you want to use the classic "direct" usage of `python setup.py`, you will
|
||||
need CMake 3.15+ and either `make` or `ninja` preinstalled (possibly via `pip
|
||||
install cmake ninja`), since directly running Python on `setup.py` cannot pick
|
||||
up and install `pyproject.toml` requirements. As long as you have those two
|
||||
things, though, everything works the way you would expect:
|
||||
|
||||
```bash
|
||||
# Normal package
|
||||
python3 setup.py sdist
|
||||
|
||||
# Global extra
|
||||
PYBIND11_GLOBAL_SDIST=1 python3 setup.py sdist
|
||||
```
|
||||
|
||||
A detailed explanation of the build procedure design for developers wanting to
|
||||
work on or maintain the packaging system is as follows:
|
||||
|
||||
#### 1. Building from the source directory
|
||||
|
||||
When you invoke any `setup.py` command from the source directory, including
|
||||
`pip wheel .` and `pip install .`, you will activate a full source build. This
|
||||
is made of the following steps:
|
||||
|
||||
1. If the tool is PEP 518 compliant, like Pip 10+, it will create a temporary
|
||||
virtual environment and install the build requirements (mostly CMake) into
|
||||
it. (if you are not on Windows, macOS, or a manylinux compliant system, you
|
||||
can disable this with `--no-build-isolation` as long as you have CMake 3.15+
|
||||
installed)
|
||||
2. The environment variable `PYBIND11_GLOBAL_SDIST` is checked - if it is set
|
||||
and truthy, this will be make the accessory `pybind11-global` package,
|
||||
instead of the normal `pybind11` package. This package is used for
|
||||
installing the files directly to your environment root directory, using
|
||||
`pybind11[global]`.
|
||||
2. `setup.py` reads the version from `pybind11/_version.py` and verifies it
|
||||
matches `includes/pybind11/detail/common.h`.
|
||||
3. CMake is run with `-DCMAKE_INSTALL_PREIFX=pybind11`. Since the CMake install
|
||||
procedure uses only relative paths and is identical on all platforms, these
|
||||
files are valid as long as they stay in the correct relative position to the
|
||||
includes. `pybind11/share/cmake/pybind11` has the CMake files, and
|
||||
`pybind11/include` has the includes. The build directory is discarded.
|
||||
4. Simpler files are placed in the SDist: `tools/setup_*.py.in`,
|
||||
`tools/pyproject.toml` (`main` or `global`)
|
||||
5. The package is created by running the setup function in the
|
||||
`tools/setup_*.py`. `setup_main.py` fills in Python packages, and
|
||||
`setup_global.py` fills in only the data/header slots.
|
||||
6. A context manager cleans up the temporary CMake install directory (even if
|
||||
an error is thrown).
|
||||
|
||||
### 2. Building from SDist
|
||||
|
||||
Since the SDist has the rendered template files in `tools` along with the
|
||||
includes and CMake files in the correct locations, the builds are completely
|
||||
trivial and simple. No extra requirements are required. You can even use Pip 9
|
||||
if you really want to.
|
||||
|
||||
|
||||
[pre-commit]: https://pre-commit.com
|
||||
[clang-format]: https://clang.llvm.org/docs/ClangFormat.html
|
||||
[clang-tidy]: https://clang.llvm.org/extra/clang-tidy/
|
||||
[pybind11.readthedocs.org]: http://pybind11.readthedocs.org/en/latest
|
||||
[issue tracker]: https://github.com/pybind/pybind11/issues
|
||||
[gitter]: https://gitter.im/pybind/Lobby
|
||||
[using pull requests]: https://help.github.com/articles/using-pull-requests
|
61
thirdparty/pybind11/.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
61
thirdparty/pybind11/.github/ISSUE_TEMPLATE/bug-report.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
name: Bug Report
|
||||
description: File an issue about a bug
|
||||
title: "[BUG]: "
|
||||
labels: [triage]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please do your best to make the issue as easy to act on as possible, and only submit here if there is clearly a problem with pybind11 (ask first if unsure). **Note that a reproducer in a PR is much more likely to get immediate attention.**
|
||||
|
||||
- type: checkboxes
|
||||
id: steps
|
||||
attributes:
|
||||
label: Required prerequisites
|
||||
description: Make sure you've completed the following steps before submitting your issue -- thank you!
|
||||
options:
|
||||
- label: Make sure you've read the [documentation](https://pybind11.readthedocs.io). Your issue may be addressed there.
|
||||
required: true
|
||||
- label: Search the [issue tracker](https://github.com/pybind/pybind11/issues) and [Discussions](https:/pybind/pybind11/discussions) to verify that this hasn't already been reported. +1 or comment there if it has.
|
||||
required: true
|
||||
- label: Consider asking first in the [Gitter chat room](https://gitter.im/pybind/Lobby) or in a [Discussion](https:/pybind/pybind11/discussions/new).
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: What version (or hash if on master) of pybind11 are you using?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Problem description
|
||||
placeholder: >-
|
||||
Provide a short description, state the expected behavior and what
|
||||
actually happens. Include relevant information like what version of
|
||||
pybind11 you are using, what system you are on, and any useful commands
|
||||
/ output.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: code
|
||||
attributes:
|
||||
label: Reproducible example code
|
||||
placeholder: >-
|
||||
The code should be minimal, have no external dependencies, isolate the
|
||||
function(s) that cause breakage. Submit matched and complete C++ and
|
||||
Python snippets that can be easily compiled and run to diagnose the
|
||||
issue. — Note that a reproducer in a PR is much more likely to get
|
||||
immediate attention: failing tests in the pybind11 CI are the best
|
||||
starting point for working out fixes.
|
||||
render: text
|
||||
|
||||
- type: input
|
||||
id: regression
|
||||
attributes:
|
||||
label: Is this a regression? Put the last known working version here if it is.
|
||||
description: Put the last known working version here if this is a regression.
|
||||
value: Not a regression
|
8
thirdparty/pybind11/.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
thirdparty/pybind11/.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Ask a question
|
||||
url: https://github.com/pybind/pybind11/discussions/new
|
||||
about: Please ask and answer questions here, or propose new ideas.
|
||||
- name: Gitter room
|
||||
url: https://gitter.im/pybind/Lobby
|
||||
about: A room for discussing pybind11 with an active community
|
7
thirdparty/pybind11/.github/dependabot.yml
vendored
Normal file
7
thirdparty/pybind11/.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Maintain dependencies for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
8
thirdparty/pybind11/.github/labeler.yml
vendored
Normal file
8
thirdparty/pybind11/.github/labeler.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
docs:
|
||||
- any:
|
||||
- 'docs/**/*.rst'
|
||||
- '!docs/changelog.rst'
|
||||
- '!docs/upgrade.rst'
|
||||
|
||||
ci:
|
||||
- '.github/workflows/*.yml'
|
3
thirdparty/pybind11/.github/labeler_merged.yml
vendored
Normal file
3
thirdparty/pybind11/.github/labeler_merged.yml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
needs changelog:
|
||||
- all:
|
||||
- '!docs/changelog.rst'
|
32
thirdparty/pybind11/.github/matchers/pylint.json
vendored
Normal file
32
thirdparty/pybind11/.github/matchers/pylint.json
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"severity": "warning",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^:]+):(\\d+):(\\d+): ([A-DF-Z]\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"code": 4,
|
||||
"message": 5
|
||||
}
|
||||
],
|
||||
"owner": "pylint-warning"
|
||||
},
|
||||
{
|
||||
"severity": "error",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^:]+):(\\d+):(\\d+): (E\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"code": 4,
|
||||
"message": 5
|
||||
}
|
||||
],
|
||||
"owner": "pylint-error"
|
||||
}
|
||||
]
|
||||
}
|
19
thirdparty/pybind11/.github/pull_request_template.md
vendored
Normal file
19
thirdparty/pybind11/.github/pull_request_template.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<!--
|
||||
Title (above): please place [branch_name] at the beginning if you are targeting a branch other than master. *Do not target stable*.
|
||||
It is recommended to use conventional commit format, see conventionalcommits.org, but not required.
|
||||
-->
|
||||
## Description
|
||||
|
||||
<!-- Include relevant issues or PRs here, describe what changed and why -->
|
||||
|
||||
|
||||
## Suggested changelog entry:
|
||||
|
||||
<!-- Fill in the below block with the expected RestructuredText entry. Delete if no entry needed;
|
||||
but do not delete header or rst block if an entry is needed! Will be collected via a script. -->
|
||||
|
||||
```rst
|
||||
|
||||
```
|
||||
|
||||
<!-- If the upgrade guide needs updating, note that here too -->
|
1185
thirdparty/pybind11/.github/workflows/ci.yml
vendored
Normal file
1185
thirdparty/pybind11/.github/workflows/ci.yml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
92
thirdparty/pybind11/.github/workflows/configure.yml
vendored
Normal file
92
thirdparty/pybind11/.github/workflows/configure.yml
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
name: Config
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable
|
||||
- v*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
PIP_BREAK_SYSTEM_PACKAGES: 1
|
||||
# For cmake:
|
||||
VERBOSE: 1
|
||||
|
||||
jobs:
|
||||
# This tests various versions of CMake in various combinations, to make sure
|
||||
# the configure step passes.
|
||||
cmake:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runs-on: [ubuntu-20.04, macos-latest, windows-latest]
|
||||
arch: [x64]
|
||||
cmake: ["3.26"]
|
||||
|
||||
include:
|
||||
- runs-on: ubuntu-20.04
|
||||
arch: x64
|
||||
cmake: "3.5"
|
||||
|
||||
- runs-on: ubuntu-20.04
|
||||
arch: x64
|
||||
cmake: "3.27"
|
||||
|
||||
- runs-on: macos-latest
|
||||
arch: x64
|
||||
cmake: "3.7"
|
||||
|
||||
- runs-on: windows-2019
|
||||
arch: x64 # x86 compilers seem to be missing on 2019 image
|
||||
cmake: "3.18"
|
||||
|
||||
name: 🐍 3.7 • CMake ${{ matrix.cmake }} • ${{ matrix.runs-on }}
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python 3.7
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.7
|
||||
architecture: ${{ matrix.arch }}
|
||||
|
||||
- name: Prepare env
|
||||
run: python -m pip install -r tests/requirements.txt
|
||||
|
||||
# An action for adding a specific version of CMake:
|
||||
# https://github.com/jwlawson/actions-setup-cmake
|
||||
- name: Setup CMake ${{ matrix.cmake }}
|
||||
uses: jwlawson/actions-setup-cmake@v1.14
|
||||
with:
|
||||
cmake-version: ${{ matrix.cmake }}
|
||||
|
||||
# These steps use a directory with a space in it intentionally
|
||||
- name: Make build directories
|
||||
run: mkdir "build dir"
|
||||
|
||||
- name: Configure
|
||||
working-directory: build dir
|
||||
shell: bash
|
||||
run: >
|
||||
cmake ..
|
||||
-DPYBIND11_WERROR=ON
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DPYTHON_EXECUTABLE=$(python -c "import sys; print(sys.executable)")
|
||||
|
||||
# Only build and test if this was manually triggered in the GitHub UI
|
||||
- name: Build
|
||||
working-directory: build dir
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: cmake --build . --config Release
|
||||
|
||||
- name: Test
|
||||
working-directory: build dir
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
run: cmake --build . --config Release --target check
|
60
thirdparty/pybind11/.github/workflows/format.yml
vendored
Normal file
60
thirdparty/pybind11/.github/workflows/format.yml
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
# This is a format job. Pre-commit has a first-party GitHub action, so we use
|
||||
# that: https://github.com/pre-commit/action
|
||||
|
||||
name: Format
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable
|
||||
- "v*"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 3
|
||||
# For cmake:
|
||||
VERBOSE: 1
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
name: Format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Add matchers
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/matchers/pylint.json"
|
||||
- uses: pre-commit/action@v3.0.0
|
||||
with:
|
||||
# Slow hooks are marked with manual - slow is okay here, run them too
|
||||
extra_args: --hook-stage manual --all-files
|
||||
|
||||
clang-tidy:
|
||||
# When making changes here, please also review the "Clang-Tidy" section
|
||||
# in .github/CONTRIBUTING.md and update as needed.
|
||||
name: Clang-Tidy
|
||||
runs-on: ubuntu-latest
|
||||
container: silkeh/clang:15-bullseye
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install requirements
|
||||
run: apt-get update && apt-get install -y git python3-dev python3-pytest
|
||||
|
||||
- name: Configure
|
||||
run: >
|
||||
cmake -S . -B build
|
||||
-DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--use-color;--warnings-as-errors=*"
|
||||
-DDOWNLOAD_EIGEN=ON
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DCMAKE_CXX_STANDARD=17
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build -j 2 -- --keep-going
|
25
thirdparty/pybind11/.github/workflows/labeler.yml
vendored
Normal file
25
thirdparty/pybind11/.github/workflows/labeler.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
name: Labeler
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [closed]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
label:
|
||||
name: Labeler
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
|
||||
- uses: actions/labeler@main
|
||||
if: >
|
||||
github.event.pull_request.merged == true &&
|
||||
!startsWith(github.event.pull_request.title, 'chore(deps):') &&
|
||||
!startsWith(github.event.pull_request.title, 'ci(fix):') &&
|
||||
!startsWith(github.event.pull_request.title, 'docs(changelog):')
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
configuration-path: .github/labeler_merged.yml
|
114
thirdparty/pybind11/.github/workflows/pip.yml
vendored
Normal file
114
thirdparty/pybind11/.github/workflows/pip.yml
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
name: Pip
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- stable
|
||||
- v*
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
PIP_BREAK_SYSTEM_PACKAGES: 1
|
||||
PIP_ONLY_BINARY: numpy
|
||||
|
||||
jobs:
|
||||
# This builds the sdists and wheels and makes sure the files are exactly as
|
||||
# expected. Using Windows and Python 3.6, since that is often the most
|
||||
# challenging matrix element.
|
||||
test-packaging:
|
||||
name: 🐍 3.6 • 📦 tests • windows-latest
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup 🐍 3.6
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.6
|
||||
|
||||
- name: Prepare env
|
||||
run: |
|
||||
python -m pip install -r tests/requirements.txt
|
||||
|
||||
- name: Python Packaging tests
|
||||
run: pytest tests/extra_python_package/
|
||||
|
||||
|
||||
# This runs the packaging tests and also builds and saves the packages as
|
||||
# artifacts.
|
||||
packaging:
|
||||
name: 🐍 3.8 • 📦 & 📦 tests • ubuntu-latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup 🐍 3.8
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.8
|
||||
|
||||
- name: Prepare env
|
||||
run: |
|
||||
python -m pip install -r tests/requirements.txt build twine
|
||||
|
||||
- name: Python Packaging tests
|
||||
run: pytest tests/extra_python_package/
|
||||
|
||||
- name: Build SDist and wheels
|
||||
run: |
|
||||
python -m build
|
||||
PYBIND11_GLOBAL_SDIST=1 python -m build
|
||||
|
||||
- name: Check metadata
|
||||
run: twine check dist/*
|
||||
|
||||
- name: Save standard package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: standard
|
||||
path: dist/pybind11-*
|
||||
|
||||
- name: Save global package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: global
|
||||
path: dist/pybind11_global-*
|
||||
|
||||
|
||||
|
||||
# When a GitHub release is made, upload the artifacts to PyPI
|
||||
upload:
|
||||
name: Upload to PyPI
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
needs: [packaging]
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
# Downloads all to directories matching the artifact names
|
||||
- uses: actions/download-artifact@v4
|
||||
|
||||
- name: Publish standard package
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.pypi_password }}
|
||||
packages-dir: standard/
|
||||
|
||||
- name: Publish global package
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.pypi_password_global }}
|
||||
packages-dir: global/
|
116
thirdparty/pybind11/.github/workflows/upstream.yml
vendored
Normal file
116
thirdparty/pybind11/.github/workflows/upstream.yml
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
name: Upstream
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: upstream-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
PIP_BREAK_SYSTEM_PACKAGES: 1
|
||||
# For cmake:
|
||||
VERBOSE: 1
|
||||
|
||||
jobs:
|
||||
standard:
|
||||
name: "🐍 3.13 latest • ubuntu-latest • x64"
|
||||
runs-on: ubuntu-latest
|
||||
# Only runs when the 'python dev' label is selected
|
||||
if: "contains(github.event.pull_request.labels.*.name, 'python dev')"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python 3.13
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.13"
|
||||
allow-prereleases: true
|
||||
|
||||
- name: Setup Boost
|
||||
run: sudo apt-get install libboost-dev
|
||||
|
||||
- name: Update CMake
|
||||
uses: jwlawson/actions-setup-cmake@v1.14
|
||||
|
||||
- name: Run pip installs
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -r tests/requirements.txt
|
||||
|
||||
- name: Show platform info
|
||||
run: |
|
||||
python -m platform
|
||||
cmake --version
|
||||
pip list
|
||||
|
||||
# First build - C++11 mode and inplace
|
||||
- name: Configure C++11
|
||||
run: >
|
||||
cmake -S . -B build11
|
||||
-DPYBIND11_WERROR=ON
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DDOWNLOAD_EIGEN=ON
|
||||
-DCMAKE_CXX_STANDARD=11
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
- name: Build C++11
|
||||
run: cmake --build build11 -j 2
|
||||
|
||||
- name: Python tests C++11
|
||||
run: cmake --build build11 --target pytest -j 2
|
||||
|
||||
- name: C++11 tests
|
||||
run: cmake --build build11 --target cpptest -j 2
|
||||
|
||||
- name: Interface test C++11
|
||||
run: cmake --build build11 --target test_cmake_build
|
||||
|
||||
# Second build - C++17 mode and in a build directory
|
||||
- name: Configure C++17
|
||||
run: >
|
||||
cmake -S . -B build17
|
||||
-DPYBIND11_WERROR=ON
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DDOWNLOAD_EIGEN=ON
|
||||
-DCMAKE_CXX_STANDARD=17
|
||||
|
||||
- name: Build C++17
|
||||
run: cmake --build build17 -j 2
|
||||
|
||||
- name: Python tests C++17
|
||||
run: cmake --build build17 --target pytest
|
||||
|
||||
- name: C++17 tests
|
||||
run: cmake --build build17 --target cpptest
|
||||
|
||||
# Third build - C++17 mode with unstable ABI
|
||||
- name: Configure (unstable ABI)
|
||||
run: >
|
||||
cmake -S . -B build17max
|
||||
-DPYBIND11_WERROR=ON
|
||||
-DDOWNLOAD_CATCH=ON
|
||||
-DDOWNLOAD_EIGEN=ON
|
||||
-DCMAKE_CXX_STANDARD=17
|
||||
-DPYBIND11_INTERNALS_VERSION=10000000
|
||||
|
||||
- name: Build (unstable ABI)
|
||||
run: cmake --build build17max -j 2
|
||||
|
||||
- name: Python tests (unstable ABI)
|
||||
run: cmake --build build17max --target pytest
|
||||
|
||||
- name: Interface test (unstable ABI)
|
||||
run: cmake --build build17max --target test_cmake_build
|
||||
|
||||
# This makes sure the setup_helpers module can build packages using
|
||||
# setuptools
|
||||
- name: Setuptools helpers test
|
||||
run: |
|
||||
pip install setuptools
|
||||
pytest tests/extra_setuptools
|
46
thirdparty/pybind11/.gitignore
vendored
Normal file
46
thirdparty/pybind11/.gitignore
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
cmake_uninstall.cmake
|
||||
.DS_Store
|
||||
*.so
|
||||
*.pyd
|
||||
*.dll
|
||||
*.sln
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.vcxproj
|
||||
*.vcxproj.user
|
||||
*.filters
|
||||
example.dir
|
||||
Win32
|
||||
x64
|
||||
Release
|
||||
Debug
|
||||
.vs
|
||||
CTestTestfile.cmake
|
||||
Testing
|
||||
autogen
|
||||
MANIFEST
|
||||
/.ninja_*
|
||||
/*.ninja
|
||||
/docs/.build
|
||||
*.py[co]
|
||||
*.egg-info
|
||||
*~
|
||||
.*.swp
|
||||
.DS_Store
|
||||
/dist
|
||||
/*build*
|
||||
.cache/
|
||||
sosize-*.txt
|
||||
pybind11Config*.cmake
|
||||
pybind11Targets.cmake
|
||||
/*env*
|
||||
/.vscode
|
||||
/pybind11/include/*
|
||||
/pybind11/share/*
|
||||
/docs/_build/*
|
||||
.ipynb_checkpoints/
|
||||
tests/main.cpp
|
148
thirdparty/pybind11/.pre-commit-config.yaml
vendored
Normal file
148
thirdparty/pybind11/.pre-commit-config.yaml
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
# To use:
|
||||
#
|
||||
# pre-commit run -a
|
||||
#
|
||||
# Or:
|
||||
#
|
||||
# pre-commit install # (runs every time you commit in git)
|
||||
#
|
||||
# To update this file:
|
||||
#
|
||||
# pre-commit autoupdate
|
||||
#
|
||||
# See https://github.com/pre-commit/pre-commit
|
||||
|
||||
|
||||
ci:
|
||||
autoupdate_commit_msg: "chore(deps): update pre-commit hooks"
|
||||
autofix_commit_msg: "style: pre-commit fixes"
|
||||
autoupdate_schedule: monthly
|
||||
|
||||
# third-party content
|
||||
exclude: ^tools/JoinPaths.cmake$
|
||||
|
||||
repos:
|
||||
|
||||
# Clang format the codebase automatically
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: "v17.0.6"
|
||||
hooks:
|
||||
- id: clang-format
|
||||
types_or: [c++, c, cuda]
|
||||
|
||||
# Ruff, the Python auto-correcting linter/formatter written in Rust
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.1.6
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: ["--fix", "--show-fixes"]
|
||||
- id: ruff-format
|
||||
|
||||
# Check static types with mypy
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: "v1.7.1"
|
||||
hooks:
|
||||
- id: mypy
|
||||
args: []
|
||||
exclude: ^(tests|docs)/
|
||||
additional_dependencies:
|
||||
- markdown-it-py<3 # Drop this together with dropping Python 3.7 support.
|
||||
- nox
|
||||
- rich
|
||||
- types-setuptools
|
||||
|
||||
# CMake formatting
|
||||
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
||||
rev: "v0.6.13"
|
||||
hooks:
|
||||
- id: cmake-format
|
||||
additional_dependencies: [pyyaml]
|
||||
types: [file]
|
||||
files: (\.cmake|CMakeLists.txt)(.in)?$
|
||||
|
||||
# Standard hooks
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: "v4.5.0"
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
- id: check-docstring-first
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
- id: debug-statements
|
||||
- id: end-of-file-fixer
|
||||
- id: mixed-line-ending
|
||||
- id: requirements-txt-fixer
|
||||
- id: trailing-whitespace
|
||||
|
||||
# Also code format the docs
|
||||
- repo: https://github.com/asottile/blacken-docs
|
||||
rev: "1.16.0"
|
||||
hooks:
|
||||
- id: blacken-docs
|
||||
additional_dependencies:
|
||||
- black==23.*
|
||||
|
||||
# Changes tabs to spaces
|
||||
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
||||
rev: "v1.5.4"
|
||||
hooks:
|
||||
- id: remove-tabs
|
||||
|
||||
# Avoid directional quotes
|
||||
- repo: https://github.com/sirosen/texthooks
|
||||
rev: "0.6.3"
|
||||
hooks:
|
||||
- id: fix-ligatures
|
||||
- id: fix-smartquotes
|
||||
|
||||
# Checking for common mistakes
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: "v1.10.0"
|
||||
hooks:
|
||||
- id: rst-backticks
|
||||
- id: rst-directive-colons
|
||||
- id: rst-inline-touching-normal
|
||||
|
||||
# Checks the manifest for missing files (native support)
|
||||
- repo: https://github.com/mgedmin/check-manifest
|
||||
rev: "0.49"
|
||||
hooks:
|
||||
- id: check-manifest
|
||||
# This is a slow hook, so only run this if --hook-stage manual is passed
|
||||
stages: [manual]
|
||||
additional_dependencies: [cmake, ninja]
|
||||
|
||||
# Check for spelling
|
||||
# Use tools/codespell_ignore_lines_from_errors.py
|
||||
# to rebuild .codespell-ignore-lines
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: "v2.2.6"
|
||||
hooks:
|
||||
- id: codespell
|
||||
exclude: ".supp$"
|
||||
args: ["-x.codespell-ignore-lines", "-Lccompiler"]
|
||||
|
||||
# Check for common shell mistakes
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: "v0.9.0.6"
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
|
||||
# Disallow some common capitalization mistakes
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: disallow-caps
|
||||
name: Disallow improper capitalization
|
||||
language: pygrep
|
||||
entry: PyBind|\bNumpy\b|Cmake|CCache|PyTest
|
||||
exclude: ^\.pre-commit-config.yaml$
|
||||
|
||||
# PyLint has native support - not always usable, but works for us
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: "v3.0.1"
|
||||
hooks:
|
||||
- id: pylint
|
||||
files: ^pybind11
|
20
thirdparty/pybind11/.readthedocs.yml
vendored
Normal file
20
thirdparty/pybind11/.readthedocs.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
# https://blog.readthedocs.com/migrate-configuration-v2/
|
||||
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
apt_packages:
|
||||
- librsvg2-bin
|
||||
tools:
|
||||
python: "3.11"
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
formats:
|
||||
- pdf
|
363
thirdparty/pybind11/CMakeLists.txt
vendored
Normal file
363
thirdparty/pybind11/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,363 @@
|
||||
# CMakeLists.txt -- Build system for the pybind11 modules
|
||||
#
|
||||
# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
|
||||
#
|
||||
# All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
# Propagate this policy (FindPythonInterp removal) so it can be detected later
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.27")
|
||||
cmake_policy(GET CMP0148 _pybind11_cmp0148)
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# The `cmake_minimum_required(VERSION 3.5...3.27)` syntax does not work with
|
||||
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
|
||||
# the behavior using the following workaround:
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.27)
|
||||
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||
else()
|
||||
cmake_policy(VERSION 3.27)
|
||||
endif()
|
||||
|
||||
if(_pybind11_cmp0148)
|
||||
cmake_policy(SET CMP0148 ${_pybind11_cmp0148})
|
||||
unset(_pybind11_cmp0148)
|
||||
endif()
|
||||
|
||||
# Avoid infinite recursion if tests include this as a subdirectory
|
||||
if(DEFINED PYBIND11_MASTER_PROJECT)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Extract project version from source
|
||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
|
||||
pybind11_version_defines REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ")
|
||||
|
||||
foreach(ver ${pybind11_version_defines})
|
||||
if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])
|
||||
set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(PYBIND11_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
|
||||
set(pybind11_VERSION_TYPE "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
string(REGEX MATCH "^[0-9]+" PYBIND11_VERSION_PATCH "${PYBIND11_VERSION_PATCH}")
|
||||
|
||||
project(
|
||||
pybind11
|
||||
LANGUAGES CXX
|
||||
VERSION "${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}")
|
||||
|
||||
# Standard includes
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
if(NOT pybind11_FIND_QUIETLY)
|
||||
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
|
||||
endif()
|
||||
|
||||
# Check if pybind11 is being used directly or via add_subdirectory
|
||||
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
### Warn if not an out-of-source builds
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
set(lines
|
||||
"You are building in-place. If that is not what you intended to "
|
||||
"do, you can clean the source directory with:\n"
|
||||
"rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake "
|
||||
"pybind11ConfigVersion.cmake tests/CMakeFiles/\n")
|
||||
message(AUTHOR_WARNING ${lines})
|
||||
endif()
|
||||
|
||||
set(PYBIND11_MASTER_PROJECT ON)
|
||||
|
||||
if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
|
||||
# Bug in macOS CMake < 3.7 is unable to download catch
|
||||
message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
|
||||
elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
|
||||
# Only tested with 3.8+ in CI.
|
||||
message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake ${CMAKE_VERSION}")
|
||||
|
||||
if(CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
|
||||
set(pybind11_system "")
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
if(CMAKE_VERSION VERSION_LESS "3.18")
|
||||
set(_pybind11_findpython_default OFF)
|
||||
else()
|
||||
set(_pybind11_findpython_default ON)
|
||||
endif()
|
||||
else()
|
||||
set(PYBIND11_MASTER_PROJECT OFF)
|
||||
set(pybind11_system SYSTEM)
|
||||
set(_pybind11_findpython_default OFF)
|
||||
endif()
|
||||
|
||||
# Options
|
||||
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
|
||||
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
|
||||
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
|
||||
option(PYBIND11_SIMPLE_GIL_MANAGEMENT
|
||||
"Use simpler GIL management logic that does not support disassociation" OFF)
|
||||
set(PYBIND11_INTERNALS_VERSION
|
||||
""
|
||||
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
|
||||
|
||||
if(PYBIND11_SIMPLE_GIL_MANAGEMENT)
|
||||
add_compile_definitions(PYBIND11_SIMPLE_GIL_MANAGEMENT)
|
||||
endif()
|
||||
|
||||
cmake_dependent_option(
|
||||
USE_PYTHON_INCLUDE_DIR
|
||||
"Install pybind11 headers in Python include directory instead of default installation prefix"
|
||||
OFF "PYBIND11_INSTALL" OFF)
|
||||
|
||||
cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" ${_pybind11_findpython_default}
|
||||
"NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
|
||||
|
||||
# Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
|
||||
# (makes transition easier while we support both modes).
|
||||
if(PYBIND11_MASTER_PROJECT
|
||||
AND PYBIND11_FINDPYTHON
|
||||
AND DEFINED PYTHON_EXECUTABLE
|
||||
AND NOT DEFINED Python_EXECUTABLE)
|
||||
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
# NB: when adding a header don't forget to also add it to setup.py
|
||||
set(PYBIND11_HEADERS
|
||||
include/pybind11/detail/class.h
|
||||
include/pybind11/detail/common.h
|
||||
include/pybind11/detail/descr.h
|
||||
include/pybind11/detail/init.h
|
||||
include/pybind11/detail/internals.h
|
||||
include/pybind11/detail/type_caster_base.h
|
||||
include/pybind11/detail/typeid.h
|
||||
include/pybind11/attr.h
|
||||
include/pybind11/buffer_info.h
|
||||
include/pybind11/cast.h
|
||||
include/pybind11/chrono.h
|
||||
include/pybind11/common.h
|
||||
include/pybind11/complex.h
|
||||
include/pybind11/options.h
|
||||
include/pybind11/eigen.h
|
||||
include/pybind11/eigen/common.h
|
||||
include/pybind11/eigen/matrix.h
|
||||
include/pybind11/eigen/tensor.h
|
||||
include/pybind11/embed.h
|
||||
include/pybind11/eval.h
|
||||
include/pybind11/gil.h
|
||||
include/pybind11/gil_safe_call_once.h
|
||||
include/pybind11/iostream.h
|
||||
include/pybind11/functional.h
|
||||
include/pybind11/numpy.h
|
||||
include/pybind11/operators.h
|
||||
include/pybind11/pybind11.h
|
||||
include/pybind11/pytypes.h
|
||||
include/pybind11/stl.h
|
||||
include/pybind11/stl_bind.h
|
||||
include/pybind11/stl/filesystem.h
|
||||
include/pybind11/type_caster_pyobject_ptr.h
|
||||
include/pybind11/typing.h)
|
||||
|
||||
# Compare with grep and warn if mismatched
|
||||
if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
|
||||
file(
|
||||
GLOB_RECURSE _pybind11_header_check
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
CONFIGURE_DEPENDS "include/pybind11/*.h")
|
||||
set(_pybind11_here_only ${PYBIND11_HEADERS})
|
||||
set(_pybind11_disk_only ${_pybind11_header_check})
|
||||
list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})
|
||||
list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})
|
||||
if(_pybind11_here_only)
|
||||
message(AUTHOR_WARNING "PYBIND11_HEADERS has extra files:" ${_pybind11_here_only})
|
||||
endif()
|
||||
if(_pybind11_disk_only)
|
||||
message(AUTHOR_WARNING "PYBIND11_HEADERS is missing files:" ${_pybind11_disk_only})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# CMake 3.12 added list(TRANSFORM <list> PREPEND
|
||||
# But we can't use it yet
|
||||
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
|
||||
"${PYBIND11_HEADERS}")
|
||||
|
||||
# Cache variable so this can be used in parent projects
|
||||
set(pybind11_INCLUDE_DIR
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include"
|
||||
CACHE INTERNAL "Directory where pybind11 headers are located")
|
||||
|
||||
# Backward compatible variable for add_subdirectory mode
|
||||
if(NOT PYBIND11_MASTER_PROJECT)
|
||||
set(PYBIND11_INCLUDE_DIR
|
||||
"${pybind11_INCLUDE_DIR}"
|
||||
CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
# Note: when creating targets, you cannot use if statements at configure time -
|
||||
# you need generator expressions, because those will be placed in the target file.
|
||||
# You can also place ifs *in* the Config.in, but not here.
|
||||
|
||||
# This section builds targets, but does *not* touch Python
|
||||
# Non-IMPORT targets cannot be defined twice
|
||||
if(NOT TARGET pybind11_headers)
|
||||
# Build the headers-only target (no Python included):
|
||||
# (long name used here to keep this from clashing in subdirectory mode)
|
||||
add_library(pybind11_headers INTERFACE)
|
||||
add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
|
||||
add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember
|
||||
|
||||
target_include_directories(
|
||||
pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
|
||||
cxx_right_angle_brackets)
|
||||
if(NOT "${PYBIND11_INTERNALS_VERSION}" STREQUAL "")
|
||||
target_compile_definitions(
|
||||
pybind11_headers INTERFACE "PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}")
|
||||
endif()
|
||||
else()
|
||||
# It is invalid to install a target twice, too.
|
||||
set(PYBIND11_INSTALL OFF)
|
||||
endif()
|
||||
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
|
||||
# https://github.com/jtojnar/cmake-snips/#concatenating-paths-when-building-pkg-config-files
|
||||
# TODO: cmake 3.20 adds the cmake_path() function, which obsoletes this snippet
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/tools/JoinPaths.cmake")
|
||||
|
||||
# Relative directory setting
|
||||
if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
|
||||
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})
|
||||
elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
|
||||
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(PYBIND11_INSTALL)
|
||||
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(PYBIND11_CMAKECONFIG_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
|
||||
CACHE STRING "install path for pybind11Config.cmake")
|
||||
|
||||
if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set(pybind11_INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
||||
else()
|
||||
set(pybind11_INCLUDEDIR "\$\{PACKAGE_PREFIX_DIR\}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
endif()
|
||||
|
||||
configure_package_config_file(
|
||||
tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS 3.14)
|
||||
# Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
|
||||
# not depend on architecture specific settings or libraries.
|
||||
set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
|
||||
unset(CMAKE_SIZEOF_VOID_P)
|
||||
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion)
|
||||
|
||||
set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
|
||||
else()
|
||||
# CMake 3.14+ natively supports header-only libraries
|
||||
write_basic_package_version_file(
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
|
||||
tools/FindPythonLibsNew.cmake
|
||||
tools/pybind11Common.cmake
|
||||
tools/pybind11Tools.cmake
|
||||
tools/pybind11NewTools.cmake
|
||||
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
||||
|
||||
if(NOT PYBIND11_EXPORT_NAME)
|
||||
set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
|
||||
endif()
|
||||
|
||||
install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}")
|
||||
|
||||
install(
|
||||
EXPORT "${PYBIND11_EXPORT_NAME}"
|
||||
NAMESPACE "pybind11::"
|
||||
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
|
||||
|
||||
# pkg-config support
|
||||
if(NOT prefix_for_pc_file)
|
||||
if(IS_ABSOLUTE "${CMAKE_INSTALL_DATAROOTDIR}")
|
||||
set(prefix_for_pc_file "${CMAKE_INSTALL_PREFIX}")
|
||||
else()
|
||||
set(pc_datarootdir "${CMAKE_INSTALL_DATAROOTDIR}")
|
||||
if(CMAKE_VERSION VERSION_LESS 3.20)
|
||||
set(prefix_for_pc_file "\${pcfiledir}/..")
|
||||
while(pc_datarootdir)
|
||||
get_filename_component(pc_datarootdir "${pc_datarootdir}" DIRECTORY)
|
||||
string(APPEND prefix_for_pc_file "/..")
|
||||
endwhile()
|
||||
else()
|
||||
cmake_path(RELATIVE_PATH CMAKE_INSTALL_PREFIX BASE_DIRECTORY CMAKE_INSTALL_DATAROOTDIR
|
||||
OUTPUT_VARIABLE prefix_for_pc_file)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11.pc.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
|
||||
|
||||
# Uninstall target
|
||||
if(PYBIND11_MASTER_PROJECT)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# BUILD_TESTING takes priority, but only if this is the master project
|
||||
if(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)
|
||||
if(BUILD_TESTING)
|
||||
if(_pybind11_nopython)
|
||||
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
||||
else()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(PYBIND11_TEST)
|
||||
if(_pybind11_nopython)
|
||||
message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
|
||||
else()
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Better symmetry with find_package(pybind11 CONFIG) mode.
|
||||
if(NOT PYBIND11_MASTER_PROJECT)
|
||||
set(pybind11_FOUND
|
||||
TRUE
|
||||
CACHE INTERNAL "True if pybind11 and all required components found on the system")
|
||||
endif()
|
29
thirdparty/pybind11/LICENSE
vendored
Normal file
29
thirdparty/pybind11/LICENSE
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of
|
||||
external contributions to this project including patches, pull requests, etc.
|
6
thirdparty/pybind11/MANIFEST.in
vendored
Normal file
6
thirdparty/pybind11/MANIFEST.in
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
prune tests
|
||||
recursive-include pybind11/include/pybind11 *.h
|
||||
recursive-include pybind11 *.py
|
||||
recursive-include pybind11 py.typed
|
||||
include pybind11/share/cmake/pybind11/*.cmake
|
||||
include LICENSE README.rst SECURITY.md pyproject.toml setup.py setup.cfg
|
180
thirdparty/pybind11/README.rst
vendored
Normal file
180
thirdparty/pybind11/README.rst
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
.. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png
|
||||
:alt: pybind11 logo
|
||||
|
||||
**pybind11 — Seamless operability between C++11 and Python**
|
||||
|
||||
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|
|
||||
|
||||
|Repology| |PyPI package| |Conda-forge| |Python Versions|
|
||||
|
||||
`Setuptools example <https://github.com/pybind/python_example>`_
|
||||
• `Scikit-build example <https://github.com/pybind/scikit_build_example>`_
|
||||
• `CMake example <https://github.com/pybind/cmake_example>`_
|
||||
|
||||
.. start
|
||||
|
||||
|
||||
**pybind11** is a lightweight header-only library that exposes C++ types
|
||||
in Python and vice versa, mainly to create Python bindings of existing
|
||||
C++ code. Its goals and syntax are similar to the excellent
|
||||
`Boost.Python <http://www.boost.org/doc/libs/1_58_0/libs/python/doc/>`_
|
||||
library by David Abrahams: to minimize boilerplate code in traditional
|
||||
extension modules by inferring type information using compile-time
|
||||
introspection.
|
||||
|
||||
The main issue with Boost.Python—and the reason for creating such a
|
||||
similar project—is Boost. Boost is an enormously large and complex suite
|
||||
of utility libraries that works with almost every C++ compiler in
|
||||
existence. This compatibility has its cost: arcane template tricks and
|
||||
workarounds are necessary to support the oldest and buggiest of compiler
|
||||
specimens. Now that C++11-compatible compilers are widely available,
|
||||
this heavy machinery has become an excessively large and unnecessary
|
||||
dependency.
|
||||
|
||||
Think of this library as a tiny self-contained version of Boost.Python
|
||||
with everything stripped away that isn't relevant for binding
|
||||
generation. Without comments, the core header files only require ~4K
|
||||
lines of code and depend on Python (3.6+, or PyPy) and the C++
|
||||
standard library. This compact implementation was possible thanks to
|
||||
some of the new C++11 language features (specifically: tuples, lambda
|
||||
functions and variadic templates). Since its creation, this library has
|
||||
grown beyond Boost.Python in many ways, leading to dramatically simpler
|
||||
binding code in many common situations.
|
||||
|
||||
Tutorial and reference documentation is provided at
|
||||
`pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.
|
||||
A PDF version of the manual is available
|
||||
`here <https://pybind11.readthedocs.io/_/downloads/en/latest/pdf/>`_.
|
||||
And the source code is always available at
|
||||
`github.com/pybind/pybind11 <https://github.com/pybind/pybind11>`_.
|
||||
|
||||
|
||||
Core features
|
||||
-------------
|
||||
|
||||
|
||||
pybind11 can map the following core C++ features to Python:
|
||||
|
||||
- Functions accepting and returning custom data structures per value,
|
||||
reference, or pointer
|
||||
- Instance methods and static methods
|
||||
- Overloaded functions
|
||||
- Instance attributes and static attributes
|
||||
- Arbitrary exception types
|
||||
- Enumerations
|
||||
- Callbacks
|
||||
- Iterators and ranges
|
||||
- Custom operators
|
||||
- Single and multiple inheritance
|
||||
- STL data structures
|
||||
- Smart pointers with reference counting like ``std::shared_ptr``
|
||||
- Internal references with correct reference counting
|
||||
- C++ classes with virtual (and pure virtual) methods can be extended
|
||||
in Python
|
||||
|
||||
Goodies
|
||||
-------
|
||||
|
||||
In addition to the core functionality, pybind11 provides some extra
|
||||
goodies:
|
||||
|
||||
- Python 3.6+, and PyPy3 7.3 are supported with an implementation-agnostic
|
||||
interface (pybind11 2.9 was the last version to support Python 2 and 3.5).
|
||||
|
||||
- It is possible to bind C++11 lambda functions with captured
|
||||
variables. The lambda capture data is stored inside the resulting
|
||||
Python function object.
|
||||
|
||||
- pybind11 uses C++11 move constructors and move assignment operators
|
||||
whenever possible to efficiently transfer custom data types.
|
||||
|
||||
- It's easy to expose the internal storage of custom data types through
|
||||
Pythons' buffer protocols. This is handy e.g. for fast conversion
|
||||
between C++ matrix classes like Eigen and NumPy without expensive
|
||||
copy operations.
|
||||
|
||||
- pybind11 can automatically vectorize functions so that they are
|
||||
transparently applied to all entries of one or more NumPy array
|
||||
arguments.
|
||||
|
||||
- Python's slice-based access and assignment operations can be
|
||||
supported with just a few lines of code.
|
||||
|
||||
- Everything is contained in just a few header files; there is no need
|
||||
to link against any additional libraries.
|
||||
|
||||
- Binaries are generally smaller by a factor of at least 2 compared to
|
||||
equivalent bindings generated by Boost.Python. A recent pybind11
|
||||
conversion of PyRosetta, an enormous Boost.Python binding project,
|
||||
`reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_
|
||||
a binary size reduction of **5.4x** and compile time reduction by
|
||||
**5.8x**.
|
||||
|
||||
- Function signatures are precomputed at compile time (using
|
||||
``constexpr``), leading to smaller binaries.
|
||||
|
||||
- With little extra effort, C++ types can be pickled and unpickled
|
||||
similar to regular Python objects.
|
||||
|
||||
Supported compilers
|
||||
-------------------
|
||||
|
||||
1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or
|
||||
newer)
|
||||
2. GCC 4.8 or newer
|
||||
3. Microsoft Visual Studio 2017 or newer
|
||||
4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)
|
||||
5. Cygwin/GCC (previously tested on 2.5.1)
|
||||
6. NVCC (CUDA 11.0 tested in CI)
|
||||
7. NVIDIA PGI (20.9 tested in CI)
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
This project was created by `Wenzel
|
||||
Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
|
||||
improvements to the code were contributed by Jonas Adler, Lori A. Burns,
|
||||
Sylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel
|
||||
Huebl, @hulucc, Yannick Jadoul, Sergey Lyskov, Johan Mabille, Tomasz Miąsko,
|
||||
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
|
||||
Schellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.
|
||||
|
||||
We thank Google for a generous financial contribution to the continuous
|
||||
integration infrastructure used by this project.
|
||||
|
||||
|
||||
Contributing
|
||||
~~~~~~~~~~~~
|
||||
|
||||
See the `contributing
|
||||
guide <https://github.com/pybind/pybind11/blob/master/.github/CONTRIBUTING.md>`_
|
||||
for information on building and contributing to pybind11.
|
||||
|
||||
License
|
||||
~~~~~~~
|
||||
|
||||
pybind11 is provided under a BSD-style license that can be found in the
|
||||
`LICENSE <https://github.com/pybind/pybind11/blob/master/LICENSE>`_
|
||||
file. By using, distributing, or contributing to this project, you agree
|
||||
to the terms and conditions of this license.
|
||||
|
||||
.. |Latest Documentation Status| image:: https://readthedocs.org/projects/pybind11/badge?version=latest
|
||||
:target: http://pybind11.readthedocs.org/en/latest
|
||||
.. |Stable Documentation Status| image:: https://img.shields.io/badge/docs-stable-blue.svg
|
||||
:target: http://pybind11.readthedocs.org/en/stable
|
||||
.. |Gitter chat| image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg
|
||||
:target: https://gitter.im/pybind/Lobby
|
||||
.. |CI| image:: https://github.com/pybind/pybind11/workflows/CI/badge.svg
|
||||
:target: https://github.com/pybind/pybind11/actions
|
||||
.. |Build status| image:: https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true
|
||||
:target: https://ci.appveyor.com/project/wjakob/pybind11
|
||||
.. |PyPI package| image:: https://img.shields.io/pypi/v/pybind11.svg
|
||||
:target: https://pypi.org/project/pybind11/
|
||||
.. |Conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pybind11.svg
|
||||
:target: https://github.com/conda-forge/pybind11-feedstock
|
||||
.. |Repology| image:: https://repology.org/badge/latest-versions/python:pybind11.svg
|
||||
:target: https://repology.org/project/python:pybind11/versions
|
||||
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg
|
||||
:target: https://pypi.org/project/pybind11/
|
||||
.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
|
||||
:target: https://github.com/pybind/pybind11/discussions
|
13
thirdparty/pybind11/SECURITY.md
vendored
Normal file
13
thirdparty/pybind11/SECURITY.md
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Security updates are applied only to the latest release.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
|
||||
|
||||
Please disclose it at [security advisory](https://github.com/pybind/pybind11/security/advisories/new).
|
||||
|
||||
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.
|
21
thirdparty/pybind11/docs/Doxyfile
vendored
Normal file
21
thirdparty/pybind11/docs/Doxyfile
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
PROJECT_NAME = pybind11
|
||||
INPUT = ../include/pybind11/
|
||||
RECURSIVE = YES
|
||||
|
||||
GENERATE_HTML = NO
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = .build/doxygenxml
|
||||
XML_PROGRAMLISTING = YES
|
||||
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
EXPAND_AS_DEFINED = PYBIND11_RUNTIME_EXCEPTION
|
||||
|
||||
ALIASES = "rst=\verbatim embed:rst"
|
||||
ALIASES += "endrst=\endverbatim"
|
||||
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
PREDEFINED = PYBIND11_NOINLINE
|
3
thirdparty/pybind11/docs/_static/css/custom.css
vendored
Normal file
3
thirdparty/pybind11/docs/_static/css/custom.css
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.highlight .go {
|
||||
color: #707070;
|
||||
}
|
81
thirdparty/pybind11/docs/advanced/cast/chrono.rst
vendored
Normal file
81
thirdparty/pybind11/docs/advanced/cast/chrono.rst
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
Chrono
|
||||
======
|
||||
|
||||
When including the additional header file :file:`pybind11/chrono.h` conversions
|
||||
from C++11 chrono datatypes to python datetime objects are automatically enabled.
|
||||
This header also enables conversions of python floats (often from sources such
|
||||
as ``time.monotonic()``, ``time.perf_counter()`` and ``time.process_time()``)
|
||||
into durations.
|
||||
|
||||
An overview of clocks in C++11
|
||||
------------------------------
|
||||
|
||||
A point of confusion when using these conversions is the differences between
|
||||
clocks provided in C++11. There are three clock types defined by the C++11
|
||||
standard and users can define their own if needed. Each of these clocks have
|
||||
different properties and when converting to and from python will give different
|
||||
results.
|
||||
|
||||
The first clock defined by the standard is ``std::chrono::system_clock``. This
|
||||
clock measures the current date and time. However, this clock changes with to
|
||||
updates to the operating system time. For example, if your time is synchronised
|
||||
with a time server this clock will change. This makes this clock a poor choice
|
||||
for timing purposes but good for measuring the wall time.
|
||||
|
||||
The second clock defined in the standard is ``std::chrono::steady_clock``.
|
||||
This clock ticks at a steady rate and is never adjusted. This makes it excellent
|
||||
for timing purposes, however the value in this clock does not correspond to the
|
||||
current date and time. Often this clock will be the amount of time your system
|
||||
has been on, although it does not have to be. This clock will never be the same
|
||||
clock as the system clock as the system clock can change but steady clocks
|
||||
cannot.
|
||||
|
||||
The third clock defined in the standard is ``std::chrono::high_resolution_clock``.
|
||||
This clock is the clock that has the highest resolution out of the clocks in the
|
||||
system. It is normally a typedef to either the system clock or the steady clock
|
||||
but can be its own independent clock. This is important as when using these
|
||||
conversions as the types you get in python for this clock might be different
|
||||
depending on the system.
|
||||
If it is a typedef of the system clock, python will get datetime objects, but if
|
||||
it is a different clock they will be timedelta objects.
|
||||
|
||||
Provided conversions
|
||||
--------------------
|
||||
|
||||
.. rubric:: C++ to Python
|
||||
|
||||
- ``std::chrono::system_clock::time_point`` → ``datetime.datetime``
|
||||
System clock times are converted to python datetime instances. They are
|
||||
in the local timezone, but do not have any timezone information attached
|
||||
to them (they are naive datetime objects).
|
||||
|
||||
- ``std::chrono::duration`` → ``datetime.timedelta``
|
||||
Durations are converted to timedeltas, any precision in the duration
|
||||
greater than microseconds is lost by rounding towards zero.
|
||||
|
||||
- ``std::chrono::[other_clocks]::time_point`` → ``datetime.timedelta``
|
||||
Any clock time that is not the system clock is converted to a time delta.
|
||||
This timedelta measures the time from the clocks epoch to now.
|
||||
|
||||
.. rubric:: Python to C++
|
||||
|
||||
- ``datetime.datetime`` or ``datetime.date`` or ``datetime.time`` → ``std::chrono::system_clock::time_point``
|
||||
Date/time objects are converted into system clock timepoints. Any
|
||||
timezone information is ignored and the type is treated as a naive
|
||||
object.
|
||||
|
||||
- ``datetime.timedelta`` → ``std::chrono::duration``
|
||||
Time delta are converted into durations with microsecond precision.
|
||||
|
||||
- ``datetime.timedelta`` → ``std::chrono::[other_clocks]::time_point``
|
||||
Time deltas that are converted into clock timepoints are treated as
|
||||
the amount of time from the start of the clocks epoch.
|
||||
|
||||
- ``float`` → ``std::chrono::duration``
|
||||
Floats that are passed to C++ as durations be interpreted as a number of
|
||||
seconds. These will be converted to the duration using ``duration_cast``
|
||||
from the float.
|
||||
|
||||
- ``float`` → ``std::chrono::[other_clocks]::time_point``
|
||||
Floats that are passed to C++ as time points will be interpreted as the
|
||||
number of seconds from the start of the clocks epoch.
|
93
thirdparty/pybind11/docs/advanced/cast/custom.rst
vendored
Normal file
93
thirdparty/pybind11/docs/advanced/cast/custom.rst
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
Custom type casters
|
||||
===================
|
||||
|
||||
In very rare cases, applications may require custom type casters that cannot be
|
||||
expressed using the abstractions provided by pybind11, thus requiring raw
|
||||
Python C API calls. This is fairly advanced usage and should only be pursued by
|
||||
experts who are familiar with the intricacies of Python reference counting.
|
||||
|
||||
The following snippets demonstrate how this works for a very simple ``inty``
|
||||
type that that should be convertible from Python types that provide a
|
||||
``__int__(self)`` method.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct inty { long long_value; };
|
||||
|
||||
void print(inty s) {
|
||||
std::cout << s.long_value << std::endl;
|
||||
}
|
||||
|
||||
The following Python snippet demonstrates the intended usage from the Python side:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class A:
|
||||
def __int__(self):
|
||||
return 123
|
||||
|
||||
|
||||
from example import print
|
||||
|
||||
print(A())
|
||||
|
||||
To register the necessary conversion routines, it is necessary to add an
|
||||
instantiation of the ``pybind11::detail::type_caster<T>`` template.
|
||||
Although this is an implementation detail, adding an instantiation of this
|
||||
type is explicitly allowed.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
namespace PYBIND11_NAMESPACE { namespace detail {
|
||||
template <> struct type_caster<inty> {
|
||||
public:
|
||||
/**
|
||||
* This macro establishes the name 'inty' in
|
||||
* function signatures and declares a local variable
|
||||
* 'value' of type inty
|
||||
*/
|
||||
PYBIND11_TYPE_CASTER(inty, const_name("inty"));
|
||||
|
||||
/**
|
||||
* Conversion part 1 (Python->C++): convert a PyObject into a inty
|
||||
* instance or return false upon failure. The second argument
|
||||
* indicates whether implicit conversions should be applied.
|
||||
*/
|
||||
bool load(handle src, bool) {
|
||||
/* Extract PyObject from handle */
|
||||
PyObject *source = src.ptr();
|
||||
/* Try converting into a Python integer value */
|
||||
PyObject *tmp = PyNumber_Long(source);
|
||||
if (!tmp)
|
||||
return false;
|
||||
/* Now try to convert into a C++ int */
|
||||
value.long_value = PyLong_AsLong(tmp);
|
||||
Py_DECREF(tmp);
|
||||
/* Ensure return code was OK (to avoid out-of-range errors etc) */
|
||||
return !(value.long_value == -1 && !PyErr_Occurred());
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion part 2 (C++ -> Python): convert an inty instance into
|
||||
* a Python object. The second and third arguments are used to
|
||||
* indicate the return value policy and parent object (for
|
||||
* ``return_value_policy::reference_internal``) and are generally
|
||||
* ignored by implicit casters.
|
||||
*/
|
||||
static handle cast(inty src, return_value_policy /* policy */, handle /* parent */) {
|
||||
return PyLong_FromLong(src.long_value);
|
||||
}
|
||||
};
|
||||
}} // namespace PYBIND11_NAMESPACE::detail
|
||||
|
||||
.. note::
|
||||
|
||||
A ``type_caster<T>`` defined with ``PYBIND11_TYPE_CASTER(T, ...)`` requires
|
||||
that ``T`` is default-constructible (``value`` is first default constructed
|
||||
and then ``load()`` assigns to it).
|
||||
|
||||
.. warning::
|
||||
|
||||
When using custom type casters, it's important to declare them consistently
|
||||
in every compilation unit of the Python extension module. Otherwise,
|
||||
undefined behavior can ensue.
|
310
thirdparty/pybind11/docs/advanced/cast/eigen.rst
vendored
Normal file
310
thirdparty/pybind11/docs/advanced/cast/eigen.rst
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
Eigen
|
||||
#####
|
||||
|
||||
`Eigen <http://eigen.tuxfamily.org>`_ is C++ header-based library for dense and
|
||||
sparse linear algebra. Due to its popularity and widespread adoption, pybind11
|
||||
provides transparent conversion and limited mapping support between Eigen and
|
||||
Scientific Python linear algebra data types.
|
||||
|
||||
To enable the built-in Eigen support you must include the optional header file
|
||||
:file:`pybind11/eigen.h`.
|
||||
|
||||
Pass-by-value
|
||||
=============
|
||||
|
||||
When binding a function with ordinary Eigen dense object arguments (for
|
||||
example, ``Eigen::MatrixXd``), pybind11 will accept any input value that is
|
||||
already (or convertible to) a ``numpy.ndarray`` with dimensions compatible with
|
||||
the Eigen type, copy its values into a temporary Eigen variable of the
|
||||
appropriate type, then call the function with this temporary variable.
|
||||
|
||||
Sparse matrices are similarly copied to or from
|
||||
``scipy.sparse.csr_matrix``/``scipy.sparse.csc_matrix`` objects.
|
||||
|
||||
Pass-by-reference
|
||||
=================
|
||||
|
||||
One major limitation of the above is that every data conversion implicitly
|
||||
involves a copy, which can be both expensive (for large matrices) and disallows
|
||||
binding functions that change their (Matrix) arguments. Pybind11 allows you to
|
||||
work around this by using Eigen's ``Eigen::Ref<MatrixType>`` class much as you
|
||||
would when writing a function taking a generic type in Eigen itself (subject to
|
||||
some limitations discussed below).
|
||||
|
||||
When calling a bound function accepting a ``Eigen::Ref<const MatrixType>``
|
||||
type, pybind11 will attempt to avoid copying by using an ``Eigen::Map`` object
|
||||
that maps into the source ``numpy.ndarray`` data: this requires both that the
|
||||
data types are the same (e.g. ``dtype='float64'`` and ``MatrixType::Scalar`` is
|
||||
``double``); and that the storage is layout compatible. The latter limitation
|
||||
is discussed in detail in the section below, and requires careful
|
||||
consideration: by default, numpy matrices and Eigen matrices are *not* storage
|
||||
compatible.
|
||||
|
||||
If the numpy matrix cannot be used as is (either because its types differ, e.g.
|
||||
passing an array of integers to an Eigen parameter requiring doubles, or
|
||||
because the storage is incompatible), pybind11 makes a temporary copy and
|
||||
passes the copy instead.
|
||||
|
||||
When a bound function parameter is instead ``Eigen::Ref<MatrixType>`` (note the
|
||||
lack of ``const``), pybind11 will only allow the function to be called if it
|
||||
can be mapped *and* if the numpy array is writeable (that is
|
||||
``a.flags.writeable`` is true). Any access (including modification) made to
|
||||
the passed variable will be transparently carried out directly on the
|
||||
``numpy.ndarray``.
|
||||
|
||||
This means you can write code such as the following and have it work as
|
||||
expected:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void scale_by_2(Eigen::Ref<Eigen::VectorXd> v) {
|
||||
v *= 2;
|
||||
}
|
||||
|
||||
Note, however, that you will likely run into limitations due to numpy and
|
||||
Eigen's difference default storage order for data; see the below section on
|
||||
:ref:`storage_orders` for details on how to bind code that won't run into such
|
||||
limitations.
|
||||
|
||||
.. note::
|
||||
|
||||
Passing by reference is not supported for sparse types.
|
||||
|
||||
Returning values to Python
|
||||
==========================
|
||||
|
||||
When returning an ordinary dense Eigen matrix type to numpy (e.g.
|
||||
``Eigen::MatrixXd`` or ``Eigen::RowVectorXf``) pybind11 keeps the matrix and
|
||||
returns a numpy array that directly references the Eigen matrix: no copy of the
|
||||
data is performed. The numpy array will have ``array.flags.owndata`` set to
|
||||
``False`` to indicate that it does not own the data, and the lifetime of the
|
||||
stored Eigen matrix will be tied to the returned ``array``.
|
||||
|
||||
If you bind a function with a non-reference, ``const`` return type (e.g.
|
||||
``const Eigen::MatrixXd``), the same thing happens except that pybind11 also
|
||||
sets the numpy array's ``writeable`` flag to false.
|
||||
|
||||
If you return an lvalue reference or pointer, the usual pybind11 rules apply,
|
||||
as dictated by the binding function's return value policy (see the
|
||||
documentation on :ref:`return_value_policies` for full details). That means,
|
||||
without an explicit return value policy, lvalue references will be copied and
|
||||
pointers will be managed by pybind11. In order to avoid copying, you should
|
||||
explicitly specify an appropriate return value policy, as in the following
|
||||
example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class MyClass {
|
||||
Eigen::MatrixXd big_mat = Eigen::MatrixXd::Zero(10000, 10000);
|
||||
public:
|
||||
Eigen::MatrixXd &getMatrix() { return big_mat; }
|
||||
const Eigen::MatrixXd &viewMatrix() { return big_mat; }
|
||||
};
|
||||
|
||||
// Later, in binding code:
|
||||
py::class_<MyClass>(m, "MyClass")
|
||||
.def(py::init<>())
|
||||
.def("copy_matrix", &MyClass::getMatrix) // Makes a copy!
|
||||
.def("get_matrix", &MyClass::getMatrix, py::return_value_policy::reference_internal)
|
||||
.def("view_matrix", &MyClass::viewMatrix, py::return_value_policy::reference_internal)
|
||||
;
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
a = MyClass()
|
||||
m = a.get_matrix() # flags.writeable = True, flags.owndata = False
|
||||
v = a.view_matrix() # flags.writeable = False, flags.owndata = False
|
||||
c = a.copy_matrix() # flags.writeable = True, flags.owndata = True
|
||||
# m[5,6] and v[5,6] refer to the same element, c[5,6] does not.
|
||||
|
||||
Note in this example that ``py::return_value_policy::reference_internal`` is
|
||||
used to tie the life of the MyClass object to the life of the returned arrays.
|
||||
|
||||
You may also return an ``Eigen::Ref``, ``Eigen::Map`` or other map-like Eigen
|
||||
object (for example, the return value of ``matrix.block()`` and related
|
||||
methods) that map into a dense Eigen type. When doing so, the default
|
||||
behaviour of pybind11 is to simply reference the returned data: you must take
|
||||
care to ensure that this data remains valid! You may ask pybind11 to
|
||||
explicitly *copy* such a return value by using the
|
||||
``py::return_value_policy::copy`` policy when binding the function. You may
|
||||
also use ``py::return_value_policy::reference_internal`` or a
|
||||
``py::keep_alive`` to ensure the data stays valid as long as the returned numpy
|
||||
array does.
|
||||
|
||||
When returning such a reference of map, pybind11 additionally respects the
|
||||
readonly-status of the returned value, marking the numpy array as non-writeable
|
||||
if the reference or map was itself read-only.
|
||||
|
||||
.. note::
|
||||
|
||||
Sparse types are always copied when returned.
|
||||
|
||||
.. _storage_orders:
|
||||
|
||||
Storage orders
|
||||
==============
|
||||
|
||||
Passing arguments via ``Eigen::Ref`` has some limitations that you must be
|
||||
aware of in order to effectively pass matrices by reference. First and
|
||||
foremost is that the default ``Eigen::Ref<MatrixType>`` class requires
|
||||
contiguous storage along columns (for column-major types, the default in Eigen)
|
||||
or rows if ``MatrixType`` is specifically an ``Eigen::RowMajor`` storage type.
|
||||
The former, Eigen's default, is incompatible with ``numpy``'s default row-major
|
||||
storage, and so you will not be able to pass numpy arrays to Eigen by reference
|
||||
without making one of two changes.
|
||||
|
||||
(Note that this does not apply to vectors (or column or row matrices): for such
|
||||
types the "row-major" and "column-major" distinction is meaningless).
|
||||
|
||||
The first approach is to change the use of ``Eigen::Ref<MatrixType>`` to the
|
||||
more general ``Eigen::Ref<MatrixType, 0, Eigen::Stride<Eigen::Dynamic,
|
||||
Eigen::Dynamic>>`` (or similar type with a fully dynamic stride type in the
|
||||
third template argument). Since this is a rather cumbersome type, pybind11
|
||||
provides a ``py::EigenDRef<MatrixType>`` type alias for your convenience (along
|
||||
with EigenDMap for the equivalent Map, and EigenDStride for just the stride
|
||||
type).
|
||||
|
||||
This type allows Eigen to map into any arbitrary storage order. This is not
|
||||
the default in Eigen for performance reasons: contiguous storage allows
|
||||
vectorization that cannot be done when storage is not known to be contiguous at
|
||||
compile time. The default ``Eigen::Ref`` stride type allows non-contiguous
|
||||
storage along the outer dimension (that is, the rows of a column-major matrix
|
||||
or columns of a row-major matrix), but not along the inner dimension.
|
||||
|
||||
This type, however, has the added benefit of also being able to map numpy array
|
||||
slices. For example, the following (contrived) example uses Eigen with a numpy
|
||||
slice to multiply by 2 all coefficients that are both on even rows (0, 2, 4,
|
||||
...) and in columns 2, 5, or 8:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("scale", [](py::EigenDRef<Eigen::MatrixXd> m, double c) { m *= c; });
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# a = np.array(...)
|
||||
scale_by_2(myarray[0::2, 2:9:3])
|
||||
|
||||
The second approach to avoid copying is more intrusive: rearranging the
|
||||
underlying data types to not run into the non-contiguous storage problem in the
|
||||
first place. In particular, that means using matrices with ``Eigen::RowMajor``
|
||||
storage, where appropriate, such as:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
using RowMatrixXd = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
// Use RowMatrixXd instead of MatrixXd
|
||||
|
||||
Now bound functions accepting ``Eigen::Ref<RowMatrixXd>`` arguments will be
|
||||
callable with numpy's (default) arrays without involving a copying.
|
||||
|
||||
You can, alternatively, change the storage order that numpy arrays use by
|
||||
adding the ``order='F'`` option when creating an array:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
myarray = np.array(source, order="F")
|
||||
|
||||
Such an object will be passable to a bound function accepting an
|
||||
``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type).
|
||||
|
||||
One major caveat with this approach, however, is that it is not entirely as
|
||||
easy as simply flipping all Eigen or numpy usage from one to the other: some
|
||||
operations may alter the storage order of a numpy array. For example, ``a2 =
|
||||
array.transpose()`` results in ``a2`` being a view of ``array`` that references
|
||||
the same data, but in the opposite storage order!
|
||||
|
||||
While this approach allows fully optimized vectorized calculations in Eigen, it
|
||||
cannot be used with array slices, unlike the first approach.
|
||||
|
||||
When *returning* a matrix to Python (either a regular matrix, a reference via
|
||||
``Eigen::Ref<>``, or a map/block into a matrix), no special storage
|
||||
consideration is required: the created numpy array will have the required
|
||||
stride that allows numpy to properly interpret the array, whatever its storage
|
||||
order.
|
||||
|
||||
Failing rather than copying
|
||||
===========================
|
||||
|
||||
The default behaviour when binding ``Eigen::Ref<const MatrixType>`` Eigen
|
||||
references is to copy matrix values when passed a numpy array that does not
|
||||
conform to the element type of ``MatrixType`` or does not have a compatible
|
||||
stride layout. If you want to explicitly avoid copying in such a case, you
|
||||
should bind arguments using the ``py::arg().noconvert()`` annotation (as
|
||||
described in the :ref:`nonconverting_arguments` documentation).
|
||||
|
||||
The following example shows an example of arguments that don't allow data
|
||||
copying to take place:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// The method and function to be bound:
|
||||
class MyClass {
|
||||
// ...
|
||||
double some_method(const Eigen::Ref<const MatrixXd> &matrix) { /* ... */ }
|
||||
};
|
||||
float some_function(const Eigen::Ref<const MatrixXf> &big,
|
||||
const Eigen::Ref<const MatrixXf> &small) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// The associated binding code:
|
||||
using namespace pybind11::literals; // for "arg"_a
|
||||
py::class_<MyClass>(m, "MyClass")
|
||||
// ... other class definitions
|
||||
.def("some_method", &MyClass::some_method, py::arg().noconvert());
|
||||
|
||||
m.def("some_function", &some_function,
|
||||
"big"_a.noconvert(), // <- Don't allow copying for this arg
|
||||
"small"_a // <- This one can be copied if needed
|
||||
);
|
||||
|
||||
With the above binding code, attempting to call the the ``some_method(m)``
|
||||
method on a ``MyClass`` object, or attempting to call ``some_function(m, m2)``
|
||||
will raise a ``RuntimeError`` rather than making a temporary copy of the array.
|
||||
It will, however, allow the ``m2`` argument to be copied into a temporary if
|
||||
necessary.
|
||||
|
||||
Note that explicitly specifying ``.noconvert()`` is not required for *mutable*
|
||||
Eigen references (e.g. ``Eigen::Ref<MatrixXd>`` without ``const`` on the
|
||||
``MatrixXd``): mutable references will never be called with a temporary copy.
|
||||
|
||||
Vectors versus column/row matrices
|
||||
==================================
|
||||
|
||||
Eigen and numpy have fundamentally different notions of a vector. In Eigen, a
|
||||
vector is simply a matrix with the number of columns or rows set to 1 at
|
||||
compile time (for a column vector or row vector, respectively). NumPy, in
|
||||
contrast, has comparable 2-dimensional 1xN and Nx1 arrays, but *also* has
|
||||
1-dimensional arrays of size N.
|
||||
|
||||
When passing a 2-dimensional 1xN or Nx1 array to Eigen, the Eigen type must
|
||||
have matching dimensions: That is, you cannot pass a 2-dimensional Nx1 numpy
|
||||
array to an Eigen value expecting a row vector, or a 1xN numpy array as a
|
||||
column vector argument.
|
||||
|
||||
On the other hand, pybind11 allows you to pass 1-dimensional arrays of length N
|
||||
as Eigen parameters. If the Eigen type can hold a column vector of length N it
|
||||
will be passed as such a column vector. If not, but the Eigen type constraints
|
||||
will accept a row vector, it will be passed as a row vector. (The column
|
||||
vector takes precedence when both are supported, for example, when passing a
|
||||
1D numpy array to a MatrixXd argument). Note that the type need not be
|
||||
explicitly a vector: it is permitted to pass a 1D numpy array of size 5 to an
|
||||
Eigen ``Matrix<double, Dynamic, 5>``: you would end up with a 1x5 Eigen matrix.
|
||||
Passing the same to an ``Eigen::MatrixXd`` would result in a 5x1 Eigen matrix.
|
||||
|
||||
When returning an Eigen vector to numpy, the conversion is ambiguous: a row
|
||||
vector of length 4 could be returned as either a 1D array of length 4, or as a
|
||||
2D array of size 1x4. When encountering such a situation, pybind11 compromises
|
||||
by considering the returned Eigen type: if it is a compile-time vector--that
|
||||
is, the type has either the number of rows or columns set to 1 at compile
|
||||
time--pybind11 converts to a 1D numpy array when returning the value. For
|
||||
instances that are a vector only at run-time (e.g. ``MatrixXd``,
|
||||
``Matrix<float, Dynamic, 4>``), pybind11 returns the vector as a 2D array to
|
||||
numpy. If this isn't want you want, you can use ``array.reshape(...)`` to get
|
||||
a view of the same data in the desired dimensions.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_eigen.cpp` contains a complete example that
|
||||
shows how to pass Eigen sparse and dense data types in more detail.
|
109
thirdparty/pybind11/docs/advanced/cast/functional.rst
vendored
Normal file
109
thirdparty/pybind11/docs/advanced/cast/functional.rst
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
Functional
|
||||
##########
|
||||
|
||||
The following features must be enabled by including :file:`pybind11/functional.h`.
|
||||
|
||||
|
||||
Callbacks and passing anonymous functions
|
||||
=========================================
|
||||
|
||||
The C++11 standard brought lambda functions and the generic polymorphic
|
||||
function wrapper ``std::function<>`` to the C++ programming language, which
|
||||
enable powerful new ways of working with functions. Lambda functions come in
|
||||
two flavors: stateless lambda function resemble classic function pointers that
|
||||
link to an anonymous piece of code, while stateful lambda functions
|
||||
additionally depend on captured variables that are stored in an anonymous
|
||||
*lambda closure object*.
|
||||
|
||||
Here is a simple example of a C++ function that takes an arbitrary function
|
||||
(stateful or stateless) with signature ``int -> int`` as an argument and runs
|
||||
it with the value 10.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int func_arg(const std::function<int(int)> &f) {
|
||||
return f(10);
|
||||
}
|
||||
|
||||
The example below is more involved: it takes a function of signature ``int -> int``
|
||||
and returns another function of the same kind. The return value is a stateful
|
||||
lambda function, which stores the value ``f`` in the capture object and adds 1 to
|
||||
its return value upon execution.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::function<int(int)> func_ret(const std::function<int(int)> &f) {
|
||||
return [f](int i) {
|
||||
return f(i) + 1;
|
||||
};
|
||||
}
|
||||
|
||||
This example demonstrates using python named parameters in C++ callbacks which
|
||||
requires using ``py::cpp_function`` as a wrapper. Usage is similar to defining
|
||||
methods of classes:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::cpp_function func_cpp() {
|
||||
return py::cpp_function([](int i) { return i+1; },
|
||||
py::arg("number"));
|
||||
}
|
||||
|
||||
After including the extra header file :file:`pybind11/functional.h`, it is almost
|
||||
trivial to generate binding code for all of these functions.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
m.def("func_arg", &func_arg);
|
||||
m.def("func_ret", &func_ret);
|
||||
m.def("func_cpp", &func_cpp);
|
||||
}
|
||||
|
||||
The following interactive session shows how to call them from Python.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
$ python
|
||||
>>> import example
|
||||
>>> def square(i):
|
||||
... return i * i
|
||||
...
|
||||
>>> example.func_arg(square)
|
||||
100L
|
||||
>>> square_plus_1 = example.func_ret(square)
|
||||
>>> square_plus_1(4)
|
||||
17L
|
||||
>>> plus_1 = func_cpp()
|
||||
>>> plus_1(number=43)
|
||||
44L
|
||||
|
||||
.. warning::
|
||||
|
||||
Keep in mind that passing a function from C++ to Python (or vice versa)
|
||||
will instantiate a piece of wrapper code that translates function
|
||||
invocations between the two languages. Naturally, this translation
|
||||
increases the computational cost of each function call somewhat. A
|
||||
problematic situation can arise when a function is copied back and forth
|
||||
between Python and C++ many times in a row, in which case the underlying
|
||||
wrappers will accumulate correspondingly. The resulting long sequence of
|
||||
C++ -> Python -> C++ -> ... roundtrips can significantly decrease
|
||||
performance.
|
||||
|
||||
There is one exception: pybind11 detects case where a stateless function
|
||||
(i.e. a function pointer or a lambda function without captured variables)
|
||||
is passed as an argument to another C++ function exposed in Python. In this
|
||||
case, there is no overhead. Pybind11 will extract the underlying C++
|
||||
function pointer from the wrapped function to sidestep a potential C++ ->
|
||||
Python -> C++ roundtrip. This is demonstrated in :file:`tests/test_callbacks.cpp`.
|
||||
|
||||
.. note::
|
||||
|
||||
This functionality is very useful when generating bindings for callbacks in
|
||||
C++ libraries (e.g. GUI libraries, asynchronous networking libraries, etc.).
|
||||
|
||||
The file :file:`tests/test_callbacks.cpp` contains a complete example
|
||||
that demonstrates how to work with callbacks and anonymous functions in
|
||||
more detail.
|
43
thirdparty/pybind11/docs/advanced/cast/index.rst
vendored
Normal file
43
thirdparty/pybind11/docs/advanced/cast/index.rst
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
.. _type-conversions:
|
||||
|
||||
Type conversions
|
||||
################
|
||||
|
||||
Apart from enabling cross-language function calls, a fundamental problem
|
||||
that a binding tool like pybind11 must address is to provide access to
|
||||
native Python types in C++ and vice versa. There are three fundamentally
|
||||
different ways to do this—which approach is preferable for a particular type
|
||||
depends on the situation at hand.
|
||||
|
||||
1. Use a native C++ type everywhere. In this case, the type must be wrapped
|
||||
using pybind11-generated bindings so that Python can interact with it.
|
||||
|
||||
2. Use a native Python type everywhere. It will need to be wrapped so that
|
||||
C++ functions can interact with it.
|
||||
|
||||
3. Use a native C++ type on the C++ side and a native Python type on the
|
||||
Python side. pybind11 refers to this as a *type conversion*.
|
||||
|
||||
Type conversions are the most "natural" option in the sense that native
|
||||
(non-wrapped) types are used everywhere. The main downside is that a copy
|
||||
of the data must be made on every Python ↔ C++ transition: this is
|
||||
needed since the C++ and Python versions of the same type generally won't
|
||||
have the same memory layout.
|
||||
|
||||
pybind11 can perform many kinds of conversions automatically. An overview
|
||||
is provided in the table ":ref:`conversion_table`".
|
||||
|
||||
The following subsections discuss the differences between these options in more
|
||||
detail. The main focus in this section is on type conversions, which represent
|
||||
the last case of the above list.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
overview
|
||||
strings
|
||||
stl
|
||||
functional
|
||||
chrono
|
||||
eigen
|
||||
custom
|
170
thirdparty/pybind11/docs/advanced/cast/overview.rst
vendored
Normal file
170
thirdparty/pybind11/docs/advanced/cast/overview.rst
vendored
Normal file
@ -0,0 +1,170 @@
|
||||
Overview
|
||||
########
|
||||
|
||||
.. rubric:: 1. Native type in C++, wrapper in Python
|
||||
|
||||
Exposing a custom C++ type using :class:`py::class_` was covered in detail
|
||||
in the :doc:`/classes` section. There, the underlying data structure is
|
||||
always the original C++ class while the :class:`py::class_` wrapper provides
|
||||
a Python interface. Internally, when an object like this is sent from C++ to
|
||||
Python, pybind11 will just add the outer wrapper layer over the native C++
|
||||
object. Getting it back from Python is just a matter of peeling off the
|
||||
wrapper.
|
||||
|
||||
.. rubric:: 2. Wrapper in C++, native type in Python
|
||||
|
||||
This is the exact opposite situation. Now, we have a type which is native to
|
||||
Python, like a ``tuple`` or a ``list``. One way to get this data into C++ is
|
||||
with the :class:`py::object` family of wrappers. These are explained in more
|
||||
detail in the :doc:`/advanced/pycpp/object` section. We'll just give a quick
|
||||
example here:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void print_list(py::list my_list) {
|
||||
for (auto item : my_list)
|
||||
std::cout << item << " ";
|
||||
}
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> print_list([1, 2, 3])
|
||||
1 2 3
|
||||
|
||||
The Python ``list`` is not converted in any way -- it's just wrapped in a C++
|
||||
:class:`py::list` class. At its core it's still a Python object. Copying a
|
||||
:class:`py::list` will do the usual reference-counting like in Python.
|
||||
Returning the object to Python will just remove the thin wrapper.
|
||||
|
||||
.. rubric:: 3. Converting between native C++ and Python types
|
||||
|
||||
In the previous two cases we had a native type in one language and a wrapper in
|
||||
the other. Now, we have native types on both sides and we convert between them.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void print_vector(const std::vector<int> &v) {
|
||||
for (auto item : v)
|
||||
std::cout << item << "\n";
|
||||
}
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> print_vector([1, 2, 3])
|
||||
1 2 3
|
||||
|
||||
In this case, pybind11 will construct a new ``std::vector<int>`` and copy each
|
||||
element from the Python ``list``. The newly constructed object will be passed
|
||||
to ``print_vector``. The same thing happens in the other direction: a new
|
||||
``list`` is made to match the value returned from C++.
|
||||
|
||||
Lots of these conversions are supported out of the box, as shown in the table
|
||||
below. They are very convenient, but keep in mind that these conversions are
|
||||
fundamentally based on copying data. This is perfectly fine for small immutable
|
||||
types but it may become quite expensive for large data structures. This can be
|
||||
avoided by overriding the automatic conversion with a custom wrapper (i.e. the
|
||||
above-mentioned approach 1). This requires some manual effort and more details
|
||||
are available in the :ref:`opaque` section.
|
||||
|
||||
.. _conversion_table:
|
||||
|
||||
List of all builtin conversions
|
||||
-------------------------------
|
||||
|
||||
The following basic data types are supported out of the box (some may require
|
||||
an additional extension header to be included). To pass other data structures
|
||||
as arguments and return values, refer to the section on binding :ref:`classes`.
|
||||
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| Data type | Description | Header file |
|
||||
+====================================+===========================+===================================+
|
||||
| ``int8_t``, ``uint8_t`` | 8-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``char`` | Character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``char16_t`` | UTF-16 character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``char32_t`` | UTF-32 character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const char16_t *`` | UTF-16 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const char32_t *`` | UTF-32 string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::u16string`` | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::u32string`` | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::string_view``, | STL C++17 string views | :file:`pybind11/pybind11.h` |
|
||||
| ``std::u16string_view``, etc. | | |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::pair<T1, T2>`` | Pair of two custom types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::complex<T>`` | Complex numbers | :file:`pybind11/complex.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::array<T, Size>`` | STL static array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::vector<T>`` | STL dynamic array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::deque<T>`` | STL double-ended queue | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::valarray<T>`` | STL value array | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::list<T>`` | STL linked list | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::map<T1, T2>`` | STL ordered map | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::unordered_map<T1, T2>`` | STL unordered map | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::set<T>`` | STL ordered set | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::unordered_set<T>`` | STL unordered set | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::optional<T>`` | STL optional type (C++17) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::experimental::optional<T>`` | STL optional type (exp.) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::variant<...>`` | Type-safe union (C++17) | :file:`pybind11/stl.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::filesystem::path<T>`` | STL path (C++17) [#]_ | :file:`pybind11/stl/filesystem.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` |
|
||||
+------------------------------------+---------------------------+-----------------------------------+
|
||||
|
||||
.. [#] ``std::filesystem::path`` is converted to ``pathlib.Path`` and
|
||||
``os.PathLike`` is converted to ``std::filesystem::path``.
|
249
thirdparty/pybind11/docs/advanced/cast/stl.rst
vendored
Normal file
249
thirdparty/pybind11/docs/advanced/cast/stl.rst
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
STL containers
|
||||
##############
|
||||
|
||||
Automatic conversion
|
||||
====================
|
||||
|
||||
When including the additional header file :file:`pybind11/stl.h`, conversions
|
||||
between ``std::vector<>``/``std::deque<>``/``std::list<>``/``std::array<>``/``std::valarray<>``,
|
||||
``std::set<>``/``std::unordered_set<>``, and
|
||||
``std::map<>``/``std::unordered_map<>`` and the Python ``list``, ``set`` and
|
||||
``dict`` data structures are automatically enabled. The types ``std::pair<>``
|
||||
and ``std::tuple<>`` are already supported out of the box with just the core
|
||||
:file:`pybind11/pybind11.h` header.
|
||||
|
||||
The major downside of these implicit conversions is that containers must be
|
||||
converted (i.e. copied) on every Python->C++ and C++->Python transition, which
|
||||
can have implications on the program semantics and performance. Please read the
|
||||
next sections for more details and alternative approaches that avoid this.
|
||||
|
||||
.. note::
|
||||
|
||||
Arbitrary nesting of any of these types is possible.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_stl.cpp` contains a complete
|
||||
example that demonstrates how to pass STL data types in more detail.
|
||||
|
||||
.. _cpp17_container_casters:
|
||||
|
||||
C++17 library containers
|
||||
========================
|
||||
|
||||
The :file:`pybind11/stl.h` header also includes support for ``std::optional<>``
|
||||
and ``std::variant<>``. These require a C++17 compiler and standard library.
|
||||
In C++14 mode, ``std::experimental::optional<>`` is supported if available.
|
||||
|
||||
Various versions of these containers also exist for C++11 (e.g. in Boost).
|
||||
pybind11 provides an easy way to specialize the ``type_caster`` for such
|
||||
types:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// `boost::optional` as an example -- can be any `std::optional`-like container
|
||||
namespace PYBIND11_NAMESPACE { namespace detail {
|
||||
template <typename T>
|
||||
struct type_caster<boost::optional<T>> : optional_caster<boost::optional<T>> {};
|
||||
}}
|
||||
|
||||
The above should be placed in a header file and included in all translation units
|
||||
where automatic conversion is needed. Similarly, a specialization can be provided
|
||||
for custom variant types:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// `boost::variant` as an example -- can be any `std::variant`-like container
|
||||
namespace PYBIND11_NAMESPACE { namespace detail {
|
||||
template <typename... Ts>
|
||||
struct type_caster<boost::variant<Ts...>> : variant_caster<boost::variant<Ts...>> {};
|
||||
|
||||
// Specifies the function used to visit the variant -- `apply_visitor` instead of `visit`
|
||||
template <>
|
||||
struct visit_helper<boost::variant> {
|
||||
template <typename... Args>
|
||||
static auto call(Args &&...args) -> decltype(boost::apply_visitor(args...)) {
|
||||
return boost::apply_visitor(args...);
|
||||
}
|
||||
};
|
||||
}} // namespace PYBIND11_NAMESPACE::detail
|
||||
|
||||
The ``visit_helper`` specialization is not required if your ``name::variant`` provides
|
||||
a ``name::visit()`` function. For any other function name, the specialization must be
|
||||
included to tell pybind11 how to visit the variant.
|
||||
|
||||
.. warning::
|
||||
|
||||
When converting a ``variant`` type, pybind11 follows the same rules as when
|
||||
determining which function overload to call (:ref:`overload_resolution`), and
|
||||
so the same caveats hold. In particular, the order in which the ``variant``'s
|
||||
alternatives are listed is important, since pybind11 will try conversions in
|
||||
this order. This means that, for example, when converting ``variant<int, bool>``,
|
||||
the ``bool`` variant will never be selected, as any Python ``bool`` is already
|
||||
an ``int`` and is convertible to a C++ ``int``. Changing the order of alternatives
|
||||
(and using ``variant<bool, int>``, in this example) provides a solution.
|
||||
|
||||
.. note::
|
||||
|
||||
pybind11 only supports the modern implementation of ``boost::variant``
|
||||
which makes use of variadic templates. This requires Boost 1.56 or newer.
|
||||
|
||||
.. _opaque:
|
||||
|
||||
Making opaque types
|
||||
===================
|
||||
|
||||
pybind11 heavily relies on a template matching mechanism to convert parameters
|
||||
and return values that are constructed from STL data types such as vectors,
|
||||
linked lists, hash tables, etc. This even works in a recursive manner, for
|
||||
instance to deal with lists of hash maps of pairs of elementary and custom
|
||||
types, etc.
|
||||
|
||||
However, a fundamental limitation of this approach is that internal conversions
|
||||
between Python and C++ types involve a copy operation that prevents
|
||||
pass-by-reference semantics. What does this mean?
|
||||
|
||||
Suppose we bind the following function
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void append_1(std::vector<int> &v) {
|
||||
v.push_back(1);
|
||||
}
|
||||
|
||||
and call it from Python, the following happens:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> v = [5, 6]
|
||||
>>> append_1(v)
|
||||
>>> print(v)
|
||||
[5, 6]
|
||||
|
||||
As you can see, when passing STL data structures by reference, modifications
|
||||
are not propagated back the Python side. A similar situation arises when
|
||||
exposing STL data structures using the ``def_readwrite`` or ``def_readonly``
|
||||
functions:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
/* ... definition ... */
|
||||
|
||||
class MyClass {
|
||||
std::vector<int> contents;
|
||||
};
|
||||
|
||||
/* ... binding code ... */
|
||||
|
||||
py::class_<MyClass>(m, "MyClass")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("contents", &MyClass::contents);
|
||||
|
||||
In this case, properties can be read and written in their entirety. However, an
|
||||
``append`` operation involving such a list type has no effect:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> m = MyClass()
|
||||
>>> m.contents = [5, 6]
|
||||
>>> print(m.contents)
|
||||
[5, 6]
|
||||
>>> m.contents.append(7)
|
||||
>>> print(m.contents)
|
||||
[5, 6]
|
||||
|
||||
Finally, the involved copy operations can be costly when dealing with very
|
||||
large lists. To deal with all of the above situations, pybind11 provides a
|
||||
macro named ``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based
|
||||
conversion machinery of types, thus rendering them *opaque*. The contents of
|
||||
opaque objects are never inspected or extracted, hence they *can* be passed by
|
||||
reference. For instance, to turn ``std::vector<int>`` into an opaque type, add
|
||||
the declaration
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_MAKE_OPAQUE(std::vector<int>);
|
||||
|
||||
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
|
||||
macro must be specified at the top level (and outside of any namespaces), since
|
||||
it adds a template instantiation of ``type_caster``. If your binding code consists of
|
||||
multiple compilation units, it must be present in every file (typically via a
|
||||
common header) preceding any usage of ``std::vector<int>``. Opaque types must
|
||||
also have a corresponding ``class_`` declaration to associate them with a name
|
||||
in Python, and to define a set of available operations, e.g.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<std::vector<int>>(m, "IntVector")
|
||||
.def(py::init<>())
|
||||
.def("clear", &std::vector<int>::clear)
|
||||
.def("pop_back", &std::vector<int>::pop_back)
|
||||
.def("__len__", [](const std::vector<int> &v) { return v.size(); })
|
||||
.def("__iter__", [](std::vector<int> &v) {
|
||||
return py::make_iterator(v.begin(), v.end());
|
||||
}, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
|
||||
// ....
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_opaque_types.cpp` contains a complete
|
||||
example that demonstrates how to create and expose opaque types using
|
||||
pybind11 in more detail.
|
||||
|
||||
.. _stl_bind:
|
||||
|
||||
Binding STL containers
|
||||
======================
|
||||
|
||||
The ability to expose STL containers as native Python objects is a fairly
|
||||
common request, hence pybind11 also provides an optional header file named
|
||||
:file:`pybind11/stl_bind.h` that does exactly this. The mapped containers try
|
||||
to match the behavior of their native Python counterparts as much as possible.
|
||||
|
||||
The following example showcases usage of :file:`pybind11/stl_bind.h`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Don't forget this
|
||||
#include <pybind11/stl_bind.h>
|
||||
|
||||
PYBIND11_MAKE_OPAQUE(std::vector<int>);
|
||||
PYBIND11_MAKE_OPAQUE(std::map<std::string, double>);
|
||||
|
||||
// ...
|
||||
|
||||
// later in binding code:
|
||||
py::bind_vector<std::vector<int>>(m, "VectorInt");
|
||||
py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
|
||||
|
||||
When binding STL containers pybind11 considers the types of the container's
|
||||
elements to decide whether the container should be confined to the local module
|
||||
(via the :ref:`module_local` feature). If the container element types are
|
||||
anything other than already-bound custom types bound without
|
||||
``py::module_local()`` the container binding will have ``py::module_local()``
|
||||
applied. This includes converting types such as numeric types, strings, Eigen
|
||||
types; and types that have not yet been bound at the time of the stl container
|
||||
binding. This module-local binding is designed to avoid potential conflicts
|
||||
between module bindings (for example, from two separate modules each attempting
|
||||
to bind ``std::vector<int>`` as a python type).
|
||||
|
||||
It is possible to override this behavior to force a definition to be either
|
||||
module-local or global. To do so, you can pass the attributes
|
||||
``py::module_local()`` (to make the binding module-local) or
|
||||
``py::module_local(false)`` (to make the binding global) into the
|
||||
``py::bind_vector`` or ``py::bind_map`` arguments:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::bind_vector<std::vector<int>>(m, "VectorInt", py::module_local(false));
|
||||
|
||||
Note, however, that such a global binding would make it impossible to load this
|
||||
module at the same time as any other pybind module that also attempts to bind
|
||||
the same container type (``std::vector<int>`` in the above example).
|
||||
|
||||
See :ref:`module_local` for more details on module-local bindings.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_stl_binders.cpp` shows how to use the
|
||||
convenience STL container wrappers.
|
296
thirdparty/pybind11/docs/advanced/cast/strings.rst
vendored
Normal file
296
thirdparty/pybind11/docs/advanced/cast/strings.rst
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
Strings, bytes and Unicode conversions
|
||||
######################################
|
||||
|
||||
Passing Python strings to C++
|
||||
=============================
|
||||
|
||||
When a Python ``str`` is passed from Python to a C++ function that accepts
|
||||
``std::string`` or ``char *`` as arguments, pybind11 will encode the Python
|
||||
string to UTF-8. All Python ``str`` can be encoded in UTF-8, so this operation
|
||||
does not fail.
|
||||
|
||||
The C++ language is encoding agnostic. It is the responsibility of the
|
||||
programmer to track encodings. It's often easiest to simply `use UTF-8
|
||||
everywhere <http://utf8everywhere.org/>`_.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
m.def("utf8_test",
|
||||
[](const std::string &s) {
|
||||
cout << "utf-8 is icing on the cake.\n";
|
||||
cout << s;
|
||||
}
|
||||
);
|
||||
m.def("utf8_charptr",
|
||||
[](const char *s) {
|
||||
cout << "My favorite food is\n";
|
||||
cout << s;
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> utf8_test("🎂")
|
||||
utf-8 is icing on the cake.
|
||||
🎂
|
||||
|
||||
>>> utf8_charptr("🍕")
|
||||
My favorite food is
|
||||
🍕
|
||||
|
||||
.. note::
|
||||
|
||||
Some terminal emulators do not support UTF-8 or emoji fonts and may not
|
||||
display the example above correctly.
|
||||
|
||||
The results are the same whether the C++ function accepts arguments by value or
|
||||
reference, and whether or not ``const`` is used.
|
||||
|
||||
Passing bytes to C++
|
||||
--------------------
|
||||
|
||||
A Python ``bytes`` object will be passed to C++ functions that accept
|
||||
``std::string`` or ``char*`` *without* conversion. In order to make a function
|
||||
*only* accept ``bytes`` (and not ``str``), declare it as taking a ``py::bytes``
|
||||
argument.
|
||||
|
||||
|
||||
Returning C++ strings to Python
|
||||
===============================
|
||||
|
||||
When a C++ function returns a ``std::string`` or ``char*`` to a Python caller,
|
||||
**pybind11 will assume that the string is valid UTF-8** and will decode it to a
|
||||
native Python ``str``, using the same API as Python uses to perform
|
||||
``bytes.decode('utf-8')``. If this implicit conversion fails, pybind11 will
|
||||
raise a ``UnicodeDecodeError``.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
m.def("std_string_return",
|
||||
[]() {
|
||||
return std::string("This string needs to be UTF-8 encoded");
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> isinstance(example.std_string_return(), str)
|
||||
True
|
||||
|
||||
|
||||
Because UTF-8 is inclusive of pure ASCII, there is never any issue with
|
||||
returning a pure ASCII string to Python. If there is any possibility that the
|
||||
string is not pure ASCII, it is necessary to ensure the encoding is valid
|
||||
UTF-8.
|
||||
|
||||
.. warning::
|
||||
|
||||
Implicit conversion assumes that a returned ``char *`` is null-terminated.
|
||||
If there is no null terminator a buffer overrun will occur.
|
||||
|
||||
Explicit conversions
|
||||
--------------------
|
||||
|
||||
If some C++ code constructs a ``std::string`` that is not a UTF-8 string, one
|
||||
can perform a explicit conversion and return a ``py::str`` object. Explicit
|
||||
conversion has the same overhead as implicit conversion.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// This uses the Python C API to convert Latin-1 to Unicode
|
||||
m.def("str_output",
|
||||
[]() {
|
||||
std::string s = "Send your r\xe9sum\xe9 to Alice in HR"; // Latin-1
|
||||
py::handle py_s = PyUnicode_DecodeLatin1(s.data(), s.length(), nullptr);
|
||||
if (!py_s) {
|
||||
throw py::error_already_set();
|
||||
}
|
||||
return py::reinterpret_steal<py::str>(py_s);
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> str_output()
|
||||
'Send your résumé to Alice in HR'
|
||||
|
||||
The `Python C API
|
||||
<https://docs.python.org/3/c-api/unicode.html#built-in-codecs>`_ provides
|
||||
several built-in codecs. Note that these all return *new* references, so
|
||||
use :cpp:func:`reinterpret_steal` when converting them to a :cpp:class:`str`.
|
||||
|
||||
|
||||
One could also use a third party encoding library such as libiconv to transcode
|
||||
to UTF-8.
|
||||
|
||||
Return C++ strings without conversion
|
||||
-------------------------------------
|
||||
|
||||
If the data in a C++ ``std::string`` does not represent text and should be
|
||||
returned to Python as ``bytes``, then one can return the data as a
|
||||
``py::bytes`` object.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
m.def("return_bytes",
|
||||
[]() {
|
||||
std::string s("\xba\xd0\xba\xd0"); // Not valid UTF-8
|
||||
return py::bytes(s); // Return the data without transcoding
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.return_bytes()
|
||||
b'\xba\xd0\xba\xd0'
|
||||
|
||||
|
||||
Note the asymmetry: pybind11 will convert ``bytes`` to ``std::string`` without
|
||||
encoding, but cannot convert ``std::string`` back to ``bytes`` implicitly.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
m.def("asymmetry",
|
||||
[](std::string s) { // Accepts str or bytes from Python
|
||||
return s; // Looks harmless, but implicitly converts to str
|
||||
}
|
||||
);
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> isinstance(example.asymmetry(b"have some bytes"), str)
|
||||
True
|
||||
|
||||
>>> example.asymmetry(b"\xba\xd0\xba\xd0") # invalid utf-8 as bytes
|
||||
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xba in position 0: invalid start byte
|
||||
|
||||
|
||||
Wide character strings
|
||||
======================
|
||||
|
||||
When a Python ``str`` is passed to a C++ function expecting ``std::wstring``,
|
||||
``wchar_t*``, ``std::u16string`` or ``std::u32string``, the ``str`` will be
|
||||
encoded to UTF-16 or UTF-32 depending on how the C++ compiler implements each
|
||||
type, in the platform's native endianness. When strings of these types are
|
||||
returned, they are assumed to contain valid UTF-16 or UTF-32, and will be
|
||||
decoded to Python ``str``.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
|
||||
m.def("set_window_text",
|
||||
[](HWND hwnd, std::wstring s) {
|
||||
// Call SetWindowText with null-terminated UTF-16 string
|
||||
::SetWindowText(hwnd, s.c_str());
|
||||
}
|
||||
);
|
||||
m.def("get_window_text",
|
||||
[](HWND hwnd) {
|
||||
const int buffer_size = ::GetWindowTextLength(hwnd) + 1;
|
||||
auto buffer = std::make_unique< wchar_t[] >(buffer_size);
|
||||
|
||||
::GetWindowText(hwnd, buffer.data(), buffer_size);
|
||||
|
||||
std::wstring text(buffer.get());
|
||||
|
||||
// wstring will be converted to Python str
|
||||
return text;
|
||||
}
|
||||
);
|
||||
|
||||
Strings in multibyte encodings such as Shift-JIS must transcoded to a
|
||||
UTF-8/16/32 before being returned to Python.
|
||||
|
||||
|
||||
Character literals
|
||||
==================
|
||||
|
||||
C++ functions that accept character literals as input will receive the first
|
||||
character of a Python ``str`` as their input. If the string is longer than one
|
||||
Unicode character, trailing characters will be ignored.
|
||||
|
||||
When a character literal is returned from C++ (such as a ``char`` or a
|
||||
``wchar_t``), it will be converted to a ``str`` that represents the single
|
||||
character.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
m.def("pass_char", [](char c) { return c; });
|
||||
m.def("pass_wchar", [](wchar_t w) { return w; });
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_char("A")
|
||||
'A'
|
||||
|
||||
While C++ will cast integers to character types (``char c = 0x65;``), pybind11
|
||||
does not convert Python integers to characters implicitly. The Python function
|
||||
``chr()`` can be used to convert integers to characters.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_char(0x65)
|
||||
TypeError
|
||||
|
||||
>>> example.pass_char(chr(0x65))
|
||||
'A'
|
||||
|
||||
If the desire is to work with an 8-bit integer, use ``int8_t`` or ``uint8_t``
|
||||
as the argument type.
|
||||
|
||||
Grapheme clusters
|
||||
-----------------
|
||||
|
||||
A single grapheme may be represented by two or more Unicode characters. For
|
||||
example 'é' is usually represented as U+00E9 but can also be expressed as the
|
||||
combining character sequence U+0065 U+0301 (that is, the letter 'e' followed by
|
||||
a combining acute accent). The combining character will be lost if the
|
||||
two-character sequence is passed as an argument, even though it renders as a
|
||||
single grapheme.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_wchar("é")
|
||||
'é'
|
||||
|
||||
>>> combining_e_acute = "e" + "\u0301"
|
||||
|
||||
>>> combining_e_acute
|
||||
'é'
|
||||
|
||||
>>> combining_e_acute == "é"
|
||||
False
|
||||
|
||||
>>> example.pass_wchar(combining_e_acute)
|
||||
'e'
|
||||
|
||||
Normalizing combining characters before passing the character literal to C++
|
||||
may resolve *some* of these issues:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> example.pass_wchar(unicodedata.normalize("NFC", combining_e_acute))
|
||||
'é'
|
||||
|
||||
In some languages (Thai for example), there are `graphemes that cannot be
|
||||
expressed as a single Unicode code point
|
||||
<http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries>`_, so there is
|
||||
no way to capture them in a C++ character type.
|
||||
|
||||
|
||||
C++17 string views
|
||||
==================
|
||||
|
||||
C++17 string views are automatically supported when compiling in C++17 mode.
|
||||
They follow the same rules for encoding and decoding as the corresponding STL
|
||||
string type (for example, a ``std::u16string_view`` argument will be passed
|
||||
UTF-16-encoded data, and a returned ``std::string_view`` will be decoded as
|
||||
UTF-8).
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
* `The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) <https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/>`_
|
||||
* `C++ - Using STL Strings at Win32 API Boundaries <https://msdn.microsoft.com/en-ca/magazine/mt238407.aspx>`_
|
1335
thirdparty/pybind11/docs/advanced/classes.rst
vendored
Normal file
1335
thirdparty/pybind11/docs/advanced/classes.rst
vendored
Normal file
File diff suppressed because it is too large
Load Diff
262
thirdparty/pybind11/docs/advanced/embedding.rst
vendored
Normal file
262
thirdparty/pybind11/docs/advanced/embedding.rst
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
.. _embedding:
|
||||
|
||||
Embedding the interpreter
|
||||
#########################
|
||||
|
||||
While pybind11 is mainly focused on extending Python using C++, it's also
|
||||
possible to do the reverse: embed the Python interpreter into a C++ program.
|
||||
All of the other documentation pages still apply here, so refer to them for
|
||||
general pybind11 usage. This section will cover a few extra things required
|
||||
for embedding.
|
||||
|
||||
Getting started
|
||||
===============
|
||||
|
||||
A basic executable with an embedded interpreter can be created with just a few
|
||||
lines of CMake and the ``pybind11::embed`` target, as shown below. For more
|
||||
information, see :doc:`/compiling`.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.27)
|
||||
project(example)
|
||||
|
||||
find_package(pybind11 REQUIRED) # or `add_subdirectory(pybind11)`
|
||||
|
||||
add_executable(example main.cpp)
|
||||
target_link_libraries(example PRIVATE pybind11::embed)
|
||||
|
||||
The essential structure of the ``main.cpp`` file looks like this:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/embed.h> // everything needed for embedding
|
||||
namespace py = pybind11;
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{}; // start the interpreter and keep it alive
|
||||
|
||||
py::print("Hello, World!"); // use the Python API
|
||||
}
|
||||
|
||||
The interpreter must be initialized before using any Python API, which includes
|
||||
all the functions and classes in pybind11. The RAII guard class ``scoped_interpreter``
|
||||
takes care of the interpreter lifetime. After the guard is destroyed, the interpreter
|
||||
shuts down and clears its memory. No Python functions can be called after this.
|
||||
|
||||
Executing Python code
|
||||
=====================
|
||||
|
||||
There are a few different ways to run Python code. One option is to use ``eval``,
|
||||
``exec`` or ``eval_file``, as explained in :ref:`eval`. Here is a quick example in
|
||||
the context of an executable with an embedded interpreter:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/embed.h>
|
||||
namespace py = pybind11;
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{};
|
||||
|
||||
py::exec(R"(
|
||||
kwargs = dict(name="World", number=42)
|
||||
message = "Hello, {name}! The answer is {number}".format(**kwargs)
|
||||
print(message)
|
||||
)");
|
||||
}
|
||||
|
||||
Alternatively, similar results can be achieved using pybind11's API (see
|
||||
:doc:`/advanced/pycpp/index` for more details).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/embed.h>
|
||||
namespace py = pybind11;
|
||||
using namespace py::literals;
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{};
|
||||
|
||||
auto kwargs = py::dict("name"_a="World", "number"_a=42);
|
||||
auto message = "Hello, {name}! The answer is {number}"_s.format(**kwargs);
|
||||
py::print(message);
|
||||
}
|
||||
|
||||
The two approaches can also be combined:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/embed.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace py::literals;
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{};
|
||||
|
||||
auto locals = py::dict("name"_a="World", "number"_a=42);
|
||||
py::exec(R"(
|
||||
message = "Hello, {name}! The answer is {number}".format(**locals())
|
||||
)", py::globals(), locals);
|
||||
|
||||
auto message = locals["message"].cast<std::string>();
|
||||
std::cout << message;
|
||||
}
|
||||
|
||||
Importing modules
|
||||
=================
|
||||
|
||||
Python modules can be imported using ``module_::import()``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::module_ sys = py::module_::import("sys");
|
||||
py::print(sys.attr("path"));
|
||||
|
||||
For convenience, the current working directory is included in ``sys.path`` when
|
||||
embedding the interpreter. This makes it easy to import local Python files:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
"""calc.py located in the working directory"""
|
||||
|
||||
|
||||
def add(i, j):
|
||||
return i + j
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::module_ calc = py::module_::import("calc");
|
||||
py::object result = calc.attr("add")(1, 2);
|
||||
int n = result.cast<int>();
|
||||
assert(n == 3);
|
||||
|
||||
Modules can be reloaded using ``module_::reload()`` if the source is modified e.g.
|
||||
by an external process. This can be useful in scenarios where the application
|
||||
imports a user defined data processing script which needs to be updated after
|
||||
changes by the user. Note that this function does not reload modules recursively.
|
||||
|
||||
.. _embedding_modules:
|
||||
|
||||
Adding embedded modules
|
||||
=======================
|
||||
|
||||
Embedded binary modules can be added using the ``PYBIND11_EMBEDDED_MODULE`` macro.
|
||||
Note that the definition must be placed at global scope. They can be imported
|
||||
like any other module.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/embed.h>
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_EMBEDDED_MODULE(fast_calc, m) {
|
||||
// `m` is a `py::module_` which is used to bind functions and classes
|
||||
m.def("add", [](int i, int j) {
|
||||
return i + j;
|
||||
});
|
||||
}
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{};
|
||||
|
||||
auto fast_calc = py::module_::import("fast_calc");
|
||||
auto result = fast_calc.attr("add")(1, 2).cast<int>();
|
||||
assert(result == 3);
|
||||
}
|
||||
|
||||
Unlike extension modules where only a single binary module can be created, on
|
||||
the embedded side an unlimited number of modules can be added using multiple
|
||||
``PYBIND11_EMBEDDED_MODULE`` definitions (as long as they have unique names).
|
||||
|
||||
These modules are added to Python's list of builtins, so they can also be
|
||||
imported in pure Python files loaded by the interpreter. Everything interacts
|
||||
naturally:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
"""py_module.py located in the working directory"""
|
||||
import cpp_module
|
||||
|
||||
a = cpp_module.a
|
||||
b = a + 1
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/embed.h>
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_EMBEDDED_MODULE(cpp_module, m) {
|
||||
m.attr("a") = 1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
py::scoped_interpreter guard{};
|
||||
|
||||
auto py_module = py::module_::import("py_module");
|
||||
|
||||
auto locals = py::dict("fmt"_a="{} + {} = {}", **py_module.attr("__dict__"));
|
||||
assert(locals["a"].cast<int>() == 1);
|
||||
assert(locals["b"].cast<int>() == 2);
|
||||
|
||||
py::exec(R"(
|
||||
c = a + b
|
||||
message = fmt.format(a, b, c)
|
||||
)", py::globals(), locals);
|
||||
|
||||
assert(locals["c"].cast<int>() == 3);
|
||||
assert(locals["message"].cast<std::string>() == "1 + 2 = 3");
|
||||
}
|
||||
|
||||
|
||||
Interpreter lifetime
|
||||
====================
|
||||
|
||||
The Python interpreter shuts down when ``scoped_interpreter`` is destroyed. After
|
||||
this, creating a new instance will restart the interpreter. Alternatively, the
|
||||
``initialize_interpreter`` / ``finalize_interpreter`` pair of functions can be used
|
||||
to directly set the state at any time.
|
||||
|
||||
Modules created with pybind11 can be safely re-initialized after the interpreter
|
||||
has been restarted. However, this may not apply to third-party extension modules.
|
||||
The issue is that Python itself cannot completely unload extension modules and
|
||||
there are several caveats with regard to interpreter restarting. In short, not
|
||||
all memory may be freed, either due to Python reference cycles or user-created
|
||||
global data. All the details can be found in the CPython documentation.
|
||||
|
||||
.. warning::
|
||||
|
||||
Creating two concurrent ``scoped_interpreter`` guards is a fatal error. So is
|
||||
calling ``initialize_interpreter`` for a second time after the interpreter
|
||||
has already been initialized.
|
||||
|
||||
Do not use the raw CPython API functions ``Py_Initialize`` and
|
||||
``Py_Finalize`` as these do not properly handle the lifetime of
|
||||
pybind11's internal data.
|
||||
|
||||
|
||||
Sub-interpreter support
|
||||
=======================
|
||||
|
||||
Creating multiple copies of ``scoped_interpreter`` is not possible because it
|
||||
represents the main Python interpreter. Sub-interpreters are something different
|
||||
and they do permit the existence of multiple interpreters. This is an advanced
|
||||
feature of the CPython API and should be handled with care. pybind11 does not
|
||||
currently offer a C++ interface for sub-interpreters, so refer to the CPython
|
||||
documentation for all the details regarding this feature.
|
||||
|
||||
We'll just mention a couple of caveats the sub-interpreters support in pybind11:
|
||||
|
||||
1. Sub-interpreters will not receive independent copies of embedded modules.
|
||||
Instead, these are shared and modifications in one interpreter may be
|
||||
reflected in another.
|
||||
|
||||
2. Managing multiple threads, multiple interpreters and the GIL can be
|
||||
challenging and there are several caveats here, even within the pure
|
||||
CPython API (please refer to the Python docs for details). As for
|
||||
pybind11, keep in mind that ``gil_scoped_release`` and ``gil_scoped_acquire``
|
||||
do not take sub-interpreters into account.
|
401
thirdparty/pybind11/docs/advanced/exceptions.rst
vendored
Normal file
401
thirdparty/pybind11/docs/advanced/exceptions.rst
vendored
Normal file
@ -0,0 +1,401 @@
|
||||
Exceptions
|
||||
##########
|
||||
|
||||
Built-in C++ to Python exception translation
|
||||
============================================
|
||||
|
||||
When Python calls C++ code through pybind11, pybind11 provides a C++ exception handler
|
||||
that will trap C++ exceptions, translate them to the corresponding Python exception,
|
||||
and raise them so that Python code can handle them.
|
||||
|
||||
pybind11 defines translations for ``std::exception`` and its standard
|
||||
subclasses, and several special exception classes that translate to specific
|
||||
Python exceptions. Note that these are not actually Python exceptions, so they
|
||||
cannot be examined using the Python C API. Instead, they are pure C++ objects
|
||||
that pybind11 will translate the corresponding Python exception when they arrive
|
||||
at its exception handler.
|
||||
|
||||
.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
|
||||
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| Exception thrown by C++ | Translated to Python exception type |
|
||||
+======================================+======================================+
|
||||
| :class:`std::exception` | ``RuntimeError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`std::bad_alloc` | ``MemoryError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`std::domain_error` | ``ValueError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`std::invalid_argument` | ``ValueError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`std::length_error` | ``ValueError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`std::out_of_range` | ``IndexError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`std::range_error` | ``ValueError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`std::overflow_error` | ``OverflowError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::stop_iteration` | ``StopIteration`` (used to implement |
|
||||
| | custom iterators) |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::index_error` | ``IndexError`` (used to indicate out |
|
||||
| | of bounds access in ``__getitem__``, |
|
||||
| | ``__setitem__``, etc.) |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::key_error` | ``KeyError`` (used to indicate out |
|
||||
| | of bounds access in ``__getitem__``, |
|
||||
| | ``__setitem__`` in dict-like |
|
||||
| | objects, etc.) |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::value_error` | ``ValueError`` (used to indicate |
|
||||
| | wrong value passed in |
|
||||
| | ``container.remove(...)``) |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::type_error` | ``TypeError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::buffer_error` | ``BufferError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::import_error` | ``ImportError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| :class:`pybind11::attribute_error` | ``AttributeError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| Any other exception | ``RuntimeError`` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
|
||||
Exception translation is not bidirectional. That is, *catching* the C++
|
||||
exceptions defined above will not trap exceptions that originate from
|
||||
Python. For that, catch :class:`pybind11::error_already_set`. See :ref:`below
|
||||
<handling_python_exceptions_cpp>` for further details.
|
||||
|
||||
There is also a special exception :class:`cast_error` that is thrown by
|
||||
:func:`handle::call` when the input arguments cannot be converted to Python
|
||||
objects.
|
||||
|
||||
Registering custom translators
|
||||
==============================
|
||||
|
||||
If the default exception conversion policy described above is insufficient,
|
||||
pybind11 also provides support for registering custom exception translators.
|
||||
Similar to pybind11 classes, exception translators can be local to the module
|
||||
they are defined in or global to the entire python session. To register a simple
|
||||
exception conversion that translates a C++ exception into a new Python exception
|
||||
using the C++ exception's ``what()`` method, a helper function is available:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_exception<CppExp>(module, "PyExp");
|
||||
|
||||
This call creates a Python exception class with the name ``PyExp`` in the given
|
||||
module and automatically converts any encountered exceptions of type ``CppExp``
|
||||
into Python exceptions of type ``PyExp``.
|
||||
|
||||
A matching function is available for registering a local exception translator:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_local_exception<CppExp>(module, "PyExp");
|
||||
|
||||
|
||||
It is possible to specify base class for the exception using the third
|
||||
parameter, a ``handle``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
|
||||
py::register_local_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
|
||||
|
||||
Then ``PyExp`` can be caught both as ``PyExp`` and ``RuntimeError``.
|
||||
|
||||
The class objects of the built-in Python exceptions are listed in the Python
|
||||
documentation on `Standard Exceptions <https://docs.python.org/3/c-api/exceptions.html#standard-exceptions>`_.
|
||||
The default base class is ``PyExc_Exception``.
|
||||
|
||||
When more advanced exception translation is needed, the functions
|
||||
``py::register_exception_translator(translator)`` and
|
||||
``py::register_local_exception_translator(translator)`` can be used to register
|
||||
functions that can translate arbitrary exception types (and which may include
|
||||
additional logic to do so). The functions takes a stateless callable (e.g. a
|
||||
function pointer or a lambda function without captured variables) with the call
|
||||
signature ``void(std::exception_ptr)``.
|
||||
|
||||
When a C++ exception is thrown, the registered exception translators are tried
|
||||
in reverse order of registration (i.e. the last registered translator gets the
|
||||
first shot at handling the exception). All local translators will be tried
|
||||
before a global translator is tried.
|
||||
|
||||
Inside the translator, ``std::rethrow_exception`` should be used within
|
||||
a try block to re-throw the exception. One or more catch clauses to catch
|
||||
the appropriate exceptions should then be used with each clause using
|
||||
``py::set_error()`` (see below).
|
||||
|
||||
To declare a custom Python exception type, declare a ``py::exception`` variable
|
||||
and use this in the associated exception translator (note: it is often useful
|
||||
to make this a static declaration when using it inside a lambda expression
|
||||
without requiring capturing).
|
||||
|
||||
The following example demonstrates this for a hypothetical exception classes
|
||||
``MyCustomException`` and ``OtherException``: the first is translated to a
|
||||
custom python exception ``MyCustomError``, while the second is translated to a
|
||||
standard python RuntimeError:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_CONSTINIT static py::gil_safe_call_once_and_store<py::object> exc_storage;
|
||||
exc_storage.call_once_and_store_result(
|
||||
[&]() { return py::exception<MyCustomException>(m, "MyCustomError"); });
|
||||
py::register_exception_translator([](std::exception_ptr p) {
|
||||
try {
|
||||
if (p) std::rethrow_exception(p);
|
||||
} catch (const MyCustomException &e) {
|
||||
py::set_error(exc_storage.get_stored(), e.what());
|
||||
} catch (const OtherException &e) {
|
||||
py::set_error(PyExc_RuntimeError, e.what());
|
||||
}
|
||||
});
|
||||
|
||||
Multiple exceptions can be handled by a single translator, as shown in the
|
||||
example above. If the exception is not caught by the current translator, the
|
||||
previously registered one gets a chance.
|
||||
|
||||
If none of the registered exception translators is able to handle the
|
||||
exception, it is handled by the default converter as described in the previous
|
||||
section.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_exceptions.cpp` contains examples
|
||||
of various custom exception translators and custom exception types.
|
||||
|
||||
.. note::
|
||||
|
||||
Call ``py::set_error()`` for every exception caught in a custom exception
|
||||
translator. Failure to do so will cause Python to crash with ``SystemError:
|
||||
error return without exception set``.
|
||||
|
||||
Exceptions that you do not plan to handle should simply not be caught, or
|
||||
may be explicitly (re-)thrown to delegate it to the other,
|
||||
previously-declared existing exception translators.
|
||||
|
||||
Note that ``libc++`` and ``libstdc++`` `behave differently under macOS
|
||||
<https://stackoverflow.com/questions/19496643/using-clang-fvisibility-hidden-and-typeinfo-and-type-erasure/28827430>`_
|
||||
with ``-fvisibility=hidden``. Therefore exceptions that are used across ABI
|
||||
boundaries need to be explicitly exported, as exercised in
|
||||
``tests/test_exceptions.h``. See also:
|
||||
"Problems with C++ exceptions" under `GCC Wiki <https://gcc.gnu.org/wiki/Visibility>`_.
|
||||
|
||||
|
||||
Local vs Global Exception Translators
|
||||
=====================================
|
||||
|
||||
When a global exception translator is registered, it will be applied across all
|
||||
modules in the reverse order of registration. This can create behavior where the
|
||||
order of module import influences how exceptions are translated.
|
||||
|
||||
If module1 has the following translator:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_exception_translator([](std::exception_ptr p) {
|
||||
try {
|
||||
if (p) std::rethrow_exception(p);
|
||||
} catch (const std::invalid_argument &e) {
|
||||
py::set_error(PyExc_ArgumentError, "module1 handled this");
|
||||
}
|
||||
}
|
||||
|
||||
and module2 has the following similar translator:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::register_exception_translator([](std::exception_ptr p) {
|
||||
try {
|
||||
if (p) std::rethrow_exception(p);
|
||||
} catch (const std::invalid_argument &e) {
|
||||
py::set_error(PyExc_ArgumentError, "module2 handled this");
|
||||
}
|
||||
}
|
||||
|
||||
then which translator handles the invalid_argument will be determined by the
|
||||
order that module1 and module2 are imported. Since exception translators are
|
||||
applied in the reverse order of registration, which ever module was imported
|
||||
last will "win" and that translator will be applied.
|
||||
|
||||
If there are multiple pybind11 modules that share exception types (either
|
||||
standard built-in or custom) loaded into a single python instance and
|
||||
consistent error handling behavior is needed, then local translators should be
|
||||
used.
|
||||
|
||||
Changing the previous example to use ``register_local_exception_translator``
|
||||
would mean that when invalid_argument is thrown in the module2 code, the
|
||||
module2 translator will always handle it, while in module1, the module1
|
||||
translator will do the same.
|
||||
|
||||
.. _handling_python_exceptions_cpp:
|
||||
|
||||
Handling exceptions from Python in C++
|
||||
======================================
|
||||
|
||||
When C++ calls Python functions, such as in a callback function or when
|
||||
manipulating Python objects, and Python raises an ``Exception``, pybind11
|
||||
converts the Python exception into a C++ exception of type
|
||||
:class:`pybind11::error_already_set` whose payload contains a C++ string textual
|
||||
summary and the actual Python exception. ``error_already_set`` is used to
|
||||
propagate Python exception back to Python (or possibly, handle them in C++).
|
||||
|
||||
.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
|
||||
|
||||
+--------------------------------------+--------------------------------------+
|
||||
| Exception raised in Python | Thrown as C++ exception type |
|
||||
+======================================+======================================+
|
||||
| Any Python ``Exception`` | :class:`pybind11::error_already_set` |
|
||||
+--------------------------------------+--------------------------------------+
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
try {
|
||||
// open("missing.txt", "r")
|
||||
auto file = py::module_::import("io").attr("open")("missing.txt", "r");
|
||||
auto text = file.attr("read")();
|
||||
file.attr("close")();
|
||||
} catch (py::error_already_set &e) {
|
||||
if (e.matches(PyExc_FileNotFoundError)) {
|
||||
py::print("missing.txt not found");
|
||||
} else if (e.matches(PyExc_PermissionError)) {
|
||||
py::print("missing.txt found but not accessible");
|
||||
} else {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
Note that C++ to Python exception translation does not apply here, since that is
|
||||
a method for translating C++ exceptions to Python, not vice versa. The error raised
|
||||
from Python is always ``error_already_set``.
|
||||
|
||||
This example illustrates this behavior:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
try {
|
||||
py::eval("raise ValueError('The Ring')");
|
||||
} catch (py::value_error &boromir) {
|
||||
// Boromir never gets the ring
|
||||
assert(false);
|
||||
} catch (py::error_already_set &frodo) {
|
||||
// Frodo gets the ring
|
||||
py::print("I will take the ring");
|
||||
}
|
||||
|
||||
try {
|
||||
// py::value_error is a request for pybind11 to raise a Python exception
|
||||
throw py::value_error("The ball");
|
||||
} catch (py::error_already_set &cat) {
|
||||
// cat won't catch the ball since
|
||||
// py::value_error is not a Python exception
|
||||
assert(false);
|
||||
} catch (py::value_error &dog) {
|
||||
// dog will catch the ball
|
||||
py::print("Run Spot run");
|
||||
throw; // Throw it again (pybind11 will raise ValueError)
|
||||
}
|
||||
|
||||
Handling errors from the Python C API
|
||||
=====================================
|
||||
|
||||
Where possible, use :ref:`pybind11 wrappers <wrappers>` instead of calling
|
||||
the Python C API directly. When calling the Python C API directly, in
|
||||
addition to manually managing reference counts, one must follow the pybind11
|
||||
error protocol, which is outlined here.
|
||||
|
||||
After calling the Python C API, if Python returns an error,
|
||||
``throw py::error_already_set();``, which allows pybind11 to deal with the
|
||||
exception and pass it back to the Python interpreter. This includes calls to
|
||||
the error setting functions such as ``py::set_error()``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::set_error(PyExc_TypeError, "C API type error demo");
|
||||
throw py::error_already_set();
|
||||
|
||||
// But it would be easier to simply...
|
||||
throw py::type_error("pybind11 wrapper type error");
|
||||
|
||||
Alternately, to ignore the error, call `PyErr_Clear
|
||||
<https://docs.python.org/3/c-api/exceptions.html#c.PyErr_Clear>`_.
|
||||
|
||||
Any Python error must be thrown or cleared, or Python/pybind11 will be left in
|
||||
an invalid state.
|
||||
|
||||
Chaining exceptions ('raise from')
|
||||
==================================
|
||||
|
||||
Python has a mechanism for indicating that exceptions were caused by other
|
||||
exceptions:
|
||||
|
||||
.. code-block:: py
|
||||
|
||||
try:
|
||||
print(1 / 0)
|
||||
except Exception as exc:
|
||||
raise RuntimeError("could not divide by zero") from exc
|
||||
|
||||
To do a similar thing in pybind11, you can use the ``py::raise_from`` function. It
|
||||
sets the current python error indicator, so to continue propagating the exception
|
||||
you should ``throw py::error_already_set()``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
try {
|
||||
py::eval("print(1 / 0"));
|
||||
} catch (py::error_already_set &e) {
|
||||
py::raise_from(e, PyExc_RuntimeError, "could not divide by zero");
|
||||
throw py::error_already_set();
|
||||
}
|
||||
|
||||
.. versionadded:: 2.8
|
||||
|
||||
.. _unraisable_exceptions:
|
||||
|
||||
Handling unraisable exceptions
|
||||
==============================
|
||||
|
||||
If a Python function invoked from a C++ destructor or any function marked
|
||||
``noexcept(true)`` (collectively, "noexcept functions") throws an exception, there
|
||||
is no way to propagate the exception, as such functions may not throw.
|
||||
Should they throw or fail to catch any exceptions in their call graph,
|
||||
the C++ runtime calls ``std::terminate()`` to abort immediately.
|
||||
|
||||
Similarly, Python exceptions raised in a class's ``__del__`` method do not
|
||||
propagate, but are logged by Python as an unraisable error. In Python 3.8+, a
|
||||
`system hook is triggered
|
||||
<https://docs.python.org/3/library/sys.html#sys.unraisablehook>`_
|
||||
and an auditing event is logged.
|
||||
|
||||
Any noexcept function should have a try-catch block that traps
|
||||
class:`error_already_set` (or any other exception that can occur). Note that
|
||||
pybind11 wrappers around Python exceptions such as
|
||||
:class:`pybind11::value_error` are *not* Python exceptions; they are C++
|
||||
exceptions that pybind11 catches and converts to Python exceptions. Noexcept
|
||||
functions cannot propagate these exceptions either. A useful approach is to
|
||||
convert them to Python exceptions and then ``discard_as_unraisable`` as shown
|
||||
below.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void nonthrowing_func() noexcept(true) {
|
||||
try {
|
||||
// ...
|
||||
} catch (py::error_already_set &eas) {
|
||||
// Discard the Python error using Python APIs, using the C++ magic
|
||||
// variable __func__. Python already knows the type and value and of the
|
||||
// exception object.
|
||||
eas.discard_as_unraisable(__func__);
|
||||
} catch (const std::exception &e) {
|
||||
// Log and discard C++ exceptions.
|
||||
third_party::log(e);
|
||||
}
|
||||
}
|
||||
|
||||
.. versionadded:: 2.6
|
614
thirdparty/pybind11/docs/advanced/functions.rst
vendored
Normal file
614
thirdparty/pybind11/docs/advanced/functions.rst
vendored
Normal file
@ -0,0 +1,614 @@
|
||||
Functions
|
||||
#########
|
||||
|
||||
Before proceeding with this section, make sure that you are already familiar
|
||||
with the basics of binding functions and classes, as explained in :doc:`/basics`
|
||||
and :doc:`/classes`. The following guide is applicable to both free and member
|
||||
functions, i.e. *methods* in Python.
|
||||
|
||||
.. _return_value_policies:
|
||||
|
||||
Return value policies
|
||||
=====================
|
||||
|
||||
Python and C++ use fundamentally different ways of managing the memory and
|
||||
lifetime of objects managed by them. This can lead to issues when creating
|
||||
bindings for functions that return a non-trivial type. Just by looking at the
|
||||
type information, it is not clear whether Python should take charge of the
|
||||
returned value and eventually free its resources, or if this is handled on the
|
||||
C++ side. For this reason, pybind11 provides several *return value policy*
|
||||
annotations that can be passed to the :func:`module_::def` and
|
||||
:func:`class_::def` functions. The default policy is
|
||||
:enum:`return_value_policy::automatic`.
|
||||
|
||||
Return value policies are tricky, and it's very important to get them right.
|
||||
Just to illustrate what can go wrong, consider the following simple example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
/* Function declaration */
|
||||
Data *get_data() { return _data; /* (pointer to a static data structure) */ }
|
||||
...
|
||||
|
||||
/* Binding code */
|
||||
m.def("get_data", &get_data); // <-- KABOOM, will cause crash when called from Python
|
||||
|
||||
What's going on here? When ``get_data()`` is called from Python, the return
|
||||
value (a native C++ type) must be wrapped to turn it into a usable Python type.
|
||||
In this case, the default return value policy (:enum:`return_value_policy::automatic`)
|
||||
causes pybind11 to assume ownership of the static ``_data`` instance.
|
||||
|
||||
When Python's garbage collector eventually deletes the Python
|
||||
wrapper, pybind11 will also attempt to delete the C++ instance (via ``operator
|
||||
delete()``) due to the implied ownership. At this point, the entire application
|
||||
will come crashing down, though errors could also be more subtle and involve
|
||||
silent data corruption.
|
||||
|
||||
In the above example, the policy :enum:`return_value_policy::reference` should have
|
||||
been specified so that the global data instance is only *referenced* without any
|
||||
implied transfer of ownership, i.e.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("get_data", &get_data, py::return_value_policy::reference);
|
||||
|
||||
On the other hand, this is not the right policy for many other situations,
|
||||
where ignoring ownership could lead to resource leaks.
|
||||
As a developer using pybind11, it's important to be familiar with the different
|
||||
return value policies, including which situation calls for which one of them.
|
||||
The following table provides an overview of available policies:
|
||||
|
||||
.. tabularcolumns:: |p{0.5\textwidth}|p{0.45\textwidth}|
|
||||
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
| Return value policy | Description |
|
||||
+==================================================+============================================================================+
|
||||
| :enum:`return_value_policy::take_ownership` | Reference an existing object (i.e. do not create a new copy) and take |
|
||||
| | ownership. Python will call the destructor and delete operator when the |
|
||||
| | object's reference count reaches zero. Undefined behavior ensues when the |
|
||||
| | C++ side does the same, or when the data was not dynamically allocated. |
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
| :enum:`return_value_policy::copy` | Create a new copy of the returned object, which will be owned by Python. |
|
||||
| | This policy is comparably safe because the lifetimes of the two instances |
|
||||
| | are decoupled. |
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
| :enum:`return_value_policy::move` | Use ``std::move`` to move the return value contents into a new instance |
|
||||
| | that will be owned by Python. This policy is comparably safe because the |
|
||||
| | lifetimes of the two instances (move source and destination) are decoupled.|
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
| :enum:`return_value_policy::reference` | Reference an existing object, but do not take ownership. The C++ side is |
|
||||
| | responsible for managing the object's lifetime and deallocating it when |
|
||||
| | it is no longer used. Warning: undefined behavior will ensue when the C++ |
|
||||
| | side deletes an object that is still referenced and used by Python. |
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
| :enum:`return_value_policy::reference_internal` | Indicates that the lifetime of the return value is tied to the lifetime |
|
||||
| | of a parent object, namely the implicit ``this``, or ``self`` argument of |
|
||||
| | the called method or property. Internally, this policy works just like |
|
||||
| | :enum:`return_value_policy::reference` but additionally applies a |
|
||||
| | ``keep_alive<0, 1>`` *call policy* (described in the next section) that |
|
||||
| | prevents the parent object from being garbage collected as long as the |
|
||||
| | return value is referenced by Python. This is the default policy for |
|
||||
| | property getters created via ``def_property``, ``def_readwrite``, etc. |
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
| :enum:`return_value_policy::automatic` | This policy falls back to the policy |
|
||||
| | :enum:`return_value_policy::take_ownership` when the return value is a |
|
||||
| | pointer. Otherwise, it uses :enum:`return_value_policy::move` or |
|
||||
| | :enum:`return_value_policy::copy` for rvalue and lvalue references, |
|
||||
| | respectively. See above for a description of what all of these different |
|
||||
| | policies do. This is the default policy for ``py::class_``-wrapped types. |
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
| :enum:`return_value_policy::automatic_reference` | As above, but use policy :enum:`return_value_policy::reference` when the |
|
||||
| | return value is a pointer. This is the default conversion policy for |
|
||||
| | function arguments when calling Python functions manually from C++ code |
|
||||
| | (i.e. via ``handle::operator()``) and the casters in ``pybind11/stl.h``. |
|
||||
| | You probably won't need to use this explicitly. |
|
||||
+--------------------------------------------------+----------------------------------------------------------------------------+
|
||||
|
||||
Return value policies can also be applied to properties:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class_<MyClass>(m, "MyClass")
|
||||
.def_property("data", &MyClass::getData, &MyClass::setData,
|
||||
py::return_value_policy::copy);
|
||||
|
||||
Technically, the code above applies the policy to both the getter and the
|
||||
setter function, however, the setter doesn't really care about *return*
|
||||
value policies which makes this a convenient terse syntax. Alternatively,
|
||||
targeted arguments can be passed through the :class:`cpp_function` constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class_<MyClass>(m, "MyClass")
|
||||
.def_property("data",
|
||||
py::cpp_function(&MyClass::getData, py::return_value_policy::copy),
|
||||
py::cpp_function(&MyClass::setData)
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Code with invalid return value policies might access uninitialized memory or
|
||||
free data structures multiple times, which can lead to hard-to-debug
|
||||
non-determinism and segmentation faults, hence it is worth spending the
|
||||
time to understand all the different options in the table above.
|
||||
|
||||
.. note::
|
||||
|
||||
One important aspect of the above policies is that they only apply to
|
||||
instances which pybind11 has *not* seen before, in which case the policy
|
||||
clarifies essential questions about the return value's lifetime and
|
||||
ownership. When pybind11 knows the instance already (as identified by its
|
||||
type and address in memory), it will return the existing Python object
|
||||
wrapper rather than creating a new copy.
|
||||
|
||||
.. note::
|
||||
|
||||
The next section on :ref:`call_policies` discusses *call policies* that can be
|
||||
specified *in addition* to a return value policy from the list above. Call
|
||||
policies indicate reference relationships that can involve both return values
|
||||
and parameters of functions.
|
||||
|
||||
.. note::
|
||||
|
||||
As an alternative to elaborate call policies and lifetime management logic,
|
||||
consider using smart pointers (see the section on :ref:`smart_pointers` for
|
||||
details). Smart pointers can tell whether an object is still referenced from
|
||||
C++ or Python, which generally eliminates the kinds of inconsistencies that
|
||||
can lead to crashes or undefined behavior. For functions returning smart
|
||||
pointers, it is not necessary to specify a return value policy.
|
||||
|
||||
.. _call_policies:
|
||||
|
||||
Additional call policies
|
||||
========================
|
||||
|
||||
In addition to the above return value policies, further *call policies* can be
|
||||
specified to indicate dependencies between parameters or ensure a certain state
|
||||
for the function call.
|
||||
|
||||
Keep alive
|
||||
----------
|
||||
|
||||
In general, this policy is required when the C++ object is any kind of container
|
||||
and another object is being added to the container. ``keep_alive<Nurse, Patient>``
|
||||
indicates that the argument with index ``Patient`` should be kept alive at least
|
||||
until the argument with index ``Nurse`` is freed by the garbage collector. Argument
|
||||
indices start at one, while zero refers to the return value. For methods, index
|
||||
``1`` refers to the implicit ``this`` pointer, while regular arguments begin at
|
||||
index ``2``. Arbitrarily many call policies can be specified. When a ``Nurse``
|
||||
with value ``None`` is detected at runtime, the call policy does nothing.
|
||||
|
||||
When the nurse is not a pybind11-registered type, the implementation internally
|
||||
relies on the ability to create a *weak reference* to the nurse object. When
|
||||
the nurse object is not a pybind11-registered type and does not support weak
|
||||
references, an exception will be thrown.
|
||||
|
||||
If you use an incorrect argument index, you will get a ``RuntimeError`` saying
|
||||
``Could not activate keep_alive!``. You should review the indices you're using.
|
||||
|
||||
Consider the following example: here, the binding code for a list append
|
||||
operation ties the lifetime of the newly added element to the underlying
|
||||
container:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<List>(m, "List")
|
||||
.def("append", &List::append, py::keep_alive<1, 2>());
|
||||
|
||||
For consistency, the argument indexing is identical for constructors. Index
|
||||
``1`` still refers to the implicit ``this`` pointer, i.e. the object which is
|
||||
being constructed. Index ``0`` refers to the return type which is presumed to
|
||||
be ``void`` when a constructor is viewed like a function. The following example
|
||||
ties the lifetime of the constructor element to the constructed object:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Nurse>(m, "Nurse")
|
||||
.def(py::init<Patient &>(), py::keep_alive<1, 2>());
|
||||
|
||||
.. note::
|
||||
|
||||
``keep_alive`` is analogous to the ``with_custodian_and_ward`` (if Nurse,
|
||||
Patient != 0) and ``with_custodian_and_ward_postcall`` (if Nurse/Patient ==
|
||||
0) policies from Boost.Python.
|
||||
|
||||
Call guard
|
||||
----------
|
||||
|
||||
The ``call_guard<T>`` policy allows any scope guard type ``T`` to be placed
|
||||
around the function call. For example, this definition:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("foo", foo, py::call_guard<T>());
|
||||
|
||||
is equivalent to the following pseudocode:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("foo", [](args...) {
|
||||
T scope_guard;
|
||||
return foo(args...); // forwarded arguments
|
||||
});
|
||||
|
||||
The only requirement is that ``T`` is default-constructible, but otherwise any
|
||||
scope guard will work. This is very useful in combination with ``gil_scoped_release``.
|
||||
See :ref:`gil`.
|
||||
|
||||
Multiple guards can also be specified as ``py::call_guard<T1, T2, T3...>``. The
|
||||
constructor order is left to right and destruction happens in reverse.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_call_policies.cpp` contains a complete example
|
||||
that demonstrates using `keep_alive` and `call_guard` in more detail.
|
||||
|
||||
.. _python_objects_as_args:
|
||||
|
||||
Python objects as arguments
|
||||
===========================
|
||||
|
||||
pybind11 exposes all major Python types using thin C++ wrapper classes. These
|
||||
wrapper classes can also be used as parameters of functions in bindings, which
|
||||
makes it possible to directly work with native Python types on the C++ side.
|
||||
For instance, the following statement iterates over a Python ``dict``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void print_dict(const py::dict& dict) {
|
||||
/* Easily interact with Python types */
|
||||
for (auto item : dict)
|
||||
std::cout << "key=" << std::string(py::str(item.first)) << ", "
|
||||
<< "value=" << std::string(py::str(item.second)) << std::endl;
|
||||
}
|
||||
|
||||
It can be exported:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("print_dict", &print_dict);
|
||||
|
||||
And used in Python as usual:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> print_dict({"foo": 123, "bar": "hello"})
|
||||
key=foo, value=123
|
||||
key=bar, value=hello
|
||||
|
||||
For more information on using Python objects in C++, see :doc:`/advanced/pycpp/index`.
|
||||
|
||||
Accepting \*args and \*\*kwargs
|
||||
===============================
|
||||
|
||||
Python provides a useful mechanism to define functions that accept arbitrary
|
||||
numbers of arguments and keyword arguments:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def generic(*args, **kwargs):
|
||||
... # do something with args and kwargs
|
||||
|
||||
Such functions can also be created using pybind11:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void generic(py::args args, const py::kwargs& kwargs) {
|
||||
/// .. do something with args
|
||||
if (kwargs)
|
||||
/// .. do something with kwargs
|
||||
}
|
||||
|
||||
/// Binding code
|
||||
m.def("generic", &generic);
|
||||
|
||||
The class ``py::args`` derives from ``py::tuple`` and ``py::kwargs`` derives
|
||||
from ``py::dict``.
|
||||
|
||||
You may also use just one or the other, and may combine these with other
|
||||
arguments. Note, however, that ``py::kwargs`` must always be the last argument
|
||||
of the function, and ``py::args`` implies that any further arguments are
|
||||
keyword-only (see :ref:`keyword_only_arguments`).
|
||||
|
||||
Please refer to the other examples for details on how to iterate over these,
|
||||
and on how to cast their entries into C++ objects. A demonstration is also
|
||||
available in ``tests/test_kwargs_and_defaults.cpp``.
|
||||
|
||||
.. note::
|
||||
|
||||
When combining \*args or \*\*kwargs with :ref:`keyword_args` you should
|
||||
*not* include ``py::arg`` tags for the ``py::args`` and ``py::kwargs``
|
||||
arguments.
|
||||
|
||||
Default arguments revisited
|
||||
===========================
|
||||
|
||||
The section on :ref:`default_args` previously discussed basic usage of default
|
||||
arguments using pybind11. One noteworthy aspect of their implementation is that
|
||||
default arguments are converted to Python objects right at declaration time.
|
||||
Consider the following example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<MyClass>("MyClass")
|
||||
.def("myFunction", py::arg("arg") = SomeType(123));
|
||||
|
||||
In this case, pybind11 must already be set up to deal with values of the type
|
||||
``SomeType`` (via a prior instantiation of ``py::class_<SomeType>``), or an
|
||||
exception will be thrown.
|
||||
|
||||
Another aspect worth highlighting is that the "preview" of the default argument
|
||||
in the function signature is generated using the object's ``__repr__`` method.
|
||||
If not available, the signature may not be very helpful, e.g.:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
FUNCTIONS
|
||||
...
|
||||
| myFunction(...)
|
||||
| Signature : (MyClass, arg : SomeType = <SomeType object at 0x101b7b080>) -> NoneType
|
||||
...
|
||||
|
||||
The first way of addressing this is by defining ``SomeType.__repr__``.
|
||||
Alternatively, it is possible to specify the human-readable preview of the
|
||||
default argument manually using the ``arg_v`` notation:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<MyClass>("MyClass")
|
||||
.def("myFunction", py::arg_v("arg", SomeType(123), "SomeType(123)"));
|
||||
|
||||
Sometimes it may be necessary to pass a null pointer value as a default
|
||||
argument. In this case, remember to cast it to the underlying type in question,
|
||||
like so:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<MyClass>("MyClass")
|
||||
.def("myFunction", py::arg("arg") = static_cast<SomeType *>(nullptr));
|
||||
|
||||
.. _keyword_only_arguments:
|
||||
|
||||
Keyword-only arguments
|
||||
======================
|
||||
|
||||
Python implements keyword-only arguments by specifying an unnamed ``*``
|
||||
argument in a function definition:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def f(a, *, b): # a can be positional or via keyword; b must be via keyword
|
||||
pass
|
||||
|
||||
|
||||
f(a=1, b=2) # good
|
||||
f(b=2, a=1) # good
|
||||
f(1, b=2) # good
|
||||
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
|
||||
|
||||
Pybind11 provides a ``py::kw_only`` object that allows you to implement
|
||||
the same behaviour by specifying the object between positional and keyword-only
|
||||
argument annotations when registering the function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("f", [](int a, int b) { /* ... */ },
|
||||
py::arg("a"), py::kw_only(), py::arg("b"));
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
A ``py::args`` argument implies that any following arguments are keyword-only,
|
||||
as if ``py::kw_only()`` had been specified in the same relative location of the
|
||||
argument list as the ``py::args`` argument. The ``py::kw_only()`` may be
|
||||
included to be explicit about this, but is not required.
|
||||
|
||||
.. versionchanged:: 2.9
|
||||
This can now be combined with ``py::args``. Before, ``py::args`` could only
|
||||
occur at the end of the argument list, or immediately before a ``py::kwargs``
|
||||
argument at the end.
|
||||
|
||||
|
||||
Positional-only arguments
|
||||
=========================
|
||||
|
||||
Python 3.8 introduced a new positional-only argument syntax, using ``/`` in the
|
||||
function definition (note that this has been a convention for CPython
|
||||
positional arguments, such as in ``pow()``, since Python 2). You can
|
||||
do the same thing in any version of Python using ``py::pos_only()``:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("f", [](int a, int b) { /* ... */ },
|
||||
py::arg("a"), py::pos_only(), py::arg("b"));
|
||||
|
||||
You now cannot give argument ``a`` by keyword. This can be combined with
|
||||
keyword-only arguments, as well.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
.. _nonconverting_arguments:
|
||||
|
||||
Non-converting arguments
|
||||
========================
|
||||
|
||||
Certain argument types may support conversion from one type to another. Some
|
||||
examples of conversions are:
|
||||
|
||||
* :ref:`implicit_conversions` declared using ``py::implicitly_convertible<A,B>()``
|
||||
* Calling a method accepting a double with an integer argument
|
||||
* Calling a ``std::complex<float>`` argument with a non-complex python type
|
||||
(for example, with a float). (Requires the optional ``pybind11/complex.h``
|
||||
header).
|
||||
* Calling a function taking an Eigen matrix reference with a numpy array of the
|
||||
wrong type or of an incompatible data layout. (Requires the optional
|
||||
``pybind11/eigen.h`` header).
|
||||
|
||||
This behaviour is sometimes undesirable: the binding code may prefer to raise
|
||||
an error rather than convert the argument. This behaviour can be obtained
|
||||
through ``py::arg`` by calling the ``.noconvert()`` method of the ``py::arg``
|
||||
object, such as:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
|
||||
m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
|
||||
|
||||
Attempting the call the second function (the one without ``.noconvert()``) with
|
||||
an integer will succeed, but attempting to call the ``.noconvert()`` version
|
||||
will fail with a ``TypeError``:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> floats_preferred(4)
|
||||
2.0
|
||||
>>> floats_only(4)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: floats_only(): incompatible function arguments. The following argument types are supported:
|
||||
1. (f: float) -> float
|
||||
|
||||
Invoked with: 4
|
||||
|
||||
You may, of course, combine this with the :var:`_a` shorthand notation (see
|
||||
:ref:`keyword_args`) and/or :ref:`default_args`. It is also permitted to omit
|
||||
the argument name by using the ``py::arg()`` constructor without an argument
|
||||
name, i.e. by specifying ``py::arg().noconvert()``.
|
||||
|
||||
.. note::
|
||||
|
||||
When specifying ``py::arg`` options it is necessary to provide the same
|
||||
number of options as the bound function has arguments. Thus if you want to
|
||||
enable no-convert behaviour for just one of several arguments, you will
|
||||
need to specify a ``py::arg()`` annotation for each argument with the
|
||||
no-convert argument modified to ``py::arg().noconvert()``.
|
||||
|
||||
.. _none_arguments:
|
||||
|
||||
Allow/Prohibiting None arguments
|
||||
================================
|
||||
|
||||
When a C++ type registered with :class:`py::class_` is passed as an argument to
|
||||
a function taking the instance as pointer or shared holder (e.g. ``shared_ptr``
|
||||
or a custom, copyable holder as described in :ref:`smart_pointers`), pybind
|
||||
allows ``None`` to be passed from Python which results in calling the C++
|
||||
function with ``nullptr`` (or an empty holder) for the argument.
|
||||
|
||||
To explicitly enable or disable this behaviour, using the
|
||||
``.none`` method of the :class:`py::arg` object:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Dog>(m, "Dog").def(py::init<>());
|
||||
py::class_<Cat>(m, "Cat").def(py::init<>());
|
||||
m.def("bark", [](Dog *dog) -> std::string {
|
||||
if (dog) return "woof!"; /* Called with a Dog instance */
|
||||
else return "(no dog)"; /* Called with None, dog == nullptr */
|
||||
}, py::arg("dog").none(true));
|
||||
m.def("meow", [](Cat *cat) -> std::string {
|
||||
// Can't be called with None argument
|
||||
return "meow";
|
||||
}, py::arg("cat").none(false));
|
||||
|
||||
With the above, the Python call ``bark(None)`` will return the string ``"(no
|
||||
dog)"``, while attempting to call ``meow(None)`` will raise a ``TypeError``:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from animals import Dog, Cat, bark, meow
|
||||
>>> bark(Dog())
|
||||
'woof!'
|
||||
>>> meow(Cat())
|
||||
'meow'
|
||||
>>> bark(None)
|
||||
'(no dog)'
|
||||
>>> meow(None)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: meow(): incompatible function arguments. The following argument types are supported:
|
||||
1. (cat: animals.Cat) -> str
|
||||
|
||||
Invoked with: None
|
||||
|
||||
The default behaviour when the tag is unspecified is to allow ``None``.
|
||||
|
||||
.. note::
|
||||
|
||||
Even when ``.none(true)`` is specified for an argument, ``None`` will be converted to a
|
||||
``nullptr`` *only* for custom and :ref:`opaque <opaque>` types. Pointers to built-in types
|
||||
(``double *``, ``int *``, ...) and STL types (``std::vector<T> *``, ...; if ``pybind11/stl.h``
|
||||
is included) are copied when converted to C++ (see :doc:`/advanced/cast/overview`) and will
|
||||
not allow ``None`` as argument. To pass optional argument of these copied types consider
|
||||
using ``std::optional<T>``
|
||||
|
||||
.. _overload_resolution:
|
||||
|
||||
Overload resolution order
|
||||
=========================
|
||||
|
||||
When a function or method with multiple overloads is called from Python,
|
||||
pybind11 determines which overload to call in two passes. The first pass
|
||||
attempts to call each overload without allowing argument conversion (as if
|
||||
every argument had been specified as ``py::arg().noconvert()`` as described
|
||||
above).
|
||||
|
||||
If no overload succeeds in the no-conversion first pass, a second pass is
|
||||
attempted in which argument conversion is allowed (except where prohibited via
|
||||
an explicit ``py::arg().noconvert()`` attribute in the function definition).
|
||||
|
||||
If the second pass also fails a ``TypeError`` is raised.
|
||||
|
||||
Within each pass, overloads are tried in the order they were registered with
|
||||
pybind11. If the ``py::prepend()`` tag is added to the definition, a function
|
||||
can be placed at the beginning of the overload sequence instead, allowing user
|
||||
overloads to proceed built in functions.
|
||||
|
||||
What this means in practice is that pybind11 will prefer any overload that does
|
||||
not require conversion of arguments to an overload that does, but otherwise
|
||||
prefers earlier-defined overloads to later-defined ones.
|
||||
|
||||
.. note::
|
||||
|
||||
pybind11 does *not* further prioritize based on the number/pattern of
|
||||
overloaded arguments. That is, pybind11 does not prioritize a function
|
||||
requiring one conversion over one requiring three, but only prioritizes
|
||||
overloads requiring no conversion at all to overloads that require
|
||||
conversion of at least one argument.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
The ``py::prepend()`` tag.
|
||||
|
||||
Binding functions with template parameters
|
||||
==========================================
|
||||
|
||||
You can bind functions that have template parameters. Here's a function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
template <typename T>
|
||||
void set(T t);
|
||||
|
||||
C++ templates cannot be instantiated at runtime, so you cannot bind the
|
||||
non-instantiated function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// BROKEN (this will not compile)
|
||||
m.def("set", &set);
|
||||
|
||||
You must bind each instantiated function template separately. You may bind
|
||||
each instantiation with the same name, which will be treated the same as
|
||||
an overloaded function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("set", &set<int>);
|
||||
m.def("set", &set<std::string>);
|
||||
|
||||
Sometimes it's more clear to bind them with separate names, which is also
|
||||
an option:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("setInt", &set<int>);
|
||||
m.def("setString", &set<std::string>);
|
429
thirdparty/pybind11/docs/advanced/misc.rst
vendored
Normal file
429
thirdparty/pybind11/docs/advanced/misc.rst
vendored
Normal file
@ -0,0 +1,429 @@
|
||||
Miscellaneous
|
||||
#############
|
||||
|
||||
.. _macro_notes:
|
||||
|
||||
General notes regarding convenience macros
|
||||
==========================================
|
||||
|
||||
pybind11 provides a few convenience macros such as
|
||||
:func:`PYBIND11_DECLARE_HOLDER_TYPE` and ``PYBIND11_OVERRIDE_*``. Since these
|
||||
are "just" macros that are evaluated in the preprocessor (which has no concept
|
||||
of types), they *will* get confused by commas in a template argument; for
|
||||
example, consider:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_OVERRIDE(MyReturnType<T1, T2>, Class<T3, T4>, func)
|
||||
|
||||
The limitation of the C preprocessor interprets this as five arguments (with new
|
||||
arguments beginning after each comma) rather than three. To get around this,
|
||||
there are two alternatives: you can use a type alias, or you can wrap the type
|
||||
using the ``PYBIND11_TYPE`` macro:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Version 1: using a type alias
|
||||
using ReturnType = MyReturnType<T1, T2>;
|
||||
using ClassType = Class<T3, T4>;
|
||||
PYBIND11_OVERRIDE(ReturnType, ClassType, func);
|
||||
|
||||
// Version 2: using the PYBIND11_TYPE macro:
|
||||
PYBIND11_OVERRIDE(PYBIND11_TYPE(MyReturnType<T1, T2>),
|
||||
PYBIND11_TYPE(Class<T3, T4>), func)
|
||||
|
||||
The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
|
||||
|
||||
.. _gil:
|
||||
|
||||
Global Interpreter Lock (GIL)
|
||||
=============================
|
||||
|
||||
The Python C API dictates that the Global Interpreter Lock (GIL) must always
|
||||
be held by the current thread to safely access Python objects. As a result,
|
||||
when Python calls into C++ via pybind11 the GIL must be held, and pybind11
|
||||
will never implicitly release the GIL.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void my_function() {
|
||||
/* GIL is held when this function is called from Python */
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
m.def("my_function", &my_function);
|
||||
}
|
||||
|
||||
pybind11 will ensure that the GIL is held when it knows that it is calling
|
||||
Python code. For example, if a Python callback is passed to C++ code via
|
||||
``std::function``, when C++ code calls the function the built-in wrapper
|
||||
will acquire the GIL before calling the Python callback. Similarly, the
|
||||
``PYBIND11_OVERRIDE`` family of macros will acquire the GIL before calling
|
||||
back into Python.
|
||||
|
||||
When writing C++ code that is called from other C++ code, if that code accesses
|
||||
Python state, it must explicitly acquire and release the GIL.
|
||||
|
||||
The classes :class:`gil_scoped_release` and :class:`gil_scoped_acquire` can be
|
||||
used to acquire and release the global interpreter lock in the body of a C++
|
||||
function call. In this way, long-running C++ code can be parallelized using
|
||||
multiple Python threads, **but great care must be taken** when any
|
||||
:class:`gil_scoped_release` appear: if there is any way that the C++ code
|
||||
can access Python objects, :class:`gil_scoped_acquire` should be used to
|
||||
reacquire the GIL. Taking :ref:`overriding_virtuals` as an example, this
|
||||
could be realized as follows (important changes highlighted):
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 8,30,31
|
||||
|
||||
class PyAnimal : public Animal {
|
||||
public:
|
||||
/* Inherit the constructors */
|
||||
using Animal::Animal;
|
||||
|
||||
/* Trampoline (need one for each virtual function) */
|
||||
std::string go(int n_times) {
|
||||
/* PYBIND11_OVERRIDE_PURE will acquire the GIL before accessing Python state */
|
||||
PYBIND11_OVERRIDE_PURE(
|
||||
std::string, /* Return type */
|
||||
Animal, /* Parent class */
|
||||
go, /* Name of function */
|
||||
n_times /* Argument(s) */
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::class_<Animal, PyAnimal> animal(m, "Animal");
|
||||
animal
|
||||
.def(py::init<>())
|
||||
.def("go", &Animal::go);
|
||||
|
||||
py::class_<Dog>(m, "Dog", animal)
|
||||
.def(py::init<>());
|
||||
|
||||
m.def("call_go", [](Animal *animal) -> std::string {
|
||||
// GIL is held when called from Python code. Release GIL before
|
||||
// calling into (potentially long-running) C++ code
|
||||
py::gil_scoped_release release;
|
||||
return call_go(animal);
|
||||
});
|
||||
}
|
||||
|
||||
The ``call_go`` wrapper can also be simplified using the ``call_guard`` policy
|
||||
(see :ref:`call_policies`) which yields the same result:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("call_go", &call_go, py::call_guard<py::gil_scoped_release>());
|
||||
|
||||
|
||||
Common Sources Of Global Interpreter Lock Errors
|
||||
==================================================================
|
||||
|
||||
Failing to properly hold the Global Interpreter Lock (GIL) is one of the
|
||||
more common sources of bugs within code that uses pybind11. If you are
|
||||
running into GIL related errors, we highly recommend you consult the
|
||||
following checklist.
|
||||
|
||||
- Do you have any global variables that are pybind11 objects or invoke
|
||||
pybind11 functions in either their constructor or destructor? You are generally
|
||||
not allowed to invoke any Python function in a global static context. We recommend
|
||||
using lazy initialization and then intentionally leaking at the end of the program.
|
||||
|
||||
- Do you have any pybind11 objects that are members of other C++ structures? One
|
||||
commonly overlooked requirement is that pybind11 objects have to increase their reference count
|
||||
whenever their copy constructor is called. Thus, you need to be holding the GIL to invoke
|
||||
the copy constructor of any C++ class that has a pybind11 member. This can sometimes be very
|
||||
tricky to track for complicated programs Think carefully when you make a pybind11 object
|
||||
a member in another struct.
|
||||
|
||||
- C++ destructors that invoke Python functions can be particularly troublesome as
|
||||
destructors can sometimes get invoked in weird and unexpected circumstances as a result
|
||||
of exceptions.
|
||||
|
||||
- You should try running your code in a debug build. That will enable additional assertions
|
||||
within pybind11 that will throw exceptions on certain GIL handling errors
|
||||
(reference counting operations).
|
||||
|
||||
Binding sequence data types, iterators, the slicing protocol, etc.
|
||||
==================================================================
|
||||
|
||||
Please refer to the supplemental example for details.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_sequences_and_iterators.cpp` contains a
|
||||
complete example that shows how to bind a sequence data type, including
|
||||
length queries (``__len__``), iterators (``__iter__``), the slicing
|
||||
protocol and other kinds of useful operations.
|
||||
|
||||
|
||||
Partitioning code over multiple extension modules
|
||||
=================================================
|
||||
|
||||
It's straightforward to split binding code over multiple extension modules,
|
||||
while referencing types that are declared elsewhere. Everything "just" works
|
||||
without any special precautions. One exception to this rule occurs when
|
||||
extending a type declared in another extension module. Recall the basic example
|
||||
from Section :ref:`inheritance`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet> pet(m, "Pet");
|
||||
pet.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
py::class_<Dog>(m, "Dog", pet /* <- specify parent */)
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
Suppose now that ``Pet`` bindings are defined in a module named ``basic``,
|
||||
whereas the ``Dog`` bindings are defined somewhere else. The challenge is of
|
||||
course that the variable ``pet`` is not available anymore though it is needed
|
||||
to indicate the inheritance relationship to the constructor of ``class_<Dog>``.
|
||||
However, it can be acquired as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::object pet = (py::object) py::module_::import("basic").attr("Pet");
|
||||
|
||||
py::class_<Dog>(m, "Dog", pet)
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
Alternatively, you can specify the base class as a template parameter option to
|
||||
``class_``, which performs an automated lookup of the corresponding Python
|
||||
type. Like the above code, however, this also requires invoking the ``import``
|
||||
function once to ensure that the pybind11 binding code of the module ``basic``
|
||||
has been executed:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::module_::import("basic");
|
||||
|
||||
py::class_<Dog, Pet>(m, "Dog")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
Naturally, both methods will fail when there are cyclic dependencies.
|
||||
|
||||
Note that pybind11 code compiled with hidden-by-default symbol visibility (e.g.
|
||||
via the command line flag ``-fvisibility=hidden`` on GCC/Clang), which is
|
||||
required for proper pybind11 functionality, can interfere with the ability to
|
||||
access types defined in another extension module. Working around this requires
|
||||
manually exporting types that are accessed by multiple extension modules;
|
||||
pybind11 provides a macro to do just this:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class PYBIND11_EXPORT Dog : public Animal {
|
||||
...
|
||||
};
|
||||
|
||||
Note also that it is possible (although would rarely be required) to share arbitrary
|
||||
C++ objects between extension modules at runtime. Internal library data is shared
|
||||
between modules using capsule machinery [#f6]_ which can be also utilized for
|
||||
storing, modifying and accessing user-defined data. Note that an extension module
|
||||
will "see" other extensions' data if and only if they were built with the same
|
||||
pybind11 version. Consider the following example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
auto data = reinterpret_cast<MyData *>(py::get_shared_data("mydata"));
|
||||
if (!data)
|
||||
data = static_cast<MyData *>(py::set_shared_data("mydata", new MyData(42)));
|
||||
|
||||
If the above snippet was used in several separately compiled extension modules,
|
||||
the first one to be imported would create a ``MyData`` instance and associate
|
||||
a ``"mydata"`` key with a pointer to it. Extensions that are imported later
|
||||
would be then able to access the data behind the same pointer.
|
||||
|
||||
.. [#f6] https://docs.python.org/3/extending/extending.html#using-capsules
|
||||
|
||||
Module Destructors
|
||||
==================
|
||||
|
||||
pybind11 does not provide an explicit mechanism to invoke cleanup code at
|
||||
module destruction time. In rare cases where such functionality is required, it
|
||||
is possible to emulate it using Python capsules or weak references with a
|
||||
destruction callback.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
auto cleanup_callback = []() {
|
||||
// perform cleanup here -- this function is called with the GIL held
|
||||
};
|
||||
|
||||
m.add_object("_cleanup", py::capsule(cleanup_callback));
|
||||
|
||||
This approach has the potential downside that instances of classes exposed
|
||||
within the module may still be alive when the cleanup callback is invoked
|
||||
(whether this is acceptable will generally depend on the application).
|
||||
|
||||
Alternatively, the capsule may also be stashed within a type object, which
|
||||
ensures that it not called before all instances of that type have been
|
||||
collected:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
auto cleanup_callback = []() { /* ... */ };
|
||||
m.attr("BaseClass").attr("_cleanup") = py::capsule(cleanup_callback);
|
||||
|
||||
Both approaches also expose a potentially dangerous ``_cleanup`` attribute in
|
||||
Python, which may be undesirable from an API standpoint (a premature explicit
|
||||
call from Python might lead to undefined behavior). Yet another approach that
|
||||
avoids this issue involves weak reference with a cleanup callback:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Register a callback function that is invoked when the BaseClass object is collected
|
||||
py::cpp_function cleanup_callback(
|
||||
[](py::handle weakref) {
|
||||
// perform cleanup here -- this function is called with the GIL held
|
||||
|
||||
weakref.dec_ref(); // release weak reference
|
||||
}
|
||||
);
|
||||
|
||||
// Create a weak reference with a cleanup callback and initially leak it
|
||||
(void) py::weakref(m.attr("BaseClass"), cleanup_callback).release();
|
||||
|
||||
.. note::
|
||||
|
||||
PyPy does not garbage collect objects when the interpreter exits. An alternative
|
||||
approach (which also works on CPython) is to use the :py:mod:`atexit` module [#f7]_,
|
||||
for example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
auto atexit = py::module_::import("atexit");
|
||||
atexit.attr("register")(py::cpp_function([]() {
|
||||
// perform cleanup here -- this function is called with the GIL held
|
||||
}));
|
||||
|
||||
.. [#f7] https://docs.python.org/3/library/atexit.html
|
||||
|
||||
|
||||
Generating documentation using Sphinx
|
||||
=====================================
|
||||
|
||||
Sphinx [#f4]_ has the ability to inspect the signatures and documentation
|
||||
strings in pybind11-based extension modules to automatically generate beautiful
|
||||
documentation in a variety formats. The python_example repository [#f5]_ contains a
|
||||
simple example repository which uses this approach.
|
||||
|
||||
There are two potential gotchas when using this approach: first, make sure that
|
||||
the resulting strings do not contain any :kbd:`TAB` characters, which break the
|
||||
docstring parsing routines. You may want to use C++11 raw string literals,
|
||||
which are convenient for multi-line comments. Conveniently, any excess
|
||||
indentation will be automatically be removed by Sphinx. However, for this to
|
||||
work, it is important that all lines are indented consistently, i.e.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// ok
|
||||
m.def("foo", &foo, R"mydelimiter(
|
||||
The foo function
|
||||
|
||||
Parameters
|
||||
----------
|
||||
)mydelimiter");
|
||||
|
||||
// *not ok*
|
||||
m.def("foo", &foo, R"mydelimiter(The foo function
|
||||
|
||||
Parameters
|
||||
----------
|
||||
)mydelimiter");
|
||||
|
||||
By default, pybind11 automatically generates and prepends a signature to the docstring of a function
|
||||
registered with ``module_::def()`` and ``class_::def()``. Sometimes this
|
||||
behavior is not desirable, because you want to provide your own signature or remove
|
||||
the docstring completely to exclude the function from the Sphinx documentation.
|
||||
The class ``options`` allows you to selectively suppress auto-generated signatures:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::options options;
|
||||
options.disable_function_signatures();
|
||||
|
||||
m.def("add", [](int a, int b) { return a + b; }, "A function which adds two numbers");
|
||||
}
|
||||
|
||||
pybind11 also appends all members of an enum to the resulting enum docstring.
|
||||
This default behavior can be disabled by using the ``disable_enum_members_docstring()``
|
||||
function of the ``options`` class.
|
||||
|
||||
With ``disable_user_defined_docstrings()`` all user defined docstrings of
|
||||
``module_::def()``, ``class_::def()`` and ``enum_()`` are disabled, but the
|
||||
function signatures and enum members are included in the docstring, unless they
|
||||
are disabled separately.
|
||||
|
||||
Note that changes to the settings affect only function bindings created during the
|
||||
lifetime of the ``options`` instance. When it goes out of scope at the end of the module's init function,
|
||||
the default settings are restored to prevent unwanted side effects.
|
||||
|
||||
.. [#f4] http://www.sphinx-doc.org
|
||||
.. [#f5] http://github.com/pybind/python_example
|
||||
|
||||
.. _avoiding-cpp-types-in-docstrings:
|
||||
|
||||
Avoiding C++ types in docstrings
|
||||
================================
|
||||
|
||||
Docstrings are generated at the time of the declaration, e.g. when ``.def(...)`` is called.
|
||||
At this point parameter and return types should be known to pybind11.
|
||||
If a custom type is not exposed yet through a ``py::class_`` constructor or a custom type caster,
|
||||
its C++ type name will be used instead to generate the signature in the docstring:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
| __init__(...)
|
||||
| __init__(self: example.Foo, arg0: ns::Bar) -> None
|
||||
^^^^^^^
|
||||
|
||||
|
||||
This limitation can be circumvented by ensuring that C++ classes are registered with pybind11
|
||||
before they are used as a parameter or return type of a function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
|
||||
auto pyFoo = py::class_<ns::Foo>(m, "Foo");
|
||||
auto pyBar = py::class_<ns::Bar>(m, "Bar");
|
||||
|
||||
pyFoo.def(py::init<const ns::Bar&>());
|
||||
pyBar.def(py::init<const ns::Foo&>());
|
||||
}
|
||||
|
||||
Setting inner type hints in docstrings
|
||||
======================================
|
||||
|
||||
When you use pybind11 wrappers for ``list``, ``dict``, and other generic python
|
||||
types, the docstring will just display the generic type. You can convey the
|
||||
inner types in the docstring by using a special 'typed' version of the generic
|
||||
type.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
m.def("pass_list_of_str", [](py::typing::List<py::str> arg) {
|
||||
// arg can be used just like py::list
|
||||
));
|
||||
}
|
||||
|
||||
The resulting docstring will be ``pass_list_of_str(arg0: list[str]) -> None``.
|
||||
|
||||
The following special types are available in ``pybind11/typing.h``:
|
||||
|
||||
* ``py::Tuple<Args...>``
|
||||
* ``py::Dict<K, V>``
|
||||
* ``py::List<V>``
|
||||
* ``py::Set<V>``
|
||||
* ``py::Callable<Signature>``
|
||||
|
||||
.. warning:: Just like in python, these are merely hints. They don't actually
|
||||
enforce the types of their contents at runtime or compile time.
|
13
thirdparty/pybind11/docs/advanced/pycpp/index.rst
vendored
Normal file
13
thirdparty/pybind11/docs/advanced/pycpp/index.rst
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
Python C++ interface
|
||||
####################
|
||||
|
||||
pybind11 exposes Python types and functions using thin C++ wrappers, which
|
||||
makes it possible to conveniently call Python code from C++ without resorting
|
||||
to Python's C API.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
object
|
||||
numpy
|
||||
utilities
|
455
thirdparty/pybind11/docs/advanced/pycpp/numpy.rst
vendored
Normal file
455
thirdparty/pybind11/docs/advanced/pycpp/numpy.rst
vendored
Normal file
@ -0,0 +1,455 @@
|
||||
.. _numpy:
|
||||
|
||||
NumPy
|
||||
#####
|
||||
|
||||
Buffer protocol
|
||||
===============
|
||||
|
||||
Python supports an extremely general and convenient approach for exchanging
|
||||
data between plugin libraries. Types can expose a buffer view [#f2]_, which
|
||||
provides fast direct access to the raw internal data representation. Suppose we
|
||||
want to bind the following simplistic Matrix class:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class Matrix {
|
||||
public:
|
||||
Matrix(size_t rows, size_t cols) : m_rows(rows), m_cols(cols) {
|
||||
m_data = new float[rows*cols];
|
||||
}
|
||||
float *data() { return m_data; }
|
||||
size_t rows() const { return m_rows; }
|
||||
size_t cols() const { return m_cols; }
|
||||
private:
|
||||
size_t m_rows, m_cols;
|
||||
float *m_data;
|
||||
};
|
||||
|
||||
The following binding code exposes the ``Matrix`` contents as a buffer object,
|
||||
making it possible to cast Matrices into NumPy arrays. It is even possible to
|
||||
completely avoid copy operations with Python expressions like
|
||||
``np.array(matrix_instance, copy = False)``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
|
||||
.def_buffer([](Matrix &m) -> py::buffer_info {
|
||||
return py::buffer_info(
|
||||
m.data(), /* Pointer to buffer */
|
||||
sizeof(float), /* Size of one scalar */
|
||||
py::format_descriptor<float>::format(), /* Python struct-style format descriptor */
|
||||
2, /* Number of dimensions */
|
||||
{ m.rows(), m.cols() }, /* Buffer dimensions */
|
||||
{ sizeof(float) * m.cols(), /* Strides (in bytes) for each index */
|
||||
sizeof(float) }
|
||||
);
|
||||
});
|
||||
|
||||
Supporting the buffer protocol in a new type involves specifying the special
|
||||
``py::buffer_protocol()`` tag in the ``py::class_`` constructor and calling the
|
||||
``def_buffer()`` method with a lambda function that creates a
|
||||
``py::buffer_info`` description record on demand describing a given matrix
|
||||
instance. The contents of ``py::buffer_info`` mirror the Python buffer protocol
|
||||
specification.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct buffer_info {
|
||||
void *ptr;
|
||||
py::ssize_t itemsize;
|
||||
std::string format;
|
||||
py::ssize_t ndim;
|
||||
std::vector<py::ssize_t> shape;
|
||||
std::vector<py::ssize_t> strides;
|
||||
};
|
||||
|
||||
To create a C++ function that can take a Python buffer object as an argument,
|
||||
simply use the type ``py::buffer`` as one of its arguments. Buffers can exist
|
||||
in a great variety of configurations, hence some safety checks are usually
|
||||
necessary in the function body. Below, you can see a basic example on how to
|
||||
define a custom constructor for the Eigen double precision matrix
|
||||
(``Eigen::MatrixXd``) type, which supports initialization from compatible
|
||||
buffer objects (e.g. a NumPy matrix).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
/* Bind MatrixXd (or some other Eigen type) to Python */
|
||||
typedef Eigen::MatrixXd Matrix;
|
||||
|
||||
typedef Matrix::Scalar Scalar;
|
||||
constexpr bool rowMajor = Matrix::Flags & Eigen::RowMajorBit;
|
||||
|
||||
py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
|
||||
.def(py::init([](py::buffer b) {
|
||||
typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides;
|
||||
|
||||
/* Request a buffer descriptor from Python */
|
||||
py::buffer_info info = b.request();
|
||||
|
||||
/* Some basic validation checks ... */
|
||||
if (info.format != py::format_descriptor<Scalar>::format())
|
||||
throw std::runtime_error("Incompatible format: expected a double array!");
|
||||
|
||||
if (info.ndim != 2)
|
||||
throw std::runtime_error("Incompatible buffer dimension!");
|
||||
|
||||
auto strides = Strides(
|
||||
info.strides[rowMajor ? 0 : 1] / (py::ssize_t)sizeof(Scalar),
|
||||
info.strides[rowMajor ? 1 : 0] / (py::ssize_t)sizeof(Scalar));
|
||||
|
||||
auto map = Eigen::Map<Matrix, 0, Strides>(
|
||||
static_cast<Scalar *>(info.ptr), info.shape[0], info.shape[1], strides);
|
||||
|
||||
return Matrix(map);
|
||||
}));
|
||||
|
||||
For reference, the ``def_buffer()`` call for this Eigen data type should look
|
||||
as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
.def_buffer([](Matrix &m) -> py::buffer_info {
|
||||
return py::buffer_info(
|
||||
m.data(), /* Pointer to buffer */
|
||||
sizeof(Scalar), /* Size of one scalar */
|
||||
py::format_descriptor<Scalar>::format(), /* Python struct-style format descriptor */
|
||||
2, /* Number of dimensions */
|
||||
{ m.rows(), m.cols() }, /* Buffer dimensions */
|
||||
{ sizeof(Scalar) * (rowMajor ? m.cols() : 1),
|
||||
sizeof(Scalar) * (rowMajor ? 1 : m.rows()) }
|
||||
/* Strides (in bytes) for each index */
|
||||
);
|
||||
})
|
||||
|
||||
For a much easier approach of binding Eigen types (although with some
|
||||
limitations), refer to the section on :doc:`/advanced/cast/eigen`.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_buffers.cpp` contains a complete example
|
||||
that demonstrates using the buffer protocol with pybind11 in more detail.
|
||||
|
||||
.. [#f2] http://docs.python.org/3/c-api/buffer.html
|
||||
|
||||
Arrays
|
||||
======
|
||||
|
||||
By exchanging ``py::buffer`` with ``py::array`` in the above snippet, we can
|
||||
restrict the function so that it only accepts NumPy arrays (rather than any
|
||||
type of Python object satisfying the buffer protocol).
|
||||
|
||||
In many situations, we want to define a function which only accepts a NumPy
|
||||
array of a certain data type. This is possible via the ``py::array_t<T>``
|
||||
template. For instance, the following function requires the argument to be a
|
||||
NumPy array containing double precision values.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void f(py::array_t<double> array);
|
||||
|
||||
When it is invoked with a different type (e.g. an integer or a list of
|
||||
integers), the binding code will attempt to cast the input into a NumPy array
|
||||
of the requested type. This feature requires the :file:`pybind11/numpy.h`
|
||||
header to be included. Note that :file:`pybind11/numpy.h` does not depend on
|
||||
the NumPy headers, and thus can be used without declaring a build-time
|
||||
dependency on NumPy; NumPy>=1.7.0 is a runtime dependency.
|
||||
|
||||
Data in NumPy arrays is not guaranteed to packed in a dense manner;
|
||||
furthermore, entries can be separated by arbitrary column and row strides.
|
||||
Sometimes, it can be useful to require a function to only accept dense arrays
|
||||
using either the C (row-major) or Fortran (column-major) ordering. This can be
|
||||
accomplished via a second template argument with values ``py::array::c_style``
|
||||
or ``py::array::f_style``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void f(py::array_t<double, py::array::c_style | py::array::forcecast> array);
|
||||
|
||||
The ``py::array::forcecast`` argument is the default value of the second
|
||||
template parameter, and it ensures that non-conforming arguments are converted
|
||||
into an array satisfying the specified requirements instead of trying the next
|
||||
function overload.
|
||||
|
||||
There are several methods on arrays; the methods listed below under references
|
||||
work, as well as the following functions based on the NumPy API:
|
||||
|
||||
- ``.dtype()`` returns the type of the contained values.
|
||||
|
||||
- ``.strides()`` returns a pointer to the strides of the array (optionally pass
|
||||
an integer axis to get a number).
|
||||
|
||||
- ``.flags()`` returns the flag settings. ``.writable()`` and ``.owndata()``
|
||||
are directly available.
|
||||
|
||||
- ``.offset_at()`` returns the offset (optionally pass indices).
|
||||
|
||||
- ``.squeeze()`` returns a view with length-1 axes removed.
|
||||
|
||||
- ``.view(dtype)`` returns a view of the array with a different dtype.
|
||||
|
||||
- ``.reshape({i, j, ...})`` returns a view of the array with a different shape.
|
||||
``.resize({...})`` is also available.
|
||||
|
||||
- ``.index_at(i, j, ...)`` gets the count from the beginning to a given index.
|
||||
|
||||
|
||||
There are also several methods for getting references (described below).
|
||||
|
||||
Structured types
|
||||
================
|
||||
|
||||
In order for ``py::array_t`` to work with structured (record) types, we first
|
||||
need to register the memory layout of the type. This can be done via
|
||||
``PYBIND11_NUMPY_DTYPE`` macro, called in the plugin definition code, which
|
||||
expects the type followed by field names:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct A {
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct B {
|
||||
int z;
|
||||
A a;
|
||||
};
|
||||
|
||||
// ...
|
||||
PYBIND11_MODULE(test, m) {
|
||||
// ...
|
||||
|
||||
PYBIND11_NUMPY_DTYPE(A, x, y);
|
||||
PYBIND11_NUMPY_DTYPE(B, z, a);
|
||||
/* now both A and B can be used as template arguments to py::array_t */
|
||||
}
|
||||
|
||||
The structure should consist of fundamental arithmetic types, ``std::complex``,
|
||||
previously registered substructures, and arrays of any of the above. Both C++
|
||||
arrays and ``std::array`` are supported. While there is a static assertion to
|
||||
prevent many types of unsupported structures, it is still the user's
|
||||
responsibility to use only "plain" structures that can be safely manipulated as
|
||||
raw memory without violating invariants.
|
||||
|
||||
Vectorizing functions
|
||||
=====================
|
||||
|
||||
Suppose we want to bind a function with the following signature to Python so
|
||||
that it can process arbitrary NumPy array arguments (vectors, matrices, general
|
||||
N-D arrays) in addition to its normal arguments:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
double my_func(int x, float y, double z);
|
||||
|
||||
After including the ``pybind11/numpy.h`` header, this is extremely simple:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("vectorized_func", py::vectorize(my_func));
|
||||
|
||||
Invoking the function like below causes 4 calls to be made to ``my_func`` with
|
||||
each of the array elements. The significant advantage of this compared to
|
||||
solutions like ``numpy.vectorize()`` is that the loop over the elements runs
|
||||
entirely on the C++ side and can be crunched down into a tight, optimized loop
|
||||
by the compiler. The result is returned as a NumPy array of type
|
||||
``numpy.dtype.float64``.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> x = np.array([[1, 3], [5, 7]])
|
||||
>>> y = np.array([[2, 4], [6, 8]])
|
||||
>>> z = 3
|
||||
>>> result = vectorized_func(x, y, z)
|
||||
|
||||
The scalar argument ``z`` is transparently replicated 4 times. The input
|
||||
arrays ``x`` and ``y`` are automatically converted into the right types (they
|
||||
are of type ``numpy.dtype.int64`` but need to be ``numpy.dtype.int32`` and
|
||||
``numpy.dtype.float32``, respectively).
|
||||
|
||||
.. note::
|
||||
|
||||
Only arithmetic, complex, and POD types passed by value or by ``const &``
|
||||
reference are vectorized; all other arguments are passed through as-is.
|
||||
Functions taking rvalue reference arguments cannot be vectorized.
|
||||
|
||||
In cases where the computation is too complicated to be reduced to
|
||||
``vectorize``, it will be necessary to create and access the buffer contents
|
||||
manually. The following snippet contains a complete example that shows how this
|
||||
works (the code is somewhat contrived, since it could have been done more
|
||||
simply using ``vectorize``).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/numpy.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
py::array_t<double> add_arrays(py::array_t<double> input1, py::array_t<double> input2) {
|
||||
py::buffer_info buf1 = input1.request(), buf2 = input2.request();
|
||||
|
||||
if (buf1.ndim != 1 || buf2.ndim != 1)
|
||||
throw std::runtime_error("Number of dimensions must be one");
|
||||
|
||||
if (buf1.size != buf2.size)
|
||||
throw std::runtime_error("Input shapes must match");
|
||||
|
||||
/* No pointer is passed, so NumPy will allocate the buffer */
|
||||
auto result = py::array_t<double>(buf1.size);
|
||||
|
||||
py::buffer_info buf3 = result.request();
|
||||
|
||||
double *ptr1 = static_cast<double *>(buf1.ptr);
|
||||
double *ptr2 = static_cast<double *>(buf2.ptr);
|
||||
double *ptr3 = static_cast<double *>(buf3.ptr);
|
||||
|
||||
for (size_t idx = 0; idx < buf1.shape[0]; idx++)
|
||||
ptr3[idx] = ptr1[idx] + ptr2[idx];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(test, m) {
|
||||
m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
|
||||
}
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_numpy_vectorize.cpp` contains a complete
|
||||
example that demonstrates using :func:`vectorize` in more detail.
|
||||
|
||||
Direct access
|
||||
=============
|
||||
|
||||
For performance reasons, particularly when dealing with very large arrays, it
|
||||
is often desirable to directly access array elements without internal checking
|
||||
of dimensions and bounds on every access when indices are known to be already
|
||||
valid. To avoid such checks, the ``array`` class and ``array_t<T>`` template
|
||||
class offer an unchecked proxy object that can be used for this unchecked
|
||||
access through the ``unchecked<N>`` and ``mutable_unchecked<N>`` methods,
|
||||
where ``N`` gives the required dimensionality of the array:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("sum_3d", [](py::array_t<double> x) {
|
||||
auto r = x.unchecked<3>(); // x must have ndim = 3; can be non-writeable
|
||||
double sum = 0;
|
||||
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
||||
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
||||
for (py::ssize_t k = 0; k < r.shape(2); k++)
|
||||
sum += r(i, j, k);
|
||||
return sum;
|
||||
});
|
||||
m.def("increment_3d", [](py::array_t<double> x) {
|
||||
auto r = x.mutable_unchecked<3>(); // Will throw if ndim != 3 or flags.writeable is false
|
||||
for (py::ssize_t i = 0; i < r.shape(0); i++)
|
||||
for (py::ssize_t j = 0; j < r.shape(1); j++)
|
||||
for (py::ssize_t k = 0; k < r.shape(2); k++)
|
||||
r(i, j, k) += 1.0;
|
||||
}, py::arg().noconvert());
|
||||
|
||||
To obtain the proxy from an ``array`` object, you must specify both the data
|
||||
type and number of dimensions as template arguments, such as ``auto r =
|
||||
myarray.mutable_unchecked<float, 2>()``.
|
||||
|
||||
If the number of dimensions is not known at compile time, you can omit the
|
||||
dimensions template parameter (i.e. calling ``arr_t.unchecked()`` or
|
||||
``arr.unchecked<T>()``. This will give you a proxy object that works in the
|
||||
same way, but results in less optimizable code and thus a small efficiency
|
||||
loss in tight loops.
|
||||
|
||||
Note that the returned proxy object directly references the array's data, and
|
||||
only reads its shape, strides, and writeable flag when constructed. You must
|
||||
take care to ensure that the referenced array is not destroyed or reshaped for
|
||||
the duration of the returned object, typically by limiting the scope of the
|
||||
returned instance.
|
||||
|
||||
The returned proxy object supports some of the same methods as ``py::array`` so
|
||||
that it can be used as a drop-in replacement for some existing, index-checked
|
||||
uses of ``py::array``:
|
||||
|
||||
- ``.ndim()`` returns the number of dimensions
|
||||
|
||||
- ``.data(1, 2, ...)`` and ``r.mutable_data(1, 2, ...)``` returns a pointer to
|
||||
the ``const T`` or ``T`` data, respectively, at the given indices. The
|
||||
latter is only available to proxies obtained via ``a.mutable_unchecked()``.
|
||||
|
||||
- ``.itemsize()`` returns the size of an item in bytes, i.e. ``sizeof(T)``.
|
||||
|
||||
- ``.ndim()`` returns the number of dimensions.
|
||||
|
||||
- ``.shape(n)`` returns the size of dimension ``n``
|
||||
|
||||
- ``.size()`` returns the total number of elements (i.e. the product of the shapes).
|
||||
|
||||
- ``.nbytes()`` returns the number of bytes used by the referenced elements
|
||||
(i.e. ``itemsize()`` times ``size()``).
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_numpy_array.cpp` contains additional examples
|
||||
demonstrating the use of this feature.
|
||||
|
||||
Ellipsis
|
||||
========
|
||||
|
||||
Python provides a convenient ``...`` ellipsis notation that is often used to
|
||||
slice multidimensional arrays. For instance, the following snippet extracts the
|
||||
middle dimensions of a tensor with the first and last index set to zero.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
a = ... # a NumPy array
|
||||
b = a[0, ..., 0]
|
||||
|
||||
The function ``py::ellipsis()`` function can be used to perform the same
|
||||
operation on the C++ side:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::array a = /* A NumPy array */;
|
||||
py::array b = a[py::make_tuple(0, py::ellipsis(), 0)];
|
||||
|
||||
|
||||
Memory view
|
||||
===========
|
||||
|
||||
For a case when we simply want to provide a direct accessor to C/C++ buffer
|
||||
without a concrete class object, we can return a ``memoryview`` object. Suppose
|
||||
we wish to expose a ``memoryview`` for 2x4 uint8_t array, we can do the
|
||||
following:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
const uint8_t buffer[] = {
|
||||
0, 1, 2, 3,
|
||||
4, 5, 6, 7
|
||||
};
|
||||
m.def("get_memoryview2d", []() {
|
||||
return py::memoryview::from_buffer(
|
||||
buffer, // buffer pointer
|
||||
{ 2, 4 }, // shape (rows, cols)
|
||||
{ sizeof(uint8_t) * 4, sizeof(uint8_t) } // strides in bytes
|
||||
);
|
||||
});
|
||||
|
||||
This approach is meant for providing a ``memoryview`` for a C/C++ buffer not
|
||||
managed by Python. The user is responsible for managing the lifetime of the
|
||||
buffer. Using a ``memoryview`` created in this way after deleting the buffer in
|
||||
C++ side results in undefined behavior.
|
||||
|
||||
We can also use ``memoryview::from_memory`` for a simple 1D contiguous buffer:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("get_memoryview1d", []() {
|
||||
return py::memoryview::from_memory(
|
||||
buffer, // buffer pointer
|
||||
sizeof(uint8_t) * 8 // buffer size
|
||||
);
|
||||
});
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
``memoryview::from_memory`` added.
|
286
thirdparty/pybind11/docs/advanced/pycpp/object.rst
vendored
Normal file
286
thirdparty/pybind11/docs/advanced/pycpp/object.rst
vendored
Normal file
@ -0,0 +1,286 @@
|
||||
Python types
|
||||
############
|
||||
|
||||
.. _wrappers:
|
||||
|
||||
Available wrappers
|
||||
==================
|
||||
|
||||
All major Python types are available as thin C++ wrapper classes. These
|
||||
can also be used as function parameters -- see :ref:`python_objects_as_args`.
|
||||
|
||||
Available types include :class:`handle`, :class:`object`, :class:`bool_`,
|
||||
:class:`int_`, :class:`float_`, :class:`str`, :class:`bytes`, :class:`tuple`,
|
||||
:class:`list`, :class:`dict`, :class:`slice`, :class:`none`, :class:`capsule`,
|
||||
:class:`iterable`, :class:`iterator`, :class:`function`, :class:`buffer`,
|
||||
:class:`array`, and :class:`array_t`.
|
||||
|
||||
.. warning::
|
||||
|
||||
Be sure to review the :ref:`pytypes_gotchas` before using this heavily in
|
||||
your C++ API.
|
||||
|
||||
.. _instantiating_compound_types:
|
||||
|
||||
Instantiating compound Python types from C++
|
||||
============================================
|
||||
|
||||
Dictionaries can be initialized in the :class:`dict` constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
using namespace pybind11::literals; // to bring in the `_a` literal
|
||||
py::dict d("spam"_a=py::none(), "eggs"_a=42);
|
||||
|
||||
A tuple of python objects can be instantiated using :func:`py::make_tuple`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::tuple tup = py::make_tuple(42, py::none(), "spam");
|
||||
|
||||
Each element is converted to a supported Python type.
|
||||
|
||||
A `simple namespace`_ can be instantiated using
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
using namespace pybind11::literals; // to bring in the `_a` literal
|
||||
py::object SimpleNamespace = py::module_::import("types").attr("SimpleNamespace");
|
||||
py::object ns = SimpleNamespace("spam"_a=py::none(), "eggs"_a=42);
|
||||
|
||||
Attributes on a namespace can be modified with the :func:`py::delattr`,
|
||||
:func:`py::getattr`, and :func:`py::setattr` functions. Simple namespaces can
|
||||
be useful as lightweight stand-ins for class instances.
|
||||
|
||||
.. _simple namespace: https://docs.python.org/3/library/types.html#types.SimpleNamespace
|
||||
|
||||
.. _casting_back_and_forth:
|
||||
|
||||
Casting back and forth
|
||||
======================
|
||||
|
||||
In this kind of mixed code, it is often necessary to convert arbitrary C++
|
||||
types to Python, which can be done using :func:`py::cast`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
MyClass *cls = ...;
|
||||
py::object obj = py::cast(cls);
|
||||
|
||||
The reverse direction uses the following syntax:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::object obj = ...;
|
||||
MyClass *cls = obj.cast<MyClass *>();
|
||||
|
||||
When conversion fails, both directions throw the exception :class:`cast_error`.
|
||||
|
||||
.. _python_libs:
|
||||
|
||||
Accessing Python libraries from C++
|
||||
===================================
|
||||
|
||||
It is also possible to import objects defined in the Python standard
|
||||
library or available in the current Python environment (``sys.path``) and work
|
||||
with these in C++.
|
||||
|
||||
This example obtains a reference to the Python ``Decimal`` class.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Equivalent to "from decimal import Decimal"
|
||||
py::object Decimal = py::module_::import("decimal").attr("Decimal");
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Try to import scipy
|
||||
py::object scipy = py::module_::import("scipy");
|
||||
return scipy.attr("__version__");
|
||||
|
||||
|
||||
.. _calling_python_functions:
|
||||
|
||||
Calling Python functions
|
||||
========================
|
||||
|
||||
It is also possible to call Python classes, functions and methods
|
||||
via ``operator()``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Construct a Python object of class Decimal
|
||||
py::object pi = Decimal("3.14159");
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Use Python to make our directories
|
||||
py::object os = py::module_::import("os");
|
||||
py::object makedirs = os.attr("makedirs");
|
||||
makedirs("/tmp/path/to/somewhere");
|
||||
|
||||
One can convert the result obtained from Python to a pure C++ version
|
||||
if a ``py::class_`` or type conversion is defined.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::function f = <...>;
|
||||
py::object result_py = f(1234, "hello", some_instance);
|
||||
MyClass &result = result_py.cast<MyClass>();
|
||||
|
||||
.. _calling_python_methods:
|
||||
|
||||
Calling Python methods
|
||||
========================
|
||||
|
||||
To call an object's method, one can again use ``.attr`` to obtain access to the
|
||||
Python method.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Calculate e^π in decimal
|
||||
py::object exp_pi = pi.attr("exp")();
|
||||
py::print(py::str(exp_pi));
|
||||
|
||||
In the example above ``pi.attr("exp")`` is a *bound method*: it will always call
|
||||
the method for that same instance of the class. Alternately one can create an
|
||||
*unbound method* via the Python class (instead of instance) and pass the ``self``
|
||||
object explicitly, followed by other arguments.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::object decimal_exp = Decimal.attr("exp");
|
||||
|
||||
// Compute the e^n for n=0..4
|
||||
for (int n = 0; n < 5; n++) {
|
||||
py::print(decimal_exp(Decimal(n));
|
||||
}
|
||||
|
||||
Keyword arguments
|
||||
=================
|
||||
|
||||
Keyword arguments are also supported. In Python, there is the usual call syntax:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def f(number, say, to):
|
||||
... # function code
|
||||
|
||||
|
||||
f(1234, say="hello", to=some_instance) # keyword call in Python
|
||||
|
||||
In C++, the same call can be made using:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
using namespace pybind11::literals; // to bring in the `_a` literal
|
||||
f(1234, "say"_a="hello", "to"_a=some_instance); // keyword call in C++
|
||||
|
||||
Unpacking arguments
|
||||
===================
|
||||
|
||||
Unpacking of ``*args`` and ``**kwargs`` is also possible and can be mixed with
|
||||
other arguments:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// * unpacking
|
||||
py::tuple args = py::make_tuple(1234, "hello", some_instance);
|
||||
f(*args);
|
||||
|
||||
// ** unpacking
|
||||
py::dict kwargs = py::dict("number"_a=1234, "say"_a="hello", "to"_a=some_instance);
|
||||
f(**kwargs);
|
||||
|
||||
// mixed keywords, * and ** unpacking
|
||||
py::tuple args = py::make_tuple(1234);
|
||||
py::dict kwargs = py::dict("to"_a=some_instance);
|
||||
f(*args, "say"_a="hello", **kwargs);
|
||||
|
||||
Generalized unpacking according to PEP448_ is also supported:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::dict kwargs1 = py::dict("number"_a=1234);
|
||||
py::dict kwargs2 = py::dict("to"_a=some_instance);
|
||||
f(**kwargs1, "say"_a="hello", **kwargs2);
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_pytypes.cpp` contains a complete
|
||||
example that demonstrates passing native Python types in more detail. The
|
||||
file :file:`tests/test_callbacks.cpp` presents a few examples of calling
|
||||
Python functions from C++, including keywords arguments and unpacking.
|
||||
|
||||
.. _PEP448: https://www.python.org/dev/peps/pep-0448/
|
||||
|
||||
.. _implicit_casting:
|
||||
|
||||
Implicit casting
|
||||
================
|
||||
|
||||
When using the C++ interface for Python types, or calling Python functions,
|
||||
objects of type :class:`object` are returned. It is possible to invoke implicit
|
||||
conversions to subclasses like :class:`dict`. The same holds for the proxy objects
|
||||
returned by ``operator[]`` or ``obj.attr()``.
|
||||
Casting to subtypes improves code readability and allows values to be passed to
|
||||
C++ functions that require a specific subtype rather than a generic :class:`object`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/numpy.h>
|
||||
using namespace pybind11::literals;
|
||||
|
||||
py::module_ os = py::module_::import("os");
|
||||
py::module_ path = py::module_::import("os.path"); // like 'import os.path as path'
|
||||
py::module_ np = py::module_::import("numpy"); // like 'import numpy as np'
|
||||
|
||||
py::str curdir_abs = path.attr("abspath")(path.attr("curdir"));
|
||||
py::print(py::str("Current directory: ") + curdir_abs);
|
||||
py::dict environ = os.attr("environ");
|
||||
py::print(environ["HOME"]);
|
||||
py::array_t<float> arr = np.attr("ones")(3, "dtype"_a="float32");
|
||||
py::print(py::repr(arr + py::int_(1)));
|
||||
|
||||
These implicit conversions are available for subclasses of :class:`object`; there
|
||||
is no need to call ``obj.cast()`` explicitly as for custom classes, see
|
||||
:ref:`casting_back_and_forth`.
|
||||
|
||||
.. note::
|
||||
If a trivial conversion via move constructor is not possible, both implicit and
|
||||
explicit casting (calling ``obj.cast()``) will attempt a "rich" conversion.
|
||||
For instance, ``py::list env = os.attr("environ");`` will succeed and is
|
||||
equivalent to the Python code ``env = list(os.environ)`` that produces a
|
||||
list of the dict keys.
|
||||
|
||||
.. TODO: Adapt text once PR #2349 has landed
|
||||
|
||||
Handling exceptions
|
||||
===================
|
||||
|
||||
Python exceptions from wrapper classes will be thrown as a ``py::error_already_set``.
|
||||
See :ref:`Handling exceptions from Python in C++
|
||||
<handling_python_exceptions_cpp>` for more information on handling exceptions
|
||||
raised when calling C++ wrapper classes.
|
||||
|
||||
.. _pytypes_gotchas:
|
||||
|
||||
Gotchas
|
||||
=======
|
||||
|
||||
Default-Constructed Wrappers
|
||||
----------------------------
|
||||
|
||||
When a wrapper type is default-constructed, it is **not** a valid Python object (i.e. it is not ``py::none()``). It is simply the same as
|
||||
``PyObject*`` null pointer. To check for this, use
|
||||
``static_cast<bool>(my_wrapper)``.
|
||||
|
||||
Assigning py::none() to wrappers
|
||||
--------------------------------
|
||||
|
||||
You may be tempted to use types like ``py::str`` and ``py::dict`` in C++
|
||||
signatures (either pure C++, or in bound signatures), and assign them default
|
||||
values of ``py::none()``. However, in a best case scenario, it will fail fast
|
||||
because ``None`` is not convertible to that type (e.g. ``py::dict``), or in a
|
||||
worse case scenario, it will silently work but corrupt the types you want to
|
||||
work with (e.g. ``py::str(py::none())`` will yield ``"None"`` in Python).
|
155
thirdparty/pybind11/docs/advanced/pycpp/utilities.rst
vendored
Normal file
155
thirdparty/pybind11/docs/advanced/pycpp/utilities.rst
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
Utilities
|
||||
#########
|
||||
|
||||
Using Python's print function in C++
|
||||
====================================
|
||||
|
||||
The usual way to write output in C++ is using ``std::cout`` while in Python one
|
||||
would use ``print``. Since these methods use different buffers, mixing them can
|
||||
lead to output order issues. To resolve this, pybind11 modules can use the
|
||||
:func:`py::print` function which writes to Python's ``sys.stdout`` for consistency.
|
||||
|
||||
Python's ``print`` function is replicated in the C++ API including optional
|
||||
keyword arguments ``sep``, ``end``, ``file``, ``flush``. Everything works as
|
||||
expected in Python:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::print(1, 2.0, "three"); // 1 2.0 three
|
||||
py::print(1, 2.0, "three", "sep"_a="-"); // 1-2.0-three
|
||||
|
||||
auto args = py::make_tuple("unpacked", true);
|
||||
py::print("->", *args, "end"_a="<-"); // -> unpacked True <-
|
||||
|
||||
.. _ostream_redirect:
|
||||
|
||||
Capturing standard output from ostream
|
||||
======================================
|
||||
|
||||
Often, a library will use the streams ``std::cout`` and ``std::cerr`` to print,
|
||||
but this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr``
|
||||
redirection. Replacing a library's printing with ``py::print <print>`` may not
|
||||
be feasible. This can be fixed using a guard around the library function that
|
||||
redirects output to the corresponding Python streams:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/iostream.h>
|
||||
|
||||
...
|
||||
|
||||
// Add a scoped redirect for your noisy code
|
||||
m.def("noisy_func", []() {
|
||||
py::scoped_ostream_redirect stream(
|
||||
std::cout, // std::ostream&
|
||||
py::module_::import("sys").attr("stdout") // Python output
|
||||
);
|
||||
call_noisy_func();
|
||||
});
|
||||
|
||||
.. warning::
|
||||
|
||||
The implementation in ``pybind11/iostream.h`` is NOT thread safe. Multiple
|
||||
threads writing to a redirected ostream concurrently cause data races
|
||||
and potentially buffer overflows. Therefore it is currently a requirement
|
||||
that all (possibly) concurrent redirected ostream writes are protected by
|
||||
a mutex. #HelpAppreciated: Work on iostream.h thread safety. For more
|
||||
background see the discussions under
|
||||
`PR #2982 <https://github.com/pybind/pybind11/pull/2982>`_ and
|
||||
`PR #2995 <https://github.com/pybind/pybind11/pull/2995>`_.
|
||||
|
||||
This method respects flushes on the output streams and will flush if needed
|
||||
when the scoped guard is destroyed. This allows the output to be redirected in
|
||||
real time, such as to a Jupyter notebook. The two arguments, the C++ stream and
|
||||
the Python output, are optional, and default to standard output if not given. An
|
||||
extra type, ``py::scoped_estream_redirect <scoped_estream_redirect>``, is identical
|
||||
except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with
|
||||
``py::call_guard``, which allows multiple items, but uses the default constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Alternative: Call single function using call guard
|
||||
m.def("noisy_func", &call_noisy_function,
|
||||
py::call_guard<py::scoped_ostream_redirect,
|
||||
py::scoped_estream_redirect>());
|
||||
|
||||
The redirection can also be done in Python with the addition of a context
|
||||
manager, using the ``py::add_ostream_redirect() <add_ostream_redirect>`` function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::add_ostream_redirect(m, "ostream_redirect");
|
||||
|
||||
The name in Python defaults to ``ostream_redirect`` if no name is passed. This
|
||||
creates the following context manager in Python:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with ostream_redirect(stdout=True, stderr=True):
|
||||
noisy_function()
|
||||
|
||||
It defaults to redirecting both streams, though you can use the keyword
|
||||
arguments to disable one of the streams if needed.
|
||||
|
||||
.. note::
|
||||
|
||||
The above methods will not redirect C-level output to file descriptors, such
|
||||
as ``fprintf``. For those cases, you'll need to redirect the file
|
||||
descriptors either directly in C or with Python's ``os.dup2`` function
|
||||
in an operating-system dependent way.
|
||||
|
||||
.. _eval:
|
||||
|
||||
Evaluating Python expressions from strings and files
|
||||
====================================================
|
||||
|
||||
pybind11 provides the ``eval``, ``exec`` and ``eval_file`` functions to evaluate
|
||||
Python expressions and statements. The following example illustrates how they
|
||||
can be used.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// At beginning of file
|
||||
#include <pybind11/eval.h>
|
||||
|
||||
...
|
||||
|
||||
// Evaluate in scope of main module
|
||||
py::object scope = py::module_::import("__main__").attr("__dict__");
|
||||
|
||||
// Evaluate an isolated expression
|
||||
int result = py::eval("my_variable + 10", scope).cast<int>();
|
||||
|
||||
// Evaluate a sequence of statements
|
||||
py::exec(
|
||||
"print('Hello')\n"
|
||||
"print('world!');",
|
||||
scope);
|
||||
|
||||
// Evaluate the statements in an separate Python file on disk
|
||||
py::eval_file("script.py", scope);
|
||||
|
||||
C++11 raw string literals are also supported and quite handy for this purpose.
|
||||
The only requirement is that the first statement must be on a new line following
|
||||
the raw string delimiter ``R"(``, ensuring all lines have common leading indent:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::exec(R"(
|
||||
x = get_answer()
|
||||
if x == 42:
|
||||
print('Hello World!')
|
||||
else:
|
||||
print('Bye!')
|
||||
)", scope
|
||||
);
|
||||
|
||||
.. note::
|
||||
|
||||
`eval` and `eval_file` accept a template parameter that describes how the
|
||||
string/file should be interpreted. Possible choices include ``eval_expr``
|
||||
(isolated expression), ``eval_single_statement`` (a single statement, return
|
||||
value is always ``none``), and ``eval_statements`` (sequence of statements,
|
||||
return value is always ``none``). `eval` defaults to ``eval_expr``,
|
||||
`eval_file` defaults to ``eval_statements`` and `exec` is just a shortcut
|
||||
for ``eval<eval_statements>``.
|
174
thirdparty/pybind11/docs/advanced/smart_ptrs.rst
vendored
Normal file
174
thirdparty/pybind11/docs/advanced/smart_ptrs.rst
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
Smart pointers
|
||||
##############
|
||||
|
||||
std::unique_ptr
|
||||
===============
|
||||
|
||||
Given a class ``Example`` with Python bindings, it's possible to return
|
||||
instances wrapped in C++11 unique pointers, like so
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::unique_ptr<Example> create_example() { return std::unique_ptr<Example>(new Example()); }
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("create_example", &create_example);
|
||||
|
||||
In other words, there is nothing special that needs to be done. While returning
|
||||
unique pointers in this way is allowed, it is *illegal* to use them as function
|
||||
arguments. For instance, the following function signature cannot be processed
|
||||
by pybind11.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void do_something_with_example(std::unique_ptr<Example> ex) { ... }
|
||||
|
||||
The above signature would imply that Python needs to give up ownership of an
|
||||
object that is passed to this function, which is generally not possible (for
|
||||
instance, the object might be referenced elsewhere).
|
||||
|
||||
std::shared_ptr
|
||||
===============
|
||||
|
||||
The binding generator for classes, :class:`class_`, can be passed a template
|
||||
type that denotes a special *holder* type that is used to manage references to
|
||||
the object. If no such holder type template argument is given, the default for
|
||||
a type named ``Type`` is ``std::unique_ptr<Type>``, which means that the object
|
||||
is deallocated when Python's reference count goes to zero.
|
||||
|
||||
It is possible to switch to other types of reference counting wrappers or smart
|
||||
pointers, which is useful in codebases that rely on them. For instance, the
|
||||
following snippet causes ``std::shared_ptr`` to be used instead.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Example, std::shared_ptr<Example> /* <- holder type */> obj(m, "Example");
|
||||
|
||||
Note that any particular class can only be associated with a single holder type.
|
||||
|
||||
One potential stumbling block when using holder types is that they need to be
|
||||
applied consistently. Can you guess what's broken about the following binding
|
||||
code?
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class Child { };
|
||||
|
||||
class Parent {
|
||||
public:
|
||||
Parent() : child(std::make_shared<Child>()) { }
|
||||
Child *get_child() { return child.get(); } /* Hint: ** DON'T DO THIS ** */
|
||||
private:
|
||||
std::shared_ptr<Child> child;
|
||||
};
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::class_<Child, std::shared_ptr<Child>>(m, "Child");
|
||||
|
||||
py::class_<Parent, std::shared_ptr<Parent>>(m, "Parent")
|
||||
.def(py::init<>())
|
||||
.def("get_child", &Parent::get_child);
|
||||
}
|
||||
|
||||
The following Python code will cause undefined behavior (and likely a
|
||||
segmentation fault).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from example import Parent
|
||||
|
||||
print(Parent().get_child())
|
||||
|
||||
The problem is that ``Parent::get_child()`` returns a pointer to an instance of
|
||||
``Child``, but the fact that this instance is already managed by
|
||||
``std::shared_ptr<...>`` is lost when passing raw pointers. In this case,
|
||||
pybind11 will create a second independent ``std::shared_ptr<...>`` that also
|
||||
claims ownership of the pointer. In the end, the object will be freed **twice**
|
||||
since these shared pointers have no way of knowing about each other.
|
||||
|
||||
There are two ways to resolve this issue:
|
||||
|
||||
1. For types that are managed by a smart pointer class, never use raw pointers
|
||||
in function arguments or return values. In other words: always consistently
|
||||
wrap pointers into their designated holder types (such as
|
||||
``std::shared_ptr<...>``). In this case, the signature of ``get_child()``
|
||||
should be modified as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::shared_ptr<Child> get_child() { return child; }
|
||||
|
||||
2. Adjust the definition of ``Child`` by specifying
|
||||
``std::enable_shared_from_this<T>`` (see cppreference_ for details) as a
|
||||
base class. This adds a small bit of information to ``Child`` that allows
|
||||
pybind11 to realize that there is already an existing
|
||||
``std::shared_ptr<...>`` and communicate with it. In this case, the
|
||||
declaration of ``Child`` should look as follows:
|
||||
|
||||
.. _cppreference: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class Child : public std::enable_shared_from_this<Child> { };
|
||||
|
||||
.. _smart_pointers:
|
||||
|
||||
Custom smart pointers
|
||||
=====================
|
||||
|
||||
pybind11 supports ``std::unique_ptr`` and ``std::shared_ptr`` right out of the
|
||||
box. For any other custom smart pointer, transparent conversions can be enabled
|
||||
using a macro invocation similar to the following. It must be declared at the
|
||||
top namespace level before any binding code:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>);
|
||||
|
||||
The first argument of :func:`PYBIND11_DECLARE_HOLDER_TYPE` should be a
|
||||
placeholder name that is used as a template parameter of the second argument.
|
||||
Thus, feel free to use any identifier, but use it consistently on both sides;
|
||||
also, don't use the name of a type that already exists in your codebase.
|
||||
|
||||
The macro also accepts a third optional boolean parameter that is set to false
|
||||
by default. Specify
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>, true);
|
||||
|
||||
if ``SmartPtr<T>`` can always be initialized from a ``T*`` pointer without the
|
||||
risk of inconsistencies (such as multiple independent ``SmartPtr`` instances
|
||||
believing that they are the sole owner of the ``T*`` pointer). A common
|
||||
situation where ``true`` should be passed is when the ``T`` instances use
|
||||
*intrusive* reference counting.
|
||||
|
||||
Please take a look at the :ref:`macro_notes` before using this feature.
|
||||
|
||||
By default, pybind11 assumes that your custom smart pointer has a standard
|
||||
interface, i.e. provides a ``.get()`` member function to access the underlying
|
||||
raw pointer. If this is not the case, pybind11's ``holder_helper`` must be
|
||||
specialized:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Always needed for custom holder types
|
||||
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>);
|
||||
|
||||
// Only needed if the type's `.get()` goes by another name
|
||||
namespace PYBIND11_NAMESPACE { namespace detail {
|
||||
template <typename T>
|
||||
struct holder_helper<SmartPtr<T>> { // <-- specialization
|
||||
static const T *get(const SmartPtr<T> &p) { return p.getPointer(); }
|
||||
};
|
||||
}}
|
||||
|
||||
The above specialization informs pybind11 that the custom ``SmartPtr`` class
|
||||
provides ``.get()`` functionality via ``.getPointer()``.
|
||||
|
||||
.. seealso::
|
||||
|
||||
The file :file:`tests/test_smart_ptr.cpp` contains a complete example
|
||||
that demonstrates how to work with custom reference-counting holder types
|
||||
in more detail.
|
307
thirdparty/pybind11/docs/basics.rst
vendored
Normal file
307
thirdparty/pybind11/docs/basics.rst
vendored
Normal file
@ -0,0 +1,307 @@
|
||||
.. _basics:
|
||||
|
||||
First steps
|
||||
###########
|
||||
|
||||
This sections demonstrates the basic features of pybind11. Before getting
|
||||
started, make sure that development environment is set up to compile the
|
||||
included set of test cases.
|
||||
|
||||
|
||||
Compiling the test cases
|
||||
========================
|
||||
|
||||
Linux/macOS
|
||||
-----------
|
||||
|
||||
On Linux you'll need to install the **python-dev** or **python3-dev** packages as
|
||||
well as **cmake**. On macOS, the included python version works out of the box,
|
||||
but **cmake** must still be installed.
|
||||
|
||||
After installing the prerequisites, run
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make check -j 4
|
||||
|
||||
The last line will both compile and run the tests.
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
On Windows, only **Visual Studio 2017** and newer are supported.
|
||||
|
||||
.. Note::
|
||||
|
||||
To use the C++17 in Visual Studio 2017 (MSVC 14.1), pybind11 requires the flag
|
||||
``/permissive-`` to be passed to the compiler `to enforce standard conformance`_. When
|
||||
building with Visual Studio 2019, this is not strictly necessary, but still advised.
|
||||
|
||||
.. _`to enforce standard conformance`: https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=vs-2017
|
||||
|
||||
To compile and run the tests:
|
||||
|
||||
.. code-block:: batch
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . --config Release --target check
|
||||
|
||||
This will create a Visual Studio project, compile and run the target, all from the
|
||||
command line.
|
||||
|
||||
.. Note::
|
||||
|
||||
If all tests fail, make sure that the Python binary and the testcases are compiled
|
||||
for the same processor type and bitness (i.e. either **i386** or **x86_64**). You
|
||||
can specify **x86_64** as the target architecture for the generated Visual Studio
|
||||
project using ``cmake -A x64 ..``.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Advanced users who are already familiar with Boost.Python may want to skip
|
||||
the tutorial and look at the test cases in the :file:`tests` directory,
|
||||
which exercise all features of pybind11.
|
||||
|
||||
Header and namespace conventions
|
||||
================================
|
||||
|
||||
For brevity, all code examples assume that the following two lines are present:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
Some features may require additional headers, but those will be specified as needed.
|
||||
|
||||
.. _simple_example:
|
||||
|
||||
Creating bindings for a simple function
|
||||
=======================================
|
||||
|
||||
Let's start by creating Python bindings for an extremely simple function, which
|
||||
adds two numbers and returns their result:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int add(int i, int j) {
|
||||
return i + j;
|
||||
}
|
||||
|
||||
For simplicity [#f1]_, we'll put both this function and the binding code into
|
||||
a file named :file:`example.cpp` with the following contents:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
int add(int i, int j) {
|
||||
return i + j;
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
m.doc() = "pybind11 example plugin"; // optional module docstring
|
||||
|
||||
m.def("add", &add, "A function that adds two numbers");
|
||||
}
|
||||
|
||||
.. [#f1] In practice, implementation and binding code will generally be located
|
||||
in separate files.
|
||||
|
||||
The :func:`PYBIND11_MODULE` macro creates a function that will be called when an
|
||||
``import`` statement is issued from within Python. The module name (``example``)
|
||||
is given as the first macro argument (it should not be in quotes). The second
|
||||
argument (``m``) defines a variable of type :class:`py::module_ <module>` which
|
||||
is the main interface for creating bindings. The method :func:`module_::def`
|
||||
generates binding code that exposes the ``add()`` function to Python.
|
||||
|
||||
.. note::
|
||||
|
||||
Notice how little code was needed to expose our function to Python: all
|
||||
details regarding the function's parameters and return value were
|
||||
automatically inferred using template metaprogramming. This overall
|
||||
approach and the used syntax are borrowed from Boost.Python, though the
|
||||
underlying implementation is very different.
|
||||
|
||||
pybind11 is a header-only library, hence it is not necessary to link against
|
||||
any special libraries and there are no intermediate (magic) translation steps.
|
||||
On Linux, the above example can be compiled using the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
|
||||
|
||||
.. note::
|
||||
|
||||
If you used :ref:`include_as_a_submodule` to get the pybind11 source, then
|
||||
use ``$(python3-config --includes) -Iextern/pybind11/include`` instead of
|
||||
``$(python3 -m pybind11 --includes)`` in the above compilation, as
|
||||
explained in :ref:`building_manually`.
|
||||
|
||||
For more details on the required compiler flags on Linux and macOS, see
|
||||
:ref:`building_manually`. For complete cross-platform compilation instructions,
|
||||
refer to the :ref:`compiling` page.
|
||||
|
||||
The `python_example`_ and `cmake_example`_ repositories are also a good place
|
||||
to start. They are both complete project examples with cross-platform build
|
||||
systems. The only difference between the two is that `python_example`_ uses
|
||||
Python's ``setuptools`` to build the module, while `cmake_example`_ uses CMake
|
||||
(which may be preferable for existing C++ projects).
|
||||
|
||||
.. _python_example: https://github.com/pybind/python_example
|
||||
.. _cmake_example: https://github.com/pybind/cmake_example
|
||||
|
||||
Building the above C++ code will produce a binary module file that can be
|
||||
imported to Python. Assuming that the compiled module is located in the
|
||||
current directory, the following interactive Python session shows how to
|
||||
load and execute the example:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
$ python
|
||||
Python 3.9.10 (main, Jan 15 2022, 11:48:04)
|
||||
[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> import example
|
||||
>>> example.add(1, 2)
|
||||
3
|
||||
>>>
|
||||
|
||||
.. _keyword_args:
|
||||
|
||||
Keyword arguments
|
||||
=================
|
||||
|
||||
With a simple code modification, it is possible to inform Python about the
|
||||
names of the arguments ("i" and "j" in this case).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("add", &add, "A function which adds two numbers",
|
||||
py::arg("i"), py::arg("j"));
|
||||
|
||||
:class:`arg` is one of several special tag classes which can be used to pass
|
||||
metadata into :func:`module_::def`. With this modified binding code, we can now
|
||||
call the function using keyword arguments, which is a more readable alternative
|
||||
particularly for functions taking many parameters:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> import example
|
||||
>>> example.add(i=1, j=2)
|
||||
3L
|
||||
|
||||
The keyword names also appear in the function signatures within the documentation.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> help(example)
|
||||
|
||||
....
|
||||
|
||||
FUNCTIONS
|
||||
add(...)
|
||||
Signature : (i: int, j: int) -> int
|
||||
|
||||
A function which adds two numbers
|
||||
|
||||
A shorter notation for named arguments is also available:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// regular notation
|
||||
m.def("add1", &add, py::arg("i"), py::arg("j"));
|
||||
// shorthand
|
||||
using namespace pybind11::literals;
|
||||
m.def("add2", &add, "i"_a, "j"_a);
|
||||
|
||||
The :var:`_a` suffix forms a C++11 literal which is equivalent to :class:`arg`.
|
||||
Note that the literal operator must first be made visible with the directive
|
||||
``using namespace pybind11::literals``. This does not bring in anything else
|
||||
from the ``pybind11`` namespace except for literals.
|
||||
|
||||
.. _default_args:
|
||||
|
||||
Default arguments
|
||||
=================
|
||||
|
||||
Suppose now that the function to be bound has default arguments, e.g.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int add(int i = 1, int j = 2) {
|
||||
return i + j;
|
||||
}
|
||||
|
||||
Unfortunately, pybind11 cannot automatically extract these parameters, since they
|
||||
are not part of the function's type information. However, they are simple to specify
|
||||
using an extension of :class:`arg`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("add", &add, "A function which adds two numbers",
|
||||
py::arg("i") = 1, py::arg("j") = 2);
|
||||
|
||||
The default values also appear within the documentation.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> help(example)
|
||||
|
||||
....
|
||||
|
||||
FUNCTIONS
|
||||
add(...)
|
||||
Signature : (i: int = 1, j: int = 2) -> int
|
||||
|
||||
A function which adds two numbers
|
||||
|
||||
The shorthand notation is also available for default arguments:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// regular notation
|
||||
m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2);
|
||||
// shorthand
|
||||
m.def("add2", &add, "i"_a=1, "j"_a=2);
|
||||
|
||||
Exporting variables
|
||||
===================
|
||||
|
||||
To expose a value from C++, use the ``attr`` function to register it in a
|
||||
module as shown below. Built-in types and general objects (more on that later)
|
||||
are automatically converted when assigned as attributes, and can be explicitly
|
||||
converted using the function ``py::cast``.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
m.attr("the_answer") = 42;
|
||||
py::object world = py::cast("World");
|
||||
m.attr("what") = world;
|
||||
}
|
||||
|
||||
These are then accessible from Python:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> import example
|
||||
>>> example.the_answer
|
||||
42
|
||||
>>> example.what
|
||||
'World'
|
||||
|
||||
.. _supported_types:
|
||||
|
||||
Supported data types
|
||||
====================
|
||||
|
||||
A large number of data types are supported out of the box and can be used
|
||||
seamlessly as functions arguments, return values or with ``py::cast`` in general.
|
||||
For a full overview, see the :doc:`advanced/cast/index` section.
|
87
thirdparty/pybind11/docs/benchmark.py
vendored
Normal file
87
thirdparty/pybind11/docs/benchmark.py
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
import datetime as dt
|
||||
import os
|
||||
import random
|
||||
|
||||
nfns = 4 # Functions per class
|
||||
nargs = 4 # Arguments per function
|
||||
|
||||
|
||||
def generate_dummy_code_pybind11(nclasses=10):
|
||||
decl = ""
|
||||
bindings = ""
|
||||
|
||||
for cl in range(nclasses):
|
||||
decl += f"class cl{cl:03};\n"
|
||||
decl += "\n"
|
||||
|
||||
for cl in range(nclasses):
|
||||
decl += f"class {cl:03} {{\n"
|
||||
decl += "public:\n"
|
||||
bindings += f' py::class_<cl{cl:03}>(m, "cl{cl:03}")\n'
|
||||
for fn in range(nfns):
|
||||
ret = random.randint(0, nclasses - 1)
|
||||
params = [random.randint(0, nclasses - 1) for i in range(nargs)]
|
||||
decl += f" cl{ret:03} *fn_{fn:03}("
|
||||
decl += ", ".join(f"cl{p:03} *" for p in params)
|
||||
decl += ");\n"
|
||||
bindings += f' .def("fn_{fn:03}", &cl{cl:03}::fn_{fn:03})\n'
|
||||
decl += "};\n\n"
|
||||
bindings += " ;\n"
|
||||
|
||||
result = "#include <pybind11/pybind11.h>\n\n"
|
||||
result += "namespace py = pybind11;\n\n"
|
||||
result += decl + "\n"
|
||||
result += "PYBIND11_MODULE(example, m) {\n"
|
||||
result += bindings
|
||||
result += "}"
|
||||
return result
|
||||
|
||||
|
||||
def generate_dummy_code_boost(nclasses=10):
|
||||
decl = ""
|
||||
bindings = ""
|
||||
|
||||
for cl in range(nclasses):
|
||||
decl += f"class cl{cl:03};\n"
|
||||
decl += "\n"
|
||||
|
||||
for cl in range(nclasses):
|
||||
decl += "class cl%03i {\n" % cl
|
||||
decl += "public:\n"
|
||||
bindings += f' py::class_<cl{cl:03}>("cl{cl:03}")\n'
|
||||
for fn in range(nfns):
|
||||
ret = random.randint(0, nclasses - 1)
|
||||
params = [random.randint(0, nclasses - 1) for i in range(nargs)]
|
||||
decl += f" cl{ret:03} *fn_{fn:03}("
|
||||
decl += ", ".join(f"cl{p:03} *" for p in params)
|
||||
decl += ");\n"
|
||||
bindings += f' .def("fn_{fn:03}", &cl{cl:03}::fn_{fn:03}, py::return_value_policy<py::manage_new_object>())\n'
|
||||
decl += "};\n\n"
|
||||
bindings += " ;\n"
|
||||
|
||||
result = "#include <boost/python.hpp>\n\n"
|
||||
result += "namespace py = boost::python;\n\n"
|
||||
result += decl + "\n"
|
||||
result += "BOOST_PYTHON_MODULE(example) {\n"
|
||||
result += bindings
|
||||
result += "}"
|
||||
return result
|
||||
|
||||
|
||||
for codegen in [generate_dummy_code_pybind11, generate_dummy_code_boost]:
|
||||
print("{")
|
||||
for i in range(10):
|
||||
nclasses = 2**i
|
||||
with open("test.cpp", "w") as f:
|
||||
f.write(codegen(nclasses))
|
||||
n1 = dt.datetime.now()
|
||||
os.system(
|
||||
"g++ -Os -shared -rdynamic -undefined dynamic_lookup "
|
||||
"-fvisibility=hidden -std=c++14 test.cpp -I include "
|
||||
"-I /System/Library/Frameworks/Python.framework/Headers -o test.so"
|
||||
)
|
||||
n2 = dt.datetime.now()
|
||||
elapsed = (n2 - n1).total_seconds()
|
||||
size = os.stat("test.so").st_size
|
||||
print(" {%i, %f, %i}," % (nclasses * nfns, elapsed, size))
|
||||
print("}")
|
95
thirdparty/pybind11/docs/benchmark.rst
vendored
Normal file
95
thirdparty/pybind11/docs/benchmark.rst
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
Benchmark
|
||||
=========
|
||||
|
||||
The following is the result of a synthetic benchmark comparing both compilation
|
||||
time and module size of pybind11 against Boost.Python. A detailed report about a
|
||||
Boost.Python to pybind11 conversion of a real project is available here: [#f1]_.
|
||||
|
||||
.. [#f1] http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf
|
||||
|
||||
Setup
|
||||
-----
|
||||
|
||||
A python script (see the ``docs/benchmark.py`` file) was used to generate a set
|
||||
of files with dummy classes whose count increases for each successive benchmark
|
||||
(between 1 and 2048 classes in powers of two). Each class has four methods with
|
||||
a randomly generated signature with a return value and four arguments. (There
|
||||
was no particular reason for this setup other than the desire to generate many
|
||||
unique function signatures whose count could be controlled in a simple way.)
|
||||
|
||||
Here is an example of the binding code for one class:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
...
|
||||
class cl034 {
|
||||
public:
|
||||
cl279 *fn_000(cl084 *, cl057 *, cl065 *, cl042 *);
|
||||
cl025 *fn_001(cl098 *, cl262 *, cl414 *, cl121 *);
|
||||
cl085 *fn_002(cl445 *, cl297 *, cl145 *, cl421 *);
|
||||
cl470 *fn_003(cl200 *, cl323 *, cl332 *, cl492 *);
|
||||
};
|
||||
...
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
...
|
||||
py::class_<cl034>(m, "cl034")
|
||||
.def("fn_000", &cl034::fn_000)
|
||||
.def("fn_001", &cl034::fn_001)
|
||||
.def("fn_002", &cl034::fn_002)
|
||||
.def("fn_003", &cl034::fn_003)
|
||||
...
|
||||
}
|
||||
|
||||
The Boost.Python version looks almost identical except that a return value
|
||||
policy had to be specified as an argument to ``def()``. For both libraries,
|
||||
compilation was done with
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
Apple LLVM version 7.0.2 (clang-700.1.81)
|
||||
|
||||
and the following compilation flags
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
g++ -Os -shared -rdynamic -undefined dynamic_lookup -fvisibility=hidden -std=c++14
|
||||
|
||||
Compilation time
|
||||
----------------
|
||||
|
||||
The following log-log plot shows how the compilation time grows for an
|
||||
increasing number of class and function declarations. pybind11 includes many
|
||||
fewer headers, which initially leads to shorter compilation times, but the
|
||||
performance is ultimately fairly similar (pybind11 is 19.8 seconds faster for
|
||||
the largest largest file with 2048 classes and a total of 8192 methods -- a
|
||||
modest **1.2x** speedup relative to Boost.Python, which required 116.35
|
||||
seconds).
|
||||
|
||||
.. only:: not latex
|
||||
|
||||
.. image:: pybind11_vs_boost_python1.svg
|
||||
|
||||
.. only:: latex
|
||||
|
||||
.. image:: pybind11_vs_boost_python1.png
|
||||
|
||||
Module size
|
||||
-----------
|
||||
|
||||
Differences between the two libraries become much more pronounced when
|
||||
considering the file size of the generated Python plugin: for the largest file,
|
||||
the binary generated by Boost.Python required 16.8 MiB, which was **2.17
|
||||
times** / **9.1 megabytes** larger than the output generated by pybind11. For
|
||||
very small inputs, Boost.Python has an edge in the plot below -- however, note
|
||||
that it stores many definitions in an external library, whose size was not
|
||||
included here, hence the comparison is slightly shifted in Boost.Python's
|
||||
favor.
|
||||
|
||||
.. only:: not latex
|
||||
|
||||
.. image:: pybind11_vs_boost_python2.svg
|
||||
|
||||
.. only:: latex
|
||||
|
||||
.. image:: pybind11_vs_boost_python2.png
|
2832
thirdparty/pybind11/docs/changelog.rst
vendored
Normal file
2832
thirdparty/pybind11/docs/changelog.rst
vendored
Normal file
File diff suppressed because it is too large
Load Diff
555
thirdparty/pybind11/docs/classes.rst
vendored
Normal file
555
thirdparty/pybind11/docs/classes.rst
vendored
Normal file
@ -0,0 +1,555 @@
|
||||
.. _classes:
|
||||
|
||||
Object-oriented code
|
||||
####################
|
||||
|
||||
Creating bindings for a custom type
|
||||
===================================
|
||||
|
||||
Let's now look at a more complex example where we'll create bindings for a
|
||||
custom C++ data structure named ``Pet``. Its definition is given below:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Pet {
|
||||
Pet(const std::string &name) : name(name) { }
|
||||
void setName(const std::string &name_) { name = name_; }
|
||||
const std::string &getName() const { return name; }
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
||||
The binding code for ``Pet`` looks as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("setName", &Pet::setName)
|
||||
.def("getName", &Pet::getName);
|
||||
}
|
||||
|
||||
:class:`class_` creates bindings for a C++ *class* or *struct*-style data
|
||||
structure. :func:`init` is a convenience function that takes the types of a
|
||||
constructor's parameters as template arguments and wraps the corresponding
|
||||
constructor (see the :ref:`custom_constructors` section for details). An
|
||||
interactive Python session demonstrating this example is shown below:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
% python
|
||||
>>> import example
|
||||
>>> p = example.Pet("Molly")
|
||||
>>> print(p)
|
||||
<example.Pet object at 0x10cd98060>
|
||||
>>> p.getName()
|
||||
'Molly'
|
||||
>>> p.setName("Charly")
|
||||
>>> p.getName()
|
||||
'Charly'
|
||||
|
||||
.. seealso::
|
||||
|
||||
Static member functions can be bound in the same way using
|
||||
:func:`class_::def_static`.
|
||||
|
||||
.. note::
|
||||
|
||||
Binding C++ types in unnamed namespaces (also known as anonymous namespaces)
|
||||
works reliably on many platforms, but not all. The `XFAIL_CONDITION` in
|
||||
tests/test_unnamed_namespace_a.py encodes the currently known conditions.
|
||||
For background see `#4319 <https://github.com/pybind/pybind11/pull/4319>`_.
|
||||
If portability is a concern, it is therefore not recommended to bind C++
|
||||
types in unnamed namespaces. It will be safest to manually pick unique
|
||||
namespace names.
|
||||
|
||||
Keyword and default arguments
|
||||
=============================
|
||||
It is possible to specify keyword and default arguments using the syntax
|
||||
discussed in the previous chapter. Refer to the sections :ref:`keyword_args`
|
||||
and :ref:`default_args` for details.
|
||||
|
||||
Binding lambda functions
|
||||
========================
|
||||
|
||||
Note how ``print(p)`` produced a rather useless summary of our data structure in the example above:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> print(p)
|
||||
<example.Pet object at 0x10cd98060>
|
||||
|
||||
To address this, we could bind a utility function that returns a human-readable
|
||||
summary to the special method slot named ``__repr__``. Unfortunately, there is no
|
||||
suitable functionality in the ``Pet`` data structure, and it would be nice if
|
||||
we did not have to change it. This can easily be accomplished by binding a
|
||||
Lambda function instead:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("setName", &Pet::setName)
|
||||
.def("getName", &Pet::getName)
|
||||
.def("__repr__",
|
||||
[](const Pet &a) {
|
||||
return "<example.Pet named '" + a.name + "'>";
|
||||
}
|
||||
);
|
||||
|
||||
Both stateless [#f1]_ and stateful lambda closures are supported by pybind11.
|
||||
With the above change, the same Python code now produces the following output:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> print(p)
|
||||
<example.Pet named 'Molly'>
|
||||
|
||||
.. [#f1] Stateless closures are those with an empty pair of brackets ``[]`` as the capture object.
|
||||
|
||||
.. _properties:
|
||||
|
||||
Instance and static fields
|
||||
==========================
|
||||
|
||||
We can also directly expose the ``name`` field using the
|
||||
:func:`class_::def_readwrite` method. A similar :func:`class_::def_readonly`
|
||||
method also exists for ``const`` fields.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name)
|
||||
// ... remainder ...
|
||||
|
||||
This makes it possible to write
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = example.Pet("Molly")
|
||||
>>> p.name
|
||||
'Molly'
|
||||
>>> p.name = "Charly"
|
||||
>>> p.name
|
||||
'Charly'
|
||||
|
||||
Now suppose that ``Pet::name`` was a private internal variable
|
||||
that can only be accessed via setters and getters.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class Pet {
|
||||
public:
|
||||
Pet(const std::string &name) : name(name) { }
|
||||
void setName(const std::string &name_) { name = name_; }
|
||||
const std::string &getName() const { return name; }
|
||||
private:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
In this case, the method :func:`class_::def_property`
|
||||
(:func:`class_::def_property_readonly` for read-only data) can be used to
|
||||
provide a field-like interface within Python that will transparently call
|
||||
the setter and getter functions:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def_property("name", &Pet::getName, &Pet::setName)
|
||||
// ... remainder ...
|
||||
|
||||
Write only properties can be defined by passing ``nullptr`` as the
|
||||
input for the read function.
|
||||
|
||||
.. seealso::
|
||||
|
||||
Similar functions :func:`class_::def_readwrite_static`,
|
||||
:func:`class_::def_readonly_static` :func:`class_::def_property_static`,
|
||||
and :func:`class_::def_property_readonly_static` are provided for binding
|
||||
static variables and properties. Please also see the section on
|
||||
:ref:`static_properties` in the advanced part of the documentation.
|
||||
|
||||
Dynamic attributes
|
||||
==================
|
||||
|
||||
Native Python classes can pick up new attributes dynamically:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> class Pet:
|
||||
... name = "Molly"
|
||||
...
|
||||
>>> p = Pet()
|
||||
>>> p.name = "Charly" # overwrite existing
|
||||
>>> p.age = 2 # dynamically add a new attribute
|
||||
|
||||
By default, classes exported from C++ do not support this and the only writable
|
||||
attributes are the ones explicitly defined using :func:`class_::def_readwrite`
|
||||
or :func:`class_::def_property`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
Trying to set any other attribute results in an error:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = example.Pet()
|
||||
>>> p.name = "Charly" # OK, attribute defined in C++
|
||||
>>> p.age = 2 # fail
|
||||
AttributeError: 'Pet' object has no attribute 'age'
|
||||
|
||||
To enable dynamic attributes for C++ classes, the :class:`py::dynamic_attr` tag
|
||||
must be added to the :class:`py::class_` constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet", py::dynamic_attr())
|
||||
.def(py::init<>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
Now everything works as expected:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = example.Pet()
|
||||
>>> p.name = "Charly" # OK, overwrite value in C++
|
||||
>>> p.age = 2 # OK, dynamically add a new attribute
|
||||
>>> p.__dict__ # just like a native Python class
|
||||
{'age': 2}
|
||||
|
||||
Note that there is a small runtime cost for a class with dynamic attributes.
|
||||
Not only because of the addition of a ``__dict__``, but also because of more
|
||||
expensive garbage collection tracking which must be activated to resolve
|
||||
possible circular references. Native Python classes incur this same cost by
|
||||
default, so this is not anything to worry about. By default, pybind11 classes
|
||||
are more efficient than native Python classes. Enabling dynamic attributes
|
||||
just brings them on par.
|
||||
|
||||
.. _inheritance:
|
||||
|
||||
Inheritance and automatic downcasting
|
||||
=====================================
|
||||
|
||||
Suppose now that the example consists of two data structures with an
|
||||
inheritance relationship:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Pet {
|
||||
Pet(const std::string &name) : name(name) { }
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct Dog : Pet {
|
||||
Dog(const std::string &name) : Pet(name) { }
|
||||
std::string bark() const { return "woof!"; }
|
||||
};
|
||||
|
||||
There are two different ways of indicating a hierarchical relationship to
|
||||
pybind11: the first specifies the C++ base class as an extra template
|
||||
parameter of the :class:`class_`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
// Method 1: template parameter:
|
||||
py::class_<Dog, Pet /* <- specify C++ parent type */>(m, "Dog")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
Alternatively, we can also assign a name to the previously bound ``Pet``
|
||||
:class:`class_` object and reference it when binding the ``Dog`` class:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet> pet(m, "Pet");
|
||||
pet.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
// Method 2: pass parent class_ object:
|
||||
py::class_<Dog>(m, "Dog", pet /* <- specify Python parent type */)
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
Functionality-wise, both approaches are equivalent. Afterwards, instances will
|
||||
expose fields and methods of both types:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = example.Dog("Molly")
|
||||
>>> p.name
|
||||
'Molly'
|
||||
>>> p.bark()
|
||||
'woof!'
|
||||
|
||||
The C++ classes defined above are regular non-polymorphic types with an
|
||||
inheritance relationship. This is reflected in Python:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Return a base pointer to a derived instance
|
||||
m.def("pet_store", []() { return std::unique_ptr<Pet>(new Dog("Molly")); });
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = example.pet_store()
|
||||
>>> type(p) # `Dog` instance behind `Pet` pointer
|
||||
Pet # no pointer downcasting for regular non-polymorphic types
|
||||
>>> p.bark()
|
||||
AttributeError: 'Pet' object has no attribute 'bark'
|
||||
|
||||
The function returned a ``Dog`` instance, but because it's a non-polymorphic
|
||||
type behind a base pointer, Python only sees a ``Pet``. In C++, a type is only
|
||||
considered polymorphic if it has at least one virtual function and pybind11
|
||||
will automatically recognize this:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct PolymorphicPet {
|
||||
virtual ~PolymorphicPet() = default;
|
||||
};
|
||||
|
||||
struct PolymorphicDog : PolymorphicPet {
|
||||
std::string bark() const { return "woof!"; }
|
||||
};
|
||||
|
||||
// Same binding code
|
||||
py::class_<PolymorphicPet>(m, "PolymorphicPet");
|
||||
py::class_<PolymorphicDog, PolymorphicPet>(m, "PolymorphicDog")
|
||||
.def(py::init<>())
|
||||
.def("bark", &PolymorphicDog::bark);
|
||||
|
||||
// Again, return a base pointer to a derived instance
|
||||
m.def("pet_store2", []() { return std::unique_ptr<PolymorphicPet>(new PolymorphicDog); });
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = example.pet_store2()
|
||||
>>> type(p)
|
||||
PolymorphicDog # automatically downcast
|
||||
>>> p.bark()
|
||||
'woof!'
|
||||
|
||||
Given a pointer to a polymorphic base, pybind11 performs automatic downcasting
|
||||
to the actual derived type. Note that this goes beyond the usual situation in
|
||||
C++: we don't just get access to the virtual functions of the base, we get the
|
||||
concrete derived type including functions and attributes that the base type may
|
||||
not even be aware of.
|
||||
|
||||
.. seealso::
|
||||
|
||||
For more information about polymorphic behavior see :ref:`overriding_virtuals`.
|
||||
|
||||
|
||||
Overloaded methods
|
||||
==================
|
||||
|
||||
Sometimes there are several overloaded C++ methods with the same name taking
|
||||
different kinds of input arguments:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Pet {
|
||||
Pet(const std::string &name, int age) : name(name), age(age) { }
|
||||
|
||||
void set(int age_) { age = age_; }
|
||||
void set(const std::string &name_) { name = name_; }
|
||||
|
||||
std::string name;
|
||||
int age;
|
||||
};
|
||||
|
||||
Attempting to bind ``Pet::set`` will cause an error since the compiler does not
|
||||
know which method the user intended to select. We can disambiguate by casting
|
||||
them to function pointers. Binding multiple functions to the same Python name
|
||||
automatically creates a chain of function overloads that will be tried in
|
||||
sequence.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &, int>())
|
||||
.def("set", static_cast<void (Pet::*)(int)>(&Pet::set), "Set the pet's age")
|
||||
.def("set", static_cast<void (Pet::*)(const std::string &)>(&Pet::set), "Set the pet's name");
|
||||
|
||||
The overload signatures are also visible in the method's docstring:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> help(example.Pet)
|
||||
|
||||
class Pet(__builtin__.object)
|
||||
| Methods defined here:
|
||||
|
|
||||
| __init__(...)
|
||||
| Signature : (Pet, str, int) -> NoneType
|
||||
|
|
||||
| set(...)
|
||||
| 1. Signature : (Pet, int) -> NoneType
|
||||
|
|
||||
| Set the pet's age
|
||||
|
|
||||
| 2. Signature : (Pet, str) -> NoneType
|
||||
|
|
||||
| Set the pet's name
|
||||
|
||||
If you have a C++14 compatible compiler [#cpp14]_, you can use an alternative
|
||||
syntax to cast the overloaded function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def("set", py::overload_cast<int>(&Pet::set), "Set the pet's age")
|
||||
.def("set", py::overload_cast<const std::string &>(&Pet::set), "Set the pet's name");
|
||||
|
||||
Here, ``py::overload_cast`` only requires the parameter types to be specified.
|
||||
The return type and class are deduced. This avoids the additional noise of
|
||||
``void (Pet::*)()`` as seen in the raw cast. If a function is overloaded based
|
||||
on constness, the ``py::const_`` tag should be used:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Widget {
|
||||
int foo(int x, float y);
|
||||
int foo(int x, float y) const;
|
||||
};
|
||||
|
||||
py::class_<Widget>(m, "Widget")
|
||||
.def("foo_mutable", py::overload_cast<int, float>(&Widget::foo))
|
||||
.def("foo_const", py::overload_cast<int, float>(&Widget::foo, py::const_));
|
||||
|
||||
If you prefer the ``py::overload_cast`` syntax but have a C++11 compatible compiler only,
|
||||
you can use ``py::detail::overload_cast_impl`` with an additional set of parentheses:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
template <typename... Args>
|
||||
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;
|
||||
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def("set", overload_cast_<int>()(&Pet::set), "Set the pet's age")
|
||||
.def("set", overload_cast_<const std::string &>()(&Pet::set), "Set the pet's name");
|
||||
|
||||
.. [#cpp14] A compiler which supports the ``-std=c++14`` flag.
|
||||
|
||||
.. note::
|
||||
|
||||
To define multiple overloaded constructors, simply declare one after the
|
||||
other using the ``.def(py::init<...>())`` syntax. The existing machinery
|
||||
for specifying keyword and default arguments also works.
|
||||
|
||||
Enumerations and internal types
|
||||
===============================
|
||||
|
||||
Let's now suppose that the example class contains internal types like enumerations, e.g.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Pet {
|
||||
enum Kind {
|
||||
Dog = 0,
|
||||
Cat
|
||||
};
|
||||
|
||||
struct Attributes {
|
||||
float age = 0;
|
||||
};
|
||||
|
||||
Pet(const std::string &name, Kind type) : name(name), type(type) { }
|
||||
|
||||
std::string name;
|
||||
Kind type;
|
||||
Attributes attr;
|
||||
};
|
||||
|
||||
The binding code for this example looks as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Pet> pet(m, "Pet");
|
||||
|
||||
pet.def(py::init<const std::string &, Pet::Kind>())
|
||||
.def_readwrite("name", &Pet::name)
|
||||
.def_readwrite("type", &Pet::type)
|
||||
.def_readwrite("attr", &Pet::attr);
|
||||
|
||||
py::enum_<Pet::Kind>(pet, "Kind")
|
||||
.value("Dog", Pet::Kind::Dog)
|
||||
.value("Cat", Pet::Kind::Cat)
|
||||
.export_values();
|
||||
|
||||
py::class_<Pet::Attributes>(pet, "Attributes")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("age", &Pet::Attributes::age);
|
||||
|
||||
|
||||
To ensure that the nested types ``Kind`` and ``Attributes`` are created within the scope of ``Pet``, the
|
||||
``pet`` :class:`class_` instance must be supplied to the :class:`enum_` and :class:`class_`
|
||||
constructor. The :func:`enum_::export_values` function exports the enum entries
|
||||
into the parent scope, which should be skipped for newer C++11-style strongly
|
||||
typed enums.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = Pet("Lucy", Pet.Cat)
|
||||
>>> p.type
|
||||
Kind.Cat
|
||||
>>> int(p.type)
|
||||
1L
|
||||
|
||||
The entries defined by the enumeration type are exposed in the ``__members__`` property:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> Pet.Kind.__members__
|
||||
{'Dog': Kind.Dog, 'Cat': Kind.Cat}
|
||||
|
||||
The ``name`` property returns the name of the enum value as a unicode string.
|
||||
|
||||
.. note::
|
||||
|
||||
It is also possible to use ``str(enum)``, however these accomplish different
|
||||
goals. The following shows how these two approaches differ.
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> p = Pet("Lucy", Pet.Cat)
|
||||
>>> pet_type = p.type
|
||||
>>> pet_type
|
||||
Pet.Cat
|
||||
>>> str(pet_type)
|
||||
'Pet.Cat'
|
||||
>>> pet_type.name
|
||||
'Cat'
|
||||
|
||||
.. note::
|
||||
|
||||
When the special tag ``py::arithmetic()`` is specified to the ``enum_``
|
||||
constructor, pybind11 creates an enumeration that also supports rudimentary
|
||||
arithmetic and bit-level operations like comparisons, and, or, xor, negation,
|
||||
etc.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::enum_<Pet::Kind>(pet, "Kind", py::arithmetic())
|
||||
...
|
||||
|
||||
By default, these are omitted to conserve space.
|
||||
|
||||
.. warning::
|
||||
|
||||
Contrary to Python customs, enum values from the wrappers should not be compared using ``is``, but with ``==`` (see `#1177 <https://github.com/pybind/pybind11/issues/1177>`_ for background).
|
8
thirdparty/pybind11/docs/cmake/index.rst
vendored
Normal file
8
thirdparty/pybind11/docs/cmake/index.rst
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
CMake helpers
|
||||
-------------
|
||||
|
||||
Pybind11 can be used with ``add_subdirectory(extern/pybind11)``, or from an
|
||||
install with ``find_package(pybind11 CONFIG)``. The interface provided in
|
||||
either case is functionally identical.
|
||||
|
||||
.. cmake-module:: ../../tools/pybind11Config.cmake.in
|
641
thirdparty/pybind11/docs/compiling.rst
vendored
Normal file
641
thirdparty/pybind11/docs/compiling.rst
vendored
Normal file
@ -0,0 +1,641 @@
|
||||
.. _compiling:
|
||||
|
||||
Build systems
|
||||
#############
|
||||
|
||||
.. _build-setuptools:
|
||||
|
||||
Building with setuptools
|
||||
========================
|
||||
|
||||
For projects on PyPI, building with setuptools is the way to go. Sylvain Corlay
|
||||
has kindly provided an example project which shows how to set up everything,
|
||||
including automatic generation of documentation using Sphinx. Please refer to
|
||||
the [python_example]_ repository.
|
||||
|
||||
.. [python_example] https://github.com/pybind/python_example
|
||||
|
||||
A helper file is provided with pybind11 that can simplify usage with setuptools.
|
||||
|
||||
To use pybind11 inside your ``setup.py``, you have to have some system to
|
||||
ensure that ``pybind11`` is installed when you build your package. There are
|
||||
four possible ways to do this, and pybind11 supports all four: You can ask all
|
||||
users to install pybind11 beforehand (bad), you can use
|
||||
:ref:`setup_helpers-pep518` (good, but very new and requires Pip 10),
|
||||
:ref:`setup_helpers-setup_requires` (discouraged by Python packagers now that
|
||||
PEP 518 is available, but it still works everywhere), or you can
|
||||
:ref:`setup_helpers-copy-manually` (always works but you have to manually sync
|
||||
your copy to get updates).
|
||||
|
||||
An example of a ``setup.py`` using pybind11's helpers:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from glob import glob
|
||||
from setuptools import setup
|
||||
from pybind11.setup_helpers import Pybind11Extension
|
||||
|
||||
ext_modules = [
|
||||
Pybind11Extension(
|
||||
"python_example",
|
||||
sorted(glob("src/*.cpp")), # Sort source files for reproducibility
|
||||
),
|
||||
]
|
||||
|
||||
setup(..., ext_modules=ext_modules)
|
||||
|
||||
If you want to do an automatic search for the highest supported C++ standard,
|
||||
that is supported via a ``build_ext`` command override; it will only affect
|
||||
``Pybind11Extensions``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from glob import glob
|
||||
from setuptools import setup
|
||||
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
||||
|
||||
ext_modules = [
|
||||
Pybind11Extension(
|
||||
"python_example",
|
||||
sorted(glob("src/*.cpp")),
|
||||
),
|
||||
]
|
||||
|
||||
setup(..., cmdclass={"build_ext": build_ext}, ext_modules=ext_modules)
|
||||
|
||||
If you have single-file extension modules that are directly stored in the
|
||||
Python source tree (``foo.cpp`` in the same directory as where a ``foo.py``
|
||||
would be located), you can also generate ``Pybind11Extensions`` using
|
||||
``setup_helpers.intree_extensions``: ``intree_extensions(["path/to/foo.cpp",
|
||||
...])`` returns a list of ``Pybind11Extensions`` which can be passed to
|
||||
``ext_modules``, possibly after further customizing their attributes
|
||||
(``libraries``, ``include_dirs``, etc.). By doing so, a ``foo.*.so`` extension
|
||||
module will be generated and made available upon installation.
|
||||
|
||||
``intree_extension`` will automatically detect if you are using a ``src``-style
|
||||
layout (as long as no namespace packages are involved), but you can also
|
||||
explicitly pass ``package_dir`` to it (as in ``setuptools.setup``).
|
||||
|
||||
Since pybind11 does not require NumPy when building, a light-weight replacement
|
||||
for NumPy's parallel compilation distutils tool is included. Use it like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pybind11.setup_helpers import ParallelCompile
|
||||
|
||||
# Optional multithreaded build
|
||||
ParallelCompile("NPY_NUM_BUILD_JOBS").install()
|
||||
|
||||
setup(...)
|
||||
|
||||
The argument is the name of an environment variable to control the number of
|
||||
threads, such as ``NPY_NUM_BUILD_JOBS`` (as used by NumPy), though you can set
|
||||
something different if you want; ``CMAKE_BUILD_PARALLEL_LEVEL`` is another choice
|
||||
a user might expect. You can also pass ``default=N`` to set the default number
|
||||
of threads (0 will take the number of threads available) and ``max=N``, the
|
||||
maximum number of threads; if you have a large extension you may want set this
|
||||
to a memory dependent number.
|
||||
|
||||
If you are developing rapidly and have a lot of C++ files, you may want to
|
||||
avoid rebuilding files that have not changed. For simple cases were you are
|
||||
using ``pip install -e .`` and do not have local headers, you can skip the
|
||||
rebuild if an object file is newer than its source (headers are not checked!)
|
||||
with the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pybind11.setup_helpers import ParallelCompile, naive_recompile
|
||||
|
||||
ParallelCompile("NPY_NUM_BUILD_JOBS", needs_recompile=naive_recompile).install()
|
||||
|
||||
|
||||
If you have a more complex build, you can implement a smarter function and pass
|
||||
it to ``needs_recompile``, or you can use [Ccache]_ instead. ``CXX="cache g++"
|
||||
pip install -e .`` would be the way to use it with GCC, for example. Unlike the
|
||||
simple solution, this even works even when not compiling in editable mode, but
|
||||
it does require Ccache to be installed.
|
||||
|
||||
Keep in mind that Pip will not even attempt to rebuild if it thinks it has
|
||||
already built a copy of your code, which it deduces from the version number.
|
||||
One way to avoid this is to use [setuptools_scm]_, which will generate a
|
||||
version number that includes the number of commits since your last tag and a
|
||||
hash for a dirty directory. Another way to force a rebuild is purge your cache
|
||||
or use Pip's ``--no-cache-dir`` option.
|
||||
|
||||
.. [Ccache] https://ccache.dev
|
||||
|
||||
.. [setuptools_scm] https://github.com/pypa/setuptools_scm
|
||||
|
||||
.. _setup_helpers-pep518:
|
||||
|
||||
PEP 518 requirements (Pip 10+ required)
|
||||
---------------------------------------
|
||||
|
||||
If you use `PEP 518's <https://www.python.org/dev/peps/pep-0518/>`_
|
||||
``pyproject.toml`` file, you can ensure that ``pybind11`` is available during
|
||||
the compilation of your project. When this file exists, Pip will make a new
|
||||
virtual environment, download just the packages listed here in ``requires=``,
|
||||
and build a wheel (binary Python package). It will then throw away the
|
||||
environment, and install your wheel.
|
||||
|
||||
Your ``pyproject.toml`` file will likely look something like this:
|
||||
|
||||
.. code-block:: toml
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=42", "pybind11>=2.6.1"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
.. note::
|
||||
|
||||
The main drawback to this method is that a `PEP 517`_ compliant build tool,
|
||||
such as Pip 10+, is required for this approach to work; older versions of
|
||||
Pip completely ignore this file. If you distribute binaries (called wheels
|
||||
in Python) using something like `cibuildwheel`_, remember that ``setup.py``
|
||||
and ``pyproject.toml`` are not even contained in the wheel, so this high
|
||||
Pip requirement is only for source builds, and will not affect users of
|
||||
your binary wheels. If you are building SDists and wheels, then
|
||||
`pypa-build`_ is the recommended official tool.
|
||||
|
||||
.. _PEP 517: https://www.python.org/dev/peps/pep-0517/
|
||||
.. _cibuildwheel: https://cibuildwheel.readthedocs.io
|
||||
.. _pypa-build: https://pypa-build.readthedocs.io/en/latest/
|
||||
|
||||
.. _setup_helpers-setup_requires:
|
||||
|
||||
Classic ``setup_requires``
|
||||
--------------------------
|
||||
|
||||
If you want to support old versions of Pip with the classic
|
||||
``setup_requires=["pybind11"]`` keyword argument to setup, which triggers a
|
||||
two-phase ``setup.py`` run, then you will need to use something like this to
|
||||
ensure the first pass works (which has not yet installed the ``setup_requires``
|
||||
packages, since it can't install something it does not know about):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
try:
|
||||
from pybind11.setup_helpers import Pybind11Extension
|
||||
except ImportError:
|
||||
from setuptools import Extension as Pybind11Extension
|
||||
|
||||
|
||||
It doesn't matter that the Extension class is not the enhanced subclass for the
|
||||
first pass run; and the second pass will have the ``setup_requires``
|
||||
requirements.
|
||||
|
||||
This is obviously more of a hack than the PEP 518 method, but it supports
|
||||
ancient versions of Pip.
|
||||
|
||||
.. _setup_helpers-copy-manually:
|
||||
|
||||
Copy manually
|
||||
-------------
|
||||
|
||||
You can also copy ``setup_helpers.py`` directly to your project; it was
|
||||
designed to be usable standalone, like the old example ``setup.py``. You can
|
||||
set ``include_pybind11=False`` to skip including the pybind11 package headers,
|
||||
so you can use it with git submodules and a specific git version. If you use
|
||||
this, you will need to import from a local file in ``setup.py`` and ensure the
|
||||
helper file is part of your MANIFEST.
|
||||
|
||||
|
||||
Closely related, if you include pybind11 as a subproject, you can run the
|
||||
``setup_helpers.py`` inplace. If loaded correctly, this should even pick up
|
||||
the correct include for pybind11, though you can turn it off as shown above if
|
||||
you want to input it manually.
|
||||
|
||||
Suggested usage if you have pybind11 as a submodule in ``extern/pybind11``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
sys.path.append(os.path.join(DIR, "extern", "pybind11"))
|
||||
from pybind11.setup_helpers import Pybind11Extension # noqa: E402
|
||||
|
||||
del sys.path[-1]
|
||||
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
|
||||
Added ``setup_helpers`` file.
|
||||
|
||||
Building with cppimport
|
||||
========================
|
||||
|
||||
[cppimport]_ is a small Python import hook that determines whether there is a C++
|
||||
source file whose name matches the requested module. If there is, the file is
|
||||
compiled as a Python extension using pybind11 and placed in the same folder as
|
||||
the C++ source file. Python is then able to find the module and load it.
|
||||
|
||||
.. [cppimport] https://github.com/tbenthompson/cppimport
|
||||
|
||||
.. _cmake:
|
||||
|
||||
Building with CMake
|
||||
===================
|
||||
|
||||
For C++ codebases that have an existing CMake-based build system, a Python
|
||||
extension module can be created with just a few lines of code:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.27)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(pybind11)
|
||||
pybind11_add_module(example example.cpp)
|
||||
|
||||
This assumes that the pybind11 repository is located in a subdirectory named
|
||||
:file:`pybind11` and that the code is located in a file named :file:`example.cpp`.
|
||||
The CMake command ``add_subdirectory`` will import the pybind11 project which
|
||||
provides the ``pybind11_add_module`` function. It will take care of all the
|
||||
details needed to build a Python extension module on any platform.
|
||||
|
||||
A working sample project, including a way to invoke CMake from :file:`setup.py` for
|
||||
PyPI integration, can be found in the [cmake_example]_ repository.
|
||||
|
||||
.. [cmake_example] https://github.com/pybind/cmake_example
|
||||
|
||||
.. versionchanged:: 2.6
|
||||
CMake 3.4+ is required.
|
||||
|
||||
.. versionchanged:: 2.11
|
||||
CMake 3.5+ is required.
|
||||
|
||||
Further information can be found at :doc:`cmake/index`.
|
||||
|
||||
pybind11_add_module
|
||||
-------------------
|
||||
|
||||
To ease the creation of Python extension modules, pybind11 provides a CMake
|
||||
function with the following signature:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
|
||||
[NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...])
|
||||
|
||||
This function behaves very much like CMake's builtin ``add_library`` (in fact,
|
||||
it's a wrapper function around that command). It will add a library target
|
||||
called ``<name>`` to be built from the listed source files. In addition, it
|
||||
will take care of all the Python-specific compiler and linker flags as well
|
||||
as the OS- and Python-version-specific file extension. The produced target
|
||||
``<name>`` can be further manipulated with regular CMake commands.
|
||||
|
||||
``MODULE`` or ``SHARED`` may be given to specify the type of library. If no
|
||||
type is given, ``MODULE`` is used by default which ensures the creation of a
|
||||
Python-exclusive module. Specifying ``SHARED`` will create a more traditional
|
||||
dynamic library which can also be linked from elsewhere. ``EXCLUDE_FROM_ALL``
|
||||
removes this target from the default build (see CMake docs for details).
|
||||
|
||||
Since pybind11 is a template library, ``pybind11_add_module`` adds compiler
|
||||
flags to ensure high quality code generation without bloat arising from long
|
||||
symbol names and duplication of code in different translation units. It
|
||||
sets default visibility to *hidden*, which is required for some pybind11
|
||||
features and functionality when attempting to load multiple pybind11 modules
|
||||
compiled under different pybind11 versions. It also adds additional flags
|
||||
enabling LTO (Link Time Optimization) and strip unneeded symbols. See the
|
||||
:ref:`FAQ entry <faq:symhidden>` for a more detailed explanation. These
|
||||
latter optimizations are never applied in ``Debug`` mode. If ``NO_EXTRAS`` is
|
||||
given, they will always be disabled, even in ``Release`` mode. However, this
|
||||
will result in code bloat and is generally not recommended.
|
||||
|
||||
As stated above, LTO is enabled by default. Some newer compilers also support
|
||||
different flavors of LTO such as `ThinLTO`_. Setting ``THIN_LTO`` will cause
|
||||
the function to prefer this flavor if available. The function falls back to
|
||||
regular LTO if ``-flto=thin`` is not available. If
|
||||
``CMAKE_INTERPROCEDURAL_OPTIMIZATION`` is set (either ``ON`` or ``OFF``), then
|
||||
that will be respected instead of the built-in flag search.
|
||||
|
||||
.. note::
|
||||
|
||||
If you want to set the property form on targets or the
|
||||
``CMAKE_INTERPROCEDURAL_OPTIMIZATION_<CONFIG>`` versions of this, you should
|
||||
still use ``set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)`` (otherwise a
|
||||
no-op) to disable pybind11's ipo flags.
|
||||
|
||||
The ``OPT_SIZE`` flag enables size-based optimization equivalent to the
|
||||
standard ``/Os`` or ``-Os`` compiler flags and the ``MinSizeRel`` build type,
|
||||
which avoid optimizations that that can substantially increase the size of the
|
||||
resulting binary. This flag is particularly useful in projects that are split
|
||||
into performance-critical parts and associated bindings. In this case, we can
|
||||
compile the project in release mode (and hence, optimize performance globally),
|
||||
and specify ``OPT_SIZE`` for the binding target, where size might be the main
|
||||
concern as performance is often less critical here. A ~25% size reduction has
|
||||
been observed in practice. This flag only changes the optimization behavior at
|
||||
a per-target level and takes precedence over the global CMake build type
|
||||
(``Release``, ``RelWithDebInfo``) except for ``Debug`` builds, where
|
||||
optimizations remain disabled.
|
||||
|
||||
.. _ThinLTO: http://clang.llvm.org/docs/ThinLTO.html
|
||||
|
||||
Configuration variables
|
||||
-----------------------
|
||||
|
||||
By default, pybind11 will compile modules with the compiler default or the
|
||||
minimum standard required by pybind11, whichever is higher. You can set the
|
||||
standard explicitly with
|
||||
`CMAKE_CXX_STANDARD <https://cmake.org/cmake/help/latest/variable/CMAKE_CXX_STANDARD.html>`_:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ version selection") # or 11, 14, 17, 20
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON) # optional, ensure standard is supported
|
||||
set(CMAKE_CXX_EXTENSIONS OFF) # optional, keep compiler extensions off
|
||||
|
||||
The variables can also be set when calling CMake from the command line using
|
||||
the ``-D<variable>=<value>`` flag. You can also manually set ``CXX_STANDARD``
|
||||
on a target or use ``target_compile_features`` on your targets - anything that
|
||||
CMake supports.
|
||||
|
||||
Classic Python support: The target Python version can be selected by setting
|
||||
``PYBIND11_PYTHON_VERSION`` or an exact Python installation can be specified
|
||||
with ``PYTHON_EXECUTABLE``. For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cmake -DPYBIND11_PYTHON_VERSION=3.6 ..
|
||||
|
||||
# Another method:
|
||||
cmake -DPYTHON_EXECUTABLE=/path/to/python ..
|
||||
|
||||
# This often is a good way to get the current Python, works in environments:
|
||||
cmake -DPYTHON_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") ..
|
||||
|
||||
|
||||
find_package vs. add_subdirectory
|
||||
---------------------------------
|
||||
|
||||
For CMake-based projects that don't include the pybind11 repository internally,
|
||||
an external installation can be detected through ``find_package(pybind11)``.
|
||||
See the `Config file`_ docstring for details of relevant CMake variables.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.4...3.18)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(pybind11 REQUIRED)
|
||||
pybind11_add_module(example example.cpp)
|
||||
|
||||
Note that ``find_package(pybind11)`` will only work correctly if pybind11
|
||||
has been correctly installed on the system, e. g. after downloading or cloning
|
||||
the pybind11 repository :
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Classic CMake
|
||||
cd pybind11
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make install
|
||||
|
||||
# CMake 3.15+
|
||||
cd pybind11
|
||||
cmake -S . -B build
|
||||
cmake --build build -j 2 # Build on 2 cores
|
||||
cmake --install build
|
||||
|
||||
Once detected, the aforementioned ``pybind11_add_module`` can be employed as
|
||||
before. The function usage and configuration variables are identical no matter
|
||||
if pybind11 is added as a subdirectory or found as an installed package. You
|
||||
can refer to the same [cmake_example]_ repository for a full sample project
|
||||
-- just swap out ``add_subdirectory`` for ``find_package``.
|
||||
|
||||
.. _Config file: https://github.com/pybind/pybind11/blob/master/tools/pybind11Config.cmake.in
|
||||
|
||||
|
||||
.. _find-python-mode:
|
||||
|
||||
FindPython mode
|
||||
---------------
|
||||
|
||||
CMake 3.12+ (3.15+ recommended, 3.18.2+ ideal) added a new module called
|
||||
FindPython that had a highly improved search algorithm and modern targets
|
||||
and tools. If you use FindPython, pybind11 will detect this and use the
|
||||
existing targets instead:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.15...3.22)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(Python 3.6 COMPONENTS Interpreter Development REQUIRED)
|
||||
find_package(pybind11 CONFIG REQUIRED)
|
||||
# or add_subdirectory(pybind11)
|
||||
|
||||
pybind11_add_module(example example.cpp)
|
||||
|
||||
You can also use the targets (as listed below) with FindPython. If you define
|
||||
``PYBIND11_FINDPYTHON``, pybind11 will perform the FindPython step for you
|
||||
(mostly useful when building pybind11's own tests, or as a way to change search
|
||||
algorithms from the CMake invocation, with ``-DPYBIND11_FINDPYTHON=ON``.
|
||||
|
||||
.. warning::
|
||||
|
||||
If you use FindPython to multi-target Python versions, use the individual
|
||||
targets listed below, and avoid targets that directly include Python parts.
|
||||
|
||||
There are `many ways to hint or force a discovery of a specific Python
|
||||
installation <https://cmake.org/cmake/help/latest/module/FindPython.html>`_),
|
||||
setting ``Python_ROOT_DIR`` may be the most common one (though with
|
||||
virtualenv/venv support, and Conda support, this tends to find the correct
|
||||
Python version more often than the old system did).
|
||||
|
||||
.. warning::
|
||||
|
||||
When the Python libraries (i.e. ``libpythonXX.a`` and ``libpythonXX.so``
|
||||
on Unix) are not available, as is the case on a manylinux image, the
|
||||
``Development`` component will not be resolved by ``FindPython``. When not
|
||||
using the embedding functionality, CMake 3.18+ allows you to specify
|
||||
``Development.Module`` instead of ``Development`` to resolve this issue.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
Advanced: interface library targets
|
||||
-----------------------------------
|
||||
|
||||
Pybind11 supports modern CMake usage patterns with a set of interface targets,
|
||||
available in all modes. The targets provided are:
|
||||
|
||||
``pybind11::headers``
|
||||
Just the pybind11 headers and minimum compile requirements
|
||||
|
||||
``pybind11::pybind11``
|
||||
Python headers + ``pybind11::headers``
|
||||
|
||||
``pybind11::python_link_helper``
|
||||
Just the "linking" part of pybind11:module
|
||||
|
||||
``pybind11::module``
|
||||
Everything for extension modules - ``pybind11::pybind11`` + ``Python::Module`` (FindPython CMake 3.15+) or ``pybind11::python_link_helper``
|
||||
|
||||
``pybind11::embed``
|
||||
Everything for embedding the Python interpreter - ``pybind11::pybind11`` + ``Python::Python`` (FindPython) or Python libs
|
||||
|
||||
``pybind11::lto`` / ``pybind11::thin_lto``
|
||||
An alternative to `INTERPROCEDURAL_OPTIMIZATION` for adding link-time optimization.
|
||||
|
||||
``pybind11::windows_extras``
|
||||
``/bigobj`` and ``/mp`` for MSVC.
|
||||
|
||||
``pybind11::opt_size``
|
||||
``/Os`` for MSVC, ``-Os`` for other compilers. Does nothing for debug builds.
|
||||
|
||||
Two helper functions are also provided:
|
||||
|
||||
``pybind11_strip(target)``
|
||||
Strips a target (uses ``CMAKE_STRIP`` after the target is built)
|
||||
|
||||
``pybind11_extension(target)``
|
||||
Sets the correct extension (with SOABI) for a target.
|
||||
|
||||
You can use these targets to build complex applications. For example, the
|
||||
``add_python_module`` function is identical to:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.27)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11)
|
||||
|
||||
add_library(example MODULE main.cpp)
|
||||
|
||||
target_link_libraries(example PRIVATE pybind11::module pybind11::lto pybind11::windows_extras)
|
||||
|
||||
pybind11_extension(example)
|
||||
if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
|
||||
# Strip unnecessary sections of the binary on Linux/macOS
|
||||
pybind11_strip(example)
|
||||
endif()
|
||||
|
||||
set_target_properties(example PROPERTIES CXX_VISIBILITY_PRESET "hidden"
|
||||
CUDA_VISIBILITY_PRESET "hidden")
|
||||
|
||||
Instead of setting properties, you can set ``CMAKE_*`` variables to initialize these correctly.
|
||||
|
||||
.. warning::
|
||||
|
||||
Since pybind11 is a metatemplate library, it is crucial that certain
|
||||
compiler flags are provided to ensure high quality code generation. In
|
||||
contrast to the ``pybind11_add_module()`` command, the CMake interface
|
||||
provides a *composable* set of targets to ensure that you retain flexibility.
|
||||
It can be especially important to provide or set these properties; the
|
||||
:ref:`FAQ <faq:symhidden>` contains an explanation on why these are needed.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
.. _nopython-mode:
|
||||
|
||||
Advanced: NOPYTHON mode
|
||||
-----------------------
|
||||
|
||||
If you want complete control, you can set ``PYBIND11_NOPYTHON`` to completely
|
||||
disable Python integration (this also happens if you run ``FindPython2`` and
|
||||
``FindPython3`` without running ``FindPython``). This gives you complete
|
||||
freedom to integrate into an existing system (like `Scikit-Build's
|
||||
<https://scikit-build.readthedocs.io>`_ ``PythonExtensions``).
|
||||
``pybind11_add_module`` and ``pybind11_extension`` will be unavailable, and the
|
||||
targets will be missing any Python specific behavior.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
|
||||
Embedding the Python interpreter
|
||||
--------------------------------
|
||||
|
||||
In addition to extension modules, pybind11 also supports embedding Python into
|
||||
a C++ executable or library. In CMake, simply link with the ``pybind11::embed``
|
||||
target. It provides everything needed to get the interpreter running. The Python
|
||||
headers and libraries are attached to the target. Unlike ``pybind11::module``,
|
||||
there is no need to manually set any additional properties here. For more
|
||||
information about usage in C++, see :doc:`/advanced/embedding`.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.27)
|
||||
project(example LANGUAGES CXX)
|
||||
|
||||
find_package(pybind11 REQUIRED) # or add_subdirectory(pybind11)
|
||||
|
||||
add_executable(example main.cpp)
|
||||
target_link_libraries(example PRIVATE pybind11::embed)
|
||||
|
||||
.. _building_manually:
|
||||
|
||||
Building manually
|
||||
=================
|
||||
|
||||
pybind11 is a header-only library, hence it is not necessary to link against
|
||||
any special libraries and there are no intermediate (magic) translation steps.
|
||||
|
||||
On Linux, you can compile an example such as the one given in
|
||||
:ref:`simple_example` using the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
|
||||
|
||||
The ``python3 -m pybind11 --includes`` command fetches the include paths for
|
||||
both pybind11 and Python headers. This assumes that pybind11 has been installed
|
||||
using ``pip`` or ``conda``. If it hasn't, you can also manually specify
|
||||
``-I <path-to-pybind11>/include`` together with the Python includes path
|
||||
``python3-config --includes``.
|
||||
|
||||
On macOS: the build command is almost the same but it also requires passing
|
||||
the ``-undefined dynamic_lookup`` flag so as to ignore missing symbols when
|
||||
building the module:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
|
||||
|
||||
In general, it is advisable to include several additional build parameters
|
||||
that can considerably reduce the size of the created binary. Refer to section
|
||||
:ref:`cmake` for a detailed example of a suitable cross-platform CMake-based
|
||||
build system that works on all platforms including Windows.
|
||||
|
||||
.. note::
|
||||
|
||||
On Linux and macOS, it's better to (intentionally) not link against
|
||||
``libpython``. The symbols will be resolved when the extension library
|
||||
is loaded into a Python binary. This is preferable because you might
|
||||
have several different installations of a given Python version (e.g. the
|
||||
system-provided Python, and one that ships with a piece of commercial
|
||||
software). In this way, the plugin will work with both versions, instead
|
||||
of possibly importing a second Python library into a process that already
|
||||
contains one (which will lead to a segfault).
|
||||
|
||||
|
||||
Building with Bazel
|
||||
===================
|
||||
|
||||
You can build with the Bazel build system using the `pybind11_bazel
|
||||
<https://github.com/pybind/pybind11_bazel>`_ repository.
|
||||
|
||||
Generating binding code automatically
|
||||
=====================================
|
||||
|
||||
The ``Binder`` project is a tool for automatic generation of pybind11 binding
|
||||
code by introspecting existing C++ codebases using LLVM/Clang. See the
|
||||
[binder]_ documentation for details.
|
||||
|
||||
.. [binder] http://cppbinder.readthedocs.io/en/latest/about.html
|
||||
|
||||
[AutoWIG]_ is a Python library that wraps automatically compiled libraries into
|
||||
high-level languages. It parses C++ code using LLVM/Clang technologies and
|
||||
generates the wrappers using the Mako templating engine. The approach is automatic,
|
||||
extensible, and applies to very complex C++ libraries, composed of thousands of
|
||||
classes or incorporating modern meta-programming constructs.
|
||||
|
||||
.. [AutoWIG] https://github.com/StatisKit/AutoWIG
|
||||
|
||||
[robotpy-build]_ is a is a pure python, cross platform build tool that aims to
|
||||
simplify creation of python wheels for pybind11 projects, and provide
|
||||
cross-project dependency management. Additionally, it is able to autogenerate
|
||||
customizable pybind11-based wrappers by parsing C++ header files.
|
||||
|
||||
.. [robotpy-build] https://robotpy-build.readthedocs.io
|
368
thirdparty/pybind11/docs/conf.py
vendored
Normal file
368
thirdparty/pybind11/docs/conf.py
vendored
Normal file
@ -0,0 +1,368 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# pybind11 documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Oct 11 19:23:48 2015.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
DIR = Path(__file__).parent.resolve()
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
"breathe",
|
||||
"sphinx_copybutton",
|
||||
"sphinxcontrib.rsvgconverter",
|
||||
"sphinxcontrib.moderncmakedomain",
|
||||
]
|
||||
|
||||
breathe_projects = {"pybind11": ".build/doxygenxml/"}
|
||||
breathe_default_project = "pybind11"
|
||||
breathe_domain_by_extension = {"h": "cpp"}
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = [".templates"]
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = ".rst"
|
||||
|
||||
# The encoding of source files.
|
||||
# source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = "pybind11"
|
||||
copyright = "2017, Wenzel Jakob"
|
||||
author = "Wenzel Jakob"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
|
||||
# Read the listed version
|
||||
with open("../pybind11/_version.py") as f:
|
||||
code = compile(f.read(), "../pybind11/_version.py", "exec")
|
||||
loc = {}
|
||||
exec(code, loc)
|
||||
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
version = loc["__version__"]
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
# today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
# today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = [".build", "release.rst"]
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
default_role = "any"
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
# add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
# add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
# show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
# pygments_style = 'monokai'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
# keep_warnings = False
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
|
||||
html_theme = "furo"
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
# html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
# html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<version> documentation".
|
||||
# html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
# html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
# html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
# html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ["_static"]
|
||||
|
||||
html_css_files = [
|
||||
"css/custom.css",
|
||||
]
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
# html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
# html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
# html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
# html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
# html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
# html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
# html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
# html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
# html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
# html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
# html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
# html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
# html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
|
||||
# html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
# html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
# html_search_scorer = 'scorer.js'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = "pybind11doc"
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_engine = "pdflatex"
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
# 'papersize': 'letterpaper',
|
||||
#
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
# 'pointsize': '10pt',
|
||||
#
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
# remove blank pages (between the title page and the TOC, etc.)
|
||||
"classoptions": ",openany,oneside",
|
||||
"preamble": r"""
|
||||
\usepackage{fontawesome}
|
||||
\usepackage{textgreek}
|
||||
\DeclareUnicodeCharacter{00A0}{}
|
||||
\DeclareUnicodeCharacter{2194}{\faArrowsH}
|
||||
\DeclareUnicodeCharacter{1F382}{\faBirthdayCake}
|
||||
\DeclareUnicodeCharacter{1F355}{\faAdjust}
|
||||
\DeclareUnicodeCharacter{0301}{'}
|
||||
\DeclareUnicodeCharacter{03C0}{\textpi}
|
||||
|
||||
""",
|
||||
# Latex figure (float) alignment
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, "pybind11.tex", "pybind11 Documentation", "Wenzel Jakob", "manual"),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
# latex_logo = 'pybind11-logo.png'
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
# latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
# latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [(master_doc, "pybind11", "pybind11 Documentation", [author], 1)]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
# man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(
|
||||
master_doc,
|
||||
"pybind11",
|
||||
"pybind11 Documentation",
|
||||
author,
|
||||
"pybind11",
|
||||
"One line description of project.",
|
||||
"Miscellaneous",
|
||||
),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
# texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
# texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
# texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
# texinfo_no_detailmenu = False
|
||||
|
||||
primary_domain = "cpp"
|
||||
highlight_language = "cpp"
|
||||
|
||||
|
||||
def generate_doxygen_xml(app):
|
||||
build_dir = os.path.join(app.confdir, ".build")
|
||||
if not os.path.exists(build_dir):
|
||||
os.mkdir(build_dir)
|
||||
|
||||
try:
|
||||
subprocess.call(["doxygen", "--version"])
|
||||
retcode = subprocess.call(["doxygen"], cwd=app.confdir)
|
||||
if retcode < 0:
|
||||
sys.stderr.write(f"doxygen error code: {-retcode}\n")
|
||||
except OSError as e:
|
||||
sys.stderr.write(f"doxygen execution failed: {e}\n")
|
||||
|
||||
|
||||
def prepare(app):
|
||||
with open(DIR.parent / "README.rst") as f:
|
||||
contents = f.read()
|
||||
|
||||
if app.builder.name == "latex":
|
||||
# Remove badges and stuff from start
|
||||
contents = contents[contents.find(r".. start") :]
|
||||
|
||||
# Filter out section titles for index.rst for LaTeX
|
||||
contents = re.sub(r"^(.*)\n[-~]{3,}$", r"**\1**", contents, flags=re.MULTILINE)
|
||||
|
||||
with open(DIR / "readme.rst", "w") as f:
|
||||
f.write(contents)
|
||||
|
||||
|
||||
def clean_up(app, exception): # noqa: ARG001
|
||||
(DIR / "readme.rst").unlink()
|
||||
|
||||
|
||||
def setup(app):
|
||||
# Add hook for building doxygen xml when needed
|
||||
app.connect("builder-inited", generate_doxygen_xml)
|
||||
|
||||
# Copy the readme in
|
||||
app.connect("builder-inited", prepare)
|
||||
|
||||
# Clean up the generated readme
|
||||
app.connect("build-finished", clean_up)
|
308
thirdparty/pybind11/docs/faq.rst
vendored
Normal file
308
thirdparty/pybind11/docs/faq.rst
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
Frequently asked questions
|
||||
##########################
|
||||
|
||||
"ImportError: dynamic module does not define init function"
|
||||
===========================================================
|
||||
|
||||
1. Make sure that the name specified in PYBIND11_MODULE is identical to the
|
||||
filename of the extension library (without suffixes such as ``.so``).
|
||||
|
||||
2. If the above did not fix the issue, you are likely using an incompatible
|
||||
version of Python that does not match what you compiled with.
|
||||
|
||||
"Symbol not found: ``__Py_ZeroStruct`` / ``_PyInstanceMethod_Type``"
|
||||
========================================================================
|
||||
|
||||
See the first answer.
|
||||
|
||||
"SystemError: dynamic module not initialized properly"
|
||||
======================================================
|
||||
|
||||
See the first answer.
|
||||
|
||||
The Python interpreter immediately crashes when importing my module
|
||||
===================================================================
|
||||
|
||||
See the first answer.
|
||||
|
||||
.. _faq_reference_arguments:
|
||||
|
||||
Limitations involving reference arguments
|
||||
=========================================
|
||||
|
||||
In C++, it's fairly common to pass arguments using mutable references or
|
||||
mutable pointers, which allows both read and write access to the value
|
||||
supplied by the caller. This is sometimes done for efficiency reasons, or to
|
||||
realize functions that have multiple return values. Here are two very basic
|
||||
examples:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void increment(int &i) { i++; }
|
||||
void increment_ptr(int *i) { (*i)++; }
|
||||
|
||||
In Python, all arguments are passed by reference, so there is no general
|
||||
issue in binding such code from Python.
|
||||
|
||||
However, certain basic Python types (like ``str``, ``int``, ``bool``,
|
||||
``float``, etc.) are **immutable**. This means that the following attempt
|
||||
to port the function to Python doesn't have the same effect on the value
|
||||
provided by the caller -- in fact, it does nothing at all.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def increment(i):
|
||||
i += 1 # nope..
|
||||
|
||||
pybind11 is also affected by such language-level conventions, which means that
|
||||
binding ``increment`` or ``increment_ptr`` will also create Python functions
|
||||
that don't modify their arguments.
|
||||
|
||||
Although inconvenient, one workaround is to encapsulate the immutable types in
|
||||
a custom type that does allow modifications.
|
||||
|
||||
An other alternative involves binding a small wrapper lambda function that
|
||||
returns a tuple with all output arguments (see the remainder of the
|
||||
documentation for examples on binding lambda functions). An example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
int foo(int &i) { i++; return 123; }
|
||||
|
||||
and the binding code
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("foo", [](int i) { int rv = foo(i); return std::make_tuple(rv, i); });
|
||||
|
||||
|
||||
How can I reduce the build time?
|
||||
================================
|
||||
|
||||
It's good practice to split binding code over multiple files, as in the
|
||||
following example:
|
||||
|
||||
:file:`example.cpp`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void init_ex1(py::module_ &);
|
||||
void init_ex2(py::module_ &);
|
||||
/* ... */
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
init_ex1(m);
|
||||
init_ex2(m);
|
||||
/* ... */
|
||||
}
|
||||
|
||||
:file:`ex1.cpp`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void init_ex1(py::module_ &m) {
|
||||
m.def("add", [](int a, int b) { return a + b; });
|
||||
}
|
||||
|
||||
:file:`ex2.cpp`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
void init_ex2(py::module_ &m) {
|
||||
m.def("sub", [](int a, int b) { return a - b; });
|
||||
}
|
||||
|
||||
:command:`python`:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> import example
|
||||
>>> example.add(1, 2)
|
||||
3
|
||||
>>> example.sub(1, 1)
|
||||
0
|
||||
|
||||
As shown above, the various ``init_ex`` functions should be contained in
|
||||
separate files that can be compiled independently from one another, and then
|
||||
linked together into the same final shared object. Following this approach
|
||||
will:
|
||||
|
||||
1. reduce memory requirements per compilation unit.
|
||||
|
||||
2. enable parallel builds (if desired).
|
||||
|
||||
3. allow for faster incremental builds. For instance, when a single class
|
||||
definition is changed, only a subset of the binding code will generally need
|
||||
to be recompiled.
|
||||
|
||||
"recursive template instantiation exceeded maximum depth of 256"
|
||||
================================================================
|
||||
|
||||
If you receive an error about excessive recursive template evaluation, try
|
||||
specifying a larger value, e.g. ``-ftemplate-depth=1024`` on GCC/Clang. The
|
||||
culprit is generally the generation of function signatures at compile time
|
||||
using C++14 template metaprogramming.
|
||||
|
||||
.. _`faq:hidden_visibility`:
|
||||
|
||||
"'SomeClass' declared with greater visibility than the type of its field 'SomeClass::member' [-Wattributes]"
|
||||
============================================================================================================
|
||||
|
||||
This error typically indicates that you are compiling without the required
|
||||
``-fvisibility`` flag. pybind11 code internally forces hidden visibility on
|
||||
all internal code, but if non-hidden (and thus *exported*) code attempts to
|
||||
include a pybind type (for example, ``py::object`` or ``py::list``) you can run
|
||||
into this warning.
|
||||
|
||||
To avoid it, make sure you are specifying ``-fvisibility=hidden`` when
|
||||
compiling pybind code.
|
||||
|
||||
As to why ``-fvisibility=hidden`` is necessary, because pybind modules could
|
||||
have been compiled under different versions of pybind itself, it is also
|
||||
important that the symbols defined in one module do not clash with the
|
||||
potentially-incompatible symbols defined in another. While Python extension
|
||||
modules are usually loaded with localized symbols (under POSIX systems
|
||||
typically using ``dlopen`` with the ``RTLD_LOCAL`` flag), this Python default
|
||||
can be changed, but even if it isn't it is not always enough to guarantee
|
||||
complete independence of the symbols involved when not using
|
||||
``-fvisibility=hidden``.
|
||||
|
||||
Additionally, ``-fvisibility=hidden`` can deliver considerably binary size
|
||||
savings. (See the following section for more details.)
|
||||
|
||||
|
||||
.. _`faq:symhidden`:
|
||||
|
||||
How can I create smaller binaries?
|
||||
==================================
|
||||
|
||||
To do its job, pybind11 extensively relies on a programming technique known as
|
||||
*template metaprogramming*, which is a way of performing computation at compile
|
||||
time using type information. Template metaprogramming usually instantiates code
|
||||
involving significant numbers of deeply nested types that are either completely
|
||||
removed or reduced to just a few instructions during the compiler's optimization
|
||||
phase. However, due to the nested nature of these types, the resulting symbol
|
||||
names in the compiled extension library can be extremely long. For instance,
|
||||
the included test suite contains the following symbol:
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
__ZN8pybind1112cpp_functionC1Iv8Example2JRNSt3__16vectorINS3_12basic_stringIwNS3_11char_traitsIwEENS3_9allocatorIwEEEENS8_ISA_EEEEEJNS_4nameENS_7siblingENS_9is_methodEA28_cEEEMT0_FT_DpT1_EDpRKT2_
|
||||
|
||||
.. only:: not html
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
__ZN8pybind1112cpp_functionC1Iv8Example2JRNSt3__16vectorINS3_12basic_stringIwNS3_11char_traitsIwEENS3_9allocatorIwEEEENS8_ISA_EEEEEJNS_4nameENS_7siblingENS_9is_methodEA28_cEEEMT0_FT_DpT1_EDpRKT2_
|
||||
|
||||
which is the mangled form of the following function type:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
pybind11::cpp_function::cpp_function<void, Example2, std::__1::vector<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::allocator<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > > >&, pybind11::name, pybind11::sibling, pybind11::is_method, char [28]>(void (Example2::*)(std::__1::vector<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >, std::__1::allocator<std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> > > >&), pybind11::name const&, pybind11::sibling const&, pybind11::is_method const&, char const (&) [28])
|
||||
|
||||
The memory needed to store just the mangled name of this function (196 bytes)
|
||||
is larger than the actual piece of code (111 bytes) it represents! On the other
|
||||
hand, it's silly to even give this function a name -- after all, it's just a
|
||||
tiny cog in a bigger piece of machinery that is not exposed to the outside
|
||||
world. So we'll generally only want to export symbols for those functions which
|
||||
are actually called from the outside.
|
||||
|
||||
This can be achieved by specifying the parameter ``-fvisibility=hidden`` to GCC
|
||||
and Clang, which sets the default symbol visibility to *hidden*, which has a
|
||||
tremendous impact on the final binary size of the resulting extension library.
|
||||
(On Visual Studio, symbols are already hidden by default, so nothing needs to
|
||||
be done there.)
|
||||
|
||||
In addition to decreasing binary size, ``-fvisibility=hidden`` also avoids
|
||||
potential serious issues when loading multiple modules and is required for
|
||||
proper pybind operation. See the previous FAQ entry for more details.
|
||||
|
||||
How can I properly handle Ctrl-C in long-running functions?
|
||||
===========================================================
|
||||
|
||||
Ctrl-C is received by the Python interpreter, and holds it until the GIL
|
||||
is released, so a long-running function won't be interrupted.
|
||||
|
||||
To interrupt from inside your function, you can use the ``PyErr_CheckSignals()``
|
||||
function, that will tell if a signal has been raised on the Python side. This
|
||||
function merely checks a flag, so its impact is negligible. When a signal has
|
||||
been received, you must either explicitly interrupt execution by throwing
|
||||
``py::error_already_set`` (which will propagate the existing
|
||||
``KeyboardInterrupt``), or clear the error (which you usually will not want):
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_MODULE(example, m)
|
||||
{
|
||||
m.def("long running_func", []()
|
||||
{
|
||||
for (;;) {
|
||||
if (PyErr_CheckSignals() != 0)
|
||||
throw py::error_already_set();
|
||||
// Long running iteration
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CMake doesn't detect the right Python version
|
||||
=============================================
|
||||
|
||||
The CMake-based build system will try to automatically detect the installed
|
||||
version of Python and link against that. When this fails, or when there are
|
||||
multiple versions of Python and it finds the wrong one, delete
|
||||
``CMakeCache.txt`` and then add ``-DPYTHON_EXECUTABLE=$(which python)`` to your
|
||||
CMake configure line. (Replace ``$(which python)`` with a path to python if
|
||||
your prefer.)
|
||||
|
||||
You can alternatively try ``-DPYBIND11_FINDPYTHON=ON``, which will activate the
|
||||
new CMake FindPython support instead of pybind11's custom search. Requires
|
||||
CMake 3.12+, and 3.15+ or 3.18.2+ are even better. You can set this in your
|
||||
``CMakeLists.txt`` before adding or finding pybind11, as well.
|
||||
|
||||
Inconsistent detection of Python version in CMake and pybind11
|
||||
==============================================================
|
||||
|
||||
The functions ``find_package(PythonInterp)`` and ``find_package(PythonLibs)``
|
||||
provided by CMake for Python version detection are modified by pybind11 due to
|
||||
unreliability and limitations that make them unsuitable for pybind11's needs.
|
||||
Instead pybind11 provides its own, more reliable Python detection CMake code.
|
||||
Conflicts can arise, however, when using pybind11 in a project that *also* uses
|
||||
the CMake Python detection in a system with several Python versions installed.
|
||||
|
||||
This difference may cause inconsistencies and errors if *both* mechanisms are
|
||||
used in the same project.
|
||||
|
||||
There are three possible solutions:
|
||||
|
||||
1. Avoid using ``find_package(PythonInterp)`` and ``find_package(PythonLibs)``
|
||||
from CMake and rely on pybind11 in detecting Python version. If this is not
|
||||
possible, the CMake machinery should be called *before* including pybind11.
|
||||
2. Set ``PYBIND11_FINDPYTHON`` to ``True`` or use ``find_package(Python
|
||||
COMPONENTS Interpreter Development)`` on modern CMake (3.12+, 3.15+ better,
|
||||
3.18.2+ best). Pybind11 in these cases uses the new CMake FindPython instead
|
||||
of the old, deprecated search tools, and these modules are much better at
|
||||
finding the correct Python. If FindPythonLibs/Interp are not available
|
||||
(CMake 3.27+), then this will be ignored and FindPython will be used.
|
||||
3. Set ``PYBIND11_NOPYTHON`` to ``TRUE``. Pybind11 will not search for Python.
|
||||
However, you will have to use the target-based system, and do more setup
|
||||
yourself, because it does not know about or include things that depend on
|
||||
Python, like ``pybind11_add_module``. This might be ideal for integrating
|
||||
into an existing system, like scikit-build's Python helpers.
|
||||
|
||||
How to cite this project?
|
||||
=========================
|
||||
|
||||
We suggest the following BibTeX template to cite pybind11 in scientific
|
||||
discourse:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@misc{pybind11,
|
||||
author = {Wenzel Jakob and Jason Rhinelander and Dean Moldovan},
|
||||
year = {2017},
|
||||
note = {https://github.com/pybind/pybind11},
|
||||
title = {pybind11 -- Seamless operability between C++11 and Python}
|
||||
}
|
48
thirdparty/pybind11/docs/index.rst
vendored
Normal file
48
thirdparty/pybind11/docs/index.rst
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
.. only:: latex
|
||||
|
||||
Intro
|
||||
=====
|
||||
|
||||
.. include:: readme.rst
|
||||
|
||||
.. only:: not latex
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
changelog
|
||||
upgrade
|
||||
|
||||
.. toctree::
|
||||
:caption: The Basics
|
||||
:maxdepth: 2
|
||||
|
||||
installing
|
||||
basics
|
||||
classes
|
||||
compiling
|
||||
|
||||
.. toctree::
|
||||
:caption: Advanced Topics
|
||||
:maxdepth: 2
|
||||
|
||||
advanced/functions
|
||||
advanced/classes
|
||||
advanced/exceptions
|
||||
advanced/smart_ptrs
|
||||
advanced/cast/index
|
||||
advanced/pycpp/index
|
||||
advanced/embedding
|
||||
advanced/misc
|
||||
|
||||
.. toctree::
|
||||
:caption: Extra Information
|
||||
:maxdepth: 1
|
||||
|
||||
faq
|
||||
benchmark
|
||||
limitations
|
||||
reference
|
||||
cmake/index
|
105
thirdparty/pybind11/docs/installing.rst
vendored
Normal file
105
thirdparty/pybind11/docs/installing.rst
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
.. _installing:
|
||||
|
||||
Installing the library
|
||||
######################
|
||||
|
||||
There are several ways to get the pybind11 source, which lives at
|
||||
`pybind/pybind11 on GitHub <https://github.com/pybind/pybind11>`_. The pybind11
|
||||
developers recommend one of the first three ways listed here, submodule, PyPI,
|
||||
or conda-forge, for obtaining pybind11.
|
||||
|
||||
.. _include_as_a_submodule:
|
||||
|
||||
Include as a submodule
|
||||
======================
|
||||
|
||||
When you are working on a project in Git, you can use the pybind11 repository
|
||||
as a submodule. From your git repository, use:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git submodule add -b stable ../../pybind/pybind11 extern/pybind11
|
||||
git submodule update --init
|
||||
|
||||
This assumes you are placing your dependencies in ``extern/``, and that you are
|
||||
using GitHub; if you are not using GitHub, use the full https or ssh URL
|
||||
instead of the relative URL ``../../pybind/pybind11`` above. Some other servers
|
||||
also require the ``.git`` extension (GitHub does not).
|
||||
|
||||
From here, you can now include ``extern/pybind11/include``, or you can use
|
||||
the various integration tools (see :ref:`compiling`) pybind11 provides directly
|
||||
from the local folder.
|
||||
|
||||
Include with PyPI
|
||||
=================
|
||||
|
||||
You can download the sources and CMake files as a Python package from PyPI
|
||||
using Pip. Just use:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install pybind11
|
||||
|
||||
This will provide pybind11 in a standard Python package format. If you want
|
||||
pybind11 available directly in your environment root, you can use:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install "pybind11[global]"
|
||||
|
||||
This is not recommended if you are installing with your system Python, as it
|
||||
will add files to ``/usr/local/include/pybind11`` and
|
||||
``/usr/local/share/cmake/pybind11``, so unless that is what you want, it is
|
||||
recommended only for use in virtual environments or your ``pyproject.toml``
|
||||
file (see :ref:`compiling`).
|
||||
|
||||
Include with conda-forge
|
||||
========================
|
||||
|
||||
You can use pybind11 with conda packaging via `conda-forge
|
||||
<https://github.com/conda-forge/pybind11-feedstock>`_:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
conda install -c conda-forge pybind11
|
||||
|
||||
|
||||
Include with vcpkg
|
||||
==================
|
||||
You can download and install pybind11 using the Microsoft `vcpkg
|
||||
<https://github.com/Microsoft/vcpkg/>`_ dependency manager:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
vcpkg install pybind11
|
||||
|
||||
The pybind11 port in vcpkg is kept up to date by Microsoft team members and
|
||||
community contributors. If the version is out of date, please `create an issue
|
||||
or pull request <https://github.com/Microsoft/vcpkg/>`_ on the vcpkg
|
||||
repository.
|
||||
|
||||
Global install with brew
|
||||
========================
|
||||
|
||||
The brew package manager (Homebrew on macOS, or Linuxbrew on Linux) has a
|
||||
`pybind11 package
|
||||
<https://github.com/Homebrew/homebrew-core/blob/master/Formula/pybind11.rb>`_.
|
||||
To install:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
brew install pybind11
|
||||
|
||||
.. We should list Conan, and possibly a few other C++ package managers (hunter,
|
||||
.. perhaps). Conan has a very clean CMake integration that would be good to show.
|
||||
|
||||
Other options
|
||||
=============
|
||||
|
||||
Other locations you can find pybind11 are `listed here
|
||||
<https://repology.org/project/python:pybind11/versions>`_; these are maintained
|
||||
by various packagers and the community.
|
72
thirdparty/pybind11/docs/limitations.rst
vendored
Normal file
72
thirdparty/pybind11/docs/limitations.rst
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
Limitations
|
||||
###########
|
||||
|
||||
Design choices
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
pybind11 strives to be a general solution to binding generation, but it also has
|
||||
certain limitations:
|
||||
|
||||
- pybind11 casts away ``const``-ness in function arguments and return values.
|
||||
This is in line with the Python language, which has no concept of ``const``
|
||||
values. This means that some additional care is needed to avoid bugs that
|
||||
would be caught by the type checker in a traditional C++ program.
|
||||
|
||||
- The NumPy interface ``pybind11::array`` greatly simplifies accessing
|
||||
numerical data from C++ (and vice versa), but it's not a full-blown array
|
||||
class like ``Eigen::Array`` or ``boost.multi_array``. ``Eigen`` objects are
|
||||
directly supported, however, with ``pybind11/eigen.h``.
|
||||
|
||||
Large but useful features could be implemented in pybind11 but would lead to a
|
||||
significant increase in complexity. Pybind11 strives to be simple and compact.
|
||||
Users who require large new features are encouraged to write an extension to
|
||||
pybind11; see `pybind11_json <https://github.com/pybind/pybind11_json>`_ for an
|
||||
example.
|
||||
|
||||
|
||||
Known bugs
|
||||
^^^^^^^^^^
|
||||
|
||||
These are issues that hopefully will one day be fixed, but currently are
|
||||
unsolved. If you know how to help with one of these issues, contributions
|
||||
are welcome!
|
||||
|
||||
- Intel 20.2 is currently having an issue with the test suite.
|
||||
`#2573 <https://github.com/pybind/pybind11/pull/2573>`_
|
||||
|
||||
- Debug mode Python does not support 1-5 tests in the test suite currently.
|
||||
`#2422 <https://github.com/pybind/pybind11/pull/2422>`_
|
||||
|
||||
- PyPy3 7.3.1 and 7.3.2 have issues with several tests on 32-bit Windows.
|
||||
|
||||
Known limitations
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
These are issues that are probably solvable, but have not been fixed yet. A
|
||||
clean, well written patch would likely be accepted to solve them.
|
||||
|
||||
- Type casters are not kept alive recursively.
|
||||
`#2527 <https://github.com/pybind/pybind11/issues/2527>`_
|
||||
One consequence is that containers of ``char *`` are currently not supported.
|
||||
`#2245 <https://github.com/pybind/pybind11/issues/2245>`_
|
||||
|
||||
- The ``cpptest`` does not run on Windows with Python 3.8 or newer, due to DLL
|
||||
loader changes. User code that is correctly installed should not be affected.
|
||||
`#2560 <https://github.com/pybind/pybind11/issue/2560>`_
|
||||
|
||||
Python 3.9.0 warning
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Combining older versions of pybind11 (< 2.6.0) with Python on exactly 3.9.0
|
||||
will trigger undefined behavior that typically manifests as crashes during
|
||||
interpreter shutdown (but could also destroy your data. **You have been
|
||||
warned**).
|
||||
|
||||
This issue was `fixed in Python <https://github.com/python/cpython/pull/22670>`_.
|
||||
As a mitigation for this bug, pybind11 2.6.0 or newer includes a workaround
|
||||
specifically when Python 3.9.0 is detected at runtime, leaking about 50 bytes
|
||||
of memory when a callback function is garbage collected. For reference, the
|
||||
pybind11 test suite has about 2,000 such callbacks, but only 49 are garbage
|
||||
collected before the end-of-process. Wheels (even if built with Python 3.9.0)
|
||||
will correctly avoid the leak when run in Python 3.9.1, and this does not
|
||||
affect other 3.X versions.
|
BIN
thirdparty/pybind11/docs/pybind11-logo.png
vendored
Normal file
BIN
thirdparty/pybind11/docs/pybind11-logo.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
BIN
thirdparty/pybind11/docs/pybind11_vs_boost_python1.png
vendored
Normal file
BIN
thirdparty/pybind11/docs/pybind11_vs_boost_python1.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
427
thirdparty/pybind11/docs/pybind11_vs_boost_python1.svg
vendored
Normal file
427
thirdparty/pybind11/docs/pybind11_vs_boost_python1.svg
vendored
Normal file
@ -0,0 +1,427 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="468pt" height="252pt" viewBox="0 0 468 252" version="1.1">
|
||||
<defs>
|
||||
<g>
|
||||
<symbol overflow="visible" id="glyph0-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-1">
|
||||
<path style="stroke:none;" d="M 3.726562 0 L 2.847656 0 L 2.847656 -5.601562 C 2.636719 -5.398438 2.359375 -5.195312 2.015625 -4.996094 C 1.671875 -4.792969 1.363281 -4.640625 1.089844 -4.539062 L 1.089844 -5.390625 C 1.582031 -5.621094 2.011719 -5.902344 2.378906 -6.230469 C 2.746094 -6.558594 3.007812 -6.878906 3.160156 -7.1875 L 3.726562 -7.1875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-2">
|
||||
<path style="stroke:none;" d="M 0.414062 -3.53125 C 0.414062 -4.375 0.503906 -5.058594 0.675781 -5.574219 C 0.851562 -6.089844 1.109375 -6.488281 1.453125 -6.765625 C 1.796875 -7.046875 2.226562 -7.1875 2.75 -7.1875 C 3.132812 -7.1875 3.46875 -7.109375 3.757812 -6.957031 C 4.046875 -6.800781 4.289062 -6.578125 4.476562 -6.285156 C 4.664062 -5.996094 4.8125 -5.640625 4.921875 -5.222656 C 5.03125 -4.804688 5.082031 -4.238281 5.082031 -3.53125 C 5.082031 -2.691406 4.996094 -2.011719 4.824219 -1.496094 C 4.652344 -0.980469 4.394531 -0.582031 4.050781 -0.300781 C 3.707031 -0.0195312 3.273438 0.121094 2.75 0.121094 C 2.058594 0.121094 1.515625 -0.125 1.125 -0.621094 C 0.652344 -1.214844 0.414062 -2.1875 0.414062 -3.53125 Z M 1.320312 -3.53125 C 1.320312 -2.355469 1.457031 -1.574219 1.730469 -1.183594 C 2.007812 -0.796875 2.34375 -0.601562 2.75 -0.601562 C 3.152344 -0.601562 3.492188 -0.796875 3.765625 -1.1875 C 4.042969 -1.578125 4.179688 -2.359375 4.179688 -3.53125 C 4.179688 -4.710938 4.042969 -5.492188 3.765625 -5.878906 C 3.492188 -6.265625 3.148438 -6.460938 2.738281 -6.460938 C 2.335938 -6.460938 2.011719 -6.289062 1.773438 -5.945312 C 1.46875 -5.511719 1.320312 -4.707031 1.320312 -3.53125 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-3">
|
||||
<path style="stroke:none;" d="M 5.035156 -0.84375 L 5.035156 0 L 0.304688 0 C 0.296875 -0.210938 0.332031 -0.414062 0.40625 -0.609375 C 0.527344 -0.933594 0.71875 -1.25 0.984375 -1.5625 C 1.25 -1.875 1.632812 -2.234375 2.132812 -2.648438 C 2.910156 -3.285156 3.4375 -3.789062 3.710938 -4.164062 C 3.984375 -4.535156 4.121094 -4.886719 4.121094 -5.21875 C 4.121094 -5.566406 3.996094 -5.863281 3.746094 -6.101562 C 3.5 -6.339844 3.171875 -6.460938 2.773438 -6.460938 C 2.351562 -6.460938 2.011719 -6.332031 1.757812 -6.078125 C 1.503906 -5.824219 1.375 -5.472656 1.371094 -5.023438 L 0.46875 -5.117188 C 0.53125 -5.789062 0.761719 -6.304688 1.167969 -6.65625 C 1.570312 -7.011719 2.113281 -7.1875 2.792969 -7.1875 C 3.480469 -7.1875 4.023438 -6.996094 4.421875 -6.617188 C 4.824219 -6.234375 5.023438 -5.761719 5.023438 -5.199219 C 5.023438 -4.914062 4.964844 -4.632812 4.847656 -4.355469 C 4.730469 -4.078125 4.535156 -3.789062 4.265625 -3.480469 C 3.992188 -3.175781 3.542969 -2.753906 2.910156 -2.222656 C 2.382812 -1.78125 2.042969 -1.480469 1.894531 -1.320312 C 1.746094 -1.164062 1.621094 -1.003906 1.523438 -0.84375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-4">
|
||||
<path style="stroke:none;" d="M 0.414062 -1.875 L 1.335938 -1.953125 C 1.40625 -1.503906 1.566406 -1.167969 1.8125 -0.941406 C 2.0625 -0.714844 2.363281 -0.601562 2.714844 -0.601562 C 3.136719 -0.601562 3.496094 -0.761719 3.789062 -1.078125 C 4.082031 -1.398438 4.226562 -1.820312 4.226562 -2.347656 C 4.226562 -2.851562 4.085938 -3.246094 3.804688 -3.535156 C 3.523438 -3.824219 3.15625 -3.96875 2.699219 -3.96875 C 2.417969 -3.96875 2.160156 -3.90625 1.933594 -3.777344 C 1.707031 -3.648438 1.527344 -3.480469 1.398438 -3.277344 L 0.570312 -3.382812 L 1.265625 -7.0625 L 4.824219 -7.0625 L 4.824219 -6.21875 L 1.96875 -6.21875 L 1.582031 -4.296875 C 2.011719 -4.597656 2.460938 -4.746094 2.933594 -4.746094 C 3.558594 -4.746094 4.085938 -4.53125 4.515625 -4.097656 C 4.945312 -3.664062 5.160156 -3.105469 5.160156 -2.425781 C 5.160156 -1.777344 4.972656 -1.21875 4.59375 -0.746094 C 4.136719 -0.167969 3.507812 0.121094 2.714844 0.121094 C 2.0625 0.121094 1.53125 -0.0585938 1.121094 -0.425781 C 0.710938 -0.789062 0.472656 -1.273438 0.414062 -1.875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-5">
|
||||
<path style="stroke:none;" d="M 0.820312 0 L 0.820312 -7.15625 L 5.648438 -7.15625 L 5.648438 -6.3125 L 1.765625 -6.3125 L 1.765625 -4.097656 L 5.125 -4.097656 L 5.125 -3.25 L 1.765625 -3.25 L 1.765625 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-6">
|
||||
<path style="stroke:none;" d="M 4.058594 0 L 4.058594 -0.761719 C 3.65625 -0.175781 3.105469 0.117188 2.414062 0.117188 C 2.105469 0.117188 1.820312 0.0585938 1.554688 -0.0585938 C 1.289062 -0.175781 1.09375 -0.324219 0.964844 -0.5 C 0.835938 -0.679688 0.746094 -0.894531 0.695312 -1.152344 C 0.65625 -1.324219 0.640625 -1.597656 0.640625 -1.972656 L 0.640625 -5.1875 L 1.519531 -5.1875 L 1.519531 -2.308594 C 1.519531 -1.851562 1.535156 -1.542969 1.570312 -1.382812 C 1.625 -1.152344 1.746094 -0.96875 1.921875 -0.835938 C 2.101562 -0.703125 2.324219 -0.640625 2.585938 -0.640625 C 2.851562 -0.640625 3.097656 -0.707031 3.328125 -0.84375 C 3.5625 -0.976562 3.726562 -1.160156 3.820312 -1.394531 C 3.917969 -1.625 3.964844 -1.964844 3.964844 -2.40625 L 3.964844 -5.1875 L 4.84375 -5.1875 L 4.84375 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-7">
|
||||
<path style="stroke:none;" d="M 0.660156 0 L 0.660156 -5.1875 L 1.449219 -5.1875 L 1.449219 -4.449219 C 1.832031 -5.019531 2.382812 -5.304688 3.101562 -5.304688 C 3.414062 -5.304688 3.699219 -5.246094 3.960938 -5.132812 C 4.222656 -5.023438 4.421875 -4.875 4.550781 -4.691406 C 4.679688 -4.507812 4.773438 -4.292969 4.824219 -4.042969 C 4.855469 -3.878906 4.875 -3.59375 4.875 -3.1875 L 4.875 0 L 3.992188 0 L 3.992188 -3.15625 C 3.992188 -3.511719 3.960938 -3.78125 3.890625 -3.957031 C 3.824219 -4.132812 3.703125 -4.277344 3.527344 -4.382812 C 3.351562 -4.488281 3.148438 -4.539062 2.914062 -4.539062 C 2.539062 -4.539062 2.21875 -4.421875 1.945312 -4.183594 C 1.671875 -3.945312 1.539062 -3.496094 1.539062 -2.832031 L 1.539062 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-8">
|
||||
<path style="stroke:none;" d="M 4.042969 -1.898438 L 4.90625 -1.789062 C 4.8125 -1.191406 4.570312 -0.726562 4.183594 -0.386719 C 3.792969 -0.0507812 3.316406 0.117188 2.75 0.117188 C 2.039062 0.117188 1.46875 -0.113281 1.039062 -0.578125 C 0.605469 -1.042969 0.390625 -1.707031 0.390625 -2.574219 C 0.390625 -3.132812 0.484375 -3.625 0.667969 -4.042969 C 0.855469 -4.460938 1.136719 -4.777344 1.515625 -4.988281 C 1.894531 -5.199219 2.308594 -5.304688 2.753906 -5.304688 C 3.316406 -5.304688 3.777344 -5.160156 4.136719 -4.875 C 4.492188 -4.589844 4.722656 -4.1875 4.824219 -3.664062 L 3.96875 -3.53125 C 3.886719 -3.878906 3.746094 -4.140625 3.539062 -4.316406 C 3.332031 -4.492188 3.082031 -4.578125 2.789062 -4.578125 C 2.34375 -4.578125 1.984375 -4.421875 1.710938 -4.105469 C 1.433594 -3.789062 1.292969 -3.285156 1.292969 -2.597656 C 1.292969 -1.902344 1.425781 -1.394531 1.695312 -1.078125 C 1.960938 -0.761719 2.308594 -0.605469 2.738281 -0.605469 C 3.085938 -0.605469 3.371094 -0.710938 3.601562 -0.921875 C 3.835938 -1.132812 3.980469 -1.460938 4.042969 -1.898438 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-9">
|
||||
<path style="stroke:none;" d="M 2.578125 -0.785156 L 2.703125 -0.0078125 C 2.457031 0.0429688 2.234375 0.0703125 2.039062 0.0703125 C 1.722656 0.0703125 1.476562 0.0195312 1.296875 -0.0820312 C 1.121094 -0.183594 1 -0.316406 0.929688 -0.480469 C 0.855469 -0.644531 0.820312 -0.992188 0.820312 -1.519531 L 0.820312 -4.5 L 0.175781 -4.5 L 0.175781 -5.1875 L 0.820312 -5.1875 L 0.820312 -6.46875 L 1.695312 -6.996094 L 1.695312 -5.1875 L 2.578125 -5.1875 L 2.578125 -4.5 L 1.695312 -4.5 L 1.695312 -1.46875 C 1.695312 -1.21875 1.710938 -1.058594 1.742188 -0.984375 C 1.773438 -0.914062 1.820312 -0.859375 1.890625 -0.816406 C 1.960938 -0.773438 2.0625 -0.75 2.191406 -0.75 C 2.289062 -0.75 2.417969 -0.761719 2.578125 -0.785156 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-10">
|
||||
<path style="stroke:none;" d="M 0.664062 -6.148438 L 0.664062 -7.15625 L 1.542969 -7.15625 L 1.542969 -6.148438 Z M 0.664062 0 L 0.664062 -5.1875 L 1.542969 -5.1875 L 1.542969 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-11">
|
||||
<path style="stroke:none;" d="M 0.332031 -2.59375 C 0.332031 -3.554688 0.597656 -4.265625 1.132812 -4.726562 C 1.578125 -5.109375 2.121094 -5.304688 2.765625 -5.304688 C 3.476562 -5.304688 4.058594 -5.070312 4.511719 -4.601562 C 4.964844 -4.132812 5.191406 -3.488281 5.191406 -2.664062 C 5.191406 -2 5.089844 -1.472656 4.890625 -1.089844 C 4.691406 -0.707031 4.398438 -0.410156 4.015625 -0.199219 C 3.632812 0.0117188 3.214844 0.117188 2.765625 0.117188 C 2.039062 0.117188 1.449219 -0.117188 1.003906 -0.582031 C 0.554688 -1.046875 0.332031 -1.71875 0.332031 -2.59375 Z M 1.234375 -2.59375 C 1.234375 -1.929688 1.378906 -1.429688 1.671875 -1.101562 C 1.960938 -0.769531 2.324219 -0.605469 2.765625 -0.605469 C 3.199219 -0.605469 3.5625 -0.773438 3.851562 -1.101562 C 4.140625 -1.433594 4.289062 -1.941406 4.289062 -2.621094 C 4.289062 -3.261719 4.140625 -3.75 3.851562 -4.078125 C 3.558594 -4.410156 3.195312 -4.574219 2.765625 -4.574219 C 2.324219 -4.574219 1.960938 -4.410156 1.671875 -4.082031 C 1.382812 -3.753906 1.234375 -3.257812 1.234375 -2.59375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-12">
|
||||
<path style="stroke:none;" d="M 0.308594 -1.546875 L 1.175781 -1.683594 C 1.226562 -1.335938 1.363281 -1.070312 1.585938 -0.882812 C 1.808594 -0.699219 2.117188 -0.605469 2.519531 -0.605469 C 2.921875 -0.605469 3.222656 -0.6875 3.417969 -0.851562 C 3.613281 -1.015625 3.710938 -1.210938 3.710938 -1.429688 C 3.710938 -1.628906 3.625 -1.785156 3.453125 -1.898438 C 3.332031 -1.976562 3.03125 -2.078125 2.554688 -2.195312 C 1.910156 -2.359375 1.460938 -2.5 1.214844 -2.621094 C 0.964844 -2.738281 0.777344 -2.902344 0.648438 -3.113281 C 0.519531 -3.324219 0.453125 -3.554688 0.453125 -3.808594 C 0.453125 -4.039062 0.507812 -4.253906 0.613281 -4.449219 C 0.71875 -4.648438 0.863281 -4.8125 1.046875 -4.941406 C 1.183594 -5.042969 1.367188 -5.128906 1.605469 -5.199219 C 1.839844 -5.269531 2.09375 -5.304688 2.363281 -5.304688 C 2.769531 -5.304688 3.128906 -5.242188 3.433594 -5.125 C 3.742188 -5.007812 3.96875 -4.851562 4.117188 -4.652344 C 4.261719 -4.453125 4.363281 -4.183594 4.417969 -3.847656 L 3.558594 -3.730469 C 3.519531 -3.996094 3.40625 -4.207031 3.21875 -4.355469 C 3.03125 -4.503906 2.769531 -4.578125 2.425781 -4.578125 C 2.023438 -4.578125 1.734375 -4.511719 1.5625 -4.378906 C 1.390625 -4.246094 1.304688 -4.089844 1.304688 -3.910156 C 1.304688 -3.796875 1.339844 -3.695312 1.410156 -3.601562 C 1.484375 -3.507812 1.59375 -3.429688 1.75 -3.367188 C 1.835938 -3.335938 2.09375 -3.261719 2.523438 -3.144531 C 3.144531 -2.976562 3.578125 -2.84375 3.824219 -2.738281 C 4.070312 -2.632812 4.265625 -2.476562 4.40625 -2.273438 C 4.546875 -2.074219 4.613281 -1.824219 4.613281 -1.523438 C 4.613281 -1.230469 4.527344 -0.953125 4.359375 -0.695312 C 4.1875 -0.4375 3.941406 -0.238281 3.617188 -0.09375 C 3.296875 0.046875 2.929688 0.117188 2.523438 0.117188 C 1.851562 0.117188 1.335938 -0.0234375 0.984375 -0.304688 C 0.632812 -0.582031 0.40625 -0.996094 0.308594 -1.546875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-1">
|
||||
<path style="stroke:none;" d="M -2.300781 -0.449219 L -2.378906 -1.34375 C -2.019531 -1.386719 -1.726562 -1.484375 -1.496094 -1.636719 C -1.265625 -1.792969 -1.082031 -2.03125 -0.941406 -2.359375 C -0.796875 -2.683594 -0.726562 -3.050781 -0.726562 -3.457031 C -0.726562 -3.820312 -0.78125 -4.136719 -0.890625 -4.414062 C -0.996094 -4.691406 -1.144531 -4.898438 -1.332031 -5.03125 C -1.519531 -5.167969 -1.722656 -5.234375 -1.945312 -5.234375 C -2.167969 -5.234375 -2.363281 -5.167969 -2.53125 -5.039062 C -2.699219 -4.910156 -2.839844 -4.695312 -2.953125 -4.394531 C -3.027344 -4.203125 -3.144531 -3.777344 -3.304688 -3.121094 C -3.460938 -2.460938 -3.609375 -2 -3.75 -1.738281 C -3.929688 -1.398438 -4.152344 -1.140625 -4.417969 -0.972656 C -4.683594 -0.804688 -4.980469 -0.722656 -5.308594 -0.722656 C -5.667969 -0.722656 -6.007812 -0.824219 -6.320312 -1.03125 C -6.632812 -1.234375 -6.875 -1.535156 -7.035156 -1.929688 C -7.199219 -2.324219 -7.28125 -2.761719 -7.28125 -3.242188 C -7.28125 -3.773438 -7.195312 -4.242188 -7.023438 -4.644531 C -6.851562 -5.050781 -6.601562 -5.363281 -6.269531 -5.582031 C -5.9375 -5.800781 -5.5625 -5.917969 -5.140625 -5.933594 L -5.074219 -5.023438 C -5.527344 -4.976562 -5.867188 -4.808594 -6.097656 -4.527344 C -6.328125 -4.246094 -6.445312 -3.832031 -6.445312 -3.28125 C -6.445312 -2.707031 -6.339844 -2.289062 -6.128906 -2.027344 C -5.921875 -1.765625 -5.667969 -1.636719 -5.371094 -1.636719 C -5.113281 -1.636719 -4.902344 -1.726562 -4.734375 -1.914062 C -4.570312 -2.097656 -4.398438 -2.574219 -4.226562 -3.34375 C -4.050781 -4.113281 -3.898438 -4.640625 -3.769531 -4.925781 C -3.578125 -5.34375 -3.335938 -5.652344 -3.039062 -5.851562 C -2.746094 -6.046875 -2.40625 -6.148438 -2.023438 -6.148438 C -1.640625 -6.148438 -1.28125 -6.039062 -0.945312 -5.820312 C -0.609375 -5.601562 -0.347656 -5.289062 -0.160156 -4.878906 C 0.0273438 -4.472656 0.121094 -4.011719 0.121094 -3.5 C 0.121094 -2.851562 0.0273438 -2.308594 -0.160156 -1.871094 C -0.351562 -1.433594 -0.632812 -1.089844 -1.011719 -0.84375 C -1.390625 -0.59375 -1.820312 -0.460938 -2.300781 -0.449219 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-2">
|
||||
<path style="stroke:none;" d="M -1.671875 -4.210938 L -1.558594 -5.117188 C -1.027344 -4.972656 -0.617188 -4.707031 -0.320312 -4.320312 C -0.0273438 -3.933594 0.117188 -3.4375 0.117188 -2.835938 C 0.117188 -2.078125 -0.117188 -1.476562 -0.582031 -1.03125 C -1.050781 -0.585938 -1.707031 -0.367188 -2.546875 -0.367188 C -3.421875 -0.367188 -4.097656 -0.589844 -4.578125 -1.039062 C -5.0625 -1.488281 -5.304688 -2.070312 -5.304688 -2.789062 C -5.304688 -3.480469 -5.066406 -4.046875 -4.59375 -4.488281 C -4.121094 -4.925781 -3.457031 -5.148438 -2.601562 -5.148438 C -2.550781 -5.148438 -2.472656 -5.144531 -2.367188 -5.140625 L -2.367188 -1.273438 C -1.796875 -1.304688 -1.363281 -1.46875 -1.058594 -1.757812 C -0.757812 -2.046875 -0.605469 -2.410156 -0.605469 -2.84375 C -0.605469 -3.164062 -0.691406 -3.4375 -0.859375 -3.667969 C -1.027344 -3.894531 -1.296875 -4.074219 -1.671875 -4.210938 Z M -3.089844 -1.324219 L -3.089844 -4.21875 C -3.527344 -4.179688 -3.855469 -4.070312 -4.070312 -3.886719 C -4.410156 -3.605469 -4.578125 -3.242188 -4.578125 -2.796875 C -4.578125 -2.394531 -4.445312 -2.054688 -4.175781 -1.78125 C -3.90625 -1.503906 -3.542969 -1.351562 -3.089844 -1.324219 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-3">
|
||||
<path style="stroke:none;" d="M -1.898438 -4.042969 L -1.789062 -4.90625 C -1.191406 -4.8125 -0.726562 -4.570312 -0.386719 -4.183594 C -0.0507812 -3.792969 0.117188 -3.316406 0.117188 -2.75 C 0.117188 -2.039062 -0.113281 -1.46875 -0.578125 -1.039062 C -1.042969 -0.605469 -1.707031 -0.390625 -2.574219 -0.390625 C -3.132812 -0.390625 -3.625 -0.484375 -4.042969 -0.667969 C -4.460938 -0.855469 -4.777344 -1.136719 -4.988281 -1.515625 C -5.199219 -1.894531 -5.304688 -2.308594 -5.304688 -2.753906 C -5.304688 -3.316406 -5.160156 -3.777344 -4.875 -4.136719 C -4.589844 -4.492188 -4.1875 -4.722656 -3.664062 -4.824219 L -3.53125 -3.96875 C -3.878906 -3.886719 -4.140625 -3.746094 -4.316406 -3.539062 C -4.492188 -3.332031 -4.578125 -3.082031 -4.578125 -2.789062 C -4.578125 -2.34375 -4.421875 -1.984375 -4.105469 -1.710938 C -3.789062 -1.433594 -3.285156 -1.292969 -2.597656 -1.292969 C -1.902344 -1.292969 -1.394531 -1.425781 -1.078125 -1.695312 C -0.761719 -1.960938 -0.605469 -2.308594 -0.605469 -2.738281 C -0.605469 -3.085938 -0.710938 -3.371094 -0.921875 -3.601562 C -1.132812 -3.835938 -1.460938 -3.980469 -1.898438 -4.042969 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-4">
|
||||
<path style="stroke:none;" d="M -2.59375 -0.332031 C -3.554688 -0.332031 -4.265625 -0.597656 -4.726562 -1.132812 C -5.109375 -1.578125 -5.304688 -2.121094 -5.304688 -2.765625 C -5.304688 -3.476562 -5.070312 -4.058594 -4.601562 -4.511719 C -4.132812 -4.964844 -3.488281 -5.191406 -2.664062 -5.191406 C -2 -5.191406 -1.472656 -5.089844 -1.089844 -4.890625 C -0.707031 -4.691406 -0.410156 -4.398438 -0.199219 -4.015625 C 0.0117188 -3.632812 0.117188 -3.214844 0.117188 -2.765625 C 0.117188 -2.039062 -0.117188 -1.449219 -0.582031 -1.003906 C -1.046875 -0.554688 -1.71875 -0.332031 -2.59375 -0.332031 Z M -2.59375 -1.234375 C -1.929688 -1.234375 -1.429688 -1.378906 -1.101562 -1.671875 C -0.769531 -1.960938 -0.605469 -2.324219 -0.605469 -2.765625 C -0.605469 -3.199219 -0.773438 -3.5625 -1.101562 -3.851562 C -1.433594 -4.140625 -1.941406 -4.289062 -2.621094 -4.289062 C -3.261719 -4.289062 -3.75 -4.140625 -4.078125 -3.851562 C -4.410156 -3.558594 -4.574219 -3.195312 -4.574219 -2.765625 C -4.574219 -2.324219 -4.410156 -1.960938 -4.082031 -1.671875 C -3.753906 -1.382812 -3.257812 -1.234375 -2.59375 -1.234375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-5">
|
||||
<path style="stroke:none;" d="M 0 -0.660156 L -5.1875 -0.660156 L -5.1875 -1.449219 L -4.449219 -1.449219 C -5.019531 -1.832031 -5.304688 -2.382812 -5.304688 -3.101562 C -5.304688 -3.414062 -5.246094 -3.699219 -5.132812 -3.960938 C -5.023438 -4.222656 -4.875 -4.421875 -4.691406 -4.550781 C -4.507812 -4.679688 -4.292969 -4.773438 -4.042969 -4.824219 C -3.878906 -4.855469 -3.59375 -4.875 -3.1875 -4.875 L 0 -4.875 L 0 -3.992188 L -3.15625 -3.992188 C -3.511719 -3.992188 -3.78125 -3.960938 -3.957031 -3.890625 C -4.132812 -3.824219 -4.277344 -3.703125 -4.382812 -3.527344 C -4.488281 -3.351562 -4.539062 -3.148438 -4.539062 -2.914062 C -4.539062 -2.539062 -4.421875 -2.21875 -4.183594 -1.945312 C -3.945312 -1.671875 -3.496094 -1.539062 -2.832031 -1.539062 L 0 -1.539062 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-6">
|
||||
<path style="stroke:none;" d="M 0 -4.023438 L -0.65625 -4.023438 C -0.140625 -3.695312 0.117188 -3.210938 0.117188 -2.574219 C 0.117188 -2.160156 0.00390625 -1.78125 -0.226562 -1.433594 C -0.453125 -1.085938 -0.769531 -0.816406 -1.179688 -0.628906 C -1.585938 -0.4375 -2.058594 -0.34375 -2.585938 -0.34375 C -3.105469 -0.34375 -3.574219 -0.429688 -3.996094 -0.601562 C -4.417969 -0.773438 -4.742188 -1.03125 -4.964844 -1.375 C -5.191406 -1.722656 -5.304688 -2.109375 -5.304688 -2.535156 C -5.304688 -2.847656 -5.238281 -3.125 -5.105469 -3.367188 C -4.972656 -3.613281 -4.800781 -3.8125 -4.589844 -3.964844 L -7.15625 -3.964844 L -7.15625 -4.839844 L 0 -4.839844 Z M -2.585938 -1.246094 C -1.921875 -1.246094 -1.425781 -1.386719 -1.097656 -1.664062 C -0.769531 -1.945312 -0.605469 -2.273438 -0.605469 -2.65625 C -0.605469 -3.039062 -0.761719 -3.367188 -1.078125 -3.636719 C -1.390625 -3.90625 -1.871094 -4.039062 -2.515625 -4.039062 C -3.226562 -4.039062 -3.746094 -3.902344 -4.078125 -3.628906 C -4.410156 -3.355469 -4.574219 -3.015625 -4.574219 -2.617188 C -4.574219 -2.226562 -4.414062 -1.898438 -4.097656 -1.636719 C -3.777344 -1.375 -3.273438 -1.246094 -2.585938 -1.246094 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-7">
|
||||
<path style="stroke:none;" d="M -1.546875 -0.308594 L -1.683594 -1.175781 C -1.335938 -1.226562 -1.070312 -1.363281 -0.882812 -1.585938 C -0.699219 -1.808594 -0.605469 -2.117188 -0.605469 -2.519531 C -0.605469 -2.921875 -0.6875 -3.222656 -0.851562 -3.417969 C -1.015625 -3.613281 -1.210938 -3.710938 -1.429688 -3.710938 C -1.628906 -3.710938 -1.785156 -3.625 -1.898438 -3.453125 C -1.976562 -3.332031 -2.078125 -3.03125 -2.195312 -2.554688 C -2.359375 -1.910156 -2.5 -1.460938 -2.621094 -1.214844 C -2.738281 -0.964844 -2.902344 -0.777344 -3.113281 -0.648438 C -3.324219 -0.519531 -3.554688 -0.453125 -3.808594 -0.453125 C -4.039062 -0.453125 -4.253906 -0.507812 -4.449219 -0.613281 C -4.648438 -0.71875 -4.8125 -0.863281 -4.941406 -1.046875 C -5.042969 -1.183594 -5.128906 -1.367188 -5.199219 -1.605469 C -5.269531 -1.839844 -5.304688 -2.09375 -5.304688 -2.363281 C -5.304688 -2.769531 -5.242188 -3.128906 -5.125 -3.433594 C -5.007812 -3.742188 -4.851562 -3.96875 -4.652344 -4.117188 C -4.453125 -4.261719 -4.183594 -4.363281 -3.847656 -4.417969 L -3.730469 -3.558594 C -3.996094 -3.519531 -4.207031 -3.40625 -4.355469 -3.21875 C -4.503906 -3.03125 -4.578125 -2.769531 -4.578125 -2.425781 C -4.578125 -2.023438 -4.511719 -1.734375 -4.378906 -1.5625 C -4.246094 -1.390625 -4.089844 -1.304688 -3.910156 -1.304688 C -3.796875 -1.304688 -3.695312 -1.339844 -3.601562 -1.410156 C -3.507812 -1.484375 -3.429688 -1.59375 -3.367188 -1.75 C -3.335938 -1.835938 -3.261719 -2.09375 -3.144531 -2.523438 C -2.976562 -3.144531 -2.84375 -3.578125 -2.738281 -3.824219 C -2.632812 -4.070312 -2.476562 -4.265625 -2.273438 -4.40625 C -2.074219 -4.546875 -1.824219 -4.613281 -1.523438 -4.613281 C -1.230469 -4.613281 -0.953125 -4.527344 -0.695312 -4.359375 C -0.4375 -4.1875 -0.238281 -3.941406 -0.09375 -3.617188 C 0.046875 -3.296875 0.117188 -2.929688 0.117188 -2.523438 C 0.117188 -1.851562 -0.0234375 -1.335938 -0.304688 -0.984375 C -0.582031 -0.632812 -0.996094 -0.40625 -1.546875 -0.308594 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-1">
|
||||
<path style="stroke:none;" d="M 7.054688 -3.011719 L 8.191406 -2.726562 C 7.953125 -1.792969 7.523438 -1.078125 6.90625 -0.589844 C 6.285156 -0.0976562 5.53125 0.148438 4.632812 0.148438 C 3.707031 0.148438 2.957031 -0.0429688 2.375 -0.417969 C 1.796875 -0.796875 1.355469 -1.34375 1.050781 -2.054688 C 0.75 -2.769531 0.597656 -3.539062 0.597656 -4.359375 C 0.597656 -5.253906 0.769531 -6.035156 1.109375 -6.699219 C 1.453125 -7.367188 1.9375 -7.871094 2.570312 -8.21875 C 3.199219 -8.5625 3.894531 -8.734375 4.652344 -8.734375 C 5.511719 -8.734375 6.234375 -8.515625 6.820312 -8.078125 C 7.40625 -7.640625 7.8125 -7.027344 8.046875 -6.234375 L 6.925781 -5.96875 C 6.726562 -6.59375 6.4375 -7.050781 6.058594 -7.335938 C 5.679688 -7.621094 5.203125 -7.765625 4.628906 -7.765625 C 3.96875 -7.765625 3.417969 -7.605469 2.972656 -7.289062 C 2.53125 -6.972656 2.21875 -6.546875 2.039062 -6.015625 C 1.859375 -5.480469 1.769531 -4.929688 1.769531 -4.367188 C 1.769531 -3.636719 1.875 -2.996094 2.089844 -2.453125 C 2.300781 -1.90625 2.632812 -1.5 3.082031 -1.230469 C 3.53125 -0.960938 4.015625 -0.828125 4.539062 -0.828125 C 5.175781 -0.828125 5.71875 -1.007812 6.15625 -1.375 C 6.597656 -1.742188 6.898438 -2.289062 7.054688 -3.011719 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-2">
|
||||
<path style="stroke:none;" d="M 0.398438 -3.109375 C 0.398438 -4.261719 0.71875 -5.117188 1.359375 -5.671875 C 1.894531 -6.132812 2.546875 -6.363281 3.316406 -6.363281 C 4.171875 -6.363281 4.871094 -6.082031 5.414062 -5.523438 C 5.957031 -4.960938 6.226562 -4.1875 6.226562 -3.199219 C 6.226562 -2.398438 6.109375 -1.769531 5.867188 -1.308594 C 5.628906 -0.851562 5.277344 -0.492188 4.820312 -0.242188 C 4.359375 0.0117188 3.859375 0.140625 3.316406 0.140625 C 2.445312 0.140625 1.742188 -0.140625 1.203125 -0.695312 C 0.667969 -1.253906 0.398438 -2.0625 0.398438 -3.109375 Z M 1.484375 -3.109375 C 1.484375 -2.3125 1.65625 -1.71875 2.003906 -1.320312 C 2.351562 -0.925781 2.789062 -0.726562 3.316406 -0.726562 C 3.839844 -0.726562 4.273438 -0.925781 4.625 -1.324219 C 4.972656 -1.722656 5.144531 -2.328125 5.144531 -3.148438 C 5.144531 -3.917969 4.96875 -4.5 4.621094 -4.894531 C 4.269531 -5.292969 3.835938 -5.492188 3.316406 -5.492188 C 2.789062 -5.492188 2.351562 -5.292969 2.003906 -4.898438 C 1.65625 -4.503906 1.484375 -3.90625 1.484375 -3.109375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-3">
|
||||
<path style="stroke:none;" d="M 0.789062 0 L 0.789062 -6.222656 L 1.734375 -6.222656 L 1.734375 -5.351562 C 1.929688 -5.65625 2.1875 -5.898438 2.515625 -6.085938 C 2.839844 -6.269531 3.207031 -6.363281 3.621094 -6.363281 C 4.082031 -6.363281 4.460938 -6.265625 4.753906 -6.078125 C 5.050781 -5.886719 5.257812 -5.617188 5.378906 -5.273438 C 5.871094 -6 6.511719 -6.363281 7.300781 -6.363281 C 7.917969 -6.363281 8.390625 -6.191406 8.726562 -5.851562 C 9.058594 -5.507812 9.222656 -4.984375 9.222656 -4.273438 L 9.222656 0 L 8.171875 0 L 8.171875 -3.921875 C 8.171875 -4.34375 8.140625 -4.644531 8.070312 -4.832031 C 8.003906 -5.015625 7.878906 -5.164062 7.699219 -5.28125 C 7.519531 -5.394531 7.308594 -5.449219 7.066406 -5.449219 C 6.628906 -5.449219 6.265625 -5.304688 5.976562 -5.011719 C 5.6875 -4.722656 5.542969 -4.257812 5.542969 -3.617188 L 5.542969 0 L 4.488281 0 L 4.488281 -4.042969 C 4.488281 -4.511719 4.402344 -4.863281 4.230469 -5.097656 C 4.058594 -5.332031 3.777344 -5.449219 3.386719 -5.449219 C 3.089844 -5.449219 2.816406 -5.371094 2.5625 -5.214844 C 2.3125 -5.058594 2.128906 -4.828125 2.015625 -4.53125 C 1.902344 -4.230469 1.84375 -3.796875 1.84375 -3.226562 L 1.84375 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-4">
|
||||
<path style="stroke:none;" d="M 0.789062 2.382812 L 0.789062 -6.222656 L 1.75 -6.222656 L 1.75 -5.414062 C 1.976562 -5.730469 2.234375 -5.96875 2.519531 -6.125 C 2.804688 -6.285156 3.148438 -6.363281 3.554688 -6.363281 C 4.085938 -6.363281 4.554688 -6.226562 4.960938 -5.953125 C 5.367188 -5.679688 5.675781 -5.292969 5.882812 -4.796875 C 6.089844 -4.296875 6.195312 -3.75 6.195312 -3.15625 C 6.195312 -2.519531 6.078125 -1.949219 5.851562 -1.4375 C 5.621094 -0.929688 5.289062 -0.539062 4.855469 -0.265625 C 4.417969 0.00390625 3.960938 0.140625 3.480469 0.140625 C 3.128906 0.140625 2.8125 0.0664062 2.535156 -0.0820312 C 2.253906 -0.230469 2.023438 -0.417969 1.84375 -0.644531 L 1.84375 2.382812 Z M 1.746094 -3.078125 C 1.746094 -2.277344 1.90625 -1.683594 2.234375 -1.300781 C 2.558594 -0.917969 2.949219 -0.726562 3.410156 -0.726562 C 3.878906 -0.726562 4.28125 -0.925781 4.613281 -1.320312 C 4.949219 -1.71875 5.117188 -2.332031 5.117188 -3.164062 C 5.117188 -3.957031 4.953125 -4.550781 4.625 -4.945312 C 4.300781 -5.339844 3.910156 -5.539062 3.457031 -5.539062 C 3.007812 -5.539062 2.609375 -5.328125 2.265625 -4.90625 C 1.917969 -4.488281 1.746094 -3.875 1.746094 -3.078125 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-5">
|
||||
<path style="stroke:none;" d="M 0.796875 -7.375 L 0.796875 -8.589844 L 1.851562 -8.589844 L 1.851562 -7.375 Z M 0.796875 0 L 0.796875 -6.222656 L 1.851562 -6.222656 L 1.851562 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-6">
|
||||
<path style="stroke:none;" d="M 0.765625 0 L 0.765625 -8.589844 L 1.820312 -8.589844 L 1.820312 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-7">
|
||||
<path style="stroke:none;" d="M 4.851562 -0.765625 C 4.460938 -0.433594 4.085938 -0.203125 3.722656 -0.0625 C 3.363281 0.0742188 2.976562 0.140625 2.5625 0.140625 C 1.878906 0.140625 1.351562 -0.0273438 0.984375 -0.359375 C 0.617188 -0.695312 0.433594 -1.121094 0.433594 -1.640625 C 0.433594 -1.945312 0.503906 -2.222656 0.640625 -2.476562 C 0.78125 -2.726562 0.960938 -2.929688 1.1875 -3.082031 C 1.410156 -3.234375 1.664062 -3.351562 1.945312 -3.429688 C 2.152344 -3.484375 2.464844 -3.535156 2.882812 -3.585938 C 3.734375 -3.6875 4.359375 -3.808594 4.765625 -3.949219 C 4.769531 -4.09375 4.769531 -4.1875 4.769531 -4.226562 C 4.769531 -4.65625 4.671875 -4.957031 4.46875 -5.132812 C 4.199219 -5.371094 3.800781 -5.492188 3.269531 -5.492188 C 2.773438 -5.492188 2.40625 -5.402344 2.171875 -5.230469 C 1.933594 -5.054688 1.757812 -4.75 1.648438 -4.304688 L 0.617188 -4.445312 C 0.710938 -4.886719 0.863281 -5.246094 1.078125 -5.515625 C 1.292969 -5.789062 1.601562 -5.996094 2.007812 -6.144531 C 2.414062 -6.289062 2.886719 -6.363281 3.421875 -6.363281 C 3.953125 -6.363281 4.382812 -6.300781 4.71875 -6.175781 C 5.050781 -6.050781 5.292969 -5.894531 5.449219 -5.703125 C 5.605469 -5.515625 5.714844 -5.273438 5.777344 -4.984375 C 5.8125 -4.804688 5.828125 -4.484375 5.828125 -4.015625 L 5.828125 -2.609375 C 5.828125 -1.628906 5.851562 -1.007812 5.898438 -0.746094 C 5.941406 -0.488281 6.03125 -0.238281 6.164062 0 L 5.0625 0 C 4.953125 -0.21875 4.882812 -0.476562 4.851562 -0.765625 Z M 4.765625 -3.125 C 4.382812 -2.96875 3.804688 -2.835938 3.039062 -2.726562 C 2.605469 -2.664062 2.300781 -2.59375 2.121094 -2.515625 C 1.941406 -2.4375 1.804688 -2.320312 1.703125 -2.171875 C 1.605469 -2.019531 1.558594 -1.851562 1.558594 -1.671875 C 1.558594 -1.390625 1.664062 -1.15625 1.878906 -0.96875 C 2.089844 -0.78125 2.402344 -0.6875 2.8125 -0.6875 C 3.21875 -0.6875 3.578125 -0.773438 3.898438 -0.953125 C 4.214844 -1.128906 4.445312 -1.375 4.59375 -1.679688 C 4.707031 -1.917969 4.765625 -2.273438 4.765625 -2.734375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-8">
|
||||
<path style="stroke:none;" d="M 3.09375 -0.945312 L 3.246094 -0.0117188 C 2.949219 0.0507812 2.683594 0.0820312 2.449219 0.0820312 C 2.066406 0.0820312 1.769531 0.0234375 1.558594 -0.101562 C 1.347656 -0.222656 1.199219 -0.378906 1.113281 -0.578125 C 1.027344 -0.773438 0.984375 -1.1875 0.984375 -1.820312 L 0.984375 -5.402344 L 0.210938 -5.402344 L 0.210938 -6.222656 L 0.984375 -6.222656 L 0.984375 -7.765625 L 2.03125 -8.398438 L 2.03125 -6.222656 L 3.09375 -6.222656 L 3.09375 -5.402344 L 2.03125 -5.402344 L 2.03125 -1.765625 C 2.03125 -1.464844 2.050781 -1.269531 2.089844 -1.183594 C 2.125 -1.097656 2.1875 -1.03125 2.269531 -0.976562 C 2.355469 -0.925781 2.476562 -0.902344 2.632812 -0.902344 C 2.75 -0.902344 2.902344 -0.914062 3.09375 -0.945312 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-9">
|
||||
<path style="stroke:none;" d="M 0.789062 0 L 0.789062 -6.222656 L 1.742188 -6.222656 L 1.742188 -5.335938 C 2.199219 -6.019531 2.859375 -6.363281 3.71875 -6.363281 C 4.09375 -6.363281 4.441406 -6.296875 4.753906 -6.160156 C 5.070312 -6.027344 5.304688 -5.851562 5.460938 -5.632812 C 5.617188 -5.414062 5.726562 -5.152344 5.789062 -4.851562 C 5.828125 -4.65625 5.847656 -4.3125 5.847656 -3.828125 L 5.847656 0 L 4.792969 0 L 4.792969 -3.785156 C 4.792969 -4.214844 4.75 -4.535156 4.671875 -4.75 C 4.589844 -4.960938 4.441406 -5.132812 4.234375 -5.257812 C 4.023438 -5.386719 3.78125 -5.449219 3.5 -5.449219 C 3.050781 -5.449219 2.660156 -5.304688 2.335938 -5.023438 C 2.007812 -4.738281 1.84375 -4.195312 1.84375 -3.398438 L 1.84375 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-10">
|
||||
<path style="stroke:none;" d="M 5.050781 -2.003906 L 6.140625 -1.867188 C 5.96875 -1.230469 5.648438 -0.738281 5.1875 -0.386719 C 4.722656 -0.0351562 4.125 0.140625 3.40625 0.140625 C 2.496094 0.140625 1.773438 -0.140625 1.238281 -0.699219 C 0.707031 -1.261719 0.4375 -2.046875 0.4375 -3.058594 C 0.4375 -4.105469 0.710938 -4.917969 1.25 -5.496094 C 1.789062 -6.074219 2.484375 -6.363281 3.34375 -6.363281 C 4.175781 -6.363281 4.859375 -6.078125 5.382812 -5.515625 C 5.910156 -4.949219 6.175781 -4.148438 6.175781 -3.125 C 6.175781 -3.0625 6.171875 -2.96875 6.171875 -2.84375 L 1.53125 -2.84375 C 1.570312 -2.160156 1.761719 -1.632812 2.109375 -1.273438 C 2.457031 -0.910156 2.890625 -0.726562 3.410156 -0.726562 C 3.796875 -0.726562 4.125 -0.828125 4.398438 -1.03125 C 4.671875 -1.234375 4.890625 -1.558594 5.050781 -2.003906 Z M 1.585938 -3.710938 L 5.0625 -3.710938 C 5.015625 -4.234375 4.882812 -4.625 4.664062 -4.886719 C 4.328125 -5.292969 3.890625 -5.496094 3.359375 -5.496094 C 2.875 -5.496094 2.464844 -5.335938 2.136719 -5.007812 C 1.804688 -4.683594 1.625 -4.25 1.585938 -3.710938 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-11">
|
||||
<path style="stroke:none;" d="M 1.042969 0 L 1.042969 -5.402344 L 0.109375 -5.402344 L 0.109375 -6.222656 L 1.042969 -6.222656 L 1.042969 -6.882812 C 1.042969 -7.300781 1.078125 -7.613281 1.15625 -7.816406 C 1.257812 -8.089844 1.433594 -8.3125 1.691406 -8.480469 C 1.945312 -8.652344 2.304688 -8.734375 2.765625 -8.734375 C 3.0625 -8.734375 3.390625 -8.703125 3.75 -8.632812 L 3.59375 -7.710938 C 3.375 -7.75 3.164062 -7.769531 2.96875 -7.769531 C 2.648438 -7.769531 2.421875 -7.703125 2.289062 -7.5625 C 2.15625 -7.425781 2.09375 -7.171875 2.09375 -6.796875 L 2.09375 -6.222656 L 3.304688 -6.222656 L 3.304688 -5.402344 L 2.09375 -5.402344 L 2.09375 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-12">
|
||||
<path style="stroke:none;" d="M 4.828125 0 L 4.828125 -0.785156 C 4.433594 -0.167969 3.851562 0.140625 3.085938 0.140625 C 2.589844 0.140625 2.136719 0.00390625 1.71875 -0.269531 C 1.304688 -0.542969 0.980469 -0.925781 0.753906 -1.414062 C 0.523438 -1.90625 0.410156 -2.46875 0.410156 -3.105469 C 0.410156 -3.726562 0.515625 -4.289062 0.71875 -4.796875 C 0.925781 -5.300781 1.238281 -5.6875 1.652344 -5.960938 C 2.066406 -6.230469 2.53125 -6.363281 3.039062 -6.363281 C 3.414062 -6.363281 3.75 -6.285156 4.042969 -6.125 C 4.335938 -5.96875 4.574219 -5.761719 4.757812 -5.507812 L 4.757812 -8.589844 L 5.804688 -8.589844 L 5.804688 0 Z M 1.492188 -3.105469 C 1.492188 -2.308594 1.664062 -1.710938 2 -1.320312 C 2.335938 -0.925781 2.730469 -0.726562 3.1875 -0.726562 C 3.648438 -0.726562 4.039062 -0.914062 4.363281 -1.292969 C 4.683594 -1.667969 4.84375 -2.242188 4.84375 -3.015625 C 4.84375 -3.867188 4.679688 -4.492188 4.351562 -4.890625 C 4.023438 -5.289062 3.621094 -5.492188 3.140625 -5.492188 C 2.671875 -5.492188 2.28125 -5.296875 1.964844 -4.914062 C 1.652344 -4.53125 1.492188 -3.929688 1.492188 -3.105469 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-13">
|
||||
<path style="stroke:none;" d="M 4.867188 0 L 4.867188 -0.914062 C 4.382812 -0.210938 3.726562 0.140625 2.894531 0.140625 C 2.527344 0.140625 2.183594 0.0703125 1.867188 -0.0703125 C 1.546875 -0.210938 1.3125 -0.386719 1.15625 -0.601562 C 1.003906 -0.8125 0.894531 -1.074219 0.832031 -1.382812 C 0.789062 -1.589844 0.765625 -1.917969 0.765625 -2.367188 L 0.765625 -6.222656 L 1.820312 -6.222656 L 1.820312 -2.773438 C 1.820312 -2.222656 1.84375 -1.851562 1.886719 -1.65625 C 1.953125 -1.378906 2.09375 -1.164062 2.308594 -1.003906 C 2.523438 -0.847656 2.789062 -0.765625 3.105469 -0.765625 C 3.421875 -0.765625 3.71875 -0.847656 3.996094 -1.011719 C 4.273438 -1.171875 4.46875 -1.394531 4.585938 -1.671875 C 4.699219 -1.953125 4.757812 -2.359375 4.757812 -2.890625 L 4.757812 -6.222656 L 5.8125 -6.222656 L 5.8125 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-1">
|
||||
<path style="stroke:none;" d="M 0.953125 0 L 0.953125 -9.304688 L 4.445312 -9.304688 C 5.15625 -9.304688 5.722656 -9.210938 6.152344 -9.023438 C 6.582031 -8.835938 6.921875 -8.546875 7.164062 -8.152344 C 7.40625 -7.761719 7.527344 -7.351562 7.527344 -6.925781 C 7.527344 -6.527344 7.421875 -6.152344 7.203125 -5.800781 C 6.988281 -5.449219 6.664062 -5.167969 6.226562 -4.953125 C 6.789062 -4.785156 7.222656 -4.503906 7.523438 -4.105469 C 7.828125 -3.707031 7.980469 -3.238281 7.980469 -2.699219 C 7.980469 -2.261719 7.886719 -1.855469 7.703125 -1.480469 C 7.519531 -1.105469 7.292969 -0.820312 7.019531 -0.617188 C 6.75 -0.414062 6.410156 -0.257812 6 -0.15625 C 5.59375 -0.0507812 5.09375 0 4.5 0 Z M 2.183594 -5.394531 L 4.195312 -5.394531 C 4.742188 -5.394531 5.132812 -5.429688 5.371094 -5.503906 C 5.683594 -5.597656 5.917969 -5.75 6.078125 -5.96875 C 6.238281 -6.183594 6.316406 -6.453125 6.316406 -6.78125 C 6.316406 -7.089844 6.242188 -7.359375 6.09375 -7.59375 C 5.945312 -7.828125 5.734375 -7.992188 5.460938 -8.078125 C 5.183594 -8.164062 4.710938 -8.207031 4.042969 -8.207031 L 2.183594 -8.207031 Z M 2.183594 -1.097656 L 4.5 -1.097656 C 4.898438 -1.097656 5.175781 -1.113281 5.339844 -1.140625 C 5.621094 -1.191406 5.859375 -1.277344 6.050781 -1.398438 C 6.242188 -1.515625 6.394531 -1.6875 6.519531 -1.914062 C 6.640625 -2.140625 6.703125 -2.402344 6.703125 -2.699219 C 6.703125 -3.046875 6.613281 -3.347656 6.4375 -3.601562 C 6.257812 -3.859375 6.011719 -4.039062 5.695312 -4.140625 C 5.382812 -4.246094 4.929688 -4.296875 4.335938 -4.296875 L 2.183594 -4.296875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-2">
|
||||
<path style="stroke:none;" d="M 0.429688 -3.371094 C 0.429688 -4.617188 0.777344 -5.542969 1.472656 -6.144531 C 2.050781 -6.644531 2.757812 -6.894531 3.59375 -6.894531 C 4.519531 -6.894531 5.277344 -6.589844 5.867188 -5.984375 C 6.453125 -5.375 6.746094 -4.535156 6.746094 -3.464844 C 6.746094 -2.597656 6.617188 -1.914062 6.355469 -1.417969 C 6.097656 -0.921875 5.71875 -0.535156 5.222656 -0.261719 C 4.722656 0.015625 4.179688 0.152344 3.59375 0.152344 C 2.648438 0.152344 1.886719 -0.148438 1.304688 -0.753906 C 0.722656 -1.359375 0.429688 -2.230469 0.429688 -3.371094 Z M 1.605469 -3.371094 C 1.605469 -2.507812 1.792969 -1.859375 2.171875 -1.429688 C 2.546875 -1 3.023438 -0.789062 3.59375 -0.789062 C 4.160156 -0.789062 4.632812 -1.003906 5.007812 -1.433594 C 5.382812 -1.867188 5.574219 -2.523438 5.574219 -3.410156 C 5.574219 -4.242188 5.382812 -4.875 5.003906 -5.304688 C 4.625 -5.734375 4.15625 -5.949219 3.59375 -5.949219 C 3.023438 -5.949219 2.546875 -5.734375 2.171875 -5.304688 C 1.792969 -4.878906 1.605469 -4.234375 1.605469 -3.371094 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-3">
|
||||
<path style="stroke:none;" d="M 0.398438 -2.011719 L 1.53125 -2.191406 C 1.59375 -1.738281 1.769531 -1.390625 2.058594 -1.148438 C 2.347656 -0.90625 2.753906 -0.789062 3.273438 -0.789062 C 3.800781 -0.789062 4.1875 -0.894531 4.445312 -1.109375 C 4.699219 -1.320312 4.824219 -1.570312 4.824219 -1.859375 C 4.824219 -2.117188 4.710938 -2.320312 4.488281 -2.46875 C 4.332031 -2.570312 3.941406 -2.699219 3.320312 -2.855469 C 2.480469 -3.066406 1.902344 -3.25 1.578125 -3.40625 C 1.253906 -3.558594 1.007812 -3.773438 0.839844 -4.046875 C 0.671875 -4.320312 0.589844 -4.621094 0.589844 -4.953125 C 0.589844 -5.253906 0.660156 -5.53125 0.796875 -5.785156 C 0.933594 -6.042969 1.121094 -6.253906 1.359375 -6.421875 C 1.535156 -6.554688 1.777344 -6.667969 2.085938 -6.757812 C 2.390625 -6.847656 2.722656 -6.894531 3.070312 -6.894531 C 3.601562 -6.894531 4.066406 -6.816406 4.464844 -6.664062 C 4.867188 -6.511719 5.160156 -6.304688 5.351562 -6.046875 C 5.542969 -5.785156 5.671875 -5.4375 5.746094 -5 L 4.628906 -4.851562 C 4.578125 -5.195312 4.429688 -5.46875 4.1875 -5.664062 C 3.945312 -5.859375 3.597656 -5.953125 3.15625 -5.953125 C 2.628906 -5.953125 2.253906 -5.867188 2.03125 -5.695312 C 1.808594 -5.519531 1.695312 -5.316406 1.695312 -5.085938 C 1.695312 -4.9375 1.742188 -4.804688 1.835938 -4.683594 C 1.929688 -4.5625 2.074219 -4.460938 2.273438 -4.378906 C 2.386719 -4.335938 2.722656 -4.242188 3.28125 -4.085938 C 4.089844 -3.871094 4.652344 -3.695312 4.972656 -3.558594 C 5.292969 -3.421875 5.542969 -3.21875 5.726562 -2.957031 C 5.90625 -2.695312 6 -2.371094 6 -1.980469 C 6 -1.601562 5.886719 -1.242188 5.664062 -0.90625 C 5.441406 -0.570312 5.121094 -0.308594 4.703125 -0.125 C 4.285156 0.0585938 3.8125 0.152344 3.28125 0.152344 C 2.40625 0.152344 1.738281 -0.03125 1.277344 -0.394531 C 0.820312 -0.757812 0.527344 -1.296875 0.398438 -2.011719 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-4">
|
||||
<path style="stroke:none;" d="M 3.351562 -1.023438 L 3.515625 -0.0117188 C 3.195312 0.0546875 2.90625 0.0898438 2.652344 0.0898438 C 2.238281 0.0898438 1.917969 0.0234375 1.6875 -0.109375 C 1.460938 -0.238281 1.300781 -0.410156 1.207031 -0.625 C 1.113281 -0.839844 1.066406 -1.289062 1.066406 -1.972656 L 1.066406 -5.851562 L 0.226562 -5.851562 L 0.226562 -6.742188 L 1.066406 -6.742188 L 1.066406 -8.410156 L 2.203125 -9.097656 L 2.203125 -6.742188 L 3.351562 -6.742188 L 3.351562 -5.851562 L 2.203125 -5.851562 L 2.203125 -1.910156 C 2.203125 -1.585938 2.222656 -1.375 2.261719 -1.28125 C 2.304688 -1.1875 2.367188 -1.113281 2.460938 -1.058594 C 2.550781 -1.003906 2.679688 -0.976562 2.851562 -0.976562 C 2.976562 -0.976562 3.144531 -0.992188 3.351562 -1.023438 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-5">
|
||||
<path style="stroke:none;" d="M 1.179688 0 L 1.179688 -1.300781 L 2.480469 -1.300781 L 2.480469 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-6">
|
||||
<path style="stroke:none;" d="M 1.003906 0 L 1.003906 -9.304688 L 4.511719 -9.304688 C 5.128906 -9.304688 5.601562 -9.277344 5.929688 -9.21875 C 6.386719 -9.140625 6.769531 -8.996094 7.078125 -8.78125 C 7.386719 -8.566406 7.636719 -8.269531 7.824219 -7.882812 C 8.011719 -7.5 8.105469 -7.074219 8.105469 -6.613281 C 8.105469 -5.824219 7.855469 -5.152344 7.351562 -4.605469 C 6.847656 -4.058594 5.9375 -3.78125 4.621094 -3.78125 L 2.234375 -3.78125 L 2.234375 0 Z M 2.234375 -4.882812 L 4.640625 -4.882812 C 5.4375 -4.882812 6 -5.03125 6.335938 -5.324219 C 6.667969 -5.621094 6.835938 -6.039062 6.835938 -6.578125 C 6.835938 -6.964844 6.738281 -7.296875 6.542969 -7.574219 C 6.34375 -7.851562 6.085938 -8.035156 5.765625 -8.125 C 5.558594 -8.179688 5.171875 -8.207031 4.613281 -8.207031 L 2.234375 -8.207031 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-7">
|
||||
<path style="stroke:none;" d="M 0.804688 2.597656 L 0.679688 1.523438 C 0.929688 1.589844 1.148438 1.625 1.332031 1.625 C 1.585938 1.625 1.789062 1.582031 1.941406 1.5 C 2.09375 1.414062 2.21875 1.296875 2.316406 1.140625 C 2.390625 1.027344 2.503906 0.746094 2.664062 0.292969 C 2.6875 0.230469 2.722656 0.136719 2.765625 0.0117188 L 0.210938 -6.742188 L 1.441406 -6.742188 L 2.84375 -2.835938 C 3.027344 -2.34375 3.1875 -1.820312 3.332031 -1.277344 C 3.464844 -1.800781 3.621094 -2.3125 3.800781 -2.8125 L 5.242188 -6.742188 L 6.386719 -6.742188 L 3.820312 0.113281 C 3.546875 0.855469 3.332031 1.363281 3.179688 1.644531 C 2.976562 2.019531 2.746094 2.296875 2.480469 2.472656 C 2.21875 2.648438 1.90625 2.734375 1.542969 2.734375 C 1.324219 2.734375 1.078125 2.6875 0.804688 2.597656 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-8">
|
||||
<path style="stroke:none;" d="M 0.855469 0 L 0.855469 -9.304688 L 2 -9.304688 L 2 -5.96875 C 2.53125 -6.585938 3.207031 -6.894531 4.019531 -6.894531 C 4.519531 -6.894531 4.953125 -6.796875 5.320312 -6.597656 C 5.6875 -6.402344 5.949219 -6.128906 6.109375 -5.78125 C 6.269531 -5.433594 6.347656 -4.933594 6.347656 -4.273438 L 6.347656 0 L 5.203125 0 L 5.203125 -4.273438 C 5.203125 -4.84375 5.082031 -5.257812 4.832031 -5.519531 C 4.585938 -5.78125 4.234375 -5.910156 3.78125 -5.910156 C 3.445312 -5.910156 3.125 -5.820312 2.828125 -5.644531 C 2.53125 -5.46875 2.316406 -5.234375 2.191406 -4.933594 C 2.0625 -4.632812 2 -4.21875 2 -3.6875 L 2 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-9">
|
||||
<path style="stroke:none;" d="M 0.855469 0 L 0.855469 -6.742188 L 1.886719 -6.742188 L 1.886719 -5.78125 C 2.382812 -6.523438 3.09375 -6.894531 4.03125 -6.894531 C 4.4375 -6.894531 4.808594 -6.820312 5.152344 -6.675781 C 5.492188 -6.527344 5.746094 -6.335938 5.914062 -6.101562 C 6.085938 -5.863281 6.203125 -5.582031 6.273438 -5.257812 C 6.3125 -5.046875 6.335938 -4.675781 6.335938 -4.144531 L 6.335938 0 L 5.191406 0 L 5.191406 -4.101562 C 5.191406 -4.566406 5.148438 -4.914062 5.058594 -5.144531 C 4.96875 -5.375 4.8125 -5.558594 4.585938 -5.695312 C 4.359375 -5.835938 4.09375 -5.902344 3.789062 -5.902344 C 3.304688 -5.902344 2.882812 -5.75 2.53125 -5.441406 C 2.175781 -5.132812 2 -4.546875 2 -3.679688 L 2 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-10">
|
||||
<path style="stroke:none;" d="M 0.855469 2.582031 L 0.855469 -6.742188 L 1.898438 -6.742188 L 1.898438 -5.867188 C 2.144531 -6.207031 2.421875 -6.464844 2.730469 -6.636719 C 3.039062 -6.808594 3.414062 -6.894531 3.851562 -6.894531 C 4.429688 -6.894531 4.9375 -6.746094 5.375 -6.449219 C 5.816406 -6.152344 6.148438 -5.734375 6.375 -5.195312 C 6.597656 -4.65625 6.710938 -4.066406 6.710938 -3.421875 C 6.710938 -2.730469 6.585938 -2.109375 6.339844 -1.558594 C 6.089844 -1.007812 5.730469 -0.582031 5.257812 -0.289062 C 4.785156 0.00390625 4.289062 0.152344 3.769531 0.152344 C 3.390625 0.152344 3.046875 0.0703125 2.746094 -0.0898438 C 2.441406 -0.25 2.195312 -0.453125 2 -0.699219 L 2 2.582031 Z M 1.890625 -3.332031 C 1.890625 -2.464844 2.066406 -1.824219 2.417969 -1.410156 C 2.769531 -0.996094 3.195312 -0.789062 3.695312 -0.789062 C 4.203125 -0.789062 4.636719 -1 5 -1.429688 C 5.359375 -1.859375 5.542969 -2.527344 5.542969 -3.429688 C 5.542969 -4.289062 5.363281 -4.929688 5.011719 -5.359375 C 4.65625 -5.785156 4.234375 -6 3.746094 -6 C 3.257812 -6 2.828125 -5.769531 2.453125 -5.316406 C 2.078125 -4.859375 1.890625 -4.199219 1.890625 -3.332031 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-11">
|
||||
<path style="stroke:none;" d="M 1.910156 0 L 0.851562 0 L 0.851562 -9.304688 L 1.992188 -9.304688 L 1.992188 -5.984375 C 2.476562 -6.589844 3.089844 -6.894531 3.839844 -6.894531 C 4.253906 -6.894531 4.648438 -6.808594 5.019531 -6.644531 C 5.390625 -6.476562 5.691406 -6.242188 5.933594 -5.9375 C 6.171875 -5.636719 6.359375 -5.269531 6.492188 -4.84375 C 6.628906 -4.414062 6.695312 -3.957031 6.695312 -3.472656 C 6.695312 -2.316406 6.410156 -1.425781 5.839844 -0.792969 C 5.269531 -0.164062 4.582031 0.152344 3.78125 0.152344 C 2.988281 0.152344 2.363281 -0.179688 1.910156 -0.84375 Z M 1.898438 -3.421875 C 1.898438 -2.613281 2.007812 -2.027344 2.226562 -1.667969 C 2.585938 -1.082031 3.074219 -0.789062 3.6875 -0.789062 C 4.1875 -0.789062 4.617188 -1.003906 4.984375 -1.4375 C 5.347656 -1.871094 5.527344 -2.519531 5.527344 -3.375 C 5.527344 -4.257812 5.355469 -4.90625 5.003906 -5.324219 C 4.65625 -5.742188 4.234375 -5.953125 3.738281 -5.953125 C 3.238281 -5.953125 2.808594 -5.738281 2.445312 -5.304688 C 2.082031 -4.871094 1.898438 -4.242188 1.898438 -3.421875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-12">
|
||||
<path style="stroke:none;" d="M 0.863281 -7.992188 L 0.863281 -9.304688 L 2.007812 -9.304688 L 2.007812 -7.992188 Z M 0.863281 0 L 0.863281 -6.742188 L 2.007812 -6.742188 L 2.007812 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-13">
|
||||
<path style="stroke:none;" d="M 5.230469 0 L 5.230469 -0.851562 C 4.804688 -0.183594 4.175781 0.152344 3.34375 0.152344 C 2.808594 0.152344 2.3125 0.00390625 1.863281 -0.292969 C 1.414062 -0.589844 1.0625 -1 0.816406 -1.53125 C 0.570312 -2.0625 0.445312 -2.675781 0.445312 -3.363281 C 0.445312 -4.035156 0.554688 -4.648438 0.78125 -5.195312 C 1.003906 -5.742188 1.339844 -6.164062 1.789062 -6.457031 C 2.238281 -6.75 2.738281 -6.894531 3.292969 -6.894531 C 3.699219 -6.894531 4.0625 -6.808594 4.378906 -6.636719 C 4.695312 -6.464844 4.957031 -6.242188 5.15625 -5.96875 L 5.15625 -9.304688 L 6.289062 -9.304688 L 6.289062 0 Z M 1.617188 -3.363281 C 1.617188 -2.5 1.800781 -1.855469 2.164062 -1.429688 C 2.527344 -1 2.957031 -0.789062 3.453125 -0.789062 C 3.953125 -0.789062 4.375 -0.992188 4.726562 -1.398438 C 5.074219 -1.808594 5.25 -2.429688 5.25 -3.269531 C 5.25 -4.191406 5.070312 -4.867188 4.714844 -5.300781 C 4.359375 -5.730469 3.921875 -5.949219 3.402344 -5.949219 C 2.894531 -5.949219 2.46875 -5.742188 2.128906 -5.324219 C 1.789062 -4.910156 1.617188 -4.257812 1.617188 -3.363281 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-14">
|
||||
<path style="stroke:none;" d="M 4.84375 0 L 3.699219 0 L 3.699219 -7.28125 C 3.425781 -7.019531 3.066406 -6.757812 2.617188 -6.492188 C 2.171875 -6.230469 1.769531 -6.035156 1.414062 -5.902344 L 1.414062 -7.007812 C 2.054688 -7.308594 2.613281 -7.671875 3.089844 -8.101562 C 3.570312 -8.527344 3.90625 -8.941406 4.105469 -9.34375 L 4.84375 -9.34375 Z "/>
|
||||
</symbol>
|
||||
</g>
|
||||
<clipPath id="clip1">
|
||||
<path d="M 89 21 L 91 21 L 91 221 L 89 221 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip2">
|
||||
<path d="M 201 21 L 203 21 L 203 221 L 201 221 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip3">
|
||||
<path d="M 313 21 L 315 21 L 315 221 L 313 221 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip4">
|
||||
<path d="M 33 180 L 355 180 L 355 182 L 33 182 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip5">
|
||||
<path d="M 33 146 L 355 146 L 355 148 L 33 148 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip6">
|
||||
<path d="M 33 120 L 355 120 L 355 122 L 33 122 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip7">
|
||||
<path d="M 33 95 L 355 95 L 355 97 L 33 97 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip8">
|
||||
<path d="M 33 61 L 355 61 L 355 63 L 33 63 Z "/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="surface11">
|
||||
<g clip-path="url(#clip1)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 90.226562 220.007812 L 90.226562 21 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip2)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 201.996094 220.007812 L 201.996094 21 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip3)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 313.761719 220.007812 L 313.761719 21 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip4)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 33 180.734375 L 355 180.734375 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip5)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 33 146.960938 L 355 146.960938 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip6)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 33 121.410156 L 355 121.410156 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip7)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 33 95.859375 L 355 95.859375 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip8)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 33 62.082031 L 355 62.082031 "/>
|
||||
</g>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 49.128906 169 C 49.128906 168.167969 48.800781 167.375 48.214844 166.785156 C 47.625 166.199219 46.832031 165.871094 46 165.871094 C 45.167969 165.871094 44.375 166.199219 43.785156 166.785156 C 43.199219 167.375 42.871094 168.167969 42.871094 169 C 42.871094 169.832031 43.199219 170.625 43.785156 171.214844 C 44.375 171.800781 45.167969 172.128906 46 172.128906 C 46.832031 172.128906 47.625 171.800781 48.214844 171.214844 C 48.800781 170.625 49.128906 169.832031 49.128906 169 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 82.128906 169 C 82.128906 168.167969 81.800781 167.375 81.214844 166.785156 C 80.625 166.199219 79.832031 165.871094 79 165.871094 C 78.167969 165.871094 77.375 166.199219 76.785156 166.785156 C 76.199219 167.375 75.871094 168.167969 75.871094 169 C 75.871094 169.832031 76.199219 170.625 76.785156 171.214844 C 77.375 171.800781 78.167969 172.128906 79 172.128906 C 79.832031 172.128906 80.625 171.800781 81.214844 171.214844 C 81.800781 170.625 82.128906 169.832031 82.128906 169 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 116.128906 167 C 116.128906 166.167969 115.800781 165.375 115.214844 164.785156 C 114.625 164.199219 113.832031 163.871094 113 163.871094 C 112.167969 163.871094 111.375 164.199219 110.785156 164.785156 C 110.199219 165.375 109.871094 166.167969 109.871094 167 C 109.871094 167.832031 110.199219 168.625 110.785156 169.214844 C 111.375 169.800781 112.167969 170.128906 113 170.128906 C 113.832031 170.128906 114.625 169.800781 115.214844 169.214844 C 115.800781 168.625 116.128906 167.832031 116.128906 167 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 150.128906 159 C 150.128906 158.167969 149.800781 157.375 149.214844 156.785156 C 148.625 156.199219 147.832031 155.871094 147 155.871094 C 146.167969 155.871094 145.375 156.199219 144.785156 156.785156 C 144.199219 157.375 143.871094 158.167969 143.871094 159 C 143.871094 159.832031 144.199219 160.625 144.785156 161.214844 C 145.375 161.800781 146.167969 162.128906 147 162.128906 C 147.832031 162.128906 148.625 161.800781 149.214844 161.214844 C 149.800781 160.625 150.128906 159.832031 150.128906 159 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 183.128906 146 C 183.128906 145.167969 182.800781 144.375 182.214844 143.785156 C 181.625 143.199219 180.832031 142.871094 180 142.871094 C 179.167969 142.871094 178.375 143.199219 177.785156 143.785156 C 177.199219 144.375 176.871094 145.167969 176.871094 146 C 176.871094 146.832031 177.199219 147.625 177.785156 148.214844 C 178.375 148.800781 179.167969 149.128906 180 149.128906 C 180.832031 149.128906 181.625 148.800781 182.214844 148.214844 C 182.800781 147.625 183.128906 146.832031 183.128906 146 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 217.128906 128 C 217.128906 127.167969 216.800781 126.375 216.214844 125.785156 C 215.625 125.199219 214.832031 124.871094 214 124.871094 C 213.167969 124.871094 212.375 125.199219 211.785156 125.785156 C 211.199219 126.375 210.871094 127.167969 210.871094 128 C 210.871094 128.832031 211.199219 129.625 211.785156 130.214844 C 212.375 130.800781 213.167969 131.128906 214 131.128906 C 214.832031 131.128906 215.625 130.800781 216.214844 130.214844 C 216.800781 129.625 217.128906 128.832031 217.128906 128 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 251.128906 108 C 251.128906 107.167969 250.800781 106.375 250.214844 105.785156 C 249.625 105.199219 248.832031 104.871094 248 104.871094 C 247.167969 104.871094 246.375 105.199219 245.785156 105.785156 C 245.199219 106.375 244.871094 107.167969 244.871094 108 C 244.871094 108.832031 245.199219 109.625 245.785156 110.214844 C 246.375 110.800781 247.167969 111.128906 248 111.128906 C 248.832031 111.128906 249.625 110.800781 250.214844 110.214844 C 250.800781 109.625 251.128906 108.832031 251.128906 108 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 284.128906 85 C 284.128906 84.167969 283.800781 83.375 283.214844 82.785156 C 282.625 82.199219 281.832031 81.871094 281 81.871094 C 280.167969 81.871094 279.375 82.199219 278.785156 82.785156 C 278.199219 83.375 277.871094 84.167969 277.871094 85 C 277.871094 85.832031 278.199219 86.625 278.785156 87.214844 C 279.375 87.800781 280.167969 88.128906 281 88.128906 C 281.832031 88.128906 282.625 87.800781 283.214844 87.214844 C 283.800781 86.625 284.128906 85.832031 284.128906 85 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 318.128906 59 C 318.128906 58.167969 317.800781 57.375 317.214844 56.785156 C 316.625 56.199219 315.832031 55.871094 315 55.871094 C 314.167969 55.871094 313.375 56.199219 312.785156 56.785156 C 312.199219 57.375 311.871094 58.167969 311.871094 59 C 311.871094 59.832031 312.199219 60.625 312.785156 61.214844 C 313.375 61.800781 314.167969 62.128906 315 62.128906 C 315.832031 62.128906 316.625 61.800781 317.214844 61.214844 C 317.800781 60.625 318.128906 59.832031 318.128906 59 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 352.128906 31 C 352.128906 30.167969 351.800781 29.375 351.214844 28.785156 C 350.625 28.199219 349.832031 27.871094 349 27.871094 C 348.167969 27.871094 347.375 28.199219 346.785156 28.785156 C 346.199219 29.375 345.871094 30.167969 345.871094 31 C 345.871094 31.832031 346.199219 32.625 346.785156 33.214844 C 347.375 33.800781 348.167969 34.128906 349 34.128906 C 349.832031 34.128906 350.625 33.800781 351.214844 33.214844 C 351.800781 32.625 352.128906 31.832031 352.128906 31 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 49.128906 205 C 49.128906 204.167969 48.800781 203.375 48.214844 202.785156 C 47.625 202.199219 46.832031 201.871094 46 201.871094 C 45.167969 201.871094 44.375 202.199219 43.785156 202.785156 C 43.199219 203.375 42.871094 204.167969 42.871094 205 C 42.871094 205.832031 43.199219 206.625 43.785156 207.214844 C 44.375 207.800781 45.167969 208.128906 46 208.128906 C 46.832031 208.128906 47.625 207.800781 48.214844 207.214844 C 48.800781 206.625 49.128906 205.832031 49.128906 205 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 82.128906 199 C 82.128906 198.167969 81.800781 197.375 81.214844 196.785156 C 80.625 196.199219 79.832031 195.871094 79 195.871094 C 78.167969 195.871094 77.375 196.199219 76.785156 196.785156 C 76.199219 197.375 75.871094 198.167969 75.871094 199 C 75.871094 199.832031 76.199219 200.625 76.785156 201.214844 C 77.375 201.800781 78.167969 202.128906 79 202.128906 C 79.832031 202.128906 80.625 201.800781 81.214844 201.214844 C 81.800781 200.625 82.128906 199.832031 82.128906 199 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 116.128906 190 C 116.128906 189.167969 115.800781 188.375 115.214844 187.785156 C 114.625 187.199219 113.832031 186.871094 113 186.871094 C 112.167969 186.871094 111.375 187.199219 110.785156 187.785156 C 110.199219 188.375 109.871094 189.167969 109.871094 190 C 109.871094 190.832031 110.199219 191.625 110.785156 192.214844 C 111.375 192.800781 112.167969 193.128906 113 193.128906 C 113.832031 193.128906 114.625 192.800781 115.214844 192.214844 C 115.800781 191.625 116.128906 190.832031 116.128906 190 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 150.128906 177 C 150.128906 176.167969 149.800781 175.375 149.214844 174.785156 C 148.625 174.199219 147.832031 173.871094 147 173.871094 C 146.167969 173.871094 145.375 174.199219 144.785156 174.785156 C 144.199219 175.375 143.871094 176.167969 143.871094 177 C 143.871094 177.832031 144.199219 178.625 144.785156 179.214844 C 145.375 179.800781 146.167969 180.128906 147 180.128906 C 147.832031 180.128906 148.625 179.800781 149.214844 179.214844 C 149.800781 178.625 150.128906 177.832031 150.128906 177 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 183.128906 159 C 183.128906 158.167969 182.800781 157.375 182.214844 156.785156 C 181.625 156.199219 180.832031 155.871094 180 155.871094 C 179.167969 155.871094 178.375 156.199219 177.785156 156.785156 C 177.199219 157.375 176.871094 158.167969 176.871094 159 C 176.871094 159.832031 177.199219 160.625 177.785156 161.214844 C 178.375 161.800781 179.167969 162.128906 180 162.128906 C 180.832031 162.128906 181.625 161.800781 182.214844 161.214844 C 182.800781 160.625 183.128906 159.832031 183.128906 159 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 217.128906 138 C 217.128906 137.167969 216.800781 136.375 216.214844 135.785156 C 215.625 135.199219 214.832031 134.871094 214 134.871094 C 213.167969 134.871094 212.375 135.199219 211.785156 135.785156 C 211.199219 136.375 210.871094 137.167969 210.871094 138 C 210.871094 138.832031 211.199219 139.625 211.785156 140.214844 C 212.375 140.800781 213.167969 141.128906 214 141.128906 C 214.832031 141.128906 215.625 140.800781 216.214844 140.214844 C 216.800781 139.625 217.128906 138.832031 217.128906 138 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 251.128906 115 C 251.128906 114.167969 250.800781 113.375 250.214844 112.785156 C 249.625 112.199219 248.832031 111.871094 248 111.871094 C 247.167969 111.871094 246.375 112.199219 245.785156 112.785156 C 245.199219 113.375 244.871094 114.167969 244.871094 115 C 244.871094 115.832031 245.199219 116.625 245.785156 117.214844 C 246.375 117.800781 247.167969 118.128906 248 118.128906 C 248.832031 118.128906 249.625 117.800781 250.214844 117.214844 C 250.800781 116.625 251.128906 115.832031 251.128906 115 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 284.128906 91 C 284.128906 90.167969 283.800781 89.375 283.214844 88.785156 C 282.625 88.199219 281.832031 87.871094 281 87.871094 C 280.167969 87.871094 279.375 88.199219 278.785156 88.785156 C 278.199219 89.375 277.871094 90.167969 277.871094 91 C 277.871094 91.832031 278.199219 92.625 278.785156 93.214844 C 279.375 93.800781 280.167969 94.128906 281 94.128906 C 281.832031 94.128906 282.625 93.800781 283.214844 93.214844 C 283.800781 92.625 284.128906 91.832031 284.128906 91 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 318.128906 65 C 318.128906 64.167969 317.800781 63.375 317.214844 62.785156 C 316.625 62.199219 315.832031 61.871094 315 61.871094 C 314.167969 61.871094 313.375 62.199219 312.785156 62.785156 C 312.199219 63.375 311.871094 64.167969 311.871094 65 C 311.871094 65.832031 312.199219 66.625 312.785156 67.214844 C 313.375 67.800781 314.167969 68.128906 315 68.128906 C 315.832031 68.128906 316.625 67.800781 317.214844 67.214844 C 317.800781 66.625 318.128906 65.832031 318.128906 65 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 352.128906 38 C 352.128906 37.167969 351.800781 36.375 351.214844 35.785156 C 350.625 35.199219 349.832031 34.871094 349 34.871094 C 348.167969 34.871094 347.375 35.199219 346.785156 35.785156 C 346.199219 36.375 345.871094 37.167969 345.871094 38 C 345.871094 38.832031 346.199219 39.625 346.785156 40.214844 C 347.375 40.800781 348.167969 41.128906 349 41.128906 C 349.832031 41.128906 350.625 40.800781 351.214844 40.214844 C 351.800781 39.625 352.128906 38.832031 352.128906 38 Z "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 220.007812 L 33 220.007812 "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 220.007812 L 33 21 "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 21 L 355 21 "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 21 L 355 220.007812 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 90.226562 220.007812 L 90.226562 216.785156 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="84.725786" y="232.006944"/>
|
||||
<use xlink:href="#glyph0-2" x="90.28731" y="232.006944"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 201.996094 220.007812 L 201.996094 216.785156 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="193.49443" y="232.006944"/>
|
||||
<use xlink:href="#glyph0-2" x="199.055953" y="232.006944"/>
|
||||
<use xlink:href="#glyph0-2" x="204.617477" y="232.006944"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 313.761719 220.007812 L 313.761719 216.785156 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="302.763074" y="232.006944"/>
|
||||
<use xlink:href="#glyph0-2" x="308.324597" y="232.006944"/>
|
||||
<use xlink:href="#glyph0-2" x="313.88612" y="232.006944"/>
|
||||
<use xlink:href="#glyph0-2" x="319.447644" y="232.006944"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 45.75 220.007812 L 45.75 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 56.578125 220.007812 L 56.578125 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 65.429688 220.007812 L 65.429688 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 72.914062 220.007812 L 72.914062 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 79.394531 220.007812 L 79.394531 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 85.113281 220.007812 L 85.113281 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 123.871094 220.007812 L 123.871094 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 143.554688 220.007812 L 143.554688 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 157.515625 220.007812 L 157.515625 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 168.347656 220.007812 L 168.347656 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 177.199219 220.007812 L 177.199219 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 184.679688 220.007812 L 184.679688 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 191.164062 220.007812 L 191.164062 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 196.878906 220.007812 L 196.878906 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 235.640625 220.007812 L 235.640625 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 255.320312 220.007812 L 255.320312 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 269.285156 220.007812 L 269.285156 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 280.117188 220.007812 L 280.117188 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 288.96875 220.007812 L 288.96875 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 296.449219 220.007812 L 296.449219 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 302.929688 220.007812 L 302.929688 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 308.648438 220.007812 L 308.648438 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 347.410156 220.007812 L 347.410156 218.398438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 180.734375 L 36.21875 180.734375 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-3" x="24" y="183.235493"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 146.960938 L 36.21875 146.960938 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-4" x="24" y="149.45964"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 121.410156 L 36.21875 121.410156 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="19" y="123.909193"/>
|
||||
<use xlink:href="#glyph0-2" x="24.561523" y="123.909193"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 95.859375 L 36.21875 95.859375 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-3" x="19" y="98.358747"/>
|
||||
<use xlink:href="#glyph0-2" x="24.561523" y="98.358747"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 62.082031 L 36.21875 62.082031 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-4" x="19" y="64.582894"/>
|
||||
<use xlink:href="#glyph0-2" x="24.561523" y="64.582894"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 206.285156 L 34.609375 206.285156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 165.789062 L 34.609375 165.789062 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 155.183594 L 34.609375 155.183594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 140.238281 L 34.609375 140.238281 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 134.558594 L 34.609375 134.558594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 129.632812 L 34.609375 129.632812 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 125.292969 L 34.609375 125.292969 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 80.914062 L 34.609375 80.914062 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 70.308594 L 34.609375 70.308594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 33 36.53125 L 34.609375 36.53125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 90.226562 21 L 90.226562 24.21875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 201.996094 21 L 201.996094 24.21875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 313.761719 21 L 313.761719 24.21875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 45.75 21 L 45.75 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 56.578125 21 L 56.578125 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 65.429688 21 L 65.429688 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 72.914062 21 L 72.914062 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 79.394531 21 L 79.394531 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 85.113281 21 L 85.113281 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 123.871094 21 L 123.871094 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 143.554688 21 L 143.554688 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 157.515625 21 L 157.515625 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 168.347656 21 L 168.347656 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 177.199219 21 L 177.199219 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 184.679688 21 L 184.679688 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 191.164062 21 L 191.164062 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 196.878906 21 L 196.878906 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 235.640625 21 L 235.640625 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 255.320312 21 L 255.320312 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 269.285156 21 L 269.285156 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 280.117188 21 L 280.117188 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 288.96875 21 L 288.96875 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 296.449219 21 L 296.449219 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 302.929688 21 L 302.929688 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 308.648438 21 L 308.648438 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 347.410156 21 L 347.410156 22.609375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 180.734375 L 351.78125 180.734375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 146.960938 L 351.78125 146.960938 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 121.410156 L 351.78125 121.410156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 95.859375 L 351.78125 95.859375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 62.082031 L 351.78125 62.082031 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 206.285156 L 353.390625 206.285156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 165.789062 L 353.390625 165.789062 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 155.183594 L 353.390625 155.183594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 140.238281 L 353.390625 140.238281 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 134.558594 L 353.390625 134.558594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 129.632812 L 353.390625 129.632812 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 125.292969 L 353.390625 125.292969 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 80.914062 L 353.390625 80.914062 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 70.308594 L 353.390625 70.308594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 36.53125 L 353.390625 36.53125 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-5" x="172.5" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-6" x="178.608398" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-7" x="184.169922" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-8" x="189.731445" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-9" x="194.731445" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-10" x="197.509766" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-11" x="199.731445" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-7" x="205.292969" y="251.006944"/>
|
||||
<use xlink:href="#glyph0-12" x="210.854492" y="251.006944"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph1-1" x="9" y="140.003472"/>
|
||||
<use xlink:href="#glyph1-2" x="9" y="133.33355"/>
|
||||
<use xlink:href="#glyph1-3" x="9" y="127.772027"/>
|
||||
<use xlink:href="#glyph1-4" x="9" y="122.772027"/>
|
||||
<use xlink:href="#glyph1-5" x="9" y="117.210503"/>
|
||||
<use xlink:href="#glyph1-6" x="9" y="111.64898"/>
|
||||
<use xlink:href="#glyph1-7" x="9" y="106.087457"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph2-1" x="122" y="12"/>
|
||||
<use xlink:href="#glyph2-2" x="130.666016" y="12"/>
|
||||
<use xlink:href="#glyph2-3" x="137.339844" y="12"/>
|
||||
<use xlink:href="#glyph2-4" x="147.335938" y="12"/>
|
||||
<use xlink:href="#glyph2-5" x="154.009766" y="12"/>
|
||||
<use xlink:href="#glyph2-6" x="156.675781" y="12"/>
|
||||
<use xlink:href="#glyph2-7" x="159.341797" y="12"/>
|
||||
<use xlink:href="#glyph2-8" x="166.015625" y="12"/>
|
||||
<use xlink:href="#glyph2-5" x="169.349609" y="12"/>
|
||||
<use xlink:href="#glyph2-2" x="172.015625" y="12"/>
|
||||
<use xlink:href="#glyph2-9" x="178.689453" y="12"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph2-8" x="188" y="12"/>
|
||||
<use xlink:href="#glyph2-5" x="191.333984" y="12"/>
|
||||
<use xlink:href="#glyph2-3" x="194" y="12"/>
|
||||
<use xlink:href="#glyph2-10" x="203.996094" y="12"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph2-2" x="214" y="12"/>
|
||||
<use xlink:href="#glyph2-11" x="220.673828" y="12"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph2-3" x="227" y="12"/>
|
||||
<use xlink:href="#glyph2-2" x="236.996094" y="12"/>
|
||||
<use xlink:href="#glyph2-12" x="243.669922" y="12"/>
|
||||
<use xlink:href="#glyph2-13" x="250.34375" y="12"/>
|
||||
<use xlink:href="#glyph2-6" x="257.017578" y="12"/>
|
||||
<use xlink:href="#glyph2-10" x="259.683594" y="12"/>
|
||||
</g>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 382.148438 116 C 382.148438 115.164062 381.816406 114.363281 381.226562 113.773438 C 380.636719 113.183594 379.835938 112.851562 379 112.851562 C 378.164062 112.851562 377.363281 113.183594 376.773438 113.773438 C 376.183594 114.363281 375.851562 115.164062 375.851562 116 C 375.851562 116.835938 376.183594 117.636719 376.773438 118.226562 C 377.363281 118.816406 378.164062 119.148438 379 119.148438 C 379.835938 119.148438 380.636719 118.816406 381.226562 118.226562 C 381.816406 117.636719 382.148438 116.835938 382.148438 116 Z "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-1" x="391" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-2" x="399.670898" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-2" x="406.901367" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-3" x="414.131836" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-4" x="420.631836" y="120.28418"/>
|
||||
</g>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-5" x="424" y="120.28418"/>
|
||||
</g>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-6" x="428" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-7" x="436.670898" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-4" x="443.170898" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-8" x="446.783203" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-2" x="454.013672" y="120.28418"/>
|
||||
<use xlink:href="#glyph3-9" x="461.244141" y="120.28418"/>
|
||||
</g>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 382.148438 139 C 382.148438 138.164062 381.816406 137.363281 381.226562 136.773438 C 380.636719 136.183594 379.835938 135.851562 379 135.851562 C 378.164062 135.851562 377.363281 136.183594 376.773438 136.773438 C 376.183594 137.363281 375.851562 138.164062 375.851562 139 C 375.851562 139.835938 376.183594 140.636719 376.773438 141.226562 C 377.363281 141.816406 378.164062 142.148438 379 142.148438 C 379.835938 142.148438 380.636719 141.816406 381.226562 141.226562 C 381.816406 140.636719 382.148438 139.835938 382.148438 139 Z "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-10" x="391" y="143.28418"/>
|
||||
<use xlink:href="#glyph3-7" x="398.230469" y="143.28418"/>
|
||||
<use xlink:href="#glyph3-11" x="404.730469" y="143.28418"/>
|
||||
<use xlink:href="#glyph3-12" x="411.960938" y="143.28418"/>
|
||||
<use xlink:href="#glyph3-9" x="414.849609" y="143.28418"/>
|
||||
<use xlink:href="#glyph3-13" x="422.080078" y="143.28418"/>
|
||||
<use xlink:href="#glyph3-14" x="429.310547" y="143.28418"/>
|
||||
<use xlink:href="#glyph3-14" x="436.541016" y="143.28418"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 86 KiB |
BIN
thirdparty/pybind11/docs/pybind11_vs_boost_python2.png
vendored
Normal file
BIN
thirdparty/pybind11/docs/pybind11_vs_boost_python2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
427
thirdparty/pybind11/docs/pybind11_vs_boost_python2.svg
vendored
Normal file
427
thirdparty/pybind11/docs/pybind11_vs_boost_python2.svg
vendored
Normal file
@ -0,0 +1,427 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="468pt" height="246pt" viewBox="0 0 468 246" version="1.1">
|
||||
<defs>
|
||||
<g>
|
||||
<symbol overflow="visible" id="glyph0-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-1">
|
||||
<path style="stroke:none;" d="M 3.726562 0 L 2.847656 0 L 2.847656 -5.601562 C 2.636719 -5.398438 2.359375 -5.195312 2.015625 -4.996094 C 1.671875 -4.792969 1.363281 -4.640625 1.089844 -4.539062 L 1.089844 -5.390625 C 1.582031 -5.621094 2.011719 -5.902344 2.378906 -6.230469 C 2.746094 -6.558594 3.007812 -6.878906 3.160156 -7.1875 L 3.726562 -7.1875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-2">
|
||||
<path style="stroke:none;" d="M 0.414062 -3.53125 C 0.414062 -4.375 0.503906 -5.058594 0.675781 -5.574219 C 0.851562 -6.089844 1.109375 -6.488281 1.453125 -6.765625 C 1.796875 -7.046875 2.226562 -7.1875 2.75 -7.1875 C 3.132812 -7.1875 3.46875 -7.109375 3.757812 -6.957031 C 4.046875 -6.800781 4.289062 -6.578125 4.476562 -6.285156 C 4.664062 -5.996094 4.8125 -5.640625 4.921875 -5.222656 C 5.03125 -4.804688 5.082031 -4.238281 5.082031 -3.53125 C 5.082031 -2.691406 4.996094 -2.011719 4.824219 -1.496094 C 4.652344 -0.980469 4.394531 -0.582031 4.050781 -0.300781 C 3.707031 -0.0195312 3.273438 0.121094 2.75 0.121094 C 2.058594 0.121094 1.515625 -0.125 1.125 -0.621094 C 0.652344 -1.214844 0.414062 -2.1875 0.414062 -3.53125 Z M 1.320312 -3.53125 C 1.320312 -2.355469 1.457031 -1.574219 1.730469 -1.183594 C 2.007812 -0.796875 2.34375 -0.601562 2.75 -0.601562 C 3.152344 -0.601562 3.492188 -0.796875 3.765625 -1.1875 C 4.042969 -1.578125 4.179688 -2.359375 4.179688 -3.53125 C 4.179688 -4.710938 4.042969 -5.492188 3.765625 -5.878906 C 3.492188 -6.265625 3.148438 -6.460938 2.738281 -6.460938 C 2.335938 -6.460938 2.011719 -6.289062 1.773438 -5.945312 C 1.46875 -5.511719 1.320312 -4.707031 1.320312 -3.53125 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-3">
|
||||
<path style="stroke:none;" d="M 0.820312 0 L 0.820312 -7.15625 L 5.648438 -7.15625 L 5.648438 -6.3125 L 1.765625 -6.3125 L 1.765625 -4.097656 L 5.125 -4.097656 L 5.125 -3.25 L 1.765625 -3.25 L 1.765625 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-4">
|
||||
<path style="stroke:none;" d="M 4.058594 0 L 4.058594 -0.761719 C 3.65625 -0.175781 3.105469 0.117188 2.414062 0.117188 C 2.105469 0.117188 1.820312 0.0585938 1.554688 -0.0585938 C 1.289062 -0.175781 1.09375 -0.324219 0.964844 -0.5 C 0.835938 -0.679688 0.746094 -0.894531 0.695312 -1.152344 C 0.65625 -1.324219 0.640625 -1.597656 0.640625 -1.972656 L 0.640625 -5.1875 L 1.519531 -5.1875 L 1.519531 -2.308594 C 1.519531 -1.851562 1.535156 -1.542969 1.570312 -1.382812 C 1.625 -1.152344 1.746094 -0.96875 1.921875 -0.835938 C 2.101562 -0.703125 2.324219 -0.640625 2.585938 -0.640625 C 2.851562 -0.640625 3.097656 -0.707031 3.328125 -0.84375 C 3.5625 -0.976562 3.726562 -1.160156 3.820312 -1.394531 C 3.917969 -1.625 3.964844 -1.964844 3.964844 -2.40625 L 3.964844 -5.1875 L 4.84375 -5.1875 L 4.84375 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-5">
|
||||
<path style="stroke:none;" d="M 0.660156 0 L 0.660156 -5.1875 L 1.449219 -5.1875 L 1.449219 -4.449219 C 1.832031 -5.019531 2.382812 -5.304688 3.101562 -5.304688 C 3.414062 -5.304688 3.699219 -5.246094 3.960938 -5.132812 C 4.222656 -5.023438 4.421875 -4.875 4.550781 -4.691406 C 4.679688 -4.507812 4.773438 -4.292969 4.824219 -4.042969 C 4.855469 -3.878906 4.875 -3.59375 4.875 -3.1875 L 4.875 0 L 3.992188 0 L 3.992188 -3.15625 C 3.992188 -3.511719 3.960938 -3.78125 3.890625 -3.957031 C 3.824219 -4.132812 3.703125 -4.277344 3.527344 -4.382812 C 3.351562 -4.488281 3.148438 -4.539062 2.914062 -4.539062 C 2.539062 -4.539062 2.21875 -4.421875 1.945312 -4.183594 C 1.671875 -3.945312 1.539062 -3.496094 1.539062 -2.832031 L 1.539062 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-6">
|
||||
<path style="stroke:none;" d="M 4.042969 -1.898438 L 4.90625 -1.789062 C 4.8125 -1.191406 4.570312 -0.726562 4.183594 -0.386719 C 3.792969 -0.0507812 3.316406 0.117188 2.75 0.117188 C 2.039062 0.117188 1.46875 -0.113281 1.039062 -0.578125 C 0.605469 -1.042969 0.390625 -1.707031 0.390625 -2.574219 C 0.390625 -3.132812 0.484375 -3.625 0.667969 -4.042969 C 0.855469 -4.460938 1.136719 -4.777344 1.515625 -4.988281 C 1.894531 -5.199219 2.308594 -5.304688 2.753906 -5.304688 C 3.316406 -5.304688 3.777344 -5.160156 4.136719 -4.875 C 4.492188 -4.589844 4.722656 -4.1875 4.824219 -3.664062 L 3.96875 -3.53125 C 3.886719 -3.878906 3.746094 -4.140625 3.539062 -4.316406 C 3.332031 -4.492188 3.082031 -4.578125 2.789062 -4.578125 C 2.34375 -4.578125 1.984375 -4.421875 1.710938 -4.105469 C 1.433594 -3.789062 1.292969 -3.285156 1.292969 -2.597656 C 1.292969 -1.902344 1.425781 -1.394531 1.695312 -1.078125 C 1.960938 -0.761719 2.308594 -0.605469 2.738281 -0.605469 C 3.085938 -0.605469 3.371094 -0.710938 3.601562 -0.921875 C 3.835938 -1.132812 3.980469 -1.460938 4.042969 -1.898438 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-7">
|
||||
<path style="stroke:none;" d="M 2.578125 -0.785156 L 2.703125 -0.0078125 C 2.457031 0.0429688 2.234375 0.0703125 2.039062 0.0703125 C 1.722656 0.0703125 1.476562 0.0195312 1.296875 -0.0820312 C 1.121094 -0.183594 1 -0.316406 0.929688 -0.480469 C 0.855469 -0.644531 0.820312 -0.992188 0.820312 -1.519531 L 0.820312 -4.5 L 0.175781 -4.5 L 0.175781 -5.1875 L 0.820312 -5.1875 L 0.820312 -6.46875 L 1.695312 -6.996094 L 1.695312 -5.1875 L 2.578125 -5.1875 L 2.578125 -4.5 L 1.695312 -4.5 L 1.695312 -1.46875 C 1.695312 -1.21875 1.710938 -1.058594 1.742188 -0.984375 C 1.773438 -0.914062 1.820312 -0.859375 1.890625 -0.816406 C 1.960938 -0.773438 2.0625 -0.75 2.191406 -0.75 C 2.289062 -0.75 2.417969 -0.761719 2.578125 -0.785156 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-8">
|
||||
<path style="stroke:none;" d="M 0.664062 -6.148438 L 0.664062 -7.15625 L 1.542969 -7.15625 L 1.542969 -6.148438 Z M 0.664062 0 L 0.664062 -5.1875 L 1.542969 -5.1875 L 1.542969 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-9">
|
||||
<path style="stroke:none;" d="M 0.332031 -2.59375 C 0.332031 -3.554688 0.597656 -4.265625 1.132812 -4.726562 C 1.578125 -5.109375 2.121094 -5.304688 2.765625 -5.304688 C 3.476562 -5.304688 4.058594 -5.070312 4.511719 -4.601562 C 4.964844 -4.132812 5.191406 -3.488281 5.191406 -2.664062 C 5.191406 -2 5.089844 -1.472656 4.890625 -1.089844 C 4.691406 -0.707031 4.398438 -0.410156 4.015625 -0.199219 C 3.632812 0.0117188 3.214844 0.117188 2.765625 0.117188 C 2.039062 0.117188 1.449219 -0.117188 1.003906 -0.582031 C 0.554688 -1.046875 0.332031 -1.71875 0.332031 -2.59375 Z M 1.234375 -2.59375 C 1.234375 -1.929688 1.378906 -1.429688 1.671875 -1.101562 C 1.960938 -0.769531 2.324219 -0.605469 2.765625 -0.605469 C 3.199219 -0.605469 3.5625 -0.773438 3.851562 -1.101562 C 4.140625 -1.433594 4.289062 -1.941406 4.289062 -2.621094 C 4.289062 -3.261719 4.140625 -3.75 3.851562 -4.078125 C 3.558594 -4.410156 3.195312 -4.574219 2.765625 -4.574219 C 2.324219 -4.574219 1.960938 -4.410156 1.671875 -4.082031 C 1.382812 -3.753906 1.234375 -3.257812 1.234375 -2.59375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph0-10">
|
||||
<path style="stroke:none;" d="M 0.308594 -1.546875 L 1.175781 -1.683594 C 1.226562 -1.335938 1.363281 -1.070312 1.585938 -0.882812 C 1.808594 -0.699219 2.117188 -0.605469 2.519531 -0.605469 C 2.921875 -0.605469 3.222656 -0.6875 3.417969 -0.851562 C 3.613281 -1.015625 3.710938 -1.210938 3.710938 -1.429688 C 3.710938 -1.628906 3.625 -1.785156 3.453125 -1.898438 C 3.332031 -1.976562 3.03125 -2.078125 2.554688 -2.195312 C 1.910156 -2.359375 1.460938 -2.5 1.214844 -2.621094 C 0.964844 -2.738281 0.777344 -2.902344 0.648438 -3.113281 C 0.519531 -3.324219 0.453125 -3.554688 0.453125 -3.808594 C 0.453125 -4.039062 0.507812 -4.253906 0.613281 -4.449219 C 0.71875 -4.648438 0.863281 -4.8125 1.046875 -4.941406 C 1.183594 -5.042969 1.367188 -5.128906 1.605469 -5.199219 C 1.839844 -5.269531 2.09375 -5.304688 2.363281 -5.304688 C 2.769531 -5.304688 3.128906 -5.242188 3.433594 -5.125 C 3.742188 -5.007812 3.96875 -4.851562 4.117188 -4.652344 C 4.261719 -4.453125 4.363281 -4.183594 4.417969 -3.847656 L 3.558594 -3.730469 C 3.519531 -3.996094 3.40625 -4.207031 3.21875 -4.355469 C 3.03125 -4.503906 2.769531 -4.578125 2.425781 -4.578125 C 2.023438 -4.578125 1.734375 -4.511719 1.5625 -4.378906 C 1.390625 -4.246094 1.304688 -4.089844 1.304688 -3.910156 C 1.304688 -3.796875 1.339844 -3.695312 1.410156 -3.601562 C 1.484375 -3.507812 1.59375 -3.429688 1.75 -3.367188 C 1.835938 -3.335938 2.09375 -3.261719 2.523438 -3.144531 C 3.144531 -2.976562 3.578125 -2.84375 3.824219 -2.738281 C 4.070312 -2.632812 4.265625 -2.476562 4.40625 -2.273438 C 4.546875 -2.074219 4.613281 -1.824219 4.613281 -1.523438 C 4.613281 -1.230469 4.527344 -0.953125 4.359375 -0.695312 C 4.1875 -0.4375 3.941406 -0.238281 3.617188 -0.09375 C 3.296875 0.046875 2.929688 0.117188 2.523438 0.117188 C 1.851562 0.117188 1.335938 -0.0234375 0.984375 -0.304688 C 0.632812 -0.582031 0.40625 -0.996094 0.308594 -1.546875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-1">
|
||||
<path style="stroke:none;" d="M 0.375 -1.6875 L 1.203125 -1.757812 C 1.265625 -1.351562 1.410156 -1.050781 1.632812 -0.847656 C 1.855469 -0.644531 2.125 -0.539062 2.445312 -0.539062 C 2.824219 -0.539062 3.148438 -0.683594 3.410156 -0.972656 C 3.671875 -1.257812 3.804688 -1.640625 3.804688 -2.113281 C 3.804688 -2.566406 3.679688 -2.921875 3.425781 -3.179688 C 3.171875 -3.441406 2.839844 -3.574219 2.429688 -3.574219 C 2.175781 -3.574219 1.945312 -3.515625 1.742188 -3.398438 C 1.535156 -3.28125 1.375 -3.132812 1.257812 -2.949219 L 0.515625 -3.046875 L 1.136719 -6.355469 L 4.34375 -6.355469 L 4.34375 -5.597656 L 1.769531 -5.597656 L 1.421875 -3.867188 C 1.808594 -4.136719 2.214844 -4.273438 2.640625 -4.273438 C 3.203125 -4.273438 3.679688 -4.078125 4.066406 -3.6875 C 4.453125 -3.296875 4.644531 -2.796875 4.644531 -2.183594 C 4.644531 -1.601562 4.476562 -1.097656 4.136719 -0.671875 C 3.722656 -0.152344 3.15625 0.109375 2.445312 0.109375 C 1.859375 0.109375 1.378906 -0.0546875 1.007812 -0.382812 C 0.636719 -0.710938 0.425781 -1.144531 0.375 -1.6875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-2">
|
||||
<path style="stroke:none;" d="M 4.476562 -4.863281 L 3.691406 -4.804688 C 3.621094 -5.113281 3.523438 -5.339844 3.390625 -5.480469 C 3.179688 -5.707031 2.914062 -5.820312 2.601562 -5.820312 C 2.351562 -5.820312 2.128906 -5.75 1.9375 -5.609375 C 1.6875 -5.425781 1.492188 -5.160156 1.347656 -4.8125 C 1.203125 -4.464844 1.132812 -3.96875 1.125 -3.320312 C 1.316406 -3.613281 1.546875 -3.828125 1.824219 -3.96875 C 2.097656 -4.109375 2.386719 -4.179688 2.6875 -4.179688 C 3.214844 -4.179688 3.664062 -3.984375 4.035156 -3.597656 C 4.40625 -3.210938 4.59375 -2.707031 4.59375 -2.09375 C 4.59375 -1.6875 4.503906 -1.3125 4.332031 -0.964844 C 4.15625 -0.617188 3.917969 -0.351562 3.613281 -0.167969 C 3.308594 0.015625 2.960938 0.109375 2.574219 0.109375 C 1.914062 0.109375 1.378906 -0.132812 0.960938 -0.617188 C 0.546875 -1.101562 0.339844 -1.902344 0.339844 -3.015625 C 0.339844 -4.261719 0.570312 -5.164062 1.027344 -5.730469 C 1.429688 -6.222656 1.96875 -6.46875 2.648438 -6.46875 C 3.15625 -6.46875 3.570312 -6.328125 3.894531 -6.042969 C 4.21875 -5.757812 4.414062 -5.367188 4.476562 -4.863281 Z M 1.25 -2.085938 C 1.25 -1.8125 1.304688 -1.554688 1.421875 -1.304688 C 1.539062 -1.054688 1.699219 -0.867188 1.90625 -0.734375 C 2.113281 -0.605469 2.332031 -0.539062 2.5625 -0.539062 C 2.894531 -0.539062 3.183594 -0.675781 3.421875 -0.945312 C 3.664062 -1.214844 3.785156 -1.582031 3.785156 -2.042969 C 3.785156 -2.488281 3.664062 -2.839844 3.429688 -3.097656 C 3.191406 -3.351562 2.890625 -3.480469 2.53125 -3.480469 C 2.171875 -3.480469 1.871094 -3.351562 1.621094 -3.097656 C 1.371094 -2.839844 1.25 -2.503906 1.25 -2.085938 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph1-3">
|
||||
<path style="stroke:none;" d="M 0.425781 -5.597656 L 0.425781 -6.359375 L 4.597656 -6.359375 L 4.597656 -5.742188 C 4.1875 -5.304688 3.78125 -4.726562 3.378906 -4.003906 C 2.976562 -3.28125 2.664062 -2.535156 2.445312 -1.769531 C 2.285156 -1.230469 2.183594 -0.640625 2.140625 0 L 1.328125 0 C 1.335938 -0.507812 1.4375 -1.117188 1.625 -1.835938 C 1.816406 -2.554688 2.089844 -3.246094 2.445312 -3.914062 C 2.800781 -4.578125 3.179688 -5.140625 3.582031 -5.597656 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-1">
|
||||
<path style="stroke:none;" d="M 0 -0.734375 L -7.15625 -0.734375 L -7.15625 -3.417969 C -7.15625 -3.964844 -7.085938 -4.402344 -6.941406 -4.734375 C -6.796875 -5.0625 -6.574219 -5.324219 -6.273438 -5.511719 C -5.972656 -5.699219 -5.65625 -5.789062 -5.328125 -5.789062 C -5.023438 -5.789062 -4.734375 -5.707031 -4.460938 -5.542969 C -4.191406 -5.375 -3.976562 -5.125 -3.808594 -4.789062 C -3.679688 -5.222656 -3.464844 -5.554688 -3.160156 -5.789062 C -2.851562 -6.023438 -2.492188 -6.136719 -2.074219 -6.136719 C -1.738281 -6.136719 -1.429688 -6.066406 -1.140625 -5.925781 C -0.851562 -5.785156 -0.628906 -5.609375 -0.472656 -5.398438 C -0.316406 -5.191406 -0.199219 -4.929688 -0.121094 -4.617188 C -0.0390625 -4.304688 0 -3.917969 0 -3.460938 Z M -4.148438 -1.679688 L -4.148438 -3.226562 C -4.148438 -3.648438 -4.179688 -3.949219 -4.234375 -4.132812 C -4.304688 -4.371094 -4.421875 -4.554688 -4.589844 -4.675781 C -4.757812 -4.796875 -4.964844 -4.859375 -5.214844 -4.859375 C -5.453125 -4.859375 -5.660156 -4.800781 -5.84375 -4.6875 C -6.023438 -4.574219 -6.148438 -4.410156 -6.214844 -4.199219 C -6.28125 -3.988281 -6.3125 -3.625 -6.3125 -3.109375 L -6.3125 -1.679688 Z M -0.84375 -1.679688 L -0.84375 -3.460938 C -0.84375 -3.765625 -0.855469 -3.984375 -0.878906 -4.105469 C -0.917969 -4.324219 -0.984375 -4.507812 -1.074219 -4.652344 C -1.164062 -4.800781 -1.296875 -4.921875 -1.472656 -5.015625 C -1.648438 -5.109375 -1.847656 -5.15625 -2.074219 -5.15625 C -2.34375 -5.15625 -2.574219 -5.085938 -2.769531 -4.953125 C -2.96875 -4.816406 -3.105469 -4.625 -3.1875 -4.382812 C -3.265625 -4.140625 -3.304688 -3.789062 -3.304688 -3.335938 L -3.304688 -1.679688 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-2">
|
||||
<path style="stroke:none;" d="M 1.996094 -0.621094 L 1.171875 -0.523438 C 1.222656 -0.714844 1.25 -0.882812 1.25 -1.023438 C 1.25 -1.21875 1.21875 -1.375 1.152344 -1.492188 C 1.085938 -1.609375 0.996094 -1.707031 0.878906 -1.78125 C 0.789062 -1.835938 0.574219 -1.925781 0.226562 -2.050781 C 0.175781 -2.066406 0.105469 -2.09375 0.0078125 -2.128906 L -5.1875 -0.160156 L -5.1875 -1.109375 L -2.183594 -2.1875 C -1.800781 -2.328125 -1.402344 -2.453125 -0.980469 -2.5625 C -1.382812 -2.664062 -1.777344 -2.785156 -2.164062 -2.925781 L -5.1875 -4.03125 L -5.1875 -4.914062 L 0.0859375 -2.9375 C 0.65625 -2.726562 1.050781 -2.5625 1.265625 -2.445312 C 1.554688 -2.289062 1.765625 -2.109375 1.902344 -1.910156 C 2.039062 -1.707031 2.105469 -1.464844 2.105469 -1.1875 C 2.105469 -1.015625 2.070312 -0.828125 1.996094 -0.621094 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-3">
|
||||
<path style="stroke:none;" d="M -0.785156 -2.578125 L -0.0078125 -2.703125 C 0.0429688 -2.457031 0.0703125 -2.234375 0.0703125 -2.039062 C 0.0703125 -1.722656 0.0195312 -1.476562 -0.0820312 -1.296875 C -0.183594 -1.121094 -0.316406 -1 -0.480469 -0.929688 C -0.644531 -0.855469 -0.992188 -0.820312 -1.519531 -0.820312 L -4.5 -0.820312 L -4.5 -0.175781 L -5.1875 -0.175781 L -5.1875 -0.820312 L -6.46875 -0.820312 L -6.996094 -1.695312 L -5.1875 -1.695312 L -5.1875 -2.578125 L -4.5 -2.578125 L -4.5 -1.695312 L -1.46875 -1.695312 C -1.21875 -1.695312 -1.058594 -1.710938 -0.984375 -1.742188 C -0.914062 -1.773438 -0.859375 -1.820312 -0.816406 -1.890625 C -0.773438 -1.960938 -0.75 -2.0625 -0.75 -2.191406 C -0.75 -2.289062 -0.761719 -2.417969 -0.785156 -2.578125 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-4">
|
||||
<path style="stroke:none;" d="M -1.671875 -4.210938 L -1.558594 -5.117188 C -1.027344 -4.972656 -0.617188 -4.707031 -0.320312 -4.320312 C -0.0273438 -3.933594 0.117188 -3.4375 0.117188 -2.835938 C 0.117188 -2.078125 -0.117188 -1.476562 -0.582031 -1.03125 C -1.050781 -0.585938 -1.707031 -0.367188 -2.546875 -0.367188 C -3.421875 -0.367188 -4.097656 -0.589844 -4.578125 -1.039062 C -5.0625 -1.488281 -5.304688 -2.070312 -5.304688 -2.789062 C -5.304688 -3.480469 -5.066406 -4.046875 -4.59375 -4.488281 C -4.121094 -4.925781 -3.457031 -5.148438 -2.601562 -5.148438 C -2.550781 -5.148438 -2.472656 -5.144531 -2.367188 -5.140625 L -2.367188 -1.273438 C -1.796875 -1.304688 -1.363281 -1.46875 -1.058594 -1.757812 C -0.757812 -2.046875 -0.605469 -2.410156 -0.605469 -2.84375 C -0.605469 -3.164062 -0.691406 -3.4375 -0.859375 -3.667969 C -1.027344 -3.894531 -1.296875 -4.074219 -1.671875 -4.210938 Z M -3.089844 -1.324219 L -3.089844 -4.21875 C -3.527344 -4.179688 -3.855469 -4.070312 -4.070312 -3.886719 C -4.410156 -3.605469 -4.578125 -3.242188 -4.578125 -2.796875 C -4.578125 -2.394531 -4.445312 -2.054688 -4.175781 -1.78125 C -3.90625 -1.503906 -3.542969 -1.351562 -3.089844 -1.324219 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph2-5">
|
||||
<path style="stroke:none;" d="M -1.546875 -0.308594 L -1.683594 -1.175781 C -1.335938 -1.226562 -1.070312 -1.363281 -0.882812 -1.585938 C -0.699219 -1.808594 -0.605469 -2.117188 -0.605469 -2.519531 C -0.605469 -2.921875 -0.6875 -3.222656 -0.851562 -3.417969 C -1.015625 -3.613281 -1.210938 -3.710938 -1.429688 -3.710938 C -1.628906 -3.710938 -1.785156 -3.625 -1.898438 -3.453125 C -1.976562 -3.332031 -2.078125 -3.03125 -2.195312 -2.554688 C -2.359375 -1.910156 -2.5 -1.460938 -2.621094 -1.214844 C -2.738281 -0.964844 -2.902344 -0.777344 -3.113281 -0.648438 C -3.324219 -0.519531 -3.554688 -0.453125 -3.808594 -0.453125 C -4.039062 -0.453125 -4.253906 -0.507812 -4.449219 -0.613281 C -4.648438 -0.71875 -4.8125 -0.863281 -4.941406 -1.046875 C -5.042969 -1.183594 -5.128906 -1.367188 -5.199219 -1.605469 C -5.269531 -1.839844 -5.304688 -2.09375 -5.304688 -2.363281 C -5.304688 -2.769531 -5.242188 -3.128906 -5.125 -3.433594 C -5.007812 -3.742188 -4.851562 -3.96875 -4.652344 -4.117188 C -4.453125 -4.261719 -4.183594 -4.363281 -3.847656 -4.417969 L -3.730469 -3.558594 C -3.996094 -3.519531 -4.207031 -3.40625 -4.355469 -3.21875 C -4.503906 -3.03125 -4.578125 -2.769531 -4.578125 -2.425781 C -4.578125 -2.023438 -4.511719 -1.734375 -4.378906 -1.5625 C -4.246094 -1.390625 -4.089844 -1.304688 -3.910156 -1.304688 C -3.796875 -1.304688 -3.695312 -1.339844 -3.601562 -1.410156 C -3.507812 -1.484375 -3.429688 -1.59375 -3.367188 -1.75 C -3.335938 -1.835938 -3.261719 -2.09375 -3.144531 -2.523438 C -2.976562 -3.144531 -2.84375 -3.578125 -2.738281 -3.824219 C -2.632812 -4.070312 -2.476562 -4.265625 -2.273438 -4.40625 C -2.074219 -4.546875 -1.824219 -4.613281 -1.523438 -4.613281 C -1.230469 -4.613281 -0.953125 -4.527344 -0.695312 -4.359375 C -0.4375 -4.1875 -0.238281 -3.941406 -0.09375 -3.617188 C 0.046875 -3.296875 0.117188 -2.929688 0.117188 -2.523438 C 0.117188 -1.851562 -0.0234375 -1.335938 -0.304688 -0.984375 C -0.582031 -0.632812 -0.996094 -0.40625 -1.546875 -0.308594 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-1">
|
||||
<path style="stroke:none;" d="M 0.984375 0 L 0.984375 -8.589844 L 6.78125 -8.589844 L 6.78125 -7.578125 L 2.121094 -7.578125 L 2.121094 -4.914062 L 6.152344 -4.914062 L 6.152344 -3.902344 L 2.121094 -3.902344 L 2.121094 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-2">
|
||||
<path style="stroke:none;" d="M 0.796875 -7.375 L 0.796875 -8.589844 L 1.851562 -8.589844 L 1.851562 -7.375 Z M 0.796875 0 L 0.796875 -6.222656 L 1.851562 -6.222656 L 1.851562 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-3">
|
||||
<path style="stroke:none;" d="M 0.765625 0 L 0.765625 -8.589844 L 1.820312 -8.589844 L 1.820312 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-4">
|
||||
<path style="stroke:none;" d="M 5.050781 -2.003906 L 6.140625 -1.867188 C 5.96875 -1.230469 5.648438 -0.738281 5.1875 -0.386719 C 4.722656 -0.0351562 4.125 0.140625 3.40625 0.140625 C 2.496094 0.140625 1.773438 -0.140625 1.238281 -0.699219 C 0.707031 -1.261719 0.4375 -2.046875 0.4375 -3.058594 C 0.4375 -4.105469 0.710938 -4.917969 1.25 -5.496094 C 1.789062 -6.074219 2.484375 -6.363281 3.34375 -6.363281 C 4.175781 -6.363281 4.859375 -6.078125 5.382812 -5.515625 C 5.910156 -4.949219 6.175781 -4.148438 6.175781 -3.125 C 6.175781 -3.0625 6.171875 -2.96875 6.171875 -2.84375 L 1.53125 -2.84375 C 1.570312 -2.160156 1.761719 -1.632812 2.109375 -1.273438 C 2.457031 -0.910156 2.890625 -0.726562 3.410156 -0.726562 C 3.796875 -0.726562 4.125 -0.828125 4.398438 -1.03125 C 4.671875 -1.234375 4.890625 -1.558594 5.050781 -2.003906 Z M 1.585938 -3.710938 L 5.0625 -3.710938 C 5.015625 -4.234375 4.882812 -4.625 4.664062 -4.886719 C 4.328125 -5.292969 3.890625 -5.496094 3.359375 -5.496094 C 2.875 -5.496094 2.464844 -5.335938 2.136719 -5.007812 C 1.804688 -4.683594 1.625 -4.25 1.585938 -3.710938 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-5">
|
||||
<path style="stroke:none;" d="M 0.367188 -1.859375 L 1.414062 -2.023438 C 1.472656 -1.605469 1.632812 -1.28125 1.902344 -1.0625 C 2.167969 -0.839844 2.542969 -0.726562 3.023438 -0.726562 C 3.507812 -0.726562 3.867188 -0.824219 4.101562 -1.023438 C 4.335938 -1.21875 4.453125 -1.453125 4.453125 -1.71875 C 4.453125 -1.957031 4.351562 -2.140625 4.140625 -2.28125 C 3.996094 -2.375 3.640625 -2.492188 3.0625 -2.636719 C 2.289062 -2.832031 1.753906 -3 1.457031 -3.144531 C 1.15625 -3.285156 0.929688 -3.484375 0.777344 -3.734375 C 0.621094 -3.988281 0.546875 -4.265625 0.546875 -4.570312 C 0.546875 -4.847656 0.609375 -5.105469 0.734375 -5.339844 C 0.863281 -5.578125 1.035156 -5.773438 1.253906 -5.929688 C 1.417969 -6.050781 1.640625 -6.152344 1.925781 -6.238281 C 2.207031 -6.320312 2.511719 -6.363281 2.835938 -6.363281 C 3.324219 -6.363281 3.753906 -6.292969 4.121094 -6.152344 C 4.492188 -6.011719 4.765625 -5.820312 4.9375 -5.582031 C 5.113281 -5.339844 5.234375 -5.019531 5.304688 -4.617188 L 4.273438 -4.476562 C 4.226562 -4.796875 4.089844 -5.046875 3.863281 -5.226562 C 3.640625 -5.40625 3.320312 -5.496094 2.914062 -5.496094 C 2.429688 -5.496094 2.082031 -5.414062 1.875 -5.257812 C 1.667969 -5.097656 1.5625 -4.90625 1.5625 -4.695312 C 1.5625 -4.558594 1.609375 -4.433594 1.695312 -4.324219 C 1.78125 -4.210938 1.914062 -4.117188 2.097656 -4.042969 C 2.203125 -4.003906 2.515625 -3.914062 3.03125 -3.773438 C 3.777344 -3.574219 4.296875 -3.410156 4.589844 -3.285156 C 4.886719 -3.15625 5.117188 -2.972656 5.285156 -2.730469 C 5.453125 -2.488281 5.539062 -2.1875 5.539062 -1.828125 C 5.539062 -1.476562 5.433594 -1.144531 5.230469 -0.835938 C 5.023438 -0.523438 4.726562 -0.285156 4.34375 -0.113281 C 3.957031 0.0546875 3.515625 0.140625 3.03125 0.140625 C 2.222656 0.140625 1.605469 -0.0273438 1.179688 -0.363281 C 0.757812 -0.699219 0.484375 -1.195312 0.367188 -1.859375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-6">
|
||||
<path style="stroke:none;" d="M 0.234375 0 L 0.234375 -0.855469 L 4.195312 -5.402344 C 3.746094 -5.378906 3.351562 -5.367188 3.007812 -5.367188 L 0.46875 -5.367188 L 0.46875 -6.222656 L 5.554688 -6.222656 L 5.554688 -5.523438 L 2.1875 -1.578125 L 1.535156 -0.855469 C 2.007812 -0.890625 2.453125 -0.90625 2.867188 -0.90625 L 5.742188 -0.90625 L 5.742188 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-7">
|
||||
<path style="stroke:none;" d="M 0.398438 -3.109375 C 0.398438 -4.261719 0.71875 -5.117188 1.359375 -5.671875 C 1.894531 -6.132812 2.546875 -6.363281 3.316406 -6.363281 C 4.171875 -6.363281 4.871094 -6.082031 5.414062 -5.523438 C 5.957031 -4.960938 6.226562 -4.1875 6.226562 -3.199219 C 6.226562 -2.398438 6.109375 -1.769531 5.867188 -1.308594 C 5.628906 -0.851562 5.277344 -0.492188 4.820312 -0.242188 C 4.359375 0.0117188 3.859375 0.140625 3.316406 0.140625 C 2.445312 0.140625 1.742188 -0.140625 1.203125 -0.695312 C 0.667969 -1.253906 0.398438 -2.0625 0.398438 -3.109375 Z M 1.484375 -3.109375 C 1.484375 -2.3125 1.65625 -1.71875 2.003906 -1.320312 C 2.351562 -0.925781 2.789062 -0.726562 3.316406 -0.726562 C 3.839844 -0.726562 4.273438 -0.925781 4.625 -1.324219 C 4.972656 -1.722656 5.144531 -2.328125 5.144531 -3.148438 C 5.144531 -3.917969 4.96875 -4.5 4.621094 -4.894531 C 4.269531 -5.292969 3.835938 -5.492188 3.316406 -5.492188 C 2.789062 -5.492188 2.351562 -5.292969 2.003906 -4.898438 C 1.65625 -4.503906 1.484375 -3.90625 1.484375 -3.109375 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-8">
|
||||
<path style="stroke:none;" d="M 1.042969 0 L 1.042969 -5.402344 L 0.109375 -5.402344 L 0.109375 -6.222656 L 1.042969 -6.222656 L 1.042969 -6.882812 C 1.042969 -7.300781 1.078125 -7.613281 1.15625 -7.816406 C 1.257812 -8.089844 1.433594 -8.3125 1.691406 -8.480469 C 1.945312 -8.652344 2.304688 -8.734375 2.765625 -8.734375 C 3.0625 -8.734375 3.390625 -8.703125 3.75 -8.632812 L 3.59375 -7.710938 C 3.375 -7.75 3.164062 -7.769531 2.96875 -7.769531 C 2.648438 -7.769531 2.421875 -7.703125 2.289062 -7.5625 C 2.15625 -7.425781 2.09375 -7.171875 2.09375 -6.796875 L 2.09375 -6.222656 L 3.304688 -6.222656 L 3.304688 -5.402344 L 2.09375 -5.402344 L 2.09375 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-9">
|
||||
<path style="stroke:none;" d="M 0.789062 0 L 0.789062 -6.222656 L 1.734375 -6.222656 L 1.734375 -5.351562 C 1.929688 -5.65625 2.1875 -5.898438 2.515625 -6.085938 C 2.839844 -6.269531 3.207031 -6.363281 3.621094 -6.363281 C 4.082031 -6.363281 4.460938 -6.265625 4.753906 -6.078125 C 5.050781 -5.886719 5.257812 -5.617188 5.378906 -5.273438 C 5.871094 -6 6.511719 -6.363281 7.300781 -6.363281 C 7.917969 -6.363281 8.390625 -6.191406 8.726562 -5.851562 C 9.058594 -5.507812 9.222656 -4.984375 9.222656 -4.273438 L 9.222656 0 L 8.171875 0 L 8.171875 -3.921875 C 8.171875 -4.34375 8.140625 -4.644531 8.070312 -4.832031 C 8.003906 -5.015625 7.878906 -5.164062 7.699219 -5.28125 C 7.519531 -5.394531 7.308594 -5.449219 7.066406 -5.449219 C 6.628906 -5.449219 6.265625 -5.304688 5.976562 -5.011719 C 5.6875 -4.722656 5.542969 -4.257812 5.542969 -3.617188 L 5.542969 0 L 4.488281 0 L 4.488281 -4.042969 C 4.488281 -4.511719 4.402344 -4.863281 4.230469 -5.097656 C 4.058594 -5.332031 3.777344 -5.449219 3.386719 -5.449219 C 3.089844 -5.449219 2.816406 -5.371094 2.5625 -5.214844 C 2.3125 -5.058594 2.128906 -4.828125 2.015625 -4.53125 C 1.902344 -4.230469 1.84375 -3.796875 1.84375 -3.226562 L 1.84375 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-10">
|
||||
<path style="stroke:none;" d="M 4.828125 0 L 4.828125 -0.785156 C 4.433594 -0.167969 3.851562 0.140625 3.085938 0.140625 C 2.589844 0.140625 2.136719 0.00390625 1.71875 -0.269531 C 1.304688 -0.542969 0.980469 -0.925781 0.753906 -1.414062 C 0.523438 -1.90625 0.410156 -2.46875 0.410156 -3.105469 C 0.410156 -3.726562 0.515625 -4.289062 0.71875 -4.796875 C 0.925781 -5.300781 1.238281 -5.6875 1.652344 -5.960938 C 2.066406 -6.230469 2.53125 -6.363281 3.039062 -6.363281 C 3.414062 -6.363281 3.75 -6.285156 4.042969 -6.125 C 4.335938 -5.96875 4.574219 -5.761719 4.757812 -5.507812 L 4.757812 -8.589844 L 5.804688 -8.589844 L 5.804688 0 Z M 1.492188 -3.105469 C 1.492188 -2.308594 1.664062 -1.710938 2 -1.320312 C 2.335938 -0.925781 2.730469 -0.726562 3.1875 -0.726562 C 3.648438 -0.726562 4.039062 -0.914062 4.363281 -1.292969 C 4.683594 -1.667969 4.84375 -2.242188 4.84375 -3.015625 C 4.84375 -3.867188 4.679688 -4.492188 4.351562 -4.890625 C 4.023438 -5.289062 3.621094 -5.492188 3.140625 -5.492188 C 2.671875 -5.492188 2.28125 -5.296875 1.964844 -4.914062 C 1.652344 -4.53125 1.492188 -3.929688 1.492188 -3.105469 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph3-11">
|
||||
<path style="stroke:none;" d="M 4.867188 0 L 4.867188 -0.914062 C 4.382812 -0.210938 3.726562 0.140625 2.894531 0.140625 C 2.527344 0.140625 2.183594 0.0703125 1.867188 -0.0703125 C 1.546875 -0.210938 1.3125 -0.386719 1.15625 -0.601562 C 1.003906 -0.8125 0.894531 -1.074219 0.832031 -1.382812 C 0.789062 -1.589844 0.765625 -1.917969 0.765625 -2.367188 L 0.765625 -6.222656 L 1.820312 -6.222656 L 1.820312 -2.773438 C 1.820312 -2.222656 1.84375 -1.851562 1.886719 -1.65625 C 1.953125 -1.378906 2.09375 -1.164062 2.308594 -1.003906 C 2.523438 -0.847656 2.789062 -0.765625 3.105469 -0.765625 C 3.421875 -0.765625 3.71875 -0.847656 3.996094 -1.011719 C 4.273438 -1.171875 4.46875 -1.394531 4.585938 -1.671875 C 4.699219 -1.953125 4.757812 -2.359375 4.757812 -2.890625 L 4.757812 -6.222656 L 5.8125 -6.222656 L 5.8125 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-0">
|
||||
<path style="stroke:none;" d=""/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-1">
|
||||
<path style="stroke:none;" d="M 0.953125 0 L 0.953125 -9.304688 L 4.445312 -9.304688 C 5.15625 -9.304688 5.722656 -9.210938 6.152344 -9.023438 C 6.582031 -8.835938 6.921875 -8.546875 7.164062 -8.152344 C 7.40625 -7.761719 7.527344 -7.351562 7.527344 -6.925781 C 7.527344 -6.527344 7.421875 -6.152344 7.203125 -5.800781 C 6.988281 -5.449219 6.664062 -5.167969 6.226562 -4.953125 C 6.789062 -4.785156 7.222656 -4.503906 7.523438 -4.105469 C 7.828125 -3.707031 7.980469 -3.238281 7.980469 -2.699219 C 7.980469 -2.261719 7.886719 -1.855469 7.703125 -1.480469 C 7.519531 -1.105469 7.292969 -0.820312 7.019531 -0.617188 C 6.75 -0.414062 6.410156 -0.257812 6 -0.15625 C 5.59375 -0.0507812 5.09375 0 4.5 0 Z M 2.183594 -5.394531 L 4.195312 -5.394531 C 4.742188 -5.394531 5.132812 -5.429688 5.371094 -5.503906 C 5.683594 -5.597656 5.917969 -5.75 6.078125 -5.96875 C 6.238281 -6.183594 6.316406 -6.453125 6.316406 -6.78125 C 6.316406 -7.089844 6.242188 -7.359375 6.09375 -7.59375 C 5.945312 -7.828125 5.734375 -7.992188 5.460938 -8.078125 C 5.183594 -8.164062 4.710938 -8.207031 4.042969 -8.207031 L 2.183594 -8.207031 Z M 2.183594 -1.097656 L 4.5 -1.097656 C 4.898438 -1.097656 5.175781 -1.113281 5.339844 -1.140625 C 5.621094 -1.191406 5.859375 -1.277344 6.050781 -1.398438 C 6.242188 -1.515625 6.394531 -1.6875 6.519531 -1.914062 C 6.640625 -2.140625 6.703125 -2.402344 6.703125 -2.699219 C 6.703125 -3.046875 6.613281 -3.347656 6.4375 -3.601562 C 6.257812 -3.859375 6.011719 -4.039062 5.695312 -4.140625 C 5.382812 -4.246094 4.929688 -4.296875 4.335938 -4.296875 L 2.183594 -4.296875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-2">
|
||||
<path style="stroke:none;" d="M 0.429688 -3.371094 C 0.429688 -4.617188 0.777344 -5.542969 1.472656 -6.144531 C 2.050781 -6.644531 2.757812 -6.894531 3.59375 -6.894531 C 4.519531 -6.894531 5.277344 -6.589844 5.867188 -5.984375 C 6.453125 -5.375 6.746094 -4.535156 6.746094 -3.464844 C 6.746094 -2.597656 6.617188 -1.914062 6.355469 -1.417969 C 6.097656 -0.921875 5.71875 -0.535156 5.222656 -0.261719 C 4.722656 0.015625 4.179688 0.152344 3.59375 0.152344 C 2.648438 0.152344 1.886719 -0.148438 1.304688 -0.753906 C 0.722656 -1.359375 0.429688 -2.230469 0.429688 -3.371094 Z M 1.605469 -3.371094 C 1.605469 -2.507812 1.792969 -1.859375 2.171875 -1.429688 C 2.546875 -1 3.023438 -0.789062 3.59375 -0.789062 C 4.160156 -0.789062 4.632812 -1.003906 5.007812 -1.433594 C 5.382812 -1.867188 5.574219 -2.523438 5.574219 -3.410156 C 5.574219 -4.242188 5.382812 -4.875 5.003906 -5.304688 C 4.625 -5.734375 4.15625 -5.949219 3.59375 -5.949219 C 3.023438 -5.949219 2.546875 -5.734375 2.171875 -5.304688 C 1.792969 -4.878906 1.605469 -4.234375 1.605469 -3.371094 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-3">
|
||||
<path style="stroke:none;" d="M 0.398438 -2.011719 L 1.53125 -2.191406 C 1.59375 -1.738281 1.769531 -1.390625 2.058594 -1.148438 C 2.347656 -0.90625 2.753906 -0.789062 3.273438 -0.789062 C 3.800781 -0.789062 4.1875 -0.894531 4.445312 -1.109375 C 4.699219 -1.320312 4.824219 -1.570312 4.824219 -1.859375 C 4.824219 -2.117188 4.710938 -2.320312 4.488281 -2.46875 C 4.332031 -2.570312 3.941406 -2.699219 3.320312 -2.855469 C 2.480469 -3.066406 1.902344 -3.25 1.578125 -3.40625 C 1.253906 -3.558594 1.007812 -3.773438 0.839844 -4.046875 C 0.671875 -4.320312 0.589844 -4.621094 0.589844 -4.953125 C 0.589844 -5.253906 0.660156 -5.53125 0.796875 -5.785156 C 0.933594 -6.042969 1.121094 -6.253906 1.359375 -6.421875 C 1.535156 -6.554688 1.777344 -6.667969 2.085938 -6.757812 C 2.390625 -6.847656 2.722656 -6.894531 3.070312 -6.894531 C 3.601562 -6.894531 4.066406 -6.816406 4.464844 -6.664062 C 4.867188 -6.511719 5.160156 -6.304688 5.351562 -6.046875 C 5.542969 -5.785156 5.671875 -5.4375 5.746094 -5 L 4.628906 -4.851562 C 4.578125 -5.195312 4.429688 -5.46875 4.1875 -5.664062 C 3.945312 -5.859375 3.597656 -5.953125 3.15625 -5.953125 C 2.628906 -5.953125 2.253906 -5.867188 2.03125 -5.695312 C 1.808594 -5.519531 1.695312 -5.316406 1.695312 -5.085938 C 1.695312 -4.9375 1.742188 -4.804688 1.835938 -4.683594 C 1.929688 -4.5625 2.074219 -4.460938 2.273438 -4.378906 C 2.386719 -4.335938 2.722656 -4.242188 3.28125 -4.085938 C 4.089844 -3.871094 4.652344 -3.695312 4.972656 -3.558594 C 5.292969 -3.421875 5.542969 -3.21875 5.726562 -2.957031 C 5.90625 -2.695312 6 -2.371094 6 -1.980469 C 6 -1.601562 5.886719 -1.242188 5.664062 -0.90625 C 5.441406 -0.570312 5.121094 -0.308594 4.703125 -0.125 C 4.285156 0.0585938 3.8125 0.152344 3.28125 0.152344 C 2.40625 0.152344 1.738281 -0.03125 1.277344 -0.394531 C 0.820312 -0.757812 0.527344 -1.296875 0.398438 -2.011719 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-4">
|
||||
<path style="stroke:none;" d="M 3.351562 -1.023438 L 3.515625 -0.0117188 C 3.195312 0.0546875 2.90625 0.0898438 2.652344 0.0898438 C 2.238281 0.0898438 1.917969 0.0234375 1.6875 -0.109375 C 1.460938 -0.238281 1.300781 -0.410156 1.207031 -0.625 C 1.113281 -0.839844 1.066406 -1.289062 1.066406 -1.972656 L 1.066406 -5.851562 L 0.226562 -5.851562 L 0.226562 -6.742188 L 1.066406 -6.742188 L 1.066406 -8.410156 L 2.203125 -9.097656 L 2.203125 -6.742188 L 3.351562 -6.742188 L 3.351562 -5.851562 L 2.203125 -5.851562 L 2.203125 -1.910156 C 2.203125 -1.585938 2.222656 -1.375 2.261719 -1.28125 C 2.304688 -1.1875 2.367188 -1.113281 2.460938 -1.058594 C 2.550781 -1.003906 2.679688 -0.976562 2.851562 -0.976562 C 2.976562 -0.976562 3.144531 -0.992188 3.351562 -1.023438 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-5">
|
||||
<path style="stroke:none;" d="M 1.179688 0 L 1.179688 -1.300781 L 2.480469 -1.300781 L 2.480469 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-6">
|
||||
<path style="stroke:none;" d="M 1.003906 0 L 1.003906 -9.304688 L 4.511719 -9.304688 C 5.128906 -9.304688 5.601562 -9.277344 5.929688 -9.21875 C 6.386719 -9.140625 6.769531 -8.996094 7.078125 -8.78125 C 7.386719 -8.566406 7.636719 -8.269531 7.824219 -7.882812 C 8.011719 -7.5 8.105469 -7.074219 8.105469 -6.613281 C 8.105469 -5.824219 7.855469 -5.152344 7.351562 -4.605469 C 6.847656 -4.058594 5.9375 -3.78125 4.621094 -3.78125 L 2.234375 -3.78125 L 2.234375 0 Z M 2.234375 -4.882812 L 4.640625 -4.882812 C 5.4375 -4.882812 6 -5.03125 6.335938 -5.324219 C 6.667969 -5.621094 6.835938 -6.039062 6.835938 -6.578125 C 6.835938 -6.964844 6.738281 -7.296875 6.542969 -7.574219 C 6.34375 -7.851562 6.085938 -8.035156 5.765625 -8.125 C 5.558594 -8.179688 5.171875 -8.207031 4.613281 -8.207031 L 2.234375 -8.207031 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-7">
|
||||
<path style="stroke:none;" d="M 0.804688 2.597656 L 0.679688 1.523438 C 0.929688 1.589844 1.148438 1.625 1.332031 1.625 C 1.585938 1.625 1.789062 1.582031 1.941406 1.5 C 2.09375 1.414062 2.21875 1.296875 2.316406 1.140625 C 2.390625 1.027344 2.503906 0.746094 2.664062 0.292969 C 2.6875 0.230469 2.722656 0.136719 2.765625 0.0117188 L 0.210938 -6.742188 L 1.441406 -6.742188 L 2.84375 -2.835938 C 3.027344 -2.34375 3.1875 -1.820312 3.332031 -1.277344 C 3.464844 -1.800781 3.621094 -2.3125 3.800781 -2.8125 L 5.242188 -6.742188 L 6.386719 -6.742188 L 3.820312 0.113281 C 3.546875 0.855469 3.332031 1.363281 3.179688 1.644531 C 2.976562 2.019531 2.746094 2.296875 2.480469 2.472656 C 2.21875 2.648438 1.90625 2.734375 1.542969 2.734375 C 1.324219 2.734375 1.078125 2.6875 0.804688 2.597656 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-8">
|
||||
<path style="stroke:none;" d="M 0.855469 0 L 0.855469 -9.304688 L 2 -9.304688 L 2 -5.96875 C 2.53125 -6.585938 3.207031 -6.894531 4.019531 -6.894531 C 4.519531 -6.894531 4.953125 -6.796875 5.320312 -6.597656 C 5.6875 -6.402344 5.949219 -6.128906 6.109375 -5.78125 C 6.269531 -5.433594 6.347656 -4.933594 6.347656 -4.273438 L 6.347656 0 L 5.203125 0 L 5.203125 -4.273438 C 5.203125 -4.84375 5.082031 -5.257812 4.832031 -5.519531 C 4.585938 -5.78125 4.234375 -5.910156 3.78125 -5.910156 C 3.445312 -5.910156 3.125 -5.820312 2.828125 -5.644531 C 2.53125 -5.46875 2.316406 -5.234375 2.191406 -4.933594 C 2.0625 -4.632812 2 -4.21875 2 -3.6875 L 2 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-9">
|
||||
<path style="stroke:none;" d="M 0.855469 0 L 0.855469 -6.742188 L 1.886719 -6.742188 L 1.886719 -5.78125 C 2.382812 -6.523438 3.09375 -6.894531 4.03125 -6.894531 C 4.4375 -6.894531 4.808594 -6.820312 5.152344 -6.675781 C 5.492188 -6.527344 5.746094 -6.335938 5.914062 -6.101562 C 6.085938 -5.863281 6.203125 -5.582031 6.273438 -5.257812 C 6.3125 -5.046875 6.335938 -4.675781 6.335938 -4.144531 L 6.335938 0 L 5.191406 0 L 5.191406 -4.101562 C 5.191406 -4.566406 5.148438 -4.914062 5.058594 -5.144531 C 4.96875 -5.375 4.8125 -5.558594 4.585938 -5.695312 C 4.359375 -5.835938 4.09375 -5.902344 3.789062 -5.902344 C 3.304688 -5.902344 2.882812 -5.75 2.53125 -5.441406 C 2.175781 -5.132812 2 -4.546875 2 -3.679688 L 2 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-10">
|
||||
<path style="stroke:none;" d="M 0.855469 2.582031 L 0.855469 -6.742188 L 1.898438 -6.742188 L 1.898438 -5.867188 C 2.144531 -6.207031 2.421875 -6.464844 2.730469 -6.636719 C 3.039062 -6.808594 3.414062 -6.894531 3.851562 -6.894531 C 4.429688 -6.894531 4.9375 -6.746094 5.375 -6.449219 C 5.816406 -6.152344 6.148438 -5.734375 6.375 -5.195312 C 6.597656 -4.65625 6.710938 -4.066406 6.710938 -3.421875 C 6.710938 -2.730469 6.585938 -2.109375 6.339844 -1.558594 C 6.089844 -1.007812 5.730469 -0.582031 5.257812 -0.289062 C 4.785156 0.00390625 4.289062 0.152344 3.769531 0.152344 C 3.390625 0.152344 3.046875 0.0703125 2.746094 -0.0898438 C 2.441406 -0.25 2.195312 -0.453125 2 -0.699219 L 2 2.582031 Z M 1.890625 -3.332031 C 1.890625 -2.464844 2.066406 -1.824219 2.417969 -1.410156 C 2.769531 -0.996094 3.195312 -0.789062 3.695312 -0.789062 C 4.203125 -0.789062 4.636719 -1 5 -1.429688 C 5.359375 -1.859375 5.542969 -2.527344 5.542969 -3.429688 C 5.542969 -4.289062 5.363281 -4.929688 5.011719 -5.359375 C 4.65625 -5.785156 4.234375 -6 3.746094 -6 C 3.257812 -6 2.828125 -5.769531 2.453125 -5.316406 C 2.078125 -4.859375 1.890625 -4.199219 1.890625 -3.332031 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-11">
|
||||
<path style="stroke:none;" d="M 1.910156 0 L 0.851562 0 L 0.851562 -9.304688 L 1.992188 -9.304688 L 1.992188 -5.984375 C 2.476562 -6.589844 3.089844 -6.894531 3.839844 -6.894531 C 4.253906 -6.894531 4.648438 -6.808594 5.019531 -6.644531 C 5.390625 -6.476562 5.691406 -6.242188 5.933594 -5.9375 C 6.171875 -5.636719 6.359375 -5.269531 6.492188 -4.84375 C 6.628906 -4.414062 6.695312 -3.957031 6.695312 -3.472656 C 6.695312 -2.316406 6.410156 -1.425781 5.839844 -0.792969 C 5.269531 -0.164062 4.582031 0.152344 3.78125 0.152344 C 2.988281 0.152344 2.363281 -0.179688 1.910156 -0.84375 Z M 1.898438 -3.421875 C 1.898438 -2.613281 2.007812 -2.027344 2.226562 -1.667969 C 2.585938 -1.082031 3.074219 -0.789062 3.6875 -0.789062 C 4.1875 -0.789062 4.617188 -1.003906 4.984375 -1.4375 C 5.347656 -1.871094 5.527344 -2.519531 5.527344 -3.375 C 5.527344 -4.257812 5.355469 -4.90625 5.003906 -5.324219 C 4.65625 -5.742188 4.234375 -5.953125 3.738281 -5.953125 C 3.238281 -5.953125 2.808594 -5.738281 2.445312 -5.304688 C 2.082031 -4.871094 1.898438 -4.242188 1.898438 -3.421875 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-12">
|
||||
<path style="stroke:none;" d="M 0.863281 -7.992188 L 0.863281 -9.304688 L 2.007812 -9.304688 L 2.007812 -7.992188 Z M 0.863281 0 L 0.863281 -6.742188 L 2.007812 -6.742188 L 2.007812 0 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-13">
|
||||
<path style="stroke:none;" d="M 5.230469 0 L 5.230469 -0.851562 C 4.804688 -0.183594 4.175781 0.152344 3.34375 0.152344 C 2.808594 0.152344 2.3125 0.00390625 1.863281 -0.292969 C 1.414062 -0.589844 1.0625 -1 0.816406 -1.53125 C 0.570312 -2.0625 0.445312 -2.675781 0.445312 -3.363281 C 0.445312 -4.035156 0.554688 -4.648438 0.78125 -5.195312 C 1.003906 -5.742188 1.339844 -6.164062 1.789062 -6.457031 C 2.238281 -6.75 2.738281 -6.894531 3.292969 -6.894531 C 3.699219 -6.894531 4.0625 -6.808594 4.378906 -6.636719 C 4.695312 -6.464844 4.957031 -6.242188 5.15625 -5.96875 L 5.15625 -9.304688 L 6.289062 -9.304688 L 6.289062 0 Z M 1.617188 -3.363281 C 1.617188 -2.5 1.800781 -1.855469 2.164062 -1.429688 C 2.527344 -1 2.957031 -0.789062 3.453125 -0.789062 C 3.953125 -0.789062 4.375 -0.992188 4.726562 -1.398438 C 5.074219 -1.808594 5.25 -2.429688 5.25 -3.269531 C 5.25 -4.191406 5.070312 -4.867188 4.714844 -5.300781 C 4.359375 -5.730469 3.921875 -5.949219 3.402344 -5.949219 C 2.894531 -5.949219 2.46875 -5.742188 2.128906 -5.324219 C 1.789062 -4.910156 1.617188 -4.257812 1.617188 -3.363281 Z "/>
|
||||
</symbol>
|
||||
<symbol overflow="visible" id="glyph4-14">
|
||||
<path style="stroke:none;" d="M 4.84375 0 L 3.699219 0 L 3.699219 -7.28125 C 3.425781 -7.019531 3.066406 -6.757812 2.617188 -6.492188 C 2.171875 -6.230469 1.769531 -6.035156 1.414062 -5.902344 L 1.414062 -7.007812 C 2.054688 -7.308594 2.613281 -7.671875 3.089844 -8.101562 C 3.570312 -8.527344 3.90625 -8.941406 4.105469 -9.34375 L 4.84375 -9.34375 Z "/>
|
||||
</symbol>
|
||||
</g>
|
||||
<clipPath id="clip1">
|
||||
<path d="M 94 19 L 96 19 L 96 215 L 94 215 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip2">
|
||||
<path d="M 204 19 L 206 19 L 206 215 L 204 215 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip3">
|
||||
<path d="M 314 19 L 316 19 L 316 215 L 314 215 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip4">
|
||||
<path d="M 39 171 L 355 171 L 355 173 L 39 173 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip5">
|
||||
<path d="M 39 107 L 355 107 L 355 109 L 39 109 Z "/>
|
||||
</clipPath>
|
||||
<clipPath id="clip6">
|
||||
<path d="M 39 44 L 355 44 L 355 46 L 39 46 Z "/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="surface18">
|
||||
<g clip-path="url(#clip1)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 95.160156 214.296875 L 95.160156 19 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip2)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 204.84375 214.296875 L 204.84375 19 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip3)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 314.53125 214.296875 L 314.53125 19 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip4)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 39 171.960938 L 355 171.960938 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip5)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 39 108.234375 L 355 108.234375 "/>
|
||||
</g>
|
||||
<g clip-path="url(#clip6)" clip-rule="nonzero">
|
||||
<path style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:0.5;stroke-dasharray:1,2;stroke-miterlimit:3.25;" d="M 39 44.511719 L 355 44.511719 "/>
|
||||
</g>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 55.070312 201 C 55.070312 200.183594 54.75 199.402344 54.171875 198.828125 C 53.597656 198.25 52.816406 197.929688 52 197.929688 C 51.183594 197.929688 50.402344 198.25 49.828125 198.828125 C 49.25 199.402344 48.929688 200.183594 48.929688 201 C 48.929688 201.816406 49.25 202.597656 49.828125 203.171875 C 50.402344 203.75 51.183594 204.070312 52 204.070312 C 52.816406 204.070312 53.597656 203.75 54.171875 203.171875 C 54.75 202.597656 55.070312 201.816406 55.070312 201 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 88.070312 176 C 88.070312 175.183594 87.75 174.402344 87.171875 173.828125 C 86.597656 173.25 85.816406 172.929688 85 172.929688 C 84.183594 172.929688 83.402344 173.25 82.828125 173.828125 C 82.25 174.402344 81.929688 175.183594 81.929688 176 C 81.929688 176.816406 82.25 177.597656 82.828125 178.171875 C 83.402344 178.75 84.183594 179.070312 85 179.070312 C 85.816406 179.070312 86.597656 178.75 87.171875 178.171875 C 87.75 177.597656 88.070312 176.816406 88.070312 176 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 121.070312 160 C 121.070312 159.183594 120.75 158.402344 120.171875 157.828125 C 119.597656 157.25 118.816406 156.929688 118 156.929688 C 117.183594 156.929688 116.402344 157.25 115.828125 157.828125 C 115.25 158.402344 114.929688 159.183594 114.929688 160 C 114.929688 160.816406 115.25 161.597656 115.828125 162.171875 C 116.402344 162.75 117.183594 163.070312 118 163.070312 C 118.816406 163.070312 119.597656 162.75 120.171875 162.171875 C 120.75 161.597656 121.070312 160.816406 121.070312 160 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 154.070312 142 C 154.070312 141.183594 153.75 140.402344 153.171875 139.828125 C 152.597656 139.25 151.816406 138.929688 151 138.929688 C 150.183594 138.929688 149.402344 139.25 148.828125 139.828125 C 148.25 140.402344 147.929688 141.183594 147.929688 142 C 147.929688 142.816406 148.25 143.597656 148.828125 144.171875 C 149.402344 144.75 150.183594 145.070312 151 145.070312 C 151.816406 145.070312 152.597656 144.75 153.171875 144.171875 C 153.75 143.597656 154.070312 142.816406 154.070312 142 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 187.070312 124 C 187.070312 123.183594 186.75 122.402344 186.171875 121.828125 C 185.597656 121.25 184.816406 120.929688 184 120.929688 C 183.183594 120.929688 182.402344 121.25 181.828125 121.828125 C 181.25 122.402344 180.929688 123.183594 180.929688 124 C 180.929688 124.816406 181.25 125.597656 181.828125 126.171875 C 182.402344 126.75 183.183594 127.070312 184 127.070312 C 184.816406 127.070312 185.597656 126.75 186.171875 126.171875 C 186.75 125.597656 187.070312 124.816406 187.070312 124 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 220.070312 105 C 220.070312 104.183594 219.75 103.402344 219.171875 102.828125 C 218.597656 102.25 217.816406 101.929688 217 101.929688 C 216.183594 101.929688 215.402344 102.25 214.828125 102.828125 C 214.25 103.402344 213.929688 104.183594 213.929688 105 C 213.929688 105.816406 214.25 106.597656 214.828125 107.171875 C 215.402344 107.75 216.183594 108.070312 217 108.070312 C 217.816406 108.070312 218.597656 107.75 219.171875 107.171875 C 219.75 106.597656 220.070312 105.816406 220.070312 105 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 253.070312 86 C 253.070312 85.183594 252.75 84.402344 252.171875 83.828125 C 251.597656 83.25 250.816406 82.929688 250 82.929688 C 249.183594 82.929688 248.402344 83.25 247.828125 83.828125 C 247.25 84.402344 246.929688 85.183594 246.929688 86 C 246.929688 86.816406 247.25 87.597656 247.828125 88.171875 C 248.402344 88.75 249.183594 89.070312 250 89.070312 C 250.816406 89.070312 251.597656 88.75 252.171875 88.171875 C 252.75 87.597656 253.070312 86.816406 253.070312 86 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 286.070312 67 C 286.070312 66.183594 285.75 65.402344 285.171875 64.828125 C 284.597656 64.25 283.816406 63.929688 283 63.929688 C 282.183594 63.929688 281.402344 64.25 280.828125 64.828125 C 280.25 65.402344 279.929688 66.183594 279.929688 67 C 279.929688 67.816406 280.25 68.597656 280.828125 69.171875 C 281.402344 69.75 282.183594 70.070312 283 70.070312 C 283.816406 70.070312 284.597656 69.75 285.171875 69.171875 C 285.75 68.597656 286.070312 67.816406 286.070312 67 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 319.070312 48 C 319.070312 47.183594 318.75 46.402344 318.171875 45.828125 C 317.597656 45.25 316.816406 44.929688 316 44.929688 C 315.183594 44.929688 314.402344 45.25 313.828125 45.828125 C 313.25 46.402344 312.929688 47.183594 312.929688 48 C 312.929688 48.816406 313.25 49.597656 313.828125 50.171875 C 314.402344 50.75 315.183594 51.070312 316 51.070312 C 316.816406 51.070312 317.597656 50.75 318.171875 50.171875 C 318.75 49.597656 319.070312 48.816406 319.070312 48 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 352.070312 29 C 352.070312 28.183594 351.75 27.402344 351.171875 26.828125 C 350.597656 26.25 349.816406 25.929688 349 25.929688 C 348.183594 25.929688 347.402344 26.25 346.828125 26.828125 C 346.25 27.402344 345.929688 28.183594 345.929688 29 C 345.929688 29.816406 346.25 30.597656 346.828125 31.171875 C 347.402344 31.75 348.183594 32.070312 349 32.070312 C 349.816406 32.070312 350.597656 31.75 351.171875 31.171875 C 351.75 30.597656 352.070312 29.816406 352.070312 29 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 55.070312 191 C 55.070312 190.183594 54.75 189.402344 54.171875 188.828125 C 53.597656 188.25 52.816406 187.929688 52 187.929688 C 51.183594 187.929688 50.402344 188.25 49.828125 188.828125 C 49.25 189.402344 48.929688 190.183594 48.929688 191 C 48.929688 191.816406 49.25 192.597656 49.828125 193.171875 C 50.402344 193.75 51.183594 194.070312 52 194.070312 C 52.816406 194.070312 53.597656 193.75 54.171875 193.171875 C 54.75 192.597656 55.070312 191.816406 55.070312 191 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 88.070312 181 C 88.070312 180.183594 87.75 179.402344 87.171875 178.828125 C 86.597656 178.25 85.816406 177.929688 85 177.929688 C 84.183594 177.929688 83.402344 178.25 82.828125 178.828125 C 82.25 179.402344 81.929688 180.183594 81.929688 181 C 81.929688 181.816406 82.25 182.597656 82.828125 183.171875 C 83.402344 183.75 84.183594 184.070312 85 184.070312 C 85.816406 184.070312 86.597656 183.75 87.171875 183.171875 C 87.75 182.597656 88.070312 181.816406 88.070312 181 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 121.070312 170 C 121.070312 169.183594 120.75 168.402344 120.171875 167.828125 C 119.597656 167.25 118.816406 166.929688 118 166.929688 C 117.183594 166.929688 116.402344 167.25 115.828125 167.828125 C 115.25 168.402344 114.929688 169.183594 114.929688 170 C 114.929688 170.816406 115.25 171.597656 115.828125 172.171875 C 116.402344 172.75 117.183594 173.070312 118 173.070312 C 118.816406 173.070312 119.597656 172.75 120.171875 172.171875 C 120.75 171.597656 121.070312 170.816406 121.070312 170 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 154.070312 157 C 154.070312 156.183594 153.75 155.402344 153.171875 154.828125 C 152.597656 154.25 151.816406 153.929688 151 153.929688 C 150.183594 153.929688 149.402344 154.25 148.828125 154.828125 C 148.25 155.402344 147.929688 156.183594 147.929688 157 C 147.929688 157.816406 148.25 158.597656 148.828125 159.171875 C 149.402344 159.75 150.183594 160.070312 151 160.070312 C 151.816406 160.070312 152.597656 159.75 153.171875 159.171875 C 153.75 158.597656 154.070312 157.816406 154.070312 157 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 187.070312 142 C 187.070312 141.183594 186.75 140.402344 186.171875 139.828125 C 185.597656 139.25 184.816406 138.929688 184 138.929688 C 183.183594 138.929688 182.402344 139.25 181.828125 139.828125 C 181.25 140.402344 180.929688 141.183594 180.929688 142 C 180.929688 142.816406 181.25 143.597656 181.828125 144.171875 C 182.402344 144.75 183.183594 145.070312 184 145.070312 C 184.816406 145.070312 185.597656 144.75 186.171875 144.171875 C 186.75 143.597656 187.070312 142.816406 187.070312 142 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 220.070312 125 C 220.070312 124.183594 219.75 123.402344 219.171875 122.828125 C 218.597656 122.25 217.816406 121.929688 217 121.929688 C 216.183594 121.929688 215.402344 122.25 214.828125 122.828125 C 214.25 123.402344 213.929688 124.183594 213.929688 125 C 213.929688 125.816406 214.25 126.597656 214.828125 127.171875 C 215.402344 127.75 216.183594 128.070312 217 128.070312 C 217.816406 128.070312 218.597656 127.75 219.171875 127.171875 C 219.75 126.597656 220.070312 125.816406 220.070312 125 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 253.070312 107 C 253.070312 106.183594 252.75 105.402344 252.171875 104.828125 C 251.597656 104.25 250.816406 103.929688 250 103.929688 C 249.183594 103.929688 248.402344 104.25 247.828125 104.828125 C 247.25 105.402344 246.929688 106.183594 246.929688 107 C 246.929688 107.816406 247.25 108.597656 247.828125 109.171875 C 248.402344 109.75 249.183594 110.070312 250 110.070312 C 250.816406 110.070312 251.597656 109.75 252.171875 109.171875 C 252.75 108.597656 253.070312 107.816406 253.070312 107 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 286.070312 88 C 286.070312 87.183594 285.75 86.402344 285.171875 85.828125 C 284.597656 85.25 283.816406 84.929688 283 84.929688 C 282.183594 84.929688 281.402344 85.25 280.828125 85.828125 C 280.25 86.402344 279.929688 87.183594 279.929688 88 C 279.929688 88.816406 280.25 89.597656 280.828125 90.171875 C 281.402344 90.75 282.183594 91.070312 283 91.070312 C 283.816406 91.070312 284.597656 90.75 285.171875 90.171875 C 285.75 89.597656 286.070312 88.816406 286.070312 88 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 319.070312 69 C 319.070312 68.183594 318.75 67.402344 318.171875 66.828125 C 317.597656 66.25 316.816406 65.929688 316 65.929688 C 315.183594 65.929688 314.402344 66.25 313.828125 66.828125 C 313.25 67.402344 312.929688 68.183594 312.929688 69 C 312.929688 69.816406 313.25 70.597656 313.828125 71.171875 C 314.402344 71.75 315.183594 72.070312 316 72.070312 C 316.816406 72.070312 317.597656 71.75 318.171875 71.171875 C 318.75 70.597656 319.070312 69.816406 319.070312 69 Z "/>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 352.070312 50 C 352.070312 49.183594 351.75 48.402344 351.171875 47.828125 C 350.597656 47.25 349.816406 46.929688 349 46.929688 C 348.183594 46.929688 347.402344 47.25 346.828125 47.828125 C 346.25 48.402344 345.929688 49.183594 345.929688 50 C 345.929688 50.816406 346.25 51.597656 346.828125 52.171875 C 347.402344 52.75 348.183594 53.070312 349 53.070312 C 349.816406 53.070312 350.597656 52.75 351.171875 52.171875 C 351.75 51.597656 352.070312 50.816406 352.070312 50 Z "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 214.296875 L 39 214.296875 "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 214.296875 L 39 19 "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 19 L 355 19 "/>
|
||||
<path style="fill:none;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 19 L 355 214.296875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 95.160156 214.296875 L 95.160156 211.140625 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="89.659467" y="226.29874"/>
|
||||
<use xlink:href="#glyph0-2" x="95.220991" y="226.29874"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 204.84375 214.296875 L 204.84375 211.140625 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="196.345465" y="226.29874"/>
|
||||
<use xlink:href="#glyph0-2" x="201.906989" y="226.29874"/>
|
||||
<use xlink:href="#glyph0-2" x="207.468512" y="226.29874"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 314.53125 214.296875 L 314.53125 211.140625 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="303.531463" y="226.29874"/>
|
||||
<use xlink:href="#glyph0-2" x="309.092987" y="226.29874"/>
|
||||
<use xlink:href="#glyph0-2" x="314.65451" y="226.29874"/>
|
||||
<use xlink:href="#glyph0-2" x="320.216034" y="226.29874"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 51.511719 214.296875 L 51.511719 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 62.140625 214.296875 L 62.140625 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 70.824219 214.296875 L 70.824219 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 78.167969 214.296875 L 78.167969 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 84.53125 214.296875 L 84.53125 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 90.140625 214.296875 L 90.140625 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 128.179688 214.296875 L 128.179688 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 147.492188 214.296875 L 147.492188 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 161.195312 214.296875 L 161.195312 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 171.828125 214.296875 L 171.828125 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 180.511719 214.296875 L 180.511719 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 187.855469 214.296875 L 187.855469 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 194.214844 214.296875 L 194.214844 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 199.828125 214.296875 L 199.828125 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 237.863281 214.296875 L 237.863281 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 257.179688 214.296875 L 257.179688 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 270.882812 214.296875 L 270.882812 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 281.511719 214.296875 L 281.511719 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 290.199219 214.296875 L 290.199219 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 297.539062 214.296875 L 297.539062 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 303.902344 214.296875 L 303.902344 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 309.511719 214.296875 L 309.511719 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 347.550781 214.296875 L 347.550781 212.71875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 171.960938 L 42.160156 171.960938 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="19" y="176.961688"/>
|
||||
<use xlink:href="#glyph0-2" x="24.561523" y="176.961688"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph1-1" x="30" y="172.81325"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 108.234375 L 42.160156 108.234375 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="19" y="113.23603"/>
|
||||
<use xlink:href="#glyph0-2" x="24.561523" y="113.23603"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph1-2" x="30" y="109.087593"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 44.511719 L 42.160156 44.511719 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-1" x="19" y="49.510373"/>
|
||||
<use xlink:href="#glyph0-2" x="24.561523" y="49.510373"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph1-3" x="30" y="45.361936"/>
|
||||
</g>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 205.28125 L 40.578125 205.28125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 197.320312 L 40.578125 197.320312 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 191.144531 L 40.578125 191.144531 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 186.097656 L 40.578125 186.097656 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 181.832031 L 40.578125 181.832031 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 178.136719 L 40.578125 178.136719 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 174.878906 L 40.578125 174.878906 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 152.777344 L 40.578125 152.777344 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 141.558594 L 40.578125 141.558594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 133.59375 L 40.578125 133.59375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 127.417969 L 40.578125 127.417969 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 122.375 L 40.578125 122.375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 118.105469 L 40.578125 118.105469 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 114.410156 L 40.578125 114.410156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 111.152344 L 40.578125 111.152344 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 89.050781 L 40.578125 89.050781 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 77.832031 L 40.578125 77.832031 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 69.871094 L 40.578125 69.871094 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 63.695312 L 40.578125 63.695312 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 58.648438 L 40.578125 58.648438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 54.382812 L 40.578125 54.382812 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 50.6875 L 40.578125 50.6875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 47.425781 L 40.578125 47.425781 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 39 25.328125 L 40.578125 25.328125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 95.160156 19 L 95.160156 22.160156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 204.84375 19 L 204.84375 22.160156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 314.53125 19 L 314.53125 22.160156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 51.511719 19 L 51.511719 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 62.140625 19 L 62.140625 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 70.824219 19 L 70.824219 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 78.167969 19 L 78.167969 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 84.53125 19 L 84.53125 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 90.140625 19 L 90.140625 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 128.179688 19 L 128.179688 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 147.492188 19 L 147.492188 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 161.195312 19 L 161.195312 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 171.828125 19 L 171.828125 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 180.511719 19 L 180.511719 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 187.855469 19 L 187.855469 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 194.214844 19 L 194.214844 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 199.828125 19 L 199.828125 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 237.863281 19 L 237.863281 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 257.179688 19 L 257.179688 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 270.882812 19 L 270.882812 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 281.511719 19 L 281.511719 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 290.199219 19 L 290.199219 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 297.539062 19 L 297.539062 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 303.902344 19 L 303.902344 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 309.511719 19 L 309.511719 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 347.550781 19 L 347.550781 20.578125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 171.960938 L 351.839844 171.960938 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 108.234375 L 351.839844 108.234375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 44.511719 L 351.839844 44.511719 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 205.28125 L 353.421875 205.28125 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 197.320312 L 353.421875 197.320312 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 191.144531 L 353.421875 191.144531 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 186.097656 L 353.421875 186.097656 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 181.832031 L 353.421875 181.832031 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 178.136719 L 353.421875 178.136719 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 174.878906 L 353.421875 174.878906 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 152.777344 L 353.421875 152.777344 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 141.558594 L 353.421875 141.558594 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 133.59375 L 353.421875 133.59375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 127.417969 L 353.421875 127.417969 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 122.375 L 353.421875 122.375 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 118.105469 L 353.421875 118.105469 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 114.410156 L 353.421875 114.410156 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 111.152344 L 353.421875 111.152344 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 89.050781 L 353.421875 89.050781 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 77.832031 L 353.421875 77.832031 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 69.871094 L 353.421875 69.871094 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 63.695312 L 353.421875 63.695312 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 58.648438 L 353.421875 58.648438 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 54.382812 L 353.421875 54.382812 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 50.6875 L 353.421875 50.6875 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 47.425781 L 353.421875 47.425781 "/>
|
||||
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(39.99939%,39.99939%,39.99939%);stroke-opacity:1;stroke-miterlimit:3.25;" d="M 355 25.328125 L 353.421875 25.328125 "/>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph0-3" x="175.5" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-4" x="181.608398" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-5" x="187.169922" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-6" x="192.731445" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-7" x="197.731445" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-8" x="200.509766" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-9" x="202.731445" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-5" x="208.292969" y="245.29874"/>
|
||||
<use xlink:href="#glyph0-10" x="213.854492" y="245.29874"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph2-1" x="9" y="129.14937"/>
|
||||
<use xlink:href="#glyph2-2" x="9" y="122.479448"/>
|
||||
<use xlink:href="#glyph2-3" x="9" y="117.479448"/>
|
||||
<use xlink:href="#glyph2-4" x="9" y="114.701128"/>
|
||||
<use xlink:href="#glyph2-5" x="9" y="109.139605"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-1" x="148" y="12"/>
|
||||
<use xlink:href="#glyph3-2" x="155.330078" y="12"/>
|
||||
<use xlink:href="#glyph3-3" x="157.996094" y="12"/>
|
||||
<use xlink:href="#glyph3-4" x="160.662109" y="12"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-5" x="170" y="12"/>
|
||||
<use xlink:href="#glyph3-2" x="176" y="12"/>
|
||||
<use xlink:href="#glyph3-6" x="178.666016" y="12"/>
|
||||
<use xlink:href="#glyph3-4" x="184.666016" y="12"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-7" x="194" y="12"/>
|
||||
<use xlink:href="#glyph3-8" x="200.673828" y="12"/>
|
||||
</g>
|
||||
<g style="fill:rgb(39.99939%,39.99939%,39.99939%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph3-9" x="207" y="12"/>
|
||||
<use xlink:href="#glyph3-7" x="216.996094" y="12"/>
|
||||
<use xlink:href="#glyph3-10" x="223.669922" y="12"/>
|
||||
<use xlink:href="#glyph3-11" x="230.34375" y="12"/>
|
||||
<use xlink:href="#glyph3-3" x="237.017578" y="12"/>
|
||||
<use xlink:href="#glyph3-4" x="239.683594" y="12"/>
|
||||
</g>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(36.84082%,50.67749%,70.979309%);fill-opacity:1;" d="M 382.148438 113 C 382.148438 112.164062 381.816406 111.363281 381.226562 110.773438 C 380.636719 110.183594 379.835938 109.851562 379 109.851562 C 378.164062 109.851562 377.363281 110.183594 376.773438 110.773438 C 376.183594 111.363281 375.851562 112.164062 375.851562 113 C 375.851562 113.835938 376.183594 114.636719 376.773438 115.226562 C 377.363281 115.816406 378.164062 116.148438 379 116.148438 C 379.835938 116.148438 380.636719 115.816406 381.226562 115.226562 C 381.816406 114.636719 382.148438 113.835938 382.148438 113 Z "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph4-1" x="391" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-2" x="399.670898" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-2" x="406.901367" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-3" x="414.131836" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-4" x="420.631836" y="117.28418"/>
|
||||
</g>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph4-5" x="424" y="117.28418"/>
|
||||
</g>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph4-6" x="428" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-7" x="436.670898" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-4" x="443.170898" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-8" x="446.783203" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-2" x="454.013672" y="117.28418"/>
|
||||
<use xlink:href="#glyph4-9" x="461.244141" y="117.28418"/>
|
||||
</g>
|
||||
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(88.070679%,61.103821%,14.204407%);fill-opacity:1;" d="M 382.148438 136 C 382.148438 135.164062 381.816406 134.363281 381.226562 133.773438 C 380.636719 133.183594 379.835938 132.851562 379 132.851562 C 378.164062 132.851562 377.363281 133.183594 376.773438 133.773438 C 376.183594 134.363281 375.851562 135.164062 375.851562 136 C 375.851562 136.835938 376.183594 137.636719 376.773438 138.226562 C 377.363281 138.816406 378.164062 139.148438 379 139.148438 C 379.835938 139.148438 380.636719 138.816406 381.226562 138.226562 C 381.816406 137.636719 382.148438 136.835938 382.148438 136 Z "/>
|
||||
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
|
||||
<use xlink:href="#glyph4-10" x="391" y="140.28418"/>
|
||||
<use xlink:href="#glyph4-7" x="398.230469" y="140.28418"/>
|
||||
<use xlink:href="#glyph4-11" x="404.730469" y="140.28418"/>
|
||||
<use xlink:href="#glyph4-12" x="411.960938" y="140.28418"/>
|
||||
<use xlink:href="#glyph4-9" x="414.849609" y="140.28418"/>
|
||||
<use xlink:href="#glyph4-13" x="422.080078" y="140.28418"/>
|
||||
<use xlink:href="#glyph4-14" x="429.310547" y="140.28418"/>
|
||||
<use xlink:href="#glyph4-14" x="436.541016" y="140.28418"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 84 KiB |
130
thirdparty/pybind11/docs/reference.rst
vendored
Normal file
130
thirdparty/pybind11/docs/reference.rst
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
.. _reference:
|
||||
|
||||
.. warning::
|
||||
|
||||
Please be advised that the reference documentation discussing pybind11
|
||||
internals is currently incomplete. Please refer to the previous sections
|
||||
and the pybind11 header files for the nitty gritty details.
|
||||
|
||||
Reference
|
||||
#########
|
||||
|
||||
.. _macros:
|
||||
|
||||
Macros
|
||||
======
|
||||
|
||||
.. doxygendefine:: PYBIND11_MODULE
|
||||
|
||||
.. _core_types:
|
||||
|
||||
Convenience classes for arbitrary Python types
|
||||
==============================================
|
||||
|
||||
Common member functions
|
||||
-----------------------
|
||||
|
||||
.. doxygenclass:: object_api
|
||||
:members:
|
||||
|
||||
Without reference counting
|
||||
--------------------------
|
||||
|
||||
.. doxygenclass:: handle
|
||||
:members:
|
||||
|
||||
With reference counting
|
||||
-----------------------
|
||||
|
||||
.. doxygenclass:: object
|
||||
:members:
|
||||
|
||||
.. doxygenfunction:: reinterpret_borrow
|
||||
|
||||
.. doxygenfunction:: reinterpret_steal
|
||||
|
||||
Convenience classes for specific Python types
|
||||
=============================================
|
||||
|
||||
.. doxygenclass:: module_
|
||||
:members:
|
||||
|
||||
.. doxygengroup:: pytypes
|
||||
:members:
|
||||
|
||||
Convenience functions converting to Python types
|
||||
================================================
|
||||
|
||||
.. doxygenfunction:: make_tuple(Args&&...)
|
||||
|
||||
.. doxygenfunction:: make_iterator(Iterator, Sentinel, Extra &&...)
|
||||
.. doxygenfunction:: make_iterator(Type &, Extra&&...)
|
||||
|
||||
.. doxygenfunction:: make_key_iterator(Iterator, Sentinel, Extra &&...)
|
||||
.. doxygenfunction:: make_key_iterator(Type &, Extra&&...)
|
||||
|
||||
.. doxygenfunction:: make_value_iterator(Iterator, Sentinel, Extra &&...)
|
||||
.. doxygenfunction:: make_value_iterator(Type &, Extra&&...)
|
||||
|
||||
.. _extras:
|
||||
|
||||
Passing extra arguments to ``def`` or ``class_``
|
||||
================================================
|
||||
|
||||
.. doxygengroup:: annotations
|
||||
:members:
|
||||
|
||||
Embedding the interpreter
|
||||
=========================
|
||||
|
||||
.. doxygendefine:: PYBIND11_EMBEDDED_MODULE
|
||||
|
||||
.. doxygenfunction:: initialize_interpreter
|
||||
|
||||
.. doxygenfunction:: finalize_interpreter
|
||||
|
||||
.. doxygenclass:: scoped_interpreter
|
||||
|
||||
Redirecting C++ streams
|
||||
=======================
|
||||
|
||||
.. doxygenclass:: scoped_ostream_redirect
|
||||
|
||||
.. doxygenclass:: scoped_estream_redirect
|
||||
|
||||
.. doxygenfunction:: add_ostream_redirect
|
||||
|
||||
Python built-in functions
|
||||
=========================
|
||||
|
||||
.. doxygengroup:: python_builtins
|
||||
:members:
|
||||
|
||||
Inheritance
|
||||
===========
|
||||
|
||||
See :doc:`/classes` and :doc:`/advanced/classes` for more detail.
|
||||
|
||||
.. doxygendefine:: PYBIND11_OVERRIDE
|
||||
|
||||
.. doxygendefine:: PYBIND11_OVERRIDE_PURE
|
||||
|
||||
.. doxygendefine:: PYBIND11_OVERRIDE_NAME
|
||||
|
||||
.. doxygendefine:: PYBIND11_OVERRIDE_PURE_NAME
|
||||
|
||||
.. doxygenfunction:: get_override
|
||||
|
||||
Exceptions
|
||||
==========
|
||||
|
||||
.. doxygenclass:: error_already_set
|
||||
:members:
|
||||
|
||||
.. doxygenclass:: builtin_exception
|
||||
:members:
|
||||
|
||||
Literals
|
||||
========
|
||||
|
||||
.. doxygennamespace:: literals
|
143
thirdparty/pybind11/docs/release.rst
vendored
Normal file
143
thirdparty/pybind11/docs/release.rst
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
On version numbers
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The two version numbers (C++ and Python) must match when combined (checked when
|
||||
you build the PyPI package), and must be a valid `PEP 440
|
||||
<https://www.python.org/dev/peps/pep-0440>`_ version when combined.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
#define PYBIND11_VERSION_MAJOR X
|
||||
#define PYBIND11_VERSION_MINOR Y
|
||||
#define PYBIND11_VERSION_PATCH Z.dev1
|
||||
|
||||
For beta, ``PYBIND11_VERSION_PATCH`` should be ``Z.b1``. RC's can be ``Z.rc1``.
|
||||
Always include the dot (even though PEP 440 allows it to be dropped). For a
|
||||
final release, this must be a simple integer. There is also
|
||||
``PYBIND11_VERSION_HEX`` just below that needs to be updated.
|
||||
|
||||
|
||||
To release a new version of pybind11:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you don't have nox, you should either use ``pipx run nox`` instead, or use
|
||||
``pipx install nox`` or ``brew install nox`` (Unix).
|
||||
|
||||
- Update the version number
|
||||
|
||||
- Update ``PYBIND11_VERSION_MAJOR`` etc. in
|
||||
``include/pybind11/detail/common.h``. PATCH should be a simple integer.
|
||||
|
||||
- Update ``PYBIND11_VERSION_HEX`` just below as well.
|
||||
|
||||
- Update ``pybind11/_version.py`` (match above).
|
||||
|
||||
- Run ``nox -s tests_packaging`` to ensure this was done correctly.
|
||||
|
||||
- Ensure that all the information in ``setup.cfg`` is up-to-date, like
|
||||
supported Python versions.
|
||||
|
||||
- Add release date in ``docs/changelog.rst`` and integrate the output of
|
||||
``nox -s make_changelog``.
|
||||
|
||||
- Note that the ``make_changelog`` command inspects
|
||||
`needs changelog <https://github.com/pybind/pybind11/pulls?q=is%3Apr+is%3Aclosed+label%3A%22needs+changelog%22>`_.
|
||||
|
||||
- Manually clear the ``needs changelog`` labels using the GitHub web
|
||||
interface (very easy: start by clicking the link above).
|
||||
|
||||
- ``git add`` and ``git commit``, ``git push``. **Ensure CI passes**. (If it
|
||||
fails due to a known flake issue, either ignore or restart CI.)
|
||||
|
||||
- Add a release branch if this is a new MINOR version, or update the existing
|
||||
release branch if it is a patch version
|
||||
|
||||
- New branch: ``git checkout -b vX.Y``, ``git push -u origin vX.Y``
|
||||
|
||||
- Update branch: ``git checkout vX.Y``, ``git merge <release branch>``, ``git push``
|
||||
|
||||
- Update tags (optional; if you skip this, the GitHub release makes a
|
||||
non-annotated tag for you)
|
||||
|
||||
- ``git tag -a vX.Y.Z -m 'vX.Y.Z release'``
|
||||
|
||||
- ``grep ^__version__ pybind11/_version.py``
|
||||
|
||||
- Last-minute consistency check: same as tag?
|
||||
|
||||
- ``git push --tags``
|
||||
|
||||
- Update stable
|
||||
|
||||
- ``git checkout stable``
|
||||
|
||||
- ``git merge -X theirs vX.Y.Z``
|
||||
|
||||
- ``git diff vX.Y.Z``
|
||||
|
||||
- Carefully review and reconcile any diffs. There should be none.
|
||||
|
||||
- ``git push``
|
||||
|
||||
- Make a GitHub release (this shows up in the UI, sends new release
|
||||
notifications to users watching releases, and also uploads PyPI packages).
|
||||
(Note: if you do not use an existing tag, this creates a new lightweight tag
|
||||
for you, so you could skip the above step.)
|
||||
|
||||
- GUI method: Under `releases <https://github.com/pybind/pybind11/releases>`_
|
||||
click "Draft a new release" on the far right, fill in the tag name
|
||||
(if you didn't tag above, it will be made here), fill in a release name
|
||||
like "Version X.Y.Z", and copy-and-paste the markdown-formatted (!) changelog
|
||||
into the description. You can use ``cat docs/changelog.rst | pandoc -f rst -t gfm``,
|
||||
then manually remove line breaks and strip links to PRs and issues,
|
||||
e.g. to a bare ``#1234``, without the surrounding ``<...>_`` hyperlink markup.
|
||||
Check "pre-release" if this is a beta/RC.
|
||||
|
||||
- CLI method: with ``gh`` installed, run ``gh release create vX.Y.Z -t "Version X.Y.Z"``
|
||||
If this is a pre-release, add ``-p``.
|
||||
|
||||
- Get back to work
|
||||
|
||||
- Make sure you are on master, not somewhere else: ``git checkout master``
|
||||
|
||||
- Update version macros in ``include/pybind11/detail/common.h`` (set PATCH to
|
||||
``0.dev1`` and increment MINOR).
|
||||
|
||||
- Update ``pybind11/_version.py`` to match.
|
||||
|
||||
- Run ``nox -s tests_packaging`` to ensure this was done correctly.
|
||||
|
||||
- If the release was a new MINOR version, add a new ``IN DEVELOPMENT``
|
||||
section in ``docs/changelog.rst``.
|
||||
|
||||
- ``git add``, ``git commit``, ``git push``
|
||||
|
||||
If a version branch is updated, remember to set PATCH to ``1.dev1``.
|
||||
|
||||
If you'd like to bump homebrew, run:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
brew bump-formula-pr --url https://github.com/pybind/pybind11/archive/vX.Y.Z.tar.gz
|
||||
|
||||
Conda-forge should automatically make a PR in a few hours, and automatically
|
||||
merge it if there are no issues.
|
||||
|
||||
|
||||
Manual packaging
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
If you need to manually upload releases, you can download the releases from
|
||||
the job artifacts and upload them with twine. You can also make the files
|
||||
locally (not recommended in general, as your local directory is more likely
|
||||
to be "dirty" and SDists love picking up random unrelated/hidden files);
|
||||
this is the procedure:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
nox -s build
|
||||
twine upload dist/*
|
||||
|
||||
This makes SDists and wheels, and the final line uploads them.
|
6
thirdparty/pybind11/docs/requirements.txt
vendored
Normal file
6
thirdparty/pybind11/docs/requirements.txt
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
breathe==4.34.0
|
||||
furo==2022.6.21
|
||||
sphinx==5.0.2
|
||||
sphinx-copybutton==0.5.0
|
||||
sphinxcontrib-moderncmakedomain==3.21.4
|
||||
sphinxcontrib-svg2pdfconverter==1.2.0
|
566
thirdparty/pybind11/docs/upgrade.rst
vendored
Normal file
566
thirdparty/pybind11/docs/upgrade.rst
vendored
Normal file
@ -0,0 +1,566 @@
|
||||
Upgrade guide
|
||||
#############
|
||||
|
||||
This is a companion guide to the :doc:`changelog`. While the changelog briefly
|
||||
lists all of the new features, improvements and bug fixes, this upgrade guide
|
||||
focuses only the subset which directly impacts your experience when upgrading
|
||||
to a new version. But it goes into more detail. This includes things like
|
||||
deprecated APIs and their replacements, build system changes, general code
|
||||
modernization and other useful information.
|
||||
|
||||
.. _upgrade-guide-2.11:
|
||||
|
||||
v2.11
|
||||
=====
|
||||
|
||||
* The minimum version of CMake is now 3.5. A future version will likely move to
|
||||
requiring something like CMake 3.15. Note that CMake 3.27 is removing the
|
||||
long-deprecated support for ``FindPythonInterp`` if you set 3.27 as the
|
||||
minimum or maximum supported version. To prepare for that future, CMake 3.15+
|
||||
using ``FindPython`` or setting ``PYBIND11_FINDPYTHON`` is highly recommended,
|
||||
otherwise pybind11 will automatically switch to using ``FindPython`` if
|
||||
``FindPythonInterp`` is not available.
|
||||
|
||||
|
||||
.. _upgrade-guide-2.9:
|
||||
|
||||
v2.9
|
||||
====
|
||||
|
||||
* Any usage of the recently added ``py::make_simple_namespace`` should be
|
||||
converted to using ``py::module_::import("types").attr("SimpleNamespace")``
|
||||
instead.
|
||||
|
||||
* The use of ``_`` in custom type casters can now be replaced with the more
|
||||
readable ``const_name`` instead. The old ``_`` shortcut has been retained
|
||||
unless it is being used as a macro (like for gettext).
|
||||
|
||||
|
||||
.. _upgrade-guide-2.7:
|
||||
|
||||
v2.7
|
||||
====
|
||||
|
||||
*Before* v2.7, ``py::str`` can hold ``PyUnicodeObject`` or ``PyBytesObject``,
|
||||
and ``py::isinstance<str>()`` is ``true`` for both ``py::str`` and
|
||||
``py::bytes``. Starting with v2.7, ``py::str`` exclusively holds
|
||||
``PyUnicodeObject`` (`#2409 <https://github.com/pybind/pybind11/pull/2409>`_),
|
||||
and ``py::isinstance<str>()`` is ``true`` only for ``py::str``. To help in
|
||||
the transition of user code, the ``PYBIND11_STR_LEGACY_PERMISSIVE`` macro
|
||||
is provided as an escape hatch to go back to the legacy behavior. This macro
|
||||
will be removed in future releases. Two types of required fixes are expected
|
||||
to be common:
|
||||
|
||||
* Accidental use of ``py::str`` instead of ``py::bytes``, masked by the legacy
|
||||
behavior. These are probably very easy to fix, by changing from
|
||||
``py::str`` to ``py::bytes``.
|
||||
|
||||
* Reliance on py::isinstance<str>(obj) being ``true`` for
|
||||
``py::bytes``. This is likely to be easy to fix in most cases by adding
|
||||
``|| py::isinstance<bytes>(obj)``, but a fix may be more involved, e.g. if
|
||||
``py::isinstance<T>`` appears in a template. Such situations will require
|
||||
careful review and custom fixes.
|
||||
|
||||
|
||||
.. _upgrade-guide-2.6:
|
||||
|
||||
v2.6
|
||||
====
|
||||
|
||||
Usage of the ``PYBIND11_OVERLOAD*`` macros and ``get_overload`` function should
|
||||
be replaced by ``PYBIND11_OVERRIDE*`` and ``get_override``. In the future, the
|
||||
old macros may be deprecated and removed.
|
||||
|
||||
``py::module`` has been renamed ``py::module_``, but a backward compatible
|
||||
typedef has been included. This change was to avoid a language change in C++20
|
||||
that requires unqualified ``module`` not be placed at the start of a logical
|
||||
line. Qualified usage is unaffected and the typedef will remain unless the
|
||||
C++ language rules change again.
|
||||
|
||||
The public constructors of ``py::module_`` have been deprecated. Use
|
||||
``PYBIND11_MODULE`` or ``module_::create_extension_module`` instead.
|
||||
|
||||
An error is now thrown when ``__init__`` is forgotten on subclasses. This was
|
||||
incorrect before, but was not checked. Add a call to ``__init__`` if it is
|
||||
missing.
|
||||
|
||||
A ``py::type_error`` is now thrown when casting to a subclass (like
|
||||
``py::bytes`` from ``py::object``) if the conversion is not valid. Make a valid
|
||||
conversion instead.
|
||||
|
||||
The undocumented ``h.get_type()`` method has been deprecated and replaced by
|
||||
``py::type::of(h)``.
|
||||
|
||||
Enums now have a ``__str__`` method pre-defined; if you want to override it,
|
||||
the simplest fix is to add the new ``py::prepend()`` tag when defining
|
||||
``"__str__"``.
|
||||
|
||||
If ``__eq__`` defined but not ``__hash__``, ``__hash__`` is now set to
|
||||
``None``, as in normal CPython. You should add ``__hash__`` if you intended the
|
||||
class to be hashable, possibly using the new ``py::hash`` shortcut.
|
||||
|
||||
The constructors for ``py::array`` now always take signed integers for size,
|
||||
for consistency. This may lead to compiler warnings on some systems. Cast to
|
||||
``py::ssize_t`` instead of ``std::size_t``.
|
||||
|
||||
The ``tools/clang`` submodule and ``tools/mkdoc.py`` have been moved to a
|
||||
standalone package, `pybind11-mkdoc`_. If you were using those tools, please
|
||||
use them via a pip install from the new location.
|
||||
|
||||
The ``pybind11`` package on PyPI no longer fills the wheel "headers" slot - if
|
||||
you were using the headers from this slot, they are available by requesting the
|
||||
``global`` extra, that is, ``pip install "pybind11[global]"``. (Most users will
|
||||
be unaffected, as the ``pybind11/include`` location is reported by ``python -m
|
||||
pybind11 --includes`` and ``pybind11.get_include()`` is still correct and has
|
||||
not changed since 2.5).
|
||||
|
||||
.. _pybind11-mkdoc: https://github.com/pybind/pybind11-mkdoc
|
||||
|
||||
CMake support:
|
||||
--------------
|
||||
|
||||
The minimum required version of CMake is now 3.4. Several details of the CMake
|
||||
support have been deprecated; warnings will be shown if you need to change
|
||||
something. The changes are:
|
||||
|
||||
* ``PYBIND11_CPP_STANDARD=<platform-flag>`` is deprecated, please use
|
||||
``CMAKE_CXX_STANDARD=<number>`` instead, or any other valid CMake CXX or CUDA
|
||||
standard selection method, like ``target_compile_features``.
|
||||
|
||||
* If you do not request a standard, pybind11 targets will compile with the
|
||||
compiler default, but not less than C++11, instead of forcing C++14 always.
|
||||
If you depend on the old behavior, please use ``set(CMAKE_CXX_STANDARD 14 CACHE STRING "")``
|
||||
instead.
|
||||
|
||||
* Direct ``pybind11::module`` usage should always be accompanied by at least
|
||||
``set(CMAKE_CXX_VISIBILITY_PRESET hidden)`` or similar - it used to try to
|
||||
manually force this compiler flag (but not correctly on all compilers or with
|
||||
CUDA).
|
||||
|
||||
* ``pybind11_add_module``'s ``SYSTEM`` argument is deprecated and does nothing;
|
||||
linking now behaves like other imported libraries consistently in both
|
||||
config and submodule mode, and behaves like a ``SYSTEM`` library by
|
||||
default.
|
||||
|
||||
* If ``PYTHON_EXECUTABLE`` is not set, virtual environments (``venv``,
|
||||
``virtualenv``, and ``conda``) are prioritized over the standard search
|
||||
(similar to the new FindPython mode).
|
||||
|
||||
In addition, the following changes may be of interest:
|
||||
|
||||
* ``CMAKE_INTERPROCEDURAL_OPTIMIZATION`` will be respected by
|
||||
``pybind11_add_module`` if set instead of linking to ``pybind11::lto`` or
|
||||
``pybind11::thin_lto``.
|
||||
|
||||
* Using ``find_package(Python COMPONENTS Interpreter Development)`` before
|
||||
pybind11 will cause pybind11 to use the new Python mechanisms instead of its
|
||||
own custom search, based on a patched version of classic ``FindPythonInterp``
|
||||
/ ``FindPythonLibs``. In the future, this may become the default. A recent
|
||||
(3.15+ or 3.18.2+) version of CMake is recommended.
|
||||
|
||||
|
||||
|
||||
v2.5
|
||||
====
|
||||
|
||||
The Python package now includes the headers as data in the package itself, as
|
||||
well as in the "headers" wheel slot. ``pybind11 --includes`` and
|
||||
``pybind11.get_include()`` report the new location, which is always correct
|
||||
regardless of how pybind11 was installed, making the old ``user=`` argument
|
||||
meaningless. If you are not using the function to get the location already, you
|
||||
are encouraged to switch to the package location.
|
||||
|
||||
|
||||
v2.2
|
||||
====
|
||||
|
||||
Deprecation of the ``PYBIND11_PLUGIN`` macro
|
||||
--------------------------------------------
|
||||
|
||||
``PYBIND11_MODULE`` is now the preferred way to create module entry points.
|
||||
The old macro emits a compile-time deprecation warning.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// old
|
||||
PYBIND11_PLUGIN(example) {
|
||||
py::module m("example", "documentation string");
|
||||
|
||||
m.def("add", [](int a, int b) { return a + b; });
|
||||
|
||||
return m.ptr();
|
||||
}
|
||||
|
||||
// new
|
||||
PYBIND11_MODULE(example, m) {
|
||||
m.doc() = "documentation string"; // optional
|
||||
|
||||
m.def("add", [](int a, int b) { return a + b; });
|
||||
}
|
||||
|
||||
|
||||
New API for defining custom constructors and pickling functions
|
||||
---------------------------------------------------------------
|
||||
|
||||
The old placement-new custom constructors have been deprecated. The new approach
|
||||
uses ``py::init()`` and factory functions to greatly improve type safety.
|
||||
|
||||
Placement-new can be called accidentally with an incompatible type (without any
|
||||
compiler errors or warnings), or it can initialize the same object multiple times
|
||||
if not careful with the Python-side ``__init__`` calls. The new-style custom
|
||||
constructors prevent such mistakes. See :ref:`custom_constructors` for details.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// old -- deprecated (runtime warning shown only in debug mode)
|
||||
py::class<Foo>(m, "Foo")
|
||||
.def("__init__", [](Foo &self, ...) {
|
||||
new (&self) Foo(...); // uses placement-new
|
||||
});
|
||||
|
||||
// new
|
||||
py::class<Foo>(m, "Foo")
|
||||
.def(py::init([](...) { // Note: no `self` argument
|
||||
return new Foo(...); // return by raw pointer
|
||||
// or: return std::make_unique<Foo>(...); // return by holder
|
||||
// or: return Foo(...); // return by value (move constructor)
|
||||
}));
|
||||
|
||||
Mirroring the custom constructor changes, ``py::pickle()`` is now the preferred
|
||||
way to get and set object state. See :ref:`pickling` for details.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// old -- deprecated (runtime warning shown only in debug mode)
|
||||
py::class<Foo>(m, "Foo")
|
||||
...
|
||||
.def("__getstate__", [](const Foo &self) {
|
||||
return py::make_tuple(self.value1(), self.value2(), ...);
|
||||
})
|
||||
.def("__setstate__", [](Foo &self, py::tuple t) {
|
||||
new (&self) Foo(t[0].cast<std::string>(), ...);
|
||||
});
|
||||
|
||||
// new
|
||||
py::class<Foo>(m, "Foo")
|
||||
...
|
||||
.def(py::pickle(
|
||||
[](const Foo &self) { // __getstate__
|
||||
return py::make_tuple(self.value1(), self.value2(), ...); // unchanged
|
||||
},
|
||||
[](py::tuple t) { // __setstate__, note: no `self` argument
|
||||
return new Foo(t[0].cast<std::string>(), ...);
|
||||
// or: return std::make_unique<Foo>(...); // return by holder
|
||||
// or: return Foo(...); // return by value (move constructor)
|
||||
}
|
||||
));
|
||||
|
||||
For both the constructors and pickling, warnings are shown at module
|
||||
initialization time (on import, not when the functions are called).
|
||||
They're only visible when compiled in debug mode. Sample warning:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pybind11-bound class 'mymodule.Foo' is using an old-style placement-new '__init__'
|
||||
which has been deprecated. See the upgrade guide in pybind11's docs.
|
||||
|
||||
|
||||
Stricter enforcement of hidden symbol visibility for pybind11 modules
|
||||
---------------------------------------------------------------------
|
||||
|
||||
pybind11 now tries to actively enforce hidden symbol visibility for modules.
|
||||
If you're using either one of pybind11's :doc:`CMake or Python build systems
|
||||
<compiling>` (the two example repositories) and you haven't been exporting any
|
||||
symbols, there's nothing to be concerned about. All the changes have been done
|
||||
transparently in the background. If you were building manually or relied on
|
||||
specific default visibility, read on.
|
||||
|
||||
Setting default symbol visibility to *hidden* has always been recommended for
|
||||
pybind11 (see :ref:`faq:symhidden`). On Linux and macOS, hidden symbol
|
||||
visibility (in conjunction with the ``strip`` utility) yields much smaller
|
||||
module binaries. `CPython's extension docs`_ also recommend hiding symbols
|
||||
by default, with the goal of avoiding symbol name clashes between modules.
|
||||
Starting with v2.2, pybind11 enforces this more strictly: (1) by declaring
|
||||
all symbols inside the ``pybind11`` namespace as hidden and (2) by including
|
||||
the ``-fvisibility=hidden`` flag on Linux and macOS (only for extension
|
||||
modules, not for embedding the interpreter).
|
||||
|
||||
.. _CPython's extension docs: https://docs.python.org/3/extending/extending.html#providing-a-c-api-for-an-extension-module
|
||||
|
||||
The namespace-scope hidden visibility is done automatically in pybind11's
|
||||
headers and it's generally transparent to users. It ensures that:
|
||||
|
||||
* Modules compiled with different pybind11 versions don't clash with each other.
|
||||
|
||||
* Some new features, like ``py::module_local`` bindings, can work as intended.
|
||||
|
||||
The ``-fvisibility=hidden`` flag applies the same visibility to user bindings
|
||||
outside of the ``pybind11`` namespace. It's now set automatic by pybind11's
|
||||
CMake and Python build systems, but this needs to be done manually by users
|
||||
of other build systems. Adding this flag:
|
||||
|
||||
* Minimizes the chances of symbol conflicts between modules. E.g. if two
|
||||
unrelated modules were statically linked to different (ABI-incompatible)
|
||||
versions of the same third-party library, a symbol clash would be likely
|
||||
(and would end with unpredictable results).
|
||||
|
||||
* Produces smaller binaries on Linux and macOS, as pointed out previously.
|
||||
|
||||
Within pybind11's CMake build system, ``pybind11_add_module`` has always been
|
||||
setting the ``-fvisibility=hidden`` flag in release mode. From now on, it's
|
||||
being applied unconditionally, even in debug mode and it can no longer be opted
|
||||
out of with the ``NO_EXTRAS`` option. The ``pybind11::module`` target now also
|
||||
adds this flag to its interface. The ``pybind11::embed`` target is unchanged.
|
||||
|
||||
The most significant change here is for the ``pybind11::module`` target. If you
|
||||
were previously relying on default visibility, i.e. if your Python module was
|
||||
doubling as a shared library with dependents, you'll need to either export
|
||||
symbols manually (recommended for cross-platform libraries) or factor out the
|
||||
shared library (and have the Python module link to it like the other
|
||||
dependents). As a temporary workaround, you can also restore default visibility
|
||||
using the CMake code below, but this is not recommended in the long run:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_link_libraries(mymodule PRIVATE pybind11::module)
|
||||
|
||||
add_library(restore_default_visibility INTERFACE)
|
||||
target_compile_options(restore_default_visibility INTERFACE -fvisibility=default)
|
||||
target_link_libraries(mymodule PRIVATE restore_default_visibility)
|
||||
|
||||
|
||||
Local STL container bindings
|
||||
----------------------------
|
||||
|
||||
Previous pybind11 versions could only bind types globally -- all pybind11
|
||||
modules, even unrelated ones, would have access to the same exported types.
|
||||
However, this would also result in a conflict if two modules exported the
|
||||
same C++ type, which is especially problematic for very common types, e.g.
|
||||
``std::vector<int>``. :ref:`module_local` were added to resolve this (see
|
||||
that section for a complete usage guide).
|
||||
|
||||
``py::class_`` still defaults to global bindings (because these types are
|
||||
usually unique across modules), however in order to avoid clashes of opaque
|
||||
types, ``py::bind_vector`` and ``py::bind_map`` will now bind STL containers
|
||||
as ``py::module_local`` if their elements are: builtins (``int``, ``float``,
|
||||
etc.), not bound using ``py::class_``, or bound as ``py::module_local``. For
|
||||
example, this change allows multiple modules to bind ``std::vector<int>``
|
||||
without causing conflicts. See :ref:`stl_bind` for more details.
|
||||
|
||||
When upgrading to this version, if you have multiple modules which depend on
|
||||
a single global binding of an STL container, note that all modules can still
|
||||
accept foreign ``py::module_local`` types in the direction of Python-to-C++.
|
||||
The locality only affects the C++-to-Python direction. If this is needed in
|
||||
multiple modules, you'll need to either:
|
||||
|
||||
* Add a copy of the same STL binding to all of the modules which need it.
|
||||
|
||||
* Restore the global status of that single binding by marking it
|
||||
``py::module_local(false)``.
|
||||
|
||||
The latter is an easy workaround, but in the long run it would be best to
|
||||
localize all common type bindings in order to avoid conflicts with
|
||||
third-party modules.
|
||||
|
||||
|
||||
Negative strides for Python buffer objects and numpy arrays
|
||||
-----------------------------------------------------------
|
||||
|
||||
Support for negative strides required changing the integer type from unsigned
|
||||
to signed in the interfaces of ``py::buffer_info`` and ``py::array``. If you
|
||||
have compiler warnings enabled, you may notice some new conversion warnings
|
||||
after upgrading. These can be resolved using ``static_cast``.
|
||||
|
||||
|
||||
Deprecation of some ``py::object`` APIs
|
||||
---------------------------------------
|
||||
|
||||
To compare ``py::object`` instances by pointer, you should now use
|
||||
``obj1.is(obj2)`` which is equivalent to ``obj1 is obj2`` in Python.
|
||||
Previously, pybind11 used ``operator==`` for this (``obj1 == obj2``), but
|
||||
that could be confusing and is now deprecated (so that it can eventually
|
||||
be replaced with proper rich object comparison in a future release).
|
||||
|
||||
For classes which inherit from ``py::object``, ``borrowed`` and ``stolen``
|
||||
were previously available as protected constructor tags. Now the types
|
||||
should be used directly instead: ``borrowed_t{}`` and ``stolen_t{}``
|
||||
(`#771 <https://github.com/pybind/pybind11/pull/771>`_).
|
||||
|
||||
|
||||
Stricter compile-time error checking
|
||||
------------------------------------
|
||||
|
||||
Some error checks have been moved from run time to compile time. Notably,
|
||||
automatic conversion of ``std::shared_ptr<T>`` is not possible when ``T`` is
|
||||
not directly registered with ``py::class_<T>`` (e.g. ``std::shared_ptr<int>``
|
||||
or ``std::shared_ptr<std::vector<T>>`` are not automatically convertible).
|
||||
Attempting to bind a function with such arguments now results in a compile-time
|
||||
error instead of waiting to fail at run time.
|
||||
|
||||
``py::init<...>()`` constructor definitions are also stricter and now prevent
|
||||
bindings which could cause unexpected behavior:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
struct Example {
|
||||
Example(int &);
|
||||
};
|
||||
|
||||
py::class_<Example>(m, "Example")
|
||||
.def(py::init<int &>()); // OK, exact match
|
||||
// .def(py::init<int>()); // compile-time error, mismatch
|
||||
|
||||
A non-``const`` lvalue reference is not allowed to bind to an rvalue. However,
|
||||
note that a constructor taking ``const T &`` can still be registered using
|
||||
``py::init<T>()`` because a ``const`` lvalue reference can bind to an rvalue.
|
||||
|
||||
v2.1
|
||||
====
|
||||
|
||||
Minimum compiler versions are enforced at compile time
|
||||
------------------------------------------------------
|
||||
|
||||
The minimums also apply to v2.0 but the check is now explicit and a compile-time
|
||||
error is raised if the compiler does not meet the requirements:
|
||||
|
||||
* GCC >= 4.8
|
||||
* clang >= 3.3 (appleclang >= 5.0)
|
||||
* MSVC >= 2015u3
|
||||
* Intel C++ >= 15.0
|
||||
|
||||
|
||||
The ``py::metaclass`` attribute is not required for static properties
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Binding classes with static properties is now possible by default. The
|
||||
zero-parameter version of ``py::metaclass()`` is deprecated. However, a new
|
||||
one-parameter ``py::metaclass(python_type)`` version was added for rare
|
||||
cases when a custom metaclass is needed to override pybind11's default.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// old -- emits a deprecation warning
|
||||
py::class_<Foo>(m, "Foo", py::metaclass())
|
||||
.def_property_readonly_static("foo", ...);
|
||||
|
||||
// new -- static properties work without the attribute
|
||||
py::class_<Foo>(m, "Foo")
|
||||
.def_property_readonly_static("foo", ...);
|
||||
|
||||
// new -- advanced feature, override pybind11's default metaclass
|
||||
py::class_<Bar>(m, "Bar", py::metaclass(custom_python_type))
|
||||
...
|
||||
|
||||
|
||||
v2.0
|
||||
====
|
||||
|
||||
Breaking changes in ``py::class_``
|
||||
----------------------------------
|
||||
|
||||
These changes were necessary to make type definitions in pybind11
|
||||
future-proof, to support PyPy via its ``cpyext`` mechanism (`#527
|
||||
<https://github.com/pybind/pybind11/pull/527>`_), and to improve efficiency
|
||||
(`rev. 86d825 <https://github.com/pybind/pybind11/commit/86d825>`_).
|
||||
|
||||
1. Declarations of types that provide access via the buffer protocol must
|
||||
now include the ``py::buffer_protocol()`` annotation as an argument to
|
||||
the ``py::class_`` constructor.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::class_<Matrix>("Matrix", py::buffer_protocol())
|
||||
.def(py::init<...>())
|
||||
.def_buffer(...);
|
||||
|
||||
2. Classes which include static properties (e.g. ``def_readwrite_static()``)
|
||||
must now include the ``py::metaclass()`` attribute. Note: this requirement
|
||||
has since been removed in v2.1. If you're upgrading from 1.x, it's
|
||||
recommended to skip directly to v2.1 or newer.
|
||||
|
||||
3. This version of pybind11 uses a redesigned mechanism for instantiating
|
||||
trampoline classes that are used to override virtual methods from within
|
||||
Python. This led to the following user-visible syntax change:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// old v1.x syntax
|
||||
py::class_<TrampolineClass>("MyClass")
|
||||
.alias<MyClass>()
|
||||
...
|
||||
|
||||
// new v2.x syntax
|
||||
py::class_<MyClass, TrampolineClass>("MyClass")
|
||||
...
|
||||
|
||||
Importantly, both the original and the trampoline class are now specified
|
||||
as arguments to the ``py::class_`` template, and the ``alias<..>()`` call
|
||||
is gone. The new scheme has zero overhead in cases when Python doesn't
|
||||
override any functions of the underlying C++ class.
|
||||
`rev. 86d825 <https://github.com/pybind/pybind11/commit/86d825>`_.
|
||||
|
||||
The class type must be the first template argument given to ``py::class_``
|
||||
while the trampoline can be mixed in arbitrary order with other arguments
|
||||
(see the following section).
|
||||
|
||||
|
||||
Deprecation of the ``py::base<T>()`` attribute
|
||||
----------------------------------------------
|
||||
|
||||
``py::base<T>()`` was deprecated in favor of specifying ``T`` as a template
|
||||
argument to ``py::class_``. This new syntax also supports multiple inheritance.
|
||||
Note that, while the type being exported must be the first argument in the
|
||||
``py::class_<Class, ...>`` template, the order of the following types (bases,
|
||||
holder and/or trampoline) is not important.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// old v1.x
|
||||
py::class_<Derived>("Derived", py::base<Base>());
|
||||
|
||||
// new v2.x
|
||||
py::class_<Derived, Base>("Derived");
|
||||
|
||||
// new -- multiple inheritance
|
||||
py::class_<Derived, Base1, Base2>("Derived");
|
||||
|
||||
// new -- apart from `Derived` the argument order can be arbitrary
|
||||
py::class_<Derived, Base1, Holder, Base2, Trampoline>("Derived");
|
||||
|
||||
|
||||
Out-of-the-box support for ``std::shared_ptr``
|
||||
----------------------------------------------
|
||||
|
||||
The relevant type caster is now built in, so it's no longer necessary to
|
||||
include a declaration of the form:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>)
|
||||
|
||||
Continuing to do so won't cause an error or even a deprecation warning,
|
||||
but it's completely redundant.
|
||||
|
||||
|
||||
Deprecation of a few ``py::object`` APIs
|
||||
----------------------------------------
|
||||
|
||||
All of the old-style calls emit deprecation warnings.
|
||||
|
||||
+---------------------------------------+---------------------------------------------+
|
||||
| Old syntax | New syntax |
|
||||
+=======================================+=============================================+
|
||||
| ``obj.call(args...)`` | ``obj(args...)`` |
|
||||
+---------------------------------------+---------------------------------------------+
|
||||
| ``obj.str()`` | ``py::str(obj)`` |
|
||||
+---------------------------------------+---------------------------------------------+
|
||||
| ``auto l = py::list(obj); l.check()`` | ``py::isinstance<py::list>(obj)`` |
|
||||
+---------------------------------------+---------------------------------------------+
|
||||
| ``py::object(ptr, true)`` | ``py::reinterpret_borrow<py::object>(ptr)`` |
|
||||
+---------------------------------------+---------------------------------------------+
|
||||
| ``py::object(ptr, false)`` | ``py::reinterpret_steal<py::object>(ptr)`` |
|
||||
+---------------------------------------+---------------------------------------------+
|
||||
| ``if (obj.attr("foo"))`` | ``if (py::hasattr(obj, "foo"))`` |
|
||||
+---------------------------------------+---------------------------------------------+
|
||||
| ``if (obj["bar"])`` | ``if (obj.contains("bar"))`` |
|
||||
+---------------------------------------+---------------------------------------------+
|
690
thirdparty/pybind11/include/pybind11/attr.h
vendored
Normal file
690
thirdparty/pybind11/include/pybind11/attr.h
vendored
Normal file
@ -0,0 +1,690 @@
|
||||
/*
|
||||
pybind11/attr.h: Infrastructure for processing custom
|
||||
type and function attributes
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "cast.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
/// \addtogroup annotations
|
||||
/// @{
|
||||
|
||||
/// Annotation for methods
|
||||
struct is_method {
|
||||
handle class_;
|
||||
explicit is_method(const handle &c) : class_(c) {}
|
||||
};
|
||||
|
||||
/// Annotation for setters
|
||||
struct is_setter {};
|
||||
|
||||
/// Annotation for operators
|
||||
struct is_operator {};
|
||||
|
||||
/// Annotation for classes that cannot be subclassed
|
||||
struct is_final {};
|
||||
|
||||
/// Annotation for parent scope
|
||||
struct scope {
|
||||
handle value;
|
||||
explicit scope(const handle &s) : value(s) {}
|
||||
};
|
||||
|
||||
/// Annotation for documentation
|
||||
struct doc {
|
||||
const char *value;
|
||||
explicit doc(const char *value) : value(value) {}
|
||||
};
|
||||
|
||||
/// Annotation for function names
|
||||
struct name {
|
||||
const char *value;
|
||||
explicit name(const char *value) : value(value) {}
|
||||
};
|
||||
|
||||
/// Annotation indicating that a function is an overload associated with a given "sibling"
|
||||
struct sibling {
|
||||
handle value;
|
||||
explicit sibling(const handle &value) : value(value.ptr()) {}
|
||||
};
|
||||
|
||||
/// Annotation indicating that a class derives from another given type
|
||||
template <typename T>
|
||||
struct base {
|
||||
|
||||
PYBIND11_DEPRECATED(
|
||||
"base<T>() was deprecated in favor of specifying 'T' as a template argument to class_")
|
||||
base() = default;
|
||||
};
|
||||
|
||||
/// Keep patient alive while nurse lives
|
||||
template <size_t Nurse, size_t Patient>
|
||||
struct keep_alive {};
|
||||
|
||||
/// Annotation indicating that a class is involved in a multiple inheritance relationship
|
||||
struct multiple_inheritance {};
|
||||
|
||||
/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class
|
||||
struct dynamic_attr {};
|
||||
|
||||
/// Annotation which enables the buffer protocol for a type
|
||||
struct buffer_protocol {};
|
||||
|
||||
/// Annotation which requests that a special metaclass is created for a type
|
||||
struct metaclass {
|
||||
handle value;
|
||||
|
||||
PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.")
|
||||
metaclass() = default;
|
||||
|
||||
/// Override pybind11's default metaclass
|
||||
explicit metaclass(handle value) : value(value) {}
|
||||
};
|
||||
|
||||
/// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that
|
||||
/// may be used to customize the Python type.
|
||||
///
|
||||
/// The callback is invoked immediately before `PyType_Ready`.
|
||||
///
|
||||
/// Note: This is an advanced interface, and uses of it may require changes to
|
||||
/// work with later versions of pybind11. You may wish to consult the
|
||||
/// implementation of `make_new_python_type` in `detail/classes.h` to understand
|
||||
/// the context in which the callback will be run.
|
||||
struct custom_type_setup {
|
||||
using callback = std::function<void(PyHeapTypeObject *heap_type)>;
|
||||
|
||||
explicit custom_type_setup(callback value) : value(std::move(value)) {}
|
||||
|
||||
callback value;
|
||||
};
|
||||
|
||||
/// Annotation that marks a class as local to the module:
|
||||
struct module_local {
|
||||
const bool value;
|
||||
constexpr explicit module_local(bool v = true) : value(v) {}
|
||||
};
|
||||
|
||||
/// Annotation to mark enums as an arithmetic type
|
||||
struct arithmetic {};
|
||||
|
||||
/// Mark a function for addition at the beginning of the existing overload chain instead of the end
|
||||
struct prepend {};
|
||||
|
||||
/** \rst
|
||||
A call policy which places one or more guard variables (``Ts...``) around the function call.
|
||||
|
||||
For example, this definition:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("foo", foo, py::call_guard<T>());
|
||||
|
||||
is equivalent to the following pseudocode:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
m.def("foo", [](args...) {
|
||||
T scope_guard;
|
||||
return foo(args...); // forwarded arguments
|
||||
});
|
||||
\endrst */
|
||||
template <typename... Ts>
|
||||
struct call_guard;
|
||||
|
||||
template <>
|
||||
struct call_guard<> {
|
||||
using type = detail::void_type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct call_guard<T> {
|
||||
static_assert(std::is_default_constructible<T>::value,
|
||||
"The guard type must be default constructible");
|
||||
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct call_guard<T, Ts...> {
|
||||
struct type {
|
||||
T guard{}; // Compose multiple guard types with left-to-right default-constructor order
|
||||
typename call_guard<Ts...>::type next{};
|
||||
};
|
||||
};
|
||||
|
||||
/// @} annotations
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
/* Forward declarations */
|
||||
enum op_id : int;
|
||||
enum op_type : int;
|
||||
struct undefined_t;
|
||||
template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>
|
||||
struct op_;
|
||||
void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
|
||||
|
||||
/// Internal data structure which holds metadata about a keyword argument
|
||||
struct argument_record {
|
||||
const char *name; ///< Argument name
|
||||
const char *descr; ///< Human-readable version of the argument value
|
||||
handle value; ///< Associated Python object
|
||||
bool convert : 1; ///< True if the argument is allowed to convert when loading
|
||||
bool none : 1; ///< True if None is allowed when loading
|
||||
|
||||
argument_record(const char *name, const char *descr, handle value, bool convert, bool none)
|
||||
: name(name), descr(descr), value(value), convert(convert), none(none) {}
|
||||
};
|
||||
|
||||
/// Internal data structure which holds metadata about a bound function (signature, overloads,
|
||||
/// etc.)
|
||||
struct function_record {
|
||||
function_record()
|
||||
: is_constructor(false), is_new_style_constructor(false), is_stateless(false),
|
||||
is_operator(false), is_method(false), is_setter(false), has_args(false),
|
||||
has_kwargs(false), prepend(false) {}
|
||||
|
||||
/// Function name
|
||||
char *name = nullptr; /* why no C++ strings? They generate heavier code.. */
|
||||
|
||||
// User-specified documentation string
|
||||
char *doc = nullptr;
|
||||
|
||||
/// Human-readable version of the function signature
|
||||
char *signature = nullptr;
|
||||
|
||||
/// List of registered keyword arguments
|
||||
std::vector<argument_record> args;
|
||||
|
||||
/// Pointer to lambda function which converts arguments and performs the actual call
|
||||
handle (*impl)(function_call &) = nullptr;
|
||||
|
||||
/// Storage for the wrapped function pointer and captured data, if any
|
||||
void *data[3] = {};
|
||||
|
||||
/// Pointer to custom destructor for 'data' (if needed)
|
||||
void (*free_data)(function_record *ptr) = nullptr;
|
||||
|
||||
/// Return value policy associated with this function
|
||||
return_value_policy policy = return_value_policy::automatic;
|
||||
|
||||
/// True if name == '__init__'
|
||||
bool is_constructor : 1;
|
||||
|
||||
/// True if this is a new-style `__init__` defined in `detail/init.h`
|
||||
bool is_new_style_constructor : 1;
|
||||
|
||||
/// True if this is a stateless function pointer
|
||||
bool is_stateless : 1;
|
||||
|
||||
/// True if this is an operator (__add__), etc.
|
||||
bool is_operator : 1;
|
||||
|
||||
/// True if this is a method
|
||||
bool is_method : 1;
|
||||
|
||||
/// True if this is a setter
|
||||
bool is_setter : 1;
|
||||
|
||||
/// True if the function has a '*args' argument
|
||||
bool has_args : 1;
|
||||
|
||||
/// True if the function has a '**kwargs' argument
|
||||
bool has_kwargs : 1;
|
||||
|
||||
/// True if this function is to be inserted at the beginning of the overload resolution chain
|
||||
bool prepend : 1;
|
||||
|
||||
/// Number of arguments (including py::args and/or py::kwargs, if present)
|
||||
std::uint16_t nargs;
|
||||
|
||||
/// Number of leading positional arguments, which are terminated by a py::args or py::kwargs
|
||||
/// argument or by a py::kw_only annotation.
|
||||
std::uint16_t nargs_pos = 0;
|
||||
|
||||
/// Number of leading arguments (counted in `nargs`) that are positional-only
|
||||
std::uint16_t nargs_pos_only = 0;
|
||||
|
||||
/// Python method object
|
||||
PyMethodDef *def = nullptr;
|
||||
|
||||
/// Python handle to the parent scope (a class or a module)
|
||||
handle scope;
|
||||
|
||||
/// Python handle to the sibling function representing an overload chain
|
||||
handle sibling;
|
||||
|
||||
/// Pointer to next overload
|
||||
function_record *next = nullptr;
|
||||
};
|
||||
|
||||
/// Special data structure which (temporarily) holds metadata about a bound class
|
||||
struct type_record {
|
||||
PYBIND11_NOINLINE type_record()
|
||||
: multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),
|
||||
default_holder(true), module_local(false), is_final(false) {}
|
||||
|
||||
/// Handle to the parent scope
|
||||
handle scope;
|
||||
|
||||
/// Name of the class
|
||||
const char *name = nullptr;
|
||||
|
||||
// Pointer to RTTI type_info data structure
|
||||
const std::type_info *type = nullptr;
|
||||
|
||||
/// How large is the underlying C++ type?
|
||||
size_t type_size = 0;
|
||||
|
||||
/// What is the alignment of the underlying C++ type?
|
||||
size_t type_align = 0;
|
||||
|
||||
/// How large is the type's holder?
|
||||
size_t holder_size = 0;
|
||||
|
||||
/// The global operator new can be overridden with a class-specific variant
|
||||
void *(*operator_new)(size_t) = nullptr;
|
||||
|
||||
/// Function pointer to class_<..>::init_instance
|
||||
void (*init_instance)(instance *, const void *) = nullptr;
|
||||
|
||||
/// Function pointer to class_<..>::dealloc
|
||||
void (*dealloc)(detail::value_and_holder &) = nullptr;
|
||||
|
||||
/// List of base classes of the newly created type
|
||||
list bases;
|
||||
|
||||
/// Optional docstring
|
||||
const char *doc = nullptr;
|
||||
|
||||
/// Custom metaclass (optional)
|
||||
handle metaclass;
|
||||
|
||||
/// Custom type setup.
|
||||
custom_type_setup::callback custom_type_setup_callback;
|
||||
|
||||
/// Multiple inheritance marker
|
||||
bool multiple_inheritance : 1;
|
||||
|
||||
/// Does the class manage a __dict__?
|
||||
bool dynamic_attr : 1;
|
||||
|
||||
/// Does the class implement the buffer protocol?
|
||||
bool buffer_protocol : 1;
|
||||
|
||||
/// Is the default (unique_ptr) holder type used?
|
||||
bool default_holder : 1;
|
||||
|
||||
/// Is the class definition local to the module shared object?
|
||||
bool module_local : 1;
|
||||
|
||||
/// Is the class inheritable from python classes?
|
||||
bool is_final : 1;
|
||||
|
||||
PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {
|
||||
auto *base_info = detail::get_type_info(base, false);
|
||||
if (!base_info) {
|
||||
std::string tname(base.name());
|
||||
detail::clean_type_id(tname);
|
||||
pybind11_fail("generic_type: type \"" + std::string(name)
|
||||
+ "\" referenced unknown base type \"" + tname + "\"");
|
||||
}
|
||||
|
||||
if (default_holder != base_info->default_holder) {
|
||||
std::string tname(base.name());
|
||||
detail::clean_type_id(tname);
|
||||
pybind11_fail("generic_type: type \"" + std::string(name) + "\" "
|
||||
+ (default_holder ? "does not have" : "has")
|
||||
+ " a non-default holder type while its base \"" + tname + "\" "
|
||||
+ (base_info->default_holder ? "does not" : "does"));
|
||||
}
|
||||
|
||||
bases.append((PyObject *) base_info->type);
|
||||
|
||||
#if PY_VERSION_HEX < 0x030B0000
|
||||
dynamic_attr |= base_info->type->tp_dictoffset != 0;
|
||||
#else
|
||||
dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0;
|
||||
#endif
|
||||
|
||||
if (caster) {
|
||||
base_info->implicit_casts.emplace_back(type, caster);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) {
|
||||
args.reserve(f.nargs);
|
||||
args_convert.reserve(f.nargs);
|
||||
}
|
||||
|
||||
/// Tag for a new-style `__init__` defined in `detail/init.h`
|
||||
struct is_new_style_constructor {};
|
||||
|
||||
/**
|
||||
* Partial template specializations to process custom attributes provided to
|
||||
* cpp_function_ and class_. These are either used to initialize the respective
|
||||
* fields in the type_record and function_record data structures or executed at
|
||||
* runtime to deal with custom call policies (e.g. keep_alive).
|
||||
*/
|
||||
template <typename T, typename SFINAE = void>
|
||||
struct process_attribute;
|
||||
|
||||
template <typename T>
|
||||
struct process_attribute_default {
|
||||
/// Default implementation: do nothing
|
||||
static void init(const T &, function_record *) {}
|
||||
static void init(const T &, type_record *) {}
|
||||
static void precall(function_call &) {}
|
||||
static void postcall(function_call &, handle) {}
|
||||
};
|
||||
|
||||
/// Process an attribute specifying the function's name
|
||||
template <>
|
||||
struct process_attribute<name> : process_attribute_default<name> {
|
||||
static void init(const name &n, function_record *r) { r->name = const_cast<char *>(n.value); }
|
||||
};
|
||||
|
||||
/// Process an attribute specifying the function's docstring
|
||||
template <>
|
||||
struct process_attribute<doc> : process_attribute_default<doc> {
|
||||
static void init(const doc &n, function_record *r) { r->doc = const_cast<char *>(n.value); }
|
||||
};
|
||||
|
||||
/// Process an attribute specifying the function's docstring (provided as a C-style string)
|
||||
template <>
|
||||
struct process_attribute<const char *> : process_attribute_default<const char *> {
|
||||
static void init(const char *d, function_record *r) { r->doc = const_cast<char *>(d); }
|
||||
static void init(const char *d, type_record *r) { r->doc = d; }
|
||||
};
|
||||
template <>
|
||||
struct process_attribute<char *> : process_attribute<const char *> {};
|
||||
|
||||
/// Process an attribute indicating the function's return value policy
|
||||
template <>
|
||||
struct process_attribute<return_value_policy> : process_attribute_default<return_value_policy> {
|
||||
static void init(const return_value_policy &p, function_record *r) { r->policy = p; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this is an overloaded function associated with a
|
||||
/// given sibling
|
||||
template <>
|
||||
struct process_attribute<sibling> : process_attribute_default<sibling> {
|
||||
static void init(const sibling &s, function_record *r) { r->sibling = s.value; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this function is a method
|
||||
template <>
|
||||
struct process_attribute<is_method> : process_attribute_default<is_method> {
|
||||
static void init(const is_method &s, function_record *r) {
|
||||
r->is_method = true;
|
||||
r->scope = s.class_;
|
||||
}
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this function is a setter
|
||||
template <>
|
||||
struct process_attribute<is_setter> : process_attribute_default<is_setter> {
|
||||
static void init(const is_setter &, function_record *r) { r->is_setter = true; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates the parent scope of a method
|
||||
template <>
|
||||
struct process_attribute<scope> : process_attribute_default<scope> {
|
||||
static void init(const scope &s, function_record *r) { r->scope = s.value; }
|
||||
};
|
||||
|
||||
/// Process an attribute which indicates that this function is an operator
|
||||
template <>
|
||||
struct process_attribute<is_operator> : process_attribute_default<is_operator> {
|
||||
static void init(const is_operator &, function_record *r) { r->is_operator = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<is_new_style_constructor>
|
||||
: process_attribute_default<is_new_style_constructor> {
|
||||
static void init(const is_new_style_constructor &, function_record *r) {
|
||||
r->is_new_style_constructor = true;
|
||||
}
|
||||
};
|
||||
|
||||
inline void check_kw_only_arg(const arg &a, function_record *r) {
|
||||
if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\0')) {
|
||||
pybind11_fail("arg(): cannot specify an unnamed argument after a kw_only() annotation or "
|
||||
"args() argument");
|
||||
}
|
||||
}
|
||||
|
||||
inline void append_self_arg_if_needed(function_record *r) {
|
||||
if (r->is_method && r->args.empty()) {
|
||||
r->args.emplace_back("self", nullptr, handle(), /*convert=*/true, /*none=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
/// Process a keyword argument attribute (*without* a default value)
|
||||
template <>
|
||||
struct process_attribute<arg> : process_attribute_default<arg> {
|
||||
static void init(const arg &a, function_record *r) {
|
||||
append_self_arg_if_needed(r);
|
||||
r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);
|
||||
|
||||
check_kw_only_arg(a, r);
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a keyword argument attribute (*with* a default value)
|
||||
template <>
|
||||
struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
||||
static void init(const arg_v &a, function_record *r) {
|
||||
if (r->is_method && r->args.empty()) {
|
||||
r->args.emplace_back(
|
||||
"self", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false);
|
||||
}
|
||||
|
||||
if (!a.value) {
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
std::string descr("'");
|
||||
if (a.name) {
|
||||
descr += std::string(a.name) + ": ";
|
||||
}
|
||||
descr += a.type + "'";
|
||||
if (r->is_method) {
|
||||
if (r->name) {
|
||||
descr += " in method '" + (std::string) str(r->scope) + "."
|
||||
+ (std::string) r->name + "'";
|
||||
} else {
|
||||
descr += " in method of '" + (std::string) str(r->scope) + "'";
|
||||
}
|
||||
} else if (r->name) {
|
||||
descr += " in function '" + (std::string) r->name + "'";
|
||||
}
|
||||
pybind11_fail("arg(): could not convert default argument " + descr
|
||||
+ " into a Python object (type not registered yet?)");
|
||||
#else
|
||||
pybind11_fail("arg(): could not convert default argument "
|
||||
"into a Python object (type not registered yet?). "
|
||||
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
|
||||
"more information.");
|
||||
#endif
|
||||
}
|
||||
r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
|
||||
|
||||
check_kw_only_arg(a, r);
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a keyword-only-arguments-follow pseudo argument
|
||||
template <>
|
||||
struct process_attribute<kw_only> : process_attribute_default<kw_only> {
|
||||
static void init(const kw_only &, function_record *r) {
|
||||
append_self_arg_if_needed(r);
|
||||
if (r->has_args && r->nargs_pos != static_cast<std::uint16_t>(r->args.size())) {
|
||||
pybind11_fail("Mismatched args() and kw_only(): they must occur at the same relative "
|
||||
"argument location (or omit kw_only() entirely)");
|
||||
}
|
||||
r->nargs_pos = static_cast<std::uint16_t>(r->args.size());
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a positional-only-argument maker
|
||||
template <>
|
||||
struct process_attribute<pos_only> : process_attribute_default<pos_only> {
|
||||
static void init(const pos_only &, function_record *r) {
|
||||
append_self_arg_if_needed(r);
|
||||
r->nargs_pos_only = static_cast<std::uint16_t>(r->args.size());
|
||||
if (r->nargs_pos_only > r->nargs_pos) {
|
||||
pybind11_fail("pos_only(): cannot follow a py::args() argument");
|
||||
}
|
||||
// It also can't follow a kw_only, but a static_assert in pybind11.h checks that
|
||||
}
|
||||
};
|
||||
|
||||
/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees
|
||||
/// that)
|
||||
template <typename T>
|
||||
struct process_attribute<T, enable_if_t<is_pyobject<T>::value>>
|
||||
: process_attribute_default<handle> {
|
||||
static void init(const handle &h, type_record *r) { r->bases.append(h); }
|
||||
};
|
||||
|
||||
/// Process a parent class attribute (deprecated, does not support multiple inheritance)
|
||||
template <typename T>
|
||||
struct process_attribute<base<T>> : process_attribute_default<base<T>> {
|
||||
static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }
|
||||
};
|
||||
|
||||
/// Process a multiple inheritance attribute
|
||||
template <>
|
||||
struct process_attribute<multiple_inheritance> : process_attribute_default<multiple_inheritance> {
|
||||
static void init(const multiple_inheritance &, type_record *r) {
|
||||
r->multiple_inheritance = true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr> {
|
||||
static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<custom_type_setup> {
|
||||
static void init(const custom_type_setup &value, type_record *r) {
|
||||
r->custom_type_setup_callback = value.value;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<is_final> : process_attribute_default<is_final> {
|
||||
static void init(const is_final &, type_record *r) { r->is_final = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {
|
||||
static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<metaclass> : process_attribute_default<metaclass> {
|
||||
static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct process_attribute<module_local> : process_attribute_default<module_local> {
|
||||
static void init(const module_local &l, type_record *r) { r->module_local = l.value; }
|
||||
};
|
||||
|
||||
/// Process a 'prepend' attribute, putting this at the beginning of the overload chain
|
||||
template <>
|
||||
struct process_attribute<prepend> : process_attribute_default<prepend> {
|
||||
static void init(const prepend &, function_record *r) { r->prepend = true; }
|
||||
};
|
||||
|
||||
/// Process an 'arithmetic' attribute for enums (does nothing here)
|
||||
template <>
|
||||
struct process_attribute<arithmetic> : process_attribute_default<arithmetic> {};
|
||||
|
||||
template <typename... Ts>
|
||||
struct process_attribute<call_guard<Ts...>> : process_attribute_default<call_guard<Ts...>> {};
|
||||
|
||||
/**
|
||||
* Process a keep_alive call policy -- invokes keep_alive_impl during the
|
||||
* pre-call handler if both Nurse, Patient != 0 and use the post-call handler
|
||||
* otherwise
|
||||
*/
|
||||
template <size_t Nurse, size_t Patient>
|
||||
struct process_attribute<keep_alive<Nurse, Patient>>
|
||||
: public process_attribute_default<keep_alive<Nurse, Patient>> {
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
|
||||
static void precall(function_call &call) {
|
||||
keep_alive_impl(Nurse, Patient, call, handle());
|
||||
}
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>
|
||||
static void postcall(function_call &, handle) {}
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
|
||||
static void precall(function_call &) {}
|
||||
template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>
|
||||
static void postcall(function_call &call, handle ret) {
|
||||
keep_alive_impl(Nurse, Patient, call, ret);
|
||||
}
|
||||
};
|
||||
|
||||
/// Recursively iterate over variadic template arguments
|
||||
template <typename... Args>
|
||||
struct process_attributes {
|
||||
static void init(const Args &...args, function_record *r) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
|
||||
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
|
||||
using expander = int[];
|
||||
(void) expander{
|
||||
0, ((void) process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
|
||||
}
|
||||
static void init(const Args &...args, type_record *r) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);
|
||||
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);
|
||||
using expander = int[];
|
||||
(void) expander{0,
|
||||
(process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};
|
||||
}
|
||||
static void precall(function_call &call) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call);
|
||||
using expander = int[];
|
||||
(void) expander{0,
|
||||
(process_attribute<typename std::decay<Args>::type>::precall(call), 0)...};
|
||||
}
|
||||
static void postcall(function_call &call, handle fn_ret) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret);
|
||||
PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret);
|
||||
using expander = int[];
|
||||
(void) expander{
|
||||
0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0)...};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using is_call_guard = is_instantiation<call_guard, T>;
|
||||
|
||||
/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)
|
||||
template <typename... Extra>
|
||||
using extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;
|
||||
|
||||
/// Check the number of named arguments at compile time
|
||||
template <typename... Extra,
|
||||
size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),
|
||||
size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>
|
||||
constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs);
|
||||
return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
208
thirdparty/pybind11/include/pybind11/buffer_info.h
vendored
Normal file
208
thirdparty/pybind11/include/pybind11/buffer_info.h
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
pybind11/buffer_info.h: Python buffer object interface
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
// Default, C-style strides
|
||||
inline std::vector<ssize_t> c_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
|
||||
auto ndim = shape.size();
|
||||
std::vector<ssize_t> strides(ndim, itemsize);
|
||||
if (ndim > 0) {
|
||||
for (size_t i = ndim - 1; i > 0; --i) {
|
||||
strides[i - 1] = strides[i] * shape[i];
|
||||
}
|
||||
}
|
||||
return strides;
|
||||
}
|
||||
|
||||
// F-style strides; default when constructing an array_t with `ExtraFlags & f_style`
|
||||
inline std::vector<ssize_t> f_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {
|
||||
auto ndim = shape.size();
|
||||
std::vector<ssize_t> strides(ndim, itemsize);
|
||||
for (size_t i = 1; i < ndim; ++i) {
|
||||
strides[i] = strides[i - 1] * shape[i - 1];
|
||||
}
|
||||
return strides;
|
||||
}
|
||||
|
||||
template <typename T, typename SFINAE = void>
|
||||
struct compare_buffer_info;
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/// Information record describing a Python buffer object
|
||||
struct buffer_info {
|
||||
void *ptr = nullptr; // Pointer to the underlying storage
|
||||
ssize_t itemsize = 0; // Size of individual items in bytes
|
||||
ssize_t size = 0; // Total number of entries
|
||||
std::string format; // For homogeneous buffers, this should be set to
|
||||
// format_descriptor<T>::format()
|
||||
ssize_t ndim = 0; // Number of dimensions
|
||||
std::vector<ssize_t> shape; // Shape of the tensor (1 entry per dimension)
|
||||
std::vector<ssize_t> strides; // Number of bytes between adjacent entries
|
||||
// (for each per dimension)
|
||||
bool readonly = false; // flag to indicate if the underlying storage may be written to
|
||||
|
||||
buffer_info() = default;
|
||||
|
||||
buffer_info(void *ptr,
|
||||
ssize_t itemsize,
|
||||
const std::string &format,
|
||||
ssize_t ndim,
|
||||
detail::any_container<ssize_t> shape_in,
|
||||
detail::any_container<ssize_t> strides_in,
|
||||
bool readonly = false)
|
||||
: ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim),
|
||||
shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) {
|
||||
if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) {
|
||||
pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length");
|
||||
}
|
||||
for (size_t i = 0; i < (size_t) ndim; ++i) {
|
||||
size *= shape[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
buffer_info(T *ptr,
|
||||
detail::any_container<ssize_t> shape_in,
|
||||
detail::any_container<ssize_t> strides_in,
|
||||
bool readonly = false)
|
||||
: buffer_info(private_ctr_tag(),
|
||||
ptr,
|
||||
sizeof(T),
|
||||
format_descriptor<T>::format(),
|
||||
static_cast<ssize_t>(shape_in->size()),
|
||||
std::move(shape_in),
|
||||
std::move(strides_in),
|
||||
readonly) {}
|
||||
|
||||
buffer_info(void *ptr,
|
||||
ssize_t itemsize,
|
||||
const std::string &format,
|
||||
ssize_t size,
|
||||
bool readonly = false)
|
||||
: buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {}
|
||||
|
||||
template <typename T>
|
||||
buffer_info(T *ptr, ssize_t size, bool readonly = false)
|
||||
: buffer_info(ptr, sizeof(T), format_descriptor<T>::format(), size, readonly) {}
|
||||
|
||||
template <typename T>
|
||||
buffer_info(const T *ptr, ssize_t size, bool readonly = true)
|
||||
: buffer_info(
|
||||
const_cast<T *>(ptr), sizeof(T), format_descriptor<T>::format(), size, readonly) {}
|
||||
|
||||
explicit buffer_info(Py_buffer *view, bool ownview = true)
|
||||
: buffer_info(
|
||||
view->buf,
|
||||
view->itemsize,
|
||||
view->format,
|
||||
view->ndim,
|
||||
{view->shape, view->shape + view->ndim},
|
||||
/* Though buffer::request() requests PyBUF_STRIDES, ctypes objects
|
||||
* ignore this flag and return a view with NULL strides.
|
||||
* When strides are NULL, build them manually. */
|
||||
view->strides
|
||||
? std::vector<ssize_t>(view->strides, view->strides + view->ndim)
|
||||
: detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize),
|
||||
(view->readonly != 0)) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
||||
this->m_view = view;
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
|
||||
this->ownview = ownview;
|
||||
}
|
||||
|
||||
buffer_info(const buffer_info &) = delete;
|
||||
buffer_info &operator=(const buffer_info &) = delete;
|
||||
|
||||
buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); }
|
||||
|
||||
buffer_info &operator=(buffer_info &&rhs) noexcept {
|
||||
ptr = rhs.ptr;
|
||||
itemsize = rhs.itemsize;
|
||||
size = rhs.size;
|
||||
format = std::move(rhs.format);
|
||||
ndim = rhs.ndim;
|
||||
shape = std::move(rhs.shape);
|
||||
strides = std::move(rhs.strides);
|
||||
std::swap(m_view, rhs.m_view);
|
||||
std::swap(ownview, rhs.ownview);
|
||||
readonly = rhs.readonly;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~buffer_info() {
|
||||
if (m_view && ownview) {
|
||||
PyBuffer_Release(m_view);
|
||||
delete m_view;
|
||||
}
|
||||
}
|
||||
|
||||
Py_buffer *view() const { return m_view; }
|
||||
Py_buffer *&view() { return m_view; }
|
||||
|
||||
/* True if the buffer item type is equivalent to `T`. */
|
||||
// To define "equivalent" by example:
|
||||
// `buffer_info::item_type_is_equivalent_to<int>(b)` and
|
||||
// `buffer_info::item_type_is_equivalent_to<long>(b)` may both be true
|
||||
// on some platforms, but `int` and `unsigned` will never be equivalent.
|
||||
// For the ground truth, please inspect `detail::compare_buffer_info<>`.
|
||||
template <typename T>
|
||||
bool item_type_is_equivalent_to() const {
|
||||
return detail::compare_buffer_info<T>::compare(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
struct private_ctr_tag {};
|
||||
|
||||
buffer_info(private_ctr_tag,
|
||||
void *ptr,
|
||||
ssize_t itemsize,
|
||||
const std::string &format,
|
||||
ssize_t ndim,
|
||||
detail::any_container<ssize_t> &&shape_in,
|
||||
detail::any_container<ssize_t> &&strides_in,
|
||||
bool readonly)
|
||||
: buffer_info(
|
||||
ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {}
|
||||
|
||||
Py_buffer *m_view = nullptr;
|
||||
bool ownview = false;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename T, typename SFINAE>
|
||||
struct compare_buffer_info {
|
||||
static bool compare(const buffer_info &b) {
|
||||
// NOLINTNEXTLINE(bugprone-sizeof-expression) Needed for `PyObject *`
|
||||
return b.format == format_descriptor<T>::format() && b.itemsize == (ssize_t) sizeof(T);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {
|
||||
static bool compare(const buffer_info &b) {
|
||||
return (size_t) b.itemsize == sizeof(T)
|
||||
&& (b.format == format_descriptor<T>::value
|
||||
|| ((sizeof(T) == sizeof(long))
|
||||
&& b.format == (std::is_unsigned<T>::value ? "L" : "l"))
|
||||
|| ((sizeof(T) == sizeof(size_t))
|
||||
&& b.format == (std::is_unsigned<T>::value ? "N" : "n")));
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
1730
thirdparty/pybind11/include/pybind11/cast.h
vendored
Normal file
1730
thirdparty/pybind11/include/pybind11/cast.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
225
thirdparty/pybind11/include/pybind11/chrono.h
vendored
Normal file
225
thirdparty/pybind11/include/pybind11/chrono.h
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime
|
||||
|
||||
Copyright (c) 2016 Trent Houliston <trent@houliston.me> and
|
||||
Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <datetime.h>
|
||||
#include <mutex>
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename type>
|
||||
class duration_caster {
|
||||
public:
|
||||
using rep = typename type::rep;
|
||||
using period = typename type::period;
|
||||
|
||||
// signed 25 bits required by the standard.
|
||||
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
|
||||
|
||||
bool load(handle src, bool) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
// If invoked with datetime.delta object
|
||||
if (PyDelta_Check(src.ptr())) {
|
||||
value = type(duration_cast<duration<rep, period>>(
|
||||
days(PyDateTime_DELTA_GET_DAYS(src.ptr()))
|
||||
+ seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr()))
|
||||
+ microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))));
|
||||
return true;
|
||||
}
|
||||
// If invoked with a float we assume it is seconds and convert
|
||||
if (PyFloat_Check(src.ptr())) {
|
||||
value = type(duration_cast<duration<rep, period>>(
|
||||
duration<double>(PyFloat_AsDouble(src.ptr()))));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this is a duration just return it back
|
||||
static const std::chrono::duration<rep, period> &
|
||||
get_duration(const std::chrono::duration<rep, period> &src) {
|
||||
return src;
|
||||
}
|
||||
|
||||
// If this is a time_point get the time_since_epoch
|
||||
template <typename Clock>
|
||||
static std::chrono::duration<rep, period>
|
||||
get_duration(const std::chrono::time_point<Clock, std::chrono::duration<rep, period>> &src) {
|
||||
return src.time_since_epoch();
|
||||
}
|
||||
|
||||
static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Use overloaded function to get our duration from our source
|
||||
// Works out if it is a duration or time_point and get the duration
|
||||
auto d = get_duration(src);
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
// Declare these special duration types so the conversions happen with the correct
|
||||
// primitive types (int)
|
||||
using dd_t = duration<int, std::ratio<86400>>;
|
||||
using ss_t = duration<int, std::ratio<1>>;
|
||||
using us_t = duration<int, std::micro>;
|
||||
|
||||
auto dd = duration_cast<dd_t>(d);
|
||||
auto subd = d - dd;
|
||||
auto ss = duration_cast<ss_t>(subd);
|
||||
auto us = duration_cast<us_t>(subd - ss);
|
||||
return PyDelta_FromDSU(dd.count(), ss.count(), us.count());
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(type, const_name("datetime.timedelta"));
|
||||
};
|
||||
|
||||
inline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) {
|
||||
#if (defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || defined(_MSC_VER)
|
||||
if (localtime_s(buf, time))
|
||||
return nullptr;
|
||||
return buf;
|
||||
#else
|
||||
static std::mutex mtx;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
std::tm *tm_ptr = std::localtime(time);
|
||||
if (tm_ptr != nullptr) {
|
||||
*buf = *tm_ptr;
|
||||
}
|
||||
return tm_ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This is for casting times on the system clock into datetime.datetime instances
|
||||
template <typename Duration>
|
||||
class type_caster<std::chrono::time_point<std::chrono::system_clock, Duration>> {
|
||||
public:
|
||||
using type = std::chrono::time_point<std::chrono::system_clock, Duration>;
|
||||
bool load(handle src, bool) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tm cal;
|
||||
microseconds msecs;
|
||||
|
||||
if (PyDateTime_Check(src.ptr())) {
|
||||
cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr());
|
||||
cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr());
|
||||
cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr());
|
||||
cal.tm_mday = PyDateTime_GET_DAY(src.ptr());
|
||||
cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;
|
||||
cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;
|
||||
cal.tm_isdst = -1;
|
||||
msecs = microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr()));
|
||||
} else if (PyDate_Check(src.ptr())) {
|
||||
cal.tm_sec = 0;
|
||||
cal.tm_min = 0;
|
||||
cal.tm_hour = 0;
|
||||
cal.tm_mday = PyDateTime_GET_DAY(src.ptr());
|
||||
cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;
|
||||
cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;
|
||||
cal.tm_isdst = -1;
|
||||
msecs = microseconds(0);
|
||||
} else if (PyTime_Check(src.ptr())) {
|
||||
cal.tm_sec = PyDateTime_TIME_GET_SECOND(src.ptr());
|
||||
cal.tm_min = PyDateTime_TIME_GET_MINUTE(src.ptr());
|
||||
cal.tm_hour = PyDateTime_TIME_GET_HOUR(src.ptr());
|
||||
cal.tm_mday = 1; // This date (day, month, year) = (1, 0, 70)
|
||||
cal.tm_mon = 0; // represents 1-Jan-1970, which is the first
|
||||
cal.tm_year = 70; // earliest available date for Python's datetime
|
||||
cal.tm_isdst = -1;
|
||||
msecs = microseconds(PyDateTime_TIME_GET_MICROSECOND(src.ptr()));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
value = time_point_cast<Duration>(system_clock::from_time_t(std::mktime(&cal)) + msecs);
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle cast(const std::chrono::time_point<std::chrono::system_clock, Duration> &src,
|
||||
return_value_policy /* policy */,
|
||||
handle /* parent */) {
|
||||
using namespace std::chrono;
|
||||
|
||||
// Lazy initialise the PyDateTime import
|
||||
if (!PyDateTimeAPI) {
|
||||
PyDateTime_IMPORT;
|
||||
}
|
||||
|
||||
// Get out microseconds, and make sure they are positive, to avoid bug in eastern
|
||||
// hemisphere time zones (cfr. https://github.com/pybind/pybind11/issues/2417)
|
||||
using us_t = duration<int, std::micro>;
|
||||
auto us = duration_cast<us_t>(src.time_since_epoch() % seconds(1));
|
||||
if (us.count() < 0) {
|
||||
us += seconds(1);
|
||||
}
|
||||
|
||||
// Subtract microseconds BEFORE `system_clock::to_time_t`, because:
|
||||
// > If std::time_t has lower precision, it is implementation-defined whether the value is
|
||||
// rounded or truncated. (https://en.cppreference.com/w/cpp/chrono/system_clock/to_time_t)
|
||||
std::time_t tt
|
||||
= system_clock::to_time_t(time_point_cast<system_clock::duration>(src - us));
|
||||
|
||||
std::tm localtime;
|
||||
std::tm *localtime_ptr = localtime_thread_safe(&tt, &localtime);
|
||||
if (!localtime_ptr) {
|
||||
throw cast_error("Unable to represent system_clock in local time");
|
||||
}
|
||||
return PyDateTime_FromDateAndTime(localtime.tm_year + 1900,
|
||||
localtime.tm_mon + 1,
|
||||
localtime.tm_mday,
|
||||
localtime.tm_hour,
|
||||
localtime.tm_min,
|
||||
localtime.tm_sec,
|
||||
us.count());
|
||||
}
|
||||
PYBIND11_TYPE_CASTER(type, const_name("datetime.datetime"));
|
||||
};
|
||||
|
||||
// Other clocks that are not the system clock are not measured as datetime.datetime objects
|
||||
// since they are not measured on calendar time. So instead we just make them timedeltas
|
||||
// Or if they have passed us a time as a float we convert that
|
||||
template <typename Clock, typename Duration>
|
||||
class type_caster<std::chrono::time_point<Clock, Duration>>
|
||||
: public duration_caster<std::chrono::time_point<Clock, Duration>> {};
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
class type_caster<std::chrono::duration<Rep, Period>>
|
||||
: public duration_caster<std::chrono::duration<Rep, Period>> {};
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
2
thirdparty/pybind11/include/pybind11/common.h
vendored
Normal file
2
thirdparty/pybind11/include/pybind11/common.h
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
#include "detail/common.h"
|
||||
#warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'."
|
74
thirdparty/pybind11/include/pybind11/complex.h
vendored
Normal file
74
thirdparty/pybind11/include/pybind11/complex.h
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
pybind11/complex.h: Complex number support
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pybind11.h"
|
||||
|
||||
#include <complex>
|
||||
|
||||
/// glibc defines I as a macro which breaks things, e.g., boost template names
|
||||
#ifdef I
|
||||
# undef I
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
template <typename T>
|
||||
struct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
|
||||
static constexpr const char c = format_descriptor<T>::c;
|
||||
static constexpr const char value[3] = {'Z', c, '\0'};
|
||||
static std::string format() { return std::string(value); }
|
||||
};
|
||||
|
||||
#ifndef PYBIND11_CPP17
|
||||
|
||||
template <typename T>
|
||||
constexpr const char
|
||||
format_descriptor<std::complex<T>,
|
||||
detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];
|
||||
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <typename T>
|
||||
struct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {
|
||||
static constexpr bool value = true;
|
||||
static constexpr int index = is_fmt_numeric<T>::index + 3;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class type_caster<std::complex<T>> {
|
||||
public:
|
||||
bool load(handle src, bool convert) {
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
if (!convert && !PyComplex_Check(src.ptr())) {
|
||||
return false;
|
||||
}
|
||||
Py_complex result = PyComplex_AsCComplex(src.ptr());
|
||||
if (result.real == -1.0 && PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
value = std::complex<T>((T) result.real, (T) result.imag);
|
||||
return true;
|
||||
}
|
||||
|
||||
static handle
|
||||
cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) {
|
||||
return PyComplex_FromDoubles((double) src.real(), (double) src.imag());
|
||||
}
|
||||
|
||||
PYBIND11_TYPE_CASTER(std::complex<T>, const_name("complex"));
|
||||
};
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
748
thirdparty/pybind11/include/pybind11/detail/class.h
vendored
Normal file
748
thirdparty/pybind11/include/pybind11/detail/class.h
vendored
Normal file
@ -0,0 +1,748 @@
|
||||
/*
|
||||
pybind11/detail/class.h: Python C API implementation details for py::class_
|
||||
|
||||
Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../attr.h"
|
||||
#include "../options.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
#if !defined(PYPY_VERSION)
|
||||
# define PYBIND11_BUILTIN_QUALNAME
|
||||
# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
|
||||
#else
|
||||
// In PyPy, we still set __qualname__ so that we can produce reliable function type
|
||||
// signatures; in CPython this macro expands to nothing:
|
||||
# define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) \
|
||||
setattr((PyObject *) obj, "__qualname__", nameobj)
|
||||
#endif
|
||||
|
||||
inline std::string get_fully_qualified_tp_name(PyTypeObject *type) {
|
||||
#if !defined(PYPY_VERSION)
|
||||
return type->tp_name;
|
||||
#else
|
||||
auto module_name = handle((PyObject *) type).attr("__module__").cast<std::string>();
|
||||
if (module_name == PYBIND11_BUILTINS_MODULE)
|
||||
return type->tp_name;
|
||||
else
|
||||
return std::move(module_name) + "." + type->tp_name;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline PyTypeObject *type_incref(PyTypeObject *type) {
|
||||
Py_INCREF(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
#if !defined(PYPY_VERSION)
|
||||
|
||||
/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance.
|
||||
extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) {
|
||||
return PyProperty_Type.tp_descr_get(self, cls, cls);
|
||||
}
|
||||
|
||||
/// `pybind11_static_property.__set__()`: Just like the above `__get__()`.
|
||||
extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {
|
||||
PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);
|
||||
return PyProperty_Type.tp_descr_set(self, cls, value);
|
||||
}
|
||||
|
||||
// Forward declaration to use in `make_static_property_type()`
|
||||
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type);
|
||||
|
||||
/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()`
|
||||
methods are modified to always use the object type instead of a concrete instance.
|
||||
Return value: New reference. */
|
||||
inline PyTypeObject *make_static_property_type() {
|
||||
constexpr auto *name = "pybind11_static_property";
|
||||
auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail("make_static_property_type(): error allocating type!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name_obj.inc_ref().ptr();
|
||||
# ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = name_obj.inc_ref().ptr();
|
||||
# endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = name;
|
||||
type->tp_base = type_incref(&PyProperty_Type);
|
||||
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
|
||||
type->tp_descr_get = pybind11_static_get;
|
||||
type->tp_descr_set = pybind11_static_set;
|
||||
|
||||
# if PY_VERSION_HEX >= 0x030C0000
|
||||
// Since Python-3.12 property-derived types are required to
|
||||
// have dynamic attributes (to set `__doc__`)
|
||||
enable_dynamic_attributes(heap_type);
|
||||
# endif
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail("make_static_property_type(): failure in PyType_Ready()!");
|
||||
}
|
||||
|
||||
setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
#else // PYPY
|
||||
|
||||
/** PyPy has some issues with the above C API, so we evaluate Python code instead.
|
||||
This function will only be called once so performance isn't really a concern.
|
||||
Return value: New reference. */
|
||||
inline PyTypeObject *make_static_property_type() {
|
||||
auto d = dict();
|
||||
PyObject *result = PyRun_String(R"(\
|
||||
class pybind11_static_property(property):
|
||||
def __get__(self, obj, cls):
|
||||
return property.__get__(self, cls, cls)
|
||||
|
||||
def __set__(self, obj, value):
|
||||
cls = obj if isinstance(obj, type) else type(obj)
|
||||
property.__set__(self, cls, value)
|
||||
)",
|
||||
Py_file_input,
|
||||
d.ptr(),
|
||||
d.ptr());
|
||||
if (result == nullptr)
|
||||
throw error_already_set();
|
||||
Py_DECREF(result);
|
||||
return (PyTypeObject *) d["pybind11_static_property"].cast<object>().release().ptr();
|
||||
}
|
||||
|
||||
#endif // PYPY
|
||||
|
||||
/** Types with static properties need to handle `Type.static_prop = x` in a specific way.
|
||||
By default, Python replaces the `static_property` itself, but for wrapped C++ types
|
||||
we need to call `static_property.__set__()` in order to propagate the new value to
|
||||
the underlying C++ data structure. */
|
||||
extern "C" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyObject *value) {
|
||||
// Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw
|
||||
// descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`).
|
||||
PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
|
||||
|
||||
// The following assignment combinations are possible:
|
||||
// 1. `Type.static_prop = value` --> descr_set: `Type.static_prop.__set__(value)`
|
||||
// 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop`
|
||||
// 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment
|
||||
auto *const static_prop = (PyObject *) get_internals().static_property_type;
|
||||
const auto call_descr_set = (descr != nullptr) && (value != nullptr)
|
||||
&& (PyObject_IsInstance(descr, static_prop) != 0)
|
||||
&& (PyObject_IsInstance(value, static_prop) == 0);
|
||||
if (call_descr_set) {
|
||||
// Call `static_property.__set__()` instead of replacing the `static_property`.
|
||||
#if !defined(PYPY_VERSION)
|
||||
return Py_TYPE(descr)->tp_descr_set(descr, obj, value);
|
||||
#else
|
||||
if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) {
|
||||
Py_DECREF(result);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// Replace existing attribute.
|
||||
return PyType_Type.tp_setattro(obj, name, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing
|
||||
* methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function,
|
||||
* when called on a class, or a PyMethod, when called on an instance. Override that behaviour here
|
||||
* to do a special case bypass for PyInstanceMethod_Types.
|
||||
*/
|
||||
extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) {
|
||||
PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
|
||||
if (descr && PyInstanceMethod_Check(descr)) {
|
||||
Py_INCREF(descr);
|
||||
return descr;
|
||||
}
|
||||
return PyType_Type.tp_getattro(obj, name);
|
||||
}
|
||||
|
||||
/// metaclass `__call__` function that is used to create all pybind11 objects.
|
||||
extern "C" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) {
|
||||
|
||||
// use the default metaclass call to create/initialize the object
|
||||
PyObject *self = PyType_Type.tp_call(type, args, kwargs);
|
||||
if (self == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ensure that the base __init__ function(s) were called
|
||||
values_and_holders vhs(self);
|
||||
for (const auto &vh : vhs) {
|
||||
if (!vh.holder_constructed() && !vhs.is_redundant_value_and_holder(vh)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"%.200s.__init__() must be called when overriding __init__",
|
||||
get_fully_qualified_tp_name(vh.type->type).c_str());
|
||||
Py_DECREF(self);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Cleanup the type-info for a pybind11-registered type.
|
||||
extern "C" inline void pybind11_meta_dealloc(PyObject *obj) {
|
||||
auto *type = (PyTypeObject *) obj;
|
||||
auto &internals = get_internals();
|
||||
|
||||
// A pybind11-registered type will:
|
||||
// 1) be found in internals.registered_types_py
|
||||
// 2) have exactly one associated `detail::type_info`
|
||||
auto found_type = internals.registered_types_py.find(type);
|
||||
if (found_type != internals.registered_types_py.end() && found_type->second.size() == 1
|
||||
&& found_type->second[0]->type == type) {
|
||||
|
||||
auto *tinfo = found_type->second[0];
|
||||
auto tindex = std::type_index(*tinfo->cpptype);
|
||||
internals.direct_conversions.erase(tindex);
|
||||
|
||||
if (tinfo->module_local) {
|
||||
get_local_internals().registered_types_cpp.erase(tindex);
|
||||
} else {
|
||||
internals.registered_types_cpp.erase(tindex);
|
||||
}
|
||||
internals.registered_types_py.erase(tinfo->type);
|
||||
|
||||
// Actually just `std::erase_if`, but that's only available in C++20
|
||||
auto &cache = internals.inactive_override_cache;
|
||||
for (auto it = cache.begin(), last = cache.end(); it != last;) {
|
||||
if (it->first == (PyObject *) tinfo->type) {
|
||||
it = cache.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
delete tinfo;
|
||||
}
|
||||
|
||||
PyType_Type.tp_dealloc(obj);
|
||||
}
|
||||
|
||||
/** This metaclass is assigned by default to all pybind11 types and is required in order
|
||||
for static properties to function correctly. Users may override this using `py::metaclass`.
|
||||
Return value: New reference. */
|
||||
inline PyTypeObject *make_default_metaclass() {
|
||||
constexpr auto *name = "pybind11_type";
|
||||
auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail("make_default_metaclass(): error allocating metaclass!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name_obj.inc_ref().ptr();
|
||||
#ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = name_obj.inc_ref().ptr();
|
||||
#endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = name;
|
||||
type->tp_base = type_incref(&PyType_Type);
|
||||
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
|
||||
|
||||
type->tp_call = pybind11_meta_call;
|
||||
|
||||
type->tp_setattro = pybind11_meta_setattro;
|
||||
type->tp_getattro = pybind11_meta_getattro;
|
||||
|
||||
type->tp_dealloc = pybind11_meta_dealloc;
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!");
|
||||
}
|
||||
|
||||
setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/// For multiple inheritance types we need to recursively register/deregister base pointers for any
|
||||
/// base classes with pointers that are difference from the instance value pointer so that we can
|
||||
/// correctly recognize an offset base class pointer. This calls a function with any offset base
|
||||
/// ptrs.
|
||||
inline void traverse_offset_bases(void *valueptr,
|
||||
const detail::type_info *tinfo,
|
||||
instance *self,
|
||||
bool (*f)(void * /*parentptr*/, instance * /*self*/)) {
|
||||
for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {
|
||||
if (auto *parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {
|
||||
for (auto &c : parent_tinfo->implicit_casts) {
|
||||
if (c.first == tinfo->cpptype) {
|
||||
auto *parentptr = c.second(valueptr);
|
||||
if (parentptr != valueptr) {
|
||||
f(parentptr, self);
|
||||
}
|
||||
traverse_offset_bases(parentptr, parent_tinfo, self, f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool register_instance_impl(void *ptr, instance *self) {
|
||||
get_internals().registered_instances.emplace(ptr, self);
|
||||
return true; // unused, but gives the same signature as the deregister func
|
||||
}
|
||||
inline bool deregister_instance_impl(void *ptr, instance *self) {
|
||||
auto ®istered_instances = get_internals().registered_instances;
|
||||
auto range = registered_instances.equal_range(ptr);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
if (self == it->second) {
|
||||
registered_instances.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void register_instance(instance *self, void *valptr, const type_info *tinfo) {
|
||||
register_instance_impl(valptr, self);
|
||||
if (!tinfo->simple_ancestors) {
|
||||
traverse_offset_bases(valptr, tinfo, self, register_instance_impl);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) {
|
||||
bool ret = deregister_instance_impl(valptr, self);
|
||||
if (!tinfo->simple_ancestors) {
|
||||
traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Instance creation function for all pybind11 types. It allocates the internal instance layout
|
||||
/// for holding C++ objects and holders. Allocation is done lazily (the first time the instance is
|
||||
/// cast to a reference or pointer), and initialization is done by an `__init__` function.
|
||||
inline PyObject *make_new_instance(PyTypeObject *type) {
|
||||
#if defined(PYPY_VERSION)
|
||||
// PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first
|
||||
// inherited object is a plain Python type (i.e. not derived from an extension type). Fix it.
|
||||
ssize_t instance_size = static_cast<ssize_t>(sizeof(instance));
|
||||
if (type->tp_basicsize < instance_size) {
|
||||
type->tp_basicsize = instance_size;
|
||||
}
|
||||
#endif
|
||||
PyObject *self = type->tp_alloc(type, 0);
|
||||
auto *inst = reinterpret_cast<instance *>(self);
|
||||
// Allocate the value/holder internals:
|
||||
inst->allocate_layout();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// Instance creation function for all pybind11 types. It only allocates space for the
|
||||
/// C++ object, but doesn't call the constructor -- an `__init__` function must do that.
|
||||
extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) {
|
||||
return make_new_instance(type);
|
||||
}
|
||||
|
||||
/// An `__init__` function constructs the C++ object. Users should provide at least one
|
||||
/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the
|
||||
/// following default function will be used which simply throws an exception.
|
||||
extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) {
|
||||
PyTypeObject *type = Py_TYPE(self);
|
||||
std::string msg = get_fully_qualified_tp_name(type) + ": No constructor defined!";
|
||||
set_error(PyExc_TypeError, msg.c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline void add_patient(PyObject *nurse, PyObject *patient) {
|
||||
auto &internals = get_internals();
|
||||
auto *instance = reinterpret_cast<detail::instance *>(nurse);
|
||||
instance->has_patients = true;
|
||||
Py_INCREF(patient);
|
||||
internals.patients[nurse].push_back(patient);
|
||||
}
|
||||
|
||||
inline void clear_patients(PyObject *self) {
|
||||
auto *instance = reinterpret_cast<detail::instance *>(self);
|
||||
auto &internals = get_internals();
|
||||
auto pos = internals.patients.find(self);
|
||||
assert(pos != internals.patients.end());
|
||||
// Clearing the patients can cause more Python code to run, which
|
||||
// can invalidate the iterator. Extract the vector of patients
|
||||
// from the unordered_map first.
|
||||
auto patients = std::move(pos->second);
|
||||
internals.patients.erase(pos);
|
||||
instance->has_patients = false;
|
||||
for (PyObject *&patient : patients) {
|
||||
Py_CLEAR(patient);
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears all internal data from the instance and removes it from registered instances in
|
||||
/// preparation for deallocation.
|
||||
inline void clear_instance(PyObject *self) {
|
||||
auto *instance = reinterpret_cast<detail::instance *>(self);
|
||||
|
||||
// Deallocate any values/holders, if present:
|
||||
for (auto &v_h : values_and_holders(instance)) {
|
||||
if (v_h) {
|
||||
|
||||
// We have to deregister before we call dealloc because, for virtual MI types, we still
|
||||
// need to be able to get the parent pointers.
|
||||
if (v_h.instance_registered()
|
||||
&& !deregister_instance(instance, v_h.value_ptr(), v_h.type)) {
|
||||
pybind11_fail(
|
||||
"pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
|
||||
}
|
||||
|
||||
if (instance->owned || v_h.holder_constructed()) {
|
||||
v_h.type->dealloc(v_h);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Deallocate the value/holder layout internals:
|
||||
instance->deallocate_layout();
|
||||
|
||||
if (instance->weakrefs) {
|
||||
PyObject_ClearWeakRefs(self);
|
||||
}
|
||||
|
||||
PyObject **dict_ptr = _PyObject_GetDictPtr(self);
|
||||
if (dict_ptr) {
|
||||
Py_CLEAR(*dict_ptr);
|
||||
}
|
||||
|
||||
if (instance->has_patients) {
|
||||
clear_patients(self);
|
||||
}
|
||||
}
|
||||
|
||||
/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc`
|
||||
/// to destroy the C++ object itself, while the rest is Python bookkeeping.
|
||||
extern "C" inline void pybind11_object_dealloc(PyObject *self) {
|
||||
auto *type = Py_TYPE(self);
|
||||
|
||||
// If this is a GC tracked object, untrack it first
|
||||
// Note that the track call is implicitly done by the
|
||||
// default tp_alloc, which we never override.
|
||||
if (PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC) != 0) {
|
||||
PyObject_GC_UnTrack(self);
|
||||
}
|
||||
|
||||
clear_instance(self);
|
||||
|
||||
type->tp_free(self);
|
||||
|
||||
#if PY_VERSION_HEX < 0x03080000
|
||||
// `type->tp_dealloc != pybind11_object_dealloc` means that we're being called
|
||||
// as part of a derived type's dealloc, in which case we're not allowed to decref
|
||||
// the type here. For cross-module compatibility, we shouldn't compare directly
|
||||
// with `pybind11_object_dealloc`, but with the common one stashed in internals.
|
||||
auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;
|
||||
if (type->tp_dealloc == pybind11_object_type->tp_dealloc)
|
||||
Py_DECREF(type);
|
||||
#else
|
||||
// This was not needed before Python 3.8 (Python issue 35810)
|
||||
// https://github.com/pybind/pybind11/issues/1946
|
||||
Py_DECREF(type);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string error_string();
|
||||
|
||||
/** Create the type which can be used as a common base for all classes. This is
|
||||
needed in order to satisfy Python's requirements for multiple inheritance.
|
||||
Return value: New reference. */
|
||||
inline PyObject *make_object_base_type(PyTypeObject *metaclass) {
|
||||
constexpr auto *name = "pybind11_object";
|
||||
auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail("make_object_base_type(): error allocating type!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name_obj.inc_ref().ptr();
|
||||
#ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = name_obj.inc_ref().ptr();
|
||||
#endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = name;
|
||||
type->tp_base = type_incref(&PyBaseObject_Type);
|
||||
type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
|
||||
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
|
||||
|
||||
type->tp_new = pybind11_object_new;
|
||||
type->tp_init = pybind11_object_init;
|
||||
type->tp_dealloc = pybind11_object_dealloc;
|
||||
|
||||
/* Support weak references (needed for the keep_alive feature) */
|
||||
type->tp_weaklistoffset = offsetof(instance, weakrefs);
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail("PyType_Ready failed in make_object_base_type(): " + error_string());
|
||||
}
|
||||
|
||||
setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
|
||||
|
||||
assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
|
||||
return (PyObject *) heap_type;
|
||||
}
|
||||
|
||||
/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.
|
||||
extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
PyObject_VisitManagedDict(self, visit, arg);
|
||||
#else
|
||||
PyObject *&dict = *_PyObject_GetDictPtr(self);
|
||||
Py_VISIT(dict);
|
||||
#endif
|
||||
// https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_traverse
|
||||
#if PY_VERSION_HEX >= 0x03090000
|
||||
Py_VISIT(Py_TYPE(self));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// dynamic_attr: Allow the GC to clear the dictionary.
|
||||
extern "C" inline int pybind11_clear(PyObject *self) {
|
||||
#if PY_VERSION_HEX >= 0x030D0000
|
||||
PyObject_ClearManagedDict(self);
|
||||
#else
|
||||
PyObject *&dict = *_PyObject_GetDictPtr(self);
|
||||
Py_CLEAR(dict);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Give instances of this type a `__dict__` and opt into garbage collection.
|
||||
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
|
||||
#if PY_VERSION_HEX < 0x030B0000
|
||||
type->tp_dictoffset = type->tp_basicsize; // place dict at the end
|
||||
type->tp_basicsize += (ssize_t) sizeof(PyObject *); // and allocate enough space for it
|
||||
#else
|
||||
type->tp_flags |= Py_TPFLAGS_MANAGED_DICT;
|
||||
#endif
|
||||
type->tp_traverse = pybind11_traverse;
|
||||
type->tp_clear = pybind11_clear;
|
||||
|
||||
static PyGetSetDef getset[] = {{
|
||||
#if PY_VERSION_HEX < 0x03070000
|
||||
const_cast<char *>("__dict__"),
|
||||
#else
|
||||
"__dict__",
|
||||
#endif
|
||||
PyObject_GenericGetDict,
|
||||
PyObject_GenericSetDict,
|
||||
nullptr,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr}};
|
||||
type->tp_getset = getset;
|
||||
}
|
||||
|
||||
/// buffer_protocol: Fill in the view as specified by flags.
|
||||
extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {
|
||||
// Look for a `get_buffer` implementation in this type's info or any bases (following MRO).
|
||||
type_info *tinfo = nullptr;
|
||||
for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {
|
||||
tinfo = get_type_info((PyTypeObject *) type.ptr());
|
||||
if (tinfo && tinfo->get_buffer) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (view == nullptr || !tinfo || !tinfo->get_buffer) {
|
||||
if (view) {
|
||||
view->obj = nullptr;
|
||||
}
|
||||
set_error(PyExc_BufferError, "pybind11_getbuffer(): Internal error");
|
||||
return -1;
|
||||
}
|
||||
std::memset(view, 0, sizeof(Py_buffer));
|
||||
buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data);
|
||||
if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {
|
||||
delete info;
|
||||
// view->obj = nullptr; // Was just memset to 0, so not necessary
|
||||
set_error(PyExc_BufferError, "Writable buffer requested for readonly storage");
|
||||
return -1;
|
||||
}
|
||||
view->obj = obj;
|
||||
view->ndim = 1;
|
||||
view->internal = info;
|
||||
view->buf = info->ptr;
|
||||
view->itemsize = info->itemsize;
|
||||
view->len = view->itemsize;
|
||||
for (auto s : info->shape) {
|
||||
view->len *= s;
|
||||
}
|
||||
view->readonly = static_cast<int>(info->readonly);
|
||||
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
|
||||
view->format = const_cast<char *>(info->format.c_str());
|
||||
}
|
||||
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
|
||||
view->ndim = (int) info->ndim;
|
||||
view->strides = info->strides.data();
|
||||
view->shape = info->shape.data();
|
||||
}
|
||||
Py_INCREF(view->obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// buffer_protocol: Release the resources of the buffer.
|
||||
extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {
|
||||
delete (buffer_info *) view->internal;
|
||||
}
|
||||
|
||||
/// Give this type a buffer interface.
|
||||
inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {
|
||||
heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;
|
||||
|
||||
heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;
|
||||
heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;
|
||||
}
|
||||
|
||||
/** Create a brand new Python type according to the `type_record` specification.
|
||||
Return value: New reference. */
|
||||
inline PyObject *make_new_python_type(const type_record &rec) {
|
||||
auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name));
|
||||
|
||||
auto qualname = name;
|
||||
if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) {
|
||||
qualname = reinterpret_steal<object>(
|
||||
PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr()));
|
||||
}
|
||||
|
||||
object module_;
|
||||
if (rec.scope) {
|
||||
if (hasattr(rec.scope, "__module__")) {
|
||||
module_ = rec.scope.attr("__module__");
|
||||
} else if (hasattr(rec.scope, "__name__")) {
|
||||
module_ = rec.scope.attr("__name__");
|
||||
}
|
||||
}
|
||||
|
||||
const auto *full_name = c_str(
|
||||
#if !defined(PYPY_VERSION)
|
||||
module_ ? str(module_).cast<std::string>() + "." + rec.name :
|
||||
#endif
|
||||
rec.name);
|
||||
|
||||
char *tp_doc = nullptr;
|
||||
if (rec.doc && options::show_user_defined_docstrings()) {
|
||||
/* Allocate memory for docstring (using PyObject_MALLOC, since
|
||||
Python will free this later on) */
|
||||
size_t size = std::strlen(rec.doc) + 1;
|
||||
tp_doc = (char *) PyObject_MALLOC(size);
|
||||
std::memcpy((void *) tp_doc, rec.doc, size);
|
||||
}
|
||||
|
||||
auto &internals = get_internals();
|
||||
auto bases = tuple(rec.bases);
|
||||
auto *base = (bases.empty()) ? internals.instance_base : bases[0].ptr();
|
||||
|
||||
/* Danger zone: from now (and until PyType_Ready), make sure to
|
||||
issue no Python C API calls which could potentially invoke the
|
||||
garbage collector (the GC will call type_traverse(), which will in
|
||||
turn find the newly constructed type in an invalid state) */
|
||||
auto *metaclass
|
||||
= rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() : internals.default_metaclass;
|
||||
|
||||
auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
|
||||
if (!heap_type) {
|
||||
pybind11_fail(std::string(rec.name) + ": Unable to create type object!");
|
||||
}
|
||||
|
||||
heap_type->ht_name = name.release().ptr();
|
||||
#ifdef PYBIND11_BUILTIN_QUALNAME
|
||||
heap_type->ht_qualname = qualname.inc_ref().ptr();
|
||||
#endif
|
||||
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_name = full_name;
|
||||
type->tp_doc = tp_doc;
|
||||
type->tp_base = type_incref((PyTypeObject *) base);
|
||||
type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
|
||||
if (!bases.empty()) {
|
||||
type->tp_bases = bases.release().ptr();
|
||||
}
|
||||
|
||||
/* Don't inherit base __init__ */
|
||||
type->tp_init = pybind11_object_init;
|
||||
|
||||
/* Supported protocols */
|
||||
type->tp_as_number = &heap_type->as_number;
|
||||
type->tp_as_sequence = &heap_type->as_sequence;
|
||||
type->tp_as_mapping = &heap_type->as_mapping;
|
||||
type->tp_as_async = &heap_type->as_async;
|
||||
|
||||
/* Flags */
|
||||
type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
|
||||
if (!rec.is_final) {
|
||||
type->tp_flags |= Py_TPFLAGS_BASETYPE;
|
||||
}
|
||||
|
||||
if (rec.dynamic_attr) {
|
||||
enable_dynamic_attributes(heap_type);
|
||||
}
|
||||
|
||||
if (rec.buffer_protocol) {
|
||||
enable_buffer_protocol(heap_type);
|
||||
}
|
||||
|
||||
if (rec.custom_type_setup_callback) {
|
||||
rec.custom_type_setup_callback(heap_type);
|
||||
}
|
||||
|
||||
if (PyType_Ready(type) < 0) {
|
||||
pybind11_fail(std::string(rec.name) + ": PyType_Ready failed: " + error_string());
|
||||
}
|
||||
|
||||
assert(!rec.dynamic_attr || PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
|
||||
|
||||
/* Register type with the parent scope */
|
||||
if (rec.scope) {
|
||||
setattr(rec.scope, rec.name, (PyObject *) type);
|
||||
} else {
|
||||
Py_INCREF(type); // Keep it alive forever (reference leak)
|
||||
}
|
||||
|
||||
if (module_) { // Needed by pydoc
|
||||
setattr((PyObject *) type, "__module__", module_);
|
||||
}
|
||||
|
||||
PYBIND11_SET_OLDPY_QUALNAME(type, qualname);
|
||||
|
||||
return (PyObject *) type;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
1263
thirdparty/pybind11/include/pybind11/detail/common.h
vendored
Normal file
1263
thirdparty/pybind11/include/pybind11/detail/common.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
171
thirdparty/pybind11/include/pybind11/detail/descr.h
vendored
Normal file
171
thirdparty/pybind11/include/pybind11/detail/descr.h
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time
|
||||
|
||||
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# define PYBIND11_DESCR_CONSTEXPR static constexpr
|
||||
#else
|
||||
# define PYBIND11_DESCR_CONSTEXPR const
|
||||
#endif
|
||||
|
||||
/* Concatenate type signatures at compile time */
|
||||
template <size_t N, typename... Ts>
|
||||
struct descr {
|
||||
char text[N + 1]{'\0'};
|
||||
|
||||
constexpr descr() = default;
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}
|
||||
|
||||
template <size_t... Is>
|
||||
constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\0'} {}
|
||||
|
||||
template <typename... Chars>
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\0'} {}
|
||||
|
||||
static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {
|
||||
return {{&typeid(Ts)..., nullptr}};
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2>
|
||||
constexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,
|
||||
const descr<N2, Ts2...> &b,
|
||||
index_sequence<Is1...>,
|
||||
index_sequence<Is2...>) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);
|
||||
return {a.text[Is1]..., b.text[Is2]...};
|
||||
}
|
||||
|
||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
||||
constexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,
|
||||
const descr<N2, Ts2...> &b) {
|
||||
return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
constexpr descr<N - 1> const_name(char const (&text)[N]) {
|
||||
return descr<N - 1>(text);
|
||||
}
|
||||
constexpr descr<0> const_name(char const (&)[1]) { return {}; }
|
||||
|
||||
template <size_t Rem, size_t... Digits>
|
||||
struct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};
|
||||
template <size_t... Digits>
|
||||
struct int_to_str<0, Digits...> {
|
||||
// WARNING: This only works with C++17 or higher.
|
||||
static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);
|
||||
};
|
||||
|
||||
// Ternary description (like std::conditional)
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {
|
||||
return const_name(text1);
|
||||
}
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {
|
||||
return const_name(text2);
|
||||
}
|
||||
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) {
|
||||
return d;
|
||||
}
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {
|
||||
return d;
|
||||
}
|
||||
|
||||
template <size_t Size>
|
||||
auto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
||||
return int_to_str<Size / 10, Size % 10>::digits;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
constexpr descr<1, Type> const_name() {
|
||||
return {'%'};
|
||||
}
|
||||
|
||||
// If "_" is defined as a macro, py::detail::_ cannot be provided.
|
||||
// It is therefore best to use py::detail::const_name universally.
|
||||
// This block is for backward compatibility only.
|
||||
// (The const_name code is repeated to avoid introducing a "_" #define ourselves.)
|
||||
#ifndef _
|
||||
# define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
|
||||
template <size_t N>
|
||||
constexpr descr<N - 1> _(char const (&text)[N]) {
|
||||
return const_name<N>(text);
|
||||
}
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
|
||||
return const_name<B, N1, N2>(text1, text2);
|
||||
}
|
||||
template <bool B, size_t N1, size_t N2>
|
||||
constexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {
|
||||
return const_name<B, N1, N2>(text1, text2);
|
||||
}
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {
|
||||
return const_name<B, T1, T2>(d1, d2);
|
||||
}
|
||||
template <bool B, typename T1, typename T2>
|
||||
constexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {
|
||||
return const_name<B, T1, T2>(d1, d2);
|
||||
}
|
||||
|
||||
template <size_t Size>
|
||||
auto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {
|
||||
return const_name<Size>();
|
||||
}
|
||||
template <typename Type>
|
||||
constexpr descr<1, Type> _() {
|
||||
return const_name<Type>();
|
||||
}
|
||||
#endif // #ifndef _
|
||||
|
||||
constexpr descr<0> concat() { return {}; }
|
||||
|
||||
template <size_t N, typename... Ts>
|
||||
constexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {
|
||||
return descr;
|
||||
}
|
||||
|
||||
#ifdef __cpp_fold_expressions
|
||||
template <size_t N1, size_t N2, typename... Ts1, typename... Ts2>
|
||||
constexpr descr<N1 + N2 + 2, Ts1..., Ts2...> operator,(const descr<N1, Ts1...> &a,
|
||||
const descr<N2, Ts2...> &b) {
|
||||
return a + const_name(", ") + b;
|
||||
}
|
||||
|
||||
template <size_t N, typename... Ts, typename... Args>
|
||||
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args) {
|
||||
return (d, ..., args);
|
||||
}
|
||||
#else
|
||||
template <size_t N, typename... Ts, typename... Args>
|
||||
constexpr auto concat(const descr<N, Ts...> &d, const Args &...args)
|
||||
-> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {
|
||||
return d + const_name(", ") + concat(args...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <size_t N, typename... Ts>
|
||||
constexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {
|
||||
return const_name("{") + descr + const_name("}");
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
434
thirdparty/pybind11/include/pybind11/detail/init.h
vendored
Normal file
434
thirdparty/pybind11/include/pybind11/detail/init.h
vendored
Normal file
@ -0,0 +1,434 @@
|
||||
/*
|
||||
pybind11/detail/init.h: init factory function implementation and support code.
|
||||
|
||||
Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "class.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
PYBIND11_WARNING_DISABLE_MSVC(4127)
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
template <>
|
||||
class type_caster<value_and_holder> {
|
||||
public:
|
||||
bool load(handle h, bool) {
|
||||
value = reinterpret_cast<value_and_holder *>(h.ptr());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename>
|
||||
using cast_op_type = value_and_holder &;
|
||||
explicit operator value_and_holder &() { return *value; }
|
||||
static constexpr auto name = const_name<value_and_holder>();
|
||||
|
||||
private:
|
||||
value_and_holder *value = nullptr;
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(initimpl)
|
||||
|
||||
inline void no_nullptr(void *ptr) {
|
||||
if (!ptr) {
|
||||
throw type_error("pybind11::init(): factory function returned nullptr");
|
||||
}
|
||||
}
|
||||
|
||||
// Implementing functions for all forms of py::init<...> and py::init(...)
|
||||
template <typename Class>
|
||||
using Cpp = typename Class::type;
|
||||
template <typename Class>
|
||||
using Alias = typename Class::type_alias;
|
||||
template <typename Class>
|
||||
using Holder = typename Class::holder_type;
|
||||
|
||||
template <typename Class>
|
||||
using is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;
|
||||
|
||||
// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance.
|
||||
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
|
||||
bool is_alias(Cpp<Class> *ptr) {
|
||||
return dynamic_cast<Alias<Class> *>(ptr) != nullptr;
|
||||
}
|
||||
// Failing fallback version of the above for a no-alias class (always returns false)
|
||||
template <typename /*Class*/>
|
||||
constexpr bool is_alias(void *) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall
|
||||
// back to brace aggregate initialization so that for aggregate initialization can be used with
|
||||
// py::init, e.g. `py::init<int, int>` to initialize a `struct T { int a; int b; }`. For
|
||||
// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually
|
||||
// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).
|
||||
template <typename Class,
|
||||
typename... Args,
|
||||
detail::enable_if_t<std::is_constructible<Class, Args...>::value, int> = 0>
|
||||
inline Class *construct_or_initialize(Args &&...args) {
|
||||
return new Class(std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename Class,
|
||||
typename... Args,
|
||||
detail::enable_if_t<!std::is_constructible<Class, Args...>::value, int> = 0>
|
||||
inline Class *construct_or_initialize(Args &&...args) {
|
||||
return new Class{std::forward<Args>(args)...};
|
||||
}
|
||||
|
||||
// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor. This allows types with
|
||||
// an alias to provide only a single Cpp factory function as long as the Alias can be
|
||||
// constructed from an rvalue reference of the base Cpp type. This means that Alias classes
|
||||
// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to
|
||||
// inherit all the base class constructors.
|
||||
template <typename Class>
|
||||
void construct_alias_from_cpp(std::true_type /*is_alias_constructible*/,
|
||||
value_and_holder &v_h,
|
||||
Cpp<Class> &&base) {
|
||||
v_h.value_ptr() = new Alias<Class>(std::move(base));
|
||||
}
|
||||
template <typename Class>
|
||||
[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/,
|
||||
value_and_holder &,
|
||||
Cpp<Class> &&) {
|
||||
throw type_error("pybind11::init(): unable to convert returned instance to required "
|
||||
"alias class: no `Alias<Class>(Class &&)` constructor available");
|
||||
}
|
||||
|
||||
// Error-generating fallback for factories that don't match one of the below construction
|
||||
// mechanisms.
|
||||
template <typename Class>
|
||||
void construct(...) {
|
||||
static_assert(!std::is_same<Class, Class>::value /* always false */,
|
||||
"pybind11::init(): init function must return a compatible pointer, "
|
||||
"holder, or value");
|
||||
}
|
||||
|
||||
// Pointer return v1: the factory function returns a class pointer for a registered class.
|
||||
// If we don't need an alias (because this class doesn't have one, or because the final type is
|
||||
// inherited on the Python side) we can simply take over ownership. Otherwise we need to try to
|
||||
// construct an Alias from the returned base instance.
|
||||
template <typename Class>
|
||||
void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
no_nullptr(ptr);
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
// We're going to try to construct an alias by moving the cpp type. Whether or not
|
||||
// that succeeds, we still need to destroy the original cpp pointer (either the
|
||||
// moved away leftover, if the alias construction works, or the value itself if we
|
||||
// throw an error), but we can't just call `delete ptr`: it might have a special
|
||||
// deleter, or might be shared_from_this. So we construct a holder around it as if
|
||||
// it was a normal instance, then steal the holder away into a local variable; thus
|
||||
// the holder and destruction happens when we leave the C++ scope, and the holder
|
||||
// class gets to handle the destruction however it likes.
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.set_instance_registered(true); // To prevent init_instance from registering it
|
||||
v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
|
||||
Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
|
||||
v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
|
||||
v_h.set_instance_registered(false);
|
||||
|
||||
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
|
||||
} else {
|
||||
// Otherwise the type isn't inherited, so we don't need an Alias
|
||||
v_h.value_ptr() = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Pointer return v2: a factory that always returns an alias instance ptr. We simply take over
|
||||
// ownership of the pointer.
|
||||
template <typename Class, enable_if_t<Class::has_alias, int> = 0>
|
||||
void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
|
||||
no_nullptr(alias_ptr);
|
||||
v_h.value_ptr() = static_cast<Cpp<Class> *>(alias_ptr);
|
||||
}
|
||||
|
||||
// Holder return: copy its pointer, and move or copy the returned holder into the new instance's
|
||||
// holder. This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
|
||||
// derived type (through those holder's implicit conversion from derived class holder
|
||||
// constructors).
|
||||
template <typename Class>
|
||||
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
auto *ptr = holder_helper<Holder<Class>>::get(holder);
|
||||
no_nullptr(ptr);
|
||||
// If we need an alias, check that the held pointer is actually an alias instance
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance "
|
||||
"is not an alias instance");
|
||||
}
|
||||
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &holder);
|
||||
}
|
||||
|
||||
// return-by-value version 1: returning a cpp class by value. If the class has an alias and an
|
||||
// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct
|
||||
// the alias from the base when needed (i.e. because of Python-side inheritance). When we don't
|
||||
// need it, we simply move-construct the cpp value into a new instance.
|
||||
template <typename Class>
|
||||
void construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {
|
||||
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
|
||||
static_assert(is_move_constructible<Cpp<Class>>::value,
|
||||
"pybind11::init() return-by-value factory function requires a movable class");
|
||||
if (Class::has_alias && need_alias) {
|
||||
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));
|
||||
} else {
|
||||
v_h.value_ptr() = new Cpp<Class>(std::move(result));
|
||||
}
|
||||
}
|
||||
|
||||
// return-by-value version 2: returning a value of the alias type itself. We move-construct an
|
||||
// Alias instance (even if no the python-side inheritance is involved). The is intended for
|
||||
// cases where Alias initialization is always desired.
|
||||
template <typename Class>
|
||||
void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
|
||||
static_assert(
|
||||
is_move_constructible<Alias<Class>>::value,
|
||||
"pybind11::init() return-by-alias-value factory function requires a movable alias class");
|
||||
v_h.value_ptr() = new Alias<Class>(std::move(result));
|
||||
}
|
||||
|
||||
// Implementing class for py::init<...>()
|
||||
template <typename... Args>
|
||||
struct constructor {
|
||||
template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h, Args... args) {
|
||||
v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename Class,
|
||||
typename... Extra,
|
||||
enable_if_t<Class::has_alias && std::is_constructible<Cpp<Class>, Args...>::value, int>
|
||||
= 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h, Args... args) {
|
||||
if (Py_TYPE(v_h.inst) == v_h.type->type) {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);
|
||||
} else {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
|
||||
}
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
|
||||
template <
|
||||
typename Class,
|
||||
typename... Extra,
|
||||
enable_if_t<Class::has_alias && !std::is_constructible<Cpp<Class>, Args...>::value, int>
|
||||
= 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h, Args... args) {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
// Implementing class for py::init_alias<...>()
|
||||
template <typename... Args>
|
||||
struct alias_constructor {
|
||||
template <
|
||||
typename Class,
|
||||
typename... Extra,
|
||||
enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value, int>
|
||||
= 0>
|
||||
static void execute(Class &cl, const Extra &...extra) {
|
||||
cl.def(
|
||||
"__init__",
|
||||
[](value_and_holder &v_h, Args... args) {
|
||||
v_h.value_ptr()
|
||||
= construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
// Implementation class for py::init(Func) and py::init(Func, AliasFunc)
|
||||
template <typename CFunc,
|
||||
typename AFunc = void_type (*)(),
|
||||
typename = function_signature_t<CFunc>,
|
||||
typename = function_signature_t<AFunc>>
|
||||
struct factory;
|
||||
|
||||
// Specialization for py::init(Func)
|
||||
template <typename Func, typename Return, typename... Args>
|
||||
struct factory<Func, void_type (*)(), Return(Args...)> {
|
||||
remove_reference_t<Func> class_factory;
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
factory(Func &&f) : class_factory(std::forward<Func>(f)) {}
|
||||
|
||||
// The given class either has no alias or has no separate alias factory;
|
||||
// this always constructs the class itself. If the class is registered with an alias
|
||||
// type and an alias instance is needed (i.e. because the final type is a Python class
|
||||
// inheriting from the C++ type) the returned value needs to either already be an alias
|
||||
// instance, or the alias needs to be constructible from a `Class &&` argument.
|
||||
template <typename Class, typename... Extra>
|
||||
void execute(Class &cl, const Extra &...extra) && {
|
||||
#if defined(PYBIND11_CPP14)
|
||||
cl.def(
|
||||
"__init__",
|
||||
[func = std::move(class_factory)]
|
||||
#else
|
||||
auto &func = class_factory;
|
||||
cl.def(
|
||||
"__init__",
|
||||
[func]
|
||||
#endif
|
||||
(value_and_holder &v_h, Args... args) {
|
||||
construct<Class>(
|
||||
v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for py::init(Func, AliasFunc)
|
||||
template <typename CFunc,
|
||||
typename AFunc,
|
||||
typename CReturn,
|
||||
typename... CArgs,
|
||||
typename AReturn,
|
||||
typename... AArgs>
|
||||
struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
|
||||
static_assert(sizeof...(CArgs) == sizeof...(AArgs),
|
||||
"pybind11::init(class_factory, alias_factory): class and alias factories "
|
||||
"must have identical argument signatures");
|
||||
static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,
|
||||
"pybind11::init(class_factory, alias_factory): class and alias factories "
|
||||
"must have identical argument signatures");
|
||||
|
||||
remove_reference_t<CFunc> class_factory;
|
||||
remove_reference_t<AFunc> alias_factory;
|
||||
|
||||
factory(CFunc &&c, AFunc &&a)
|
||||
: class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) {}
|
||||
|
||||
// The class factory is called when the `self` type passed to `__init__` is the direct
|
||||
// class (i.e. not inherited), the alias factory when `self` is a Python-side subtype.
|
||||
template <typename Class, typename... Extra>
|
||||
void execute(Class &cl, const Extra &...extra) && {
|
||||
static_assert(Class::has_alias,
|
||||
"The two-argument version of `py::init()` can "
|
||||
"only be used if the class has an alias");
|
||||
#if defined(PYBIND11_CPP14)
|
||||
cl.def(
|
||||
"__init__",
|
||||
[class_func = std::move(class_factory), alias_func = std::move(alias_factory)]
|
||||
#else
|
||||
auto &class_func = class_factory;
|
||||
auto &alias_func = alias_factory;
|
||||
cl.def(
|
||||
"__init__",
|
||||
[class_func, alias_func]
|
||||
#endif
|
||||
(value_and_holder &v_h, CArgs... args) {
|
||||
if (Py_TYPE(v_h.inst) == v_h.type->type) {
|
||||
// If the instance type equals the registered type we don't have inheritance,
|
||||
// so don't need the alias and can construct using the class function:
|
||||
construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);
|
||||
} else {
|
||||
construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);
|
||||
}
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
/// Set just the C++ state. Same as `__init__`.
|
||||
template <typename Class, typename T>
|
||||
void setstate(value_and_holder &v_h, T &&result, bool need_alias) {
|
||||
construct<Class>(v_h, std::forward<T>(result), need_alias);
|
||||
}
|
||||
|
||||
/// Set both the C++ and Python states
|
||||
template <typename Class,
|
||||
typename T,
|
||||
typename O,
|
||||
enable_if_t<std::is_convertible<O, handle>::value, int> = 0>
|
||||
void setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias) {
|
||||
construct<Class>(v_h, std::move(result.first), need_alias);
|
||||
auto d = handle(result.second);
|
||||
if (PyDict_Check(d.ptr()) && PyDict_Size(d.ptr()) == 0) {
|
||||
// Skipping setattr below, to not force use of py::dynamic_attr() for Class unnecessarily.
|
||||
// See PR #2972 for details.
|
||||
return;
|
||||
}
|
||||
setattr((PyObject *) v_h.inst, "__dict__", d);
|
||||
}
|
||||
|
||||
/// Implementation for py::pickle(GetState, SetState)
|
||||
template <typename Get,
|
||||
typename Set,
|
||||
typename = function_signature_t<Get>,
|
||||
typename = function_signature_t<Set>>
|
||||
struct pickle_factory;
|
||||
|
||||
template <typename Get,
|
||||
typename Set,
|
||||
typename RetState,
|
||||
typename Self,
|
||||
typename NewInstance,
|
||||
typename ArgState>
|
||||
struct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {
|
||||
static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,
|
||||
"The type returned by `__getstate__` must be the same "
|
||||
"as the argument accepted by `__setstate__`");
|
||||
|
||||
remove_reference_t<Get> get;
|
||||
remove_reference_t<Set> set;
|
||||
|
||||
pickle_factory(Get get, Set set) : get(std::forward<Get>(get)), set(std::forward<Set>(set)) {}
|
||||
|
||||
template <typename Class, typename... Extra>
|
||||
void execute(Class &cl, const Extra &...extra) && {
|
||||
cl.def("__getstate__", std::move(get));
|
||||
|
||||
#if defined(PYBIND11_CPP14)
|
||||
cl.def(
|
||||
"__setstate__",
|
||||
[func = std::move(set)]
|
||||
#else
|
||||
auto &func = set;
|
||||
cl.def(
|
||||
"__setstate__",
|
||||
[func]
|
||||
#endif
|
||||
(value_and_holder &v_h, ArgState state) {
|
||||
setstate<Class>(
|
||||
v_h, func(std::forward<ArgState>(state)), Py_TYPE(v_h.inst) != v_h.type->type);
|
||||
},
|
||||
is_new_style_constructor(),
|
||||
extra...);
|
||||
}
|
||||
};
|
||||
|
||||
PYBIND11_NAMESPACE_END(initimpl)
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
662
thirdparty/pybind11/include/pybind11/detail/internals.h
vendored
Normal file
662
thirdparty/pybind11/include/pybind11/detail/internals.h
vendored
Normal file
@ -0,0 +1,662 @@
|
||||
/*
|
||||
pybind11/detail/internals.h: Internal data structure and related functions
|
||||
|
||||
Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>
|
||||
|
||||
All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if defined(WITH_THREAD) && defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
|
||||
# include "../gil.h"
|
||||
#endif
|
||||
|
||||
#include "../pytypes.h"
|
||||
|
||||
#include <exception>
|
||||
|
||||
/// Tracks the `internals` and `type_info` ABI version independent of the main library version.
|
||||
///
|
||||
/// Some portions of the code use an ABI that is conditional depending on this
|
||||
/// version number. That allows ABI-breaking changes to be "pre-implemented".
|
||||
/// Once the default version number is incremented, the conditional logic that
|
||||
/// no longer applies can be removed. Additionally, users that need not
|
||||
/// maintain ABI compatibility can increase the version number in order to take
|
||||
/// advantage of any functionality/efficiency improvements that depend on the
|
||||
/// newer ABI.
|
||||
///
|
||||
/// WARNING: If you choose to manually increase the ABI version, note that
|
||||
/// pybind11 may not be tested as thoroughly with a non-default ABI version, and
|
||||
/// further ABI-incompatible changes may be made before the ABI is officially
|
||||
/// changed to the new version.
|
||||
#ifndef PYBIND11_INTERNALS_VERSION
|
||||
# if PY_VERSION_HEX >= 0x030C0000 || defined(_MSC_VER)
|
||||
// Version bump for Python 3.12+, before first 3.12 beta release.
|
||||
// Version bump for MSVC piggy-backed on PR #4779. See comments there.
|
||||
# define PYBIND11_INTERNALS_VERSION 5
|
||||
# else
|
||||
# define PYBIND11_INTERNALS_VERSION 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// This requirement is mainly to reduce the support burden (see PR #4570).
|
||||
static_assert(PY_VERSION_HEX < 0x030C0000 || PYBIND11_INTERNALS_VERSION >= 5,
|
||||
"pybind11 ABI version 5 is the minimum for Python 3.12+");
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
using ExceptionTranslator = void (*)(std::exception_ptr);
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(detail)
|
||||
|
||||
constexpr const char *internals_function_record_capsule_name = "pybind11_function_record_capsule";
|
||||
|
||||
// Forward declarations
|
||||
inline PyTypeObject *make_static_property_type();
|
||||
inline PyTypeObject *make_default_metaclass();
|
||||
inline PyObject *make_object_base_type(PyTypeObject *metaclass);
|
||||
|
||||
// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
|
||||
// Thread Specific Storage (TSS) API.
|
||||
#if PY_VERSION_HEX >= 0x03070000
|
||||
// Avoid unnecessary allocation of `Py_tss_t`, since we cannot use
|
||||
// `Py_LIMITED_API` anyway.
|
||||
# if PYBIND11_INTERNALS_VERSION > 4
|
||||
# define PYBIND11_TLS_KEY_REF Py_tss_t &
|
||||
# if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||||
// Clang on macOS warns due to `Py_tss_NEEDS_INIT` not specifying an initializer
|
||||
// for every field.
|
||||
# define PYBIND11_TLS_KEY_INIT(var) \
|
||||
_Pragma("GCC diagnostic push") /**/ \
|
||||
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
|
||||
Py_tss_t var \
|
||||
= Py_tss_NEEDS_INIT; \
|
||||
_Pragma("GCC diagnostic pop")
|
||||
# else
|
||||
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
|
||||
# endif
|
||||
# define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
|
||||
# define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
|
||||
# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
|
||||
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
|
||||
# define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
|
||||
# else
|
||||
# define PYBIND11_TLS_KEY_REF Py_tss_t *
|
||||
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr;
|
||||
# define PYBIND11_TLS_KEY_CREATE(var) \
|
||||
(((var) = PyThread_tss_alloc()) != nullptr && (PyThread_tss_create((var)) == 0))
|
||||
# define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))
|
||||
# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))
|
||||
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)
|
||||
# define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)
|
||||
# endif
|
||||
#else
|
||||
// Usually an int but a long on Cygwin64 with Python 3.x
|
||||
# define PYBIND11_TLS_KEY_REF decltype(PyThread_create_key())
|
||||
# define PYBIND11_TLS_KEY_INIT(var) PYBIND11_TLS_KEY_REF var = 0;
|
||||
# define PYBIND11_TLS_KEY_CREATE(var) (((var) = PyThread_create_key()) != -1)
|
||||
# define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key))
|
||||
# if defined(PYPY_VERSION)
|
||||
// On CPython < 3.4 and on PyPy, `PyThread_set_key_value` strangely does not set
|
||||
// the value if it has already been set. Instead, it must first be deleted and
|
||||
// then set again.
|
||||
inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) {
|
||||
PyThread_delete_key_value(key);
|
||||
PyThread_set_key_value(key, value);
|
||||
}
|
||||
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_delete_key_value(key)
|
||||
# define PYBIND11_TLS_REPLACE_VALUE(key, value) \
|
||||
::pybind11::detail::tls_replace_value((key), (value))
|
||||
# else
|
||||
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_set_key_value((key), nullptr)
|
||||
# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_set_key_value((key), (value))
|
||||
# endif
|
||||
# define PYBIND11_TLS_FREE(key) (void) key
|
||||
#endif
|
||||
|
||||
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
|
||||
// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
|
||||
// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under
|
||||
// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,
|
||||
// which works. If not under a known-good stl, provide our own name-based hash and equality
|
||||
// functions that use the type name.
|
||||
#if (PYBIND11_INTERNALS_VERSION <= 4 && defined(__GLIBCXX__)) \
|
||||
|| (PYBIND11_INTERNALS_VERSION >= 5 && !defined(_LIBCPP_VERSION))
|
||||
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
|
||||
using type_hash = std::hash<std::type_index>;
|
||||
using type_equal_to = std::equal_to<std::type_index>;
|
||||
#else
|
||||
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {
|
||||
return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
|
||||
}
|
||||
|
||||
struct type_hash {
|
||||
size_t operator()(const std::type_index &t) const {
|
||||
size_t hash = 5381;
|
||||
const char *ptr = t.name();
|
||||
while (auto c = static_cast<unsigned char>(*ptr++)) {
|
||||
hash = (hash * 33) ^ c;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
|
||||
struct type_equal_to {
|
||||
bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {
|
||||
return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename value_type>
|
||||
using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;
|
||||
|
||||
struct override_hash {
|
||||
inline size_t operator()(const std::pair<const PyObject *, const char *> &v) const {
|
||||
size_t value = std::hash<const void *>()(v.first);
|
||||
value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
/// Internal data structure used to track registered instances and types.
|
||||
/// Whenever binary incompatible changes are made to this structure,
|
||||
/// `PYBIND11_INTERNALS_VERSION` must be incremented.
|
||||
struct internals {
|
||||
// std::type_index -> pybind11's type information
|
||||
type_map<type_info *> registered_types_cpp;
|
||||
// PyTypeObject* -> base type_info(s)
|
||||
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
|
||||
std::unordered_multimap<const void *, instance *> registered_instances; // void * -> instance*
|
||||
std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>
|
||||
inactive_override_cache;
|
||||
type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
|
||||
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
|
||||
std::forward_list<ExceptionTranslator> registered_exception_translators;
|
||||
std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across
|
||||
// extensions
|
||||
#if PYBIND11_INTERNALS_VERSION == 4
|
||||
std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;
|
||||
#endif
|
||||
std::forward_list<std::string> static_strings; // Stores the std::strings backing
|
||||
// detail::c_str()
|
||||
PyTypeObject *static_property_type;
|
||||
PyTypeObject *default_metaclass;
|
||||
PyObject *instance_base;
|
||||
#if defined(WITH_THREAD)
|
||||
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
|
||||
PYBIND11_TLS_KEY_INIT(tstate)
|
||||
# if PYBIND11_INTERNALS_VERSION > 4
|
||||
PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
|
||||
# endif // PYBIND11_INTERNALS_VERSION > 4
|
||||
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
|
||||
PyInterpreterState *istate = nullptr;
|
||||
|
||||
# if PYBIND11_INTERNALS_VERSION > 4
|
||||
// Note that we have to use a std::string to allocate memory to ensure a unique address
|
||||
// We want unique addresses since we use pointer equality to compare function records
|
||||
std::string function_record_capsule_name = internals_function_record_capsule_name;
|
||||
# endif
|
||||
|
||||
internals() = default;
|
||||
internals(const internals &other) = delete;
|
||||
internals &operator=(const internals &other) = delete;
|
||||
~internals() {
|
||||
# if PYBIND11_INTERNALS_VERSION > 4
|
||||
PYBIND11_TLS_FREE(loader_life_support_tls_key);
|
||||
# endif // PYBIND11_INTERNALS_VERSION > 4
|
||||
|
||||
// This destructor is called *after* Py_Finalize() in finalize_interpreter().
|
||||
// That *SHOULD BE* fine. The following details what happens when PyThread_tss_free is
|
||||
// called. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does
|
||||
// nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.
|
||||
// PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).
|
||||
// Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*
|
||||
// that the `tstate` be allocated with the CPython allocator.
|
||||
PYBIND11_TLS_FREE(tstate);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Additional type information which does not fit into the PyTypeObject.
|
||||
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
|
||||
struct type_info {
|
||||
PyTypeObject *type;
|
||||
const std::type_info *cpptype;
|
||||
size_t type_size, type_align, holder_size_in_ptrs;
|
||||
void *(*operator_new)(size_t);
|
||||
void (*init_instance)(instance *, const void *);
|
||||
void (*dealloc)(value_and_holder &v_h);
|
||||
std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;
|
||||
std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;
|
||||
std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;
|
||||
buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
|
||||
void *get_buffer_data = nullptr;
|
||||
void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
|
||||
/* A simple type never occurs as a (direct or indirect) parent
|
||||
* of a class that makes use of multiple inheritance.
|
||||
* A type can be simple even if it has non-simple ancestors as long as it has no descendants.
|
||||
*/
|
||||
bool simple_type : 1;
|
||||
/* True if there is no multiple inheritance in this type's inheritance tree */
|
||||
bool simple_ancestors : 1;
|
||||
/* for base vs derived holder_type checks */
|
||||
bool default_holder : 1;
|
||||
/* true if this is a type registered with py::module_local */
|
||||
bool module_local : 1;
|
||||
};
|
||||
|
||||
/// On MSVC, debug and release builds are not ABI-compatible!
|
||||
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
# define PYBIND11_BUILD_TYPE "_debug"
|
||||
#else
|
||||
# define PYBIND11_BUILD_TYPE ""
|
||||
#endif
|
||||
|
||||
/// Let's assume that different compilers are ABI-incompatible.
|
||||
/// A user can manually set this string if they know their
|
||||
/// compiler is compatible.
|
||||
#ifndef PYBIND11_COMPILER_TYPE
|
||||
# if defined(_MSC_VER)
|
||||
# define PYBIND11_COMPILER_TYPE "_msvc"
|
||||
# elif defined(__INTEL_COMPILER)
|
||||
# define PYBIND11_COMPILER_TYPE "_icc"
|
||||
# elif defined(__clang__)
|
||||
# define PYBIND11_COMPILER_TYPE "_clang"
|
||||
# elif defined(__PGI)
|
||||
# define PYBIND11_COMPILER_TYPE "_pgi"
|
||||
# elif defined(__MINGW32__)
|
||||
# define PYBIND11_COMPILER_TYPE "_mingw"
|
||||
# elif defined(__CYGWIN__)
|
||||
# define PYBIND11_COMPILER_TYPE "_gcc_cygwin"
|
||||
# elif defined(__GNUC__)
|
||||
# define PYBIND11_COMPILER_TYPE "_gcc"
|
||||
# else
|
||||
# define PYBIND11_COMPILER_TYPE "_unknown"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/// Also standard libs
|
||||
#ifndef PYBIND11_STDLIB
|
||||
# if defined(_LIBCPP_VERSION)
|
||||
# define PYBIND11_STDLIB "_libcpp"
|
||||
# elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
|
||||
# define PYBIND11_STDLIB "_libstdcpp"
|
||||
# else
|
||||
# define PYBIND11_STDLIB ""
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.
|
||||
/// On MSVC, changes in _MSC_VER may indicate ABI incompatibility (#2898).
|
||||
#ifndef PYBIND11_BUILD_ABI
|
||||
# if defined(__GXX_ABI_VERSION)
|
||||
# define PYBIND11_BUILD_ABI "_cxxabi" PYBIND11_TOSTRING(__GXX_ABI_VERSION)
|
||||
# elif defined(_MSC_VER)
|
||||
# define PYBIND11_BUILD_ABI "_mscver" PYBIND11_TOSTRING(_MSC_VER)
|
||||
# else
|
||||
# define PYBIND11_BUILD_ABI ""
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PYBIND11_INTERNALS_KIND
|
||||
# if defined(WITH_THREAD)
|
||||
# define PYBIND11_INTERNALS_KIND ""
|
||||
# else
|
||||
# define PYBIND11_INTERNALS_KIND "_without_thread"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define PYBIND11_INTERNALS_ID \
|
||||
"__pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
|
||||
PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI \
|
||||
PYBIND11_BUILD_TYPE "__"
|
||||
|
||||
#define PYBIND11_MODULE_LOCAL_ID \
|
||||
"__pybind11_module_local_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
|
||||
PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI \
|
||||
PYBIND11_BUILD_TYPE "__"
|
||||
|
||||
/// Each module locally stores a pointer to the `internals` data. The data
|
||||
/// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.
|
||||
inline internals **&get_internals_pp() {
|
||||
static internals **internals_pp = nullptr;
|
||||
return internals_pp;
|
||||
}
|
||||
|
||||
// forward decl
|
||||
inline void translate_exception(std::exception_ptr);
|
||||
|
||||
template <class T,
|
||||
enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
|
||||
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
|
||||
std::exception_ptr nested = exc.nested_ptr();
|
||||
if (nested != nullptr && nested != p) {
|
||||
translate_exception(nested);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T,
|
||||
enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
|
||||
bool handle_nested_exception(const T &exc, const std::exception_ptr &p) {
|
||||
if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {
|
||||
return handle_nested_exception(*nep, p);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool raise_err(PyObject *exc_type, const char *msg) {
|
||||
if (PyErr_Occurred()) {
|
||||
raise_from(exc_type, msg);
|
||||
return true;
|
||||
}
|
||||
set_error(exc_type, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void translate_exception(std::exception_ptr p) {
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
std::rethrow_exception(p);
|
||||
} catch (error_already_set &e) {
|
||||
handle_nested_exception(e, p);
|
||||
e.restore();
|
||||
return;
|
||||
} catch (const builtin_exception &e) {
|
||||
// Could not use template since it's an abstract class.
|
||||
if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {
|
||||
handle_nested_exception(*nep, p);
|
||||
}
|
||||
e.set_error();
|
||||
return;
|
||||
} catch (const std::bad_alloc &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_MemoryError, e.what());
|
||||
return;
|
||||
} catch (const std::domain_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::invalid_argument &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::length_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::out_of_range &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_IndexError, e.what());
|
||||
return;
|
||||
} catch (const std::range_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_ValueError, e.what());
|
||||
return;
|
||||
} catch (const std::overflow_error &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_OverflowError, e.what());
|
||||
return;
|
||||
} catch (const std::exception &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_RuntimeError, e.what());
|
||||
return;
|
||||
} catch (const std::nested_exception &e) {
|
||||
handle_nested_exception(e, p);
|
||||
raise_err(PyExc_RuntimeError, "Caught an unknown nested exception!");
|
||||
return;
|
||||
} catch (...) {
|
||||
raise_err(PyExc_RuntimeError, "Caught an unknown exception!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(__GLIBCXX__)
|
||||
inline void translate_local_exception(std::exception_ptr p) {
|
||||
try {
|
||||
if (p) {
|
||||
std::rethrow_exception(p);
|
||||
}
|
||||
} catch (error_already_set &e) {
|
||||
e.restore();
|
||||
return;
|
||||
} catch (const builtin_exception &e) {
|
||||
e.set_error();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline object get_python_state_dict() {
|
||||
object state_dict;
|
||||
#if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
|
||||
state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
|
||||
#else
|
||||
# if PY_VERSION_HEX < 0x03090000
|
||||
PyInterpreterState *istate = _PyInterpreterState_Get();
|
||||
# else
|
||||
PyInterpreterState *istate = PyInterpreterState_Get();
|
||||
# endif
|
||||
if (istate) {
|
||||
state_dict = reinterpret_borrow<object>(PyInterpreterState_GetDict(istate));
|
||||
}
|
||||
#endif
|
||||
if (!state_dict) {
|
||||
raise_from(PyExc_SystemError, "pybind11::detail::get_python_state_dict() FAILED");
|
||||
throw error_already_set();
|
||||
}
|
||||
return state_dict;
|
||||
}
|
||||
|
||||
inline object get_internals_obj_from_state_dict(handle state_dict) {
|
||||
return reinterpret_borrow<object>(dict_getitemstring(state_dict.ptr(), PYBIND11_INTERNALS_ID));
|
||||
}
|
||||
|
||||
inline internals **get_internals_pp_from_capsule(handle obj) {
|
||||
void *raw_ptr = PyCapsule_GetPointer(obj.ptr(), /*name=*/nullptr);
|
||||
if (raw_ptr == nullptr) {
|
||||
raise_from(PyExc_SystemError, "pybind11::detail::get_internals_pp_from_capsule() FAILED");
|
||||
throw error_already_set();
|
||||
}
|
||||
return static_cast<internals **>(raw_ptr);
|
||||
}
|
||||
|
||||
/// Return a reference to the current `internals` data
|
||||
PYBIND11_NOINLINE internals &get_internals() {
|
||||
auto **&internals_pp = get_internals_pp();
|
||||
if (internals_pp && *internals_pp) {
|
||||
return **internals_pp;
|
||||
}
|
||||
|
||||
#if defined(WITH_THREAD)
|
||||
# if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
|
||||
gil_scoped_acquire gil;
|
||||
# else
|
||||
// Ensure that the GIL is held since we will need to make Python calls.
|
||||
// Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
|
||||
struct gil_scoped_acquire_local {
|
||||
gil_scoped_acquire_local() : state(PyGILState_Ensure()) {}
|
||||
gil_scoped_acquire_local(const gil_scoped_acquire_local &) = delete;
|
||||
gil_scoped_acquire_local &operator=(const gil_scoped_acquire_local &) = delete;
|
||||
~gil_scoped_acquire_local() { PyGILState_Release(state); }
|
||||
const PyGILState_STATE state;
|
||||
} gil;
|
||||
# endif
|
||||
#endif
|
||||
error_scope err_scope;
|
||||
|
||||
dict state_dict = get_python_state_dict();
|
||||
if (object internals_obj = get_internals_obj_from_state_dict(state_dict)) {
|
||||
internals_pp = get_internals_pp_from_capsule(internals_obj);
|
||||
}
|
||||
if (internals_pp && *internals_pp) {
|
||||
// We loaded the internals through `state_dict`, which means that our `error_already_set`
|
||||
// and `builtin_exception` may be different local classes than the ones set up in the
|
||||
// initial exception translator, below, so add another for our local exception classes.
|
||||
//
|
||||
// libstdc++ doesn't require this (types there are identified only by name)
|
||||
// libc++ with CPython doesn't require this (types are explicitly exported)
|
||||
// libc++ with PyPy still need it, awaiting further investigation
|
||||
#if !defined(__GLIBCXX__)
|
||||
(*internals_pp)->registered_exception_translators.push_front(&translate_local_exception);
|
||||
#endif
|
||||
} else {
|
||||
if (!internals_pp) {
|
||||
internals_pp = new internals *();
|
||||
}
|
||||
auto *&internals_ptr = *internals_pp;
|
||||
internals_ptr = new internals();
|
||||
#if defined(WITH_THREAD)
|
||||
|
||||
PyThreadState *tstate = PyThreadState_Get();
|
||||
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
|
||||
if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {
|
||||
pybind11_fail("get_internals: could not successfully initialize the tstate TSS key!");
|
||||
}
|
||||
PYBIND11_TLS_REPLACE_VALUE(internals_ptr->tstate, tstate);
|
||||
|
||||
# if PYBIND11_INTERNALS_VERSION > 4
|
||||
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
|
||||
if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->loader_life_support_tls_key)) {
|
||||
pybind11_fail("get_internals: could not successfully initialize the "
|
||||
"loader_life_support TSS key!");
|
||||
}
|
||||
# endif
|
||||
internals_ptr->istate = tstate->interp;
|
||||
#endif
|
||||
state_dict[PYBIND11_INTERNALS_ID] = capsule(internals_pp);
|
||||
internals_ptr->registered_exception_translators.push_front(&translate_exception);
|
||||
internals_ptr->static_property_type = make_static_property_type();
|
||||
internals_ptr->default_metaclass = make_default_metaclass();
|
||||
internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
|
||||
}
|
||||
return **internals_pp;
|
||||
}
|
||||
|
||||
// the internals struct (above) is shared between all the modules. local_internals are only
|
||||
// for a single module. Any changes made to internals may require an update to
|
||||
// PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,
|
||||
// restricted to a single module. Whether a module has local internals or not should not
|
||||
// impact any other modules, because the only things accessing the local internals is the
|
||||
// module that contains them.
|
||||
struct local_internals {
|
||||
type_map<type_info *> registered_types_cpp;
|
||||
std::forward_list<ExceptionTranslator> registered_exception_translators;
|
||||
#if defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4
|
||||
|
||||
// For ABI compatibility, we can't store the loader_life_support TLS key in
|
||||
// the `internals` struct directly. Instead, we store it in `shared_data` and
|
||||
// cache a copy in `local_internals`. If we allocated a separate TLS key for
|
||||
// each instance of `local_internals`, we could end up allocating hundreds of
|
||||
// TLS keys if hundreds of different pybind11 modules are loaded (which is a
|
||||
// plausible number).
|
||||
PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
|
||||
|
||||
// Holds the shared TLS key for the loader_life_support stack.
|
||||
struct shared_loader_life_support_data {
|
||||
PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
|
||||
shared_loader_life_support_data() {
|
||||
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
|
||||
if (!PYBIND11_TLS_KEY_CREATE(loader_life_support_tls_key)) {
|
||||
pybind11_fail("local_internals: could not successfully initialize the "
|
||||
"loader_life_support TLS key!");
|
||||
}
|
||||
}
|
||||
// We can't help but leak the TLS key, because Python never unloads extension modules.
|
||||
};
|
||||
|
||||
local_internals() {
|
||||
auto &internals = get_internals();
|
||||
// Get or create the `loader_life_support_stack_key`.
|
||||
auto &ptr = internals.shared_data["_life_support"];
|
||||
if (!ptr) {
|
||||
ptr = new shared_loader_life_support_data;
|
||||
}
|
||||
loader_life_support_tls_key
|
||||
= static_cast<shared_loader_life_support_data *>(ptr)->loader_life_support_tls_key;
|
||||
}
|
||||
#endif // defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4
|
||||
};
|
||||
|
||||
/// Works like `get_internals`, but for things which are locally registered.
|
||||
inline local_internals &get_local_internals() {
|
||||
// Current static can be created in the interpreter finalization routine. If the later will be
|
||||
// destroyed in another static variable destructor, creation of this static there will cause
|
||||
// static deinitialization fiasco. In order to avoid it we avoid destruction of the
|
||||
// local_internals static. One can read more about the problem and current solution here:
|
||||
// https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
|
||||
static auto *locals = new local_internals();
|
||||
return *locals;
|
||||
}
|
||||
|
||||
/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its
|
||||
/// `c_str()`. Such strings objects have a long storage duration -- the internal strings are only
|
||||
/// cleared when the program exits or after interpreter shutdown (when embedding), and so are
|
||||
/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name).
|
||||
template <typename... Args>
|
||||
const char *c_str(Args &&...args) {
|
||||
auto &strings = get_internals().static_strings;
|
||||
strings.emplace_front(std::forward<Args>(args)...);
|
||||
return strings.front().c_str();
|
||||
}
|
||||
|
||||
inline const char *get_function_record_capsule_name() {
|
||||
#if PYBIND11_INTERNALS_VERSION > 4
|
||||
return get_internals().function_record_capsule_name.c_str();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Determine whether or not the following capsule contains a pybind11 function record.
|
||||
// Note that we use `internals` to make sure that only ABI compatible records are touched.
|
||||
//
|
||||
// This check is currently used in two places:
|
||||
// - An important optimization in functional.h to avoid overhead in C++ -> Python -> C++
|
||||
// - The sibling feature of cpp_function to allow overloads
|
||||
inline bool is_function_record_capsule(const capsule &cap) {
|
||||
// Pointer equality as we rely on internals() to ensure unique pointers
|
||||
return cap.name() == get_function_record_capsule_name();
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
/// Returns a named pointer that is shared among all extension modules (using the same
|
||||
/// pybind11 version) running in the current interpreter. Names starting with underscores
|
||||
/// are reserved for internal usage. Returns `nullptr` if no matching entry was found.
|
||||
PYBIND11_NOINLINE void *get_shared_data(const std::string &name) {
|
||||
auto &internals = detail::get_internals();
|
||||
auto it = internals.shared_data.find(name);
|
||||
return it != internals.shared_data.end() ? it->second : nullptr;
|
||||
}
|
||||
|
||||
/// Set the shared data that can be later recovered by `get_shared_data()`.
|
||||
PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
|
||||
detail::get_internals().shared_data[name] = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if
|
||||
/// such entry exists. Otherwise, a new object of default-constructible type `T` is
|
||||
/// added to the shared data under the given name and a reference to it is returned.
|
||||
template <typename T>
|
||||
T &get_or_create_shared_data(const std::string &name) {
|
||||
auto &internals = detail::get_internals();
|
||||
auto it = internals.shared_data.find(name);
|
||||
T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
|
||||
if (!ptr) {
|
||||
ptr = new T();
|
||||
internals.shared_data[name] = ptr;
|
||||
}
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
1214
thirdparty/pybind11/include/pybind11/detail/type_caster_base.h
vendored
Normal file
1214
thirdparty/pybind11/include/pybind11/detail/type_caster_base.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user