| Server IP : 217.160.0.135 / Your IP : 216.73.217.25 Web Server : Apache System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64 User : sws1074145052 ( 1074145052) PHP Version : 8.3.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /lib/python3/dist-packages/pythran/pythonic/include/types/ |
Upload File : |
#ifndef PYTHONIC_INCLUDE_TYPES_DICT_HPP
#define PYTHONIC_INCLUDE_TYPES_DICT_HPP
#include "pythonic/include/types/assignable.hpp"
#include "pythonic/include/types/tuple.hpp"
#include "pythonic/include/types/empty_iterator.hpp"
#include "pythonic/include/utils/shared_ref.hpp"
#include "pythonic/include/utils/iterator.hpp"
#include "pythonic/include/utils/reserve.hpp"
#include "pythonic/include/builtins/None.hpp"
#include <memory>
#include <utility>
#include <limits>
#include <algorithm>
#include <iterator>
#include <unordered_map>
PYTHONIC_NS_BEGIN
namespace types
{
static const size_t DEFAULT_DICT_CAPACITY = 64;
struct empty_dict;
template <class I>
struct item_iterator_adaptator : public I {
using value_type = make_tuple_t<
typename std::remove_cv<typename I::value_type::first_type>::type,
typename I::value_type::second_type>;
using pointer = value_type *;
using reference = value_type &;
item_iterator_adaptator() = default;
item_iterator_adaptator(I const &i);
value_type operator*() const;
};
template <class I>
struct key_iterator_adaptator : public I {
using value_type = typename I::value_type::first_type;
using pointer = typename I::value_type::first_type *;
using reference = typename I::value_type::first_type &;
key_iterator_adaptator();
key_iterator_adaptator(I const &i);
value_type operator*() const;
};
template <class I>
struct value_iterator_adaptator : public I {
using value_type = typename I::value_type::second_type;
using pointer = typename I::value_type::second_type *;
using reference = typename I::value_type::second_type &;
value_iterator_adaptator();
value_iterator_adaptator(I const &i);
value_type operator*() const;
};
template <class D>
struct dict_items {
using iterator = typename D::item_const_iterator;
using value_type = typename iterator::value_type;
D data;
dict_items();
dict_items(D const &d);
iterator begin() const;
iterator end() const;
long size() const;
};
template <class D>
struct dict_keys {
using iterator = typename D::key_const_iterator;
using value_type = typename iterator::value_type;
D data;
dict_keys();
dict_keys(D const &d);
iterator begin() const;
iterator end() const;
long size() const;
};
template <class D>
struct dict_values {
using iterator = typename D::value_const_iterator;
using value_type = typename iterator::value_type;
D data;
dict_values();
dict_values(D const &d);
iterator begin() const;
iterator end() const;
long size() const;
};
template <class K, class V>
class dict
{
// data holder
using _key_type =
typename std::remove_cv<typename std::remove_reference<K>::type>::type;
using _value_type =
typename std::remove_cv<typename std::remove_reference<V>::type>::type;
using container_type = std::unordered_map<_key_type, _value_type>;
utils::shared_ref<container_type> data;
template <class Kp, class Vp>
friend class dict;
public:
// types
using reference = typename container_type::reference;
using const_reference = typename container_type::const_reference;
using iterator = utils::comparable_iterator<
key_iterator_adaptator<typename container_type::iterator>>;
using const_iterator = utils::comparable_iterator<
key_iterator_adaptator<typename container_type::const_iterator>>;
using item_iterator = utils::comparable_iterator<
item_iterator_adaptator<typename container_type::iterator>>;
using item_const_iterator = utils::comparable_iterator<
item_iterator_adaptator<typename container_type::const_iterator>>;
using key_iterator = utils::comparable_iterator<
key_iterator_adaptator<typename container_type::iterator>>;
using key_const_iterator = utils::comparable_iterator<
key_iterator_adaptator<typename container_type::const_iterator>>;
using value_iterator = utils::comparable_iterator<
value_iterator_adaptator<typename container_type::iterator>>;
using value_const_iterator = utils::comparable_iterator<
value_iterator_adaptator<typename container_type::const_iterator>>;
using size_type = typename container_type::size_type;
using difference_type = typename container_type::difference_type;
using value_type = typename container_type::value_type;
using allocator_type = typename container_type::allocator_type;
using pointer = typename container_type::pointer;
using const_pointer = typename container_type::const_pointer;
// constructors
dict();
dict(empty_dict const &);
dict(std::initializer_list<value_type> l);
dict(dict<K, V> const &other);
template <class Kp, class Vp>
dict(dict<Kp, Vp> const &other);
template <class B, class E>
dict(B begin, E end);
// iterators
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
item_iterator item_begin();
item_const_iterator item_begin() const;
item_iterator item_end();
item_const_iterator item_end() const;
key_iterator key_begin();
key_const_iterator key_begin() const;
key_iterator key_end();
key_const_iterator key_end() const;
value_iterator value_begin();
value_const_iterator value_begin() const;
value_iterator value_end();
value_const_iterator value_end() const;
// dict interface
operator bool();
V &operator[](K const &key);
template <class OtherKey>
V &operator[](OtherKey const &key)
{
return (*this)[K(key)];
}
V const &operator[](K const &key) const;
template <class OtherKey>
V const &operator[](OtherKey const &key) const
{
return (*this)[K(key)];
}
V &fast(K const &key);
V const &fast(K const &key) const;
item_const_iterator find(K const &key) const;
void clear();
dict<K, V> copy() const;
template <class W>
typename __combined<V, W>::type get(K const &key, W d) const;
none<V> get(K const &key) const;
template <class W>
V &setdefault(K const &key, W d);
none<V> &setdefault(K const &key);
template <class K0, class W0>
void update(dict<K0, W0> const &d);
template <class Iterable>
void update(Iterable const &d);
template <class W>
typename __combined<V, W>::type pop(K const &key, W d);
V pop(K const &key);
make_tuple_t<K, V> popitem();
long size() const;
dict_items<dict<K, V>> items() const;
dict_keys<dict<K, V>> keys() const;
dict_values<dict<K, V>> values() const;
// type inference stuff
template <class K_, class V_>
dict<typename __combined<K, K_>::type, typename __combined<V, V_>::type>
operator+(dict<K_, V_> const &);
// id interface
intptr_t id() const;
template <class T>
bool contains(T const &key) const;
};
struct empty_dict {
using value_type = void;
using iterator = empty_iterator;
using const_iterator = empty_iterator;
template <class K, class V>
dict<K, V> operator+(dict<K, V> const &s);
empty_dict operator+(empty_dict const &);
operator bool() const;
iterator begin() const;
iterator end() const;
template <class V>
bool contains(V const &) const;
};
template <class K, class V>
dict<K, V> operator+(dict<K, V> const &d, empty_dict);
}
template <class K, class V>
struct assignable<types::dict<K, V>> {
using type =
types::dict<typename assignable<K>::type, typename assignable<V>::type>;
};
std::ostream &operator<<(std::ostream &os, types::empty_dict const &);
template <class K, class V>
std::ostream &operator<<(std::ostream &os, std::pair<K, V> const &p);
template <class K, class V>
std::ostream &operator<<(std::ostream &os, types::dict<K, V> const &v);
PYTHONIC_NS_END
/* overload std::get */
namespace std
{
template <size_t I, class K, class V>
auto get(pythonic::types::dict<K, V> &d) -> decltype(d[I]);
template <size_t I, class K, class V>
auto get(pythonic::types::dict<K, V> const &d) -> decltype(d[I]);
template <size_t I, class K, class V>
struct tuple_element<I, pythonic::types::dict<K, V>> {
using type = V;
};
}
/* type inference stuff {*/
#include "pythonic/include/types/combined.hpp"
#include "pythonic/include/types/list.hpp"
template <class A>
struct __combined<container<A>, pythonic::types::empty_dict> {
using type = dict_container<A>;
};
template <class A>
struct __combined<pythonic::types::empty_dict, container<A>> {
using type = dict_container<A>;
};
template <class A, class B, class C>
struct __combined<container<A>, pythonic::types::dict<C, B>> {
using type = pythonic::types::dict<C, typename __combined<A, B>::type>;
};
template <class A, class B, class C>
struct __combined<pythonic::types::dict<C, B>, container<A>> {
using type = pythonic::types::dict<C, typename __combined<A, B>::type>;
};
template <class T>
struct __combined<pythonic::types::empty_dict, pythonic::types::list<T>> {
using type = pythonic::types::dict<typename std::tuple_element<0, T>::type,
typename std::tuple_element<1, T>::type>;
};
template <class T, size_t N>
struct __combined<pythonic::types::empty_dict,
pythonic::types::static_list<T, N>> {
using type = pythonic::types::dict<typename std::tuple_element<0, T>::type,
typename std::tuple_element<1, T>::type>;
};
template <class T>
struct __combined<pythonic::types::list<T>, pythonic::types::empty_dict> {
using type = pythonic::types::dict<typename std::tuple_element<0, T>::type,
typename std::tuple_element<1, T>::type>;
};
template <class T, size_t N>
struct __combined<pythonic::types::static_list<T, N>,
pythonic::types::empty_dict> {
using type = pythonic::types::dict<typename std::tuple_element<0, T>::type,
typename std::tuple_element<1, T>::type>;
};
template <class K0, class V0, class T>
struct __combined<pythonic::types::dict<K0, V0>, pythonic::types::list<T>> {
using type = pythonic::types::dict<
typename __combined<K0, typename std::tuple_element<0, T>::type>::type,
typename __combined<V0, typename std::tuple_element<1, T>::type>::type>;
};
template <class K0, class V0, class T, size_t N>
struct __combined<pythonic::types::dict<K0, V0>,
pythonic::types::static_list<T, N>> {
using type = pythonic::types::dict<
typename __combined<K0, typename std::tuple_element<0, T>::type>::type,
typename __combined<V0, typename std::tuple_element<1, T>::type>::type>;
};
template <class K0, class V0, class T>
struct __combined<pythonic::types::list<T>, pythonic::types::dict<K0, V0>> {
using type = pythonic::types::dict<
typename __combined<K0, typename std::tuple_element<0, T>::type>::type,
typename __combined<V0, typename std::tuple_element<1, T>::type>::type>;
};
template <class K0, class V0, class T, size_t N>
struct __combined<pythonic::types::static_list<T, N>,
pythonic::types::dict<K0, V0>> {
using type = pythonic::types::dict<
typename __combined<K0, typename std::tuple_element<0, T>::type>::type,
typename __combined<V0, typename std::tuple_element<1, T>::type>::type>;
};
template <class K>
struct __combined<indexable<K>, pythonic::types::empty_dict> {
using type = indexable_dict<K>;
};
template <class K>
struct __combined<pythonic::types::empty_dict, indexable_dict<K>> {
using type = indexable_dict<K>;
};
template <class K>
struct __combined<indexable_dict<K>, pythonic::types::empty_dict> {
using type = indexable_dict<K>;
};
template <class K0, class K1, class V1>
struct __combined<pythonic::types::dict<K1, V1>, indexable_dict<K0>> {
using type = pythonic::types::dict<typename __combined<K0, K1>::type, V1>;
};
template <class K0, class K1, class V1>
struct __combined<indexable_dict<K0>, pythonic::types::dict<K1, V1>> {
using type = pythonic::types::dict<typename __combined<K0, K1>::type, V1>;
};
template <class K>
struct __combined<pythonic::types::empty_dict, indexable<K>> {
using type = indexable_dict<K>;
};
template <class K0, class V, class K1>
struct __combined<pythonic::types::dict<K0, V>, indexable<K1>> {
using type = pythonic::types::dict<typename __combined<K0, K1>::type, V>;
};
template <class K0, class V, class K1>
struct __combined<indexable<K1>, pythonic::types::dict<K0, V>> {
using type = pythonic::types::dict<typename __combined<K0, K1>::type, V>;
};
template <class K, class V>
struct __combined<pythonic::types::empty_dict, indexable_container<K, V>> {
using type = pythonic::types::dict<K, V>;
};
template <class K0, class V0, class K1, class V1>
struct __combined<pythonic::types::dict<K0, V0>, indexable_container<K1, V1>> {
using type = pythonic::types::dict<typename __combined<K0, K1>::type,
typename __combined<V0, V1>::type>;
};
template <class K0, class V0, class K1, class V1>
struct __combined<indexable_container<K1, V1>, pythonic::types::dict<K0, V0>> {
using type = pythonic::types::dict<typename __combined<K0, K1>::type,
typename __combined<V0, V1>::type>;
};
template <class K, class V>
struct __combined<indexable_container<K, V>, pythonic::types::empty_dict> {
using type = pythonic::types::dict<K, V>;
};
template <class K, class V>
struct __combined<indexable<K>, dict_container<V>> {
using type = pythonic::types::dict<K, V>;
};
template <class V, class K>
struct __combined<dict_container<V>, indexable<K>> {
using type = pythonic::types::dict<K, V>;
};
template <class V, class K, class W>
struct __combined<dict_container<V>, indexable_container<K, W>> {
using type = pythonic::types::dict<K, typename __combined<V, W>::type>;
};
template <class V, class K, class W>
struct __combined<indexable_container<K, W>, dict_container<V>> {
using type = pythonic::types::dict<K, typename __combined<V, W>::type>;
};
template <class V, class K, class W>
struct __combined<indexable_dict<V>, indexable_container<K, W>> {
using type = pythonic::types::dict<typename __combined<K, V>::type, W>;
};
template <class V, class K, class W>
struct __combined<indexable_container<K, W>, indexable_dict<V>> {
using type = pythonic::types::dict<typename __combined<K, V>::type, W>;
};
template <class K, class V, class W>
struct __combined<pythonic::types::dict<K, V>, dict_container<W>> {
using type = pythonic::types::dict<K, typename __combined<V, W>::type>;
};
template <class V, class K, class W>
struct __combined<dict_container<W>, pythonic::types::dict<K, V>> {
using type = pythonic::types::dict<K, typename __combined<V, W>::type>;
};
template <class K, class V>
struct __combined<indexable_dict<K>, container<V>> {
using type = pythonic::types::dict<K, V>;
};
template <class K0, class K1>
struct __combined<indexable_dict<K0>, indexable<K1>> {
using type = indexable_dict<typename __combined<K0, K1>::type>;
};
template <class K0, class K1>
struct __combined<indexable<K0>, indexable_dict<K1>> {
using type = indexable_dict<typename __combined<K0, K1>::type>;
};
template <class V, class K>
struct __combined<container<V>, indexable_dict<K>> {
using type = pythonic::types::dict<K, V>;
};
/* } */
#ifdef ENABLE_PYTHON_MODULE
#include "pythonic/python/core.hpp"
PYTHONIC_NS_BEGIN
template <typename K, typename V>
struct to_python<types::dict<K, V>> {
static PyObject *convert(types::dict<K, V> const &v);
};
template <>
struct to_python<types::empty_dict> {
static PyObject *convert(types::empty_dict);
};
template <typename K, typename V>
struct from_python<types::dict<K, V>> {
static bool is_convertible(PyObject *obj);
static types::dict<K, V> convert(PyObject *obj);
};
PYTHONIC_NS_END
#endif
#endif