Delfin Rillustration> So what I ask is a library that works everywhere, just like you say.
I understand your point about POSIX file systems but since the library
is
compiled for Windows _or_ for POSIX systems I think it would be possible to compile for single char strings or double byte strings (UTF16). Windows systems solve this problem with the concept of TCHAR, a type that is defined as a char or wchar_t depending on a preprocessor definition. Then, boost::fylesystem::path could accept std::basic_string<TCHAR> instead of std::basic_string<char>. That would solve the problem and everybody would be happy ;)
I'm very much opposed to the idea of having templated classes for unicode support.
Let me explain. Suppose I write a library which does something with strings, paths, whatever in the interface. I have these choices:
1. Make the library interface templated. 2. Use narrow classes: e.g. string 3. Use wide classes: e.g. wstring 4. Have some class which works with ascii and unicode.
The first approach is bad for code size reasons. If the library does substantial work (e.g. HTTP library), it better be dynamic library, so
I can't see why this has to be so complicated. I either build my Windows
apps for DBCS or for Unicode, so use the narrow or wide Win32 file system
API accordingly. All that I want from boost::filesystem is a simple switch
that sets its mode at compile time. Doing that with a template parameter is
not going to cause any code bloat, and is neater than Microsoft's #ifdef
_UNICODE method.
I suppose some people may want to use narrow and wide APIs within a single
application, but they can't use boost::filesystem now anyway, so just keep
it simple.
- Keith MacDonald
"Vladimir Prus"
applications don't have include all the code. Of course, you might want static linking, but dynamic linking should be possible too.
The second approach is what's commonly done. As the result, unicode is not very supported in the standard C++.
The third approach looks reasonable. However, Mr. Random Library Writer might think: "I don't have a need for unicode now, so wstring is overhead". So he might discard this approach and use std::string.
Even if wstring is used, there are some issues. E.g. std::wstring does not have a constructor taking either char* or std:string, or if you ever get ascii string, you're in trouble.
The last solution is what looks most reasonable to me. It would be nice to have unicode string which can be created from ascii or unicode, converted back to either representation, and manipulated without regard to encoding.
For fs::path it would be that unicode will be just supported. The templated solution will bring us back to the above choice. And if you have a library which has boost::filesystem::basic_path<char> in the interface, it does not matter if your whole application uses basic_path<charT> -- you'd need conversions somewhere, so why don't have single fs::path which can do all conversions.
Just an illustraction:
class path { path(const std::string& s); // The 's' is in the local 8-bit encoding path(const std::wstring& s); // The 's' in in unicode
template<class charT> std::basic_string<charT> native_file_path();
// other operations, independed of charT };
- Volodya