tuplelist.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #pragma once
  2. #include "common.h"
  3. #include "memory.h"
  4. #include "str.h"
  5. namespace pkpy {
  6. using List = std::vector<PyVar>;
  7. class Args {
  8. static THREAD_LOCAL SmallArrayPool<PyVar, 10> _pool;
  9. PyVar* _args;
  10. int _size;
  11. inline void _alloc(int n){
  12. this->_args = _pool.alloc(n);
  13. this->_size = n;
  14. }
  15. public:
  16. Args(int n){ _alloc(n); }
  17. Args(const Args& other){
  18. _alloc(other._size);
  19. for(int i=0; i<_size; i++) _args[i] = other._args[i];
  20. }
  21. Args(Args&& other) noexcept {
  22. this->_args = other._args;
  23. this->_size = other._size;
  24. other._args = nullptr;
  25. other._size = 0;
  26. }
  27. static pkpy::Args from_list(List&& other) noexcept {
  28. Args ret(other.size());
  29. memcpy((void*)ret._args, (void*)other.data(), sizeof(PyVar)*ret.size());
  30. memset((void*)other.data(), 0, sizeof(PyVar)*ret.size());
  31. other.clear();
  32. return ret;
  33. }
  34. PyVar& operator[](int i){ return _args[i]; }
  35. const PyVar& operator[](int i) const { return _args[i]; }
  36. Args& operator=(Args&& other) noexcept {
  37. _pool.dealloc(_args, _size);
  38. this->_args = other._args;
  39. this->_size = other._size;
  40. other._args = nullptr;
  41. other._size = 0;
  42. return *this;
  43. }
  44. inline int size() const { return _size; }
  45. List move_to_list() noexcept {
  46. List ret(_size);
  47. memcpy((void*)ret.data(), (void*)_args, sizeof(PyVar)*_size);
  48. memset((void*)_args, 0, sizeof(PyVar)*_size);
  49. return ret;
  50. }
  51. void extend_self(const PyVar& self){
  52. static_assert(std::is_standard_layout_v<PyVar>);
  53. PyVar* old_args = _args;
  54. int old_size = _size;
  55. _alloc(old_size+1);
  56. _args[0] = self;
  57. if(old_size == 0) return;
  58. memcpy((void*)(_args+1), (void*)old_args, sizeof(PyVar)*old_size);
  59. memset((void*)old_args, 0, sizeof(PyVar)*old_size);
  60. _pool.dealloc(old_args, old_size);
  61. }
  62. ~Args(){ _pool.dealloc(_args, _size); }
  63. };
  64. static const Args _zero(0);
  65. inline const Args& no_arg() { return _zero; }
  66. template<typename T>
  67. Args one_arg(T&& a) {
  68. Args ret(1);
  69. ret[0] = std::forward<T>(a);
  70. return ret;
  71. }
  72. template<typename T1, typename T2>
  73. Args two_args(T1&& a, T2&& b) {
  74. Args ret(2);
  75. ret[0] = std::forward<T1>(a);
  76. ret[1] = std::forward<T2>(b);
  77. return ret;
  78. }
  79. template<typename T1, typename T2, typename T3>
  80. Args three_args(T1&& a, T2&& b, T3&& c) {
  81. Args ret(3);
  82. ret[0] = std::forward<T1>(a);
  83. ret[1] = std::forward<T2>(b);
  84. ret[2] = std::forward<T3>(c);
  85. return ret;
  86. }
  87. typedef Args Tuple;
  88. THREAD_LOCAL SmallArrayPool<PyVar, 10> Args::_pool;
  89. } // namespace pkpy