1+ /* *
2+ * This file contains the pybind11 reference implementation for the stugen tests,
3+ * and was originally inspired by:
4+ *
5+ * https://github.com/sizmailov/pybind11-mypy-demo
6+ *
7+ * Copyright (c) 2016 The Pybind Development Team, All rights reserved.
8+ *
9+ * Redistribution and use in source and binary forms, with or without
10+ * modification, are permitted provided that the following conditions are met:
11+ *
12+ * 1. Redistributions of source code must retain the above copyright notice, this
13+ * list of conditions and the following disclaimer.
14+ *
15+ * 2. Redistributions in binary form must reproduce the above copyright notice,
16+ * this list of conditions and the following disclaimer in the documentation
17+ * and/or other materials provided with the distribution.
18+ *
19+ * 3. Neither the name of the copyright holder nor the names of its contributors
20+ * may be used to endorse or promote products derived from this software
21+ * without specific prior written permission.
22+ *
23+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33+ *
34+ * You are under no obligation whatsoever to provide any bug fixes, patches, or
35+ * upgrades to the features, functionality or performance of the source code
36+ * ("Enhancements") to anyone; however, if you choose to make your Enhancements
37+ * available either publicly, or directly to the author of this software, without
38+ * imposing a separate written license agreement for such Enhancements, then you
39+ * hereby grant the following license: a non-exclusive, royalty-free perpetual
40+ * license to install, use, modify, prepare derivative works, incorporate into
41+ * other computer software, distribute, and sublicense such enhancements or
42+ * derivative works thereof, in binary and source code form.
43+ */
44+
45+ #include < cmath>
46+ #include < pybind11/pybind11.h>
47+
48+ namespace py = pybind11;
49+
50+ namespace basics {
51+
52+ int answer () {
53+ return 42 ;
54+ }
55+
56+ int sum (int a, int b) {
57+ return a + b;
58+ }
59+
60+ double midpoint (double left, double right){
61+ return left + (right - left)/2 ;
62+ }
63+
64+ double weighted_midpoint (double left, double right, double alpha=0.5 ) {
65+ return left + (right - left) * alpha;
66+ }
67+
68+ struct Point {
69+
70+ enum class LengthUnit {
71+ mm=0 ,
72+ pixel,
73+ inch
74+ };
75+
76+ enum class AngleUnit {
77+ radian=0 ,
78+ degree
79+ };
80+
81+ Point () : Point(0 , 0 ) {}
82+ Point (double x, double y) : x(x), y(y) {}
83+
84+ static const Point origin;
85+ static const Point x_axis;
86+ static const Point y_axis;
87+
88+ static LengthUnit length_unit;
89+ static AngleUnit angle_unit;
90+
91+ double length () const {
92+ return std::sqrt (x * x + y * y);
93+ }
94+
95+ double distance_to (double other_x, double other_y) const {
96+ double dx = x - other_x;
97+ double dy = y - other_y;
98+ return std::sqrt (dx*dx + dy*dy);
99+ }
100+
101+ double distance_to (const Point& other) const {
102+ return distance_to (other.x , other.y );
103+ }
104+
105+ double x, y;
106+ };
107+
108+ const Point Point::origin = Point(0 , 0 );
109+ const Point Point::x_axis = Point(1 , 0 );
110+ const Point Point::y_axis = Point(0 , 1 );
111+
112+ Point::LengthUnit Point::length_unit = Point::LengthUnit::mm;
113+ Point::AngleUnit Point::angle_unit = Point::AngleUnit::radian;
114+
115+ } // namespace: basics
116+
117+ void bind_basics (py::module & basics) {
118+
119+ using namespace basics ;
120+
121+ // Functions
122+ basics.def (" answer" , &answer);
123+ basics.def (" sum" , &sum);
124+ basics.def (" midpoint" , &midpoint, py::arg (" left" ), py::arg (" right" ));
125+ basics.def (" weighted_midpoint" , weighted_midpoint, py::arg (" left" ), py::arg (" right" ), py::arg (" alpha" )=0.5 );
126+
127+ // Classes
128+ py::class_<Point> pyPoint (basics, " Point" );
129+ py::enum_<Point::LengthUnit> pyLengthUnit (pyPoint, " LengthUnit" );
130+ py::enum_<Point::AngleUnit> pyAngleUnit (pyPoint, " AngleUnit" );
131+
132+ pyPoint
133+ .def (py::init<>())
134+ .def (py::init<double , double >(), py::arg (" x" ), py::arg (" y" ))
135+ .def (" distance_to" , py::overload_cast<double , double >(&Point::distance_to, py::const_), py::arg (" x" ), py::arg (" y" ))
136+ .def (" distance_to" , py::overload_cast<const Point&>(&Point::distance_to, py::const_), py::arg (" other" ))
137+ .def_readwrite (" x" , &Point::x)
138+ .def_property (" y" ,
139+ [](Point& self){ return self.y ; },
140+ [](Point& self, double value){ self.y = value; }
141+ )
142+ .def_property_readonly (" length" , &Point::length)
143+ .def_property_readonly_static (" x_axis" , [](py::object cls){return Point::x_axis;})
144+ .def_property_readonly_static (" y_axis" , [](py::object cls){return Point::y_axis;})
145+ .def_readwrite_static (" length_unit" , &Point::length_unit)
146+ .def_property_static (" angle_unit" ,
147+ [](py::object& /* cls*/ ){ return Point::angle_unit; },
148+ [](py::object& /* cls*/ , Point::AngleUnit value){ Point::angle_unit = value; }
149+ );
150+
151+ pyPoint.attr (" origin" ) = Point::origin;
152+
153+ pyLengthUnit
154+ .value (" mm" , Point::LengthUnit::mm)
155+ .value (" pixel" , Point::LengthUnit::pixel)
156+ .value (" inch" , Point::LengthUnit::inch);
157+
158+ pyAngleUnit
159+ .value (" radian" , Point::AngleUnit::radian)
160+ .value (" degree" , Point::AngleUnit::degree);
161+
162+ // Module-level attributes
163+ basics.attr (" PI" ) = std::acos (-1 );
164+ basics.attr (" __version__" ) = " 0.0.1" ;
165+ }
166+
167+ PYBIND11_MODULE (pybind11_mypy_demo, m) {
168+ auto basics = m.def_submodule (" basics" );
169+ bind_basics (basics);
170+ }
0 commit comments