├── .clang-format
├── .gitignore
├── AUTHORS
├── CMakeLists.txt
├── LICENSE
├── LICENSE_HEADER
├── README.md
├── cmake
├── bindings.cmake
├── cpp_bindgen-config.cmake.in
├── cpp_bindgen.cmake.in
├── cpp_bindgen_fortran_helpers.cmake
├── cpp_bindgen_generate.cmake
├── detect_features.cmake
└── export.cmake
├── example
├── simple
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── driver.f90
│ └── simple.cpp
└── simple_fetch_content
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── driver.f90
│ └── simple.cpp
├── include
└── cpp_bindgen
│ ├── array_descriptor.h
│ ├── common
│ ├── any_moveable.hpp
│ ├── disjunction.hpp
│ ├── for_each.hpp
│ ├── function_traits.hpp
│ ├── make_indices.hpp
│ └── type_traits.hpp
│ ├── export.hpp
│ ├── fortran_array_view.hpp
│ ├── fortran_string_view.hpp
│ ├── function_wrapper.hpp
│ ├── generator.hpp
│ ├── handle.h
│ ├── handle_impl.hpp
│ └── string_descriptor.h
├── jenkins
└── build.sh
├── src
└── cpp_bindgen
│ ├── array_descriptor.f90
│ ├── generator.cpp
│ ├── generator_main.cpp
│ ├── handle.cpp
│ ├── handle.f90
│ └── string_descriptor.f90
├── tests
├── CMakeLists.txt
├── regression
│ ├── CMakeLists.txt
│ ├── array
│ │ ├── CMakeLists.txt
│ │ ├── bindgen_regression_array.f90
│ │ ├── bindgen_regression_array.h
│ │ ├── bindgen_regression_array_cu.f90
│ │ ├── bindgen_regression_array_cu.h
│ │ ├── driver.f90
│ │ ├── driver_cu.f90
│ │ ├── implementation.cpp
│ │ └── implementation.cu
│ ├── simple
│ │ ├── CMakeLists.txt
│ │ ├── bindgen_regression_simple.f90
│ │ ├── bindgen_regression_simple.h
│ │ ├── driver.c
│ │ ├── driver.f90
│ │ └── simple.cpp
│ └── string
│ │ ├── CMakeLists.txt
│ │ ├── driver.f90
│ │ └── implementation.cpp
└── unit_tests
│ ├── CMakeLists.txt
│ ├── common
│ ├── CMakeLists.txt
│ ├── test_any_moveable.cpp
│ ├── test_any_moveable.cu
│ ├── test_make_indices.cpp
│ └── test_make_indices.cu
│ ├── test_export.cpp
│ ├── test_export.cu
│ ├── test_fortran_array_view.cpp
│ ├── test_fortran_array_view.cu
│ ├── test_function_traits.cpp
│ ├── test_function_traits.cu
│ ├── test_function_wrapper.cpp
│ ├── test_function_wrapper.cu
│ ├── test_generator.cpp
│ └── test_generator.cu
└── version.txt
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | Language: Cpp
3 | # BasedOnStyle: LLVM
4 | AccessModifierOffset: -2
5 | ConstructorInitializerIndentWidth: 4
6 | #AlignEscapedNewlinesLeft: false
7 | AlignTrailingComments: true
8 | AllowAllParametersOfDeclarationOnNextLine: true
9 | AllowShortBlocksOnASingleLine: false
10 | AllowShortIfStatementsOnASingleLine: false
11 | AllowShortLoopsOnASingleLine: false
12 | AllowShortFunctionsOnASingleLine: All
13 | AlwaysBreakTemplateDeclarations: true
14 | AlwaysBreakBeforeMultilineStrings: false
15 | BreakBeforeBinaryOperators: false
16 | BreakBeforeTernaryOperators: true
17 | BreakConstructorInitializersBeforeComma: false
18 | BinPackParameters: false
19 | BinPackArguments: false
20 | ColumnLimit: 120
21 | ConstructorInitializerAllOnOneLineOrOnePerLine: false
22 | DerivePointerAlignment: false
23 | ExperimentalAutoDetectBinPacking: false
24 | IndentCaseLabels: false
25 | IndentWrappedFunctionNames: false
26 | IndentFunctionDeclarationAfterType: false
27 | MaxEmptyLinesToKeep: 1
28 | KeepEmptyLinesAtTheStartOfBlocks: true
29 | NamespaceIndentation: All
30 | ObjCSpaceAfterProperty: false
31 | ObjCSpaceBeforeProtocolList: true
32 | PenaltyBreakBeforeFirstCallParameter: 19
33 | PenaltyBreakComment: 300
34 | PenaltyBreakString: 1000
35 | PenaltyBreakFirstLessLess: 120
36 | PenaltyExcessCharacter: 1000000
37 | PenaltyReturnTypeOnItsOwnLine: 60
38 | PointerAlignment: Right
39 | SpacesBeforeTrailingComments: 1
40 | Cpp11BracedListStyle: true
41 | Standard: Cpp11
42 | IndentWidth: 4
43 | TabWidth: 8
44 | UseTab: Never
45 | BreakBeforeBraces: Attach
46 | SpacesInParentheses: false
47 | SpacesInAngles: false
48 | SpaceInEmptyParentheses: false
49 | SpacesInCStyleCastParentheses: false
50 | SpacesInContainerLiterals: true
51 | SpaceBeforeAssignmentOperators: true
52 | ContinuationIndentWidth: 4
53 | CommentPragmas: '*'
54 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
55 | SpaceBeforeParens: ControlStatements
56 | DisableFormat: false
57 | AlignAfterOpenBracket: false
58 | AlignEscapedNewlinesLeft: true
59 | ...
60 |
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IDEs
2 | *.project
3 | *.cproject
4 | *.settings
5 | .idea
6 | .pydevproject
7 | .clangd
8 |
9 | # Build folders
10 | build*/
11 | install*/
12 |
13 | # Prerequisites
14 | *.d
15 |
16 | # Compiled Object files
17 | *.slo
18 | *.lo
19 | *.o
20 | *.obj
21 |
22 | # Precompiled Headers
23 | *.gch
24 | *.pch
25 |
26 | # Compiled Dynamic libraries
27 | *.so
28 | *.dylib
29 | *.dll
30 |
31 | # Fortran module files
32 | *.mod
33 | *.smod
34 |
35 | # Compiled Static libraries
36 | *.lai
37 | *.la
38 | *.a
39 | *.lib
40 |
41 | # Executables
42 | *.exe
43 | *.out
44 | *.app
45 |
46 | # Logs
47 | *.log
48 |
49 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Anton Afanasyev (anstaf), ETH Zurich (CSCS)
2 | Lukas Mosimann (lukasm91), ETH Zurich (CSCS), NVIDIA
3 | Hannes Vogt (havogt), ETH Zurich (CSCS)
4 | Mauro Bianco (mbianco), ETH Zurich (CSCS)
5 | Felix Thaler (fthaler), ETH Zurich (CSCS)
6 | Willem Deconinck (wdeconinck), ECMWF
7 |
8 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.14.5)
2 | # when increasing the minium required version, consider updating in examples as well
3 |
4 | file(STRINGS "version.txt" __CPP_BINDGEN_VERSION)
5 | project(cpp_bindgen VERSION ${__CPP_BINDGEN_VERSION} LANGUAGES CXX)
6 | unset(__CPP_BINDGEN_VERSION)
7 |
8 | # Switch default of NO_PACKAGE_REGISTRY. TODO: Can be removed with CMake 3.15+
9 | set(CMAKE_EXPORT_NO_PACKAGE_REGISTRY ON CACHE BOOL "")
10 | mark_as_advanced(CMAKE_EXPORT_NO_PACKAGE_REGISTRY)
11 |
12 | set(REQUIRED_BOOST_VERSION 1.58)
13 | find_package(Boost ${REQUIRED_BOOST_VERSION} REQUIRED)
14 |
15 | # if used via FetchContent/add_subdirectory() we need to make the add_bindings_library() available here
16 | include(${CMAKE_CURRENT_LIST_DIR}/cmake/bindings.cmake)
17 |
18 | if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
19 | include(CTest)
20 | if(BUILD_TESTING)
21 | add_subdirectory(tests)
22 | endif()
23 | endif()
24 |
25 | include(${CMAKE_CURRENT_LIST_DIR}/cmake/export.cmake)
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GridTools
2 |
3 | Copyright (c) 2014-2019, ETH Zurich
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are
8 | met:
9 |
10 | 1. Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in the
15 | documentation and/or other materials provided with the distribution.
16 |
17 | 3. Neither the name of the copyright holder nor the names of its
18 | contributors may be used to endorse or promote products derived from
19 | this software without specific prior written permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 |
33 | For information: https://eth-cscs.github.io/gridtools/
34 |
--------------------------------------------------------------------------------
/LICENSE_HEADER:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ![License: BSD][BSD.License]
4 |
5 | **cpp_bindgen** is a library to generate C and Fortran bindings for C++ functions from C++. It is part of the GridTools framework, a set of libraries and utilities to develop performance portable applications in the area of weather and climate.
6 |
7 | Currently the documentation of **cpp_bindgen** is part of the [GridTools documentation](https://gridtools.github.io/gridtools/latest/user_manual/user_manual.html#interfacing-to-other-programming-languages). For simple examples, see the examples folder of this repository. More advanced examples are available in https://github.com/GridTools/gridtools.
8 |
9 | ### Installation instructions
10 |
11 | You can easily integrate **cpp_bindgen** in your CMake project with the following snippet which makes the function `bindgen_add_library()` available.
12 |
13 | ```cmake
14 | include(FetchContent)
15 | FetchContent_Declare(
16 | cpp_bindgen
17 | GIT_REPOSITORY https://github.com/GridTools/cpp_bindgen.git
18 | GIT_TAG master # consider replacing master by a tagged version
19 | )
20 | FetchContent_MakeAvailable(cpp_bindgen)
21 | ```
22 |
23 | See also https://github.com/GridTools/cpp_bindgen/tree/master/example/simple_fetch_content.
24 |
25 | ##### Requirements
26 |
27 | - Boost (1.65.1 or later)
28 | - CMake (3.14.5 or later)
29 |
30 | ##### Known issues
31 |
32 | - The library doesn't work with NVCC <= 9.2 using Clang as host compiler, if c++14 is enabled, due to a bug in NVCC.
33 |
34 | ### Continuous integration
35 |
36 | We use Jenkins to test this library. To test your PR use
37 | - `launch jenkins` to execute the tests which are part of this repository.
38 | - `launch gridtools` to run the changes against the GridTools integration tests from the GridTools/gridtools repository.
39 |
40 | ### Contributing
41 |
42 | Contributions to the GridTools framework are welcome. Please open an issue for any bugs that you encounter or provide a fix or enhancement as a PR. External contributions to GridTools require us a signed copy of a copyright release form to ETH Zurich. We will contact you on the PR.
43 |
44 | [BSD.License]: https://img.shields.io/badge/License-BSD--3--Clause-blue.svg
45 |
--------------------------------------------------------------------------------
/cmake/bindings.cmake:
--------------------------------------------------------------------------------
1 | function(generate_gt_bindings)
2 | set(__CPP_BINDGEN_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src)
3 | set(__CPP_BINDGEN_CMAKE_DIR ${PROJECT_SOURCE_DIR}/cmake)
4 | set(__CPP_BINDGEN_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
5 | configure_file(${PROJECT_SOURCE_DIR}/cmake/cpp_bindgen.cmake.in
6 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/bindings_for_build/cpp_bindgen.cmake
7 | @ONLY)
8 | endfunction()
9 |
10 | generate_gt_bindings()
11 | include(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/bindings_for_build/cpp_bindgen.cmake)
12 |
--------------------------------------------------------------------------------
/cmake/cpp_bindgen-config.cmake.in:
--------------------------------------------------------------------------------
1 | @PACKAGE_INIT@
2 |
3 | get_filename_component(cpp_bindgen_CONFIG_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
4 |
5 | message(STATUS "GridTools cpp_bindgen version @PROJECT_VERSION@ found at ${cpp_bindgen_CONFIG_CMAKE_DIR}")
6 |
7 | include(CMakeFindDependencyMacro)
8 | find_dependency(Boost @REQUIRED_BOOST_VERSION@)
9 |
10 | set_and_check(cpp_bindgen_CMAKE_DIR @PACKAGE_cpp_bindgen_CMAKE_DIR@)
11 | set_and_check(cpp_bindgen_SOURCE_DIR @PACKAGE_cpp_bindgen_SOURCE_DIR@)
12 | set_and_check(cpp_bindgen_INCLUDE_DIR @PACKAGE_cpp_bindgen_INCLUDE_DIR@)
13 |
14 | include(${cpp_bindgen_CMAKE_DIR}/cpp_bindgen.cmake)
15 |
--------------------------------------------------------------------------------
/cmake/cpp_bindgen.cmake.in:
--------------------------------------------------------------------------------
1 | # Create a library with c- and Fortran-bindings
2 | #
3 | # Usage of this module:
4 | #
5 | # bindgen_add_library( SOURCES [...] [FORTRAN_OUTPUT_DIR fortran_dir] [C_OUTPUT_DIR c_dir] [FORTRAN_MODULE_NAME name])
6 | #
7 | # Arguments:
8 | # SOURCES: sources of the library
9 | # FORTRAN_OUTPUT_DIR: destination for generated Fortran files (default: ${CMAKE_CURRENT_LIST_DIR})
10 | # C_OUTPUT_DIR: destination for generated C files (default: ${CMAKE_CURRENT_LIST_DIR})
11 | # FORTRAN_MODULE_NAME: name for the Fortran module (default: )
12 | #
13 | # Variables used by this module:
14 | #
15 | # GT_ENABLE_BINDINGS_GENERATION:
16 | # If GT_ENABLE_BINDINGS_GENERATION=OFF, bindings will not be generated, but expected to be provided,
17 | # as part of the user source code, e.g. by updating bindings with the bindings generator during development.
18 | # If GT_ENABLE_BINDINGS_GENERATION is not defined already it will be made available after including this file.
19 | #
20 | # In the default case (GT_ENABLE_BINDINGS_GENERATION=ON), the bindings files are generated in the directory
21 | # where the CMakeLists.txt with the call to bindgen_add_library() is located.
22 | #
23 | # Targets generated by bindgen_add_library( ...):
24 | # - library build from without bindings (ususally this target is not used)
25 | # - _declarations will run the generator for this library
26 | # - _c the C-bindings with linked to it
27 | # - _fortran the Fortran-bindings with linked to it
28 |
29 | include_guard(GLOBAL)
30 |
31 | option(GT_ENABLE_BINDINGS_GENERATION "If turned off, bindings will not be generated." ON)
32 |
33 | # in some conditions the include guard above doesn't work
34 | if( NOT TARGET cpp_bindgen_interface )
35 |
36 | # variables are unset after use for scoping, they need to be redefined in the macros
37 | set(__CPP_BINDGEN_SOURCE_DIR @__CPP_BINDGEN_SOURCE_DIR@)
38 | set(__CPP_BINDGEN_INCLUDE_DIR @__CPP_BINDGEN_INCLUDE_DIR@)
39 |
40 | add_library(cpp_bindgen_interface INTERFACE)
41 | target_include_directories(cpp_bindgen_interface INTERFACE $ $)
42 | target_compile_features(cpp_bindgen_interface INTERFACE cxx_std_11)
43 | target_compile_definitions(cpp_bindgen_interface INTERFACE BOOST_PP_VARIADICS=1)
44 |
45 | add_library(cpp_bindgen_generator STATIC ${__CPP_BINDGEN_SOURCE_DIR}/cpp_bindgen/generator.cpp)
46 | # PUBLIC to make export.hpp available in the sources passed to add_bindings_library()
47 | target_link_libraries(cpp_bindgen_generator PUBLIC Boost::boost)
48 | target_link_libraries(cpp_bindgen_generator PUBLIC cpp_bindgen_interface)
49 |
50 | add_library(cpp_bindgen_handle STATIC ${__CPP_BINDGEN_SOURCE_DIR}/cpp_bindgen/handle.cpp)
51 | target_link_libraries(cpp_bindgen_handle PUBLIC cpp_bindgen_interface)
52 |
53 | unset(__CPP_BINDGEN_SOURCE_DIR)
54 | unset(__CPP_BINDGEN_INCLUDE_DIR)
55 |
56 | endif()
57 |
58 | # bindgen_enable_fortran_library()
59 | #
60 | # Create a target to compile the generated Fortran module.
61 | # In the default case, when Fortran is enabled on the call to bindgen_add_library(), this target is automatically created.
62 | # In case when the Fortran language was not enabled, we cannot create a library (add_library()) with Fortran files.
63 | # However if the user wants to use the target at a later stage, e.g. in testing (with Fortran enabled), the target can
64 | # be created by a call to bindgen_enable_fortran_library().
65 | function(bindgen_enable_fortran_library target_name)
66 | set(__CPP_BINDGEN_SOURCE_DIR @__CPP_BINDGEN_SOURCE_DIR@)
67 | set(__CPP_BINDGEN_CMAKE_DIR @__CPP_BINDGEN_CMAKE_DIR@)
68 |
69 | if(CMAKE_Fortran_COMPILER_LOADED)
70 | if(NOT TARGET cpp_bindgen_fortran_handle)
71 | add_library(
72 | cpp_bindgen_fortran_handle
73 | ${__CPP_BINDGEN_SOURCE_DIR}/cpp_bindgen/array_descriptor.f90
74 | ${__CPP_BINDGEN_SOURCE_DIR}/cpp_bindgen/string_descriptor.f90
75 | ${__CPP_BINDGEN_SOURCE_DIR}/cpp_bindgen/handle.f90)
76 | # the following variable is used to install the .mod files in install_cpp_bindgen_targets() and
77 | # therefore needs to be available project-wide
78 | set(CPP_BINDGEN_Fortran_MODULES_DIRECTORY ${CMAKE_BINARY_DIR}/cpp_bindgen_modules
79 | CACHE INTERNAL "Directory for Fortran modules of cpp_bindgen")
80 | set_target_properties(cpp_bindgen_fortran_handle PROPERTIES Fortran_MODULE_DIRECTORY ${CPP_BINDGEN_Fortran_MODULES_DIRECTORY})
81 | target_link_libraries(cpp_bindgen_fortran_handle PUBLIC cpp_bindgen_handle)
82 | target_include_directories(cpp_bindgen_fortran_handle INTERFACE $ $)
83 | include(${__CPP_BINDGEN_CMAKE_DIR}/cpp_bindgen_fortran_helpers.cmake)
84 | bindgen_enable_fortran_preprocessing_on_target(cpp_bindgen_fortran_handle)
85 | endif()
86 | if(NOT TARGET ${target_name}_fortran)
87 | set_source_files_properties(GT_${${target_name}_fortran_bindings_path} PROPERTIES GENERATED TRUE)
88 | add_library(${target_name}_fortran EXCLUDE_FROM_ALL ${CPP_BINDGEN_${target_name}_fortran_bindings_path})
89 | target_link_libraries(${target_name}_fortran PUBLIC ${target_name})
90 | target_link_libraries(${target_name}_fortran PUBLIC cpp_bindgen_fortran_handle)
91 | # location of .mod file (we cannot know the INSTALL_INTERFACE directory here)
92 | target_include_directories(${target_name}_fortran PUBLIC $)
93 | add_dependencies(${target_name}_fortran ${target_name}_declarations)
94 | endif()
95 | elseif(NOT ${ARGN}) # internal: the second (optional) parameter can be used to surpress this fatal error
96 | message(FATAL_ERROR "Please enable_language(Fortran) to compile the Fortran bindings.")
97 | endif()
98 | endfunction()
99 |
100 | function(bindgen_add_library target_name)
101 | set(options)
102 | set(one_value_args FORTRAN_OUTPUT_DIR C_OUTPUT_DIR FORTRAN_MODULE_NAME)
103 | set(multi_value_args SOURCES)
104 | cmake_parse_arguments(ARG "${options}" "${one_value_args};" "${multi_value_args}" ${ARGN})
105 |
106 | set(__CPP_BINDGEN_SOURCE_DIR @__CPP_BINDGEN_SOURCE_DIR@)
107 | set(__CPP_BINDGEN_CMAKE_DIR @__CPP_BINDGEN_CMAKE_DIR@)
108 |
109 | if(NOT DEFINED ARG_FORTRAN_MODULE_NAME)
110 | set(ARG_FORTRAN_MODULE_NAME ${target_name}) # default value
111 | endif()
112 |
113 | if(ARG_C_OUTPUT_DIR)
114 | set(bindings_c_decl_filename ${ARG_C_OUTPUT_DIR}/${target_name}.h)
115 | else()
116 | set(bindings_c_decl_filename ${CMAKE_CURRENT_LIST_DIR}/${target_name}.h) # default value
117 | endif()
118 | if(ARG_FORTRAN_OUTPUT_DIR)
119 | set(bindings_fortran_decl_filename ${ARG_FORTRAN_OUTPUT_DIR}/${target_name}.f90)
120 | else()
121 | set(bindings_fortran_decl_filename ${CMAKE_CURRENT_LIST_DIR}/${target_name}.f90) # default value
122 | endif()
123 |
124 | add_library(${target_name} STATIC ${ARG_SOURCES})
125 | target_link_libraries(${target_name} PRIVATE cpp_bindgen_generator)
126 |
127 | if(GT_ENABLE_BINDINGS_GENERATION)
128 | # generator
129 | add_executable(${target_name}_decl_generator
130 | ${__CPP_BINDGEN_SOURCE_DIR}/cpp_bindgen/generator_main.cpp)
131 | set_target_properties(${target_name}_decl_generator PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/decl_generator")
132 | target_link_libraries(${target_name}_decl_generator cpp_bindgen_generator)
133 |
134 | if (${APPLE})
135 | target_link_libraries(${target_name}_decl_generator
136 | -Wl,-force_load ${target_name})
137 | else()
138 | target_link_libraries(${target_name}_decl_generator
139 | -Xlinker --whole-archive ${target_name}
140 | -Xlinker --no-whole-archive)
141 | endif()
142 |
143 | add_custom_target(${target_name}_declarations
144 | ALL
145 | COMMAND ${CMAKE_COMMAND}
146 | -DGENERATOR=${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/decl_generator/${target_name}_decl_generator
147 | -DBINDINGS_C_DECL_FILENAME=${bindings_c_decl_filename}
148 | -DBINDINGS_FORTRAN_DECL_FILENAME=${bindings_fortran_decl_filename}
149 | -DFORTRAN_MODULE_NAME=${ARG_FORTRAN_MODULE_NAME}
150 | -P ${__CPP_BINDGEN_CMAKE_DIR}/cpp_bindgen_generate.cmake
151 | BYPRODUCTS ${bindings_c_decl_filename} ${bindings_fortran_decl_filename}
152 | DEPENDS $)
153 | else()
154 | if(EXISTS ${bindings_c_decl_filename} AND (EXISTS ${bindings_fortran_decl_filename}))
155 | add_custom_target(${target_name}_declarations) # noop, the dependencies are satisfied if the files exist
156 | else()
157 | message(FATAL_ERROR "Cross-compilation for bindings is enabled: no bindings will be generated, but "
158 | "${bindings_c_decl_filename} and/or "
159 | "${bindings_fortran_decl_filename} "
160 | "are missing. Generate the bindings and consider making them part of your repository.")
161 | endif()
162 | endif()
163 |
164 | # bindings c library
165 | add_library(${target_name}_c INTERFACE)
166 | target_link_libraries(${target_name}_c INTERFACE ${target_name})
167 | target_link_libraries(${target_name}_c INTERFACE cpp_bindgen_handle)
168 | target_link_libraries(${target_name}_c INTERFACE cpp_bindgen_interface)
169 |
170 | add_dependencies(${target_name}_c ${target_name}_declarations)
171 |
172 | # bindings Fortran library
173 | # Export the name of the generated file. The variable needs to exist in the whole cmake!
174 | # Reason: see description of bindgen_enable_fortran_library().
175 | set(CPP_BINDGEN_${target_name}_fortran_bindings_path ${bindings_fortran_decl_filename}
176 | CACHE INTERNAL "Path to the generated Fortran file for ${target_name}")
177 | bindgen_enable_fortran_library(${target_name} TRUE)
178 | endfunction()
179 |
180 | # install_cpp_bindgen_targets()
181 | #
182 | # cpp_bindgen contains some generic files which are being built on first use of bindgen_add_library().
183 | # These libraries can be installed with this function which takes the same arguments
184 | # as install(TARGETS targets... [other-options]), except
185 | # - you must not specify "TARGETS targets..." but only all [other-options].
186 | # - if Fortran is enabled Fortran_MODULE_DESTINATION needs to be set to the location where Fortran modules
187 | # should be installed to (e.g. include)
188 | function(install_cpp_bindgen_targets)
189 | set(options)
190 | set(oneValueArgs Fortran_MODULE_DESTINATION)
191 | set(multiValueArgs TARGETS)
192 | cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
193 |
194 | if(ARG_TARGETS)
195 | message(FATAL_ERROR "install_cpp_bindgen_targets() must not be called with TARGETS argument.")
196 | endif()
197 |
198 | if(TARGET cpp_bindgen_fortran_handle) # Fortran is enabled, we need to install a mod file
199 | if(ARG_Fortran_MODULE_DESTINATION)
200 | install(DIRECTORY ${CPP_BINDGEN_Fortran_MODULES_DIRECTORY}/ DESTINATION ${ARG_Fortran_MODULE_DESTINATION})
201 | else()
202 | message(WARNING "Fortran_MODULE_DESTINATION was NOT specified, but Fortran was enabled. Modules files for
203 | cpp_bindgen won't be installed.")
204 | endif()
205 | install(TARGETS cpp_bindgen_fortran_handle ${ARG_UNPARSED_ARGUMENTS})
206 | else()
207 | if(ARG_Fortran_MODULE_DESTINATION)
208 | message(WARNING "Fortran_MODULE_DESTINATION was specified, but Fortran is disabled.")
209 | endif()
210 | endif()
211 | install(TARGETS cpp_bindgen_generator cpp_bindgen_handle cpp_bindgen_interface ${ARG_UNPARSED_ARGUMENTS})
212 | endfunction()
213 |
--------------------------------------------------------------------------------
/cmake/cpp_bindgen_fortran_helpers.cmake:
--------------------------------------------------------------------------------
1 | function(bindgen_enable_fortran_openacc_on_target target)
2 | # TODO check if find_package(OpenACC) solves this problem
3 | if(CMAKE_Fortran_COMPILER_ID STREQUAL "Cray")
4 | target_compile_options(${target} PRIVATE $<$:-h acc>)
5 | elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
6 | target_compile_options(${target} PRIVATE $<$:-fopenacc>)
7 | set_target_properties(${target} PROPERTIES APPEND_STRING PROPERTY LINK_FLAGS -fopenacc)
8 | else()
9 | message(FATAL_ERROR "OpenACC is not configured for this compiler.")
10 | endif()
11 | endfunction()
12 |
13 | function(bindgen_enable_fortran_preprocessing_on_target target)
14 | if (CMAKE_Fortran_COMPILER_ID STREQUAL "Cray")
15 | target_compile_options(${target} PRIVATE $<$:-eF>)
16 | else()
17 | target_compile_options(${target} PRIVATE $<$:-cpp>)
18 | endif()
19 | endfunction()
20 |
--------------------------------------------------------------------------------
/cmake/cpp_bindgen_generate.cmake:
--------------------------------------------------------------------------------
1 | function(check_and_update target_file new_file)
2 | execute_process(
3 | COMMAND ${CMAKE_COMMAND} -E compare_files ${target_file} ${new_file}
4 | RESULT_VARIABLE compare_result
5 | )
6 |
7 | if(${compare_result} EQUAL 0)
8 | message(STATUS "${target_file} is up-to-date")
9 | else()
10 | message(WARNING "${target_file} was generated! "
11 | "If you ship the generated bindings with your sources, don't forget to ship this updated file (and its variants). "
12 | "Otherwise, this warning can be ignored.")
13 |
14 | get_filename_component(target_path ${target_file} PATH)
15 | file(COPY ${new_file} DESTINATION ${target_path})
16 | endif()
17 | file(REMOVE ${new_file})
18 | endfunction()
19 |
20 | # Generate bindings and compare against existing ones
21 | message(STATUS "Generating bindings for library ${FORTRAN_MODULE_NAME}")
22 |
23 | set(generator_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/generated_bindings)
24 | file(MAKE_DIRECTORY ${generator_dir})
25 | get_filename_component(filename_BINDINGS_C_DECL_FILENAME ${BINDINGS_C_DECL_FILENAME} NAME)
26 | set(new_BINDINGS_C_DECL_FILENAME ${generator_dir}/${filename_BINDINGS_C_DECL_FILENAME})
27 | get_filename_component(filename_BINDINGS_FORTRAN_DECL_FILENAME ${BINDINGS_FORTRAN_DECL_FILENAME} NAME)
28 | set(new_BINDINGS_FORTRAN_DECL_FILENAME ${generator_dir}/${filename_BINDINGS_FORTRAN_DECL_FILENAME})
29 |
30 | # run generator
31 | execute_process(COMMAND ${GENERATOR} ${new_BINDINGS_C_DECL_FILENAME} ${new_BINDINGS_FORTRAN_DECL_FILENAME} ${FORTRAN_MODULE_NAME}
32 | RESULT_VARIABLE generate_result
33 | OUTPUT_VARIABLE generate_out
34 | ERROR_VARIABLE generate_out
35 | )
36 |
37 | if(${generate_result} STREQUAL "0")
38 | # only update the bindings if they changed (file not touched -> no rebuild is triggered)
39 | check_and_update(${BINDINGS_C_DECL_FILENAME} ${new_BINDINGS_C_DECL_FILENAME})
40 | check_and_update(${BINDINGS_FORTRAN_DECL_FILENAME} ${new_BINDINGS_FORTRAN_DECL_FILENAME})
41 | else()
42 | message(FATAL_ERROR "GENERATING BINDINGS FAILED. Possibly you cross-compiled the bindings generator for a target "
43 | " which cannot be executed on this host. Consider using the cross-compilation option.\n Exit code: ${generate_result}\n${generate_out}")
44 | endif()
45 |
--------------------------------------------------------------------------------
/cmake/detect_features.cmake:
--------------------------------------------------------------------------------
1 | if(NOT DEFINED CPP_BINDGEN_ENABLE_COMPILER_DETECTION)
2 | if(${PROJECT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR})
3 | set(CPP_BINDGEN_ENABLE_COMPILER_DETECTION ON)
4 | else()
5 | # If turned OFF, it will still use the compilers,
6 | # - if they are available from a super-project, or
7 | # - if compilers are forced to on via other options.
8 | set(CPP_BINDGEN_ENABLE_COMPILER_DETECTION OFF)
9 | endif()
10 | endif()
11 |
12 | macro(detect_cuda)
13 | if(CPP_BINDGEN_ENABLE_COMPILER_DETECTION)
14 | if(NOT DEFINED CPP_BINDGEN_TEST_CUDA)
15 | # detect CUDA support
16 | include(CheckLanguage)
17 | check_language(CUDA)
18 |
19 | if(CMAKE_CUDA_COMPILER)
20 | enable_language (CUDA)
21 | message(STATUS "Enable CUDA tests")
22 | set(CUDA_AVAILABLE ON)
23 | else()
24 | message(STATUS "Disable CUDA tests")
25 | set(CUDA_AVAILABLE OFF)
26 | endif()
27 | elseif(CPP_BINDGEN_TEST_CUDA)
28 | enable_language(CUDA)
29 | message(STATUS "Enable CUDA tests")
30 | set(CUDA_AVAILABLE ON)
31 | else()
32 | message(STATUS "Disable CUDA tests")
33 | set(CUDA_AVAILABLE OFF)
34 | endif()
35 | endif()
36 | endmacro(detect_cuda)
37 |
38 | include (CMakeDependentOption)
39 |
40 | macro(detect_fortran_compiler)
41 | if(CPP_BINDGEN_ENABLE_COMPILER_DETECTION)
42 | CMAKE_DEPENDENT_OPTION (CPP_BINDGEN_REQUIRE_TEST_Fortran "CMake will abort if no Fortran compiler can be found"
43 | OFF "BUILD_TESTING" OFF)
44 |
45 | include(CheckLanguage)
46 | check_language(Fortran)
47 | if (CMAKE_Fortran_COMPILER OR CPP_BINDGEN_REQUIRE_TEST_Fortran)
48 | enable_language(Fortran)
49 | else()
50 | message(WARNING "Fortran Compiler has not been found. Tests using Fortran will not be built!")
51 | endif()
52 | endif()
53 | endmacro(detect_fortran_compiler)
54 |
55 | macro(detect_c_compiler)
56 | if(CPP_BINDGEN_ENABLE_COMPILER_DETECTION)
57 | CMAKE_DEPENDENT_OPTION (CPP_BINDGEN_REQUIRE_TEST_C "CMake will abort if no C compiler can be found"
58 | OFF "BUILD_TESTING" OFF)
59 |
60 | include(CheckLanguage)
61 | check_language(C)
62 | if (CMAKE_C_COMPILER OR CPP_BINDGEN_REQUIRE_TEST_C)
63 | enable_language(C)
64 | else()
65 | message(WARNING "C Compiler has not been found. Tests using C will not be built!")
66 | endif()
67 | endif()
68 | endmacro(detect_c_compiler)
69 |
--------------------------------------------------------------------------------
/cmake/export.cmake:
--------------------------------------------------------------------------------
1 | # this registers the build-tree with a global CMake-registry
2 | export(PACKAGE cpp_bindgen)
3 |
4 | include(CMakePackageConfigHelpers)
5 |
6 | # for build tree
7 | set(cpp_bindgen_CMAKE_DIR ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/build-install/lib/cmake)
8 | set(cpp_bindgen_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src)
9 | set(cpp_bindgen_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
10 | configure_package_config_file(
11 | cmake/cpp_bindgen-config.cmake.in
12 | ${PROJECT_BINARY_DIR}/cpp_bindgen-config.cmake
13 | PATH_VARS cpp_bindgen_CMAKE_DIR cpp_bindgen_SOURCE_DIR cpp_bindgen_INCLUDE_DIR
14 | INSTALL_DESTINATION ${PROJECT_BINARY_DIR}
15 | )
16 | write_basic_package_version_file(
17 | ${PROJECT_BINARY_DIR}/cpp_bindgen-config-version.cmake
18 | VERSION ${PROJECT_VERSION}
19 | COMPATIBILITY SameMajorVersion
20 | )
21 |
22 | # for install tree
23 | set(cpp_bindgen_CMAKE_DIR lib/cmake)
24 | set(cpp_bindgen_SOURCE_DIR src)
25 | set(cpp_bindgen_INCLUDE_DIR include)
26 | configure_package_config_file(
27 | cmake/cpp_bindgen-config.cmake.in
28 | ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/cpp_bindgen-config.cmake
29 | PATH_VARS cpp_bindgen_CMAKE_DIR cpp_bindgen_SOURCE_DIR cpp_bindgen_INCLUDE_DIR
30 | INSTALL_DESTINATION lib/cmake
31 | )
32 | write_basic_package_version_file(
33 | ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/cpp_bindgen-config-version.cmake
34 | VERSION ${PROJECT_VERSION}
35 | COMPATIBILITY SameMajorVersion
36 | )
37 |
38 | install(
39 | FILES
40 | ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/cpp_bindgen-config.cmake
41 | ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/cpp_bindgen-config-version.cmake
42 | DESTINATION lib/cmake
43 | )
44 |
45 | set(__CPP_BINDGEN_CMAKE_DIR "\${cpp_bindgen_CMAKE_DIR}")
46 | set(__CPP_BINDGEN_SOURCE_DIR "\${cpp_bindgen_SOURCE_DIR}")
47 | set(__CPP_BINDGEN_INCLUDE_DIR "\${cpp_bindgen_INCLUDE_DIR}")
48 | configure_file(cmake/cpp_bindgen.cmake.in
49 | ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/build-install/lib/cmake/cpp_bindgen.cmake
50 | @ONLY)
51 | unset(__CPP_BINDGEN_CMAKE_DIR)
52 | unset(__CPP_BINDGEN_SOURCE_DIR)
53 | unset(__CPP_BINDGEN_INCLUDE_DIR)
54 |
55 | set(CMAKE_SOURCES
56 | "${PROJECT_SOURCE_DIR}/cmake/cpp_bindgen_generate.cmake"
57 | "${PROJECT_SOURCE_DIR}/cmake/cpp_bindgen_fortran_helpers.cmake"
58 | "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/build-install/lib/cmake/cpp_bindgen.cmake"
59 | )
60 | set(CBINDINGS_SOURCES
61 | "${PROJECT_SOURCE_DIR}/src/cpp_bindgen/generator.cpp"
62 | "${PROJECT_SOURCE_DIR}/src/cpp_bindgen/generator_main.cpp"
63 | "${PROJECT_SOURCE_DIR}/src/cpp_bindgen/array_descriptor.f90"
64 | "${PROJECT_SOURCE_DIR}/src/cpp_bindgen/string_descriptor.f90"
65 | "${PROJECT_SOURCE_DIR}/src/cpp_bindgen/handle.f90"
66 | "${PROJECT_SOURCE_DIR}/src/cpp_bindgen/handle.cpp"
67 | )
68 |
69 | install(DIRECTORY include/ DESTINATION include)
70 | install(FILES ${CMAKE_SOURCES} DESTINATION "lib/cmake")
71 | install(FILES ${CBINDINGS_SOURCES} DESTINATION "src/cpp_bindgen")
72 |
73 | file(COPY ${CMAKE_SOURCES} DESTINATION "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/build-install/lib/cmake")
74 |
--------------------------------------------------------------------------------
/example/simple/.gitignore:
--------------------------------------------------------------------------------
1 | simple.f90
2 | simple.h
3 |
4 |
--------------------------------------------------------------------------------
/example/simple/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.14.5)
2 | project(simple_example LANGUAGES CXX C Fortran)
3 |
4 | # 1) find installed cpp_bindgen version
5 | find_package(cpp_bindgen)
6 |
7 | # 2) create a library with bindings
8 | bindgen_add_library(simple SOURCES simple.cpp)
9 |
10 | # 3) link the library to a fortran executable
11 | add_executable(driver driver.f90)
12 | target_link_libraries(driver simple_fortran)
13 |
--------------------------------------------------------------------------------
/example/simple/driver.f90:
--------------------------------------------------------------------------------
1 | ! GridTools
2 | !
3 | ! Copyright (c) 2014-2019, ETH Zurich
4 | ! All rights reserved.
5 | !
6 | ! Please, refer to the LICENSE file in the root directory.
7 | ! SPDX-License-Identifier: BSD-3-Clause
8 |
9 | program main
10 | use iso_c_binding
11 | use bindgen_handle
12 | use simple
13 | implicit none
14 | integer, parameter :: i = 9
15 |
16 | call print_number_from_cpp(i)
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/example/simple/simple.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #include
12 | #include
13 |
14 | // In this example, we demonstrate how the cpp_bindgen library can be used to export functions to C and Fortran.
15 |
16 | namespace {
17 | void print_number(int i) { std::cout << "Printing from C++: " << i << std::endl; }
18 |
19 | BINDGEN_EXPORT_BINDING_1(print_number_from_cpp, print_number);
20 | } // namespace
21 |
--------------------------------------------------------------------------------
/example/simple_fetch_content/.gitignore:
--------------------------------------------------------------------------------
1 | simple.f90
2 | simple.h
3 |
4 |
--------------------------------------------------------------------------------
/example/simple_fetch_content/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.14.5)
2 | project(simple_example_with_fetch_content LANGUAGES CXX Fortran)
3 |
4 | # 1) fetch cpp_bindgen from the repository
5 | include(FetchContent)
6 | FetchContent_Declare(
7 | cpp_bindgen
8 | # In your application remove SOURCE_DIR ...
9 | SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..
10 | # By the following 2 lines to fetch content directly from github
11 | # GIT_REPOSITORY https://github.com/GridTools/cpp_bindgen.git
12 | # GIT_TAG master # consider replacing master by a tagged version
13 | )
14 | FetchContent_MakeAvailable(cpp_bindgen)
15 |
16 | # 2) create a library with bindings. This will generate the files simple.h and simple.f90 which can be included within C and Fortran. In CMake you can use them by linking against `simple_c`or `simple_fortran`.
17 | bindgen_add_library(simple SOURCES simple.cpp)
18 |
19 | # 3) link the generated library to a fortran executable
20 | add_executable(driver driver.f90)
21 | target_link_libraries(driver simple_fortran)
22 |
23 | # 4) optional: demonstrates installing the library with CMake
24 | # installs general cpp_bindgen targets
25 | install_cpp_bindgen_targets(
26 | EXPORT simple_fortran_targets
27 | Fortran_MODULE_DESTINATION include
28 | LIBRARY DESTINATION lib
29 | ARCHIVE DESTINATION lib
30 | )
31 | # install your library (simple) and the generated bindings library (simple_fortran) as usual
32 | install(
33 | TARGETS simple simple_fortran
34 | EXPORT simple_fortran_targets
35 | LIBRARY DESTINATION lib
36 | ARCHIVE DESTINATION lib
37 | )
38 | install(EXPORT simple_fortran_targets DESTINATION cmake NAMESPACE SimpleFortran::)
39 |
--------------------------------------------------------------------------------
/example/simple_fetch_content/driver.f90:
--------------------------------------------------------------------------------
1 | ! GridTools
2 | !
3 | ! Copyright (c) 2014-2019, ETH Zurich
4 | ! All rights reserved.
5 | !
6 | ! Please, refer to the LICENSE file in the root directory.
7 | ! SPDX-License-Identifier: BSD-3-Clause
8 |
9 | program main
10 | use iso_c_binding
11 | use bindgen_handle
12 | use simple
13 | implicit none
14 | integer, parameter :: i = 9
15 |
16 | call print_number_from_cpp(i)
17 |
18 | end
19 |
--------------------------------------------------------------------------------
/example/simple_fetch_content/simple.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #include
12 | #include
13 |
14 | // In this example, we demonstrate how the cpp_bindgen library can be used to export functions to C and Fortran.
15 |
16 | namespace {
17 | void print_number(int i) { std::cout << "Printing from C++: " << i << std::endl; }
18 |
19 | // Exports a unary function with the name `print_number_from_cpp`, which forwards to `print_number`.
20 | BINDGEN_EXPORT_BINDING_1(print_number_from_cpp, print_number);
21 | } // namespace
22 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/array_descriptor.h:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #pragma once
12 |
13 | #include
14 |
15 | enum bindgen_fortran_array_kind {
16 | bindgen_fk_Bool,
17 | bindgen_fk_Int,
18 | bindgen_fk_Short,
19 | bindgen_fk_Long,
20 | bindgen_fk_LongLong,
21 | bindgen_fk_Float,
22 | bindgen_fk_Double,
23 | bindgen_fk_LongDouble,
24 | bindgen_fk_SignedChar,
25 | };
26 | typedef enum bindgen_fortran_array_kind bindgen_fortran_array_kind;
27 |
28 | struct bindgen_fortran_array_descriptor {
29 | bindgen_fortran_array_kind type;
30 | int rank;
31 | int dims[7];
32 | void *data;
33 | bool is_acc_present;
34 | // TODO: add support for strides, bounds end type bindgen_fortran_array_descriptor
35 | };
36 | typedef struct bindgen_fortran_array_descriptor bindgen_fortran_array_descriptor;
37 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/common/any_moveable.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 | #pragma once
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | namespace cpp_bindgen {
18 |
19 | struct bad_any_cast : std::bad_cast {
20 | const char *what() const noexcept override { return "cpp_bindgen::bad_any_cast"; }
21 | };
22 |
23 | /**
24 | * this class implements the subset of std::any interface and can hold move only objects.
25 | *
26 | * TODO(anstaf): implement missing std::any components: piecewise ctors, emplace, reset, swap, make_any
27 | */
28 | class any_moveable {
29 | struct iface {
30 | virtual ~iface() = default;
31 | virtual std::type_info const &type() const noexcept = 0;
32 | };
33 | template
34 | struct impl : iface {
35 | T m_obj;
36 | impl(T const &obj) : m_obj(obj) {}
37 | impl(T &&obj) : m_obj(std::move(obj)) {}
38 | std::type_info const &type() const noexcept override { return typeid(T); }
39 | };
40 | std::unique_ptr m_impl;
41 |
42 | public:
43 | any_moveable() = default;
44 |
45 | template ::type>
46 | any_moveable(Arg &&arg) : m_impl(new impl(std::forward(arg))) {}
47 | any_moveable(any_moveable &&) = default;
48 |
49 | template ::type>
50 | any_moveable &operator=(Arg &&obj) {
51 | m_impl.reset(new impl(std::forward(obj)));
52 | return *this;
53 | }
54 | any_moveable &operator=(any_moveable &&) = default;
55 |
56 | bool has_value() const noexcept { return !!m_impl; }
57 | std::type_info const &type() const noexcept { return m_impl->type(); }
58 |
59 | template
60 | friend T *any_cast(any_moveable *src) noexcept {
61 | return src && src->type() == typeid(T) ? &static_cast *>(src->m_impl.get())->m_obj : nullptr;
62 | }
63 | };
64 |
65 | template
66 | T const *any_cast(any_moveable const *src) noexcept {
67 | return any_cast(const_cast(src));
68 | }
69 |
70 | template
71 | T any_cast(any_moveable &src) {
72 | auto *ptr = any_cast::type>(&src);
73 | if (!ptr)
74 | throw bad_any_cast{};
75 | using ref_t = typename std::
76 | conditional::value, T, typename std::add_lvalue_reference::type>::type;
77 | return static_cast(*ptr);
78 | }
79 |
80 | template
81 | T any_cast(any_moveable const &src) {
82 | return any_cast(const_cast(src));
83 | }
84 |
85 | template
86 | T any_cast(any_moveable &&src) {
87 | static_assert(
88 | std::is_rvalue_reference::value || std::is_const::type>::value,
89 | "any_cast shall not be used for getting nonconst references to temporary objects");
90 | return any_cast(src);
91 | }
92 | } // namespace cpp_bindgen
93 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/common/disjunction.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 | #pragma once
11 |
12 | #include
13 |
14 | namespace cpp_bindgen {
15 |
16 | template
17 | struct disjunction : std::false_type {};
18 | template
19 | struct disjunction : B1 {};
20 | template
21 | struct disjunction : std::conditional>::type {};
22 | } // namespace cpp_bindgen
23 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/common/for_each.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #pragma once
12 |
13 | namespace cpp_bindgen {
14 |
15 | namespace for_each_detail {
16 | template
17 | struct for_each_impl;
18 |
19 | template class L, class... Ts>
20 | struct for_each_impl> {
21 | template
22 | static void exec(Fun const &fun) {
23 | (void)(int[]){((void)fun(Ts{}), 0)...};
24 | }
25 | };
26 |
27 | template
28 | struct for_each_type_impl;
29 |
30 | template class L, class... Ts>
31 | struct for_each_type_impl> {
32 | template
33 | static void exec(Fun const &fun) {
34 | (void)(int[]){((void)fun.template operator()(), 0)...};
35 | }
36 | };
37 | } // namespace for_each_detail
38 |
39 | /// Calls fun(T{}) for each element of the type list List.
40 | template
41 | void for_each(Fun const &fun) {
42 | for_each_detail::for_each_impl::exec(fun);
43 | };
44 |
45 | /// Calls fun.template operator() for each element of the type list List.
46 | ///
47 | /// Note the difference between for_each: T is passed only as a template parameter; the operator itself has to
48 | /// be a nullary function. This ensures that the object of type T is nor created, nor passed to the function.
49 | /// The disadvantage is that the functor can not be a [generic] lambda (in C++14 syntax) and also it limits the
50 | /// ability to do operator(). However, if T is not a POD it makes sense to use this for_each flavour. Also
51 | /// nvcc8 has problems with the code generation for the regular for_each even if all the types are empty
52 | /// structs.
53 | template
54 | void for_each_type(Fun const &fun) {
55 | for_each_detail::for_each_type_impl::exec(fun);
56 | }
57 | } // namespace cpp_bindgen
58 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/common/function_traits.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 | #pragma once
11 |
12 | #include
13 | #include
14 |
15 | namespace cpp_bindgen {
16 | namespace function_traits {
17 | namespace _impl {
18 | template
19 | struct parameter_types_helper;
20 |
21 | template
22 | struct parameter_types_helper {
23 | using type = std::tuple;
24 | };
25 |
26 | template
27 | struct result_type_helper;
28 |
29 | template
30 | struct result_type_helper {
31 | using type = Ret;
32 | };
33 |
34 | template
35 | struct arity_helper;
36 |
37 | template
38 | struct arity_helper {
39 | static constexpr std::size_t value = sizeof...(Args);
40 | };
41 |
42 | template
43 | struct nuke_fptr_helper;
44 |
45 | template
46 | struct nuke_fptr_helper {
47 | using type = Ret(Args...);
48 | };
49 | template
50 | struct nuke_fptr_helper {
51 | using type = Ret(Args...);
52 | };
53 | template
54 | struct nuke_fptr_helper {
55 | using type = Ret(Args...);
56 | };
57 |
58 | template
59 | using nuke_fptr = typename nuke_fptr_helper::type>::type;
60 | } // namespace _impl
61 |
62 | template
63 | struct parameter_types : _impl::parameter_types_helper<_impl::nuke_fptr> {};
64 |
65 | template
66 | struct result_type : _impl::result_type_helper<_impl::nuke_fptr> {};
67 |
68 | template
69 | struct arity : _impl::arity_helper<_impl::nuke_fptr> {};
70 |
71 | } // namespace function_traits
72 | } // namespace cpp_bindgen
73 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/common/make_indices.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #pragma once
12 |
13 | #include
14 | #include
15 |
16 | namespace cpp_bindgen {
17 | /**
18 | * The default list constructor.
19 | *
20 | * Used within the library when it needed to produce something, that satisfy list concept.
21 | */
22 | template
23 | struct list {
24 | using type = list;
25 | };
26 |
27 | template
28 | struct integer_sequence {
29 | using value_type = Int;
30 | static constexpr std::size_t size() noexcept { return sizeof...(Indices); }
31 | };
32 |
33 | namespace make_indices_impl_ {
34 | template
35 | struct expand_integer_sequence;
36 |
37 | template
38 | struct expand_integer_sequence, Size, 0> {
39 | using type = integer_sequence;
40 | };
41 |
42 | template
43 | struct expand_integer_sequence, Size, 1> {
44 | using type = integer_sequence;
45 | };
46 |
47 | template
48 | struct generate_integer_sequence {
49 | using type = typename expand_integer_sequence::type,
50 | N / 2,
51 | N % 2>::type;
52 | };
53 |
54 | template
55 | struct generate_integer_sequence {
56 | using type = integer_sequence;
57 | };
58 | } // namespace make_indices_impl_
59 |
60 | template
61 | using make_integer_sequence = typename make_indices_impl_::generate_integer_sequence::type;
62 |
63 | template
64 | using index_sequence = integer_sequence;
65 |
66 | template
67 | using make_index_sequence = make_integer_sequence;
68 |
69 | /**
70 | * Convert an integer sequence to a list of corresponding integral constants.
71 | */
72 | template class = list>
73 | struct iseq_to_list;
74 | template class ISec, class Int, Int... Is, template class L>
75 | struct iseq_to_list, L> {
76 | using type = L...>;
77 | };
78 |
79 | /**
80 | * Make a list of integral constants of indices from 0 to N
81 | */
82 | template class L = list>
83 | struct make_indices_c : iseq_to_list, L>::type {};
84 |
85 | } // namespace cpp_bindgen
86 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/common/type_traits.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #pragma once
12 |
13 | #include
14 |
15 | namespace cpp_bindgen {
16 |
17 | /**
18 | * @file
19 | * Some c++14/c++17 type_traits drop offs. Please refer to C++14/17 specifications
20 | * to know more about them.
21 | */
22 |
23 | template
24 | using bool_constant = std::integral_constant;
25 |
26 | template
27 | using remove_reference_t = typename std::remove_reference::type;
28 | template
29 | using remove_pointer_t = typename std::remove_pointer::type;
30 | template
31 | using add_pointer_t = typename std::add_pointer::type;
32 | template
33 | using remove_all_extents_t = typename std::remove_all_extents::type;
34 | template
35 | using decay_t = typename std::decay::type;
36 | template
37 | using enable_if_t = typename std::enable_if::type;
38 |
39 | template
40 | struct make_void {
41 | typedef void type;
42 | };
43 | template
44 | using void_t = typename make_void::type;
45 | } // namespace cpp_bindgen
46 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/export.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 | #pragma once
11 |
12 | #include
13 |
14 | #include "common/function_traits.hpp"
15 | #include "function_wrapper.hpp"
16 | #include "generator.hpp"
17 |
18 | #define BINDGEN_EXPORT_BINDING_IMPL_PARAM_DECL(z, i, signature) \
19 | typename std::tuple_element>::type>::type param_##i
21 |
22 | #define BINDGEN_ADD_GENERATED_DEFINITION_IMPL(n, name, cppsignature, impl) \
23 | static_assert(::cpp_bindgen::function_traits::arity::value == n, "arity mismatch"); \
24 | extern "C" typename ::cpp_bindgen::function_traits::result_type<::cpp_bindgen::wrapped_t>::type \
25 | name(BOOST_PP_ENUM(n, BINDGEN_EXPORT_BINDING_IMPL_PARAM_DECL, cppsignature)) { \
26 | return ::cpp_bindgen::wrap(impl)(BOOST_PP_ENUM_PARAMS(n, param_)); \
27 | }
28 |
29 | /**
30 | * Defines the function with the given name with the C linkage.
31 | *
32 | * The signature if the generated function will be transformed from the provided signature according to the following
33 | * rules:
34 | * - for result type:
35 | * - `void` and arithmetic types remain the same;
36 | * - classes (and structures) and references to them are transformed to the pointer to the opaque handle
37 | * (`bindgen_handle*`) which should be released by calling `void bindgen_release(bindgen_handle*)` function;
38 | * - all other result types will cause a compiler error.
39 | * - for parameter types:
40 | * - arithmetic types and pointers to them remain the same;
41 | * - references to arithmetic types are transformed to the corresponded pointers;
42 | * - types that fulfill the concept of being fortran_array_bindable are transformed to a
43 | * bindgen_fortran_array_descriptor
44 | * - classes (and structures) and references or pointers to them are transformed to `bindgen_handle*`;
45 | * - all other parameter types will cause a compiler error.
46 | * Additionally the newly generated function will be registered for automatic interface generation.
47 | *
48 | * @param n The arity of the generated function.
49 | * @param name The name of the generated function.
50 | * @param cppsignature The signature that will be used to invoke `impl`.
51 | * @param impl The functor that the generated function will delegate to.
52 | */
53 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(n, name, cppsignature, impl) \
54 | BINDGEN_ADD_GENERATED_DEFINITION_IMPL(n, name, cppsignature, impl) \
55 | BINDGEN_ADD_GENERATED_DECLARATION(::cpp_bindgen::wrapped_t, name)
56 |
57 | /**
58 | * Defines the function with the given name with the C linkage with an additional wrapper in the fortran bindings. The
59 | * additional wrapper provides the following functionality:
60 | * - It generates a bindgen_fortran_array_descriptor from an array, if the type on C++-side is
61 | * fortran_array_wrappable.
62 | *
63 | * The signature if the generated function will be transformed from the provided signature according to the following
64 | * rules:
65 | * - for result type:
66 | * - `void` and arithmetic types remain the same;
67 | * - classes (and structures) and references to them are transformed to the pointer to the opaque handle
68 | * (`bindgen_handle*`) which should be released by calling `void bindgen_release(bindgen_handle*)` function;
69 | * - all other result types will cause a compiler error.
70 | * - for parameter types:
71 | * - arithmetic types and pointers to them remain the same;
72 | * - references to arithmetic types are transformed to the corresponded pointers;
73 | * - types that are fortran_array_bindable but not fortran_array_wrappable are transformed to a
74 | * bindgen_fortran_array_descriptor
75 | * - types that are fortran_array_wrappable are transformed to a bindgen_fortran_array_descriptor in the
76 | * c-bindings, and provide a wrapper in the fortran-bindings such that they can be called with a fortran array
77 | * - types that are fortran_string_bindable are transformed to a bindgen_fortran_string_descriptor in the
78 | * c-bindings, and provide a wrapper in the fortran-bindings such that they can be called with a fortran string
79 | * - classes (and structures) and references or pointers to them are transformed to `bindgen_handle*`;
80 | * - all other parameter types will cause a compiler error.
81 | * Additionally the newly generated function will be registered for automatic interface generation.
82 | *
83 | * A note about fortran strings support:
84 | * `std::string` (and `std::string_view` for C++ standard >= 17) and their R-refs and const L-refs satisfy
85 | * `fortran_string_bindable` criteria. This means that for the C++ function like `void f(std::string& const)`
86 | * fortran wrapper will be generated that takes `character(*)` as a parameter. Note that in this case additional
87 | * data copy will take place while calling `std::string` constructor. For C++17 and higher the user can use
88 | * `void f(std::string_view)` signature to avoid data copy. For the C++11/C++14 there are also copy free solutions:
89 | * - use f(bindgen_fortran_string_descriptor) signature for the raw access to the fortran data or
90 | * - use custom `string_view like` class (T) and provide
91 | * `T bindgen_make_fortran_string_view(bindgen_fortran_string_descriptor desc, T*);` function available by ADL.
92 | *
93 | * @param n The arity of the generated function.
94 | * @param name The name of the generated function.
95 | * @param cppsignature The signature that will be used to invoke `impl`.
96 | * @param impl The functor that the generated function will delegate to.
97 | */
98 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(n, name, cppsignature, impl) \
99 | BINDGEN_ADD_GENERATED_DEFINITION_IMPL(n, name, cppsignature, impl) \
100 | BINDGEN_ADD_GENERATED_DECLARATION_WRAPPED(cppsignature, name)
101 |
102 | /// The flavour of BINDGEN_EXPORT_BINDING_WITH_SIGNATURE where the `impl` parameter is a function pointer.
103 | #define BINDGEN_EXPORT_BINDING(n, name, impl) \
104 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(n, name, decltype(BOOST_PP_REMOVE_PARENS(impl)), impl)
105 | #define BINDGEN_EXPORT_BINDING_WRAPPED(n, name, impl) \
106 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(n, name, decltype(BOOST_PP_REMOVE_PARENS(impl)), impl)
107 |
108 | #define BINDGEN_EXPORT_GENERIC_BINDING_IMPL_IMPL(generatorsuffix, n, generic_name, concrete_name, impl) \
109 | BOOST_PP_CAT(BINDGEN_EXPORT_BINDING, generatorsuffix)(n, concrete_name, impl); \
110 | BINDGEN_ADD_GENERIC_DECLARATION(generic_name, concrete_name)
111 |
112 | #define BINDGEN_EXPORT_GENERIC_BINDING_IMPL(generatorsuffix, n, name, suffix, impl) \
113 | BINDGEN_EXPORT_GENERIC_BINDING_IMPL_IMPL(generatorsuffix, n, name, BOOST_PP_CAT(name, suffix), impl)
114 |
115 | #define BINDGEN_EXPORT_GENERIC_BINDING_IMPL_FUNCTOR(r, data, i, elem) \
116 | BINDGEN_EXPORT_GENERIC_BINDING_IMPL(BOOST_PP_TUPLE_ELEM(4, 0, data), \
117 | BOOST_PP_TUPLE_ELEM(4, 1, data), \
118 | BOOST_PP_TUPLE_ELEM(4, 2, data), \
119 | i, \
120 | (BOOST_PP_TUPLE_ELEM(4, 3, data) < BOOST_PP_REMOVE_PARENS(elem) >));
121 |
122 | #define BINDGEN_EXPORT_GENERIC_BINDING(n, name, impl_template, template_params) \
123 | BOOST_PP_SEQ_FOR_EACH_I(BINDGEN_EXPORT_GENERIC_BINDING_IMPL_FUNCTOR, \
124 | (, n, name, impl_template), \
125 | BOOST_PP_VARIADIC_SEQ_TO_SEQ(template_params)) \
126 | static_assert(1, "")
127 |
128 | #define BINDGEN_EXPORT_GENERIC_BINDING_WRAPPED(n, name, impl_template, template_params) \
129 | BOOST_PP_SEQ_FOR_EACH_I(BINDGEN_EXPORT_GENERIC_BINDING_IMPL_FUNCTOR, \
130 | (_WRAPPED, n, name, impl_template), \
131 | BOOST_PP_VARIADIC_SEQ_TO_SEQ(template_params)) \
132 | static_assert(1, "")
133 |
134 | /// BINDGEN_EXPORT_BINDING_WITH_SIGNATURE shortcuts for the given arity
135 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_0(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(0, name, s, i)
136 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_1(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(1, name, s, i)
137 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_2(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(2, name, s, i)
138 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_3(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(3, name, s, i)
139 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_4(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(4, name, s, i)
140 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_5(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(5, name, s, i)
141 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_6(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(6, name, s, i)
142 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_7(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(7, name, s, i)
143 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_8(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(8, name, s, i)
144 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_9(name, s, i) BINDGEN_EXPORT_BINDING_WITH_SIGNATURE(9, name, s, i)
145 |
146 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_0(name, s, i) \
147 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(0, name, s, i)
148 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_1(name, s, i) \
149 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(1, name, s, i)
150 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_2(name, s, i) \
151 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(2, name, s, i)
152 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_3(name, s, i) \
153 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(3, name, s, i)
154 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_4(name, s, i) \
155 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(4, name, s, i)
156 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_5(name, s, i) \
157 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(5, name, s, i)
158 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_6(name, s, i) \
159 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(6, name, s, i)
160 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_7(name, s, i) \
161 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(7, name, s, i)
162 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_8(name, s, i) \
163 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(8, name, s, i)
164 | #define BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED_9(name, s, i) \
165 | BINDGEN_EXPORT_BINDING_WITH_SIGNATURE_WRAPPED(9, name, s, i)
166 |
167 | /// BINDGEN_EXPORT_BINDING shortcuts for the given arity
168 | #define BINDGEN_EXPORT_BINDING_0(name, impl) BINDGEN_EXPORT_BINDING(0, name, impl)
169 | #define BINDGEN_EXPORT_BINDING_1(name, impl) BINDGEN_EXPORT_BINDING(1, name, impl)
170 | #define BINDGEN_EXPORT_BINDING_2(name, impl) BINDGEN_EXPORT_BINDING(2, name, impl)
171 | #define BINDGEN_EXPORT_BINDING_3(name, impl) BINDGEN_EXPORT_BINDING(3, name, impl)
172 | #define BINDGEN_EXPORT_BINDING_4(name, impl) BINDGEN_EXPORT_BINDING(4, name, impl)
173 | #define BINDGEN_EXPORT_BINDING_5(name, impl) BINDGEN_EXPORT_BINDING(5, name, impl)
174 | #define BINDGEN_EXPORT_BINDING_6(name, impl) BINDGEN_EXPORT_BINDING(6, name, impl)
175 | #define BINDGEN_EXPORT_BINDING_7(name, impl) BINDGEN_EXPORT_BINDING(7, name, impl)
176 | #define BINDGEN_EXPORT_BINDING_8(name, impl) BINDGEN_EXPORT_BINDING(8, name, impl)
177 | #define BINDGEN_EXPORT_BINDING_9(name, impl) BINDGEN_EXPORT_BINDING(9, name, impl)
178 |
179 | #define BINDGEN_EXPORT_BINDING_WRAPPED_0(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(0, name, impl)
180 | #define BINDGEN_EXPORT_BINDING_WRAPPED_1(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(1, name, impl)
181 | #define BINDGEN_EXPORT_BINDING_WRAPPED_2(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(2, name, impl)
182 | #define BINDGEN_EXPORT_BINDING_WRAPPED_3(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(3, name, impl)
183 | #define BINDGEN_EXPORT_BINDING_WRAPPED_4(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(4, name, impl)
184 | #define BINDGEN_EXPORT_BINDING_WRAPPED_5(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(5, name, impl)
185 | #define BINDGEN_EXPORT_BINDING_WRAPPED_6(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(6, name, impl)
186 | #define BINDGEN_EXPORT_BINDING_WRAPPED_7(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(7, name, impl)
187 | #define BINDGEN_EXPORT_BINDING_WRAPPED_8(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(8, name, impl)
188 | #define BINDGEN_EXPORT_BINDING_WRAPPED_9(name, impl) BINDGEN_EXPORT_BINDING_WRAPPED(9, name, impl)
189 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/fortran_array_view.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #pragma once
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #include "common/for_each.hpp"
18 | #include "common/make_indices.hpp"
19 | #include "common/type_traits.hpp"
20 |
21 | #include "array_descriptor.h"
22 |
23 | namespace cpp_bindgen {
24 | namespace _impl {
25 | template
26 | struct fill_extent_f {
27 | template
28 | void operator()(N, bindgen_fortran_array_descriptor &descriptor) const {
29 | descriptor.dims[N::value] = std::extent::value;
30 | }
31 | };
32 | template
33 | struct fortran_array_element_kind_impl;
34 | template <>
35 | struct fortran_array_element_kind_impl
36 | : std::integral_constant {};
37 | template <>
38 | struct fortran_array_element_kind_impl
39 | : std::integral_constant {};
40 | template <>
41 | struct fortran_array_element_kind_impl
42 | : std::integral_constant {};
43 | template <>
44 | struct fortran_array_element_kind_impl
45 | : std::integral_constant {};
46 | template <>
47 | struct fortran_array_element_kind_impl
48 | : std::integral_constant {};
49 | template <>
50 | struct fortran_array_element_kind_impl
51 | : std::integral_constant {};
52 | template <>
53 | struct fortran_array_element_kind_impl
54 | : std::integral_constant {};
55 | template <>
56 | struct fortran_array_element_kind_impl
57 | : std::integral_constant {};
58 | template <>
59 | struct fortran_array_element_kind_impl
60 | : std::integral_constant {};
61 | } // namespace _impl
62 |
63 | template
64 | struct fortran_array_element_kind;
65 | template
66 | struct fortran_array_element_kind::value>>
67 | : _impl::fortran_array_element_kind_impl::type> {};
68 | template
69 | struct fortran_array_element_kind::value>>
70 | : _impl::fortran_array_element_kind_impl {};
71 |
72 | namespace get_fortran_view_meta_impl {
73 | template , class ElementType = remove_all_extents_t>
74 | enable_if_t::value && std::is_arithmetic::value,
75 | bindgen_fortran_array_descriptor>
76 | get_fortran_view_meta(T *) {
77 | bindgen_fortran_array_descriptor descriptor;
78 | descriptor.type = fortran_array_element_kind::value;
79 | descriptor.rank = std::rank::value;
80 | descriptor.is_acc_present = false;
81 |
82 | using indices = typename make_indices_c::value>::type;
83 | cpp_bindgen::for_each(
84 | std::bind(_impl::fill_extent_f{}, std::placeholders::_1, std::ref(descriptor)));
85 |
86 | return descriptor;
87 | }
88 |
89 | template
90 | enable_if_t<(T::bindgen_view_rank::value > 0) &&
91 | std::is_arithmetic::value &&
92 | (T::bindgen_is_acc_present::value == T::bindgen_is_acc_present::value),
93 | bindgen_fortran_array_descriptor>
94 | get_fortran_view_meta(T *) {
95 | bindgen_fortran_array_descriptor descriptor;
96 | descriptor.type = fortran_array_element_kind::value;
97 | descriptor.rank = T::bindgen_view_rank::value;
98 | descriptor.is_acc_present = T::bindgen_is_acc_present::value;
99 |
100 | return descriptor;
101 | }
102 |
103 | template
104 | using bindgen_fortran_array_view_t = decltype(
105 | bindgen_make_fortran_array_view(std::declval(), std::declval()));
106 |
107 | } // namespace get_fortran_view_meta_impl
108 | using get_fortran_view_meta_impl::get_fortran_view_meta;
109 | /**
110 | * A type T is fortran_array_view_inspectable, one of the following conditions holds:
111 | *
112 | * - There exists a function
113 | *
114 | * @code
115 | * bindgen_fortran_array_descriptor get_fortran_view_meta(T*)
116 | * @endcode
117 | *
118 | * which returns the meta-data of the type `T`. type, rank and is_acc_present must be set correctly.
119 | *
120 | * - T defines T::bindgen_view_element_type as the element type of the array, T::bindgen_view_rank is an integral
121 | * constant holding the rank of the type, and T::bindgen_is_acc_present is a bool_constant indicating whether
122 | * the data is present on device (when compiling with OpenACC, this will pass a device pointer to the
123 | * constructor).
124 | *
125 | * - T is a reference to a c-array.
126 | */
127 | template
128 | struct is_fortran_array_view_inspectable : std::false_type {};
129 | template
130 | struct is_fortran_array_view_inspectable>())),
132 | bindgen_fortran_array_descriptor>::value>> : std::true_type {};
133 |
134 | /**
135 | * The concept of fortran_array_convertible requires that a fortran array described by a
136 | * bindgen_fortran_array_descriptor can be converted into T:
137 | *
138 | * - T is fortran_array_convertible, if T is a reference to an array of a fortran-compatible type (arithmetic
139 | * types).
140 | * - T is fortran_array_convertible, if bindgen_fortran_array_descriptor is implicity convertible to T
141 | * - T is fortran_array_convertible, if there exists a function with the following signature:
142 | * @code
143 | * T bindgen_make_fortran_array_view(bindgen_fortran_array_descriptor*, T*)
144 | * @endcode
145 | * .
146 | */
147 | template
148 | struct is_fortran_array_convertible : std::false_type {};
149 |
150 | template
151 | struct is_fortran_array_convertible, bindgen_fortran_array_descriptor>::value ||
153 | std::is_convertible::value>> : std::true_type {};
154 |
155 | template
156 | struct is_fortran_array_convertible::value && std::is_array>::value &&
158 | std::is_arithmetic>>::value>> : std::true_type {};
159 |
160 | // simplify this when support for CUDA 9.2 is gone, or if GT is at v2.0
161 | template
162 | struct is_fortran_array_convertible,
164 | enable_if_t,
165 | T>::value>> //
166 | > : std::true_type {};
167 |
168 | /**
169 | * @brief A type is fortran_array_bindable if it is fortran_array_convertible
170 | *
171 | * A fortran_array_bindable type will appear in the c-bindings as a bindgen_fortran_array_descriptor.
172 | */
173 | template
174 | struct is_fortran_array_bindable : is_fortran_array_convertible {};
175 | /**
176 | * @brief A type is fortran_array_wrappable if it is both fortran_array_bindable and
177 | * fortran_array_view_inspectable.
178 | *
179 | * If used with the wrapper-versions of the export-function, fortran_array_wrappable types can be created from a
180 | * fortran array in the fortran bindings, whereas fortran_array_convertible-types that are not bindable will
181 | * appear as bindgen_fortran_array_descriptors and must be filled manually.
182 | */
183 | template
184 | struct is_fortran_array_wrappable
185 | : bool_constant::value && is_fortran_array_view_inspectable::value> {};
186 |
187 | template
188 | enable_if_t, bindgen_fortran_array_descriptor>::value ||
189 | std::is_convertible::value,
190 | T>
191 | make_fortran_array_view(bindgen_fortran_array_descriptor *descriptor) {
192 | return *descriptor;
193 | }
194 | template
195 | enable_if_t::value && std::is_array>::value &&
196 | std::is_arithmetic>>::value,
197 | T>
198 | make_fortran_array_view(bindgen_fortran_array_descriptor *descriptor) {
199 | static bindgen_fortran_array_descriptor cpp_meta = get_fortran_view_meta((add_pointer_t){nullptr});
200 | if (descriptor->type != cpp_meta.type) {
201 | throw std::runtime_error("Types do not match: fortran-type (" + std::to_string(descriptor->type) +
202 | ") != c-type (" + std::to_string(cpp_meta.type) + ")");
203 | }
204 | if (descriptor->rank != cpp_meta.rank) {
205 | throw std::runtime_error("Rank does not match: fortran-rank (" + std::to_string(descriptor->rank) +
206 | ") != c-rank (" + std::to_string(cpp_meta.rank) + ")");
207 | }
208 | for (int i = 0; i < descriptor->rank; ++i) {
209 | if (cpp_meta.dims[i] != descriptor->dims[descriptor->rank - i - 1])
210 | throw std::runtime_error("Extents do not match");
211 | }
212 |
213 | return *static_cast *>(descriptor->data);
214 | }
215 | // simplify this when support for CUDA 9.2 is gone, or if GT is at v2.0
216 | template
217 | enable_if_t, T>::value,
218 | get_fortran_view_meta_impl::bindgen_fortran_array_view_t>
219 | make_fortran_array_view(bindgen_fortran_array_descriptor *descriptor) {
220 | return bindgen_make_fortran_array_view(descriptor, (T *){nullptr});
221 | }
222 |
223 | } // namespace cpp_bindgen
224 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/fortran_string_view.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 |
11 | #pragma once
12 |
13 | #include
14 |
15 | #include "string_descriptor.h"
16 |
17 | bindgen_fortran_string_descriptor inline bindgen_make_fortran_string_view(
18 | bindgen_fortran_string_descriptor desc, bindgen_fortran_string_descriptor *) {
19 | return desc;
20 | }
21 |
22 | #include
23 |
24 | namespace std {
25 | inline string bindgen_make_fortran_string_view(bindgen_fortran_string_descriptor desc, string *) {
26 | return {desc.data, (size_t)desc.size};
27 | }
28 | } // namespace std
29 |
30 | #if __cplusplus >= 201703L
31 | #include
32 |
33 | namespace std {
34 | inline string_view bindgen_make_fortran_string_view(bindgen_fortran_string_descriptor desc, string_view *) {
35 | return {desc.data, (size_t)desc.size};
36 | }
37 | } // namespace std
38 | #endif
39 |
40 | namespace cpp_bindgen {
41 | namespace fortran_string_view_impl_ {
42 |
43 | template
44 | auto make_fortran_string_view(bindgen_fortran_string_descriptor desc)
45 | -> decltype(bindgen_make_fortran_string_view(desc, (T *)0)) {
46 | return bindgen_make_fortran_string_view(desc, (T *)0);
47 | }
48 |
49 | template
50 | struct is_fortran_string_bindable : std::false_type {};
51 |
52 | template
53 | struct is_fortran_string_bindable::type>(
55 | std::declval())),
56 | T>::value>::type> : std::true_type {};
57 | } // namespace fortran_string_view_impl_
58 | using fortran_string_view_impl_::is_fortran_string_bindable;
59 | using fortran_string_view_impl_::make_fortran_string_view;
60 | } // namespace cpp_bindgen
61 |
--------------------------------------------------------------------------------
/include/cpp_bindgen/function_wrapper.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * GridTools
3 | *
4 | * Copyright (c) 2014-2019, ETH Zurich
5 | * All rights reserved.
6 | *
7 | * Please, refer to the LICENSE file in the root directory.
8 | * SPDX-License-Identifier: BSD-3-Clause
9 | */
10 | #pragma once
11 |
12 | #include
13 |
14 | #include
15 |
16 | #include "common/any_moveable.hpp"
17 |
18 | #include "fortran_array_view.hpp"
19 | #include "fortran_string_view.hpp"
20 | #include "handle_impl.hpp"
21 |
22 | namespace cpp_bindgen {
23 | namespace _impl {
24 |
25 | template
26 | struct result_converted_to_c;
27 |
28 | template
29 | struct result_converted_to_c::value || std::is_arithmetic::value>::type> {
31 | using type = T;
32 | };
33 |
34 | template
35 | struct result_converted_to_c::type>::value>::type> {
37 | using type = bindgen_handle *;
38 | };
39 |
40 | template
41 | struct param_converted_to_c;
42 |
43 | template
44 | struct param_converted_to_c::value>::type> {
45 | using type = T;
46 | };
47 |
48 | template
49 | struct param_converted_to_c