OSDN Git Service

memberwise_swap を追加
[gintenlib/gintenlib.git] / gintenlib / list_format.hpp
1 #ifndef GINTENLIB_INCLUDED_LIST_FORMAT_HPP_
2 #define GINTENLIB_INCLUDED_LIST_FORMAT_HPP_
3
4 /*
5
6       <gintenlib/list_format.hpp>
7
8   list_format : コンテナのお手軽ストリーム出力
9
10   宣言:
11     template< typename Range >
12     unspecified list_format( const Range& src );
13
14     template< typename InIte >
15     unspecified list_format( const InIte& begin, const InIte& end );
16
17     template< typename Range, typename Pre, typename Delim, typename Post  >
18     unspecified list_format( const Range& src, const Pre& pre, const Delim& delim, const Post& post );
19
20     template< typename InIte, typename Pre, typename Delim, typename Post  >
21     unspecified list_format( const InIte& begin, const InIte& end, const Pre& pre, const Delim& delim, const Post& post );
22
23   機能:
24     任意のコンテナや配列( boost 使用版では任意の range )を、ストリームに流せるよう加工します。
25     デフォルトでは ( 1, 2, 3, 4 ) のように出力されますが、引数を指定することでスタイルは変更できます。
26
27   使用例:
28     // v は任意のコンテナ。( 1, 2, 3 ) のように表示されます
29     cout << gintenlib::list_format(v) << endl;
30     // 引数を指定すれば、[ 1 | 2 | 3 ] のような表示にもできます
31     cout << gintenlib::list_format( v, "[ ", " | ", " ]" ) << endl;
32     // また、イテレータを使って出力対象を指定することも出来ます。
33     // この場合は逆順の表示になります
34     cout << gintenlib::list_format( v.rbegin(), v.rend() ) << endl;
35
36   補足:
37     ・基本的に list_format 関数は、「戻り値をストリームに流す」という使い方のみを想定しています。
38     ・ただし、list_format 関数の戻り値に boost::lexical_cast を適応することは可能です。
39     ・また、戻り値を gintenlib::output_element オブジェクトに格納することも出来ます。
40     ・上記以外の目的で使った場合、list_format 関数の動作は不定となります。
41
42 */
43
44 // タイプ数削減のための using 宣言
45 #include "call_traits.hpp"
46
47 #include <boost/range.hpp>
48
49 namespace gintenlib
50 {
51   // 実際にストリームに流すクラス
52   template< typename InIte, typename Pre = const char*, 
53     typename Delim = const char*, typename Post = const char* >
54   struct list_format_impl_
55   {
56     typedef typename call_traits<InIte>::param_type inite_param_t;
57     typedef typename call_traits<Pre>::param_type pre_param_t;
58     typedef typename call_traits<Delim>::param_type delim_param_t;
59     typedef typename call_traits<Post>::param_type post_param_t;
60     
61     // constructor
62     list_format_impl_( inite_param_t begin, inite_param_t end,
63       pre_param_t pre, delim_param_t delim, post_param_t post )
64      : begin_(begin), end_(end), pre_(pre), delim_(delim), post_(post) {}
65
66     typename call_traits<InIte>::value_type begin_, end_;
67     typename call_traits<Pre>::value_type pre_;
68     typename call_traits<Delim>::value_type delim_;
69     typename call_traits<Post>::value_type post_;
70
71     // 出力の実装
72     // テンプレートにより std::ostream に限らず出力できます
73     template<typename Stream>
74     friend Stream& operator<< ( Stream& os, const list_format_impl_& src )
75     {
76       // 空のリストを表示させようとした場合、何も表示されない
77       if( src.begin_ == src.end_ ){ return os; }
78   
79       // 表示本体
80       os << src.pre_;
81   
82       InIte ite = src.begin_;
83       os << *ite;
84       for( ++ite; ite != src.end_; ++ite )
85       {
86         os << src.delim_ << *ite;
87       }
88   
89       os << src.post_;
90   
91       return os;
92   
93     }   // operator<< ( Stream&, const list_format_impl_& )
94     
95   };  // struct list_format_impl_
96
97
98   // 関数本体
99
100   // コンテナ版
101
102   // 一般形。任意の pre, delim, post に関して
103   // os << pre << 要素1 << delim << 要素2 << ... << delim << 要素n << end;
104   // というイメージで出力される。
105   template< typename Range, typename Pre, typename Delim, typename Post >
106   inline const list_format_impl_< typename boost::range_iterator<const Range>::type, Pre, Delim, Post >
107   list_format
108     ( const Range& src, const Pre& pre, const Delim& delim, const Post& post )
109   {
110     using namespace boost;
111     
112     return list_format_impl_< typename range_iterator<const Range>::type, Pre, Delim, Post >
113           ( begin(src), end(src), pre, delim, post );
114   }
115
116   // 省略版。( 要素1, 要素2, ... , 要素n ) という感じに出力
117   template< typename Range >
118     inline const list_format_impl_< typename boost::range_iterator<const Range>::type >
119   list_format( const Range& src )
120   {
121     using namespace boost;
122     
123     return list_format_impl_< typename range_iterator<const Range>::type >
124           ( begin(src), end(src), "( ", ", ", " )" );
125   }
126
127
128   // イテレータ版
129
130   // 一般形
131   template< typename InIte, typename Pre, typename Delim, typename Post >
132     inline const list_format_impl_<InIte, Pre, Delim, Post>
133   list_format
134     ( const InIte& begin, const InIte& end, const Pre& pre, const Delim& delim, const Post& post )
135   {
136     return list_format_impl_<InIte, Pre, Delim, Post>( begin, end, pre, delim, post );
137   }
138
139   // 省略版
140   template< typename InIte >
141     inline const list_format_impl_<InIte>
142   list_format( const InIte& begin, const InIte& end )
143   {
144     return list_format_impl_<InIte>( begin, end, "( ", ", ", " )" );
145   }
146
147 }   // namespace gintenlib
148
149
150 #endif  // #ifndef GINTENLIB_INCLUDED_LIST_FORMAT_HPP_