: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 #include #include #include #include #include #include template using Value_type = typename T::value_type; namespace py { // 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; } 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(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 // 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(base)} // { // } // [[nodiscard]] auto contains(T n) const -> bool // { // return !(n < *this->begin()) && n < *this->end(); // } // }; // return iterable_wrapper {ranges::views::iota(start, stop)}; // } template inline 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 (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::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