Chris@16: // filesystem path_traits.hpp --------------------------------------------------------// Chris@16: Chris@16: // Copyright Beman Dawes 2009 Chris@16: Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See http://www.boost.org/LICENSE_1_0.txt Chris@16: Chris@16: // Library home page: http://www.boost.org/libs/filesystem Chris@16: Chris@16: #ifndef BOOST_FILESYSTEM_PATH_TRAITS_HPP Chris@16: #define BOOST_FILESYSTEM_PATH_TRAITS_HPP Chris@16: Chris@16: #include Chris@16: Chris@16: # if defined( BOOST_NO_STD_WSTRING ) Chris@16: # error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support Chris@16: # endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include // for mbstate_t Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: // #include //**** comment me out **** Chris@16: Chris@16: #include // must be the last #include Chris@16: Chris@16: namespace boost { namespace filesystem { Chris@16: Chris@16: BOOST_FILESYSTEM_DECL const system::error_category& codecvt_error_category(); Chris@16: // uses std::codecvt_base::result used for error codes: Chris@16: // Chris@16: // ok: Conversion successful. Chris@16: // partial: Not all source characters converted; one or more additional source Chris@16: // characters are needed to produce the final target character, or the Chris@16: // size of the target intermediate buffer was too small to hold the result. Chris@16: // error: A character in the source could not be converted to the target encoding. Chris@16: // noconv: The source and target characters have the same type and encoding, so no Chris@16: // conversion was necessary. Chris@16: Chris@16: class directory_entry; Chris@16: Chris@16: namespace path_traits { Chris@16: Chris@16: typedef std::codecvt codecvt_type; Chris@16: Chris@16: // is_pathable type trait; allows disabling over-agressive class path member templates Chris@16: Chris@16: template Chris@16: struct is_pathable { static const bool value = false; }; Chris@16: Chris@16: template<> struct is_pathable { static const bool value = true; }; Chris@16: template<> struct is_pathable { static const bool value = true; }; Chris@16: template<> struct is_pathable { static const bool value = true; }; Chris@16: template<> struct is_pathable { static const bool value = true; }; Chris@16: template<> struct is_pathable { static const bool value = true; }; Chris@16: template<> struct is_pathable { static const bool value = true; }; Chris@16: template<> struct is_pathable > { static const bool value = true; }; Chris@16: template<> struct is_pathable > { static const bool value = true; }; Chris@16: template<> struct is_pathable > { static const bool value = true; }; Chris@16: template<> struct is_pathable > { static const bool value = true; }; Chris@16: template<> struct is_pathable { static const bool value = true; }; Chris@16: Chris@16: // Pathable empty Chris@16: Chris@16: template inline Chris@16: // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for Chris@16: // conforming compilers. Replace by plain "bool" at some future date (2012?) Chris@16: typename boost::disable_if, bool>::type Chris@16: empty(const Container & c) Chris@16: { return c.begin() == c.end(); } Chris@16: Chris@16: template inline Chris@16: bool empty(T * const & c_str) Chris@16: { Chris@16: BOOST_ASSERT(c_str); Chris@16: return !*c_str; Chris@16: } Chris@16: Chris@16: template inline Chris@16: bool empty(T (&x)[N]) Chris@16: { return !x[0]; } Chris@16: Chris@16: // value types differ ---------------------------------------------------------------// Chris@16: // Chris@16: // A from_end argument of 0 is less efficient than a known end, so use only if needed Chris@101: Chris@101: // with codecvt Chris@16: Chris@16: BOOST_FILESYSTEM_DECL Chris@101: void convert(const char* from, Chris@101: const char* from_end, // 0 for null terminated MBCS Chris@101: std::wstring & to, Chris@101: const codecvt_type& cvt); Chris@16: Chris@101: BOOST_FILESYSTEM_DECL Chris@101: void convert(const wchar_t* from, Chris@101: const wchar_t* from_end, // 0 for null terminated MBCS Chris@101: std::string & to, Chris@101: const codecvt_type& cvt); Chris@101: Chris@101: inline Chris@101: void convert(const char* from, Chris@101: std::wstring & to, Chris@101: const codecvt_type& cvt) Chris@16: { Chris@16: BOOST_ASSERT(from); Chris@16: convert(from, 0, to, cvt); Chris@16: } Chris@16: Chris@101: inline Chris@101: void convert(const wchar_t* from, Chris@101: std::string & to, Chris@101: const codecvt_type& cvt) Chris@16: { Chris@16: BOOST_ASSERT(from); Chris@16: convert(from, 0, to, cvt); Chris@16: } Chris@16: Chris@101: // without codecvt Chris@101: Chris@101: inline Chris@101: void convert(const char* from, Chris@101: const char* from_end, // 0 for null terminated MBCS Chris@101: std::wstring & to); Chris@101: Chris@101: inline Chris@101: void convert(const wchar_t* from, Chris@101: const wchar_t* from_end, // 0 for null terminated MBCS Chris@101: std::string & to); Chris@101: Chris@101: inline Chris@101: void convert(const char* from, Chris@101: std::wstring & to); Chris@101: Chris@101: inline Chris@101: void convert(const wchar_t* from, Chris@101: std::string & to); Chris@101: Chris@16: // value types same -----------------------------------------------------------------// Chris@16: Chris@101: // char with codecvt Chris@16: Chris@101: inline Chris@101: void convert(const char* from, const char* from_end, std::string & to, Chris@16: const codecvt_type&) Chris@16: { Chris@16: BOOST_ASSERT(from); Chris@16: BOOST_ASSERT(from_end); Chris@16: to.append(from, from_end); Chris@16: } Chris@16: Chris@101: inline Chris@101: void convert(const char* from, Chris@101: std::string & to, Chris@101: const codecvt_type&) Chris@16: { Chris@16: BOOST_ASSERT(from); Chris@16: to += from; Chris@16: } Chris@16: Chris@101: // wchar_t with codecvt Chris@16: Chris@101: inline Chris@101: void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to, Chris@16: const codecvt_type&) Chris@16: { Chris@16: BOOST_ASSERT(from); Chris@16: BOOST_ASSERT(from_end); Chris@16: to.append(from, from_end); Chris@16: } Chris@16: Chris@101: inline Chris@101: void convert(const wchar_t* from, Chris@101: std::wstring & to, Chris@101: const codecvt_type&) Chris@101: { Chris@101: BOOST_ASSERT(from); Chris@101: to += from; Chris@101: } Chris@101: Chris@101: // char without codecvt Chris@101: Chris@101: inline Chris@101: void convert(const char* from, const char* from_end, std::string & to) Chris@101: { Chris@101: BOOST_ASSERT(from); Chris@101: BOOST_ASSERT(from_end); Chris@101: to.append(from, from_end); Chris@101: } Chris@101: Chris@101: inline Chris@101: void convert(const char* from, std::string & to) Chris@101: { Chris@101: BOOST_ASSERT(from); Chris@101: to += from; Chris@101: } Chris@101: Chris@101: // wchar_t without codecvt Chris@101: Chris@101: inline Chris@101: void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to) Chris@101: { Chris@101: BOOST_ASSERT(from); Chris@101: BOOST_ASSERT(from_end); Chris@101: to.append(from, from_end); Chris@101: } Chris@101: Chris@101: inline Chris@101: void convert(const wchar_t* from, std::wstring & to) Chris@16: { Chris@16: BOOST_ASSERT(from); Chris@16: to += from; Chris@16: } Chris@16: Chris@16: // Source dispatch -----------------------------------------------------------------// Chris@16: Chris@101: // contiguous containers with codecvt Chris@16: template inline Chris@16: void dispatch(const std::string& c, U& to, const codecvt_type& cvt) Chris@16: { Chris@16: if (c.size()) Chris@16: convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); Chris@16: } Chris@16: template inline Chris@16: void dispatch(const std::wstring& c, U& to, const codecvt_type& cvt) Chris@16: { Chris@16: if (c.size()) Chris@16: convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); Chris@16: } Chris@16: template inline Chris@16: void dispatch(const std::vector& c, U& to, const codecvt_type& cvt) Chris@16: { Chris@16: if (c.size()) Chris@16: convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); Chris@16: } Chris@16: template inline Chris@16: void dispatch(const std::vector& c, U& to, const codecvt_type& cvt) Chris@16: { Chris@16: if (c.size()) Chris@16: convert(&*c.begin(), &*c.begin() + c.size(), to, cvt); Chris@16: } Chris@16: Chris@101: // contiguous containers without codecvt Chris@101: template inline Chris@101: void dispatch(const std::string& c, U& to) Chris@101: { Chris@101: if (c.size()) Chris@101: convert(&*c.begin(), &*c.begin() + c.size(), to); Chris@101: } Chris@101: template inline Chris@101: void dispatch(const std::wstring& c, U& to) Chris@101: { Chris@101: if (c.size()) Chris@101: convert(&*c.begin(), &*c.begin() + c.size(), to); Chris@101: } Chris@101: template inline Chris@101: void dispatch(const std::vector& c, U& to) Chris@101: { Chris@101: if (c.size()) Chris@101: convert(&*c.begin(), &*c.begin() + c.size(), to); Chris@101: } Chris@101: template inline Chris@101: void dispatch(const std::vector& c, U& to) Chris@101: { Chris@101: if (c.size()) Chris@101: convert(&*c.begin(), &*c.begin() + c.size(), to); Chris@101: } Chris@101: Chris@101: // non-contiguous containers with codecvt Chris@16: template inline Chris@16: // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for Chris@16: // conforming compilers. Replace by plain "void" at some future date (2012?) Chris@16: typename boost::disable_if, void>::type Chris@101: dispatch(const Container & c, U& to, const codecvt_type& cvt) Chris@16: { Chris@16: if (c.size()) Chris@16: { Chris@16: std::basic_string s(c.begin(), c.end()); Chris@16: convert(s.c_str(), s.c_str()+s.size(), to, cvt); Chris@16: } Chris@16: } Chris@16: Chris@16: // c_str Chris@16: template inline Chris@101: void dispatch(T * const & c_str, U& to, const codecvt_type& cvt) Chris@16: { Chris@101: // std::cout << "dispatch() const T *\n"; Chris@16: BOOST_ASSERT(c_str); Chris@16: convert(c_str, to, cvt); Chris@16: } Chris@101: Chris@16: // Note: there is no dispatch on C-style arrays because the array may Chris@16: // contain a string smaller than the array size. Chris@16: Chris@16: BOOST_FILESYSTEM_DECL Chris@101: void dispatch(const directory_entry & de, Chris@16: # ifdef BOOST_WINDOWS_API Chris@101: std::wstring & to, Chris@16: # else Chris@101: std::string & to, Chris@16: # endif Chris@101: const codecvt_type&); Chris@101: Chris@101: // non-contiguous containers without codecvt Chris@101: template inline Chris@101: // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for Chris@101: // conforming compilers. Replace by plain "void" at some future date (2012?) Chris@101: typename boost::disable_if, void>::type Chris@101: dispatch(const Container & c, U& to) Chris@101: { Chris@101: if (c.size()) Chris@101: { Chris@101: std::basic_string seq(c.begin(), c.end()); Chris@101: convert(seq.c_str(), seq.c_str()+seq.size(), to); Chris@101: } Chris@101: } Chris@101: Chris@101: // c_str Chris@101: template inline Chris@101: void dispatch(T * const & c_str, U& to) Chris@101: { Chris@101: // std::cout << "dispatch() const T *\n"; Chris@101: BOOST_ASSERT(c_str); Chris@101: convert(c_str, to); Chris@101: } Chris@101: Chris@101: // Note: there is no dispatch on C-style arrays because the array may Chris@101: // contain a string smaller than the array size. Chris@101: Chris@101: BOOST_FILESYSTEM_DECL Chris@101: void dispatch(const directory_entry & de, Chris@101: # ifdef BOOST_WINDOWS_API Chris@101: std::wstring & to Chris@101: # else Chris@101: std::string & to Chris@101: # endif Chris@101: ); Chris@16: Chris@16: Chris@16: }}} // namespace boost::filesystem::path_traits Chris@16: Chris@16: #include // pops abi_prefix.hpp pragmas Chris@16: Chris@16: #endif // BOOST_FILESYSTEM_PATH_TRAITS_HPP