OSDN Git Service

list_formatter::iterator<Stream> に output proxy を導入
authorSubaruG <subaru_g@users.sourceforge.jp>
Fri, 22 Jan 2010 10:11:35 +0000 (19:11 +0900)
committerSubaruG <subaru_g@users.sourceforge.jp>
Fri, 22 Jan 2010 10:11:35 +0000 (19:11 +0900)
gintenlib/list_formatter.hpp

index d99fbb5..b09dbbb 100644 (file)
@@ -156,6 +156,7 @@ namespace gintenlib
     struct iterator
       : std::iterator< std::output_iterator_tag, void, void, void, void >
     {
+      // イテレータを制作する
       iterator( const basic_list_formatter& formatter, Stream& os )
         : formatter_(&formatter), os_(&os)
       {
@@ -165,10 +166,12 @@ namespace gintenlib
         // この時点でカウントは負
         --formatter_->iterator_count_;
       }
-
+      
+      // コピーコンストラクタ
       iterator( const iterator& src )
         : formatter_(src.formatter_), os_(src.os_)
       {
+        // イテレータカウントを変更する
         if( formatter_->iterator_count_ > 0 )
         {
           ++formatter_->iterator_count_;
@@ -179,7 +182,7 @@ namespace gintenlib
         }
         else
         {
-          assert( !"basic_list_formatter::iterator::iterator(const iterator&) : sould not get here." );
+          assert( !"sould not get here." );
         }
       }
 
@@ -196,18 +199,19 @@ namespace gintenlib
         }
         else if( formatter_->iterator_count_ < 0 )
         {
+          // count が負 <==> 閉じる必要はない
           ++formatter_->iterator_count_;
         }
         else
         {
-          assert( !"basic_list_formatter::iterator::~iterator() : sould not get here." );
+          assert( !"sould not get here." );
         }
       }
 
+      // 代入演算
       iterator& operator=( const iterator& src )
       {
-        iterator temp(src);
-        swap(temp);
+        iterator(src).swap(*this);
         return *this;
       }
       void swap( iterator& other )
@@ -223,22 +227,23 @@ namespace gintenlib
 
       // 実際の出力
       template< typename T >
-      iterator& operator=( const T& val )
+      void output( const T& val ) const
       {
         if( formatter_->iterator_count_ > 0 )
         {
+          // 既に何かが出力された
           *os_ << formatter_->delim << val;
         }
         else if( formatter_->iterator_count_ < 0 )
         {
+          // まだなにも出力されてない
           *os_ << formatter_->pre << val;
           formatter_->iterator_count_ = -formatter_->iterator_count_;
         }
         else
         {
-          assert( !"basic_list_formatter::iterator::operator=(const T&) : sould not get here." );
+          assert( !"sould not get here." );
         }
-        return *this;
       }
 
       // 「出力を閉じる」
@@ -255,8 +260,24 @@ namespace gintenlib
         return *this;
       }
 
-      // 参照外しも、前置/後置インクリメントも、何もしない
-      iterator& operator*(){ return *this; }
+      // 参照を外した場合、出力用プロキシを作って返す
+      struct output_proxy
+      {
+        const iterator* p;
+        explicit output_proxy( const iterator* p_ )
+          : p( p_ ){}
+        
+        // 出力操作
+        template<typename T>
+        output_proxy& operator=( const T& val )
+        {
+          p->output( val );
+          return *this;
+        }
+      };
+      output_proxy operator*() const { return output_proxy(this); }
+      
+      // 前置/後置インクリメントは何もしない
       iterator& operator++(){ return *this; }
       iterator& operator++(int){ return *this; }
 
@@ -275,6 +296,11 @@ namespace gintenlib
     {
       return iterator<Stream>( *this, os );
     }
+    template< typename Stream >
+    friend iterator<Stream> make_iterator( const basic_list_formatter& fmt, Stream& os )
+    {
+      return iterator<Stream>( fmt, os );
+    }
 
   private:
     mutable int iterator_count_;