#ifndef QUERY_QUERY_RESULT_HPP #define QUERY_QUERY_RESULT_HPP #include "matador/object/attribute_definition.hpp" #include "matador/sql/internal/query_result_impl.hpp" #include #include namespace matador::sql { class record; template < typename Type > class query_result; template < typename Type > class query_result_iterator { public: using iterator_category = std::forward_iterator_tag; using value_type = Type; using difference_type = std::ptrdiff_t; using self = query_result_iterator; /**< Shortcut for this class. */ using pointer = value_type*; /**< Shortcut for the pointer type. */ using reference = value_type&; /**< Shortcut for the reference type */ public: query_result_iterator() = default; explicit query_result_iterator(query_result *res) : result_(res) {} query_result_iterator(query_result *res, std::unique_ptr obj) : obj_(std::move(obj)) , result_(res) {} query_result_iterator(query_result_iterator&& x) noexcept : obj_(std::move(x.obj_)) , result_(x.result_) {} query_result_iterator& operator=(query_result_iterator&& x) noexcept { result_ = x.result_; obj_ = std::move(x.obj_); return *this; } ~query_result_iterator() = default; bool operator==(const query_result_iterator& rhs) { return obj_ == rhs.obj_; } bool operator!=(const query_result_iterator& rhs) { return obj_ != rhs.obj_; } self& operator++() { obj_.reset(result_->create()); result_->bind(*obj_); if (!result_->fetch(*obj_)) { obj_.reset(); } return *this; } self operator++(int) { const self tmp(result_, obj_); obj_.reset(result_->create()); result_->bind(*obj_); if (!result_->fetch(*obj_)) { obj_.reset(); } return tmp; } pointer operator->() { return obj_.get(); } reference operator*() { return *obj_; } pointer get() { return obj_.get(); } pointer release() { return obj_.release(); } private: std::unique_ptr obj_; query_result *result_{nullptr}; }; namespace detail { template < typename Type > Type* create_prototype(const std::vector &/*prototype*/) { return new Type{}; } template <> record* create_prototype(const std::vector &prototype); } template class query_result final { public: using iterator = query_result_iterator; using creator_func = std::function; public: // explicit query_result(std::unique_ptr &&impl) // : impl_(std::move(impl)) // , creator_([this] { // return detail::create_prototype(impl_->prototype()); // }) {} query_result(std::unique_ptr &&impl, creator_func&& creator) : impl_(std::move(impl)) , creator_(std::move(creator)) {} iterator begin() { return std::move(++iterator(this)); } iterator end() { return {}; } private: friend class query_result_iterator; Type* create(); void bind(const Type& obj); bool fetch(Type& obj); protected: std::unique_ptr impl_; creator_func creator_; }; template Type *query_result::create() { return creator_(); } template void query_result::bind(const Type &obj) { impl_->bind(obj); } template bool query_result::fetch(Type &obj) { return impl_->fetch(obj); } } // namespace matador::sql #endif //QUERY_QUERY_RESULT_HPP