lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
00001 /*****************************************************/ 00002 /* lean Strings (c) Tobias Zirr 2011 */ 00003 /*****************************************************/ 00004 00005 #ifndef LEAN_STRINGS_CONVERSIONS 00006 #define LEAN_STRINGS_CONVERSIONS 00007 00008 #include "../lean.h" 00009 #include "types.h" 00010 #include <string> 00011 #include <locale> 00012 #include "../utf8.h" 00013 00014 namespace lean 00015 { 00016 namespace strings 00017 { 00018 00020 static inline const std::locale& system_locale() 00021 { 00022 static std::locale system(""); 00023 return system; 00024 } 00025 00026 00028 00030 template <class String, class Range> 00031 inline String utf8_to_utf16(const Range &wide) 00032 { 00033 String result; 00034 result.resize(wide.size()); 00035 result.erase( 00036 utf8::unchecked::utf8to16(wide.begin(), wide.end(), result.begin()), 00037 result.end()); 00038 return result; 00039 } 00041 template <class String> 00042 LEAN_INLINE String utf_to_utf16(const utf8_ntri &wide) 00043 { 00044 return utf8_to_utf16<String>(wide); 00045 } 00047 LEAN_INLINE utf16_string utf_to_utf16(const utf8_ntri &wide) 00048 { 00049 return utf8_to_utf16<utf16_string>(wide); 00050 } 00051 00053 template <class String, class Range> 00054 inline String utf16_to_utf8(const Range &wide) 00055 { 00056 String result; 00057 result.resize(2 * wide.size()); 00058 result.erase( 00059 utf8::unchecked::utf16to8(wide.begin(), wide.end(), result.begin()), 00060 result.end()); 00061 return result; 00062 } 00064 template <class String> 00065 LEAN_INLINE String utf_to_utf8(const utf16_ntri &wide) 00066 { 00067 return utf16_to_utf8<String>(wide); 00068 } 00070 LEAN_INLINE utf8_string utf_to_utf8(const utf16_ntri &wide) 00071 { 00072 return utf16_to_utf8<utf8_string>(wide); 00073 } 00074 00075 00077 template <class String, class Range> 00078 inline String utf8_to_utf32(const Range &wide) 00079 { 00080 String result; 00081 result.resize(wide.size()); 00082 result.erase( 00083 utf8::unchecked::utf8to32(wide.begin(), wide.end(), result.begin()), 00084 result.end()); 00085 return result; 00086 } 00088 template <class String> 00089 LEAN_INLINE String utf_to_utf32(const utf8_ntri &wide) 00090 { 00091 return utf8_to_utf32<String>(wide); 00092 } 00094 LEAN_INLINE utf32_string utf_to_utf32(const utf8_ntri &wide) 00095 { 00096 return utf8_to_utf32<utf32_string>(wide); 00097 } 00098 00100 template <class String, class Range> 00101 inline String utf32_to_utf8(const Range &wide) 00102 { 00103 String result; 00104 result.resize(4 * wide.size()); 00105 result.erase( 00106 utf8::unchecked::utf32to8(wide.begin(), wide.end(), result.begin()), 00107 result.end()); 00108 return result; 00109 } 00111 template <class String> 00112 LEAN_INLINE String utf_to_utf8(const utf32_ntri &wide) 00113 { 00114 return utf32_to_utf8<String>(wide); 00115 } 00117 LEAN_INLINE utf8_string utf_to_utf8(const utf32_ntri &wide) 00118 { 00119 return utf32_to_utf8<utf8_string>(wide); 00120 } 00121 00122 00124 template <class String> 00125 LEAN_INLINE String utf_to_utf32(const utf16_ntri &wide) 00126 { 00127 return utf8_to_utf32<String>(utf16_to_utf8<utf8_string>(wide)); 00128 } 00130 LEAN_INLINE utf32_string utf_to_utf32(const utf16_ntri &wide) 00131 { 00132 return utf8_to_utf32<utf32_string>(utf16_to_utf8<utf8_string>(wide)); 00133 } 00134 00136 template <class String> 00137 LEAN_INLINE String utf_to_utf16(const utf32_ntri &wide) 00138 { 00139 return utf8_to_utf16<String>(utf32_to_utf8<utf8_string>(wide)); 00140 } 00142 LEAN_INLINE utf16_string utf_to_utf16(const utf32_ntri &wide) 00143 { 00144 return utf8_to_utf16<utf16_string>(utf32_to_utf8<utf8_string>(wide)); 00145 } 00146 00147 00149 template <class String> 00150 LEAN_INLINE String utf_to_utf8(const utf8_ntri &wide) 00151 { 00152 return String(wide.begin(), wide.end()); 00153 } 00155 LEAN_INLINE utf8_ntri utf_to_utf8(const utf8_ntri &wide) 00156 { 00157 return wide; 00158 } 00159 00161 template <class String> 00162 LEAN_INLINE String utf_to_utf16(const utf16_ntri &wide) 00163 { 00164 return String(wide.begin(), wide.end()); 00165 } 00167 LEAN_INLINE utf16_ntri utf_to_utf16(const utf16_ntri &wide) 00168 { 00169 return wide; 00170 } 00171 00173 template <class String> 00174 LEAN_INLINE String utf_to_utf32(const utf32_ntri &wide) 00175 { 00176 return String(wide.begin(), wide.end()); 00177 } 00179 LEAN_INLINE utf32_ntri utf_to_utf32(const utf32_ntri &wide) 00180 { 00181 return wide; 00182 } 00183 00184 00185 namespace impl 00186 { 00187 00188 template <class String, class DestChar> 00189 struct utf_to_utf_helper; 00190 00191 template <class String> 00192 struct utf_to_utf_helper<String, utf8_t> 00193 { 00194 template <class Range> 00195 LEAN_INLINE String operator ()(const Range &str) const { return utf_to_utf8<String>(str); } 00196 }; 00197 template <class String> 00198 struct utf_to_utf_helper<String, utf16_t> 00199 { 00200 template <class Range> 00201 LEAN_INLINE String operator ()(const Range &str) const { return utf_to_utf16<String>(str); } 00202 }; 00203 template <class String> 00204 struct utf_to_utf_helper<String, utf32_t> 00205 { 00206 template <class Range> 00207 LEAN_INLINE String operator ()(const Range &str) const { return utf_to_utf32<String>(str); } 00208 }; 00209 00210 } // namespace 00211 00213 template <class String, class Range> 00214 LEAN_INLINE String utf_to_utf(const Range &str) 00215 { 00216 return impl::utf_to_utf_helper<String, typename String::value_type>()(str); 00217 } 00218 00219 00221 00223 template <class String> // , class Range 00224 inline String char_to_wchar(const char_ntri &narrow, const std::locale &locale = std::locale()) 00225 { 00226 String result; 00227 result.resize(narrow.size()); 00228 std::use_facet< std::ctype<wchar_t> >(locale).widen(narrow.begin(), narrow.end(), &result[0]); 00229 return result; 00230 } 00232 template <class String> 00233 LEAN_INLINE String to_wchar(const char_ntri &narrow, const std::locale &locale = std::locale()) 00234 { 00235 return char_to_wchar<String>(narrow, locale); 00236 } 00238 LEAN_INLINE std::wstring to_wchar(const char_ntri &narrow, const std::locale &locale = std::locale()) 00239 { 00240 return char_to_wchar<std::wstring>(narrow, locale); 00241 } 00242 00244 template <class String> // , class Range 00245 inline String wchar_to_char(const wchar_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00246 { 00247 String result; 00248 result.resize(wide.size()); 00249 std::use_facet< std::ctype<wchar_t> >(locale).narrow(wide.begin(), wide.end(), invalid, &result[0]); 00250 return result; 00251 } 00253 template <class String> 00254 LEAN_INLINE String to_char(const wchar_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00255 { 00256 return wchar_to_char<String>(wide, locale, invalid); 00257 } 00259 LEAN_INLINE std::string to_char(const wchar_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00260 { 00261 return wchar_to_char<std::string>(wide, locale, invalid); 00262 } 00263 00264 00266 template <class String> // , class Range 00267 inline String char_to_utf16(const char_ntri &narrow, const std::locale &locale = std::locale()) 00268 { 00269 String result; 00270 result.resize(narrow.size()); 00271 std::use_facet< std::ctype<utf16_t> >(locale).widen(narrow.begin(), narrow.end(), &result[0]); 00272 return result; 00273 } 00275 template <class String> 00276 LEAN_INLINE String to_utf16(const char_ntri &narrow, const std::locale &locale = std::locale()) 00277 { 00278 return char_to_utf16<String>(narrow, locale); 00279 } 00281 LEAN_INLINE utf16_string to_utf16(const char_ntri &narrow, const std::locale &locale = std::locale()) 00282 { 00283 return char_to_utf16<utf16_string>(narrow, locale); 00284 } 00285 00287 template <class String> // , class Range 00288 inline String utf16_to_char(const utf16_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00289 { 00290 String result; 00291 result.resize(wide.size()); 00292 std::use_facet< std::ctype<utf16_t> >(locale).narrow(wide.begin(), wide.end(), invalid, &result[0]); 00293 return result; 00294 } 00296 template <class String> 00297 LEAN_INLINE String utf_to_char(const utf16_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00298 { 00299 return utf16_to_char<String>(wide, locale, invalid); 00300 } 00302 LEAN_INLINE std::string utf_to_char(const utf16_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00303 { 00304 return utf16_to_char<std::string>(wide, locale, invalid); 00305 } 00306 00307 00309 template <class String> // , class Range 00310 inline String char_to_utf32(const char_ntri &narrow, const std::locale &locale = std::locale()) 00311 { 00312 String result; 00313 result.resize(narrow.size()); 00314 std::use_facet< std::ctype<utf32_t> >(locale).widen(narrow.begin(), narrow.end(), &result[0]); 00315 return result; 00316 } 00318 template <class String> 00319 LEAN_INLINE utf32_string to_utf32(const char_ntri &narrow, const std::locale &locale = std::locale()) 00320 { 00321 return char_to_utf32<String>(narrow, locale); 00322 } 00324 LEAN_INLINE utf32_string to_utf32(const char_ntri &narrow, const std::locale &locale = std::locale()) 00325 { 00326 return char_to_utf32<utf32_string>(narrow, locale); 00327 } 00328 00330 template <class String> // , class Range 00331 inline String utf32_to_char(const utf32_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00332 { 00333 String result; 00334 result.resize(wide.size()); 00335 std::use_facet< std::ctype<utf32_t> >(locale).narrow(wide.begin(), wide.end(), invalid, &result[0]); 00336 return result; 00337 } 00339 template <class String> 00340 LEAN_INLINE String utf_to_char(const utf32_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00341 { 00342 return utf32_to_char<String>(wide, locale, invalid); 00343 } 00345 LEAN_INLINE std::string utf_to_char(const utf32_ntri &wide, const std::locale &locale = std::locale(), char invalid = '?') 00346 { 00347 return utf32_to_char<std::string>(wide, locale, invalid); 00348 } 00349 00350 00352 00354 template <class String> 00355 LEAN_INLINE String to_utf8(const char_ntri &narrow, const std::locale &locale = std::locale()) 00356 { 00357 return utf16_to_utf8<String>(char_to_utf16<utf16_string>(narrow, locale)); 00358 } 00360 LEAN_INLINE utf8_string to_utf8(const char_ntri &narrow, const std::locale &locale = std::locale()) 00361 { 00362 return utf16_to_utf8<utf8_string>(char_to_utf16<utf16_string>(narrow, locale)); 00363 } 00364 00366 template <class String> 00367 LEAN_INLINE String utf_to_char(const utf8_ntri &utf8, const std::locale &locale = std::locale(), char invalid = '?') 00368 { 00369 return utf16_to_char<String>(utf8_to_utf16<utf16_string>(utf8), locale, invalid); 00370 } 00372 LEAN_INLINE std::string utf_to_char(const utf8_ntri &utf8, const std::locale &locale = std::locale(), char invalid = '?') 00373 { 00374 return utf16_to_char<std::string>(utf8_to_utf16<utf16_string>(utf8), locale, invalid); 00375 } 00376 00377 } // namespace 00378 00379 using strings::to_wchar; 00380 using strings::to_char; 00381 00382 using strings::to_utf8; 00383 using strings::to_utf16; 00384 using strings::to_utf32; 00385 00386 using strings::utf_to_utf8; 00387 using strings::utf_to_utf16; 00388 using strings::utf_to_utf32; 00389 00390 using strings::utf_to_char; 00391 00392 } // namespace 00393 00394 #endif