|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
-
- #pragma once
-
- #include <optional>
- #include <functional>
- #include <memory>
- #include <chrono>
- #include <type_traits>
- #include <stddef.h>
-
- namespace Swan {
-
- // Inherit from this class to make a class non-copyable
- class NonCopyable {
- public:
- NonCopyable(const NonCopyable &) = delete;
- NonCopyable(NonCopyable &&) noexcept = default;
- NonCopyable &operator=(const NonCopyable &) = delete;
- NonCopyable &operator=(NonCopyable &&) = default;
-
- protected:
- NonCopyable() = default;
- ~NonCopyable() = default;
- };
-
- // Take a deleter function, turn it into a class with an operator() for unique_ptr
- template<typename T, void (*Func)(T *)>
- class CPtrDeleter {
- public:
- void operator()(T *ptr) { Func(ptr); }
- };
-
- // This is just a bit nicer to use than using unique_ptr directly
- template<typename T, void (*Func)(T *)>
- using CPtr = std::unique_ptr<T, CPtrDeleter<T, Func>>;
-
- // Take a function, run it when the object goes out of scope
- template<void (*Func)()>
- class Deferred: NonCopyable {
- public:
- Deferred() = default;
- ~Deferred() { Func(); }
- };
-
- // Calling begin/end is stupid...
- template<typename T>
- auto callBegin(T &v) {
- using namespace std;
- return begin(v);
- }
- template<typename T>
- auto callEnd(T &v) {
- using namespace std;
- return end(v);
- }
-
- // Ret can't be a reference, because C++ doesn't support optional<T&>.
- template<typename Ret, typename Func = std::function<std::optional<Ret>()>>
- class Iter {
- public:
- class It {
- public:
- It(std::optional<Ret> next, Func &func): next_(std::move(next)), func_(func) {}
-
- bool operator==(const It &other) const {
- return next_ == std::nullopt && other.next_ == std::nullopt;
- }
-
- bool operator!=(const It &other) const {
- return !(*this == other);
- }
-
- void operator++() {
- auto val(func_());
- if (val)
- next_.emplace(std::move(*val));
- else
- next_.reset();
- }
-
- Ret operator*() {
- return std::move(*next_);
- }
-
- private:
- std::optional<Ret> next_;
- Func &func_;
- };
-
- Iter(Func func): func_(func) {}
-
- operator Iter<Ret, std::function<std::optional<Ret>()>>() {
- return Iter<Ret, std::function<std::optional<Ret>()>>(func_);
- }
-
- It begin() {
- return It(func_(), func_);
- }
-
- It end() {
- return It(std::nullopt, func_);
- }
-
- private:
- Func func_;
- };
-
- template<typename InputIterator, typename Func>
- auto map(InputIterator first, InputIterator last, Func func) {
- using RetT = decltype(func(*first));
-
- auto l = [=]() mutable -> std::optional<RetT> {
- if (first == last)
- return std::nullopt;
-
- RetT r = func(*first);
- ++first;
- return r;
- };
-
- return Iter<RetT, decltype(l)>(l);
- }
-
- template<typename Range, typename Func>
- auto map(Range &rng, Func func) {
- return map(callBegin(rng), callEnd(rng), func);
- }
-
- template<typename InputIterator, typename Func>
- auto filter(InputIterator first, InputIterator last, Func pred) {
- using RetT = std::remove_reference_t<decltype(*first)>;
-
- auto l = [=]() mutable -> std::optional<RetT> {
- if (first == last)
- return std::nullopt;
-
- while (!pred(*first)) {
- ++first;
- if (first == last)
- return std::nullopt;
- }
-
- RetT r = *first;
- ++first;
- return r;
- };
-
- return Iter<RetT, decltype(l)>(l);
- }
-
- template<typename Range, typename Func>
- auto filter(Range &rng, Func func) {
- return filter(callBegin(rng), callEnd(rng), func);
- }
-
- template<typename InputIterator, typename Func>
- auto mapFilter(InputIterator first, InputIterator last, Func func) {
- using RetT = std::remove_reference_t<decltype(*func(*first))>;
-
- auto l = [=]() mutable -> std::optional<RetT> {
- if (first == last)
- return std::nullopt;
-
- std::optional<RetT> r;
- while ((r = func(*first)) == std::nullopt) {
- ++first;
- if (first == last)
- return std::nullopt;
- }
-
- ++first;
- return r;
- };
-
- return Iter<RetT, decltype(l)>(l);
- }
-
- template<typename Range, typename Func>
- auto mapFilter(Range &rng, Func func) {
- return mapFilter(callBegin(rng), callEnd(rng), func);
- }
-
- }
|