Moved path_traits.hpp to detail.

The public path_traits.hpp header is deprecated and will be removed. Its
contents are path implementation details and are now in detail.
This commit is contained in:
Andrey Semashev
2022-08-21 18:45:59 +03:00
parent bb7dc550d5
commit 349daee54b
10 changed files with 478 additions and 503 deletions

View File

@@ -405,6 +405,16 @@ can be suppressed by defining <code>BOOST_FILESYSTEM_ALLOW_DEPRECATED</code> mac
<td style="font-size: 10pt" valign="top">
<i>The header is deprecated, use a different implementation of these functions. Unavailable if </i><code>BOOST_FILESYSTEM_NO_DEPRECATED</code><i> is defined and will be permanently removed in a future release.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>path_traits.hpp</code></td>
<td style="font-size: 10pt" valign="top">
The header contains implementation details of class <code>path</code>.</td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>The header is deprecated and should not be used in user's code. Unavailable if </i><code>BOOST_FILESYSTEM_NO_DEPRECATED</code><i> is defined and will be permanently removed in a future release.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
Macro definitions</td>

View File

@@ -42,6 +42,7 @@
<h2>1.81.0</h2>
<ul>
<li><b>Deprecated:</b> <code>path</code> construction, assignment and appending from containers of characters, such as <code>std::vector&lt;char&gt;</code> or <code>std::list&lt;wchar_t&gt;</code>, is deprecated in <b>v3</b> and removed in <b>v4</b>. Please use string types or iterators instead.</li>
<li><b>Deprecated:</b> <code>boost/filesystem/path_traits.hpp</code> header is deprecated and will be removed in a future release. The header contained implementation details of <code>path</code> and should not be used in user's code.</li>
<li>Previously deprecated APIs will now generate compilation warnings on use. To suppress these warnings, <code>BOOST_FILESYSTEM_ALLOW_DEPRECATED</code> macro can be defined when compiling user's code.</li>
<li>Fixed compilation due to a missing include on POSIX systems that do not support <code>*at</code> APIs. (<a href="https://github.com/boostorg/filesystem/issues/250">#250</a>)</li>
<li>On Windows prior to 10, added a workaround for network share filesystem that produces <code>ERROR_INVALID_PARAMETER</code> when constructing directory iterators. (<a href="https://github.com/boostorg/filesystem/pull/246">PR#246</a>, <a href="https://github.com/boostorg/filesystem/issues/245">#245</a>)</li>

View File

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

View File

@@ -18,7 +18,7 @@
#include <boost/assert.hpp>
#include <boost/filesystem/config.hpp>
#include <boost/filesystem/path_traits.hpp> // includes <cwchar>
#include <boost/filesystem/detail/path_traits.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/core/enable_if.hpp>
@@ -208,10 +208,10 @@ public:
template< class Source >
path(Source const& source, typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value
>::type* = NULL)
{
path_traits::dispatch(source, m_pathname);
detail::path_traits::dispatch(source, m_pathname);
}
path(const value_type* s) : m_pathname(s) {}
@@ -273,10 +273,10 @@ public:
template< class Source >
path(Source const& source, codecvt_type const& cvt, typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value
>::type* = NULL)
{
path_traits::dispatch(source, m_pathname, cvt);
detail::path_traits::dispatch(source, m_pathname, cvt);
}
path(const value_type* begin, const value_type* end) : m_pathname(begin, end) {}
@@ -288,7 +288,7 @@ public:
{
// convert requires contiguous string, so copy
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname);
}
}
@@ -301,7 +301,7 @@ public:
{
// convert requires contiguous string, so copy
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt);
}
}
@@ -325,7 +325,7 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type operator=(Source const& source)
{
@@ -352,12 +352,12 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type assign(Source const& source)
{
m_pathname.clear();
path_traits::dispatch(source, m_pathname);
detail::path_traits::dispatch(source, m_pathname);
return *this;
}
@@ -381,12 +381,12 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type assign(Source const& source, codecvt_type const& cvt)
{
m_pathname.clear();
path_traits::dispatch(source, m_pathname, cvt);
detail::path_traits::dispatch(source, m_pathname, cvt);
return *this;
}
@@ -404,7 +404,7 @@ public:
if (begin != end)
{
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname);
}
return *this;
}
@@ -423,7 +423,7 @@ public:
if (begin != end)
{
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt);
}
return *this;
}
@@ -447,7 +447,7 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type operator+=(Source const& source)
{
@@ -490,11 +490,11 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type concat(Source const& source)
{
path_traits::dispatch(source, m_pathname);
detail::path_traits::dispatch(source, m_pathname);
return *this;
}
@@ -518,11 +518,11 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type concat(Source const& source, codecvt_type const& cvt)
{
path_traits::dispatch(source, m_pathname, cvt);
detail::path_traits::dispatch(source, m_pathname, cvt);
return *this;
}
@@ -539,7 +539,7 @@ public:
if (begin != end)
{
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname);
}
return *this;
}
@@ -557,7 +557,7 @@ public:
if (begin != end)
{
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), m_pathname, cvt);
}
return *this;
}
@@ -584,7 +584,7 @@ public:
template< class Source >
BOOST_FORCEINLINE typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type operator/=(Source const& source)
{
@@ -611,12 +611,12 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type append(Source const& source)
{
path p;
path_traits::dispatch(source, p.m_pathname);
detail::path_traits::dispatch(source, p.m_pathname);
return append(p);
}
@@ -640,12 +640,12 @@ public:
template< class Source >
typename boost::enable_if_c<
path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
detail::path_traits::is_pathable< typename boost::decay< Source >::type >::value && !path_detail::is_native_pathable< Source >::value,
path&
>::type append(Source const& source, codecvt_type const& cvt)
{
path p;
path_traits::dispatch(source, p.m_pathname, cvt);
detail::path_traits::dispatch(source, p.m_pathname, cvt);
return append(p);
}
@@ -663,7 +663,7 @@ public:
if (begin != end)
{
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname);
}
return append(p);
}
@@ -682,7 +682,7 @@ public:
if (begin != end)
{
std::basic_string< typename std::iterator_traits< InputIterator >::value_type > seq(begin, end);
path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname, cvt);
detail::path_traits::convert(seq.c_str(), seq.c_str() + seq.size(), p.m_pathname, cvt);
}
return append(p);
}
@@ -744,14 +744,14 @@ public:
{
std::string tmp;
if (!m_pathname.empty())
path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp);
detail::path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp);
return tmp;
}
std::string string(codecvt_type const& cvt) const
{
std::string tmp;
if (!m_pathname.empty())
path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt);
detail::path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt);
return tmp;
}
@@ -767,14 +767,14 @@ public:
{
std::wstring tmp;
if (!m_pathname.empty())
path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp);
detail::path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp);
return tmp;
}
std::wstring wstring(codecvt_type const& cvt) const
{
std::wstring tmp;
if (!m_pathname.empty())
path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt);
detail::path_traits::convert(m_pathname.c_str(), m_pathname.c_str() + m_pathname.size(), tmp, cvt);
return tmp;
}
#endif
@@ -1370,6 +1370,7 @@ inline std::wstring path::generic_string< std::wstring >(codecvt_type const& cvt
// requiring path::codecvt() be visable //
//--------------------------------------------------------------------------------------//
namespace detail {
namespace path_traits { // without codecvt
inline void convert(const char* from,
@@ -1399,6 +1400,7 @@ inline void convert(const wchar_t* from, std::string& to)
}
} // namespace path_traits
} // namespace detail
} // namespace filesystem
} // namespace boost

