| 2197 | } |
| 2198 | |
| 2199 | class dict : public object { |
| 2200 | public: |
| 2201 | PYBIND11_OBJECT_CVT(dict, object, PyDict_Check, raw_dict) |
| 2202 | dict() : object(PyDict_New(), stolen_t{}) { |
| 2203 | if (!m_ptr) { |
| 2204 | pybind11_fail("Could not allocate dict object!"); |
| 2205 | } |
| 2206 | } |
| 2207 | template <typename... Args, |
| 2208 | typename = detail::enable_if_t<args_are_all_keyword_or_ds<Args...>()>, |
| 2209 | // MSVC workaround: it can't compile an out-of-line definition, so defer the |
| 2210 | // collector |
| 2211 | typename collector = detail::deferred_t<detail::unpacking_collector<>, Args...>> |
| 2212 | explicit dict(Args &&...args) : dict(collector(std::forward<Args>(args)...).kwargs()) {} |
| 2213 | |
| 2214 | size_t size() const { return static_cast<size_t>(PyDict_Size(m_ptr)); } |
| 2215 | bool empty() const { return size() == 0; } |
| 2216 | detail::dict_iterator begin() const { return {*this, 0}; } |
| 2217 | detail::dict_iterator end() const { return {}; } |
| 2218 | void clear() /* py-non-const */ { PyDict_Clear(ptr()); } |
| 2219 | template <typename T> |
| 2220 | bool contains(T &&key) const { |
| 2221 | auto result = PyDict_Contains(m_ptr, detail::object_or_cast(std::forward<T>(key)).ptr()); |
| 2222 | if (result == -1) { |
| 2223 | throw error_already_set(); |
| 2224 | } |
| 2225 | return result == 1; |
| 2226 | } |
| 2227 | |
| 2228 | private: |
| 2229 | /// Call the `dict` Python type -- always returns a new reference |
| 2230 | static PyObject *raw_dict(PyObject *op) { |
| 2231 | if (PyDict_Check(op)) { |
| 2232 | return handle(op).inc_ref().ptr(); |
| 2233 | } |
| 2234 | return PyObject_CallFunctionObjArgs( |
| 2235 | reinterpret_cast<PyObject *>(&PyDict_Type), op, nullptr); |
| 2236 | } |
| 2237 | }; |
| 2238 | |
| 2239 | class sequence : public object { |
| 2240 | public: |
no outgoing calls