|
|
@@ -11,10 +11,17 @@ using List = pod_vector<PyObject*>;
|
|
|
|
|
|
class Tuple {
|
|
|
PyObject** _args;
|
|
|
+ PyObject* _inlined[3];
|
|
|
int _size;
|
|
|
|
|
|
+ bool is_inlined() const { return _args == _inlined; }
|
|
|
+
|
|
|
void _alloc(int n){
|
|
|
- this->_args = (n==0) ? nullptr : (PyObject**)pool64.alloc(n * sizeof(void*));
|
|
|
+ if(n <= 3){
|
|
|
+ this->_args = _inlined;
|
|
|
+ }else{
|
|
|
+ this->_args = (PyObject**)pool64.alloc(n * sizeof(void*));
|
|
|
+ }
|
|
|
this->_size = n;
|
|
|
}
|
|
|
|
|
|
@@ -27,40 +34,38 @@ public:
|
|
|
}
|
|
|
|
|
|
Tuple(Tuple&& other) noexcept {
|
|
|
- this->_args = other._args;
|
|
|
- this->_size = other._size;
|
|
|
- other._args = nullptr;
|
|
|
- other._size = 0;
|
|
|
+ _size = other._size;
|
|
|
+ if(other.is_inlined()){
|
|
|
+ _args = _inlined;
|
|
|
+ for(int i=0; i<_size; i++) _args[i] = other._args[i];
|
|
|
+ }else{
|
|
|
+ _args = other._args;
|
|
|
+ other._args = other._inlined;
|
|
|
+ other._size = 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- Tuple(std::initializer_list<PyObject*> list) : Tuple(list.size()){
|
|
|
- int i = 0;
|
|
|
- for(PyObject* p : list) _args[i++] = p;
|
|
|
- }
|
|
|
-
|
|
|
- Tuple(List&& other) noexcept : Tuple(other.size()){
|
|
|
+ Tuple(List&& other) noexcept {
|
|
|
+ _size = other.size();
|
|
|
_args = other._data;
|
|
|
other._data = nullptr;
|
|
|
}
|
|
|
|
|
|
+ Tuple(std::initializer_list<PyObject*> list) {
|
|
|
+ _alloc(list.size());
|
|
|
+ int i = 0;
|
|
|
+ for(PyObject* obj: list) _args[i++] = obj;
|
|
|
+ }
|
|
|
+
|
|
|
PyObject*& operator[](int i){ return _args[i]; }
|
|
|
PyObject* operator[](int i) const { return _args[i]; }
|
|
|
|
|
|
- Tuple& operator=(Tuple&& other) noexcept {
|
|
|
- if(_args!=nullptr) pool64.dealloc(_args);
|
|
|
- this->_args = other._args;
|
|
|
- this->_size = other._size;
|
|
|
- other._args = nullptr;
|
|
|
- other._size = 0;
|
|
|
- return *this;
|
|
|
- }
|
|
|
-
|
|
|
int size() const { return _size; }
|
|
|
|
|
|
PyObject** begin() const { return _args; }
|
|
|
PyObject** end() const { return _args + _size; }
|
|
|
|
|
|
- ~Tuple(){ if(_args!=nullptr) pool64.dealloc(_args); }
|
|
|
+ ~Tuple(){ if(!is_inlined()) pool64.dealloc(_args); }
|
|
|
};
|
|
|
|
|
|
// a lightweight view for function args, it does not own the memory
|
|
|
@@ -70,7 +75,6 @@ struct ArgsView{
|
|
|
|
|
|
ArgsView(PyObject** begin, PyObject** end) : _begin(begin), _end(end) {}
|
|
|
ArgsView(const Tuple& t) : _begin(t.begin()), _end(t.end()) {}
|
|
|
- ArgsView(): _begin(nullptr), _end(nullptr) {}
|
|
|
|
|
|
PyObject** begin() const { return _begin; }
|
|
|
PyObject** end() const { return _end; }
|