View File

@@ -12,397 +12,22 @@
#define BOOST_FILESYSTEM_PATH_TRAITS_HPP
#include <boost/filesystem/config.hpp>
#include <cstddef>
#include <cwchar> // for mbstate_t
#include <locale>
#include <string>
#include <boost/assert.hpp>
#include <boost/system/error_category.hpp>
#if BOOST_FILESYSTEM_VERSION < 4
#include <vector>
#include <list>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/is_array.hpp>
#if !defined(BOOST_FILESYSTEM_DEPRECATED) && !defined(BOOST_FILESYSTEM_ALLOW_DEPRECATED)
#include <boost/config/header_deprecated.hpp>
BOOST_HEADER_DEPRECATED("your own implementation")
#endif
#if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
#include <boost/filesystem/detail/path_traits.hpp>
#include <boost/filesystem/detail/header.hpp> // must be the last #include
namespace boost {
namespace filesystem {
BOOST_FILESYSTEM_DECL system::error_category const& codecvt_error_category() BOOST_NOEXCEPT;
// uses std::codecvt_base::result used for error codes:
//
// ok: Conversion successful.
// partial: Not all source characters converted; one or more additional source
// characters are needed to produce the final target character, or the
// size of the target intermediate buffer was too small to hold the result.
// error: A character in the source could not be converted to the target encoding.
// noconv: The source and target characters have the same type and encoding, so no
// conversion was necessary.
namespace path_traits = boost::filesystem::detail::path_traits;
class directory_entry;
namespace path_traits {
typedef std::codecvt< wchar_t, char, std::mbstate_t > codecvt_type;
// is_pathable type trait; allows disabling over-agressive class path member templates
template< class T >
struct is_pathable
{
static const bool value = false;
};
template<>
struct is_pathable< char* >
{
static const bool value = true;
};
template<>
struct is_pathable< const char* >
{
static const bool value = true;
};
template<>
struct is_pathable< wchar_t* >
{
static const bool value = true;
};
template<>
struct is_pathable< const wchar_t* >
{
static const bool value = true;
};
template<>
struct is_pathable< std::string >
{
static const bool value = true;
};
template<>
struct is_pathable< std::wstring >
{
static const bool value = true;
};
#if BOOST_FILESYSTEM_VERSION < 4
template<>
struct
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
is_pathable< std::vector< char > >
{
static const bool value = true;
};
template<>
struct
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
is_pathable< std::vector< wchar_t > >
{
static const bool value = true;
};
template<>
struct
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
is_pathable< std::list< char > >
{
static const bool value = true;
};
template<>
struct
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
is_pathable< std::list< wchar_t > >
{
static const bool value = true;
};
#endif // BOOST_FILESYSTEM_VERSION < 4
template<>
struct is_pathable< directory_entry >
{
static const bool value = true;
};
// Pathable empty
#if BOOST_FILESYSTEM_VERSION < 4
template< class Container >
inline
// disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
// conforming compilers. Replace by plain "bool" at some future date (2012?)
typename boost::disable_if< boost::is_array< Container >, bool >::type
empty(Container const& c)
{
return c.begin() == c.end();
}
#endif // BOOST_FILESYSTEM_VERSION < 4
template< class T >
inline bool empty(T* const& c_str)
{
BOOST_ASSERT(c_str != NULL);
return !*c_str;
}
template< typename T, std::size_t N >
inline bool empty(T (&x)[N])
{
return !x[0];
}
// value types differ ---------------------------------------------------------------//
//
// A from_end argument of NULL is less efficient than a known end, so use only if needed
// with codecvt
BOOST_FILESYSTEM_DECL
void convert(const char* from,
const char* from_end, // NULL for null terminated MBCS
std::wstring& to, codecvt_type const& cvt);
BOOST_FILESYSTEM_DECL
void convert(const wchar_t* from,
const wchar_t* from_end, // NULL for null terminated MBCS
std::string& to, codecvt_type const& cvt);
inline void convert(const char* from, std::wstring& to, codecvt_type const& cvt)
{
BOOST_ASSERT(from);
convert(from, NULL, to, cvt);
}
inline void convert(const wchar_t* from, std::string& to, codecvt_type const& cvt)
{
BOOST_ASSERT(from);
convert(from, NULL, to, cvt);
}
// without codecvt
inline void convert(const char* from,
const char* from_end, // NULL for null terminated MBCS
std::wstring& to);
inline void convert(const wchar_t* from,
const wchar_t* from_end, // NULL for null terminated MBCS
std::string& to);
inline void convert(const char* from, std::wstring& to);
inline void convert(const wchar_t* from, std::string& to);
// value types same -----------------------------------------------------------------//
// char with codecvt
inline void convert(const char* from, const char* from_end, std::string& to, codecvt_type const&)
{
BOOST_ASSERT(from);
BOOST_ASSERT(from_end);
to.append(from, from_end);
}
inline void convert(const char* from, std::string& to, codecvt_type const&)
{
BOOST_ASSERT(from);
to += from;
}
// wchar_t with codecvt
inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to, codecvt_type const&)
{
BOOST_ASSERT(from);
BOOST_ASSERT(from_end);
to.append(from, from_end);
}
inline void convert(const wchar_t* from, std::wstring& to, codecvt_type const&)
{
BOOST_ASSERT(from);
to += from;
}
// char without codecvt
inline void convert(const char* from, const char* from_end, std::string& to)
{
BOOST_ASSERT(from);
BOOST_ASSERT(from_end);
to.append(from, from_end);
}
inline void convert(const char* from, std::string& to)
{
BOOST_ASSERT(from);
to += from;
}
// wchar_t without codecvt
inline void convert(const wchar_t* from, const wchar_t* from_end, std::wstring& to)
{
BOOST_ASSERT(from);
BOOST_ASSERT(from_end);
to.append(from, from_end);
}
inline void convert(const wchar_t* from, std::wstring& to)
{
BOOST_ASSERT(from);
to += from;
}
// Source dispatch -----------------------------------------------------------------//
// contiguous containers with codecvt
template< class U >
inline void dispatch(std::string const& c, U& to, codecvt_type const& cvt)
{
const char* p = c.c_str();
convert(p, p + c.size(), to, cvt);
}
template< class U >
inline void dispatch(std::wstring const& c, U& to, codecvt_type const& cvt)
{
const wchar_t* p = c.c_str();
convert(p, p + c.size(), to, cvt);
}
#if BOOST_FILESYSTEM_VERSION < 4
template< class U >
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
inline void dispatch(std::vector< char > const& c, U& to, codecvt_type const& cvt)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
}
template< class U >
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
inline void dispatch(std::vector< wchar_t > const& c, U& to, codecvt_type const& cvt)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
}
#endif // BOOST_FILESYSTEM_VERSION < 4
// contiguous containers without codecvt
template< class U >
inline void dispatch(std::string const& c, U& to)
{
const char* p = c.c_str();
convert(p, p + c.size(), to);
}
template< class U >
inline void dispatch(std::wstring const& c, U& to)
{
const wchar_t* p = c.c_str();
convert(p, p + c.size(), to);
}
#if BOOST_FILESYSTEM_VERSION < 4
template< class U >
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
inline void dispatch(std::vector< char > const& c, U& to)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), to);
}
template< class U >
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
inline void dispatch(std::vector< wchar_t > const& c, U& to)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), to);
}
// non-contiguous containers with codecvt
template< class Container, class U >
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
inline
// disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
// conforming compilers. Replace by plain "void" at some future date (2012?)
typename boost::disable_if< boost::is_array< Container >, void >::type
dispatch(Container const& c, U& to, codecvt_type const& cvt)
{
if (!c.empty())
{
std::basic_string< typename Container::value_type > s(c.begin(), c.end());
convert(s.c_str(), s.c_str() + s.size(), to, cvt);
}
}
#endif // BOOST_FILESYSTEM_VERSION < 4
// c_str
template< class T, class U >
inline void dispatch(T* const& c_str, U& to, codecvt_type const& cvt)
{
// std::cout << "dispatch() const T *\n";
BOOST_ASSERT(c_str);
convert(c_str, to, cvt);
}
// Note: there is no dispatch on C-style arrays because the array may
// contain a string smaller than the array size.
BOOST_FILESYSTEM_DECL
void dispatch(directory_entry const& de,
#ifdef BOOST_WINDOWS_API
std::wstring& to,
#else
std::string& to,
#endif
codecvt_type const&);
#if BOOST_FILESYSTEM_VERSION < 4
// non-contiguous containers without codecvt
template< class Container, class U >
BOOST_FILESYSTEM_DETAIL_DEPRECATED("Boost.Filesystem path construction/assignment/appending from containers is deprecated, use strings or iterators instead.")
inline
// disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
// conforming compilers. Replace by plain "void" at some future date (2012?)
typename boost::disable_if< boost::is_array< Container >, void >::type
dispatch(Container const& c, U& to)
{
if (!c.empty())
{
std::basic_string< typename Container::value_type > seq(c.begin(), c.end());
convert(seq.c_str(), seq.c_str() + seq.size(), to);
}
}
#endif // BOOST_FILESYSTEM_VERSION < 4
// c_str
template< class T, class U >
inline void dispatch(T* const& c_str, U& to)
{
// std::cout << "dispatch() const T *\n";
BOOST_ASSERT(c_str != NULL);
convert(c_str, to);
}
// Note: there is no dispatch on C-style arrays because the array may
// contain a string smaller than the array size.
BOOST_FILESYSTEM_DECL
void dispatch(directory_entry const& de,
#ifdef BOOST_WINDOWS_API
std::wstring& to
#else
std::string& to
#endif
);
} // namespace path_traits
} // namespace filesystem
} // namespace boost

