tuplelist.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #pragma once
  2. #include "common.h"
  3. #include "memory.h"
  4. #include "str.h"
  5. #include "vector.h"
  6. namespace pkpy {
  7. using List = pod_vector<PyObject*>;
  8. class Tuple {
  9. PyObject** _args;
  10. int _size;
  11. void _alloc(int n){
  12. this->_args = (n==0) ? nullptr : (PyObject**)pool64.alloc(n * sizeof(void*));
  13. this->_size = n;
  14. }
  15. public:
  16. Tuple(int n){ _alloc(n); }
  17. Tuple(const Tuple& other){
  18. _alloc(other._size);
  19. for(int i=0; i<_size; i++) _args[i] = other._args[i];
  20. }
  21. Tuple(Tuple&& other) noexcept {
  22. this->_args = other._args;
  23. this->_size = other._size;
  24. other._args = nullptr;
  25. other._size = 0;
  26. }
  27. Tuple(std::initializer_list<PyObject*> list) : Tuple(list.size()){
  28. int i = 0;
  29. for(PyObject* p : list) _args[i++] = p;
  30. }
  31. Tuple(List&& other) noexcept : Tuple(other.size()){
  32. for(int i=0; i<_size; i++) _args[i] = other[i];
  33. other.clear();
  34. }
  35. PyObject*& operator[](int i){ return _args[i]; }
  36. PyObject* operator[](int i) const { return _args[i]; }
  37. Tuple& operator=(Tuple&& other) noexcept {
  38. if(_args!=nullptr) pool64.dealloc(_args);
  39. this->_args = other._args;
  40. this->_size = other._size;
  41. other._args = nullptr;
  42. other._size = 0;
  43. return *this;
  44. }
  45. int size() const { return _size; }
  46. PyObject** begin() const { return _args; }
  47. PyObject** end() const { return _args + _size; }
  48. List to_list() noexcept {
  49. List ret(_size);
  50. // TODO: use move/memcpy
  51. for(int i=0; i<_size; i++) ret[i] = _args[i];
  52. return ret;
  53. }
  54. void extend_self(PyObject* self){
  55. PyObject** old_args = _args;
  56. int old_size = _size;
  57. _alloc(old_size+1);
  58. _args[0] = self;
  59. for(int i=0; i<old_size; i++) _args[i+1] = old_args[i];
  60. if(old_args!=nullptr) pool64.dealloc(old_args);
  61. }
  62. ~Tuple(){ if(_args!=nullptr) pool64.dealloc(_args); }
  63. };
  64. using Args = Tuple;
  65. inline const Args& no_arg() {
  66. static const Args _zero(0);
  67. return _zero;
  68. }
  69. // a lightweight view for function args, it does not own the memory
  70. struct ArgsView{
  71. PyObject** _begin;
  72. PyObject** _end;
  73. ArgsView(PyObject** begin, PyObject** end) : _begin(begin), _end(end) {}
  74. ArgsView(const Tuple& t) : _begin(t.begin()), _end(t.end()) {}
  75. ArgsView(): _begin(nullptr), _end(nullptr) {}
  76. PyObject** begin() const { return _begin; }
  77. PyObject** end() const { return _end; }
  78. int size() const { return _end - _begin; }
  79. bool empty() const { return _begin == _end; }
  80. PyObject* operator[](int i) const { return _begin[i]; }
  81. };
  82. } // namespace pkpy