:github_url: https://github.com/svenevs/exhale-companion .. _program_listing_file_py2cpp_py2cpp.hpp: Program Listing for File py2cpp.hpp =================================== |exhale_lsh| :ref:`Return to documentation for file ` (``py2cpp/py2cpp.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include // std::max #include #include #include #include #include #include template using Value_type = typename T::value_type; namespace py { template ())), typename = decltype(std::end(std::declval()))> constexpr auto enumerate(T &&iterable) { struct iterator { size_t i; TIter iter; auto operator!=(const iterator &other) const -> bool { return iter != other.iter; } void operator++() { ++i; ++iter; } auto operator*() const { return std::tie(i, *iter); } auto operator*() { return std::tie(i, *iter); } }; struct iterable_wrapper { T iterable; auto begin() { return iterator{0, std::begin(iterable)}; } auto end() { return iterator{0, std::end(iterable)}; } }; return iterable_wrapper{std::forward(iterable)}; } // template // 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 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; } }; 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 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; } }; stop = std::max(stop, start); // if (stop < start) { // stop = start; // } return iterable_wrapper{start, stop}; } template inline constexpr auto range(T stop) { return range(T(0), stop); } template class set : public std::unordered_set { using Self = set; public: set() : std::unordered_set{} {} template set(const FwdIter &start, const FwdIter &stop) : std::unordered_set(start, stop) {} set(std::initializer_list init) : std::unordered_set{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 &&) noexcept = default; // private: set(const set &) = default; }; template inline auto operator<(const Key &key, const set &m) -> bool { return m.contains(key); } template inline auto len(const set &m) -> size_t { return m.size(); } // template // set(std::initializer_list) -> set; // template // set(std::initializer_list ) -> set; template 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 class dict : public std::unordered_map { using Self = dict; using Base = std::unordered_map; public: using value_type = std::pair; dict() : std::unordered_map{} {} dict(std::initializer_list init) : std::unordered_map{init} {} // template // explicit dict(const Sequence &S) { // this->reserve(S.size()); // for (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::begin()); return key_iterator{std::unordered_map::begin()}; } auto end() const { using Iter = decltype(std::unordered_map::end()); return key_iterator{std::unordered_map::end()}; } auto items() -> std::unordered_map & { return *this; } auto items() const -> const std::unordered_map & { 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 &&) noexcept = default; ~dict() = default; // private: dict(const dict &) = default; }; template inline auto operator<(const Key &key, const dict &m) -> bool { return m.contains(key); } template inline auto len(const dict &m) -> size_t { return m.size(); } // template // dict(std::initializer_list>) -> dict; // template // dict(const Sequence& S) // -> dict, size_t>; } // namespace py