├── async_io ├── asyncio │ ├── __init__.py │ └── async_executor.py ├── websocket │ └── __init__.py └── rest │ └── __init__.py ├── cpp_api_binding ├── generator │ ├── autocxxpy │ │ ├── __init__.py │ │ ├── clang │ │ │ ├── __init__.py │ │ │ └── enumerations.py │ │ ├── type.py │ │ ├── textholder.py │ │ └── preprocessor.py │ ├── __init__.py │ ├── .gitignore │ ├── templates │ │ ├── wrapper_class.h │ │ ├── hint.py.in │ │ ├── class_generators.h │ │ ├── wrappers.hpp │ │ ├── class.cpp │ │ ├── module.cpp │ │ ├── property_helper.hpp │ │ └── dispatcher.hpp │ ├── tests │ │ └── tests │ │ │ ├── tests.vcxproj.user │ │ │ ├── tests.vcxproj.filters │ │ │ ├── Source.cpp │ │ │ └── tests.vcxproj │ ├── 3rd_party │ │ ├── googletest │ │ │ ├── gtest.vcxproj.user │ │ │ ├── gtest.vcxproj.filters │ │ │ ├── src │ │ │ │ ├── gtest_main.cc │ │ │ │ ├── gtest-test-part.cc │ │ │ │ ├── gtest-typed-test.cc │ │ │ │ └── gtest-matchers.cc │ │ │ ├── gtest-all.cc │ │ │ └── gtest.vcxproj │ │ └── include │ │ │ └── gtest │ │ │ ├── internal │ │ │ ├── custom │ │ │ │ ├── README.md │ │ │ │ ├── gtest.h │ │ │ │ ├── gtest-port.h │ │ │ │ └── gtest-printers.h │ │ │ ├── gtest-port-arch.h │ │ │ ├── gtest-string.h │ │ │ └── gtest-param-util-generated.h.pump │ │ │ ├── gtest_prod.h │ │ │ ├── gtest-test-part.h │ │ │ └── gtest-message.h │ ├── TODO.txt │ ├── doc │ │ ├── ctp.md │ │ └── converts.md │ ├── env.props │ ├── README.MD │ ├── generate_ctp.py │ ├── adaptor │ │ └── ctpadaptor.py │ └── tests.sln ├── TODO.txt ├── __init__.py ├── tests │ ├── __init__.py │ └── test.py ├── source │ ├── CMakeLists.txt │ └── ctp │ │ ├── api │ │ ├── ThostFtdcMdApi.h │ │ ├── ThostFtdcTraderApi.h │ │ ├── thostmduserapi_se.dll │ │ ├── thostmduserapi_se.lib │ │ ├── thosttraderapi_se.dll │ │ ├── thosttraderapi_se.lib │ │ ├── ThostFtdcUserApiDataType.h │ │ └── ThostFtdcUserApiStruct.h │ │ ├── CMakeLists.txt │ │ ├── custom_wrappers │ │ └── spi.hpp │ │ ├── property_helper.hpp │ │ └── dispatcher.hpp ├── third_party │ └── include │ │ └── pybind11 │ │ ├── common.h │ │ ├── detail │ │ ├── typeid.h │ │ └── descr.h │ │ ├── complex.h │ │ ├── options.h │ │ ├── functional.h │ │ ├── eval.h │ │ ├── buffer_info.h │ │ ├── iostream.h │ │ ├── chrono.h │ │ ├── embed.h │ │ └── operators.h ├── CMakeLists.txt ├── README.md ├── doc │ ├── build.md │ ├── build.linux.md │ └── build.windows.md ├── build.bat └── cmake │ ├── py_find.cmake │ ├── py.cmake │ └── flags.cmake ├── candle_chart ├── __init__.py ├── base │ ├── __init__.py │ ├── data_source.py │ ├── base.py │ └── drawer.py └── candle.py ├── README.md ├── code_format └── .flake8 ├── LICENSE └── .gitignore /async_io/asyncio/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/autocxxpy/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cpp_api_binding/TODO.txt: -------------------------------------------------------------------------------- 1 | * use CMake as build system -------------------------------------------------------------------------------- /async_io/websocket/__init__.py: -------------------------------------------------------------------------------- 1 | from .websocket_client import WebsocketClient 2 | -------------------------------------------------------------------------------- /cpp_api_binding/__init__.py: -------------------------------------------------------------------------------- 1 | # this file is created only for making pylint work 2 | -------------------------------------------------------------------------------- /candle_chart/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | """ 4 | from .candle import CandleChart 5 | 6 | -------------------------------------------------------------------------------- /cpp_api_binding/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # this file is created only for making pylint work 2 | -------------------------------------------------------------------------------- /async_io/rest/__init__.py: -------------------------------------------------------------------------------- 1 | from .rest_client import Request, RequestStatus, RestClient 2 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/__init__.py: -------------------------------------------------------------------------------- 1 | # this file is created only for making pylint work 2 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vs/ 3 | 4 | build/ 5 | generated_files/ 6 | 7 | *.pyc -------------------------------------------------------------------------------- /cpp_api_binding/source/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | add_subdirectory(ctp) 4 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/wrapper_class.h: -------------------------------------------------------------------------------- 1 | 2 | class Py$class_name : public $class_name 3 | { 4 | public: 5 | $body 6 | }; 7 | -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/ThostFtdcMdApi.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/ThostFtdcMdApi.h -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/ThostFtdcTraderApi.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/ThostFtdcTraderApi.h -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/thostmduserapi_se.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/thostmduserapi_se.dll -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/thostmduserapi_se.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/thostmduserapi_se.lib -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/thosttraderapi_se.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/thosttraderapi_se.dll -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/thosttraderapi_se.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/thosttraderapi_se.lib -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/ThostFtdcUserApiDataType.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/ThostFtdcUserApiDataType.h -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/api/ThostFtdcUserApiStruct.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vnpy/vnpy_lab/HEAD/cpp_api_binding/source/ctp/api/ThostFtdcUserApiStruct.h -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/common.h: -------------------------------------------------------------------------------- 1 | #include "detail/common.h" 2 | #warning "Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'." 3 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/hint.py.in: -------------------------------------------------------------------------------- 1 | # noinspection PyUnresolvedReferences 2 | from typing import * 3 | # noinspection PyUnresolvedReferences 4 | from enum import Enum 5 | 6 | 7 | $hint_code 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vn.py lab 2 | 3 | * cpp_api_binding: 4 | * 基于clang的C++ API结构分析 5 | * 自动生成pybind11的封装代码 6 | * 采用对象(而非字典)作为API中使用的数据结构 7 | * 使用全局Dispatcher实现Python内的异步回调,只有一个线程从而实现更好的性能(减少GIL获取开销) 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/tests/tests/tests.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/class_generators.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include 5 | 6 | #include "dispatcher.hpp" 7 | #include "property_helper.hpp" 8 | #include "wrapper_helper.hpp" 9 | 10 | $includes 11 | 12 | $class_generator_declarations 13 | 14 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/gtest.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/wrappers.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "dispatcher.hpp" 6 | #include "property_helper.hpp" 7 | #include "wrapper_helper.hpp" 8 | 9 | #include "class_generators.h" 10 | 11 | $includes 12 | 13 | $wrappers 14 | -------------------------------------------------------------------------------- /cpp_api_binding/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(vnpy_binding) 4 | 5 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") 6 | include(cmake/flags.cmake) 7 | include(cmake/py.cmake) 8 | 9 | include_directories(third_party/include) 10 | 11 | add_subdirectory(source) 12 | -------------------------------------------------------------------------------- /code_format/.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude = .git,__pycache__,clang,build,dist,generated_files,templates,__init__.py, 3 | ignore = 4 | E501 line too long, fixed by black 5 | W503 line break before binary operator 6 | 7 | W293 blank line contains whitespace 8 | W291 trailing whitespace 9 | 10 | [pycodestyle] 11 | max_line_length = 79 -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/class.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "dispatcher.hpp" 6 | #include "property_helper.hpp" 7 | #include "wrapper_helper.hpp" 8 | #include "wrappers.hpp" 9 | 10 | #include "class_generators.h" 11 | 12 | $includes 13 | 14 | $class_generator_definition -------------------------------------------------------------------------------- /cpp_api_binding/README.md: -------------------------------------------------------------------------------- 1 | # vnpy.bindings 2 | 3 | 这个文件夹包含了vnpy中所有对c++层的封装 4 | 5 | 所有的封装都是使用脚本生成的,使用的脚本为autocxxpy 6 | 7 | 若要看如何构建,请看[build.md](./doc/build.md) 8 | 9 | --- 10 | 11 | ## 目录结构 12 | * cmake/ cmake相关文件 13 | * source/ 所有源码都在这里 14 | * tests/ 测试相关文件 15 | * third_party/ 第三方库的文件,包括头文件,源码或者库文件 16 | 17 | --- 18 | -------------------------------------------------------------------------------- /cpp_api_binding/doc/build.md: -------------------------------------------------------------------------------- 1 | # Building vnpy.bindings 2 | 3 | vnpy.binding使用CMake作为构建系统,正常地使用CMake去构建即可。 4 | 5 | 我们也提供了针对不同操作系统的简单教程。 6 | 7 | ## 前置要求 8 | 9 | * Python3 10 | * 支持C++17标准及以上的C++编译器(Visual Studio 2017+,GCC7+) 11 | * CMake 12 | 13 | ## 简单教程 14 | 针对不同操作系统有不同的构建方式,请查看对应的文件。 15 | 16 | * Windows : [build.windows.md](./build.windows.md) 17 | * Linux : [build.linux.md](./build.linux.md) 18 | -------------------------------------------------------------------------------- /cpp_api_binding/build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | if "%VS150COMNTOOLS%"=="" ( 3 | echo Please run this batch file under "x64 Native Tools Command Prompt for VS 2017" 4 | echo Read the doc! 5 | exit 1 6 | ) 7 | 8 | @echo on 9 | set binding_dir=%~dp0 10 | cd %binding_dir% 11 | 12 | rmdir /S /Q build 13 | mkdir build 14 | cd build 15 | cmake -G "Visual Studio 15 2017 Win64" .. 16 | msbuild vnpy_binding.sln /p:Configuration=Release /p:Platform=x64 17 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/TODO.txt: -------------------------------------------------------------------------------- 1 | todo: 2 | tests: 3 | app: 4 | * ctp test 5 | 6 | future plan: 7 | cxx_analysis: 8 | * namespaces 9 | 10 | 11 | not supported: 12 | * namespace is currently not supported 13 | * c++11 strong typed enums(treat as traditional enum) 14 | * constructor is not supported 15 | * default arguments are not supported 16 | 17 | hacks: 18 | * treat any virtual function as callback 19 | * if argument for a async callback is pointer or reference, its value will be copied, modifying its value will have no effect 20 | * 21 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/doc/ctp.md: -------------------------------------------------------------------------------- 1 | #为类ctp接口生成代码 2 | 3 | ## 为ctp接口生成代码 4 | 5 | 运行generate_ctp.py即可,生成的文件位于generated_files/目录下 6 | 7 | ## 为类ctp接口生成代码 8 | 9 | 我们提供了一个CtpAdaptor,位于generator/adaptor目录下。 10 | 参考generate_ctp.py使用即可。 11 | 额外需要手写的的custom_wrapper在/vnpy/binding/source/ctp/custeom_wrapper下已经有了成品。 12 | 13 | ## 细节 14 | ### CtpAdaptor如何工作 15 | 16 | 这个适配器作了以下工作: 17 | 1.将识别为常量的define加入全局常量之中 18 | 2.将所有Api的函数设置为final,防止python调用的时候去检查python端的overload,提升效率。 19 | 3.将所有Spi的函数设置为virtual,非final(默认就是这样的) 20 | 4.增加include一个wrapper:custeom_wrappers/spi.hpp,这个wrapper需要自己写,一般是用来自己实现spi的回调调用(以后会考虑自动生成代码) 21 | 22 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/autocxxpy/clang/__init__.py: -------------------------------------------------------------------------------- 1 | #===- __init__.py - Clang Python Bindings --------------------*- python -*--===# 2 | # 3 | # The LLVM Compiler Infrastructure 4 | # 5 | # This file is distributed under the University of Illinois Open Source 6 | # License. See LICENSE.TXT for details. 7 | # 8 | #===------------------------------------------------------------------------===# 9 | 10 | r""" 11 | Clang Library Bindings 12 | ====================== 13 | 14 | This package provides access to the Clang compiler and libraries. 15 | 16 | The available modules are: 17 | 18 | cindex 19 | 20 | Bindings for the Clang indexing library. 21 | """ 22 | 23 | __all__ = ['cindex'] 24 | 25 | -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(vnctp) 2 | 3 | set(HEADERS 4 | class_generators.h 5 | dispatcher.hpp 6 | property_helper.hpp 7 | vnctptd.cpp 8 | wrappers.hpp 9 | wrapper_helper.hpp 10 | ) 11 | 12 | 13 | set(SOURCES 14 | classes_1.cpp 15 | classes_2.cpp 16 | classes_3.cpp 17 | classes_4.cpp 18 | vnctp.cpp 19 | ) 20 | 21 | include_directories(${PY_INCLUDE_DIRS}) 22 | link_directories(${PY_LIBRARY_DIRS}) 23 | include_directories("${CMAKE_CURRENT_SOURCE_DIR}/api") 24 | link_directories("${CMAKE_CURRENT_SOURCE_DIR}/api") 25 | 26 | 27 | add_library(vnctp SHARED ${SOURCES}) 28 | target_link_libraries(vnctp ${PY_LIBRARIES}) 29 | target_link_libraries(vnctp thostmduserapi_se thosttraderapi_se) 30 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/env.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(SolutionDir)..\build\tests\$(Platform)\$(Configuration)\ 7 | $(SolutionDir)..\build\tests\intermediate\$(ProjectName)\$(Platform)\$(Configuration)\ 8 | $(SolutionDir)\3rd_party\include;$(SolutionDir)\templates;$(IncludePath) 9 | 10 | 11 | 12 | stdcpp17 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /candle_chart/base/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | """ 4 | from .axis import ( 5 | AutoGeneratedAxisDataSource, 6 | AxisBase, 7 | AxisDataSource, 8 | BarAxisX, 9 | BarAxisY, 10 | CandleLabelDataSource, 11 | DateTimeDataSource, 12 | GridDrawer, 13 | LabelDrawer, 14 | LineGridDataSource, 15 | LineGridDrawer, 16 | TextLabelDrawer, 17 | TextLabelInfo, 18 | ValueAxisX, 19 | ValueAxisY, 20 | CandleAxisX, 21 | ValueLabelDataSource, 22 | ValueSequenceGenerator, 23 | ) 24 | from .base import Alignment, DrawConfig, DrawingCache, Orientation 25 | from .data_source import CandleData, CandleDataSource, DataSource, DataSourceQObject 26 | from .drawer import BarChartDrawer, CandleChartDrawer, ChartDrawerBase, HistogramDrawer 27 | from .chart import ChartWidget 28 | from .advanced_chart import AdvancedChartWidget 29 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/module.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "dispatcher.hpp" 6 | #include "property_helper.hpp" 7 | #include "wrapper_helper.hpp" 8 | 9 | #include "class_generators.h" 10 | 11 | $includes 12 | 13 | void init_dispatcher() 14 | { 15 | autocxxpy::dispatcher::instance().start(); 16 | } 17 | 18 | void generate_classes(pybind11::module &m) 19 | { 20 | $classes_code 21 | } 22 | 23 | void generate_enums(pybind11::module &m) 24 | { 25 | $enums_code 26 | } 27 | 28 | void generate_constants(pybind11::module &m) 29 | { 30 | $constants_code 31 | } 32 | 33 | // begin generated code - combined_class_generator_definitions 34 | // code will appear only when split_in_files is off 35 | $combined_class_generator_definitions 36 | // end generated code 37 | 38 | PYBIND11_MODULE($module_name, m) 39 | { 40 | init_dispatcher(); 41 | generate_classes(m); 42 | generate_constants(m); 43 | generate_enums(m); 44 | } 45 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/tests/tests/tests.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/gtest.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /cpp_api_binding/doc/build.linux.md: -------------------------------------------------------------------------------- 1 | # Building vnpy.binding on Linux 2 | 3 | 目前只有Ubuntu和CentOS两种Linux发行版的教程。 4 | 5 | ## 硬件要求 6 | 7 | 使用G++编译vnpy.binding需要至少3G的可用内存,否则请调整虚拟内存大小。 8 | 9 | ## Ubuntu 10 | 11 | 首先是安装编译套件,python3及其依赖库,git,cmake: 12 | ```bash 13 | sudo apt install -y build-essential python3.7 python3.7-dev git cmake 14 | ``` 15 | 16 | 然后克隆vnpy源码: 17 | ```bash 18 | git clone https://github.com/vnpy/vnpy.git 19 | cd vnpy 20 | git checkout v2.0-DEV 21 | ``` 22 | 23 | 构建 24 | ```bash 25 | cd binding 26 | mkdir build; cd build 27 | cmake .. 28 | make 29 | ``` 30 | 31 | 32 | ## CentOS 33 | 34 | 首先启用epel和scl源 35 | ```bash 36 | sudo yum install -y epel-release centos-release-scl 37 | ``` 38 | 39 | 然后安装编译套件,python3及其依赖库,git,cmake: 40 | ```bash 41 | sudo yum install -y devtoolset-7 python36 python36-devel git cmake3 42 | ``` 43 | 44 | 接着克隆vnpy源码: 45 | ```bash 46 | git clone https://github.com/vnpy/vnpy.git 47 | cd vnpy 48 | git checkout v2.0-DEV 49 | ``` 50 | 51 | 最后启用gcc7并构建: 52 | ```bash 53 | cd binding 54 | mkdir build; cd build 55 | scl enable devtoolset-7 bash 56 | cmake3 .. 57 | make 58 | ``` 59 | 60 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/README.MD: -------------------------------------------------------------------------------- 1 | # autocxxpy 2 | 3 | ## 项目主旨 4 | 5 | 这个项目意在分析C++头文件,并且生成一个对应的pyd文件,以便python调用。 6 | 作为vnpy的一个代码生成工具,目前主要用来生成vnpy.binding的代码,以便vnpy调用C++的东西。 7 | 8 | ## 特点 9 | 10 | * 可以从头文件以及相应的依赖库直接生pyd文件对应的代码。 11 | * 可以在C++层自定义任何函数的转化细节 12 | * 精准的分析:基于clang进行语法分析,不会因为代码格式而出现分析失误。 13 | 14 | ## 可以做到哪些东西 15 | 目前可以正确分析C++的以下元素: 16 | 全局域: 17 | define 18 | enum 19 | class/struct 20 | functions 21 | typedef 22 | class: 23 | data member(variable) 24 | method(functions) 25 | destructor 26 | 27 | ## 分析正确率 28 | 基于CLang编译器,分析的正确率取决于clang。 29 | 30 | ## 转化细节 31 | 32 | 请看[converts.md](doc/converts.md) 33 | 34 | ## 如何使用 35 | 36 | 在使用之前,先下载[clang]。如果需要其他版本的CLang,[请看这里](http://releases.llvm.org/download.html)。 37 | 安装好clang之后将所需的库复制至/vnpy/binding/generator/目录下。 38 | 在Windows下所需的库是libclang.dll。Linux下则为libclang.so。 39 | 40 | 如果想为类ctp接口生成代码,请看[ctp.md](doc/ctp.md) 41 | 42 | 如果想为新接口生成代码,请看[converts.md](doc/converts.md) 43 | 44 | ## 以后会增加哪些支持 45 | 增加什么的分析主要看以后遇到哪些接口。 46 | 若目前的生成器能无法分析所遇到接口的所有元素,那么肯定会增加新功能。 47 | 48 | 49 | [clang]:http://releases.llvm.org/7.0.1/LLVM-7.0.1-win64.exe -------------------------------------------------------------------------------- /cpp_api_binding/cmake/py_find.cmake: -------------------------------------------------------------------------------- 1 | # try to find python use : user_defined_path, FindPython3 and FindPythonLibs 2 | # outputs: PY_LIBRARIES PY_INCLUDE_DIRS 3 | 4 | # check if user supplied path 5 | if(USER_PYTHON_LIBRARIY AND USER_PYTHON_INCLUDE_DIRS) 6 | set(PY_LIBRARIES ${USER_PYTHON_LIBRARIY}) 7 | set(PY_INCLUDE_DIRS ${USER_PYTHON_INCLUDE_DIRS}) 8 | message("use user supplied python paths") 9 | return() 10 | endif() 11 | 12 | if (${CMAKE_VERSION} VERSION_GREATER "3.12.0") 13 | find_package(Python3) 14 | 15 | if(${Python3_LIBRARIES} AND ${Python3_INCLUDE_DIRS}) 16 | set(PY_LIBRARIES ${Python3_LIBRARIES}) 17 | set(PY_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) 18 | message("use FindPython3 found python paths") 19 | return() 20 | endif() 21 | endif() 22 | 23 | find_package(PythonLibs 3) 24 | 25 | if(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS) 26 | set(PY_LIBRARIES ${PYTHON_LIBRARIES}) 27 | set(PY_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) 28 | message("use FindPythonLibs found python paths") 29 | return() 30 | endif() 31 | 32 | message(WARNING "no python path found!") -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 vn.py 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/autocxxpy/type.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | import re 3 | 4 | base_types = { 5 | "char8_t", 6 | "char16_t", 7 | "char32_t", 8 | "wchar_t", 9 | "char", 10 | "short", 11 | "int", 12 | "long", 13 | "long long" "unsigned char", 14 | "unsigned short", 15 | "unsigned int", 16 | "unsigned long", 17 | "unsigned long long", 18 | "float", 19 | "double", 20 | } 21 | 22 | 23 | def is_array_type(t: str): 24 | return "[" in t 25 | 26 | 27 | def array_base(t: str): 28 | """ 29 | :raise ValueError if t is not a array type 30 | """ 31 | return t[: t.index("[") - 1] 32 | 33 | 34 | def is_pointer_type(t: str): 35 | return "*" in t 36 | 37 | 38 | _REMOVE_POINTER_RE = re.compile("[ \t]*\\*[ \t]*") 39 | 40 | 41 | def pointer_base(t: str): 42 | return _REMOVE_POINTER_RE.sub("", t) 43 | 44 | 45 | def is_reference_type(t: str): 46 | return "&" in t 47 | 48 | 49 | def remove_cvref(t: str): 50 | return ( 51 | t.replace("const ", "") 52 | .replace("volatile ", "") 53 | .replace("&", "") 54 | .strip() 55 | ) 56 | -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/custom_wrappers/spi.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../api/ThostFtdcMdApi.h" 6 | #include "../wrapper_helper.hpp" 7 | 8 | namespace autocxxpy 9 | { 10 | 11 | template 12 | struct spi_vector_wrapper 13 | { 14 | static constexpr auto value = [](CThostFtdcMdApi *instance, std::vector &arg) 15 | { 16 | return (instance->*method)(&arg.at(0), static_cast(arg.size())); 17 | }; 18 | }; 19 | 20 | #define DEF_SPI_VECTOR_CALLING_WRAPPER(method) \ 21 | template <>\ 22 | struct calling_wrapper \ 23 | : spi_vector_wrapper\ 24 | {}; 25 | 26 | DEF_SPI_VECTOR_CALLING_WRAPPER(&CThostFtdcMdApi::SubscribeMarketData) 27 | DEF_SPI_VECTOR_CALLING_WRAPPER(&CThostFtdcMdApi::UnSubscribeMarketData) 28 | DEF_SPI_VECTOR_CALLING_WRAPPER(&CThostFtdcMdApi::SubscribeForQuoteRsp) 29 | DEF_SPI_VECTOR_CALLING_WRAPPER(&CThostFtdcMdApi::UnSubscribeForQuoteRsp) 30 | //template <> 31 | //struct calling_wrapper<&CThostFtdcMdApi::SubscribeMarketData> 32 | // : spi_vector_wrapper<&CThostFtdcMdApi::SubscribeMarketData> 33 | //{}; 34 | } 35 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/generate_ctp.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | 4 | from adaptor.ctpadaptor import CtpAdaptor 5 | from autocxxpy.generator import GeneratorOptions, Generator 6 | 7 | logger = logging.getLogger(__file__) 8 | 9 | 10 | def clear_dir(path: str): 11 | for file in os.listdir(path): 12 | os.unlink(os.path.join(path, file)) 13 | 14 | 15 | def main(): 16 | options: GeneratorOptions = CtpAdaptor( 17 | "../source/ctp/api/ThostFtdcMdApi.h", 18 | "../source/ctp/api/ThostFtdcTraderApi.h", 19 | ).parse() 20 | 21 | options.includes.append("api/ThostFtdcTraderApi.h") 22 | options.includes.append("api/ThostFtdcMdApi.h") 23 | options.split_in_files = True 24 | options.module_name = "vnctp" 25 | options.max_classes_in_one_file = 100 26 | 27 | saved_files = Generator(options=options).generate() 28 | output_dir = "./generated_files" 29 | # clear output dir 30 | if not os.path.exists(output_dir): 31 | os.mkdir(output_dir) 32 | clear_dir(output_dir) 33 | 34 | for name, data in saved_files.items(): 35 | with open(f"{output_dir}/{name}", "wt") as f: 36 | f.write(data) 37 | 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /cpp_api_binding/doc/build.windows.md: -------------------------------------------------------------------------------- 1 | # Building vnpy.binding on Windows 2 | 3 | ## 环境要求 4 | 5 | 在编译之前,你必须确保已经安装好如下组件: 6 | * [Python3][Python] 7 | * [CMake][CMake] 8 | * [Visual Studio 2017][VS2017] with C++ Desktop Development 9 | 10 | > 在安装CMake的时候必须勾选将CMake加入PATH 11 | > 在安装Visual Studio的时候必须勾选使用C++的桌面开发(Desktop Development with C++) 12 | 13 | ## 一键编译 14 | 15 | 打开开始菜单-Visual Studio 2017-x64 Native Tools Command Prompt for VS 2017 16 | 将vnpy/binding/build.bat拖入弹出的控制台,回车运行即可。 17 | 18 | 19 | ## 手动编译 20 | 21 | 确保你安装好了Python3,CMake还有Visual Studio和C++编译环境,下载好[vnpy]并解压。 22 | 打开开始菜单-Visual Studio 2017-x64 Native Tools Command Prompt for VS 2017 23 | 在弹出的控制台中运行以下命令(将vnpy解压目录改为你将vnpy解压到的目录): 24 | ```bat 25 | cd vnpy解压目录 26 | mkdir binding\build 27 | cd binding\build 28 | cmake -G "Visual Studio 15 2017 Win64" .. 29 | msbuild vnpy_binding.sln /p:Configuration=Release /p:Platform=x64 30 | ``` 31 | 32 | [Python]:https://www.python.org/ftp/python/3.7.2/python-3.7.2-amd64-webinstall.exe 33 | [CMake]:https://github.com/Kitware/CMake/releases/download/v3.13.3/cmake-3.13.3-win64-x64.msi 34 | [VS2017]:https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=Community&rel=15# 35 | [vnpy]:https://github.com/vnpy/vnpy/archive/v2.0-DEV.zip 36 | -------------------------------------------------------------------------------- /cpp_api_binding/cmake/py.cmake: -------------------------------------------------------------------------------- 1 | # try to find python use : user_defined_path, FindPython3 and FindPythonLibs 2 | # outputs: USER_PYTHON_LIBRARIY USER_PYTHON_INCLUDE_DIRS 3 | 4 | 5 | # ignore default input library in MSVC first 6 | if (CMAKE_CXX_COMPILER_ID MATCHES MSVC) 7 | set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:\"python37_d.lib\"") 8 | set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:\"python37.lib\"") 9 | endif() 10 | 11 | # define user options 12 | set(USER_PYTHON_LIBRARIY ${USER_PYTHON_LIBRARIY} CACHE PATH "include dir for python3, eg: C:/Python37/include") 13 | set(USER_PYTHON_INCLUDE_DIRS ${USER_PYTHON_INCLUDE_DIRS} CACHE FILEPATH "Helpstring, eg: C:/Python37/libs/python3.lib") 14 | 15 | include(cmake/py_find.cmake) 16 | 17 | set(USER_PYTHON_LIBRARIY ${PY_LIBRARIES} CACHE PATH "include dir for python3, eg: C:/Python37/include" FORCE) 18 | set(USER_PYTHON_INCLUDE_DIRS ${PY_INCLUDE_DIRS} CACHE FILEPATH "Helpstring, eg: C:/Python37/libs/python3.lib" FORCE) 19 | 20 | message("USER_PYTHON_LIBRARIY : ${USER_PYTHON_LIBRARIY}") 21 | message("USER_PYTHON_INCLUDE_DIRS : ${USER_PYTHON_INCLUDE_DIRS}") 22 | 23 | include_directories(${USER_PYTHON_INCLUDE_DIRS}) 24 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/autocxxpy/clang/enumerations.py: -------------------------------------------------------------------------------- 1 | #===- enumerations.py - Python Enumerations ------------------*- python -*--===# 2 | # 3 | # The LLVM Compiler Infrastructure 4 | # 5 | # This file is distributed under the University of Illinois Open Source 6 | # License. See LICENSE.TXT for details. 7 | # 8 | #===------------------------------------------------------------------------===# 9 | 10 | # pylint: skip-file 11 | 12 | """ 13 | Clang Enumerations 14 | ================== 15 | 16 | This module provides static definitions of enumerations that exist in libclang. 17 | 18 | Enumerations are typically defined as a list of tuples. The exported values are 19 | typically munged into other types or classes at module load time. 20 | 21 | All enumerations are centrally defined in this file so they are all grouped 22 | together and easier to audit. And, maybe even one day this file will be 23 | automatically generated by scanning the libclang headers! 24 | """ 25 | 26 | # Maps to CXTokenKind. Note that libclang maintains a separate set of token 27 | # enumerations from the C++ API. 28 | TokenKinds = [ 29 | ('PUNCTUATION', 0), 30 | ('KEYWORD', 1), 31 | ('IDENTIFIER', 2), 32 | ('LITERAL', 3), 33 | ('COMMENT', 4), 34 | ] 35 | 36 | __all__ = ['TokenKinds'] 37 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/doc/converts.md: -------------------------------------------------------------------------------- 1 | # 生成细节 2 | 3 | autocxxpy核心分为三部分: 4 | * CXXParser:负责分析C++文件,输出defines,class,function,constants之类的信息 5 | * PreProcessor:负责分析CXXParser的结果,对一些特别的量进行识别,比如定义成常量的define,一个类是否是纯类等等 6 | * Generator:负责生成代码 7 | 8 | ## 生成过程 9 | 要使用这个生成器,首先指定要分析的头文件,使用CXXParser分析。 10 | ```python 11 | r0: CXXParseResult = CXXParser([self.md_header, self.td_header]).parse() 12 | ``` 13 | 然后将结果传入预处理器 14 | ```python 15 | r1: PreProcessorResult = PreProcessor(r0).process() 16 | ``` 17 | 最后将第一步和第二部的结果一起传入Generator。 18 | 注意:除了classes以外,所有参数都可以置空或者仅从第一步提取。 19 | 最终返回的是一组字典```Dict[str, str]```,记录着生成的文件名和对应的内容。 20 | 用户只需要江这些结果保存下来即可。 21 | ```python 22 | options = GeneratorOptions( 23 | typedefs=r0.typedefs, 24 | constants=r0.variables & r1.const_macros, 25 | functions=r0.functions, 26 | classes=r1.classes, 27 | dict_classes=r1.dict_classes, 28 | enums=r0.enums, 29 | ) 30 | 31 | ``` 32 | 33 | ## Q & A 34 | ### 为什么会有PreProcessor 35 | 理想情况下,一个cxx到pyd的生成器应该是只需要提供头文件,即可生成正确的pyd文件。 36 | 但是cxx语法丰富,包容各种写法。虽然主流写法大体是一致的,但是我们也不能忽视大量非主流写法的存在。要包容所有的写法是一件比较困难的事情。 37 | 这些写法虽然不会导致最终无法生成pyd,但是会导致pyd难以使用,或者使得最终生成的文件效率低下。 38 | 例如有些人可能会用define定义常量或者内联函数。忽略掉这些东西显然会降低我们的python端的代码体验。 39 | 所以我们使用PreProcessor将一些分析奇葩写法得到的结果转换成主流写法的结果。 40 | 如果你觉得这些转化是多余的,你可以不使用PreProcessor的结果。 41 | 42 | -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/property_helper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace autocxxpy 12 | { 13 | template 14 | auto wrap_getter(value_type class_type::*member) 15 | { 16 | return [member](const class_type &instance)->const value_type & { 17 | return instance.*member; 18 | }; 19 | } 20 | 21 | 22 | template 23 | auto wrap_setter(value_type class_type::*member) 24 | { 25 | return [member](class_type &instance, const value_type &value) { 26 | instance.*member = value; 27 | }; 28 | } 29 | 30 | template 31 | using string_literal = char[size]; 32 | 33 | template 34 | auto wrap_getter(string_literal class_type::*member) 35 | { 36 | return [member](const class_type &instance) { 37 | //return std::string_view(instance.*member); 38 | return instance.*member; 39 | }; 40 | } 41 | 42 | 43 | template 44 | auto wrap_setter(string_literal class_type::*member) 45 | { 46 | return [member](class_type &instance, const std::string_view &value) { 47 | #ifdef _MSC_VER 48 | strcpy_s(instance.*member, value.data()); 49 | #else 50 | strcpy(instance.*member, value.data()); 51 | #endif 52 | }; 53 | //return [member](class_type &instance, const py::str &) { 54 | // strcpy_s(instance.*member, str->raw_str()); 55 | //}; 56 | } 57 | 58 | #define AUTOCXXPY_DEF_PROPERTY(cls, name) \ 59 | def_property(#name, autocxxpy::wrap_getter(&cls::name), autocxxpy::wrap_setter(&cls::name)) 60 | } 61 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/property_helper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | 11 | namespace autocxxpy 12 | { 13 | template 14 | auto wrap_getter(value_type class_type::*member) 15 | { 16 | return [member](const class_type &instance)->const value_type & { 17 | return instance.*member; 18 | }; 19 | } 20 | 21 | 22 | template 23 | auto wrap_setter(value_type class_type::*member) 24 | { 25 | return [member](class_type &instance, const value_type &value) { 26 | instance.*member = value; 27 | }; 28 | } 29 | 30 | template 31 | using string_literal = char[size]; 32 | 33 | template 34 | auto wrap_getter(string_literal class_type::*member) 35 | { 36 | return [member](const class_type &instance) { 37 | //return std::string_view(instance.*member); 38 | return instance.*member; 39 | }; 40 | } 41 | 42 | 43 | template 44 | auto wrap_setter(string_literal class_type::*member) 45 | { 46 | return [member](class_type &instance, const std::string_view &value) { 47 | #ifdef _MSC_VER 48 | strcpy_s(instance.*member, value.data()); 49 | #else 50 | strcpy(instance.*member, value.data()); 51 | #endif 52 | }; 53 | //return [member](class_type &instance, const py::str &) { 54 | // strcpy_s(instance.*member, str->raw_str()); 55 | //}; 56 | } 57 | 58 | #define AUTOCXXPY_DEF_PROPERTY(cls, name) \ 59 | def_property(#name, autocxxpy::wrap_getter(&cls::name), autocxxpy::wrap_setter(&cls::name)) 60 | } 61 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/detail/typeid.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/typeid.h: Compiler-independent access to type identifiers 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #if defined(__GNUG__) 16 | #include 17 | #endif 18 | 19 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 20 | NAMESPACE_BEGIN(detail) 21 | /// Erase all occurrences of a substring 22 | inline void erase_all(std::string &string, const std::string &search) { 23 | for (size_t pos = 0;;) { 24 | pos = string.find(search, pos); 25 | if (pos == std::string::npos) break; 26 | string.erase(pos, search.length()); 27 | } 28 | } 29 | 30 | PYBIND11_NOINLINE inline void clean_type_id(std::string &name) { 31 | #if defined(__GNUG__) 32 | int status = 0; 33 | std::unique_ptr res { 34 | abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free }; 35 | if (status == 0) 36 | name = res.get(); 37 | #else 38 | detail::erase_all(name, "class "); 39 | detail::erase_all(name, "struct "); 40 | detail::erase_all(name, "enum "); 41 | #endif 42 | detail::erase_all(name, "pybind11::"); 43 | } 44 | NAMESPACE_END(detail) 45 | 46 | /// Return a string representation of a C++ type 47 | template static std::string type_id() { 48 | std::string name(typeid(T).name()); 49 | detail::clean_type_id(name); 50 | return name; 51 | } 52 | 53 | NAMESPACE_END(PYBIND11_NAMESPACE) 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/internal/custom/README.md: -------------------------------------------------------------------------------- 1 | # Customization Points 2 | 3 | The custom directory is an injection point for custom user configurations. 4 | 5 | ## Header `gtest.h` 6 | 7 | ### The following macros can be defined: 8 | 9 | * `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of 10 | `OsStackTraceGetterInterface`. 11 | * `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See 12 | `testing::TempDir` for semantics and signature. 13 | 14 | ## Header `gtest-port.h` 15 | 16 | The following macros can be defined: 17 | 18 | ### Flag related macros: 19 | 20 | * `GTEST_FLAG(flag_name)` 21 | * `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its 22 | own flagfile flag parsing. 23 | * `GTEST_DECLARE_bool_(name)` 24 | * `GTEST_DECLARE_int32_(name)` 25 | * `GTEST_DECLARE_string_(name)` 26 | * `GTEST_DEFINE_bool_(name, default_val, doc)` 27 | * `GTEST_DEFINE_int32_(name, default_val, doc)` 28 | * `GTEST_DEFINE_string_(name, default_val, doc)` 29 | 30 | ### Logging: 31 | 32 | * `GTEST_LOG_(severity)` 33 | * `GTEST_CHECK_(condition)` 34 | * Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too. 35 | 36 | ### Threading: 37 | 38 | * `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided. 39 | * `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal` 40 | are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)` 41 | and `GTEST_DEFINE_STATIC_MUTEX_(mutex)` 42 | * `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)` 43 | * `GTEST_LOCK_EXCLUDED_(locks)` 44 | 45 | ### Underlying library support features 46 | 47 | * `GTEST_HAS_CXXABI_H_` 48 | 49 | ### Exporting API symbols: 50 | 51 | * `GTEST_API_` - Specifier for exported symbols. 52 | 53 | ## Header `gtest-printers.h` 54 | 55 | * See documentation at `gtest/gtest-printers.h` for details on how to define a 56 | custom printer. 57 | -------------------------------------------------------------------------------- /cpp_api_binding/cmake/flags.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 17) 2 | 3 | 4 | set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") 5 | if ("${CMAKE_BUILD_TYPE}" STREQUAL "") 6 | set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) 7 | endif() 8 | 9 | if (CMAKE_BUILD_TYPE STREQUAL "Release") 10 | add_definitions(/DNDEBUG) 11 | endif() 12 | 13 | if (CMAKE_CXX_COMPILER_ID MATCHES GNU) 14 | 15 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing") 16 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast") 17 | 18 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-class-memaccess") 19 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s") 20 | 21 | #MinGW cross-compile 22 | if (WIN32) 23 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") 24 | else() 25 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") 26 | endif() 27 | 28 | if (${CMAKE_VERSION} VERSION_LESS "3.1.0") 29 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") 30 | endif() 31 | 32 | # add debug information 33 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ggdb") 34 | 35 | elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) 36 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /EHsc /MP /bigobj") 37 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /EHsc /Ox /Ob2 /Ot /Oi /MT /GL /MP") 38 | set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") 39 | 40 | add_definitions(/D_CRT_SECURE_NO_WARNINGS) 41 | add_definitions(/D_CRT_NONSTDC_NO_WARNINGS) 42 | add_definitions(/DNOMINMAX) 43 | 44 | elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) 45 | 46 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") 47 | set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast") 48 | 49 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-missing-braces") 50 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast") 51 | endif() 52 | -------------------------------------------------------------------------------- /candle_chart/base/data_source.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from datetime import datetime 3 | from typing import Generic, Iterable, List, TYPE_CHECKING, TypeVar 4 | 5 | from PyQt5.QtCore import QObject, pyqtSignal 6 | 7 | if TYPE_CHECKING: 8 | from .base import Alignment 9 | 10 | T = TypeVar("T") 11 | 12 | 13 | class DataSourceQObject(QObject): 14 | data_removed = pyqtSignal(int, int) # (start: int, end: int) 15 | 16 | 17 | class DataSource(Generic[T]): 18 | """ 19 | DataSource for a Drawer. 20 | A DataSource is just like a list, but not all the operation is supported in list. 21 | Supported operations are: 22 | append(), clear(), __len__(), __getitem__(), 23 | """ 24 | 25 | def __init__(self, parent=None): 26 | super().__init__() 27 | self.data_list: List[T] = [] 28 | self.qobject = DataSourceQObject(parent) 29 | 30 | def extend(self, seq: Iterable[T]) -> None: 31 | self.data_list.extend(seq) 32 | 33 | def append(self, object: T) -> None: 34 | self.data_list.append(object) 35 | 36 | def clear(self) -> None: 37 | self.qobject.data_removed.emit(0, len(self.data_list)) 38 | self.data_list.clear() 39 | 40 | def append_by_sequence(self, xs: List[float], align: "Alignment", item: List[T]): 41 | raise NotImplementedError() 42 | 43 | def __getitem__(self, item): 44 | return self.data_list[item] 45 | 46 | def __len__(self): 47 | return len(self.data_list) 48 | 49 | def __str__(self): 50 | return str(self.data_list) 51 | 52 | def __repr__(self): 53 | return repr(self.data_list) 54 | 55 | 56 | @dataclass 57 | class CandleData: 58 | """ 59 | Represent a single record in DataSource for CandleChartDrawer 60 | """ 61 | 62 | open_price: float 63 | low_price: float 64 | high_price: float 65 | close_price: float 66 | datetime: datetime 67 | 68 | 69 | CandleDataSource = DataSource["CandleData"] 70 | HistogramDataSource = DataSource[float] 71 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 35 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 36 | 37 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 38 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/internal/custom/gtest-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 35 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 36 | 37 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 38 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/adaptor/ctpadaptor.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import os 3 | 4 | from autocxxpy.cxxparser import CXXFileParser, CXXParseResult 5 | from autocxxpy.generator import GeneratorOptions 6 | from autocxxpy.preprocessor import PreProcessorResult, PreProcessor 7 | 8 | logger = logging.getLogger(__file__) 9 | 10 | 11 | def clear_dir(path: str): 12 | for file in os.listdir(path): 13 | os.unlink(os.path.join(path, file)) 14 | 15 | 16 | class CtpAdaptor: 17 | def __init__(self, td_header, md_header): 18 | self.td_header = td_header 19 | self.md_header = md_header 20 | 21 | def parse(self) -> GeneratorOptions: 22 | r0: CXXParseResult = CXXFileParser( 23 | [self.md_header, self.td_header] 24 | ).parse() 25 | r1: PreProcessorResult = PreProcessor(r0).process() 26 | 27 | constants = r0.variables 28 | constants.update(r1.const_macros) 29 | constants = { 30 | k: v for k, v in constants.items() if not k.startswith("_") 31 | } 32 | 33 | functions = r0.functions 34 | classes = r1.classes 35 | 36 | # make all api "final" to improve performance 37 | for c in classes.values(): 38 | type = c.name[-3:] 39 | if type == "Api": 40 | for ms in c.functions.values(): 41 | for m in ms: 42 | if m.is_virtual: 43 | m.is_pure_virtual = False 44 | m.is_final = True 45 | elif type == "Spi": 46 | for ms in c.functions.values(): 47 | for m in ms: 48 | m.is_virtual = True 49 | # m.is_pure_virtual = True 50 | m.is_final = False 51 | 52 | options = GeneratorOptions( 53 | typedefs=r0.typedefs, 54 | constants=constants, 55 | functions=functions, 56 | classes=classes, 57 | dict_classes=r1.dict_classes, 58 | enums=r0.enums, 59 | ) 60 | options.includes = ["custom_wrappers/spi.hpp"] 61 | return options 62 | -------------------------------------------------------------------------------- /cpp_api_binding/tests/test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | print(sys.path) 5 | print(os.environ) 6 | 7 | import vnctp # noqa 8 | from vnctp import ( 9 | CThostFtdcTraderApi, 10 | CThostFtdcTraderSpi, 11 | CThostFtdcRspAuthenticateField, 12 | CThostFtdcRspInfoField, 13 | CThostFtdcRspUserLoginField, 14 | CThostFtdcUserLogoutField, 15 | ) # noqa 16 | 17 | print(vnctp) 18 | print(dir(vnctp)) 19 | 20 | for i in dir(vnctp): 21 | print(f"{i} : {vnctp.__dict__[i]}") 22 | 23 | print("creating ctp api") 24 | api = CThostFtdcTraderApi.CreateFtdcTraderApi("flow2") 25 | 26 | print("creating ctp spi") 27 | 28 | 29 | # pylint: disable=invalid-name 30 | class Spi(CThostFtdcTraderSpi): 31 | def OnFrontConnected(self) -> None: 32 | print("OnFrontConnected!") 33 | 34 | def OnFrontDisconnected(self, nReason: int) -> None: 35 | print("OnFrontDisconnected!") 36 | 37 | def OnRspAuthenticate( 38 | self, 39 | pRspAuthenticateField: CThostFtdcRspAuthenticateField, 40 | pRspInfo: CThostFtdcRspInfoField, 41 | nRequestID: int, 42 | bIsLast: bool, 43 | ) -> None: 44 | print("OnRspAuthenticate!") 45 | 46 | def OnRspUserLogin( 47 | self, 48 | pRspUserLogin: CThostFtdcRspUserLoginField, 49 | pRspInfo: CThostFtdcRspInfoField, 50 | nRequestID: int, 51 | bIsLast: bool, 52 | ) -> None: 53 | print("OnRspUserLogin!") 54 | 55 | def OnRspUserLogout( 56 | self, 57 | pUserLogout: CThostFtdcUserLogoutField, 58 | pRspInfo: CThostFtdcRspInfoField, 59 | nRequestID: int, 60 | bIsLast: bool, 61 | ) -> None: 62 | print("OnRspUserLogout!") 63 | 64 | def OnRspError( 65 | self, pRspInfo: CThostFtdcRspInfoField, nRequestID: int, bIsLast: bool 66 | ) -> None: 67 | print("OnRspError!") 68 | 69 | 70 | # pylint: enable=invalid-name 71 | 72 | 73 | spi = Spi() 74 | 75 | print("registering spi") 76 | api.RegisterSpi(spi) 77 | print("registering front") 78 | api.RegisterFront("tcp://180.168.146.187:10030") 79 | print("Init() ...") 80 | api.Init() 81 | 82 | print("Join() ...") 83 | while True: 84 | pass 85 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // 35 | // Injection point for custom user configurations. See README for details 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/complex.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/complex.h: Complex number support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | /// glibc defines I as a macro which breaks things, e.g., boost template names 16 | #ifdef I 17 | # undef I 18 | #endif 19 | 20 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 21 | 22 | template struct format_descriptor, detail::enable_if_t::value>> { 23 | static constexpr const char c = format_descriptor::c; 24 | static constexpr const char value[3] = { 'Z', c, '\0' }; 25 | static std::string format() { return std::string(value); } 26 | }; 27 | 28 | #ifndef PYBIND11_CPP17 29 | 30 | template constexpr const char format_descriptor< 31 | std::complex, detail::enable_if_t::value>>::value[3]; 32 | 33 | #endif 34 | 35 | NAMESPACE_BEGIN(detail) 36 | 37 | template struct is_fmt_numeric, detail::enable_if_t::value>> { 38 | static constexpr bool value = true; 39 | static constexpr int index = is_fmt_numeric::index + 3; 40 | }; 41 | 42 | template class type_caster> { 43 | public: 44 | bool load(handle src, bool convert) { 45 | if (!src) 46 | return false; 47 | if (!convert && !PyComplex_Check(src.ptr())) 48 | return false; 49 | Py_complex result = PyComplex_AsCComplex(src.ptr()); 50 | if (result.real == -1.0 && PyErr_Occurred()) { 51 | PyErr_Clear(); 52 | return false; 53 | } 54 | value = std::complex((T) result.real, (T) result.imag); 55 | return true; 56 | } 57 | 58 | static handle cast(const std::complex &src, return_value_policy /* policy */, handle /* parent */) { 59 | return PyComplex_FromDoubles((double) src.real(), (double) src.imag()); 60 | } 61 | 62 | PYBIND11_TYPE_CASTER(std::complex, _("complex")); 63 | }; 64 | NAMESPACE_END(detail) 65 | NAMESPACE_END(PYBIND11_NAMESPACE) 66 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/tests.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.168 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "3rd_party\googletest\gtest.vcxproj", "{064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests\tests\tests.vcxproj", "{BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Debug|x64.ActiveCfg = Debug|x64 19 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Debug|x64.Build.0 = Debug|x64 20 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Debug|x86.ActiveCfg = Debug|Win32 21 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Debug|x86.Build.0 = Debug|Win32 22 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Release|x64.ActiveCfg = Release|x64 23 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Release|x64.Build.0 = Release|x64 24 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Release|x86.ActiveCfg = Release|Win32 25 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8}.Release|x86.Build.0 = Release|Win32 26 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Debug|x64.ActiveCfg = Debug|x64 27 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Debug|x64.Build.0 = Debug|x64 28 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Debug|x86.ActiveCfg = Debug|Win32 29 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Debug|x86.Build.0 = Debug|Win32 30 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Release|x64.ActiveCfg = Release|x64 31 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Release|x64.Build.0 = Release|x64 32 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Release|x86.ActiveCfg = Release|Win32 33 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {BF779EA3-BC4C-49BE-9218-F292B16F85F5} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/src/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | #include "gtest/gtest.h" 32 | 33 | #ifdef ARDUINO 34 | void setup() { 35 | // Since Arduino doesn't have a command line, fake out the argc/argv arguments 36 | int argc = 1; 37 | const auto arg0 = "PlatformIO"; 38 | char* argv0 = const_cast(arg0); 39 | char** argv = &argv0; 40 | 41 | testing::InitGoogleTest(&argc, argv); 42 | } 43 | 44 | void loop() { RUN_ALL_TESTS(); } 45 | 46 | #else 47 | 48 | GTEST_API_ int main(int argc, char **argv) { 49 | printf("Running main() from %s\n", __FILE__); 50 | testing::InitGoogleTest(&argc, argv); 51 | return RUN_ALL_TESTS(); 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/options.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/options.h: global settings that are configurable at runtime. 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "detail/common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | 16 | class options { 17 | public: 18 | 19 | // Default RAII constructor, which leaves settings as they currently are. 20 | options() : previous_state(global_state()) {} 21 | 22 | // Class is non-copyable. 23 | options(const options&) = delete; 24 | options& operator=(const options&) = delete; 25 | 26 | // Destructor, which restores settings that were in effect before. 27 | ~options() { 28 | global_state() = previous_state; 29 | } 30 | 31 | // Setter methods (affect the global state): 32 | 33 | options& disable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = false; return *this; } 34 | 35 | options& enable_user_defined_docstrings() & { global_state().show_user_defined_docstrings = true; return *this; } 36 | 37 | options& disable_function_signatures() & { global_state().show_function_signatures = false; return *this; } 38 | 39 | options& enable_function_signatures() & { global_state().show_function_signatures = true; return *this; } 40 | 41 | // Getter methods (return the global state): 42 | 43 | static bool show_user_defined_docstrings() { return global_state().show_user_defined_docstrings; } 44 | 45 | static bool show_function_signatures() { return global_state().show_function_signatures; } 46 | 47 | // This type is not meant to be allocated on the heap. 48 | void* operator new(size_t) = delete; 49 | 50 | private: 51 | 52 | struct state { 53 | bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. 54 | bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. 55 | }; 56 | 57 | static state &global_state() { 58 | static state instance; 59 | return instance; 60 | } 61 | 62 | state previous_state; 63 | }; 64 | 65 | NAMESPACE_END(PYBIND11_NAMESPACE) 66 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/gtest-all.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Google C++ Testing and Mocking Framework (Google Test) 32 | // 33 | // Sometimes it's desirable to build Google Test by compiling a single file. 34 | // This file serves this purpose. 35 | 36 | // This line ensures that gtest.h can be compiled on its own, even 37 | // when it's fused. 38 | #include "gtest/gtest.h" 39 | 40 | // The following lines pull in the real gtest *.cc files. 41 | #include "src/gtest.cc" 42 | #include "src/gtest-death-test.cc" 43 | #include "src/gtest-filepath.cc" 44 | #include "src/gtest-matchers.cc" 45 | #include "src/gtest-port.cc" 46 | #include "src/gtest-printers.cc" 47 | #include "src/gtest-test-part.cc" 48 | #include "src/gtest-typed-test.cc" 49 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // Google C++ Testing and Mocking Framework definitions useful in production code. 32 | // GOOGLETEST_CM0003 DO NOT DELETE 33 | 34 | #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 36 | 37 | // When you need to test the private or protected members of a class, 38 | // use the FRIEND_TEST macro to declare your tests as friends of the 39 | // class. For example: 40 | // 41 | // class MyClass { 42 | // private: 43 | // void PrivateMethod(); 44 | // FRIEND_TEST(MyClassTest, PrivateMethodWorks); 45 | // }; 46 | // 47 | // class MyClassTest : public testing::Test { 48 | // // ... 49 | // }; 50 | // 51 | // TEST_F(MyClassTest, PrivateMethodWorks) { 52 | // // Can call MyClass::PrivateMethod() here. 53 | // } 54 | // 55 | // Note: The test class must be in the same namespace as the class being tested. 56 | // For example, putting MyClassTest in an anonymous namespace will not work. 57 | 58 | #define FRIEND_TEST(test_case_name, test_name)\ 59 | friend class test_case_name##_##test_name##_Test 60 | 61 | #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ 62 | -------------------------------------------------------------------------------- /cpp_api_binding/source/ctp/dispatcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace autocxxpy 11 | { 12 | class dispatcher 13 | { 14 | public: 15 | using task_type = std::function; 16 | using task_list_type = std::vector; 17 | public: 18 | inline void add(const task_type &f) 19 | { 20 | { 21 | std::lock_guard l(_m); 22 | _ts.push_back(f); 23 | } 24 | this->_notify_one(); 25 | } 26 | void start() 27 | { 28 | _run = true; 29 | _thread = std::thread(&dispatcher::_loop, this); 30 | } 31 | void stop() 32 | { 33 | _run = false; 34 | } 35 | void join() 36 | { 37 | assert(!this->_run); 38 | this->_notify_one(); 39 | _thread.join(); 40 | } 41 | public: 42 | inline static dispatcher &instance() 43 | { 44 | static dispatcher *_instance = nullptr; 45 | if (_instance != nullptr) 46 | return *_instance; 47 | 48 | static std::mutex m; 49 | std::lock_guard l(m); 50 | if (_instance == nullptr) 51 | _instance = new dispatcher; 52 | return *_instance; 53 | } 54 | protected: 55 | void _loop() 56 | { 57 | while (_run) 58 | { 59 | task_list_type ts; 60 | { 61 | auto l = _wait_and_lock(); 62 | ts = this->_ts; 63 | _ts.clear(); 64 | l.unlock(); 65 | } 66 | _process_all(ts); 67 | } 68 | } 69 | 70 | inline void _process_all(const task_list_type &ts) 71 | { 72 | for (const auto &task : ts) 73 | { 74 | task(); 75 | } 76 | } 77 | 78 | inline void _notify_one() 79 | { 80 | return _cv.notify_one(); 81 | } 82 | 83 | inline std::unique_lock _wait_and_lock() 84 | { 85 | std::unique_lock l(_m); 86 | _cv.wait(l, [this]() 87 | { 88 | return !_run || _ts.size(); 89 | }); 90 | return std::move(l); 91 | } 92 | 93 | protected: 94 | volatile bool _run = false; 95 | std::thread _thread; 96 | std::mutex _m; 97 | std::condition_variable _cv; 98 | task_list_type _ts; 99 | }; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/templates/dispatcher.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace autocxxpy 11 | { 12 | class dispatcher 13 | { 14 | public: 15 | using task_type = std::function; 16 | using task_list_type = std::vector; 17 | public: 18 | inline void add(const task_type &f) 19 | { 20 | { 21 | std::lock_guard l(_m); 22 | _ts.push_back(f); 23 | } 24 | this->_notify_one(); 25 | } 26 | void start() 27 | { 28 | _run = true; 29 | _thread = std::thread(&dispatcher::_loop, this); 30 | } 31 | void stop() 32 | { 33 | _run = false; 34 | } 35 | void join() 36 | { 37 | assert(!this->_run); 38 | this->_notify_one(); 39 | _thread.join(); 40 | } 41 | public: 42 | inline static dispatcher &instance() 43 | { 44 | static dispatcher *_instance = nullptr; 45 | if (_instance != nullptr) 46 | return *_instance; 47 | 48 | static std::mutex m; 49 | std::lock_guard l(m); 50 | if (_instance == nullptr) 51 | _instance = new dispatcher; 52 | return *_instance; 53 | } 54 | protected: 55 | void _loop() 56 | { 57 | while (_run) 58 | { 59 | task_list_type ts; 60 | { 61 | auto l = _wait_and_lock(); 62 | ts = this->_ts; 63 | _ts.clear(); 64 | l.unlock(); 65 | } 66 | _process_all(ts); 67 | } 68 | } 69 | 70 | inline void _process_all(const task_list_type &ts) 71 | { 72 | for (const auto &task : ts) 73 | { 74 | task(); 75 | } 76 | } 77 | 78 | inline void _notify_one() 79 | { 80 | return _cv.notify_one(); 81 | } 82 | 83 | inline std::unique_lock _wait_and_lock() 84 | { 85 | std::unique_lock l(_m); 86 | _cv.wait(l, [this]() 87 | { 88 | return !_run || _ts.size(); 89 | }); 90 | return std::move(l); 91 | } 92 | 93 | protected: 94 | volatile bool _run = false; 95 | std::thread _thread; 96 | std::mutex _m; 97 | std::condition_variable _cv; 98 | task_list_type _ts; 99 | }; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /candle_chart/base/base.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | from enum import Enum 3 | from typing import Optional, TYPE_CHECKING, TypeVar, Union 4 | 5 | from PyQt5.QtCore import QPointF, QRectF 6 | from PyQt5.QtGui import QColor, QTransform 7 | 8 | if TYPE_CHECKING: 9 | pass 10 | 11 | T = TypeVar("T") 12 | 13 | ColorType = Union[ 14 | str, # "red", "#RGB", "#RRGGBB", "#AARRGGBB", "#RRRGGGBBB", "#RRRRGGGGBBBB" 15 | int, # Qt.GlobalColor 16 | QColor, # QtCore.QColor 17 | None, # Don't draw 18 | ] 19 | 20 | 21 | class Orientation(Enum): 22 | HORIZONTAL = 1 23 | VERTICAL = 2 24 | 25 | 26 | class Alignment(Enum): 27 | BEFORE = 0 28 | MID = 1 29 | AFTER = 2 30 | 31 | 32 | @dataclass() 33 | class DrawingCache: 34 | # intermediate variables to speed up calculation 35 | drawer_transform: Optional["QTransform"] = None # 坐标转化矩阵(UI->drawer) 36 | ui_transform: Optional[QTransform] = None # 坐标转化矩阵(drawer->UI) 37 | drawer_area: Optional["QRectF"] = None # drawer坐标的世界大小 38 | drawer_area_width: Optional["float"] = None 39 | # self.drawer_area_height: Optional['float'] = None 40 | plot_area: Optional[QRectF] = None # UI坐标中属于绘制区域的部分 41 | # self.plot_area_width: Optional['float'] = None 42 | # self.plot_area_height: Optional['float'] = None 43 | p2d_w: Optional[float] = None # drawer_area.width / plot_area.width 44 | p2d_h: Optional[float] = None # drawer_area.height / plot_area.height 45 | 46 | def drawer_to_ui(self, value: T) -> T: 47 | """ 48 | 将drawer坐标系中的值(点或者矩形)转化为UI坐标系 49 | """ 50 | return self.drawer_transform.map(value) 51 | 52 | def drawer_x_to_ui(self, value: float) -> float: 53 | """ 54 | 将drawer坐标系中的x值转化为UI坐标系中的x值 55 | """ 56 | return self.drawer_transform.map(QPointF(value, value)).x() 57 | 58 | def drawer_y_to_ui(self, value: float) -> float: 59 | """ 60 | 将drawer坐标系中的y值转化为UI坐标系中的y值 61 | """ 62 | return self.drawer_transform.map(QPointF(value, value)).y() 63 | 64 | def ui_width_to_drawer(self, value: float) -> float: 65 | return value * self.p2d_w 66 | 67 | def ui_height_to_drawer(self, value: float) -> float: 68 | return value * self.p2d_h 69 | 70 | def ui_to_drawer(self, value: T) -> T: 71 | return self.ui_transform.map(value) 72 | 73 | def ui_x_to_drawer(self, value: float) -> float: 74 | return self.ui_transform.map(QPointF(value, value)).x() 75 | 76 | def ui_y_to_drawer(self, value: float) -> float: 77 | return self.ui_transform.map(QPointF(value, value)).y() 78 | 79 | 80 | @dataclass() 81 | class DrawConfig: 82 | begin: int = 0 # 第一个绘制的元素 83 | end: int = 0 # 最后一个绘制的元素+1:也就是说绘制元素的范围为[begin, end) 84 | y_low: float = 0 # 图表顶端所代表的y值 85 | y_high: float = 1 # 图表底端所代表的y值 86 | 87 | drawing_cache: Optional["DrawingCache"] = None 88 | -------------------------------------------------------------------------------- /async_io/asyncio/async_executor.py: -------------------------------------------------------------------------------- 1 | """ 2 | support for asyncio 3 | If you use this module, call async_executor.start() at startup. 4 | and call async_executor.stop() at cleanup. 5 | call async_executor.join() if you want to wait until it exit. 6 | """ 7 | import asyncio 8 | import threading 9 | from typing import Coroutine, Iterable, Union 10 | 11 | 12 | class AsyncExecutor: 13 | 14 | def __init__(self): 15 | self.loop = asyncio.new_event_loop() 16 | self._thread = threading.Thread(target=self._exec) 17 | 18 | def start(self): 19 | self._thread.start() 20 | 21 | def stop(self): 22 | self.loop.stop() 23 | 24 | def join(self): 25 | self._thread.join() 26 | 27 | def _exec(self): 28 | self.loop.call_soon(lambda: None) 29 | self.loop.run_forever() 30 | 31 | 32 | class SyncWrapper: 33 | wrapper_loop = asyncio.new_event_loop() 34 | 35 | def __init__(self, co: Coroutine): 36 | self.co = co 37 | self.result = None 38 | 39 | def __call__(self, *args, **kwargs): 40 | if self.result is None: 41 | try: 42 | if loop is asyncio.get_running_loop(): 43 | # fucking shit 44 | self.schedule_new_coroutine() 45 | else: 46 | self.schedule_coroutine() 47 | except RuntimeError: 48 | self.schedule_coroutine() 49 | return self.result 50 | 51 | def schedule_coroutine(self): 52 | task = asyncio.run_coroutine_threadsafe(self.co, loop=loop) 53 | self.result = task.result() 54 | 55 | def schedule_new_coroutine(self): 56 | thread = threading.Thread(target=self.run) 57 | thread.start() 58 | thread.join() 59 | 60 | def run(self): 61 | self.result = self.wrapper_loop.run_until_complete(self.co) 62 | 63 | 64 | def wrap_as_sync(co: Coroutine): 65 | """ 66 | run a coroutine in ANY context, and return its result. 67 | """ 68 | return SyncWrapper(co) 69 | 70 | 71 | def create_async_task(co: Coroutine): 72 | """ 73 | start a coroutine asynchronously in ANY context, ignoring its result. 74 | """ 75 | return loop.create_task(co) 76 | 77 | 78 | def wait_for_async_task(task: asyncio.Task): 79 | return wrap_as_sync(asyncio.wait([task], loop=loop))() 80 | 81 | 82 | def start_asyncio(): 83 | global ref_count 84 | with ref_count_lock: 85 | if ref_count == 0: 86 | async_executor.start() 87 | ref_count = ref_count + 1 88 | 89 | 90 | def stop_asyncio(): 91 | global ref_count 92 | with ref_count_lock: 93 | ref_count = ref_count - 1 94 | if ref_count == 0: 95 | async_executor.stop() 96 | 97 | 98 | def join_asyncio(): 99 | async_executor.join() 100 | 101 | ref_count = 0 102 | ref_count_lock = threading.Lock() 103 | async_executor: "AsyncExecutor" = AsyncExecutor() 104 | loop = async_executor.loop 105 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/functional.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/functional.h: std::function<> support 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include 14 | 15 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 16 | NAMESPACE_BEGIN(detail) 17 | 18 | template 19 | struct type_caster> { 20 | using type = std::function; 21 | using retval_type = conditional_t::value, void_type, Return>; 22 | using function_type = Return (*) (Args...); 23 | 24 | public: 25 | bool load(handle src, bool convert) { 26 | if (src.is_none()) { 27 | // Defer accepting None to other overloads (if we aren't in convert mode): 28 | if (!convert) return false; 29 | return true; 30 | } 31 | 32 | if (!isinstance(src)) 33 | return false; 34 | 35 | auto func = reinterpret_borrow(src); 36 | 37 | /* 38 | When passing a C++ function as an argument to another C++ 39 | function via Python, every function call would normally involve 40 | a full C++ -> Python -> C++ roundtrip, which can be prohibitive. 41 | Here, we try to at least detect the case where the function is 42 | stateless (i.e. function pointer or lambda function without 43 | captured variables), in which case the roundtrip can be avoided. 44 | */ 45 | if (auto cfunc = func.cpp_function()) { 46 | auto c = reinterpret_borrow(PyCFunction_GET_SELF(cfunc.ptr())); 47 | auto rec = (function_record *) c; 48 | 49 | if (rec && rec->is_stateless && 50 | same_type(typeid(function_type), *reinterpret_cast(rec->data[1]))) { 51 | struct capture { function_type f; }; 52 | value = ((capture *) &rec->data)->f; 53 | return true; 54 | } 55 | } 56 | 57 | value = [func](Args... args) -> Return { 58 | gil_scoped_acquire acq; 59 | object retval(func(std::forward(args)...)); 60 | /* Visual studio 2015 parser issue: need parentheses around this expression */ 61 | return (retval.template cast()); 62 | }; 63 | return true; 64 | } 65 | 66 | template 67 | static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) { 68 | if (!f_) 69 | return none().inc_ref(); 70 | 71 | auto result = f_.template target(); 72 | if (result) 73 | return cpp_function(*result, policy).release(); 74 | else 75 | return cpp_function(std::forward(f_), policy).release(); 76 | } 77 | 78 | PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster::name...) + _("], ") 79 | + make_caster::name + _("]")); 80 | }; 81 | 82 | NAMESPACE_END(detail) 83 | NAMESPACE_END(PYBIND11_NAMESPACE) 84 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/autocxxpy/textholder.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | from typing import Optional, Union 3 | 4 | 5 | class Indent: 6 | class IdentStart: 7 | def __init__(self, text): 8 | self.text = text 9 | 10 | class IdentEnd: 11 | def __init__(self, text): 12 | self.text = text 13 | 14 | class IdentEndLater: 15 | def __init__(self, text): 16 | self.text = text 17 | 18 | def __init__(self, text: Optional[Union[str, "TextHolder"]] = None): 19 | self.text = text 20 | 21 | def __add__(self, other: str): 22 | assert self.text is None 23 | return Indent(other) 24 | 25 | def __radd__(self, other: str): 26 | assert self.text is None 27 | return Indent.IdentStart(other) 28 | 29 | def __rsub__(self, other: str): 30 | assert self.text is None 31 | return Indent.IdentEnd(other) 32 | 33 | 34 | class IndentLater: 35 | def __rsub__(self, other: str): 36 | return Indent.IdentEndLater(other) 37 | 38 | 39 | class TextHolder: 40 | def __init__(self, text: Optional[str] = None): 41 | super().__init__() 42 | if text is None: 43 | text = "" 44 | self.text = text 45 | self.ident_text = " " 46 | self._ident = 0 47 | 48 | def __add__(self, other: Union[str, int]): 49 | if isinstance(other, Indent.IdentStart): 50 | self.append(other.text) 51 | self.ident(1) 52 | elif isinstance(other, Indent.IdentEnd): 53 | self.ident(-1) 54 | self.append(other.text) 55 | elif isinstance(other, Indent.IdentEndLater): 56 | self.append(other.text) 57 | self.ident(-1) 58 | elif isinstance(other, Indent): 59 | self.append( 60 | TextHolder(str(other.text)).ident_all( 61 | n=self._ident + 1, ident_text=self.ident_text 62 | ), 63 | add_ident=False, 64 | ) 65 | elif isinstance(other, str): 66 | self.append(other) 67 | elif isinstance(other, TextHolder): 68 | self.append( 69 | TextHolder(str(other.text)).ident_all( 70 | n=self._ident, ident_text=self.ident_text 71 | ), 72 | add_ident=False, 73 | ) 74 | elif isinstance(other, int): 75 | self.ident(other) 76 | else: 77 | raise TypeError(f"can only add str or int, but {type(other)} got") 78 | return self 79 | 80 | def __sub__(self, other): 81 | if isinstance(other, int): 82 | self.ident(-other) 83 | else: 84 | raise TypeError(f"can only add str or int, but {type(other)} got") 85 | return self 86 | 87 | def __bool__(self): 88 | return bool(self.text) 89 | 90 | def __str__(self): 91 | return self.text 92 | 93 | def append( 94 | self, 95 | text: Union[str, "TextHolder"], 96 | ensure_new_line=True, 97 | ignore_empty=True, 98 | add_ident=True, 99 | ): 100 | strtext = str(text) 101 | if ignore_empty and not strtext: 102 | return self 103 | if not strtext.endswith("\n") and ensure_new_line: 104 | strtext += "\n" 105 | if add_ident: 106 | self.text += self._ident * self.ident_text + strtext 107 | else: 108 | self.text += strtext 109 | return self 110 | 111 | def ident_all(self, n: int = 1, ident_text: str = None): 112 | if ident_text is None: 113 | ident_text = self.ident_text 114 | text = self.text 115 | if text.endswith("\n"): 116 | text = text[:-1] 117 | return "\n".join([ident_text * n + i for i in text.split("\n")]) 118 | 119 | def ident(self, n: int = 1): 120 | self._ident += n 121 | return self 122 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/detail/descr.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | NAMESPACE_BEGIN(detail) 16 | 17 | #if !defined(_MSC_VER) 18 | # define PYBIND11_DESCR_CONSTEXPR static constexpr 19 | #else 20 | # define PYBIND11_DESCR_CONSTEXPR const 21 | #endif 22 | 23 | /* Concatenate type signatures at compile time */ 24 | template 25 | struct descr { 26 | char text[N + 1]; 27 | 28 | constexpr descr() : text{'\0'} { } 29 | constexpr descr(char const (&s)[N+1]) : descr(s, make_index_sequence()) { } 30 | 31 | template 32 | constexpr descr(char const (&s)[N+1], index_sequence) : text{s[Is]..., '\0'} { } 33 | 34 | template 35 | constexpr descr(char c, Chars... cs) : text{c, static_cast(cs)..., '\0'} { } 36 | 37 | static constexpr std::array types() { 38 | return {{&typeid(Ts)..., nullptr}}; 39 | } 40 | }; 41 | 42 | template 43 | constexpr descr plus_impl(const descr &a, const descr &b, 44 | index_sequence, index_sequence) { 45 | return {a.text[Is1]..., b.text[Is2]...}; 46 | } 47 | 48 | template 49 | constexpr descr operator+(const descr &a, const descr &b) { 50 | return plus_impl(a, b, make_index_sequence(), make_index_sequence()); 51 | } 52 | 53 | template 54 | constexpr descr _(char const(&text)[N]) { return descr(text); } 55 | constexpr descr<0> _(char const(&)[1]) { return {}; } 56 | 57 | template struct int_to_str : int_to_str { }; 58 | template struct int_to_str<0, Digits...> { 59 | static constexpr auto digits = descr(('0' + Digits)...); 60 | }; 61 | 62 | // Ternary description (like std::conditional) 63 | template 64 | constexpr enable_if_t> _(char const(&text1)[N1], char const(&)[N2]) { 65 | return _(text1); 66 | } 67 | template 68 | constexpr enable_if_t> _(char const(&)[N1], char const(&text2)[N2]) { 69 | return _(text2); 70 | } 71 | 72 | template 73 | constexpr enable_if_t _(const T1 &d, const T2 &) { return d; } 74 | template 75 | constexpr enable_if_t _(const T1 &, const T2 &d) { return d; } 76 | 77 | template auto constexpr _() -> decltype(int_to_str::digits) { 78 | return int_to_str::digits; 79 | } 80 | 81 | template constexpr descr<1, Type> _() { return {'%'}; } 82 | 83 | constexpr descr<0> concat() { return {}; } 84 | 85 | template 86 | constexpr descr concat(const descr &descr) { return descr; } 87 | 88 | template 89 | constexpr auto concat(const descr &d, const Args &...args) 90 | -> decltype(std::declval>() + concat(args...)) { 91 | return d + _(", ") + concat(args...); 92 | } 93 | 94 | template 95 | constexpr descr type_descr(const descr &descr) { 96 | return _("{") + descr + _("}"); 97 | } 98 | 99 | NAMESPACE_END(detail) 100 | NAMESPACE_END(PYBIND11_NAMESPACE) 101 | -------------------------------------------------------------------------------- /candle_chart/candle.py: -------------------------------------------------------------------------------- 1 | from typing import Sequence 2 | 3 | from vnpy.chart.base import (AdvancedChartWidget, CandleAxisX, CandleChartDrawer, CandleDataSource, 4 | ChartWidget, HistogramDrawer, ValueAxisY) 5 | from vnpy.chart.base.advanced_chart import CrossHairBarAxisX, SubChartWrapper 6 | from vnpy.chart.base.data_source import HistogramDataSource 7 | from vnpy.trader.object import BarData 8 | 9 | 10 | class CandleChart(AdvancedChartWidget): 11 | """""" 12 | 13 | def __init__(self, parent=None): 14 | """""" 15 | super().__init__(parent) 16 | self.__init_ui() 17 | 18 | def __init_ui(self): 19 | # main chart: candle chart 20 | candle_ds = CandleDataSource() 21 | candle_drawer = CandleChartDrawer(candle_ds) 22 | candle_chart = ChartWidget(self) 23 | candle_chart.add_drawer(candle_drawer) 24 | candle_chart.add_axis(CandleAxisX(candle_ds), ValueAxisY()) 25 | candle_chart.clip_plot_area = False # disabling clip makes it runs a bit faster 26 | 27 | # volume chart: His 28 | volume_ds = HistogramDataSource() 29 | volume_drawer = HistogramDrawer(volume_ds) 30 | volume_chart = ChartWidget(self) 31 | volume_chart.add_drawer(volume_drawer) 32 | volume_chart.add_axis(CandleAxisX(candle_ds), ValueAxisY()) 33 | 34 | candle_wrapper = self.add_chart(candle_chart, 4) 35 | volume_wrapper = self.add_chart(volume_chart, 1) 36 | 37 | # create cross hair 38 | candle_wrapper.create_cross_hair_y() 39 | candle_wrapper.set_cross_hair_x(CrossHairBarAxisX(candle_chart.all_axis_x[0])) 40 | volume_wrapper.create_cross_hair_y() 41 | volume_wrapper.set_cross_hair_x(CrossHairBarAxisX(volume_chart.all_axis_x[0])) 42 | 43 | # link vertical line of cross hair 44 | candle_wrapper.link_x_to(volume_wrapper) 45 | volume_wrapper.link_x_to(candle_wrapper) 46 | 47 | self.candle_ds: "CandleDataSource" = candle_ds 48 | self.volume_ds: "HistogramDataSource" = volume_ds 49 | self.candle_chart: "SubChartWrapper" = candle_wrapper 50 | self.volume_chart: "SubChartWrapper" = volume_wrapper 51 | self.setMouseTracking(True) 52 | 53 | def update_bar(self, bar: BarData): 54 | """ 55 | Update one bar data into the chart. 56 | 57 | The bar data may be a new one or an existing one. 58 | """ 59 | self.candle_ds.append(bar) 60 | self.volume_ds.append(bar.volume) 61 | begin, end = self.get_x_range() 62 | self.set_x_range(begin, end + 1) 63 | 64 | def update_bars(self, bars: Sequence[BarData]): 65 | """ 66 | Update a list of bar data into the chart. 67 | """ 68 | self.candle_ds.extend(bars) 69 | self.volume_ds.extend([i.volume for i in bars]) 70 | begin, end = self.get_x_range() 71 | self.set_x_range(begin, end + len(bars)) 72 | pass 73 | 74 | def clear(self): 75 | """ 76 | Clear all data displayed in the chart. 77 | """ 78 | self.candle_ds.clear() 79 | self.volume_ds.clear() 80 | pass 81 | 82 | def set_volume_visible(self, visible: bool): 83 | """ 84 | Set if the volume data visible on the chart. 85 | """ 86 | self.volume_chart.set_chart_visible(visible) 87 | 88 | def set_cursor_visible(self, visible: bool): 89 | """ 90 | Set if the cross cursor visible on the chart. 91 | """ 92 | self.candle_chart.set_crosshair_visible(visible) 93 | self.volume_chart.set_crosshair_visible(visible) 94 | 95 | def to_left_end(self): 96 | """ 97 | Scroll chart to the left end. 98 | """ 99 | begin, end = self.get_x_range() 100 | new_end = len(self.candle_ds) 101 | self.scroll_x(new_end - end) 102 | 103 | def to_right_end(self): 104 | """ 105 | Scroll chart to the right end. 106 | """ 107 | begin, end = self.get_x_range() 108 | self.scroll_x(0 - begin) 109 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/internal/gtest-port-arch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file defines the GTEST_OS_* macro. 33 | // It is separate from gtest-port.h so that custom/gtest-port.h can include it. 34 | 35 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 36 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 37 | 38 | // Determines the platform on which Google Test is compiled. 39 | #ifdef __CYGWIN__ 40 | # define GTEST_OS_CYGWIN 1 41 | # elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) 42 | # define GTEST_OS_WINDOWS_MINGW 1 43 | # define GTEST_OS_WINDOWS 1 44 | #elif defined _WIN32 45 | # define GTEST_OS_WINDOWS 1 46 | # ifdef _WIN32_WCE 47 | # define GTEST_OS_WINDOWS_MOBILE 1 48 | # elif defined(WINAPI_FAMILY) 49 | # include 50 | # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 51 | # define GTEST_OS_WINDOWS_DESKTOP 1 52 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) 53 | # define GTEST_OS_WINDOWS_PHONE 1 54 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 55 | # define GTEST_OS_WINDOWS_RT 1 56 | # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) 57 | # define GTEST_OS_WINDOWS_PHONE 1 58 | # define GTEST_OS_WINDOWS_TV_TITLE 1 59 | # else 60 | // WINAPI_FAMILY defined but no known partition matched. 61 | // Default to desktop. 62 | # define GTEST_OS_WINDOWS_DESKTOP 1 63 | # endif 64 | # else 65 | # define GTEST_OS_WINDOWS_DESKTOP 1 66 | # endif // _WIN32_WCE 67 | #elif defined __OS2__ 68 | # define GTEST_OS_OS2 1 69 | #elif defined __APPLE__ 70 | # define GTEST_OS_MAC 1 71 | # if TARGET_OS_IPHONE 72 | # define GTEST_OS_IOS 1 73 | # endif 74 | #elif defined __FreeBSD__ 75 | # define GTEST_OS_FREEBSD 1 76 | #elif defined __Fuchsia__ 77 | # define GTEST_OS_FUCHSIA 1 78 | #elif defined __linux__ 79 | # define GTEST_OS_LINUX 1 80 | # if defined __ANDROID__ 81 | # define GTEST_OS_LINUX_ANDROID 1 82 | # endif 83 | #elif defined __MVS__ 84 | # define GTEST_OS_ZOS 1 85 | #elif defined(__sun) && defined(__SVR4) 86 | # define GTEST_OS_SOLARIS 1 87 | #elif defined(_AIX) 88 | # define GTEST_OS_AIX 1 89 | #elif defined(__hpux) 90 | # define GTEST_OS_HPUX 1 91 | #elif defined __native_client__ 92 | # define GTEST_OS_NACL 1 93 | #elif defined __NetBSD__ 94 | # define GTEST_OS_NETBSD 1 95 | #elif defined __OpenBSD__ 96 | # define GTEST_OS_OPENBSD 1 97 | #elif defined __QNX__ 98 | # define GTEST_OS_QNX 1 99 | #endif // __CYGWIN__ 100 | 101 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 102 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/eval.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/exec.h: Support for evaluating Python expressions and statements 3 | from strings and files 4 | 5 | Copyright (c) 2016 Klemens Morgenstern and 6 | Wenzel Jakob 7 | 8 | All rights reserved. Use of this source code is governed by a 9 | BSD-style license that can be found in the LICENSE file. 10 | */ 11 | 12 | #pragma once 13 | 14 | #include "pybind11.h" 15 | 16 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 17 | 18 | enum eval_mode { 19 | /// Evaluate a string containing an isolated expression 20 | eval_expr, 21 | 22 | /// Evaluate a string containing a single statement. Returns \c none 23 | eval_single_statement, 24 | 25 | /// Evaluate a string containing a sequence of statement. Returns \c none 26 | eval_statements 27 | }; 28 | 29 | template 30 | object eval(str expr, object global = globals(), object local = object()) { 31 | if (!local) 32 | local = global; 33 | 34 | /* PyRun_String does not accept a PyObject / encoding specifier, 35 | this seems to be the only alternative */ 36 | std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr; 37 | 38 | int start; 39 | switch (mode) { 40 | case eval_expr: start = Py_eval_input; break; 41 | case eval_single_statement: start = Py_single_input; break; 42 | case eval_statements: start = Py_file_input; break; 43 | default: pybind11_fail("invalid evaluation mode"); 44 | } 45 | 46 | PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr()); 47 | if (!result) 48 | throw error_already_set(); 49 | return reinterpret_steal(result); 50 | } 51 | 52 | template 53 | object eval(const char (&s)[N], object global = globals(), object local = object()) { 54 | /* Support raw string literals by removing common leading whitespace */ 55 | auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s)) 56 | : str(s); 57 | return eval(expr, global, local); 58 | } 59 | 60 | inline void exec(str expr, object global = globals(), object local = object()) { 61 | eval(expr, global, local); 62 | } 63 | 64 | template 65 | void exec(const char (&s)[N], object global = globals(), object local = object()) { 66 | eval(s, global, local); 67 | } 68 | 69 | template 70 | object eval_file(str fname, object global = globals(), object local = object()) { 71 | if (!local) 72 | local = global; 73 | 74 | int start; 75 | switch (mode) { 76 | case eval_expr: start = Py_eval_input; break; 77 | case eval_single_statement: start = Py_single_input; break; 78 | case eval_statements: start = Py_file_input; break; 79 | default: pybind11_fail("invalid evaluation mode"); 80 | } 81 | 82 | int closeFile = 1; 83 | std::string fname_str = (std::string) fname; 84 | #if PY_VERSION_HEX >= 0x03040000 85 | FILE *f = _Py_fopen_obj(fname.ptr(), "r"); 86 | #elif PY_VERSION_HEX >= 0x03000000 87 | FILE *f = _Py_fopen(fname.ptr(), "r"); 88 | #else 89 | /* No unicode support in open() :( */ 90 | auto fobj = reinterpret_steal(PyFile_FromString( 91 | const_cast(fname_str.c_str()), 92 | const_cast("r"))); 93 | FILE *f = nullptr; 94 | if (fobj) 95 | f = PyFile_AsFile(fobj.ptr()); 96 | closeFile = 0; 97 | #endif 98 | if (!f) { 99 | PyErr_Clear(); 100 | pybind11_fail("File \"" + fname_str + "\" could not be opened!"); 101 | } 102 | 103 | #if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION) 104 | PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), 105 | local.ptr()); 106 | (void) closeFile; 107 | #else 108 | PyObject *result = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), 109 | local.ptr(), closeFile); 110 | #endif 111 | 112 | if (!result) 113 | throw error_already_set(); 114 | return reinterpret_steal(result); 115 | } 116 | 117 | NAMESPACE_END(PYBIND11_NAMESPACE) 118 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/src/gtest-test-part.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // The Google C++ Testing and Mocking Framework (Google Test) 32 | 33 | #include "gtest/gtest-test-part.h" 34 | #include "src/gtest-internal-inl.h" 35 | 36 | namespace testing { 37 | 38 | using internal::GetUnitTestImpl; 39 | 40 | // Gets the summary of the failure message by omitting the stack trace 41 | // in it. 42 | std::string TestPartResult::ExtractSummary(const char* message) { 43 | const char* const stack_trace = strstr(message, internal::kStackTraceMarker); 44 | return stack_trace == nullptr ? message : std::string(message, stack_trace); 45 | } 46 | 47 | // Prints a TestPartResult object. 48 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { 49 | return os << result.file_name() << ":" << result.line_number() << ": " 50 | << (result.type() == TestPartResult::kSuccess 51 | ? "Success" 52 | : result.type() == TestPartResult::kSkip 53 | ? "Skipped" 54 | : result.type() == TestPartResult::kFatalFailure 55 | ? "Fatal failure" 56 | : "Non-fatal failure") 57 | << ":\n" 58 | << result.message() << std::endl; 59 | } 60 | 61 | // Appends a TestPartResult to the array. 62 | void TestPartResultArray::Append(const TestPartResult& result) { 63 | array_.push_back(result); 64 | } 65 | 66 | // Returns the TestPartResult at the given index (0-based). 67 | const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { 68 | if (index < 0 || index >= size()) { 69 | printf("\nInvalid index (%d) into TestPartResultArray.\n", index); 70 | internal::posix::Abort(); 71 | } 72 | 73 | return array_[index]; 74 | } 75 | 76 | // Returns the number of TestPartResult objects in the array. 77 | int TestPartResultArray::size() const { 78 | return static_cast(array_.size()); 79 | } 80 | 81 | namespace internal { 82 | 83 | HasNewFatalFailureHelper::HasNewFatalFailureHelper() 84 | : has_new_fatal_failure_(false), 85 | original_reporter_(GetUnitTestImpl()-> 86 | GetTestPartResultReporterForCurrentThread()) { 87 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); 88 | } 89 | 90 | HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { 91 | GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( 92 | original_reporter_); 93 | } 94 | 95 | void HasNewFatalFailureHelper::ReportTestPartResult( 96 | const TestPartResult& result) { 97 | if (result.fatally_failed()) 98 | has_new_fatal_failure_ = true; 99 | original_reporter_->ReportTestPartResult(result); 100 | } 101 | 102 | } // namespace internal 103 | 104 | } // namespace testing 105 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/src/gtest-typed-test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | #include "gtest/gtest-typed-test.h" 32 | 33 | #include "gtest/gtest.h" 34 | 35 | namespace testing { 36 | namespace internal { 37 | 38 | #if GTEST_HAS_TYPED_TEST_P 39 | 40 | // Skips to the first non-space char in str. Returns an empty string if str 41 | // contains only whitespace characters. 42 | static const char* SkipSpaces(const char* str) { 43 | while (IsSpace(*str)) 44 | str++; 45 | return str; 46 | } 47 | 48 | static std::vector SplitIntoTestNames(const char* src) { 49 | std::vector name_vec; 50 | src = SkipSpaces(src); 51 | for (; src != nullptr; src = SkipComma(src)) { 52 | name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); 53 | } 54 | return name_vec; 55 | } 56 | 57 | // Verifies that registered_tests match the test names in 58 | // registered_tests_; returns registered_tests if successful, or 59 | // aborts the program otherwise. 60 | const char* TypedTestSuitePState::VerifyRegisteredTestNames( 61 | const char* file, int line, const char* registered_tests) { 62 | typedef RegisteredTestsMap::const_iterator RegisteredTestIter; 63 | registered_ = true; 64 | 65 | std::vector name_vec = SplitIntoTestNames(registered_tests); 66 | 67 | Message errors; 68 | 69 | std::set tests; 70 | for (std::vector::const_iterator name_it = name_vec.begin(); 71 | name_it != name_vec.end(); ++name_it) { 72 | const std::string& name = *name_it; 73 | if (tests.count(name) != 0) { 74 | errors << "Test " << name << " is listed more than once.\n"; 75 | continue; 76 | } 77 | 78 | bool found = false; 79 | for (RegisteredTestIter it = registered_tests_.begin(); 80 | it != registered_tests_.end(); 81 | ++it) { 82 | if (name == it->first) { 83 | found = true; 84 | break; 85 | } 86 | } 87 | 88 | if (found) { 89 | tests.insert(name); 90 | } else { 91 | errors << "No test named " << name 92 | << " can be found in this test suite.\n"; 93 | } 94 | } 95 | 96 | for (RegisteredTestIter it = registered_tests_.begin(); 97 | it != registered_tests_.end(); 98 | ++it) { 99 | if (tests.count(it->first) == 0) { 100 | errors << "You forgot to list test " << it->first << ".\n"; 101 | } 102 | } 103 | 104 | const std::string& errors_str = errors.GetString(); 105 | if (errors_str != "") { 106 | fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), 107 | errors_str.c_str()); 108 | fflush(stderr); 109 | posix::Abort(); 110 | } 111 | 112 | return registered_tests; 113 | } 114 | 115 | #endif // GTEST_HAS_TYPED_TEST_P 116 | 117 | } // namespace internal 118 | } // namespace testing 119 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/buffer_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/buffer_info.h: Python buffer object interface 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "detail/common.h" 13 | 14 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 15 | 16 | /// Information record describing a Python buffer object 17 | struct buffer_info { 18 | void *ptr = nullptr; // Pointer to the underlying storage 19 | ssize_t itemsize = 0; // Size of individual items in bytes 20 | ssize_t size = 0; // Total number of entries 21 | std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() 22 | ssize_t ndim = 0; // Number of dimensions 23 | std::vector shape; // Shape of the tensor (1 entry per dimension) 24 | std::vector strides; // Number of entries between adjacent entries (for each per dimension) 25 | 26 | buffer_info() { } 27 | 28 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, 29 | detail::any_container shape_in, detail::any_container strides_in) 30 | : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), 31 | shape(std::move(shape_in)), strides(std::move(strides_in)) { 32 | if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) 33 | pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); 34 | for (size_t i = 0; i < (size_t) ndim; ++i) 35 | size *= shape[i]; 36 | } 37 | 38 | template 39 | buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in) 40 | : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in)) { } 41 | 42 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size) 43 | : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}) { } 44 | 45 | template 46 | buffer_info(T *ptr, ssize_t size) 47 | : buffer_info(ptr, sizeof(T), format_descriptor::format(), size) { } 48 | 49 | explicit buffer_info(Py_buffer *view, bool ownview = true) 50 | : buffer_info(view->buf, view->itemsize, view->format, view->ndim, 51 | {view->shape, view->shape + view->ndim}, {view->strides, view->strides + view->ndim}) { 52 | this->view = view; 53 | this->ownview = ownview; 54 | } 55 | 56 | buffer_info(const buffer_info &) = delete; 57 | buffer_info& operator=(const buffer_info &) = delete; 58 | 59 | buffer_info(buffer_info &&other) { 60 | (*this) = std::move(other); 61 | } 62 | 63 | buffer_info& operator=(buffer_info &&rhs) { 64 | ptr = rhs.ptr; 65 | itemsize = rhs.itemsize; 66 | size = rhs.size; 67 | format = std::move(rhs.format); 68 | ndim = rhs.ndim; 69 | shape = std::move(rhs.shape); 70 | strides = std::move(rhs.strides); 71 | std::swap(view, rhs.view); 72 | std::swap(ownview, rhs.ownview); 73 | return *this; 74 | } 75 | 76 | ~buffer_info() { 77 | if (view && ownview) { PyBuffer_Release(view); delete view; } 78 | } 79 | 80 | private: 81 | struct private_ctr_tag { }; 82 | 83 | buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, 84 | detail::any_container &&shape_in, detail::any_container &&strides_in) 85 | : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in)) { } 86 | 87 | Py_buffer *view = nullptr; 88 | bool ownview = false; 89 | }; 90 | 91 | NAMESPACE_BEGIN(detail) 92 | 93 | template struct compare_buffer_info { 94 | static bool compare(const buffer_info& b) { 95 | return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); 96 | } 97 | }; 98 | 99 | template struct compare_buffer_info::value>> { 100 | static bool compare(const buffer_info& b) { 101 | return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || 102 | ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || 103 | ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); 104 | } 105 | }; 106 | 107 | NAMESPACE_END(detail) 108 | NAMESPACE_END(PYBIND11_NAMESPACE) 109 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/tests/tests/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "gtest/gtest.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class MokerClass 10 | { 11 | public: 12 | void sum(int val, int *val2) 13 | { 14 | int _sum = val + *val2; 15 | p.set_value(_sum); 16 | } 17 | 18 | void sum_delay(int val, int *val2, std::chrono::seconds delay) 19 | { 20 | std::this_thread::sleep_for(delay); 21 | int _sum = val + *val2; 22 | p.set_value(_sum); 23 | } 24 | public: 25 | std::promise p; 26 | }; 27 | 28 | // The fixture for testing class Foo. 29 | class callback_wrapper_test : public ::testing::Test { 30 | protected: 31 | // You can remove any or all of the following functions if its body 32 | // is empty. 33 | 34 | callback_wrapper_test() { 35 | // You can do set-up work for each test here. 36 | } 37 | 38 | ~callback_wrapper_test() override { 39 | // You can do clean-up work that doesn't throw exceptions here. 40 | } 41 | 42 | // If the constructor and destructor are not enough for setting up 43 | // and cleaning up each test, you can define the following methods: 44 | 45 | void SetUp() override { 46 | // Code here will be called immediately after the constructor (right 47 | // before each test). 48 | dispatcher::instance().start(); 49 | } 50 | 51 | void TearDown() override { 52 | // Code here will be called immediately after each test (right 53 | // before the destructor). 54 | printf("ask dispatcher to stop ...\n"); 55 | dispatcher::instance().stop(); 56 | dispatcher::instance().join(); 57 | printf("dispatcher stopped!\n"); 58 | } 59 | 60 | // Objects declared here can be used by all tests in the test case for Foo. 61 | MokerClass m; 62 | MokerClass *instance = &m; 63 | std::random_device rd; 64 | std::mt19937 mt = std::mt19937(rd()); 65 | std::uniform_int_distribution dis; 66 | }; 67 | 68 | // tests: 69 | 70 | // * function is really called 71 | TEST_F(callback_wrapper_test, async) { 72 | int val1 = dis(mt); 73 | int *val2 = new int(dis(mt)); 74 | int excepted_sum = val1 + *val2; 75 | callback_wrapper<&MokerClass::sum>::async(instance, "", val1, val2); 76 | 77 | auto result = m.p.get_future().get(); 78 | EXPECT_EQ(excepted_sum, result); 79 | } 80 | 81 | TEST_F(callback_wrapper_test, sync) { 82 | int val1 = dis(mt); 83 | int *val2 = new int(dis(mt)); 84 | int excepted_sum = val1 + *val2; 85 | callback_wrapper<&MokerClass::sum>::sync(instance, "", val1, val2); 86 | 87 | auto result = m.p.get_future().get(); 88 | EXPECT_EQ(excepted_sum, result); 89 | } 90 | 91 | // * after pointer is deleted, that method should be still called because value is always copied in async call 92 | TEST_F(callback_wrapper_test, async_pointer) { 93 | int val1 = dis(mt); 94 | int *val2 = new int(dis(mt)); 95 | int excepted_sum = val1 + *val2; 96 | callback_wrapper<&MokerClass::sum_delay>::async(instance, "", val1, val2, std::chrono::seconds(1)); 97 | delete val2; 98 | 99 | auto result = m.p.get_future().get(); 100 | EXPECT_EQ(excepted_sum, result); 101 | } 102 | 103 | // * after pointer is deleted, that method should be still called because value is always copied in async call 104 | // * this is also a stress test 105 | TEST_F(callback_wrapper_test, async_sequential) { 106 | int n = 1000000; 107 | std::vector val1s; 108 | std::vector val2s; 109 | std::vector excepted_results; 110 | excepted_results.reserve(n); 111 | std::vector ms; 112 | ms.reserve(n); 113 | printf("generating tasks\n"); 114 | for (int i=0; i< n; i++) 115 | { 116 | int val1 = dis(mt); 117 | int val2 = dis(mt); 118 | int excepted_sum = val1 + val2; 119 | 120 | val1s.push_back(val1); 121 | val2s.push_back(val2); 122 | excepted_results.push_back(excepted_sum); 123 | ms.emplace_back(); 124 | } 125 | printf("pushing tasks\n"); 126 | for (int i = 0; i < n; i++) 127 | { 128 | auto &val1 = val1s.at(i); 129 | auto &val2 = val2s.at(i); 130 | auto &m = ms.at(i); 131 | callback_wrapper<&MokerClass::sum>::async(&m, "", val1, &val2); 132 | } 133 | printf("tasks generated and pushed!\n"); 134 | 135 | for (int i = 0; i < n; i++) 136 | { 137 | int excepted_sum = excepted_results.at(i); 138 | int result = ms.at(i).p.get_future().get(); 139 | EXPECT_EQ(excepted_sum, result); 140 | } 141 | printf("task checked!\n"); 142 | } 143 | 144 | #ifdef ARDUINO 145 | void setup() { 146 | // Since Arduino doesn't have a command line, fake out the argc/argv arguments 147 | int argc = 1; 148 | const auto arg0 = "PlatformIO"; 149 | char* argv0 = const_cast(arg0); 150 | char** argv = &argv0; 151 | 152 | testing::InitGoogleTest(&argc, argv); 153 | } 154 | 155 | void loop() { RUN_ALL_TESTS(); } 156 | 157 | #else 158 | 159 | GTEST_API_ int main(int argc, char **argv) { 160 | testing::InitGoogleTest(&argc, argv); 161 | return RUN_ALL_TESTS(); 162 | } 163 | #endif 164 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/iostream.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python 3 | 4 | Copyright (c) 2017 Henry F. Schreiner 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 21 | NAMESPACE_BEGIN(detail) 22 | 23 | // Buffer that writes to Python instead of C++ 24 | class pythonbuf : public std::streambuf { 25 | private: 26 | using traits_type = std::streambuf::traits_type; 27 | 28 | char d_buffer[1024]; 29 | object pywrite; 30 | object pyflush; 31 | 32 | int overflow(int c) { 33 | if (!traits_type::eq_int_type(c, traits_type::eof())) { 34 | *pptr() = traits_type::to_char_type(c); 35 | pbump(1); 36 | } 37 | return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof(); 38 | } 39 | 40 | int sync() { 41 | if (pbase() != pptr()) { 42 | // This subtraction cannot be negative, so dropping the sign 43 | str line(pbase(), static_cast(pptr() - pbase())); 44 | 45 | pywrite(line); 46 | pyflush(); 47 | 48 | setp(pbase(), epptr()); 49 | } 50 | return 0; 51 | } 52 | 53 | public: 54 | pythonbuf(object pyostream) 55 | : pywrite(pyostream.attr("write")), 56 | pyflush(pyostream.attr("flush")) { 57 | setp(d_buffer, d_buffer + sizeof(d_buffer) - 1); 58 | } 59 | 60 | /// Sync before destroy 61 | ~pythonbuf() { 62 | sync(); 63 | } 64 | }; 65 | 66 | NAMESPACE_END(detail) 67 | 68 | 69 | /** \rst 70 | This a move-only guard that redirects output. 71 | 72 | .. code-block:: cpp 73 | 74 | #include 75 | 76 | ... 77 | 78 | { 79 | py::scoped_ostream_redirect output; 80 | std::cout << "Hello, World!"; // Python stdout 81 | } // <-- return std::cout to normal 82 | 83 | You can explicitly pass the c++ stream and the python object, 84 | for example to guard stderr instead. 85 | 86 | .. code-block:: cpp 87 | 88 | { 89 | py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; 90 | std::cerr << "Hello, World!"; 91 | } 92 | \endrst */ 93 | class scoped_ostream_redirect { 94 | protected: 95 | std::streambuf *old; 96 | std::ostream &costream; 97 | detail::pythonbuf buffer; 98 | 99 | public: 100 | scoped_ostream_redirect( 101 | std::ostream &costream = std::cout, 102 | object pyostream = module::import("sys").attr("stdout")) 103 | : costream(costream), buffer(pyostream) { 104 | old = costream.rdbuf(&buffer); 105 | } 106 | 107 | ~scoped_ostream_redirect() { 108 | costream.rdbuf(old); 109 | } 110 | 111 | scoped_ostream_redirect(const scoped_ostream_redirect &) = delete; 112 | scoped_ostream_redirect(scoped_ostream_redirect &&other) = default; 113 | scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete; 114 | scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete; 115 | }; 116 | 117 | 118 | /** \rst 119 | Like `scoped_ostream_redirect`, but redirects cerr by default. This class 120 | is provided primary to make ``py::call_guard`` easier to make. 121 | 122 | .. code-block:: cpp 123 | 124 | m.def("noisy_func", &noisy_func, 125 | py::call_guard()); 127 | 128 | \endrst */ 129 | class scoped_estream_redirect : public scoped_ostream_redirect { 130 | public: 131 | scoped_estream_redirect( 132 | std::ostream &costream = std::cerr, 133 | object pyostream = module::import("sys").attr("stderr")) 134 | : scoped_ostream_redirect(costream,pyostream) {} 135 | }; 136 | 137 | 138 | NAMESPACE_BEGIN(detail) 139 | 140 | // Class to redirect output as a context manager. C++ backend. 141 | class OstreamRedirect { 142 | bool do_stdout_; 143 | bool do_stderr_; 144 | std::unique_ptr redirect_stdout; 145 | std::unique_ptr redirect_stderr; 146 | 147 | public: 148 | OstreamRedirect(bool do_stdout = true, bool do_stderr = true) 149 | : do_stdout_(do_stdout), do_stderr_(do_stderr) {} 150 | 151 | void enter() { 152 | if (do_stdout_) 153 | redirect_stdout.reset(new scoped_ostream_redirect()); 154 | if (do_stderr_) 155 | redirect_stderr.reset(new scoped_estream_redirect()); 156 | } 157 | 158 | void exit() { 159 | redirect_stdout.reset(); 160 | redirect_stderr.reset(); 161 | } 162 | }; 163 | 164 | NAMESPACE_END(detail) 165 | 166 | /** \rst 167 | This is a helper function to add a C++ redirect context manager to Python 168 | instead of using a C++ guard. To use it, add the following to your binding code: 169 | 170 | .. code-block:: cpp 171 | 172 | #include 173 | 174 | ... 175 | 176 | py::add_ostream_redirect(m, "ostream_redirect"); 177 | 178 | You now have a Python context manager that redirects your output: 179 | 180 | .. code-block:: python 181 | 182 | with m.ostream_redirect(): 183 | m.print_to_cout_function() 184 | 185 | This manager can optionally be told which streams to operate on: 186 | 187 | .. code-block:: python 188 | 189 | with m.ostream_redirect(stdout=true, stderr=true): 190 | m.noisy_function_with_error_printing() 191 | 192 | \endrst */ 193 | inline class_ add_ostream_redirect(module m, std::string name = "ostream_redirect") { 194 | return class_(m, name.c_str(), module_local()) 195 | .def(init(), arg("stdout")=true, arg("stderr")=true) 196 | .def("__enter__", &detail::OstreamRedirect::enter) 197 | .def("__exit__", [](detail::OstreamRedirect &self_, args) { self_.exit(); }); 198 | } 199 | 200 | NAMESPACE_END(PYBIND11_NAMESPACE) 201 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/src/gtest-matchers.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This file implements just enough of the matcher interface to allow 33 | // EXPECT_DEATH and friends to accept a matcher argument. 34 | 35 | #include "gtest/internal/gtest-internal.h" 36 | #include "gtest/internal/gtest-port.h" 37 | #include "gtest/gtest-matchers.h" 38 | 39 | #include 40 | 41 | namespace testing { 42 | 43 | // Constructs a matcher that matches a const std::string& whose value is 44 | // equal to s. 45 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 46 | 47 | #if GTEST_HAS_GLOBAL_STRING 48 | // Constructs a matcher that matches a const std::string& whose value is 49 | // equal to s. 50 | Matcher::Matcher(const ::string& s) { 51 | *this = Eq(static_cast(s)); 52 | } 53 | #endif // GTEST_HAS_GLOBAL_STRING 54 | 55 | // Constructs a matcher that matches a const std::string& whose value is 56 | // equal to s. 57 | Matcher::Matcher(const char* s) { 58 | *this = Eq(std::string(s)); 59 | } 60 | 61 | // Constructs a matcher that matches a std::string whose value is equal to 62 | // s. 63 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 64 | 65 | #if GTEST_HAS_GLOBAL_STRING 66 | // Constructs a matcher that matches a std::string whose value is equal to 67 | // s. 68 | Matcher::Matcher(const ::string& s) { 69 | *this = Eq(static_cast(s)); 70 | } 71 | #endif // GTEST_HAS_GLOBAL_STRING 72 | 73 | // Constructs a matcher that matches a std::string whose value is equal to 74 | // s. 75 | Matcher::Matcher(const char* s) { *this = Eq(std::string(s)); } 76 | 77 | #if GTEST_HAS_GLOBAL_STRING 78 | // Constructs a matcher that matches a const ::string& whose value is 79 | // equal to s. 80 | Matcher::Matcher(const std::string& s) { 81 | *this = Eq(static_cast<::string>(s)); 82 | } 83 | 84 | // Constructs a matcher that matches a const ::string& whose value is 85 | // equal to s. 86 | Matcher::Matcher(const ::string& s) { *this = Eq(s); } 87 | 88 | // Constructs a matcher that matches a const ::string& whose value is 89 | // equal to s. 90 | Matcher::Matcher(const char* s) { *this = Eq(::string(s)); } 91 | 92 | // Constructs a matcher that matches a ::string whose value is equal to s. 93 | Matcher<::string>::Matcher(const std::string& s) { 94 | *this = Eq(static_cast<::string>(s)); 95 | } 96 | 97 | // Constructs a matcher that matches a ::string whose value is equal to s. 98 | Matcher<::string>::Matcher(const ::string& s) { *this = Eq(s); } 99 | 100 | // Constructs a matcher that matches a string whose value is equal to s. 101 | Matcher<::string>::Matcher(const char* s) { *this = Eq(::string(s)); } 102 | #endif // GTEST_HAS_GLOBAL_STRING 103 | 104 | #if GTEST_HAS_ABSL 105 | // Constructs a matcher that matches a const absl::string_view& whose value is 106 | // equal to s. 107 | Matcher::Matcher(const std::string& s) { 108 | *this = Eq(s); 109 | } 110 | 111 | #if GTEST_HAS_GLOBAL_STRING 112 | // Constructs a matcher that matches a const absl::string_view& whose value is 113 | // equal to s. 114 | Matcher::Matcher(const ::string& s) { *this = Eq(s); } 115 | #endif // GTEST_HAS_GLOBAL_STRING 116 | 117 | // Constructs a matcher that matches a const absl::string_view& whose value is 118 | // equal to s. 119 | Matcher::Matcher(const char* s) { 120 | *this = Eq(std::string(s)); 121 | } 122 | 123 | // Constructs a matcher that matches a const absl::string_view& whose value is 124 | // equal to s. 125 | Matcher::Matcher(absl::string_view s) { 126 | *this = Eq(std::string(s)); 127 | } 128 | 129 | // Constructs a matcher that matches a absl::string_view whose value is equal to 130 | // s. 131 | Matcher::Matcher(const std::string& s) { *this = Eq(s); } 132 | 133 | #if GTEST_HAS_GLOBAL_STRING 134 | // Constructs a matcher that matches a absl::string_view whose value is equal to 135 | // s. 136 | Matcher::Matcher(const ::string& s) { *this = Eq(s); } 137 | #endif // GTEST_HAS_GLOBAL_STRING 138 | 139 | // Constructs a matcher that matches a absl::string_view whose value is equal to 140 | // s. 141 | Matcher::Matcher(const char* s) { 142 | *this = Eq(std::string(s)); 143 | } 144 | 145 | // Constructs a matcher that matches a absl::string_view whose value is equal to 146 | // s. 147 | Matcher::Matcher(absl::string_view s) { 148 | *this = Eq(std::string(s)); 149 | } 150 | #endif // GTEST_HAS_ABSL 151 | 152 | } // namespace testing 153 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/googletest/gtest.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 15.0 26 | {064DCEC7-172B-4334-8DF4-75A4EC7C8DD8} 27 | gtest 28 | 10.0.17763.0 29 | 30 | 31 | 32 | StaticLibrary 33 | true 34 | v141 35 | MultiByte 36 | 37 | 38 | StaticLibrary 39 | false 40 | v141 41 | true 42 | MultiByte 43 | 44 | 45 | StaticLibrary 46 | true 47 | v141 48 | MultiByte 49 | 50 | 51 | StaticLibrary 52 | false 53 | v141 54 | true 55 | MultiByte 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Level3 83 | Disabled 84 | true 85 | true 86 | 87 | 88 | 89 | 90 | Level3 91 | Disabled 92 | true 93 | true 94 | 95 | 96 | 97 | 98 | Level3 99 | MaxSpeed 100 | true 101 | true 102 | true 103 | true 104 | 105 | 106 | true 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | MaxSpeed 114 | true 115 | true 116 | true 117 | true 118 | 119 | 120 | true 121 | true 122 | 123 | 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/tests/tests/tests.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {BDE8B29F-8E69-4B91-9AEF-520FB6CA883A} 24 | tests 25 | 10.0.17763.0 26 | 27 | 28 | 29 | Application 30 | true 31 | v141 32 | MultiByte 33 | 34 | 35 | Application 36 | false 37 | v141 38 | true 39 | MultiByte 40 | 41 | 42 | Application 43 | true 44 | v141 45 | MultiByte 46 | 47 | 48 | Application 49 | false 50 | v141 51 | true 52 | MultiByte 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Level3 80 | Disabled 81 | true 82 | true 83 | 84 | 85 | Console 86 | 87 | 88 | 89 | 90 | Level3 91 | Disabled 92 | true 93 | true 94 | 95 | 96 | Console 97 | 98 | 99 | 100 | 101 | Level3 102 | MaxSpeed 103 | true 104 | true 105 | true 106 | true 107 | 108 | 109 | true 110 | true 111 | Console 112 | 113 | 114 | 115 | 116 | Level3 117 | MaxSpeed 118 | true 119 | true 120 | true 121 | true 122 | 123 | 124 | true 125 | true 126 | Console 127 | 128 | 129 | 130 | 131 | {064dcec7-172b-4334-8df4-75a4ec7c8dd8} 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/chrono.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime 3 | 4 | Copyright (c) 2016 Trent Houliston and 5 | Wenzel Jakob 6 | 7 | All rights reserved. Use of this source code is governed by a 8 | BSD-style license that can be found in the LICENSE file. 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "pybind11.h" 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | // Backport the PyDateTime_DELTA functions from Python3.3 if required 20 | #ifndef PyDateTime_DELTA_GET_DAYS 21 | #define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) 22 | #endif 23 | #ifndef PyDateTime_DELTA_GET_SECONDS 24 | #define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) 25 | #endif 26 | #ifndef PyDateTime_DELTA_GET_MICROSECONDS 27 | #define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) 28 | #endif 29 | 30 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 31 | NAMESPACE_BEGIN(detail) 32 | 33 | template class duration_caster { 34 | public: 35 | typedef typename type::rep rep; 36 | typedef typename type::period period; 37 | 38 | typedef std::chrono::duration> days; 39 | 40 | bool load(handle src, bool) { 41 | using namespace std::chrono; 42 | 43 | // Lazy initialise the PyDateTime import 44 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 45 | 46 | if (!src) return false; 47 | // If invoked with datetime.delta object 48 | if (PyDelta_Check(src.ptr())) { 49 | value = type(duration_cast>( 50 | days(PyDateTime_DELTA_GET_DAYS(src.ptr())) 51 | + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr())) 52 | + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr())))); 53 | return true; 54 | } 55 | // If invoked with a float we assume it is seconds and convert 56 | else if (PyFloat_Check(src.ptr())) { 57 | value = type(duration_cast>(duration(PyFloat_AsDouble(src.ptr())))); 58 | return true; 59 | } 60 | else return false; 61 | } 62 | 63 | // If this is a duration just return it back 64 | static const std::chrono::duration& get_duration(const std::chrono::duration &src) { 65 | return src; 66 | } 67 | 68 | // If this is a time_point get the time_since_epoch 69 | template static std::chrono::duration get_duration(const std::chrono::time_point> &src) { 70 | return src.time_since_epoch(); 71 | } 72 | 73 | static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) { 74 | using namespace std::chrono; 75 | 76 | // Use overloaded function to get our duration from our source 77 | // Works out if it is a duration or time_point and get the duration 78 | auto d = get_duration(src); 79 | 80 | // Lazy initialise the PyDateTime import 81 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 82 | 83 | // Declare these special duration types so the conversions happen with the correct primitive types (int) 84 | using dd_t = duration>; 85 | using ss_t = duration>; 86 | using us_t = duration; 87 | 88 | auto dd = duration_cast(d); 89 | auto subd = d - dd; 90 | auto ss = duration_cast(subd); 91 | auto us = duration_cast(subd - ss); 92 | return PyDelta_FromDSU(dd.count(), ss.count(), us.count()); 93 | } 94 | 95 | PYBIND11_TYPE_CASTER(type, _("datetime.timedelta")); 96 | }; 97 | 98 | // This is for casting times on the system clock into datetime.datetime instances 99 | template class type_caster> { 100 | public: 101 | typedef std::chrono::time_point type; 102 | bool load(handle src, bool) { 103 | using namespace std::chrono; 104 | 105 | // Lazy initialise the PyDateTime import 106 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 107 | 108 | if (!src) return false; 109 | if (PyDateTime_Check(src.ptr())) { 110 | std::tm cal; 111 | cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr()); 112 | cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr()); 113 | cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr()); 114 | cal.tm_mday = PyDateTime_GET_DAY(src.ptr()); 115 | cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1; 116 | cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900; 117 | cal.tm_isdst = -1; 118 | 119 | value = system_clock::from_time_t(std::mktime(&cal)) + microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr())); 120 | return true; 121 | } 122 | else return false; 123 | } 124 | 125 | static handle cast(const std::chrono::time_point &src, return_value_policy /* policy */, handle /* parent */) { 126 | using namespace std::chrono; 127 | 128 | // Lazy initialise the PyDateTime import 129 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; } 130 | 131 | std::time_t tt = system_clock::to_time_t(src); 132 | // this function uses static memory so it's best to copy it out asap just in case 133 | // otherwise other code that is using localtime may break this (not just python code) 134 | std::tm localtime = *std::localtime(&tt); 135 | 136 | // Declare these special duration types so the conversions happen with the correct primitive types (int) 137 | using us_t = duration; 138 | 139 | return PyDateTime_FromDateAndTime(localtime.tm_year + 1900, 140 | localtime.tm_mon + 1, 141 | localtime.tm_mday, 142 | localtime.tm_hour, 143 | localtime.tm_min, 144 | localtime.tm_sec, 145 | (duration_cast(src.time_since_epoch() % seconds(1))).count()); 146 | } 147 | PYBIND11_TYPE_CASTER(type, _("datetime.datetime")); 148 | }; 149 | 150 | // Other clocks that are not the system clock are not measured as datetime.datetime objects 151 | // since they are not measured on calendar time. So instead we just make them timedeltas 152 | // Or if they have passed us a time as a float we convert that 153 | template class type_caster> 154 | : public duration_caster> { 155 | }; 156 | 157 | template class type_caster> 158 | : public duration_caster> { 159 | }; 160 | 161 | NAMESPACE_END(detail) 162 | NAMESPACE_END(PYBIND11_NAMESPACE) 163 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/gtest-test-part.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // GOOGLETEST_CM0001 DO NOT DELETE 31 | 32 | #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 33 | #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 34 | 35 | #include 36 | #include 37 | #include "gtest/internal/gtest-internal.h" 38 | #include "gtest/internal/gtest-string.h" 39 | 40 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 41 | /* class A needs to have dll-interface to be used by clients of class B */) 42 | 43 | namespace testing { 44 | 45 | // A copyable object representing the result of a test part (i.e. an 46 | // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). 47 | // 48 | // Don't inherit from TestPartResult as its destructor is not virtual. 49 | class GTEST_API_ TestPartResult { 50 | public: 51 | // The possible outcomes of a test part (i.e. an assertion or an 52 | // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). 53 | enum Type { 54 | kSuccess, // Succeeded. 55 | kNonFatalFailure, // Failed but the test can continue. 56 | kFatalFailure, // Failed and the test should be terminated. 57 | kSkip // Skipped. 58 | }; 59 | 60 | // C'tor. TestPartResult does NOT have a default constructor. 61 | // Always use this constructor (with parameters) to create a 62 | // TestPartResult object. 63 | TestPartResult(Type a_type, const char* a_file_name, int a_line_number, 64 | const char* a_message) 65 | : type_(a_type), 66 | file_name_(a_file_name == nullptr ? "" : a_file_name), 67 | line_number_(a_line_number), 68 | summary_(ExtractSummary(a_message)), 69 | message_(a_message) {} 70 | 71 | // Gets the outcome of the test part. 72 | Type type() const { return type_; } 73 | 74 | // Gets the name of the source file where the test part took place, or 75 | // NULL if it's unknown. 76 | const char* file_name() const { 77 | return file_name_.empty() ? nullptr : file_name_.c_str(); 78 | } 79 | 80 | // Gets the line in the source file where the test part took place, 81 | // or -1 if it's unknown. 82 | int line_number() const { return line_number_; } 83 | 84 | // Gets the summary of the failure message. 85 | const char* summary() const { return summary_.c_str(); } 86 | 87 | // Gets the message associated with the test part. 88 | const char* message() const { return message_.c_str(); } 89 | 90 | // Returns true iff the test part was skipped. 91 | bool skipped() const { return type_ == kSkip; } 92 | 93 | // Returns true iff the test part passed. 94 | bool passed() const { return type_ == kSuccess; } 95 | 96 | // Returns true iff the test part non-fatally failed. 97 | bool nonfatally_failed() const { return type_ == kNonFatalFailure; } 98 | 99 | // Returns true iff the test part fatally failed. 100 | bool fatally_failed() const { return type_ == kFatalFailure; } 101 | 102 | // Returns true iff the test part failed. 103 | bool failed() const { return fatally_failed() || nonfatally_failed(); } 104 | 105 | private: 106 | Type type_; 107 | 108 | // Gets the summary of the failure message by omitting the stack 109 | // trace in it. 110 | static std::string ExtractSummary(const char* message); 111 | 112 | // The name of the source file where the test part took place, or 113 | // "" if the source file is unknown. 114 | std::string file_name_; 115 | // The line in the source file where the test part took place, or -1 116 | // if the line number is unknown. 117 | int line_number_; 118 | std::string summary_; // The test failure summary. 119 | std::string message_; // The test failure message. 120 | }; 121 | 122 | // Prints a TestPartResult object. 123 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result); 124 | 125 | // An array of TestPartResult objects. 126 | // 127 | // Don't inherit from TestPartResultArray as its destructor is not 128 | // virtual. 129 | class GTEST_API_ TestPartResultArray { 130 | public: 131 | TestPartResultArray() {} 132 | 133 | // Appends the given TestPartResult to the array. 134 | void Append(const TestPartResult& result); 135 | 136 | // Returns the TestPartResult at the given index (0-based). 137 | const TestPartResult& GetTestPartResult(int index) const; 138 | 139 | // Returns the number of TestPartResult objects in the array. 140 | int size() const; 141 | 142 | private: 143 | std::vector array_; 144 | 145 | GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); 146 | }; 147 | 148 | // This interface knows how to report a test part result. 149 | class GTEST_API_ TestPartResultReporterInterface { 150 | public: 151 | virtual ~TestPartResultReporterInterface() {} 152 | 153 | virtual void ReportTestPartResult(const TestPartResult& result) = 0; 154 | }; 155 | 156 | namespace internal { 157 | 158 | // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a 159 | // statement generates new fatal failures. To do so it registers itself as the 160 | // current test part result reporter. Besides checking if fatal failures were 161 | // reported, it only delegates the reporting to the former result reporter. 162 | // The original result reporter is restored in the destructor. 163 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 164 | class GTEST_API_ HasNewFatalFailureHelper 165 | : public TestPartResultReporterInterface { 166 | public: 167 | HasNewFatalFailureHelper(); 168 | ~HasNewFatalFailureHelper() override; 169 | void ReportTestPartResult(const TestPartResult& result) override; 170 | bool has_new_fatal_failure() const { return has_new_fatal_failure_; } 171 | private: 172 | bool has_new_fatal_failure_; 173 | TestPartResultReporterInterface* original_reporter_; 174 | 175 | GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); 176 | }; 177 | 178 | } // namespace internal 179 | 180 | } // namespace testing 181 | 182 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 183 | 184 | #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 185 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/internal/gtest-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file declares the String class and functions used internally by 33 | // Google Test. They are subject to change without notice. They should not used 34 | // by code external to Google Test. 35 | // 36 | // This header file is #included by gtest-internal.h. 37 | // It should not be #included by other files. 38 | 39 | // GOOGLETEST_CM0001 DO NOT DELETE 40 | 41 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 42 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 43 | 44 | #ifdef __BORLANDC__ 45 | // string.h is not guaranteed to provide strcpy on C++ Builder. 46 | # include 47 | #endif 48 | 49 | #include 50 | #include 51 | 52 | #include "gtest/internal/gtest-port.h" 53 | 54 | namespace testing { 55 | namespace internal { 56 | 57 | // String - an abstract class holding static string utilities. 58 | class GTEST_API_ String { 59 | public: 60 | // Static utility methods 61 | 62 | // Clones a 0-terminated C string, allocating memory using new. The 63 | // caller is responsible for deleting the return value using 64 | // delete[]. Returns the cloned string, or NULL if the input is 65 | // NULL. 66 | // 67 | // This is different from strdup() in string.h, which allocates 68 | // memory using malloc(). 69 | static const char* CloneCString(const char* c_str); 70 | 71 | #if GTEST_OS_WINDOWS_MOBILE 72 | // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be 73 | // able to pass strings to Win32 APIs on CE we need to convert them 74 | // to 'Unicode', UTF-16. 75 | 76 | // Creates a UTF-16 wide string from the given ANSI string, allocating 77 | // memory using new. The caller is responsible for deleting the return 78 | // value using delete[]. Returns the wide string, or NULL if the 79 | // input is NULL. 80 | // 81 | // The wide string is created using the ANSI codepage (CP_ACP) to 82 | // match the behaviour of the ANSI versions of Win32 calls and the 83 | // C runtime. 84 | static LPCWSTR AnsiToUtf16(const char* c_str); 85 | 86 | // Creates an ANSI string from the given wide string, allocating 87 | // memory using new. The caller is responsible for deleting the return 88 | // value using delete[]. Returns the ANSI string, or NULL if the 89 | // input is NULL. 90 | // 91 | // The returned string is created using the ANSI codepage (CP_ACP) to 92 | // match the behaviour of the ANSI versions of Win32 calls and the 93 | // C runtime. 94 | static const char* Utf16ToAnsi(LPCWSTR utf16_str); 95 | #endif 96 | 97 | // Compares two C strings. Returns true iff they have the same content. 98 | // 99 | // Unlike strcmp(), this function can handle NULL argument(s). A 100 | // NULL C string is considered different to any non-NULL C string, 101 | // including the empty string. 102 | static bool CStringEquals(const char* lhs, const char* rhs); 103 | 104 | // Converts a wide C string to a String using the UTF-8 encoding. 105 | // NULL will be converted to "(null)". If an error occurred during 106 | // the conversion, "(failed to convert from wide string)" is 107 | // returned. 108 | static std::string ShowWideCString(const wchar_t* wide_c_str); 109 | 110 | // Compares two wide C strings. Returns true iff they have the same 111 | // content. 112 | // 113 | // Unlike wcscmp(), this function can handle NULL argument(s). A 114 | // NULL C string is considered different to any non-NULL C string, 115 | // including the empty string. 116 | static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); 117 | 118 | // Compares two C strings, ignoring case. Returns true iff they 119 | // have the same content. 120 | // 121 | // Unlike strcasecmp(), this function can handle NULL argument(s). 122 | // A NULL C string is considered different to any non-NULL C string, 123 | // including the empty string. 124 | static bool CaseInsensitiveCStringEquals(const char* lhs, 125 | const char* rhs); 126 | 127 | // Compares two wide C strings, ignoring case. Returns true iff they 128 | // have the same content. 129 | // 130 | // Unlike wcscasecmp(), this function can handle NULL argument(s). 131 | // A NULL C string is considered different to any non-NULL wide C string, 132 | // including the empty string. 133 | // NB: The implementations on different platforms slightly differ. 134 | // On windows, this method uses _wcsicmp which compares according to LC_CTYPE 135 | // environment variable. On GNU platform this method uses wcscasecmp 136 | // which compares according to LC_CTYPE category of the current locale. 137 | // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the 138 | // current locale. 139 | static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, 140 | const wchar_t* rhs); 141 | 142 | // Returns true iff the given string ends with the given suffix, ignoring 143 | // case. Any string is considered to end with an empty suffix. 144 | static bool EndsWithCaseInsensitive( 145 | const std::string& str, const std::string& suffix); 146 | 147 | // Formats an int value as "%02d". 148 | static std::string FormatIntWidth2(int value); // "%02d" for width == 2 149 | 150 | // Formats an int value as "%X". 151 | static std::string FormatHexInt(int value); 152 | 153 | // Formats a byte as "%02X". 154 | static std::string FormatByte(unsigned char value); 155 | 156 | private: 157 | String(); // Not meant to be instantiated. 158 | }; // class String 159 | 160 | // Gets the content of the stringstream's buffer as an std::string. Each '\0' 161 | // character in the buffer is replaced with "\\0". 162 | GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); 163 | 164 | } // namespace internal 165 | } // namespace testing 166 | 167 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 168 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/autocxxpy/preprocessor.py: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | import ast 4 | import re 5 | from collections import defaultdict 6 | from dataclasses import dataclass, field 7 | from typing import Dict, List, Optional, Set 8 | 9 | from .cxxparser import ( 10 | CXXFileParser, 11 | CXXParseResult, 12 | Class, 13 | LiteralVariable, 14 | Method, 15 | Variable, 16 | ) 17 | from .type import array_base, base_types, is_array_type 18 | 19 | 20 | """ 21 | 42 - dec 22 | 0b101010 - bin 23 | 052 - oct 24 | 0xaa - hex 25 | 0Xaa - hex 26 | 1234u - suffix 27 | 1234ull - suffix 28 | 145'920 - with single quotes 29 | 1.0 - double 30 | 1.0f - float 31 | 32 | ignore: 33 | 5.9604644775390625e-8F16 34 | '123123' 35 | 36 | unsuportted: 37 | 1e10 - science 38 | 1E10 - science 39 | 1e+10 40 | 1e-10 41 | 1E-10 42 | 1E+10 43 | 44 | """ 45 | cpp_digit_re = re.compile( 46 | "(0b[01]+|0[0-7]+|0[Xx][0-9a-fA-F]+|[0-9']*[0-9]+)((ull)|(ULL)|(llu)|(LLU)|(ul)|(UL)|(ll)|(LL)|[UuLl])?$" 47 | ) 48 | 49 | cpp_digit_suffix_types = { 50 | "u": "unsigned int", 51 | "l": "long", 52 | "ul": "usngined long", 53 | "ll": "long long", 54 | "ull": "unsigned long long", 55 | "llu": "unsigned long long", 56 | "f": "float", 57 | } 58 | cpp_digit_suffix_types.update( 59 | {k.upper(): v for k, v in cpp_digit_suffix_types.items()} 60 | ) 61 | 62 | 63 | @dataclass 64 | class PreprocessedMethod(Method): 65 | has_overload: bool = False 66 | 67 | 68 | @dataclass 69 | class PreprocessedClass(Class): 70 | functions: Dict[str, List[PreprocessedMethod]] = field( 71 | default_factory=(lambda: defaultdict(list)) 72 | ) 73 | need_wrap: bool = False # if need_wrap is true, wrap this to dict 74 | # generator will not assign python constructor for pure virtual 75 | is_pure_virtual: bool = False 76 | 77 | 78 | class PreProcessorResult: 79 | def __init__(self): 80 | super().__init__() 81 | self.dict_classes: Set[str] = set() 82 | self.const_macros: Dict[str, Variable] = {} 83 | self.classes: Dict[str, PreprocessedClass] = {} 84 | 85 | 86 | class PreProcessor: 87 | def __init__(self, parse_result: CXXParseResult): 88 | self.parser_result = parse_result 89 | 90 | def process(self) -> PreProcessorResult: 91 | result = PreProcessorResult() 92 | 93 | # all pod struct to dict 94 | # todo: generator doesn't support dict class currently 95 | # result.dict_classes = self._find_dict_classes() 96 | 97 | # all error written macros to constant 98 | result.const_macros = self._pre_process_constant_macros() 99 | 100 | result.classes = self._pre_process_classes(result.dict_classes) 101 | return result 102 | 103 | def _pre_process_classes(self, dict_classes: Set[str]): 104 | classes: Dict[str, PreprocessedClass] = {} 105 | for c in self.parser_result.classes.values(): 106 | gc = PreprocessedClass(**c.__dict__) 107 | gc.functions = { 108 | name: [PreprocessedMethod(**m.__dict__) for m in ms] 109 | for name, ms in gc.functions.items() 110 | } 111 | if c.is_polymorphic: 112 | gc.need_wrap = True 113 | classes[gc.name] = gc 114 | for c in classes.values(): 115 | for ms in c.functions.values(): 116 | 117 | # check overload 118 | if len(ms) >= 2: 119 | for m in ms: 120 | m.has_overload = True 121 | 122 | # check pure virtual 123 | for m in ms: 124 | if m.is_pure_virtual: 125 | c.is_pure_virtual = True 126 | 127 | return classes 128 | 129 | def _pre_process_constant_macros(self): 130 | macros = {} 131 | for name, definition in self.parser_result.macros.items(): 132 | value = PreProcessor._try_convert_to_constant(definition) 133 | if value is not None: 134 | value.name = name 135 | macros[name] = value 136 | return macros 137 | 138 | def _find_dict_classes(self): 139 | dict_classes = set() 140 | for c in self.parser_result.classes.values(): 141 | if self._can_convert_to_dict(c): 142 | dict_classes.add(c.name) 143 | return dict_classes 144 | 145 | def _to_basic_type_combination(self, t: str): 146 | try: 147 | return self._to_basic_type_combination( 148 | self.parser_result.typedefs[t] 149 | ) 150 | except KeyError: 151 | return t 152 | 153 | def _is_basic_type(self, t: str): 154 | basic_combination = self._to_basic_type_combination(t) 155 | 156 | # just a basic type, such as int, char, short, double etc. 157 | if basic_combination in base_types: 158 | return True 159 | 160 | # array of basic type, such as int[], char[] 161 | if ( 162 | is_array_type(basic_combination) and 163 | array_base(basic_combination) in base_types 164 | ): 165 | return True 166 | 167 | print(basic_combination) 168 | return False 169 | 170 | def _can_convert_to_dict(self, c: Class): 171 | # first: no functions 172 | if c.functions: 173 | return False 174 | 175 | # second: all variables are basic 176 | for v in c.variables.values(): 177 | if not self._is_basic_type(v.type): 178 | return False 179 | 180 | return True 181 | 182 | @staticmethod 183 | def _try_parse_cpp_digit_literal(literal: str): 184 | m = cpp_digit_re.match(literal) 185 | if m: 186 | digit = m.group(1) 187 | suffix = m.group(2) 188 | val = ast.literal_eval(digit.replace("'", "")) 189 | t = "int" 190 | if suffix: 191 | t = cpp_digit_suffix_types[suffix] 192 | return LiteralVariable( 193 | name="", type=t, default=val, literal=literal 194 | ) 195 | return None 196 | 197 | @staticmethod 198 | def _try_convert_to_constant(definition: str) -> Optional[Variable]: 199 | definition = definition.strip() 200 | try: 201 | if definition: 202 | var = PreProcessor._try_parse_cpp_digit_literal(definition) 203 | if var: 204 | return var 205 | val = None 206 | if definition.startswith('"') and definition.endswith('"'): 207 | val = ast.literal_eval(definition) 208 | return LiteralVariable( 209 | name="", 210 | type="const char *", 211 | default=val, 212 | literal=definition, 213 | ) 214 | if definition.startswith("'") and definition.endswith("'"): 215 | val = CXXFileParser.character_literal_to_int( 216 | definition[1:-1] 217 | ) 218 | t = "unsigned int" 219 | valid = True 220 | if len(definition) >= 6: 221 | t = "unsigned long long" 222 | valid = False 223 | return LiteralVariable( 224 | name="", 225 | type=t, 226 | default=val, 227 | literal=definition, 228 | literal_valid=valid, 229 | ) 230 | except SyntaxError: 231 | pass 232 | return None 233 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/embed.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/embed.h: Support for embedding the interpreter 3 | 4 | Copyright (c) 2017 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | #include "eval.h" 14 | 15 | #if defined(PYPY_VERSION) 16 | # error Embedding the interpreter is not supported with PyPy 17 | #endif 18 | 19 | #if PY_MAJOR_VERSION >= 3 20 | # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 21 | extern "C" PyObject *pybind11_init_impl_##name() { \ 22 | return pybind11_init_wrapper_##name(); \ 23 | } 24 | #else 25 | # define PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 26 | extern "C" void pybind11_init_impl_##name() { \ 27 | pybind11_init_wrapper_##name(); \ 28 | } 29 | #endif 30 | 31 | /** \rst 32 | Add a new module to the table of builtins for the interpreter. Must be 33 | defined in global scope. The first macro parameter is the name of the 34 | module (without quotes). The second parameter is the variable which will 35 | be used as the interface to add functions and classes to the module. 36 | 37 | .. code-block:: cpp 38 | 39 | PYBIND11_EMBEDDED_MODULE(example, m) { 40 | // ... initialize functions and classes here 41 | m.def("foo", []() { 42 | return "Hello, World!"; 43 | }); 44 | } 45 | \endrst */ 46 | #define PYBIND11_EMBEDDED_MODULE(name, variable) \ 47 | static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \ 48 | static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \ 49 | auto m = pybind11::module(PYBIND11_TOSTRING(name)); \ 50 | try { \ 51 | PYBIND11_CONCAT(pybind11_init_, name)(m); \ 52 | return m.ptr(); \ 53 | } catch (pybind11::error_already_set &e) { \ 54 | PyErr_SetString(PyExc_ImportError, e.what()); \ 55 | return nullptr; \ 56 | } catch (const std::exception &e) { \ 57 | PyErr_SetString(PyExc_ImportError, e.what()); \ 58 | return nullptr; \ 59 | } \ 60 | } \ 61 | PYBIND11_EMBEDDED_MODULE_IMPL(name) \ 62 | pybind11::detail::embedded_module name(PYBIND11_TOSTRING(name), \ 63 | PYBIND11_CONCAT(pybind11_init_impl_, name)); \ 64 | void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &variable) 65 | 66 | 67 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 68 | NAMESPACE_BEGIN(detail) 69 | 70 | /// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks. 71 | struct embedded_module { 72 | #if PY_MAJOR_VERSION >= 3 73 | using init_t = PyObject *(*)(); 74 | #else 75 | using init_t = void (*)(); 76 | #endif 77 | embedded_module(const char *name, init_t init) { 78 | if (Py_IsInitialized()) 79 | pybind11_fail("Can't add new modules after the interpreter has been initialized"); 80 | 81 | auto result = PyImport_AppendInittab(name, init); 82 | if (result == -1) 83 | pybind11_fail("Insufficient memory to add a new module"); 84 | } 85 | }; 86 | 87 | NAMESPACE_END(detail) 88 | 89 | /** \rst 90 | Initialize the Python interpreter. No other pybind11 or CPython API functions can be 91 | called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The 92 | optional parameter can be used to skip the registration of signal handlers (see the 93 | `Python documentation`_ for details). Calling this function again after the interpreter 94 | has already been initialized is a fatal error. 95 | 96 | If initializing the Python interpreter fails, then the program is terminated. (This 97 | is controlled by the CPython runtime and is an exception to pybind11's normal behavior 98 | of throwing exceptions on errors.) 99 | 100 | .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx 101 | \endrst */ 102 | inline void initialize_interpreter(bool init_signal_handlers = true) { 103 | if (Py_IsInitialized()) 104 | pybind11_fail("The interpreter is already running"); 105 | 106 | Py_InitializeEx(init_signal_handlers ? 1 : 0); 107 | 108 | // Make .py files in the working directory available by default 109 | module::import("sys").attr("path").cast().append("."); 110 | } 111 | 112 | /** \rst 113 | Shut down the Python interpreter. No pybind11 or CPython API functions can be called 114 | after this. In addition, pybind11 objects must not outlive the interpreter: 115 | 116 | .. code-block:: cpp 117 | 118 | { // BAD 119 | py::initialize_interpreter(); 120 | auto hello = py::str("Hello, World!"); 121 | py::finalize_interpreter(); 122 | } // <-- BOOM, hello's destructor is called after interpreter shutdown 123 | 124 | { // GOOD 125 | py::initialize_interpreter(); 126 | { // scoped 127 | auto hello = py::str("Hello, World!"); 128 | } // <-- OK, hello is cleaned up properly 129 | py::finalize_interpreter(); 130 | } 131 | 132 | { // BETTER 133 | py::scoped_interpreter guard{}; 134 | auto hello = py::str("Hello, World!"); 135 | } 136 | 137 | .. warning:: 138 | 139 | The interpreter can be restarted by calling `initialize_interpreter` again. 140 | Modules created using pybind11 can be safely re-initialized. However, Python 141 | itself cannot completely unload binary extension modules and there are several 142 | caveats with regard to interpreter restarting. All the details can be found 143 | in the CPython documentation. In short, not all interpreter memory may be 144 | freed, either due to reference cycles or user-created global data. 145 | 146 | \endrst */ 147 | inline void finalize_interpreter() { 148 | handle builtins(PyEval_GetBuiltins()); 149 | const char *id = PYBIND11_INTERNALS_ID; 150 | 151 | // Get the internals pointer (without creating it if it doesn't exist). It's possible for the 152 | // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()` 153 | // during destruction), so we get the pointer-pointer here and check it after Py_Finalize(). 154 | detail::internals **internals_ptr_ptr = detail::get_internals_pp(); 155 | // It could also be stashed in builtins, so look there too: 156 | if (builtins.contains(id) && isinstance(builtins[id])) 157 | internals_ptr_ptr = capsule(builtins[id]); 158 | 159 | Py_Finalize(); 160 | 161 | if (internals_ptr_ptr) { 162 | delete *internals_ptr_ptr; 163 | *internals_ptr_ptr = nullptr; 164 | } 165 | } 166 | 167 | /** \rst 168 | Scope guard version of `initialize_interpreter` and `finalize_interpreter`. 169 | This a move-only guard and only a single instance can exist. 170 | 171 | .. code-block:: cpp 172 | 173 | #include 174 | 175 | int main() { 176 | py::scoped_interpreter guard{}; 177 | py::print(Hello, World!); 178 | } // <-- interpreter shutdown 179 | \endrst */ 180 | class scoped_interpreter { 181 | public: 182 | scoped_interpreter(bool init_signal_handlers = true) { 183 | initialize_interpreter(init_signal_handlers); 184 | } 185 | 186 | scoped_interpreter(const scoped_interpreter &) = delete; 187 | scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; } 188 | scoped_interpreter &operator=(const scoped_interpreter &) = delete; 189 | scoped_interpreter &operator=(scoped_interpreter &&) = delete; 190 | 191 | ~scoped_interpreter() { 192 | if (is_valid) 193 | finalize_interpreter(); 194 | } 195 | 196 | private: 197 | bool is_valid = true; 198 | }; 199 | 200 | NAMESPACE_END(PYBIND11_NAMESPACE) 201 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/internal/gtest-param-util-generated.h.pump: -------------------------------------------------------------------------------- 1 | $$ -*- mode: c++; -*- 2 | $var n = 50 $$ Maximum length of Values arguments we want to support. 3 | $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. 4 | // Copyright 2008 Google Inc. 5 | // All Rights Reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without 8 | // modification, are permitted provided that the following conditions are 9 | // met: 10 | // 11 | // * Redistributions of source code must retain the above copyright 12 | // notice, this list of conditions and the following disclaimer. 13 | // * Redistributions in binary form must reproduce the above 14 | // copyright notice, this list of conditions and the following disclaimer 15 | // in the documentation and/or other materials provided with the 16 | // distribution. 17 | // * Neither the name of Google Inc. nor the names of its 18 | // contributors may be used to endorse or promote products derived from 19 | // this software without specific prior written permission. 20 | // 21 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | 34 | // Type and function utilities for implementing parameterized tests. 35 | // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! 36 | // 37 | // Currently Google Test supports at most $n arguments in Values, 38 | // and at most $maxtuple arguments in Combine. Please contact 39 | // googletestframework@googlegroups.com if you need more. 40 | // Please note that the number of arguments to Combine is limited 41 | // by the maximum arity of the implementation of tuple which is 42 | // currently set at $maxtuple. 43 | 44 | // GOOGLETEST_CM0001 DO NOT DELETE 45 | 46 | #include 47 | 48 | #include 49 | 50 | #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ 51 | #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ 52 | 53 | #include "gtest/internal/gtest-param-util.h" 54 | #include "gtest/internal/gtest-port.h" 55 | 56 | namespace testing { 57 | 58 | namespace internal { 59 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 60 | // 61 | // Generates values from the Cartesian product of values produced 62 | // by the argument generators. 63 | // 64 | $range i 2..maxtuple 65 | $for i [[ 66 | $range j 1..i 67 | $range k 2..i 68 | 69 | template <$for j, [[typename T$j]]> 70 | class CartesianProductGenerator$i 71 | : public ParamGeneratorInterface< ::std::tuple<$for j, [[T$j]]> > { 72 | public: 73 | typedef ::std::tuple<$for j, [[T$j]]> ParamType; 74 | 75 | CartesianProductGenerator$i($for j, [[const ParamGenerator& g$j]]) 76 | : $for j, [[g$(j)_(g$j)]] {} 77 | ~CartesianProductGenerator$i() override {} 78 | 79 | ParamIteratorInterface* Begin() const override { 80 | return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]); 81 | } 82 | ParamIteratorInterface* End() const override { 83 | return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]); 84 | } 85 | 86 | private: 87 | class Iterator : public ParamIteratorInterface { 88 | public: 89 | Iterator(const ParamGeneratorInterface* base, $for j, [[ 90 | 91 | const ParamGenerator& g$j, 92 | const typename ParamGenerator::iterator& current$(j)]]) 93 | : base_(base), 94 | $for j, [[ 95 | 96 | begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j) 97 | ]] { 98 | ComputeCurrentValue(); 99 | } 100 | ~Iterator() override {} 101 | 102 | const ParamGeneratorInterface* BaseGenerator() const override { 103 | return base_; 104 | } 105 | // Advance should not be called on beyond-of-range iterators 106 | // so no component iterators must be beyond end of range, either. 107 | void Advance() override { 108 | assert(!AtEnd()); 109 | ++current$(i)_; 110 | 111 | $for k [[ 112 | if (current$(i+2-k)_ == end$(i+2-k)_) { 113 | current$(i+2-k)_ = begin$(i+2-k)_; 114 | ++current$(i+2-k-1)_; 115 | } 116 | 117 | ]] 118 | ComputeCurrentValue(); 119 | } 120 | ParamIteratorInterface* Clone() const override { 121 | return new Iterator(*this); 122 | } 123 | const ParamType* Current() const override { return current_value_.get(); } 124 | bool Equals(const ParamIteratorInterface& other) const override { 125 | // Having the same base generator guarantees that the other 126 | // iterator is of the same type and we can downcast. 127 | GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) 128 | << "The program attempted to compare iterators " 129 | << "from different generators." << std::endl; 130 | const Iterator* typed_other = 131 | CheckedDowncastToActualType(&other); 132 | // We must report iterators equal if they both point beyond their 133 | // respective ranges. That can happen in a variety of fashions, 134 | // so we have to consult AtEnd(). 135 | return (AtEnd() && typed_other->AtEnd()) || 136 | ($for j && [[ 137 | 138 | current$(j)_ == typed_other->current$(j)_ 139 | ]]); 140 | } 141 | 142 | private: 143 | Iterator(const Iterator& other) 144 | : base_(other.base_), $for j, [[ 145 | 146 | begin$(j)_(other.begin$(j)_), 147 | end$(j)_(other.end$(j)_), 148 | current$(j)_(other.current$(j)_) 149 | ]] { 150 | ComputeCurrentValue(); 151 | } 152 | 153 | void ComputeCurrentValue() { 154 | if (!AtEnd()) 155 | current_value_.reset(new ParamType($for j, [[*current$(j)_]])); 156 | } 157 | bool AtEnd() const { 158 | // We must report iterator past the end of the range when either of the 159 | // component iterators has reached the end of its range. 160 | return 161 | $for j || [[ 162 | 163 | current$(j)_ == end$(j)_ 164 | ]]; 165 | } 166 | 167 | // No implementation - assignment is unsupported. 168 | void operator=(const Iterator& other); 169 | 170 | const ParamGeneratorInterface* const base_; 171 | // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. 172 | // current[i]_ is the actual traversing iterator. 173 | $for j [[ 174 | 175 | const typename ParamGenerator::iterator begin$(j)_; 176 | const typename ParamGenerator::iterator end$(j)_; 177 | typename ParamGenerator::iterator current$(j)_; 178 | ]] 179 | 180 | std::shared_ptr current_value_; 181 | }; // class CartesianProductGenerator$i::Iterator 182 | 183 | // No implementation - assignment is unsupported. 184 | void operator=(const CartesianProductGenerator$i& other); 185 | 186 | 187 | $for j [[ 188 | const ParamGenerator g$(j)_; 189 | 190 | ]] 191 | }; // class CartesianProductGenerator$i 192 | 193 | 194 | ]] 195 | 196 | // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. 197 | // 198 | // Helper classes providing Combine() with polymorphic features. They allow 199 | // casting CartesianProductGeneratorN to ParamGenerator if T is 200 | // convertible to U. 201 | // 202 | $range i 2..maxtuple 203 | $for i [[ 204 | $range j 1..i 205 | 206 | template <$for j, [[class Generator$j]]> 207 | class CartesianProductHolder$i { 208 | public: 209 | CartesianProductHolder$i($for j, [[const Generator$j& g$j]]) 210 | : $for j, [[g$(j)_(g$j)]] {} 211 | template <$for j, [[typename T$j]]> 212 | operator ParamGenerator< ::std::tuple<$for j, [[T$j]]> >() const { 213 | return ParamGenerator< ::std::tuple<$for j, [[T$j]]> >( 214 | new CartesianProductGenerator$i<$for j, [[T$j]]>( 215 | $for j,[[ 216 | 217 | static_cast >(g$(j)_) 218 | ]])); 219 | } 220 | 221 | private: 222 | // No implementation - assignment is unsupported. 223 | void operator=(const CartesianProductHolder$i& other); 224 | 225 | 226 | $for j [[ 227 | const Generator$j g$(j)_; 228 | 229 | ]] 230 | }; // class CartesianProductHolder$i 231 | 232 | ]] 233 | 234 | } // namespace internal 235 | } // namespace testing 236 | 237 | #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ 238 | -------------------------------------------------------------------------------- /cpp_api_binding/generator/3rd_party/include/gtest/gtest-message.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // 31 | // The Google C++ Testing and Mocking Framework (Google Test) 32 | // 33 | // This header file defines the Message class. 34 | // 35 | // IMPORTANT NOTE: Due to limitation of the C++ language, we have to 36 | // leave some internal implementation details in this header file. 37 | // They are clearly marked by comments like this: 38 | // 39 | // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 40 | // 41 | // Such code is NOT meant to be used by a user directly, and is subject 42 | // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user 43 | // program! 44 | 45 | // GOOGLETEST_CM0001 DO NOT DELETE 46 | 47 | #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 48 | #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 49 | 50 | #include 51 | #include 52 | 53 | #include "gtest/internal/gtest-port.h" 54 | 55 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 56 | /* class A needs to have dll-interface to be used by clients of class B */) 57 | 58 | // Ensures that there is at least one operator<< in the global namespace. 59 | // See Message& operator<<(...) below for why. 60 | void operator<<(const testing::internal::Secret&, int); 61 | 62 | namespace testing { 63 | 64 | // The Message class works like an ostream repeater. 65 | // 66 | // Typical usage: 67 | // 68 | // 1. You stream a bunch of values to a Message object. 69 | // It will remember the text in a stringstream. 70 | // 2. Then you stream the Message object to an ostream. 71 | // This causes the text in the Message to be streamed 72 | // to the ostream. 73 | // 74 | // For example; 75 | // 76 | // testing::Message foo; 77 | // foo << 1 << " != " << 2; 78 | // std::cout << foo; 79 | // 80 | // will print "1 != 2". 81 | // 82 | // Message is not intended to be inherited from. In particular, its 83 | // destructor is not virtual. 84 | // 85 | // Note that stringstream behaves differently in gcc and in MSVC. You 86 | // can stream a NULL char pointer to it in the former, but not in the 87 | // latter (it causes an access violation if you do). The Message 88 | // class hides this difference by treating a NULL char pointer as 89 | // "(null)". 90 | class GTEST_API_ Message { 91 | private: 92 | // The type of basic IO manipulators (endl, ends, and flush) for 93 | // narrow streams. 94 | typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); 95 | 96 | public: 97 | // Constructs an empty Message. 98 | Message(); 99 | 100 | // Copy constructor. 101 | Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT 102 | *ss_ << msg.GetString(); 103 | } 104 | 105 | // Constructs a Message from a C-string. 106 | explicit Message(const char* str) : ss_(new ::std::stringstream) { 107 | *ss_ << str; 108 | } 109 | 110 | // Streams a non-pointer value to this object. 111 | template 112 | inline Message& operator <<(const T& val) { 113 | // Some libraries overload << for STL containers. These 114 | // overloads are defined in the global namespace instead of ::std. 115 | // 116 | // C++'s symbol lookup rule (i.e. Koenig lookup) says that these 117 | // overloads are visible in either the std namespace or the global 118 | // namespace, but not other namespaces, including the testing 119 | // namespace which Google Test's Message class is in. 120 | // 121 | // To allow STL containers (and other types that has a << operator 122 | // defined in the global namespace) to be used in Google Test 123 | // assertions, testing::Message must access the custom << operator 124 | // from the global namespace. With this using declaration, 125 | // overloads of << defined in the global namespace and those 126 | // visible via Koenig lookup are both exposed in this function. 127 | using ::operator <<; 128 | *ss_ << val; 129 | return *this; 130 | } 131 | 132 | // Streams a pointer value to this object. 133 | // 134 | // This function is an overload of the previous one. When you 135 | // stream a pointer to a Message, this definition will be used as it 136 | // is more specialized. (The C++ Standard, section 137 | // [temp.func.order].) If you stream a non-pointer, then the 138 | // previous definition will be used. 139 | // 140 | // The reason for this overload is that streaming a NULL pointer to 141 | // ostream is undefined behavior. Depending on the compiler, you 142 | // may get "0", "(nil)", "(null)", or an access violation. To 143 | // ensure consistent result across compilers, we always treat NULL 144 | // as "(null)". 145 | template 146 | inline Message& operator <<(T* const& pointer) { // NOLINT 147 | if (pointer == nullptr) { 148 | *ss_ << "(null)"; 149 | } else { 150 | *ss_ << pointer; 151 | } 152 | return *this; 153 | } 154 | 155 | // Since the basic IO manipulators are overloaded for both narrow 156 | // and wide streams, we have to provide this specialized definition 157 | // of operator <<, even though its body is the same as the 158 | // templatized version above. Without this definition, streaming 159 | // endl or other basic IO manipulators to Message will confuse the 160 | // compiler. 161 | Message& operator <<(BasicNarrowIoManip val) { 162 | *ss_ << val; 163 | return *this; 164 | } 165 | 166 | // Instead of 1/0, we want to see true/false for bool values. 167 | Message& operator <<(bool b) { 168 | return *this << (b ? "true" : "false"); 169 | } 170 | 171 | // These two overloads allow streaming a wide C string to a Message 172 | // using the UTF-8 encoding. 173 | Message& operator <<(const wchar_t* wide_c_str); 174 | Message& operator <<(wchar_t* wide_c_str); 175 | 176 | #if GTEST_HAS_STD_WSTRING 177 | // Converts the given wide string to a narrow string using the UTF-8 178 | // encoding, and streams the result to this Message object. 179 | Message& operator <<(const ::std::wstring& wstr); 180 | #endif // GTEST_HAS_STD_WSTRING 181 | 182 | #if GTEST_HAS_GLOBAL_WSTRING 183 | // Converts the given wide string to a narrow string using the UTF-8 184 | // encoding, and streams the result to this Message object. 185 | Message& operator <<(const ::wstring& wstr); 186 | #endif // GTEST_HAS_GLOBAL_WSTRING 187 | 188 | // Gets the text streamed to this object so far as an std::string. 189 | // Each '\0' character in the buffer is replaced with "\\0". 190 | // 191 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 192 | std::string GetString() const; 193 | 194 | private: 195 | // We'll hold the text streamed to this object here. 196 | const std::unique_ptr< ::std::stringstream> ss_; 197 | 198 | // We declare (but don't implement) this to prevent the compiler 199 | // from implementing the assignment operator. 200 | void operator=(const Message&); 201 | }; 202 | 203 | // Streams a Message to an ostream. 204 | inline std::ostream& operator <<(std::ostream& os, const Message& sb) { 205 | return os << sb.GetString(); 206 | } 207 | 208 | namespace internal { 209 | 210 | // Converts a streamable value to an std::string. A NULL pointer is 211 | // converted to "(null)". When the input value is a ::string, 212 | // ::std::string, ::wstring, or ::std::wstring object, each NUL 213 | // character in it is replaced with "\\0". 214 | template 215 | std::string StreamableToString(const T& streamable) { 216 | return (Message() << streamable).GetString(); 217 | } 218 | 219 | } // namespace internal 220 | } // namespace testing 221 | 222 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 223 | 224 | #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 225 | -------------------------------------------------------------------------------- /candle_chart/base/drawer.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from threading import Lock 3 | from typing import Optional, TYPE_CHECKING, TypeVar 4 | 5 | from PyQt5.QtCore import QRectF 6 | from PyQt5.QtGui import QBrush, QColor, QPainter 7 | 8 | from .data_source import CandleData, DataSource 9 | 10 | if TYPE_CHECKING: 11 | from .base import ColorType, DrawConfig 12 | 13 | T = TypeVar("T") 14 | 15 | 16 | class ChartDrawerBase(ABC): 17 | """ 18 | 数据序列 19 | 有两个职责: 20 | 1、管理自身的数据 21 | 2、将数据绘制出来 22 | 23 | 各个虚函数的调用顺序是这样的: 24 | ``` 25 | for series in all_series: 26 | series.before_draw() 27 | for i in ...: 28 | series.draw_item() 29 | series.after_draw() 30 | ``` 31 | """ 32 | 33 | def __init__(self, data_source: Optional["DataSource"] = None): 34 | self._data_source: Optional["DataSource"] = None 35 | self._data_source_lock = Lock() 36 | self.set_data_source(data_source) 37 | 38 | def set_data_source(self, data_source: "DataSource"): 39 | with self._data_source_lock: 40 | if self._data_source is not data_source: 41 | if self._data_source is not None: 42 | self._detach_data_source() 43 | self._data_source = data_source 44 | self._attach_data_source() 45 | 46 | def has_data(self): 47 | return self._data_source is not None and len(self._data_source) 48 | 49 | def on_data_source_data_removed(self, begin: int, end: int): 50 | pass 51 | 52 | def on_data_source_destroyed(self): 53 | with self._data_source_lock: 54 | self._data_source = None 55 | 56 | @abstractmethod 57 | def prepare_draw(self, config: "DrawConfig") -> "DrawConfig": 58 | """ 59 | 在准备绘制的时候会被调用,可能会被调用多次。 60 | 这个函数应该根据config的值计算出自身所需的y值 61 | 并且将[y_low, y_high]设置为自己绘制所有图像所覆盖的y值范围。 62 | 绘图引擎会根据各个数据序列所覆盖的y值范围不断调整图表自身值的范围,直到刚好能显示所有数据序列为止 63 | 64 | 注意:这里收到的config并不是draw_all时所使用的设置 65 | :return: "DrawConfig" 66 | """ 67 | return config 68 | 69 | @abstractmethod 70 | def draw(self, config: "DrawConfig", painter: QPainter): 71 | """ 72 | 绘制数据,可以在整张图上任意绘制,但是该函数最好每次只绘制坐标属于x的图 73 | 坐标系(以下称为drawer坐标系)使用和数据x-y值一致的坐标系:原点在左下角,x轴向右,y轴向上 => 坐下到右上 74 | 整个图形的坐标范围为: (left, bottom, right, top) = (begin, y_low, end, y_high) 75 | 因为图标并不知道数据的任何细节,所以draw_item函数应该自己检查x值是否越界 76 | """ 77 | pass 78 | 79 | def _attach_data_source(self): 80 | self._data_source.qobject.data_removed.connect(self.on_data_source_data_removed) 81 | self._data_source.qobject.destroyed.connect(self.on_data_source_destroyed) 82 | 83 | def _detach_data_source(self): 84 | raise RuntimeError("Rest of DataSource is currently not implemented.") 85 | 86 | 87 | class CandleChartDrawer(ChartDrawerBase): 88 | """ 89 | Drawer to present candlestick chart 90 | 91 | if cache is enabled 92 | """ 93 | 94 | def __init__(self, data_source: Optional["DataSource"] = None): 95 | super().__init__(data_source) 96 | self.body_width = 0.95 97 | self.line_width = 0.15 98 | self.minimum_box_height = 0.01 99 | self.growing_color: "ColorType" = "red" 100 | self.falling_color: "ColorType" = "green" 101 | self.use_cache = True 102 | 103 | # cached variables for draw 104 | self._cache_raising = [] 105 | self._cache_falling = [] 106 | self._cache_end = 0 107 | 108 | def on_data_source_data_removed(self, begin: int, end: int): 109 | # todo: fix cache, but not to rebuild it. 110 | self.clear_cache() 111 | 112 | def prepare_draw(self, config: "DrawConfig") -> "DrawConfig": 113 | showing_data = self._data_source[config.begin: config.end] 114 | if showing_data: 115 | low = min(showing_data, key=lambda c: c.low_price).low_price 116 | high = max(showing_data, key=lambda c: c.high_price).high_price 117 | config.y_low, config.y_high = low, high 118 | return config 119 | 120 | def draw(self, config: "DrawConfig", painter: "QPainter"): 121 | raising_brush = QBrush(QColor(self.growing_color)) 122 | falling_brush = QBrush(QColor(self.falling_color)) 123 | 124 | begin, end = config.begin, config.end 125 | 126 | # 如果不使用cache,简单的做法就是每次绘图之前清空一下cache 127 | if not self.use_cache: 128 | self.clear_cache() 129 | data_len = len(self._data_source) 130 | if data_len > self._cache_end: 131 | self._generate_cache(self._cache_end, data_len) 132 | 133 | painter.setBrush(raising_brush) 134 | painter.drawRects([i for i in self._cache_raising[begin * 2: end * 2] if i]) 135 | painter.setBrush(falling_brush) 136 | painter.drawRects([i for i in self._cache_falling[begin * 2: end * 2] if i]) 137 | 138 | def clear_cache(self): 139 | self._cache_end = 0 140 | self._cache_raising = [] 141 | self._cache_falling = [] 142 | 143 | def _generate_cache(self, begin, end): 144 | for i in range(begin, end): 145 | data: "CandleData" = self._data_source[i] 146 | 147 | if data.open_price <= data.close_price: 148 | push_cache = self._cache_raising 149 | nop_cache = self._cache_falling 150 | else: 151 | push_cache = self._cache_falling 152 | nop_cache = self._cache_raising 153 | 154 | # draw box 155 | box = self.get_rect(i, data.open_price, data.close_price, self.body_width) 156 | push_cache.append(box) 157 | nop_cache.append(None) 158 | 159 | # draw line 160 | line = self.get_rect(i, data.low_price, data.high_price, self.line_width) 161 | push_cache.append(line) 162 | nop_cache.append(None) 163 | 164 | self._cache_end = end 165 | 166 | def get_rect(self, i, start_y, end_y, width): 167 | left = i + 0.5 - 0.5 * width 168 | rect = QRectF( 169 | left, 170 | min(start_y, end_y), 171 | width, 172 | max(abs(start_y - end_y), self.minimum_box_height), 173 | ) 174 | return rect 175 | 176 | 177 | class BarChartDrawer(ChartDrawerBase): 178 | """ 179 | Drawer to present Histogram. 180 | 181 | When use_cache is disable, BarChartDrawer supports any list like DataSource, 182 | including un-formal DataSource). 183 | When use_cache is enabled, BarChartDrawer supports only formal DataSource 184 | """ 185 | 186 | def __init__(self, data_source: Optional["DataSource"] = None): 187 | super().__init__(data_source) 188 | self.body_width = 1 189 | self.positive_color: "ColorType" = "red" 190 | self.negative_color: "ColorType" = "green" 191 | 192 | self.use_cache = True 193 | 194 | # cached variables for draw 195 | self._cache_positive = [] 196 | self._cache_negative = [] 197 | self._cache_end = 0 198 | 199 | def on_data_source_data_removed(self, begin: int, end: int): 200 | self.clear_cache() 201 | 202 | def prepare_draw(self, config: "DrawConfig") -> "DrawConfig": 203 | showing_data = self._data_source[config.begin: config.end] 204 | if showing_data: 205 | low = min(showing_data) 206 | high = max(showing_data) 207 | config.y_low, config.y_high = low, high 208 | return config 209 | 210 | def draw(self, config: "DrawConfig", painter: "QPainter"): 211 | raising_brush = QBrush(QColor(self.positive_color)) 212 | falling_brush = QBrush(QColor(self.negative_color)) 213 | 214 | begin, end = config.begin, config.end 215 | 216 | if not self.use_cache: 217 | self.clear_cache() 218 | cache_end = self._cache_end 219 | 220 | data_len = len(self._data_source) 221 | if data_len > cache_end: 222 | self._generate_cache(cache_end, data_len) 223 | 224 | painter.setBrush(raising_brush) 225 | painter.drawRects([i for i in self._cache_positive[begin:end] if i]) 226 | painter.setBrush(falling_brush) 227 | painter.drawRects([i for i in self._cache_negative[begin:end] if i]) 228 | 229 | def clear_cache(self): 230 | self._cache_end = 0 231 | self._cache_positive = [] 232 | self._cache_negative = [] 233 | 234 | def _generate_cache(self, begin, end): 235 | for i in range(begin, end): 236 | data: "float" = self._data_source[i] 237 | 238 | if data > 0: 239 | push_cache = self._cache_positive 240 | nop_cache = self._cache_negative 241 | else: 242 | push_cache = self._cache_negative 243 | nop_cache = self._cache_positive 244 | 245 | # draw box 246 | box = self.get_rect(i, 0, data, self.body_width) 247 | push_cache.append(box) 248 | nop_cache.append(None) 249 | 250 | self._cache_end = end 251 | 252 | def get_rect(self, i, start_y, end_y, width): 253 | left = i + 0.5 - 0.5 * width 254 | rect = QRectF(left, min(start_y, end_y), width, abs(start_y - end_y)) 255 | return rect 256 | 257 | 258 | HistogramDrawer = BarChartDrawer 259 | -------------------------------------------------------------------------------- /cpp_api_binding/third_party/include/pybind11/operators.h: -------------------------------------------------------------------------------- 1 | /* 2 | pybind11/operator.h: Metatemplates for operator overloading 3 | 4 | Copyright (c) 2016 Wenzel Jakob 5 | 6 | All rights reserved. Use of this source code is governed by a 7 | BSD-style license that can be found in the LICENSE file. 8 | */ 9 | 10 | #pragma once 11 | 12 | #include "pybind11.h" 13 | 14 | #if defined(__clang__) && !defined(__INTEL_COMPILER) 15 | # pragma clang diagnostic ignored "-Wunsequenced" // multiple unsequenced modifications to 'self' (when using def(py::self OP Type())) 16 | #elif defined(_MSC_VER) 17 | # pragma warning(push) 18 | # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant 19 | #endif 20 | 21 | NAMESPACE_BEGIN(PYBIND11_NAMESPACE) 22 | NAMESPACE_BEGIN(detail) 23 | 24 | /// Enumeration with all supported operator types 25 | enum op_id : int { 26 | op_add, op_sub, op_mul, op_div, op_mod, op_divmod, op_pow, op_lshift, 27 | op_rshift, op_and, op_xor, op_or, op_neg, op_pos, op_abs, op_invert, 28 | op_int, op_long, op_float, op_str, op_cmp, op_gt, op_ge, op_lt, op_le, 29 | op_eq, op_ne, op_iadd, op_isub, op_imul, op_idiv, op_imod, op_ilshift, 30 | op_irshift, op_iand, op_ixor, op_ior, op_complex, op_bool, op_nonzero, 31 | op_repr, op_truediv, op_itruediv, op_hash 32 | }; 33 | 34 | enum op_type : int { 35 | op_l, /* base type on left */ 36 | op_r, /* base type on right */ 37 | op_u /* unary operator */ 38 | }; 39 | 40 | struct self_t { }; 41 | static const self_t self = self_t(); 42 | 43 | /// Type for an unused type slot 44 | struct undefined_t { }; 45 | 46 | /// Don't warn about an unused variable 47 | inline self_t __self() { return self; } 48 | 49 | /// base template of operator implementations 50 | template struct op_impl { }; 51 | 52 | /// Operator implementation generator 53 | template struct op_ { 54 | template void execute(Class &cl, const Extra&... extra) const { 55 | using Base = typename Class::type; 56 | using L_type = conditional_t::value, Base, L>; 57 | using R_type = conditional_t::value, Base, R>; 58 | using op = op_impl; 59 | cl.def(op::name(), &op::execute, is_operator(), extra...); 60 | #if PY_MAJOR_VERSION < 3 61 | if (id == op_truediv || id == op_itruediv) 62 | cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 63 | &op::execute, is_operator(), extra...); 64 | #endif 65 | } 66 | template void execute_cast(Class &cl, const Extra&... extra) const { 67 | using Base = typename Class::type; 68 | using L_type = conditional_t::value, Base, L>; 69 | using R_type = conditional_t::value, Base, R>; 70 | using op = op_impl; 71 | cl.def(op::name(), &op::execute_cast, is_operator(), extra...); 72 | #if PY_MAJOR_VERSION < 3 73 | if (id == op_truediv || id == op_itruediv) 74 | cl.def(id == op_itruediv ? "__idiv__" : ot == op_l ? "__div__" : "__rdiv__", 75 | &op::execute, is_operator(), extra...); 76 | #endif 77 | } 78 | }; 79 | 80 | #define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \ 81 | template struct op_impl { \ 82 | static char const* name() { return "__" #id "__"; } \ 83 | static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \ 84 | static B execute_cast(const L &l, const R &r) { return B(expr); } \ 85 | }; \ 86 | template struct op_impl { \ 87 | static char const* name() { return "__" #rid "__"; } \ 88 | static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \ 89 | static B execute_cast(const R &r, const L &l) { return B(expr); } \ 90 | }; \ 91 | inline op_ op(const self_t &, const self_t &) { \ 92 | return op_(); \ 93 | } \ 94 | template op_ op(const self_t &, const T &) { \ 95 | return op_(); \ 96 | } \ 97 | template op_ op(const T &, const self_t &) { \ 98 | return op_(); \ 99 | } 100 | 101 | #define PYBIND11_INPLACE_OPERATOR(id, op, expr) \ 102 | template struct op_impl { \ 103 | static char const* name() { return "__" #id "__"; } \ 104 | static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \ 105 | static B execute_cast(L &l, const R &r) { return B(expr); } \ 106 | }; \ 107 | template op_ op(const self_t &, const T &) { \ 108 | return op_(); \ 109 | } 110 | 111 | #define PYBIND11_UNARY_OPERATOR(id, op, expr) \ 112 | template struct op_impl { \ 113 | static char const* name() { return "__" #id "__"; } \ 114 | static auto execute(const L &l) -> decltype(expr) { return expr; } \ 115 | static B execute_cast(const L &l) { return B(expr); } \ 116 | }; \ 117 | inline op_ op(const self_t &) { \ 118 | return op_(); \ 119 | } 120 | 121 | PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r) 122 | PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r) 123 | PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l * r) 124 | PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r) 125 | PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r) 126 | PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r) 127 | PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r) 128 | PYBIND11_BINARY_OPERATOR(and, rand, operator&, l & r) 129 | PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r) 130 | PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r) 131 | PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r) 132 | PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r) 133 | PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r) 134 | PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r) 135 | PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r) 136 | PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r) 137 | //PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r)) 138 | PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r) 139 | PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r) 140 | PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r) 141 | PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r) 142 | PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r) 143 | PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r) 144 | PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r) 145 | PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r) 146 | PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r) 147 | PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r) 148 | PYBIND11_UNARY_OPERATOR(neg, operator-, -l) 149 | PYBIND11_UNARY_OPERATOR(pos, operator+, +l) 150 | PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l)) 151 | PYBIND11_UNARY_OPERATOR(hash, hash, std::hash()(l)) 152 | PYBIND11_UNARY_OPERATOR(invert, operator~, (~l)) 153 | PYBIND11_UNARY_OPERATOR(bool, operator!, !!l) 154 | PYBIND11_UNARY_OPERATOR(int, int_, (int) l) 155 | PYBIND11_UNARY_OPERATOR(float, float_, (double) l) 156 | 157 | #undef PYBIND11_BINARY_OPERATOR 158 | #undef PYBIND11_INPLACE_OPERATOR 159 | #undef PYBIND11_UNARY_OPERATOR 160 | NAMESPACE_END(detail) 161 | 162 | using detail::self; 163 | 164 | NAMESPACE_END(PYBIND11_NAMESPACE) 165 | 166 | #if defined(_MSC_VER) 167 | # pragma warning(pop) 168 | #endif 169 | --------------------------------------------------------------------------------