View File

@@ -15,7 +15,7 @@
#include <boost/config/warning_disable.hpp>
#include <boost/filesystem/config.hpp>
#include <boost/filesystem/path_traits.hpp>
#include <boost/filesystem/detail/path_traits.hpp>
#include <boost/system/error_category.hpp>
#include <locale>
#include <string>
@@ -28,6 +28,7 @@
namespace boost {
namespace filesystem {
namespace detail {
namespace {
@@ -114,6 +115,7 @@ const codecvt_error_category_initializer g_codecvt_error_category_initializer;
#endif // !defined(BOOST_SYSTEM_HAS_CONSTEXPR) && !defined(_MSC_VER)
} // namespace detail
} // namespace filesystem
} // namespace boost

View File

@@ -134,8 +134,10 @@ file_status directory_entry::get_symlink_status(system::error_code* ec) const
return m_symlink_status;
}
namespace detail {
// dispatch directory_entry supplied here rather than in
// <boost/filesystem/path_traits.hpp>, thus avoiding header circularity.
// <boost/filesystem/detail/path_traits.hpp>, thus avoiding header circularity.
// test cases are in operations_unit_test.cpp
namespace path_traits {
@@ -172,8 +174,6 @@ void dispatch(directory_entry const& de,
// //
//--------------------------------------------------------------------------------------//
namespace detail {
BOOST_CONSTEXPR_OR_CONST std::size_t dir_itr_imp_extra_data_alignment = 16u;
BOOST_FILESYSTEM_DECL void* dir_itr_imp::operator new(std::size_t class_size, std::size_t extra_size) BOOST_NOEXCEPT

View File

@@ -12,7 +12,7 @@
#include <boost/filesystem/config.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/path_traits.hpp> // codecvt_error_category()
#include <boost/filesystem/detail/path_traits.hpp> // codecvt_error_category()
#include <boost/scoped_array.hpp>
#include <boost/system/error_category.hpp> // for BOOST_SYSTEM_HAS_CONSTEXPR
#include <boost/assert.hpp>

View File

@@ -12,7 +12,7 @@
#include "platform_config.hpp"
#include <boost/filesystem/config.hpp>
#include <boost/filesystem/path_traits.hpp>
#include <boost/filesystem/detail/path_traits.hpp>
#include <boost/system/system_error.hpp>
#include <boost/smart_ptr/scoped_array.hpp>
#include <boost/assert.hpp>
@@ -119,6 +119,7 @@ void convert_aux(
namespace boost {
namespace filesystem {
namespace detail {
namespace path_traits {
//--------------------------------------------------------------------------------------//
@@ -130,12 +131,10 @@ void convert(const char* from,
const char* from_end, // 0 for null terminated MBCS
std::wstring& to, codecvt_type const& cvt)
{
BOOST_ASSERT(from);
BOOST_ASSERT(from != NULL);
if (!from_end) // null terminated
{
from_end = from + std::strlen(from);
}
if (from == from_end)
return;
@@ -164,12 +163,10 @@ void convert(const wchar_t* from,
const wchar_t* from_end, // 0 for null terminated MBCS
std::string& to, codecvt_type const& cvt)
{
BOOST_ASSERT(from);
BOOST_ASSERT(from != NULL);
if (!from_end) // null terminated
{
from_end = from + std::wcslen(from);
}
if (from == from_end)
return;
@@ -195,6 +192,7 @@ void convert(const wchar_t* from,
}
} // namespace path_traits
} // namespace detail
} // namespace filesystem
} // namespace boost

View File

@@ -1099,82 +1099,6 @@ void test_error_handling()
std::cout << " testing error handling complete" << std::endl;
}
#if 0
// // test_locales --------------------------------------------------------------------//
//
// void test_locales()
// {
// std::cout << "testing locales..." << std::endl;
//
// }
// test_user_supplied_type ---------------------------------------------------------//
typedef std::basic_string<int> user_string;
} // unnamed namespace
namespace boost {
namespace filesystem {
namespace path_traits {
template<> struct is_iterator< const user_string::value_type* > { static const bool value = true; };
template<> struct is_iterator< user_string::value_type* > { static const bool value = true; };
template<> struct is_iterator< user_string::iterator > { static const bool value = true; };
template<> struct is_iterator< user_string::const_iterator > { static const bool value = true; };
template<> struct is_container< user_string > { static const bool value = true; };
template<>
void append< user_string::value_type >(const user_string::value_type* begin,
const user_string::value_type* end, string_type& target, system::error_code& ec)
{
for (; begin != end && *begin; ++begin)
target += *begin + 1; // change so that results distinguishable from char cvts
}
#ifdef __GNUC__
// This specialization shouldn't be needed, and VC++, Intel, and others work
// fine without it. But gcc 4.3.2, and presumably other versions, need it.
template<>
void append< user_string::value_type >(const user_string::value_type* begin,
string_type& target, system::error_code& ec)
{
path_traits::append<user_string::value_type>(begin,
static_cast<const user_string::value_type *>(0), target, ec);
}
#endif
template<>
user_string convert< user_string >(string_type const& source, system::error_code& ec)
{
user_string temp;
for (string_type::const_iterator it = source.begin(); it != source.end(); ++it)
temp += *it - 1;
return temp;
}
} // namespace path_traits
} // namespace filesystem
} // namespace boost
namespace {
void test_user_supplied_type()
{
std::cout << "testing user supplied type..." << std::endl;
user_string::value_type usr_c_str[] = { 'a', 'b', 'c', 0 };
user_string usr(usr_c_str);
path p1(usr.c_str());
CHECK(p1 == path("bcd"));
CHECK(p1 == "bcd");
user_string s1(p1.string<user_string>());
CHECK(s1 == usr);
}
#endif
inline const char* macro_value(const char* name, const char* value)
{