PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/nuitka/build/include/nuitka/helper/slices.hpp

https://bitbucket.org/pombredanne/nuitka
C++ Header | 236 lines | 162 code | 54 blank | 20 comment | 43 complexity | 9b144174f0486d8f17f1985d9f3404b4 MD5 | raw file
  1. // Copyright 2013, Kay Hayen, mailto:kay.hayen@gmail.com
  2. //
  3. // Part of "Nuitka", an optimizing Python compiler that is compatible and
  4. // integrates with CPython, but also works on its own.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License");
  7. // you may not use this file except in compliance with the License.
  8. // You may obtain a copy of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS,
  14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. // See the License for the specific language governing permissions and
  16. // limitations under the License.
  17. //
  18. #ifndef __NUITKA_HELPER_SLICES_H__
  19. #define __NUITKA_HELPER_SLICES_H__
  20. static inline bool IS_INDEXABLE( PyObject *value )
  21. {
  22. return
  23. value == Py_None ||
  24. #if PYTHON_VERSION < 300
  25. PyInt_Check( value ) ||
  26. #endif
  27. PyLong_Check( value ) ||
  28. PyIndex_Check( value );
  29. }
  30. #if PYTHON_VERSION < 300
  31. // Note: It appears that Python3 has no index slicing operations anymore, but uses slice
  32. // objects all the time. That's fine and make sure we adhere to it by guarding the
  33. // presence of the helpers.
  34. #define LOOKUP_SLICE( source, lower, upper ) _LOOKUP_SLICE( EVAL_ORDERED_3( source, lower, upper ) )
  35. NUITKA_MAY_BE_UNUSED static PyObject *_LOOKUP_SLICE( EVAL_ORDERED_3( PyObject *source, PyObject *lower, PyObject *upper ) )
  36. {
  37. assertObject( source );
  38. assertObject( lower );
  39. assertObject( upper );
  40. PySequenceMethods *tp_as_sequence = Py_TYPE( source )->tp_as_sequence;
  41. if ( tp_as_sequence && tp_as_sequence->sq_slice && IS_INDEXABLE( lower ) && IS_INDEXABLE( upper ) )
  42. {
  43. Py_ssize_t ilow = 0;
  44. if ( lower != Py_None )
  45. {
  46. ilow = CONVERT_TO_INDEX( lower );
  47. }
  48. Py_ssize_t ihigh = PY_SSIZE_T_MAX;
  49. if ( upper != Py_None )
  50. {
  51. ihigh = CONVERT_TO_INDEX( upper );
  52. }
  53. PyObject *result = PySequence_GetSlice( source, ilow, ihigh );
  54. if (unlikely( result == NULL ))
  55. {
  56. throw PythonException();
  57. }
  58. return result;
  59. }
  60. else
  61. {
  62. PyObject *slice = PySlice_New( lower, upper, NULL );
  63. if (unlikely( slice == NULL ))
  64. {
  65. throw PythonException();
  66. }
  67. PyObject *result = PyObject_GetItem( source, slice );
  68. Py_DECREF( slice );
  69. if (unlikely( result == NULL ))
  70. {
  71. throw PythonException();
  72. }
  73. return result;
  74. }
  75. }
  76. #define LOOKUP_INDEX_SLICE( source, lower, upper ) _LOOKUP_INDEX_SLICE( EVAL_ORDERED_3( source, lower, upper ) )
  77. NUITKA_MAY_BE_UNUSED static PyObject *_LOOKUP_INDEX_SLICE( EVAL_ORDERED_3( PyObject *source, Py_ssize_t lower, Py_ssize_t upper ) )
  78. {
  79. assertObject( source );
  80. PyObject *result = PySequence_GetSlice( source, lower, upper );
  81. if (unlikely( result == NULL ))
  82. {
  83. throw PythonException();
  84. }
  85. return result;
  86. }
  87. #define SET_SLICE( value, target, upper, lower ) _SET_SLICE( EVAL_ORDERED_4( value, target, upper, lower ) )
  88. NUITKA_MAY_BE_UNUSED static void _SET_SLICE( EVAL_ORDERED_4( PyObject *value, PyObject *target, PyObject *lower, PyObject *upper ) )
  89. {
  90. assertObject( target );
  91. assertObject( lower );
  92. assertObject( upper );
  93. assertObject( value );
  94. PySequenceMethods *tp_as_sequence = Py_TYPE( target )->tp_as_sequence;
  95. if ( tp_as_sequence && tp_as_sequence->sq_ass_slice && IS_INDEXABLE( lower ) && IS_INDEXABLE( upper ) )
  96. {
  97. Py_ssize_t lower_int = 0;
  98. if ( lower != Py_None )
  99. {
  100. lower_int = CONVERT_TO_INDEX( lower );
  101. }
  102. Py_ssize_t upper_int = PY_SSIZE_T_MAX;
  103. if ( upper != Py_None )
  104. {
  105. upper_int = CONVERT_TO_INDEX( upper );
  106. }
  107. int status = PySequence_SetSlice( target, lower_int, upper_int, value );
  108. if (unlikely( status == -1 ))
  109. {
  110. throw PythonException();
  111. }
  112. }
  113. else
  114. {
  115. PyObject *slice = PySlice_New( lower, upper, NULL );
  116. if (unlikely( slice == NULL ))
  117. {
  118. throw PythonException();
  119. }
  120. int status = PyObject_SetItem( target, slice, value );
  121. Py_DECREF( slice );
  122. if (unlikely( status == -1 ))
  123. {
  124. throw PythonException();
  125. }
  126. }
  127. }
  128. #define SET_INDEX_SLICE( target, lower, upper, value ) _SET_INDEX_SLICE( EVAL_ORDERED_4( target, lower, upper, value ) )
  129. NUITKA_MAY_BE_UNUSED static void _SET_INDEX_SLICE( EVAL_ORDERED_4( PyObject *target, Py_ssize_t lower, Py_ssize_t upper, PyObject *value ) )
  130. {
  131. assertObject( target );
  132. assertObject( value );
  133. int status = PySequence_SetSlice( target, lower, upper, value );
  134. if (unlikely( status == -1 ))
  135. {
  136. throw PythonException();
  137. }
  138. }
  139. #define DEL_SLICE( target, lower, upper ) _DEL_SLICE( EVAL_ORDERED_3( target, lower, upper ) )
  140. NUITKA_MAY_BE_UNUSED static void _DEL_SLICE( EVAL_ORDERED_3( PyObject *target, Py_ssize_t lower, Py_ssize_t upper ) )
  141. {
  142. assertObject( target );
  143. if ( Py_TYPE( target )->tp_as_sequence && Py_TYPE( target )->tp_as_sequence->sq_ass_slice )
  144. {
  145. int status = PySequence_DelSlice( target, lower, upper );
  146. if (unlikely( status == -1 ))
  147. {
  148. throw PythonException();
  149. }
  150. }
  151. else
  152. {
  153. PyObjectTemporary lower_obj( PyInt_FromSsize_t( lower ) );
  154. PyObjectTemporary upper_obj( PyInt_FromSsize_t( upper ) );
  155. PyObject *slice = PySlice_New( lower_obj.asObject(), upper_obj.asObject(), NULL );
  156. if (unlikely( slice == NULL ))
  157. {
  158. throw PythonException();
  159. }
  160. int status = PyObject_DelItem( target, slice );
  161. Py_DECREF( slice );
  162. if (unlikely( status == -1 ))
  163. {
  164. throw PythonException();
  165. }
  166. }
  167. }
  168. #endif
  169. #define MAKE_SLICEOBJ( start, stop, step ) _MAKE_SLICEOBJ( EVAL_ORDERED_3( start, stop, step ) )
  170. NUITKA_MAY_BE_UNUSED static PyObject *_MAKE_SLICEOBJ( EVAL_ORDERED_3( PyObject *start, PyObject *stop, PyObject *step ) )
  171. {
  172. assertObject( start );
  173. assertObject( stop );
  174. assertObject( step );
  175. PyObject *result = PySlice_New( start, stop, step );
  176. if (unlikely( result == NULL ))
  177. {
  178. throw PythonException();
  179. }
  180. return result;
  181. }
  182. #endif