Techt3o commited on
Commit
9796b13
·
verified ·
1 Parent(s): 2d4409a

970d35941313771ebaf2f6d7f6c9bd1d96d8cdcbc0fdaef7295715b4a06cc1bc

Browse files
Files changed (50) hide show
  1. third-party/DPVO/DPViewer/pybind11/LICENSE +29 -0
  2. third-party/DPVO/DPViewer/pybind11/MANIFEST.in +5 -0
  3. third-party/DPVO/DPViewer/pybind11/README.rst +180 -0
  4. third-party/DPVO/DPViewer/pybind11/include/pybind11/embed.h +253 -0
  5. third-party/DPVO/DPViewer/pybind11/include/pybind11/eval.h +156 -0
  6. third-party/DPVO/DPViewer/pybind11/include/pybind11/functional.h +130 -0
  7. third-party/DPVO/DPViewer/pybind11/include/pybind11/gil.h +202 -0
  8. third-party/DPVO/DPViewer/pybind11/include/pybind11/iostream.h +265 -0
  9. third-party/DPVO/DPViewer/pybind11/include/pybind11/numpy.h +1984 -0
  10. third-party/DPVO/DPViewer/pybind11/include/pybind11/operators.h +201 -0
  11. third-party/DPVO/DPViewer/pybind11/include/pybind11/options.h +76 -0
  12. third-party/DPVO/DPViewer/pybind11/include/pybind11/pybind11.h +0 -0
  13. third-party/DPVO/DPViewer/pybind11/include/pybind11/pytypes.h +2373 -0
  14. third-party/DPVO/DPViewer/pybind11/include/pybind11/stl.h +425 -0
  15. third-party/DPVO/DPViewer/pybind11/include/pybind11/stl/filesystem.h +116 -0
  16. third-party/DPVO/DPViewer/pybind11/include/pybind11/stl_bind.h +785 -0
  17. third-party/DPVO/DPViewer/pybind11/noxfile.py +97 -0
  18. third-party/DPVO/DPViewer/pybind11/pybind11/__init__.py +16 -0
  19. third-party/DPVO/DPViewer/pybind11/pybind11/__main__.py +49 -0
  20. third-party/DPVO/DPViewer/pybind11/pybind11/_version.py +12 -0
  21. third-party/DPVO/DPViewer/pybind11/pybind11/commands.py +25 -0
  22. third-party/DPVO/DPViewer/pybind11/pybind11/py.typed +0 -0
  23. third-party/DPVO/DPViewer/pybind11/pybind11/setup_helpers.py +504 -0
  24. third-party/DPVO/DPViewer/pybind11/pyproject.toml +61 -0
  25. third-party/DPVO/DPViewer/pybind11/setup.cfg +49 -0
  26. third-party/DPVO/DPViewer/pybind11/setup.py +149 -0
  27. third-party/DPVO/DPViewer/pybind11/tools/FindCatch.cmake +72 -0
  28. third-party/DPVO/DPViewer/pybind11/tools/FindEigen3.cmake +86 -0
  29. third-party/DPVO/DPViewer/pybind11/tools/FindPythonLibsNew.cmake +281 -0
  30. third-party/DPVO/DPViewer/pybind11/tools/check-style.sh +44 -0
  31. third-party/DPVO/DPViewer/pybind11/tools/cmake_uninstall.cmake.in +23 -0
  32. third-party/DPVO/DPViewer/pybind11/tools/libsize.py +36 -0
  33. third-party/DPVO/DPViewer/pybind11/tools/make_changelog.py +63 -0
  34. third-party/DPVO/DPViewer/pybind11/tools/pybind11Common.cmake +385 -0
  35. third-party/DPVO/DPViewer/pybind11/tools/pybind11Config.cmake.in +231 -0
  36. third-party/DPVO/DPViewer/pybind11/tools/pybind11NewTools.cmake +254 -0
  37. third-party/DPVO/DPViewer/pybind11/tools/pybind11Tools.cmake +227 -0
  38. third-party/DPVO/DPViewer/pybind11/tools/pyproject.toml +3 -0
  39. third-party/DPVO/DPViewer/pybind11/tools/setup_global.py.in +59 -0
  40. third-party/DPVO/DPViewer/pybind11/tools/setup_main.py.in +40 -0
  41. third-party/DPVO/DPViewer/setup.py +132 -0
  42. third-party/DPVO/dpvo/__init__.py +0 -0
  43. third-party/DPVO/dpvo/altcorr/__init__.py +1 -0
  44. third-party/DPVO/dpvo/altcorr/correlation.cpp +63 -0
  45. third-party/DPVO/dpvo/altcorr/correlation.py +74 -0
  46. third-party/DPVO/dpvo/altcorr/correlation_kernel.cu +333 -0
  47. third-party/DPVO/dpvo/ba.py +182 -0
  48. third-party/DPVO/dpvo/blocks.py +118 -0
  49. third-party/DPVO/dpvo/config.py +38 -0
  50. third-party/DPVO/dpvo/data_readers/__init__.py +1 -0
third-party/DPVO/DPViewer/pybind11/LICENSE ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>, All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this
7
+ list of conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ 3. Neither the name of the copyright holder nor the names of its contributors
14
+ may be used to endorse or promote products derived from this software
15
+ without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ Please also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of
29
+ external contributions to this project including patches, pull requests, etc.
third-party/DPVO/DPViewer/pybind11/MANIFEST.in ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ recursive-include pybind11/include/pybind11 *.h
2
+ recursive-include pybind11 *.py
3
+ recursive-include pybind11 py.typed
4
+ include pybind11/share/cmake/pybind11/*.cmake
5
+ include LICENSE README.rst pyproject.toml setup.py setup.cfg
third-party/DPVO/DPViewer/pybind11/README.rst ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png
2
+ :alt: pybind11 logo
3
+
4
+ **pybind11 — Seamless operability between C++11 and Python**
5
+
6
+ |Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|
7
+
8
+ |Repology| |PyPI package| |Conda-forge| |Python Versions|
9
+
10
+ `Setuptools example <https://github.com/pybind/python_example>`_
11
+ • `Scikit-build example <https://github.com/pybind/scikit_build_example>`_
12
+ • `CMake example <https://github.com/pybind/cmake_example>`_
13
+
14
+ .. start
15
+
16
+
17
+ **pybind11** is a lightweight header-only library that exposes C++ types
18
+ in Python and vice versa, mainly to create Python bindings of existing
19
+ C++ code. Its goals and syntax are similar to the excellent
20
+ `Boost.Python <http://www.boost.org/doc/libs/1_58_0/libs/python/doc/>`_
21
+ library by David Abrahams: to minimize boilerplate code in traditional
22
+ extension modules by inferring type information using compile-time
23
+ introspection.
24
+
25
+ The main issue with Boost.Python—and the reason for creating such a
26
+ similar project—is Boost. Boost is an enormously large and complex suite
27
+ of utility libraries that works with almost every C++ compiler in
28
+ existence. This compatibility has its cost: arcane template tricks and
29
+ workarounds are necessary to support the oldest and buggiest of compiler
30
+ specimens. Now that C++11-compatible compilers are widely available,
31
+ this heavy machinery has become an excessively large and unnecessary
32
+ dependency.
33
+
34
+ Think of this library as a tiny self-contained version of Boost.Python
35
+ with everything stripped away that isn't relevant for binding
36
+ generation. Without comments, the core header files only require ~4K
37
+ lines of code and depend on Python (3.6+, or PyPy) and the C++
38
+ standard library. This compact implementation was possible thanks to
39
+ some of the new C++11 language features (specifically: tuples, lambda
40
+ functions and variadic templates). Since its creation, this library has
41
+ grown beyond Boost.Python in many ways, leading to dramatically simpler
42
+ binding code in many common situations.
43
+
44
+ Tutorial and reference documentation is provided at
45
+ `pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.
46
+ A PDF version of the manual is available
47
+ `here <https://pybind11.readthedocs.io/_/downloads/en/latest/pdf/>`_.
48
+ And the source code is always available at
49
+ `github.com/pybind/pybind11 <https://github.com/pybind/pybind11>`_.
50
+
51
+
52
+ Core features
53
+ -------------
54
+
55
+
56
+ pybind11 can map the following core C++ features to Python:
57
+
58
+ - Functions accepting and returning custom data structures per value,
59
+ reference, or pointer
60
+ - Instance methods and static methods
61
+ - Overloaded functions
62
+ - Instance attributes and static attributes
63
+ - Arbitrary exception types
64
+ - Enumerations
65
+ - Callbacks
66
+ - Iterators and ranges
67
+ - Custom operators
68
+ - Single and multiple inheritance
69
+ - STL data structures
70
+ - Smart pointers with reference counting like ``std::shared_ptr``
71
+ - Internal references with correct reference counting
72
+ - C++ classes with virtual (and pure virtual) methods can be extended
73
+ in Python
74
+
75
+ Goodies
76
+ -------
77
+
78
+ In addition to the core functionality, pybind11 provides some extra
79
+ goodies:
80
+
81
+ - Python 3.6+, and PyPy3 7.3 are supported with an implementation-agnostic
82
+ interface (pybind11 2.9 was the last version to support Python 2 and 3.5).
83
+
84
+ - It is possible to bind C++11 lambda functions with captured
85
+ variables. The lambda capture data is stored inside the resulting
86
+ Python function object.
87
+
88
+ - pybind11 uses C++11 move constructors and move assignment operators
89
+ whenever possible to efficiently transfer custom data types.
90
+
91
+ - It's easy to expose the internal storage of custom data types through
92
+ Pythons' buffer protocols. This is handy e.g. for fast conversion
93
+ between C++ matrix classes like Eigen and NumPy without expensive
94
+ copy operations.
95
+
96
+ - pybind11 can automatically vectorize functions so that they are
97
+ transparently applied to all entries of one or more NumPy array
98
+ arguments.
99
+
100
+ - Python's slice-based access and assignment operations can be
101
+ supported with just a few lines of code.
102
+
103
+ - Everything is contained in just a few header files; there is no need
104
+ to link against any additional libraries.
105
+
106
+ - Binaries are generally smaller by a factor of at least 2 compared to
107
+ equivalent bindings generated by Boost.Python. A recent pybind11
108
+ conversion of PyRosetta, an enormous Boost.Python binding project,
109
+ `reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_
110
+ a binary size reduction of **5.4x** and compile time reduction by
111
+ **5.8x**.
112
+
113
+ - Function signatures are precomputed at compile time (using
114
+ ``constexpr``), leading to smaller binaries.
115
+
116
+ - With little extra effort, C++ types can be pickled and unpickled
117
+ similar to regular Python objects.
118
+
119
+ Supported compilers
120
+ -------------------
121
+
122
+ 1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or
123
+ newer)
124
+ 2. GCC 4.8 or newer
125
+ 3. Microsoft Visual Studio 2017 or newer
126
+ 4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)
127
+ 5. Cygwin/GCC (previously tested on 2.5.1)
128
+ 6. NVCC (CUDA 11.0 tested in CI)
129
+ 7. NVIDIA PGI (20.9 tested in CI)
130
+
131
+ About
132
+ -----
133
+
134
+ This project was created by `Wenzel
135
+ Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
136
+ improvements to the code were contributed by Jonas Adler, Lori A. Burns,
137
+ Sylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel
138
+ Huebl, @hulucc, Yannick Jadoul, Sergey Lyskov Johan Mabille, Tomasz Miąsko,
139
+ Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
140
+ Schellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.
141
+
142
+ We thank Google for a generous financial contribution to the continuous
143
+ integration infrastructure used by this project.
144
+
145
+
146
+ Contributing
147
+ ~~~~~~~~~~~~
148
+
149
+ See the `contributing
150
+ guide <https://github.com/pybind/pybind11/blob/master/.github/CONTRIBUTING.md>`_
151
+ for information on building and contributing to pybind11.
152
+
153
+ License
154
+ ~~~~~~~
155
+
156
+ pybind11 is provided under a BSD-style license that can be found in the
157
+ `LICENSE <https://github.com/pybind/pybind11/blob/master/LICENSE>`_
158
+ file. By using, distributing, or contributing to this project, you agree
159
+ to the terms and conditions of this license.
160
+
161
+ .. |Latest Documentation Status| image:: https://readthedocs.org/projects/pybind11/badge?version=latest
162
+ :target: http://pybind11.readthedocs.org/en/latest
163
+ .. |Stable Documentation Status| image:: https://img.shields.io/badge/docs-stable-blue.svg
164
+ :target: http://pybind11.readthedocs.org/en/stable
165
+ .. |Gitter chat| image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg
166
+ :target: https://gitter.im/pybind/Lobby
167
+ .. |CI| image:: https://github.com/pybind/pybind11/workflows/CI/badge.svg
168
+ :target: https://github.com/pybind/pybind11/actions
169
+ .. |Build status| image:: https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true
170
+ :target: https://ci.appveyor.com/project/wjakob/pybind11
171
+ .. |PyPI package| image:: https://img.shields.io/pypi/v/pybind11.svg
172
+ :target: https://pypi.org/project/pybind11/
173
+ .. |Conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pybind11.svg
174
+ :target: https://github.com/conda-forge/pybind11-feedstock
175
+ .. |Repology| image:: https://repology.org/badge/latest-versions/python:pybind11.svg
176
+ :target: https://repology.org/project/python:pybind11/versions
177
+ .. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg
178
+ :target: https://pypi.org/project/pybind11/
179
+ .. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
180
+ :target: https://github.com/pybind/pybind11/discussions
third-party/DPVO/DPViewer/pybind11/include/pybind11/embed.h ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/embed.h: Support for embedding the interpreter
3
+
4
+ Copyright (c) 2017 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "pybind11.h"
13
+ #include "eval.h"
14
+
15
+ #include <memory>
16
+ #include <vector>
17
+
18
+ #if defined(PYPY_VERSION)
19
+ # error Embedding the interpreter is not supported with PyPy
20
+ #endif
21
+
22
+ #define PYBIND11_EMBEDDED_MODULE_IMPL(name) \
23
+ extern "C" PyObject *pybind11_init_impl_##name(); \
24
+ extern "C" PyObject *pybind11_init_impl_##name() { return pybind11_init_wrapper_##name(); }
25
+
26
+ /** \rst
27
+ Add a new module to the table of builtins for the interpreter. Must be
28
+ defined in global scope. The first macro parameter is the name of the
29
+ module (without quotes). The second parameter is the variable which will
30
+ be used as the interface to add functions and classes to the module.
31
+
32
+ .. code-block:: cpp
33
+
34
+ PYBIND11_EMBEDDED_MODULE(example, m) {
35
+ // ... initialize functions and classes here
36
+ m.def("foo", []() {
37
+ return "Hello, World!";
38
+ });
39
+ }
40
+ \endrst */
41
+ #define PYBIND11_EMBEDDED_MODULE(name, variable) \
42
+ static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name); \
43
+ static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &); \
44
+ static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() { \
45
+ auto m = ::pybind11::module_::create_extension_module( \
46
+ PYBIND11_TOSTRING(name), nullptr, &PYBIND11_CONCAT(pybind11_module_def_, name)); \
47
+ try { \
48
+ PYBIND11_CONCAT(pybind11_init_, name)(m); \
49
+ return m.ptr(); \
50
+ } \
51
+ PYBIND11_CATCH_INIT_EXCEPTIONS \
52
+ } \
53
+ PYBIND11_EMBEDDED_MODULE_IMPL(name) \
54
+ ::pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name)( \
55
+ PYBIND11_TOSTRING(name), PYBIND11_CONCAT(pybind11_init_impl_, name)); \
56
+ void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ \
57
+ & variable) // NOLINT(bugprone-macro-parentheses)
58
+
59
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
60
+ PYBIND11_NAMESPACE_BEGIN(detail)
61
+
62
+ /// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks.
63
+ struct embedded_module {
64
+ using init_t = PyObject *(*) ();
65
+ embedded_module(const char *name, init_t init) {
66
+ if (Py_IsInitialized() != 0) {
67
+ pybind11_fail("Can't add new modules after the interpreter has been initialized");
68
+ }
69
+
70
+ auto result = PyImport_AppendInittab(name, init);
71
+ if (result == -1) {
72
+ pybind11_fail("Insufficient memory to add a new module");
73
+ }
74
+ }
75
+ };
76
+
77
+ struct wide_char_arg_deleter {
78
+ void operator()(wchar_t *ptr) const {
79
+ // API docs: https://docs.python.org/3/c-api/sys.html#c.Py_DecodeLocale
80
+ PyMem_RawFree(ptr);
81
+ }
82
+ };
83
+
84
+ inline wchar_t *widen_chars(const char *safe_arg) {
85
+ wchar_t *widened_arg = Py_DecodeLocale(safe_arg, nullptr);
86
+ return widened_arg;
87
+ }
88
+
89
+ /// Python 2.x/3.x-compatible version of `PySys_SetArgv`
90
+ inline void set_interpreter_argv(int argc, const char *const *argv, bool add_program_dir_to_path) {
91
+ // Before it was special-cased in python 3.8, passing an empty or null argv
92
+ // caused a segfault, so we have to reimplement the special case ourselves.
93
+ bool special_case = (argv == nullptr || argc <= 0);
94
+
95
+ const char *const empty_argv[]{"\0"};
96
+ const char *const *safe_argv = special_case ? empty_argv : argv;
97
+ if (special_case) {
98
+ argc = 1;
99
+ }
100
+
101
+ auto argv_size = static_cast<size_t>(argc);
102
+ // SetArgv* on python 3 takes wchar_t, so we have to convert.
103
+ std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);
104
+ std::vector<std::unique_ptr<wchar_t[], wide_char_arg_deleter>> widened_argv_entries;
105
+ widened_argv_entries.reserve(argv_size);
106
+ for (size_t ii = 0; ii < argv_size; ++ii) {
107
+ widened_argv_entries.emplace_back(widen_chars(safe_argv[ii]));
108
+ if (!widened_argv_entries.back()) {
109
+ // A null here indicates a character-encoding failure or the python
110
+ // interpreter out of memory. Give up.
111
+ return;
112
+ }
113
+ widened_argv[ii] = widened_argv_entries.back().get();
114
+ }
115
+
116
+ auto *pysys_argv = widened_argv.get();
117
+ PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));
118
+ }
119
+
120
+ PYBIND11_NAMESPACE_END(detail)
121
+
122
+ /** \rst
123
+ Initialize the Python interpreter. No other pybind11 or CPython API functions can be
124
+ called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The
125
+ optional `init_signal_handlers` parameter can be used to skip the registration of
126
+ signal handlers (see the `Python documentation`_ for details). Calling this function
127
+ again after the interpreter has already been initialized is a fatal error.
128
+
129
+ If initializing the Python interpreter fails, then the program is terminated. (This
130
+ is controlled by the CPython runtime and is an exception to pybind11's normal behavior
131
+ of throwing exceptions on errors.)
132
+
133
+ The remaining optional parameters, `argc`, `argv`, and `add_program_dir_to_path` are
134
+ used to populate ``sys.argv`` and ``sys.path``.
135
+ See the |PySys_SetArgvEx documentation|_ for details.
136
+
137
+ .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx
138
+ .. |PySys_SetArgvEx documentation| replace:: ``PySys_SetArgvEx`` documentation
139
+ .. _PySys_SetArgvEx documentation: https://docs.python.org/3/c-api/init.html#c.PySys_SetArgvEx
140
+ \endrst */
141
+ inline void initialize_interpreter(bool init_signal_handlers = true,
142
+ int argc = 0,
143
+ const char *const *argv = nullptr,
144
+ bool add_program_dir_to_path = true) {
145
+ if (Py_IsInitialized() != 0) {
146
+ pybind11_fail("The interpreter is already running");
147
+ }
148
+
149
+ Py_InitializeEx(init_signal_handlers ? 1 : 0);
150
+
151
+ detail::set_interpreter_argv(argc, argv, add_program_dir_to_path);
152
+ }
153
+
154
+ /** \rst
155
+ Shut down the Python interpreter. No pybind11 or CPython API functions can be called
156
+ after this. In addition, pybind11 objects must not outlive the interpreter:
157
+
158
+ .. code-block:: cpp
159
+
160
+ { // BAD
161
+ py::initialize_interpreter();
162
+ auto hello = py::str("Hello, World!");
163
+ py::finalize_interpreter();
164
+ } // <-- BOOM, hello's destructor is called after interpreter shutdown
165
+
166
+ { // GOOD
167
+ py::initialize_interpreter();
168
+ { // scoped
169
+ auto hello = py::str("Hello, World!");
170
+ } // <-- OK, hello is cleaned up properly
171
+ py::finalize_interpreter();
172
+ }
173
+
174
+ { // BETTER
175
+ py::scoped_interpreter guard{};
176
+ auto hello = py::str("Hello, World!");
177
+ }
178
+
179
+ .. warning::
180
+
181
+ The interpreter can be restarted by calling `initialize_interpreter` again.
182
+ Modules created using pybind11 can be safely re-initialized. However, Python
183
+ itself cannot completely unload binary extension modules and there are several
184
+ caveats with regard to interpreter restarting. All the details can be found
185
+ in the CPython documentation. In short, not all interpreter memory may be
186
+ freed, either due to reference cycles or user-created global data.
187
+
188
+ \endrst */
189
+ inline void finalize_interpreter() {
190
+ handle builtins(PyEval_GetBuiltins());
191
+ const char *id = PYBIND11_INTERNALS_ID;
192
+
193
+ // Get the internals pointer (without creating it if it doesn't exist). It's possible for the
194
+ // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()`
195
+ // during destruction), so we get the pointer-pointer here and check it after Py_Finalize().
196
+ detail::internals **internals_ptr_ptr = detail::get_internals_pp();
197
+ // It could also be stashed in builtins, so look there too:
198
+ if (builtins.contains(id) && isinstance<capsule>(builtins[id])) {
199
+ internals_ptr_ptr = capsule(builtins[id]);
200
+ }
201
+ // Local internals contains data managed by the current interpreter, so we must clear them to
202
+ // avoid undefined behaviors when initializing another interpreter
203
+ detail::get_local_internals().registered_types_cpp.clear();
204
+ detail::get_local_internals().registered_exception_translators.clear();
205
+
206
+ Py_Finalize();
207
+
208
+ if (internals_ptr_ptr) {
209
+ delete *internals_ptr_ptr;
210
+ *internals_ptr_ptr = nullptr;
211
+ }
212
+ }
213
+
214
+ /** \rst
215
+ Scope guard version of `initialize_interpreter` and `finalize_interpreter`.
216
+ This a move-only guard and only a single instance can exist.
217
+
218
+ See `initialize_interpreter` for a discussion of its constructor arguments.
219
+
220
+ .. code-block:: cpp
221
+
222
+ #include <pybind11/embed.h>
223
+
224
+ int main() {
225
+ py::scoped_interpreter guard{};
226
+ py::print(Hello, World!);
227
+ } // <-- interpreter shutdown
228
+ \endrst */
229
+ class scoped_interpreter {
230
+ public:
231
+ explicit scoped_interpreter(bool init_signal_handlers = true,
232
+ int argc = 0,
233
+ const char *const *argv = nullptr,
234
+ bool add_program_dir_to_path = true) {
235
+ initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);
236
+ }
237
+
238
+ scoped_interpreter(const scoped_interpreter &) = delete;
239
+ scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }
240
+ scoped_interpreter &operator=(const scoped_interpreter &) = delete;
241
+ scoped_interpreter &operator=(scoped_interpreter &&) = delete;
242
+
243
+ ~scoped_interpreter() {
244
+ if (is_valid) {
245
+ finalize_interpreter();
246
+ }
247
+ }
248
+
249
+ private:
250
+ bool is_valid = true;
251
+ };
252
+
253
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/eval.h ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/eval.h: Support for evaluating Python expressions and statements
3
+ from strings and files
4
+
5
+ Copyright (c) 2016 Klemens Morgenstern <[email protected]> and
6
+ Wenzel Jakob <[email protected]>
7
+
8
+ All rights reserved. Use of this source code is governed by a
9
+ BSD-style license that can be found in the LICENSE file.
10
+ */
11
+
12
+ #pragma once
13
+
14
+ #include "pybind11.h"
15
+
16
+ #include <utility>
17
+
18
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
19
+ PYBIND11_NAMESPACE_BEGIN(detail)
20
+
21
+ inline void ensure_builtins_in_globals(object &global) {
22
+ #if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000
23
+ // Running exec and eval adds `builtins` module under `__builtins__` key to
24
+ // globals if not yet present. Python 3.8 made PyRun_String behave
25
+ // similarly. Let's also do that for older versions, for consistency. This
26
+ // was missing from PyPy3.8 7.3.7.
27
+ if (!global.contains("__builtins__"))
28
+ global["__builtins__"] = module_::import(PYBIND11_BUILTINS_MODULE);
29
+ #else
30
+ (void) global;
31
+ #endif
32
+ }
33
+
34
+ PYBIND11_NAMESPACE_END(detail)
35
+
36
+ enum eval_mode {
37
+ /// Evaluate a string containing an isolated expression
38
+ eval_expr,
39
+
40
+ /// Evaluate a string containing a single statement. Returns \c none
41
+ eval_single_statement,
42
+
43
+ /// Evaluate a string containing a sequence of statement. Returns \c none
44
+ eval_statements
45
+ };
46
+
47
+ template <eval_mode mode = eval_expr>
48
+ object eval(const str &expr, object global = globals(), object local = object()) {
49
+ if (!local) {
50
+ local = global;
51
+ }
52
+
53
+ detail::ensure_builtins_in_globals(global);
54
+
55
+ /* PyRun_String does not accept a PyObject / encoding specifier,
56
+ this seems to be the only alternative */
57
+ std::string buffer = "# -*- coding: utf-8 -*-\n" + (std::string) expr;
58
+
59
+ int start = 0;
60
+ switch (mode) {
61
+ case eval_expr:
62
+ start = Py_eval_input;
63
+ break;
64
+ case eval_single_statement:
65
+ start = Py_single_input;
66
+ break;
67
+ case eval_statements:
68
+ start = Py_file_input;
69
+ break;
70
+ default:
71
+ pybind11_fail("invalid evaluation mode");
72
+ }
73
+
74
+ PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());
75
+ if (!result) {
76
+ throw error_already_set();
77
+ }
78
+ return reinterpret_steal<object>(result);
79
+ }
80
+
81
+ template <eval_mode mode = eval_expr, size_t N>
82
+ object eval(const char (&s)[N], object global = globals(), object local = object()) {
83
+ /* Support raw string literals by removing common leading whitespace */
84
+ auto expr = (s[0] == '\n') ? str(module_::import("textwrap").attr("dedent")(s)) : str(s);
85
+ return eval<mode>(expr, std::move(global), std::move(local));
86
+ }
87
+
88
+ inline void exec(const str &expr, object global = globals(), object local = object()) {
89
+ eval<eval_statements>(expr, std::move(global), std::move(local));
90
+ }
91
+
92
+ template <size_t N>
93
+ void exec(const char (&s)[N], object global = globals(), object local = object()) {
94
+ eval<eval_statements>(s, std::move(global), std::move(local));
95
+ }
96
+
97
+ #if defined(PYPY_VERSION)
98
+ template <eval_mode mode = eval_statements>
99
+ object eval_file(str, object, object) {
100
+ pybind11_fail("eval_file not supported in PyPy3. Use eval");
101
+ }
102
+ template <eval_mode mode = eval_statements>
103
+ object eval_file(str, object) {
104
+ pybind11_fail("eval_file not supported in PyPy3. Use eval");
105
+ }
106
+ template <eval_mode mode = eval_statements>
107
+ object eval_file(str) {
108
+ pybind11_fail("eval_file not supported in PyPy3. Use eval");
109
+ }
110
+ #else
111
+ template <eval_mode mode = eval_statements>
112
+ object eval_file(str fname, object global = globals(), object local = object()) {
113
+ if (!local) {
114
+ local = global;
115
+ }
116
+
117
+ detail::ensure_builtins_in_globals(global);
118
+
119
+ int start = 0;
120
+ switch (mode) {
121
+ case eval_expr:
122
+ start = Py_eval_input;
123
+ break;
124
+ case eval_single_statement:
125
+ start = Py_single_input;
126
+ break;
127
+ case eval_statements:
128
+ start = Py_file_input;
129
+ break;
130
+ default:
131
+ pybind11_fail("invalid evaluation mode");
132
+ }
133
+
134
+ int closeFile = 1;
135
+ std::string fname_str = (std::string) fname;
136
+ FILE *f = _Py_fopen_obj(fname.ptr(), "r");
137
+ if (!f) {
138
+ PyErr_Clear();
139
+ pybind11_fail("File \"" + fname_str + "\" could not be opened!");
140
+ }
141
+
142
+ if (!global.contains("__file__")) {
143
+ global["__file__"] = std::move(fname);
144
+ }
145
+
146
+ PyObject *result
147
+ = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), local.ptr(), closeFile);
148
+
149
+ if (!result) {
150
+ throw error_already_set();
151
+ }
152
+ return reinterpret_steal<object>(result);
153
+ }
154
+ #endif
155
+
156
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/functional.h ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/functional.h: std::function<> support
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "pybind11.h"
13
+
14
+ #include <functional>
15
+
16
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
17
+ PYBIND11_NAMESPACE_BEGIN(detail)
18
+
19
+ template <typename Return, typename... Args>
20
+ struct type_caster<std::function<Return(Args...)>> {
21
+ using type = std::function<Return(Args...)>;
22
+ using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
23
+ using function_type = Return (*)(Args...);
24
+
25
+ public:
26
+ bool load(handle src, bool convert) {
27
+ if (src.is_none()) {
28
+ // Defer accepting None to other overloads (if we aren't in convert mode):
29
+ if (!convert) {
30
+ return false;
31
+ }
32
+ return true;
33
+ }
34
+
35
+ if (!isinstance<function>(src)) {
36
+ return false;
37
+ }
38
+
39
+ auto func = reinterpret_borrow<function>(src);
40
+
41
+ /*
42
+ When passing a C++ function as an argument to another C++
43
+ function via Python, every function call would normally involve
44
+ a full C++ -> Python -> C++ roundtrip, which can be prohibitive.
45
+ Here, we try to at least detect the case where the function is
46
+ stateless (i.e. function pointer or lambda function without
47
+ captured variables), in which case the roundtrip can be avoided.
48
+ */
49
+ if (auto cfunc = func.cpp_function()) {
50
+ auto *cfunc_self = PyCFunction_GET_SELF(cfunc.ptr());
51
+ if (isinstance<capsule>(cfunc_self)) {
52
+ auto c = reinterpret_borrow<capsule>(cfunc_self);
53
+ auto *rec = (function_record *) c;
54
+
55
+ while (rec != nullptr) {
56
+ if (rec->is_stateless
57
+ && same_type(typeid(function_type),
58
+ *reinterpret_cast<const std::type_info *>(rec->data[1]))) {
59
+ struct capture {
60
+ function_type f;
61
+ };
62
+ value = ((capture *) &rec->data)->f;
63
+ return true;
64
+ }
65
+ rec = rec->next;
66
+ }
67
+ }
68
+ // PYPY segfaults here when passing builtin function like sum.
69
+ // Raising an fail exception here works to prevent the segfault, but only on gcc.
70
+ // See PR #1413 for full details
71
+ }
72
+
73
+ // ensure GIL is held during functor destruction
74
+ struct func_handle {
75
+ function f;
76
+ #if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17))
77
+ // This triggers a syntax error under very special conditions (very weird indeed).
78
+ explicit
79
+ #endif
80
+ func_handle(function &&f_) noexcept
81
+ : f(std::move(f_)) {
82
+ }
83
+ func_handle(const func_handle &f_) { operator=(f_); }
84
+ func_handle &operator=(const func_handle &f_) {
85
+ gil_scoped_acquire acq;
86
+ f = f_.f;
87
+ return *this;
88
+ }
89
+ ~func_handle() {
90
+ gil_scoped_acquire acq;
91
+ function kill_f(std::move(f));
92
+ }
93
+ };
94
+
95
+ // to emulate 'move initialization capture' in C++11
96
+ struct func_wrapper {
97
+ func_handle hfunc;
98
+ explicit func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {}
99
+ Return operator()(Args... args) const {
100
+ gil_scoped_acquire acq;
101
+ // casts the returned object as a rvalue to the return type
102
+ return hfunc.f(std::forward<Args>(args)...).template cast<Return>();
103
+ }
104
+ };
105
+
106
+ value = func_wrapper(func_handle(std::move(func)));
107
+ return true;
108
+ }
109
+
110
+ template <typename Func>
111
+ static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) {
112
+ if (!f_) {
113
+ return none().inc_ref();
114
+ }
115
+
116
+ auto result = f_.template target<function_type>();
117
+ if (result) {
118
+ return cpp_function(*result, policy).release();
119
+ }
120
+ return cpp_function(std::forward<Func>(f_), policy).release();
121
+ }
122
+
123
+ PYBIND11_TYPE_CASTER(type,
124
+ const_name("Callable[[") + concat(make_caster<Args>::name...)
125
+ + const_name("], ") + make_caster<retval_type>::name
126
+ + const_name("]"));
127
+ };
128
+
129
+ PYBIND11_NAMESPACE_END(detail)
130
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/gil.h ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/gil.h: RAII helpers for managing the GIL
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "detail/common.h"
13
+ #include "detail/internals.h"
14
+
15
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
16
+
17
+ PYBIND11_NAMESPACE_BEGIN(detail)
18
+
19
+ // forward declarations
20
+ PyThreadState *get_thread_state_unchecked();
21
+
22
+ PYBIND11_NAMESPACE_END(detail)
23
+
24
+ #if defined(WITH_THREAD) && !defined(PYPY_VERSION)
25
+
26
+ /* The functions below essentially reproduce the PyGILState_* API using a RAII
27
+ * pattern, but there are a few important differences:
28
+ *
29
+ * 1. When acquiring the GIL from an non-main thread during the finalization
30
+ * phase, the GILState API blindly terminates the calling thread, which
31
+ * is often not what is wanted. This API does not do this.
32
+ *
33
+ * 2. The gil_scoped_release function can optionally cut the relationship
34
+ * of a PyThreadState and its associated thread, which allows moving it to
35
+ * another thread (this is a fairly rare/advanced use case).
36
+ *
37
+ * 3. The reference count of an acquired thread state can be controlled. This
38
+ * can be handy to prevent cases where callbacks issued from an external
39
+ * thread would otherwise constantly construct and destroy thread state data
40
+ * structures.
41
+ *
42
+ * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an
43
+ * example which uses features 2 and 3 to migrate the Python thread of
44
+ * execution to another thread (to run the event loop on the original thread,
45
+ * in this case).
46
+ */
47
+
48
+ class gil_scoped_acquire {
49
+ public:
50
+ PYBIND11_NOINLINE gil_scoped_acquire() {
51
+ auto &internals = detail::get_internals();
52
+ tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate);
53
+
54
+ if (!tstate) {
55
+ /* Check if the GIL was acquired using the PyGILState_* API instead (e.g. if
56
+ calling from a Python thread). Since we use a different key, this ensures
57
+ we don't create a new thread state and deadlock in PyEval_AcquireThread
58
+ below. Note we don't save this state with internals.tstate, since we don't
59
+ create it we would fail to clear it (its reference count should be > 0). */
60
+ tstate = PyGILState_GetThisThreadState();
61
+ }
62
+
63
+ if (!tstate) {
64
+ tstate = PyThreadState_New(internals.istate);
65
+ # if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
66
+ if (!tstate) {
67
+ pybind11_fail("scoped_acquire: could not create thread state!");
68
+ }
69
+ # endif
70
+ tstate->gilstate_counter = 0;
71
+ PYBIND11_TLS_REPLACE_VALUE(internals.tstate, tstate);
72
+ } else {
73
+ release = detail::get_thread_state_unchecked() != tstate;
74
+ }
75
+
76
+ if (release) {
77
+ PyEval_AcquireThread(tstate);
78
+ }
79
+
80
+ inc_ref();
81
+ }
82
+
83
+ void inc_ref() { ++tstate->gilstate_counter; }
84
+
85
+ PYBIND11_NOINLINE void dec_ref() {
86
+ --tstate->gilstate_counter;
87
+ # if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
88
+ if (detail::get_thread_state_unchecked() != tstate) {
89
+ pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!");
90
+ }
91
+ if (tstate->gilstate_counter < 0) {
92
+ pybind11_fail("scoped_acquire::dec_ref(): reference count underflow!");
93
+ }
94
+ # endif
95
+ if (tstate->gilstate_counter == 0) {
96
+ # if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
97
+ if (!release) {
98
+ pybind11_fail("scoped_acquire::dec_ref(): internal error!");
99
+ }
100
+ # endif
101
+ PyThreadState_Clear(tstate);
102
+ if (active) {
103
+ PyThreadState_DeleteCurrent();
104
+ }
105
+ PYBIND11_TLS_DELETE_VALUE(detail::get_internals().tstate);
106
+ release = false;
107
+ }
108
+ }
109
+
110
+ /// This method will disable the PyThreadState_DeleteCurrent call and the
111
+ /// GIL won't be acquired. This method should be used if the interpreter
112
+ /// could be shutting down when this is called, as thread deletion is not
113
+ /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
114
+ /// protect subsequent code.
115
+ PYBIND11_NOINLINE void disarm() { active = false; }
116
+
117
+ PYBIND11_NOINLINE ~gil_scoped_acquire() {
118
+ dec_ref();
119
+ if (release) {
120
+ PyEval_SaveThread();
121
+ }
122
+ }
123
+
124
+ private:
125
+ PyThreadState *tstate = nullptr;
126
+ bool release = true;
127
+ bool active = true;
128
+ };
129
+
130
+ class gil_scoped_release {
131
+ public:
132
+ explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) {
133
+ // `get_internals()` must be called here unconditionally in order to initialize
134
+ // `internals.tstate` for subsequent `gil_scoped_acquire` calls. Otherwise, an
135
+ // initialization race could occur as multiple threads try `gil_scoped_acquire`.
136
+ auto &internals = detail::get_internals();
137
+ // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
138
+ tstate = PyEval_SaveThread();
139
+ if (disassoc) {
140
+ // Python >= 3.7 can remove this, it's an int before 3.7
141
+ // NOLINTNEXTLINE(readability-qualified-auto)
142
+ auto key = internals.tstate;
143
+ PYBIND11_TLS_DELETE_VALUE(key);
144
+ }
145
+ }
146
+
147
+ /// This method will disable the PyThreadState_DeleteCurrent call and the
148
+ /// GIL won't be acquired. This method should be used if the interpreter
149
+ /// could be shutting down when this is called, as thread deletion is not
150
+ /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
151
+ /// protect subsequent code.
152
+ PYBIND11_NOINLINE void disarm() { active = false; }
153
+
154
+ ~gil_scoped_release() {
155
+ if (!tstate) {
156
+ return;
157
+ }
158
+ // `PyEval_RestoreThread()` should not be called if runtime is finalizing
159
+ if (active) {
160
+ PyEval_RestoreThread(tstate);
161
+ }
162
+ if (disassoc) {
163
+ // Python >= 3.7 can remove this, it's an int before 3.7
164
+ // NOLINTNEXTLINE(readability-qualified-auto)
165
+ auto key = detail::get_internals().tstate;
166
+ PYBIND11_TLS_REPLACE_VALUE(key, tstate);
167
+ }
168
+ }
169
+
170
+ private:
171
+ PyThreadState *tstate;
172
+ bool disassoc;
173
+ bool active = true;
174
+ };
175
+ #elif defined(PYPY_VERSION)
176
+ class gil_scoped_acquire {
177
+ PyGILState_STATE state;
178
+
179
+ public:
180
+ gil_scoped_acquire() { state = PyGILState_Ensure(); }
181
+ ~gil_scoped_acquire() { PyGILState_Release(state); }
182
+ void disarm() {}
183
+ };
184
+
185
+ class gil_scoped_release {
186
+ PyThreadState *state;
187
+
188
+ public:
189
+ gil_scoped_release() { state = PyEval_SaveThread(); }
190
+ ~gil_scoped_release() { PyEval_RestoreThread(state); }
191
+ void disarm() {}
192
+ };
193
+ #else
194
+ class gil_scoped_acquire {
195
+ void disarm() {}
196
+ };
197
+ class gil_scoped_release {
198
+ void disarm() {}
199
+ };
200
+ #endif
201
+
202
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/iostream.h ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python
3
+
4
+ Copyright (c) 2017 Henry F. Schreiner
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+
9
+ WARNING: The implementation in this file is NOT thread safe. Multiple
10
+ threads writing to a redirected ostream concurrently cause data races
11
+ and potentially buffer overflows. Therefore it is currently a requirement
12
+ that all (possibly) concurrent redirected ostream writes are protected by
13
+ a mutex.
14
+ #HelpAppreciated: Work on iostream.h thread safety.
15
+ For more background see the discussions under
16
+ https://github.com/pybind/pybind11/pull/2982 and
17
+ https://github.com/pybind/pybind11/pull/2995.
18
+ */
19
+
20
+ #pragma once
21
+
22
+ #include "pybind11.h"
23
+
24
+ #include <algorithm>
25
+ #include <cstring>
26
+ #include <iostream>
27
+ #include <iterator>
28
+ #include <memory>
29
+ #include <ostream>
30
+ #include <streambuf>
31
+ #include <string>
32
+ #include <utility>
33
+
34
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
35
+ PYBIND11_NAMESPACE_BEGIN(detail)
36
+
37
+ // Buffer that writes to Python instead of C++
38
+ class pythonbuf : public std::streambuf {
39
+ private:
40
+ using traits_type = std::streambuf::traits_type;
41
+
42
+ const size_t buf_size;
43
+ std::unique_ptr<char[]> d_buffer;
44
+ object pywrite;
45
+ object pyflush;
46
+
47
+ int overflow(int c) override {
48
+ if (!traits_type::eq_int_type(c, traits_type::eof())) {
49
+ *pptr() = traits_type::to_char_type(c);
50
+ pbump(1);
51
+ }
52
+ return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof();
53
+ }
54
+
55
+ // Computes how many bytes at the end of the buffer are part of an
56
+ // incomplete sequence of UTF-8 bytes.
57
+ // Precondition: pbase() < pptr()
58
+ size_t utf8_remainder() const {
59
+ const auto rbase = std::reverse_iterator<char *>(pbase());
60
+ const auto rpptr = std::reverse_iterator<char *>(pptr());
61
+ auto is_ascii = [](char c) { return (static_cast<unsigned char>(c) & 0x80) == 0x00; };
62
+ auto is_leading = [](char c) { return (static_cast<unsigned char>(c) & 0xC0) == 0xC0; };
63
+ auto is_leading_2b = [](char c) { return static_cast<unsigned char>(c) <= 0xDF; };
64
+ auto is_leading_3b = [](char c) { return static_cast<unsigned char>(c) <= 0xEF; };
65
+ // If the last character is ASCII, there are no incomplete code points
66
+ if (is_ascii(*rpptr)) {
67
+ return 0;
68
+ }
69
+ // Otherwise, work back from the end of the buffer and find the first
70
+ // UTF-8 leading byte
71
+ const auto rpend = rbase - rpptr >= 3 ? rpptr + 3 : rbase;
72
+ const auto leading = std::find_if(rpptr, rpend, is_leading);
73
+ if (leading == rbase) {
74
+ return 0;
75
+ }
76
+ const auto dist = static_cast<size_t>(leading - rpptr);
77
+ size_t remainder = 0;
78
+
79
+ if (dist == 0) {
80
+ remainder = 1; // 1-byte code point is impossible
81
+ } else if (dist == 1) {
82
+ remainder = is_leading_2b(*leading) ? 0 : dist + 1;
83
+ } else if (dist == 2) {
84
+ remainder = is_leading_3b(*leading) ? 0 : dist + 1;
85
+ }
86
+ // else if (dist >= 3), at least 4 bytes before encountering an UTF-8
87
+ // leading byte, either no remainder or invalid UTF-8.
88
+ // Invalid UTF-8 will cause an exception later when converting
89
+ // to a Python string, so that's not handled here.
90
+ return remainder;
91
+ }
92
+
93
+ // This function must be non-virtual to be called in a destructor.
94
+ int _sync() {
95
+ if (pbase() != pptr()) { // If buffer is not empty
96
+ gil_scoped_acquire tmp;
97
+ // This subtraction cannot be negative, so dropping the sign.
98
+ auto size = static_cast<size_t>(pptr() - pbase());
99
+ size_t remainder = utf8_remainder();
100
+
101
+ if (size > remainder) {
102
+ str line(pbase(), size - remainder);
103
+ pywrite(std::move(line));
104
+ pyflush();
105
+ }
106
+
107
+ // Copy the remainder at the end of the buffer to the beginning:
108
+ if (remainder > 0) {
109
+ std::memmove(pbase(), pptr() - remainder, remainder);
110
+ }
111
+ setp(pbase(), epptr());
112
+ pbump(static_cast<int>(remainder));
113
+ }
114
+ return 0;
115
+ }
116
+
117
+ int sync() override { return _sync(); }
118
+
119
+ public:
120
+ explicit pythonbuf(const object &pyostream, size_t buffer_size = 1024)
121
+ : buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr("write")),
122
+ pyflush(pyostream.attr("flush")) {
123
+ setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
124
+ }
125
+
126
+ pythonbuf(pythonbuf &&) = default;
127
+
128
+ /// Sync before destroy
129
+ ~pythonbuf() override { _sync(); }
130
+ };
131
+
132
+ PYBIND11_NAMESPACE_END(detail)
133
+
134
+ /** \rst
135
+ This a move-only guard that redirects output.
136
+
137
+ .. code-block:: cpp
138
+
139
+ #include <pybind11/iostream.h>
140
+
141
+ ...
142
+
143
+ {
144
+ py::scoped_ostream_redirect output;
145
+ std::cout << "Hello, World!"; // Python stdout
146
+ } // <-- return std::cout to normal
147
+
148
+ You can explicitly pass the c++ stream and the python object,
149
+ for example to guard stderr instead.
150
+
151
+ .. code-block:: cpp
152
+
153
+ {
154
+ py::scoped_ostream_redirect output{
155
+ std::cerr, py::module::import("sys").attr("stderr")};
156
+ std::cout << "Hello, World!";
157
+ }
158
+ \endrst */
159
+ class scoped_ostream_redirect {
160
+ protected:
161
+ std::streambuf *old;
162
+ std::ostream &costream;
163
+ detail::pythonbuf buffer;
164
+
165
+ public:
166
+ explicit scoped_ostream_redirect(std::ostream &costream = std::cout,
167
+ const object &pyostream
168
+ = module_::import("sys").attr("stdout"))
169
+ : costream(costream), buffer(pyostream) {
170
+ old = costream.rdbuf(&buffer);
171
+ }
172
+
173
+ ~scoped_ostream_redirect() { costream.rdbuf(old); }
174
+
175
+ scoped_ostream_redirect(const scoped_ostream_redirect &) = delete;
176
+ scoped_ostream_redirect(scoped_ostream_redirect &&other) = default;
177
+ scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete;
178
+ scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete;
179
+ };
180
+
181
+ /** \rst
182
+ Like `scoped_ostream_redirect`, but redirects cerr by default. This class
183
+ is provided primary to make ``py::call_guard`` easier to make.
184
+
185
+ .. code-block:: cpp
186
+
187
+ m.def("noisy_func", &noisy_func,
188
+ py::call_guard<scoped_ostream_redirect,
189
+ scoped_estream_redirect>());
190
+
191
+ \endrst */
192
+ class scoped_estream_redirect : public scoped_ostream_redirect {
193
+ public:
194
+ explicit scoped_estream_redirect(std::ostream &costream = std::cerr,
195
+ const object &pyostream
196
+ = module_::import("sys").attr("stderr"))
197
+ : scoped_ostream_redirect(costream, pyostream) {}
198
+ };
199
+
200
+ PYBIND11_NAMESPACE_BEGIN(detail)
201
+
202
+ // Class to redirect output as a context manager. C++ backend.
203
+ class OstreamRedirect {
204
+ bool do_stdout_;
205
+ bool do_stderr_;
206
+ std::unique_ptr<scoped_ostream_redirect> redirect_stdout;
207
+ std::unique_ptr<scoped_estream_redirect> redirect_stderr;
208
+
209
+ public:
210
+ explicit OstreamRedirect(bool do_stdout = true, bool do_stderr = true)
211
+ : do_stdout_(do_stdout), do_stderr_(do_stderr) {}
212
+
213
+ void enter() {
214
+ if (do_stdout_) {
215
+ redirect_stdout.reset(new scoped_ostream_redirect());
216
+ }
217
+ if (do_stderr_) {
218
+ redirect_stderr.reset(new scoped_estream_redirect());
219
+ }
220
+ }
221
+
222
+ void exit() {
223
+ redirect_stdout.reset();
224
+ redirect_stderr.reset();
225
+ }
226
+ };
227
+
228
+ PYBIND11_NAMESPACE_END(detail)
229
+
230
+ /** \rst
231
+ This is a helper function to add a C++ redirect context manager to Python
232
+ instead of using a C++ guard. To use it, add the following to your binding code:
233
+
234
+ .. code-block:: cpp
235
+
236
+ #include <pybind11/iostream.h>
237
+
238
+ ...
239
+
240
+ py::add_ostream_redirect(m, "ostream_redirect");
241
+
242
+ You now have a Python context manager that redirects your output:
243
+
244
+ .. code-block:: python
245
+
246
+ with m.ostream_redirect():
247
+ m.print_to_cout_function()
248
+
249
+ This manager can optionally be told which streams to operate on:
250
+
251
+ .. code-block:: python
252
+
253
+ with m.ostream_redirect(stdout=true, stderr=true):
254
+ m.noisy_function_with_error_printing()
255
+
256
+ \endrst */
257
+ inline class_<detail::OstreamRedirect>
258
+ add_ostream_redirect(module_ m, const std::string &name = "ostream_redirect") {
259
+ return class_<detail::OstreamRedirect>(std::move(m), name.c_str(), module_local())
260
+ .def(init<bool, bool>(), arg("stdout") = true, arg("stderr") = true)
261
+ .def("__enter__", &detail::OstreamRedirect::enter)
262
+ .def("__exit__", [](detail::OstreamRedirect &self_, const args &) { self_.exit(); });
263
+ }
264
+
265
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/numpy.h ADDED
@@ -0,0 +1,1984 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/numpy.h: Basic NumPy support, vectorize() wrapper
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "pybind11.h"
13
+ #include "complex.h"
14
+
15
+ #include <algorithm>
16
+ #include <array>
17
+ #include <cstdint>
18
+ #include <cstdlib>
19
+ #include <cstring>
20
+ #include <functional>
21
+ #include <numeric>
22
+ #include <sstream>
23
+ #include <string>
24
+ #include <type_traits>
25
+ #include <typeindex>
26
+ #include <utility>
27
+ #include <vector>
28
+
29
+ /* This will be true on all flat address space platforms and allows us to reduce the
30
+ whole npy_intp / ssize_t / Py_intptr_t business down to just ssize_t for all size
31
+ and dimension types (e.g. shape, strides, indexing), instead of inflicting this
32
+ upon the library user. */
33
+ static_assert(sizeof(::pybind11::ssize_t) == sizeof(Py_intptr_t), "ssize_t != Py_intptr_t");
34
+ static_assert(std::is_signed<Py_intptr_t>::value, "Py_intptr_t must be signed");
35
+ // We now can reinterpret_cast between py::ssize_t and Py_intptr_t (MSVC + PyPy cares)
36
+
37
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
38
+
39
+ class array; // Forward declaration
40
+
41
+ PYBIND11_NAMESPACE_BEGIN(detail)
42
+
43
+ template <>
44
+ struct handle_type_name<array> {
45
+ static constexpr auto name = const_name("numpy.ndarray");
46
+ };
47
+
48
+ template <typename type, typename SFINAE = void>
49
+ struct npy_format_descriptor;
50
+
51
+ struct PyArrayDescr_Proxy {
52
+ PyObject_HEAD
53
+ PyObject *typeobj;
54
+ char kind;
55
+ char type;
56
+ char byteorder;
57
+ char flags;
58
+ int type_num;
59
+ int elsize;
60
+ int alignment;
61
+ char *subarray;
62
+ PyObject *fields;
63
+ PyObject *names;
64
+ };
65
+
66
+ struct PyArray_Proxy {
67
+ PyObject_HEAD
68
+ char *data;
69
+ int nd;
70
+ ssize_t *dimensions;
71
+ ssize_t *strides;
72
+ PyObject *base;
73
+ PyObject *descr;
74
+ int flags;
75
+ };
76
+
77
+ struct PyVoidScalarObject_Proxy {
78
+ PyObject_VAR_HEAD char *obval;
79
+ PyArrayDescr_Proxy *descr;
80
+ int flags;
81
+ PyObject *base;
82
+ };
83
+
84
+ struct numpy_type_info {
85
+ PyObject *dtype_ptr;
86
+ std::string format_str;
87
+ };
88
+
89
+ struct numpy_internals {
90
+ std::unordered_map<std::type_index, numpy_type_info> registered_dtypes;
91
+
92
+ numpy_type_info *get_type_info(const std::type_info &tinfo, bool throw_if_missing = true) {
93
+ auto it = registered_dtypes.find(std::type_index(tinfo));
94
+ if (it != registered_dtypes.end()) {
95
+ return &(it->second);
96
+ }
97
+ if (throw_if_missing) {
98
+ pybind11_fail(std::string("NumPy type info missing for ") + tinfo.name());
99
+ }
100
+ return nullptr;
101
+ }
102
+
103
+ template <typename T>
104
+ numpy_type_info *get_type_info(bool throw_if_missing = true) {
105
+ return get_type_info(typeid(typename std::remove_cv<T>::type), throw_if_missing);
106
+ }
107
+ };
108
+
109
+ PYBIND11_NOINLINE void load_numpy_internals(numpy_internals *&ptr) {
110
+ ptr = &get_or_create_shared_data<numpy_internals>("_numpy_internals");
111
+ }
112
+
113
+ inline numpy_internals &get_numpy_internals() {
114
+ static numpy_internals *ptr = nullptr;
115
+ if (!ptr) {
116
+ load_numpy_internals(ptr);
117
+ }
118
+ return *ptr;
119
+ }
120
+
121
+ template <typename T>
122
+ struct same_size {
123
+ template <typename U>
124
+ using as = bool_constant<sizeof(T) == sizeof(U)>;
125
+ };
126
+
127
+ template <typename Concrete>
128
+ constexpr int platform_lookup() {
129
+ return -1;
130
+ }
131
+
132
+ // Lookup a type according to its size, and return a value corresponding to the NumPy typenum.
133
+ template <typename Concrete, typename T, typename... Ts, typename... Ints>
134
+ constexpr int platform_lookup(int I, Ints... Is) {
135
+ return sizeof(Concrete) == sizeof(T) ? I : platform_lookup<Concrete, Ts...>(Is...);
136
+ }
137
+
138
+ struct npy_api {
139
+ enum constants {
140
+ NPY_ARRAY_C_CONTIGUOUS_ = 0x0001,
141
+ NPY_ARRAY_F_CONTIGUOUS_ = 0x0002,
142
+ NPY_ARRAY_OWNDATA_ = 0x0004,
143
+ NPY_ARRAY_FORCECAST_ = 0x0010,
144
+ NPY_ARRAY_ENSUREARRAY_ = 0x0040,
145
+ NPY_ARRAY_ALIGNED_ = 0x0100,
146
+ NPY_ARRAY_WRITEABLE_ = 0x0400,
147
+ NPY_BOOL_ = 0,
148
+ NPY_BYTE_,
149
+ NPY_UBYTE_,
150
+ NPY_SHORT_,
151
+ NPY_USHORT_,
152
+ NPY_INT_,
153
+ NPY_UINT_,
154
+ NPY_LONG_,
155
+ NPY_ULONG_,
156
+ NPY_LONGLONG_,
157
+ NPY_ULONGLONG_,
158
+ NPY_FLOAT_,
159
+ NPY_DOUBLE_,
160
+ NPY_LONGDOUBLE_,
161
+ NPY_CFLOAT_,
162
+ NPY_CDOUBLE_,
163
+ NPY_CLONGDOUBLE_,
164
+ NPY_OBJECT_ = 17,
165
+ NPY_STRING_,
166
+ NPY_UNICODE_,
167
+ NPY_VOID_,
168
+ // Platform-dependent normalization
169
+ NPY_INT8_ = NPY_BYTE_,
170
+ NPY_UINT8_ = NPY_UBYTE_,
171
+ NPY_INT16_ = NPY_SHORT_,
172
+ NPY_UINT16_ = NPY_USHORT_,
173
+ // `npy_common.h` defines the integer aliases. In order, it checks:
174
+ // NPY_BITSOF_LONG, NPY_BITSOF_LONGLONG, NPY_BITSOF_INT, NPY_BITSOF_SHORT, NPY_BITSOF_CHAR
175
+ // and assigns the alias to the first matching size, so we should check in this order.
176
+ NPY_INT32_
177
+ = platform_lookup<std::int32_t, long, int, short>(NPY_LONG_, NPY_INT_, NPY_SHORT_),
178
+ NPY_UINT32_ = platform_lookup<std::uint32_t, unsigned long, unsigned int, unsigned short>(
179
+ NPY_ULONG_, NPY_UINT_, NPY_USHORT_),
180
+ NPY_INT64_
181
+ = platform_lookup<std::int64_t, long, long long, int>(NPY_LONG_, NPY_LONGLONG_, NPY_INT_),
182
+ NPY_UINT64_
183
+ = platform_lookup<std::uint64_t, unsigned long, unsigned long long, unsigned int>(
184
+ NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),
185
+ };
186
+
187
+ struct PyArray_Dims {
188
+ Py_intptr_t *ptr;
189
+ int len;
190
+ };
191
+
192
+ static npy_api &get() {
193
+ static npy_api api = lookup();
194
+ return api;
195
+ }
196
+
197
+ bool PyArray_Check_(PyObject *obj) const {
198
+ return PyObject_TypeCheck(obj, PyArray_Type_) != 0;
199
+ }
200
+ bool PyArrayDescr_Check_(PyObject *obj) const {
201
+ return PyObject_TypeCheck(obj, PyArrayDescr_Type_) != 0;
202
+ }
203
+
204
+ unsigned int (*PyArray_GetNDArrayCFeatureVersion_)();
205
+ PyObject *(*PyArray_DescrFromType_)(int);
206
+ PyObject *(*PyArray_NewFromDescr_)(PyTypeObject *,
207
+ PyObject *,
208
+ int,
209
+ Py_intptr_t const *,
210
+ Py_intptr_t const *,
211
+ void *,
212
+ int,
213
+ PyObject *);
214
+ // Unused. Not removed because that affects ABI of the class.
215
+ PyObject *(*PyArray_DescrNewFromType_)(int);
216
+ int (*PyArray_CopyInto_)(PyObject *, PyObject *);
217
+ PyObject *(*PyArray_NewCopy_)(PyObject *, int);
218
+ PyTypeObject *PyArray_Type_;
219
+ PyTypeObject *PyVoidArrType_Type_;
220
+ PyTypeObject *PyArrayDescr_Type_;
221
+ PyObject *(*PyArray_DescrFromScalar_)(PyObject *);
222
+ PyObject *(*PyArray_FromAny_)(PyObject *, PyObject *, int, int, int, PyObject *);
223
+ int (*PyArray_DescrConverter_)(PyObject *, PyObject **);
224
+ bool (*PyArray_EquivTypes_)(PyObject *, PyObject *);
225
+ int (*PyArray_GetArrayParamsFromObject_)(PyObject *,
226
+ PyObject *,
227
+ unsigned char,
228
+ PyObject **,
229
+ int *,
230
+ Py_intptr_t *,
231
+ PyObject **,
232
+ PyObject *);
233
+ PyObject *(*PyArray_Squeeze_)(PyObject *);
234
+ // Unused. Not removed because that affects ABI of the class.
235
+ int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);
236
+ PyObject *(*PyArray_Resize_)(PyObject *, PyArray_Dims *, int, int);
237
+ PyObject *(*PyArray_Newshape_)(PyObject *, PyArray_Dims *, int);
238
+ PyObject *(*PyArray_View_)(PyObject *, PyObject *, PyObject *);
239
+
240
+ private:
241
+ enum functions {
242
+ API_PyArray_GetNDArrayCFeatureVersion = 211,
243
+ API_PyArray_Type = 2,
244
+ API_PyArrayDescr_Type = 3,
245
+ API_PyVoidArrType_Type = 39,
246
+ API_PyArray_DescrFromType = 45,
247
+ API_PyArray_DescrFromScalar = 57,
248
+ API_PyArray_FromAny = 69,
249
+ API_PyArray_Resize = 80,
250
+ API_PyArray_CopyInto = 82,
251
+ API_PyArray_NewCopy = 85,
252
+ API_PyArray_NewFromDescr = 94,
253
+ API_PyArray_DescrNewFromType = 96,
254
+ API_PyArray_Newshape = 135,
255
+ API_PyArray_Squeeze = 136,
256
+ API_PyArray_View = 137,
257
+ API_PyArray_DescrConverter = 174,
258
+ API_PyArray_EquivTypes = 182,
259
+ API_PyArray_GetArrayParamsFromObject = 278,
260
+ API_PyArray_SetBaseObject = 282
261
+ };
262
+
263
+ static npy_api lookup() {
264
+ module_ m = module_::import("numpy.core.multiarray");
265
+ auto c = m.attr("_ARRAY_API");
266
+ void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), nullptr);
267
+ npy_api api;
268
+ #define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];
269
+ DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion);
270
+ if (api.PyArray_GetNDArrayCFeatureVersion_() < 0x7) {
271
+ pybind11_fail("pybind11 numpy support requires numpy >= 1.7.0");
272
+ }
273
+ DECL_NPY_API(PyArray_Type);
274
+ DECL_NPY_API(PyVoidArrType_Type);
275
+ DECL_NPY_API(PyArrayDescr_Type);
276
+ DECL_NPY_API(PyArray_DescrFromType);
277
+ DECL_NPY_API(PyArray_DescrFromScalar);
278
+ DECL_NPY_API(PyArray_FromAny);
279
+ DECL_NPY_API(PyArray_Resize);
280
+ DECL_NPY_API(PyArray_CopyInto);
281
+ DECL_NPY_API(PyArray_NewCopy);
282
+ DECL_NPY_API(PyArray_NewFromDescr);
283
+ DECL_NPY_API(PyArray_DescrNewFromType);
284
+ DECL_NPY_API(PyArray_Newshape);
285
+ DECL_NPY_API(PyArray_Squeeze);
286
+ DECL_NPY_API(PyArray_View);
287
+ DECL_NPY_API(PyArray_DescrConverter);
288
+ DECL_NPY_API(PyArray_EquivTypes);
289
+ DECL_NPY_API(PyArray_GetArrayParamsFromObject);
290
+ DECL_NPY_API(PyArray_SetBaseObject);
291
+
292
+ #undef DECL_NPY_API
293
+ return api;
294
+ }
295
+ };
296
+
297
+ inline PyArray_Proxy *array_proxy(void *ptr) { return reinterpret_cast<PyArray_Proxy *>(ptr); }
298
+
299
+ inline const PyArray_Proxy *array_proxy(const void *ptr) {
300
+ return reinterpret_cast<const PyArray_Proxy *>(ptr);
301
+ }
302
+
303
+ inline PyArrayDescr_Proxy *array_descriptor_proxy(PyObject *ptr) {
304
+ return reinterpret_cast<PyArrayDescr_Proxy *>(ptr);
305
+ }
306
+
307
+ inline const PyArrayDescr_Proxy *array_descriptor_proxy(const PyObject *ptr) {
308
+ return reinterpret_cast<const PyArrayDescr_Proxy *>(ptr);
309
+ }
310
+
311
+ inline bool check_flags(const void *ptr, int flag) {
312
+ return (flag == (array_proxy(ptr)->flags & flag));
313
+ }
314
+
315
+ template <typename T>
316
+ struct is_std_array : std::false_type {};
317
+ template <typename T, size_t N>
318
+ struct is_std_array<std::array<T, N>> : std::true_type {};
319
+ template <typename T>
320
+ struct is_complex : std::false_type {};
321
+ template <typename T>
322
+ struct is_complex<std::complex<T>> : std::true_type {};
323
+
324
+ template <typename T>
325
+ struct array_info_scalar {
326
+ using type = T;
327
+ static constexpr bool is_array = false;
328
+ static constexpr bool is_empty = false;
329
+ static constexpr auto extents = const_name("");
330
+ static void append_extents(list & /* shape */) {}
331
+ };
332
+ // Computes underlying type and a comma-separated list of extents for array
333
+ // types (any mix of std::array and built-in arrays). An array of char is
334
+ // treated as scalar because it gets special handling.
335
+ template <typename T>
336
+ struct array_info : array_info_scalar<T> {};
337
+ template <typename T, size_t N>
338
+ struct array_info<std::array<T, N>> {
339
+ using type = typename array_info<T>::type;
340
+ static constexpr bool is_array = true;
341
+ static constexpr bool is_empty = (N == 0) || array_info<T>::is_empty;
342
+ static constexpr size_t extent = N;
343
+
344
+ // appends the extents to shape
345
+ static void append_extents(list &shape) {
346
+ shape.append(N);
347
+ array_info<T>::append_extents(shape);
348
+ }
349
+
350
+ static constexpr auto extents = const_name<array_info<T>::is_array>(
351
+ concat(const_name<N>(), array_info<T>::extents), const_name<N>());
352
+ };
353
+ // For numpy we have special handling for arrays of characters, so we don't include
354
+ // the size in the array extents.
355
+ template <size_t N>
356
+ struct array_info<char[N]> : array_info_scalar<char[N]> {};
357
+ template <size_t N>
358
+ struct array_info<std::array<char, N>> : array_info_scalar<std::array<char, N>> {};
359
+ template <typename T, size_t N>
360
+ struct array_info<T[N]> : array_info<std::array<T, N>> {};
361
+ template <typename T>
362
+ using remove_all_extents_t = typename array_info<T>::type;
363
+
364
+ template <typename T>
365
+ using is_pod_struct
366
+ = all_of<std::is_standard_layout<T>, // since we're accessing directly in memory
367
+ // we need a standard layout type
368
+ #if defined(__GLIBCXX__) \
369
+ && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150426 || __GLIBCXX__ == 20150623 \
370
+ || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803)
371
+ // libstdc++ < 5 (including versions 4.8.5, 4.9.3 and 4.9.4 which were released after
372
+ // 5) don't implement is_trivially_copyable, so approximate it
373
+ std::is_trivially_destructible<T>,
374
+ satisfies_any_of<T, std::has_trivial_copy_constructor, std::has_trivial_copy_assign>,
375
+ #else
376
+ std::is_trivially_copyable<T>,
377
+ #endif
378
+ satisfies_none_of<T,
379
+ std::is_reference,
380
+ std::is_array,
381
+ is_std_array,
382
+ std::is_arithmetic,
383
+ is_complex,
384
+ std::is_enum>>;
385
+
386
+ // Replacement for std::is_pod (deprecated in C++20)
387
+ template <typename T>
388
+ using is_pod = all_of<std::is_standard_layout<T>, std::is_trivial<T>>;
389
+
390
+ template <ssize_t Dim = 0, typename Strides>
391
+ ssize_t byte_offset_unsafe(const Strides &) {
392
+ return 0;
393
+ }
394
+ template <ssize_t Dim = 0, typename Strides, typename... Ix>
395
+ ssize_t byte_offset_unsafe(const Strides &strides, ssize_t i, Ix... index) {
396
+ return i * strides[Dim] + byte_offset_unsafe<Dim + 1>(strides, index...);
397
+ }
398
+
399
+ /**
400
+ * Proxy class providing unsafe, unchecked const access to array data. This is constructed through
401
+ * the `unchecked<T, N>()` method of `array` or the `unchecked<N>()` method of `array_t<T>`. `Dims`
402
+ * will be -1 for dimensions determined at runtime.
403
+ */
404
+ template <typename T, ssize_t Dims>
405
+ class unchecked_reference {
406
+ protected:
407
+ static constexpr bool Dynamic = Dims < 0;
408
+ const unsigned char *data_;
409
+ // Storing the shape & strides in local variables (i.e. these arrays) allows the compiler to
410
+ // make large performance gains on big, nested loops, but requires compile-time dimensions
411
+ conditional_t<Dynamic, const ssize_t *, std::array<ssize_t, (size_t) Dims>> shape_, strides_;
412
+ const ssize_t dims_;
413
+
414
+ friend class pybind11::array;
415
+ // Constructor for compile-time dimensions:
416
+ template <bool Dyn = Dynamic>
417
+ unchecked_reference(const void *data,
418
+ const ssize_t *shape,
419
+ const ssize_t *strides,
420
+ enable_if_t<!Dyn, ssize_t>)
421
+ : data_{reinterpret_cast<const unsigned char *>(data)}, dims_{Dims} {
422
+ for (size_t i = 0; i < (size_t) dims_; i++) {
423
+ shape_[i] = shape[i];
424
+ strides_[i] = strides[i];
425
+ }
426
+ }
427
+ // Constructor for runtime dimensions:
428
+ template <bool Dyn = Dynamic>
429
+ unchecked_reference(const void *data,
430
+ const ssize_t *shape,
431
+ const ssize_t *strides,
432
+ enable_if_t<Dyn, ssize_t> dims)
433
+ : data_{reinterpret_cast<const unsigned char *>(data)}, shape_{shape}, strides_{strides},
434
+ dims_{dims} {}
435
+
436
+ public:
437
+ /**
438
+ * Unchecked const reference access to data at the given indices. For a compile-time known
439
+ * number of dimensions, this requires the correct number of arguments; for run-time
440
+ * dimensionality, this is not checked (and so is up to the caller to use safely).
441
+ */
442
+ template <typename... Ix>
443
+ const T &operator()(Ix... index) const {
444
+ static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic,
445
+ "Invalid number of indices for unchecked array reference");
446
+ return *reinterpret_cast<const T *>(data_
447
+ + byte_offset_unsafe(strides_, ssize_t(index)...));
448
+ }
449
+ /**
450
+ * Unchecked const reference access to data; this operator only participates if the reference
451
+ * is to a 1-dimensional array. When present, this is exactly equivalent to `obj(index)`.
452
+ */
453
+ template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>
454
+ const T &operator[](ssize_t index) const {
455
+ return operator()(index);
456
+ }
457
+
458
+ /// Pointer access to the data at the given indices.
459
+ template <typename... Ix>
460
+ const T *data(Ix... ix) const {
461
+ return &operator()(ssize_t(ix)...);
462
+ }
463
+
464
+ /// Returns the item size, i.e. sizeof(T)
465
+ constexpr static ssize_t itemsize() { return sizeof(T); }
466
+
467
+ /// Returns the shape (i.e. size) of dimension `dim`
468
+ ssize_t shape(ssize_t dim) const { return shape_[(size_t) dim]; }
469
+
470
+ /// Returns the number of dimensions of the array
471
+ ssize_t ndim() const { return dims_; }
472
+
473
+ /// Returns the total number of elements in the referenced array, i.e. the product of the
474
+ /// shapes
475
+ template <bool Dyn = Dynamic>
476
+ enable_if_t<!Dyn, ssize_t> size() const {
477
+ return std::accumulate(
478
+ shape_.begin(), shape_.end(), (ssize_t) 1, std::multiplies<ssize_t>());
479
+ }
480
+ template <bool Dyn = Dynamic>
481
+ enable_if_t<Dyn, ssize_t> size() const {
482
+ return std::accumulate(shape_, shape_ + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());
483
+ }
484
+
485
+ /// Returns the total number of bytes used by the referenced data. Note that the actual span
486
+ /// in memory may be larger if the referenced array has non-contiguous strides (e.g. for a
487
+ /// slice).
488
+ ssize_t nbytes() const { return size() * itemsize(); }
489
+ };
490
+
491
+ template <typename T, ssize_t Dims>
492
+ class unchecked_mutable_reference : public unchecked_reference<T, Dims> {
493
+ friend class pybind11::array;
494
+ using ConstBase = unchecked_reference<T, Dims>;
495
+ using ConstBase::ConstBase;
496
+ using ConstBase::Dynamic;
497
+
498
+ public:
499
+ // Bring in const-qualified versions from base class
500
+ using ConstBase::operator();
501
+ using ConstBase::operator[];
502
+
503
+ /// Mutable, unchecked access to data at the given indices.
504
+ template <typename... Ix>
505
+ T &operator()(Ix... index) {
506
+ static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic,
507
+ "Invalid number of indices for unchecked array reference");
508
+ return const_cast<T &>(ConstBase::operator()(index...));
509
+ }
510
+ /**
511
+ * Mutable, unchecked access data at the given index; this operator only participates if the
512
+ * reference is to a 1-dimensional array (or has runtime dimensions). When present, this is
513
+ * exactly equivalent to `obj(index)`.
514
+ */
515
+ template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>
516
+ T &operator[](ssize_t index) {
517
+ return operator()(index);
518
+ }
519
+
520
+ /// Mutable pointer access to the data at the given indices.
521
+ template <typename... Ix>
522
+ T *mutable_data(Ix... ix) {
523
+ return &operator()(ssize_t(ix)...);
524
+ }
525
+ };
526
+
527
+ template <typename T, ssize_t Dim>
528
+ struct type_caster<unchecked_reference<T, Dim>> {
529
+ static_assert(Dim == 0 && Dim > 0 /* always fail */,
530
+ "unchecked array proxy object is not castable");
531
+ };
532
+ template <typename T, ssize_t Dim>
533
+ struct type_caster<unchecked_mutable_reference<T, Dim>>
534
+ : type_caster<unchecked_reference<T, Dim>> {};
535
+
536
+ PYBIND11_NAMESPACE_END(detail)
537
+
538
+ class dtype : public object {
539
+ public:
540
+ PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_);
541
+
542
+ explicit dtype(const buffer_info &info) {
543
+ dtype descr(_dtype_from_pep3118()(pybind11::str(info.format)));
544
+ // If info.itemsize == 0, use the value calculated from the format string
545
+ m_ptr = descr.strip_padding(info.itemsize != 0 ? info.itemsize : descr.itemsize())
546
+ .release()
547
+ .ptr();
548
+ }
549
+
550
+ explicit dtype(const pybind11::str &format) : dtype(from_args(format)) {}
551
+
552
+ explicit dtype(const std::string &format) : dtype(pybind11::str(format)) {}
553
+
554
+ explicit dtype(const char *format) : dtype(pybind11::str(format)) {}
555
+
556
+ dtype(list names, list formats, list offsets, ssize_t itemsize) {
557
+ dict args;
558
+ args["names"] = std::move(names);
559
+ args["formats"] = std::move(formats);
560
+ args["offsets"] = std::move(offsets);
561
+ args["itemsize"] = pybind11::int_(itemsize);
562
+ m_ptr = from_args(args).release().ptr();
563
+ }
564
+
565
+ explicit dtype(int typenum)
566
+ : object(detail::npy_api::get().PyArray_DescrFromType_(typenum), stolen_t{}) {
567
+ if (m_ptr == nullptr) {
568
+ throw error_already_set();
569
+ }
570
+ }
571
+
572
+ /// This is essentially the same as calling numpy.dtype(args) in Python.
573
+ static dtype from_args(const object &args) {
574
+ PyObject *ptr = nullptr;
575
+ if ((detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) == 0) || !ptr) {
576
+ throw error_already_set();
577
+ }
578
+ return reinterpret_steal<dtype>(ptr);
579
+ }
580
+
581
+ /// Return dtype associated with a C++ type.
582
+ template <typename T>
583
+ static dtype of() {
584
+ return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype();
585
+ }
586
+
587
+ /// Size of the data type in bytes.
588
+ ssize_t itemsize() const { return detail::array_descriptor_proxy(m_ptr)->elsize; }
589
+
590
+ /// Returns true for structured data types.
591
+ bool has_fields() const { return detail::array_descriptor_proxy(m_ptr)->names != nullptr; }
592
+
593
+ /// Single-character code for dtype's kind.
594
+ /// For example, floating point types are 'f' and integral types are 'i'.
595
+ char kind() const { return detail::array_descriptor_proxy(m_ptr)->kind; }
596
+
597
+ /// Single-character for dtype's type.
598
+ /// For example, ``float`` is 'f', ``double`` 'd', ``int`` 'i', and ``long`` 'l'.
599
+ char char_() const {
600
+ // Note: The signature, `dtype::char_` follows the naming of NumPy's
601
+ // public Python API (i.e., ``dtype.char``), rather than its internal
602
+ // C API (``PyArray_Descr::type``).
603
+ return detail::array_descriptor_proxy(m_ptr)->type;
604
+ }
605
+
606
+ /// type number of dtype.
607
+ int num() const {
608
+ // Note: The signature, `dtype::num` follows the naming of NumPy's public
609
+ // Python API (i.e., ``dtype.num``), rather than its internal
610
+ // C API (``PyArray_Descr::type_num``).
611
+ return detail::array_descriptor_proxy(m_ptr)->type_num;
612
+ }
613
+
614
+ /// Single character for byteorder
615
+ char byteorder() const { return detail::array_descriptor_proxy(m_ptr)->byteorder; }
616
+
617
+ /// Alignment of the data type
618
+ int alignment() const { return detail::array_descriptor_proxy(m_ptr)->alignment; }
619
+
620
+ /// Flags for the array descriptor
621
+ char flags() const { return detail::array_descriptor_proxy(m_ptr)->flags; }
622
+
623
+ private:
624
+ static object _dtype_from_pep3118() {
625
+ static PyObject *obj = module_::import("numpy.core._internal")
626
+ .attr("_dtype_from_pep3118")
627
+ .cast<object>()
628
+ .release()
629
+ .ptr();
630
+ return reinterpret_borrow<object>(obj);
631
+ }
632
+
633
+ dtype strip_padding(ssize_t itemsize) {
634
+ // Recursively strip all void fields with empty names that are generated for
635
+ // padding fields (as of NumPy v1.11).
636
+ if (!has_fields()) {
637
+ return *this;
638
+ }
639
+
640
+ struct field_descr {
641
+ pybind11::str name;
642
+ object format;
643
+ pybind11::int_ offset;
644
+ field_descr(pybind11::str &&name, object &&format, pybind11::int_ &&offset)
645
+ : name{std::move(name)}, format{std::move(format)}, offset{std::move(offset)} {};
646
+ };
647
+ auto field_dict = attr("fields").cast<dict>();
648
+ std::vector<field_descr> field_descriptors;
649
+ field_descriptors.reserve(field_dict.size());
650
+
651
+ for (auto field : field_dict.attr("items")()) {
652
+ auto spec = field.cast<tuple>();
653
+ auto name = spec[0].cast<pybind11::str>();
654
+ auto spec_fo = spec[1].cast<tuple>();
655
+ auto format = spec_fo[0].cast<dtype>();
656
+ auto offset = spec_fo[1].cast<pybind11::int_>();
657
+ if ((len(name) == 0u) && format.kind() == 'V') {
658
+ continue;
659
+ }
660
+ field_descriptors.emplace_back(
661
+ std::move(name), format.strip_padding(format.itemsize()), std::move(offset));
662
+ }
663
+
664
+ std::sort(field_descriptors.begin(),
665
+ field_descriptors.end(),
666
+ [](const field_descr &a, const field_descr &b) {
667
+ return a.offset.cast<int>() < b.offset.cast<int>();
668
+ });
669
+
670
+ list names, formats, offsets;
671
+ for (auto &descr : field_descriptors) {
672
+ names.append(std::move(descr.name));
673
+ formats.append(std::move(descr.format));
674
+ offsets.append(std::move(descr.offset));
675
+ }
676
+ return dtype(std::move(names), std::move(formats), std::move(offsets), itemsize);
677
+ }
678
+ };
679
+
680
+ class array : public buffer {
681
+ public:
682
+ PYBIND11_OBJECT_CVT(array, buffer, detail::npy_api::get().PyArray_Check_, raw_array)
683
+
684
+ enum {
685
+ c_style = detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_,
686
+ f_style = detail::npy_api::NPY_ARRAY_F_CONTIGUOUS_,
687
+ forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_
688
+ };
689
+
690
+ array() : array(0, static_cast<const double *>(nullptr)) {}
691
+
692
+ using ShapeContainer = detail::any_container<ssize_t>;
693
+ using StridesContainer = detail::any_container<ssize_t>;
694
+
695
+ // Constructs an array taking shape/strides from arbitrary container types
696
+ array(const pybind11::dtype &dt,
697
+ ShapeContainer shape,
698
+ StridesContainer strides,
699
+ const void *ptr = nullptr,
700
+ handle base = handle()) {
701
+
702
+ if (strides->empty()) {
703
+ *strides = detail::c_strides(*shape, dt.itemsize());
704
+ }
705
+
706
+ auto ndim = shape->size();
707
+ if (ndim != strides->size()) {
708
+ pybind11_fail("NumPy: shape ndim doesn't match strides ndim");
709
+ }
710
+ auto descr = dt;
711
+
712
+ int flags = 0;
713
+ if (base && ptr) {
714
+ if (isinstance<array>(base)) {
715
+ /* Copy flags from base (except ownership bit) */
716
+ flags = reinterpret_borrow<array>(base).flags()
717
+ & ~detail::npy_api::NPY_ARRAY_OWNDATA_;
718
+ } else {
719
+ /* Writable by default, easy to downgrade later on if needed */
720
+ flags = detail::npy_api::NPY_ARRAY_WRITEABLE_;
721
+ }
722
+ }
723
+
724
+ auto &api = detail::npy_api::get();
725
+ auto tmp = reinterpret_steal<object>(api.PyArray_NewFromDescr_(
726
+ api.PyArray_Type_,
727
+ descr.release().ptr(),
728
+ (int) ndim,
729
+ // Use reinterpret_cast for PyPy on Windows (remove if fixed, checked on 7.3.1)
730
+ reinterpret_cast<Py_intptr_t *>(shape->data()),
731
+ reinterpret_cast<Py_intptr_t *>(strides->data()),
732
+ const_cast<void *>(ptr),
733
+ flags,
734
+ nullptr));
735
+ if (!tmp) {
736
+ throw error_already_set();
737
+ }
738
+ if (ptr) {
739
+ if (base) {
740
+ api.PyArray_SetBaseObject_(tmp.ptr(), base.inc_ref().ptr());
741
+ } else {
742
+ tmp = reinterpret_steal<object>(
743
+ api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */));
744
+ }
745
+ }
746
+ m_ptr = tmp.release().ptr();
747
+ }
748
+
749
+ array(const pybind11::dtype &dt,
750
+ ShapeContainer shape,
751
+ const void *ptr = nullptr,
752
+ handle base = handle())
753
+ : array(dt, std::move(shape), {}, ptr, base) {}
754
+
755
+ template <typename T,
756
+ typename
757
+ = detail::enable_if_t<std::is_integral<T>::value && !std::is_same<bool, T>::value>>
758
+ array(const pybind11::dtype &dt, T count, const void *ptr = nullptr, handle base = handle())
759
+ : array(dt, {{count}}, ptr, base) {}
760
+
761
+ template <typename T>
762
+ array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle())
763
+ : array(pybind11::dtype::of<T>(), std::move(shape), std::move(strides), ptr, base) {}
764
+
765
+ template <typename T>
766
+ array(ShapeContainer shape, const T *ptr, handle base = handle())
767
+ : array(std::move(shape), {}, ptr, base) {}
768
+
769
+ template <typename T>
770
+ explicit array(ssize_t count, const T *ptr, handle base = handle())
771
+ : array({count}, {}, ptr, base) {}
772
+
773
+ explicit array(const buffer_info &info, handle base = handle())
774
+ : array(pybind11::dtype(info), info.shape, info.strides, info.ptr, base) {}
775
+
776
+ /// Array descriptor (dtype)
777
+ pybind11::dtype dtype() const {
778
+ return reinterpret_borrow<pybind11::dtype>(detail::array_proxy(m_ptr)->descr);
779
+ }
780
+
781
+ /// Total number of elements
782
+ ssize_t size() const {
783
+ return std::accumulate(shape(), shape() + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());
784
+ }
785
+
786
+ /// Byte size of a single element
787
+ ssize_t itemsize() const {
788
+ return detail::array_descriptor_proxy(detail::array_proxy(m_ptr)->descr)->elsize;
789
+ }
790
+
791
+ /// Total number of bytes
792
+ ssize_t nbytes() const { return size() * itemsize(); }
793
+
794
+ /// Number of dimensions
795
+ ssize_t ndim() const { return detail::array_proxy(m_ptr)->nd; }
796
+
797
+ /// Base object
798
+ object base() const { return reinterpret_borrow<object>(detail::array_proxy(m_ptr)->base); }
799
+
800
+ /// Dimensions of the array
801
+ const ssize_t *shape() const { return detail::array_proxy(m_ptr)->dimensions; }
802
+
803
+ /// Dimension along a given axis
804
+ ssize_t shape(ssize_t dim) const {
805
+ if (dim >= ndim()) {
806
+ fail_dim_check(dim, "invalid axis");
807
+ }
808
+ return shape()[dim];
809
+ }
810
+
811
+ /// Strides of the array
812
+ const ssize_t *strides() const { return detail::array_proxy(m_ptr)->strides; }
813
+
814
+ /// Stride along a given axis
815
+ ssize_t strides(ssize_t dim) const {
816
+ if (dim >= ndim()) {
817
+ fail_dim_check(dim, "invalid axis");
818
+ }
819
+ return strides()[dim];
820
+ }
821
+
822
+ /// Return the NumPy array flags
823
+ int flags() const { return detail::array_proxy(m_ptr)->flags; }
824
+
825
+ /// If set, the array is writeable (otherwise the buffer is read-only)
826
+ bool writeable() const {
827
+ return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_WRITEABLE_);
828
+ }
829
+
830
+ /// If set, the array owns the data (will be freed when the array is deleted)
831
+ bool owndata() const {
832
+ return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_OWNDATA_);
833
+ }
834
+
835
+ /// Pointer to the contained data. If index is not provided, points to the
836
+ /// beginning of the buffer. May throw if the index would lead to out of bounds access.
837
+ template <typename... Ix>
838
+ const void *data(Ix... index) const {
839
+ return static_cast<const void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));
840
+ }
841
+
842
+ /// Mutable pointer to the contained data. If index is not provided, points to the
843
+ /// beginning of the buffer. May throw if the index would lead to out of bounds access.
844
+ /// May throw if the array is not writeable.
845
+ template <typename... Ix>
846
+ void *mutable_data(Ix... index) {
847
+ check_writeable();
848
+ return static_cast<void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));
849
+ }
850
+
851
+ /// Byte offset from beginning of the array to a given index (full or partial).
852
+ /// May throw if the index would lead to out of bounds access.
853
+ template <typename... Ix>
854
+ ssize_t offset_at(Ix... index) const {
855
+ if ((ssize_t) sizeof...(index) > ndim()) {
856
+ fail_dim_check(sizeof...(index), "too many indices for an array");
857
+ }
858
+ return byte_offset(ssize_t(index)...);
859
+ }
860
+
861
+ ssize_t offset_at() const { return 0; }
862
+
863
+ /// Item count from beginning of the array to a given index (full or partial).
864
+ /// May throw if the index would lead to out of bounds access.
865
+ template <typename... Ix>
866
+ ssize_t index_at(Ix... index) const {
867
+ return offset_at(index...) / itemsize();
868
+ }
869
+
870
+ /**
871
+ * Returns a proxy object that provides access to the array's data without bounds or
872
+ * dimensionality checking. Will throw if the array is missing the `writeable` flag. Use with
873
+ * care: the array must not be destroyed or reshaped for the duration of the returned object,
874
+ * and the caller must take care not to access invalid dimensions or dimension indices.
875
+ */
876
+ template <typename T, ssize_t Dims = -1>
877
+ detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
878
+ if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
879
+ throw std::domain_error("array has incorrect number of dimensions: "
880
+ + std::to_string(ndim()) + "; expected "
881
+ + std::to_string(Dims));
882
+ }
883
+ return detail::unchecked_mutable_reference<T, Dims>(
884
+ mutable_data(), shape(), strides(), ndim());
885
+ }
886
+
887
+ /**
888
+ * Returns a proxy object that provides const access to the array's data without bounds or
889
+ * dimensionality checking. Unlike `mutable_unchecked()`, this does not require that the
890
+ * underlying array have the `writable` flag. Use with care: the array must not be destroyed
891
+ * or reshaped for the duration of the returned object, and the caller must take care not to
892
+ * access invalid dimensions or dimension indices.
893
+ */
894
+ template <typename T, ssize_t Dims = -1>
895
+ detail::unchecked_reference<T, Dims> unchecked() const & {
896
+ if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {
897
+ throw std::domain_error("array has incorrect number of dimensions: "
898
+ + std::to_string(ndim()) + "; expected "
899
+ + std::to_string(Dims));
900
+ }
901
+ return detail::unchecked_reference<T, Dims>(data(), shape(), strides(), ndim());
902
+ }
903
+
904
+ /// Return a new view with all of the dimensions of length 1 removed
905
+ array squeeze() {
906
+ auto &api = detail::npy_api::get();
907
+ return reinterpret_steal<array>(api.PyArray_Squeeze_(m_ptr));
908
+ }
909
+
910
+ /// Resize array to given shape
911
+ /// If refcheck is true and more that one reference exist to this array
912
+ /// then resize will succeed only if it makes a reshape, i.e. original size doesn't change
913
+ void resize(ShapeContainer new_shape, bool refcheck = true) {
914
+ detail::npy_api::PyArray_Dims d
915
+ = {// Use reinterpret_cast for PyPy on Windows (remove if fixed, checked on 7.3.1)
916
+ reinterpret_cast<Py_intptr_t *>(new_shape->data()),
917
+ int(new_shape->size())};
918
+ // try to resize, set ordering param to -1 cause it's not used anyway
919
+ auto new_array = reinterpret_steal<object>(
920
+ detail::npy_api::get().PyArray_Resize_(m_ptr, &d, int(refcheck), -1));
921
+ if (!new_array) {
922
+ throw error_already_set();
923
+ }
924
+ if (isinstance<array>(new_array)) {
925
+ *this = std::move(new_array);
926
+ }
927
+ }
928
+
929
+ /// Optional `order` parameter omitted, to be added as needed.
930
+ array reshape(ShapeContainer new_shape) {
931
+ detail::npy_api::PyArray_Dims d
932
+ = {reinterpret_cast<Py_intptr_t *>(new_shape->data()), int(new_shape->size())};
933
+ auto new_array
934
+ = reinterpret_steal<array>(detail::npy_api::get().PyArray_Newshape_(m_ptr, &d, 0));
935
+ if (!new_array) {
936
+ throw error_already_set();
937
+ }
938
+ return new_array;
939
+ }
940
+
941
+ /// Create a view of an array in a different data type.
942
+ /// This function may fundamentally reinterpret the data in the array.
943
+ /// It is the responsibility of the caller to ensure that this is safe.
944
+ /// Only supports the `dtype` argument, the `type` argument is omitted,
945
+ /// to be added as needed.
946
+ array view(const std::string &dtype) {
947
+ auto &api = detail::npy_api::get();
948
+ auto new_view = reinterpret_steal<array>(api.PyArray_View_(
949
+ m_ptr, dtype::from_args(pybind11::str(dtype)).release().ptr(), nullptr));
950
+ if (!new_view) {
951
+ throw error_already_set();
952
+ }
953
+ return new_view;
954
+ }
955
+
956
+ /// Ensure that the argument is a NumPy array
957
+ /// In case of an error, nullptr is returned and the Python error is cleared.
958
+ static array ensure(handle h, int ExtraFlags = 0) {
959
+ auto result = reinterpret_steal<array>(raw_array(h.ptr(), ExtraFlags));
960
+ if (!result) {
961
+ PyErr_Clear();
962
+ }
963
+ return result;
964
+ }
965
+
966
+ protected:
967
+ template <typename, typename>
968
+ friend struct detail::npy_format_descriptor;
969
+
970
+ void fail_dim_check(ssize_t dim, const std::string &msg) const {
971
+ throw index_error(msg + ": " + std::to_string(dim) + " (ndim = " + std::to_string(ndim())
972
+ + ')');
973
+ }
974
+
975
+ template <typename... Ix>
976
+ ssize_t byte_offset(Ix... index) const {
977
+ check_dimensions(index...);
978
+ return detail::byte_offset_unsafe(strides(), ssize_t(index)...);
979
+ }
980
+
981
+ void check_writeable() const {
982
+ if (!writeable()) {
983
+ throw std::domain_error("array is not writeable");
984
+ }
985
+ }
986
+
987
+ template <typename... Ix>
988
+ void check_dimensions(Ix... index) const {
989
+ check_dimensions_impl(ssize_t(0), shape(), ssize_t(index)...);
990
+ }
991
+
992
+ void check_dimensions_impl(ssize_t, const ssize_t *) const {}
993
+
994
+ template <typename... Ix>
995
+ void check_dimensions_impl(ssize_t axis, const ssize_t *shape, ssize_t i, Ix... index) const {
996
+ if (i >= *shape) {
997
+ throw index_error(std::string("index ") + std::to_string(i)
998
+ + " is out of bounds for axis " + std::to_string(axis)
999
+ + " with size " + std::to_string(*shape));
1000
+ }
1001
+ check_dimensions_impl(axis + 1, shape + 1, index...);
1002
+ }
1003
+
1004
+ /// Create array from any object -- always returns a new reference
1005
+ static PyObject *raw_array(PyObject *ptr, int ExtraFlags = 0) {
1006
+ if (ptr == nullptr) {
1007
+ PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array from a nullptr");
1008
+ return nullptr;
1009
+ }
1010
+ return detail::npy_api::get().PyArray_FromAny_(
1011
+ ptr, nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr);
1012
+ }
1013
+ };
1014
+
1015
+ template <typename T, int ExtraFlags = array::forcecast>
1016
+ class array_t : public array {
1017
+ private:
1018
+ struct private_ctor {};
1019
+ // Delegating constructor needed when both moving and accessing in the same constructor
1020
+ array_t(private_ctor,
1021
+ ShapeContainer &&shape,
1022
+ StridesContainer &&strides,
1023
+ const T *ptr,
1024
+ handle base)
1025
+ : array(std::move(shape), std::move(strides), ptr, base) {}
1026
+
1027
+ public:
1028
+ static_assert(!detail::array_info<T>::is_array, "Array types cannot be used with array_t");
1029
+
1030
+ using value_type = T;
1031
+
1032
+ array_t() : array(0, static_cast<const T *>(nullptr)) {}
1033
+ array_t(handle h, borrowed_t) : array(h, borrowed_t{}) {}
1034
+ array_t(handle h, stolen_t) : array(h, stolen_t{}) {}
1035
+
1036
+ PYBIND11_DEPRECATED("Use array_t<T>::ensure() instead")
1037
+ array_t(handle h, bool is_borrowed) : array(raw_array_t(h.ptr()), stolen_t{}) {
1038
+ if (!m_ptr) {
1039
+ PyErr_Clear();
1040
+ }
1041
+ if (!is_borrowed) {
1042
+ Py_XDECREF(h.ptr());
1043
+ }
1044
+ }
1045
+
1046
+ // NOLINTNEXTLINE(google-explicit-constructor)
1047
+ array_t(const object &o) : array(raw_array_t(o.ptr()), stolen_t{}) {
1048
+ if (!m_ptr) {
1049
+ throw error_already_set();
1050
+ }
1051
+ }
1052
+
1053
+ explicit array_t(const buffer_info &info, handle base = handle()) : array(info, base) {}
1054
+
1055
+ array_t(ShapeContainer shape,
1056
+ StridesContainer strides,
1057
+ const T *ptr = nullptr,
1058
+ handle base = handle())
1059
+ : array(std::move(shape), std::move(strides), ptr, base) {}
1060
+
1061
+ explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle())
1062
+ : array_t(private_ctor{},
1063
+ std::move(shape),
1064
+ (ExtraFlags & f_style) != 0 ? detail::f_strides(*shape, itemsize())
1065
+ : detail::c_strides(*shape, itemsize()),
1066
+ ptr,
1067
+ base) {}
1068
+
1069
+ explicit array_t(ssize_t count, const T *ptr = nullptr, handle base = handle())
1070
+ : array({count}, {}, ptr, base) {}
1071
+
1072
+ constexpr ssize_t itemsize() const { return sizeof(T); }
1073
+
1074
+ template <typename... Ix>
1075
+ ssize_t index_at(Ix... index) const {
1076
+ return offset_at(index...) / itemsize();
1077
+ }
1078
+
1079
+ template <typename... Ix>
1080
+ const T *data(Ix... index) const {
1081
+ return static_cast<const T *>(array::data(index...));
1082
+ }
1083
+
1084
+ template <typename... Ix>
1085
+ T *mutable_data(Ix... index) {
1086
+ return static_cast<T *>(array::mutable_data(index...));
1087
+ }
1088
+
1089
+ // Reference to element at a given index
1090
+ template <typename... Ix>
1091
+ const T &at(Ix... index) const {
1092
+ if ((ssize_t) sizeof...(index) != ndim()) {
1093
+ fail_dim_check(sizeof...(index), "index dimension mismatch");
1094
+ }
1095
+ return *(static_cast<const T *>(array::data())
1096
+ + byte_offset(ssize_t(index)...) / itemsize());
1097
+ }
1098
+
1099
+ // Mutable reference to element at a given index
1100
+ template <typename... Ix>
1101
+ T &mutable_at(Ix... index) {
1102
+ if ((ssize_t) sizeof...(index) != ndim()) {
1103
+ fail_dim_check(sizeof...(index), "index dimension mismatch");
1104
+ }
1105
+ return *(static_cast<T *>(array::mutable_data())
1106
+ + byte_offset(ssize_t(index)...) / itemsize());
1107
+ }
1108
+
1109
+ /**
1110
+ * Returns a proxy object that provides access to the array's data without bounds or
1111
+ * dimensionality checking. Will throw if the array is missing the `writeable` flag. Use with
1112
+ * care: the array must not be destroyed or reshaped for the duration of the returned object,
1113
+ * and the caller must take care not to access invalid dimensions or dimension indices.
1114
+ */
1115
+ template <ssize_t Dims = -1>
1116
+ detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {
1117
+ return array::mutable_unchecked<T, Dims>();
1118
+ }
1119
+
1120
+ /**
1121
+ * Returns a proxy object that provides const access to the array's data without bounds or
1122
+ * dimensionality checking. Unlike `unchecked()`, this does not require that the underlying
1123
+ * array have the `writable` flag. Use with care: the array must not be destroyed or reshaped
1124
+ * for the duration of the returned object, and the caller must take care not to access invalid
1125
+ * dimensions or dimension indices.
1126
+ */
1127
+ template <ssize_t Dims = -1>
1128
+ detail::unchecked_reference<T, Dims> unchecked() const & {
1129
+ return array::unchecked<T, Dims>();
1130
+ }
1131
+
1132
+ /// Ensure that the argument is a NumPy array of the correct dtype (and if not, try to convert
1133
+ /// it). In case of an error, nullptr is returned and the Python error is cleared.
1134
+ static array_t ensure(handle h) {
1135
+ auto result = reinterpret_steal<array_t>(raw_array_t(h.ptr()));
1136
+ if (!result) {
1137
+ PyErr_Clear();
1138
+ }
1139
+ return result;
1140
+ }
1141
+
1142
+ static bool check_(handle h) {
1143
+ const auto &api = detail::npy_api::get();
1144
+ return api.PyArray_Check_(h.ptr())
1145
+ && api.PyArray_EquivTypes_(detail::array_proxy(h.ptr())->descr,
1146
+ dtype::of<T>().ptr())
1147
+ && detail::check_flags(h.ptr(), ExtraFlags & (array::c_style | array::f_style));
1148
+ }
1149
+
1150
+ protected:
1151
+ /// Create array from any object -- always returns a new reference
1152
+ static PyObject *raw_array_t(PyObject *ptr) {
1153
+ if (ptr == nullptr) {
1154
+ PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array_t from a nullptr");
1155
+ return nullptr;
1156
+ }
1157
+ return detail::npy_api::get().PyArray_FromAny_(ptr,
1158
+ dtype::of<T>().release().ptr(),
1159
+ 0,
1160
+ 0,
1161
+ detail::npy_api::NPY_ARRAY_ENSUREARRAY_
1162
+ | ExtraFlags,
1163
+ nullptr);
1164
+ }
1165
+ };
1166
+
1167
+ template <typename T>
1168
+ struct format_descriptor<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {
1169
+ static std::string format() {
1170
+ return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::format();
1171
+ }
1172
+ };
1173
+
1174
+ template <size_t N>
1175
+ struct format_descriptor<char[N]> {
1176
+ static std::string format() { return std::to_string(N) + 's'; }
1177
+ };
1178
+ template <size_t N>
1179
+ struct format_descriptor<std::array<char, N>> {
1180
+ static std::string format() { return std::to_string(N) + 's'; }
1181
+ };
1182
+
1183
+ template <typename T>
1184
+ struct format_descriptor<T, detail::enable_if_t<std::is_enum<T>::value>> {
1185
+ static std::string format() {
1186
+ return format_descriptor<
1187
+ typename std::remove_cv<typename std::underlying_type<T>::type>::type>::format();
1188
+ }
1189
+ };
1190
+
1191
+ template <typename T>
1192
+ struct format_descriptor<T, detail::enable_if_t<detail::array_info<T>::is_array>> {
1193
+ static std::string format() {
1194
+ using namespace detail;
1195
+ static constexpr auto extents = const_name("(") + array_info<T>::extents + const_name(")");
1196
+ return extents.text + format_descriptor<remove_all_extents_t<T>>::format();
1197
+ }
1198
+ };
1199
+
1200
+ PYBIND11_NAMESPACE_BEGIN(detail)
1201
+ template <typename T, int ExtraFlags>
1202
+ struct pyobject_caster<array_t<T, ExtraFlags>> {
1203
+ using type = array_t<T, ExtraFlags>;
1204
+
1205
+ bool load(handle src, bool convert) {
1206
+ if (!convert && !type::check_(src)) {
1207
+ return false;
1208
+ }
1209
+ value = type::ensure(src);
1210
+ return static_cast<bool>(value);
1211
+ }
1212
+
1213
+ static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {
1214
+ return src.inc_ref();
1215
+ }
1216
+ PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);
1217
+ };
1218
+
1219
+ template <typename T>
1220
+ struct compare_buffer_info<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {
1221
+ static bool compare(const buffer_info &b) {
1222
+ return npy_api::get().PyArray_EquivTypes_(dtype::of<T>().ptr(), dtype(b).ptr());
1223
+ }
1224
+ };
1225
+
1226
+ template <typename T, typename = void>
1227
+ struct npy_format_descriptor_name;
1228
+
1229
+ template <typename T>
1230
+ struct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {
1231
+ static constexpr auto name = const_name<std::is_same<T, bool>::value>(
1232
+ const_name("bool"),
1233
+ const_name<std::is_signed<T>::value>("numpy.int", "numpy.uint")
1234
+ + const_name<sizeof(T) * 8>());
1235
+ };
1236
+
1237
+ template <typename T>
1238
+ struct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {
1239
+ static constexpr auto name = const_name < std::is_same<T, float>::value
1240
+ || std::is_same<T, const float>::value
1241
+ || std::is_same<T, double>::value
1242
+ || std::is_same<T, const double>::value
1243
+ > (const_name("numpy.float") + const_name<sizeof(T) * 8>(),
1244
+ const_name("numpy.longdouble"));
1245
+ };
1246
+
1247
+ template <typename T>
1248
+ struct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {
1249
+ static constexpr auto name = const_name < std::is_same<typename T::value_type, float>::value
1250
+ || std::is_same<typename T::value_type, const float>::value
1251
+ || std::is_same<typename T::value_type, double>::value
1252
+ || std::is_same<typename T::value_type, const double>::value
1253
+ > (const_name("numpy.complex")
1254
+ + const_name<sizeof(typename T::value_type) * 16>(),
1255
+ const_name("numpy.longcomplex"));
1256
+ };
1257
+
1258
+ template <typename T>
1259
+ struct npy_format_descriptor<
1260
+ T,
1261
+ enable_if_t<satisfies_any_of<T, std::is_arithmetic, is_complex>::value>>
1262
+ : npy_format_descriptor_name<T> {
1263
+ private:
1264
+ // NB: the order here must match the one in common.h
1265
+ constexpr static const int values[15] = {npy_api::NPY_BOOL_,
1266
+ npy_api::NPY_BYTE_,
1267
+ npy_api::NPY_UBYTE_,
1268
+ npy_api::NPY_INT16_,
1269
+ npy_api::NPY_UINT16_,
1270
+ npy_api::NPY_INT32_,
1271
+ npy_api::NPY_UINT32_,
1272
+ npy_api::NPY_INT64_,
1273
+ npy_api::NPY_UINT64_,
1274
+ npy_api::NPY_FLOAT_,
1275
+ npy_api::NPY_DOUBLE_,
1276
+ npy_api::NPY_LONGDOUBLE_,
1277
+ npy_api::NPY_CFLOAT_,
1278
+ npy_api::NPY_CDOUBLE_,
1279
+ npy_api::NPY_CLONGDOUBLE_};
1280
+
1281
+ public:
1282
+ static constexpr int value = values[detail::is_fmt_numeric<T>::index];
1283
+
1284
+ static pybind11::dtype dtype() {
1285
+ if (auto *ptr = npy_api::get().PyArray_DescrFromType_(value)) {
1286
+ return reinterpret_steal<pybind11::dtype>(ptr);
1287
+ }
1288
+ pybind11_fail("Unsupported buffer format!");
1289
+ }
1290
+ };
1291
+
1292
+ #define PYBIND11_DECL_CHAR_FMT \
1293
+ static constexpr auto name = const_name("S") + const_name<N>(); \
1294
+ static pybind11::dtype dtype() { \
1295
+ return pybind11::dtype(std::string("S") + std::to_string(N)); \
1296
+ }
1297
+ template <size_t N>
1298
+ struct npy_format_descriptor<char[N]> {
1299
+ PYBIND11_DECL_CHAR_FMT
1300
+ };
1301
+ template <size_t N>
1302
+ struct npy_format_descriptor<std::array<char, N>> {
1303
+ PYBIND11_DECL_CHAR_FMT
1304
+ };
1305
+ #undef PYBIND11_DECL_CHAR_FMT
1306
+
1307
+ template <typename T>
1308
+ struct npy_format_descriptor<T, enable_if_t<array_info<T>::is_array>> {
1309
+ private:
1310
+ using base_descr = npy_format_descriptor<typename array_info<T>::type>;
1311
+
1312
+ public:
1313
+ static_assert(!array_info<T>::is_empty, "Zero-sized arrays are not supported");
1314
+
1315
+ static constexpr auto name
1316
+ = const_name("(") + array_info<T>::extents + const_name(")") + base_descr::name;
1317
+ static pybind11::dtype dtype() {
1318
+ list shape;
1319
+ array_info<T>::append_extents(shape);
1320
+ return pybind11::dtype::from_args(
1321
+ pybind11::make_tuple(base_descr::dtype(), std::move(shape)));
1322
+ }
1323
+ };
1324
+
1325
+ template <typename T>
1326
+ struct npy_format_descriptor<T, enable_if_t<std::is_enum<T>::value>> {
1327
+ private:
1328
+ using base_descr = npy_format_descriptor<typename std::underlying_type<T>::type>;
1329
+
1330
+ public:
1331
+ static constexpr auto name = base_descr::name;
1332
+ static pybind11::dtype dtype() { return base_descr::dtype(); }
1333
+ };
1334
+
1335
+ struct field_descriptor {
1336
+ const char *name;
1337
+ ssize_t offset;
1338
+ ssize_t size;
1339
+ std::string format;
1340
+ dtype descr;
1341
+ };
1342
+
1343
+ PYBIND11_NOINLINE void register_structured_dtype(any_container<field_descriptor> fields,
1344
+ const std::type_info &tinfo,
1345
+ ssize_t itemsize,
1346
+ bool (*direct_converter)(PyObject *, void *&)) {
1347
+
1348
+ auto &numpy_internals = get_numpy_internals();
1349
+ if (numpy_internals.get_type_info(tinfo, false)) {
1350
+ pybind11_fail("NumPy: dtype is already registered");
1351
+ }
1352
+
1353
+ // Use ordered fields because order matters as of NumPy 1.14:
1354
+ // https://docs.scipy.org/doc/numpy/release.html#multiple-field-indexing-assignment-of-structured-arrays
1355
+ std::vector<field_descriptor> ordered_fields(std::move(fields));
1356
+ std::sort(
1357
+ ordered_fields.begin(),
1358
+ ordered_fields.end(),
1359
+ [](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; });
1360
+
1361
+ list names, formats, offsets;
1362
+ for (auto &field : ordered_fields) {
1363
+ if (!field.descr) {
1364
+ pybind11_fail(std::string("NumPy: unsupported field dtype: `") + field.name + "` @ "
1365
+ + tinfo.name());
1366
+ }
1367
+ names.append(pybind11::str(field.name));
1368
+ formats.append(field.descr);
1369
+ offsets.append(pybind11::int_(field.offset));
1370
+ }
1371
+ auto *dtype_ptr
1372
+ = pybind11::dtype(std::move(names), std::move(formats), std::move(offsets), itemsize)
1373
+ .release()
1374
+ .ptr();
1375
+
1376
+ // There is an existing bug in NumPy (as of v1.11): trailing bytes are
1377
+ // not encoded explicitly into the format string. This will supposedly
1378
+ // get fixed in v1.12; for further details, see these:
1379
+ // - https://github.com/numpy/numpy/issues/7797
1380
+ // - https://github.com/numpy/numpy/pull/7798
1381
+ // Because of this, we won't use numpy's logic to generate buffer format
1382
+ // strings and will just do it ourselves.
1383
+ ssize_t offset = 0;
1384
+ std::ostringstream oss;
1385
+ // mark the structure as unaligned with '^', because numpy and C++ don't
1386
+ // always agree about alignment (particularly for complex), and we're
1387
+ // explicitly listing all our padding. This depends on none of the fields
1388
+ // overriding the endianness. Putting the ^ in front of individual fields
1389
+ // isn't guaranteed to work due to https://github.com/numpy/numpy/issues/9049
1390
+ oss << "^T{";
1391
+ for (auto &field : ordered_fields) {
1392
+ if (field.offset > offset) {
1393
+ oss << (field.offset - offset) << 'x';
1394
+ }
1395
+ oss << field.format << ':' << field.name << ':';
1396
+ offset = field.offset + field.size;
1397
+ }
1398
+ if (itemsize > offset) {
1399
+ oss << (itemsize - offset) << 'x';
1400
+ }
1401
+ oss << '}';
1402
+ auto format_str = oss.str();
1403
+
1404
+ // Sanity check: verify that NumPy properly parses our buffer format string
1405
+ auto &api = npy_api::get();
1406
+ auto arr = array(buffer_info(nullptr, itemsize, format_str, 1));
1407
+ if (!api.PyArray_EquivTypes_(dtype_ptr, arr.dtype().ptr())) {
1408
+ pybind11_fail("NumPy: invalid buffer descriptor!");
1409
+ }
1410
+
1411
+ auto tindex = std::type_index(tinfo);
1412
+ numpy_internals.registered_dtypes[tindex] = {dtype_ptr, std::move(format_str)};
1413
+ get_internals().direct_conversions[tindex].push_back(direct_converter);
1414
+ }
1415
+
1416
+ template <typename T, typename SFINAE>
1417
+ struct npy_format_descriptor {
1418
+ static_assert(is_pod_struct<T>::value,
1419
+ "Attempt to use a non-POD or unimplemented POD type as a numpy dtype");
1420
+
1421
+ static constexpr auto name = make_caster<T>::name;
1422
+
1423
+ static pybind11::dtype dtype() { return reinterpret_borrow<pybind11::dtype>(dtype_ptr()); }
1424
+
1425
+ static std::string format() {
1426
+ static auto format_str = get_numpy_internals().get_type_info<T>(true)->format_str;
1427
+ return format_str;
1428
+ }
1429
+
1430
+ static void register_dtype(any_container<field_descriptor> fields) {
1431
+ register_structured_dtype(std::move(fields),
1432
+ typeid(typename std::remove_cv<T>::type),
1433
+ sizeof(T),
1434
+ &direct_converter);
1435
+ }
1436
+
1437
+ private:
1438
+ static PyObject *dtype_ptr() {
1439
+ static PyObject *ptr = get_numpy_internals().get_type_info<T>(true)->dtype_ptr;
1440
+ return ptr;
1441
+ }
1442
+
1443
+ static bool direct_converter(PyObject *obj, void *&value) {
1444
+ auto &api = npy_api::get();
1445
+ if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_)) {
1446
+ return false;
1447
+ }
1448
+ if (auto descr = reinterpret_steal<object>(api.PyArray_DescrFromScalar_(obj))) {
1449
+ if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) {
1450
+ value = ((PyVoidScalarObject_Proxy *) obj)->obval;
1451
+ return true;
1452
+ }
1453
+ }
1454
+ return false;
1455
+ }
1456
+ };
1457
+
1458
+ #ifdef __CLION_IDE__ // replace heavy macro with dummy code for the IDE (doesn't affect code)
1459
+ # define PYBIND11_NUMPY_DTYPE(Type, ...) ((void) 0)
1460
+ # define PYBIND11_NUMPY_DTYPE_EX(Type, ...) ((void) 0)
1461
+ #else
1462
+
1463
+ # define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name) \
1464
+ ::pybind11::detail::field_descriptor { \
1465
+ Name, offsetof(T, Field), sizeof(decltype(std::declval<T>().Field)), \
1466
+ ::pybind11::format_descriptor<decltype(std::declval<T>().Field)>::format(), \
1467
+ ::pybind11::detail::npy_format_descriptor< \
1468
+ decltype(std::declval<T>().Field)>::dtype() \
1469
+ }
1470
+
1471
+ // Extract name, offset and format descriptor for a struct field
1472
+ # define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, # Field)
1473
+
1474
+ // The main idea of this macro is borrowed from https://github.com/swansontec/map-macro
1475
+ // (C) William Swanson, Paul Fultz
1476
+ # define PYBIND11_EVAL0(...) __VA_ARGS__
1477
+ # define PYBIND11_EVAL1(...) PYBIND11_EVAL0(PYBIND11_EVAL0(PYBIND11_EVAL0(__VA_ARGS__)))
1478
+ # define PYBIND11_EVAL2(...) PYBIND11_EVAL1(PYBIND11_EVAL1(PYBIND11_EVAL1(__VA_ARGS__)))
1479
+ # define PYBIND11_EVAL3(...) PYBIND11_EVAL2(PYBIND11_EVAL2(PYBIND11_EVAL2(__VA_ARGS__)))
1480
+ # define PYBIND11_EVAL4(...) PYBIND11_EVAL3(PYBIND11_EVAL3(PYBIND11_EVAL3(__VA_ARGS__)))
1481
+ # define PYBIND11_EVAL(...) PYBIND11_EVAL4(PYBIND11_EVAL4(PYBIND11_EVAL4(__VA_ARGS__)))
1482
+ # define PYBIND11_MAP_END(...)
1483
+ # define PYBIND11_MAP_OUT
1484
+ # define PYBIND11_MAP_COMMA ,
1485
+ # define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END
1486
+ # define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT
1487
+ # define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0(test, next, 0)
1488
+ # define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1(PYBIND11_MAP_GET_END test, next)
1489
+ # if defined(_MSC_VER) \
1490
+ && !defined(__clang__) // MSVC is not as eager to expand macros, hence this workaround
1491
+ # define PYBIND11_MAP_LIST_NEXT1(test, next) \
1492
+ PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0))
1493
+ # else
1494
+ # define PYBIND11_MAP_LIST_NEXT1(test, next) \
1495
+ PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)
1496
+ # endif
1497
+ # define PYBIND11_MAP_LIST_NEXT(test, next) \
1498
+ PYBIND11_MAP_LIST_NEXT1(PYBIND11_MAP_GET_END test, next)
1499
+ # define PYBIND11_MAP_LIST0(f, t, x, peek, ...) \
1500
+ f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST1)(f, t, peek, __VA_ARGS__)
1501
+ # define PYBIND11_MAP_LIST1(f, t, x, peek, ...) \
1502
+ f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST0)(f, t, peek, __VA_ARGS__)
1503
+ // PYBIND11_MAP_LIST(f, t, a1, a2, ...) expands to f(t, a1), f(t, a2), ...
1504
+ # define PYBIND11_MAP_LIST(f, t, ...) \
1505
+ PYBIND11_EVAL(PYBIND11_MAP_LIST1(f, t, __VA_ARGS__, (), 0))
1506
+
1507
+ # define PYBIND11_NUMPY_DTYPE(Type, ...) \
1508
+ ::pybind11::detail::npy_format_descriptor<Type>::register_dtype( \
1509
+ ::std::vector<::pybind11::detail::field_descriptor>{ \
1510
+ PYBIND11_MAP_LIST(PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)})
1511
+
1512
+ # if defined(_MSC_VER) && !defined(__clang__)
1513
+ # define PYBIND11_MAP2_LIST_NEXT1(test, next) \
1514
+ PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0))
1515
+ # else
1516
+ # define PYBIND11_MAP2_LIST_NEXT1(test, next) \
1517
+ PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)
1518
+ # endif
1519
+ # define PYBIND11_MAP2_LIST_NEXT(test, next) \
1520
+ PYBIND11_MAP2_LIST_NEXT1(PYBIND11_MAP_GET_END test, next)
1521
+ # define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...) \
1522
+ f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST1)(f, t, peek, __VA_ARGS__)
1523
+ # define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...) \
1524
+ f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST0)(f, t, peek, __VA_ARGS__)
1525
+ // PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ...
1526
+ # define PYBIND11_MAP2_LIST(f, t, ...) \
1527
+ PYBIND11_EVAL(PYBIND11_MAP2_LIST1(f, t, __VA_ARGS__, (), 0))
1528
+
1529
+ # define PYBIND11_NUMPY_DTYPE_EX(Type, ...) \
1530
+ ::pybind11::detail::npy_format_descriptor<Type>::register_dtype( \
1531
+ ::std::vector<::pybind11::detail::field_descriptor>{ \
1532
+ PYBIND11_MAP2_LIST(PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)})
1533
+
1534
+ #endif // __CLION_IDE__
1535
+
1536
+ class common_iterator {
1537
+ public:
1538
+ using container_type = std::vector<ssize_t>;
1539
+ using value_type = container_type::value_type;
1540
+ using size_type = container_type::size_type;
1541
+
1542
+ common_iterator() : m_strides() {}
1543
+
1544
+ common_iterator(void *ptr, const container_type &strides, const container_type &shape)
1545
+ : p_ptr(reinterpret_cast<char *>(ptr)), m_strides(strides.size()) {
1546
+ m_strides.back() = static_cast<value_type>(strides.back());
1547
+ for (size_type i = m_strides.size() - 1; i != 0; --i) {
1548
+ size_type j = i - 1;
1549
+ auto s = static_cast<value_type>(shape[i]);
1550
+ m_strides[j] = strides[j] + m_strides[i] - strides[i] * s;
1551
+ }
1552
+ }
1553
+
1554
+ void increment(size_type dim) { p_ptr += m_strides[dim]; }
1555
+
1556
+ void *data() const { return p_ptr; }
1557
+
1558
+ private:
1559
+ char *p_ptr{nullptr};
1560
+ container_type m_strides;
1561
+ };
1562
+
1563
+ template <size_t N>
1564
+ class multi_array_iterator {
1565
+ public:
1566
+ using container_type = std::vector<ssize_t>;
1567
+
1568
+ multi_array_iterator(const std::array<buffer_info, N> &buffers, const container_type &shape)
1569
+ : m_shape(shape.size()), m_index(shape.size(), 0), m_common_iterator() {
1570
+
1571
+ // Manual copy to avoid conversion warning if using std::copy
1572
+ for (size_t i = 0; i < shape.size(); ++i) {
1573
+ m_shape[i] = shape[i];
1574
+ }
1575
+
1576
+ container_type strides(shape.size());
1577
+ for (size_t i = 0; i < N; ++i) {
1578
+ init_common_iterator(buffers[i], shape, m_common_iterator[i], strides);
1579
+ }
1580
+ }
1581
+
1582
+ multi_array_iterator &operator++() {
1583
+ for (size_t j = m_index.size(); j != 0; --j) {
1584
+ size_t i = j - 1;
1585
+ if (++m_index[i] != m_shape[i]) {
1586
+ increment_common_iterator(i);
1587
+ break;
1588
+ }
1589
+ m_index[i] = 0;
1590
+ }
1591
+ return *this;
1592
+ }
1593
+
1594
+ template <size_t K, class T = void>
1595
+ T *data() const {
1596
+ return reinterpret_cast<T *>(m_common_iterator[K].data());
1597
+ }
1598
+
1599
+ private:
1600
+ using common_iter = common_iterator;
1601
+
1602
+ void init_common_iterator(const buffer_info &buffer,
1603
+ const container_type &shape,
1604
+ common_iter &iterator,
1605
+ container_type &strides) {
1606
+ auto buffer_shape_iter = buffer.shape.rbegin();
1607
+ auto buffer_strides_iter = buffer.strides.rbegin();
1608
+ auto shape_iter = shape.rbegin();
1609
+ auto strides_iter = strides.rbegin();
1610
+
1611
+ while (buffer_shape_iter != buffer.shape.rend()) {
1612
+ if (*shape_iter == *buffer_shape_iter) {
1613
+ *strides_iter = *buffer_strides_iter;
1614
+ } else {
1615
+ *strides_iter = 0;
1616
+ }
1617
+
1618
+ ++buffer_shape_iter;
1619
+ ++buffer_strides_iter;
1620
+ ++shape_iter;
1621
+ ++strides_iter;
1622
+ }
1623
+
1624
+ std::fill(strides_iter, strides.rend(), 0);
1625
+ iterator = common_iter(buffer.ptr, strides, shape);
1626
+ }
1627
+
1628
+ void increment_common_iterator(size_t dim) {
1629
+ for (auto &iter : m_common_iterator) {
1630
+ iter.increment(dim);
1631
+ }
1632
+ }
1633
+
1634
+ container_type m_shape;
1635
+ container_type m_index;
1636
+ std::array<common_iter, N> m_common_iterator;
1637
+ };
1638
+
1639
+ enum class broadcast_trivial { non_trivial, c_trivial, f_trivial };
1640
+
1641
+ // Populates the shape and number of dimensions for the set of buffers. Returns a
1642
+ // broadcast_trivial enum value indicating whether the broadcast is "trivial"--that is, has each
1643
+ // buffer being either a singleton or a full-size, C-contiguous (`c_trivial`) or Fortran-contiguous
1644
+ // (`f_trivial`) storage buffer; returns `non_trivial` otherwise.
1645
+ template <size_t N>
1646
+ broadcast_trivial
1647
+ broadcast(const std::array<buffer_info, N> &buffers, ssize_t &ndim, std::vector<ssize_t> &shape) {
1648
+ ndim = std::accumulate(
1649
+ buffers.begin(), buffers.end(), ssize_t(0), [](ssize_t res, const buffer_info &buf) {
1650
+ return std::max(res, buf.ndim);
1651
+ });
1652
+
1653
+ shape.clear();
1654
+ shape.resize((size_t) ndim, 1);
1655
+
1656
+ // Figure out the output size, and make sure all input arrays conform (i.e. are either size 1
1657
+ // or the full size).
1658
+ for (size_t i = 0; i < N; ++i) {
1659
+ auto res_iter = shape.rbegin();
1660
+ auto end = buffers[i].shape.rend();
1661
+ for (auto shape_iter = buffers[i].shape.rbegin(); shape_iter != end;
1662
+ ++shape_iter, ++res_iter) {
1663
+ const auto &dim_size_in = *shape_iter;
1664
+ auto &dim_size_out = *res_iter;
1665
+
1666
+ // Each input dimension can either be 1 or `n`, but `n` values must match across
1667
+ // buffers
1668
+ if (dim_size_out == 1) {
1669
+ dim_size_out = dim_size_in;
1670
+ } else if (dim_size_in != 1 && dim_size_in != dim_size_out) {
1671
+ pybind11_fail("pybind11::vectorize: incompatible size/dimension of inputs!");
1672
+ }
1673
+ }
1674
+ }
1675
+
1676
+ bool trivial_broadcast_c = true;
1677
+ bool trivial_broadcast_f = true;
1678
+ for (size_t i = 0; i < N && (trivial_broadcast_c || trivial_broadcast_f); ++i) {
1679
+ if (buffers[i].size == 1) {
1680
+ continue;
1681
+ }
1682
+
1683
+ // Require the same number of dimensions:
1684
+ if (buffers[i].ndim != ndim) {
1685
+ return broadcast_trivial::non_trivial;
1686
+ }
1687
+
1688
+ // Require all dimensions be full-size:
1689
+ if (!std::equal(buffers[i].shape.cbegin(), buffers[i].shape.cend(), shape.cbegin())) {
1690
+ return broadcast_trivial::non_trivial;
1691
+ }
1692
+
1693
+ // Check for C contiguity (but only if previous inputs were also C contiguous)
1694
+ if (trivial_broadcast_c) {
1695
+ ssize_t expect_stride = buffers[i].itemsize;
1696
+ auto end = buffers[i].shape.crend();
1697
+ for (auto shape_iter = buffers[i].shape.crbegin(),
1698
+ stride_iter = buffers[i].strides.crbegin();
1699
+ trivial_broadcast_c && shape_iter != end;
1700
+ ++shape_iter, ++stride_iter) {
1701
+ if (expect_stride == *stride_iter) {
1702
+ expect_stride *= *shape_iter;
1703
+ } else {
1704
+ trivial_broadcast_c = false;
1705
+ }
1706
+ }
1707
+ }
1708
+
1709
+ // Check for Fortran contiguity (if previous inputs were also F contiguous)
1710
+ if (trivial_broadcast_f) {
1711
+ ssize_t expect_stride = buffers[i].itemsize;
1712
+ auto end = buffers[i].shape.cend();
1713
+ for (auto shape_iter = buffers[i].shape.cbegin(),
1714
+ stride_iter = buffers[i].strides.cbegin();
1715
+ trivial_broadcast_f && shape_iter != end;
1716
+ ++shape_iter, ++stride_iter) {
1717
+ if (expect_stride == *stride_iter) {
1718
+ expect_stride *= *shape_iter;
1719
+ } else {
1720
+ trivial_broadcast_f = false;
1721
+ }
1722
+ }
1723
+ }
1724
+ }
1725
+
1726
+ return trivial_broadcast_c ? broadcast_trivial::c_trivial
1727
+ : trivial_broadcast_f ? broadcast_trivial::f_trivial
1728
+ : broadcast_trivial::non_trivial;
1729
+ }
1730
+
1731
+ template <typename T>
1732
+ struct vectorize_arg {
1733
+ static_assert(!std::is_rvalue_reference<T>::value,
1734
+ "Functions with rvalue reference arguments cannot be vectorized");
1735
+ // The wrapped function gets called with this type:
1736
+ using call_type = remove_reference_t<T>;
1737
+ // Is this a vectorized argument?
1738
+ static constexpr bool vectorize
1739
+ = satisfies_any_of<call_type, std::is_arithmetic, is_complex, is_pod>::value
1740
+ && satisfies_none_of<call_type,
1741
+ std::is_pointer,
1742
+ std::is_array,
1743
+ is_std_array,
1744
+ std::is_enum>::value
1745
+ && (!std::is_reference<T>::value
1746
+ || (std::is_lvalue_reference<T>::value && std::is_const<call_type>::value));
1747
+ // Accept this type: an array for vectorized types, otherwise the type as-is:
1748
+ using type = conditional_t<vectorize, array_t<remove_cv_t<call_type>, array::forcecast>, T>;
1749
+ };
1750
+
1751
+ // py::vectorize when a return type is present
1752
+ template <typename Func, typename Return, typename... Args>
1753
+ struct vectorize_returned_array {
1754
+ using Type = array_t<Return>;
1755
+
1756
+ static Type create(broadcast_trivial trivial, const std::vector<ssize_t> &shape) {
1757
+ if (trivial == broadcast_trivial::f_trivial) {
1758
+ return array_t<Return, array::f_style>(shape);
1759
+ }
1760
+ return array_t<Return>(shape);
1761
+ }
1762
+
1763
+ static Return *mutable_data(Type &array) { return array.mutable_data(); }
1764
+
1765
+ static Return call(Func &f, Args &...args) { return f(args...); }
1766
+
1767
+ static void call(Return *out, size_t i, Func &f, Args &...args) { out[i] = f(args...); }
1768
+ };
1769
+
1770
+ // py::vectorize when a return type is not present
1771
+ template <typename Func, typename... Args>
1772
+ struct vectorize_returned_array<Func, void, Args...> {
1773
+ using Type = none;
1774
+
1775
+ static Type create(broadcast_trivial, const std::vector<ssize_t> &) { return none(); }
1776
+
1777
+ static void *mutable_data(Type &) { return nullptr; }
1778
+
1779
+ static detail::void_type call(Func &f, Args &...args) {
1780
+ f(args...);
1781
+ return {};
1782
+ }
1783
+
1784
+ static void call(void *, size_t, Func &f, Args &...args) { f(args...); }
1785
+ };
1786
+
1787
+ template <typename Func, typename Return, typename... Args>
1788
+ struct vectorize_helper {
1789
+
1790
+ // NVCC for some reason breaks if NVectorized is private
1791
+ #ifdef __CUDACC__
1792
+ public:
1793
+ #else
1794
+ private:
1795
+ #endif
1796
+
1797
+ static constexpr size_t N = sizeof...(Args);
1798
+ static constexpr size_t NVectorized = constexpr_sum(vectorize_arg<Args>::vectorize...);
1799
+ static_assert(
1800
+ NVectorized >= 1,
1801
+ "pybind11::vectorize(...) requires a function with at least one vectorizable argument");
1802
+
1803
+ public:
1804
+ template <typename T,
1805
+ // SFINAE to prevent shadowing the copy constructor.
1806
+ typename = detail::enable_if_t<
1807
+ !std::is_same<vectorize_helper, typename std::decay<T>::type>::value>>
1808
+ explicit vectorize_helper(T &&f) : f(std::forward<T>(f)) {}
1809
+
1810
+ object operator()(typename vectorize_arg<Args>::type... args) {
1811
+ return run(args...,
1812
+ make_index_sequence<N>(),
1813
+ select_indices<vectorize_arg<Args>::vectorize...>(),
1814
+ make_index_sequence<NVectorized>());
1815
+ }
1816
+
1817
+ private:
1818
+ remove_reference_t<Func> f;
1819
+
1820
+ // Internal compiler error in MSVC 19.16.27025.1 (Visual Studio 2017 15.9.4), when compiling
1821
+ // with "/permissive-" flag when arg_call_types is manually inlined.
1822
+ using arg_call_types = std::tuple<typename vectorize_arg<Args>::call_type...>;
1823
+ template <size_t Index>
1824
+ using param_n_t = typename std::tuple_element<Index, arg_call_types>::type;
1825
+
1826
+ using returned_array = vectorize_returned_array<Func, Return, Args...>;
1827
+
1828
+ // Runs a vectorized function given arguments tuple and three index sequences:
1829
+ // - Index is the full set of 0 ... (N-1) argument indices;
1830
+ // - VIndex is the subset of argument indices with vectorized parameters, letting us access
1831
+ // vectorized arguments (anything not in this sequence is passed through)
1832
+ // - BIndex is a incremental sequence (beginning at 0) of the same size as VIndex, so that
1833
+ // we can store vectorized buffer_infos in an array (argument VIndex has its buffer at
1834
+ // index BIndex in the array).
1835
+ template <size_t... Index, size_t... VIndex, size_t... BIndex>
1836
+ object run(typename vectorize_arg<Args>::type &...args,
1837
+ index_sequence<Index...> i_seq,
1838
+ index_sequence<VIndex...> vi_seq,
1839
+ index_sequence<BIndex...> bi_seq) {
1840
+
1841
+ // Pointers to values the function was called with; the vectorized ones set here will start
1842
+ // out as array_t<T> pointers, but they will be changed them to T pointers before we make
1843
+ // call the wrapped function. Non-vectorized pointers are left as-is.
1844
+ std::array<void *, N> params{{&args...}};
1845
+
1846
+ // The array of `buffer_info`s of vectorized arguments:
1847
+ std::array<buffer_info, NVectorized> buffers{
1848
+ {reinterpret_cast<array *>(params[VIndex])->request()...}};
1849
+
1850
+ /* Determine dimensions parameters of output array */
1851
+ ssize_t nd = 0;
1852
+ std::vector<ssize_t> shape(0);
1853
+ auto trivial = broadcast(buffers, nd, shape);
1854
+ auto ndim = (size_t) nd;
1855
+
1856
+ size_t size
1857
+ = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies<size_t>());
1858
+
1859
+ // If all arguments are 0-dimension arrays (i.e. single values) return a plain value (i.e.
1860
+ // not wrapped in an array).
1861
+ if (size == 1 && ndim == 0) {
1862
+ PYBIND11_EXPAND_SIDE_EFFECTS(params[VIndex] = buffers[BIndex].ptr);
1863
+ return cast(
1864
+ returned_array::call(f, *reinterpret_cast<param_n_t<Index> *>(params[Index])...));
1865
+ }
1866
+
1867
+ auto result = returned_array::create(trivial, shape);
1868
+
1869
+ if (size == 0) {
1870
+ return std::move(result);
1871
+ }
1872
+
1873
+ /* Call the function */
1874
+ auto *mutable_data = returned_array::mutable_data(result);
1875
+ if (trivial == broadcast_trivial::non_trivial) {
1876
+ apply_broadcast(buffers, params, mutable_data, size, shape, i_seq, vi_seq, bi_seq);
1877
+ } else {
1878
+ apply_trivial(buffers, params, mutable_data, size, i_seq, vi_seq, bi_seq);
1879
+ }
1880
+
1881
+ return std::move(result);
1882
+ }
1883
+
1884
+ template <size_t... Index, size_t... VIndex, size_t... BIndex>
1885
+ void apply_trivial(std::array<buffer_info, NVectorized> &buffers,
1886
+ std::array<void *, N> &params,
1887
+ Return *out,
1888
+ size_t size,
1889
+ index_sequence<Index...>,
1890
+ index_sequence<VIndex...>,
1891
+ index_sequence<BIndex...>) {
1892
+
1893
+ // Initialize an array of mutable byte references and sizes with references set to the
1894
+ // appropriate pointer in `params`; as we iterate, we'll increment each pointer by its size
1895
+ // (except for singletons, which get an increment of 0).
1896
+ std::array<std::pair<unsigned char *&, const size_t>, NVectorized> vecparams{
1897
+ {std::pair<unsigned char *&, const size_t>(
1898
+ reinterpret_cast<unsigned char *&>(params[VIndex] = buffers[BIndex].ptr),
1899
+ buffers[BIndex].size == 1 ? 0 : sizeof(param_n_t<VIndex>))...}};
1900
+
1901
+ for (size_t i = 0; i < size; ++i) {
1902
+ returned_array::call(
1903
+ out, i, f, *reinterpret_cast<param_n_t<Index> *>(params[Index])...);
1904
+ for (auto &x : vecparams) {
1905
+ x.first += x.second;
1906
+ }
1907
+ }
1908
+ }
1909
+
1910
+ template <size_t... Index, size_t... VIndex, size_t... BIndex>
1911
+ void apply_broadcast(std::array<buffer_info, NVectorized> &buffers,
1912
+ std::array<void *, N> &params,
1913
+ Return *out,
1914
+ size_t size,
1915
+ const std::vector<ssize_t> &output_shape,
1916
+ index_sequence<Index...>,
1917
+ index_sequence<VIndex...>,
1918
+ index_sequence<BIndex...>) {
1919
+
1920
+ multi_array_iterator<NVectorized> input_iter(buffers, output_shape);
1921
+
1922
+ for (size_t i = 0; i < size; ++i, ++input_iter) {
1923
+ PYBIND11_EXPAND_SIDE_EFFECTS((params[VIndex] = input_iter.template data<BIndex>()));
1924
+ returned_array::call(
1925
+ out, i, f, *reinterpret_cast<param_n_t<Index> *>(std::get<Index>(params))...);
1926
+ }
1927
+ }
1928
+ };
1929
+
1930
+ template <typename Func, typename Return, typename... Args>
1931
+ vectorize_helper<Func, Return, Args...> vectorize_extractor(const Func &f, Return (*)(Args...)) {
1932
+ return detail::vectorize_helper<Func, Return, Args...>(f);
1933
+ }
1934
+
1935
+ template <typename T, int Flags>
1936
+ struct handle_type_name<array_t<T, Flags>> {
1937
+ static constexpr auto name
1938
+ = const_name("numpy.ndarray[") + npy_format_descriptor<T>::name + const_name("]");
1939
+ };
1940
+
1941
+ PYBIND11_NAMESPACE_END(detail)
1942
+
1943
+ // Vanilla pointer vectorizer:
1944
+ template <typename Return, typename... Args>
1945
+ detail::vectorize_helper<Return (*)(Args...), Return, Args...> vectorize(Return (*f)(Args...)) {
1946
+ return detail::vectorize_helper<Return (*)(Args...), Return, Args...>(f);
1947
+ }
1948
+
1949
+ // lambda vectorizer:
1950
+ template <typename Func, detail::enable_if_t<detail::is_lambda<Func>::value, int> = 0>
1951
+ auto vectorize(Func &&f)
1952
+ -> decltype(detail::vectorize_extractor(std::forward<Func>(f),
1953
+ (detail::function_signature_t<Func> *) nullptr)) {
1954
+ return detail::vectorize_extractor(std::forward<Func>(f),
1955
+ (detail::function_signature_t<Func> *) nullptr);
1956
+ }
1957
+
1958
+ // Vectorize a class method (non-const):
1959
+ template <typename Return,
1960
+ typename Class,
1961
+ typename... Args,
1962
+ typename Helper = detail::vectorize_helper<
1963
+ decltype(std::mem_fn(std::declval<Return (Class::*)(Args...)>())),
1964
+ Return,
1965
+ Class *,
1966
+ Args...>>
1967
+ Helper vectorize(Return (Class::*f)(Args...)) {
1968
+ return Helper(std::mem_fn(f));
1969
+ }
1970
+
1971
+ // Vectorize a class method (const):
1972
+ template <typename Return,
1973
+ typename Class,
1974
+ typename... Args,
1975
+ typename Helper = detail::vectorize_helper<
1976
+ decltype(std::mem_fn(std::declval<Return (Class::*)(Args...) const>())),
1977
+ Return,
1978
+ const Class *,
1979
+ Args...>>
1980
+ Helper vectorize(Return (Class::*f)(Args...) const) {
1981
+ return Helper(std::mem_fn(f));
1982
+ }
1983
+
1984
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/operators.h ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/operator.h: Metatemplates for operator overloading
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "pybind11.h"
13
+
14
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
15
+ PYBIND11_NAMESPACE_BEGIN(detail)
16
+
17
+ /// Enumeration with all supported operator types
18
+ enum op_id : int {
19
+ op_add,
20
+ op_sub,
21
+ op_mul,
22
+ op_div,
23
+ op_mod,
24
+ op_divmod,
25
+ op_pow,
26
+ op_lshift,
27
+ op_rshift,
28
+ op_and,
29
+ op_xor,
30
+ op_or,
31
+ op_neg,
32
+ op_pos,
33
+ op_abs,
34
+ op_invert,
35
+ op_int,
36
+ op_long,
37
+ op_float,
38
+ op_str,
39
+ op_cmp,
40
+ op_gt,
41
+ op_ge,
42
+ op_lt,
43
+ op_le,
44
+ op_eq,
45
+ op_ne,
46
+ op_iadd,
47
+ op_isub,
48
+ op_imul,
49
+ op_idiv,
50
+ op_imod,
51
+ op_ilshift,
52
+ op_irshift,
53
+ op_iand,
54
+ op_ixor,
55
+ op_ior,
56
+ op_complex,
57
+ op_bool,
58
+ op_nonzero,
59
+ op_repr,
60
+ op_truediv,
61
+ op_itruediv,
62
+ op_hash
63
+ };
64
+
65
+ enum op_type : int {
66
+ op_l, /* base type on left */
67
+ op_r, /* base type on right */
68
+ op_u /* unary operator */
69
+ };
70
+
71
+ struct self_t {};
72
+ static const self_t self = self_t();
73
+
74
+ /// Type for an unused type slot
75
+ struct undefined_t {};
76
+
77
+ /// Don't warn about an unused variable
78
+ inline self_t __self() { return self; }
79
+
80
+ /// base template of operator implementations
81
+ template <op_id, op_type, typename B, typename L, typename R>
82
+ struct op_impl {};
83
+
84
+ /// Operator implementation generator
85
+ template <op_id id, op_type ot, typename L, typename R>
86
+ struct op_ {
87
+ template <typename Class, typename... Extra>
88
+ void execute(Class &cl, const Extra &...extra) const {
89
+ using Base = typename Class::type;
90
+ using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
91
+ using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
92
+ using op = op_impl<id, ot, Base, L_type, R_type>;
93
+ cl.def(op::name(), &op::execute, is_operator(), extra...);
94
+ }
95
+ template <typename Class, typename... Extra>
96
+ void execute_cast(Class &cl, const Extra &...extra) const {
97
+ using Base = typename Class::type;
98
+ using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;
99
+ using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;
100
+ using op = op_impl<id, ot, Base, L_type, R_type>;
101
+ cl.def(op::name(), &op::execute_cast, is_operator(), extra...);
102
+ }
103
+ };
104
+
105
+ #define PYBIND11_BINARY_OPERATOR(id, rid, op, expr) \
106
+ template <typename B, typename L, typename R> \
107
+ struct op_impl<op_##id, op_l, B, L, R> { \
108
+ static char const *name() { return "__" #id "__"; } \
109
+ static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); } \
110
+ static B execute_cast(const L &l, const R &r) { return B(expr); } \
111
+ }; \
112
+ template <typename B, typename L, typename R> \
113
+ struct op_impl<op_##id, op_r, B, L, R> { \
114
+ static char const *name() { return "__" #rid "__"; } \
115
+ static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); } \
116
+ static B execute_cast(const R &r, const L &l) { return B(expr); } \
117
+ }; \
118
+ inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) { \
119
+ return op_<op_##id, op_l, self_t, self_t>(); \
120
+ } \
121
+ template <typename T> \
122
+ op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) { \
123
+ return op_<op_##id, op_l, self_t, T>(); \
124
+ } \
125
+ template <typename T> \
126
+ op_<op_##id, op_r, T, self_t> op(const T &, const self_t &) { \
127
+ return op_<op_##id, op_r, T, self_t>(); \
128
+ }
129
+
130
+ #define PYBIND11_INPLACE_OPERATOR(id, op, expr) \
131
+ template <typename B, typename L, typename R> \
132
+ struct op_impl<op_##id, op_l, B, L, R> { \
133
+ static char const *name() { return "__" #id "__"; } \
134
+ static auto execute(L &l, const R &r) -> decltype(expr) { return expr; } \
135
+ static B execute_cast(L &l, const R &r) { return B(expr); } \
136
+ }; \
137
+ template <typename T> \
138
+ op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) { \
139
+ return op_<op_##id, op_l, self_t, T>(); \
140
+ }
141
+
142
+ #define PYBIND11_UNARY_OPERATOR(id, op, expr) \
143
+ template <typename B, typename L> \
144
+ struct op_impl<op_##id, op_u, B, L, undefined_t> { \
145
+ static char const *name() { return "__" #id "__"; } \
146
+ static auto execute(const L &l) -> decltype(expr) { return expr; } \
147
+ static B execute_cast(const L &l) { return B(expr); } \
148
+ }; \
149
+ inline op_<op_##id, op_u, self_t, undefined_t> op(const self_t &) { \
150
+ return op_<op_##id, op_u, self_t, undefined_t>(); \
151
+ }
152
+
153
+ PYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r)
154
+ PYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r)
155
+ PYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l *r)
156
+ PYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r)
157
+ PYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r)
158
+ PYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r)
159
+ PYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r)
160
+ PYBIND11_BINARY_OPERATOR(and, rand, operator&, l &r)
161
+ PYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r)
162
+ PYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)
163
+ PYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r)
164
+ PYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r)
165
+ PYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r)
166
+ PYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r)
167
+ PYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r)
168
+ PYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r)
169
+ // PYBIND11_BINARY_OPERATOR(pow, rpow, pow, std::pow(l, r))
170
+ PYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r)
171
+ PYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r)
172
+ PYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r)
173
+ PYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r)
174
+ PYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r)
175
+ PYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r)
176
+ PYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r)
177
+ PYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r)
178
+ PYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r)
179
+ PYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r)
180
+ PYBIND11_UNARY_OPERATOR(neg, operator-, -l)
181
+ PYBIND11_UNARY_OPERATOR(pos, operator+, +l)
182
+ // WARNING: This usage of `abs` should only be done for existing STL overloads.
183
+ // Adding overloads directly in to the `std::` namespace is advised against:
184
+ // https://en.cppreference.com/w/cpp/language/extending_std
185
+ PYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l))
186
+ PYBIND11_UNARY_OPERATOR(hash, hash, std::hash<L>()(l))
187
+ PYBIND11_UNARY_OPERATOR(invert, operator~, (~l))
188
+ PYBIND11_UNARY_OPERATOR(bool, operator!, !!l)
189
+ PYBIND11_UNARY_OPERATOR(int, int_, (int) l)
190
+ PYBIND11_UNARY_OPERATOR(float, float_, (double) l)
191
+
192
+ #undef PYBIND11_BINARY_OPERATOR
193
+ #undef PYBIND11_INPLACE_OPERATOR
194
+ #undef PYBIND11_UNARY_OPERATOR
195
+ PYBIND11_NAMESPACE_END(detail)
196
+
197
+ using detail::self;
198
+ // Add named operators so that they are accessible via `py::`.
199
+ using detail::hash;
200
+
201
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/options.h ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/options.h: global settings that are configurable at runtime.
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "detail/common.h"
13
+
14
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
15
+
16
+ class options {
17
+ public:
18
+ // Default RAII constructor, which leaves settings as they currently are.
19
+ options() : previous_state(global_state()) {}
20
+
21
+ // Class is non-copyable.
22
+ options(const options &) = delete;
23
+ options &operator=(const options &) = delete;
24
+
25
+ // Destructor, which restores settings that were in effect before.
26
+ ~options() { global_state() = previous_state; }
27
+
28
+ // Setter methods (affect the global state):
29
+
30
+ options &disable_user_defined_docstrings() & {
31
+ global_state().show_user_defined_docstrings = false;
32
+ return *this;
33
+ }
34
+
35
+ options &enable_user_defined_docstrings() & {
36
+ global_state().show_user_defined_docstrings = true;
37
+ return *this;
38
+ }
39
+
40
+ options &disable_function_signatures() & {
41
+ global_state().show_function_signatures = false;
42
+ return *this;
43
+ }
44
+
45
+ options &enable_function_signatures() & {
46
+ global_state().show_function_signatures = true;
47
+ return *this;
48
+ }
49
+
50
+ // Getter methods (return the global state):
51
+
52
+ static bool show_user_defined_docstrings() {
53
+ return global_state().show_user_defined_docstrings;
54
+ }
55
+
56
+ static bool show_function_signatures() { return global_state().show_function_signatures; }
57
+
58
+ // This type is not meant to be allocated on the heap.
59
+ void *operator new(size_t) = delete;
60
+
61
+ private:
62
+ struct state {
63
+ bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.
64
+ bool show_function_signatures = true; //< Include auto-generated function signatures
65
+ // in docstrings.
66
+ };
67
+
68
+ static state &global_state() {
69
+ static state instance;
70
+ return instance;
71
+ }
72
+
73
+ state previous_state;
74
+ };
75
+
76
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/pybind11.h ADDED
The diff for this file is too large to render. See raw diff
 
third-party/DPVO/DPViewer/pybind11/include/pybind11/pytypes.h ADDED
@@ -0,0 +1,2373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/pytypes.h: Convenience wrapper classes for basic Python types
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "detail/common.h"
13
+ #include "buffer_info.h"
14
+
15
+ #include <assert.h>
16
+ #include <cstddef>
17
+ #include <exception>
18
+ #include <frameobject.h>
19
+ #include <iterator>
20
+ #include <memory>
21
+ #include <string>
22
+ #include <type_traits>
23
+ #include <typeinfo>
24
+ #include <utility>
25
+
26
+ #if defined(PYBIND11_HAS_OPTIONAL)
27
+ # include <optional>
28
+ #endif
29
+
30
+ #ifdef PYBIND11_HAS_STRING_VIEW
31
+ # include <string_view>
32
+ #endif
33
+
34
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
35
+
36
+ /* A few forward declarations */
37
+ class handle;
38
+ class object;
39
+ class str;
40
+ class iterator;
41
+ class type;
42
+ struct arg;
43
+ struct arg_v;
44
+
45
+ PYBIND11_NAMESPACE_BEGIN(detail)
46
+ class args_proxy;
47
+ bool isinstance_generic(handle obj, const std::type_info &tp);
48
+
49
+ // Accessor forward declarations
50
+ template <typename Policy>
51
+ class accessor;
52
+ namespace accessor_policies {
53
+ struct obj_attr;
54
+ struct str_attr;
55
+ struct generic_item;
56
+ struct sequence_item;
57
+ struct list_item;
58
+ struct tuple_item;
59
+ } // namespace accessor_policies
60
+ using obj_attr_accessor = accessor<accessor_policies::obj_attr>;
61
+ using str_attr_accessor = accessor<accessor_policies::str_attr>;
62
+ using item_accessor = accessor<accessor_policies::generic_item>;
63
+ using sequence_accessor = accessor<accessor_policies::sequence_item>;
64
+ using list_accessor = accessor<accessor_policies::list_item>;
65
+ using tuple_accessor = accessor<accessor_policies::tuple_item>;
66
+
67
+ /// Tag and check to identify a class which implements the Python object API
68
+ class pyobject_tag {};
69
+ template <typename T>
70
+ using is_pyobject = std::is_base_of<pyobject_tag, remove_reference_t<T>>;
71
+
72
+ /** \rst
73
+ A mixin class which adds common functions to `handle`, `object` and various accessors.
74
+ The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``.
75
+ \endrst */
76
+ template <typename Derived>
77
+ class object_api : public pyobject_tag {
78
+ const Derived &derived() const { return static_cast<const Derived &>(*this); }
79
+
80
+ public:
81
+ /** \rst
82
+ Return an iterator equivalent to calling ``iter()`` in Python. The object
83
+ must be a collection which supports the iteration protocol.
84
+ \endrst */
85
+ iterator begin() const;
86
+ /// Return a sentinel which ends iteration.
87
+ iterator end() const;
88
+
89
+ /** \rst
90
+ Return an internal functor to invoke the object's sequence protocol. Casting
91
+ the returned ``detail::item_accessor`` instance to a `handle` or `object`
92
+ subclass causes a corresponding call to ``__getitem__``. Assigning a `handle`
93
+ or `object` subclass causes a call to ``__setitem__``.
94
+ \endrst */
95
+ item_accessor operator[](handle key) const;
96
+ /// See above (the only difference is that the key's reference is stolen)
97
+ item_accessor operator[](object &&key) const;
98
+ /// See above (the only difference is that the key is provided as a string literal)
99
+ item_accessor operator[](const char *key) const;
100
+
101
+ /** \rst
102
+ Return an internal functor to access the object's attributes. Casting the
103
+ returned ``detail::obj_attr_accessor`` instance to a `handle` or `object`
104
+ subclass causes a corresponding call to ``getattr``. Assigning a `handle`
105
+ or `object` subclass causes a call to ``setattr``.
106
+ \endrst */
107
+ obj_attr_accessor attr(handle key) const;
108
+ /// See above (the only difference is that the key's reference is stolen)
109
+ obj_attr_accessor attr(object &&key) const;
110
+ /// See above (the only difference is that the key is provided as a string literal)
111
+ str_attr_accessor attr(const char *key) const;
112
+
113
+ /** \rst
114
+ Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple``
115
+ or ``list`` for a function call. Applying another * to the result yields
116
+ ** unpacking, e.g. to unpack a dict as function keyword arguments.
117
+ See :ref:`calling_python_functions`.
118
+ \endrst */
119
+ args_proxy operator*() const;
120
+
121
+ /// Check if the given item is contained within this object, i.e. ``item in obj``.
122
+ template <typename T>
123
+ bool contains(T &&item) const;
124
+
125
+ /** \rst
126
+ Assuming the Python object is a function or implements the ``__call__``
127
+ protocol, ``operator()`` invokes the underlying function, passing an
128
+ arbitrary set of parameters. The result is returned as a `object` and
129
+ may need to be converted back into a Python object using `handle::cast()`.
130
+
131
+ When some of the arguments cannot be converted to Python objects, the
132
+ function will throw a `cast_error` exception. When the Python function
133
+ call fails, a `error_already_set` exception is thrown.
134
+ \endrst */
135
+ template <return_value_policy policy = return_value_policy::automatic_reference,
136
+ typename... Args>
137
+ object operator()(Args &&...args) const;
138
+ template <return_value_policy policy = return_value_policy::automatic_reference,
139
+ typename... Args>
140
+ PYBIND11_DEPRECATED("call(...) was deprecated in favor of operator()(...)")
141
+ object call(Args &&...args) const;
142
+
143
+ /// Equivalent to ``obj is other`` in Python.
144
+ bool is(object_api const &other) const { return derived().ptr() == other.derived().ptr(); }
145
+ /// Equivalent to ``obj is None`` in Python.
146
+ bool is_none() const { return derived().ptr() == Py_None; }
147
+ /// Equivalent to obj == other in Python
148
+ bool equal(object_api const &other) const { return rich_compare(other, Py_EQ); }
149
+ bool not_equal(object_api const &other) const { return rich_compare(other, Py_NE); }
150
+ bool operator<(object_api const &other) const { return rich_compare(other, Py_LT); }
151
+ bool operator<=(object_api const &other) const { return rich_compare(other, Py_LE); }
152
+ bool operator>(object_api const &other) const { return rich_compare(other, Py_GT); }
153
+ bool operator>=(object_api const &other) const { return rich_compare(other, Py_GE); }
154
+
155
+ object operator-() const;
156
+ object operator~() const;
157
+ object operator+(object_api const &other) const;
158
+ object operator+=(object_api const &other) const;
159
+ object operator-(object_api const &other) const;
160
+ object operator-=(object_api const &other) const;
161
+ object operator*(object_api const &other) const;
162
+ object operator*=(object_api const &other) const;
163
+ object operator/(object_api const &other) const;
164
+ object operator/=(object_api const &other) const;
165
+ object operator|(object_api const &other) const;
166
+ object operator|=(object_api const &other) const;
167
+ object operator&(object_api const &other) const;
168
+ object operator&=(object_api const &other) const;
169
+ object operator^(object_api const &other) const;
170
+ object operator^=(object_api const &other) const;
171
+ object operator<<(object_api const &other) const;
172
+ object operator<<=(object_api const &other) const;
173
+ object operator>>(object_api const &other) const;
174
+ object operator>>=(object_api const &other) const;
175
+
176
+ PYBIND11_DEPRECATED("Use py::str(obj) instead")
177
+ pybind11::str str() const;
178
+
179
+ /// Get or set the object's docstring, i.e. ``obj.__doc__``.
180
+ str_attr_accessor doc() const;
181
+
182
+ /// Return the object's current reference count
183
+ int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
184
+
185
+ // TODO PYBIND11_DEPRECATED(
186
+ // "Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()")
187
+ handle get_type() const;
188
+
189
+ private:
190
+ bool rich_compare(object_api const &other, int value) const;
191
+ };
192
+
193
+ PYBIND11_NAMESPACE_END(detail)
194
+
195
+ #if !defined(PYBIND11_HANDLE_REF_DEBUG) && !defined(NDEBUG)
196
+ # define PYBIND11_HANDLE_REF_DEBUG
197
+ #endif
198
+
199
+ /** \rst
200
+ Holds a reference to a Python object (no reference counting)
201
+
202
+ The `handle` class is a thin wrapper around an arbitrary Python object (i.e. a
203
+ ``PyObject *`` in Python's C API). It does not perform any automatic reference
204
+ counting and merely provides a basic C++ interface to various Python API functions.
205
+
206
+ .. seealso::
207
+ The `object` class inherits from `handle` and adds automatic reference
208
+ counting features.
209
+ \endrst */
210
+ class handle : public detail::object_api<handle> {
211
+ public:
212
+ /// The default constructor creates a handle with a ``nullptr``-valued pointer
213
+ handle() = default;
214
+ /// Creates a ``handle`` from the given raw Python object pointer
215
+ // NOLINTNEXTLINE(google-explicit-constructor)
216
+ handle(PyObject *ptr) : m_ptr(ptr) {} // Allow implicit conversion from PyObject*
217
+
218
+ /// Return the underlying ``PyObject *`` pointer
219
+ PyObject *ptr() const { return m_ptr; }
220
+ PyObject *&ptr() { return m_ptr; }
221
+
222
+ /** \rst
223
+ Manually increase the reference count of the Python object. Usually, it is
224
+ preferable to use the `object` class which derives from `handle` and calls
225
+ this function automatically. Returns a reference to itself.
226
+ \endrst */
227
+ const handle &inc_ref() const & {
228
+ #ifdef PYBIND11_HANDLE_REF_DEBUG
229
+ inc_ref_counter(1);
230
+ #endif
231
+ Py_XINCREF(m_ptr);
232
+ return *this;
233
+ }
234
+
235
+ /** \rst
236
+ Manually decrease the reference count of the Python object. Usually, it is
237
+ preferable to use the `object` class which derives from `handle` and calls
238
+ this function automatically. Returns a reference to itself.
239
+ \endrst */
240
+ const handle &dec_ref() const & {
241
+ Py_XDECREF(m_ptr);
242
+ return *this;
243
+ }
244
+
245
+ /** \rst
246
+ Attempt to cast the Python object into the given C++ type. A `cast_error`
247
+ will be throw upon failure.
248
+ \endrst */
249
+ template <typename T>
250
+ T cast() const;
251
+ /// Return ``true`` when the `handle` wraps a valid Python object
252
+ explicit operator bool() const { return m_ptr != nullptr; }
253
+ /** \rst
254
+ Deprecated: Check that the underlying pointers are the same.
255
+ Equivalent to ``obj1 is obj2`` in Python.
256
+ \endrst */
257
+ PYBIND11_DEPRECATED("Use obj1.is(obj2) instead")
258
+ bool operator==(const handle &h) const { return m_ptr == h.m_ptr; }
259
+ PYBIND11_DEPRECATED("Use !obj1.is(obj2) instead")
260
+ bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; }
261
+ PYBIND11_DEPRECATED("Use handle::operator bool() instead")
262
+ bool check() const { return m_ptr != nullptr; }
263
+
264
+ protected:
265
+ PyObject *m_ptr = nullptr;
266
+
267
+ #ifdef PYBIND11_HANDLE_REF_DEBUG
268
+ private:
269
+ static std::size_t inc_ref_counter(std::size_t add) {
270
+ thread_local std::size_t counter = 0;
271
+ counter += add;
272
+ return counter;
273
+ }
274
+
275
+ public:
276
+ static std::size_t inc_ref_counter() { return inc_ref_counter(0); }
277
+ #endif
278
+ };
279
+
280
+ /** \rst
281
+ Holds a reference to a Python object (with reference counting)
282
+
283
+ Like `handle`, the `object` class is a thin wrapper around an arbitrary Python
284
+ object (i.e. a ``PyObject *`` in Python's C API). In contrast to `handle`, it
285
+ optionally increases the object's reference count upon construction, and it
286
+ *always* decreases the reference count when the `object` instance goes out of
287
+ scope and is destructed. When using `object` instances consistently, it is much
288
+ easier to get reference counting right at the first attempt.
289
+ \endrst */
290
+ class object : public handle {
291
+ public:
292
+ object() = default;
293
+ PYBIND11_DEPRECATED("Use reinterpret_borrow<object>() or reinterpret_steal<object>()")
294
+ object(handle h, bool is_borrowed) : handle(h) {
295
+ if (is_borrowed) {
296
+ inc_ref();
297
+ }
298
+ }
299
+ /// Copy constructor; always increases the reference count
300
+ object(const object &o) : handle(o) { inc_ref(); }
301
+ /// Move constructor; steals the object from ``other`` and preserves its reference count
302
+ object(object &&other) noexcept : handle(other) { other.m_ptr = nullptr; }
303
+ /// Destructor; automatically calls `handle::dec_ref()`
304
+ ~object() { dec_ref(); }
305
+
306
+ /** \rst
307
+ Resets the internal pointer to ``nullptr`` without decreasing the
308
+ object's reference count. The function returns a raw handle to the original
309
+ Python object.
310
+ \endrst */
311
+ handle release() {
312
+ PyObject *tmp = m_ptr;
313
+ m_ptr = nullptr;
314
+ return handle(tmp);
315
+ }
316
+
317
+ object &operator=(const object &other) {
318
+ other.inc_ref();
319
+ // Use temporary variable to ensure `*this` remains valid while
320
+ // `Py_XDECREF` executes, in case `*this` is accessible from Python.
321
+ handle temp(m_ptr);
322
+ m_ptr = other.m_ptr;
323
+ temp.dec_ref();
324
+ return *this;
325
+ }
326
+
327
+ object &operator=(object &&other) noexcept {
328
+ if (this != &other) {
329
+ handle temp(m_ptr);
330
+ m_ptr = other.m_ptr;
331
+ other.m_ptr = nullptr;
332
+ temp.dec_ref();
333
+ }
334
+ return *this;
335
+ }
336
+
337
+ // Calling cast() on an object lvalue just copies (via handle::cast)
338
+ template <typename T>
339
+ T cast() const &;
340
+ // Calling on an object rvalue does a move, if needed and/or possible
341
+ template <typename T>
342
+ T cast() &&;
343
+
344
+ protected:
345
+ // Tags for choosing constructors from raw PyObject *
346
+ struct borrowed_t {};
347
+ struct stolen_t {};
348
+
349
+ /// @cond BROKEN
350
+ template <typename T>
351
+ friend T reinterpret_borrow(handle);
352
+ template <typename T>
353
+ friend T reinterpret_steal(handle);
354
+ /// @endcond
355
+
356
+ public:
357
+ // Only accessible from derived classes and the reinterpret_* functions
358
+ object(handle h, borrowed_t) : handle(h) { inc_ref(); }
359
+ object(handle h, stolen_t) : handle(h) {}
360
+ };
361
+
362
+ /** \rst
363
+ Declare that a `handle` or ``PyObject *`` is a certain type and borrow the reference.
364
+ The target type ``T`` must be `object` or one of its derived classes. The function
365
+ doesn't do any conversions or checks. It's up to the user to make sure that the
366
+ target type is correct.
367
+
368
+ .. code-block:: cpp
369
+
370
+ PyObject *p = PyList_GetItem(obj, index);
371
+ py::object o = reinterpret_borrow<py::object>(p);
372
+ // or
373
+ py::tuple t = reinterpret_borrow<py::tuple>(p); // <-- `p` must be already be a `tuple`
374
+ \endrst */
375
+ template <typename T>
376
+ T reinterpret_borrow(handle h) {
377
+ return {h, object::borrowed_t{}};
378
+ }
379
+
380
+ /** \rst
381
+ Like `reinterpret_borrow`, but steals the reference.
382
+
383
+ .. code-block:: cpp
384
+
385
+ PyObject *p = PyObject_Str(obj);
386
+ py::str s = reinterpret_steal<py::str>(p); // <-- `p` must be already be a `str`
387
+ \endrst */
388
+ template <typename T>
389
+ T reinterpret_steal(handle h) {
390
+ return {h, object::stolen_t{}};
391
+ }
392
+
393
+ PYBIND11_NAMESPACE_BEGIN(detail)
394
+
395
+ // Equivalent to obj.__class__.__name__ (or obj.__name__ if obj is a class).
396
+ inline const char *obj_class_name(PyObject *obj) {
397
+ if (Py_TYPE(obj) == &PyType_Type) {
398
+ return reinterpret_cast<PyTypeObject *>(obj)->tp_name;
399
+ }
400
+ return Py_TYPE(obj)->tp_name;
401
+ }
402
+
403
+ std::string error_string();
404
+
405
+ struct error_fetch_and_normalize {
406
+ // Immediate normalization is long-established behavior (starting with
407
+ // https://github.com/pybind/pybind11/commit/135ba8deafb8bf64a15b24d1513899eb600e2011
408
+ // from Sep 2016) and safest. Normalization could be deferred, but this could mask
409
+ // errors elsewhere, the performance gain is very minor in typical situations
410
+ // (usually the dominant bottleneck is EH unwinding), and the implementation here
411
+ // would be more complex.
412
+ explicit error_fetch_and_normalize(const char *called) {
413
+ PyErr_Fetch(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());
414
+ if (!m_type) {
415
+ pybind11_fail("Internal error: " + std::string(called)
416
+ + " called while "
417
+ "Python error indicator not set.");
418
+ }
419
+ const char *exc_type_name_orig = detail::obj_class_name(m_type.ptr());
420
+ if (exc_type_name_orig == nullptr) {
421
+ pybind11_fail("Internal error: " + std::string(called)
422
+ + " failed to obtain the name "
423
+ "of the original active exception type.");
424
+ }
425
+ m_lazy_error_string = exc_type_name_orig;
426
+ // PyErr_NormalizeException() may change the exception type if there are cascading
427
+ // failures. This can potentially be extremely confusing.
428
+ PyErr_NormalizeException(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());
429
+ if (m_type.ptr() == nullptr) {
430
+ pybind11_fail("Internal error: " + std::string(called)
431
+ + " failed to normalize the "
432
+ "active exception.");
433
+ }
434
+ const char *exc_type_name_norm = detail::obj_class_name(m_type.ptr());
435
+ if (exc_type_name_orig == nullptr) {
436
+ pybind11_fail("Internal error: " + std::string(called)
437
+ + " failed to obtain the name "
438
+ "of the normalized active exception type.");
439
+ }
440
+ if (exc_type_name_norm != m_lazy_error_string) {
441
+ std::string msg = std::string(called)
442
+ + ": MISMATCH of original and normalized "
443
+ "active exception types: ";
444
+ msg += "ORIGINAL ";
445
+ msg += m_lazy_error_string;
446
+ msg += " REPLACED BY ";
447
+ msg += exc_type_name_norm;
448
+ msg += ": " + format_value_and_trace();
449
+ pybind11_fail(msg);
450
+ }
451
+ }
452
+
453
+ error_fetch_and_normalize(const error_fetch_and_normalize &) = delete;
454
+ error_fetch_and_normalize(error_fetch_and_normalize &&) = delete;
455
+
456
+ std::string format_value_and_trace() const {
457
+ std::string result;
458
+ std::string message_error_string;
459
+ if (m_value) {
460
+ auto value_str = reinterpret_steal<object>(PyObject_Str(m_value.ptr()));
461
+ if (!value_str) {
462
+ message_error_string = detail::error_string();
463
+ result = "<MESSAGE UNAVAILABLE DUE TO ANOTHER EXCEPTION>";
464
+ } else {
465
+ result = value_str.cast<std::string>();
466
+ }
467
+ } else {
468
+ result = "<MESSAGE UNAVAILABLE>";
469
+ }
470
+ if (result.empty()) {
471
+ result = "<EMPTY MESSAGE>";
472
+ }
473
+
474
+ bool have_trace = false;
475
+ if (m_trace) {
476
+ #if !defined(PYPY_VERSION)
477
+ auto *tb = reinterpret_cast<PyTracebackObject *>(m_trace.ptr());
478
+
479
+ // Get the deepest trace possible.
480
+ while (tb->tb_next) {
481
+ tb = tb->tb_next;
482
+ }
483
+
484
+ PyFrameObject *frame = tb->tb_frame;
485
+ Py_XINCREF(frame);
486
+ result += "\n\nAt:\n";
487
+ while (frame) {
488
+ # if PY_VERSION_HEX >= 0x030900B1
489
+ PyCodeObject *f_code = PyFrame_GetCode(frame);
490
+ # else
491
+ PyCodeObject *f_code = frame->f_code;
492
+ Py_INCREF(f_code);
493
+ # endif
494
+ int lineno = PyFrame_GetLineNumber(frame);
495
+ result += " ";
496
+ result += handle(f_code->co_filename).cast<std::string>();
497
+ result += '(';
498
+ result += std::to_string(lineno);
499
+ result += "): ";
500
+ result += handle(f_code->co_name).cast<std::string>();
501
+ result += '\n';
502
+ Py_DECREF(f_code);
503
+ # if PY_VERSION_HEX >= 0x030900B1
504
+ auto *b_frame = PyFrame_GetBack(frame);
505
+ # else
506
+ auto *b_frame = frame->f_back;
507
+ Py_XINCREF(b_frame);
508
+ # endif
509
+ Py_DECREF(frame);
510
+ frame = b_frame;
511
+ }
512
+
513
+ have_trace = true;
514
+ #endif //! defined(PYPY_VERSION)
515
+ }
516
+
517
+ if (!message_error_string.empty()) {
518
+ if (!have_trace) {
519
+ result += '\n';
520
+ }
521
+ result += "\nMESSAGE UNAVAILABLE DUE TO EXCEPTION: " + message_error_string;
522
+ }
523
+
524
+ return result;
525
+ }
526
+
527
+ std::string const &error_string() const {
528
+ if (!m_lazy_error_string_completed) {
529
+ m_lazy_error_string += ": " + format_value_and_trace();
530
+ m_lazy_error_string_completed = true;
531
+ }
532
+ return m_lazy_error_string;
533
+ }
534
+
535
+ void restore() {
536
+ if (m_restore_called) {
537
+ pybind11_fail("Internal error: pybind11::detail::error_fetch_and_normalize::restore() "
538
+ "called a second time. ORIGINAL ERROR: "
539
+ + error_string());
540
+ }
541
+ PyErr_Restore(m_type.inc_ref().ptr(), m_value.inc_ref().ptr(), m_trace.inc_ref().ptr());
542
+ m_restore_called = true;
543
+ }
544
+
545
+ bool matches(handle exc) const {
546
+ return (PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()) != 0);
547
+ }
548
+
549
+ // Not protecting these for simplicity.
550
+ object m_type, m_value, m_trace;
551
+
552
+ private:
553
+ // Only protecting invariants.
554
+ mutable std::string m_lazy_error_string;
555
+ mutable bool m_lazy_error_string_completed = false;
556
+ mutable bool m_restore_called = false;
557
+ };
558
+
559
+ inline std::string error_string() {
560
+ return error_fetch_and_normalize("pybind11::detail::error_string").error_string();
561
+ }
562
+
563
+ PYBIND11_NAMESPACE_END(detail)
564
+
565
+ #if defined(_MSC_VER)
566
+ # pragma warning(push)
567
+ # pragma warning(disable : 4275 4251)
568
+ // warning C4275: An exported class was derived from a class that wasn't exported.
569
+ // Can be ignored when derived from a STL class.
570
+ #endif
571
+ /// Fetch and hold an error which was already set in Python. An instance of this is typically
572
+ /// thrown to propagate python-side errors back through C++ which can either be caught manually or
573
+ /// else falls back to the function dispatcher (which then raises the captured error back to
574
+ /// python).
575
+ class PYBIND11_EXPORT_EXCEPTION error_already_set : public std::exception {
576
+ public:
577
+ /// Fetches the current Python exception (using PyErr_Fetch()), which will clear the
578
+ /// current Python error indicator.
579
+ error_already_set()
580
+ : m_fetched_error{new detail::error_fetch_and_normalize("pybind11::error_already_set"),
581
+ m_fetched_error_deleter} {}
582
+
583
+ /// The what() result is built lazily on demand.
584
+ /// WARNING: This member function needs to acquire the Python GIL. This can lead to
585
+ /// crashes (undefined behavior) if the Python interpreter is finalizing.
586
+ const char *what() const noexcept override;
587
+
588
+ /// Restores the currently-held Python error (which will clear the Python error indicator first
589
+ /// if already set).
590
+ /// NOTE: This member function will always restore the normalized exception, which may or may
591
+ /// not be the original Python exception.
592
+ /// WARNING: The GIL must be held when this member function is called!
593
+ void restore() { m_fetched_error->restore(); }
594
+
595
+ /// If it is impossible to raise the currently-held error, such as in a destructor, we can
596
+ /// write it out using Python's unraisable hook (`sys.unraisablehook`). The error context
597
+ /// should be some object whose `repr()` helps identify the location of the error. Python
598
+ /// already knows the type and value of the error, so there is no need to repeat that.
599
+ void discard_as_unraisable(object err_context) {
600
+ restore();
601
+ PyErr_WriteUnraisable(err_context.ptr());
602
+ }
603
+ /// An alternate version of `discard_as_unraisable()`, where a string provides information on
604
+ /// the location of the error. For example, `__func__` could be helpful.
605
+ /// WARNING: The GIL must be held when this member function is called!
606
+ void discard_as_unraisable(const char *err_context) {
607
+ discard_as_unraisable(reinterpret_steal<object>(PYBIND11_FROM_STRING(err_context)));
608
+ }
609
+
610
+ // Does nothing; provided for backwards compatibility.
611
+ PYBIND11_DEPRECATED("Use of error_already_set.clear() is deprecated")
612
+ void clear() {}
613
+
614
+ /// Check if the currently trapped error type matches the given Python exception class (or a
615
+ /// subclass thereof). May also be passed a tuple to search for any exception class matches in
616
+ /// the given tuple.
617
+ bool matches(handle exc) const { return m_fetched_error->matches(exc); }
618
+
619
+ const object &type() const { return m_fetched_error->m_type; }
620
+ const object &value() const { return m_fetched_error->m_value; }
621
+ const object &trace() const { return m_fetched_error->m_trace; }
622
+
623
+ private:
624
+ std::shared_ptr<detail::error_fetch_and_normalize> m_fetched_error;
625
+
626
+ /// WARNING: This custom deleter needs to acquire the Python GIL. This can lead to
627
+ /// crashes (undefined behavior) if the Python interpreter is finalizing.
628
+ static void m_fetched_error_deleter(detail::error_fetch_and_normalize *raw_ptr);
629
+ };
630
+ #if defined(_MSC_VER)
631
+ # pragma warning(pop)
632
+ #endif
633
+
634
+ /// Replaces the current Python error indicator with the chosen error, performing a
635
+ /// 'raise from' to indicate that the chosen error was caused by the original error.
636
+ inline void raise_from(PyObject *type, const char *message) {
637
+ // Based on _PyErr_FormatVFromCause:
638
+ // https://github.com/python/cpython/blob/467ab194fc6189d9f7310c89937c51abeac56839/Python/errors.c#L405
639
+ // See https://github.com/pybind/pybind11/pull/2112 for details.
640
+ PyObject *exc = nullptr, *val = nullptr, *val2 = nullptr, *tb = nullptr;
641
+
642
+ assert(PyErr_Occurred());
643
+ PyErr_Fetch(&exc, &val, &tb);
644
+ PyErr_NormalizeException(&exc, &val, &tb);
645
+ if (tb != nullptr) {
646
+ PyException_SetTraceback(val, tb);
647
+ Py_DECREF(tb);
648
+ }
649
+ Py_DECREF(exc);
650
+ assert(!PyErr_Occurred());
651
+
652
+ PyErr_SetString(type, message);
653
+
654
+ PyErr_Fetch(&exc, &val2, &tb);
655
+ PyErr_NormalizeException(&exc, &val2, &tb);
656
+ Py_INCREF(val);
657
+ PyException_SetCause(val2, val);
658
+ PyException_SetContext(val2, val);
659
+ PyErr_Restore(exc, val2, tb);
660
+ }
661
+
662
+ /// Sets the current Python error indicator with the chosen error, performing a 'raise from'
663
+ /// from the error contained in error_already_set to indicate that the chosen error was
664
+ /// caused by the original error.
665
+ inline void raise_from(error_already_set &err, PyObject *type, const char *message) {
666
+ err.restore();
667
+ raise_from(type, message);
668
+ }
669
+
670
+ /** \defgroup python_builtins const_name
671
+ Unless stated otherwise, the following C++ functions behave the same
672
+ as their Python counterparts.
673
+ */
674
+
675
+ /** \ingroup python_builtins
676
+ \rst
677
+ Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of
678
+ `object` or a class which was exposed to Python as ``py::class_<T>``.
679
+ \endrst */
680
+ template <typename T, detail::enable_if_t<std::is_base_of<object, T>::value, int> = 0>
681
+ bool isinstance(handle obj) {
682
+ return T::check_(obj);
683
+ }
684
+
685
+ template <typename T, detail::enable_if_t<!std::is_base_of<object, T>::value, int> = 0>
686
+ bool isinstance(handle obj) {
687
+ return detail::isinstance_generic(obj, typeid(T));
688
+ }
689
+
690
+ template <>
691
+ inline bool isinstance<handle>(handle) = delete;
692
+ template <>
693
+ inline bool isinstance<object>(handle obj) {
694
+ return obj.ptr() != nullptr;
695
+ }
696
+
697
+ /// \ingroup python_builtins
698
+ /// Return true if ``obj`` is an instance of the ``type``.
699
+ inline bool isinstance(handle obj, handle type) {
700
+ const auto result = PyObject_IsInstance(obj.ptr(), type.ptr());
701
+ if (result == -1) {
702
+ throw error_already_set();
703
+ }
704
+ return result != 0;
705
+ }
706
+
707
+ /// \addtogroup python_builtins
708
+ /// @{
709
+ inline bool hasattr(handle obj, handle name) {
710
+ return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1;
711
+ }
712
+
713
+ inline bool hasattr(handle obj, const char *name) {
714
+ return PyObject_HasAttrString(obj.ptr(), name) == 1;
715
+ }
716
+
717
+ inline void delattr(handle obj, handle name) {
718
+ if (PyObject_DelAttr(obj.ptr(), name.ptr()) != 0) {
719
+ throw error_already_set();
720
+ }
721
+ }
722
+
723
+ inline void delattr(handle obj, const char *name) {
724
+ if (PyObject_DelAttrString(obj.ptr(), name) != 0) {
725
+ throw error_already_set();
726
+ }
727
+ }
728
+
729
+ inline object getattr(handle obj, handle name) {
730
+ PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr());
731
+ if (!result) {
732
+ throw error_already_set();
733
+ }
734
+ return reinterpret_steal<object>(result);
735
+ }
736
+
737
+ inline object getattr(handle obj, const char *name) {
738
+ PyObject *result = PyObject_GetAttrString(obj.ptr(), name);
739
+ if (!result) {
740
+ throw error_already_set();
741
+ }
742
+ return reinterpret_steal<object>(result);
743
+ }
744
+
745
+ inline object getattr(handle obj, handle name, handle default_) {
746
+ if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) {
747
+ return reinterpret_steal<object>(result);
748
+ }
749
+ PyErr_Clear();
750
+ return reinterpret_borrow<object>(default_);
751
+ }
752
+
753
+ inline object getattr(handle obj, const char *name, handle default_) {
754
+ if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) {
755
+ return reinterpret_steal<object>(result);
756
+ }
757
+ PyErr_Clear();
758
+ return reinterpret_borrow<object>(default_);
759
+ }
760
+
761
+ inline void setattr(handle obj, handle name, handle value) {
762
+ if (PyObject_SetAttr(obj.ptr(), name.ptr(), value.ptr()) != 0) {
763
+ throw error_already_set();
764
+ }
765
+ }
766
+
767
+ inline void setattr(handle obj, const char *name, handle value) {
768
+ if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) {
769
+ throw error_already_set();
770
+ }
771
+ }
772
+
773
+ inline ssize_t hash(handle obj) {
774
+ auto h = PyObject_Hash(obj.ptr());
775
+ if (h == -1) {
776
+ throw error_already_set();
777
+ }
778
+ return h;
779
+ }
780
+
781
+ /// @} python_builtins
782
+
783
+ PYBIND11_NAMESPACE_BEGIN(detail)
784
+ inline handle get_function(handle value) {
785
+ if (value) {
786
+ if (PyInstanceMethod_Check(value.ptr())) {
787
+ value = PyInstanceMethod_GET_FUNCTION(value.ptr());
788
+ } else if (PyMethod_Check(value.ptr())) {
789
+ value = PyMethod_GET_FUNCTION(value.ptr());
790
+ }
791
+ }
792
+ return value;
793
+ }
794
+
795
+ // Reimplementation of python's dict helper functions to ensure that exceptions
796
+ // aren't swallowed (see #2862)
797
+
798
+ // copied from cpython _PyDict_GetItemStringWithError
799
+ inline PyObject *dict_getitemstring(PyObject *v, const char *key) {
800
+ PyObject *kv = nullptr, *rv = nullptr;
801
+ kv = PyUnicode_FromString(key);
802
+ if (kv == nullptr) {
803
+ throw error_already_set();
804
+ }
805
+
806
+ rv = PyDict_GetItemWithError(v, kv);
807
+ Py_DECREF(kv);
808
+ if (rv == nullptr && PyErr_Occurred()) {
809
+ throw error_already_set();
810
+ }
811
+ return rv;
812
+ }
813
+
814
+ inline PyObject *dict_getitem(PyObject *v, PyObject *key) {
815
+ PyObject *rv = PyDict_GetItemWithError(v, key);
816
+ if (rv == nullptr && PyErr_Occurred()) {
817
+ throw error_already_set();
818
+ }
819
+ return rv;
820
+ }
821
+
822
+ // Helper aliases/functions to support implicit casting of values given to python
823
+ // accessors/methods. When given a pyobject, this simply returns the pyobject as-is; for other C++
824
+ // type, the value goes through pybind11::cast(obj) to convert it to an `object`.
825
+ template <typename T, enable_if_t<is_pyobject<T>::value, int> = 0>
826
+ auto object_or_cast(T &&o) -> decltype(std::forward<T>(o)) {
827
+ return std::forward<T>(o);
828
+ }
829
+ // The following casting version is implemented in cast.h:
830
+ template <typename T, enable_if_t<!is_pyobject<T>::value, int> = 0>
831
+ object object_or_cast(T &&o);
832
+ // Match a PyObject*, which we want to convert directly to handle via its converting constructor
833
+ inline handle object_or_cast(PyObject *ptr) { return ptr; }
834
+
835
+ #if defined(_MSC_VER) && _MSC_VER < 1920
836
+ # pragma warning(push)
837
+ # pragma warning(disable : 4522) // warning C4522: multiple assignment operators specified
838
+ #endif
839
+ template <typename Policy>
840
+ class accessor : public object_api<accessor<Policy>> {
841
+ using key_type = typename Policy::key_type;
842
+
843
+ public:
844
+ accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) {}
845
+ accessor(const accessor &) = default;
846
+ accessor(accessor &&) noexcept = default;
847
+
848
+ // accessor overload required to override default assignment operator (templates are not
849
+ // allowed to replace default compiler-generated assignments).
850
+ void operator=(const accessor &a) && { std::move(*this).operator=(handle(a)); }
851
+ void operator=(const accessor &a) & { operator=(handle(a)); }
852
+
853
+ template <typename T>
854
+ void operator=(T &&value) && {
855
+ Policy::set(obj, key, object_or_cast(std::forward<T>(value)));
856
+ }
857
+ template <typename T>
858
+ void operator=(T &&value) & {
859
+ get_cache() = ensure_object(object_or_cast(std::forward<T>(value)));
860
+ }
861
+
862
+ template <typename T = Policy>
863
+ PYBIND11_DEPRECATED(
864
+ "Use of obj.attr(...) as bool is deprecated in favor of pybind11::hasattr(obj, ...)")
865
+ explicit
866
+ operator enable_if_t<std::is_same<T, accessor_policies::str_attr>::value
867
+ || std::is_same<T, accessor_policies::obj_attr>::value,
868
+ bool>() const {
869
+ return hasattr(obj, key);
870
+ }
871
+ template <typename T = Policy>
872
+ PYBIND11_DEPRECATED("Use of obj[key] as bool is deprecated in favor of obj.contains(key)")
873
+ explicit
874
+ operator enable_if_t<std::is_same<T, accessor_policies::generic_item>::value, bool>() const {
875
+ return obj.contains(key);
876
+ }
877
+
878
+ // NOLINTNEXTLINE(google-explicit-constructor)
879
+ operator object() const { return get_cache(); }
880
+ PyObject *ptr() const { return get_cache().ptr(); }
881
+ template <typename T>
882
+ T cast() const {
883
+ return get_cache().template cast<T>();
884
+ }
885
+
886
+ private:
887
+ static object ensure_object(object &&o) { return std::move(o); }
888
+ static object ensure_object(handle h) { return reinterpret_borrow<object>(h); }
889
+
890
+ object &get_cache() const {
891
+ if (!cache) {
892
+ cache = Policy::get(obj, key);
893
+ }
894
+ return cache;
895
+ }
896
+
897
+ private:
898
+ handle obj;
899
+ key_type key;
900
+ mutable object cache;
901
+ };
902
+ #if defined(_MSC_VER) && _MSC_VER < 1920
903
+ # pragma warning(pop)
904
+ #endif
905
+
906
+ PYBIND11_NAMESPACE_BEGIN(accessor_policies)
907
+ struct obj_attr {
908
+ using key_type = object;
909
+ static object get(handle obj, handle key) { return getattr(obj, key); }
910
+ static void set(handle obj, handle key, handle val) { setattr(obj, key, val); }
911
+ };
912
+
913
+ struct str_attr {
914
+ using key_type = const char *;
915
+ static object get(handle obj, const char *key) { return getattr(obj, key); }
916
+ static void set(handle obj, const char *key, handle val) { setattr(obj, key, val); }
917
+ };
918
+
919
+ struct generic_item {
920
+ using key_type = object;
921
+
922
+ static object get(handle obj, handle key) {
923
+ PyObject *result = PyObject_GetItem(obj.ptr(), key.ptr());
924
+ if (!result) {
925
+ throw error_already_set();
926
+ }
927
+ return reinterpret_steal<object>(result);
928
+ }
929
+
930
+ static void set(handle obj, handle key, handle val) {
931
+ if (PyObject_SetItem(obj.ptr(), key.ptr(), val.ptr()) != 0) {
932
+ throw error_already_set();
933
+ }
934
+ }
935
+ };
936
+
937
+ struct sequence_item {
938
+ using key_type = size_t;
939
+
940
+ template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
941
+ static object get(handle obj, const IdxType &index) {
942
+ PyObject *result = PySequence_GetItem(obj.ptr(), ssize_t_cast(index));
943
+ if (!result) {
944
+ throw error_already_set();
945
+ }
946
+ return reinterpret_steal<object>(result);
947
+ }
948
+
949
+ template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
950
+ static void set(handle obj, const IdxType &index, handle val) {
951
+ // PySequence_SetItem does not steal a reference to 'val'
952
+ if (PySequence_SetItem(obj.ptr(), ssize_t_cast(index), val.ptr()) != 0) {
953
+ throw error_already_set();
954
+ }
955
+ }
956
+ };
957
+
958
+ struct list_item {
959
+ using key_type = size_t;
960
+
961
+ template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
962
+ static object get(handle obj, const IdxType &index) {
963
+ PyObject *result = PyList_GetItem(obj.ptr(), ssize_t_cast(index));
964
+ if (!result) {
965
+ throw error_already_set();
966
+ }
967
+ return reinterpret_borrow<object>(result);
968
+ }
969
+
970
+ template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
971
+ static void set(handle obj, const IdxType &index, handle val) {
972
+ // PyList_SetItem steals a reference to 'val'
973
+ if (PyList_SetItem(obj.ptr(), ssize_t_cast(index), val.inc_ref().ptr()) != 0) {
974
+ throw error_already_set();
975
+ }
976
+ }
977
+ };
978
+
979
+ struct tuple_item {
980
+ using key_type = size_t;
981
+
982
+ template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
983
+ static object get(handle obj, const IdxType &index) {
984
+ PyObject *result = PyTuple_GetItem(obj.ptr(), ssize_t_cast(index));
985
+ if (!result) {
986
+ throw error_already_set();
987
+ }
988
+ return reinterpret_borrow<object>(result);
989
+ }
990
+
991
+ template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
992
+ static void set(handle obj, const IdxType &index, handle val) {
993
+ // PyTuple_SetItem steals a reference to 'val'
994
+ if (PyTuple_SetItem(obj.ptr(), ssize_t_cast(index), val.inc_ref().ptr()) != 0) {
995
+ throw error_already_set();
996
+ }
997
+ }
998
+ };
999
+ PYBIND11_NAMESPACE_END(accessor_policies)
1000
+
1001
+ /// STL iterator template used for tuple, list, sequence and dict
1002
+ template <typename Policy>
1003
+ class generic_iterator : public Policy {
1004
+ using It = generic_iterator;
1005
+
1006
+ public:
1007
+ using difference_type = ssize_t;
1008
+ using iterator_category = typename Policy::iterator_category;
1009
+ using value_type = typename Policy::value_type;
1010
+ using reference = typename Policy::reference;
1011
+ using pointer = typename Policy::pointer;
1012
+
1013
+ generic_iterator() = default;
1014
+ generic_iterator(handle seq, ssize_t index) : Policy(seq, index) {}
1015
+
1016
+ // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
1017
+ reference operator*() const { return Policy::dereference(); }
1018
+ // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
1019
+ reference operator[](difference_type n) const { return *(*this + n); }
1020
+ pointer operator->() const { return **this; }
1021
+
1022
+ It &operator++() {
1023
+ Policy::increment();
1024
+ return *this;
1025
+ }
1026
+ It operator++(int) {
1027
+ auto copy = *this;
1028
+ Policy::increment();
1029
+ return copy;
1030
+ }
1031
+ It &operator--() {
1032
+ Policy::decrement();
1033
+ return *this;
1034
+ }
1035
+ It operator--(int) {
1036
+ auto copy = *this;
1037
+ Policy::decrement();
1038
+ return copy;
1039
+ }
1040
+ It &operator+=(difference_type n) {
1041
+ Policy::advance(n);
1042
+ return *this;
1043
+ }
1044
+ It &operator-=(difference_type n) {
1045
+ Policy::advance(-n);
1046
+ return *this;
1047
+ }
1048
+
1049
+ friend It operator+(const It &a, difference_type n) {
1050
+ auto copy = a;
1051
+ return copy += n;
1052
+ }
1053
+ friend It operator+(difference_type n, const It &b) { return b + n; }
1054
+ friend It operator-(const It &a, difference_type n) {
1055
+ auto copy = a;
1056
+ return copy -= n;
1057
+ }
1058
+ friend difference_type operator-(const It &a, const It &b) { return a.distance_to(b); }
1059
+
1060
+ friend bool operator==(const It &a, const It &b) { return a.equal(b); }
1061
+ friend bool operator!=(const It &a, const It &b) { return !(a == b); }
1062
+ friend bool operator<(const It &a, const It &b) { return b - a > 0; }
1063
+ friend bool operator>(const It &a, const It &b) { return b < a; }
1064
+ friend bool operator>=(const It &a, const It &b) { return !(a < b); }
1065
+ friend bool operator<=(const It &a, const It &b) { return !(a > b); }
1066
+ };
1067
+
1068
+ PYBIND11_NAMESPACE_BEGIN(iterator_policies)
1069
+ /// Quick proxy class needed to implement ``operator->`` for iterators which can't return pointers
1070
+ template <typename T>
1071
+ struct arrow_proxy {
1072
+ T value;
1073
+
1074
+ // NOLINTNEXTLINE(google-explicit-constructor)
1075
+ arrow_proxy(T &&value) noexcept : value(std::move(value)) {}
1076
+ T *operator->() const { return &value; }
1077
+ };
1078
+
1079
+ /// Lightweight iterator policy using just a simple pointer: see ``PySequence_Fast_ITEMS``
1080
+ class sequence_fast_readonly {
1081
+ protected:
1082
+ using iterator_category = std::random_access_iterator_tag;
1083
+ using value_type = handle;
1084
+ using reference = const handle; // PR #3263
1085
+ using pointer = arrow_proxy<const handle>;
1086
+
1087
+ sequence_fast_readonly(handle obj, ssize_t n) : ptr(PySequence_Fast_ITEMS(obj.ptr()) + n) {}
1088
+
1089
+ // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
1090
+ reference dereference() const { return *ptr; }
1091
+ void increment() { ++ptr; }
1092
+ void decrement() { --ptr; }
1093
+ void advance(ssize_t n) { ptr += n; }
1094
+ bool equal(const sequence_fast_readonly &b) const { return ptr == b.ptr; }
1095
+ ssize_t distance_to(const sequence_fast_readonly &b) const { return ptr - b.ptr; }
1096
+
1097
+ private:
1098
+ PyObject **ptr;
1099
+ };
1100
+
1101
+ /// Full read and write access using the sequence protocol: see ``detail::sequence_accessor``
1102
+ class sequence_slow_readwrite {
1103
+ protected:
1104
+ using iterator_category = std::random_access_iterator_tag;
1105
+ using value_type = object;
1106
+ using reference = sequence_accessor;
1107
+ using pointer = arrow_proxy<const sequence_accessor>;
1108
+
1109
+ sequence_slow_readwrite(handle obj, ssize_t index) : obj(obj), index(index) {}
1110
+
1111
+ reference dereference() const { return {obj, static_cast<size_t>(index)}; }
1112
+ void increment() { ++index; }
1113
+ void decrement() { --index; }
1114
+ void advance(ssize_t n) { index += n; }
1115
+ bool equal(const sequence_slow_readwrite &b) const { return index == b.index; }
1116
+ ssize_t distance_to(const sequence_slow_readwrite &b) const { return index - b.index; }
1117
+
1118
+ private:
1119
+ handle obj;
1120
+ ssize_t index;
1121
+ };
1122
+
1123
+ /// Python's dictionary protocol permits this to be a forward iterator
1124
+ class dict_readonly {
1125
+ protected:
1126
+ using iterator_category = std::forward_iterator_tag;
1127
+ using value_type = std::pair<handle, handle>;
1128
+ using reference = const value_type; // PR #3263
1129
+ using pointer = arrow_proxy<const value_type>;
1130
+
1131
+ dict_readonly() = default;
1132
+ dict_readonly(handle obj, ssize_t pos) : obj(obj), pos(pos) { increment(); }
1133
+
1134
+ // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
1135
+ reference dereference() const { return {key, value}; }
1136
+ void increment() {
1137
+ if (PyDict_Next(obj.ptr(), &pos, &key, &value) == 0) {
1138
+ pos = -1;
1139
+ }
1140
+ }
1141
+ bool equal(const dict_readonly &b) const { return pos == b.pos; }
1142
+
1143
+ private:
1144
+ handle obj;
1145
+ PyObject *key = nullptr, *value = nullptr;
1146
+ ssize_t pos = -1;
1147
+ };
1148
+ PYBIND11_NAMESPACE_END(iterator_policies)
1149
+
1150
+ #if !defined(PYPY_VERSION)
1151
+ using tuple_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;
1152
+ using list_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;
1153
+ #else
1154
+ using tuple_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;
1155
+ using list_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;
1156
+ #endif
1157
+
1158
+ using sequence_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;
1159
+ using dict_iterator = generic_iterator<iterator_policies::dict_readonly>;
1160
+
1161
+ inline bool PyIterable_Check(PyObject *obj) {
1162
+ PyObject *iter = PyObject_GetIter(obj);
1163
+ if (iter) {
1164
+ Py_DECREF(iter);
1165
+ return true;
1166
+ }
1167
+ PyErr_Clear();
1168
+ return false;
1169
+ }
1170
+
1171
+ inline bool PyNone_Check(PyObject *o) { return o == Py_None; }
1172
+ inline bool PyEllipsis_Check(PyObject *o) { return o == Py_Ellipsis; }
1173
+
1174
+ #ifdef PYBIND11_STR_LEGACY_PERMISSIVE
1175
+ inline bool PyUnicode_Check_Permissive(PyObject *o) {
1176
+ return PyUnicode_Check(o) || PYBIND11_BYTES_CHECK(o);
1177
+ }
1178
+ # define PYBIND11_STR_CHECK_FUN detail::PyUnicode_Check_Permissive
1179
+ #else
1180
+ # define PYBIND11_STR_CHECK_FUN PyUnicode_Check
1181
+ #endif
1182
+
1183
+ inline bool PyStaticMethod_Check(PyObject *o) { return o->ob_type == &PyStaticMethod_Type; }
1184
+
1185
+ class kwargs_proxy : public handle {
1186
+ public:
1187
+ explicit kwargs_proxy(handle h) : handle(h) {}
1188
+ };
1189
+
1190
+ class args_proxy : public handle {
1191
+ public:
1192
+ explicit args_proxy(handle h) : handle(h) {}
1193
+ kwargs_proxy operator*() const { return kwargs_proxy(*this); }
1194
+ };
1195
+
1196
+ /// Python argument categories (using PEP 448 terms)
1197
+ template <typename T>
1198
+ using is_keyword = std::is_base_of<arg, T>;
1199
+ template <typename T>
1200
+ using is_s_unpacking = std::is_same<args_proxy, T>; // * unpacking
1201
+ template <typename T>
1202
+ using is_ds_unpacking = std::is_same<kwargs_proxy, T>; // ** unpacking
1203
+ template <typename T>
1204
+ using is_positional = satisfies_none_of<T, is_keyword, is_s_unpacking, is_ds_unpacking>;
1205
+ template <typename T>
1206
+ using is_keyword_or_ds = satisfies_any_of<T, is_keyword, is_ds_unpacking>;
1207
+
1208
+ // Call argument collector forward declarations
1209
+ template <return_value_policy policy = return_value_policy::automatic_reference>
1210
+ class simple_collector;
1211
+ template <return_value_policy policy = return_value_policy::automatic_reference>
1212
+ class unpacking_collector;
1213
+
1214
+ PYBIND11_NAMESPACE_END(detail)
1215
+
1216
+ // TODO: After the deprecated constructors are removed, this macro can be simplified by
1217
+ // inheriting ctors: `using Parent::Parent`. It's not an option right now because
1218
+ // the `using` statement triggers the parent deprecation warning even if the ctor
1219
+ // isn't even used.
1220
+ #define PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \
1221
+ public: \
1222
+ PYBIND11_DEPRECATED("Use reinterpret_borrow<" #Name ">() or reinterpret_steal<" #Name ">()") \
1223
+ Name(handle h, bool is_borrowed) \
1224
+ : Parent(is_borrowed ? Parent(h, borrowed_t{}) : Parent(h, stolen_t{})) {} \
1225
+ Name(handle h, borrowed_t) : Parent(h, borrowed_t{}) {} \
1226
+ Name(handle h, stolen_t) : Parent(h, stolen_t{}) {} \
1227
+ PYBIND11_DEPRECATED("Use py::isinstance<py::python_type>(obj) instead") \
1228
+ bool check() const { return m_ptr != nullptr && (CheckFun(m_ptr) != 0); } \
1229
+ static bool check_(handle h) { return h.ptr() != nullptr && CheckFun(h.ptr()); } \
1230
+ template <typename Policy_> /* NOLINTNEXTLINE(google-explicit-constructor) */ \
1231
+ Name(const ::pybind11::detail::accessor<Policy_> &a) : Name(object(a)) {}
1232
+
1233
+ #define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun) \
1234
+ PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \
1235
+ /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \
1236
+ /* NOLINTNEXTLINE(google-explicit-constructor) */ \
1237
+ Name(const object &o) \
1238
+ : Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \
1239
+ if (!m_ptr) \
1240
+ throw ::pybind11::error_already_set(); \
1241
+ } \
1242
+ /* NOLINTNEXTLINE(google-explicit-constructor) */ \
1243
+ Name(object &&o) : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) { \
1244
+ if (!m_ptr) \
1245
+ throw ::pybind11::error_already_set(); \
1246
+ }
1247
+
1248
+ #define PYBIND11_OBJECT_CVT_DEFAULT(Name, Parent, CheckFun, ConvertFun) \
1249
+ PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun) \
1250
+ Name() : Parent() {}
1251
+
1252
+ #define PYBIND11_OBJECT_CHECK_FAILED(Name, o_ptr) \
1253
+ ::pybind11::type_error("Object of type '" \
1254
+ + ::pybind11::detail::get_fully_qualified_tp_name(Py_TYPE(o_ptr)) \
1255
+ + "' is not an instance of '" #Name "'")
1256
+
1257
+ #define PYBIND11_OBJECT(Name, Parent, CheckFun) \
1258
+ PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun) \
1259
+ /* This is deliberately not 'explicit' to allow implicit conversion from object: */ \
1260
+ /* NOLINTNEXTLINE(google-explicit-constructor) */ \
1261
+ Name(const object &o) : Parent(o) { \
1262
+ if (m_ptr && !check_(m_ptr)) \
1263
+ throw PYBIND11_OBJECT_CHECK_FAILED(Name, m_ptr); \
1264
+ } \
1265
+ /* NOLINTNEXTLINE(google-explicit-constructor) */ \
1266
+ Name(object &&o) : Parent(std::move(o)) { \
1267
+ if (m_ptr && !check_(m_ptr)) \
1268
+ throw PYBIND11_OBJECT_CHECK_FAILED(Name, m_ptr); \
1269
+ }
1270
+
1271
+ #define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun) \
1272
+ PYBIND11_OBJECT(Name, Parent, CheckFun) \
1273
+ Name() : Parent() {}
1274
+
1275
+ /// \addtogroup pytypes
1276
+ /// @{
1277
+
1278
+ /** \rst
1279
+ Wraps a Python iterator so that it can also be used as a C++ input iterator
1280
+
1281
+ Caveat: copying an iterator does not (and cannot) clone the internal
1282
+ state of the Python iterable. This also applies to the post-increment
1283
+ operator. This iterator should only be used to retrieve the current
1284
+ value using ``operator*()``.
1285
+ \endrst */
1286
+ class iterator : public object {
1287
+ public:
1288
+ using iterator_category = std::input_iterator_tag;
1289
+ using difference_type = ssize_t;
1290
+ using value_type = handle;
1291
+ using reference = const handle; // PR #3263
1292
+ using pointer = const handle *;
1293
+
1294
+ PYBIND11_OBJECT_DEFAULT(iterator, object, PyIter_Check)
1295
+
1296
+ iterator &operator++() {
1297
+ advance();
1298
+ return *this;
1299
+ }
1300
+
1301
+ iterator operator++(int) {
1302
+ auto rv = *this;
1303
+ advance();
1304
+ return rv;
1305
+ }
1306
+
1307
+ // NOLINTNEXTLINE(readability-const-return-type) // PR #3263
1308
+ reference operator*() const {
1309
+ if (m_ptr && !value.ptr()) {
1310
+ auto &self = const_cast<iterator &>(*this);
1311
+ self.advance();
1312
+ }
1313
+ return value;
1314
+ }
1315
+
1316
+ pointer operator->() const {
1317
+ operator*();
1318
+ return &value;
1319
+ }
1320
+
1321
+ /** \rst
1322
+ The value which marks the end of the iteration. ``it == iterator::sentinel()``
1323
+ is equivalent to catching ``StopIteration`` in Python.
1324
+
1325
+ .. code-block:: cpp
1326
+
1327
+ void foo(py::iterator it) {
1328
+ while (it != py::iterator::sentinel()) {
1329
+ // use `*it`
1330
+ ++it;
1331
+ }
1332
+ }
1333
+ \endrst */
1334
+ static iterator sentinel() { return {}; }
1335
+
1336
+ friend bool operator==(const iterator &a, const iterator &b) { return a->ptr() == b->ptr(); }
1337
+ friend bool operator!=(const iterator &a, const iterator &b) { return a->ptr() != b->ptr(); }
1338
+
1339
+ private:
1340
+ void advance() {
1341
+ value = reinterpret_steal<object>(PyIter_Next(m_ptr));
1342
+ if (PyErr_Occurred()) {
1343
+ throw error_already_set();
1344
+ }
1345
+ }
1346
+
1347
+ private:
1348
+ object value = {};
1349
+ };
1350
+
1351
+ class type : public object {
1352
+ public:
1353
+ PYBIND11_OBJECT(type, object, PyType_Check)
1354
+
1355
+ /// Return a type handle from a handle or an object
1356
+ static handle handle_of(handle h) { return handle((PyObject *) Py_TYPE(h.ptr())); }
1357
+
1358
+ /// Return a type object from a handle or an object
1359
+ static type of(handle h) { return type(type::handle_of(h), borrowed_t{}); }
1360
+
1361
+ // Defined in pybind11/cast.h
1362
+ /// Convert C++ type to handle if previously registered. Does not convert
1363
+ /// standard types, like int, float. etc. yet.
1364
+ /// See https://github.com/pybind/pybind11/issues/2486
1365
+ template <typename T>
1366
+ static handle handle_of();
1367
+
1368
+ /// Convert C++ type to type if previously registered. Does not convert
1369
+ /// standard types, like int, float. etc. yet.
1370
+ /// See https://github.com/pybind/pybind11/issues/2486
1371
+ template <typename T>
1372
+ static type of() {
1373
+ return type(type::handle_of<T>(), borrowed_t{});
1374
+ }
1375
+ };
1376
+
1377
+ class iterable : public object {
1378
+ public:
1379
+ PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check)
1380
+ };
1381
+
1382
+ class bytes;
1383
+
1384
+ class str : public object {
1385
+ public:
1386
+ PYBIND11_OBJECT_CVT(str, object, PYBIND11_STR_CHECK_FUN, raw_str)
1387
+
1388
+ template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>
1389
+ str(const char *c, const SzType &n)
1390
+ : object(PyUnicode_FromStringAndSize(c, ssize_t_cast(n)), stolen_t{}) {
1391
+ if (!m_ptr) {
1392
+ pybind11_fail("Could not allocate string object!");
1393
+ }
1394
+ }
1395
+
1396
+ // 'explicit' is explicitly omitted from the following constructors to allow implicit
1397
+ // conversion to py::str from C++ string-like objects
1398
+ // NOLINTNEXTLINE(google-explicit-constructor)
1399
+ str(const char *c = "") : object(PyUnicode_FromString(c), stolen_t{}) {
1400
+ if (!m_ptr) {
1401
+ pybind11_fail("Could not allocate string object!");
1402
+ }
1403
+ }
1404
+
1405
+ // NOLINTNEXTLINE(google-explicit-constructor)
1406
+ str(const std::string &s) : str(s.data(), s.size()) {}
1407
+
1408
+ #ifdef PYBIND11_HAS_STRING_VIEW
1409
+ // enable_if is needed to avoid "ambiguous conversion" errors (see PR #3521).
1410
+ template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0>
1411
+ // NOLINTNEXTLINE(google-explicit-constructor)
1412
+ str(T s) : str(s.data(), s.size()) {}
1413
+
1414
+ # ifdef PYBIND11_HAS_U8STRING
1415
+ // reinterpret_cast here is safe (C++20 guarantees char8_t has the same size/alignment as char)
1416
+ // NOLINTNEXTLINE(google-explicit-constructor)
1417
+ str(std::u8string_view s) : str(reinterpret_cast<const char *>(s.data()), s.size()) {}
1418
+ # endif
1419
+
1420
+ #endif
1421
+
1422
+ explicit str(const bytes &b);
1423
+
1424
+ /** \rst
1425
+ Return a string representation of the object. This is analogous to
1426
+ the ``str()`` function in Python.
1427
+ \endrst */
1428
+ explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) {
1429
+ if (!m_ptr) {
1430
+ throw error_already_set();
1431
+ }
1432
+ }
1433
+
1434
+ // NOLINTNEXTLINE(google-explicit-constructor)
1435
+ operator std::string() const {
1436
+ object temp = *this;
1437
+ if (PyUnicode_Check(m_ptr)) {
1438
+ temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(m_ptr));
1439
+ if (!temp) {
1440
+ throw error_already_set();
1441
+ }
1442
+ }
1443
+ char *buffer = nullptr;
1444
+ ssize_t length = 0;
1445
+ if (PyBytes_AsStringAndSize(temp.ptr(), &buffer, &length) != 0) {
1446
+ throw error_already_set();
1447
+ }
1448
+ return std::string(buffer, (size_t) length);
1449
+ }
1450
+
1451
+ template <typename... Args>
1452
+ str format(Args &&...args) const {
1453
+ return attr("format")(std::forward<Args>(args)...);
1454
+ }
1455
+
1456
+ private:
1457
+ /// Return string representation -- always returns a new reference, even if already a str
1458
+ static PyObject *raw_str(PyObject *op) {
1459
+ PyObject *str_value = PyObject_Str(op);
1460
+ return str_value;
1461
+ }
1462
+ };
1463
+ /// @} pytypes
1464
+
1465
+ inline namespace literals {
1466
+ /** \rst
1467
+ String literal version of `str`
1468
+ \endrst */
1469
+ inline str operator"" _s(const char *s, size_t size) { return {s, size}; }
1470
+ } // namespace literals
1471
+
1472
+ /// \addtogroup pytypes
1473
+ /// @{
1474
+ class bytes : public object {
1475
+ public:
1476
+ PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK)
1477
+
1478
+ // Allow implicit conversion:
1479
+ // NOLINTNEXTLINE(google-explicit-constructor)
1480
+ bytes(const char *c = "") : object(PYBIND11_BYTES_FROM_STRING(c), stolen_t{}) {
1481
+ if (!m_ptr) {
1482
+ pybind11_fail("Could not allocate bytes object!");
1483
+ }
1484
+ }
1485
+
1486
+ template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>
1487
+ bytes(const char *c, const SzType &n)
1488
+ : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(c, ssize_t_cast(n)), stolen_t{}) {
1489
+ if (!m_ptr) {
1490
+ pybind11_fail("Could not allocate bytes object!");
1491
+ }
1492
+ }
1493
+
1494
+ // Allow implicit conversion:
1495
+ // NOLINTNEXTLINE(google-explicit-constructor)
1496
+ bytes(const std::string &s) : bytes(s.data(), s.size()) {}
1497
+
1498
+ explicit bytes(const pybind11::str &s);
1499
+
1500
+ // NOLINTNEXTLINE(google-explicit-constructor)
1501
+ operator std::string() const { return string_op<std::string>(); }
1502
+
1503
+ #ifdef PYBIND11_HAS_STRING_VIEW
1504
+ // enable_if is needed to avoid "ambiguous conversion" errors (see PR #3521).
1505
+ template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0>
1506
+ // NOLINTNEXTLINE(google-explicit-constructor)
1507
+ bytes(T s) : bytes(s.data(), s.size()) {}
1508
+
1509
+ // Obtain a string view that views the current `bytes` buffer value. Note that this is only
1510
+ // valid so long as the `bytes` instance remains alive and so generally should not outlive the
1511
+ // lifetime of the `bytes` instance.
1512
+ // NOLINTNEXTLINE(google-explicit-constructor)
1513
+ operator std::string_view() const { return string_op<std::string_view>(); }
1514
+ #endif
1515
+ private:
1516
+ template <typename T>
1517
+ T string_op() const {
1518
+ char *buffer = nullptr;
1519
+ ssize_t length = 0;
1520
+ if (PyBytes_AsStringAndSize(m_ptr, &buffer, &length) != 0) {
1521
+ throw error_already_set();
1522
+ }
1523
+ return {buffer, static_cast<size_t>(length)};
1524
+ }
1525
+ };
1526
+ // Note: breathe >= 4.17.0 will fail to build docs if the below two constructors
1527
+ // are included in the doxygen group; close here and reopen after as a workaround
1528
+ /// @} pytypes
1529
+
1530
+ inline bytes::bytes(const pybind11::str &s) {
1531
+ object temp = s;
1532
+ if (PyUnicode_Check(s.ptr())) {
1533
+ temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(s.ptr()));
1534
+ if (!temp) {
1535
+ throw error_already_set();
1536
+ }
1537
+ }
1538
+ char *buffer = nullptr;
1539
+ ssize_t length = 0;
1540
+ if (PyBytes_AsStringAndSize(temp.ptr(), &buffer, &length) != 0) {
1541
+ throw error_already_set();
1542
+ }
1543
+ auto obj = reinterpret_steal<object>(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length));
1544
+ if (!obj) {
1545
+ pybind11_fail("Could not allocate bytes object!");
1546
+ }
1547
+ m_ptr = obj.release().ptr();
1548
+ }
1549
+
1550
+ inline str::str(const bytes &b) {
1551
+ char *buffer = nullptr;
1552
+ ssize_t length = 0;
1553
+ if (PyBytes_AsStringAndSize(b.ptr(), &buffer, &length) != 0) {
1554
+ throw error_already_set();
1555
+ }
1556
+ auto obj = reinterpret_steal<object>(PyUnicode_FromStringAndSize(buffer, length));
1557
+ if (!obj) {
1558
+ pybind11_fail("Could not allocate string object!");
1559
+ }
1560
+ m_ptr = obj.release().ptr();
1561
+ }
1562
+
1563
+ /// \addtogroup pytypes
1564
+ /// @{
1565
+ class bytearray : public object {
1566
+ public:
1567
+ PYBIND11_OBJECT_CVT(bytearray, object, PyByteArray_Check, PyByteArray_FromObject)
1568
+
1569
+ template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>
1570
+ bytearray(const char *c, const SzType &n)
1571
+ : object(PyByteArray_FromStringAndSize(c, ssize_t_cast(n)), stolen_t{}) {
1572
+ if (!m_ptr) {
1573
+ pybind11_fail("Could not allocate bytearray object!");
1574
+ }
1575
+ }
1576
+
1577
+ bytearray() : bytearray("", 0) {}
1578
+
1579
+ explicit bytearray(const std::string &s) : bytearray(s.data(), s.size()) {}
1580
+
1581
+ size_t size() const { return static_cast<size_t>(PyByteArray_Size(m_ptr)); }
1582
+
1583
+ explicit operator std::string() const {
1584
+ char *buffer = PyByteArray_AS_STRING(m_ptr);
1585
+ ssize_t size = PyByteArray_GET_SIZE(m_ptr);
1586
+ return std::string(buffer, static_cast<size_t>(size));
1587
+ }
1588
+ };
1589
+ // Note: breathe >= 4.17.0 will fail to build docs if the below two constructors
1590
+ // are included in the doxygen group; close here and reopen after as a workaround
1591
+ /// @} pytypes
1592
+
1593
+ /// \addtogroup pytypes
1594
+ /// @{
1595
+ class none : public object {
1596
+ public:
1597
+ PYBIND11_OBJECT(none, object, detail::PyNone_Check)
1598
+ none() : object(Py_None, borrowed_t{}) {}
1599
+ };
1600
+
1601
+ class ellipsis : public object {
1602
+ public:
1603
+ PYBIND11_OBJECT(ellipsis, object, detail::PyEllipsis_Check)
1604
+ ellipsis() : object(Py_Ellipsis, borrowed_t{}) {}
1605
+ };
1606
+
1607
+ class bool_ : public object {
1608
+ public:
1609
+ PYBIND11_OBJECT_CVT(bool_, object, PyBool_Check, raw_bool)
1610
+ bool_() : object(Py_False, borrowed_t{}) {}
1611
+ // Allow implicit conversion from and to `bool`:
1612
+ // NOLINTNEXTLINE(google-explicit-constructor)
1613
+ bool_(bool value) : object(value ? Py_True : Py_False, borrowed_t{}) {}
1614
+ // NOLINTNEXTLINE(google-explicit-constructor)
1615
+ operator bool() const { return (m_ptr != nullptr) && PyLong_AsLong(m_ptr) != 0; }
1616
+
1617
+ private:
1618
+ /// Return the truth value of an object -- always returns a new reference
1619
+ static PyObject *raw_bool(PyObject *op) {
1620
+ const auto value = PyObject_IsTrue(op);
1621
+ if (value == -1) {
1622
+ return nullptr;
1623
+ }
1624
+ return handle(value != 0 ? Py_True : Py_False).inc_ref().ptr();
1625
+ }
1626
+ };
1627
+
1628
+ PYBIND11_NAMESPACE_BEGIN(detail)
1629
+ // Converts a value to the given unsigned type. If an error occurs, you get back (Unsigned) -1;
1630
+ // otherwise you get back the unsigned long or unsigned long long value cast to (Unsigned).
1631
+ // (The distinction is critically important when casting a returned -1 error value to some other
1632
+ // unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes).
1633
+ template <typename Unsigned>
1634
+ Unsigned as_unsigned(PyObject *o) {
1635
+ if (PYBIND11_SILENCE_MSVC_C4127(sizeof(Unsigned) <= sizeof(unsigned long))) {
1636
+ unsigned long v = PyLong_AsUnsignedLong(o);
1637
+ return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
1638
+ }
1639
+ unsigned long long v = PyLong_AsUnsignedLongLong(o);
1640
+ return v == (unsigned long long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
1641
+ }
1642
+ PYBIND11_NAMESPACE_END(detail)
1643
+
1644
+ class int_ : public object {
1645
+ public:
1646
+ PYBIND11_OBJECT_CVT(int_, object, PYBIND11_LONG_CHECK, PyNumber_Long)
1647
+ int_() : object(PyLong_FromLong(0), stolen_t{}) {}
1648
+ // Allow implicit conversion from C++ integral types:
1649
+ template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
1650
+ // NOLINTNEXTLINE(google-explicit-constructor)
1651
+ int_(T value) {
1652
+ if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) {
1653
+ if (std::is_signed<T>::value) {
1654
+ m_ptr = PyLong_FromLong((long) value);
1655
+ } else {
1656
+ m_ptr = PyLong_FromUnsignedLong((unsigned long) value);
1657
+ }
1658
+ } else {
1659
+ if (std::is_signed<T>::value) {
1660
+ m_ptr = PyLong_FromLongLong((long long) value);
1661
+ } else {
1662
+ m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value);
1663
+ }
1664
+ }
1665
+ if (!m_ptr) {
1666
+ pybind11_fail("Could not allocate int object!");
1667
+ }
1668
+ }
1669
+
1670
+ template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>
1671
+ // NOLINTNEXTLINE(google-explicit-constructor)
1672
+ operator T() const {
1673
+ return std::is_unsigned<T>::value ? detail::as_unsigned<T>(m_ptr)
1674
+ : sizeof(T) <= sizeof(long) ? (T) PyLong_AsLong(m_ptr)
1675
+ : (T) PYBIND11_LONG_AS_LONGLONG(m_ptr);
1676
+ }
1677
+ };
1678
+
1679
+ class float_ : public object {
1680
+ public:
1681
+ PYBIND11_OBJECT_CVT(float_, object, PyFloat_Check, PyNumber_Float)
1682
+ // Allow implicit conversion from float/double:
1683
+ // NOLINTNEXTLINE(google-explicit-constructor)
1684
+ float_(float value) : object(PyFloat_FromDouble((double) value), stolen_t{}) {
1685
+ if (!m_ptr) {
1686
+ pybind11_fail("Could not allocate float object!");
1687
+ }
1688
+ }
1689
+ // NOLINTNEXTLINE(google-explicit-constructor)
1690
+ float_(double value = .0) : object(PyFloat_FromDouble((double) value), stolen_t{}) {
1691
+ if (!m_ptr) {
1692
+ pybind11_fail("Could not allocate float object!");
1693
+ }
1694
+ }
1695
+ // NOLINTNEXTLINE(google-explicit-constructor)
1696
+ operator float() const { return (float) PyFloat_AsDouble(m_ptr); }
1697
+ // NOLINTNEXTLINE(google-explicit-constructor)
1698
+ operator double() const { return (double) PyFloat_AsDouble(m_ptr); }
1699
+ };
1700
+
1701
+ class weakref : public object {
1702
+ public:
1703
+ PYBIND11_OBJECT_CVT_DEFAULT(weakref, object, PyWeakref_Check, raw_weakref)
1704
+ explicit weakref(handle obj, handle callback = {})
1705
+ : object(PyWeakref_NewRef(obj.ptr(), callback.ptr()), stolen_t{}) {
1706
+ if (!m_ptr) {
1707
+ if (PyErr_Occurred()) {
1708
+ throw error_already_set();
1709
+ }
1710
+ pybind11_fail("Could not allocate weak reference!");
1711
+ }
1712
+ }
1713
+
1714
+ private:
1715
+ static PyObject *raw_weakref(PyObject *o) { return PyWeakref_NewRef(o, nullptr); }
1716
+ };
1717
+
1718
+ class slice : public object {
1719
+ public:
1720
+ PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check)
1721
+ slice(handle start, handle stop, handle step)
1722
+ : object(PySlice_New(start.ptr(), stop.ptr(), step.ptr()), stolen_t{}) {
1723
+ if (!m_ptr) {
1724
+ pybind11_fail("Could not allocate slice object!");
1725
+ }
1726
+ }
1727
+
1728
+ #ifdef PYBIND11_HAS_OPTIONAL
1729
+ slice(std::optional<ssize_t> start, std::optional<ssize_t> stop, std::optional<ssize_t> step)
1730
+ : slice(index_to_object(start), index_to_object(stop), index_to_object(step)) {}
1731
+ #else
1732
+ slice(ssize_t start_, ssize_t stop_, ssize_t step_)
1733
+ : slice(int_(start_), int_(stop_), int_(step_)) {}
1734
+ #endif
1735
+
1736
+ bool
1737
+ compute(size_t length, size_t *start, size_t *stop, size_t *step, size_t *slicelength) const {
1738
+ return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr,
1739
+ (ssize_t) length,
1740
+ (ssize_t *) start,
1741
+ (ssize_t *) stop,
1742
+ (ssize_t *) step,
1743
+ (ssize_t *) slicelength)
1744
+ == 0;
1745
+ }
1746
+ bool compute(
1747
+ ssize_t length, ssize_t *start, ssize_t *stop, ssize_t *step, ssize_t *slicelength) const {
1748
+ return PySlice_GetIndicesEx(
1749
+ (PYBIND11_SLICE_OBJECT *) m_ptr, length, start, stop, step, slicelength)
1750
+ == 0;
1751
+ }
1752
+
1753
+ private:
1754
+ template <typename T>
1755
+ static object index_to_object(T index) {
1756
+ return index ? object(int_(*index)) : object(none());
1757
+ }
1758
+ };
1759
+
1760
+ class capsule : public object {
1761
+ public:
1762
+ PYBIND11_OBJECT_DEFAULT(capsule, object, PyCapsule_CheckExact)
1763
+ PYBIND11_DEPRECATED("Use reinterpret_borrow<capsule>() or reinterpret_steal<capsule>()")
1764
+ capsule(PyObject *ptr, bool is_borrowed)
1765
+ : object(is_borrowed ? object(ptr, borrowed_t{}) : object(ptr, stolen_t{})) {}
1766
+
1767
+ explicit capsule(const void *value,
1768
+ const char *name = nullptr,
1769
+ void (*destructor)(PyObject *) = nullptr)
1770
+ : object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {
1771
+ if (!m_ptr) {
1772
+ throw error_already_set();
1773
+ }
1774
+ }
1775
+
1776
+ PYBIND11_DEPRECATED("Please pass a destructor that takes a void pointer as input")
1777
+ capsule(const void *value, void (*destruct)(PyObject *))
1778
+ : object(PyCapsule_New(const_cast<void *>(value), nullptr, destruct), stolen_t{}) {
1779
+ if (!m_ptr) {
1780
+ throw error_already_set();
1781
+ }
1782
+ }
1783
+
1784
+ capsule(const void *value, void (*destructor)(void *)) {
1785
+ m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {
1786
+ // guard if destructor called while err indicator is set
1787
+ error_scope error_guard;
1788
+ auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));
1789
+ if (destructor == nullptr) {
1790
+ if (PyErr_Occurred()) {
1791
+ throw error_already_set();
1792
+ }
1793
+ pybind11_fail("Unable to get capsule context");
1794
+ }
1795
+ const char *name = get_name_in_error_scope(o);
1796
+ void *ptr = PyCapsule_GetPointer(o, name);
1797
+ if (ptr == nullptr) {
1798
+ throw error_already_set();
1799
+ }
1800
+ destructor(ptr);
1801
+ });
1802
+
1803
+ if (!m_ptr || PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) {
1804
+ throw error_already_set();
1805
+ }
1806
+ }
1807
+
1808
+ explicit capsule(void (*destructor)()) {
1809
+ m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {
1810
+ const char *name = get_name_in_error_scope(o);
1811
+ auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, name));
1812
+ if (destructor == nullptr) {
1813
+ throw error_already_set();
1814
+ }
1815
+ destructor();
1816
+ });
1817
+
1818
+ if (!m_ptr) {
1819
+ throw error_already_set();
1820
+ }
1821
+ }
1822
+
1823
+ template <typename T>
1824
+ operator T *() const { // NOLINT(google-explicit-constructor)
1825
+ return get_pointer<T>();
1826
+ }
1827
+
1828
+ /// Get the pointer the capsule holds.
1829
+ template <typename T = void>
1830
+ T *get_pointer() const {
1831
+ const auto *name = this->name();
1832
+ T *result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));
1833
+ if (!result) {
1834
+ throw error_already_set();
1835
+ }
1836
+ return result;
1837
+ }
1838
+
1839
+ /// Replaces a capsule's pointer *without* calling the destructor on the existing one.
1840
+ void set_pointer(const void *value) {
1841
+ if (PyCapsule_SetPointer(m_ptr, const_cast<void *>(value)) != 0) {
1842
+ throw error_already_set();
1843
+ }
1844
+ }
1845
+
1846
+ const char *name() const {
1847
+ const char *name = PyCapsule_GetName(m_ptr);
1848
+ if ((name == nullptr) && PyErr_Occurred()) {
1849
+ throw error_already_set();
1850
+ }
1851
+ return name;
1852
+ }
1853
+
1854
+ /// Replaces a capsule's name *without* calling the destructor on the existing one.
1855
+ void set_name(const char *new_name) {
1856
+ if (PyCapsule_SetName(m_ptr, new_name) != 0) {
1857
+ throw error_already_set();
1858
+ }
1859
+ }
1860
+
1861
+ private:
1862
+ static const char *get_name_in_error_scope(PyObject *o) {
1863
+ error_scope error_guard;
1864
+
1865
+ const char *name = PyCapsule_GetName(o);
1866
+ if ((name == nullptr) && PyErr_Occurred()) {
1867
+ // write out and consume error raised by call to PyCapsule_GetName
1868
+ PyErr_WriteUnraisable(o);
1869
+ }
1870
+
1871
+ return name;
1872
+ }
1873
+ };
1874
+
1875
+ class tuple : public object {
1876
+ public:
1877
+ PYBIND11_OBJECT_CVT(tuple, object, PyTuple_Check, PySequence_Tuple)
1878
+ template <typename SzType = ssize_t,
1879
+ detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>
1880
+ // Some compilers generate link errors when using `const SzType &` here:
1881
+ explicit tuple(SzType size = 0) : object(PyTuple_New(ssize_t_cast(size)), stolen_t{}) {
1882
+ if (!m_ptr) {
1883
+ pybind11_fail("Could not allocate tuple object!");
1884
+ }
1885
+ }
1886
+ size_t size() const { return (size_t) PyTuple_Size(m_ptr); }
1887
+ bool empty() const { return size() == 0; }
1888
+ detail::tuple_accessor operator[](size_t index) const { return {*this, index}; }
1889
+ template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
1890
+ detail::item_accessor operator[](T &&o) const {
1891
+ return object::operator[](std::forward<T>(o));
1892
+ }
1893
+ detail::tuple_iterator begin() const { return {*this, 0}; }
1894
+ detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; }
1895
+ };
1896
+
1897
+ // We need to put this into a separate function because the Intel compiler
1898
+ // fails to compile enable_if_t<all_of<is_keyword_or_ds<Args>...>::value> part below
1899
+ // (tested with ICC 2021.1 Beta 20200827).
1900
+ template <typename... Args>
1901
+ constexpr bool args_are_all_keyword_or_ds() {
1902
+ return detail::all_of<detail::is_keyword_or_ds<Args>...>::value;
1903
+ }
1904
+
1905
+ class dict : public object {
1906
+ public:
1907
+ PYBIND11_OBJECT_CVT(dict, object, PyDict_Check, raw_dict)
1908
+ dict() : object(PyDict_New(), stolen_t{}) {
1909
+ if (!m_ptr) {
1910
+ pybind11_fail("Could not allocate dict object!");
1911
+ }
1912
+ }
1913
+ template <typename... Args,
1914
+ typename = detail::enable_if_t<args_are_all_keyword_or_ds<Args...>()>,
1915
+ // MSVC workaround: it can't compile an out-of-line definition, so defer the
1916
+ // collector
1917
+ typename collector = detail::deferred_t<detail::unpacking_collector<>, Args...>>
1918
+ explicit dict(Args &&...args) : dict(collector(std::forward<Args>(args)...).kwargs()) {}
1919
+
1920
+ size_t size() const { return (size_t) PyDict_Size(m_ptr); }
1921
+ bool empty() const { return size() == 0; }
1922
+ detail::dict_iterator begin() const { return {*this, 0}; }
1923
+ detail::dict_iterator end() const { return {}; }
1924
+ void clear() /* py-non-const */ { PyDict_Clear(ptr()); }
1925
+ template <typename T>
1926
+ bool contains(T &&key) const {
1927
+ return PyDict_Contains(m_ptr, detail::object_or_cast(std::forward<T>(key)).ptr()) == 1;
1928
+ }
1929
+
1930
+ private:
1931
+ /// Call the `dict` Python type -- always returns a new reference
1932
+ static PyObject *raw_dict(PyObject *op) {
1933
+ if (PyDict_Check(op)) {
1934
+ return handle(op).inc_ref().ptr();
1935
+ }
1936
+ return PyObject_CallFunctionObjArgs((PyObject *) &PyDict_Type, op, nullptr);
1937
+ }
1938
+ };
1939
+
1940
+ class sequence : public object {
1941
+ public:
1942
+ PYBIND11_OBJECT_DEFAULT(sequence, object, PySequence_Check)
1943
+ size_t size() const {
1944
+ ssize_t result = PySequence_Size(m_ptr);
1945
+ if (result == -1) {
1946
+ throw error_already_set();
1947
+ }
1948
+ return (size_t) result;
1949
+ }
1950
+ bool empty() const { return size() == 0; }
1951
+ detail::sequence_accessor operator[](size_t index) const { return {*this, index}; }
1952
+ template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
1953
+ detail::item_accessor operator[](T &&o) const {
1954
+ return object::operator[](std::forward<T>(o));
1955
+ }
1956
+ detail::sequence_iterator begin() const { return {*this, 0}; }
1957
+ detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; }
1958
+ };
1959
+
1960
+ class list : public object {
1961
+ public:
1962
+ PYBIND11_OBJECT_CVT(list, object, PyList_Check, PySequence_List)
1963
+ template <typename SzType = ssize_t,
1964
+ detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>
1965
+ // Some compilers generate link errors when using `const SzType &` here:
1966
+ explicit list(SzType size = 0) : object(PyList_New(ssize_t_cast(size)), stolen_t{}) {
1967
+ if (!m_ptr) {
1968
+ pybind11_fail("Could not allocate list object!");
1969
+ }
1970
+ }
1971
+ size_t size() const { return (size_t) PyList_Size(m_ptr); }
1972
+ bool empty() const { return size() == 0; }
1973
+ detail::list_accessor operator[](size_t index) const { return {*this, index}; }
1974
+ template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
1975
+ detail::item_accessor operator[](T &&o) const {
1976
+ return object::operator[](std::forward<T>(o));
1977
+ }
1978
+ detail::list_iterator begin() const { return {*this, 0}; }
1979
+ detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; }
1980
+ template <typename T>
1981
+ void append(T &&val) /* py-non-const */ {
1982
+ PyList_Append(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr());
1983
+ }
1984
+ template <typename IdxType,
1985
+ typename ValType,
1986
+ detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
1987
+ void insert(const IdxType &index, ValType &&val) /* py-non-const */ {
1988
+ PyList_Insert(
1989
+ m_ptr, ssize_t_cast(index), detail::object_or_cast(std::forward<ValType>(val)).ptr());
1990
+ }
1991
+ };
1992
+
1993
+ class args : public tuple {
1994
+ PYBIND11_OBJECT_DEFAULT(args, tuple, PyTuple_Check)
1995
+ };
1996
+ class kwargs : public dict {
1997
+ PYBIND11_OBJECT_DEFAULT(kwargs, dict, PyDict_Check)
1998
+ };
1999
+
2000
+ class anyset : public object {
2001
+ public:
2002
+ PYBIND11_OBJECT(anyset, object, PyAnySet_Check)
2003
+ size_t size() const { return static_cast<size_t>(PySet_Size(m_ptr)); }
2004
+ bool empty() const { return size() == 0; }
2005
+ template <typename T>
2006
+ bool contains(T &&val) const {
2007
+ return PySet_Contains(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr()) == 1;
2008
+ }
2009
+ };
2010
+
2011
+ class set : public anyset {
2012
+ public:
2013
+ PYBIND11_OBJECT_CVT(set, anyset, PySet_Check, PySet_New)
2014
+ set() : anyset(PySet_New(nullptr), stolen_t{}) {
2015
+ if (!m_ptr) {
2016
+ pybind11_fail("Could not allocate set object!");
2017
+ }
2018
+ }
2019
+ template <typename T>
2020
+ bool add(T &&val) /* py-non-const */ {
2021
+ return PySet_Add(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr()) == 0;
2022
+ }
2023
+ void clear() /* py-non-const */ { PySet_Clear(m_ptr); }
2024
+ };
2025
+
2026
+ class frozenset : public anyset {
2027
+ public:
2028
+ PYBIND11_OBJECT_CVT(frozenset, anyset, PyFrozenSet_Check, PyFrozenSet_New)
2029
+ };
2030
+
2031
+ class function : public object {
2032
+ public:
2033
+ PYBIND11_OBJECT_DEFAULT(function, object, PyCallable_Check)
2034
+ handle cpp_function() const {
2035
+ handle fun = detail::get_function(m_ptr);
2036
+ if (fun && PyCFunction_Check(fun.ptr())) {
2037
+ return fun;
2038
+ }
2039
+ return handle();
2040
+ }
2041
+ bool is_cpp_function() const { return (bool) cpp_function(); }
2042
+ };
2043
+
2044
+ class staticmethod : public object {
2045
+ public:
2046
+ PYBIND11_OBJECT_CVT(staticmethod, object, detail::PyStaticMethod_Check, PyStaticMethod_New)
2047
+ };
2048
+
2049
+ class buffer : public object {
2050
+ public:
2051
+ PYBIND11_OBJECT_DEFAULT(buffer, object, PyObject_CheckBuffer)
2052
+
2053
+ buffer_info request(bool writable = false) const {
2054
+ int flags = PyBUF_STRIDES | PyBUF_FORMAT;
2055
+ if (writable) {
2056
+ flags |= PyBUF_WRITABLE;
2057
+ }
2058
+ auto *view = new Py_buffer();
2059
+ if (PyObject_GetBuffer(m_ptr, view, flags) != 0) {
2060
+ delete view;
2061
+ throw error_already_set();
2062
+ }
2063
+ return buffer_info(view);
2064
+ }
2065
+ };
2066
+
2067
+ class memoryview : public object {
2068
+ public:
2069
+ PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject)
2070
+
2071
+ /** \rst
2072
+ Creates ``memoryview`` from ``buffer_info``.
2073
+
2074
+ ``buffer_info`` must be created from ``buffer::request()``. Otherwise
2075
+ throws an exception.
2076
+
2077
+ For creating a ``memoryview`` from objects that support buffer protocol,
2078
+ use ``memoryview(const object& obj)`` instead of this constructor.
2079
+ \endrst */
2080
+ explicit memoryview(const buffer_info &info) {
2081
+ if (!info.view()) {
2082
+ pybind11_fail("Prohibited to create memoryview without Py_buffer");
2083
+ }
2084
+ // Note: PyMemoryView_FromBuffer never increments obj reference.
2085
+ m_ptr = (info.view()->obj) ? PyMemoryView_FromObject(info.view()->obj)
2086
+ : PyMemoryView_FromBuffer(info.view());
2087
+ if (!m_ptr) {
2088
+ pybind11_fail("Unable to create memoryview from buffer descriptor");
2089
+ }
2090
+ }
2091
+
2092
+ /** \rst
2093
+ Creates ``memoryview`` from static buffer.
2094
+
2095
+ This method is meant for providing a ``memoryview`` for C/C++ buffer not
2096
+ managed by Python. The caller is responsible for managing the lifetime
2097
+ of ``ptr`` and ``format``, which MUST outlive the memoryview constructed
2098
+ here.
2099
+
2100
+ See also: Python C API documentation for `PyMemoryView_FromBuffer`_.
2101
+
2102
+ .. _PyMemoryView_FromBuffer:
2103
+ https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromBuffer
2104
+
2105
+ :param ptr: Pointer to the buffer.
2106
+ :param itemsize: Byte size of an element.
2107
+ :param format: Pointer to the null-terminated format string. For
2108
+ homogeneous Buffers, this should be set to
2109
+ ``format_descriptor<T>::value``.
2110
+ :param shape: Shape of the tensor (1 entry per dimension).
2111
+ :param strides: Number of bytes between adjacent entries (for each
2112
+ per dimension).
2113
+ :param readonly: Flag to indicate if the underlying storage may be
2114
+ written to.
2115
+ \endrst */
2116
+ static memoryview from_buffer(void *ptr,
2117
+ ssize_t itemsize,
2118
+ const char *format,
2119
+ detail::any_container<ssize_t> shape,
2120
+ detail::any_container<ssize_t> strides,
2121
+ bool readonly = false);
2122
+
2123
+ static memoryview from_buffer(const void *ptr,
2124
+ ssize_t itemsize,
2125
+ const char *format,
2126
+ detail::any_container<ssize_t> shape,
2127
+ detail::any_container<ssize_t> strides) {
2128
+ return memoryview::from_buffer(
2129
+ const_cast<void *>(ptr), itemsize, format, std::move(shape), std::move(strides), true);
2130
+ }
2131
+
2132
+ template <typename T>
2133
+ static memoryview from_buffer(T *ptr,
2134
+ detail::any_container<ssize_t> shape,
2135
+ detail::any_container<ssize_t> strides,
2136
+ bool readonly = false) {
2137
+ return memoryview::from_buffer(reinterpret_cast<void *>(ptr),
2138
+ sizeof(T),
2139
+ format_descriptor<T>::value,
2140
+ std::move(shape),
2141
+ std::move(strides),
2142
+ readonly);
2143
+ }
2144
+
2145
+ template <typename T>
2146
+ static memoryview from_buffer(const T *ptr,
2147
+ detail::any_container<ssize_t> shape,
2148
+ detail::any_container<ssize_t> strides) {
2149
+ return memoryview::from_buffer(
2150
+ const_cast<T *>(ptr), std::move(shape), std::move(strides), true);
2151
+ }
2152
+
2153
+ /** \rst
2154
+ Creates ``memoryview`` from static memory.
2155
+
2156
+ This method is meant for providing a ``memoryview`` for C/C++ buffer not
2157
+ managed by Python. The caller is responsible for managing the lifetime
2158
+ of ``mem``, which MUST outlive the memoryview constructed here.
2159
+
2160
+ See also: Python C API documentation for `PyMemoryView_FromBuffer`_.
2161
+
2162
+ .. _PyMemoryView_FromMemory:
2163
+ https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory
2164
+ \endrst */
2165
+ static memoryview from_memory(void *mem, ssize_t size, bool readonly = false) {
2166
+ PyObject *ptr = PyMemoryView_FromMemory(
2167
+ reinterpret_cast<char *>(mem), size, (readonly) ? PyBUF_READ : PyBUF_WRITE);
2168
+ if (!ptr) {
2169
+ pybind11_fail("Could not allocate memoryview object!");
2170
+ }
2171
+ return memoryview(object(ptr, stolen_t{}));
2172
+ }
2173
+
2174
+ static memoryview from_memory(const void *mem, ssize_t size) {
2175
+ return memoryview::from_memory(const_cast<void *>(mem), size, true);
2176
+ }
2177
+
2178
+ #ifdef PYBIND11_HAS_STRING_VIEW
2179
+ static memoryview from_memory(std::string_view mem) {
2180
+ return from_memory(const_cast<char *>(mem.data()), static_cast<ssize_t>(mem.size()), true);
2181
+ }
2182
+ #endif
2183
+ };
2184
+
2185
+ /// @cond DUPLICATE
2186
+ inline memoryview memoryview::from_buffer(void *ptr,
2187
+ ssize_t itemsize,
2188
+ const char *format,
2189
+ detail::any_container<ssize_t> shape,
2190
+ detail::any_container<ssize_t> strides,
2191
+ bool readonly) {
2192
+ size_t ndim = shape->size();
2193
+ if (ndim != strides->size()) {
2194
+ pybind11_fail("memoryview: shape length doesn't match strides length");
2195
+ }
2196
+ ssize_t size = ndim != 0u ? 1 : 0;
2197
+ for (size_t i = 0; i < ndim; ++i) {
2198
+ size *= (*shape)[i];
2199
+ }
2200
+ Py_buffer view;
2201
+ view.buf = ptr;
2202
+ view.obj = nullptr;
2203
+ view.len = size * itemsize;
2204
+ view.readonly = static_cast<int>(readonly);
2205
+ view.itemsize = itemsize;
2206
+ view.format = const_cast<char *>(format);
2207
+ view.ndim = static_cast<int>(ndim);
2208
+ view.shape = shape->data();
2209
+ view.strides = strides->data();
2210
+ view.suboffsets = nullptr;
2211
+ view.internal = nullptr;
2212
+ PyObject *obj = PyMemoryView_FromBuffer(&view);
2213
+ if (!obj) {
2214
+ throw error_already_set();
2215
+ }
2216
+ return memoryview(object(obj, stolen_t{}));
2217
+ }
2218
+ /// @endcond
2219
+ /// @} pytypes
2220
+
2221
+ /// \addtogroup python_builtins
2222
+ /// @{
2223
+
2224
+ /// Get the length of a Python object.
2225
+ inline size_t len(handle h) {
2226
+ ssize_t result = PyObject_Length(h.ptr());
2227
+ if (result < 0) {
2228
+ throw error_already_set();
2229
+ }
2230
+ return (size_t) result;
2231
+ }
2232
+
2233
+ /// Get the length hint of a Python object.
2234
+ /// Returns 0 when this cannot be determined.
2235
+ inline size_t len_hint(handle h) {
2236
+ ssize_t result = PyObject_LengthHint(h.ptr(), 0);
2237
+ if (result < 0) {
2238
+ // Sometimes a length can't be determined at all (eg generators)
2239
+ // In which case simply return 0
2240
+ PyErr_Clear();
2241
+ return 0;
2242
+ }
2243
+ return (size_t) result;
2244
+ }
2245
+
2246
+ inline str repr(handle h) {
2247
+ PyObject *str_value = PyObject_Repr(h.ptr());
2248
+ if (!str_value) {
2249
+ throw error_already_set();
2250
+ }
2251
+ return reinterpret_steal<str>(str_value);
2252
+ }
2253
+
2254
+ inline iterator iter(handle obj) {
2255
+ PyObject *result = PyObject_GetIter(obj.ptr());
2256
+ if (!result) {
2257
+ throw error_already_set();
2258
+ }
2259
+ return reinterpret_steal<iterator>(result);
2260
+ }
2261
+ /// @} python_builtins
2262
+
2263
+ PYBIND11_NAMESPACE_BEGIN(detail)
2264
+ template <typename D>
2265
+ iterator object_api<D>::begin() const {
2266
+ return iter(derived());
2267
+ }
2268
+ template <typename D>
2269
+ iterator object_api<D>::end() const {
2270
+ return iterator::sentinel();
2271
+ }
2272
+ template <typename D>
2273
+ item_accessor object_api<D>::operator[](handle key) const {
2274
+ return {derived(), reinterpret_borrow<object>(key)};
2275
+ }
2276
+ template <typename D>
2277
+ item_accessor object_api<D>::operator[](object &&key) const {
2278
+ return {derived(), std::move(key)};
2279
+ }
2280
+ template <typename D>
2281
+ item_accessor object_api<D>::operator[](const char *key) const {
2282
+ return {derived(), pybind11::str(key)};
2283
+ }
2284
+ template <typename D>
2285
+ obj_attr_accessor object_api<D>::attr(handle key) const {
2286
+ return {derived(), reinterpret_borrow<object>(key)};
2287
+ }
2288
+ template <typename D>
2289
+ obj_attr_accessor object_api<D>::attr(object &&key) const {
2290
+ return {derived(), std::move(key)};
2291
+ }
2292
+ template <typename D>
2293
+ str_attr_accessor object_api<D>::attr(const char *key) const {
2294
+ return {derived(), key};
2295
+ }
2296
+ template <typename D>
2297
+ args_proxy object_api<D>::operator*() const {
2298
+ return args_proxy(derived().ptr());
2299
+ }
2300
+ template <typename D>
2301
+ template <typename T>
2302
+ bool object_api<D>::contains(T &&item) const {
2303
+ return attr("__contains__")(std::forward<T>(item)).template cast<bool>();
2304
+ }
2305
+
2306
+ template <typename D>
2307
+ pybind11::str object_api<D>::str() const {
2308
+ return pybind11::str(derived());
2309
+ }
2310
+
2311
+ template <typename D>
2312
+ str_attr_accessor object_api<D>::doc() const {
2313
+ return attr("__doc__");
2314
+ }
2315
+
2316
+ template <typename D>
2317
+ handle object_api<D>::get_type() const {
2318
+ return type::handle_of(derived());
2319
+ }
2320
+
2321
+ template <typename D>
2322
+ bool object_api<D>::rich_compare(object_api const &other, int value) const {
2323
+ int rv = PyObject_RichCompareBool(derived().ptr(), other.derived().ptr(), value);
2324
+ if (rv == -1) {
2325
+ throw error_already_set();
2326
+ }
2327
+ return rv == 1;
2328
+ }
2329
+
2330
+ #define PYBIND11_MATH_OPERATOR_UNARY(op, fn) \
2331
+ template <typename D> \
2332
+ object object_api<D>::op() const { \
2333
+ object result = reinterpret_steal<object>(fn(derived().ptr())); \
2334
+ if (!result.ptr()) \
2335
+ throw error_already_set(); \
2336
+ return result; \
2337
+ }
2338
+
2339
+ #define PYBIND11_MATH_OPERATOR_BINARY(op, fn) \
2340
+ template <typename D> \
2341
+ object object_api<D>::op(object_api const &other) const { \
2342
+ object result = reinterpret_steal<object>(fn(derived().ptr(), other.derived().ptr())); \
2343
+ if (!result.ptr()) \
2344
+ throw error_already_set(); \
2345
+ return result; \
2346
+ }
2347
+
2348
+ PYBIND11_MATH_OPERATOR_UNARY(operator~, PyNumber_Invert)
2349
+ PYBIND11_MATH_OPERATOR_UNARY(operator-, PyNumber_Negative)
2350
+ PYBIND11_MATH_OPERATOR_BINARY(operator+, PyNumber_Add)
2351
+ PYBIND11_MATH_OPERATOR_BINARY(operator+=, PyNumber_InPlaceAdd)
2352
+ PYBIND11_MATH_OPERATOR_BINARY(operator-, PyNumber_Subtract)
2353
+ PYBIND11_MATH_OPERATOR_BINARY(operator-=, PyNumber_InPlaceSubtract)
2354
+ PYBIND11_MATH_OPERATOR_BINARY(operator*, PyNumber_Multiply)
2355
+ PYBIND11_MATH_OPERATOR_BINARY(operator*=, PyNumber_InPlaceMultiply)
2356
+ PYBIND11_MATH_OPERATOR_BINARY(operator/, PyNumber_TrueDivide)
2357
+ PYBIND11_MATH_OPERATOR_BINARY(operator/=, PyNumber_InPlaceTrueDivide)
2358
+ PYBIND11_MATH_OPERATOR_BINARY(operator|, PyNumber_Or)
2359
+ PYBIND11_MATH_OPERATOR_BINARY(operator|=, PyNumber_InPlaceOr)
2360
+ PYBIND11_MATH_OPERATOR_BINARY(operator&, PyNumber_And)
2361
+ PYBIND11_MATH_OPERATOR_BINARY(operator&=, PyNumber_InPlaceAnd)
2362
+ PYBIND11_MATH_OPERATOR_BINARY(operator^, PyNumber_Xor)
2363
+ PYBIND11_MATH_OPERATOR_BINARY(operator^=, PyNumber_InPlaceXor)
2364
+ PYBIND11_MATH_OPERATOR_BINARY(operator<<, PyNumber_Lshift)
2365
+ PYBIND11_MATH_OPERATOR_BINARY(operator<<=, PyNumber_InPlaceLshift)
2366
+ PYBIND11_MATH_OPERATOR_BINARY(operator>>, PyNumber_Rshift)
2367
+ PYBIND11_MATH_OPERATOR_BINARY(operator>>=, PyNumber_InPlaceRshift)
2368
+
2369
+ #undef PYBIND11_MATH_OPERATOR_UNARY
2370
+ #undef PYBIND11_MATH_OPERATOR_BINARY
2371
+
2372
+ PYBIND11_NAMESPACE_END(detail)
2373
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/stl.h ADDED
@@ -0,0 +1,425 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/stl.h: Transparent conversion for STL data types
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "pybind11.h"
13
+ #include "detail/common.h"
14
+
15
+ #include <deque>
16
+ #include <list>
17
+ #include <map>
18
+ #include <ostream>
19
+ #include <set>
20
+ #include <unordered_map>
21
+ #include <unordered_set>
22
+ #include <valarray>
23
+
24
+ // See `detail/common.h` for implementation of these guards.
25
+ #if defined(PYBIND11_HAS_OPTIONAL)
26
+ # include <optional>
27
+ #elif defined(PYBIND11_HAS_EXP_OPTIONAL)
28
+ # include <experimental/optional>
29
+ #endif
30
+
31
+ #if defined(PYBIND11_HAS_VARIANT)
32
+ # include <variant>
33
+ #endif
34
+
35
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
36
+ PYBIND11_NAMESPACE_BEGIN(detail)
37
+
38
+ /// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for
39
+ /// forwarding a container element). Typically used indirect via forwarded_type(), below.
40
+ template <typename T, typename U>
41
+ using forwarded_type = conditional_t<std::is_lvalue_reference<T>::value,
42
+ remove_reference_t<U> &,
43
+ remove_reference_t<U> &&>;
44
+
45
+ /// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically
46
+ /// used for forwarding a container's elements.
47
+ template <typename T, typename U>
48
+ forwarded_type<T, U> forward_like(U &&u) {
49
+ return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));
50
+ }
51
+
52
+ template <typename Type, typename Key>
53
+ struct set_caster {
54
+ using type = Type;
55
+ using key_conv = make_caster<Key>;
56
+
57
+ bool load(handle src, bool convert) {
58
+ if (!isinstance<anyset>(src)) {
59
+ return false;
60
+ }
61
+ auto s = reinterpret_borrow<anyset>(src);
62
+ value.clear();
63
+ for (auto entry : s) {
64
+ key_conv conv;
65
+ if (!conv.load(entry, convert)) {
66
+ return false;
67
+ }
68
+ value.insert(cast_op<Key &&>(std::move(conv)));
69
+ }
70
+ return true;
71
+ }
72
+
73
+ template <typename T>
74
+ static handle cast(T &&src, return_value_policy policy, handle parent) {
75
+ if (!std::is_lvalue_reference<T>::value) {
76
+ policy = return_value_policy_override<Key>::policy(policy);
77
+ }
78
+ pybind11::set s;
79
+ for (auto &&value : src) {
80
+ auto value_ = reinterpret_steal<object>(
81
+ key_conv::cast(forward_like<T>(value), policy, parent));
82
+ if (!value_ || !s.add(std::move(value_))) {
83
+ return handle();
84
+ }
85
+ }
86
+ return s.release();
87
+ }
88
+
89
+ PYBIND11_TYPE_CASTER(type, const_name("Set[") + key_conv::name + const_name("]"));
90
+ };
91
+
92
+ template <typename Type, typename Key, typename Value>
93
+ struct map_caster {
94
+ using key_conv = make_caster<Key>;
95
+ using value_conv = make_caster<Value>;
96
+
97
+ bool load(handle src, bool convert) {
98
+ if (!isinstance<dict>(src)) {
99
+ return false;
100
+ }
101
+ auto d = reinterpret_borrow<dict>(src);
102
+ value.clear();
103
+ for (auto it : d) {
104
+ key_conv kconv;
105
+ value_conv vconv;
106
+ if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) {
107
+ return false;
108
+ }
109
+ value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));
110
+ }
111
+ return true;
112
+ }
113
+
114
+ template <typename T>
115
+ static handle cast(T &&src, return_value_policy policy, handle parent) {
116
+ dict d;
117
+ return_value_policy policy_key = policy;
118
+ return_value_policy policy_value = policy;
119
+ if (!std::is_lvalue_reference<T>::value) {
120
+ policy_key = return_value_policy_override<Key>::policy(policy_key);
121
+ policy_value = return_value_policy_override<Value>::policy(policy_value);
122
+ }
123
+ for (auto &&kv : src) {
124
+ auto key = reinterpret_steal<object>(
125
+ key_conv::cast(forward_like<T>(kv.first), policy_key, parent));
126
+ auto value = reinterpret_steal<object>(
127
+ value_conv::cast(forward_like<T>(kv.second), policy_value, parent));
128
+ if (!key || !value) {
129
+ return handle();
130
+ }
131
+ d[std::move(key)] = std::move(value);
132
+ }
133
+ return d.release();
134
+ }
135
+
136
+ PYBIND11_TYPE_CASTER(Type,
137
+ const_name("Dict[") + key_conv::name + const_name(", ") + value_conv::name
138
+ + const_name("]"));
139
+ };
140
+
141
+ template <typename Type, typename Value>
142
+ struct list_caster {
143
+ using value_conv = make_caster<Value>;
144
+
145
+ bool load(handle src, bool convert) {
146
+ if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src)) {
147
+ return false;
148
+ }
149
+ auto s = reinterpret_borrow<sequence>(src);
150
+ value.clear();
151
+ reserve_maybe(s, &value);
152
+ for (auto it : s) {
153
+ value_conv conv;
154
+ if (!conv.load(it, convert)) {
155
+ return false;
156
+ }
157
+ value.push_back(cast_op<Value &&>(std::move(conv)));
158
+ }
159
+ return true;
160
+ }
161
+
162
+ private:
163
+ template <
164
+ typename T = Type,
165
+ enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0>
166
+ void reserve_maybe(const sequence &s, Type *) {
167
+ value.reserve(s.size());
168
+ }
169
+ void reserve_maybe(const sequence &, void *) {}
170
+
171
+ public:
172
+ template <typename T>
173
+ static handle cast(T &&src, return_value_policy policy, handle parent) {
174
+ if (!std::is_lvalue_reference<T>::value) {
175
+ policy = return_value_policy_override<Value>::policy(policy);
176
+ }
177
+ list l(src.size());
178
+ ssize_t index = 0;
179
+ for (auto &&value : src) {
180
+ auto value_ = reinterpret_steal<object>(
181
+ value_conv::cast(forward_like<T>(value), policy, parent));
182
+ if (!value_) {
183
+ return handle();
184
+ }
185
+ PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
186
+ }
187
+ return l.release();
188
+ }
189
+
190
+ PYBIND11_TYPE_CASTER(Type, const_name("List[") + value_conv::name + const_name("]"));
191
+ };
192
+
193
+ template <typename Type, typename Alloc>
194
+ struct type_caster<std::vector<Type, Alloc>> : list_caster<std::vector<Type, Alloc>, Type> {};
195
+
196
+ template <typename Type, typename Alloc>
197
+ struct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc>, Type> {};
198
+
199
+ template <typename Type, typename Alloc>
200
+ struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
201
+
202
+ template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
203
+ struct array_caster {
204
+ using value_conv = make_caster<Value>;
205
+
206
+ private:
207
+ template <bool R = Resizable>
208
+ bool require_size(enable_if_t<R, size_t> size) {
209
+ if (value.size() != size) {
210
+ value.resize(size);
211
+ }
212
+ return true;
213
+ }
214
+ template <bool R = Resizable>
215
+ bool require_size(enable_if_t<!R, size_t> size) {
216
+ return size == Size;
217
+ }
218
+
219
+ public:
220
+ bool load(handle src, bool convert) {
221
+ if (!isinstance<sequence>(src)) {
222
+ return false;
223
+ }
224
+ auto l = reinterpret_borrow<sequence>(src);
225
+ if (!require_size(l.size())) {
226
+ return false;
227
+ }
228
+ size_t ctr = 0;
229
+ for (auto it : l) {
230
+ value_conv conv;
231
+ if (!conv.load(it, convert)) {
232
+ return false;
233
+ }
234
+ value[ctr++] = cast_op<Value &&>(std::move(conv));
235
+ }
236
+ return true;
237
+ }
238
+
239
+ template <typename T>
240
+ static handle cast(T &&src, return_value_policy policy, handle parent) {
241
+ list l(src.size());
242
+ ssize_t index = 0;
243
+ for (auto &&value : src) {
244
+ auto value_ = reinterpret_steal<object>(
245
+ value_conv::cast(forward_like<T>(value), policy, parent));
246
+ if (!value_) {
247
+ return handle();
248
+ }
249
+ PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference
250
+ }
251
+ return l.release();
252
+ }
253
+
254
+ PYBIND11_TYPE_CASTER(ArrayType,
255
+ const_name("List[") + value_conv::name
256
+ + const_name<Resizable>(const_name(""),
257
+ const_name("[") + const_name<Size>()
258
+ + const_name("]"))
259
+ + const_name("]"));
260
+ };
261
+
262
+ template <typename Type, size_t Size>
263
+ struct type_caster<std::array<Type, Size>>
264
+ : array_caster<std::array<Type, Size>, Type, false, Size> {};
265
+
266
+ template <typename Type>
267
+ struct type_caster<std::valarray<Type>> : array_caster<std::valarray<Type>, Type, true> {};
268
+
269
+ template <typename Key, typename Compare, typename Alloc>
270
+ struct type_caster<std::set<Key, Compare, Alloc>>
271
+ : set_caster<std::set<Key, Compare, Alloc>, Key> {};
272
+
273
+ template <typename Key, typename Hash, typename Equal, typename Alloc>
274
+ struct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>
275
+ : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> {};
276
+
277
+ template <typename Key, typename Value, typename Compare, typename Alloc>
278
+ struct type_caster<std::map<Key, Value, Compare, Alloc>>
279
+ : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> {};
280
+
281
+ template <typename Key, typename Value, typename Hash, typename Equal, typename Alloc>
282
+ struct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>
283
+ : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> {};
284
+
285
+ // This type caster is intended to be used for std::optional and std::experimental::optional
286
+ template <typename Type, typename Value = typename Type::value_type>
287
+ struct optional_caster {
288
+ using value_conv = make_caster<Value>;
289
+
290
+ template <typename T>
291
+ static handle cast(T &&src, return_value_policy policy, handle parent) {
292
+ if (!src) {
293
+ return none().inc_ref();
294
+ }
295
+ if (!std::is_lvalue_reference<T>::value) {
296
+ policy = return_value_policy_override<Value>::policy(policy);
297
+ }
298
+ return value_conv::cast(*std::forward<T>(src), policy, parent);
299
+ }
300
+
301
+ bool load(handle src, bool convert) {
302
+ if (!src) {
303
+ return false;
304
+ }
305
+ if (src.is_none()) {
306
+ return true; // default-constructed value is already empty
307
+ }
308
+ value_conv inner_caster;
309
+ if (!inner_caster.load(src, convert)) {
310
+ return false;
311
+ }
312
+
313
+ value.emplace(cast_op<Value &&>(std::move(inner_caster)));
314
+ return true;
315
+ }
316
+
317
+ PYBIND11_TYPE_CASTER(Type, const_name("Optional[") + value_conv::name + const_name("]"));
318
+ };
319
+
320
+ #if defined(PYBIND11_HAS_OPTIONAL)
321
+ template <typename T>
322
+ struct type_caster<std::optional<T>> : public optional_caster<std::optional<T>> {};
323
+
324
+ template <>
325
+ struct type_caster<std::nullopt_t> : public void_caster<std::nullopt_t> {};
326
+ #endif
327
+
328
+ #if defined(PYBIND11_HAS_EXP_OPTIONAL)
329
+ template <typename T>
330
+ struct type_caster<std::experimental::optional<T>>
331
+ : public optional_caster<std::experimental::optional<T>> {};
332
+
333
+ template <>
334
+ struct type_caster<std::experimental::nullopt_t>
335
+ : public void_caster<std::experimental::nullopt_t> {};
336
+ #endif
337
+
338
+ /// Visit a variant and cast any found type to Python
339
+ struct variant_caster_visitor {
340
+ return_value_policy policy;
341
+ handle parent;
342
+
343
+ using result_type = handle; // required by boost::variant in C++11
344
+
345
+ template <typename T>
346
+ result_type operator()(T &&src) const {
347
+ return make_caster<T>::cast(std::forward<T>(src), policy, parent);
348
+ }
349
+ };
350
+
351
+ /// Helper class which abstracts away variant's `visit` function. `std::variant` and similar
352
+ /// `namespace::variant` types which provide a `namespace::visit()` function are handled here
353
+ /// automatically using argument-dependent lookup. Users can provide specializations for other
354
+ /// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`.
355
+ template <template <typename...> class Variant>
356
+ struct visit_helper {
357
+ template <typename... Args>
358
+ static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {
359
+ return visit(std::forward<Args>(args)...);
360
+ }
361
+ };
362
+
363
+ /// Generic variant caster
364
+ template <typename Variant>
365
+ struct variant_caster;
366
+
367
+ template <template <typename...> class V, typename... Ts>
368
+ struct variant_caster<V<Ts...>> {
369
+ static_assert(sizeof...(Ts) > 0, "Variant must consist of at least one alternative.");
370
+
371
+ template <typename U, typename... Us>
372
+ bool load_alternative(handle src, bool convert, type_list<U, Us...>) {
373
+ auto caster = make_caster<U>();
374
+ if (caster.load(src, convert)) {
375
+ value = cast_op<U>(std::move(caster));
376
+ return true;
377
+ }
378
+ return load_alternative(src, convert, type_list<Us...>{});
379
+ }
380
+
381
+ bool load_alternative(handle, bool, type_list<>) { return false; }
382
+
383
+ bool load(handle src, bool convert) {
384
+ // Do a first pass without conversions to improve constructor resolution.
385
+ // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`
386
+ // slot of the variant. Without two-pass loading `double` would be filled
387
+ // because it appears first and a conversion is possible.
388
+ if (convert && load_alternative(src, false, type_list<Ts...>{})) {
389
+ return true;
390
+ }
391
+ return load_alternative(src, convert, type_list<Ts...>{});
392
+ }
393
+
394
+ template <typename Variant>
395
+ static handle cast(Variant &&src, return_value_policy policy, handle parent) {
396
+ return visit_helper<V>::call(variant_caster_visitor{policy, parent},
397
+ std::forward<Variant>(src));
398
+ }
399
+
400
+ using Type = V<Ts...>;
401
+ PYBIND11_TYPE_CASTER(Type,
402
+ const_name("Union[") + detail::concat(make_caster<Ts>::name...)
403
+ + const_name("]"));
404
+ };
405
+
406
+ #if defined(PYBIND11_HAS_VARIANT)
407
+ template <typename... Ts>
408
+ struct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};
409
+
410
+ template <>
411
+ struct type_caster<std::monostate> : public void_caster<std::monostate> {};
412
+ #endif
413
+
414
+ PYBIND11_NAMESPACE_END(detail)
415
+
416
+ inline std::ostream &operator<<(std::ostream &os, const handle &obj) {
417
+ #ifdef PYBIND11_HAS_STRING_VIEW
418
+ os << str(obj).cast<std::string_view>();
419
+ #else
420
+ os << (std::string) str(obj);
421
+ #endif
422
+ return os;
423
+ }
424
+
425
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/stl/filesystem.h ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Copyright (c) 2021 The Pybind Development Team.
2
+ // All rights reserved. Use of this source code is governed by a
3
+ // BSD-style license that can be found in the LICENSE file.
4
+
5
+ #pragma once
6
+
7
+ #include "../pybind11.h"
8
+ #include "../detail/common.h"
9
+ #include "../detail/descr.h"
10
+ #include "../cast.h"
11
+ #include "../pytypes.h"
12
+
13
+ #include <string>
14
+
15
+ #ifdef __has_include
16
+ # if defined(PYBIND11_CPP17)
17
+ # if __has_include(<filesystem>) && \
18
+ PY_VERSION_HEX >= 0x03060000
19
+ # include <filesystem>
20
+ # define PYBIND11_HAS_FILESYSTEM 1
21
+ # elif __has_include(<experimental/filesystem>)
22
+ # include <experimental/filesystem>
23
+ # define PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM 1
24
+ # endif
25
+ # endif
26
+ #endif
27
+
28
+ #if !defined(PYBIND11_HAS_FILESYSTEM) && !defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM) \
29
+ && !defined(PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL)
30
+ # error \
31
+ "Neither #include <filesystem> nor #include <experimental/filesystem is available. (Use -DPYBIND11_HAS_FILESYSTEM_IS_OPTIONAL to ignore.)"
32
+ #endif
33
+
34
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
35
+ PYBIND11_NAMESPACE_BEGIN(detail)
36
+
37
+ #if defined(PYBIND11_HAS_FILESYSTEM) || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
38
+ template <typename T>
39
+ struct path_caster {
40
+
41
+ private:
42
+ static PyObject *unicode_from_fs_native(const std::string &w) {
43
+ # if !defined(PYPY_VERSION)
44
+ return PyUnicode_DecodeFSDefaultAndSize(w.c_str(), ssize_t(w.size()));
45
+ # else
46
+ // PyPy mistakenly declares the first parameter as non-const.
47
+ return PyUnicode_DecodeFSDefaultAndSize(const_cast<char *>(w.c_str()), ssize_t(w.size()));
48
+ # endif
49
+ }
50
+
51
+ static PyObject *unicode_from_fs_native(const std::wstring &w) {
52
+ return PyUnicode_FromWideChar(w.c_str(), ssize_t(w.size()));
53
+ }
54
+
55
+ public:
56
+ static handle cast(const T &path, return_value_policy, handle) {
57
+ if (auto py_str = unicode_from_fs_native(path.native())) {
58
+ return module_::import("pathlib")
59
+ .attr("Path")(reinterpret_steal<object>(py_str))
60
+ .release();
61
+ }
62
+ return nullptr;
63
+ }
64
+
65
+ bool load(handle handle, bool) {
66
+ // PyUnicode_FSConverter and PyUnicode_FSDecoder normally take care of
67
+ // calling PyOS_FSPath themselves, but that's broken on PyPy (PyPy
68
+ // issue #3168) so we do it ourselves instead.
69
+ PyObject *buf = PyOS_FSPath(handle.ptr());
70
+ if (!buf) {
71
+ PyErr_Clear();
72
+ return false;
73
+ }
74
+ PyObject *native = nullptr;
75
+ if constexpr (std::is_same_v<typename T::value_type, char>) {
76
+ if (PyUnicode_FSConverter(buf, &native) != 0) {
77
+ if (auto *c_str = PyBytes_AsString(native)) {
78
+ // AsString returns a pointer to the internal buffer, which
79
+ // must not be free'd.
80
+ value = c_str;
81
+ }
82
+ }
83
+ } else if constexpr (std::is_same_v<typename T::value_type, wchar_t>) {
84
+ if (PyUnicode_FSDecoder(buf, &native) != 0) {
85
+ if (auto *c_str = PyUnicode_AsWideCharString(native, nullptr)) {
86
+ // AsWideCharString returns a new string that must be free'd.
87
+ value = c_str; // Copies the string.
88
+ PyMem_Free(c_str);
89
+ }
90
+ }
91
+ }
92
+ Py_XDECREF(native);
93
+ Py_DECREF(buf);
94
+ if (PyErr_Occurred()) {
95
+ PyErr_Clear();
96
+ return false;
97
+ }
98
+ return true;
99
+ }
100
+
101
+ PYBIND11_TYPE_CASTER(T, const_name("os.PathLike"));
102
+ };
103
+
104
+ #endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
105
+
106
+ #if defined(PYBIND11_HAS_FILESYSTEM)
107
+ template <>
108
+ struct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};
109
+ #elif defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)
110
+ template <>
111
+ struct type_caster<std::experimental::filesystem::path>
112
+ : public path_caster<std::experimental::filesystem::path> {};
113
+ #endif
114
+
115
+ PYBIND11_NAMESPACE_END(detail)
116
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/include/pybind11/stl_bind.h ADDED
@@ -0,0 +1,785 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ pybind11/std_bind.h: Binding generators for STL data types
3
+
4
+ Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob
5
+
6
+ All rights reserved. Use of this source code is governed by a
7
+ BSD-style license that can be found in the LICENSE file.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include "detail/common.h"
13
+ #include "operators.h"
14
+
15
+ #include <algorithm>
16
+ #include <sstream>
17
+
18
+ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
19
+ PYBIND11_NAMESPACE_BEGIN(detail)
20
+
21
+ /* SFINAE helper class used by 'is_comparable */
22
+ template <typename T>
23
+ struct container_traits {
24
+ template <typename T2>
25
+ static std::true_type
26
+ test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);
27
+ template <typename T2>
28
+ static std::false_type test_comparable(...);
29
+ template <typename T2>
30
+ static std::true_type test_value(typename T2::value_type *);
31
+ template <typename T2>
32
+ static std::false_type test_value(...);
33
+ template <typename T2>
34
+ static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);
35
+ template <typename T2>
36
+ static std::false_type test_pair(...);
37
+
38
+ static constexpr const bool is_comparable
39
+ = std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;
40
+ static constexpr const bool is_pair
41
+ = std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;
42
+ static constexpr const bool is_vector
43
+ = std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;
44
+ static constexpr const bool is_element = !is_pair && !is_vector;
45
+ };
46
+
47
+ /* Default: is_comparable -> std::false_type */
48
+ template <typename T, typename SFINAE = void>
49
+ struct is_comparable : std::false_type {};
50
+
51
+ /* For non-map data structures, check whether operator== can be instantiated */
52
+ template <typename T>
53
+ struct is_comparable<
54
+ T,
55
+ enable_if_t<container_traits<T>::is_element && container_traits<T>::is_comparable>>
56
+ : std::true_type {};
57
+
58
+ /* For a vector/map data structure, recursively check the value type
59
+ (which is std::pair for maps) */
60
+ template <typename T>
61
+ struct is_comparable<T, enable_if_t<container_traits<T>::is_vector>> {
62
+ static constexpr const bool value = is_comparable<typename T::value_type>::value;
63
+ };
64
+
65
+ /* For pairs, recursively check the two data types */
66
+ template <typename T>
67
+ struct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {
68
+ static constexpr const bool value = is_comparable<typename T::first_type>::value
69
+ && is_comparable<typename T::second_type>::value;
70
+ };
71
+
72
+ /* Fallback functions */
73
+ template <typename, typename, typename... Args>
74
+ void vector_if_copy_constructible(const Args &...) {}
75
+ template <typename, typename, typename... Args>
76
+ void vector_if_equal_operator(const Args &...) {}
77
+ template <typename, typename, typename... Args>
78
+ void vector_if_insertion_operator(const Args &...) {}
79
+ template <typename, typename, typename... Args>
80
+ void vector_modifiers(const Args &...) {}
81
+
82
+ template <typename Vector, typename Class_>
83
+ void vector_if_copy_constructible(enable_if_t<is_copy_constructible<Vector>::value, Class_> &cl) {
84
+ cl.def(init<const Vector &>(), "Copy constructor");
85
+ }
86
+
87
+ template <typename Vector, typename Class_>
88
+ void vector_if_equal_operator(enable_if_t<is_comparable<Vector>::value, Class_> &cl) {
89
+ using T = typename Vector::value_type;
90
+
91
+ cl.def(self == self);
92
+ cl.def(self != self);
93
+
94
+ cl.def(
95
+ "count",
96
+ [](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },
97
+ arg("x"),
98
+ "Return the number of times ``x`` appears in the list");
99
+
100
+ cl.def(
101
+ "remove",
102
+ [](Vector &v, const T &x) {
103
+ auto p = std::find(v.begin(), v.end(), x);
104
+ if (p != v.end()) {
105
+ v.erase(p);
106
+ } else {
107
+ throw value_error();
108
+ }
109
+ },
110
+ arg("x"),
111
+ "Remove the first item from the list whose value is x. "
112
+ "It is an error if there is no such item.");
113
+
114
+ cl.def(
115
+ "__contains__",
116
+ [](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },
117
+ arg("x"),
118
+ "Return true the container contains ``x``");
119
+ }
120
+
121
+ // Vector modifiers -- requires a copyable vector_type:
122
+ // (Technically, some of these (pop and __delitem__) don't actually require copyability, but it
123
+ // seems silly to allow deletion but not insertion, so include them here too.)
124
+ template <typename Vector, typename Class_>
125
+ void vector_modifiers(
126
+ enable_if_t<is_copy_constructible<typename Vector::value_type>::value, Class_> &cl) {
127
+ using T = typename Vector::value_type;
128
+ using SizeType = typename Vector::size_type;
129
+ using DiffType = typename Vector::difference_type;
130
+
131
+ auto wrap_i = [](DiffType i, SizeType n) {
132
+ if (i < 0) {
133
+ i += n;
134
+ }
135
+ if (i < 0 || (SizeType) i >= n) {
136
+ throw index_error();
137
+ }
138
+ return i;
139
+ };
140
+
141
+ cl.def(
142
+ "append",
143
+ [](Vector &v, const T &value) { v.push_back(value); },
144
+ arg("x"),
145
+ "Add an item to the end of the list");
146
+
147
+ cl.def(init([](const iterable &it) {
148
+ auto v = std::unique_ptr<Vector>(new Vector());
149
+ v->reserve(len_hint(it));
150
+ for (handle h : it) {
151
+ v->push_back(h.cast<T>());
152
+ }
153
+ return v.release();
154
+ }));
155
+
156
+ cl.def(
157
+ "clear", [](Vector &v) { v.clear(); }, "Clear the contents");
158
+
159
+ cl.def(
160
+ "extend",
161
+ [](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },
162
+ arg("L"),
163
+ "Extend the list by appending all the items in the given list");
164
+
165
+ cl.def(
166
+ "extend",
167
+ [](Vector &v, const iterable &it) {
168
+ const size_t old_size = v.size();
169
+ v.reserve(old_size + len_hint(it));
170
+ try {
171
+ for (handle h : it) {
172
+ v.push_back(h.cast<T>());
173
+ }
174
+ } catch (const cast_error &) {
175
+ v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),
176
+ v.end());
177
+ try {
178
+ v.shrink_to_fit();
179
+ } catch (const std::exception &) {
180
+ // Do nothing
181
+ }
182
+ throw;
183
+ }
184
+ },
185
+ arg("L"),
186
+ "Extend the list by appending all the items in the given list");
187
+
188
+ cl.def(
189
+ "insert",
190
+ [](Vector &v, DiffType i, const T &x) {
191
+ // Can't use wrap_i; i == v.size() is OK
192
+ if (i < 0) {
193
+ i += v.size();
194
+ }
195
+ if (i < 0 || (SizeType) i > v.size()) {
196
+ throw index_error();
197
+ }
198
+ v.insert(v.begin() + i, x);
199
+ },
200
+ arg("i"),
201
+ arg("x"),
202
+ "Insert an item at a given position.");
203
+
204
+ cl.def(
205
+ "pop",
206
+ [](Vector &v) {
207
+ if (v.empty()) {
208
+ throw index_error();
209
+ }
210
+ T t = std::move(v.back());
211
+ v.pop_back();
212
+ return t;
213
+ },
214
+ "Remove and return the last item");
215
+
216
+ cl.def(
217
+ "pop",
218
+ [wrap_i](Vector &v, DiffType i) {
219
+ i = wrap_i(i, v.size());
220
+ T t = std::move(v[(SizeType) i]);
221
+ v.erase(std::next(v.begin(), i));
222
+ return t;
223
+ },
224
+ arg("i"),
225
+ "Remove and return the item at index ``i``");
226
+
227
+ cl.def("__setitem__", [wrap_i](Vector &v, DiffType i, const T &t) {
228
+ i = wrap_i(i, v.size());
229
+ v[(SizeType) i] = t;
230
+ });
231
+
232
+ /// Slicing protocol
233
+ cl.def(
234
+ "__getitem__",
235
+ [](const Vector &v, const slice &slice) -> Vector * {
236
+ size_t start = 0, stop = 0, step = 0, slicelength = 0;
237
+
238
+ if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
239
+ throw error_already_set();
240
+ }
241
+
242
+ auto *seq = new Vector();
243
+ seq->reserve((size_t) slicelength);
244
+
245
+ for (size_t i = 0; i < slicelength; ++i) {
246
+ seq->push_back(v[start]);
247
+ start += step;
248
+ }
249
+ return seq;
250
+ },
251
+ arg("s"),
252
+ "Retrieve list elements using a slice object");
253
+
254
+ cl.def(
255
+ "__setitem__",
256
+ [](Vector &v, const slice &slice, const Vector &value) {
257
+ size_t start = 0, stop = 0, step = 0, slicelength = 0;
258
+ if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
259
+ throw error_already_set();
260
+ }
261
+
262
+ if (slicelength != value.size()) {
263
+ throw std::runtime_error(
264
+ "Left and right hand size of slice assignment have different sizes!");
265
+ }
266
+
267
+ for (size_t i = 0; i < slicelength; ++i) {
268
+ v[start] = value[i];
269
+ start += step;
270
+ }
271
+ },
272
+ "Assign list elements using a slice object");
273
+
274
+ cl.def(
275
+ "__delitem__",
276
+ [wrap_i](Vector &v, DiffType i) {
277
+ i = wrap_i(i, v.size());
278
+ v.erase(v.begin() + i);
279
+ },
280
+ "Delete the list elements at index ``i``");
281
+
282
+ cl.def(
283
+ "__delitem__",
284
+ [](Vector &v, const slice &slice) {
285
+ size_t start = 0, stop = 0, step = 0, slicelength = 0;
286
+
287
+ if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {
288
+ throw error_already_set();
289
+ }
290
+
291
+ if (step == 1 && false) {
292
+ v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));
293
+ } else {
294
+ for (size_t i = 0; i < slicelength; ++i) {
295
+ v.erase(v.begin() + DiffType(start));
296
+ start += step - 1;
297
+ }
298
+ }
299
+ },
300
+ "Delete list elements using a slice object");
301
+ }
302
+
303
+ // If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),
304
+ // we have to access by copying; otherwise we return by reference.
305
+ template <typename Vector>
306
+ using vector_needs_copy
307
+ = negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),
308
+ typename Vector::value_type &>>;
309
+
310
+ // The usual case: access and iterate by reference
311
+ template <typename Vector, typename Class_>
312
+ void vector_accessor(enable_if_t<!vector_needs_copy<Vector>::value, Class_> &cl) {
313
+ using T = typename Vector::value_type;
314
+ using SizeType = typename Vector::size_type;
315
+ using DiffType = typename Vector::difference_type;
316
+ using ItType = typename Vector::iterator;
317
+
318
+ auto wrap_i = [](DiffType i, SizeType n) {
319
+ if (i < 0) {
320
+ i += n;
321
+ }
322
+ if (i < 0 || (SizeType) i >= n) {
323
+ throw index_error();
324
+ }
325
+ return i;
326
+ };
327
+
328
+ cl.def(
329
+ "__getitem__",
330
+ [wrap_i](Vector &v, DiffType i) -> T & {
331
+ i = wrap_i(i, v.size());
332
+ return v[(SizeType) i];
333
+ },
334
+ return_value_policy::reference_internal // ref + keepalive
335
+ );
336
+
337
+ cl.def(
338
+ "__iter__",
339
+ [](Vector &v) {
340
+ return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(
341
+ v.begin(), v.end());
342
+ },
343
+ keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
344
+ );
345
+ }
346
+
347
+ // The case for special objects, like std::vector<bool>, that have to be returned-by-copy:
348
+ template <typename Vector, typename Class_>
349
+ void vector_accessor(enable_if_t<vector_needs_copy<Vector>::value, Class_> &cl) {
350
+ using T = typename Vector::value_type;
351
+ using SizeType = typename Vector::size_type;
352
+ using DiffType = typename Vector::difference_type;
353
+ using ItType = typename Vector::iterator;
354
+ cl.def("__getitem__", [](const Vector &v, DiffType i) -> T {
355
+ if (i < 0 && (i += v.size()) < 0) {
356
+ throw index_error();
357
+ }
358
+ if ((SizeType) i >= v.size()) {
359
+ throw index_error();
360
+ }
361
+ return v[(SizeType) i];
362
+ });
363
+
364
+ cl.def(
365
+ "__iter__",
366
+ [](Vector &v) {
367
+ return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());
368
+ },
369
+ keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
370
+ );
371
+ }
372
+
373
+ template <typename Vector, typename Class_>
374
+ auto vector_if_insertion_operator(Class_ &cl, std::string const &name)
375
+ -> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),
376
+ void()) {
377
+ using size_type = typename Vector::size_type;
378
+
379
+ cl.def(
380
+ "__repr__",
381
+ [name](Vector &v) {
382
+ std::ostringstream s;
383
+ s << name << '[';
384
+ for (size_type i = 0; i < v.size(); ++i) {
385
+ s << v[i];
386
+ if (i != v.size() - 1) {
387
+ s << ", ";
388
+ }
389
+ }
390
+ s << ']';
391
+ return s.str();
392
+ },
393
+ "Return the canonical string representation of this list.");
394
+ }
395
+
396
+ // Provide the buffer interface for vectors if we have data() and we have a format for it
397
+ // GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data()
398
+ // is insufficient, we need to check it returns an appropriate pointer
399
+ template <typename Vector, typename = void>
400
+ struct vector_has_data_and_format : std::false_type {};
401
+ template <typename Vector>
402
+ struct vector_has_data_and_format<
403
+ Vector,
404
+ enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),
405
+ std::declval<Vector>().data()),
406
+ typename Vector::value_type *>::value>> : std::true_type {};
407
+
408
+ // [workaround(intel)] Separate function required here
409
+ // Workaround as the Intel compiler does not compile the enable_if_t part below
410
+ // (tested with icc (ICC) 2021.1 Beta 20200827)
411
+ template <typename... Args>
412
+ constexpr bool args_any_are_buffer() {
413
+ return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;
414
+ }
415
+
416
+ // [workaround(intel)] Separate function required here
417
+ // [workaround(msvc)] Can't use constexpr bool in return type
418
+
419
+ // Add the buffer interface to a vector
420
+ template <typename Vector, typename Class_, typename... Args>
421
+ void vector_buffer_impl(Class_ &cl, std::true_type) {
422
+ using T = typename Vector::value_type;
423
+
424
+ static_assert(vector_has_data_and_format<Vector>::value,
425
+ "There is not an appropriate format descriptor for this vector");
426
+
427
+ // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard
428
+ // at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here
429
+ format_descriptor<T>::format();
430
+
431
+ cl.def_buffer([](Vector &v) -> buffer_info {
432
+ return buffer_info(v.data(),
433
+ static_cast<ssize_t>(sizeof(T)),
434
+ format_descriptor<T>::format(),
435
+ 1,
436
+ {v.size()},
437
+ {sizeof(T)});
438
+ });
439
+
440
+ cl.def(init([](const buffer &buf) {
441
+ auto info = buf.request();
442
+ if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {
443
+ throw type_error("Only valid 1D buffers can be copied to a vector");
444
+ }
445
+ if (!detail::compare_buffer_info<T>::compare(info)
446
+ || (ssize_t) sizeof(T) != info.itemsize) {
447
+ throw type_error("Format mismatch (Python: " + info.format
448
+ + " C++: " + format_descriptor<T>::format() + ")");
449
+ }
450
+
451
+ T *p = static_cast<T *>(info.ptr);
452
+ ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));
453
+ T *end = p + info.shape[0] * step;
454
+ if (step == 1) {
455
+ return Vector(p, end);
456
+ }
457
+ Vector vec;
458
+ vec.reserve((size_t) info.shape[0]);
459
+ for (; p != end; p += step) {
460
+ vec.push_back(*p);
461
+ }
462
+ return vec;
463
+ }));
464
+
465
+ return;
466
+ }
467
+
468
+ template <typename Vector, typename Class_, typename... Args>
469
+ void vector_buffer_impl(Class_ &, std::false_type) {}
470
+
471
+ template <typename Vector, typename Class_, typename... Args>
472
+ void vector_buffer(Class_ &cl) {
473
+ vector_buffer_impl<Vector, Class_, Args...>(
474
+ cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});
475
+ }
476
+
477
+ PYBIND11_NAMESPACE_END(detail)
478
+
479
+ //
480
+ // std::vector
481
+ //
482
+ template <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>
483
+ class_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {
484
+ using Class_ = class_<Vector, holder_type>;
485
+
486
+ // If the value_type is unregistered (e.g. a converting type) or is itself registered
487
+ // module-local then make the vector binding module-local as well:
488
+ using vtype = typename Vector::value_type;
489
+ auto *vtype_info = detail::get_type_info(typeid(vtype));
490
+ bool local = !vtype_info || vtype_info->module_local;
491
+
492
+ Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
493
+
494
+ // Declare the buffer interface if a buffer_protocol() is passed in
495
+ detail::vector_buffer<Vector, Class_, Args...>(cl);
496
+
497
+ cl.def(init<>());
498
+
499
+ // Register copy constructor (if possible)
500
+ detail::vector_if_copy_constructible<Vector, Class_>(cl);
501
+
502
+ // Register comparison-related operators and functions (if possible)
503
+ detail::vector_if_equal_operator<Vector, Class_>(cl);
504
+
505
+ // Register stream insertion operator (if possible)
506
+ detail::vector_if_insertion_operator<Vector, Class_>(cl, name);
507
+
508
+ // Modifiers require copyable vector value type
509
+ detail::vector_modifiers<Vector, Class_>(cl);
510
+
511
+ // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive
512
+ detail::vector_accessor<Vector, Class_>(cl);
513
+
514
+ cl.def(
515
+ "__bool__",
516
+ [](const Vector &v) -> bool { return !v.empty(); },
517
+ "Check whether the list is nonempty");
518
+
519
+ cl.def("__len__", &Vector::size);
520
+
521
+ #if 0
522
+ // C++ style functions deprecated, leaving it here as an example
523
+ cl.def(init<size_type>());
524
+
525
+ cl.def("resize",
526
+ (void (Vector::*) (size_type count)) & Vector::resize,
527
+ "changes the number of elements stored");
528
+
529
+ cl.def("erase",
530
+ [](Vector &v, SizeType i) {
531
+ if (i >= v.size())
532
+ throw index_error();
533
+ v.erase(v.begin() + i);
534
+ }, "erases element at index ``i``");
535
+
536
+ cl.def("empty", &Vector::empty, "checks whether the container is empty");
537
+ cl.def("size", &Vector::size, "returns the number of elements");
538
+ cl.def("push_back", (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end");
539
+ cl.def("pop_back", &Vector::pop_back, "removes the last element");
540
+
541
+ cl.def("max_size", &Vector::max_size, "returns the maximum possible number of elements");
542
+ cl.def("reserve", &Vector::reserve, "reserves storage");
543
+ cl.def("capacity", &Vector::capacity, "returns the number of elements that can be held in currently allocated storage");
544
+ cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory");
545
+
546
+ cl.def("clear", &Vector::clear, "clears the contents");
547
+ cl.def("swap", &Vector::swap, "swaps the contents");
548
+
549
+ cl.def("front", [](Vector &v) {
550
+ if (v.size()) return v.front();
551
+ else throw index_error();
552
+ }, "access the first element");
553
+
554
+ cl.def("back", [](Vector &v) {
555
+ if (v.size()) return v.back();
556
+ else throw index_error();
557
+ }, "access the last element ");
558
+
559
+ #endif
560
+
561
+ return cl;
562
+ }
563
+
564
+ //
565
+ // std::map, std::unordered_map
566
+ //
567
+
568
+ PYBIND11_NAMESPACE_BEGIN(detail)
569
+
570
+ /* Fallback functions */
571
+ template <typename, typename, typename... Args>
572
+ void map_if_insertion_operator(const Args &...) {}
573
+ template <typename, typename, typename... Args>
574
+ void map_assignment(const Args &...) {}
575
+
576
+ // Map assignment when copy-assignable: just copy the value
577
+ template <typename Map, typename Class_>
578
+ void map_assignment(
579
+ enable_if_t<is_copy_assignable<typename Map::mapped_type>::value, Class_> &cl) {
580
+ using KeyType = typename Map::key_type;
581
+ using MappedType = typename Map::mapped_type;
582
+
583
+ cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
584
+ auto it = m.find(k);
585
+ if (it != m.end()) {
586
+ it->second = v;
587
+ } else {
588
+ m.emplace(k, v);
589
+ }
590
+ });
591
+ }
592
+
593
+ // Not copy-assignable, but still copy-constructible: we can update the value by erasing and
594
+ // reinserting
595
+ template <typename Map, typename Class_>
596
+ void map_assignment(enable_if_t<!is_copy_assignable<typename Map::mapped_type>::value
597
+ && is_copy_constructible<typename Map::mapped_type>::value,
598
+ Class_> &cl) {
599
+ using KeyType = typename Map::key_type;
600
+ using MappedType = typename Map::mapped_type;
601
+
602
+ cl.def("__setitem__", [](Map &m, const KeyType &k, const MappedType &v) {
603
+ // We can't use m[k] = v; because value type might not be default constructable
604
+ auto r = m.emplace(k, v);
605
+ if (!r.second) {
606
+ // value type is not copy assignable so the only way to insert it is to erase it
607
+ // first...
608
+ m.erase(r.first);
609
+ m.emplace(k, v);
610
+ }
611
+ });
612
+ }
613
+
614
+ template <typename Map, typename Class_>
615
+ auto map_if_insertion_operator(Class_ &cl, std::string const &name)
616
+ -> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()
617
+ << std::declval<typename Map::mapped_type>(),
618
+ void()) {
619
+
620
+ cl.def(
621
+ "__repr__",
622
+ [name](Map &m) {
623
+ std::ostringstream s;
624
+ s << name << '{';
625
+ bool f = false;
626
+ for (auto const &kv : m) {
627
+ if (f) {
628
+ s << ", ";
629
+ }
630
+ s << kv.first << ": " << kv.second;
631
+ f = true;
632
+ }
633
+ s << '}';
634
+ return s.str();
635
+ },
636
+ "Return the canonical string representation of this map.");
637
+ }
638
+
639
+ template <typename Map>
640
+ struct keys_view {
641
+ Map &map;
642
+ };
643
+
644
+ template <typename Map>
645
+ struct values_view {
646
+ Map &map;
647
+ };
648
+
649
+ template <typename Map>
650
+ struct items_view {
651
+ Map &map;
652
+ };
653
+
654
+ PYBIND11_NAMESPACE_END(detail)
655
+
656
+ template <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>
657
+ class_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {
658
+ using KeyType = typename Map::key_type;
659
+ using MappedType = typename Map::mapped_type;
660
+ using KeysView = detail::keys_view<Map>;
661
+ using ValuesView = detail::values_view<Map>;
662
+ using ItemsView = detail::items_view<Map>;
663
+ using Class_ = class_<Map, holder_type>;
664
+
665
+ // If either type is a non-module-local bound type then make the map binding non-local as well;
666
+ // otherwise (e.g. both types are either module-local or converting) the map will be
667
+ // module-local.
668
+ auto *tinfo = detail::get_type_info(typeid(MappedType));
669
+ bool local = !tinfo || tinfo->module_local;
670
+ if (local) {
671
+ tinfo = detail::get_type_info(typeid(KeyType));
672
+ local = !tinfo || tinfo->module_local;
673
+ }
674
+
675
+ Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);
676
+ class_<KeysView> keys_view(
677
+ scope, ("KeysView[" + name + "]").c_str(), pybind11::module_local(local));
678
+ class_<ValuesView> values_view(
679
+ scope, ("ValuesView[" + name + "]").c_str(), pybind11::module_local(local));
680
+ class_<ItemsView> items_view(
681
+ scope, ("ItemsView[" + name + "]").c_str(), pybind11::module_local(local));
682
+
683
+ cl.def(init<>());
684
+
685
+ // Register stream insertion operator (if possible)
686
+ detail::map_if_insertion_operator<Map, Class_>(cl, name);
687
+
688
+ cl.def(
689
+ "__bool__",
690
+ [](const Map &m) -> bool { return !m.empty(); },
691
+ "Check whether the map is nonempty");
692
+
693
+ cl.def(
694
+ "__iter__",
695
+ [](Map &m) { return make_key_iterator(m.begin(), m.end()); },
696
+ keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */
697
+ );
698
+
699
+ cl.def(
700
+ "keys",
701
+ [](Map &m) { return KeysView{m}; },
702
+ keep_alive<0, 1>() /* Essential: keep map alive while view exists */
703
+ );
704
+
705
+ cl.def(
706
+ "values",
707
+ [](Map &m) { return ValuesView{m}; },
708
+ keep_alive<0, 1>() /* Essential: keep map alive while view exists */
709
+ );
710
+
711
+ cl.def(
712
+ "items",
713
+ [](Map &m) { return ItemsView{m}; },
714
+ keep_alive<0, 1>() /* Essential: keep map alive while view exists */
715
+ );
716
+
717
+ cl.def(
718
+ "__getitem__",
719
+ [](Map &m, const KeyType &k) -> MappedType & {
720
+ auto it = m.find(k);
721
+ if (it == m.end()) {
722
+ throw key_error();
723
+ }
724
+ return it->second;
725
+ },
726
+ return_value_policy::reference_internal // ref + keepalive
727
+ );
728
+
729
+ cl.def("__contains__", [](Map &m, const KeyType &k) -> bool {
730
+ auto it = m.find(k);
731
+ if (it == m.end()) {
732
+ return false;
733
+ }
734
+ return true;
735
+ });
736
+ // Fallback for when the object is not of the key type
737
+ cl.def("__contains__", [](Map &, const object &) -> bool { return false; });
738
+
739
+ // Assignment provided only if the type is copyable
740
+ detail::map_assignment<Map, Class_>(cl);
741
+
742
+ cl.def("__delitem__", [](Map &m, const KeyType &k) {
743
+ auto it = m.find(k);
744
+ if (it == m.end()) {
745
+ throw key_error();
746
+ }
747
+ m.erase(it);
748
+ });
749
+
750
+ cl.def("__len__", &Map::size);
751
+
752
+ keys_view.def("__len__", [](KeysView &view) { return view.map.size(); });
753
+ keys_view.def(
754
+ "__iter__",
755
+ [](KeysView &view) { return make_key_iterator(view.map.begin(), view.map.end()); },
756
+ keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
757
+ );
758
+ keys_view.def("__contains__", [](KeysView &view, const KeyType &k) -> bool {
759
+ auto it = view.map.find(k);
760
+ if (it == view.map.end()) {
761
+ return false;
762
+ }
763
+ return true;
764
+ });
765
+ // Fallback for when the object is not of the key type
766
+ keys_view.def("__contains__", [](KeysView &, const object &) -> bool { return false; });
767
+
768
+ values_view.def("__len__", [](ValuesView &view) { return view.map.size(); });
769
+ values_view.def(
770
+ "__iter__",
771
+ [](ValuesView &view) { return make_value_iterator(view.map.begin(), view.map.end()); },
772
+ keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
773
+ );
774
+
775
+ items_view.def("__len__", [](ItemsView &view) { return view.map.size(); });
776
+ items_view.def(
777
+ "__iter__",
778
+ [](ItemsView &view) { return make_iterator(view.map.begin(), view.map.end()); },
779
+ keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */
780
+ );
781
+
782
+ return cl;
783
+ }
784
+
785
+ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
third-party/DPVO/DPViewer/pybind11/noxfile.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import nox
4
+
5
+ nox.needs_version = ">=2022.1.7"
6
+ nox.options.sessions = ["lint", "tests", "tests_packaging"]
7
+
8
+ PYTHON_VERISONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy3.7", "pypy3.8"]
9
+
10
+ if os.environ.get("CI", None):
11
+ nox.options.error_on_missing_interpreters = True
12
+
13
+
14
+ @nox.session(reuse_venv=True)
15
+ def lint(session: nox.Session) -> None:
16
+ """
17
+ Lint the codebase (except for clang-format/tidy).
18
+ """
19
+ session.install("pre-commit")
20
+ session.run("pre-commit", "run", "-a")
21
+
22
+
23
+ @nox.session(python=PYTHON_VERISONS)
24
+ def tests(session: nox.Session) -> None:
25
+ """
26
+ Run the tests (requires a compiler).
27
+ """
28
+ tmpdir = session.create_tmp()
29
+ session.install("cmake")
30
+ session.install("-r", "tests/requirements.txt")
31
+ session.run(
32
+ "cmake",
33
+ "-S.",
34
+ f"-B{tmpdir}",
35
+ "-DPYBIND11_WERROR=ON",
36
+ "-DDOWNLOAD_CATCH=ON",
37
+ "-DDOWNLOAD_EIGEN=ON",
38
+ *session.posargs,
39
+ )
40
+ session.run("cmake", "--build", tmpdir)
41
+ session.run("cmake", "--build", tmpdir, "--config=Release", "--target", "check")
42
+
43
+
44
+ @nox.session
45
+ def tests_packaging(session: nox.Session) -> None:
46
+ """
47
+ Run the packaging tests.
48
+ """
49
+
50
+ session.install("-r", "tests/requirements.txt", "--prefer-binary")
51
+ session.run("pytest", "tests/extra_python_package")
52
+
53
+
54
+ @nox.session(reuse_venv=True)
55
+ def docs(session: nox.Session) -> None:
56
+ """
57
+ Build the docs. Pass "serve" to serve.
58
+ """
59
+
60
+ session.install("-r", "docs/requirements.txt")
61
+ session.chdir("docs")
62
+
63
+ if "pdf" in session.posargs:
64
+ session.run("sphinx-build", "-b", "latexpdf", ".", "_build")
65
+ return
66
+
67
+ session.run("sphinx-build", "-b", "html", ".", "_build")
68
+
69
+ if "serve" in session.posargs:
70
+ session.log("Launching docs at http://localhost:8000/ - use Ctrl-C to quit")
71
+ session.run("python", "-m", "http.server", "8000", "-d", "_build/html")
72
+ elif session.posargs:
73
+ session.error("Unsupported argument to docs")
74
+
75
+
76
+ @nox.session(reuse_venv=True)
77
+ def make_changelog(session: nox.Session) -> None:
78
+ """
79
+ Inspect the closed issues and make entries for a changelog.
80
+ """
81
+ session.install("ghapi", "rich")
82
+ session.run("python", "tools/make_changelog.py")
83
+
84
+
85
+ @nox.session(reuse_venv=True)
86
+ def build(session: nox.Session) -> None:
87
+ """
88
+ Build SDists and wheels.
89
+ """
90
+
91
+ session.install("build")
92
+ session.log("Building normal files")
93
+ session.run("python", "-m", "build", *session.posargs)
94
+ session.log("Building pybind11-global files (PYBIND11_GLOBAL_SDIST=1)")
95
+ session.run(
96
+ "python", "-m", "build", *session.posargs, env={"PYBIND11_GLOBAL_SDIST": "1"}
97
+ )
third-party/DPVO/DPViewer/pybind11/pybind11/__init__.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ if sys.version_info < (3, 6):
4
+ msg = "pybind11 does not support Python < 3.6. 2.9 was the last release supporting Python 2.7 and 3.5."
5
+ raise ImportError(msg)
6
+
7
+
8
+ from ._version import __version__, version_info
9
+ from .commands import get_cmake_dir, get_include
10
+
11
+ __all__ = (
12
+ "version_info",
13
+ "__version__",
14
+ "get_include",
15
+ "get_cmake_dir",
16
+ )
third-party/DPVO/DPViewer/pybind11/pybind11/__main__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # pylint: disable=missing-function-docstring
2
+
3
+ import argparse
4
+ import sys
5
+ import sysconfig
6
+
7
+ from .commands import get_cmake_dir, get_include
8
+
9
+
10
+ def print_includes() -> None:
11
+ dirs = [
12
+ sysconfig.get_path("include"),
13
+ sysconfig.get_path("platinclude"),
14
+ get_include(),
15
+ ]
16
+
17
+ # Make unique but preserve order
18
+ unique_dirs = []
19
+ for d in dirs:
20
+ if d and d not in unique_dirs:
21
+ unique_dirs.append(d)
22
+
23
+ print(" ".join("-I" + d for d in unique_dirs))
24
+
25
+
26
+ def main() -> None:
27
+
28
+ parser = argparse.ArgumentParser()
29
+ parser.add_argument(
30
+ "--includes",
31
+ action="store_true",
32
+ help="Include flags for both pybind11 and Python headers.",
33
+ )
34
+ parser.add_argument(
35
+ "--cmakedir",
36
+ action="store_true",
37
+ help="Print the CMake module directory, ideal for setting -Dpybind11_ROOT in CMake.",
38
+ )
39
+ args = parser.parse_args()
40
+ if not sys.argv[1:]:
41
+ parser.print_help()
42
+ if args.includes:
43
+ print_includes()
44
+ if args.cmakedir:
45
+ print(get_cmake_dir())
46
+
47
+
48
+ if __name__ == "__main__":
49
+ main()
third-party/DPVO/DPViewer/pybind11/pybind11/_version.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Union
2
+
3
+
4
+ def _to_int(s: str) -> Union[int, str]:
5
+ try:
6
+ return int(s)
7
+ except ValueError:
8
+ return s
9
+
10
+
11
+ __version__ = "2.10.0.dev1"
12
+ version_info = tuple(_to_int(s) for s in __version__.split("."))
third-party/DPVO/DPViewer/pybind11/pybind11/commands.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ DIR = os.path.abspath(os.path.dirname(__file__))
4
+
5
+
6
+ def get_include(user: bool = False) -> str: # pylint: disable=unused-argument
7
+ """
8
+ Return the path to the pybind11 include directory. The historical "user"
9
+ argument is unused, and may be removed.
10
+ """
11
+ installed_path = os.path.join(DIR, "include")
12
+ source_path = os.path.join(os.path.dirname(DIR), "include")
13
+ return installed_path if os.path.exists(installed_path) else source_path
14
+
15
+
16
+ def get_cmake_dir() -> str:
17
+ """
18
+ Return the path to the pybind11 CMake module directory.
19
+ """
20
+ cmake_installed_path = os.path.join(DIR, "share", "cmake", "pybind11")
21
+ if os.path.exists(cmake_installed_path):
22
+ return cmake_installed_path
23
+
24
+ msg = "pybind11 not installed, installation required to access the CMake files"
25
+ raise ImportError(msg)
third-party/DPVO/DPViewer/pybind11/pybind11/py.typed ADDED
File without changes
third-party/DPVO/DPViewer/pybind11/pybind11/setup_helpers.py ADDED
@@ -0,0 +1,504 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module provides helpers for C++11+ projects using pybind11.
3
+
4
+ LICENSE:
5
+
6
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>, All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are met:
10
+
11
+ 1. Redistributions of source code must retain the above copyright notice, this
12
+ list of conditions and the following disclaimer.
13
+
14
+ 2. Redistributions in binary form must reproduce the above copyright notice,
15
+ this list of conditions and the following disclaimer in the documentation
16
+ and/or other materials provided with the distribution.
17
+
18
+ 3. Neither the name of the copyright holder nor the names of its contributors
19
+ may be used to endorse or promote products derived from this software
20
+ without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ """
33
+
34
+ # IMPORTANT: If you change this file in the pybind11 repo, also review
35
+ # setup_helpers.pyi for matching changes.
36
+ #
37
+ # If you copy this file in, you don't
38
+ # need the .pyi file; it's just an interface file for static type checkers.
39
+
40
+ import contextlib
41
+ import os
42
+ import platform
43
+ import shlex
44
+ import shutil
45
+ import sys
46
+ import sysconfig
47
+ import tempfile
48
+ import threading
49
+ import warnings
50
+ from functools import lru_cache
51
+ from pathlib import Path
52
+ from typing import (
53
+ Any,
54
+ Callable,
55
+ Dict,
56
+ Iterable,
57
+ Iterator,
58
+ List,
59
+ Optional,
60
+ Tuple,
61
+ TypeVar,
62
+ Union,
63
+ )
64
+
65
+ try:
66
+ from setuptools import Extension as _Extension
67
+ from setuptools.command.build_ext import build_ext as _build_ext
68
+ except ImportError:
69
+ from distutils.command.build_ext import build_ext as _build_ext
70
+ from distutils.extension import Extension as _Extension
71
+
72
+ import distutils.ccompiler
73
+ import distutils.errors
74
+
75
+ WIN = sys.platform.startswith("win32") and "mingw" not in sysconfig.get_platform()
76
+ MACOS = sys.platform.startswith("darwin")
77
+ STD_TMPL = "/std:c++{}" if WIN else "-std=c++{}"
78
+
79
+
80
+ # It is recommended to use PEP 518 builds if using this module. However, this
81
+ # file explicitly supports being copied into a user's project directory
82
+ # standalone, and pulling pybind11 with the deprecated setup_requires feature.
83
+ # If you copy the file, remember to add it to your MANIFEST.in, and add the current
84
+ # directory into your path if it sits beside your setup.py.
85
+
86
+
87
+ class Pybind11Extension(_Extension): # type: ignore[misc]
88
+ """
89
+ Build a C++11+ Extension module with pybind11. This automatically adds the
90
+ recommended flags when you init the extension and assumes C++ sources - you
91
+ can further modify the options yourself.
92
+
93
+ The customizations are:
94
+
95
+ * ``/EHsc`` and ``/bigobj`` on Windows
96
+ * ``stdlib=libc++`` on macOS
97
+ * ``visibility=hidden`` and ``-g0`` on Unix
98
+
99
+ Finally, you can set ``cxx_std`` via constructor or afterwards to enable
100
+ flags for C++ std, and a few extra helper flags related to the C++ standard
101
+ level. It is _highly_ recommended you either set this, or use the provided
102
+ ``build_ext``, which will search for the highest supported extension for
103
+ you if the ``cxx_std`` property is not set. Do not set the ``cxx_std``
104
+ property more than once, as flags are added when you set it. Set the
105
+ property to None to disable the addition of C++ standard flags.
106
+
107
+ If you want to add pybind11 headers manually, for example for an exact
108
+ git checkout, then set ``include_pybind11=False``.
109
+ """
110
+
111
+ # flags are prepended, so that they can be further overridden, e.g. by
112
+ # ``extra_compile_args=["-g"]``.
113
+
114
+ def _add_cflags(self, flags: List[str]) -> None:
115
+ self.extra_compile_args[:0] = flags
116
+
117
+ def _add_ldflags(self, flags: List[str]) -> None:
118
+ self.extra_link_args[:0] = flags
119
+
120
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
121
+
122
+ self._cxx_level = 0
123
+ cxx_std = kwargs.pop("cxx_std", 0)
124
+
125
+ if "language" not in kwargs:
126
+ kwargs["language"] = "c++"
127
+
128
+ include_pybind11 = kwargs.pop("include_pybind11", True)
129
+
130
+ super().__init__(*args, **kwargs)
131
+
132
+ # Include the installed package pybind11 headers
133
+ if include_pybind11:
134
+ # If using setup_requires, this fails the first time - that's okay
135
+ try:
136
+ import pybind11
137
+
138
+ pyinc = pybind11.get_include()
139
+
140
+ if pyinc not in self.include_dirs:
141
+ self.include_dirs.append(pyinc)
142
+ except ModuleNotFoundError:
143
+ pass
144
+
145
+ self.cxx_std = cxx_std
146
+
147
+ cflags = []
148
+ ldflags = []
149
+ if WIN:
150
+ cflags += ["/EHsc", "/bigobj"]
151
+ else:
152
+ cflags += ["-fvisibility=hidden"]
153
+ env_cflags = os.environ.get("CFLAGS", "")
154
+ env_cppflags = os.environ.get("CPPFLAGS", "")
155
+ c_cpp_flags = shlex.split(env_cflags) + shlex.split(env_cppflags)
156
+ if not any(opt.startswith("-g") for opt in c_cpp_flags):
157
+ cflags += ["-g0"]
158
+ if MACOS:
159
+ cflags += ["-stdlib=libc++"]
160
+ ldflags += ["-stdlib=libc++"]
161
+ self._add_cflags(cflags)
162
+ self._add_ldflags(ldflags)
163
+
164
+ @property
165
+ def cxx_std(self) -> int:
166
+ """
167
+ The CXX standard level. If set, will add the required flags. If left at
168
+ 0, it will trigger an automatic search when pybind11's build_ext is
169
+ used. If None, will have no effect. Besides just the flags, this may
170
+ add a macos-min 10.9 or 10.14 flag if MACOSX_DEPLOYMENT_TARGET is
171
+ unset.
172
+ """
173
+ return self._cxx_level
174
+
175
+ @cxx_std.setter
176
+ def cxx_std(self, level: int) -> None:
177
+
178
+ if self._cxx_level:
179
+ warnings.warn("You cannot safely change the cxx_level after setting it!")
180
+
181
+ # MSVC 2015 Update 3 and later only have 14 (and later 17) modes, so
182
+ # force a valid flag here.
183
+ if WIN and level == 11:
184
+ level = 14
185
+
186
+ self._cxx_level = level
187
+
188
+ if not level:
189
+ return
190
+
191
+ cflags = [STD_TMPL.format(level)]
192
+ ldflags = []
193
+
194
+ if MACOS and "MACOSX_DEPLOYMENT_TARGET" not in os.environ:
195
+ # C++17 requires a higher min version of macOS. An earlier version
196
+ # (10.12 or 10.13) can be set manually via environment variable if
197
+ # you are careful in your feature usage, but 10.14 is the safest
198
+ # setting for general use. However, never set higher than the
199
+ # current macOS version!
200
+ current_macos = tuple(int(x) for x in platform.mac_ver()[0].split(".")[:2])
201
+ desired_macos = (10, 9) if level < 17 else (10, 14)
202
+ macos_string = ".".join(str(x) for x in min(current_macos, desired_macos))
203
+ macosx_min = f"-mmacosx-version-min={macos_string}"
204
+ cflags += [macosx_min]
205
+ ldflags += [macosx_min]
206
+
207
+ self._add_cflags(cflags)
208
+ self._add_ldflags(ldflags)
209
+
210
+
211
+ # Just in case someone clever tries to multithread
212
+ tmp_chdir_lock = threading.Lock()
213
+
214
+
215
+ @contextlib.contextmanager
216
+ def tmp_chdir() -> Iterator[str]:
217
+ "Prepare and enter a temporary directory, cleanup when done"
218
+
219
+ # Threadsafe
220
+ with tmp_chdir_lock:
221
+ olddir = os.getcwd()
222
+ try:
223
+ tmpdir = tempfile.mkdtemp()
224
+ os.chdir(tmpdir)
225
+ yield tmpdir
226
+ finally:
227
+ os.chdir(olddir)
228
+ shutil.rmtree(tmpdir)
229
+
230
+
231
+ # cf http://bugs.python.org/issue26689
232
+ def has_flag(compiler: Any, flag: str) -> bool:
233
+ """
234
+ Return the flag if a flag name is supported on the
235
+ specified compiler, otherwise None (can be used as a boolean).
236
+ If multiple flags are passed, return the first that matches.
237
+ """
238
+
239
+ with tmp_chdir():
240
+ fname = Path("flagcheck.cpp")
241
+ # Don't trigger -Wunused-parameter.
242
+ fname.write_text("int main (int, char **) { return 0; }", encoding="utf-8")
243
+
244
+ try:
245
+ compiler.compile([str(fname)], extra_postargs=[flag])
246
+ except distutils.errors.CompileError:
247
+ return False
248
+ return True
249
+
250
+
251
+ # Every call will cache the result
252
+ cpp_flag_cache = None
253
+
254
+
255
+ @lru_cache()
256
+ def auto_cpp_level(compiler: Any) -> Union[str, int]:
257
+ """
258
+ Return the max supported C++ std level (17, 14, or 11). Returns latest on Windows.
259
+ """
260
+
261
+ if WIN:
262
+ return "latest"
263
+
264
+ levels = [17, 14, 11]
265
+
266
+ for level in levels:
267
+ if has_flag(compiler, STD_TMPL.format(level)):
268
+ return level
269
+
270
+ msg = "Unsupported compiler -- at least C++11 support is needed!"
271
+ raise RuntimeError(msg)
272
+
273
+
274
+ class build_ext(_build_ext): # type: ignore[misc] # noqa: N801
275
+ """
276
+ Customized build_ext that allows an auto-search for the highest supported
277
+ C++ level for Pybind11Extension. This is only needed for the auto-search
278
+ for now, and is completely optional otherwise.
279
+ """
280
+
281
+ def build_extensions(self) -> None:
282
+ """
283
+ Build extensions, injecting C++ std for Pybind11Extension if needed.
284
+ """
285
+
286
+ for ext in self.extensions:
287
+ if hasattr(ext, "_cxx_level") and ext._cxx_level == 0:
288
+ ext.cxx_std = auto_cpp_level(self.compiler)
289
+
290
+ super().build_extensions()
291
+
292
+
293
+ def intree_extensions(
294
+ paths: Iterable[str], package_dir: Optional[Dict[str, str]] = None
295
+ ) -> List[Pybind11Extension]:
296
+ """
297
+ Generate Pybind11Extensions from source files directly located in a Python
298
+ source tree.
299
+
300
+ ``package_dir`` behaves as in ``setuptools.setup``. If unset, the Python
301
+ package root parent is determined as the first parent directory that does
302
+ not contain an ``__init__.py`` file.
303
+ """
304
+ exts = []
305
+
306
+ if package_dir is None:
307
+ for path in paths:
308
+ parent, _ = os.path.split(path)
309
+ while os.path.exists(os.path.join(parent, "__init__.py")):
310
+ parent, _ = os.path.split(parent)
311
+ relname, _ = os.path.splitext(os.path.relpath(path, parent))
312
+ qualified_name = relname.replace(os.path.sep, ".")
313
+ exts.append(Pybind11Extension(qualified_name, [path]))
314
+ return exts
315
+
316
+ for path in paths:
317
+ for prefix, parent in package_dir.items():
318
+ if path.startswith(parent):
319
+ relname, _ = os.path.splitext(os.path.relpath(path, parent))
320
+ qualified_name = relname.replace(os.path.sep, ".")
321
+ if prefix:
322
+ qualified_name = prefix + "." + qualified_name
323
+ exts.append(Pybind11Extension(qualified_name, [path]))
324
+ break
325
+ else:
326
+ msg = (
327
+ f"path {path} is not a child of any of the directories listed "
328
+ f"in 'package_dir' ({package_dir})"
329
+ )
330
+ raise ValueError(msg)
331
+
332
+ return exts
333
+
334
+
335
+ def naive_recompile(obj: str, src: str) -> bool:
336
+ """
337
+ This will recompile only if the source file changes. It does not check
338
+ header files, so a more advanced function or Ccache is better if you have
339
+ editable header files in your package.
340
+ """
341
+ return os.stat(obj).st_mtime < os.stat(src).st_mtime
342
+
343
+
344
+ def no_recompile(obg: str, src: str) -> bool: # pylint: disable=unused-argument
345
+ """
346
+ This is the safest but slowest choice (and is the default) - will always
347
+ recompile sources.
348
+ """
349
+ return True
350
+
351
+
352
+ S = TypeVar("S", bound="ParallelCompile")
353
+
354
+ CCompilerMethod = Callable[
355
+ [
356
+ distutils.ccompiler.CCompiler,
357
+ List[str],
358
+ Optional[str],
359
+ Optional[Union[Tuple[str], Tuple[str, Optional[str]]]],
360
+ Optional[List[str]],
361
+ bool,
362
+ Optional[List[str]],
363
+ Optional[List[str]],
364
+ Optional[List[str]],
365
+ ],
366
+ List[str],
367
+ ]
368
+
369
+
370
+ # Optional parallel compile utility
371
+ # inspired by: http://stackoverflow.com/questions/11013851/speeding-up-build-process-with-distutils
372
+ # and: https://github.com/tbenthompson/cppimport/blob/stable/cppimport/build_module.py
373
+ # and NumPy's parallel distutils module:
374
+ # https://github.com/numpy/numpy/blob/master/numpy/distutils/ccompiler.py
375
+ class ParallelCompile:
376
+ """
377
+ Make a parallel compile function. Inspired by
378
+ numpy.distutils.ccompiler.CCompiler.compile and cppimport.
379
+
380
+ This takes several arguments that allow you to customize the compile
381
+ function created:
382
+
383
+ envvar:
384
+ Set an environment variable to control the compilation threads, like
385
+ NPY_NUM_BUILD_JOBS
386
+ default:
387
+ 0 will automatically multithread, or 1 will only multithread if the
388
+ envvar is set.
389
+ max:
390
+ The limit for automatic multithreading if non-zero
391
+ needs_recompile:
392
+ A function of (obj, src) that returns True when recompile is needed. No
393
+ effect in isolated mode; use ccache instead, see
394
+ https://github.com/matplotlib/matplotlib/issues/1507/
395
+
396
+ To use::
397
+
398
+ ParallelCompile("NPY_NUM_BUILD_JOBS").install()
399
+
400
+ or::
401
+
402
+ with ParallelCompile("NPY_NUM_BUILD_JOBS"):
403
+ setup(...)
404
+
405
+ By default, this assumes all files need to be recompiled. A smarter
406
+ function can be provided via needs_recompile. If the output has not yet
407
+ been generated, the compile will always run, and this function is not
408
+ called.
409
+ """
410
+
411
+ __slots__ = ("envvar", "default", "max", "_old", "needs_recompile")
412
+
413
+ def __init__(
414
+ self,
415
+ envvar: Optional[str] = None,
416
+ default: int = 0,
417
+ max: int = 0, # pylint: disable=redefined-builtin
418
+ needs_recompile: Callable[[str, str], bool] = no_recompile,
419
+ ) -> None:
420
+ self.envvar = envvar
421
+ self.default = default
422
+ self.max = max
423
+ self.needs_recompile = needs_recompile
424
+ self._old: List[CCompilerMethod] = []
425
+
426
+ def function(self) -> CCompilerMethod:
427
+ """
428
+ Builds a function object usable as distutils.ccompiler.CCompiler.compile.
429
+ """
430
+
431
+ def compile_function(
432
+ compiler: distutils.ccompiler.CCompiler,
433
+ sources: List[str],
434
+ output_dir: Optional[str] = None,
435
+ macros: Optional[Union[Tuple[str], Tuple[str, Optional[str]]]] = None,
436
+ include_dirs: Optional[List[str]] = None,
437
+ debug: bool = False,
438
+ extra_preargs: Optional[List[str]] = None,
439
+ extra_postargs: Optional[List[str]] = None,
440
+ depends: Optional[List[str]] = None,
441
+ ) -> Any:
442
+
443
+ # These lines are directly from distutils.ccompiler.CCompiler
444
+ macros, objects, extra_postargs, pp_opts, build = compiler._setup_compile( # type: ignore[attr-defined]
445
+ output_dir, macros, include_dirs, sources, depends, extra_postargs
446
+ )
447
+ cc_args = compiler._get_cc_args(pp_opts, debug, extra_preargs) # type: ignore[attr-defined]
448
+
449
+ # The number of threads; start with default.
450
+ threads = self.default
451
+
452
+ # Determine the number of compilation threads, unless set by an environment variable.
453
+ if self.envvar is not None:
454
+ threads = int(os.environ.get(self.envvar, self.default))
455
+
456
+ def _single_compile(obj: Any) -> None:
457
+ try:
458
+ src, ext = build[obj]
459
+ except KeyError:
460
+ return
461
+
462
+ if not os.path.exists(obj) or self.needs_recompile(obj, src):
463
+ compiler._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) # type: ignore[attr-defined]
464
+
465
+ try:
466
+ # Importing .synchronize checks for platforms that have some multiprocessing
467
+ # capabilities but lack semaphores, such as AWS Lambda and Android Termux.
468
+ import multiprocessing.synchronize
469
+ from multiprocessing.pool import ThreadPool
470
+ except ImportError:
471
+ threads = 1
472
+
473
+ if threads == 0:
474
+ try:
475
+ threads = multiprocessing.cpu_count()
476
+ threads = self.max if self.max and self.max < threads else threads
477
+ except NotImplementedError:
478
+ threads = 1
479
+
480
+ if threads > 1:
481
+ with ThreadPool(threads) as pool:
482
+ for _ in pool.imap_unordered(_single_compile, objects):
483
+ pass
484
+ else:
485
+ for ob in objects:
486
+ _single_compile(ob)
487
+
488
+ return objects
489
+
490
+ return compile_function
491
+
492
+ def install(self: S) -> S:
493
+ """
494
+ Installs the compile function into distutils.ccompiler.CCompiler.compile.
495
+ """
496
+ distutils.ccompiler.CCompiler.compile = self.function() # type: ignore[assignment]
497
+ return self
498
+
499
+ def __enter__(self: S) -> S:
500
+ self._old.append(distutils.ccompiler.CCompiler.compile)
501
+ return self.install()
502
+
503
+ def __exit__(self, *args: Any) -> None:
504
+ distutils.ccompiler.CCompiler.compile = self._old.pop() # type: ignore[assignment]
third-party/DPVO/DPViewer/pybind11/pyproject.toml ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [build-system]
2
+ requires = ["setuptools>=42", "cmake>=3.18", "ninja"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [tool.check-manifest]
6
+ ignore = [
7
+ "tests/**",
8
+ "docs/**",
9
+ "tools/**",
10
+ "include/**",
11
+ ".*",
12
+ "pybind11/include/**",
13
+ "pybind11/share/**",
14
+ "CMakeLists.txt",
15
+ "noxfile.py",
16
+ ]
17
+
18
+ [tool.isort]
19
+ # Needs the compiled .so modules and env.py from tests
20
+ known_first_party = "env,pybind11_cross_module_tests,pybind11_tests,"
21
+ # For black compatibility
22
+ profile = "black"
23
+
24
+ [tool.mypy]
25
+ files = ["pybind11"]
26
+ python_version = "3.6"
27
+ strict = true
28
+ show_error_codes = true
29
+ enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
30
+ warn_unreachable = true
31
+
32
+ [[tool.mypy.overrides]]
33
+ module = ["ghapi.*", "setuptools.*"]
34
+ ignore_missing_imports = true
35
+
36
+
37
+ [tool.pytest.ini_options]
38
+ minversion = "6.0"
39
+ addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
40
+ xfail_strict = true
41
+ filterwarnings = ["error"]
42
+ log_cli_level = "info"
43
+ testpaths = [
44
+ "tests",
45
+ ]
46
+ timeout=300
47
+
48
+
49
+ [tool.pylint]
50
+ master.py-version = "3.6"
51
+ reports.output-format = "colorized"
52
+ messages_control.disable = [
53
+ "design",
54
+ "fixme",
55
+ "imports",
56
+ "line-too-long",
57
+ "imports",
58
+ "invalid-name",
59
+ "protected-access",
60
+ "missing-module-docstring",
61
+ ]
third-party/DPVO/DPViewer/pybind11/setup.cfg ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [metadata]
2
+ long_description = file: README.rst
3
+ long_description_content_type = text/x-rst
4
+ description = Seamless operability between C++11 and Python
5
+ author = Wenzel Jakob
6
+ author_email = [email protected]
7
+ url = https://github.com/pybind/pybind11
8
+ license = BSD
9
+
10
+ classifiers =
11
+ Development Status :: 5 - Production/Stable
12
+ Intended Audience :: Developers
13
+ Topic :: Software Development :: Libraries :: Python Modules
14
+ Topic :: Utilities
15
+ Programming Language :: C++
16
+ Programming Language :: Python :: 3 :: Only
17
+ Programming Language :: Python :: 3.6
18
+ Programming Language :: Python :: 3.7
19
+ Programming Language :: Python :: 3.8
20
+ Programming Language :: Python :: 3.9
21
+ Programming Language :: Python :: 3.10
22
+ License :: OSI Approved :: BSD License
23
+ Programming Language :: Python :: Implementation :: PyPy
24
+ Programming Language :: Python :: Implementation :: CPython
25
+ Programming Language :: C++
26
+ Topic :: Software Development :: Libraries :: Python Modules
27
+
28
+ keywords =
29
+ C++11
30
+ Python bindings
31
+
32
+ project_urls =
33
+ Documentation = https://pybind11.readthedocs.io/
34
+ Bug Tracker = https://github.com/pybind/pybind11/issues
35
+ Discussions = https://github.com/pybind/pybind11/discussions
36
+ Changelog = https://pybind11.readthedocs.io/en/latest/changelog.html
37
+ Chat = https://gitter.im/pybind/Lobby
38
+
39
+ [options]
40
+ python_requires = >=3.6
41
+ zip_safe = False
42
+
43
+
44
+ [flake8]
45
+ max-line-length = 120
46
+ show_source = True
47
+ exclude = .git, __pycache__, build, dist, docs, tools, venv
48
+ extend-ignore = E203, E722, B950
49
+ extend-select = B9
third-party/DPVO/DPViewer/pybind11/setup.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ # Setup script for PyPI; use CMakeFile.txt to build extension modules
4
+
5
+ import contextlib
6
+ import os
7
+ import re
8
+ import shutil
9
+ import string
10
+ import subprocess
11
+ import sys
12
+ from pathlib import Path
13
+ from tempfile import TemporaryDirectory
14
+ from typing import Dict, Iterator, List, Union
15
+
16
+ import setuptools.command.sdist
17
+
18
+ DIR = Path(__file__).parent.absolute()
19
+ VERSION_REGEX = re.compile(
20
+ r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE
21
+ )
22
+ VERSION_FILE = Path("pybind11/_version.py")
23
+ COMMON_FILE = Path("include/pybind11/detail/common.h")
24
+
25
+
26
+ def build_expected_version_hex(matches: Dict[str, str]) -> str:
27
+ patch_level_serial = matches["PATCH"]
28
+ serial = None
29
+ major = int(matches["MAJOR"])
30
+ minor = int(matches["MINOR"])
31
+ flds = patch_level_serial.split(".")
32
+ if flds:
33
+ patch = int(flds[0])
34
+ if len(flds) == 1:
35
+ level = "0"
36
+ serial = 0
37
+ elif len(flds) == 2:
38
+ level_serial = flds[1]
39
+ for level in ("a", "b", "c", "dev"):
40
+ if level_serial.startswith(level):
41
+ serial = int(level_serial[len(level) :])
42
+ break
43
+ if serial is None:
44
+ msg = f'Invalid PYBIND11_VERSION_PATCH: "{patch_level_serial}"'
45
+ raise RuntimeError(msg)
46
+ version_hex_str = f"{major:02x}{minor:02x}{patch:02x}{level[:1]}{serial:x}"
47
+ return f"0x{version_hex_str.upper()}"
48
+
49
+
50
+ # PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers
51
+ # files, and the sys.prefix files (CMake and headers).
52
+
53
+ global_sdist = os.environ.get("PYBIND11_GLOBAL_SDIST", False)
54
+
55
+ setup_py = Path(
56
+ "tools/setup_global.py.in" if global_sdist else "tools/setup_main.py.in"
57
+ )
58
+ extra_cmd = 'cmdclass["sdist"] = SDist\n'
59
+
60
+ to_src = (
61
+ (Path("pyproject.toml"), Path("tools/pyproject.toml")),
62
+ (Path("setup.py"), setup_py),
63
+ )
64
+
65
+
66
+ # Read the listed version
67
+ loc: Dict[str, str] = {}
68
+ code = compile(VERSION_FILE.read_text(encoding="utf-8"), "pybind11/_version.py", "exec")
69
+ exec(code, loc)
70
+ version = loc["__version__"]
71
+
72
+ # Verify that the version matches the one in C++
73
+ matches = dict(VERSION_REGEX.findall(COMMON_FILE.read_text(encoding="utf8")))
74
+ cpp_version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches)
75
+ if version != cpp_version:
76
+ msg = f"Python version {version} does not match C++ version {cpp_version}!"
77
+ raise RuntimeError(msg)
78
+
79
+ version_hex = matches.get("HEX", "MISSING")
80
+ exp_version_hex = build_expected_version_hex(matches)
81
+ if version_hex != exp_version_hex:
82
+ msg = f"PYBIND11_VERSION_HEX {version_hex} does not match expected value {exp_version_hex}!"
83
+ raise RuntimeError(msg)
84
+
85
+
86
+ # TODO: use literals & overload (typing extensions or Python 3.8)
87
+ def get_and_replace(
88
+ filename: Path, binary: bool = False, **opts: str
89
+ ) -> Union[bytes, str]:
90
+ if binary:
91
+ contents = filename.read_bytes()
92
+ return string.Template(contents.decode()).substitute(opts).encode()
93
+
94
+ return string.Template(filename.read_text()).substitute(opts)
95
+
96
+
97
+ # Use our input files instead when making the SDist (and anything that depends
98
+ # on it, like a wheel)
99
+ class SDist(setuptools.command.sdist.sdist): # type: ignore[misc]
100
+ def make_release_tree(self, base_dir: str, files: List[str]) -> None:
101
+ super().make_release_tree(base_dir, files)
102
+
103
+ for to, src in to_src:
104
+ txt = get_and_replace(src, binary=True, version=version, extra_cmd="")
105
+
106
+ dest = Path(base_dir) / to
107
+
108
+ # This is normally linked, so unlink before writing!
109
+ dest.unlink()
110
+ dest.write_bytes(txt) # type: ignore[arg-type]
111
+
112
+
113
+ # Remove the CMake install directory when done
114
+ @contextlib.contextmanager
115
+ def remove_output(*sources: str) -> Iterator[None]:
116
+ try:
117
+ yield
118
+ finally:
119
+ for src in sources:
120
+ shutil.rmtree(src)
121
+
122
+
123
+ with remove_output("pybind11/include", "pybind11/share"):
124
+ # Generate the files if they are not present.
125
+ with TemporaryDirectory() as tmpdir:
126
+ cmd = ["cmake", "-S", ".", "-B", tmpdir] + [
127
+ "-DCMAKE_INSTALL_PREFIX=pybind11",
128
+ "-DBUILD_TESTING=OFF",
129
+ "-DPYBIND11_NOPYTHON=ON",
130
+ ]
131
+ if "CMAKE_ARGS" in os.environ:
132
+ fcommand = [
133
+ c
134
+ for c in os.environ["CMAKE_ARGS"].split()
135
+ if "DCMAKE_INSTALL_PREFIX" not in c
136
+ ]
137
+ cmd += fcommand
138
+ subprocess.run(cmd, check=True, cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)
139
+ subprocess.run(
140
+ ["cmake", "--install", tmpdir],
141
+ check=True,
142
+ cwd=DIR,
143
+ stdout=sys.stdout,
144
+ stderr=sys.stderr,
145
+ )
146
+
147
+ txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd)
148
+ code = compile(txt, setup_py, "exec")
149
+ exec(code, {"SDist": SDist})
third-party/DPVO/DPViewer/pybind11/tools/FindCatch.cmake ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # - Find the Catch test framework or download it (single header)
2
+ #
3
+ # This is a quick module for internal use. It assumes that Catch is
4
+ # REQUIRED and that a minimum version is provided (not EXACT). If
5
+ # a suitable version isn't found locally, the single header file
6
+ # will be downloaded and placed in the build dir: PROJECT_BINARY_DIR.
7
+ #
8
+ # This code sets the following variables:
9
+ # CATCH_INCLUDE_DIR - path to catch.hpp
10
+ # CATCH_VERSION - version number
11
+
12
+ option(DOWNLOAD_CATCH "Download catch2 if not found")
13
+
14
+ if(NOT Catch_FIND_VERSION)
15
+ message(FATAL_ERROR "A version number must be specified.")
16
+ elseif(Catch_FIND_REQUIRED)
17
+ message(FATAL_ERROR "This module assumes Catch is not required.")
18
+ elseif(Catch_FIND_VERSION_EXACT)
19
+ message(FATAL_ERROR "Exact version numbers are not supported, only minimum.")
20
+ endif()
21
+
22
+ # Extract the version number from catch.hpp
23
+ function(_get_catch_version)
24
+ file(
25
+ STRINGS "${CATCH_INCLUDE_DIR}/catch.hpp" version_line
26
+ REGEX "Catch v.*"
27
+ LIMIT_COUNT 1)
28
+ if(version_line MATCHES "Catch v([0-9]+)\\.([0-9]+)\\.([0-9]+)")
29
+ set(CATCH_VERSION
30
+ "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}"
31
+ PARENT_SCOPE)
32
+ endif()
33
+ endfunction()
34
+
35
+ # Download the single-header version of Catch
36
+ function(_download_catch version destination_dir)
37
+ message(STATUS "Downloading catch v${version}...")
38
+ set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp)
39
+ file(DOWNLOAD ${url} "${destination_dir}/catch.hpp" STATUS status)
40
+ list(GET status 0 error)
41
+ if(error)
42
+ message(FATAL_ERROR "Could not download ${url}")
43
+ endif()
44
+ set(CATCH_INCLUDE_DIR
45
+ "${destination_dir}"
46
+ CACHE INTERNAL "")
47
+ endfunction()
48
+
49
+ # Look for catch locally
50
+ find_path(
51
+ CATCH_INCLUDE_DIR
52
+ NAMES catch.hpp
53
+ PATH_SUFFIXES catch2)
54
+ if(CATCH_INCLUDE_DIR)
55
+ _get_catch_version()
56
+ endif()
57
+
58
+ # Download the header if it wasn't found or if it's outdated
59
+ if(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION})
60
+ if(DOWNLOAD_CATCH)
61
+ _download_catch(${Catch_FIND_VERSION} "${PROJECT_BINARY_DIR}/catch/")
62
+ _get_catch_version()
63
+ else()
64
+ set(CATCH_FOUND FALSE)
65
+ return()
66
+ endif()
67
+ endif()
68
+
69
+ add_library(Catch2::Catch2 IMPORTED INTERFACE)
70
+ set_property(TARGET Catch2::Catch2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CATCH_INCLUDE_DIR}")
71
+
72
+ set(CATCH_FOUND TRUE)
third-party/DPVO/DPViewer/pybind11/tools/FindEigen3.cmake ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # - Try to find Eigen3 lib
2
+ #
3
+ # This module supports requiring a minimum version, e.g. you can do
4
+ # find_package(Eigen3 3.1.2)
5
+ # to require version 3.1.2 or newer of Eigen3.
6
+ #
7
+ # Once done this will define
8
+ #
9
+ # EIGEN3_FOUND - system has eigen lib with correct version
10
+ # EIGEN3_INCLUDE_DIR - the eigen include directory
11
+ # EIGEN3_VERSION - eigen version
12
+
13
+ # Copyright (c) 2006, 2007 Montel Laurent, <[email protected]>
14
+ # Copyright (c) 2008, 2009 Gael Guennebaud, <[email protected]>
15
+ # Copyright (c) 2009 Benoit Jacob <[email protected]>
16
+ # Redistribution and use is allowed according to the terms of the 2-clause BSD license.
17
+
18
+ if(NOT Eigen3_FIND_VERSION)
19
+ if(NOT Eigen3_FIND_VERSION_MAJOR)
20
+ set(Eigen3_FIND_VERSION_MAJOR 2)
21
+ endif(NOT Eigen3_FIND_VERSION_MAJOR)
22
+ if(NOT Eigen3_FIND_VERSION_MINOR)
23
+ set(Eigen3_FIND_VERSION_MINOR 91)
24
+ endif(NOT Eigen3_FIND_VERSION_MINOR)
25
+ if(NOT Eigen3_FIND_VERSION_PATCH)
26
+ set(Eigen3_FIND_VERSION_PATCH 0)
27
+ endif(NOT Eigen3_FIND_VERSION_PATCH)
28
+
29
+ set(Eigen3_FIND_VERSION
30
+ "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")
31
+ endif(NOT Eigen3_FIND_VERSION)
32
+
33
+ macro(_eigen3_check_version)
34
+ file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
35
+
36
+ string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match
37
+ "${_eigen3_version_header}")
38
+ set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
39
+ string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match
40
+ "${_eigen3_version_header}")
41
+ set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")
42
+ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match
43
+ "${_eigen3_version_header}")
44
+ set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")
45
+
46
+ set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})
47
+ if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
48
+ set(EIGEN3_VERSION_OK FALSE)
49
+ else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
50
+ set(EIGEN3_VERSION_OK TRUE)
51
+ endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})
52
+
53
+ if(NOT EIGEN3_VERSION_OK)
54
+
55
+ message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "
56
+ "but at least version ${Eigen3_FIND_VERSION} is required")
57
+ endif(NOT EIGEN3_VERSION_OK)
58
+ endmacro(_eigen3_check_version)
59
+
60
+ if(EIGEN3_INCLUDE_DIR)
61
+
62
+ # in cache already
63
+ _eigen3_check_version()
64
+ set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})
65
+
66
+ else(EIGEN3_INCLUDE_DIR)
67
+ if(NOT DEFINED KDE4_INCLUDE_DIR)
68
+ set(KDE4_INCLUDE_DIR "")
69
+ endif()
70
+
71
+ find_path(
72
+ EIGEN3_INCLUDE_DIR
73
+ NAMES signature_of_eigen3_matrix_library
74
+ PATHS ${CMAKE_INSTALL_PREFIX}/include ${KDE4_INCLUDE_DIR}
75
+ PATH_SUFFIXES eigen3 eigen)
76
+
77
+ if(EIGEN3_INCLUDE_DIR)
78
+ _eigen3_check_version()
79
+ endif(EIGEN3_INCLUDE_DIR)
80
+
81
+ include(FindPackageHandleStandardArgs)
82
+ find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)
83
+
84
+ mark_as_advanced(EIGEN3_INCLUDE_DIR)
85
+
86
+ endif(EIGEN3_INCLUDE_DIR)
third-party/DPVO/DPViewer/pybind11/tools/FindPythonLibsNew.cmake ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # - Find python libraries
2
+ # This module finds the libraries corresponding to the Python interpreter
3
+ # FindPythonInterp provides.
4
+ # This code sets the following variables:
5
+ #
6
+ # PYTHONLIBS_FOUND - have the Python libs been found
7
+ # PYTHON_PREFIX - path to the Python installation
8
+ # PYTHON_LIBRARIES - path to the python library
9
+ # PYTHON_INCLUDE_DIRS - path to where Python.h is found
10
+ # PYTHON_MODULE_EXTENSION - lib extension, e.g. '.so' or '.pyd'
11
+ # PYTHON_MODULE_PREFIX - lib name prefix: usually an empty string
12
+ # PYTHON_SITE_PACKAGES - path to installation site-packages
13
+ # PYTHON_IS_DEBUG - whether the Python interpreter is a debug build
14
+ #
15
+ # Thanks to talljimbo for the patch adding the 'LDVERSION' config
16
+ # variable usage.
17
+
18
+ #=============================================================================
19
+ # Copyright 2001-2009 Kitware, Inc.
20
+ # Copyright 2012 Continuum Analytics, Inc.
21
+ #
22
+ # All rights reserved.
23
+ #
24
+ # Redistribution and use in source and binary forms, with or without
25
+ # modification, are permitted provided that the following conditions
26
+ # are met:
27
+ #
28
+ # * Redistributions of source code must retain the above copyright
29
+ # notice, this list of conditions and the following disclaimer.
30
+ #
31
+ # * Redistributions in binary form must reproduce the above copyright
32
+ # notice, this list of conditions and the following disclaimer in the
33
+ # documentation and/or other materials provided with the distribution.
34
+ #
35
+ # * Neither the names of Kitware, Inc., the Insight Software Consortium,
36
+ # nor the names of their contributors may be used to endorse or promote
37
+ # products derived from this software without specific prior written
38
+ # permission.
39
+ #
40
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43
+ # # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44
+ # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51
+ #=============================================================================
52
+
53
+ # Checking for the extension makes sure that `LibsNew` was found and not just `Libs`.
54
+ if(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION)
55
+ return()
56
+ endif()
57
+
58
+ if(PythonLibsNew_FIND_QUIETLY)
59
+ set(_pythonlibs_quiet QUIET)
60
+ else()
61
+ set(_pythonlibs_quiet "")
62
+ endif()
63
+
64
+ if(PythonLibsNew_FIND_REQUIRED)
65
+ set(_pythonlibs_required REQUIRED)
66
+ endif()
67
+
68
+ # Check to see if the `python` command is present and from a virtual
69
+ # environment, conda, or GHA activation - if it is, try to use that.
70
+
71
+ if(NOT DEFINED PYTHON_EXECUTABLE)
72
+ if(DEFINED ENV{VIRTUAL_ENV})
73
+ find_program(
74
+ PYTHON_EXECUTABLE python
75
+ PATHS "$ENV{VIRTUAL_ENV}" "$ENV{VIRTUAL_ENV}/bin"
76
+ NO_DEFAULT_PATH)
77
+ elseif(DEFINED ENV{CONDA_PREFIX})
78
+ find_program(
79
+ PYTHON_EXECUTABLE python
80
+ PATHS "$ENV{CONDA_PREFIX}" "$ENV{CONDA_PREFIX}/bin"
81
+ NO_DEFAULT_PATH)
82
+ elseif(DEFINED ENV{pythonLocation})
83
+ find_program(
84
+ PYTHON_EXECUTABLE python
85
+ PATHS "$ENV{pythonLocation}" "$ENV{pythonLocation}/bin"
86
+ NO_DEFAULT_PATH)
87
+ endif()
88
+ if(NOT PYTHON_EXECUTABLE)
89
+ unset(PYTHON_EXECUTABLE)
90
+ endif()
91
+ endif()
92
+
93
+ # Use the Python interpreter to find the libs.
94
+ if(NOT PythonLibsNew_FIND_VERSION)
95
+ set(PythonLibsNew_FIND_VERSION "3.6")
96
+ endif()
97
+
98
+ find_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required}
99
+ ${_pythonlibs_quiet})
100
+
101
+ if(NOT PYTHONINTERP_FOUND)
102
+ set(PYTHONLIBS_FOUND FALSE)
103
+ set(PythonLibsNew_FOUND FALSE)
104
+ return()
105
+ endif()
106
+
107
+ # According to https://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter
108
+ # testing whether sys has the gettotalrefcount function is a reliable, cross-platform
109
+ # way to detect a CPython debug interpreter.
110
+ #
111
+ # The library suffix is from the config var LDVERSION sometimes, otherwise
112
+ # VERSION. VERSION will typically be like "2.7" on unix, and "27" on windows.
113
+ execute_process(
114
+ COMMAND
115
+ "${PYTHON_EXECUTABLE}" "-c" "
116
+ import sys;import struct;
117
+ import sysconfig as s
118
+ USE_SYSCONFIG = sys.version_info >= (3, 10)
119
+ if not USE_SYSCONFIG:
120
+ from distutils import sysconfig as ds
121
+ print('.'.join(str(v) for v in sys.version_info));
122
+ print(sys.prefix);
123
+ if USE_SYSCONFIG:
124
+ scheme = s.get_default_scheme()
125
+ if scheme == 'posix_local':
126
+ # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/
127
+ scheme = 'posix_prefix'
128
+ print(s.get_path('platinclude', scheme))
129
+ print(s.get_path('platlib'))
130
+ print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))
131
+ else:
132
+ print(ds.get_python_inc(plat_specific=True));
133
+ print(ds.get_python_lib(plat_specific=True));
134
+ print(ds.get_config_var('EXT_SUFFIX') or ds.get_config_var('SO'));
135
+ print(hasattr(sys, 'gettotalrefcount')+0);
136
+ print(struct.calcsize('@P'));
137
+ print(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));
138
+ print(s.get_config_var('LIBDIR') or '');
139
+ print(s.get_config_var('MULTIARCH') or '');
140
+ "
141
+ RESULT_VARIABLE _PYTHON_SUCCESS
142
+ OUTPUT_VARIABLE _PYTHON_VALUES
143
+ ERROR_VARIABLE _PYTHON_ERROR_VALUE)
144
+
145
+ if(NOT _PYTHON_SUCCESS MATCHES 0)
146
+ if(PythonLibsNew_FIND_REQUIRED)
147
+ message(FATAL_ERROR "Python config failure:\n${_PYTHON_ERROR_VALUE}")
148
+ endif()
149
+ set(PYTHONLIBS_FOUND FALSE)
150
+ set(PythonLibsNew_FOUND FALSE)
151
+ return()
152
+ endif()
153
+
154
+ # Can manually set values when cross-compiling
155
+ macro(_PYBIND11_GET_IF_UNDEF lst index name)
156
+ if(NOT DEFINED "${name}")
157
+ list(GET "${lst}" "${index}" "${name}")
158
+ endif()
159
+ endmacro()
160
+
161
+ # Convert the process output into a list
162
+ if(WIN32)
163
+ string(REGEX REPLACE "\\\\" "/" _PYTHON_VALUES ${_PYTHON_VALUES})
164
+ endif()
165
+ string(REGEX REPLACE ";" "\\\\;" _PYTHON_VALUES ${_PYTHON_VALUES})
166
+ string(REGEX REPLACE "\n" ";" _PYTHON_VALUES ${_PYTHON_VALUES})
167
+ _pybind11_get_if_undef(_PYTHON_VALUES 0 _PYTHON_VERSION_LIST)
168
+ _pybind11_get_if_undef(_PYTHON_VALUES 1 PYTHON_PREFIX)
169
+ _pybind11_get_if_undef(_PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)
170
+ _pybind11_get_if_undef(_PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)
171
+ _pybind11_get_if_undef(_PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)
172
+ _pybind11_get_if_undef(_PYTHON_VALUES 5 PYTHON_IS_DEBUG)
173
+ _pybind11_get_if_undef(_PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)
174
+ _pybind11_get_if_undef(_PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)
175
+ _pybind11_get_if_undef(_PYTHON_VALUES 8 PYTHON_LIBDIR)
176
+ _pybind11_get_if_undef(_PYTHON_VALUES 9 PYTHON_MULTIARCH)
177
+
178
+ # Make sure the Python has the same pointer-size as the chosen compiler
179
+ # Skip if CMAKE_SIZEOF_VOID_P is not defined
180
+ # This should be skipped for (non-Apple) cross-compiles (like EMSCRIPTEN)
181
+ if(NOT CMAKE_CROSSCOMPILING
182
+ AND CMAKE_SIZEOF_VOID_P
183
+ AND (NOT "${PYTHON_SIZEOF_VOID_P}" STREQUAL "${CMAKE_SIZEOF_VOID_P}"))
184
+ if(PythonLibsNew_FIND_REQUIRED)
185
+ math(EXPR _PYTHON_BITS "${PYTHON_SIZEOF_VOID_P} * 8")
186
+ math(EXPR _CMAKE_BITS "${CMAKE_SIZEOF_VOID_P} * 8")
187
+ message(FATAL_ERROR "Python config failure: Python is ${_PYTHON_BITS}-bit, "
188
+ "chosen compiler is ${_CMAKE_BITS}-bit")
189
+ endif()
190
+ set(PYTHONLIBS_FOUND FALSE)
191
+ set(PythonLibsNew_FOUND FALSE)
192
+ return()
193
+ endif()
194
+
195
+ # The built-in FindPython didn't always give the version numbers
196
+ string(REGEX REPLACE "\\." ";" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST})
197
+ list(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR)
198
+ list(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR)
199
+ list(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)
200
+ set(PYTHON_VERSION "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}")
201
+
202
+ # Make sure all directory separators are '/'
203
+ string(REGEX REPLACE "\\\\" "/" PYTHON_PREFIX "${PYTHON_PREFIX}")
204
+ string(REGEX REPLACE "\\\\" "/" PYTHON_INCLUDE_DIR "${PYTHON_INCLUDE_DIR}")
205
+ string(REGEX REPLACE "\\\\" "/" PYTHON_SITE_PACKAGES "${PYTHON_SITE_PACKAGES}")
206
+
207
+ if(CMAKE_HOST_WIN32)
208
+ set(PYTHON_LIBRARY "${PYTHON_PREFIX}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib")
209
+
210
+ # when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the
211
+ # original python installation. They may be found relative to PYTHON_INCLUDE_DIR.
212
+ if(NOT EXISTS "${PYTHON_LIBRARY}")
213
+ get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)
214
+ set(PYTHON_LIBRARY "${_PYTHON_ROOT}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib")
215
+ endif()
216
+
217
+ # if we are in MSYS & MINGW, and we didn't find windows python lib, look for system python lib
218
+ if(DEFINED ENV{MSYSTEM}
219
+ AND MINGW
220
+ AND NOT EXISTS "${PYTHON_LIBRARY}")
221
+ if(PYTHON_MULTIARCH)
222
+ set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}")
223
+ else()
224
+ set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}")
225
+ endif()
226
+ unset(PYTHON_LIBRARY)
227
+ find_library(
228
+ PYTHON_LIBRARY
229
+ NAMES "python${PYTHON_LIBRARY_SUFFIX}"
230
+ PATHS ${_PYTHON_LIBS_SEARCH}
231
+ NO_DEFAULT_PATH)
232
+ endif()
233
+
234
+ # raise an error if the python libs are still not found.
235
+ if(NOT EXISTS "${PYTHON_LIBRARY}")
236
+ message(FATAL_ERROR "Python libraries not found")
237
+ endif()
238
+
239
+ else()
240
+ if(PYTHON_MULTIARCH)
241
+ set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}" "${PYTHON_LIBDIR}")
242
+ else()
243
+ set(_PYTHON_LIBS_SEARCH "${PYTHON_LIBDIR}")
244
+ endif()
245
+ #message(STATUS "Searching for Python libs in ${_PYTHON_LIBS_SEARCH}")
246
+ # Probably this needs to be more involved. It would be nice if the config
247
+ # information the python interpreter itself gave us were more complete.
248
+ find_library(
249
+ PYTHON_LIBRARY
250
+ NAMES "python${PYTHON_LIBRARY_SUFFIX}"
251
+ PATHS ${_PYTHON_LIBS_SEARCH}
252
+ NO_DEFAULT_PATH)
253
+
254
+ # If all else fails, just set the name/version and let the linker figure out the path.
255
+ if(NOT PYTHON_LIBRARY)
256
+ set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX})
257
+ endif()
258
+ endif()
259
+
260
+ mark_as_advanced(PYTHON_LIBRARY PYTHON_INCLUDE_DIR)
261
+
262
+ # We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the
263
+ # cache entries because they are meant to specify the location of a single
264
+ # library. We now set the variables listed by the documentation for this
265
+ # module.
266
+ set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
267
+ set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
268
+ if(NOT PYTHON_DEBUG_LIBRARY)
269
+ set(PYTHON_DEBUG_LIBRARY "")
270
+ endif()
271
+ set(PYTHON_DEBUG_LIBRARIES "${PYTHON_DEBUG_LIBRARY}")
272
+
273
+ find_package_message(PYTHON "Found PythonLibs: ${PYTHON_LIBRARY}"
274
+ "${PYTHON_EXECUTABLE}${PYTHON_VERSION_STRING}")
275
+
276
+ set(PYTHONLIBS_FOUND TRUE)
277
+ set(PythonLibsNew_FOUND TRUE)
278
+
279
+ if(NOT PYTHON_MODULE_PREFIX)
280
+ set(PYTHON_MODULE_PREFIX "")
281
+ endif()
third-party/DPVO/DPViewer/pybind11/tools/check-style.sh ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ #
3
+ # Script to check include/test code for common pybind11 code style errors.
4
+ #
5
+ # This script currently checks for
6
+ #
7
+ # 1. missing space between keyword and parenthesis, e.g.: for(, if(, while(
8
+ # 2. Missing space between right parenthesis and brace, e.g. 'for (...){'
9
+ # 3. opening brace on its own line. It should always be on the same line as the
10
+ # if/while/for/do statement.
11
+ #
12
+ # Invoke as: tools/check-style.sh <filenames>
13
+ #
14
+
15
+ check_style_errors=0
16
+ IFS=$'\n'
17
+
18
+
19
+ found="$(grep '\<\(if\|for\|while\|catch\)(\|){' "$@" -rn --color=always)"
20
+ if [ -n "$found" ]; then
21
+ echo -e '\033[31;01mError: found the following coding style problems:\033[0m'
22
+ check_style_errors=1
23
+ echo "${found//^/ /}"
24
+ fi
25
+
26
+ found="$(awk '
27
+ function prefix(filename, lineno) {
28
+ return " \033[35m" filename "\033[36m:\033[32m" lineno "\033[36m:\033[0m"
29
+ }
30
+ function mark(pattern, string) { sub(pattern, "\033[01;31m&\033[0m", string); return string }
31
+ last && /^\s*{/ {
32
+ print prefix(FILENAME, FNR-1) mark("\\)\\s*$", last)
33
+ print prefix(FILENAME, FNR) mark("^\\s*{", $0)
34
+ last=""
35
+ }
36
+ { last = /(if|for|while|catch|switch)\s*\(.*\)\s*$/ ? $0 : "" }
37
+ ' "$(find include -type f)" "$@")"
38
+ if [ -n "$found" ]; then
39
+ check_style_errors=1
40
+ echo -e '\033[31;01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files:\033[0m'
41
+ echo "$found"
42
+ fi
43
+
44
+ exit $check_style_errors
third-party/DPVO/DPViewer/pybind11/tools/cmake_uninstall.cmake.in ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
2
+
3
+ if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
4
+ message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
5
+ endif()
6
+
7
+ file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
8
+ string(REGEX REPLACE "\n" ";" files "${files}")
9
+ foreach(file ${files})
10
+ message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
11
+ if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
12
+ exec_program(
13
+ "@CMAKE_COMMAND@" ARGS
14
+ "-E remove \"$ENV{DESTDIR}${file}\""
15
+ OUTPUT_VARIABLE rm_out
16
+ RETURN_VALUE rm_retval)
17
+ if(NOT "${rm_retval}" STREQUAL 0)
18
+ message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
19
+ endif()
20
+ else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
21
+ message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
22
+ endif()
23
+ endforeach()
third-party/DPVO/DPViewer/pybind11/tools/libsize.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ # Internal build script for generating debugging test .so size.
5
+ # Usage:
6
+ # python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the
7
+ # size in it, then overwrites save.txt with the new size for future runs.
8
+
9
+ if len(sys.argv) != 3:
10
+ sys.exit("Invalid arguments: usage: python libsize.py file.so save.txt")
11
+
12
+ lib = sys.argv[1]
13
+ save = sys.argv[2]
14
+
15
+ if not os.path.exists(lib):
16
+ sys.exit(f"Error: requested file ({lib}) does not exist")
17
+
18
+ libsize = os.path.getsize(lib)
19
+
20
+ print("------", os.path.basename(lib), "file size:", libsize, end="")
21
+
22
+ if os.path.exists(save):
23
+ with open(save) as sf:
24
+ oldsize = int(sf.readline())
25
+
26
+ if oldsize > 0:
27
+ change = libsize - oldsize
28
+ if change == 0:
29
+ print(" (no change)")
30
+ else:
31
+ print(f" (change of {change:+} bytes = {change / oldsize:+.2%})")
32
+ else:
33
+ print()
34
+
35
+ with open(save, "w") as sf:
36
+ sf.write(str(libsize))
third-party/DPVO/DPViewer/pybind11/tools/make_changelog.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ import re
4
+
5
+ import ghapi.all
6
+ from rich import print
7
+ from rich.syntax import Syntax
8
+
9
+ ENTRY = re.compile(
10
+ r"""
11
+ Suggested \s changelog \s entry:
12
+ .*
13
+ ```rst
14
+ \s*
15
+ (.*?)
16
+ \s*
17
+ ```
18
+ """,
19
+ re.DOTALL | re.VERBOSE,
20
+ )
21
+
22
+ print()
23
+
24
+
25
+ api = ghapi.all.GhApi(owner="pybind", repo="pybind11")
26
+
27
+ issues_pages = ghapi.page.paged(
28
+ api.issues.list_for_repo, labels="needs changelog", state="closed"
29
+ )
30
+ issues = (issue for page in issues_pages for issue in page)
31
+ missing = []
32
+
33
+ for issue in issues:
34
+ changelog = ENTRY.findall(issue.body)
35
+ if changelog:
36
+ (msg,) = changelog
37
+ if not msg.startswith("* "):
38
+ msg = "* " + msg
39
+ if not msg.endswith("."):
40
+ msg += "."
41
+
42
+ msg += f"\n `#{issue.number} <{issue.html_url}>`_"
43
+
44
+ print(Syntax(msg, "rst", theme="ansi_light", word_wrap=True))
45
+ print()
46
+
47
+ else:
48
+ missing.append(issue)
49
+
50
+ if missing:
51
+ print()
52
+ print("[blue]" + "-" * 30)
53
+ print()
54
+
55
+ for issue in missing:
56
+ print(f"[red bold]Missing:[/red bold][red] {issue.title}")
57
+ print(f"[red] {issue.html_url}\n")
58
+
59
+ print("[bold]Template:\n")
60
+ msg = "## Suggested changelog entry:\n\n```rst\n\n```"
61
+ print(Syntax(msg, "md", theme="ansi_light"))
62
+
63
+ print()
third-party/DPVO/DPViewer/pybind11/tools/pybind11Common.cmake ADDED
@@ -0,0 +1,385 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #[======================================================[.rst
2
+
3
+ Adds the following targets::
4
+
5
+ pybind11::pybind11 - link to headers and pybind11
6
+ pybind11::module - Adds module links
7
+ pybind11::embed - Adds embed links
8
+ pybind11::lto - Link time optimizations (manual selection)
9
+ pybind11::thin_lto - Link time optimizations (manual selection)
10
+ pybind11::python_link_helper - Adds link to Python libraries
11
+ pybind11::windows_extras - MSVC bigobj and mp for building multithreaded
12
+ pybind11::opt_size - avoid optimizations that increase code size
13
+
14
+ Adds the following functions::
15
+
16
+ pybind11_strip(target) - strip target after building on linux/macOS
17
+ pybind11_find_import(module) - See if a module is installed.
18
+
19
+ #]======================================================]
20
+
21
+ # CMake 3.10 has an include_guard command, but we can't use that yet
22
+ # include_guard(global) (pre-CMake 3.10)
23
+ if(TARGET pybind11::lto)
24
+ return()
25
+ endif()
26
+
27
+ # If we are in subdirectory mode, all IMPORTED targets must be GLOBAL. If we
28
+ # are in CONFIG mode, they should be "normal" targets instead.
29
+ # In CMake 3.11+ you can promote a target to global after you create it,
30
+ # which might be simpler than this check.
31
+ get_property(
32
+ is_config
33
+ TARGET pybind11::headers
34
+ PROPERTY IMPORTED)
35
+ if(NOT is_config)
36
+ set(optional_global GLOBAL)
37
+ endif()
38
+
39
+ # If not run in Python mode, we still would like this to at least
40
+ # include pybind11's include directory:
41
+ set(pybind11_INCLUDE_DIRS
42
+ "${pybind11_INCLUDE_DIR}"
43
+ CACHE INTERNAL "Include directory for pybind11 (Python not requested)")
44
+
45
+ # --------------------- Shared targets ----------------------------
46
+
47
+ # Build an interface library target:
48
+ add_library(pybind11::pybind11 IMPORTED INTERFACE ${optional_global})
49
+ set_property(
50
+ TARGET pybind11::pybind11
51
+ APPEND
52
+ PROPERTY INTERFACE_LINK_LIBRARIES pybind11::headers)
53
+
54
+ # Build a module target:
55
+ add_library(pybind11::module IMPORTED INTERFACE ${optional_global})
56
+ set_property(
57
+ TARGET pybind11::module
58
+ APPEND
59
+ PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
60
+
61
+ # Build an embed library target:
62
+ add_library(pybind11::embed IMPORTED INTERFACE ${optional_global})
63
+ set_property(
64
+ TARGET pybind11::embed
65
+ APPEND
66
+ PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)
67
+
68
+ # --------------------------- link helper ---------------------------
69
+
70
+ add_library(pybind11::python_link_helper IMPORTED INTERFACE ${optional_global})
71
+
72
+ if(CMAKE_VERSION VERSION_LESS 3.13)
73
+ # In CMake 3.11+, you can set INTERFACE properties via the normal methods, and
74
+ # this would be simpler.
75
+ set_property(
76
+ TARGET pybind11::python_link_helper
77
+ APPEND
78
+ PROPERTY INTERFACE_LINK_LIBRARIES "$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>")
79
+ else()
80
+ # link_options was added in 3.13+
81
+ # This is safer, because you are ensured the deduplication pass in CMake will not consider
82
+ # these separate and remove one but not the other.
83
+ set_property(
84
+ TARGET pybind11::python_link_helper
85
+ APPEND
86
+ PROPERTY INTERFACE_LINK_OPTIONS "$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>")
87
+ endif()
88
+
89
+ # ------------------------ Windows extras -------------------------
90
+
91
+ add_library(pybind11::windows_extras IMPORTED INTERFACE ${optional_global})
92
+
93
+ if(MSVC) # That's also clang-cl
94
+ # /bigobj is needed for bigger binding projects due to the limit to 64k
95
+ # addressable sections
96
+ set_property(
97
+ TARGET pybind11::windows_extras
98
+ APPEND
99
+ PROPERTY INTERFACE_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CXX>:/bigobj>)
100
+
101
+ # /MP enables multithreaded builds (relevant when there are many files) for MSVC
102
+ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # no Clang no Intel
103
+ if(CMAKE_VERSION VERSION_LESS 3.11)
104
+ set_property(
105
+ TARGET pybind11::windows_extras
106
+ APPEND
107
+ PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:/MP>)
108
+ else()
109
+ # Only set these options for C++ files. This is important so that, for
110
+ # instance, projects that include other types of source files like CUDA
111
+ # .cu files don't get these options propagated to nvcc since that would
112
+ # cause the build to fail.
113
+ set_property(
114
+ TARGET pybind11::windows_extras
115
+ APPEND
116
+ PROPERTY INTERFACE_COMPILE_OPTIONS
117
+ $<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)
118
+ endif()
119
+ endif()
120
+ endif()
121
+
122
+ # ----------------------- Optimize binary size --------------------------
123
+
124
+ add_library(pybind11::opt_size IMPORTED INTERFACE ${optional_global})
125
+
126
+ if(MSVC)
127
+ set(PYBIND11_OPT_SIZE /Os)
128
+ else()
129
+ set(PYBIND11_OPT_SIZE -Os)
130
+ endif()
131
+
132
+ set_property(
133
+ TARGET pybind11::opt_size
134
+ APPEND
135
+ PROPERTY INTERFACE_COMPILE_OPTIONS $<$<CONFIG:Release>:${PYBIND11_OPT_SIZE}>
136
+ $<$<CONFIG:MinSizeRel>:${PYBIND11_OPT_SIZE}>
137
+ $<$<CONFIG:RelWithDebInfo>:${PYBIND11_OPT_SIZE}>)
138
+
139
+ # ----------------------- Legacy option --------------------------
140
+
141
+ # Warn or error if old variable name used
142
+ if(PYBIND11_CPP_STANDARD)
143
+ string(REGEX MATCH [[..$]] VAL "${PYBIND11_CPP_STANDARD}")
144
+ if(CMAKE_CXX_STANDARD)
145
+ if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)
146
+ message(WARNING "CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match "
147
+ "PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, "
148
+ "please remove PYBIND11_CPP_STANDARD from your cache")
149
+ endif()
150
+ else()
151
+ set(supported_standards 11 14 17 20)
152
+ if("${VAL}" IN_LIST supported_standards)
153
+ message(WARNING "USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_CPP_STANDARD")
154
+ set(CMAKE_CXX_STANDARD
155
+ ${VAL}
156
+ CACHE STRING "From PYBIND11_CPP_STANDARD")
157
+ else()
158
+ message(FATAL_ERROR "PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD "
159
+ "(last two chars: ${VAL} not understood as a valid CXX std)")
160
+ endif()
161
+ endif()
162
+ endif()
163
+
164
+ # --------------------- Python specifics -------------------------
165
+
166
+ # Check to see which Python mode we are in, new, old, or no python
167
+ if(PYBIND11_NOPYTHON)
168
+ set(_pybind11_nopython ON)
169
+ elseif(
170
+ PYBIND11_FINDPYTHON
171
+ OR Python_FOUND
172
+ OR Python2_FOUND
173
+ OR Python3_FOUND)
174
+ # New mode
175
+ include("${CMAKE_CURRENT_LIST_DIR}/pybind11NewTools.cmake")
176
+
177
+ else()
178
+
179
+ # Classic mode
180
+ include("${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake")
181
+
182
+ endif()
183
+
184
+ # --------------------- pybind11_find_import -------------------------------
185
+
186
+ if(NOT _pybind11_nopython)
187
+ # Check to see if modules are importable. Use REQUIRED to force an error if
188
+ # one of the modules is not found. <package_name>_FOUND will be set if the
189
+ # package was found (underscores replace dashes if present). QUIET will hide
190
+ # the found message, and VERSION will require a minimum version. A successful
191
+ # find will cache the result.
192
+ function(pybind11_find_import PYPI_NAME)
193
+ # CMake variables need underscores (PyPI doesn't care)
194
+ string(REPLACE "-" "_" NORM_PYPI_NAME "${PYPI_NAME}")
195
+
196
+ # Return if found previously
197
+ if(${NORM_PYPI_NAME}_FOUND)
198
+ return()
199
+ endif()
200
+
201
+ set(options "REQUIRED;QUIET")
202
+ set(oneValueArgs "VERSION")
203
+ cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "" ${ARGN})
204
+
205
+ if(ARG_REQUIRED)
206
+ set(status_level FATAL_ERROR)
207
+ else()
208
+ set(status_level WARNING)
209
+ endif()
210
+
211
+ execute_process(
212
+ COMMAND
213
+ ${${_Python}_EXECUTABLE} -c
214
+ "from pkg_resources import get_distribution; print(get_distribution('${PYPI_NAME}').version)"
215
+ RESULT_VARIABLE RESULT_PRESENT
216
+ OUTPUT_VARIABLE PKG_VERSION
217
+ ERROR_QUIET)
218
+
219
+ string(STRIP "${PKG_VERSION}" PKG_VERSION)
220
+
221
+ # If a result is present, this failed
222
+ if(RESULT_PRESENT)
223
+ set(${NORM_PYPI_NAME}_FOUND
224
+ ${NORM_PYPI_NAME}-NOTFOUND
225
+ CACHE INTERNAL "")
226
+ # Always warn or error
227
+ message(
228
+ ${status_level}
229
+ "Missing: ${PYPI_NAME} ${ARG_VERSION}\nTry: ${${_Python}_EXECUTABLE} -m pip install ${PYPI_NAME}"
230
+ )
231
+ else()
232
+ if(ARG_VERSION AND PKG_VERSION VERSION_LESS ARG_VERSION)
233
+ message(
234
+ ${status_level}
235
+ "Version incorrect: ${PYPI_NAME} ${PKG_VERSION} found, ${ARG_VERSION} required - try upgrading"
236
+ )
237
+ else()
238
+ set(${NORM_PYPI_NAME}_FOUND
239
+ YES
240
+ CACHE INTERNAL "")
241
+ set(${NORM_PYPI_NAME}_VERSION
242
+ ${PKG_VERSION}
243
+ CACHE INTERNAL "")
244
+ endif()
245
+ if(NOT ARG_QUIET)
246
+ message(STATUS "Found ${PYPI_NAME} ${PKG_VERSION}")
247
+ endif()
248
+ endif()
249
+ if(NOT ARG_VERSION OR (NOT PKG_VERSION VERSION_LESS ARG_VERSION))
250
+ # We have successfully found a good version, cache to avoid calling again.
251
+ endif()
252
+ endfunction()
253
+ endif()
254
+
255
+ # --------------------- LTO -------------------------------
256
+
257
+ include(CheckCXXCompilerFlag)
258
+
259
+ # Checks whether the given CXX/linker flags can compile and link a cxx file.
260
+ # cxxflags and linkerflags are lists of flags to use. The result variable is a
261
+ # unique variable name for each set of flags: the compilation result will be
262
+ # cached base on the result variable. If the flags work, sets them in
263
+ # cxxflags_out/linkerflags_out internal cache variables (in addition to
264
+ # ${result}).
265
+ function(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out
266
+ linkerflags_out)
267
+ set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})
268
+ check_cxx_compiler_flag("${cxxflags}" ${result})
269
+ if(${result})
270
+ set(${cxxflags_out}
271
+ "${cxxflags}"
272
+ PARENT_SCOPE)
273
+ set(${linkerflags_out}
274
+ "${linkerflags}"
275
+ PARENT_SCOPE)
276
+ endif()
277
+ endfunction()
278
+
279
+ function(_pybind11_generate_lto target prefer_thin_lto)
280
+ if(MINGW)
281
+ message(STATUS "${target} disabled (problems with undefined symbols for MinGW for now)")
282
+ return()
283
+ endif()
284
+
285
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
286
+ set(cxx_append "")
287
+ set(linker_append "")
288
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT APPLE)
289
+ # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it
290
+ set(linker_append ";$<$<CONFIG:MinSizeRel>:-O3>")
291
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT MINGW)
292
+ set(cxx_append ";-fno-fat-lto-objects")
293
+ endif()
294
+
295
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le" OR CMAKE_SYSTEM_PROCESSOR MATCHES "mips64")
296
+ set(NO_FLTO_ARCH TRUE)
297
+ else()
298
+ set(NO_FLTO_ARCH FALSE)
299
+ endif()
300
+
301
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang"
302
+ AND prefer_thin_lto
303
+ AND NOT NO_FLTO_ARCH)
304
+ _pybind11_return_if_cxx_and_linker_flags_work(
305
+ HAS_FLTO_THIN "-flto=thin${cxx_append}" "-flto=thin${linker_append}"
306
+ PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
307
+ endif()
308
+
309
+ if(NOT HAS_FLTO_THIN AND NOT NO_FLTO_ARCH)
310
+ _pybind11_return_if_cxx_and_linker_flags_work(
311
+ HAS_FLTO "-flto${cxx_append}" "-flto${linker_append}" PYBIND11_LTO_CXX_FLAGS
312
+ PYBIND11_LTO_LINKER_FLAGS)
313
+ endif()
314
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
315
+ # Intel equivalent to LTO is called IPO
316
+ _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO "-ipo" "-ipo"
317
+ PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
318
+ elseif(MSVC)
319
+ # cmake only interprets libraries as linker flags when they start with a - (otherwise it
320
+ # converts /LTCG to \LTCG as if it was a Windows path). Luckily MSVC supports passing flags
321
+ # with - instead of /, even if it is a bit non-standard:
322
+ _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG "/GL" "-LTCG"
323
+ PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)
324
+ endif()
325
+
326
+ # Enable LTO flags if found, except for Debug builds
327
+ if(PYBIND11_LTO_CXX_FLAGS)
328
+ # CONFIG takes multiple values in CMake 3.19+, until then we have to use OR
329
+ set(is_debug "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>")
330
+ set(not_debug "$<NOT:${is_debug}>")
331
+ set(cxx_lang "$<COMPILE_LANGUAGE:CXX>")
332
+ if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)
333
+ set(genex "${not_debug}")
334
+ else()
335
+ set(genex "$<AND:${not_debug},${cxx_lang}>")
336
+ endif()
337
+ set_property(
338
+ TARGET ${target}
339
+ APPEND
340
+ PROPERTY INTERFACE_COMPILE_OPTIONS "$<${genex}:${PYBIND11_LTO_CXX_FLAGS}>")
341
+ if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
342
+ message(STATUS "${target} enabled")
343
+ endif()
344
+ else()
345
+ if(CMAKE_PROJECT_NAME STREQUAL "pybind11")
346
+ message(STATUS "${target} disabled (not supported by the compiler and/or linker)")
347
+ endif()
348
+ endif()
349
+
350
+ if(PYBIND11_LTO_LINKER_FLAGS)
351
+ if(CMAKE_VERSION VERSION_LESS 3.11)
352
+ set_property(
353
+ TARGET ${target}
354
+ APPEND
355
+ PROPERTY INTERFACE_LINK_LIBRARIES "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
356
+ else()
357
+ set_property(
358
+ TARGET ${target}
359
+ APPEND
360
+ PROPERTY INTERFACE_LINK_OPTIONS "$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>")
361
+ endif()
362
+ endif()
363
+ endfunction()
364
+
365
+ add_library(pybind11::lto IMPORTED INTERFACE ${optional_global})
366
+ _pybind11_generate_lto(pybind11::lto FALSE)
367
+
368
+ add_library(pybind11::thin_lto IMPORTED INTERFACE ${optional_global})
369
+ _pybind11_generate_lto(pybind11::thin_lto TRUE)
370
+
371
+ # ---------------------- pybind11_strip -----------------------------
372
+
373
+ function(pybind11_strip target_name)
374
+ # Strip unnecessary sections of the binary on Linux/macOS
375
+ if(CMAKE_STRIP)
376
+ if(APPLE)
377
+ set(x_opt -x)
378
+ endif()
379
+
380
+ add_custom_command(
381
+ TARGET ${target_name}
382
+ POST_BUILD
383
+ COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${target_name}>)
384
+ endif()
385
+ endfunction()
third-party/DPVO/DPViewer/pybind11/tools/pybind11Config.cmake.in ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #[=============================================================================[.rst:
2
+
3
+ pybind11Config.cmake
4
+ ####################
5
+
6
+ Exported variables
7
+ ==================
8
+
9
+ This module sets the following variables in your project:
10
+
11
+ ``pybind11_FOUND``
12
+ true if pybind11 and all required components found on the system
13
+ ``pybind11_VERSION``
14
+ pybind11 version in format Major.Minor.Release
15
+ ``pybind11_VERSION_TYPE``
16
+ pybind11 version type (``dev*`` or empty for a release)
17
+ ``pybind11_INCLUDE_DIRS``
18
+ Directories where pybind11 and python headers are located.
19
+ ``pybind11_INCLUDE_DIR``
20
+ Directory where pybind11 headers are located.
21
+ ``pybind11_DEFINITIONS``
22
+ Definitions necessary to use pybind11, namely USING_pybind11.
23
+ ``pybind11_LIBRARIES``
24
+ Compile flags and python libraries (as needed) to link against.
25
+ ``pybind11_LIBRARY``
26
+ Empty.
27
+
28
+ Available components: None
29
+
30
+
31
+ Exported targets
32
+ ================
33
+
34
+ If pybind11 is found, this module defines the following ``IMPORTED``
35
+ interface library targets:
36
+
37
+ ``pybind11::module``
38
+ for extension modules.
39
+ ``pybind11::embed``
40
+ for embedding the Python interpreter.
41
+
42
+ Python headers, libraries (as needed by platform), and the C++ standard
43
+ are attached to the target.
44
+
45
+ Advanced targets are also supplied - these are primary for users building
46
+ complex applications, and they are available in all modes:
47
+
48
+ ``pybind11::headers``
49
+ Just the pybind11 headers and minimum compile requirements.
50
+ ``pybind11::pybind11``
51
+ Python headers too.
52
+ ``pybind11::python_link_helper``
53
+ Just the "linking" part of ``pybind11:module``, for CMake < 3.15.
54
+ ``pybind11::thin_lto``
55
+ An alternative to ``INTERPROCEDURAL_OPTIMIZATION``.
56
+ ``pybind11::lto``
57
+ An alternative to ``INTERPROCEDURAL_OPTIMIZATION`` (also avoids thin LTO on clang).
58
+ ``pybind11::windows_extras``
59
+ Adds bigobj and mp for MSVC.
60
+
61
+ Modes
62
+ =====
63
+
64
+ There are two modes provided; classic, which is built on the old Python
65
+ discovery packages in CMake, or the new FindPython mode, which uses FindPython
66
+ from 3.12+ forward (3.15+ _highly_ recommended).
67
+
68
+ New FindPython mode
69
+ ^^^^^^^^^^^^^^^^^^^
70
+
71
+ To activate this mode, either call ``find_package(Python COMPONENTS Interpreter Development)``
72
+ before finding this package, or set the ``PYBIND11_FINDPYTHON`` variable to ON. In this mode,
73
+ you can either use the basic targets, or use the FindPython tools:
74
+
75
+ .. code-block:: cmake
76
+
77
+ find_package(Python COMPONENTS Interpreter Development)
78
+ find_package(pybind11 CONFIG)
79
+
80
+ # pybind11 method:
81
+ pybind11_add_module(MyModule1 src1.cpp)
82
+
83
+ # Python method:
84
+ Python_add_library(MyModule2 src2.cpp)
85
+ target_link_libraries(MyModule2 pybind11::headers)
86
+ set_target_properties(MyModule2 PROPERTIES
87
+ INTERPROCEDURAL_OPTIMIZATION ON
88
+ CXX_VISIBILITY_PRESET ON
89
+ VISIBILITY_INLINES_HIDDEN ON)
90
+
91
+ If you build targets yourself, you may be interested in stripping the output
92
+ for reduced size; this is the one other feature that the helper function gives you.
93
+
94
+ Classic mode
95
+ ^^^^^^^^^^^^
96
+
97
+ Set PythonLibsNew variables to influence python detection and
98
+ CMAKE_CXX_STANDARD to influence standard setting.
99
+
100
+ .. code-block:: cmake
101
+
102
+ find_package(pybind11 CONFIG REQUIRED)
103
+
104
+ # Create an extension module
105
+ add_library(mylib MODULE main.cpp)
106
+ target_link_libraries(mylib PUBLIC pybind11::module)
107
+
108
+ # Or embed the Python interpreter into an executable
109
+ add_executable(myexe main.cpp)
110
+ target_link_libraries(myexe PUBLIC pybind11::embed)
111
+
112
+
113
+ Hints
114
+ =====
115
+
116
+ The following variables can be set to guide the search for this package:
117
+
118
+ ``pybind11_DIR``
119
+ CMake variable, set to directory containing this Config file.
120
+ ``CMAKE_PREFIX_PATH``
121
+ CMake variable, set to root directory of this package.
122
+ ``PATH``
123
+ Environment variable, set to bin directory of this package.
124
+ ``CMAKE_DISABLE_FIND_PACKAGE_pybind11``
125
+ CMake variable, disables ``find_package(pybind11)`` when not ``REQUIRED``,
126
+ perhaps to force internal build.
127
+
128
+ Commands
129
+ ========
130
+
131
+ pybind11_add_module
132
+ ^^^^^^^^^^^^^^^^^^^
133
+
134
+ This module defines the following commands to assist with creating Python modules:
135
+
136
+ .. code-block:: cmake
137
+
138
+ pybind11_add_module(<target>
139
+ [STATIC|SHARED|MODULE]
140
+ [THIN_LTO] [OPT_SIZE] [NO_EXTRAS] [WITHOUT_SOABI]
141
+ <files>...
142
+ )
143
+
144
+ Add a module and setup all helpers. You can select the type of the library; the
145
+ default is ``MODULE``. There are several options:
146
+
147
+ ``OPT_SIZE``
148
+ Optimize for size, even if the ``CMAKE_BUILD_TYPE`` is not ``MinSizeRel``.
149
+ ``THIN_LTO``
150
+ Use thin TLO instead of regular if there's a choice (pybind11's selection
151
+ is disabled if ``CMAKE_INTERPROCEDURAL_OPTIMIZATIONS`` is set).
152
+ ``WITHOUT_SOABI``
153
+ Disable the SOABI component (``PYBIND11_NEWPYTHON`` mode only).
154
+ ``NO_EXTRAS``
155
+ Disable all extras, exit immediately after making the module.
156
+
157
+ pybind11_strip
158
+ ^^^^^^^^^^^^^^
159
+
160
+ .. code-block:: cmake
161
+
162
+ pybind11_strip(<target>)
163
+
164
+ Strip a target after building it (linux/macOS), called by ``pybind11_add_module``.
165
+
166
+ pybind11_extension
167
+ ^^^^^^^^^^^^^^^^^^
168
+
169
+ .. code-block:: cmake
170
+
171
+ pybind11_extension(<target>)
172
+
173
+ Sets the Python extension name correctly for Python on your platform, called by
174
+ ``pybind11_add_module``.
175
+
176
+ pybind11_find_import(module)
177
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
178
+
179
+ .. code-block:: cmake
180
+
181
+ pybind11_find_import(<module> [VERSION <number>] [REQUIRED] [QUIET])
182
+
183
+ See if a module is installed. Use the registered name (the one on PyPI). You
184
+ can specify a ``VERSION``, and you can specify ``REQUIRED`` or ``QUIET``. Only available if
185
+ ``NOPYTHON`` mode is not active. Sets ``module_VERSION`` and ``module_FOUND``. Caches the
186
+ result once a valid install is found.
187
+
188
+ Suggested usage
189
+ ===============
190
+
191
+ Using ``find_package`` with version info is not recommended except for release versions.
192
+
193
+ .. code-block:: cmake
194
+
195
+ find_package(pybind11 CONFIG)
196
+ find_package(pybind11 2.9 EXACT CONFIG REQUIRED)
197
+
198
+ #]=============================================================================]
199
+ @PACKAGE_INIT@
200
+
201
+ # Location of pybind11/pybind11.h
202
+ # This will be relative unless explicitly set as absolute
203
+ set(pybind11_INCLUDE_DIR "@pybind11_INCLUDEDIR@")
204
+
205
+ set(pybind11_LIBRARY "")
206
+ set(pybind11_DEFINITIONS USING_pybind11)
207
+ set(pybind11_VERSION_TYPE "@pybind11_VERSION_TYPE@")
208
+
209
+ check_required_components(pybind11)
210
+
211
+ if(TARGET pybind11::python_link_helper)
212
+ # This has already been setup elsewhere, such as with a previous call or
213
+ # add_subdirectory
214
+ return()
215
+ endif()
216
+
217
+ include("${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake")
218
+
219
+ # Easier to use / remember
220
+ add_library(pybind11::headers IMPORTED INTERFACE)
221
+ set_target_properties(pybind11::headers PROPERTIES INTERFACE_LINK_LIBRARIES
222
+ pybind11::pybind11_headers)
223
+
224
+ include("${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake")
225
+
226
+ if(NOT pybind11_FIND_QUIETLY)
227
+ message(
228
+ STATUS
229
+ "Found pybind11: ${pybind11_INCLUDE_DIR} (found version \"${pybind11_VERSION}${pybind11_VERSION_TYPE}\")"
230
+ )
231
+ endif()
third-party/DPVO/DPViewer/pybind11/tools/pybind11NewTools.cmake ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # tools/pybind11NewTools.cmake -- Build system for the pybind11 modules
2
+ #
3
+ # Copyright (c) 2020 Wenzel Jakob <[email protected]> and Henry Schreiner
4
+ #
5
+ # All rights reserved. Use of this source code is governed by a
6
+ # BSD-style license that can be found in the LICENSE file.
7
+
8
+ if(CMAKE_VERSION VERSION_LESS 3.12)
9
+ message(FATAL_ERROR "You cannot use the new FindPython module with CMake < 3.12")
10
+ endif()
11
+
12
+ include_guard(GLOBAL)
13
+
14
+ get_property(
15
+ is_config
16
+ TARGET pybind11::headers
17
+ PROPERTY IMPORTED)
18
+
19
+ if(pybind11_FIND_QUIETLY)
20
+ set(_pybind11_quiet QUIET)
21
+ else()
22
+ set(_pybind11_quiet "")
23
+ endif()
24
+
25
+ if(NOT Python_FOUND AND NOT Python3_FOUND)
26
+ if(NOT DEFINED Python_FIND_IMPLEMENTATIONS)
27
+ set(Python_FIND_IMPLEMENTATIONS CPython PyPy)
28
+ endif()
29
+
30
+ # GitHub Actions like activation
31
+ if(NOT DEFINED Python_ROOT_DIR AND DEFINED ENV{pythonLocation})
32
+ set(Python_ROOT_DIR "$ENV{pythonLocation}")
33
+ endif()
34
+
35
+ find_package(Python 3.6 REQUIRED COMPONENTS Interpreter Development ${_pybind11_quiet})
36
+
37
+ # If we are in submodule mode, export the Python targets to global targets.
38
+ # If this behavior is not desired, FindPython _before_ pybind11.
39
+ if(NOT is_config)
40
+ set_property(TARGET Python::Python PROPERTY IMPORTED_GLOBAL TRUE)
41
+ set_property(TARGET Python::Interpreter PROPERTY IMPORTED_GLOBAL TRUE)
42
+ if(TARGET Python::Module)
43
+ set_property(TARGET Python::Module PROPERTY IMPORTED_GLOBAL TRUE)
44
+ endif()
45
+ endif()
46
+ endif()
47
+
48
+ if(Python_FOUND)
49
+ set(_Python
50
+ Python
51
+ CACHE INTERNAL "" FORCE)
52
+ elseif(Python3_FOUND)
53
+ set(_Python
54
+ Python3
55
+ CACHE INTERNAL "" FORCE)
56
+ endif()
57
+
58
+ if(PYBIND11_MASTER_PROJECT)
59
+ if(${_Python}_INTERPRETER_ID MATCHES "PyPy")
60
+ message(STATUS "PyPy ${${_Python}_PyPy_VERSION} (Py ${${_Python}_VERSION})")
61
+ else()
62
+ message(STATUS "${_Python} ${${_Python}_VERSION}")
63
+ endif()
64
+ endif()
65
+
66
+ # If a user finds Python, they may forget to include the Interpreter component
67
+ # and the following two steps require it. It is highly recommended by CMake
68
+ # when finding development libraries anyway, so we will require it.
69
+ if(NOT DEFINED ${_Python}_EXECUTABLE)
70
+ message(
71
+ FATAL_ERROR
72
+ "${_Python} was found without the Interpreter component. Pybind11 requires this component.")
73
+
74
+ endif()
75
+
76
+ if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST)
77
+ # Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed
78
+ unset(PYTHON_IS_DEBUG CACHE)
79
+ unset(PYTHON_MODULE_EXTENSION CACHE)
80
+ set(PYBIND11_PYTHON_EXECUTABLE_LAST
81
+ "${${_Python}_EXECUTABLE}"
82
+ CACHE INTERNAL "Python executable during the last CMake run")
83
+ endif()
84
+
85
+ if(NOT DEFINED PYTHON_IS_DEBUG)
86
+ # Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter
87
+ execute_process(
88
+ COMMAND "${${_Python}_EXECUTABLE}" "-c"
89
+ "import sys; sys.exit(hasattr(sys, 'gettotalrefcount'))"
90
+ RESULT_VARIABLE _PYTHON_IS_DEBUG)
91
+ set(PYTHON_IS_DEBUG
92
+ "${_PYTHON_IS_DEBUG}"
93
+ CACHE INTERNAL "Python debug status")
94
+ endif()
95
+
96
+ # Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is
97
+ # required for PyPy3 (as of 7.3.1)
98
+ if(NOT DEFINED PYTHON_MODULE_EXTENSION)
99
+ execute_process(
100
+ COMMAND
101
+ "${${_Python}_EXECUTABLE}" "-c"
102
+ "import sys, importlib; s = importlib.import_module('distutils.sysconfig' if sys.version_info < (3, 10) else 'sysconfig'); print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))"
103
+ OUTPUT_VARIABLE _PYTHON_MODULE_EXTENSION
104
+ ERROR_VARIABLE _PYTHON_MODULE_EXTENSION_ERR
105
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
106
+
107
+ if(_PYTHON_MODULE_EXTENSION STREQUAL "")
108
+ message(
109
+ FATAL_ERROR "pybind11 could not query the module file extension, likely the 'distutils'"
110
+ "package is not installed. Full error message:\n${_PYTHON_MODULE_EXTENSION_ERR}")
111
+ endif()
112
+
113
+ # This needs to be available for the pybind11_extension function
114
+ set(PYTHON_MODULE_EXTENSION
115
+ "${_PYTHON_MODULE_EXTENSION}"
116
+ CACHE INTERNAL "")
117
+ endif()
118
+
119
+ # Python debug libraries expose slightly different objects before 3.8
120
+ # https://docs.python.org/3.6/c-api/intro.html#debugging-builds
121
+ # https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
122
+ if(PYTHON_IS_DEBUG)
123
+ set_property(
124
+ TARGET pybind11::pybind11
125
+ APPEND
126
+ PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
127
+ endif()
128
+
129
+ # Check on every access - since Python can change - do nothing in that case.
130
+
131
+ if(DEFINED ${_Python}_INCLUDE_DIRS)
132
+ # Only add Python for build - must be added during the import for config
133
+ # since it has to be re-discovered.
134
+ #
135
+ # This needs to be a target to be included after the local pybind11
136
+ # directory, just in case there there is an installed pybind11 sitting
137
+ # next to Python's includes. It also ensures Python is a SYSTEM library.
138
+ add_library(pybind11::python_headers INTERFACE IMPORTED)
139
+ set_property(
140
+ TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES
141
+ "$<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>")
142
+ set_property(
143
+ TARGET pybind11::pybind11
144
+ APPEND
145
+ PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)
146
+ set(pybind11_INCLUDE_DIRS
147
+ "${pybind11_INCLUDE_DIR}" "${${_Python}_INCLUDE_DIRS}"
148
+ CACHE INTERNAL "Directories where pybind11 and possibly Python headers are located")
149
+ endif()
150
+
151
+ # In CMake 3.18+, you can find these separately, so include an if
152
+ if(TARGET ${_Python}::Python)
153
+ set_property(
154
+ TARGET pybind11::embed
155
+ APPEND
156
+ PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Python)
157
+ endif()
158
+
159
+ # CMake 3.15+ has this
160
+ if(TARGET ${_Python}::Module)
161
+ set_property(
162
+ TARGET pybind11::module
163
+ APPEND
164
+ PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)
165
+ else()
166
+ set_property(
167
+ TARGET pybind11::module
168
+ APPEND
169
+ PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)
170
+ endif()
171
+
172
+ # WITHOUT_SOABI and WITH_SOABI will disable the custom extension handling used by pybind11.
173
+ # WITH_SOABI is passed on to python_add_library.
174
+ function(pybind11_add_module target_name)
175
+ cmake_parse_arguments(PARSE_ARGV 1 ARG
176
+ "STATIC;SHARED;MODULE;THIN_LTO;OPT_SIZE;NO_EXTRAS;WITHOUT_SOABI" "" "")
177
+
178
+ if(ARG_STATIC)
179
+ set(lib_type STATIC)
180
+ elseif(ARG_SHARED)
181
+ set(lib_type SHARED)
182
+ else()
183
+ set(lib_type MODULE)
184
+ endif()
185
+
186
+ if("${_Python}" STREQUAL "Python")
187
+ python_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
188
+ elseif("${_Python}" STREQUAL "Python3")
189
+ python3_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})
190
+ else()
191
+ message(FATAL_ERROR "Cannot detect FindPython version: ${_Python}")
192
+ endif()
193
+
194
+ target_link_libraries(${target_name} PRIVATE pybind11::headers)
195
+
196
+ if(lib_type STREQUAL "MODULE")
197
+ target_link_libraries(${target_name} PRIVATE pybind11::module)
198
+ else()
199
+ target_link_libraries(${target_name} PRIVATE pybind11::embed)
200
+ endif()
201
+
202
+ if(MSVC)
203
+ target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
204
+ endif()
205
+
206
+ # -fvisibility=hidden is required to allow multiple modules compiled against
207
+ # different pybind versions to work properly, and for some features (e.g.
208
+ # py::module_local). We force it on everything inside the `pybind11`
209
+ # namespace; also turning it on for a pybind module compilation here avoids
210
+ # potential warnings or issues from having mixed hidden/non-hidden types.
211
+ if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)
212
+ set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
213
+ endif()
214
+
215
+ if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)
216
+ set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
217
+ endif()
218
+
219
+ # If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions
220
+ if(NOT ARG_WITHOUT_SOABI AND NOT "WITH_SOABI" IN_LIST ARG_UNPARSED_ARGUMENTS)
221
+ pybind11_extension(${target_name})
222
+ endif()
223
+
224
+ if(ARG_NO_EXTRAS)
225
+ return()
226
+ endif()
227
+
228
+ if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
229
+ if(ARG_THIN_LTO)
230
+ target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
231
+ else()
232
+ target_link_libraries(${target_name} PRIVATE pybind11::lto)
233
+ endif()
234
+ endif()
235
+
236
+ if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
237
+ # Strip unnecessary sections of the binary on Linux/macOS
238
+ pybind11_strip(${target_name})
239
+ endif()
240
+
241
+ if(MSVC)
242
+ target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
243
+ endif()
244
+
245
+ if(ARG_OPT_SIZE)
246
+ target_link_libraries(${target_name} PRIVATE pybind11::opt_size)
247
+ endif()
248
+ endfunction()
249
+
250
+ function(pybind11_extension name)
251
+ # The extension is precomputed
252
+ set_target_properties(${name} PROPERTIES PREFIX "" SUFFIX "${PYTHON_MODULE_EXTENSION}")
253
+
254
+ endfunction()
third-party/DPVO/DPViewer/pybind11/tools/pybind11Tools.cmake ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # tools/pybind11Tools.cmake -- Build system for the pybind11 modules
2
+ #
3
+ # Copyright (c) 2020 Wenzel Jakob <[email protected]>
4
+ #
5
+ # All rights reserved. Use of this source code is governed by a
6
+ # BSD-style license that can be found in the LICENSE file.
7
+
8
+ # include_guard(global) (pre-CMake 3.10)
9
+ if(TARGET pybind11::python_headers)
10
+ return()
11
+ endif()
12
+
13
+ # Built-in in CMake 3.5+
14
+ include(CMakeParseArguments)
15
+
16
+ if(pybind11_FIND_QUIETLY)
17
+ set(_pybind11_quiet QUIET)
18
+ else()
19
+ set(_pybind11_quiet "")
20
+ endif()
21
+
22
+ # If this is the first run, PYTHON_VERSION can stand in for PYBIND11_PYTHON_VERSION
23
+ if(NOT DEFINED PYBIND11_PYTHON_VERSION AND DEFINED PYTHON_VERSION)
24
+ message(WARNING "Set PYBIND11_PYTHON_VERSION to search for a specific version, not "
25
+ "PYTHON_VERSION (which is an output). Assuming that is what you "
26
+ "meant to do and continuing anyway.")
27
+ set(PYBIND11_PYTHON_VERSION
28
+ "${PYTHON_VERSION}"
29
+ CACHE STRING "Python version to use for compiling modules")
30
+ unset(PYTHON_VERSION)
31
+ unset(PYTHON_VERSION CACHE)
32
+ elseif(DEFINED PYBIND11_PYTHON_VERSION)
33
+ # If this is set as a normal variable, promote it
34
+ set(PYBIND11_PYTHON_VERSION
35
+ "${PYBIND11_PYTHON_VERSION}"
36
+ CACHE STRING "Python version to use for compiling modules")
37
+ else()
38
+ # Make an empty cache variable.
39
+ set(PYBIND11_PYTHON_VERSION
40
+ ""
41
+ CACHE STRING "Python version to use for compiling modules")
42
+ endif()
43
+
44
+ # A user can set versions manually too
45
+ set(Python_ADDITIONAL_VERSIONS
46
+ "3.11;3.10;3.9;3.8;3.7;3.6"
47
+ CACHE INTERNAL "")
48
+
49
+ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
50
+ find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED ${_pybind11_quiet})
51
+ list(REMOVE_AT CMAKE_MODULE_PATH -1)
52
+
53
+ # Makes a normal variable a cached variable
54
+ macro(_PYBIND11_PROMOTE_TO_CACHE NAME)
55
+ set(_tmp_ptc "${${NAME}}")
56
+ # CMake 3.21 complains if a cached variable is shadowed by a normal one
57
+ unset(${NAME})
58
+ set(${NAME}
59
+ "${_tmp_ptc}"
60
+ CACHE INTERNAL "")
61
+ endmacro()
62
+
63
+ # Cache variables so pybind11_add_module can be used in parent projects
64
+ _pybind11_promote_to_cache(PYTHON_INCLUDE_DIRS)
65
+ _pybind11_promote_to_cache(PYTHON_LIBRARIES)
66
+ _pybind11_promote_to_cache(PYTHON_MODULE_PREFIX)
67
+ _pybind11_promote_to_cache(PYTHON_MODULE_EXTENSION)
68
+ _pybind11_promote_to_cache(PYTHON_VERSION_MAJOR)
69
+ _pybind11_promote_to_cache(PYTHON_VERSION_MINOR)
70
+ _pybind11_promote_to_cache(PYTHON_VERSION)
71
+ _pybind11_promote_to_cache(PYTHON_IS_DEBUG)
72
+
73
+ if(PYBIND11_MASTER_PROJECT)
74
+ if(PYTHON_MODULE_EXTENSION MATCHES "pypy")
75
+ if(NOT DEFINED PYPY_VERSION)
76
+ execute_process(
77
+ COMMAND ${PYTHON_EXECUTABLE} -c
78
+ [=[import sys; sys.stdout.write(".".join(map(str, sys.pypy_version_info[:3])))]=]
79
+ OUTPUT_VARIABLE pypy_version)
80
+ set(PYPY_VERSION
81
+ ${pypy_version}
82
+ CACHE INTERNAL "")
83
+ endif()
84
+ message(STATUS "PYPY ${PYPY_VERSION} (Py ${PYTHON_VERSION})")
85
+ else()
86
+ message(STATUS "PYTHON ${PYTHON_VERSION}")
87
+ endif()
88
+ endif()
89
+
90
+ # Only add Python for build - must be added during the import for config since
91
+ # it has to be re-discovered.
92
+ #
93
+ # This needs to be an target to it is included after the local pybind11
94
+ # directory, just in case there are multiple versions of pybind11, we want the
95
+ # one we expect.
96
+ add_library(pybind11::python_headers INTERFACE IMPORTED)
97
+ set_property(TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES
98
+ "$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>")
99
+ set_property(
100
+ TARGET pybind11::pybind11
101
+ APPEND
102
+ PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)
103
+
104
+ set(pybind11_INCLUDE_DIRS
105
+ "${pybind11_INCLUDE_DIR}" "${PYTHON_INCLUDE_DIRS}"
106
+ CACHE INTERNAL "Directories where pybind11 and possibly Python headers are located")
107
+
108
+ # Python debug libraries expose slightly different objects before 3.8
109
+ # https://docs.python.org/3.6/c-api/intro.html#debugging-builds
110
+ # https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib
111
+ if(PYTHON_IS_DEBUG)
112
+ set_property(
113
+ TARGET pybind11::pybind11
114
+ APPEND
115
+ PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)
116
+ endif()
117
+
118
+ if(CMAKE_VERSION VERSION_LESS 3.11)
119
+ set_property(
120
+ TARGET pybind11::module
121
+ APPEND
122
+ PROPERTY
123
+ INTERFACE_LINK_LIBRARIES
124
+ pybind11::python_link_helper
125
+ "$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>"
126
+ )
127
+
128
+ set_property(
129
+ TARGET pybind11::embed
130
+ APPEND
131
+ PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
132
+ else()
133
+ target_link_libraries(
134
+ pybind11::module
135
+ INTERFACE
136
+ pybind11::python_link_helper
137
+ "$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>"
138
+ )
139
+
140
+ target_link_libraries(pybind11::embed INTERFACE pybind11::pybind11
141
+ $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)
142
+
143
+ endif()
144
+
145
+ function(pybind11_extension name)
146
+ # The prefix and extension are provided by FindPythonLibsNew.cmake
147
+ set_target_properties(${name} PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}"
148
+ SUFFIX "${PYTHON_MODULE_EXTENSION}")
149
+ endfunction()
150
+
151
+ # Build a Python extension module:
152
+ # pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]
153
+ # [NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...])
154
+ #
155
+ function(pybind11_add_module target_name)
156
+ set(options "MODULE;SHARED;EXCLUDE_FROM_ALL;NO_EXTRAS;SYSTEM;THIN_LTO;OPT_SIZE")
157
+ cmake_parse_arguments(ARG "${options}" "" "" ${ARGN})
158
+
159
+ if(ARG_MODULE AND ARG_SHARED)
160
+ message(FATAL_ERROR "Can't be both MODULE and SHARED")
161
+ elseif(ARG_SHARED)
162
+ set(lib_type SHARED)
163
+ else()
164
+ set(lib_type MODULE)
165
+ endif()
166
+
167
+ if(ARG_EXCLUDE_FROM_ALL)
168
+ set(exclude_from_all EXCLUDE_FROM_ALL)
169
+ else()
170
+ set(exclude_from_all "")
171
+ endif()
172
+
173
+ add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS})
174
+
175
+ target_link_libraries(${target_name} PRIVATE pybind11::module)
176
+
177
+ if(ARG_SYSTEM)
178
+ message(
179
+ STATUS
180
+ "Warning: this does not have an effect - use NO_SYSTEM_FROM_IMPORTED if using imported targets"
181
+ )
182
+ endif()
183
+
184
+ pybind11_extension(${target_name})
185
+
186
+ # -fvisibility=hidden is required to allow multiple modules compiled against
187
+ # different pybind versions to work properly, and for some features (e.g.
188
+ # py::module_local). We force it on everything inside the `pybind11`
189
+ # namespace; also turning it on for a pybind module compilation here avoids
190
+ # potential warnings or issues from having mixed hidden/non-hidden types.
191
+ if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)
192
+ set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
193
+ endif()
194
+
195
+ if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)
196
+ set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET "hidden")
197
+ endif()
198
+
199
+ if(ARG_NO_EXTRAS)
200
+ return()
201
+ endif()
202
+
203
+ if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)
204
+ if(ARG_THIN_LTO)
205
+ target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)
206
+ else()
207
+ target_link_libraries(${target_name} PRIVATE pybind11::lto)
208
+ endif()
209
+ endif()
210
+
211
+ if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)
212
+ pybind11_strip(${target_name})
213
+ endif()
214
+
215
+ if(MSVC)
216
+ target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)
217
+ endif()
218
+
219
+ if(ARG_OPT_SIZE)
220
+ target_link_libraries(${target_name} PRIVATE pybind11::opt_size)
221
+ endif()
222
+ endfunction()
223
+
224
+ # Provide general way to call common Python commands in "common" file.
225
+ set(_Python
226
+ PYTHON
227
+ CACHE INTERNAL "" FORCE)
third-party/DPVO/DPViewer/pybind11/tools/pyproject.toml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
third-party/DPVO/DPViewer/pybind11/tools/setup_global.py.in ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ # Setup script for pybind11-global (in the sdist or in tools/setup_global.py in the repository)
4
+ # This package is targeted for easy use from CMake.
5
+
6
+ import glob
7
+ import os
8
+ import re
9
+
10
+ # Setuptools has to be before distutils
11
+ from setuptools import setup
12
+
13
+ from distutils.command.install_headers import install_headers
14
+
15
+ class InstallHeadersNested(install_headers):
16
+ def run(self):
17
+ headers = self.distribution.headers or []
18
+ for header in headers:
19
+ # Remove pybind11/include/
20
+ short_header = header.split("/", 2)[-1]
21
+
22
+ dst = os.path.join(self.install_dir, os.path.dirname(short_header))
23
+ self.mkpath(dst)
24
+ (out, _) = self.copy_file(header, dst)
25
+ self.outfiles.append(out)
26
+
27
+
28
+ main_headers = glob.glob("pybind11/include/pybind11/*.h")
29
+ detail_headers = glob.glob("pybind11/include/pybind11/detail/*.h")
30
+ stl_headers = glob.glob("pybind11/include/pybind11/stl/*.h")
31
+ cmake_files = glob.glob("pybind11/share/cmake/pybind11/*.cmake")
32
+ headers = main_headers + detail_headers + stl_headers
33
+
34
+ cmdclass = {"install_headers": InstallHeadersNested}
35
+ $extra_cmd
36
+
37
+ # This will _not_ affect installing from wheels,
38
+ # only building wheels or installing from SDist.
39
+ # Primarily intended on Windows, where this is sometimes
40
+ # customized (for example, conda-forge uses Library/)
41
+ base = os.environ.get("PYBIND11_GLOBAL_PREFIX", "")
42
+
43
+ # Must have a separator
44
+ if base and not base.endswith("/"):
45
+ base += "/"
46
+
47
+ setup(
48
+ name="pybind11_global",
49
+ version="$version",
50
+ packages=[],
51
+ headers=headers,
52
+ data_files=[
53
+ (base + "share/cmake/pybind11", cmake_files),
54
+ (base + "include/pybind11", main_headers),
55
+ (base + "include/pybind11/detail", detail_headers),
56
+ (base + "include/pybind11/stl", stl_headers),
57
+ ],
58
+ cmdclass=cmdclass,
59
+ )
third-party/DPVO/DPViewer/pybind11/tools/setup_main.py.in ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ # Setup script (in the sdist or in tools/setup_main.py in the repository)
4
+
5
+ from setuptools import setup
6
+
7
+ cmdclass = {}
8
+ $extra_cmd
9
+
10
+ setup(
11
+ name="pybind11",
12
+ version="$version",
13
+ download_url='https://github.com/pybind/pybind11/tarball/v$version',
14
+ packages=[
15
+ "pybind11",
16
+ "pybind11.include.pybind11",
17
+ "pybind11.include.pybind11.detail",
18
+ "pybind11.include.pybind11.stl",
19
+ "pybind11.share.cmake.pybind11",
20
+ ],
21
+ package_data={
22
+ "pybind11": ["py.typed"],
23
+ "pybind11.include.pybind11": ["*.h"],
24
+ "pybind11.include.pybind11.detail": ["*.h"],
25
+ "pybind11.include.pybind11.stl": ["*.h"],
26
+ "pybind11.share.cmake.pybind11": ["*.cmake"],
27
+ },
28
+ extras_require={
29
+ "global": ["pybind11_global==$version"]
30
+ },
31
+ entry_points={
32
+ "console_scripts": [
33
+ "pybind11-config = pybind11.__main__:main",
34
+ ],
35
+ "pipx.run": [
36
+ "pybind11 = pybind11.__main__:main",
37
+ ]
38
+ },
39
+ cmdclass=cmdclass
40
+ )
third-party/DPVO/DPViewer/setup.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import os
3
+ import re
4
+ import subprocess
5
+ import sys
6
+ import torch
7
+
8
+
9
+ from setuptools import setup, Extension
10
+ from setuptools.command.build_ext import build_ext
11
+
12
+ # Convert distutils Windows platform specifiers to CMake -A arguments
13
+ PLAT_TO_CMAKE = {
14
+ "win32": "Win32",
15
+ "win-amd64": "x64",
16
+ "win-arm32": "ARM",
17
+ "win-arm64": "ARM64",
18
+ }
19
+
20
+
21
+ # A CMakeExtension needs a sourcedir instead of a file list.
22
+ # The name must be the _single_ output extension from the CMake build.
23
+ # If you need multiple extensions, see scikit-build.
24
+ class CMakeExtension(Extension):
25
+ def __init__(self, name, sourcedir=""):
26
+ Extension.__init__(self, name, sources=[])
27
+ self.sourcedir = os.path.abspath(sourcedir)
28
+
29
+
30
+ class CMakeBuild(build_ext):
31
+ def build_extension(self, ext):
32
+ extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
33
+
34
+ # required for auto-detection & inclusion of auxiliary "native" libs
35
+ if not extdir.endswith(os.path.sep):
36
+ extdir += os.path.sep
37
+
38
+ debug = int(os.environ.get("DEBUG", 0)) if self.debug is None else self.debug
39
+ cfg = "Debug" if debug else "Release"
40
+
41
+ # CMake lets you override the generator - we need to check this.
42
+ # Can be set with Conda-Build, for example.
43
+ cmake_generator = os.environ.get("CMAKE_GENERATOR", "")
44
+
45
+ # Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON
46
+ # EXAMPLE_VERSION_INFO shows you how to pass a value into the C++ code
47
+ # from Python.
48
+
49
+ cmake_args = [
50
+ "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}".format(extdir),
51
+ "-DPYTHON_EXECUTABLE={}".format(sys.executable),
52
+ "-DCMAKE_BUILD_TYPE={}".format(cfg), # not used on MSVC, but no harm
53
+ "-DTORCH_PATH={}".format(torch.__path__[0])
54
+ ]
55
+ build_args = ["--verbose"]
56
+ # Adding CMake arguments set as environment variable
57
+ # (needed e.g. to build for ARM OSx on conda-forge)
58
+ if "CMAKE_ARGS" in os.environ:
59
+ cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item]
60
+
61
+ # In this example, we pass in the version to C++. You might not need to.
62
+ cmake_args += [
63
+ "-DEXAMPLE_VERSION_INFO={}".format(self.distribution.get_version())
64
+ ]
65
+
66
+ if self.compiler.compiler_type != "msvc":
67
+ # Using Ninja-build since it a) is available as a wheel and b)
68
+ # multithreads automatically. MSVC would require all variables be
69
+ # exported for Ninja to pick it up, which is a little tricky to do.
70
+ # Users can override the generator with CMAKE_GENERATOR in CMake
71
+ # 3.15+.
72
+ if not cmake_generator:
73
+ try:
74
+ import ninja # noqa: F401
75
+
76
+ cmake_args += ["-GNinja"]
77
+ except ImportError:
78
+ pass
79
+
80
+ else:
81
+
82
+ # Single config generators are handled "normally"
83
+ single_config = any(x in cmake_generator for x in {"NMake", "Ninja"})
84
+
85
+ # CMake allows an arch-in-generator style for backward compatibility
86
+ contains_arch = any(x in cmake_generator for x in {"ARM", "Win64"})
87
+
88
+ # Specify the arch if using MSVC generator, but only if it doesn't
89
+ # contain a backward-compatibility arch spec already in the
90
+ # generator name.
91
+ if not single_config and not contains_arch:
92
+ cmake_args += ["-A", PLAT_TO_CMAKE[self.plat_name]]
93
+
94
+ # Multi-config generators have a different way to specify configs
95
+ if not single_config:
96
+ cmake_args += [
97
+ "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}".format(cfg.upper(), extdir)
98
+ ]
99
+ build_args += ["--config", cfg]
100
+
101
+ if sys.platform.startswith("darwin"):
102
+ # Cross-compile support for macOS - respect ARCHFLAGS if set
103
+ archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", ""))
104
+ if archs:
105
+ cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))]
106
+
107
+ build_args += ["-j"]
108
+
109
+ if not os.path.exists(self.build_temp):
110
+ os.makedirs(self.build_temp)
111
+
112
+ subprocess.check_call(
113
+ ["cmake", ext.sourcedir] + cmake_args, cwd=self.build_temp,
114
+ )
115
+
116
+ subprocess.check_call(
117
+ ["cmake", "--build", "."] + build_args, cwd=self.build_temp
118
+ )
119
+
120
+
121
+ # The information here can also be placed in setup.cfg - better separation of
122
+ # logic and declaration, and simpler if you include description/version in a file.
123
+ setup(
124
+ name="dpviewer",
125
+ version="0.0.1",
126
+ author="Zachary Teed",
127
+ packages=['dpviewer'],
128
+ ext_modules=[CMakeExtension("dpviewer")],
129
+ cmdclass={"build_ext": CMakeBuild},
130
+ zip_safe=False,
131
+ extras_require={"test": ["pytest"]},
132
+ )
third-party/DPVO/dpvo/__init__.py ADDED
File without changes
third-party/DPVO/dpvo/altcorr/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from .correlation import corr, patchify
third-party/DPVO/dpvo/altcorr/correlation.cpp ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <torch/extension.h>
2
+ #include <vector>
3
+
4
+ // CUDA forward declarations
5
+ std::vector<torch::Tensor> corr_cuda_forward(
6
+ torch::Tensor fmap1,
7
+ torch::Tensor fmap2,
8
+ torch::Tensor coords,
9
+ torch::Tensor ii,
10
+ torch::Tensor jj,
11
+ int radius);
12
+
13
+ std::vector<torch::Tensor> corr_cuda_backward(
14
+ torch::Tensor fmap1,
15
+ torch::Tensor fmap2,
16
+ torch::Tensor coords,
17
+ torch::Tensor ii,
18
+ torch::Tensor jj,
19
+ torch::Tensor corr_grad,
20
+ int radius);
21
+
22
+ std::vector<torch::Tensor> patchify_cuda_forward(
23
+ torch::Tensor net, torch::Tensor coords, int radius);
24
+
25
+ std::vector<torch::Tensor> patchify_cuda_backward(
26
+ torch::Tensor net, torch::Tensor coords, torch::Tensor gradient, int radius);
27
+
28
+ std::vector<torch::Tensor> corr_forward(
29
+ torch::Tensor fmap1,
30
+ torch::Tensor fmap2,
31
+ torch::Tensor coords,
32
+ torch::Tensor ii,
33
+ torch::Tensor jj, int radius) {
34
+ return corr_cuda_forward(fmap1, fmap2, coords, ii, jj, radius);
35
+ }
36
+
37
+ std::vector<torch::Tensor> corr_backward(
38
+ torch::Tensor fmap1,
39
+ torch::Tensor fmap2,
40
+ torch::Tensor coords,
41
+ torch::Tensor ii,
42
+ torch::Tensor jj,
43
+ torch::Tensor corr_grad, int radius) {
44
+ return corr_cuda_backward(fmap1, fmap2, coords, ii, jj, corr_grad, radius);
45
+ }
46
+
47
+ std::vector<torch::Tensor> patchify_forward(
48
+ torch::Tensor net, torch::Tensor coords, int radius) {
49
+ return patchify_cuda_forward(net, coords, radius);
50
+ }
51
+
52
+ std::vector<torch::Tensor> patchify_backward(
53
+ torch::Tensor net, torch::Tensor coords, torch::Tensor gradient, int radius) {
54
+ return patchify_cuda_backward(net, coords, gradient, radius);
55
+ }
56
+
57
+ PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
58
+ m.def("forward", &corr_forward, "CORR forward");
59
+ m.def("backward", &corr_backward, "CORR backward");
60
+
61
+ m.def("patchify_forward", &patchify_forward, "PATCHIFY forward");
62
+ m.def("patchify_backward", &patchify_backward, "PATCHIFY backward");
63
+ }
third-party/DPVO/dpvo/altcorr/correlation.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import cuda_corr
3
+
4
+ class CorrLayer(torch.autograd.Function):
5
+ @staticmethod
6
+ def forward(ctx, fmap1, fmap2, coords, ii, jj, radius, dropout):
7
+ """ forward correlation """
8
+ ctx.save_for_backward(fmap1, fmap2, coords, ii, jj)
9
+ ctx.radius = radius
10
+ ctx.dropout = dropout
11
+ corr, = cuda_corr.forward(fmap1, fmap2, coords, ii, jj, radius)
12
+
13
+ return corr
14
+
15
+ @staticmethod
16
+ def backward(ctx, grad):
17
+ """ backward correlation """
18
+ fmap1, fmap2, coords, ii, jj = ctx.saved_tensors
19
+
20
+ if ctx.dropout < 1:
21
+ perm = torch.rand(len(ii), device="cuda") < ctx.dropout
22
+ coords = coords[:,perm]
23
+ grad = grad[:,perm]
24
+ ii = ii[perm]
25
+ jj = jj[perm]
26
+
27
+ fmap1_grad, fmap2_grad = \
28
+ cuda_corr.backward(fmap1, fmap2, coords, ii, jj, grad, ctx.radius)
29
+
30
+ return fmap1_grad, fmap2_grad, None, None, None, None, None
31
+
32
+
33
+ class PatchLayer(torch.autograd.Function):
34
+ @staticmethod
35
+ def forward(ctx, net, coords, radius):
36
+ """ forward patchify """
37
+ ctx.radius = radius
38
+ ctx.save_for_backward(net, coords)
39
+
40
+ patches, = cuda_corr.patchify_forward(net, coords, radius)
41
+ return patches
42
+
43
+ @staticmethod
44
+ def backward(ctx, grad):
45
+ """ backward patchify """
46
+ net, coords = ctx.saved_tensors
47
+ grad, = cuda_corr.patchify_backward(net, coords, grad, ctx.radius)
48
+
49
+ return grad, None, None
50
+
51
+ def patchify(net, coords, radius, mode='bilinear'):
52
+ """ extract patches """
53
+
54
+ patches = PatchLayer.apply(net, coords, radius)
55
+
56
+ if mode == 'bilinear':
57
+ offset = (coords - coords.floor()).to(net.device)
58
+ dx, dy = offset[:,:,None,None,None].unbind(dim=-1)
59
+
60
+ d = 2 * radius + 1
61
+ x00 = (1-dy) * (1-dx) * patches[...,:d,:d]
62
+ x01 = (1-dy) * ( dx) * patches[...,:d,1:]
63
+ x10 = ( dy) * (1-dx) * patches[...,1:,:d]
64
+ x11 = ( dy) * ( dx) * patches[...,1:,1:]
65
+
66
+ return x00 + x01 + x10 + x11
67
+
68
+ return patches
69
+
70
+
71
+ def corr(fmap1, fmap2, coords, ii, jj, radius=1, dropout=1):
72
+ return CorrLayer.apply(fmap1, fmap2, coords, ii, jj, radius, dropout)
73
+
74
+
third-party/DPVO/dpvo/altcorr/correlation_kernel.cu ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <torch/extension.h>
2
+ #include <THC/THCAtomics.cuh>
3
+ #include <vector>
4
+ #include <iostream>
5
+
6
+ using namespace torch::indexing;
7
+
8
+ #define THREADS 256
9
+ #define BLOCKS(n) (n + THREADS - 1) / THREADS
10
+
11
+ __forceinline__ __device__
12
+ bool within_bounds(int h, int w, int H, int W) {
13
+ return h >= 0 && h < H && w >= 0 && w < W;
14
+ }
15
+
16
+ template <typename scalar_t>
17
+ __global__ void patchify_forward_kernel(int R,
18
+ const torch::PackedTensorAccessor32<scalar_t,4,torch::RestrictPtrTraits> net,
19
+ const torch::PackedTensorAccessor32<float,3,torch::RestrictPtrTraits> coords,
20
+ torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> patches)
21
+ {
22
+ // diameter
23
+ const int D = 2*R + 2;
24
+
25
+ const int B = coords.size(0);
26
+ const int M = coords.size(1);
27
+ const int C = net.size(1);
28
+ const int H = net.size(2);
29
+ const int W = net.size(3);
30
+
31
+ int n = blockIdx.x * blockDim.x + threadIdx.x;
32
+ if (n < B * M * D * D) {
33
+ const int ii = n % D; n /= D;
34
+ const int jj = n % D; n /= D;
35
+ const int m = n % M; n /= M;
36
+
37
+ const float x = coords[n][m][0];
38
+ const float y = coords[n][m][1];
39
+ const int i = static_cast<int>(floor(y)) + (ii - R);
40
+ const int j = static_cast<int>(floor(x)) + (jj - R);
41
+
42
+ if (within_bounds(i, j, H, W)) {
43
+ for (int k=0; k<C; k++)
44
+ patches[n][m][k][ii][jj] = net[n][k][i][j];
45
+ }
46
+ }
47
+ }
48
+
49
+ template <typename scalar_t>
50
+ __global__ void patchify_backward_kernel(int R,
51
+ const torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> patch_gradient,
52
+ const torch::PackedTensorAccessor32<float,3,torch::RestrictPtrTraits> coords,
53
+ torch::PackedTensorAccessor32<scalar_t,4,torch::RestrictPtrTraits> gradient)
54
+ {
55
+ // diameter
56
+ const int D = 2*R + 2;
57
+
58
+ const int B = coords.size(0);
59
+ const int M = coords.size(1);
60
+ const int C = gradient.size(1);
61
+ const int H = gradient.size(2);
62
+ const int W = gradient.size(3);
63
+
64
+ int n = blockIdx.x * blockDim.x + threadIdx.x;
65
+ if (n < B * M * D * D) {
66
+ const int ii = n % D; n /= D;
67
+ const int jj = n % D; n /= D;
68
+ const int m = n % M; n /= M;
69
+
70
+ const float x = coords[n][m][0];
71
+ const float y = coords[n][m][1];
72
+ const int i = static_cast<int>(floor(y)) + (ii - R);
73
+ const int j = static_cast<int>(floor(x)) + (jj - R);
74
+
75
+ if (within_bounds(i, j, H, W)) {
76
+ for (int k=0; k<C; k++)
77
+ atomicAdd(&gradient[n][k][i][j], patch_gradient[n][m][k][ii][jj]);
78
+ }
79
+ }
80
+ }
81
+
82
+ template <typename scalar_t>
83
+ __global__ void corr_forward_kernel(int R,
84
+ const torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> fmap1,
85
+ const torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> fmap2,
86
+ const torch::PackedTensorAccessor32<float,5,torch::RestrictPtrTraits> coords,
87
+ const torch::PackedTensorAccessor32<long,1,torch::RestrictPtrTraits> us,
88
+ const torch::PackedTensorAccessor32<long,1,torch::RestrictPtrTraits> vs,
89
+ torch::PackedTensorAccessor32<scalar_t,6,torch::RestrictPtrTraits> corr)
90
+ {
91
+ // diameter
92
+ const int D = 2*R + 2;
93
+
94
+ const int B = coords.size(0);
95
+ const int M = coords.size(1);
96
+ const int H = coords.size(3);
97
+ const int W = coords.size(4);
98
+
99
+ const int C = fmap1.size(2);
100
+ const int H2 = fmap2.size(3);
101
+ const int W2 = fmap2.size(4);
102
+
103
+ int n = blockIdx.x * blockDim.x + threadIdx.x;
104
+
105
+ if (n < B * M * H * W * D * D) {
106
+ const int jj = n % D; n /= D;
107
+ const int ii = n % D; n /= D;
108
+ const int j0 = n % W; n /= W;
109
+ const int i0 = n % H; n /= H;
110
+ const int m = n % M; n /= M;
111
+
112
+ const int ix = us[m];
113
+ const int jx = vs[m];
114
+
115
+ const float x = coords[n][m][0][i0][j0];
116
+ const float y = coords[n][m][1][i0][j0];
117
+
118
+ const int i1 = static_cast<int>(floor(y)) + (ii - R);
119
+ const int j1 = static_cast<int>(floor(x)) + (jj - R);
120
+
121
+ scalar_t s = 0;
122
+ if (within_bounds(i1, j1, H2, W2)) {
123
+
124
+ #pragma unroll 8
125
+ for (int i=0; i<C; i+=8) {
126
+ scalar_t f1[8]; for (int j=0; j<8; j++) f1[j] = fmap1[n][ix][i+j][i0][j0];
127
+ scalar_t f2[8]; for (int j=0; j<8; j++) f2[j] = fmap2[n][jx][i+j][i1][j1];
128
+
129
+ #pragma unroll
130
+ for (int j=0; j<8; j++) s += f1[j] * f2[j];
131
+ }
132
+ }
133
+
134
+ corr[n][m][ii][jj][i0][j0] = s;
135
+ }
136
+ }
137
+
138
+
139
+ template <typename scalar_t>
140
+ __global__ void corr_backward_kernel(int R,
141
+ const torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> fmap1,
142
+ const torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> fmap2,
143
+ const torch::PackedTensorAccessor32<float,5,torch::RestrictPtrTraits> coords,
144
+ const torch::PackedTensorAccessor32<long,1,torch::RestrictPtrTraits> us,
145
+ const torch::PackedTensorAccessor32<long,1,torch::RestrictPtrTraits> vs,
146
+ const torch::PackedTensorAccessor32<float,6,torch::RestrictPtrTraits> corr_grad,
147
+ torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> fmap1_grad,
148
+ torch::PackedTensorAccessor32<scalar_t,5,torch::RestrictPtrTraits> fmap2_grad)
149
+ {
150
+ // diameter
151
+ const int D = 2*R + 2;
152
+
153
+ const int B = coords.size(0);
154
+ const int M = coords.size(1);
155
+ const int H = coords.size(3);
156
+ const int W = coords.size(4);
157
+
158
+ const int C = fmap1.size(2);
159
+ const int H2 = fmap2.size(3);
160
+ const int W2 = fmap2.size(4);
161
+
162
+ int n = blockIdx.x * blockDim.x + threadIdx.x;
163
+
164
+ if (n < B * M * H * W * D * D) {
165
+ const int jj = n % D; n /= D;
166
+ const int ii = n % D; n /= D;
167
+ const int j0 = n % W; n /= W;
168
+ const int i0 = n % H; n /= H;
169
+ const int m = n % M; n /= M;
170
+
171
+ const int ix = us[m];
172
+ const int jx = vs[m];
173
+
174
+ const float x = coords[n][m][0][i0][j0];
175
+ const float y = coords[n][m][1][i0][j0];
176
+
177
+ const int i1 = static_cast<int>(floor(y)) + (ii - R);
178
+ const int j1 = static_cast<int>(floor(x)) + (jj - R);
179
+
180
+ const scalar_t g = (scalar_t) corr_grad[n][m][ii][jj][i0][j0];
181
+
182
+ if (within_bounds(i1, j1, H2, W2)) {
183
+ #pragma unroll 32
184
+ for (int i=0; i<C; i++) {
185
+ atomicAdd(&fmap1_grad[n][ix][i][i0][j0], g * fmap2[n][jx][i][i1][j1]);
186
+ atomicAdd(&fmap2_grad[n][jx][i][i1][j1], g * fmap1[n][ix][i][i0][j0]);
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+
193
+ std::vector<torch::Tensor> corr_cuda_forward(
194
+ torch::Tensor fmap1,
195
+ torch::Tensor fmap2,
196
+ torch::Tensor coords,
197
+ torch::Tensor ii,
198
+ torch::Tensor jj,
199
+ int radius)
200
+ {
201
+ const int B = coords.size(0);
202
+ const int M = coords.size(1);
203
+
204
+ const int H = coords.size(3);
205
+ const int W = coords.size(4);
206
+ const int D = 2 * radius + 2;
207
+
208
+ auto opts = fmap1.options();
209
+ auto corr = torch::empty({B, M, D, D, H, W}, opts);
210
+
211
+ AT_DISPATCH_FLOATING_TYPES_AND_HALF(fmap1.type(), "corr_forward_kernel", ([&] {
212
+ corr_forward_kernel<scalar_t><<<BLOCKS(B * M * H * W * D * D), THREADS>>>(radius,
213
+ fmap1.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>(),
214
+ fmap2.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>(),
215
+ coords.packed_accessor32<float,5,torch::RestrictPtrTraits>(),
216
+ ii.packed_accessor32<long,1,torch::RestrictPtrTraits>(),
217
+ jj.packed_accessor32<long,1,torch::RestrictPtrTraits>(),
218
+ corr.packed_accessor32<scalar_t,6,torch::RestrictPtrTraits>());
219
+ }));
220
+
221
+ torch::Tensor x = coords.index({Slice(), Slice(), 0, None, None});
222
+ torch::Tensor y = coords.index({Slice(), Slice(), 1, None, None});
223
+ torch::Tensor dx = x - x.floor(); dx = dx.to(fmap1.dtype());
224
+ torch::Tensor dy = y - y.floor(); dy = dy.to(fmap2.dtype());
225
+
226
+ torch::Tensor out;
227
+ out = (1 - dx) * (1 - dy) * corr.index({Slice(), Slice(), Slice(0, D-1), Slice(0, D-1)});
228
+ out += (dx) * (1 - dy) * corr.index({Slice(), Slice(), Slice(0, D-1), Slice(1, D-0)});
229
+ out += (1 - dx) * (dy) * corr.index({Slice(), Slice(), Slice(1, D-0), Slice(0, D-1)});
230
+ out += (dx) * (dy) * corr.index({Slice(), Slice(), Slice(1, D-0), Slice(1, D-0)});
231
+
232
+ return { out.permute({0,1,3,2,4,5}) };
233
+ }
234
+
235
+
236
+ std::vector<torch::Tensor> corr_cuda_backward(
237
+ torch::Tensor fmap1,
238
+ torch::Tensor fmap2,
239
+ torch::Tensor coords,
240
+ torch::Tensor ii,
241
+ torch::Tensor jj,
242
+ torch::Tensor grad,
243
+ int radius)
244
+ {
245
+ const int B = coords.size(0);
246
+ const int M = coords.size(1);
247
+
248
+ const int H = coords.size(3);
249
+ const int W = coords.size(4);
250
+ const int D = 2 * radius + 2;
251
+
252
+ grad = grad.permute({0,1,3,2,4,5}).contiguous();
253
+ torch::Tensor x = coords.index({Slice(), Slice(), 0, None, None});
254
+ torch::Tensor y = coords.index({Slice(), Slice(), 1, None, None});
255
+ torch::Tensor dx = x - x.floor();
256
+ torch::Tensor dy = y - y.floor();
257
+
258
+ auto opts = torch::TensorOptions().dtype(torch::kFloat).device(torch::kCUDA);
259
+ torch::Tensor g1 = torch::zeros({B, M, D, D, H, W}, grad.options());
260
+ torch::Tensor g2 = torch::zeros({B, M, D, D, H, W}, grad.options());
261
+ torch::Tensor g3 = torch::zeros({B, M, D, D, H, W}, grad.options());
262
+ torch::Tensor g4 = torch::zeros({B, M, D, D, H, W}, grad.options());
263
+
264
+ g1.index_put_({Slice(), Slice(), Slice(0, D-1), Slice(0, D-1)}, (1 - dx) * (1 - dy) * grad);
265
+ g2.index_put_({Slice(), Slice(), Slice(0, D-1), Slice(1, D-0)}, (dx) * (1 - dy) * grad);
266
+ g3.index_put_({Slice(), Slice(), Slice(1, D-0), Slice(0, D-1)}, (1 - dx) * (dy) * grad);
267
+ g4.index_put_({Slice(), Slice(), Slice(1, D-0), Slice(1, D-0)}, (dx) * (dy) * grad);
268
+
269
+ torch::Tensor corr_grad = g1 + g2 + g3 + g4;
270
+ auto fmap1_grad = torch::zeros_like(fmap1);
271
+ auto fmap2_grad = torch::zeros_like(fmap2);
272
+
273
+ AT_DISPATCH_FLOATING_TYPES_AND_HALF(fmap1.type(), "corr_backward_kernel", ([&] {
274
+ corr_backward_kernel<scalar_t><<<BLOCKS(B * M * H * W * D * D), THREADS>>>(radius,
275
+ fmap1.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>(),
276
+ fmap2.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>(),
277
+ coords.packed_accessor32<float,5,torch::RestrictPtrTraits>(),
278
+ ii.packed_accessor32<long,1,torch::RestrictPtrTraits>(),
279
+ jj.packed_accessor32<long,1,torch::RestrictPtrTraits>(),
280
+ corr_grad.packed_accessor32<float,6,torch::RestrictPtrTraits>(),
281
+ fmap1_grad.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>(),
282
+ fmap2_grad.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>());
283
+ }));
284
+
285
+ return {fmap1_grad, fmap2_grad};
286
+ }
287
+
288
+ std::vector<torch::Tensor> patchify_cuda_forward(
289
+ torch::Tensor net, torch::Tensor coords, int radius)
290
+ {
291
+ const int B = coords.size(0);
292
+ const int M = coords.size(1);
293
+ const int C = net.size(1);
294
+ const int D = 2 * radius + 2;
295
+
296
+ auto opts = net.options();
297
+ auto patches = torch::zeros({B, M, C, D, D}, opts);
298
+
299
+ AT_DISPATCH_FLOATING_TYPES_AND_HALF(net.type(), "patchify_forward_kernel", ([&] {
300
+ patchify_forward_kernel<scalar_t><<<BLOCKS(B * M * D * D), THREADS>>>(radius,
301
+ net.packed_accessor32<scalar_t,4,torch::RestrictPtrTraits>(),
302
+ coords.packed_accessor32<float,3,torch::RestrictPtrTraits>(),
303
+ patches.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>());
304
+ }));
305
+
306
+ return { patches };
307
+ }
308
+
309
+
310
+ std::vector<torch::Tensor> patchify_cuda_backward(
311
+ torch::Tensor net,
312
+ torch::Tensor coords,
313
+ torch::Tensor gradient,
314
+ int radius)
315
+ {
316
+ const int B = coords.size(0);
317
+ const int M = coords.size(1);
318
+ const int C = net.size(1);
319
+ const int H = net.size(2);
320
+ const int W = net.size(3);
321
+ const int D = 2 * radius + 2;
322
+
323
+ torch::Tensor net_gradient = torch::zeros_like(net);
324
+
325
+ AT_DISPATCH_FLOATING_TYPES_AND_HALF(net.type(), "patchify_backward_kernel", ([&] {
326
+ patchify_backward_kernel<scalar_t><<<BLOCKS(B * M * D * D), THREADS>>>(radius,
327
+ gradient.packed_accessor32<scalar_t,5,torch::RestrictPtrTraits>(),
328
+ coords.packed_accessor32<float,3,torch::RestrictPtrTraits>(),
329
+ net_gradient.packed_accessor32<scalar_t,4,torch::RestrictPtrTraits>());
330
+ }));
331
+
332
+ return { net_gradient };
333
+ }
third-party/DPVO/dpvo/ba.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from torch_scatter import scatter_sum
3
+
4
+ from . import fastba
5
+ from . import lietorch
6
+ from .lietorch import SE3
7
+
8
+ from .utils import Timer
9
+
10
+ from . import projective_ops as pops
11
+
12
+ class CholeskySolver(torch.autograd.Function):
13
+ @staticmethod
14
+ def forward(ctx, H, b):
15
+ # don't crash training if cholesky decomp fails
16
+ U, info = torch.linalg.cholesky_ex(H)
17
+
18
+ if torch.any(info):
19
+ ctx.failed = True
20
+ return torch.zeros_like(b)
21
+
22
+ xs = torch.cholesky_solve(b, U)
23
+ ctx.save_for_backward(U, xs)
24
+ ctx.failed = False
25
+
26
+ return xs
27
+
28
+ @staticmethod
29
+ def backward(ctx, grad_x):
30
+ if ctx.failed:
31
+ return None, None
32
+
33
+ U, xs = ctx.saved_tensors
34
+ dz = torch.cholesky_solve(grad_x, U)
35
+ dH = -torch.matmul(xs, dz.transpose(-1,-2))
36
+
37
+ return dH, dz
38
+
39
+ # utility functions for scattering ops
40
+ def safe_scatter_add_mat(A, ii, jj, n, m):
41
+ v = (ii >= 0) & (jj >= 0) & (ii < n) & (jj < m)
42
+ return scatter_sum(A[:,v], ii[v]*m + jj[v], dim=1, dim_size=n*m)
43
+
44
+ def safe_scatter_add_vec(b, ii, n):
45
+ v = (ii >= 0) & (ii < n)
46
+ return scatter_sum(b[:,v], ii[v], dim=1, dim_size=n)
47
+
48
+ # apply retraction operator to inv-depth maps
49
+ def disp_retr(disps, dz, ii):
50
+ ii = ii.to(device=dz.device)
51
+ return disps + scatter_sum(dz, ii, dim=1, dim_size=disps.shape[1])
52
+
53
+ # apply retraction operator to poses
54
+ def pose_retr(poses, dx, ii):
55
+ ii = ii.to(device=dx.device)
56
+ return poses.retr(scatter_sum(dx, ii, dim=1, dim_size=poses.shape[1]))
57
+
58
+ def block_matmul(A, B):
59
+ """ block matrix multiply """
60
+ b, n1, m1, p1, q1 = A.shape
61
+ b, n2, m2, p2, q2 = B.shape
62
+ A = A.permute(0, 1, 3, 2, 4).reshape(b, n1*p1, m1*q1)
63
+ B = B.permute(0, 1, 3, 2, 4).reshape(b, n2*p2, m2*q2)
64
+ return torch.matmul(A, B).reshape(b, n1, p1, m2, q2).permute(0, 1, 3, 2, 4)
65
+
66
+ def block_solve(A, B, ep=1.0, lm=1e-4):
67
+ """ block matrix solve """
68
+ b, n1, m1, p1, q1 = A.shape
69
+ b, n2, m2, p2, q2 = B.shape
70
+ A = A.permute(0, 1, 3, 2, 4).reshape(b, n1*p1, m1*q1)
71
+ B = B.permute(0, 1, 3, 2, 4).reshape(b, n2*p2, m2*q2)
72
+
73
+ A = A + (ep + lm * A) * torch.eye(n1*p1, device=A.device)
74
+
75
+ X = CholeskySolver.apply(A, B)
76
+ return X.reshape(b, n1, p1, m2, q2).permute(0, 1, 3, 2, 4)
77
+
78
+
79
+ def block_show(A):
80
+ import matplotlib.pyplot as plt
81
+ b, n1, m1, p1, q1 = A.shape
82
+ A = A.permute(0, 1, 3, 2, 4).reshape(b, n1*p1, m1*q1)
83
+ plt.imshow(A[0].detach().cpu().numpy())
84
+ plt.show()
85
+
86
+ def BA(poses, patches, intrinsics, targets, weights, lmbda, ii, jj, kk, bounds, ep=100.0, PRINT=False, fixedp=1, structure_only=False):
87
+ """ bundle adjustment """
88
+
89
+ b = 1
90
+ n = max(ii.max().item(), jj.max().item()) + 1
91
+
92
+ coords, v, (Ji, Jj, Jz) = \
93
+ pops.transform(poses, patches, intrinsics, ii, jj, kk, jacobian=True)
94
+
95
+ p = coords.shape[3]
96
+ r = targets - coords[...,p//2,p//2,:]
97
+
98
+ v *= (r.norm(dim=-1) < 250).float()
99
+
100
+ in_bounds = \
101
+ (coords[...,p//2,p//2,0] > bounds[0]) & \
102
+ (coords[...,p//2,p//2,1] > bounds[1]) & \
103
+ (coords[...,p//2,p//2,0] < bounds[2]) & \
104
+ (coords[...,p//2,p//2,1] < bounds[3])
105
+
106
+ v *= in_bounds.float()
107
+
108
+ if PRINT:
109
+ print((r * v[...,None]).norm(dim=-1).mean().item())
110
+
111
+ r = (v[...,None] * r).unsqueeze(dim=-1)
112
+ weights = (v[...,None] * weights).unsqueeze(dim=-1)
113
+
114
+ wJiT = (weights * Ji).transpose(2,3)
115
+ wJjT = (weights * Jj).transpose(2,3)
116
+ wJzT = (weights * Jz).transpose(2,3)
117
+
118
+ Bii = torch.matmul(wJiT, Ji)
119
+ Bij = torch.matmul(wJiT, Jj)
120
+ Bji = torch.matmul(wJjT, Ji)
121
+ Bjj = torch.matmul(wJjT, Jj)
122
+
123
+ Eik = torch.matmul(wJiT, Jz)
124
+ Ejk = torch.matmul(wJjT, Jz)
125
+
126
+ vi = torch.matmul(wJiT, r)
127
+ vj = torch.matmul(wJjT, r)
128
+
129
+ # fix first pose
130
+ ii = ii.clone()
131
+ jj = jj.clone()
132
+
133
+ n = n - fixedp
134
+ ii = ii - fixedp
135
+ jj = jj - fixedp
136
+
137
+ kx, kk = torch.unique(kk, return_inverse=True, sorted=True)
138
+ m = len(kx)
139
+
140
+ B = safe_scatter_add_mat(Bii, ii, ii, n, n).view(b, n, n, 6, 6) + \
141
+ safe_scatter_add_mat(Bij, ii, jj, n, n).view(b, n, n, 6, 6) + \
142
+ safe_scatter_add_mat(Bji, jj, ii, n, n).view(b, n, n, 6, 6) + \
143
+ safe_scatter_add_mat(Bjj, jj, jj, n, n).view(b, n, n, 6, 6)
144
+
145
+ E = safe_scatter_add_mat(Eik, ii, kk, n, m).view(b, n, m, 6, 1) + \
146
+ safe_scatter_add_mat(Ejk, jj, kk, n, m).view(b, n, m, 6, 1)
147
+
148
+ C = safe_scatter_add_vec(torch.matmul(wJzT, Jz), kk, m)
149
+
150
+ v = safe_scatter_add_vec(vi, ii, n).view(b, n, 1, 6, 1) + \
151
+ safe_scatter_add_vec(vj, jj, n).view(b, n, 1, 6, 1)
152
+
153
+ w = safe_scatter_add_vec(torch.matmul(wJzT, r), kk, m)
154
+
155
+ if isinstance(lmbda, torch.Tensor):
156
+ lmbda = lmbda.reshape(*C.shape)
157
+
158
+ Q = 1.0 / (C + lmbda)
159
+
160
+ ### solve w/ schur complement ###
161
+ EQ = E * Q[:,None]
162
+
163
+ if structure_only or n == 0:
164
+ dZ = (Q * w).view(b, -1, 1, 1)
165
+
166
+ else:
167
+ S = B - block_matmul(EQ, E.permute(0,2,1,4,3))
168
+ y = v - block_matmul(EQ, w.unsqueeze(dim=2))
169
+ dX = block_solve(S, y, ep=ep, lm=1e-4)
170
+
171
+ dZ = Q * (w - block_matmul(E.permute(0,2,1,4,3), dX).squeeze(dim=-1))
172
+ dX = dX.view(b, -1, 6)
173
+ dZ = dZ.view(b, -1, 1, 1)
174
+
175
+ x, y, disps = patches.unbind(dim=2)
176
+ disps = disp_retr(disps, dZ, kx).clamp(min=1e-3, max=10.0)
177
+ patches = torch.stack([x, y, disps], dim=2)
178
+
179
+ if not structure_only and n > 0:
180
+ poses = pose_retr(poses, dX, fixedp + torch.arange(n))
181
+
182
+ return poses, patches
third-party/DPVO/dpvo/blocks.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+
5
+ import torch_scatter
6
+
7
+ class LayerNorm1D(nn.Module):
8
+ def __init__(self, dim):
9
+ super(LayerNorm1D, self).__init__()
10
+ self.norm = nn.LayerNorm(dim, eps=1e-4)
11
+
12
+ def forward(self, x):
13
+ return self.norm(x.transpose(1,2)).transpose(1,2)
14
+
15
+ class GatedResidual(nn.Module):
16
+ def __init__(self, dim):
17
+ super().__init__()
18
+
19
+ self.gate = nn.Sequential(
20
+ nn.Linear(dim, dim),
21
+ nn.Sigmoid())
22
+
23
+ self.res = nn.Sequential(
24
+ nn.Linear(dim, dim),
25
+ nn.ReLU(inplace=True),
26
+ nn.Linear(dim, dim))
27
+
28
+ def forward(self, x):
29
+ return x + self.gate(x) * self.res(x)
30
+
31
+ class SoftAgg(nn.Module):
32
+ def __init__(self, dim=512, expand=True):
33
+ super(SoftAgg, self).__init__()
34
+ self.dim = dim
35
+ self.expand = expand
36
+ self.f = nn.Linear(self.dim, self.dim)
37
+ self.g = nn.Linear(self.dim, self.dim)
38
+ self.h = nn.Linear(self.dim, self.dim)
39
+
40
+ def forward(self, x, ix):
41
+ _, jx = torch.unique(ix, return_inverse=True)
42
+ w = torch_scatter.scatter_softmax(self.g(x), jx, dim=1)
43
+ y = torch_scatter.scatter_sum(self.f(x) * w, jx, dim=1)
44
+
45
+ if self.expand:
46
+ return self.h(y)[:,jx]
47
+
48
+ return self.h(y)
49
+
50
+ class SoftAggBasic(nn.Module):
51
+ def __init__(self, dim=512, expand=True):
52
+ super(SoftAggBasic, self).__init__()
53
+ self.dim = dim
54
+ self.expand = expand
55
+ self.f = nn.Linear(self.dim, self.dim)
56
+ self.g = nn.Linear(self.dim, 1)
57
+ self.h = nn.Linear(self.dim, self.dim)
58
+
59
+ def forward(self, x, ix):
60
+ _, jx = torch.unique(ix, return_inverse=True)
61
+ w = torch_scatter.scatter_softmax(self.g(x), jx, dim=1)
62
+ y = torch_scatter.scatter_sum(self.f(x) * w, jx, dim=1)
63
+
64
+ if self.expand:
65
+ return self.h(y)[:,jx]
66
+
67
+ return self.h(y)
68
+
69
+
70
+ ### Gradient Clipping and Zeroing Operations ###
71
+
72
+ GRAD_CLIP = 0.1
73
+
74
+ class GradClip(torch.autograd.Function):
75
+ @staticmethod
76
+ def forward(ctx, x):
77
+ return x
78
+
79
+ @staticmethod
80
+ def backward(ctx, grad_x):
81
+ grad_x = torch.where(torch.isnan(grad_x), torch.zeros_like(grad_x), grad_x)
82
+ return grad_x.clamp(min=-0.01, max=0.01)
83
+
84
+ class GradientClip(nn.Module):
85
+ def __init__(self):
86
+ super(GradientClip, self).__init__()
87
+
88
+ def forward(self, x):
89
+ return GradClip.apply(x)
90
+
91
+ class GradZero(torch.autograd.Function):
92
+ @staticmethod
93
+ def forward(ctx, x):
94
+ return x
95
+
96
+ @staticmethod
97
+ def backward(ctx, grad_x):
98
+ grad_x = torch.where(torch.isnan(grad_x), torch.zeros_like(grad_x), grad_x)
99
+ grad_x = torch.where(torch.abs(grad_x) > GRAD_CLIP, torch.zeros_like(grad_x), grad_x)
100
+ return grad_x
101
+
102
+ class GradientZero(nn.Module):
103
+ def __init__(self):
104
+ super(GradientZero, self).__init__()
105
+
106
+ def forward(self, x):
107
+ return GradZero.apply(x)
108
+
109
+
110
+ class GradMag(torch.autograd.Function):
111
+ @staticmethod
112
+ def forward(ctx, x):
113
+ return x
114
+
115
+ @staticmethod
116
+ def backward(ctx, grad_x):
117
+ print(grad_x.abs().mean())
118
+ return grad_x
third-party/DPVO/dpvo/config.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from yacs.config import CfgNode as CN
2
+
3
+ _C = CN()
4
+
5
+ # max number of keyframes
6
+ _C.BUFFER_SIZE = 4096
7
+
8
+ # bias patch selection towards high gradient regions?
9
+ _C.CENTROID_SEL_STRAT = 'RANDOM'
10
+
11
+ # VO config (increase for better accuracy)
12
+ _C.PATCHES_PER_FRAME = 80
13
+ _C.REMOVAL_WINDOW = 20
14
+ _C.OPTIMIZATION_WINDOW = 12
15
+ _C.PATCH_LIFETIME = 12
16
+
17
+ # threshold for keyframe removal
18
+ _C.KEYFRAME_INDEX = 4
19
+ _C.KEYFRAME_THRESH = 12.5
20
+
21
+ # camera motion model
22
+ _C.MOTION_MODEL = 'DAMPED_LINEAR'
23
+ _C.MOTION_DAMPING = 0.5
24
+
25
+ _C.MIXED_PRECISION = True
26
+
27
+ # Loop closure
28
+ _C.LOOP_CLOSURE = False
29
+ _C.BACKEND_THRESH = 64.0
30
+ _C.MAX_EDGE_AGE = 1000
31
+ _C.GLOBAL_OPT_FREQ = 15
32
+
33
+ # Classic loop closure
34
+ _C.CLASSIC_LOOP_CLOSURE = False
35
+ _C.LOOP_CLOSE_WINDOW_SIZE = 3
36
+ _C.LOOP_RETR_THRESH = 0.04
37
+
38
+ cfg = _C
third-party/DPVO/dpvo/data_readers/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+