#ifndef ARABICA_UTILS_STRING_ADAPTOR_H #define ARABICA_UTILS_STRING_ADAPTOR_H #include #include #include #include #include namespace Arabica { template class default_string_adaptor; template class default_string_adaptor_base { public: typedef stringT string_type; typedef typename string_type::const_iterator const_iterator; typedef typename string_type::iterator mutable_iterator; typedef typename string_type::const_reverse_iterator const_reverse_iterator; typedef typename string_type::iterator iterator; typedef typename string_type::value_type value_type; typedef typename string_type::size_type size_type; virtual ~default_string_adaptor_base() {} static size_type npos() { return static_cast(-1); } //todo: is this safe? template static inline string_type construct(InputIterator from, InputIterator to) { return string_type(from, to); } static inline string_type construct(const_iterator from, const_iterator to) { return string_type(from, to); } static inline string_type construct(const std::basic_string& str) { return construct(str.begin(), str.end()); } // construct static string_type construct(const value_type* str) { return str ? string_type(str) : string_type(); } static const string_type& empty_string() { static string_type es; return es; } //todo: fix for utf8 static size_type length(const string_type& str) { return str.length(); } // all these functions should operate as std::string member functions do static bool empty(const string_type& str) { return str.empty(); } static size_type find(const string_type& str, value_type what) { return str.find(what); } static size_type find(const string_type& str, const string_type& what) { return str.find(what); } static size_type find(const string_type& str, value_type what, size_type from) { return str.find(what, from); } static size_type find(const string_type& str, const string_type& what, size_type from) { return str.find(what, from); } static string_type substr(const string_type& str, const size_type& offset) { return str.substr(offset); } static string_type substr(const string_type& str, const size_type& offset, const size_type& count) { return str.substr(offset, count); } static void append(string_type& str, const string_type& a) { str.append(a); } static void append(string_type& str, const value_type& a) { str += a; } static string_type concat(const string_type& str, const string_type& a) { return str + a; } static string_type concat(const string_type& str, const value_type& a) { return str + a; } static void insert(string_type& str, size_type offset, const string_type& a) { str.insert(offset, a); } static void replace(string_type& str, size_type offset, size_type count, const string_type& a) { str.replace(offset, count, a); } static const_iterator begin(const string_type& str) { return str.begin(); } static const_iterator end(const string_type& str) { return str.end(); } static iterator begin(string_type& str) { return str.begin(); } static iterator end(string_type& str) { return str.end(); } static const_reverse_iterator rbegin(const string_type& str) { return str.rbegin(); } // only used to constuct error strings - don't have to be highly efficient! static std::string asStdString(const string_type& str); #ifndef ARABICA_NO_WCHAR_T static string_type construct_from_utf16(const wchar_t* str); static string_type construct_from_utf16(const wchar_t* str, int length); static std::wstring asStdWString(const string_type& str); typedef Arabica::io::basic_iconvertstream, char, std::char_traits > widener_t; typedef Arabica::io::basic_oconvertstream, char, std::char_traits > narrower_t; static const std::locale& utf8ucs2_locale() { static const std::locale loc = std::locale(std::locale(), new Arabica::convert::utf8ucs2codecvt); return loc; } #endif //ARABICA_NO_WCHAR_T }; // class default_string_adaptor_base // specialize for std::string and std::wstring template<> class default_string_adaptor : public string_adaptor_tag, public default_string_adaptor_base { public: static char convert_from_utf8(char c) { return c; } static std::string construct_from_utf8(const char* str) { return str ? std::string(str) : std::string(); } // construct_from_utf8 static std::string construct_from_utf8(const char* str, int length) { return std::string(str, length); } // construct_from_utf8 static const std::string& asStdString(const std::string& str) { return str; } // asStdString #ifndef ARABICA_NO_WCHAR_T static std::string construct_from_utf16(const wchar_t* str) { narrower_t n; n.imbue(utf8ucs2_locale()); n.str(str ? str : L""); //n << str; return n.str(); } static std::string construct_from_utf16(const wchar_t* str, int length) { narrower_t n; n.imbue(utf8ucs2_locale()); n.str(std::wstring(str, length)); //for(int i = 0; i < length; ++i) // n << str[i]; return n.str(); } // construct_from_utf16 static std::wstring asStdWString(const std::string& str) { widener_t w; w.imbue(utf8ucs2_locale()); w.str(str); return w.str(); } // toStdWString #endif //ARABICA_NO_WCHAR_T }; // class default_string_adaptor #ifndef ARABICA_NO_WCHAR_T template<> class default_string_adaptor : public string_adaptor_tag, public default_string_adaptor_base { public: static wchar_t makeValueT(char c) { return static_cast(c); } // makeValueT template static inline string_type construct(InputIterator from, InputIterator to) { return string_type(from, to); } static inline string_type construct(const_iterator from, const_iterator to) { return string_type(from, to); } static inline string_type construct(const std::basic_string& str) { return construct(str.begin(), str.end()); } // construct static string_type construct(const value_type* str) { return str ? string_type(str) : string_type(); } static std::wstring construct(const std::string& str) { return construct_from_utf8(str.c_str()); } static std::wstring construct_from_utf8(const char* str) { widener_t w; w.imbue(utf8ucs2_locale()); w.str(str ? str : ""); return w.str(); } static std::wstring construct_from_utf8(const char* str, int length) { widener_t w; w.imbue(utf8ucs2_locale()); w.str(std::string(str, length)); return w.str(); } static std::wstring construct_from_utf16(const wchar_t* str) { return str ? std::wstring(str) : std::wstring(); } static std::wstring construct_from_utf16(const wchar_t* str, int length) { return std::wstring(str, length); } static std::string asStdString(const std::wstring& str) { narrower_t n; n.imbue(utf8ucs2_locale()); n.str(str); return n.str(); } // toStdString static const std::wstring& asStdWString(const std::wstring& str) { return str; } // toStdWString }; // class default_string_adaptor #endif // ARABICA_NO_WCHAR_T } // namespace Arabica #endif // end of file