[filesystem] Make basic_path more generic?

Hi, in several places I need to have code which works both with char and wchar_t. Those are template functions. I also work with paths there so I wanted to actually write something like template <typename CharType> void foo(const std::basic_string<CharType>& s) { typedef fs::basic_path<std::basic_string<CharType> > path_type; ... } but it turned out that I can't do it because 1) basic_path has the second Traits template parameter mandatory and 2) this Traits parameter has actually different type for path and wpath: struct path_traits; typedef basic_path< std::string, path_traits > path; // ... struct BOOST_FILESYSTEM_DECL wpath_traits; typedef basic_path< std::wstring, wpath_traits > wpath; Of course, I can easily workaround it with my own traits, but I wonder could it be in the first place like: template<class String> class basic_path_traits; template<class String, class Traits = basic_path_traits<String> > class basic_path; with basic_path_traits being specialized for std::string and std::wstring and fs::path and fs::wpath being just typedef basic_path< std::string > path; typedef basic_path< std::wstring > wpath; ? Thanks. -- Alexei Alexandrov

Alexei Alexandrov wrote:
Hi,
in several places I need to have code which works both with char and wchar_t. Those are template functions. I also work with paths there so I wanted to actually write something like
template <typename CharType> void foo(const std::basic_string<CharType>& s) { typedef fs::basic_path<std::basic_string<CharType> > path_type; ... }
but it turned out that I can't do it because 1) basic_path has the second Traits template parameter mandatory and 2) this Traits parameter has actually different type for path and wpath:
struct path_traits; typedef basic_path< std::string, path_traits > path; // ... struct BOOST_FILESYSTEM_DECL wpath_traits; typedef basic_path< std::wstring, wpath_traits > wpath;
Of course, I can easily workaround it with my own traits, but I wonder could it be in the first place like:
template<class String> class basic_path_traits;
template<class String, class Traits = basic_path_traits<String> > class basic_path;
with basic_path_traits being specialized for std::string and std::wstring and fs::path and fs::wpath being just
typedef basic_path< std::string > path; typedef basic_path< std::wstring > wpath;
I've created ticket #1936 with the above. There are two perspectives to consider at this issue. * As a very specific tweak to the current interface. * As a further indication that there should be a single path type that can handle both wide and narrow types. Peter Dimov suggested that once, and I keep turning over in my mind how it could be accomplished. With C++0x supplying two new character types, the need becomes more pressing. I still don't want to invent a solution that applies only to filesystem paths; there is a general need for strings that can cope with multiple character types and encodings. Thanks, --Beman

Beman Dawes wrote:
I've created ticket #1936 with the above.
There are two perspectives to consider at this issue.
* As a very specific tweak to the current interface.
* As a further indication that there should be a single path type that can handle both wide and narrow types. Peter Dimov suggested that once, and I keep turning over in my mind how it could be accomplished. With C++0x supplying two new character types, the need becomes more pressing. I still don't want to invent a solution that applies only to filesystem paths; there is a general need for strings that can cope with multiple character types and encodings.
Thanks. I don't think that this tweak is that much specific, though. I think it is rather in line with the rest of STL interfaces that try to be type-generic. Thanks again. -- Alexei Alexandrov

On Tuesday 20 May 2008 15:13:02 Beman Dawes wrote: [ issues using path and wpath in parallel]
* As a further indication that there should be a single path type that can handle both wide and narrow types. Peter Dimov suggested that once, and I keep turning over in my mind how it could be accomplished. With C++0x supplying two new character types, the need becomes more pressing. I still don't want to invent a solution that applies only to filesystem paths; there is a general need for strings that can cope with multiple character types and encodings.
I'm currently working on an application where paths are represented as an evil mixture of both std::string and std::wstring, including the ensuing confusion which encoding a std::string has and how to represent a mixture between e.g. Latin and Cyrillic in the same path when passing a char* to std::fstream. Currently, I resolved to using a helper structure that exposes this interface: struct path { // for digestion by std::fstream // will throw in order to signal conversion failure char const* c_str() const; // convert to a Unicode-string std::wstring to_string() const; // add an element to the path path& operator/=(std::wstring const& s); // ... further methods ... private: // ... data ... }; The interface is built on Unicode strings (with the assumption that std::wstring is suitable). The storage internally is a wchar_t string with UTF-16 encoding on MS Windows (because that's its native encoding on all systems relevant to me) and a UTF-8 char string on POSIX. However, it could also be implemented as any other container, i.e. whatever best suits the system. In all cases, when modifying the path the arguments are converted to an OS-native representation and errors are thrown in case of unsupported uses. The main difference to current Boost.Filesystem is that a path is not treated as a string. Rather, it is considered something depending on the OS and which is related to a string or uses strings in its interface. In other words, it is an implementation-specific subset of all strings. Further, it is convertible to a string (sometimes). Note that I'm currently still experimenting with this but I can keep you updated if the above interface and implementation will be useful beyond this particular application. Uli
participants (3)
-
Alexei Alexandrov
-
Beman Dawes
-
Ulrich Eckhardt