OSDN Git Service

マルチプロジェクト型にレポジトリを変更するために移動した
[toppersasp4lpc/asp.git] / asp / cfg / toppers / misc.hpp
1 /*
2  *  TOPPERS Software
3  *      Toyohashi Open Platform for Embedded Real-Time Systems
4  *
5  *  Copyright (C) 2005-2008 by TAKAGI Nobuhisa
6  * 
7  *  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8  *  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9  *  変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12  *      スコード中に含まれていること.
13  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16  *      の無保証規定を掲載すること.
17  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19  *      と.
20  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
22  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23  *        報告すること.
24  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26  *      また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27  *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28  *      免責すること.
29  * 
30  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32  *  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33  *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34  *  の責任を負わない.
35  * 
36  */
37
38 /*!
39  *  \file   toppers/misc.hpp
40  *  \brief  雑多なライブラリのための宣言定義
41  */
42 #ifndef TOPPERS_MISC_HPP_
43 #define TOPPERS_MISC_HPP_
44
45 #include <stdexcept>
46 #include <locale>
47 #include <iosfwd>
48 #include <string>
49 #include <algorithm>
50 #include <cctype>
51 #include <cwchar>
52 #include <cwctype>
53 #include <cstdlib>
54 #include "toppers/codeset.hpp"
55 #include <boost/scoped_array.hpp>
56
57 // workaround
58 #include <ctype.h>
59 #include <wctype.h>
60
61 #define TOPPERS_STRINGIFY( s )  TOPPERS_STRINGIFY_( s )
62 #define TOPPERS_STRINGIFY_( s ) # s
63
64 namespace toppers
65 {
66
67   /*!
68    *  \class  conversion_error misc.hpp "toppers/misc.hpp"
69    *  \brief  変換エラー例外クラス
70    */
71   class conversion_error : public std::runtime_error
72   {
73   public:
74     /*!
75      *  \brief  コンストラクタ
76      *  \param  what  例外原因文字列
77      */
78     explicit conversion_error( std::string const& what ) : std::runtime_error( what ) {}
79   };
80
81   /*!
82    *  \brief  シングルバイト文字から CharT 型(多くは wchar_t 型)文字への変換
83    *  \param  ch  シングルバイト文字
84    *  \return CharT 型文字を返す
85    */
86   template < typename CharT >
87     inline CharT widen( char ch )
88   {
89     return std::use_facet< std::ctype< CharT > >( std::locale() ).widen( ch );
90   }
91
92   template <>
93     inline char widen< char >( char ch )
94   {
95     return ch;
96   }
97
98   template <>
99     inline unsigned char widen< unsigned char >( char ch )
100   {
101     return static_cast< unsigned char >( ch );
102   }
103
104   template <>
105     inline wchar_t widen< wchar_t >( char ch )
106   {
107 #if defined( __MINGW32__ )
108     wchar_t wc = wchar_t( -1 );
109     if ( std::mbtowc( &wc, &ch, 1 ) < 0 )
110     {
111       return WEOF;
112     }
113     return wc;
114 #elif defined( __CYGWIN__ )
115     return static_cast< wchar_t >( static_cast< unsigned char >( ch ) );
116 #else
117     return static_cast< wchar_t >( std::btowc( static_cast< unsigned char >( ch ) ) );
118 #endif
119   }
120
121   /*!
122    *  \brief  シングルバイト文字列から CharT 型文字列への変換
123    *  \param  str   シングルバイト文字列
124    *  \return CharT 型文字列を返す
125    */
126   template < typename CharT >
127     std::basic_string< CharT > const widen( std::string const& str );
128
129   template <>
130     inline std::basic_string< char > const widen( std::string const& str )
131   {
132     return str;
133   }
134
135   template <>
136     inline std::basic_string< wchar_t > const widen( std::string const& str )
137   {
138     boost::scoped_array< wchar_t > t( new wchar_t[str.size()+1] );
139     if ( std::mbstowcs( t.get(), str.c_str(), str.size() ) == size_t( -1 ) )
140     {
141       static conversion_error x( "in function widen" );
142       throw x;
143     }
144     return t.get();
145   }
146
147 #undef  tolower
148
149   /*!
150    *  \brief  小文字への変換
151    *  \param  ch    変換対象の文字
152    *  \return ch が大文字であれば対応する小文字を、それ以外は ch を返す
153    */
154   inline char tolower( char ch )
155   {
156     return static_cast< char >( std::tolower( static_cast< unsigned char >( ch ) ) );
157   }
158
159   /*!
160    *  \brief  文字列を小文字に変換
161    *  \param  str   変換対象の文字
162    *  \return str に含まれる大文字を小文字に変換した文字列を返す
163    */
164   inline std::string const tolower( std::string str )
165   {
166     char ( *f )( char ) = &tolower;
167     std::transform( str.begin(), str.end(), str.begin(), f );
168     return str;
169   }
170
171   /*!
172    *  \brief  ワイド文字列を小文字に変換
173    *  \param  str   変換対象の文字
174    *  \return str に含まれる大文字を小文字に変換したワイド文字列を返す
175    */
176   template < class Traits, class Allocator >
177     std::basic_string< wchar_t, Traits, Allocator > const tolower( std::basic_string< wchar_t, Traits, Allocator > str )
178   {
179         wint_t ( *f )( wint_t ) = &towlower;
180     std::transform( str.begin(), str.end(), str.begin(), f );
181     return str;
182   }
183
184 #undef  toupper
185
186   /*!
187    *  \brief  大文字への変換
188    *  \param  ch    変換対象の文字
189    *  \return ch が小文字であれば対応する大文字を、それ以外は ch を返す
190    */
191   inline char toupper( char ch )
192   {
193     return static_cast< char >( std::toupper( static_cast< unsigned char >( ch ) ) );
194   }
195
196   /*!
197    *  \brief  文字列を大文字に変換
198    *  \param  str   変換対象の文字
199    *  \return str に含まれる小文字を大文字に変換した文字列を返す
200    */
201   inline std::string const toupper( std::string str )
202   {
203     char ( *f )( char ) = &toupper;
204     std::transform( str.begin(), str.end(), str.begin(), f );
205     return str;
206   }
207
208   /*!
209    *  \brief  ワイド文字列を大文字に変換
210    *  \param  str   変換対象の文字
211    *  \return str に含まれる小文字を大文字に変換したワイド文字列を返す
212    */
213   template < class Traits, class Allocator >
214     std::basic_string< wchar_t, Traits, Allocator > const toupper( std::basic_string< wchar_t, Traits, Allocator > str )
215   {
216         wint_t ( *f )( wint_t ) = &towupper;
217     std::transform( str.begin(), str.end(), str.begin(), f );
218     return str;
219   }
220
221 #undef  isspace
222
223   /*!
224    *  \brief  空白類の判別
225    *  
226    */
227   inline bool isspace( char ch )
228   {
229     return std::isspace( static_cast< unsigned char >( ch ) ) != 0;
230   }
231
232   /*!
233    *  \brief  指定文字で区切られたリスト出力
234    *  \param  first   出力する先頭要素位置
235    *  \param  last    出力する終端要素位置+1
236    *  \param  ostr    出力ストリーム
237    *  \param  pred    各要素を受け取り出力値を返す述語
238    *  \param  delim   区切文字
239    *
240    *  この関数は区間 [first, last) の各要素を pred に渡して得られる値を delim
241    *  で区切って ostr に出力します。\n
242    *  終端の要素の後には delim は出力されず、要素と要素の間にのみ delim が
243    *  出力されます。
244    */
245   template < class InputIterator, typename CharT, class Traits, class Pred >
246     void output_list( InputIterator first, InputIterator last, std::basic_ostream< CharT, Traits >& ostr, Pred pred, CharT const* delim = 0 )
247   {
248     if ( delim == 0 )
249     {
250       static CharT const null_delim[] = { 0 };
251       delim = null_delim;
252     }
253
254     for ( bool f = false; first != last; ++first )
255     {
256       if ( f )
257       {
258         ostr << delim;
259       }
260       ostr << pred( *first );
261       f = true;
262     }
263   }
264
265   template < typename CharT, class Traits, class Allocator >
266     std::basic_string< CharT, Traits, Allocator > trim( std::basic_string< CharT, Traits, Allocator > const& str, std::basic_string< CharT, Traits, Allocator > const& ws )
267   {
268     if ( str.empty() || ws.empty() )
269     {
270       return str;
271     }
272     typename std::basic_string< CharT, Traits, Allocator >::size_type first = str.find_first_not_of( ws, 0 );
273     for ( typename std::basic_string< CharT, Traits, Allocator >::size_type i = str.size() - 1; i >= 0; i-- )
274     {
275       if ( ws.find( str[ i ] ) == ws.npos )
276       {
277         return str.substr( first, i );
278       }
279     }
280     return str.substr( first );
281   }
282
283 }
284
285 #endif  // ! TOPPERS_MISC_HPP_