Program Listing for File py2cpp.hpp¶
↰ Return to documentation for file (py2cpp/py2cpp.hpp)
#pragma once
#include <initializer_list>
#include <range/v3/view/iota.hpp>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
template <typename T>
using Value_type = typename T::value_type;
namespace py
{
// template <typename T>
// constexpr auto range(T stop) {
// struct iterator {
// T i;
// constexpr bool operator!=(const iterator &other) const { return i !=
// other.i; } constexpr bool operator==(const iterator &other) const {
// return i == other.i; } constexpr T operator*() const { return i; }
// constexpr iterator &operator++() {
// ++i;
// return *this;
// }
// };
// struct iterable_wrapper {
// using value_type = T; // luk
// T stop;
// constexpr auto begin() const { return iterator{0}; }
// constexpr auto end() const { return iterator{stop}; }
// constexpr auto empty() const -> bool { return stop == 0; }
// constexpr auto size() const -> size_t { return stop; }
// constexpr auto operator[](size_t n) const -> T { return n; } // no
// bounds checking constexpr auto contains(T n) const -> bool { return n
// < stop; }
// };
// if (stop < 0) stop = 0;
// return iterable_wrapper{stop};
// }
template <typename T>
inline constexpr auto range(T start, T stop)
{
struct _iterator
{
T i;
constexpr auto operator!=(const _iterator& other) const -> bool
{
return this->i != other.i;
}
constexpr auto operator==(const _iterator& other) const -> bool
{
return this->i == other.i;
}
constexpr auto operator*() const -> T
{
return this->i;
}
constexpr auto operator++() -> _iterator&
{
++this->i;
return *this;
}
constexpr auto operator++(int) -> _iterator
{
auto temp = *this;
++*this;
return temp;
}
};
struct iterable_wrapper
{
public:
using value_type [[maybe_unused]] = T; // luk:
using key_type [[maybe_unused]] = T; // luk:
using iterator = _iterator; // luk
T start;
T stop;
[[nodiscard]] constexpr auto begin() const
{
return iterator {this->start};
}
[[nodiscard]] constexpr auto end() const
{
return iterator {this->stop};
}
[[nodiscard]] constexpr auto empty() const -> bool
{
return this->stop == this->start;
}
[[nodiscard]] constexpr auto size() const -> size_t
{
return static_cast<size_t>(this->stop - this->start);
}
constexpr auto operator[](size_t n) const -> T
{
return T(this->start + n);
} // no bounds checking
[[nodiscard]] constexpr auto contains(T n) const -> bool
{
return !(n < this->start) && n < this->stop;
}
};
if (stop < start) {
stop = start;
}
return iterable_wrapper {start, stop};
}
// template <typename T>
// inline auto range(T start, T stop)
// {
// using iota_return_type = decltype(ranges::views::iota(start, stop));
// class iterable_wrapper : public iota_return_type
// {
// public:
// using value_type [[maybe_unused]] = T; // luk:
// using key_type [[maybe_unused]] = T; // luk:
// iterable_wrapper(iota_return_type&& base)
// : iota_return_type{std::forward<iota_return_type>(base)}
// {
// }
// [[nodiscard]] auto contains(T n) const -> bool
// {
// return !(n < *this->begin()) && n < *this->end();
// }
// };
// return iterable_wrapper {ranges::views::iota(start, stop)};
// }
template <typename T>
inline auto range(T stop)
{
return range(T(0), stop);
}
template <typename Key>
class set : public std::unordered_set<Key>
{
using Self = set<Key>;
public:
set()
: std::unordered_set<Key> {}
{
}
template <typename FwdIter>
set(const FwdIter& start, const FwdIter& stop)
: std::unordered_set<Key>(start, stop)
{
}
set(std::initializer_list<Key> init)
: std::unordered_set<Key> {init}
{
}
auto contains(const Key& key) const -> bool
{
return this->find(key) != this->end();
}
auto copy() const -> set
{
return *this;
}
auto operator=(const set&) -> set& = delete;
auto operator=(set&&) noexcept -> set& = default;
set(set<Key>&&) noexcept = default;
// private:
set(const set<Key>&) = default;
};
template <typename Key>
inline auto operator<(const Key& key, const set<Key>& m) -> bool
{
return m.contains(key);
}
template <typename Key>
inline auto len(const set<Key>& m) -> size_t
{
return m.size();
}
// template <typename Key>
// set(std::initializer_list<Key>) -> set<Key>;
// template <typename Key>
// set(std::initializer_list<const char*> ) -> set<std::string>;
template <typename Iter>
struct key_iterator : Iter
{
explicit key_iterator(Iter it)
: Iter(it)
{
}
auto operator*() const
{
return Iter::operator*().first;
}
auto operator++() -> key_iterator&
{
Iter::operator++();
return *this;
}
};
template <typename Key, typename T>
class dict : public std::unordered_map<Key, T>
{
using Self = dict<Key, T>;
using Base = std::unordered_map<Key, T>;
public:
using value_type = std::pair<const Key, T>;
dict()
: std::unordered_map<Key, T> {}
{
}
dict(std::initializer_list<value_type> init)
: std::unordered_map<Key, T> {init}
{
}
// template <class Sequence>
// explicit dict(const Sequence &S) {
// this->reserve(S.size());
// for (const auto& [i_v, v] : py::enumerate(S)) {
// (*this)[v] = i_v;
// }
// }
auto contains(const Key& key) const -> bool
{
return this->find(key) != this->end();
}
auto get(const Key& key, const T& default_value) -> T
{
if (!contains(key))
{
return default_value;
}
return (*this)[key];
}
auto begin() const
{
using Iter = decltype(std::unordered_map<Key, T>::begin());
return key_iterator<Iter> {std::unordered_map<Key, T>::begin()};
}
auto end() const
{
using Iter = decltype(std::unordered_map<Key, T>::end());
return key_iterator<Iter> {std::unordered_map<Key, T>::end()};
}
auto items() -> std::unordered_map<Key, T>&
{
return *this;
}
auto items() const -> const std::unordered_map<Key, T>&
{
return *this;
}
auto copy() const -> Self
{
return *this;
}
auto operator[](const Key& k) const -> const T&
{
return this->at(k); // luk: a bug in std::unordered_map?
}
auto operator[](const Key& k) -> T&
{
return Base::operator[](k);
}
auto operator=(const Self&) -> Self& = delete;
auto operator=(Self&&) noexcept -> dict& = default;
dict(dict<Key, T>&&) noexcept = default;
~dict() = default;
// private:
dict(const dict<Key, T>&) = default;
};
template <typename Key, typename T>
inline auto operator<(const Key& key, const dict<Key, T>& m) -> bool
{
return m.contains(key);
}
template <typename Key, typename T>
inline auto len(const dict<Key, T>& m) -> size_t
{
return m.size();
}
// template <typename Key, typename T>
// dict(std::initializer_list<std::pair<const Key, T>>) -> dict<Key, T>;
// template <class Sequence>
// dict(const Sequence& S)
// -> dict<std::remove_cv_t<decltype(*std::begin(S))>, size_t>;
} // namespace py