├── .azure-pipelines.yml ├── .ci ├── azure-pipelines │ ├── docker.yml │ └── native.yml ├── docker │ ├── Dockerfile.ubuntu-bionic │ ├── Dockerfile.ubuntu-eoan │ ├── Dockerfile.ubuntu-focal │ ├── Dockerfile.ubuntu-xenial │ └── env.list ├── install.sh ├── install_linux.sh ├── install_macos.sh └── script.sh ├── .clang-format ├── .codecov.yml ├── .dockerignore ├── .github └── workflows │ └── ccpp.yml ├── .gitignore ├── .travis.yml ├── Brewfile ├── CMakeLists.txt ├── Dockerfile ├── LICENSE ├── README.md ├── bindings ├── CMakeLists.txt ├── binding-impl.h.tmpl ├── binding.cpp.tmpl ├── boost_python │ ├── class.cpp.tmpl │ ├── class.h.tmpl │ ├── enum.cpp.tmpl │ ├── enum.h.tmpl │ ├── function.cpp.tmpl │ ├── function.h.tmpl │ ├── module.cpp.tmpl │ ├── module.h.tmpl │ ├── typedef.cpp.tmpl │ ├── typedef.h.tmpl │ ├── variable.cpp.tmpl │ └── variable.h.tmpl └── pybind11 │ ├── class.cpp.tmpl │ ├── class.h.tmpl │ ├── enum.cpp.tmpl │ ├── enum.h.tmpl │ ├── function.cpp.tmpl │ ├── function.h.tmpl │ ├── module.cpp.tmpl │ ├── module.h.tmpl │ ├── typedef.cpp.tmpl │ ├── typedef.h.tmpl │ ├── variable.cpp.tmpl │ └── variable.h.tmpl ├── cmake ├── ClangFormat.cmake ├── CodeCoverage.cmake ├── FindClang.cmake ├── FindYamlCpp.cmake ├── chimeraConfig.cmake.in ├── chimeraFindLLVM.cmake ├── chimeraFunctions.cmake └── generateChimeraBinding.cmake ├── external ├── CMakeLists.txt ├── cling │ ├── CMakeLists.txt │ ├── cling_license.txt │ ├── include │ │ └── cling_utils_AST.h │ └── src │ │ └── cling_utils_AST.cpp └── mstch │ ├── .appveyor.yml │ ├── .gitignore │ ├── .travis.yml │ ├── CMakeLists.txt │ ├── LICENSE │ ├── README.md │ ├── benchmark │ ├── CMakeLists.txt │ └── benchmark_main.cpp │ ├── cmake │ └── mstch-config.cmake │ ├── include │ └── mstch │ │ └── mstch.hpp │ ├── src │ ├── CMakeLists.txt │ ├── mstch.cpp │ ├── render_context.cpp │ ├── render_context.hpp │ ├── state │ │ ├── in_section.cpp │ │ ├── in_section.hpp │ │ ├── outside_section.cpp │ │ ├── outside_section.hpp │ │ └── render_state.hpp │ ├── template_type.cpp │ ├── template_type.hpp │ ├── token.cpp │ ├── token.hpp │ ├── utils.cpp │ ├── utils.hpp │ └── visitor │ │ ├── get_token.hpp │ │ ├── has_token.hpp │ │ ├── is_node_empty.hpp │ │ ├── render_node.hpp │ │ └── render_section.hpp │ └── test │ ├── CMakeLists.txt │ ├── data │ ├── ampersand_escape.hpp │ ├── ampersand_escape.mustache │ ├── ampersand_escape.txt │ ├── apostrophe.hpp │ ├── apostrophe.mustache │ ├── apostrophe.txt │ ├── array_of_strings.hpp │ ├── array_of_strings.mustache │ ├── array_of_strings.txt │ ├── backslashes.hpp │ ├── backslashes.mustache │ ├── backslashes.txt │ ├── bug_11_eating_whitespace.hpp │ ├── bug_11_eating_whitespace.mustache │ ├── bug_11_eating_whitespace.txt │ ├── bug_length_property.hpp │ ├── bug_length_property.mustache │ ├── bug_length_property.txt │ ├── changing_delimiters.hpp │ ├── changing_delimiters.mustache │ ├── changing_delimiters.txt │ ├── comments.hpp │ ├── comments.mustache │ ├── comments.txt │ ├── complex.hpp │ ├── complex.mustache │ ├── complex.txt │ ├── context_lookup.hpp │ ├── context_lookup.mustache │ ├── context_lookup.txt │ ├── delimiters.hpp │ ├── delimiters.mustache │ ├── delimiters.txt │ ├── disappearing_whitespace.hpp │ ├── disappearing_whitespace.mustache │ ├── disappearing_whitespace.txt │ ├── dot_notation.hpp │ ├── dot_notation.mustache │ ├── dot_notation.txt │ ├── double_render.hpp │ ├── double_render.mustache │ ├── double_render.txt │ ├── empty_list.hpp │ ├── empty_list.mustache │ ├── empty_list.txt │ ├── empty_sections.hpp │ ├── empty_sections.mustache │ ├── empty_sections.txt │ ├── empty_string.hpp │ ├── empty_string.mustache │ ├── empty_string.txt │ ├── empty_template.hpp │ ├── empty_template.mustache │ ├── empty_template.txt │ ├── error_eof_in_section.hpp │ ├── error_eof_in_section.mustache │ ├── error_eof_in_section.txt │ ├── error_eof_in_tag.hpp │ ├── error_eof_in_tag.mustache │ ├── error_eof_in_tag.txt │ ├── error_not_found.hpp │ ├── error_not_found.mustache │ ├── error_not_found.txt │ ├── escaped.hpp │ ├── escaped.mustache │ ├── escaped.txt │ ├── falsy.hpp │ ├── falsy.mustache │ ├── falsy.txt │ ├── falsy_array.hpp │ ├── falsy_array.mustache │ ├── falsy_array.txt │ ├── grandparent_context.hpp │ ├── grandparent_context.mustache │ ├── grandparent_context.txt │ ├── higher_order_sections.hpp │ ├── higher_order_sections.mustache │ ├── higher_order_sections.txt │ ├── implicit_iterator.hpp │ ├── implicit_iterator.mustache │ ├── implicit_iterator.txt │ ├── included_tag.hpp │ ├── included_tag.mustache │ ├── included_tag.txt │ ├── inverted_section.hpp │ ├── inverted_section.mustache │ ├── inverted_section.txt │ ├── keys_with_questionmarks.hpp │ ├── keys_with_questionmarks.mustache │ ├── keys_with_questionmarks.txt │ ├── multiline_comment.hpp │ ├── multiline_comment.mustache │ ├── multiline_comment.txt │ ├── nested_dot.hpp │ ├── nested_dot.mustache │ ├── nested_dot.txt │ ├── nested_higher_order_sections.hpp │ ├── nested_higher_order_sections.mustache │ ├── nested_higher_order_sections.txt │ ├── nested_iterating.hpp │ ├── nested_iterating.mustache │ ├── nested_iterating.txt │ ├── nesting.hpp │ ├── nesting.mustache │ ├── nesting.txt │ ├── nesting_same_name.hpp │ ├── nesting_same_name.mustache │ ├── nesting_same_name.txt │ ├── null_lookup_array.hpp │ ├── null_lookup_array.mustache │ ├── null_lookup_array.txt │ ├── null_lookup_object.hpp │ ├── null_lookup_object.mustache │ ├── null_lookup_object.txt │ ├── null_string.hpp │ ├── null_string.mustache │ ├── null_string.txt │ ├── null_view.hpp │ ├── null_view.mustache │ ├── null_view.txt │ ├── partial_array.hpp │ ├── partial_array.mustache │ ├── partial_array.partial │ ├── partial_array.txt │ ├── partial_array_of_partials.hpp │ ├── partial_array_of_partials.mustache │ ├── partial_array_of_partials.partial │ ├── partial_array_of_partials.txt │ ├── partial_array_of_partials_implicit.hpp │ ├── partial_array_of_partials_implicit.mustache │ ├── partial_array_of_partials_implicit.partial │ ├── partial_array_of_partials_implicit.txt │ ├── partial_empty.hpp │ ├── partial_empty.mustache │ ├── partial_empty.partial │ ├── partial_empty.txt │ ├── partial_template.hpp │ ├── partial_template.mustache │ ├── partial_template.partial │ ├── partial_template.txt │ ├── partial_view.hpp │ ├── partial_view.mustache │ ├── partial_view.partial │ ├── partial_view.txt │ ├── partial_whitespace.hpp │ ├── partial_whitespace.mustache │ ├── partial_whitespace.partial │ ├── partial_whitespace.txt │ ├── recursion_with_same_names.hpp │ ├── recursion_with_same_names.mustache │ ├── recursion_with_same_names.txt │ ├── reuse_of_enumerables.hpp │ ├── reuse_of_enumerables.mustache │ ├── reuse_of_enumerables.txt │ ├── section_as_context.hpp │ ├── section_as_context.mustache │ ├── section_as_context.txt │ ├── section_functions_in_partials.hpp │ ├── section_functions_in_partials.mustache │ ├── section_functions_in_partials.partial │ ├── section_functions_in_partials.txt │ ├── simple.hpp │ ├── simple.mustache │ ├── simple.txt │ ├── string_as_context.hpp │ ├── string_as_context.mustache │ ├── string_as_context.txt │ ├── two_in_a_row.hpp │ ├── two_in_a_row.mustache │ ├── two_in_a_row.txt │ ├── two_sections.hpp │ ├── two_sections.mustache │ ├── two_sections.txt │ ├── unescaped.hpp │ ├── unescaped.mustache │ ├── unescaped.txt │ ├── whitespace.hpp │ ├── whitespace.mustache │ ├── whitespace.txt │ ├── zero_view.hpp │ ├── zero_view.mustache │ └── zero_view.txt │ ├── specs_lambdas.hpp │ ├── test_context.hpp │ └── test_main.cpp ├── include └── chimera │ ├── binding.h │ ├── chimera.h │ ├── configuration.h │ ├── consumer.h │ ├── frontend_action.h │ ├── mstch.h │ ├── util.h │ └── visitor.h ├── package.xml ├── src ├── chimera.cpp ├── chimera_main.cpp ├── configuration.cpp ├── consumer.cpp ├── frontend_action.cpp ├── mstch.cpp ├── util.cpp └── visitor.cpp ├── test ├── CMakeLists.txt ├── emulator.cpp ├── emulator.h ├── examples │ ├── 00_module │ │ ├── CMakeLists.txt │ │ ├── module.h │ │ ├── module.py │ │ ├── module_boost_python.yaml │ │ └── module_pybind11.yaml │ ├── 01_function │ │ ├── CMakeLists.txt │ │ ├── function.cpp │ │ ├── function.h │ │ ├── function.py │ │ ├── function_boost_python.yaml │ │ └── function_pybind11.yaml │ ├── 02_class │ │ ├── CMakeLists.txt │ │ ├── class.cpp │ │ ├── class.h │ │ ├── class.py │ │ └── class.yaml │ ├── 03_smart_pointers │ │ ├── CMakeLists.txt │ │ ├── smart_pointers.cpp │ │ ├── smart_pointers.h │ │ ├── smart_pointers.py │ │ ├── smart_pointers_boost_python.yaml │ │ └── smart_pointers_pybind11.yaml │ ├── 04_enumeration │ │ ├── CMakeLists.txt │ │ ├── enumeration.cpp │ │ ├── enumeration.h │ │ ├── enumeration.py │ │ └── enumeration.yaml │ ├── 05_variable │ │ ├── CMakeLists.txt │ │ ├── variable.cpp │ │ ├── variable.h │ │ ├── variable.py │ │ └── variable.yaml │ ├── 06_template_class │ │ ├── CMakeLists.txt │ │ ├── boost_python.yaml │ │ ├── pybind11.yaml │ │ ├── template_class.cpp │ │ ├── template_class.h │ │ └── template_class.py │ ├── 07_typedef │ │ ├── CMakeLists.txt │ │ ├── typedef.h │ │ ├── typedef.py │ │ └── typedef.yaml │ ├── 20_eigen │ │ ├── CMakeLists.txt │ │ ├── eigen.cpp │ │ ├── eigen.h │ │ ├── eigen.py │ │ ├── eigen_boost_python.yaml │ │ └── eigen_pybind11.yaml │ ├── 30_pybind11_examples │ │ ├── 01_basics │ │ │ ├── 01_first_steps │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── chimera_boost_python.yaml │ │ │ │ ├── chimera_pybind11.yaml │ │ │ │ ├── first_steps.cpp │ │ │ │ ├── first_steps.h │ │ │ │ └── first_steps.py │ │ │ ├── 02_object_oriented_code │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── chimera_boost_python.yaml │ │ │ │ ├── chimera_pybind11.yaml │ │ │ │ ├── object_oriented_code.cpp │ │ │ │ ├── object_oriented_code.h │ │ │ │ └── object_oriented_code.py │ │ │ └── CMakeLists.txt │ │ ├── 02_advanced │ │ │ ├── 01_functions │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── chimera_boost_python.yaml │ │ │ │ ├── chimera_pybind11.yaml │ │ │ │ ├── functions.cpp │ │ │ │ ├── functions.h │ │ │ │ └── functions.py │ │ │ ├── 02_classes │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── chimera_boost_python.yaml │ │ │ │ ├── chimera_pybind11.yaml │ │ │ │ ├── classes.cpp │ │ │ │ ├── classes.h │ │ │ │ └── classes.py │ │ │ ├── 03_exceptions │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── chimera_boost_python.yaml │ │ │ │ ├── chimera_pybind11.yaml │ │ │ │ ├── exceptions.cpp │ │ │ │ ├── exceptions.h │ │ │ │ └── exceptions.py │ │ │ ├── 05_type_conversions │ │ │ │ ├── 03_functional │ │ │ │ │ ├── CMakeLists.txt │ │ │ │ │ ├── chimera_boost_python.yaml │ │ │ │ │ ├── chimera_pybind11.yaml │ │ │ │ │ ├── functional.cpp │ │ │ │ │ ├── functional.h │ │ │ │ │ └── functional.py │ │ │ │ └── CMakeLists.txt │ │ │ └── CMakeLists.txt │ │ └── CMakeLists.txt │ ├── 99_dart_example │ │ ├── CMakeLists.txt │ │ ├── dart_example.h │ │ ├── dart_example.py │ │ └── dart_example.yaml │ ├── CMakeLists.txt │ ├── cmake │ │ ├── chimeraTest.cmake │ │ ├── chimeraTestBoostPython.cmake │ │ └── chimeraTestPybind11.cmake │ └── regression │ │ ├── CMakeLists.txt │ │ ├── issue105_extra_commas │ │ ├── CMakeLists.txt │ │ ├── boost_python.yaml │ │ ├── issue105_extra_commas.h │ │ ├── issue105_extra_commas.py │ │ └── pybind11.yaml │ │ ├── issue148_lambda_function │ │ ├── CMakeLists.txt │ │ ├── boost_python.yaml │ │ ├── issue148_lambda_function.cpp │ │ ├── issue148_lambda_function.h │ │ ├── issue148_lambda_function.py │ │ └── pybind11.yaml │ │ ├── issue216_template_param │ │ ├── CMakeLists.txt │ │ ├── issue216_template_param.cpp │ │ ├── issue216_template_param.h │ │ ├── issue216_template_param.py │ │ ├── issue216_template_param_boost_python.yaml │ │ └── issue216_template_param_pybind11.yaml │ │ ├── issue228_template_type_alias │ │ ├── CMakeLists.txt │ │ ├── issue228_template_type_alias.cpp │ │ ├── issue228_template_type_alias.h │ │ ├── issue228_template_type_alias.py │ │ ├── issue228_template_type_alias_boost_python.yaml │ │ └── issue228_template_type_alias_pybind11.yaml │ │ ├── issue262_static_method │ │ ├── CMakeLists.txt │ │ ├── boost_python.yaml │ │ ├── issue262_static_method.h │ │ ├── issue262_static_method.py │ │ └── pybind11.yaml │ │ ├── issue297_template_variable │ │ ├── CMakeLists.txt │ │ ├── boost_python.yaml │ │ ├── issue297_template_variable.cpp │ │ ├── issue297_template_variable.h │ │ ├── issue297_template_variable.py │ │ └── pybind11.yaml │ │ ├── issue310_nested_class_name │ │ ├── CMakeLists.txt │ │ ├── boost_python.yaml │ │ ├── issue310_nested_class_name.cpp │ │ ├── issue310_nested_class_name.h │ │ ├── issue310_nested_class_name.py │ │ └── pybind11.yaml │ │ └── issue328_dependent_name │ │ ├── CMakeLists.txt │ │ ├── boost_python.yaml │ │ ├── issue328_dependent_name.h │ │ ├── issue328_dependent_name.py │ │ └── pybind11.yaml ├── gtest │ ├── cmake │ │ ├── Config.cmake.in │ │ ├── gtest.pc.in │ │ ├── gtest_main.pc.in │ │ └── internal_utils.cmake │ ├── include │ │ └── gtest │ │ │ ├── gtest-death-test.h │ │ │ ├── gtest-message.h │ │ │ ├── gtest-param-test.h │ │ │ ├── gtest-param-test.h.pump │ │ │ ├── gtest-printers.h │ │ │ ├── gtest-spi.h │ │ │ ├── gtest-test-part.h │ │ │ ├── gtest-typed-test.h │ │ │ ├── gtest.h │ │ │ ├── gtest_pred_impl.h │ │ │ ├── gtest_prod.h │ │ │ └── internal │ │ │ ├── custom │ │ │ ├── README.md │ │ │ ├── gtest-port.h │ │ │ ├── gtest-printers.h │ │ │ └── gtest.h │ │ │ ├── gtest-death-test-internal.h │ │ │ ├── gtest-filepath.h │ │ │ ├── gtest-internal.h │ │ │ ├── gtest-linked_ptr.h │ │ │ ├── gtest-param-util-generated.h │ │ │ ├── gtest-param-util-generated.h.pump │ │ │ ├── gtest-param-util.h │ │ │ ├── gtest-port-arch.h │ │ │ ├── gtest-port.h │ │ │ ├── gtest-string.h │ │ │ ├── gtest-tuple.h │ │ │ ├── gtest-tuple.h.pump │ │ │ ├── gtest-type-util.h │ │ │ └── gtest-type-util.h.pump │ └── src │ │ ├── gtest-all.cc │ │ ├── gtest-death-test.cc │ │ ├── gtest-filepath.cc │ │ ├── gtest-internal-inl.h │ │ ├── gtest-port.cc │ │ ├── gtest-printers.cc │ │ ├── gtest-test-part.cc │ │ ├── gtest-typed-test.cc │ │ ├── gtest.cc │ │ └── gtest_main.cc └── test_emulator.cpp └── tools └── check_format.sh /.ci/azure-pipelines/docker.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | numThreads: 4 3 | 4 | steps: 5 | - script: | 6 | docker build -t ${DOCKERFILE,,} -f ".ci/docker/$DOCKERFILE" .; 7 | docker run -itd -v $(Build.SourcesDirectory):$(Build.SourcesDirectory) --env-file .ci/docker/env.list --name chimera-docker ${DOCKERFILE,,}; 8 | docker exec chimera-docker /bin/sh -c "cd $(Build.SourcesDirectory) && ./.ci/install.sh"; 9 | displayName: 'Install' 10 | - script: | 11 | docker exec chimera-docker /bin/sh -c "cd $(Build.SourcesDirectory) && ./.ci/script.sh -j${{ parameters.numThreads }}"; 12 | displayName: 'Script' 13 | -------------------------------------------------------------------------------- /.ci/azure-pipelines/native.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | numThreads: 4 3 | 4 | steps: 5 | - script: | 6 | ./.ci/install.sh 7 | displayName: 'Install' 8 | - script: | 9 | ./.ci/script.sh -j${{ parameters.numThreads }} 10 | displayName: 'Script' 11 | -------------------------------------------------------------------------------- /.ci/docker/Dockerfile.ubuntu-bionic: -------------------------------------------------------------------------------- 1 | FROM ubuntu:bionic 2 | 3 | # Workaround to suppress "Warning: apt-key output should not be parsed (stdout is not a terminal)" 4 | ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 5 | -------------------------------------------------------------------------------- /.ci/docker/Dockerfile.ubuntu-eoan: -------------------------------------------------------------------------------- 1 | FROM ubuntu:eoan 2 | -------------------------------------------------------------------------------- /.ci/docker/Dockerfile.ubuntu-focal: -------------------------------------------------------------------------------- 1 | FROM ubuntu:focal 2 | 3 | ENV DEBIAN_FRONTEND=noninteractive 4 | -------------------------------------------------------------------------------- /.ci/docker/Dockerfile.ubuntu-xenial: -------------------------------------------------------------------------------- 1 | FROM ubuntu:xenial 2 | -------------------------------------------------------------------------------- /.ci/docker/env.list: -------------------------------------------------------------------------------- 1 | REPO_SLUG 2 | IS_PULL_REQUEST 3 | OS_NAME 4 | BUILD_DIR 5 | 6 | BUILD_NAME 7 | BUILD_TYPE 8 | COMPILER 9 | DOCKERFILE 10 | LLVM_DIR 11 | LLVM_VERSION 12 | PYTHON_VERSION 13 | SUDO 14 | 15 | CI 16 | -------------------------------------------------------------------------------- /.ci/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | 4 | if [ "${OS_NAME}" = "linux" ]; then . .ci/install_linux.sh; fi 5 | if [ "${OS_NAME}" = "osx" ]; then . .ci/install_macos.sh; fi 6 | -------------------------------------------------------------------------------- /.ci/install_linux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | 4 | $SUDO apt-get -q update 5 | $SUDO apt-get -y install \ 6 | lsb-release 7 | 8 | if [ $(lsb_release -sc) = "trusty" ]; then 9 | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | $SUDO apt-key add - 10 | $SUDO add-apt-repository -y "deb http://llvm.org/apt/$(lsb_release -sc)/ llvm-toolchain-$(lsb_release -sc)-${LLVM_VERSION} main" 11 | $SUDO apt-get -q update 12 | fi 13 | $SUDO apt-get -y install "llvm-${LLVM_VERSION}-dev" "llvm-${LLVM_VERSION}-tools" "libclang-${LLVM_VERSION}-dev" libedit-dev libyaml-cpp-dev libboost-dev 14 | 15 | # Install build tools 16 | $SUDO apt-get -y install \ 17 | build-essential \ 18 | cmake \ 19 | curl \ 20 | git \ 21 | lib32z1-dev \ 22 | lsb-release \ 23 | pkg-config \ 24 | software-properties-common \ 25 | sudo \ 26 | wget 27 | 28 | # Install test dependencies. 29 | $SUDO apt-get -y install libeigen3-dev 30 | $SUDO apt-get -y install libboost-python-dev libboost-thread-dev 31 | $SUDO apt-get -y install lcov 32 | # Install Python 2 up to Eoan 33 | if [ $(lsb_release -sc) = "xenial" ] || [ $(lsb_release -sc) = "bionic" ] || [ $(lsb_release -sc) = "eoan" ]; then 34 | $SUDO apt-get -y install python-dev libpython-dev 35 | fi 36 | $SUDO apt-get -y install python3-dev libpython3-dev 37 | 38 | # Install ClangFormat 6 39 | if [ $(lsb_release -sc) = "bionic" ]; then 40 | $SUDO apt-get -y install clang-format-6.0 41 | fi 42 | 43 | # Install pybind11 (we need pybind11 (>=2.2.4)) 44 | if [ $(lsb_release -sc) = "xenial" ] || [ $(lsb_release -sc) = "bionic" ]; then 45 | git clone https://github.com/pybind/pybind11.git 46 | cd pybind11 47 | git checkout tags/v2.2.4 48 | mkdir build 49 | cd build 50 | cmake .. -DPYBIND11_TEST=OFF -DPYBIND11_PYTHON_VERSION=$PYTHON_VERSION 51 | make -j4 52 | $SUDO make install 53 | cd ../.. 54 | else 55 | $SUDO apt-get -y install pybind11-dev 56 | fi 57 | -------------------------------------------------------------------------------- /.ci/script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -ex 3 | 4 | if [ "${OS_NAME}" = "linux" ]; then 5 | if [ "${CI}" = "TRAVIS" ]; then 6 | export LLVM_DIR="/usr/share/llvm-${LLVM_VERSION}/cmake/" 7 | else 8 | export LLVM_DIR="/usr/lib/llvm-${LLVM_VERSION}/lib/cmake/llvm/" 9 | fi 10 | fi 11 | 12 | mkdir build 13 | cd build 14 | 15 | if [ $BUILD_NAME = TRUSTY_GCC_DEBUG ]; then 16 | cmake "-DCMAKE_BUILD_TYPE=${BUILD_TYPE}" "-DLLVM_DIR=${LLVM_DIR}" "-DCODECOV=ON" .. 17 | else 18 | cmake "-DCMAKE_BUILD_TYPE=${BUILD_TYPE}" "-DLLVM_DIR=${LLVM_DIR}" "-DCODECOV=OFF" .. 19 | fi 20 | 21 | if [ "$OS_NAME" = "linux" ] && [ $(lsb_release -sc) = "bionic" ]; then 22 | make check-format 23 | fi 24 | 25 | make -j4 26 | 27 | # Building tests and binding_tests fails on macOS (see: https://github.com/personalrobotics/chimera/issues/218) 28 | if [ "${OS_NAME}" = "linux" ]; then 29 | # Building binding_tests fails on Ubuntu Focal 30 | if [ ! $(lsb_release -sc) = "focal" ]; then 31 | # Parallel build for examples is disabled by 32 | # https://github.com/personalrobotics/chimera/pull/274 33 | # because it seems to cause missing intermediate target. Here are examples of the 34 | # build failures: 35 | # - https://travis-ci.org/github/personalrobotics/chimera/jobs/671315806#L2226-L2301 36 | # - https://travis-ci.org/github/personalrobotics/chimera/jobs/671301082#L2523-L2573 37 | make tests binding_tests 38 | 39 | if [ $BUILD_NAME = TRUSTY_GCC_DEBUG ]; then 40 | make chimera_coverage 41 | else 42 | ctest --output-on-failure 43 | fi 44 | fi 45 | fi 46 | 47 | $SUDO make install 48 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | # Reference: https://github.com/codecov/support/wiki/Codecov-Yaml 2 | 3 | coverage: 4 | ignore: 5 | - "external" 6 | comment: 7 | layout: "diff, flags, files" 8 | 9 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | build/ 2 | ci/ 3 | .codecov.yml 4 | .gitignore 5 | .travis.yml 6 | Dockerfile 7 | LICENSE 8 | README.md 9 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | brew 'boost' 2 | brew 'yaml-cpp' 3 | 4 | # For testing 5 | brew 'boost-python' 6 | brew 'boost-python3' 7 | brew 'pybind11' 8 | brew 'z3' 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 as builder 2 | 3 | # Install APT dependencies required for building chimera. 4 | RUN apt-get update -qq \ 5 | && apt-get install -y -qq \ 6 | cmake \ 7 | clang \ 8 | clang-format \ 9 | llvm-6.0-dev \ 10 | llvm-6.0-tools \ 11 | libboost-dev \ 12 | libclang-6.0-dev \ 13 | libedit-dev \ 14 | libyaml-cpp-dev \ 15 | libz-dev \ 16 | && rm -rf /var/lib/apt/lists/* 17 | 18 | # Compile and install chimera 19 | COPY . /opt/chimera 20 | WORKDIR /opt/chimera 21 | RUN mkdir build && cd build \ 22 | && cmake -DBUILD_TESTING=off .. \ 23 | && make install 24 | 25 | ############################################################################# 26 | FROM ubuntu:18.04 27 | 28 | # Install APT dependencies required for running chimera. 29 | RUN apt-get update -qq \ 30 | && apt-get install -y -qq \ 31 | llvm-6.0-tools \ 32 | libclang-6.0 \ 33 | libedit2 \ 34 | libyaml-cpp0.5v5 \ 35 | zlib1g \ 36 | && rm -rf /var/lib/apt/lists/* 37 | 38 | # Install Chimera from the build image. 39 | COPY --from=builder /usr/local/bin/chimera /usr/local/bin/chimera 40 | 41 | # Create a non-root user to run Chimera application 42 | RUN useradd --create-home -s /bin/bash user 43 | WORKDIR /home/user 44 | USER user 45 | 46 | # Set chimera as the default entrypoint. 47 | ENTRYPOINT ["/usr/local/bin/chimera"] 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2020 Michael Koval, Pras Velagapudi, and Jeongseok Lee 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 met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /bindings/binding.cpp.tmpl: -------------------------------------------------------------------------------- 1 | // This file was autogenerated by the Chimera build. 2 | 3 | // Include binding definitions for each built-in language. 4 | @BINDING_INCLUDES_LIST@ 5 | 6 | // Set the default binding. 7 | std::string chimera::binding::DEFAULT_NAME = "boost_python"; 8 | 9 | // Create initialized map for all built-in bindings. 10 | std::map chimera::binding::DEFINITIONS { 11 | @BINDING_REGISTRATIONS_LIST@ 12 | }; 13 | -------------------------------------------------------------------------------- /bindings/boost_python/class.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{class.mangled_name}}(); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /bindings/boost_python/enum.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{enum.mangled_name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{enum.mangled_name}}() 14 | { 15 | {{precontent}} 16 | 17 | {{#enum.scope?}}{{! 18 | }}::boost::python::object parent_object(::boost::python::scope(){{! 19 | }}{{#enum.scope}}{{#name}}.attr("{{name}}"){{/name}}{{/enum.scope}}); 20 | ::boost::python::scope parent_scope(parent_object); 21 | {{/enum.scope?}} 22 | 23 | ::boost::python::enum_<{{enum.type}}>("{{enum.name}}"){{#enum.values}} 24 | .value("{{name}}", {{qualified_name}}){{/enum.values}} 25 | ; 26 | 27 | {{postcontent}} 28 | } 29 | {{footer}} 30 | -------------------------------------------------------------------------------- /bindings/boost_python/enum.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{enum.mangled_name}}(); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /bindings/boost_python/function.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{function.mangled_name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | namespace { 14 | 15 | {{#function.comment?}}{{! 16 | }}constexpr char {{function.mangled_name}}_docstring[] = R"CHIMERA_STRING({{! 17 | }}{{#function.comment}}{{! 18 | }}{{.}} 19 | {{/function.comment}}{{! 20 | }})CHIMERA_STRING"; 21 | {{/function.comment?}} 22 | 23 | } // namespace 24 | 25 | void {{function.mangled_name}}() 26 | { 27 | {{precontent}} 28 | 29 | {{#function.scope?}}{{! 30 | }}::boost::python::object parent_object(::boost::python::scope(){{! 31 | }}{{#function.scope}}.attr("{{name}}"){{/function.scope}}); 32 | ::boost::python::scope parent_scope(parent_object); 33 | {{/function.scope?}} 34 | 35 | {{#function.overloads}}{{! 36 | }} ::boost::python::def("{{name}}", +[]({{#params}}{{type}} {{name}}{{^__last__}}, {{/__last__}}{{/params}}){{! 37 | }}{{#is_void}} { {{/is_void}}{{! 38 | }}{{^is_void}} -> {{return_type}} { return {{/is_void}}{{! 39 | }}{{qualified_call}}({{#params}}{{name}}{{^__last__}}, {{/__last__}}{{/params}}); }{{! 40 | }}{{#comment?}}, {{function.mangled_name}}_docstring{{/comment?}}{{! 41 | }}{{#return_value_policy}}, ::boost::python::return_value_policy<::boost::python::{{.}} >(){{/return_value_policy}}{{! 42 | }}{{#params?}}, ({{#params}}::boost::python::arg("{{name}}"){{^__last__}}, {{/__last__}}{{/params}}){{/params?}}); 43 | {{/function.overloads}} 44 | 45 | {{postcontent}} 46 | } 47 | {{footer}} 48 | -------------------------------------------------------------------------------- /bindings/boost_python/function.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{function.mangled_name}}(); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /bindings/boost_python/module.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{module.name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | {{#module.bindings}} 13 | void {{.}}(); 14 | {{/module.bindings}} 15 | 16 | BOOST_PYTHON_MODULE({{module.name}}) 17 | { 18 | {{precontent}} 19 | 20 | ::boost::python::docstring_options options(true, true, false); 21 | 22 | ::boost::python::scope().attr("__doc__") = "{{doc}}"; 23 | ::boost::python::scope().attr("__version__") = "{{version}}"; 24 | 25 | {{#module.namespaces}}{{#name}} 26 | ::boost::python::scope(){{! 27 | }}{{#scope}}{{#name}}.attr("{{name}}"){{/name}}{{/scope}}.attr("{{name}}") = {{! 28 | }}::boost::python::object(::boost::python::handle<>({{! 29 | }}::boost::python::borrowed(::PyImport_AddModule({{! 30 | }}"{{module.name}}{{#scope}}{{#name}}.{{name}}{{/name}}{{/scope}}.{{name}}")))); 31 | {{/name}}{{/module.namespaces}} 32 | 33 | {{#module.bindings}} 34 | {{.}}(); 35 | {{/module.bindings}} 36 | 37 | {{postcontent}} 38 | } 39 | {{footer}} 40 | -------------------------------------------------------------------------------- /bindings/boost_python/module.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | {{footer}} 14 | -------------------------------------------------------------------------------- /bindings/boost_python/typedef.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{typedef.mangled_name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{typedef.mangled_name}}() 14 | { 15 | {{precontent}} 16 | 17 | ::boost::python::scope(::boost::python::scope(){{! 18 | }}{{#typedef.scope}}{{#name}}.attr("{{name}}"){{/name}}{{/typedef.scope}}).attr("{{typedef.name}}") = {{! 19 | }}{{^typedef.is_builtin_type}}::boost::python::scope(){{#typedef.underlying_class.scope}}{{#name}}.attr("{{name}}"){{/name}}{{/typedef.underlying_class.scope}}.attr("{{typedef.underlying_class.name}}"){{/typedef.is_builtin_type}}{{! 20 | }}{{#typedef.is_builtin_type}}::boost::python::import("__main__").attr("__builtins__").attr("{{typedef.underlying_type}}"){{/typedef.is_builtin_type}}{{! 21 | }}; 22 | 23 | {{postcontent}} 24 | } 25 | {{footer}} 26 | -------------------------------------------------------------------------------- /bindings/boost_python/typedef.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{typedef.mangled_name}}(); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /bindings/boost_python/variable.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{variable.mangled_name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{variable.mangled_name}}() 14 | { 15 | {{precontent}} 16 | 17 | {{#variable.scope?}}{{! 18 | }}::boost::python::object parent_object(::boost::python::scope(){{! 19 | }}{{#variable.scope}}{{#name}}.attr("{{name}}"){{/name}}{{/variable.scope}}); 20 | ::boost::python::scope parent_scope(parent_object); 21 | {{/variable.scope?}} 22 | 23 | ::boost::python::scope().attr("{{variable.name}}") = {{variable.qualified_name}}; 24 | 25 | {{postcontent}} 26 | } 27 | {{footer}} 28 | -------------------------------------------------------------------------------- /bindings/boost_python/variable.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{variable.mangled_name}}(); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /bindings/pybind11/enum.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{enum.mangled_name}}.h" 2 | 3 | {{{header}}} 4 | {{#includes}} 5 | #include <{{{.}}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{enum.mangled_name}}(pybind11::module& m) 14 | { 15 | {{{precontent}}} 16 | 17 | auto sm = m{{! 18 | }}{{#enum.namespace_scope}}{{#name}}.def_submodule("{{name}}"){{/name}}{{/enum.namespace_scope}}; 19 | 20 | auto attr = sm{{! 21 | }}{{#enum.class_scope}}{{#name}}.attr("{{name}}"){{/name}}{{/enum.class_scope}}; 22 | 23 | ::pybind11::enum_<{{{enum.type}}}>(attr, "{{enum.name}}"){{#enum.values}} 24 | .value("{{name}}", {{{qualified_name}}}){{/enum.values}} 25 | .export_values(); 26 | 27 | {{{postcontent}}} 28 | } 29 | {{{footer}}} 30 | -------------------------------------------------------------------------------- /bindings/pybind11/enum.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{{header}}} 4 | {{#includes}} 5 | #include <{{{.}}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{enum.mangled_name}}(pybind11::module& m); 14 | {{{footer}}} 15 | -------------------------------------------------------------------------------- /bindings/pybind11/function.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{function.mangled_name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | namespace { 14 | 15 | {{#function.comment?}}{{! 16 | }}constexpr char {{function.mangled_name}}_docstring[] = R"CHIMERA_STRING({{! 17 | }}{{#function.comment}}{{! 18 | }}{{.}} 19 | {{/function.comment}}{{! 20 | }})CHIMERA_STRING"; 21 | {{/function.comment?}} 22 | 23 | } // namespace 24 | 25 | void {{function.mangled_name}}(pybind11::module& m) 26 | { 27 | {{precontent}} 28 | 29 | auto sm = m{{! 30 | }}{{#function.namespace_scope}}{{#name}}.def_submodule("{{name}}"){{/name}}{{/function.namespace_scope}}; 31 | 32 | auto attr = sm{{! 33 | }}{{#function.class_scope}}{{#name}}.attr("{{name}}"){{/name}}{{/function.class_scope}}; 34 | 35 | {{#function.overloads}}{{! 36 | }} attr.def("{{name}}", +[]({{#params}}{{type}} {{name}}{{^__last__}}, {{/__last__}}{{/params}}){{! 37 | }}{{#is_void}} { {{/is_void}}{{! 38 | }}{{^is_void}} -> {{return_type}} { return {{/is_void}}{{! 39 | }}{{qualified_call}}({{#params}}{{name}}{{^__last__}}, {{/__last__}}{{/params}}); }{{! 40 | }}{{#comment?}}, {{function.mangled_name}}_docstring{{/comment?}}{{! 41 | }}{{#return_value_policy}}, ::pybind11::return_value_policy<{{.}} >(){{/return_value_policy}}{{! 42 | }}{{#params?}}, {{#params}}::pybind11::arg("{{name}}"){{^__last__}}, {{/__last__}}{{/params}}{{/params?}}); 43 | {{/function.overloads}} 44 | 45 | {{postcontent}} 46 | } 47 | {{footer}} 48 | -------------------------------------------------------------------------------- /bindings/pybind11/function.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{function.mangled_name}}(::pybind11::module& m); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /bindings/pybind11/module.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{module.name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | {{#module.bindings}} 13 | void {{.}}(pybind11::module& m); 14 | {{/module.bindings}} 15 | 16 | PYBIND11_MODULE({{module.name}}, m) 17 | { 18 | {{precontent}} 19 | 20 | m.doc() = "{{doc}}"; 21 | m.attr("__version__") = "{{version}}"; 22 | 23 | {{#module.bindings}} 24 | {{.}}(m); 25 | {{/module.bindings}} 26 | 27 | {{postcontent}} 28 | } 29 | {{footer}} 30 | -------------------------------------------------------------------------------- /bindings/pybind11/module.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | {{footer}} 14 | -------------------------------------------------------------------------------- /bindings/pybind11/typedef.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{typedef.mangled_name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{typedef.mangled_name}}(::pybind11::module& m) 14 | { 15 | {{precontent}} 16 | 17 | auto sm = m{{! 18 | }}{{#typedef.namespace_scope}}{{#name}}.def_submodule("{{name}}"){{/name}}{{/typedef.namespace_scope}}; 19 | 20 | auto attr = sm{{! 21 | }}{{#typedef.class_scope}}{{#name}}.attr("{{name}}"){{/name}}{{/typedef.class_scope}}; 22 | 23 | attr.attr("{{typedef.name}}") = {{! 24 | }}{{^typedef.is_builtin_type}}{{#typedef.underlying_class}}m{{#namespace_scope}}{{#name}}.attr("{{name}}"){{/name}}{{/namespace_scope}}{{#class_scope}}{{#name}}.def_submodule("{{name}}"){{/name}}{{/class_scope}}.attr("{{name}}{{/typedef.underlying_class}}{{/typedef.is_builtin_type}}{{! 25 | }}{{#typedef.is_builtin_type}}::pybind11::module::import("__main__").attr("__builtins__").attr("{{typedef.underlying_type}}{{/typedef.is_builtin_type}}{{! 26 | }}"); 27 | 28 | {{postcontent}} 29 | } 30 | {{footer}} 31 | -------------------------------------------------------------------------------- /bindings/pybind11/typedef.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{typedef.mangled_name}}(::pybind11::module& m); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /bindings/pybind11/variable.cpp.tmpl: -------------------------------------------------------------------------------- 1 | #include "{{variable.mangled_name}}.h" 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{variable.mangled_name}}(::pybind11::module& m) 14 | { 15 | {{precontent}} 16 | 17 | auto sm = m{{! 18 | }}{{#variable.namespace_scope}}{{#name}}.def_submodule("{{name}}"){{/name}}{{/variable.namespace_scope}}; 19 | 20 | auto attr = sm{{! 21 | }}{{#variable.class_scope}}{{#name}}.attr("{{name}}"){{/name}}{{/variable.class_scope}}; 22 | 23 | attr.attr("{{variable.name}}") = {{variable.qualified_name}}; 24 | 25 | {{postcontent}} 26 | } 27 | {{footer}} 28 | -------------------------------------------------------------------------------- /bindings/pybind11/variable.h.tmpl: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | {{header}} 4 | {{#includes}} 5 | #include <{{.}}> 6 | {{/includes}} 7 | {{#sources}} 8 | #include <{{.}}> 9 | {{/sources}} 10 | #include 11 | {{postinclude}} 12 | 13 | void {{variable.mangled_name}}(::pybind11::module& m); 14 | {{footer}} 15 | -------------------------------------------------------------------------------- /cmake/FindYamlCpp.cmake: -------------------------------------------------------------------------------- 1 | # Locate yaml-cpp 2 | # 3 | # This module defines 4 | # YAMLCPP_FOUND - System has yaml-cpp 5 | # YAMLCPP_INCLUDE_DIRS - The yaml-cpp include directories 6 | # YAMLCPP_LIBRARIES - The libraries needed to use yaml-cpp 7 | # YAMLCPP_DEFINITIONS - Compiler switches required for using yaml-cpp 8 | # 9 | # By default, the dynamic libraries of yaml-cpp will be found. To find the 10 | # static ones instead, set the YAMLCPP_STATIC_LIBRARY variable to TRUE before 11 | # calling find_package(YamlCpp ...). 12 | # 13 | # If yaml-cpp is not installed in a standard path, you can use the YAMLCPP_DIR 14 | # CMake variable to tell CMake where yaml-cpp is. 15 | 16 | # Attempt to find static library first if this is set 17 | if(YAMLCPP_STATIC_LIBRARY) 18 | set(YAMLCPP_STATIC libyaml-cpp.a) 19 | endif() 20 | 21 | # Set up pkg-config to find yaml-cpp. 22 | find_package(PkgConfig) 23 | pkg_check_modules(PC_YAMLCPP QUIET yaml-cpp) 24 | set(YAMLCPP_DEFINITIONS ${PC_YAMLCPP_CFLAGS_OTHER}) 25 | 26 | # Find the yaml-cpp include directory. 27 | find_path(YAMLCPP_INCLUDE_DIR yaml-cpp/yaml.h 28 | HINTS ${PC_YAMLCPP_INCLUDEDIR} ${PC_YAMLCPP_INCLUDE_DIRS} 29 | PATHS ${YAMLCPP_DIR}/include/ 30 | PATH_SUFFIXES include) 31 | 32 | # Find the yaml-cpp library. 33 | find_library(YAMLCPP_LIBRARY NAMES ${YAMLCPP_STATIC} yaml-cpp 34 | HINTS ${PC_YAMLCPP_LIBDIR} ${PC_YAMLCPP_LIBRARY_DIRS} 35 | PATHS ${YAMLCPP_DIR}/lib/ 36 | PATH_SUFFIXES lib64 lib) 37 | 38 | set(YAMLCPP_LIBRARIES ${YAMLCPP_LIBRARY}) 39 | set(YAMLCPP_INCLUDE_DIRS ${YAMLCPP_INCLUDE_DIR}) 40 | 41 | # Handle the QUIETLY and REQUIRED arguments and set YAMLCPP_FOUND to TRUE 42 | # if all listed variables are TRUE. 43 | include(FindPackageHandleStandardArgs) 44 | find_package_handle_standard_args(YAMLCPP DEFAULT_MSG 45 | YAMLCPP_INCLUDE_DIR YAMLCPP_LIBRARY) 46 | mark_as_advanced(YAMLCPP_INCLUDE_DIR YAMLCPP_LIBRARY) 47 | -------------------------------------------------------------------------------- /cmake/chimeraConfig.cmake.in: -------------------------------------------------------------------------------- 1 | set(chimera_VERSION x.y.z) 2 | 3 | @PACKAGE_INIT@ 4 | 5 | include("${CMAKE_CURRENT_LIST_DIR}/chimeraTargets.cmake") 6 | 7 | get_target_property(chimera_EXECUTABLE chimera LOCATION) 8 | 9 | set_and_check(chimera_C_COMPILER "@CMAKE_C_COMPILER@") 10 | set_and_check(chimera_CXX_COMPILER "@CMAKE_CXX_COMPILER@") 11 | 12 | include("${CMAKE_CURRENT_LIST_DIR}/chimeraFunctions.cmake") 13 | -------------------------------------------------------------------------------- /cmake/chimeraFindLLVM.cmake: -------------------------------------------------------------------------------- 1 | if(NOT APPLE) 2 | 3 | # We don't need anything special to find LLVM on Linux 4 | find_package(LLVM REQUIRED CONFIG) 5 | 6 | else() 7 | 8 | # Find LLVM without LLVM_DIR 9 | find_package(LLVM QUIET) 10 | 11 | if(NOT LLVM_FOUND) 12 | # Set LLVM_DIR using Homebrew 13 | find_program(BREW_EXECUTABLE brew) 14 | if(NOT BREW_EXECUTABLE) 15 | message(FATAL_ERROR "Failed to find LLVM. Chimera now would like to find \ 16 | LLVM using Homebrew, but it's not installed. Please install Homebrew \ 17 | and install LLVM using Homebrew for building Chimera." 18 | ) 19 | endif() 20 | execute_process(COMMAND 21 | ${BREW_EXECUTABLE} --prefix llvm 22 | OUTPUT_VARIABLE LLVM_PREFIX 23 | ) 24 | string(REGEX REPLACE "\n$" "" LLVM_PREFIX "${LLVM_PREFIX}") 25 | set(LLVM_DIR "${LLVM_PREFIX}/lib/cmake/llvm") 26 | 27 | # Find LLVM with LLVM_DIR 28 | find_package(LLVM REQUIRED CONFIG) 29 | endif() 30 | 31 | endif() 32 | 33 | # Check if LLVM is compatible with Chimera 34 | # 35 | # Note that LLVM >= 7 causes memory leaks in chimera::util::resolveDeclaration() 36 | # See https://github.com/personalrobotics/chimera/issues/222 37 | set(COMPATIBLE_LLVM_VERSIONS 6.0 7.0 8.0 9.0) 38 | set(LLVM_VERSION_MAJOR_MINOR ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}) 39 | set(FOUND_COMPATIBLE_LLVM FALSE) 40 | foreach(version ${COMPATIBLE_LLVM_VERSIONS}) 41 | if (${LLVM_VERSION_MAJOR_MINOR} VERSION_EQUAL ${version}) 42 | set(FOUND_COMPATIBLE_LLVM TRUE) 43 | break() 44 | endif() 45 | endforeach() 46 | if(NOT FOUND_COMPATIBLE_LLVM) 47 | message(FATAL_ERROR "Found LLVM ${LLVM_VERSION}, but it's not compatible \ 48 | with Chimera. Please build Chimera with one of following LLVM \ 49 | versions: ${COMPATIBLE_LLVM_VERSIONS}" 50 | ) 51 | endif() 52 | -------------------------------------------------------------------------------- /cmake/generateChimeraBinding.cmake: -------------------------------------------------------------------------------- 1 | # Run a CMake script which loads bindings and assembles them into a header. 2 | # 3 | # Requires the following CMake environment variables to be set: 4 | # BINDING_PATH - Path to .tmpl files for each CXX type. 5 | # BINDING_TEMPLATE - Path to .tmpl file defining the output header. 6 | # BINDING_OUTPUT - Path to output header that will be generated. 7 | 8 | # Load variables which will be used in binding template. 9 | file(READ "${BINDING_PATH}/class.h.tmpl" BINDING_CLASS_H) 10 | file(READ "${BINDING_PATH}/class.cpp.tmpl" BINDING_CLASS_CPP) 11 | file(READ "${BINDING_PATH}/enum.h.tmpl" BINDING_ENUM_H) 12 | file(READ "${BINDING_PATH}/enum.cpp.tmpl" BINDING_ENUM_CPP) 13 | file(READ "${BINDING_PATH}/function.h.tmpl" BINDING_FUNCTION_H) 14 | file(READ "${BINDING_PATH}/function.cpp.tmpl" BINDING_FUNCTION_CPP) 15 | file(READ "${BINDING_PATH}/variable.h.tmpl" BINDING_VARIABLE_H) 16 | file(READ "${BINDING_PATH}/variable.cpp.tmpl" BINDING_VARIABLE_CPP) 17 | file(READ "${BINDING_PATH}/typedef.h.tmpl" BINDING_TYPEDEF_H) 18 | file(READ "${BINDING_PATH}/typedef.cpp.tmpl" BINDING_TYPEDEF_CPP) 19 | file(READ "${BINDING_PATH}/module.h.tmpl" BINDING_MODULE_H) 20 | file(READ "${BINDING_PATH}/module.cpp.tmpl" BINDING_MODULE_CPP) 21 | 22 | # Uses a binding template to assemble the above files into a header. 23 | configure_file("${BINDING_TEMPLATE}" "${BINDING_OUTPUT}" 24 | @ONLY NEWLINE_STYLE UNIX 25 | ) 26 | -------------------------------------------------------------------------------- /external/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Build a small subcomponent of cling using a custom `CMakeLists.txt`. 2 | # This `CMakeLists.txt` has no install step so we can directly include it. 3 | add_subdirectory(cling) 4 | 5 | # Build mstch as *only* a static library for linking into chimera. 6 | # Uses ExternalProject to prevent install steps from propagating to chimera. 7 | include(ExternalProject) 8 | ExternalProject_Add(mstch_EXTERNAL 9 | SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mstch" 10 | DOWNLOAD_COMMAND "" 11 | INSTALL_COMMAND "" 12 | CMAKE_GENERATOR "${CMAKE_GENERATOR}" 13 | ) 14 | 15 | # Retrieve properties of the ExternalProject to find build artifacts. 16 | ExternalProject_Get_Property(mstch_EXTERNAL SOURCE_DIR BINARY_DIR) 17 | set(mstch_INCLUDE_DIR "${SOURCE_DIR}/include") 18 | set(mstch_LIBRARY "${BINARY_DIR}/src/${CMAKE_STATIC_LIBRARY_PREFIX}mstch${CMAKE_STATIC_LIBRARY_SUFFIX}") 19 | 20 | # Create an IMPORTED target so that CMake can propagate the build properties of 21 | # this ExternalProject to dependent targets. 22 | # (Note: This target must be GLOBAL as per: http://stackoverflow.com/a/26315239) 23 | add_library(mstch STATIC IMPORTED GLOBAL) 24 | add_dependencies(mstch mstch_EXTERNAL) 25 | set_target_properties(mstch PROPERTIES 26 | INTERFACE_INCLUDE_DIRECTORIES "${mstch_INCLUDE_DIR}" 27 | IMPORTED_LOCATION "${mstch_LIBRARY}" 28 | ) 29 | -------------------------------------------------------------------------------- /external/cling/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Compile a small subset of cling::utils. 2 | add_library(cling_utils STATIC 3 | src/cling_utils_AST.cpp 4 | ) 5 | 6 | target_compile_options(cling_utils 7 | PUBLIC "-std=c++11" 8 | ) 9 | 10 | target_link_libraries(cling_utils 11 | ${CLANG_LIBS} 12 | ${llvm_libs} 13 | ) 14 | 15 | target_include_directories(cling_utils 16 | PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" 17 | ) 18 | -------------------------------------------------------------------------------- /external/mstch/.appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - GENERATOR: "Visual Studio 12 2013" 4 | CONFIG: Release 5 | BOOST_ROOT: "C:\\Libraries\\boost" 6 | BOOST_LIBRARYDIR: "C:\\Libraries\\boost\\lib32-msvc-12.0" 7 | 8 | - GENERATOR: "Visual Studio 14 2015" 9 | CONFIG: Release 10 | BOOST_ROOT: "C:\\Libraries\\boost_1_59_0" 11 | BOOST_LIBRARYDIR: "C:\\Libraries\\boost_1_59_0\\lib32-msvc-14.0" 12 | 13 | - GENERATOR: "Visual Studio 14 2015 Win64" 14 | CONFIG: Release 15 | BOOST_ROOT: "C:\\Libraries\\boost_1_59_0" 16 | BOOST_LIBRARYDIR: "C:\\Libraries\\boost_1_59_0\\lib64-msvc-14.0" 17 | 18 | - GENERATOR: "Visual Studio 12 2013" 19 | CONFIG: Debug 20 | BOOST_ROOT: "C:\\Libraries\\boost" 21 | BOOST_LIBRARYDIR: "C:\\Libraries\\boost\\lib32-msvc-12.0" 22 | 23 | - GENERATOR: "Visual Studio 14 2015" 24 | CONFIG: Debug 25 | BOOST_ROOT: "C:\\Libraries\\boost_1_59_0" 26 | BOOST_LIBRARYDIR: "C:\\Libraries\\boost_1_59_0\\lib32-msvc-14.0" 27 | 28 | - GENERATOR: "Visual Studio 14 2015 Win64" 29 | CONFIG: Debug 30 | BOOST_ROOT: "C:\\Libraries\\boost_1_59_0" 31 | BOOST_LIBRARYDIR: "C:\\Libraries\\boost_1_59_0\\lib64-msvc-14.0" 32 | 33 | install: 34 | - git submodule init 35 | - git submodule update 36 | 37 | build_script: 38 | - mkdir build 39 | - cd build 40 | - cmake "-G%GENERATOR%" -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" -DBoost_USE_STATIC_LIBS=ON -DWITH_UNIT_TESTS=ON .. 41 | - cmake --build . --config "%CONFIG%" 42 | 43 | test_script: 44 | - ctest --build-config "%CONFIG%" 45 | -------------------------------------------------------------------------------- /external/mstch/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | build* 3 | -------------------------------------------------------------------------------- /external/mstch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(mstch) 3 | 4 | option(WITH_UNIT_TESTS "enable building unit test executable" OFF) 5 | option(WITH_BENCHMARK "enable building benchmark executable" OFF) 6 | 7 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 8 | set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) 9 | set(CMAKE_BUILD_TYPE Release) 10 | 11 | set(mstch_VERSION 1.0.1) 12 | 13 | if(NOT MSVC) 14 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -O3") 15 | endif() 16 | 17 | add_subdirectory(src) 18 | 19 | if(WITH_UNIT_TESTS) 20 | enable_testing() 21 | add_subdirectory(vendor/headerize) 22 | add_subdirectory(test) 23 | endif() 24 | 25 | if(WITH_BENCHMARK) 26 | add_subdirectory(vendor/benchmark) 27 | add_subdirectory(benchmark) 28 | endif() 29 | -------------------------------------------------------------------------------- /external/mstch/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Daniel Sipka 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 | 23 | -------------------------------------------------------------------------------- /external/mstch/benchmark/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories( 2 | ${CMAKE_SOURCE_DIR}/include 3 | ${CMAKE_SOURCE_DIR}/vendor/benchmark/include) 4 | 5 | add_executable(mstch_benchmark benchmark_main.cpp) 6 | target_link_libraries(mstch_benchmark mstch benchmark) 7 | -------------------------------------------------------------------------------- /external/mstch/benchmark/benchmark_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "mstch/mstch.hpp" 4 | 5 | static void basic_usage(benchmark::State& state) { 6 | std::string comment_tmp{ 7 | "

