mirror of
				https://github.com/pocketpy/pocketpy
				synced 2025-10-30 16:30:16 +00:00 
			
		
		
		
	* add some clang-format offs. * add formats. * format the world. * AllowShortIfStatementsOnASingleLine * off REGION. * Rollback vm.hpp * Disable insert.
		
			
				
	
	
		
			253 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| 
 | |
| #include "kernel.h"
 | |
| 
 | |
| namespace pybind11 {
 | |
| class handle;
 | |
| class object;
 | |
| class attr_accessor;
 | |
| class item_accessor;
 | |
| class iterator;
 | |
| class str;
 | |
| class bytes;
 | |
| class iterable;
 | |
| class tuple;
 | |
| class dict;
 | |
| class list;
 | |
| class set;
 | |
| class function;
 | |
| class module;
 | |
| class type;
 | |
| class bool_;
 | |
| class int_;
 | |
| class float_;
 | |
| class str;
 | |
| class bytes;
 | |
| 
 | |
| template <typename T>
 | |
| T& _builtin_cast(const handle& obj);
 | |
| 
 | |
| template <typename T>
 | |
| T reinterpret_borrow(const handle& h);
 | |
| 
 | |
| template <typename T>
 | |
| T reinterpret_steal(const handle& h);
 | |
| 
 | |
| class handle {
 | |
| protected:
 | |
|     pkpy::PyVar m_ptr = nullptr;
 | |
|     mutable int* ref_count = nullptr;
 | |
| 
 | |
| public:
 | |
|     handle() = default;
 | |
|     handle(const handle& h) = default;
 | |
|     handle& operator= (const handle& other) = default;
 | |
| 
 | |
|     handle(pkpy::PyVar ptr) : m_ptr(ptr) {}
 | |
| 
 | |
|     pkpy::PyVar ptr() const { return m_ptr; }
 | |
| 
 | |
|     int reference_count() const { return ref_count == nullptr ? 0 : *ref_count; }
 | |
| 
 | |
|     const handle& inc_ref() const {
 | |
|         assert(m_ptr != nullptr);
 | |
|         if(ref_count == nullptr) {
 | |
|             auto iter = _ref_counts_map->find(m_ptr);
 | |
|             if(iter == _ref_counts_map->end()) {
 | |
|                 ref_count = ::new int(1);
 | |
|                 _ref_counts_map->insert({m_ptr, ref_count});
 | |
|             } else {
 | |
|                 ref_count = iter->second;
 | |
|                 *ref_count += 1;
 | |
|             }
 | |
|         } else {
 | |
|             *ref_count += 1;
 | |
|         }
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     const handle& dec_ref() const {
 | |
|         assert(m_ptr != nullptr);
 | |
|         assert(ref_count != nullptr);
 | |
| 
 | |
|         *ref_count -= 1;
 | |
|         try {
 | |
|             if(*ref_count == 0) {
 | |
|                 _ref_counts_map->erase(m_ptr);
 | |
|                 ::delete ref_count;
 | |
|                 ref_count = nullptr;
 | |
|             }
 | |
|         } catch(std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; }
 | |
| 
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
| public:
 | |
|     template <typename T>
 | |
|     T cast() const;
 | |
| 
 | |
|     explicit operator bool () const { return m_ptr.operator bool (); }
 | |
| 
 | |
|     bool is(const handle& other) const { return m_ptr == other.m_ptr; }
 | |
| 
 | |
|     bool is_none() const { return m_ptr == vm->None; }
 | |
| 
 | |
|     bool in(const handle& other) const {
 | |
|         return pkpy::py_cast<bool>(vm, vm->call(vm->py_op("contains"), other.m_ptr, m_ptr));
 | |
|     }
 | |
| 
 | |
|     bool contains(const handle& other) const {
 | |
|         return pkpy::py_cast<bool>(vm, vm->call(vm->py_op("contains"), m_ptr, other.m_ptr));
 | |
|     }
 | |
| 
 | |
|     iterator begin() const;
 | |
|     iterator end() const;
 | |
| 
 | |
|     str doc() const;
 | |
| 
 | |
|     attr_accessor attr(const char* name) const;
 | |
|     attr_accessor attr(const handle& name) const;
 | |
|     attr_accessor attr(object&& name) const;
 | |
| 
 | |
|     item_accessor operator[] (int64_t key) const;
 | |
|     item_accessor operator[] (const char* key) const;
 | |
|     item_accessor operator[] (const handle& key) const;
 | |
|     item_accessor operator[] (object&& key) const;
 | |
| 
 | |
|     object operator- () const;
 | |
|     object operator~() const;
 | |
| 
 | |
|     template <return_value_policy policy = return_value_policy::automatic, typename... Args>
 | |
|     object operator() (Args&&... args) const;
 | |
| 
 | |
| private:
 | |
|     friend object operator+ (const handle& lhs, const handle& rhs);
 | |
|     friend object operator- (const handle& lhs, const handle& rhs);
 | |
|     friend object operator* (const handle& lhs, const handle& rhs);
 | |
|     friend object operator% (const handle& lhs, const handle& rhs);
 | |
|     friend object operator/ (const handle& lhs, const handle& rhs);
 | |
|     friend object operator| (const handle& lhs, const handle& rhs);
 | |
|     friend object operator& (const handle& lhs, const handle& rhs);
 | |
|     friend object operator^ (const handle& lhs, const handle& rhs);
 | |
|     friend object operator<< (const handle& lhs, const handle& rhs);
 | |
|     friend object operator>> (const handle& lhs, const handle& rhs);
 | |
| 
 | |
|     friend object operator+= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator-= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator*= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator/= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator%= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator|= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator&= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator^= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator<<= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator>>= (const handle& lhs, const handle& rhs);
 | |
| 
 | |
|     friend object operator== (const handle& lhs, const handle& rhs);
 | |
|     friend object operator!= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator< (const handle& lhs, const handle& rhs);
 | |
|     friend object operator> (const handle& lhs, const handle& rhs);
 | |
|     friend object operator<= (const handle& lhs, const handle& rhs);
 | |
|     friend object operator>= (const handle& lhs, const handle& rhs);
 | |
| 
 | |
|     template <typename T>
 | |
|     friend T& _builtin_cast(const handle& obj) {
 | |
|         // FIXME: 2.0 does not use Py_<T> anymore
 | |
|         static_assert(!std::is_reference_v<T>, "T must not be a reference type.");
 | |
|         return obj.ptr().obj_get<T>();
 | |
|     }
 | |
| };
 | |
| 
 | |
| static_assert(std::is_trivially_copyable_v<handle>);
 | |
| 
 | |
| class object : public handle {
 | |
| public:
 | |
|     object(const object& other) : handle(other) { inc_ref(); }
 | |
| 
 | |
|     object(object&& other) noexcept : handle(other) {
 | |
|         other.m_ptr = nullptr;
 | |
|         other.ref_count = nullptr;
 | |
|     }
 | |
| 
 | |
|     object& operator= (const object& other) {
 | |
|         if(this != &other) {
 | |
|             dec_ref();
 | |
|             m_ptr = other.m_ptr;
 | |
|             ref_count = other.ref_count;
 | |
|             inc_ref();
 | |
|         }
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     object& operator= (object&& other) noexcept {
 | |
|         if(this != &other) {
 | |
|             dec_ref();
 | |
|             m_ptr = other.m_ptr;
 | |
|             ref_count = other.ref_count;
 | |
|             other.m_ptr = nullptr;
 | |
|             other.ref_count = nullptr;
 | |
|         }
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     ~object() {
 | |
|         if(m_ptr != nullptr) { dec_ref(); }
 | |
|     }
 | |
| 
 | |
| protected:
 | |
|     object(const handle& h, bool borrow) : handle(h) {
 | |
|         if(borrow) { inc_ref(); }
 | |
|     }
 | |
| 
 | |
|     template <typename T>
 | |
|     friend T reinterpret_borrow(const handle& h) {
 | |
|         return {h, true};
 | |
|     }
 | |
| 
 | |
|     template <typename T>
 | |
|     friend T reinterpret_steal(const handle& h) {
 | |
|         return {h, false};
 | |
|     }
 | |
| };
 | |
| 
 | |
| inline void setattr(const handle& obj, const handle& name, const handle& value);
 | |
| inline void setitem(const handle& obj, const handle& key, const handle& value);
 | |
| 
 | |
| #define PYBIND11_BINARY_OPERATOR(OP, NAME)                                                                             \
 | |
|     inline object operator OP (const handle& lhs, const handle& rhs) {                                                 \
 | |
|         return reinterpret_borrow<object>(vm->call(vm->py_op(NAME), lhs.m_ptr, rhs.m_ptr));                            \
 | |
|     }
 | |
| 
 | |
| PYBIND11_BINARY_OPERATOR(+, "add");
 | |
| PYBIND11_BINARY_OPERATOR(-, "sub");
 | |
| PYBIND11_BINARY_OPERATOR(*, "mul");
 | |
| PYBIND11_BINARY_OPERATOR(/, "truediv");
 | |
| PYBIND11_BINARY_OPERATOR(%, "mod");
 | |
| PYBIND11_BINARY_OPERATOR(|, "or_");
 | |
| PYBIND11_BINARY_OPERATOR(&, "and_");
 | |
| PYBIND11_BINARY_OPERATOR(^, "xor");
 | |
| PYBIND11_BINARY_OPERATOR(<<, "lshift");
 | |
| PYBIND11_BINARY_OPERATOR(>>, "rshift");
 | |
| 
 | |
| PYBIND11_BINARY_OPERATOR(+=, "iadd");
 | |
| PYBIND11_BINARY_OPERATOR(-=, "isub");
 | |
| PYBIND11_BINARY_OPERATOR(*=, "imul");
 | |
| PYBIND11_BINARY_OPERATOR(/=, "itruediv");
 | |
| PYBIND11_BINARY_OPERATOR(%=, "imod");
 | |
| PYBIND11_BINARY_OPERATOR(|=, "ior");
 | |
| PYBIND11_BINARY_OPERATOR(&=, "iand");
 | |
| PYBIND11_BINARY_OPERATOR(^=, "ixor");
 | |
| PYBIND11_BINARY_OPERATOR(<<=, "ilshift");
 | |
| PYBIND11_BINARY_OPERATOR(>>=, "irshift");
 | |
| 
 | |
| PYBIND11_BINARY_OPERATOR(==, "eq");
 | |
| PYBIND11_BINARY_OPERATOR(!=, "ne");
 | |
| PYBIND11_BINARY_OPERATOR(<, "lt");
 | |
| PYBIND11_BINARY_OPERATOR(>, "gt");
 | |
| PYBIND11_BINARY_OPERATOR(<=, "le");
 | |
| PYBIND11_BINARY_OPERATOR(>=, "ge");
 | |
| 
 | |
| #undef PYBIND11_BINARY_OPERATOR
 | |
| 
 | |
| }  // namespace pybind11
 |