mirror of
https://github.com/boostorg/filesystem.git
synced 2026-01-30 20:02:10 +00:00
Initial pass at adding support for char16_t and char32_t. Unstable work-in-progress.
This commit is contained in:
@@ -38,12 +38,22 @@
|
||||
#include <boost/system/api_config.hpp> // for BOOST_POSIX_API or BOOST_WINDOWS_API
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
// BOOST_FILESYSTEM_DEPRECATED needed for source compiles -----------------------------//
|
||||
// BOOST_FILESYSTEM_DEPRECATED needed for source compiles
|
||||
|
||||
# ifdef BOOST_FILESYSTEM_SOURCE
|
||||
# define BOOST_FILESYSTEM_DEPRECATED
|
||||
# endif
|
||||
|
||||
// Support for C++11 char16_t and char32_t paths requires both character type (or
|
||||
// equivalent typedef) support and header <codecvt> support.
|
||||
|
||||
# if BOOST_FILESYSTEM_VERSION > 3 \
|
||||
&& !defined(BOOST_NO_CXX11_HDR_CODECVT) \
|
||||
&& ((!defined(BOOST_NO_CXX11_CHAR16_T) && (!defined(BOOST_NO_CXX11_CHAR32_T)) \
|
||||
|| (defined(_MSC_VER) && _MSC_VER >= 1600)))
|
||||
# define BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
#endif
|
||||
|
||||
// throw an exception ----------------------------------------------------------------//
|
||||
//
|
||||
// Exceptions were originally thrown via boost::throw_exception().
|
||||
|
||||
@@ -75,6 +75,7 @@ namespace boost
|
||||
<< BOOST_FILESYSTEM_SHOW_MACRO(BOOST_FILESYSTEM_NO_DEPRECATED) << '\n'
|
||||
<< BOOST_FILESYSTEM_SHOW_MACRO(BOOST_FILESYSTEM_DECL) << '\n'
|
||||
<< BOOST_FILESYSTEM_SHOW_MACRO(BOOST_SYMBOL_VISIBLE) << '\n'
|
||||
<< BOOST_FILESYSTEM_SHOW_MACRO(BOOST_FILESYSTEM_CHAR16_CHAR32) << '\n'
|
||||
<< BOOST_FILESYSTEM_SHOW_MACRO(BOOST_FILESYSTEM_OPERATIONS_TEST_TEMP) << '\n'
|
||||
;
|
||||
return os;
|
||||
|
||||
@@ -124,6 +124,40 @@ namespace boost { namespace BOOST_FILESYSTEM_NAMESPACE {
|
||||
convert(from, 0, to, cvt);
|
||||
}
|
||||
|
||||
# ifdef BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
|
||||
BOOST_FILESYSTEM_DECL
|
||||
void convert(const char32_t* from,
|
||||
const char32_t* from_end, // 0 for null terminated MBCS
|
||||
std::wstring & to,
|
||||
const codecvt_type&);
|
||||
|
||||
//BOOST_FILESYSTEM_DECL
|
||||
// void convert(const char32_t* from,
|
||||
// const char32_t* from_end, // 0 for null terminated MBCS
|
||||
// std::string & to,
|
||||
// const codecvt_type& cvt);
|
||||
|
||||
//inline
|
||||
// void convert(const char32_t* from,
|
||||
// std::wstring & to,
|
||||
// const codecvt_type& cvt)
|
||||
//{
|
||||
// BOOST_ASSERT(from);
|
||||
// convert(from, 0, to, cvt);
|
||||
//}
|
||||
|
||||
//inline
|
||||
// void convert(const wchar_t* from,
|
||||
// std::string & to,
|
||||
// const codecvt_type& cvt)
|
||||
//{
|
||||
// BOOST_ASSERT(from);
|
||||
// convert(from, 0, to, cvt);
|
||||
//}
|
||||
|
||||
# endif
|
||||
|
||||
// value types same -----------------------------------------------------------------//
|
||||
|
||||
// char
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include <cstring> // for strlen
|
||||
#include <cwchar> // for wcslen
|
||||
|
||||
#ifdef BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
# include <codecvt>
|
||||
#endif
|
||||
|
||||
namespace pt = boost::filesystem::path_traits;
|
||||
namespace fs = boost::filesystem;
|
||||
namespace bs = boost::system;
|
||||
@@ -93,6 +97,46 @@ namespace {
|
||||
target.append(to, to_next);
|
||||
}
|
||||
|
||||
#ifdef BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// convert_aux const char32_t* to wstring //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
static void convert_aux(
|
||||
const char32_t* from,
|
||||
const char32_t* from_end,
|
||||
wchar_t* to, wchar_t* to_end,
|
||||
std::wstring& target)
|
||||
{
|
||||
//std::cout << std::hex
|
||||
// << " from=" << std::size_t(from)
|
||||
// << " from_end=" << std::size_t(from_end)
|
||||
// << " to=" << std::size_t(to)
|
||||
// << " to_end=" << std::size_t(to_end)
|
||||
// << std::endl;
|
||||
|
||||
typedef std::codecvt_utf16<char32_t> codecvt_type;
|
||||
static codecvt_type cvt;
|
||||
|
||||
std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
|
||||
const char32_t* from_next;
|
||||
wchar_t* to_next;
|
||||
|
||||
std::codecvt_base::result res;
|
||||
|
||||
if ((res = cvt.in(state, from, from_end, from_next,
|
||||
to, to_end, to_next)) != std::codecvt_base::ok)
|
||||
{
|
||||
//std::cout << " result is " << static_cast<int>(res) << std::endl;
|
||||
BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(),
|
||||
"boost::filesystem::path codecvt to wstring"));
|
||||
}
|
||||
target.append(to, to_next);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// convert_aux const wchar_t* to string //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
@@ -207,4 +251,47 @@ namespace boost { namespace BOOST_FILESYSTEM_NAMESPACE { namespace path_traits {
|
||||
convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to, cvt);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
|
||||
# ifdef BOOST_WINDOWS_API
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
// convert const char32_t* to wstring //
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
BOOST_FILESYSTEM_DECL
|
||||
void convert(const char32_t* from,
|
||||
const char32_t* from_end, // 0 for null terminated MBCS
|
||||
std::wstring& to,
|
||||
const codecvt_type&)
|
||||
{
|
||||
BOOST_ASSERT(from);
|
||||
|
||||
if (!from_end) // null terminated
|
||||
{
|
||||
for (from_end = from; *from_end; ++from_end); // find end
|
||||
}
|
||||
|
||||
if (from == from_end)
|
||||
return;
|
||||
|
||||
std::size_t buf_size = (from_end - from) * 2*4; // perhaps too large, but that's OK
|
||||
|
||||
// dynamically allocate a buffer only if source is unusually large
|
||||
if (buf_size > default_codecvt_buf_size)
|
||||
{
|
||||
boost::scoped_array< wchar_t > buf(new wchar_t[buf_size]);
|
||||
convert_aux(from, from_end, buf.get(), buf.get()+buf_size, to);
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t buf[default_codecvt_buf_size];
|
||||
convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::filesystem::path_traits
|
||||
|
||||
@@ -22,14 +22,39 @@
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/detail/lightweight_main.hpp>
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
namespace fs = boost::filesystem;
|
||||
using boost::basic_string_ref;
|
||||
using boost::string_ref;
|
||||
using boost::wstring_ref;
|
||||
|
||||
void f1(const string_ref&)
|
||||
{
|
||||
cout << "narrow" << endl;
|
||||
}
|
||||
void f1(const wstring_ref&)
|
||||
{
|
||||
cout << "wide" << endl;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void foo(const T& from)
|
||||
{
|
||||
f1(basic_string_ref<typename T::value_type>(from));
|
||||
}
|
||||
|
||||
//------------------------------------ cpp_main --------------------------------------//
|
||||
|
||||
int cpp_main(int argc, char* argv[])
|
||||
{
|
||||
foo(std::string("string"));
|
||||
//foo<char>(std::string("string"));
|
||||
//foo<char, std::char_traits<char>>("string");
|
||||
|
||||
|
||||
cout << "Hello, filesystem world" << endl;
|
||||
cout << fs::config() << endl;
|
||||
|
||||
|
||||
@@ -65,12 +65,12 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\config.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\config_info.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\convenience.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\detail\is_iterator.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\detail\source_value_type.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\detail\utf8_codecvt_facet.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\detail\version.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\detail\version_imp.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\exception.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\fstream.hpp" />
|
||||
<ClInclude Include="..\..\..\include\boost\filesystem\operations.hpp" />
|
||||
|
||||
@@ -63,6 +63,12 @@ using std::endl;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
|
||||
#ifdef BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
using std::u16string;
|
||||
using std::u32string;
|
||||
#endif
|
||||
|
||||
|
||||
#define CHECK(x) check(x, __FILE__, __LINE__)
|
||||
#define PATH_IS(a, b) check_path(a, b, __FILE__, __LINE__)
|
||||
#define NATIVE_IS(p, s, ws) check_native(p, s, ws, __FILE__, __LINE__)
|
||||
@@ -160,6 +166,14 @@ namespace
|
||||
boost::container::vector<wchar_t> wbv; // see main() for initialization to w, f, u, z
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
const char16_t u16a[] = {'u', '1', '6', 's', 't', 'r', 'i', 'n', 'g', '\0'};
|
||||
const char32_t u32a[] = {'u', '3', '2', 's', 't', 'r', 'i', 'n', 'g', '\0'};
|
||||
u16string u16s(u16a);
|
||||
u32string u32s(u32a);
|
||||
|
||||
#endif
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
void fun(const boost::shared_ptr< Base >&) {}
|
||||
@@ -301,6 +315,25 @@ namespace
|
||||
BOOST_TEST_EQ(x19.native().size(), 7U);
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_FILESYSTEM_CHAR16_CHAR32
|
||||
|
||||
{
|
||||
path x1(u32a);
|
||||
PATH_IS(x1, L"u32string");
|
||||
BOOST_TEST_EQ(x1.native().size(), 9U);
|
||||
|
||||
path x2(u32s);
|
||||
PATH_IS(x2, L"u32string");
|
||||
BOOST_TEST_EQ(x2.native().size(), 9U);
|
||||
|
||||
path x3(&u32a[0], &u32a[8]);
|
||||
PATH_IS(x3, L"u32string");
|
||||
BOOST_TEST_EQ(x3.native().size(), 9U);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// easy-to-make coding errors
|
||||
// path e1(x0, path::codecvt()); // fails to compile, and that is OK
|
||||
|
||||
|
||||
Reference in New Issue
Block a user