lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
conversions.h
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