Von Indexiteratoren und Threads die mit Von beginnen



  • Heute eine Schwemme von mir, entschuldigung 😞

    Ich habe im Schweiße meines Angesichts einen folgenden Iterator geschrieben:

    struct default_tag {};
    
    		template< typename ReferenceType, typename PointerType, typename Tag, typename SizeType = std::size_t >
    		struct do_dereference {
    			static ReferenceType dereference( PointerType obj_, SizeType index_ )
    			{
    				return obj_->dereference( index_, Tag() );
    			}
    		};
    
    		template< typename ReferenceType, typename PointerType, typename SizeType >
    		struct do_dereference< ReferenceType, PointerType, default_tag, SizeType > {
    			static ReferenceType dereference( PointerType obj_, SizeType index_ )
    			{
    				return obj_->dereference( index_ );
    			}
    		};
    
    		template< typename ValueType, typename FriendClass, bool IsConst, typename Tag = default_tag, typename SizeType = std::size_t >
    		class index_iterator : 
    public boost::iterator_facade< index_iterator< ValueType, FriendClass, IsConst, Tag, SizeType >,
    typename std::conditional< IsConst, const ValueType, ValueType >::type, std::random_access_iterator_tag > {
    		private:
    			typedef Tag tag_type;
    			typedef SizeType size_type;
    			friend FriendClass;
    
    		public:
    			typedef typename std::conditional< IsConst, const FriendClass*, FriendClass* >::type pointer_type;
    			typedef SizeType size_type;
    
    			index_iterator( pointer_type object, size_type index )
    				: object_( object ), index_( index )
    			{
    			}
    
    			index_iterator( const index_iterator& other )
    			{
    				object_ = other.object_;
    				index_ = other.index_;
    			}
    
    		public:
    			reference dereference() {
    				return do_dereference<reference,pointer_type, tag_type>::dereference( object_, index_ );
    			}
    
    			const reference dereference() const {
    				return do_dereference<const reference,pointer_type, tag_type>::dereference( object_, index_ );
    			}
    
    			void increment() {
    				++index_;
    			}
    
    			void decrement() {
    				--index_;
    			}
    
    			void advance( size_type off ) {
    				index += off;
    			}
    
    			bool equal( const index_iterator& other ) const {
    				assert( object_ == other.object_ );
    				return index_ == other.index_;
    			}
    
    			difference_type distance( index_iterator& other ) const {
    				return index_ - other.index_;
    			}
    
    			operator index_iterator< ValueType, FriendClass, true, Tag, SizeType >() const
    			{
    				return index_iterator< ValueType, FriendClass, true, Tag, SizeType >( object_, index_ )
    			}
    
    		private:
    			pointer_type object_;
    			size_type get_index() const { return index_; }
    			size_type index_;
    		};
    

    Sodass folgendes Minimalbeispiel funktioniert:

    class my_vector {
    public:
    	typedef utility::index_iterator< double, my_vector, false > iterator;
    	typedef utility::index_iterator< double, my_vector, true  > const_iterator;
    
    	iterator begin() {
    		return iterator( this, 0 );
    	}
    
    	iterator end() {
    		return iterator( this, vec_.size() );
    	}
    
    	double& dereference( std::size_t index ) {
    		return vec_[index];
    	}
    
    private:
    	std::vector< double > vec_;
    };
    

    Jetzt meine Fragen:
    - Gibts sowas schon? Sinnlos?
    - Werden die nutzlosen Tag-Argumente vom Compiler wegoptimiert?

    Viele Grüße,
    Deci



  • Beschreibe in WORTEN was dein Gebilde sein soll und welches Problem geloest werden muss!



  • Nun, ich dachte es erschließt sich aus der Beispielklasse da unten.
    Diese index_iterator-Klasse ist dazu gedacht, eine Iterator-Sequenz über irgendwas zu bauen, das nicht "direkt da" ist. Also irgendwelche Temp-Objekte oder ähnliches, die aber ansonsten semantisch Random-Accessible sind. Ein Beispiel wäre zum Beispiel (wer sollte es glauben) ein Reihen-Iterator, der intern über einem std::vector< std::vector< some > > läuft, wobei hier die innere Dimension einer Spalte entspricht. Es gibt also nicht direkt Reihen, aber man kann dennoch einen Wrapper für sowas basteln. So, und hier kommt der index_iterator ins Spiel, man entwickelt einen Reihen-Wrapper, implementiert eine dereference-Methode mit oder ohne Tag-Argument (besser mit, wegen Typsicherheit), macht noch einen typedef und ist fertig. Man muss sich also nicht mehr einen pseudo-iterator basteln.

    Viele Grüße,
    Deci


Anmelden zum Antworten