OSDN Git Service

first commit.
[gintenlib/gintenlib.git] / gintenlib / list_formatter.hpp
1 #ifndef GINTENLIB_INCLUDED_LIST_FORMATTER_HPP_
2 #define GINTENLIB_INCLUDED_LIST_FORMATTER_HPP_
3
4 /*
5
6       <gintenlib/list_formatter.hpp>
7
8   list_formatter ¡§ ¥Õ¥¡¥ó¥¯¥¿ÈÇ list_format¡Êconst char* ÈÇ¡Ë
9
10   Àë¸À¡§
11   template< typename Elem >
12   struct basic_list_formatter
13   {
14     explicit basic_list_formatter
15       ( 
16         gintenlib_param_t(Elem) pre_ = "( ",
17         gintenlib_param_t(Elem) delim_ = ", ",
18         gintenlib_param_t(Elem) post_ = " )" 
19       );
20
21     typedef gintenlib_value_t(Elem) element_type;
22     // ¥á¥ó¥Ð¡ÖÊÑ¿ô¡×¡¢¼«Í³¤Ë³°Éô¤«¤é¥¢¥¯¥»¥¹¤Ç¤­¤ë
23     element_type pre, delim, post;
24
25     // ½ÐÎÏÈϰϤò»ØÄꤷ¡¢¥¹¥È¥ê¡¼¥à¤Ëή¤»¤ë¤è¤¦¤Ë¤¹¤ë
26     template< typename InIte >
27       list_format_impl_< InIte, Elem, Elem, Elem >
28     operator()( const InIte& begin, const InIte& end ) const;
29
30     // ½ÐÎÏÈϰϤò range ¤Ç»ØÄê
31     template< typename Range >
32       list_format_impl_< gintenlib_const_ite_of(Range), Elem, Elem, Elem >
33     operator()( const Range& src ) const;
34
35     // ostream_iterator ¤Î¤è¤¦¤Ë¿¶Éñ¤¦¥¤¥Æ¥ì¡¼¥¿¤òÀ½ºî¡£
36     // ¥¤¥Æ¥ì¡¼¥¿¤¬´û¤ËÀ½ºî¤µ¤ì¤Æ¤¤¤¿¾ì¹ç¤Ï¡¢¤¤¤Ã¤¿¤ó¥ê¥¹¥È¤¬ÊĤ¸¤é¤ì¤ë
37     template< typename Stream >
38     iterator<Stream> make_iterator( Stream& os ) const;
39
40     template< typename Stream >
41     struct iterator
42       : std::iterator< std::output_iterator_tag, void, void, void, void >
43     {
44       iterator( const basic_list_formatter& formatter, Stream& os );
45       iterator( const iterator& src );
46
47       ~iterator();
48
49       iterator& operator=( const iterator& src );
50       iterator& swap( iterator& other );
51
52       template< typename T >
53       iterator& operator=( const T& val );
54
55       iterator& close();
56
57       iterator& operator*(){ return *this; }
58       iterator& operator++(){ return *this; }
59       iterator& operator++(int){ return *this; }
60
61     };  // struct iterator
62
63   };  // struct basic_list_formatter
64
65   typedef basic_list_formatter<const char*> list_formatter;
66
67   µ¡Ç½¡§
68     list_format(v) ¤ä list_format( begin, end ) ¤È»È¤¦Éôʬ¤Ç¡¢Âå¤ï¤ê¤Ë»ÈÍѤǤ­¤ë¥Õ¥¡¥ó¥¯¥¿¡£
69
70     list_formatter formatter( pre, delim, post );
71     cout << formatter(v) << endl;
72
73     ¤³¤Î¥³¡¼¥É¤Î¼Â¹Ô·ë²Ì¤Ï cout << list_format( v, pre, delim, post ) << endl; ¤ÈÅù²Á¡£
74     Í½¤á pre, delim, post ¤ÎÀßÄê¤ò¤·¤Æ¤ª¤¤¤Æ»È¤¤¤Þ¤ï¤·¤¿¤¤¾ì¹ç¤Ë»ÈÍѤǤ­¤ë¡£
75
76     ¤â¤¦°ì¤Ä¤Îµ¡Ç½¤È¤·¤Æ¡¢make_iterator() ¥á¥ó¥Ð´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ç½ÐÎÏ¥¤¥Æ¥ì¡¼¥¿¤ò¹½ÃۤǤ­¤ëµ¡Ç½¤â¤¢¤ê¡¢
77
78     cout << formatter(v);
79     cout << formatter( v.begin(), v.end() );
80     copy( v.begin(), v.end(), formatter.make_iterator(cout) );
81
82     ¤³¤Î»°¤Ä¤Îʸ¤Î¼Â¹Ô·ë²Ì¤Ï¡¢¤É¤ì¤âÅù¤·¤¤¡£
83
84   »ÈÍÑÎ㡧
85     // ¹½ÃÛ¤·¤Æ
86     gintenlib::list_formatter formatter( "[ ", " | ", " ]\n" );
87
88     // Ç¤°Õ¤Î¥³¥ó¥Æ¥Ê v ¤ËÂФ·¡¢Å¬ÍѤ¹¤ë
89     cout << formatter(v);
90     // µÕ½ç¤Ëɽ¼¨¤ò¤·¤Æ¤ß¤ë
91     cout << formatter( v.rbegin(), v.rend() );
92     // µÕ½ç¤Ëɽ¼¨¤¹¤ë¤Ë¤Ï¡¢¤³¤¦½ñ¤¤¤Æ¤â¤è¤¤
93     reverse_copy( v.begin(), v.end(), formatter.ite(cout) );
94
95   Êä­¡§
96     ¡¦pre, delim, post ¤Ï const char* ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
97       Ç¤°ÕÍ×ÁǤò³ÊǼ¤·¤¿¤¤¾ì¹ç¤Ï¡¢list_formatter_ex ¤òÍѤ¤¤ë¡£
98     ¡¦operator() ¤ÎŬÍÑ·ë²Ì¤Î¼è¤ê°·¤¤¤Ï¡¢ list_format ´Ø¿ô¤ÎÌá¤êÃͤÈƱ¤¸¤è¤¦¤Ë°·¤¦¡£
99     ¡¦½ÐÎÏ¥¤¥Æ¥ì¡¼¥¿¤ò»ÈÍѤ¹¤ë¾ì¹ç¤ÎÃí°Õ»ö¹à¡§
100       ¡¦pre Í×ÁǤϡֺǽé¤ÎÍ×ÁǤ¬¼ÂºÝ¤Ë½ÐÎϤµ¤ì¤ëľÁ°¡×¤Ë½ÐÎϤµ¤ì¤ë¡£
101       ¡¦delim Í×ÁǤϡÖÆó²óÌܰʹߤÎÍ×ÁǤ¬½ÐÎϤµ¤ì¤ëľÁ°¡×¤Ë½ÐÎϤµ¤ì¤ë¡£
102       ¡¦post Í×ÁǤϡ֥³¥Ô¡¼¤ò´Þ¤á¡¢Á´¤Æ¤Î¥¤¥Æ¥ì¡¼¥¿¤¬ÇË´þ¤µ¤ì¤¿¤È¤­¡×¤Ë½ÐÎϤµ¤ì¤ë¡£
103         ¤¿¤À¤·¡¢Ì¤¤À pre ¤¬½ÐÎϤµ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢post ¤â½ÐÎϤµ¤ì¤Ê¤¤¡£
104       ¡¦¤â¤·Á´¤Æ¤Î¥¤¥Æ¥ì¡¼¥¿¤¬ÇË´þ¤µ¤ì¤ëÁ°¤Ë¿·¤¿¤Ê¥¤¥Æ¥ì¡¼¥¿¤òÀ½ºî¤·¤¿¾ì¹ç¡¢
105         ¤½¤Î»þÅÀ¤Ç post Í×ÁǤ¬½ÐÎϤµ¤ì¡¢¡Ö²¿¤â½ÐÎϤµ¤ì¤Æ¤¤¤Ê¤¤¡×¾õÂ֤ˤʤ롣
106
107 */
108
109 #include <iterator>
110 #include <cassert>
111 #include <algorithm>  // for swap()
112
113 #include <boost/range.hpp>
114 #include <boost/call_traits.hpp>
115
116 #include "list_format.hpp"
117
118 namespace gintenlib
119 {
120   template< typename Elem >
121   class basic_list_formatter
122   {
123     typedef typename boost::call_traits<Elem>::param_type param_type;
124
125    public:
126     typedef typename boost::call_traits<Elem>::value_type element_type;
127
128     basic_list_formatter()
129       : pre("( "), delim(", "), post(" )"), iterator_count_(0) {}
130     
131     explicit basic_list_formatter
132       ( param_type pre_, param_type delim_, param_type post_ )
133        : pre(pre_), delim(delim_), post(post_), iterator_count_(0) {}
134
135     // ¥á¥ó¥ÐÊÑ¿ô¤Ê¤Î¤Ç¡¢¼«Í³¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¡£
136     element_type pre, delim, post;
137
138     // ½ÐÎÏÈϰϤò¥¤¥Æ¥ì¡¼¥¿¤Ç»ØÄꤷ¤Æ¡¢¥¹¥È¥ê¡¼¥à¤Ëή¤»¤ë¤è¤¦¤Ë
139     template< typename InIte >
140       list_format_impl_< InIte, Elem, Elem, Elem >
141     operator()( const InIte& begin, const InIte& end ) const
142     {
143       return list_format_impl_< InIte, Elem, Elem, Elem >( begin, end, pre, delim, post );
144     }
145     // ½ÐÎÏÈϰϤò range ¤Ç»ØÄꤷ¤Æ¡¢¥¹¥È¥ê¡¼¥à¤Ëή¤»¤ë¤è¤¦¤Ë
146     template< typename Range >
147       list_format_impl_< typename boost::range_iterator<const Range>::type, Elem, Elem, Elem >
148     operator()( const Range& src ) const
149     {
150       return list_format_impl_< typename boost::range_iterator<const Range>::type, Elem, Elem, Elem >
151           ( boost::begin(src), boost::end(src), pre, delim, post );
152     }
153
154     // ¥¤¥Æ¥ì¡¼¥¿
155     template< typename Stream >
156     struct iterator
157       : std::iterator< std::output_iterator_tag, void, void, void, void >
158     {
159       iterator( const basic_list_formatter& formatter, Stream& os )
160         : formatter_(&formatter), os_(&os)
161       {
162         // ½ÐÎϤ¬¡ÖÊĤ¸¤Æ¡×¤Ê¤¤¤Ê¤é¡¢ÊĤ¸¤ë
163         close();
164
165         // ¤³¤Î»þÅÀ¤Ç¥«¥¦¥ó¥È¤ÏÉé
166         --formatter_->iterator_count_;
167       }
168
169       iterator( const iterator& src )
170         : formatter_(src.formatter_), os_(src.os_)
171       {
172         if( formatter_->iterator_count_ > 0 )
173         {
174           ++formatter_->iterator_count_;
175         }
176         else if( formatter_->iterator_count_ < 0 )
177         {
178           --formatter_->iterator_count_;
179         }
180         else
181         {
182           assert( !"basic_list_formatter::iterator::iterator(const iterator&) : sould not get here." );
183         }
184       }
185
186       ~iterator()
187       {
188         if( formatter_->iterator_count_ > 0 )
189         {
190           // count ¤¬Àµ <==> ´û¤Ë²¿¤«½ÐÎϤµ¤ì¤Æ¤¤¤ë
191           if( --formatter_->iterator_count_ == 0 )
192           {
193             // count ¤¬ 0 ¤Ë¤Ê¤Ã¤¿ <==> ¤â¤¦Â¾¤Î¥¤¥Æ¥ì¡¼¥¿¤Ï̵¤¤
194             *os_ << formatter_->post;
195           }
196         }
197         else if( formatter_->iterator_count_ < 0 )
198         {
199           ++formatter_->iterator_count_;
200         }
201         else
202         {
203           assert( !"basic_list_formatter::iterator::~iterator() : sould not get here." );
204         }
205       }
206
207       iterator& operator=( const iterator& src )
208       {
209         iterator temp(src);
210         swap(temp);
211         return *this;
212       }
213       void swap( iterator& other )
214       {
215         using std::swap;
216         swap( formatter_, other.formatter_ );
217         swap( os_, other.os_ );
218       }
219       friend void swap( iterator& one, iterator& other )
220       {
221         one.swap(other);
222       }
223
224       // ¼ÂºÝ¤Î½ÐÎÏ
225       template< typename T >
226       iterator& operator=( const T& val )
227       {
228         if( formatter_->iterator_count_ > 0 )
229         {
230           *os_ << formatter_->delim << val;
231         }
232         else if( formatter_->iterator_count_ < 0 )
233         {
234           *os_ << formatter_->pre << val;
235           formatter_->iterator_count_ = -formatter_->iterator_count_;
236         }
237         else
238         {
239           assert( !"basic_list_formatter::iterator::operator=(const T&) : sould not get here." );
240         }
241         return *this;
242       }
243
244       // ¡Ö½ÐÎϤòÊĤ¸¤ë¡×
245       iterator& close()
246       {
247         // ¥«¥¦¥ó¥È¤¬Àµ <==> ½ÐÎϤ¬¡ÖÊĤ¸¤Æ¡×¤Ê¤¤
248         if( formatter_->iterator_count_ > 0 )
249         {
250           // ÊĤ¸¤ë
251           *os_ << formatter_->post;
252           // ¡Ö̤½ÐÎϡפؤÈÀßÄê
253           formatter_->iterator_count_ = -formatter_->iterator_count_;
254         }
255         return *this;
256       }
257
258       // »²¾È³°¤·¤â¡¢Á°ÃÖ¡¿¸åÃÖ¥¤¥ó¥¯¥ê¥á¥ó¥È¤â¡¢²¿¤â¤·¤Ê¤¤
259       iterator& operator*(){ return *this; }
260       iterator& operator++(){ return *this; }
261       iterator& operator++(int){ return *this; }
262
263     private:
264       const basic_list_formatter* formatter_;
265       Stream* os_;
266
267     };  // struct iterator
268
269     template< typename Stream >
270     friend struct iterator;
271
272     // ½ÐÎÏ¥¤¥Æ¥ì¡¼¥¿¤òºî¤ë
273     template< typename Stream >
274     iterator<Stream> make_iterator( Stream& os ) const
275     {
276       return iterator<Stream>( *this, os );
277     }
278
279   private:
280     mutable int iterator_count_;
281
282   };  // struct basic_list_formatter
283
284   typedef basic_list_formatter<const char*> list_formatter;
285
286 }   // namespace gintenlib
287
288
289 #endif  // #ifndef GINTENLIB_INCLUDED_LIST_FORMATTER_HPP_