// file : odb/result.hxx // copyright : Copyright (c) 2009-2019 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file #ifndef ODB_RESULT_HXX #define ODB_RESULT_HXX #include #include // std::ptrdiff_t, std::size_t #include // odb::core #include #include #include namespace odb { class LIBODB_EXPORT result_impl: public details::shared_base { public: virtual ~result_impl (); virtual void invalidate () = 0; protected: result_impl (connection&); protected: database& db_; connection& conn_; // Doubly-linked list of results. // // prev_ == 0 means we are the first element. // next_ == 0 means we are the last element. // next_ == this means we are not on the list. // protected: friend class connection; void list_remove (); result_impl* prev_; result_impl* next_; }; template class result_base; template ::kind> class result_iterator; // Input iterator requirements. // template inline bool operator== (result_iterator i, result_iterator j) { return i.equal (j); } template inline bool operator!= (result_iterator i, result_iterator j) { return !i.equal (j); } template class result: result_base::kind> { public: static const class_kind kind = class_traits::kind; typedef result_base base; typedef typename base::value_type value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef result_iterator iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef typename base::result_impl_type result_impl_type; public: result () { } explicit result (details::shared_ptr impl) : impl_ (impl) { } // Copying or assignment of a result instance leads to one instance // being an alias for another. Think of copying a result as copying // a file handle -- the file you access through either of them is // still the same. // public: result (const result& r) : impl_ (r.impl_) { } result& operator= (const result& r) { if (impl_ != r.impl_) impl_ = r.impl_; return *this; } // Conversion from result to result. // template result (const result& r) // // If you get a compiler error pointing to the line below saying // that the impl_ member is inaccessible, then you are most likely // trying to perform an illegal result conversion, for example, // from result to result. // : impl_ (r.impl_) { } template result& operator= (const result& r) { // If you get a compiler error pointing to the line below saying // that the impl_ member is inaccessible, then you are most likely // trying to perform an illegal result conversion, for example, // from result to result. // if (impl_ != r.impl_) impl_ = r.impl_; return *this; } void swap (result& r) { // @@ add swap() to shared_ptr. // details::shared_ptr p (impl_); impl_ = r.impl_; r.impl_ = p; } public: iterator begin () { if (impl_) impl_->begin (); return iterator (impl_.get ()); } iterator end () { return iterator (); } // Cache the result instead of fetching the data from the database // one row at a time. This is necessary if you plan on performing // database operations while iterating over the result. // public: void cache () { if (impl_) impl_->cache (); } public: bool empty () const { if (impl_ == 0) return true; impl_->begin (); return impl_->end (); } // Size is only known in cached results. // size_type size () const { return impl_ ? impl_->size () : 0; } // query_one() and query_value() implementation details. // public: typedef typename iterator::pointer_type pointer_type; pointer_type one (); bool one (T&); // We cannot return by value here since result can be instantiated // for an abstract type (polymorphic abstract base) and it seems // the signature must be valid to the point being able to call the // necessary constructors. // void value (T&); private: friend class result; details::shared_ptr impl_; }; namespace common { using odb::result; using odb::result_iterator; } } #include #include #endif // ODB_RESULT_HXX