variable.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*-----------------------------------------------------------------------------
  2. | Copyright (c) 2013-2017, Nucleic Development Team.
  3. |
  4. | Distributed under the terms of the Modified BSD License.
  5. |
  6. | The full license is in the file COPYING.txt, distributed with this software.
  7. |----------------------------------------------------------------------------*/
  8. #include <Python.h>
  9. #include <kiwi/kiwi.h>
  10. #include "pythonhelpers.h"
  11. #include "symbolics.h"
  12. #include "types.h"
  13. #include "util.h"
  14. using namespace PythonHelpers;
  15. static PyObject*
  16. Variable_new( PyTypeObject* type, PyObject* args, PyObject* kwargs )
  17. {
  18. static const char *kwlist[] = { "name", "context", 0 };
  19. PyObject* context = 0;
  20. PyObject* name = 0;
  21. if( !PyArg_ParseTupleAndKeywords(
  22. args, kwargs, "|OO:__new__", const_cast<char**>( kwlist ),
  23. &name, &context ) )
  24. return 0;
  25. PyObjectPtr pyvar( PyType_GenericNew( type, args, kwargs ) );
  26. if( !pyvar )
  27. return 0;
  28. Variable* self = reinterpret_cast<Variable*>( pyvar.get() );
  29. self->context = xnewref( context );
  30. if( name != 0 )
  31. {
  32. #if PY_MAJOR_VERSION >= 3
  33. if( !PyUnicode_Check( name ) )
  34. return py_expected_type_fail( name, "unicode" );
  35. #else
  36. if( !( PyString_Check( name ) | PyUnicode_Check( name ) ) )
  37. {
  38. return py_expected_type_fail( name, "str or unicode" );
  39. }
  40. #endif
  41. std::string c_name;
  42. if( !convert_pystr_to_str(name, c_name) )
  43. return 0; // LCOV_EXCL_LINE
  44. new( &self->variable ) kiwi::Variable( c_name );
  45. }
  46. else
  47. {
  48. new( &self->variable ) kiwi::Variable();
  49. }
  50. return pyvar.release();
  51. }
  52. static void
  53. Variable_clear( Variable* self )
  54. {
  55. Py_CLEAR( self->context );
  56. }
  57. static int
  58. Variable_traverse( Variable* self, visitproc visit, void* arg )
  59. {
  60. Py_VISIT( self->context );
  61. return 0;
  62. }
  63. static void
  64. Variable_dealloc( Variable* self )
  65. {
  66. PyObject_GC_UnTrack( self );
  67. Variable_clear( self );
  68. self->variable.~Variable();
  69. Py_TYPE( self )->tp_free( pyobject_cast( self ) );
  70. }
  71. static PyObject*
  72. Variable_repr( Variable* self )
  73. {
  74. return FROM_STRING( self->variable.name().c_str() );
  75. }
  76. static PyObject*
  77. Variable_name( Variable* self )
  78. {
  79. return FROM_STRING( self->variable.name().c_str() );
  80. }
  81. static PyObject*
  82. Variable_setName( Variable* self, PyObject* pystr )
  83. {
  84. #if PY_MAJOR_VERSION >= 3
  85. if( !PyUnicode_Check( pystr ) )
  86. return py_expected_type_fail( pystr, "unicode" );
  87. #else
  88. if( !(PyString_Check( pystr ) | PyUnicode_Check( pystr ) ) )
  89. {
  90. return py_expected_type_fail( pystr, "str or unicode" );
  91. }
  92. #endif
  93. std::string str;
  94. if( !convert_pystr_to_str( pystr, str ) )
  95. return 0;
  96. self->variable.setName( str );
  97. Py_RETURN_NONE;
  98. }
  99. static PyObject*
  100. Variable_context( Variable* self )
  101. {
  102. if( self->context )
  103. return newref( self->context );
  104. Py_RETURN_NONE;
  105. }
  106. static PyObject*
  107. Variable_setContext( Variable* self, PyObject* value )
  108. {
  109. if( value != self->context )
  110. {
  111. PyObject* temp = self->context;
  112. self->context = newref( value );
  113. Py_XDECREF( temp );
  114. }
  115. Py_RETURN_NONE;
  116. }
  117. static PyObject*
  118. Variable_value( Variable* self )
  119. {
  120. return PyFloat_FromDouble( self->variable.value() );
  121. }
  122. static PyObject*
  123. Variable_add( PyObject* first, PyObject* second )
  124. {
  125. return BinaryInvoke<BinaryAdd, Variable>()( first, second );
  126. }
  127. static PyObject*
  128. Variable_sub( PyObject* first, PyObject* second )
  129. {
  130. return BinaryInvoke<BinarySub, Variable>()( first, second );
  131. }
  132. static PyObject*
  133. Variable_mul( PyObject* first, PyObject* second )
  134. {
  135. return BinaryInvoke<BinaryMul, Variable>()( first, second );
  136. }
  137. static PyObject*
  138. Variable_div( PyObject* first, PyObject* second )
  139. {
  140. return BinaryInvoke<BinaryDiv, Variable>()( first, second );
  141. }
  142. static PyObject*
  143. Variable_neg( PyObject* value )
  144. {
  145. return UnaryInvoke<UnaryNeg, Variable>()( value );
  146. }
  147. static PyObject*
  148. Variable_richcmp( PyObject* first, PyObject* second, int op )
  149. {
  150. switch( op )
  151. {
  152. case Py_EQ:
  153. return BinaryInvoke<CmpEQ, Variable>()( first, second );
  154. case Py_LE:
  155. return BinaryInvoke<CmpLE, Variable>()( first, second );
  156. case Py_GE:
  157. return BinaryInvoke<CmpGE, Variable>()( first, second );
  158. default:
  159. break;
  160. }
  161. PyErr_Format(
  162. PyExc_TypeError,
  163. "unsupported operand type(s) for %s: "
  164. "'%.100s' and '%.100s'",
  165. pyop_str( op ),
  166. first->ob_type->tp_name,
  167. second->ob_type->tp_name
  168. );
  169. return 0;
  170. }
  171. static PyMethodDef
  172. Variable_methods[] = {
  173. { "name", ( PyCFunction )Variable_name, METH_NOARGS,
  174. "Get the name of the variable." },
  175. { "setName", ( PyCFunction )Variable_setName, METH_O,
  176. "Set the name of the variable." },
  177. { "context", ( PyCFunction )Variable_context, METH_NOARGS,
  178. "Get the context object associated with the variable." },
  179. { "setContext", ( PyCFunction )Variable_setContext, METH_O,
  180. "Set the context object associated with the variable." },
  181. { "value", ( PyCFunction )Variable_value, METH_NOARGS,
  182. "Get the current value of the variable." },
  183. { 0 } // sentinel
  184. };
  185. static PyNumberMethods
  186. Variable_as_number = {
  187. (binaryfunc)Variable_add, /* nb_add */
  188. (binaryfunc)Variable_sub, /* nb_subtract */
  189. (binaryfunc)Variable_mul, /* nb_multiply */
  190. #if PY_MAJOR_VERSION < 3
  191. (binaryfunc)Variable_div, /* nb_divide */
  192. #endif
  193. 0, /* nb_remainder */
  194. 0, /* nb_divmod */
  195. 0, /* nb_power */
  196. (unaryfunc)Variable_neg, /* nb_negative */
  197. 0, /* nb_positive */
  198. 0, /* nb_absolute */
  199. #if PY_MAJOR_VERSION >= 3
  200. 0, /* nb_bool */
  201. #else
  202. 0, /* nb_nonzero */
  203. #endif
  204. 0, /* nb_invert */
  205. 0, /* nb_lshift */
  206. 0, /* nb_rshift */
  207. 0, /* nb_and */
  208. 0, /* nb_xor */
  209. (binaryfunc)0, /* nb_or */
  210. #if PY_MAJOR_VERSION < 3
  211. 0, /* nb_coerce */
  212. #endif
  213. 0, /* nb_int */
  214. 0, /* nb_long */
  215. 0, /* nb_float */
  216. #if PY_MAJOR_VERSION < 3
  217. 0, /* nb_oct */
  218. 0, /* nb_hex */
  219. #endif
  220. 0, /* nb_inplace_add */
  221. 0, /* nb_inplace_subtract */
  222. 0, /* nb_inplace_multiply */
  223. #if PY_MAJOR_VERSION < 3
  224. 0, /* nb_inplace_divide */
  225. #endif
  226. 0, /* nb_inplace_remainder */
  227. 0, /* nb_inplace_power */
  228. 0, /* nb_inplace_lshift */
  229. 0, /* nb_inplace_rshift */
  230. 0, /* nb_inplace_and */
  231. 0, /* nb_inplace_xor */
  232. 0, /* nb_inplace_or */
  233. (binaryfunc)0, /* nb_floor_divide */
  234. (binaryfunc)Variable_div, /* nb_true_divide */
  235. 0, /* nb_inplace_floor_divide */
  236. 0, /* nb_inplace_true_divide */
  237. #if PY_VERSION_HEX >= 0x02050000
  238. (unaryfunc)0, /* nb_index */
  239. #endif
  240. #if PY_VERSION_HEX >= 0x03050000
  241. (binaryfunc)0, /* nb_matrix_multiply */
  242. (binaryfunc)0, /* nb_inplace_matrix_multiply */
  243. #endif
  244. };
  245. PyTypeObject Variable_Type = {
  246. PyVarObject_HEAD_INIT( &PyType_Type, 0 )
  247. "kiwisolver.Variable", /* tp_name */
  248. sizeof( Variable ), /* tp_basicsize */
  249. 0, /* tp_itemsize */
  250. (destructor)Variable_dealloc, /* tp_dealloc */
  251. (printfunc)0, /* tp_print */
  252. (getattrfunc)0, /* tp_getattr */
  253. (setattrfunc)0, /* tp_setattr */
  254. #if PY_VERSION_HEX >= 0x03050000
  255. ( PyAsyncMethods* )0, /* tp_as_async */
  256. #elif PY_VERSION_HEX >= 0x03000000
  257. ( void* ) 0, /* tp_reserved */
  258. #else
  259. ( cmpfunc )0, /* tp_compare */
  260. #endif
  261. (reprfunc)Variable_repr, /* tp_repr */
  262. (PyNumberMethods*)&Variable_as_number, /* tp_as_number */
  263. (PySequenceMethods*)0, /* tp_as_sequence */
  264. (PyMappingMethods*)0, /* tp_as_mapping */
  265. (hashfunc)0, /* tp_hash */
  266. (ternaryfunc)0, /* tp_call */
  267. (reprfunc)0, /* tp_str */
  268. (getattrofunc)0, /* tp_getattro */
  269. (setattrofunc)0, /* tp_setattro */
  270. (PyBufferProcs*)0, /* tp_as_buffer */
  271. #if PY_MAJOR_VERSION >= 3
  272. Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_BASETYPE, /* tp_flags */
  273. #else
  274. Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */
  275. #endif
  276. 0, /* Documentation string */
  277. (traverseproc)Variable_traverse, /* tp_traverse */
  278. (inquiry)Variable_clear, /* tp_clear */
  279. (richcmpfunc)Variable_richcmp, /* tp_richcompare */
  280. 0, /* tp_weaklistoffset */
  281. (getiterfunc)0, /* tp_iter */
  282. (iternextfunc)0, /* tp_iternext */
  283. (struct PyMethodDef*)Variable_methods, /* tp_methods */
  284. (struct PyMemberDef*)0, /* tp_members */
  285. 0, /* tp_getset */
  286. 0, /* tp_base */
  287. 0, /* tp_dict */
  288. (descrgetfunc)0, /* tp_descr_get */
  289. (descrsetfunc)0, /* tp_descr_set */
  290. 0, /* tp_dictoffset */
  291. (initproc)0, /* tp_init */
  292. (allocfunc)PyType_GenericAlloc, /* tp_alloc */
  293. (newfunc)Variable_new, /* tp_new */
  294. (freefunc)PyObject_GC_Del, /* tp_free */
  295. (inquiry)0, /* tp_is_gc */
  296. 0, /* tp_bases */
  297. 0, /* tp_mro */
  298. 0, /* tp_cache */
  299. 0, /* tp_subclasses */
  300. 0, /* tp_weaklist */
  301. (destructor)0 /* tp_del */
  302. };
  303. int import_variable()
  304. {
  305. return PyType_Ready( &Variable_Type );
  306. }