{{header}}

    " 8 | "{{#comments}}
  • {{name}}
    " 9 | "

    {{body}}

  • {{/comments}}
"}; 10 | 11 | auto comment_view = mstch::map{ 12 | {"header", std::string{"My Post Comments"}}, 13 | {"comments", mstch::array{ 14 | mstch::map{{"name", std::string{"Joe"}}, {"body", std::string{"Thanks for this post!"}}}, 15 | mstch::map{{"name", std::string{"Sam"}}, {"body", std::string{"Thanks for this post!"}}}, 16 | mstch::map{{"name", std::string{"Heather"}}, {"body", std::string{"Thanks for this post!"}}}, 17 | mstch::map{{"name", std::string{"Kathy"}}, {"body", std::string{"Thanks for this post!"}}}, 18 | mstch::map{{"name", std::string{"George"}}, {"body", std::string{"Thanks for this post!"}}}}}}; 19 | 20 | while (state.KeepRunning()) 21 | mstch::render(comment_tmp, comment_view); 22 | } 23 | 24 | BENCHMARK(basic_usage); 25 | 26 | BENCHMARK_MAIN(); 27 | -------------------------------------------------------------------------------- /external/mstch/cmake/mstch-config.cmake: -------------------------------------------------------------------------------- 1 | include("${CMAKE_CURRENT_LIST_DIR}/mstch-targets.cmake") -------------------------------------------------------------------------------- /external/mstch/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Boost 1.54 REQUIRED) 2 | 3 | set(mstch_INCLUDE_DIR 4 | ${PROJECT_SOURCE_DIR}/include CACHE STRING "mstch include directory") 5 | 6 | include_directories( 7 | ${mstch_INCLUDE_DIR} 8 | ${Boost_INCLUDE_DIR}) 9 | 10 | set(SRC 11 | state/in_section.cpp 12 | state/outside_section.cpp 13 | state/render_state.hpp 14 | visitor/get_token.hpp 15 | visitor/has_token.hpp 16 | visitor/is_node_empty.hpp 17 | visitor/render_node.hpp 18 | visitor/render_section.hpp 19 | mstch.cpp 20 | render_context.cpp 21 | template_type.cpp 22 | token.cpp 23 | utils.cpp) 24 | 25 | add_library(mstch STATIC ${SRC}) 26 | 27 | set_property(TARGET mstch PROPERTY VERSION ${mstch_VERSION}) 28 | 29 | install( 30 | TARGETS mstch EXPORT mstchTargets 31 | LIBRARY DESTINATION lib 32 | ARCHIVE DESTINATION lib) 33 | 34 | install( 35 | FILES "${PROJECT_SOURCE_DIR}/include/mstch/mstch.hpp" 36 | DESTINATION include/mstch 37 | COMPONENT Devel) 38 | 39 | include(CMakePackageConfigHelpers) 40 | write_basic_package_version_file( 41 | "${CMAKE_CURRENT_BINARY_DIR}/mstch/mstch-config-version.cmake" 42 | VERSION ${mstch_VERSION} 43 | COMPATIBILITY AnyNewerVersion) 44 | 45 | export( 46 | EXPORT mstchTargets 47 | FILE "${CMAKE_CURRENT_BINARY_DIR}/mstch/mstch-targets.cmake" 48 | NAMESPACE mstch::) 49 | 50 | configure_file( 51 | "${PROJECT_SOURCE_DIR}/cmake/mstch-config.cmake" 52 | "${CMAKE_CURRENT_BINARY_DIR}/mstch/mstch-config.cmake") 53 | 54 | install( 55 | EXPORT mstchTargets 56 | FILE mstch-targets.cmake 57 | NAMESPACE mstch:: 58 | DESTINATION lib/cmake/mstch) 59 | 60 | install(FILES 61 | "${PROJECT_SOURCE_DIR}/cmake/mstch-config.cmake" 62 | "${CMAKE_CURRENT_BINARY_DIR}/mstch/mstch-config-version.cmake" 63 | DESTINATION lib/cmake/mstch 64 | COMPONENT Devel) 65 | -------------------------------------------------------------------------------- /external/mstch/src/mstch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "mstch/mstch.hpp" 4 | #include "render_context.hpp" 5 | 6 | using namespace mstch; 7 | 8 | std::function mstch::config::escape; 9 | 10 | std::string mstch::render( 11 | const std::string& tmplt, 12 | const node& root, 13 | const std::map& partials) 14 | { 15 | std::map partial_templates; 16 | for (auto& partial: partials) 17 | partial_templates.insert({partial.first, {partial.second}}); 18 | 19 | return render_context(root, partial_templates).render(tmplt); 20 | } 21 | -------------------------------------------------------------------------------- /external/mstch/src/render_context.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "mstch/mstch.hpp" 10 | #include "state/render_state.hpp" 11 | #include "template_type.hpp" 12 | 13 | namespace mstch { 14 | 15 | class render_context { 16 | public: 17 | class push { 18 | public: 19 | push(render_context& context, const mstch::node& node = {}); 20 | ~push(); 21 | std::string render(const template_type& templt); 22 | private: 23 | render_context& m_context; 24 | }; 25 | 26 | render_context( 27 | const mstch::node& node, 28 | const std::map& partials); 29 | const mstch::node& get_node(const std::string& token); 30 | std::string render( 31 | const template_type& templt, const std::string& prefix = ""); 32 | std::string render_partial( 33 | const std::string& partial_name, const std::string& prefix); 34 | template 35 | void set_state(Args&& ... args) { 36 | m_state.top() = std::unique_ptr( 37 | new T(std::forward(args)...)); 38 | } 39 | 40 | private: 41 | static const mstch::node null_node; 42 | const mstch::node& find_node( 43 | const std::string& token, 44 | std::list current_nodes); 45 | std::map m_partials; 46 | std::deque m_nodes; 47 | std::list m_node_ptrs; 48 | std::stack> m_state; 49 | }; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /external/mstch/src/state/in_section.cpp: -------------------------------------------------------------------------------- 1 | #include "in_section.hpp" 2 | #include "outside_section.hpp" 3 | #include "visitor/is_node_empty.hpp" 4 | #include "visitor/render_section.hpp" 5 | 6 | using namespace mstch; 7 | 8 | in_section::in_section(type type, const token& start_token): 9 | m_type(type), m_start_token(start_token), m_skipped_openings(0) 10 | { 11 | } 12 | 13 | std::string in_section::render(render_context& ctx, const token& token) { 14 | if (token.token_type() == token::type::section_close) 15 | if (token.name() == m_start_token.name() && m_skipped_openings == 0) { 16 | auto& node = ctx.get_node(m_start_token.name()); 17 | std::string out; 18 | 19 | if (m_type == type::normal && !visit(is_node_empty(), node)) 20 | out = visit(render_section(ctx, m_section, m_start_token.delims()), node); 21 | else if (m_type == type::inverted && visit(is_node_empty(), node)) 22 | out = render_context::push(ctx).render(m_section); 23 | 24 | ctx.set_state(); 25 | return out; 26 | } else 27 | m_skipped_openings--; 28 | else if (token.token_type() == token::type::inverted_section_open || 29 | token.token_type() == token::type::section_open) 30 | m_skipped_openings++; 31 | 32 | m_section << token; 33 | return ""; 34 | } 35 | -------------------------------------------------------------------------------- /external/mstch/src/state/in_section.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "render_state.hpp" 7 | #include "template_type.hpp" 8 | 9 | namespace mstch { 10 | 11 | class in_section: public render_state { 12 | public: 13 | enum class type { inverted, normal }; 14 | in_section(type type, const token& start_token); 15 | std::string render(render_context& context, const token& token) override; 16 | 17 | private: 18 | const type m_type; 19 | const token& m_start_token; 20 | template_type m_section; 21 | int m_skipped_openings; 22 | }; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /external/mstch/src/state/outside_section.cpp: -------------------------------------------------------------------------------- 1 | #include "outside_section.hpp" 2 | 3 | #include "visitor/render_node.hpp" 4 | #include "in_section.hpp" 5 | #include "render_context.hpp" 6 | 7 | using namespace mstch; 8 | 9 | std::string outside_section::render( 10 | render_context& ctx, const token& token) 11 | { 12 | using flag = render_node::flag; 13 | switch (token.token_type()) { 14 | case token::type::section_open: 15 | ctx.set_state(in_section::type::normal, token); 16 | break; 17 | case token::type::inverted_section_open: 18 | ctx.set_state(in_section::type::inverted, token); 19 | break; 20 | case token::type::variable: 21 | return visit(render_node(ctx, flag::escape_html), ctx.get_node(token.name())); 22 | case token::type::unescaped_variable: 23 | return visit(render_node(ctx, flag::none), ctx.get_node(token.name())); 24 | case token::type::text: 25 | return token.raw(); 26 | case token::type::partial: 27 | return ctx.render_partial(token.name(), token.partial_prefix()); 28 | default: 29 | break; 30 | } 31 | return ""; 32 | } 33 | -------------------------------------------------------------------------------- /external/mstch/src/state/outside_section.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "render_state.hpp" 4 | 5 | namespace mstch { 6 | 7 | class outside_section: public render_state { 8 | public: 9 | std::string render(render_context& context, const token& token) override; 10 | }; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /external/mstch/src/state/render_state.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "token.hpp" 6 | 7 | namespace mstch { 8 | 9 | class render_context; 10 | 11 | class render_state { 12 | public: 13 | virtual ~render_state() {} 14 | virtual std::string render(render_context& context, const token& token) = 0; 15 | }; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /external/mstch/src/template_type.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "token.hpp" 7 | #include "utils.hpp" 8 | 9 | namespace mstch { 10 | 11 | class template_type { 12 | public: 13 | template_type() = default; 14 | template_type(const std::string& str); 15 | template_type(const std::string& str, const delim_type& delims); 16 | std::vector::const_iterator begin() const { return m_tokens.begin(); } 17 | std::vector::const_iterator end() const { return m_tokens.end(); } 18 | void operator<<(const token& token) { m_tokens.push_back(token); } 19 | 20 | private: 21 | std::vector m_tokens; 22 | std::string m_open; 23 | std::string m_close; 24 | void strip_whitespace(); 25 | void process_text(citer beg, citer end); 26 | void tokenize(const std::string& tmp); 27 | void store_prefixes(std::vector::iterator beg); 28 | }; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /external/mstch/src/token.cpp: -------------------------------------------------------------------------------- 1 | #include "token.hpp" 2 | #include "utils.hpp" 3 | 4 | using namespace mstch; 5 | 6 | token::type token::token_info(char c) { 7 | switch (c) { 8 | case '>': return type::partial; 9 | case '^': return type::inverted_section_open; 10 | case '/': return type::section_close; 11 | case '&': return type::unescaped_variable; 12 | case '#': return type::section_open; 13 | case '!': return type::comment; 14 | default: return type::variable; 15 | } 16 | } 17 | 18 | token::token(const std::string& str, std::size_t left, std::size_t right): 19 | m_raw(str), m_eol(false), m_ws_only(false) 20 | { 21 | if (left != 0 && right != 0) { 22 | if (str[left] == '=' && str[str.size() - right - 1] == '=') { 23 | m_type = type::delimiter_change; 24 | } else if (str[left] == '{' && str[str.size() - right - 1] == '}') { 25 | m_type = type::unescaped_variable; 26 | m_name = {first_not_ws(str.begin() + left + 1, str.end() - right), 27 | first_not_ws(str.rbegin() + 1 + right, str.rend() - left) + 1}; 28 | } else { 29 | auto c = first_not_ws(str.begin() + left, str.end() - right); 30 | m_type = token_info(*c); 31 | if (m_type != type::variable) 32 | c = first_not_ws(c + 1, str.end() - right); 33 | m_name = {c, first_not_ws(str.rbegin() + right, str.rend() - left) + 1}; 34 | m_delims = {{str.begin(), str.begin() + left}, 35 | {str.end() - right, str.end()}}; 36 | } 37 | } else { 38 | m_type = type::text; 39 | m_eol = (str.size() > 0 && str[str.size() - 1] == '\n'); 40 | m_ws_only = (str.find_first_not_of(" \r\n\t") == std::string::npos); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /external/mstch/src/token.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace mstch { 6 | 7 | using delim_type = std::pair; 8 | 9 | class token { 10 | public: 11 | enum class type { 12 | text, variable, section_open, section_close, inverted_section_open, 13 | unescaped_variable, comment, partial, delimiter_change 14 | }; 15 | token(const std::string& str, std::size_t left = 0, std::size_t right = 0); 16 | type token_type() const { return m_type; }; 17 | const std::string& raw() const { return m_raw; }; 18 | const std::string& name() const { return m_name; }; 19 | const std::string& partial_prefix() const { return m_partial_prefix; }; 20 | const delim_type& delims() const { return m_delims; }; 21 | void partial_prefix(const std::string& p_partial_prefix) { 22 | m_partial_prefix = p_partial_prefix; 23 | }; 24 | bool eol() const { return m_eol; } 25 | void eol(bool eol) { m_eol = eol; } 26 | bool ws_only() const { return m_ws_only; } 27 | 28 | private: 29 | type m_type; 30 | std::string m_name; 31 | std::string m_raw; 32 | std::string m_partial_prefix; 33 | delim_type m_delims; 34 | bool m_eol; 35 | bool m_ws_only; 36 | type token_info(char c); 37 | }; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /external/mstch/src/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.hpp" 2 | #include "mstch/mstch.hpp" 3 | 4 | mstch::citer mstch::first_not_ws(mstch::citer begin, mstch::citer end) { 5 | for (auto it = begin; it != end; ++it) 6 | if (*it != ' ') return it; 7 | return end; 8 | } 9 | 10 | mstch::citer mstch::first_not_ws(mstch::criter begin, mstch::criter end) { 11 | for (auto rit = begin; rit != end; ++rit) 12 | if (*rit != ' ') return --(rit.base()); 13 | return --(end.base()); 14 | } 15 | 16 | mstch::criter mstch::reverse(mstch::citer it) { 17 | return std::reverse_iterator(it); 18 | } 19 | 20 | std::string mstch::html_escape(const std::string& str) { 21 | if (mstch::config::escape) 22 | return mstch::config::escape(str); 23 | 24 | std::string out; 25 | citer start = str.begin(); 26 | 27 | auto add_escape = [&out, &start](const std::string& escaped, citer& it) { 28 | out += std::string{start, it} + escaped; 29 | start = it + 1; 30 | }; 31 | 32 | for (auto it = str.begin(); it != str.end(); ++it) 33 | switch (*it) { 34 | case '&': add_escape("&", it); break; 35 | case '\'': add_escape("'", it); break; 36 | case '"': add_escape(""", it); break; 37 | case '<': add_escape("<", it); break; 38 | case '>': add_escape(">", it); break; 39 | case '/': add_escape("/", it); break; 40 | default: break; 41 | } 42 | 43 | return out + std::string{start, str.end()}; 44 | } 45 | -------------------------------------------------------------------------------- /external/mstch/src/utils.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace mstch { 7 | 8 | using citer = std::string::const_iterator; 9 | using criter = std::string::const_reverse_iterator; 10 | 11 | citer first_not_ws(citer begin, citer end); 12 | citer first_not_ws(criter begin, criter end); 13 | std::string html_escape(const std::string& str); 14 | criter reverse(citer it); 15 | 16 | template 17 | auto visit(Args&&... args) -> decltype(boost::apply_visitor( 18 | std::forward(args)...)) 19 | { 20 | return boost::apply_visitor(std::forward(args)...); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /external/mstch/src/visitor/get_token.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "mstch/mstch.hpp" 6 | #include "has_token.hpp" 7 | 8 | namespace mstch { 9 | 10 | class get_token: public boost::static_visitor { 11 | public: 12 | get_token(const std::string& token, const mstch::node& node): 13 | m_token(token), m_node(node) 14 | { 15 | } 16 | 17 | template 18 | const mstch::node& operator()(const T&) const { 19 | return m_node; 20 | } 21 | 22 | const mstch::node& operator()(const map& map) const { 23 | return map.at(m_token); 24 | } 25 | 26 | const mstch::node& operator()(const std::shared_ptr& object) const { 27 | return object->at(m_token); 28 | } 29 | 30 | private: 31 | const std::string& m_token; 32 | const mstch::node& m_node; 33 | }; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /external/mstch/src/visitor/has_token.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "mstch/mstch.hpp" 6 | 7 | namespace mstch { 8 | 9 | class has_token: public boost::static_visitor { 10 | public: 11 | has_token(const std::string& token): m_token(token) { 12 | } 13 | 14 | template 15 | bool operator()(const T&) const { 16 | return m_token == "."; 17 | } 18 | 19 | bool operator()(const map& map) const { 20 | return map.count(m_token) == 1; 21 | } 22 | 23 | bool operator()(const std::shared_ptr& object) const { 24 | return object->has(m_token); 25 | } 26 | 27 | private: 28 | const std::string& m_token; 29 | }; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /external/mstch/src/visitor/is_node_empty.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "mstch/mstch.hpp" 6 | 7 | namespace mstch { 8 | 9 | class is_node_empty: public boost::static_visitor { 10 | public: 11 | template 12 | bool operator()(const T&) const { 13 | return false; 14 | } 15 | 16 | bool operator()(const std::nullptr_t&) const { 17 | return true; 18 | } 19 | 20 | bool operator()(const int& value) const { 21 | return value == 0; 22 | } 23 | 24 | bool operator()(const double& value) const { 25 | return value == 0; 26 | } 27 | 28 | bool operator()(const bool& value) const { 29 | return !value; 30 | } 31 | 32 | bool operator()(const std::string& value) const { 33 | return value == ""; 34 | } 35 | 36 | bool operator()(const array& array) const { 37 | return array.size() == 0; 38 | } 39 | }; 40 | 41 | } 42 | -------------------------------------------------------------------------------- /external/mstch/src/visitor/render_node.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "render_context.hpp" 7 | #include "mstch/mstch.hpp" 8 | #include "utils.hpp" 9 | 10 | namespace mstch { 11 | 12 | class render_node: public boost::static_visitor { 13 | public: 14 | enum class flag { none, escape_html }; 15 | render_node(render_context& ctx, flag p_flag = flag::none): 16 | m_ctx(ctx), m_flag(p_flag) 17 | { 18 | } 19 | 20 | template 21 | std::string operator()(const T&) const { 22 | return ""; 23 | } 24 | 25 | std::string operator()(const int& value) const { 26 | return std::to_string(value); 27 | } 28 | 29 | std::string operator()(const double& value) const { 30 | std::stringstream ss; 31 | ss << value; 32 | return ss.str(); 33 | } 34 | 35 | std::string operator()(const bool& value) const { 36 | return value ? "true" : "false"; 37 | } 38 | 39 | std::string operator()(const lambda& value) const { 40 | template_type interpreted{value([this](const mstch::node& n) { 41 | return visit(render_node(m_ctx), n); 42 | })}; 43 | auto rendered = render_context::push(m_ctx).render(interpreted); 44 | return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered; 45 | } 46 | 47 | std::string operator()(const std::string& value) const { 48 | return (m_flag == flag::escape_html) ? html_escape(value) : value; 49 | } 50 | 51 | private: 52 | render_context& m_ctx; 53 | flag m_flag; 54 | }; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /external/mstch/src/visitor/render_section.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "render_context.hpp" 6 | #include "mstch/mstch.hpp" 7 | #include "utils.hpp" 8 | #include "render_node.hpp" 9 | 10 | namespace mstch { 11 | 12 | class render_section: public boost::static_visitor { 13 | public: 14 | enum class flag { none, keep_array }; 15 | render_section( 16 | render_context& ctx, 17 | const template_type& section, 18 | const delim_type& delims, 19 | flag p_flag = flag::none): 20 | m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag) 21 | { 22 | } 23 | 24 | template 25 | std::string operator()(const T& t) const { 26 | return render_context::push(m_ctx, t).render(m_section); 27 | } 28 | 29 | std::string operator()(const lambda& fun) const { 30 | std::string section_str; 31 | for (auto& token: m_section) 32 | section_str += token.raw(); 33 | template_type interpreted{fun([this](const mstch::node& n) { 34 | return visit(render_node(m_ctx), n); 35 | }, section_str), m_delims}; 36 | return render_context::push(m_ctx).render(interpreted); 37 | } 38 | 39 | std::string operator()(const array& array) const { 40 | std::string out; 41 | if (m_flag == flag::keep_array) 42 | return render_context::push(m_ctx, array).render(m_section); 43 | else 44 | for (auto& item: array) 45 | out += visit(render_section( 46 | m_ctx, m_section, m_delims, flag::keep_array), item); 47 | return out; 48 | } 49 | 50 | private: 51 | render_context& m_ctx; 52 | const template_type& m_section; 53 | const delim_type& m_delims; 54 | flag m_flag; 55 | }; 56 | 57 | } 58 | -------------------------------------------------------------------------------- /external/mstch/test/data/ampersand_escape.hpp: -------------------------------------------------------------------------------- 1 | const auto ampersand_escape_data = mstch::map{ 2 | {"message", std::string{"Some "}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/ampersand_escape.mustache: -------------------------------------------------------------------------------- 1 | {{&message}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/ampersand_escape.txt: -------------------------------------------------------------------------------- 1 | Some 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/apostrophe.hpp: -------------------------------------------------------------------------------- 1 | const auto apostrophe_data = mstch::map{ 2 | {"apos", std::string{"'"}}, 3 | {"control", std::string{"X"}} 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/apostrophe.mustache: -------------------------------------------------------------------------------- 1 | {{apos}}{{control}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/apostrophe.txt: -------------------------------------------------------------------------------- 1 | 'X 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/array_of_strings.hpp: -------------------------------------------------------------------------------- 1 | const auto array_of_strings_data = mstch::map{ 2 | {"array_of_strings", mstch::array{std::string{"hello"}, std::string{"world"}}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/array_of_strings.mustache: -------------------------------------------------------------------------------- 1 | {{#array_of_strings}}{{.}} {{/array_of_strings}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/array_of_strings.txt: -------------------------------------------------------------------------------- 1 | hello world 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/backslashes.hpp: -------------------------------------------------------------------------------- 1 | const auto backslashes_data = mstch::map{ 2 | {"value", std::string{"\\abc"}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/backslashes.mustache: -------------------------------------------------------------------------------- 1 | * {{value}} 2 | * {{{value}}} 3 | * {{&value}} 4 | 8 | -------------------------------------------------------------------------------- /external/mstch/test/data/backslashes.txt: -------------------------------------------------------------------------------- 1 | * \abc 2 | * \abc 3 | * \abc 4 | 8 | -------------------------------------------------------------------------------- /external/mstch/test/data/bug_11_eating_whitespace.hpp: -------------------------------------------------------------------------------- 1 | const auto bug_11_eating_whitespace_data = mstch::map{ 2 | {"tag", std::string{"yo"}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/bug_11_eating_whitespace.mustache: -------------------------------------------------------------------------------- 1 | {{tag}} foo 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/bug_11_eating_whitespace.txt: -------------------------------------------------------------------------------- 1 | yo foo 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/bug_length_property.hpp: -------------------------------------------------------------------------------- 1 | const auto bug_length_property_data = mstch::map{ 2 | {"length", std::string{"hello"}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/bug_length_property.mustache: -------------------------------------------------------------------------------- 1 | {{#length}}The length variable is: {{length}}{{/length}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/bug_length_property.txt: -------------------------------------------------------------------------------- 1 | The length variable is: hello 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/changing_delimiters.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node changing_delimiters_data = mstch::map{ 2 | {"foo", std::string{"foooooooooooooo"}}, 3 | {"bar", std::string{"bar!"}} 4 | }; 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/changing_delimiters.mustache: -------------------------------------------------------------------------------- 1 | {{=<% %>=}}<% foo %> {{foo}} <%{bar}%> {{{bar}}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/changing_delimiters.txt: -------------------------------------------------------------------------------- 1 | foooooooooooooo {{foo}} bar! {{{bar}}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/comments.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node comments_data = mstch::map{ 2 | {"title", mstch::lambda{[]()->mstch::node{return std::string{"A Comedy of Errors"};}}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/comments.mustache: -------------------------------------------------------------------------------- 1 |

{{title}}{{! just something interesting... or not... }}

2 | -------------------------------------------------------------------------------- /external/mstch/test/data/comments.txt: -------------------------------------------------------------------------------- 1 |

A Comedy of Errors

2 | -------------------------------------------------------------------------------- /external/mstch/test/data/complex.hpp: -------------------------------------------------------------------------------- 1 | class complex_item: public mstch::object { 2 | private: 3 | std::string m_name; 4 | bool m_current; 5 | std::string m_url; 6 | public: 7 | complex_item(const std::string& name, bool current, const std::string& url): 8 | m_name(name), m_current(current), m_url(url) 9 | { 10 | register_methods(this, std::map{ 11 | {"name", &complex_item::name}, {"current", &complex_item::current}, 12 | {"url", &complex_item::url}, {"link", &complex_item::link} 13 | }); 14 | } 15 | 16 | mstch::node current() { 17 | return m_current; 18 | } 19 | 20 | mstch::node url() { 21 | return m_url; 22 | } 23 | 24 | mstch::node name() { 25 | return m_name; 26 | } 27 | 28 | mstch::node link() { 29 | return !m_current; 30 | } 31 | }; 32 | 33 | class complex: public mstch::object { 34 | private: 35 | std::string m_header; 36 | mstch::array m_item; 37 | public: 38 | complex(): 39 | m_header("Colors"), 40 | m_item(mstch::array{ 41 | std::make_shared("red", true, "#Red"), 42 | std::make_shared("green", false, "#Green"), 43 | std::make_shared("blue", false, "#Blue") 44 | }) 45 | { 46 | register_methods(this, std::map{ 47 | {"header", &complex::header}, {"item", &complex::item}, 48 | {"list", &complex::list}, {"empty", &complex::empty} 49 | }); 50 | } 51 | 52 | mstch::node header() { 53 | return m_header; 54 | } 55 | 56 | mstch::node item() { 57 | return m_item; 58 | } 59 | 60 | mstch::node list() { 61 | return m_item.size() != 0; 62 | } 63 | 64 | mstch::node empty() { 65 | return m_item.size() == 0; 66 | } 67 | }; 68 | 69 | const auto complex_data = std::make_shared(); -------------------------------------------------------------------------------- /external/mstch/test/data/complex.mustache: -------------------------------------------------------------------------------- 1 |

{{header}}

2 | {{#list}} 3 |
    4 | {{#item}} 5 | {{#current}} 6 |
  • {{name}}
  • 7 | {{/current}} 8 | {{#link}} 9 |
  • {{name}}
  • 10 | {{/link}} 11 | {{/item}} 12 |
13 | {{/list}} 14 | {{#empty}} 15 |

The list is empty.

16 | {{/empty}} 17 | -------------------------------------------------------------------------------- /external/mstch/test/data/complex.txt: -------------------------------------------------------------------------------- 1 |

Colors

2 | 7 | -------------------------------------------------------------------------------- /external/mstch/test/data/context_lookup.hpp: -------------------------------------------------------------------------------- 1 | const auto context_lookup_data = mstch::map{ 2 | {"outer", mstch::map{ 3 | {"id", 1}, 4 | {"second", mstch::map{ 5 | {"nothing", 2} 6 | }} 7 | }} 8 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/context_lookup.mustache: -------------------------------------------------------------------------------- 1 | {{#outer}}{{#second}}{{id}}{{/second}}{{/outer}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/context_lookup.txt: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/delimiters.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node delimiters_data = mstch::map{ 2 | {"first", std::string{"It worked the first time."}}, 3 | {"second", std::string{"And it worked the second time."}}, 4 | {"third", std::string{"Then, surprisingly, it worked the third time."}}, 5 | {"fourth", std::string{"Fourth time also fine!."}} 6 | }; 7 | -------------------------------------------------------------------------------- /external/mstch/test/data/delimiters.mustache: -------------------------------------------------------------------------------- 1 | {{=<% %>=}}* 2 | <% first %> 3 | * <% second %> 4 | <%=| |=%> 5 | * | third | 6 | |={{ }}=| 7 | * {{ fourth }} 8 | -------------------------------------------------------------------------------- /external/mstch/test/data/delimiters.txt: -------------------------------------------------------------------------------- 1 | * 2 | It worked the first time. 3 | * And it worked the second time. 4 | * Then, surprisingly, it worked the third time. 5 | * Fourth time also fine!. 6 | -------------------------------------------------------------------------------- /external/mstch/test/data/disappearing_whitespace.hpp: -------------------------------------------------------------------------------- 1 | const auto disappearing_whitespace_data = mstch::map{ 2 | {"bedrooms", true}, 3 | {"total", 1} 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/disappearing_whitespace.mustache: -------------------------------------------------------------------------------- 1 | {{#bedrooms}}{{total}}{{/bedrooms}} BED 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/disappearing_whitespace.txt: -------------------------------------------------------------------------------- 1 | 1 BED 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/dot_notation.hpp: -------------------------------------------------------------------------------- 1 | class dot_notation_price: public mstch::object { 2 | private: 3 | int m_value; 4 | mstch::map m_currency; 5 | public: 6 | dot_notation_price(): 7 | m_value(200), m_currency(mstch::map{{"symbol", std::string{"$"}}, {"name", std::string{"USD"}}}) 8 | { 9 | register_methods(this, std::map{ 10 | {"value", &dot_notation_price::value}, 11 | {"vat", &dot_notation_price::vat}, 12 | {"currency", &dot_notation_price::currency}}); 13 | } 14 | 15 | mstch::node value() { 16 | return m_value; 17 | } 18 | 19 | mstch::node vat() { 20 | return m_value * 0.2; 21 | } 22 | 23 | mstch::node currency() { 24 | return m_currency; 25 | } 26 | }; 27 | 28 | const auto dot_notation_data = mstch::map{ 29 | {"name", std::string{"A Book"}}, 30 | {"authors", mstch::array{std::string{"John Power"}, std::string{"Jamie Walsh"}}}, 31 | {"price", std::make_shared()}, 32 | {"availability", mstch::map{{"status", true}, {"text", std::string{"In Stock"}}}}, 33 | {"truthy", mstch::map{{"zero", 0}, {"notTrue", false}}} 34 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/dot_notation.mustache: -------------------------------------------------------------------------------- 1 | 2 |

{{name}}

3 |

Authors:

    {{#authors}}
  • {{.}}
  • {{/authors}}

4 |

Price: {{{price.currency.symbol}}}{{price.value}} {{#price.currency}}{{name}} {{availability.text}}{{/price.currency}}

5 |

VAT: {{{price.currency.symbol}}}{{#price}}{{vat}}{{/price}}

6 | 7 |

Test truthy false values:

8 |

Zero: {{truthy.zero}}

9 |

False: {{truthy.notTrue}}

10 | -------------------------------------------------------------------------------- /external/mstch/test/data/dot_notation.txt: -------------------------------------------------------------------------------- 1 | 2 |

A Book

3 |

Authors:

  • John Power
  • Jamie Walsh

4 |

Price: $200 USD In Stock

5 |

VAT: $40

6 | 7 |

Test truthy false values:

8 |

Zero: 0

9 |

False: false

10 | -------------------------------------------------------------------------------- /external/mstch/test/data/double_render.hpp: -------------------------------------------------------------------------------- 1 | const auto double_render_data = mstch::map{ 2 | {"foo", true}, 3 | {"bar", std::string{"{{win}}"}}, 4 | {"win", std::string{"FAIL"}} 5 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/double_render.mustache: -------------------------------------------------------------------------------- 1 | {{#foo}}{{bar}}{{/foo}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/double_render.txt: -------------------------------------------------------------------------------- 1 | {{win}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/empty_list.hpp: -------------------------------------------------------------------------------- 1 | const auto empty_list_data = mstch::map{ 2 | {"jobs", mstch::array{}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/empty_list.mustache: -------------------------------------------------------------------------------- 1 | These are the jobs: 2 | {{#jobs}} 3 | {{.}} 4 | {{/jobs}} 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/empty_list.txt: -------------------------------------------------------------------------------- 1 | These are the jobs: 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/empty_sections.hpp: -------------------------------------------------------------------------------- 1 | const auto empty_sections_data = mstch::map{}; -------------------------------------------------------------------------------- /external/mstch/test/data/empty_sections.mustache: -------------------------------------------------------------------------------- 1 | {{#foo}}{{/foo}}foo{{#bar}}{{/bar}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/empty_sections.txt: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/empty_string.hpp: -------------------------------------------------------------------------------- 1 | const auto empty_string_data = mstch::map{ 2 | {"description", std::string{"That is all!"}}, 3 | {"child", mstch::map{ 4 | {"description", std::string{""}} 5 | }} 6 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/empty_string.mustache: -------------------------------------------------------------------------------- 1 | {{description}}{{#child}}{{description}}{{/child}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/empty_string.txt: -------------------------------------------------------------------------------- 1 | That is all! 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/empty_template.hpp: -------------------------------------------------------------------------------- 1 | const auto empty_template_data = mstch::map{}; -------------------------------------------------------------------------------- /external/mstch/test/data/empty_template.mustache: -------------------------------------------------------------------------------- 1 |

Test

-------------------------------------------------------------------------------- /external/mstch/test/data/empty_template.txt: -------------------------------------------------------------------------------- 1 |

Test

-------------------------------------------------------------------------------- /external/mstch/test/data/error_eof_in_section.hpp: -------------------------------------------------------------------------------- 1 | const auto error_eof_in_section_data = mstch::map{ 2 | {"hello", mstch::array{std::string{"a"}, std::string{"b"}}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/error_eof_in_section.mustache: -------------------------------------------------------------------------------- 1 | yay{{#hello}}{{.}} -------------------------------------------------------------------------------- /external/mstch/test/data/error_eof_in_section.txt: -------------------------------------------------------------------------------- 1 | yay -------------------------------------------------------------------------------- /external/mstch/test/data/error_eof_in_tag.hpp: -------------------------------------------------------------------------------- 1 | const auto error_eof_in_tag_data = mstch::map{{"hello", std::string{"world"}}}; -------------------------------------------------------------------------------- /external/mstch/test/data/error_eof_in_tag.mustache: -------------------------------------------------------------------------------- 1 | {{hello{{hello}}{{hello -------------------------------------------------------------------------------- /external/mstch/test/data/error_eof_in_tag.txt: -------------------------------------------------------------------------------- 1 | {{hello -------------------------------------------------------------------------------- /external/mstch/test/data/error_not_found.hpp: -------------------------------------------------------------------------------- 1 | const auto error_not_found_data = mstch::map{ 2 | {"bar", 2} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/error_not_found.mustache: -------------------------------------------------------------------------------- 1 | {{foo}} -------------------------------------------------------------------------------- /external/mstch/test/data/error_not_found.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/personalrobotics/chimera/089e8360da01c04777c904e3106d822aa49e00de/external/mstch/test/data/error_not_found.txt -------------------------------------------------------------------------------- /external/mstch/test/data/escaped.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node escaped_data = mstch::map{ 2 | {"title", mstch::lambda{[]()->mstch::node{ return std::string{"Bear > Shark"}; }}}, 3 | {"entities", mstch::lambda{[]()->mstch::node{ return std::string{"" \"'<>/"}; }}} 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/escaped.mustache: -------------------------------------------------------------------------------- 1 |

{{title}}

2 | And even {{entities}}, but not {{{entities}}}. 3 | -------------------------------------------------------------------------------- /external/mstch/test/data/escaped.txt: -------------------------------------------------------------------------------- 1 |

Bear > Shark

2 | And even &quot; "'<>/, but not " "'<>/. 3 | -------------------------------------------------------------------------------- /external/mstch/test/data/falsy.hpp: -------------------------------------------------------------------------------- 1 | const auto falsy_data = mstch::map{ 2 | {"emptyString", std::string{""}}, 3 | {"emptyArray", mstch::array{}}, 4 | {"zero", 0}, 5 | {"null", mstch::node{}} 6 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/falsy.mustache: -------------------------------------------------------------------------------- 1 | {{#emptyString}}empty string{{/emptyString}} 2 | {{^emptyString}}inverted empty string{{/emptyString}} 3 | {{#emptyArray}}empty array{{/emptyArray}} 4 | {{^emptyArray}}inverted empty array{{/emptyArray}} 5 | {{#zero}}zero{{/zero}} 6 | {{^zero}}inverted zero{{/zero}} 7 | {{#null}}null{{/null}} 8 | {{^null}}inverted null{{/null}} 9 | -------------------------------------------------------------------------------- /external/mstch/test/data/falsy.txt: -------------------------------------------------------------------------------- 1 | 2 | inverted empty string 3 | 4 | inverted empty array 5 | 6 | inverted zero 7 | 8 | inverted null 9 | -------------------------------------------------------------------------------- /external/mstch/test/data/falsy_array.hpp: -------------------------------------------------------------------------------- 1 | const auto falsy_array_data = mstch::map{ 2 | {"list", mstch::array{ 3 | mstch::array{std::string{""}, std::string{"emptyString"}}, 4 | mstch::array{mstch::array{}, std::string{"emptyArray"}}, 5 | mstch::array{0, std::string{"zero"}}, 6 | mstch::array{mstch::node{}, std::string{"null"}}} 7 | } 8 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/falsy_array.mustache: -------------------------------------------------------------------------------- 1 | {{#list}} 2 | {{#.}}{{#.}}{{.}}{{/.}}{{^.}}inverted {{/.}}{{/.}} 3 | {{/list}} -------------------------------------------------------------------------------- /external/mstch/test/data/falsy_array.txt: -------------------------------------------------------------------------------- 1 | inverted emptyString 2 | inverted emptyArray 3 | inverted zero 4 | inverted null 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/grandparent_context.hpp: -------------------------------------------------------------------------------- 1 | const auto grandparent_context_data = mstch::map{ 2 | {"grand_parent_id", std::string{"grand_parent1"}}, 3 | {"parent_contexts", mstch::array{ 4 | mstch::map{ 5 | {"parent_id", std::string{"parent1"}}, 6 | {"child_contexts", mstch::array{ 7 | mstch::map{{"child_id", std::string{"parent1-child1"}}}, 8 | mstch::map{{"child_id", std::string{"parent1-child2"}}} 9 | }} 10 | }, 11 | mstch::map{ 12 | {"parent_id", std::string{"parent2"}}, 13 | {"child_contexts", mstch::array{ 14 | mstch::map{{"child_id", std::string{"parent2-child1"}}}, 15 | mstch::map{{"child_id", std::string{"parent2-child2"}}} 16 | }} 17 | } 18 | }} 19 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/grandparent_context.mustache: -------------------------------------------------------------------------------- 1 | {{grand_parent_id}} 2 | {{#parent_contexts}} 3 | {{grand_parent_id}} 4 | {{parent_id}} 5 | {{#child_contexts}} 6 | {{grand_parent_id}} 7 | {{parent_id}} 8 | {{child_id}} 9 | {{/child_contexts}} 10 | {{/parent_contexts}} 11 | -------------------------------------------------------------------------------- /external/mstch/test/data/grandparent_context.txt: -------------------------------------------------------------------------------- 1 | grand_parent1 2 | grand_parent1 3 | parent1 4 | grand_parent1 5 | parent1 6 | parent1-child1 7 | grand_parent1 8 | parent1 9 | parent1-child2 10 | grand_parent1 11 | parent2 12 | grand_parent1 13 | parent2 14 | parent2-child1 15 | grand_parent1 16 | parent2 17 | parent2-child2 18 | -------------------------------------------------------------------------------- /external/mstch/test/data/higher_order_sections.hpp: -------------------------------------------------------------------------------- 1 | class higher_order_sections: public mstch::object { 2 | private: 3 | std::string m_helper; 4 | public: 5 | higher_order_sections(): m_helper("To tinker?") { 6 | register_methods(this, std::map{ 7 | {"name", &higher_order_sections::name}, 8 | {"helper", &higher_order_sections::helper}, 9 | {"bolder", &higher_order_sections::bolder} 10 | }); 11 | } 12 | 13 | mstch::node name() { 14 | return std::string{"Tater"}; 15 | } 16 | 17 | mstch::node helper() { 18 | return m_helper; 19 | } 20 | 21 | mstch::node bolder() { 22 | return mstch::lambda{[this](const std::string& text) -> mstch::node { 23 | return "" + text + " " + m_helper; 24 | }}; 25 | } 26 | }; 27 | 28 | const mstch::node higher_order_sections_data = std::make_shared(); -------------------------------------------------------------------------------- /external/mstch/test/data/higher_order_sections.mustache: -------------------------------------------------------------------------------- 1 | {{#bolder}}Hi {{name}}.{{/bolder}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/higher_order_sections.txt: -------------------------------------------------------------------------------- 1 | Hi Tater. To tinker? 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/implicit_iterator.hpp: -------------------------------------------------------------------------------- 1 | const auto implicit_iterator_data = mstch::map{ 2 | {"data", mstch::map{ 3 | {"author", mstch::map{ 4 | {"twitter_id", 819606}, 5 | {"name", std::string{"janl"}} 6 | }} 7 | }} 8 | }; 9 | -------------------------------------------------------------------------------- /external/mstch/test/data/implicit_iterator.mustache: -------------------------------------------------------------------------------- 1 | {{# data.author.twitter_id }} 2 | 3 | {{/ data.author.twitter_id }} 4 | 5 | {{# data.author.name }} 6 | 7 | {{/ data.author.name }} 8 | -------------------------------------------------------------------------------- /external/mstch/test/data/implicit_iterator.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/included_tag.hpp: -------------------------------------------------------------------------------- 1 | const auto included_tag_data = mstch::map{ 2 | {"html", std::string{"I like {{mustache}}"}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/included_tag.mustache: -------------------------------------------------------------------------------- 1 | You said "{{{html}}}" today 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/included_tag.txt: -------------------------------------------------------------------------------- 1 | You said "I like {{mustache}}" today 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/inverted_section.hpp: -------------------------------------------------------------------------------- 1 | const auto inverted_section_data = mstch::map{ 2 | {"repos", mstch::array{}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/inverted_section.mustache: -------------------------------------------------------------------------------- 1 | {{#repos}}{{name}}{{/repos}} 2 | {{^repos}}No repos :({{/repos}} 3 | {{^nothin}}Hello!{{/nothin}} 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/inverted_section.txt: -------------------------------------------------------------------------------- 1 | 2 | No repos :( 3 | Hello! 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/keys_with_questionmarks.hpp: -------------------------------------------------------------------------------- 1 | const auto keys_with_questionmarks_data = mstch::map{ 2 | {"person?", mstch::map{ 3 | {"name", std::string{"Jon"}} 4 | }} 5 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/keys_with_questionmarks.mustache: -------------------------------------------------------------------------------- 1 | {{#person?}} 2 | Hi {{name}}! 3 | {{/person?}} 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/keys_with_questionmarks.txt: -------------------------------------------------------------------------------- 1 | Hi Jon! 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/multiline_comment.hpp: -------------------------------------------------------------------------------- 1 | const auto multiline_comment_data = mstch::map{}; -------------------------------------------------------------------------------- /external/mstch/test/data/multiline_comment.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | 3 | This is a multi-line comment. 4 | 5 | }} 6 | Hello world! 7 | -------------------------------------------------------------------------------- /external/mstch/test/data/multiline_comment.txt: -------------------------------------------------------------------------------- 1 | Hello world! 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/nested_dot.hpp: -------------------------------------------------------------------------------- 1 | const auto nested_dot_data = mstch::map{{"name", std::string{"Bruno"}}}; -------------------------------------------------------------------------------- /external/mstch/test/data/nested_dot.mustache: -------------------------------------------------------------------------------- 1 | {{#name}}Hello {{.}}{{/name}} -------------------------------------------------------------------------------- /external/mstch/test/data/nested_dot.txt: -------------------------------------------------------------------------------- 1 | Hello Bruno -------------------------------------------------------------------------------- /external/mstch/test/data/nested_higher_order_sections.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node nested_higher_order_sections_data = mstch::map{ 2 | {"bold", mstch::lambda{[](const std::string& text) -> mstch::node { 3 | return std::string{""} + text + std::string{""}; 4 | }}}, 5 | {"person", mstch::map{{"name", std::string{"Jonas"}}}} 6 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/nested_higher_order_sections.mustache: -------------------------------------------------------------------------------- 1 | {{#bold}}{{#person}}My name is {{name}}!{{/person}}{{/bold}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/nested_higher_order_sections.txt: -------------------------------------------------------------------------------- 1 | My name is Jonas! 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/nested_iterating.hpp: -------------------------------------------------------------------------------- 1 | const auto nested_iterating_data = mstch::map{ 2 | {"inner", mstch::array{mstch::map{ 3 | {"foo", std::string{"foo"}}, 4 | {"inner", mstch::array{mstch::map{ 5 | {"bar", std::string{"bar"}} 6 | }}} 7 | }}} 8 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/nested_iterating.mustache: -------------------------------------------------------------------------------- 1 | {{#inner}}{{foo}}{{#inner}}{{bar}}{{/inner}}{{/inner}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/nested_iterating.txt: -------------------------------------------------------------------------------- 1 | foobar 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/nesting.hpp: -------------------------------------------------------------------------------- 1 | const auto nesting_data = mstch::map{ 2 | {"foo", mstch::array{ 3 | mstch::map{{"a", mstch::map{{"b", 1}}}}, 4 | mstch::map{{"a", mstch::map{{"b", 2}}}}, 5 | mstch::map{{"a", mstch::map{{"b", 3}}}} 6 | }} 7 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/nesting.mustache: -------------------------------------------------------------------------------- 1 | {{#foo}} 2 | {{#a}} 3 | {{b}} 4 | {{/a}} 5 | {{/foo}} 6 | -------------------------------------------------------------------------------- /external/mstch/test/data/nesting.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/nesting_same_name.hpp: -------------------------------------------------------------------------------- 1 | const auto nesting_same_name_data = mstch::map{ 2 | {"items", mstch::array{ 3 | mstch::map{ 4 | {"name", std::string{"name"}}, 5 | {"items", mstch::array{1, 2, 3, 4}} 6 | } 7 | }} 8 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/nesting_same_name.mustache: -------------------------------------------------------------------------------- 1 | {{#items}}{{name}}{{#items}}{{.}}{{/items}}{{/items}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/nesting_same_name.txt: -------------------------------------------------------------------------------- 1 | name1234 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_lookup_array.hpp: -------------------------------------------------------------------------------- 1 | const auto null_lookup_array_data = mstch::map{ 2 | {"name", std::string{"David"}}, 3 | {"twitter", std::string{"@dasilvacontin"}}, 4 | {"farray", mstch::array{ 5 | mstch::array{std::string{"Flor"}, std::string{"@florrts"}}, 6 | mstch::array{std::string{"Miquel"}, mstch::node{}}, 7 | }} 8 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/null_lookup_array.mustache: -------------------------------------------------------------------------------- 1 | {{#farray}} 2 | {{#.}}{{#.}}{{.}} {{/.}}{{^.}}no twitter{{/.}}{{/.}} 3 | {{/farray}} 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_lookup_array.txt: -------------------------------------------------------------------------------- 1 | Flor @florrts 2 | Miquel no twitter 3 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_lookup_object.hpp: -------------------------------------------------------------------------------- 1 | const auto null_lookup_object_data = mstch::map{ 2 | {"name", std::string{"David"}}, 3 | {"twitter", std::string{"@dasilvacontin"}}, 4 | {"fobject", mstch::array{ 5 | mstch::map{ 6 | {"name", std::string{"Flor"}}, 7 | {"twitter", std::string{"@florrts"}} 8 | }, 9 | mstch::map{ 10 | {"name", std::string{"Miquel"}}, 11 | {"twitter", mstch::node{}} 12 | } 13 | }} 14 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/null_lookup_object.mustache: -------------------------------------------------------------------------------- 1 | {{#fobject}} 2 | {{name}}'s twitter: {{#twitter}}{{.}}{{/twitter}}{{^twitter}}unknown{{/twitter}}. 3 | {{/fobject}} 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_lookup_object.txt: -------------------------------------------------------------------------------- 1 | Flor's twitter: @florrts. 2 | Miquel's twitter: unknown. 3 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_string.hpp: -------------------------------------------------------------------------------- 1 | const auto null_string_data = mstch::map{ 2 | {"name", std::string{"Elise"}}, 3 | {"glytch", true}, 4 | {"binary", false}, 5 | {"value", mstch::node{}} 6 | }; 7 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_string.mustache: -------------------------------------------------------------------------------- 1 | Hello {{name}} 2 | glytch {{glytch}} 3 | binary {{binary}} 4 | value {{value}} 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_string.txt: -------------------------------------------------------------------------------- 1 | Hello Elise 2 | glytch true 3 | binary false 4 | value 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/null_view.hpp: -------------------------------------------------------------------------------- 1 | const auto null_view_data = mstch::map{ 2 | {"name", std::string{"Joe"}}, 3 | {"friends", mstch::node{}} 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/null_view.mustache: -------------------------------------------------------------------------------- 1 | {{name}}'s friends: {{#friends}}{{name}}, {{/friends}} -------------------------------------------------------------------------------- /external/mstch/test/data/null_view.txt: -------------------------------------------------------------------------------- 1 | Joe's friends: -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array.hpp: -------------------------------------------------------------------------------- 1 | const auto partial_array_data = mstch::map{ 2 | {"array", mstch::array{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array.mustache: -------------------------------------------------------------------------------- 1 | {{>partial}} -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array.partial: -------------------------------------------------------------------------------- 1 | Here's a non-sense array of values 2 | {{#array}} 3 | {{.}} 4 | {{/array}} 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array.txt: -------------------------------------------------------------------------------- 1 | Here's a non-sense array of values 2 | 1 3 | 2 4 | 3 5 | 4 6 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials.hpp: -------------------------------------------------------------------------------- 1 | const auto partial_array_of_partials_data = mstch::map{ 2 | {"numbers", mstch::array{ 3 | mstch::map{{"i", std::string{"1"}}}, 4 | mstch::map{{"i", std::string{"2"}}}, 5 | mstch::map{{"i", std::string{"3"}}}, 6 | mstch::map{{"i", std::string{"4"}}} 7 | }} 8 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials.mustache: -------------------------------------------------------------------------------- 1 | Here is some stuff! 2 | {{#numbers}} 3 | {{>partial}} 4 | {{/numbers}} 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials.partial: -------------------------------------------------------------------------------- 1 | {{i}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials.txt: -------------------------------------------------------------------------------- 1 | Here is some stuff! 2 | 1 3 | 2 4 | 3 5 | 4 6 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials_implicit.hpp: -------------------------------------------------------------------------------- 1 | const auto partial_array_of_partials_implicit_data = mstch::map{ 2 | {"numbers", mstch::array{std::string{"1"}, std::string{"2"}, std::string{"3"}, std::string{"4"}}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials_implicit.mustache: -------------------------------------------------------------------------------- 1 | Here is some stuff! 2 | {{#numbers}} 3 | {{>partial}} 4 | {{/numbers}} 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials_implicit.partial: -------------------------------------------------------------------------------- 1 | {{.}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_array_of_partials_implicit.txt: -------------------------------------------------------------------------------- 1 | Here is some stuff! 2 | 1 3 | 2 4 | 3 5 | 4 6 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_empty.hpp: -------------------------------------------------------------------------------- 1 | const auto partial_empty_data = mstch::map{ 2 | {"foo", 1} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/partial_empty.mustache: -------------------------------------------------------------------------------- 1 | hey {{foo}} 2 | {{>partial}} 3 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_empty.partial: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/personalrobotics/chimera/089e8360da01c04777c904e3106d822aa49e00de/external/mstch/test/data/partial_empty.partial -------------------------------------------------------------------------------- /external/mstch/test/data/partial_empty.txt: -------------------------------------------------------------------------------- 1 | hey 1 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_template.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node partial_template_data = mstch::map{ 2 | {"title", mstch::lambda{[]()->mstch::node{ return std::string{"Welcome"}; }}}, 3 | {"again", mstch::lambda{[]()->mstch::node{ return std::string{"Goodbye"}; }}}, 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/partial_template.mustache: -------------------------------------------------------------------------------- 1 |

{{title}}

2 | {{>partial}} 3 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_template.partial: -------------------------------------------------------------------------------- 1 | Again, {{again}}! 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_template.txt: -------------------------------------------------------------------------------- 1 |

Welcome

2 | Again, Goodbye! 3 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_view.hpp: -------------------------------------------------------------------------------- 1 | class partial_view: public mstch::object { 2 | private: 3 | int m_value; 4 | 5 | public: 6 | partial_view(): m_value(10000) { 7 | register_methods(this, std::map{ 8 | {"greeting", &partial_view::greeting}, 9 | {"farewell", &partial_view::farewell}, 10 | {"name", &partial_view::name}, 11 | {"value", &partial_view::value}, 12 | {"taxed_value", &partial_view::taxed_value}, 13 | {"in_ca", &partial_view::in_ca} 14 | }); 15 | } 16 | 17 | mstch::node greeting() { 18 | return std::string{"Welcome"}; 19 | } 20 | 21 | mstch::node farewell() { 22 | return std::string{"Fair enough, right?"}; 23 | } 24 | 25 | mstch::node name() { 26 | return std::string{"Chris"}; 27 | } 28 | 29 | mstch::node value() { 30 | return m_value; 31 | } 32 | 33 | mstch::node taxed_value() { 34 | return m_value - (m_value * 0.4); 35 | } 36 | 37 | mstch::node in_ca() { 38 | return true; 39 | } 40 | }; 41 | 42 | const auto partial_view_data = std::make_shared(); -------------------------------------------------------------------------------- /external/mstch/test/data/partial_view.mustache: -------------------------------------------------------------------------------- 1 |

{{greeting}}

2 | {{>partial}} 3 |

{{farewell}}

4 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_view.partial: -------------------------------------------------------------------------------- 1 | Hello {{name}} 2 | You have just won ${{value}}! 3 | {{#in_ca}} 4 | Well, ${{ taxed_value }}, after taxes. 5 | {{/in_ca}} -------------------------------------------------------------------------------- /external/mstch/test/data/partial_view.txt: -------------------------------------------------------------------------------- 1 |

Welcome

2 | Hello Chris 3 | You have just won $10000! 4 | Well, $6000, after taxes. 5 |

Fair enough, right?

6 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_whitespace.hpp: -------------------------------------------------------------------------------- 1 | class partial_whitespace: public mstch::object { 2 | private: 3 | int m_value; 4 | public: 5 | partial_whitespace(): m_value(10000) { 6 | register_methods(this, std::map{ 7 | {"greeting", &partial_whitespace::greeting}, 8 | {"farewell", &partial_whitespace::farewell}, 9 | {"name", &partial_whitespace::name}, 10 | {"value", &partial_whitespace::value}, 11 | {"taxed_value", &partial_whitespace::taxed_value}, 12 | {"in_ca", &partial_whitespace::in_ca} 13 | }); 14 | } 15 | 16 | mstch::node greeting() { 17 | return std::string{"Welcome"}; 18 | } 19 | 20 | mstch::node farewell() { 21 | return std::string{"Fair enough, right?"}; 22 | } 23 | 24 | mstch::node name() { 25 | return std::string{"Chris"}; 26 | } 27 | 28 | mstch::node value() { 29 | return m_value; 30 | } 31 | 32 | mstch::node taxed_value() { 33 | return static_cast(m_value - (m_value * 0.4)); 34 | } 35 | 36 | mstch::node in_ca() { 37 | return true; 38 | } 39 | }; 40 | 41 | const auto partial_whitespace_data = std::make_shared(); -------------------------------------------------------------------------------- /external/mstch/test/data/partial_whitespace.mustache: -------------------------------------------------------------------------------- 1 |

{{ greeting }}

2 | {{> partial }} 3 |

{{ farewell }}

4 | -------------------------------------------------------------------------------- /external/mstch/test/data/partial_whitespace.partial: -------------------------------------------------------------------------------- 1 | Hello {{ name}} 2 | You have just won ${{value }}! 3 | {{# in_ca }} 4 | Well, ${{ taxed_value }}, after taxes. 5 | {{/ in_ca }} -------------------------------------------------------------------------------- /external/mstch/test/data/partial_whitespace.txt: -------------------------------------------------------------------------------- 1 |

Welcome

2 | Hello Chris 3 | You have just won $10000! 4 | Well, $6000, after taxes. 5 |

Fair enough, right?

6 | -------------------------------------------------------------------------------- /external/mstch/test/data/recursion_with_same_names.hpp: -------------------------------------------------------------------------------- 1 | const auto recursion_with_same_names_data = mstch::map{ 2 | {"name", std::string{"name"}}, 3 | {"description", std::string{"desc"}}, 4 | {"terms", mstch::array{ 5 | mstch::map{{"name", std::string{"t1"}}, {"index", 0}}, 6 | mstch::map{{"name", std::string{"t2"}}, {"index", 1}} 7 | }} 8 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/recursion_with_same_names.mustache: -------------------------------------------------------------------------------- 1 | {{ name }} 2 | {{ description }} 3 | 4 | {{#terms}} 5 | {{name}} 6 | {{index}} 7 | {{/terms}} 8 | -------------------------------------------------------------------------------- /external/mstch/test/data/recursion_with_same_names.txt: -------------------------------------------------------------------------------- 1 | name 2 | desc 3 | 4 | t1 5 | 0 6 | t2 7 | 1 8 | -------------------------------------------------------------------------------- /external/mstch/test/data/reuse_of_enumerables.hpp: -------------------------------------------------------------------------------- 1 | const auto reuse_of_enumerables_data = mstch::map{ 2 | {"terms", mstch::array{ 3 | mstch::map{{"name", std::string{"t1"}}, {"index", 0}}, 4 | mstch::map{{"name", std::string{"t2"}}, {"index", 1}} 5 | }} 6 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/reuse_of_enumerables.mustache: -------------------------------------------------------------------------------- 1 | {{#terms}} 2 | {{name}} 3 | {{index}} 4 | {{/terms}} 5 | {{#terms}} 6 | {{name}} 7 | {{index}} 8 | {{/terms}} 9 | -------------------------------------------------------------------------------- /external/mstch/test/data/reuse_of_enumerables.txt: -------------------------------------------------------------------------------- 1 | t1 2 | 0 3 | t2 4 | 1 5 | t1 6 | 0 7 | t2 8 | 1 9 | -------------------------------------------------------------------------------- /external/mstch/test/data/section_as_context.hpp: -------------------------------------------------------------------------------- 1 | const auto section_as_context_data = mstch::map{ 2 | {"a_object", mstch::map{ 3 | {"title", std::string{"this is an object"}}, 4 | {"description", std::string{"one of its attributes is a list"}}, 5 | {"a_list", mstch::array{ 6 | mstch::map{{"label", std::string{"listitem1"}}}, 7 | mstch::map{{"label", std::string{"listitem2"}}} 8 | }} 9 | }} 10 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/section_as_context.mustache: -------------------------------------------------------------------------------- 1 | {{#a_object}} 2 |

{{title}}

3 |

{{description}}

4 |
    5 | {{#a_list}} 6 |
  • {{label}}
  • 7 | {{/a_list}} 8 |
9 | {{/a_object}} 10 | -------------------------------------------------------------------------------- /external/mstch/test/data/section_as_context.txt: -------------------------------------------------------------------------------- 1 |

this is an object

2 |

one of its attributes is a list

3 |
    4 |
  • listitem1
  • 5 |
  • listitem2
  • 6 |
7 | -------------------------------------------------------------------------------- /external/mstch/test/data/section_functions_in_partials.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node section_functions_in_partials_data = mstch::map{ 2 | {"bold", mstch::lambda{[](const std::string& text) -> mstch::node { 3 | return std::string{""} + text + std::string{""}; 4 | }}} 5 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/section_functions_in_partials.mustache: -------------------------------------------------------------------------------- 1 | {{> partial}} 2 | 3 |

some more text

4 | -------------------------------------------------------------------------------- /external/mstch/test/data/section_functions_in_partials.partial: -------------------------------------------------------------------------------- 1 | {{#bold}}Hello There{{/bold}} 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/section_functions_in_partials.txt: -------------------------------------------------------------------------------- 1 | Hello There 2 | 3 |

some more text

4 | -------------------------------------------------------------------------------- /external/mstch/test/data/simple.hpp: -------------------------------------------------------------------------------- 1 | class simple: public mstch::object { 2 | private: 3 | int m_value; 4 | public: 5 | simple(): 6 | m_value(10000) 7 | { 8 | register_methods(this, std::map{ 9 | {"name", &simple::name}, 10 | {"value", &simple::value}, 11 | {"taxed_value", &simple::taxed_value}, 12 | {"in_ca", &simple::in_ca}}); 13 | } 14 | 15 | mstch::node name() { 16 | return std::string{"Chris"}; 17 | } 18 | 19 | mstch::node value() { 20 | return m_value; 21 | } 22 | 23 | mstch::node taxed_value() { 24 | return m_value - (m_value * 0.4); 25 | } 26 | 27 | mstch::node in_ca() { 28 | return true; 29 | } 30 | }; 31 | 32 | const auto simple_data = std::make_shared(); -------------------------------------------------------------------------------- /external/mstch/test/data/simple.mustache: -------------------------------------------------------------------------------- 1 | Hello {{name}} 2 | You have just won ${{value}}! 3 | {{#in_ca}} 4 | Well, ${{ taxed_value }}, after taxes. 5 | {{/in_ca}} 6 | -------------------------------------------------------------------------------- /external/mstch/test/data/simple.txt: -------------------------------------------------------------------------------- 1 | Hello Chris 2 | You have just won $10000! 3 | Well, $6000, after taxes. 4 | -------------------------------------------------------------------------------- /external/mstch/test/data/string_as_context.hpp: -------------------------------------------------------------------------------- 1 | const auto string_as_context_data = mstch::map{ 2 | {"a_string", std::string{"aa"}}, 3 | {"a_list", mstch::array{std::string{"a"},std::string{"b"},std::string{"c"}}} 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/string_as_context.mustache: -------------------------------------------------------------------------------- 1 |
    2 | {{#a_list}} 3 |
  • {{a_string}}/{{.}}
  • 4 | {{/a_list}} 5 |
-------------------------------------------------------------------------------- /external/mstch/test/data/string_as_context.txt: -------------------------------------------------------------------------------- 1 |
    2 |
  • aa/a
  • 3 |
  • aa/b
  • 4 |
  • aa/c
  • 5 |
-------------------------------------------------------------------------------- /external/mstch/test/data/two_in_a_row.hpp: -------------------------------------------------------------------------------- 1 | const auto two_in_a_row_data = mstch::map{ 2 | {"name", std::string{"Joe"}}, 3 | {"greeting", std::string{"Welcome"}} 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/two_in_a_row.mustache: -------------------------------------------------------------------------------- 1 | {{greeting}}, {{name}}! 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/two_in_a_row.txt: -------------------------------------------------------------------------------- 1 | Welcome, Joe! 2 | -------------------------------------------------------------------------------- /external/mstch/test/data/two_sections.hpp: -------------------------------------------------------------------------------- 1 | const auto two_sections_data = mstch::map{}; -------------------------------------------------------------------------------- /external/mstch/test/data/two_sections.mustache: -------------------------------------------------------------------------------- 1 | {{#foo}} 2 | {{/foo}} 3 | {{#bar}} 4 | {{/bar}} 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/two_sections.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/personalrobotics/chimera/089e8360da01c04777c904e3106d822aa49e00de/external/mstch/test/data/two_sections.txt -------------------------------------------------------------------------------- /external/mstch/test/data/unescaped.hpp: -------------------------------------------------------------------------------- 1 | const mstch::node unescaped_data = mstch::map{ 2 | {"title", mstch::lambda{[]()->mstch::node{ return std::string{"Bear > Shark"}; }}} 3 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/unescaped.mustache: -------------------------------------------------------------------------------- 1 |

{{{title}}}

2 | -------------------------------------------------------------------------------- /external/mstch/test/data/unescaped.txt: -------------------------------------------------------------------------------- 1 |

Bear > Shark

2 | -------------------------------------------------------------------------------- /external/mstch/test/data/whitespace.hpp: -------------------------------------------------------------------------------- 1 | const auto whitespace_data = mstch::map{ 2 | {"tag1", std::string{"Hello"}}, 3 | {"tag2", std::string{"World"}} 4 | }; -------------------------------------------------------------------------------- /external/mstch/test/data/whitespace.mustache: -------------------------------------------------------------------------------- 1 | {{tag1}} 2 | 3 | 4 | {{tag2}}. 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/whitespace.txt: -------------------------------------------------------------------------------- 1 | Hello 2 | 3 | 4 | World. 5 | -------------------------------------------------------------------------------- /external/mstch/test/data/zero_view.hpp: -------------------------------------------------------------------------------- 1 | const auto zero_view_data = mstch::map{{"nums", mstch::array{0, 1, 2}}}; -------------------------------------------------------------------------------- /external/mstch/test/data/zero_view.mustache: -------------------------------------------------------------------------------- 1 | {{#nums}}{{.}},{{/nums}} -------------------------------------------------------------------------------- /external/mstch/test/data/zero_view.txt: -------------------------------------------------------------------------------- 1 | 0,1,2, -------------------------------------------------------------------------------- /external/mstch/test/specs_lambdas.hpp: -------------------------------------------------------------------------------- 1 | std::map specs_lambdas { 2 | {"Interpolation", mstch::lambda{[](const std::string&) -> mstch::node { 3 | return std::string{"world"}; 4 | }}}, 5 | {"Interpolation - Expansion", mstch::lambda{[](const std::string&) -> mstch::node { 6 | return std::string{"{{planet}}"}; 7 | }}}, 8 | {"Interpolation - Alternate Delimiters", mstch::lambda{[](const std::string&) -> mstch::node { 9 | return std::string{"|planet| => {{planet}}"}; 10 | }}}, 11 | {"Interpolation - Multiple Calls", mstch::lambda{[](const std::string&) -> mstch::node { 12 | static int calls = 0; return ++calls; 13 | }}}, 14 | {"Escaping", mstch::lambda{[](const std::string&) -> mstch::node { 15 | return std::string{">"}; 16 | }}}, 17 | {"Section", mstch::lambda{[](const std::string& txt) -> mstch::node { 18 | return std::string{(txt == "{{x}}") ? "yes" : "no"}; 19 | }}}, 20 | {"Section - Expansion", mstch::lambda{[](const std::string& txt) -> mstch::node { 21 | return txt + std::string{"{{planet}}"} + txt; 22 | }}}, 23 | {"Section - Alternate Delimiters", mstch::lambda{[](const std::string& txt) -> mstch::node { 24 | return txt + std::string{"{{planet}} => |planet|"} + txt; 25 | }}}, 26 | {"Section - Multiple Calls", mstch::lambda{[](const std::string& txt) -> mstch::node { 27 | return "__" + txt + "__"; 28 | }}}, 29 | {"Inverted Section", mstch::lambda{[](const std::string&) -> mstch::node { 30 | return false; 31 | }}} 32 | }; -------------------------------------------------------------------------------- /include/chimera/binding.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHIMERA_BINDING_H__ 2 | #define __CHIMERA_BINDING_H__ 3 | 4 | #include 5 | #include 6 | 7 | namespace chimera 8 | { 9 | namespace binding 10 | { 11 | 12 | /** 13 | * Interface for defining a built-in language binding. 14 | */ 15 | struct Definition 16 | { 17 | std::string class_h; 18 | std::string class_cpp; 19 | std::string enum_h; 20 | std::string enum_cpp; 21 | std::string function_h; 22 | std::string function_cpp; 23 | std::string module_h; 24 | std::string module_cpp; 25 | std::string variable_h; 26 | std::string variable_cpp; 27 | std::string typedef_h; 28 | std::string typedef_cpp; 29 | }; 30 | 31 | /** 32 | * Static map of available built-in binding definitions. 33 | */ 34 | extern std::map DEFINITIONS; 35 | 36 | /** 37 | * Name of default built-in binding. 38 | * 39 | * This is defined as a static instead of const so that it can be more easily 40 | * auto-generated at build time. 41 | */ 42 | extern std::string DEFAULT_NAME; 43 | 44 | /** 45 | * Loads pre-built bindings into Configuration. 46 | * The body of this function is auto-generated by CMake. 47 | */ 48 | void initializeBuiltinBindings(); 49 | 50 | } // namespace binding 51 | } // namespace chimera 52 | 53 | #endif // __CHIMERA_BINDING_H__ 54 | -------------------------------------------------------------------------------- /include/chimera/chimera.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHIMERA_H__ 2 | #define __CHIMERA_H__ 3 | 4 | namespace chimera 5 | { 6 | 7 | int run(int argc, const char **argv); 8 | 9 | } // namespace chimera 10 | 11 | #endif // __CHIMERA_H__ 12 | -------------------------------------------------------------------------------- /include/chimera/consumer.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHIMERA_CONSUMER_H__ 2 | #define __CHIMERA_CONSUMER_H__ 3 | 4 | #include "chimera/configuration.h" 5 | 6 | #include 7 | #include 8 | 9 | namespace chimera 10 | { 11 | 12 | class Consumer : public clang::ASTConsumer 13 | { 14 | public: 15 | // Overrides the constructor in order to receive CompilerInstance. 16 | Consumer(clang::CompilerInstance *ci, const chimera::Configuration &config); 17 | 18 | // Overrides method to call our ChimeraVisitor on the entire source file. 19 | void HandleTranslationUnit(clang::ASTContext &context) override; 20 | 21 | private: 22 | clang::CompilerInstance *ci_; 23 | const chimera::Configuration &config_; 24 | }; 25 | 26 | } // namespace chimera 27 | 28 | #endif // __CHIMERA_CONSUMER_H__ 29 | -------------------------------------------------------------------------------- /include/chimera/frontend_action.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHIMERA_FRONTEND_ACTION_H__ 2 | #define __CHIMERA_FRONTEND_ACTION_H__ 3 | 4 | #include "chimera/configuration.h" 5 | #include "chimera/util.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace chimera 14 | { 15 | 16 | /** 17 | * Front-end that runs the Chimera AST consumer on the provided source. 18 | */ 19 | class FrontendAction : public clang::ASTFrontendAction 20 | { 21 | public: 22 | // Overrides the constructor in order to receive ChimeraConfiguration. 23 | FrontendAction(const chimera::Configuration &config); 24 | 25 | std::unique_ptr CreateASTConsumer( 26 | clang::CompilerInstance &CI, clang::StringRef file) override; 27 | 28 | protected: 29 | const chimera::Configuration &config_; 30 | }; 31 | 32 | // Create a custom action factory that forwards the ChimeraConfiguration. 33 | class ChimeraFrontendActionFactory 34 | : public clang::tooling::FrontendActionFactory 35 | { 36 | public: 37 | ChimeraFrontendActionFactory(const chimera::Configuration &config); 38 | 39 | // Between Clang 9 and Clang 10, the return value for 40 | // FrontendActionFactory::create() changed from raw pointer to std::unique_ptr. 41 | #if LLVM_VERSION_AT_LEAST(10, 0, 0) 42 | std::unique_ptr create() override; 43 | #else 44 | clang::FrontendAction *create() override; 45 | #endif 46 | 47 | protected: 48 | const chimera::Configuration &config_; 49 | }; 50 | 51 | /** 52 | * Custom frontend factory that forwards a ChimeraConfiguration. 53 | */ 54 | std::unique_ptr newFrontendActionFactory( 55 | const chimera::Configuration &config); 56 | 57 | } // namespace chimera 58 | 59 | #endif // __CHIMERA_FRONTEND_ACTION_H__ 60 | -------------------------------------------------------------------------------- /include/chimera/visitor.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHIMERA_VISITOR_H__ 2 | #define __CHIMERA_VISITOR_H__ 3 | 4 | #include "chimera/configuration.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace chimera 12 | { 13 | 14 | class Visitor : public clang::RecursiveASTVisitor 15 | { 16 | public: 17 | Visitor(clang::CompilerInstance *ci, CompiledConfiguration &cc); 18 | 19 | bool shouldVisitImplicitCode() const; 20 | bool shouldVisitTemplateInstantiations() const; 21 | bool VisitDecl(clang::Decl *decl); 22 | 23 | protected: 24 | bool GenerateCXXRecord(clang::CXXRecordDecl *decl); 25 | bool GenerateEnum(clang::EnumDecl *decl); 26 | bool GenerateGlobalVar(clang::VarDecl *decl); 27 | bool GenerateGlobalFunction(clang::FunctionDecl *decl); 28 | bool GenerateTypedefName(clang::TypedefNameDecl *decl); 29 | 30 | private: 31 | clang::PrintingPolicy printing_policy_; 32 | CompiledConfiguration &config_; 33 | 34 | std::set traversed_class_decls_; 35 | }; 36 | 37 | } // namespace chimera 38 | 39 | #endif // __CHIMERA_VISITOR_H__ 40 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | chimera 7 | 0.0.1 8 | 9 | Chimera is a tool for generating Boost.Python bindings from C/C++ header 10 | files. It uses the Clang/LLVM toolchain, making it capable of automatically 11 | handling fairly complex source files. 12 | 13 | https://github.com/personalrobotics/chimera 14 | https://github.com/personalrobotics/chimera.git 15 | https://github.com/personalrobotics/chimera/issues 16 | Michael Koval 17 | Pras Velagapudi 18 | Michael Koval 19 | Pras Velagapudi 20 | unreleased 21 | cmake 22 | pkg-config 23 | yaml-cpp 24 | 25 | 26 | 27 | catkin 28 | 29 | cmake 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/chimera_main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Chimera - a tool to convert c++ headers into Boost.Python bindings. 3 | */ 4 | #include "chimera/chimera.h" 5 | 6 | int main(int argc, const char **argv) 7 | { 8 | chimera::run(argc, argv); 9 | } 10 | -------------------------------------------------------------------------------- /src/consumer.cpp: -------------------------------------------------------------------------------- 1 | #include "chimera/consumer.h" 2 | #include "chimera/visitor.h" 3 | 4 | #include 5 | 6 | using namespace clang; 7 | 8 | chimera::Consumer::Consumer(CompilerInstance *ci, 9 | const chimera::Configuration &config) 10 | : ci_(ci), config_(config) 11 | { 12 | // Do nothing. 13 | } 14 | 15 | void chimera::Consumer::HandleTranslationUnit(ASTContext &context) 16 | { 17 | // Use the current translation unit to resolve the YAML configuration. 18 | std::unique_ptr compiled_config 19 | = config_.Process(ci_); 20 | chimera::Visitor visitor(ci_, *compiled_config); 21 | 22 | // We can use ASTContext to get the TranslationUnitDecl, which is 23 | // a single Decl that collectively represents the entire source file. 24 | visitor.TraverseDecl(context.getTranslationUnitDecl()); 25 | 26 | // Render the top-level mstch template 27 | compiled_config->Render(); 28 | } 29 | -------------------------------------------------------------------------------- /test/emulator.h: -------------------------------------------------------------------------------- 1 | #ifndef __CHIMERA_TEST_EMULATOR_H__ 2 | #define __CHIMERA_TEST_EMULATOR_H__ 3 | 4 | #include 5 | #include 6 | #include "chimera/chimera.h" 7 | 8 | namespace chimera 9 | { 10 | namespace test 11 | { 12 | 13 | class Emulator 14 | { 15 | public: 16 | Emulator(); 17 | 18 | void Run(); 19 | 20 | static void Run(const std::string &args); 21 | 22 | static void RunHelp(); 23 | static void RunHelpList(); 24 | static void RunVersion(); 25 | 26 | void SetSource(const std::string &filename); 27 | void SetSources(const std::vector &filenames); 28 | 29 | void SetModuleName(const std::string &name); 30 | 31 | void SetBinding(const std::string &name); 32 | 33 | void SetConfigurationFile(const std::string &path); 34 | 35 | static const std::string &GetExamplesDirPath(); 36 | static const std::string &GetBuildPath(); 37 | 38 | private: 39 | /// Binding definition name (boost_python/pybind11) for option '-b' 40 | std::string binding_; 41 | 42 | /// YAML configuration filename for option '-c' 43 | std::string config_filepath_; 44 | 45 | /// Output top-level module name for option '-m' 46 | std::string modulename_; 47 | 48 | /// Sources paths 49 | std::vector sources_; 50 | }; 51 | 52 | } // namespace test 53 | } // namespace chimera 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /test/examples/00_module/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "module") 2 | 3 | chimera_add_binding_test_boost_python(${test_name}_boost_python 4 | SOURCES ${test_name}.h 5 | NAMESPACES chimera_test 6 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_boost_python.yaml 7 | COPY_MODULE 8 | ) 9 | 10 | chimera_add_binding_test_pybind11(${test_name}_pybind11 11 | SOURCES ${test_name}.h 12 | NAMESPACES chimera_test 13 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_pybind11.yaml 14 | COPY_MODULE 15 | ) 16 | 17 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 18 | -------------------------------------------------------------------------------- /test/examples/00_module/module.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace chimera_test 4 | { 5 | 6 | } // namespace chimera_test 7 | -------------------------------------------------------------------------------- /test/examples/00_module/module.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import module_pybind11 as py11 4 | import module_boost_python as boost 5 | 6 | 7 | class TestModule(unittest.TestCase): 8 | 9 | def _test_typedef(self, binding): 10 | if binding is py11: 11 | self.assertEqual(binding.__name__, "module_pybind11") 12 | elif binding is boost: 13 | self.assertEqual(binding.__name__, "module_boost_python") 14 | self.assertEqual( 15 | binding.__doc__, "The first example module generated by chimera") 16 | self.assertEqual( 17 | binding.__version__, "0.1.0") 18 | 19 | def test_typedef(self): 20 | self._test_typedef(boost) 21 | self._test_typedef(py11) 22 | 23 | 24 | if __name__ == '__main__': 25 | unittest.main() 26 | -------------------------------------------------------------------------------- /test/examples/00_module/module_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | template: 5 | module: 6 | doc: "The first example module generated by chimera" 7 | version: "0.1.0" 8 | -------------------------------------------------------------------------------- /test/examples/00_module/module_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | template: 5 | module: 6 | doc: "The first example module generated by chimera" 7 | version: "0.1.0" 8 | -------------------------------------------------------------------------------- /test/examples/01_function/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "function") 2 | 3 | chimera_add_binding_test_boost_python(${test_name}_boost_python 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_boost_python.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_pybind11(${test_name}_pybind11 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_pybind11.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/01_function/function.cpp: -------------------------------------------------------------------------------- 1 | #include "function.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | int add(int i, int j) 8 | { 9 | return i + j; 10 | } 11 | 12 | //============================================================================== 13 | int void_pointer_param(void *dummy) 14 | { 15 | Dummy *casted = static_cast(dummy); 16 | return casted->val; 17 | } 18 | 19 | //============================================================================== 20 | void void_param() 21 | { 22 | // Do nothing 23 | } 24 | 25 | //============================================================================== 26 | void void_return() 27 | { 28 | // Do nothing 29 | } 30 | 31 | //============================================================================== 32 | void function_with_suppressed_param(const SuppressedClass &) 33 | { 34 | // Do nothing 35 | } 36 | 37 | //============================================================================== 38 | void function_with_suppressed_template_param( 39 | const SuppressedTemplateClass &) 40 | { 41 | // Do nothing 42 | } 43 | 44 | } // namespace chimera_test 45 | -------------------------------------------------------------------------------- /test/examples/01_function/function.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace chimera_test 4 | { 5 | 6 | int add(int i = 1, int j = 2); 7 | 8 | inline int inline_add(int i = 1, int j = 2) 9 | { 10 | return i + j; 11 | } 12 | 13 | struct Dummy 14 | { 15 | int val; 16 | Dummy() = default; 17 | }; 18 | 19 | int void_pointer_param(void *dummy); 20 | 21 | void void_param(void); 22 | 23 | void void_return(); 24 | 25 | // This class is suppressed by the configuration so that not to be binded 26 | class SuppressedClass 27 | { 28 | }; 29 | 30 | // This function should be suppressed as well because the parameter is of a 31 | // suppressed type. 32 | void function_with_suppressed_param(const SuppressedClass &); 33 | 34 | // This class is suppressed by the configuration so that not to be binded 35 | template 36 | class SuppressedTemplateClass 37 | { 38 | }; 39 | 40 | // This function should be suppressed as well because the parameter is of a 41 | // suppressed type. 42 | void function_with_suppressed_template_param( 43 | const SuppressedTemplateClass &); 44 | 45 | } // namespace chimera_test 46 | -------------------------------------------------------------------------------- /test/examples/01_function/function.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | try: 4 | import function_pybind11 as py11 5 | has_pybind11 = True 6 | except: 7 | has_pybind11 = False 8 | 9 | import function_boost_python as boost 10 | 11 | 12 | class TestFunction(unittest.TestCase): 13 | 14 | def test_function_py11(self): 15 | if not has_pybind11: 16 | return 17 | 18 | self.assertEqual(py11.add(), 3) 19 | self.assertEqual(py11.add(3, 4), 7) 20 | self.assertEqual(py11.add(i=5, j=6), 11) 21 | 22 | self.assertEqual(py11.inline_add(), 3) 23 | self.assertEqual(py11.inline_add(3, 4), 7) 24 | self.assertEqual(py11.inline_add(i=5, j=6), 11) 25 | 26 | py11.void_return() 27 | 28 | dummy = py11.Dummy() 29 | dummy.val = 5 30 | self.assertEqual(py11.void_pointer_param(dummy), 5) 31 | 32 | py11.void_param() 33 | 34 | self.assertFalse(hasattr(py11, 'function_with_suppressed_param')) 35 | self.assertFalse(hasattr(py11, 'function_with_suppressed_template_param')) 36 | 37 | 38 | def test_function_bp(self): 39 | self.assertEqual(boost.add(), 3) 40 | self.assertEqual(boost.add(3, 4), 7) 41 | self.assertEqual(boost.add(i=5, j=6), 11) 42 | 43 | self.assertEqual(boost.inline_add(), 3) 44 | self.assertEqual(boost.inline_add(3, 4), 7) 45 | self.assertEqual(boost.inline_add(i=5, j=6), 11) 46 | 47 | boost.void_return() 48 | 49 | dummy = boost.Dummy() 50 | dummy.val = 5 51 | # TODO: void pointer parameter doesn't work with Boost.Python 52 | # self.assertEqual(boost.void_pointer_param(dummy), 5) 53 | 54 | boost.void_param() 55 | 56 | self.assertFalse(hasattr(boost, 'function_with_suppressed_param')) 57 | self.assertFalse(hasattr(boost, 'function_with_suppressed_template_param')) 58 | 59 | 60 | if __name__ == '__main__': 61 | unittest.main() 62 | -------------------------------------------------------------------------------- /test/examples/01_function/function_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | 'template chimera_test::SuppressedTemplateClass': null 6 | 'chimera_test::SuppressedClass': null 7 | -------------------------------------------------------------------------------- /test/examples/01_function/function_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | 'template chimera_test::SuppressedTemplateClass': null 6 | 'chimera_test::SuppressedClass': null 7 | -------------------------------------------------------------------------------- /test/examples/02_class/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "class") 2 | 3 | chimera_add_binding_tests(${test_name} 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 12 | -------------------------------------------------------------------------------- /test/examples/02_class/class.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | 'chimera_test::detail': null 5 | -------------------------------------------------------------------------------- /test/examples/03_smart_pointers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "smart_pointers") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_pybind11.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | # TODO(JS): Disabled Boost.Python test until resolving issue of returning unique_ptr 12 | # chimera_add_binding_test_boost_python(${test_name}_boost_python 13 | # SOURCES ${test_name}.h 14 | # EXTRA_SOURCES ${test_name}.cpp 15 | # NAMESPACES chimera_test 16 | # CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_boost_python.yaml 17 | # COPY_MODULE 18 | # ) 19 | 20 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 21 | -------------------------------------------------------------------------------- /test/examples/03_smart_pointers/smart_pointers.cpp: -------------------------------------------------------------------------------- 1 | #include "smart_pointers.h" 2 | 3 | namespace chimera_test { 4 | 5 | //============================================================================== 6 | std::unique_ptr create_example() 7 | { 8 | return std::unique_ptr(new Example()); 9 | } 10 | 11 | //============================================================================== 12 | std::shared_ptr create_example_shared() 13 | { 14 | return std::shared_ptr(new ExampleShared()); 15 | } 16 | 17 | } // namespace chimera_test 18 | -------------------------------------------------------------------------------- /test/examples/03_smart_pointers/smart_pointers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace chimera_test { 8 | 9 | class Example {}; 10 | 11 | std::unique_ptr create_example(); 12 | 13 | // Taking unique_ptr by value or reference is not allowed by pybind11 14 | // See: https://pybind11.readthedocs.io/en/master/advanced/smart_ptrs.html#std-unique-ptr 15 | // void take_unique_ptr_by_value(std::unique_ptr example); 16 | // void take_unique_ptr_by_reference(std::unique_ptr& example); 17 | 18 | class ExampleShared {}; 19 | 20 | // By default, pybind11 holds objects as unique_ptr. In order to use shared_ptr, 21 | // you should specify the hold type in the Chimera configuration file something 22 | // like: 23 | // 24 | // classes: 25 | // 'ExampleShared': 26 | // held_type: 'std::shared_ptr' 27 | // 28 | // Otherwise, it will causes segfaults. 29 | std::shared_ptr create_example_shared(); 30 | 31 | } // namespace chimera_test 32 | -------------------------------------------------------------------------------- /test/examples/03_smart_pointers/smart_pointers.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | try: 4 | import smart_pointers_pybind11 as py11 5 | has_pybind11 = True 6 | except: 7 | has_pybind11 = False 8 | 9 | try: 10 | import smart_pointers_boost_python as boost 11 | has_boost_python = True 12 | except: 13 | has_boost_python = False 14 | 15 | class TestFunction(unittest.TestCase): 16 | 17 | def test_function_py11(self): 18 | if not has_pybind11: 19 | return 20 | 21 | example_unique_ptr = py11.create_example() 22 | example_shared_ptr = py11.create_example_shared() 23 | 24 | def test_function_bp(self): 25 | if not has_boost_python: 26 | return 27 | 28 | # TODO(JS): Boost.Python requires to specify held_type for smart pointers 29 | # Following test is disabled for now 30 | # example_unique_ptr = boost.create_example() 31 | 32 | if __name__ == '__main__': 33 | unittest.main() 34 | -------------------------------------------------------------------------------- /test/examples/03_smart_pointers/smart_pointers_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | 'chimera_test::ExampleShared': 6 | held_type: 'std::shared_ptr' 7 | -------------------------------------------------------------------------------- /test/examples/03_smart_pointers/smart_pointers_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | 'chimera_test::ExampleShared': 6 | held_type: 'std::shared_ptr' 7 | -------------------------------------------------------------------------------- /test/examples/04_enumeration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "enumeration") 2 | 3 | chimera_add_binding_tests(${test_name} 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 12 | -------------------------------------------------------------------------------- /test/examples/04_enumeration/enumeration.cpp: -------------------------------------------------------------------------------- 1 | #include "enumeration.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/04_enumeration/enumeration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace chimera_test 4 | { 5 | 6 | struct Animal 7 | { 8 | enum Type 9 | { 10 | Dog = 0, 11 | Cat 12 | }; 13 | 14 | Animal(Type type) : type(type) 15 | { 16 | } 17 | 18 | Type type; 19 | }; 20 | 21 | namespace test1 22 | { 23 | 24 | // Anonymous enum 25 | enum 26 | { 27 | TRUE, 28 | FALSE, 29 | }; 30 | 31 | } // namespace test1 32 | 33 | } // namespace chimera_test 34 | -------------------------------------------------------------------------------- /test/examples/04_enumeration/enumeration.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | try: 4 | import enumeration_pybind11 as py11 5 | has_pybind11 = True 6 | except: 7 | has_pybind11 = False 8 | 9 | import enumeration_boost_python as boost 10 | 11 | 12 | class TestFunction(unittest.TestCase): 13 | 14 | def test_function_py11(self): 15 | if not has_pybind11: 16 | return 17 | 18 | animal = py11.Animal(py11.Animal.Cat) 19 | self.assertEqual(animal.type, py11.Animal.Cat) 20 | 21 | 22 | def test_function_bp(self): 23 | animal = boost.Animal(boost.Animal.Type.Cat) 24 | self.assertEqual(animal.type, boost.Animal.Type.Cat) 25 | 26 | 27 | if __name__ == '__main__': 28 | unittest.main() 29 | -------------------------------------------------------------------------------- /test/examples/04_enumeration/enumeration.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/05_variable/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "variable") 2 | 3 | chimera_add_binding_tests(${test_name} 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 12 | -------------------------------------------------------------------------------- /test/examples/05_variable/variable.cpp: -------------------------------------------------------------------------------- 1 | #include "variable.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/05_variable/variable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | const int const_int_val = 10; 9 | 10 | } // namespace chimera_test 11 | -------------------------------------------------------------------------------- /test/examples/05_variable/variable.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | try: 4 | import variable_pybind11 as py11 5 | has_pybind11 = True 6 | except: 7 | has_pybind11 = False 8 | 9 | import variable_boost_python as boost 10 | 11 | 12 | class TestFunction(unittest.TestCase): 13 | 14 | def test_function_py11(self): 15 | if not has_pybind11: 16 | return 17 | 18 | self.assertEqual(py11.const_int_val, 10) 19 | 20 | def test_function_bp(self): 21 | self.assertEqual(boost.const_int_val, 10) 22 | 23 | 24 | if __name__ == '__main__': 25 | unittest.main() 26 | -------------------------------------------------------------------------------- /test/examples/05_variable/variable.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/06_template_class/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "template_class") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/pybind11.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_boost_python(${test_name}_boost_python 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/boost_python.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/06_template_class/boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | "chimera_test::Vector": 6 | name: VectorXd 7 | -------------------------------------------------------------------------------- /test/examples/06_template_class/pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | "chimera_test::Vector": 6 | name: VectorXd 7 | -------------------------------------------------------------------------------- /test/examples/06_template_class/template_class.cpp: -------------------------------------------------------------------------------- 1 | #include "template_class.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/06_template_class/template_class.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | template 9 | class Vector 10 | { 11 | public: 12 | Vector() = default; 13 | 14 | void resize(int dim) 15 | { 16 | m_data.resize(dim); 17 | } 18 | 19 | int size() const 20 | { 21 | return m_data.size(); 22 | } 23 | 24 | private: 25 | std::vector m_data; 26 | }; 27 | 28 | // Explicit instantiation declaration 29 | template class Vector; 30 | 31 | } // namespace chimera_test 32 | -------------------------------------------------------------------------------- /test/examples/06_template_class/template_class.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import template_class_pybind11 as py11 4 | import template_class_boost_python as boost 5 | 6 | 7 | class TestTemplateClass(unittest.TestCase): 8 | 9 | def _test_template_class(self, binding): 10 | v = binding.VectorXd() 11 | self.assertEqual(v.size(), 0) 12 | 13 | v.resize(10) 14 | self.assertEqual(v.size(), 10) 15 | 16 | def test_template_class(self): 17 | self._test_template_class(py11) 18 | self._test_template_class(boost) 19 | 20 | 21 | if __name__ == '__main__': 22 | unittest.main() 23 | -------------------------------------------------------------------------------- /test/examples/07_typedef/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "typedef") 2 | 3 | chimera_add_binding_tests(${test_name} 4 | SOURCES ${test_name}.h 5 | NAMESPACES chimera_test 6 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}.yaml 7 | COPY_MODULE 8 | ) 9 | 10 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 11 | -------------------------------------------------------------------------------- /test/examples/07_typedef/typedef.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace chimera_test 9 | { 10 | 11 | namespace test1 12 | { 13 | 14 | using Float = float; 15 | using Double = double; 16 | 17 | } // namespace test1 18 | 19 | namespace test2 20 | { 21 | 22 | class Position 23 | { 24 | public: 25 | Position() = default; 26 | }; 27 | 28 | template 29 | class Vector 30 | { 31 | public: 32 | Vector() = default; 33 | }; 34 | 35 | } // namespace test2 36 | 37 | namespace test3 38 | { 39 | 40 | // Not binded because the underlying type, std::string, is not binded 41 | // TODO: Fix to generate bind since std::string is binded by Boost.Python and 42 | // pybind11 43 | using String = std::string; 44 | using String2 = String; 45 | 46 | using Position = test2::Position; 47 | using Position2 = Position; 48 | 49 | // Not binded because it's a templated type alias 50 | template 51 | using Vector = test2::Vector; 52 | 53 | // Not binded because of missing binding for the template class 54 | using Vectori = test2::Vector; 55 | using Vectord = Vector; 56 | 57 | // Not binded because the underlying type, std::string, is not binded 58 | // TODO: Fix to generate bind since std::string is binded by Boost.Python and 59 | // pybind11 60 | typedef std::string StringTypedef; 61 | typedef StringTypedef StringTypedef2; 62 | 63 | typedef test2::Position PositionTypedef; 64 | typedef PositionTypedef PositionTypedef2; 65 | 66 | // Not binded because of missing binding for the template class 67 | typedef test2::Vector VectoriTypedef; 68 | typedef Vector VectordTypedef; 69 | 70 | } // namespace test3 71 | 72 | } // namespace chimera_test 73 | -------------------------------------------------------------------------------- /test/examples/07_typedef/typedef.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/20_eigen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "eigen") 2 | 3 | find_package(Eigen3 QUIET) 4 | if(NOT EIGEN3_FOUND) 5 | message(WARNING "${test_name} requires Eigen3, but couldn't find it. \ 6 | Disabling ${test_name}.") 7 | return() 8 | endif() 9 | 10 | chimera_add_binding_test_boost_python(${test_name}_boost_python 11 | SOURCES ${test_name}.h 12 | EXTRA_SOURCES ${test_name}.cpp 13 | NAMESPACES chimera_test 14 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_boost_python.yaml 15 | COPY_MODULE 16 | INCLUDE_DIRS ${EIGEN3_INCLUDE_DIRS} 17 | ) 18 | 19 | chimera_add_binding_test_pybind11(${test_name}_pybind11 20 | SOURCES ${test_name}.h 21 | EXTRA_SOURCES ${test_name}.cpp 22 | NAMESPACES chimera_test 23 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_pybind11.yaml 24 | COPY_MODULE 25 | INCLUDE_DIRS ${EIGEN3_INCLUDE_DIRS} 26 | ) 27 | 28 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 29 | -------------------------------------------------------------------------------- /test/examples/20_eigen/eigen.cpp: -------------------------------------------------------------------------------- 1 | #include "eigen.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | void function_with_map_param(Eigen::Map map) 8 | { 9 | std::cout << "size: " << map.size() << std::endl; 10 | } 11 | 12 | //============================================================================== 13 | void test_function_with_map_param() 14 | { 15 | Eigen::VectorXd vec = Eigen::VectorXd::Zero(10); 16 | Eigen::Map map(vec.data(), vec.size()); 17 | function_with_map_param(map); 18 | } 19 | 20 | } // namespace chimera_test 21 | -------------------------------------------------------------------------------- /test/examples/20_eigen/eigen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace chimera_test 7 | { 8 | 9 | template 10 | void print_size(const Eigen::EigenBase &b) 11 | { 12 | std::cout << "size (rows, cols): " << b.size() << " (" << b.rows() << ", " 13 | << b.cols() << ")" << std::endl; 14 | } 15 | 16 | inline void test_print_size() 17 | { 18 | print_size(Eigen::Matrix3d::Identity()); 19 | } 20 | 21 | template 22 | void print_block(const Eigen::DenseBase &b, int x, int y, int r, int c) 23 | { 24 | std::cout << "block: " << b.block(x, y, r, c) << std::endl; 25 | } 26 | 27 | inline void test_print_block() 28 | { 29 | print_block(Eigen::Matrix3d::Identity(), 1, 2, 2, 1); 30 | } 31 | 32 | template 33 | void print_max_coeff(const Eigen::ArrayBase &a) 34 | { 35 | std::cout << "max: " << a.maxCoeff() << std::endl; 36 | } 37 | 38 | inline void test_print_max_coeff() 39 | { 40 | print_max_coeff(Eigen::ArrayXd::Zero(3)); 41 | } 42 | 43 | template 44 | void print_inv_cond(const Eigen::MatrixBase &a) 45 | { 46 | const typename Eigen::JacobiSVD< 47 | typename Derived::PlainObject>::SingularValuesType &sing_vals 48 | = a.jacobiSvd().singularValues(); 49 | std::cout << "inv cond: " << sing_vals(sing_vals.size() - 1) / sing_vals(0) 50 | << std::endl; 51 | } 52 | 53 | inline void test_print_inv_cond() 54 | { 55 | print_inv_cond(Eigen::Matrix3d::Identity()); 56 | } 57 | 58 | void function_with_map_param(Eigen::Map map); 59 | 60 | void test_function_with_map_param(); 61 | 62 | } // namespace chimera_test 63 | -------------------------------------------------------------------------------- /test/examples/20_eigen/eigen.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import eigen_pybind11 as py11 4 | import eigen_boost_python as boost 5 | 6 | 7 | class TestFunction(unittest.TestCase): 8 | 9 | def test_function_py11(self): 10 | 11 | self.assertTrue(hasattr(py11, 'print_size')) 12 | self.assertTrue(hasattr(py11, 'print_block')) 13 | self.assertTrue(hasattr(py11, 'print_max_coeff')) 14 | self.assertTrue(hasattr(py11, 'print_inv_cond')) 15 | 16 | py11.test_print_size() 17 | py11.test_print_block() 18 | py11.test_print_max_coeff() 19 | py11.test_print_inv_cond() 20 | 21 | self.assertFalse(hasattr(py11, 'function_with_map_param')) 22 | self.assertTrue(hasattr(py11, 'test_function_with_map_param')) 23 | 24 | 25 | def test_function_bp(self): 26 | self.assertTrue(hasattr(boost, 'print_size')) 27 | self.assertTrue(hasattr(boost, 'print_block')) 28 | self.assertTrue(hasattr(boost, 'print_max_coeff')) 29 | self.assertTrue(hasattr(boost, 'print_inv_cond')) 30 | 31 | boost.test_print_size() 32 | boost.test_print_block() 33 | boost.test_print_max_coeff() 34 | boost.test_print_inv_cond() 35 | 36 | # Boost.Python < 1.65.1 doesn't work for Eigen::Map parameter 37 | # Once Boost.Python >= 1.65.1 becomes the minimum required version, change following check to self.assertTrue(...) 38 | self.assertFalse(hasattr(boost, 'function_with_map_param')) 39 | 40 | self.assertTrue(hasattr(boost, 'test_function_with_map_param')) 41 | 42 | 43 | if __name__ == '__main__': 44 | unittest.main() 45 | -------------------------------------------------------------------------------- /test/examples/20_eigen/eigen_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | # Boost.Python < 1.65.1 doesn't work for Eigen::Map parameter 5 | # Once Boost.Python >= 1.65.1 becomes the minimum required version, remove followings 6 | classes: 7 | 'template class Eigen::Map': null 8 | -------------------------------------------------------------------------------- /test/examples/20_eigen/eigen_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | template: 5 | file: 6 | header: | 7 | #include 8 | classes: 9 | 'template class Eigen::Map': null 10 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/01_first_steps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "first_steps") 2 | 3 | chimera_add_binding_test_boost_python(${test_name}_boost_python 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_boost_python.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_pybind11(${test_name}_pybind11 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_pybind11.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/01_first_steps/chimera_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/01_first_steps/chimera_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/01_first_steps/first_steps.cpp: -------------------------------------------------------------------------------- 1 | #include "first_steps.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | int add(int i, int j) 8 | { 9 | return i + j; 10 | } 11 | 12 | //============================================================================== 13 | int add_def_args(int i, int j) 14 | { 15 | return i + j; 16 | } 17 | 18 | } // namespace chimera_test 19 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/01_first_steps/first_steps.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //////////////////////////////////////////////////////////////////////////////// 4 | // 5 | // Following examples are from 6 | // https://pybind11.readthedocs.io/en/stable/basics.html 7 | // 8 | //////////////////////////////////////////////////////////////////////////////// 9 | 10 | namespace chimera_test 11 | { 12 | 13 | //----------------------------------------- 14 | // Creating bindings for a simple function 15 | //----------------------------------------- 16 | 17 | /// Returns sum of two integers 18 | int add(int i, int j); 19 | 20 | //------------------- 21 | // Keyword arguments 22 | //------------------- 23 | 24 | // Keyword argument is supported by default 25 | 26 | //------------------- 27 | // Default arguments 28 | //------------------- 29 | 30 | /// @brief Returns sum of two integers 31 | int add_def_args(int i = 1, int j = 2); 32 | 33 | } // namespace chimera_test 34 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/01_first_steps/first_steps.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import first_steps_pybind11 as py11 4 | import first_steps_boost_python as boost 5 | 6 | 7 | class TestFirstSteps(unittest.TestCase): 8 | 9 | def _test_function(self, binding): 10 | # Test function docstring 11 | self.assertTrue("Returns sum of two integers" in binding.add.__doc__) 12 | 13 | # TODO: Docstring doesn't get generated when Doxygen keyword encountered. 14 | # See #332. 15 | self.assertFalse("Returns sum of two integers" in binding.add_def_args.__doc__) 16 | 17 | self.assertEqual(binding.add(1, 2), 3) 18 | self.assertEqual(binding.add(i=3, j=4), 7) 19 | 20 | self.assertEqual(binding.add_def_args(), 3) 21 | self.assertEqual(binding.add_def_args(2), 4) 22 | self.assertEqual(binding.add_def_args(3, 4), 7) 23 | self.assertEqual(binding.add_def_args(i=5, j=6), 11) 24 | 25 | def test_function(self): 26 | self._test_function(py11) 27 | self._test_function(boost) 28 | 29 | 30 | if __name__ == '__main__': 31 | unittest.main() 32 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/02_object_oriented_code/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "object_oriented_code") 2 | 3 | chimera_add_binding_test_boost_python(${test_name}_boost_python 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_boost_python.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_pybind11(${test_name}_pybind11 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_pybind11.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/02_object_oriented_code/chimera_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | types: 5 | "const std::string &": 6 | return_value_policy: copy_const_reference 7 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/02_object_oriented_code/chimera_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | types: 5 | "const std::string &": 6 | return_value_policy: copy 7 | classes: 8 | "chimera_test::test1::Pet": 9 | dynamic_attr: True 10 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/02_object_oriented_code/object_oriented_code.cpp: -------------------------------------------------------------------------------- 1 | #include "object_oriented_code.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/01_basics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(01_first_steps) 2 | add_subdirectory(02_object_oriented_code) 3 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/01_functions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "functions") 2 | 3 | chimera_add_binding_test_boost_python(${test_name}_boost_python 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_boost_python.yaml 8 | COPY_MODULE 9 | INCLUDE_DIRS ${pybind11_INCLUDE_DIRS} 10 | LINK_LIBRARIES ${pybind11_LIBRARIES} 11 | ) 12 | 13 | chimera_add_binding_test_pybind11(${test_name}_pybind11 14 | SOURCES ${test_name}.h 15 | EXTRA_SOURCES ${test_name}.cpp 16 | NAMESPACES chimera_test 17 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_pybind11.yaml 18 | COPY_MODULE 19 | INCLUDE_DIRS ${pybind11_INCLUDE_DIRS} 20 | LINK_LIBRARIES ${pybind11_LIBRARIES} 21 | ) 22 | 23 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 24 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/01_functions/chimera_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/01_functions/chimera_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/01_functions/functions.cpp: -------------------------------------------------------------------------------- 1 | #include "functions.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | void print_dict(const pybind11::dict &dict) 8 | { 9 | /* Easily interact with Python types */ 10 | for (auto item : dict) 11 | std::cout << "key=" << std::string(pybind11::str(item.first)) << ", " 12 | << "value=" << std::string(pybind11::str(item.second)) 13 | << std::endl; 14 | } 15 | 16 | } // namespace chimera_test 17 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/01_functions/functions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | //////////////////////////////////////////////////////////////////////////////// 9 | // 10 | // Following examples are from 11 | // https://pybind11.readthedocs.io/en/stable/advanced/functions.html 12 | // 13 | //////////////////////////////////////////////////////////////////////////////// 14 | 15 | namespace chimera_test 16 | { 17 | 18 | //----------------------- 19 | // Return value policies 20 | //----------------------- 21 | 22 | // TODO: Add examples 23 | 24 | //-------------------------- 25 | // Additional call policies 26 | //-------------------------- 27 | 28 | // TODO: Add examples 29 | 30 | //----------------------------- 31 | // Python objects as arguments 32 | //----------------------------- 33 | 34 | // TODO: Fix not able to generate function with arguments passed by value 35 | void print_dict(const pybind11::dict &dict); 36 | 37 | //------------------------------ 38 | // Accepting *args and **kwargs 39 | //------------------------------ 40 | 41 | // TODO: Add examples 42 | 43 | //----------------------------- 44 | // Default arguments revisited 45 | //----------------------------- 46 | 47 | // TODO: Add examples 48 | 49 | //-------------------------- 50 | // Non-converting arguments 51 | //-------------------------- 52 | 53 | // TODO: Add examples 54 | 55 | //---------------------------------- 56 | // Allow/Prohibiting None arguments 57 | //---------------------------------- 58 | 59 | // TODO: Add examples 60 | 61 | //--------------------------- 62 | // Overload resolution order 63 | //--------------------------- 64 | 65 | // TODO: Add examples 66 | 67 | } // namespace chimera_test 68 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/01_functions/functions.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import functions_pybind11 as py11 4 | import functions_boost_python as boost 5 | 6 | 7 | class TestFunctions(unittest.TestCase): 8 | 9 | def _test_function(self, binding): 10 | if binding is py11: 11 | self.assertTrue(hasattr(binding, 'print_dict')) 12 | binding.print_dict({'foo': 123, 'bar': 'hello'}) 13 | 14 | def test_function(self): 15 | self._test_function(py11) 16 | self._test_function(boost) 17 | 18 | 19 | if __name__ == '__main__': 20 | unittest.main() 21 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/02_classes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "classes") 2 | 3 | chimera_add_binding_test_boost_python(${test_name}_boost_python 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_boost_python.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_pybind11(${test_name}_pybind11 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_pybind11.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/02_classes/chimera_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | functions: 5 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator+=(const chimera_test::test3::Vector2&)": 6 | return_value_policy: "copy_non_const_reference" 7 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator-=(const chimera_test::test3::Vector2&)": 8 | return_value_policy: "copy_non_const_reference" 9 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator*=(const chimera_test::test3::Vector2&)": 10 | return_value_policy: "copy_non_const_reference" 11 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator/=(const chimera_test::test3::Vector2&)": 12 | return_value_policy: "copy_non_const_reference" 13 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator+=(float)": 14 | return_value_policy: "copy_non_const_reference" 15 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator-=(float)": 16 | return_value_policy: "copy_non_const_reference" 17 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator*=(float)": 18 | return_value_policy: "copy_non_const_reference" 19 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator/=(float)": 20 | return_value_policy: "copy_non_const_reference" 21 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/02_classes/chimera_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | "chimera_test::test1::Animal": 6 | allow_inheritance: True 7 | "chimera_test::test1::Dog": 8 | allow_inheritance: True 9 | "chimera_test::test2::Animal": 10 | allow_inheritance: True 11 | "chimera_test::test2::Dog": 12 | allow_inheritance: True 13 | "chimera_test::test2::Husky": 14 | allow_inheritance: True 15 | functions: 16 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator+=(const chimera_test::test3::Vector2&)": 17 | return_value_policy: "reference_internal" 18 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator-=(const chimera_test::test3::Vector2&)": 19 | return_value_policy: "reference_internal" 20 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator*=(const chimera_test::test3::Vector2&)": 21 | return_value_policy: "reference_internal" 22 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator/=(const chimera_test::test3::Vector2&)": 23 | return_value_policy: "reference_internal" 24 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator+=(float)": 25 | return_value_policy: "reference_internal" 26 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator-=(float)": 27 | return_value_policy: "reference_internal" 28 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator*=(float)": 29 | return_value_policy: "reference_internal" 30 | "chimera_test::test3::Vector2& chimera_test::test3::Vector2::operator/=(float)": 31 | return_value_policy: "reference_internal" 32 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/02_classes/classes.cpp: -------------------------------------------------------------------------------- 1 | #include "classes.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/03_exceptions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "exceptions") 2 | 3 | chimera_add_binding_test_boost_python(${test_name}_boost_python 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_boost_python.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_pybind11(${test_name}_pybind11 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_pybind11.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/03_exceptions/chimera_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/03_exceptions/chimera_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/03_exceptions/exceptions.cpp: -------------------------------------------------------------------------------- 1 | #include "exceptions.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/03_exceptions/exceptions.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import exceptions_pybind11 as py11 4 | import exceptions_boost_python as boost 5 | 6 | 7 | class TestExceptions(unittest.TestCase): 8 | 9 | def _test_built_in_exception_translation(self, binding): 10 | if binding is py11: 11 | self.assertRaises(RuntimeError, binding.throw_std_exception) 12 | self.assertRaises(MemoryError, binding.throw_bad_alloc) 13 | self.assertRaises(ValueError, binding.throw_domain_error) 14 | self.assertRaises(ValueError, binding.throw_invalid_argument) 15 | self.assertRaises(ValueError, binding.throw_length_error) 16 | self.assertRaises(IndexError, binding.throw_out_of_range) 17 | self.assertRaises(ValueError, binding.throw_range_error) 18 | # binding.throw_overflow_error is generated only for pybind11 >= 2.5.0 19 | if hasattr(binding, 'throw_overflow_error'): 20 | self.assertRaises(OverflowError, binding.throw_overflow_error) 21 | # TODO: Fill in Boost.Python handling of exceptions. 22 | 23 | def test_built_in_exception_translation(self): 24 | self._test_built_in_exception_translation(py11) 25 | self._test_built_in_exception_translation(boost) 26 | 27 | 28 | if __name__ == '__main__': 29 | unittest.main() 30 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/05_type_conversions/03_functional/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "functional") 2 | 3 | # TODO: Fix binding for Boost.Python 4 | # chimera_add_binding_test_boost_python(${test_name}_boost_python 5 | # SOURCES ${test_name}.h 6 | # EXTRA_SOURCES ${test_name}.cpp 7 | # NAMESPACES chimera_test 8 | # CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_boost_python.yaml 9 | # COPY_MODULE 10 | # ) 11 | 12 | chimera_add_binding_test_pybind11(${test_name}_pybind11 13 | SOURCES ${test_name}.h 14 | EXTRA_SOURCES ${test_name}.cpp 15 | NAMESPACES chimera_test 16 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/chimera_pybind11.yaml 17 | COPY_MODULE 18 | ) 19 | 20 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 21 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/05_type_conversions/03_functional/chimera_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/05_type_conversions/03_functional/chimera_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | template: 5 | file: 6 | header: | 7 | #include 8 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/05_type_conversions/03_functional/functional.cpp: -------------------------------------------------------------------------------- 1 | #include "functional.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | int func_arg(const std::function &f) 8 | { 9 | return f(10); 10 | } 11 | 12 | //============================================================================== 13 | std::function func_ret(const std::function &f) 14 | { 15 | return [f](int i) { return f(i) + 1; }; 16 | } 17 | 18 | //============================================================================== 19 | pybind11::cpp_function func_cpp() 20 | { 21 | return pybind11::cpp_function([](int i) { return i + 1; }, 22 | pybind11::arg("number")); 23 | } 24 | 25 | } // namespace chimera_test 26 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/05_type_conversions/03_functional/functional.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | //////////////////////////////////////////////////////////////////////////////// 9 | // 10 | // The following examples are from 11 | // https://pybind11.readthedocs.io/en/stable/advanced/cast/functional.html 12 | // 13 | //////////////////////////////////////////////////////////////////////////////// 14 | 15 | namespace chimera_test 16 | { 17 | 18 | //------------------------------------------- 19 | // Callbacks and passing anonymous functions 20 | //------------------------------------------- 21 | 22 | int func_arg(const std::function &f); 23 | 24 | std::function func_ret(const std::function &f); 25 | 26 | pybind11::cpp_function func_cpp(); 27 | 28 | //--------------------------------------------- 29 | // TODO: Add more sections... 30 | //--------------------------------------------- 31 | 32 | } // namespace chimera_test 33 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/05_type_conversions/03_functional/functional.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import functional_pybind11 as py11 4 | # import functional_boost_python as boost # TODO: Fix binding for Boost.Python 5 | 6 | 7 | class TestFunctional(unittest.TestCase): 8 | 9 | def _test_callbacks_and_passing_anonymous_functions(self, binding): 10 | def square(i): 11 | return i * i 12 | 13 | self.assertEqual(binding.func_arg(square), 100) 14 | 15 | square_plus_1 = binding.func_ret(square) 16 | self.assertEqual(square_plus_1(4), 17) 17 | 18 | plus_1 = binding.func_cpp() 19 | self.assertEqual(plus_1(number=43), 44) 20 | 21 | def test_callbacks_and_passing_anonymous_functions(self): 22 | self._test_callbacks_and_passing_anonymous_functions(py11) 23 | # TODO: Fix binding for Boost.Python 24 | # self._test_callbacks_and_passing_anonymous_functions(boost) 25 | 26 | 27 | if __name__ == '__main__': 28 | unittest.main() 29 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/05_type_conversions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(03_functional) 2 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/02_advanced/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(01_functions) 2 | add_subdirectory(02_classes) 3 | add_subdirectory(03_exceptions) 4 | add_subdirectory(05_type_conversions) 5 | -------------------------------------------------------------------------------- /test/examples/30_pybind11_examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(01_basics) 2 | add_subdirectory(02_advanced) 3 | -------------------------------------------------------------------------------- /test/examples/99_dart_example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | chimera_add_binding_test_boost_python(dart_example_boost_python 2 | SOURCES dart_example.h 3 | NAMESPACES dart 4 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/dart_example.yaml 5 | COPY_MODULE 6 | ) 7 | 8 | #chimera_add_binding_test_pybind11(dart_example_pybind11 9 | # EXCLUDE_FROM_ALL 10 | # SOURCES dart_example.h 11 | # NAMESPACES dart 12 | # CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/dart_example.yaml 13 | # COPY_MODULE 14 | #) 15 | -------------------------------------------------------------------------------- /test/examples/99_dart_example/dart_example.h: -------------------------------------------------------------------------------- 1 | #ifndef __DART_EXAMPLE_H__ 2 | #define __DART_EXAMPLE_H__ 3 | 4 | namespace dart 5 | { 6 | namespace common 7 | { 8 | 9 | namespace signal 10 | { 11 | namespace detail 12 | { 13 | 14 | template 15 | struct DefaultCombiner 16 | { 17 | }; 18 | 19 | } // namespace detail 20 | } // namespace signal 21 | 22 | template class Combiner = signal::detail::DefaultCombiner> 24 | class Signal; 25 | 26 | template 27 | class Signal 28 | { 29 | public: 30 | void f(){/* do nothing */}; 31 | }; 32 | 33 | template 34 | class SlotRegister 35 | { 36 | }; 37 | 38 | } // namespace common 39 | 40 | namespace dynamics 41 | { 42 | 43 | class Frame 44 | { 45 | }; 46 | 47 | class Entity 48 | { 49 | using FrameChangedSignal = common::Signal; 51 | 52 | FrameChangedSignal mFrameChangedSignal; 53 | }; 54 | 55 | } // namespace dynamics 56 | } // namespace dart 57 | 58 | #endif // __DART_EXAMPLE_H__ 59 | -------------------------------------------------------------------------------- /test/examples/99_dart_example/dart_example.py: -------------------------------------------------------------------------------- 1 | # import dart_example_pybind11 2 | import dart_example_boost_python 3 | -------------------------------------------------------------------------------- /test/examples/99_dart_example/dart_example.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'dart': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/cmake/chimeraTest.cmake: -------------------------------------------------------------------------------- 1 | # Include helpers to define tests for each language. 2 | include(chimeraTestBoostPython) 3 | include(chimeraTestPybind11) 4 | 5 | # Define a single helper function that runs all tests using the same configuration. 6 | # (This can be used in simpler tests where all of the bindings can use the same 7 | # configuration YAML.) 8 | # 9 | # chimera_add_binding_tests(target 10 | # SOURCES source1_file [source2_file ...] 11 | # [EXTRA_SOURCES source1_file ...] 12 | # [DESTINATION destination_dir] # Defaults to `target` 13 | # [MODULE module] # Defaults to `target` 14 | # [CONFIGURATION config_file] 15 | # [NAMESPACES namespace1 namespace2 ...]) 16 | # [DEBUG] 17 | # [EXCLUDE_FROM_ALL] 18 | # [COPY_MODULE] 19 | # 20 | function(chimera_add_binding_tests test_name) 21 | chimera_add_binding_test_boost_python(${test_name}_boost_python ${ARGN}) 22 | chimera_add_binding_test_pybind11(${test_name}_pybind11 ${ARGN}) 23 | endfunction(chimera_add_binding_tests) 24 | 25 | # Add a Python test that will run against the generated code. The Python test 26 | # will be able to run through CTest 27 | # 28 | # chimera_add_binding_tests(test_name test_script) 29 | function(chimera_add_python_test test_name python_filename) 30 | add_test( 31 | NAME ${test_name} 32 | COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/${python_filename} 33 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 34 | ) 35 | endfunction(chimera_add_python_test) 36 | -------------------------------------------------------------------------------- /test/examples/regression/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(issue105_extra_commas) 2 | add_subdirectory(issue148_lambda_function) 3 | add_subdirectory(issue216_template_param) 4 | add_subdirectory(issue228_template_type_alias) 5 | add_subdirectory(issue262_static_method) 6 | add_subdirectory(issue297_template_variable) 7 | add_subdirectory(issue310_nested_class_name) 8 | add_subdirectory(issue328_dependent_name) 9 | -------------------------------------------------------------------------------- /test/examples/regression/issue105_extra_commas/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue105_extra_commas") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | NAMESPACES chimera_test 6 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/pybind11.yaml 7 | COPY_MODULE 8 | ) 9 | 10 | chimera_add_binding_test_boost_python(${test_name}_boost_python 11 | SOURCES ${test_name}.h 12 | NAMESPACES chimera_test 13 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/boost_python.yaml 14 | COPY_MODULE 15 | ) 16 | 17 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 18 | -------------------------------------------------------------------------------- /test/examples/regression/issue105_extra_commas/boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | "chimera_test::Derived": 6 | bases: 7 | - qualified_name: "chimera_test::Base1" 8 | - qualified_name: "chimera_test::Base2" 9 | -------------------------------------------------------------------------------- /test/examples/regression/issue105_extra_commas/issue105_extra_commas.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | class Base1 9 | { 10 | public: 11 | Base1() = default; 12 | }; 13 | 14 | class Base2 15 | { 16 | public: 17 | Base2() = default; 18 | }; 19 | 20 | class Derived : public Base1, public Base2 21 | { 22 | public: 23 | Derived() = default; 24 | }; 25 | 26 | } // namespace chimera_test 27 | -------------------------------------------------------------------------------- /test/examples/regression/issue105_extra_commas/issue105_extra_commas.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import issue105_extra_commas_boost_python as boost 4 | import issue105_extra_commas_pybind11 as py11 5 | 6 | class TestIssue105(unittest.TestCase): 7 | 8 | def _test_issue105(self, binding): 9 | self.assertTrue(hasattr(binding, 'Base1')) 10 | self.assertTrue(hasattr(binding, 'Base2')) 11 | self.assertTrue(hasattr(binding, 'Derived')) 12 | 13 | def test_issue105(self): 14 | self._test_issue105(boost) 15 | self._test_issue105(py11) 16 | 17 | 18 | if __name__ == '__main__': 19 | unittest.main() 20 | -------------------------------------------------------------------------------- /test/examples/regression/issue105_extra_commas/pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | classes: 5 | "chimera_test::Derived": 6 | bases: 7 | - qualified_name: "chimera_test::Base1" 8 | - qualified_name: "chimera_test::Base2" 9 | -------------------------------------------------------------------------------- /test/examples/regression/issue148_lambda_function/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue148_lambda_function") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/pybind11.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_boost_python(${test_name}_boost_python 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/boost_python.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/regression/issue148_lambda_function/boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue148_lambda_function/issue148_lambda_function.cpp: -------------------------------------------------------------------------------- 1 | #include "issue148_lambda_function.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/regression/issue148_lambda_function/issue148_lambda_function.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | inline std::function foo() 9 | { 10 | return [] {}; 11 | } 12 | 13 | } // namespace chimera_test 14 | -------------------------------------------------------------------------------- /test/examples/regression/issue148_lambda_function/issue148_lambda_function.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import issue148_lambda_function_pybind11 as py11 4 | import issue148_lambda_function_boost_python as boost 5 | 6 | 7 | class TestFunction(unittest.TestCase): 8 | 9 | def _test_lambda_function(self, binding): 10 | pass 11 | 12 | def test_lambda_function(self): 13 | self._test_lambda_function(py11) 14 | self._test_lambda_function(boost) 15 | 16 | 17 | if __name__ == '__main__': 18 | unittest.main() 19 | -------------------------------------------------------------------------------- /test/examples/regression/issue148_lambda_function/pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue216_template_param/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue216_template_param") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_pybind11.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_boost_python(${test_name}_boost_python 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_boost_python.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/regression/issue216_template_param/issue216_template_param.cpp: -------------------------------------------------------------------------------- 1 | #include "issue216_template_param.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/regression/issue216_template_param/issue216_template_param.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace chimera_test 9 | { 10 | 11 | template 12 | void val_param(T /*val*/) 13 | { 14 | } 15 | 16 | template 17 | void vec_param(const std::vector & /*vec*/) 18 | { 19 | } 20 | 21 | template 22 | void arr_param(const std::array & /*arr*/) 23 | { 24 | } 25 | 26 | template 27 | void set_param(const std::set & /*set*/) 28 | { 29 | } 30 | 31 | class Node 32 | { 33 | public: 34 | Node() = default; 35 | }; 36 | 37 | class Skeleton 38 | { 39 | public: 40 | Skeleton() = default; 41 | 42 | inline void foo() 43 | { 44 | val_param(Node()); // ok 45 | val_param(new Node()); // ok 46 | 47 | auto vec = std::vector(); 48 | auto ptrVec = std::vector(); 49 | auto constPtrVec = std::vector(); 50 | vec_param(vec); // ok 51 | vec_param(ptrVec); // now ok! 52 | vec_param(constPtrVec); // now ok! 53 | 54 | auto arr = std::array(); 55 | auto ptrArr = std::array(); 56 | auto constPtrArr = std::array(); 57 | arr_param(arr); // ok 58 | arr_param(ptrArr); // now ok! 59 | arr_param(constPtrArr); // now ok! 60 | 61 | auto set = std::set(); 62 | auto ptrSet = std::set(); 63 | auto constPtrSet = std::set(); 64 | set_param(set); // ok 65 | set_param(ptrSet); // now ok! 66 | set_param(constPtrSet); // now ok! 67 | } 68 | }; 69 | 70 | } // namespace chimera_test 71 | -------------------------------------------------------------------------------- /test/examples/regression/issue216_template_param/issue216_template_param.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | try: 4 | import issue216_template_param_pybind11 as py11 5 | has_pybind11 = True 6 | except: 7 | has_pybind11 = False 8 | 9 | try: 10 | import issue216_template_param_boost_python as boost 11 | has_boost_python = True 12 | except: 13 | has_boost_python = False 14 | 15 | class TestFunction(unittest.TestCase): 16 | 17 | def test_function_py11(self): 18 | if not has_pybind11: 19 | return 20 | 21 | def test_function_bp(self): 22 | if not has_boost_python: 23 | return 24 | 25 | if __name__ == '__main__': 26 | unittest.main() 27 | -------------------------------------------------------------------------------- /test/examples/regression/issue216_template_param/issue216_template_param_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue216_template_param/issue216_template_param_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue228_template_type_alias/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue228_template_type_alias") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_pybind11.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_boost_python(${test_name}_boost_python 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/${test_name}_boost_python.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/regression/issue228_template_type_alias/issue228_template_type_alias.cpp: -------------------------------------------------------------------------------- 1 | #include "issue228_template_type_alias.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | void take_template_type_alias(const my_vector & /*vec*/) 8 | { 9 | // Do nothing 10 | } 11 | 12 | } // namespace chimera_test 13 | -------------------------------------------------------------------------------- /test/examples/regression/issue228_template_type_alias/issue228_template_type_alias.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | template 9 | using my_vector = std::vector; 10 | 11 | void take_template_type_alias(const my_vector &vec); 12 | 13 | } // namespace chimera_test 14 | -------------------------------------------------------------------------------- /test/examples/regression/issue228_template_type_alias/issue228_template_type_alias.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | try: 4 | import issue228_template_type_alias_pybind11 as py11 5 | has_pybind11 = True 6 | except: 7 | has_pybind11 = False 8 | import issue228_template_type_alias_boost_python as boost 9 | 10 | class TestFunction(unittest.TestCase): 11 | 12 | def test_function_py11(self): 13 | if not has_pybind11: 14 | return 15 | self.assertTrue(hasattr(py11, 'take_template_type_alias')) 16 | 17 | def test_function_bp(self): 18 | self.assertTrue(hasattr(boost, 'take_template_type_alias')) 19 | 20 | if __name__ == '__main__': 21 | unittest.main() 22 | -------------------------------------------------------------------------------- /test/examples/regression/issue228_template_type_alias/issue228_template_type_alias_boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue228_template_type_alias/issue228_template_type_alias_pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | 'chimera_test': 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue262_static_method/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue262_static_method") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | NAMESPACES chimera_test 6 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/pybind11.yaml 7 | COPY_MODULE 8 | ) 9 | 10 | chimera_add_binding_test_boost_python(${test_name}_boost_python 11 | SOURCES ${test_name}.h 12 | NAMESPACES chimera_test 13 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/boost_python.yaml 14 | COPY_MODULE 15 | ) 16 | 17 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 18 | -------------------------------------------------------------------------------- /test/examples/regression/issue262_static_method/boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue262_static_method/issue262_static_method.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | class Integer 9 | { 10 | public: 11 | Integer(int val) : m_val(val) 12 | { 13 | } 14 | int add(int a) 15 | { 16 | return a + m_val; 17 | } 18 | // Should be skipped as this static method overloads instance method 19 | static int add(int a, int b) 20 | { 21 | return a + b; 22 | } 23 | static int add_static(int a, int b) 24 | { 25 | return a + b; 26 | } 27 | 28 | private: 29 | int m_val; 30 | }; 31 | 32 | } // namespace chimera_test 33 | -------------------------------------------------------------------------------- /test/examples/regression/issue262_static_method/issue262_static_method.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import issue262_static_method_boost_python as boost 4 | import issue262_static_method_pybind11 as py11 5 | 6 | 7 | class TestIssue262(unittest.TestCase): 8 | 9 | def _test_issue262(self, binding): 10 | # Should be skipped as this static method overloads instance method 11 | with self.assertRaises(TypeError): 12 | binding.Integer.add(1, 2) 13 | 14 | self.assertEqual(binding.Integer.add_static(1, 2), 3) 15 | 16 | # Call instance method 17 | i = binding.Integer(1) 18 | self.assertEqual(i.add(2), 3) 19 | 20 | def test_issue262(self): 21 | self._test_issue262(boost) 22 | self._test_issue262(py11) 23 | 24 | 25 | if __name__ == '__main__': 26 | unittest.main() 27 | -------------------------------------------------------------------------------- /test/examples/regression/issue262_static_method/pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue297_template_variable/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue297_template_variable") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/pybind11.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_boost_python(${test_name}_boost_python 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/boost_python.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/regression/issue297_template_variable/boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue297_template_variable/issue297_template_variable.cpp: -------------------------------------------------------------------------------- 1 | #include "issue297_template_variable.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/regression/issue297_template_variable/issue297_template_variable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | template 9 | constexpr bool template_var = std::true_type::value; 10 | 11 | constexpr bool specialized_var = template_var; 12 | 13 | } // namespace chimera_test 14 | -------------------------------------------------------------------------------- /test/examples/regression/issue297_template_variable/issue297_template_variable.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import issue297_template_variable_pybind11 as py11 4 | import issue297_template_variable_boost_python as boost 5 | 6 | 7 | class TestIssue297(unittest.TestCase): 8 | 9 | def _test_issue297(self, binding): 10 | self.assertFalse(hasattr(binding, 'template_var')) 11 | self.assertTrue(hasattr(binding, 'specialized_var')) 12 | 13 | def test_issue297(self): 14 | self._test_issue297(py11) 15 | self._test_issue297(boost) 16 | 17 | if __name__ == '__main__': 18 | unittest.main() 19 | -------------------------------------------------------------------------------- /test/examples/regression/issue297_template_variable/pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue310_nested_class_name/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue310_nested_class_name") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | EXTRA_SOURCES ${test_name}.cpp 6 | NAMESPACES chimera_test 7 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/pybind11.yaml 8 | COPY_MODULE 9 | ) 10 | 11 | chimera_add_binding_test_boost_python(${test_name}_boost_python 12 | SOURCES ${test_name}.h 13 | EXTRA_SOURCES ${test_name}.cpp 14 | NAMESPACES chimera_test 15 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/boost_python.yaml 16 | COPY_MODULE 17 | ) 18 | 19 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 20 | -------------------------------------------------------------------------------- /test/examples/regression/issue310_nested_class_name/boost_python.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue310_nested_class_name/issue310_nested_class_name.cpp: -------------------------------------------------------------------------------- 1 | #include "issue310_nested_class_name.h" 2 | 3 | namespace chimera_test 4 | { 5 | 6 | //============================================================================== 7 | 8 | } // namespace chimera_test 9 | -------------------------------------------------------------------------------- /test/examples/regression/issue310_nested_class_name/issue310_nested_class_name.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | class Base 9 | { 10 | public: 11 | Base() = default; 12 | class Option 13 | { 14 | public: 15 | Option() = default; 16 | }; 17 | }; 18 | 19 | class Derived : public Base 20 | { 21 | public: 22 | Derived() = default; 23 | class Option : public Base::Option 24 | { 25 | public: 26 | Option() = default; 27 | }; 28 | }; 29 | 30 | } // namespace chimera_test 31 | -------------------------------------------------------------------------------- /test/examples/regression/issue310_nested_class_name/issue310_nested_class_name.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import issue310_nested_class_name_boost_python as boost 4 | 5 | 6 | class TestIssue310(unittest.TestCase): 7 | 8 | def _test_issue310(self, binding): 9 | self.assertTrue(hasattr(binding.Base, 'Option')) 10 | self.assertTrue(hasattr(binding.Derived, 'Option')) 11 | 12 | def test_issue310(self): 13 | with self.assertRaises(ImportError): 14 | __import__('issue310_nested_class_name_pybind11') 15 | self._test_issue310(boost) 16 | 17 | 18 | if __name__ == '__main__': 19 | unittest.main() 20 | -------------------------------------------------------------------------------- /test/examples/regression/issue310_nested_class_name/pybind11.yaml: -------------------------------------------------------------------------------- 1 | namespaces: 2 | "chimera_test": 3 | name: null # TODO: otherwise, import error 4 | -------------------------------------------------------------------------------- /test/examples/regression/issue328_dependent_name/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(test_name "issue328_dependent_name") 2 | 3 | chimera_add_binding_test_pybind11(${test_name}_pybind11 4 | SOURCES ${test_name}.h 5 | NAMESPACES chimera_test 6 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/pybind11.yaml 7 | COPY_MODULE 8 | ) 9 | 10 | chimera_add_binding_test_boost_python(${test_name}_boost_python 11 | SOURCES ${test_name}.h 12 | NAMESPACES chimera_test 13 | CONFIGURATION ${CMAKE_CURRENT_SOURCE_DIR}/boost_python.yaml 14 | COPY_MODULE 15 | ) 16 | 17 | chimera_add_python_test(${test_name}_python_tests ${test_name}.py) 18 | -------------------------------------------------------------------------------- /test/examples/regression/issue328_dependent_name/boost_python.yaml: -------------------------------------------------------------------------------- 1 | # Arguments that will be appended in-order before command line arguments. 2 | arguments: 3 | - "-extra-arg" 4 | - "-I/usr/lib/clang/3.6/include" 5 | namespaces: 6 | "chimera_test": 7 | name: null # TODO: otherwise, import error 8 | -------------------------------------------------------------------------------- /test/examples/regression/issue328_dependent_name/issue328_dependent_name.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace chimera_test 6 | { 7 | 8 | template 9 | class Vector 10 | { 11 | public: 12 | using Scalar = T; 13 | 14 | Vector() = default; 15 | }; 16 | 17 | template 18 | struct ScalarTrait 19 | { 20 | typedef typename S::Scalar type; 21 | }; 22 | 23 | using VectorScalar = ScalarTrait>::type; 24 | 25 | } // namespace chimera_test 26 | -------------------------------------------------------------------------------- /test/examples/regression/issue328_dependent_name/issue328_dependent_name.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | import issue328_dependent_name_pybind11 as py11 4 | import issue328_dependent_name_boost_python as boost 5 | 6 | 7 | class TestIssue328(unittest.TestCase): 8 | 9 | def _test_issue328(self, binding): 10 | # TODO: The next line should be uncommented once #328 is resolved. 11 | # self.assertEqual(binding.VectorScalar, float) 12 | pass 13 | 14 | def test_issue328(self): 15 | self._test_issue328(py11) 16 | self._test_issue328(boost) 17 | 18 | 19 | if __name__ == '__main__': 20 | unittest.main() 21 | -------------------------------------------------------------------------------- /test/examples/regression/issue328_dependent_name/pybind11.yaml: -------------------------------------------------------------------------------- 1 | # Arguments that will be appended in-order before command line arguments. 2 | arguments: 3 | - "-extra-arg" 4 | - "-I/usr/lib/clang/3.6/include" 5 | namespaces: 6 | "chimera_test": 7 | name: null # TODO: otherwise, import error 8 | -------------------------------------------------------------------------------- /test/gtest/cmake/Config.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | include(CMakeFindDependencyMacro) 3 | if (@GTEST_HAS_PTHREAD@) 4 | set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@) 5 | find_dependency(Threads) 6 | endif() 7 | 8 | include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") 9 | check_required_components("@project_name@") 10 | -------------------------------------------------------------------------------- /test/gtest/cmake/gtest.pc.in: -------------------------------------------------------------------------------- 1 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 2 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 3 | 4 | Name: gtest 5 | Description: GoogleTest (without main() function) 6 | Version: @PROJECT_VERSION@ 7 | URL: https://github.com/google/googletest 8 | Libs: -L${libdir} -lgtest @CMAKE_THREAD_LIBS_INIT@ 9 | Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ 10 | -------------------------------------------------------------------------------- /test/gtest/cmake/gtest_main.pc.in: -------------------------------------------------------------------------------- 1 | libdir=@CMAKE_INSTALL_FULL_LIBDIR@ 2 | includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ 3 | 4 | Name: gtest_main 5 | Description: GoogleTest (with main() function) 6 | Version: @PROJECT_VERSION@ 7 | URL: https://github.com/google/googletest 8 | Requires: gtest 9 | Libs: -L${libdir} -lgtest_main @CMAKE_THREAD_LIBS_INIT@ 10 | Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ @CMAKE_THREAD_LIBS_INIT@ 11 | -------------------------------------------------------------------------------- /test/gtest/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 | -------------------------------------------------------------------------------- /test/gtest/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 | GTEST_API_ int main(int argc, char **argv) { 34 | printf("Running main() from %s\n", __FILE__); 35 | testing::InitGoogleTest(&argc, argv); 36 | return RUN_ALL_TESTS(); 37 | } 38 | -------------------------------------------------------------------------------- /tools/check_format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ "$#" -lt 2 ]; then 3 | echo "Usage: ./check_format.sh [ ...]" >&2 4 | exit 0 5 | fi 6 | 7 | num_changes=`$1 -style=file -output-replacements-xml "${@:2}" | grep -c "