tuplelist.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. void extend_self(PyObject* self){
  49. PyObject** old_args = _args;
  50. int old_size = _size;
  51. _alloc(old_size+1);
  52. _args[0] = self;
  53. for(int i=0; i<old_size; i++) _args[i+1] = old_args[i];
  54. if(old_args!=nullptr) pool64.dealloc(old_args);
  55. }
  56. ~Tuple(){ if(_args!=nullptr) pool64.dealloc(_args); }
  57. };
  58. using Args = Tuple;
  59. inline const Args& no_arg() {
  60. static const Args _zero(0);
  61. return _zero;
  62. }
  63. // a lightweight view for function args, it does not own the memory
  64. struct ArgsView{
  65. PyObject** _begin;
  66. PyObject** _end;
  67. ArgsView(PyObject** begin, PyObject** end) : _begin(begin), _end(end) {}
  68. ArgsView(const Tuple& t) : _begin(t.begin()), _end(t.end()) {}
  69. ArgsView(): _begin(nullptr), _end(nullptr) {}
  70. PyObject** begin() const { return _begin; }
  71. PyObject** end() const { return _end; }
  72. int size() const { return _end - _begin; }
  73. bool empty() const { return _begin == _end; }
  74. PyObject* operator[](int i) const { return _begin[i]; }
  75. List to_list() const{
  76. List ret(size());
  77. for(int i=0; i<size(); i++) ret[i] = _begin[i];
  78. return ret;
  79. }
  80. Tuple to_tuple() const{
  81. Tuple ret(size());
  82. for(int i=0; i<size(); i++) ret[i] = _begin[i];
  83. return ret;
  84. }
  85. };
  86. } // namespace pkpy