Deprecated path construction/assignment/appending from container types.

Users are advised to use string types and iterators instead of containers
to construct/assign/append to paths.

In v4, the support for containers is removed.
This commit is contained in:
Andrey Semashev 2022-08-14 19:14:42 +03:00
parent d58eb7a714
commit d829a46b31
8 changed files with 179 additions and 52 deletions

View File

@ -215,6 +215,16 @@ BOOST_FILESYSTEM_NO_DEPRECATED</code> is defined.</p>
<td style="font-size: 10pt" valign="top">
<p style="font-size: 10pt"><code>remove_filename()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<p style="font-size: 10pt">Construction, assignment and appending from container types.</td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<p style="font-size: 10pt">Use string types or iterators as the source for path construction, assignment and appending.</td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>path.hpp</code></td>

View File

@ -1288,7 +1288,7 @@ otherwise it shall be treated as a regular file path.</p>
path</code> argument encoding conversions</a>
[path.arg.encoding.cvt]</h5>
<p>For member function arguments that take character sequences representing
paths, if the value type of the argument is not <code>value_type and </code>one
paths, if the value type of the argument is not <code>value_type</code> and one
of the value types is <code>char</code> and the other is <code>wchar_t</code>, conversion to <code>value_type</code>
shall be performed by the <code>path::codecvt()</code> facet. ([<a href="#path-imbued-locale">path.imbued.locale</a>]).</p>
<h4><a name="path-Conversions-to-generic-format"><code>path</code> Conversions
@ -1297,20 +1297,20 @@ to generic format</a> [fs.cvt.to.generic]</h4>
shall return strings formatted according to the <a href="#generic-pathname-format">generic pathname format</a>
using <i>preferred-separator</i>. See [<a href="#Operating-system-examples">fs.os.examples</a>].</p>
<h3><a name="path-Requirements"><code>path</code> Requirements</a> [path.req]</h3>
<p>Template parameters named <code><a name="InputIterator">InputIterator</a></code> are required meet the
requirements for a C++ standard library <code>RandomIterator</code> compliant iterator. The iterator's value type is required to be <code>char</code>, <code>wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</p>
<p>Template parameters named <code><a name="InputIterator">InputIterator</a></code> are required to meet the
requirements for a C++ standard library <code>RandomIterator</code> compliant iterator. The iterator's value type is required
to be one of: <code>char</code>, <code>wchar_t</code>. Collectively, these types are referred to as supported character types.</p>
<p>Template parameters named <code><a name="Source">Source</a></code> are required to be one of:</p>
<ul>
<li>
<p>A container with a value type of <code>char</code>, <code>
wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li>
<p>A <code>std::basic_string</code> specialization with a value type of one of the supported character types.</li>
<li>
<p>An iterator for a null terminated byte-string. The value type is required
to be <code>char</code>, <code>wchar_t</code>, <code>char16_t</code>, or <code>
char32_t</code>.</li>
<p><b>v3, deprecated:</b> A container with a value type of one of the supported character types.</li>
<li>
<p>A C-array. The value type is required to be <code>char</code>, <code>
wchar_t</code>, <code>char16_t</code>, or <code>char32_t</code>.</li>
<p>A pointer into a null terminated string. The value type is required
to be a supported character type.</li>
<li>
<p>A C-array. The value type is required to be a supported character type.</li>
<li>
<p>A <code>boost::filesystem::directory_entry</code>.</li>
</ul>
@ -1327,7 +1327,7 @@ path(InputIterator begin, InputIterator end, const codecvt_type&amp; cvt=codecvt
<blockquote>
<p><i>Effects:</i> Stores the contents [<code>begin</code>,<code>end</code>)
or <code>source</code> in <code>pathname</code>, converting format and
of <code>source</code> in <code>pathname</code>, converting format and
encoding if required ([<a href="#path.arg.convert">path.arg.convert</a>]).</p>
</blockquote>
<h3> <a name="path-assignments"> <code>

View File

@ -41,6 +41,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>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>
<li>On Windows, fixed <code>weakly_canonical</code> failing with an <code>ERROR_INVALID_FUNCTION</code> error code if the path started with the "\\?\" prefix. (<a href="https://github.com/boostorg/filesystem/issues/247">#247</a>)</li>

View File

@ -52,10 +52,11 @@ It removes the features that were <a href="deprecated.html">deprecated</a> in Ve
<li><a href="reference.html#path-filename"><code>path::filename</code></a> and <a href="reference.html#path-iterators"><code>path::iterator</code></a> no longer return an implicit trailing dot (".") element if the path ends with a directory separator. Instead, an empty path is returned, similar to C++17 std::filesystem. This also affects other methods that are defined in terms of iterators or filename, such as <code>path::stem</code>, <code>path::compare</code> or <code>lexicographical_compare</code>. For example, <code>path("a/b/") == path("a/b/.")</code> no longer holds true.</li>
<li><a href="reference.html#lexically_normal"><code>path::lexically_normal</code></a> no longer produces a trailing dot (".") element and omits a directory separator after a trailing dot-dot ("..") element in the normalized paths.</li>
<li><a href="reference.html#path-appends"><code>path</code> appends</a> consider root name and root directory of the appended path. If the appended path is absolute, or root name is present and differs from the source path, the resulting path is equivalent to the appended path. If root directory is present, the result is the root directory and relative path rebased on top of the root name of the source path. Otherwise, the behavior is similar to v3. This behavior is similar to C++17 std::filesystem.</li>
<li><code>path</code> no longer supports construction, assignment or appending from containers of characters. Use string types or iterators as the source for these opereations instead.</li>
</ul>
<hr>
<p>&copy; Copyright Andrey Semashev, 2021</p>
<p>&copy; Copyright Andrey Semashev, 2021-2022</p>
<p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>

View File

@ -67,6 +67,54 @@
#error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
#endif
// Deprecated symbols markup -----------------------------------------------------------//
#if !defined(BOOST_FILESYSTEM_DEPRECATED)
#if !defined(BOOST_FILESYSTEM_DETAIL_DEPRECATED) && defined(_MSC_VER)
#if (_MSC_VER) >= 1400
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) __declspec(deprecated(msg))
#else
// MSVC 7.1 only supports the attribute without a message
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) __declspec(deprecated)
#endif
#endif
#if !defined(BOOST_FILESYSTEM_DETAIL_DEPRECATED) && defined(__has_extension)
#if __has_extension(attribute_deprecated_with_message)
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg)))
#endif
#endif
// gcc since 4.5 supports deprecated attribute with a message; older versions support the attribute without a message.
// Oracle Studio 12.4 supports deprecated attribute with a message; this is the first release that supports the attribute.
#if !defined(BOOST_FILESYSTEM_DETAIL_DEPRECATED) && (\
(defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 405) ||\
(defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5130))
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg)))
#endif
#if !defined(BOOST_FILESYSTEM_DETAIL_DEPRECATED) && __cplusplus >= 201402
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) [[deprecated(msg)]]
#endif
#if !defined(BOOST_FILESYSTEM_DETAIL_DEPRECATED) && defined(__GNUC__)
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) __attribute__((deprecated))
#endif
#if !defined(BOOST_FILESYSTEM_DETAIL_DEPRECATED) && defined(__has_attribute)
#if __has_attribute(deprecated)
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg) __attribute__((deprecated))
#endif
#endif
#endif // !defined(BOOST_FILESYSTEM_DEPRECATED)
#if !defined(BOOST_FILESYSTEM_DETAIL_DEPRECATED)
#define BOOST_FILESYSTEM_DETAIL_DEPRECATED(msg)
#endif
// This header implements separate compilation features as described in
// http://www.boost.org/more/separate_compilation.html

View File

@ -1,6 +1,7 @@
// 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
@ -11,18 +12,18 @@
#define BOOST_FILESYSTEM_PATH_TRAITS_HPP
#include <boost/filesystem/config.hpp>
#include <boost/system/error_category.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/core/enable_if.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 <iterator>
#include <locale>
#include <boost/assert.hpp>
#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
@ -90,29 +91,39 @@ struct is_pathable< std::wstring >
static const bool value = true;
};
#if BOOST_FILESYSTEM_VERSION < 4
template<>
struct is_pathable< std::vector< char > >
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 is_pathable< std::vector< wchar_t > >
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 is_pathable< std::list< char > >
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 is_pathable< std::list< wchar_t > >
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 >
@ -122,6 +133,7 @@ struct is_pathable< directory_entry >
// Pathable empty
#if BOOST_FILESYSTEM_VERSION < 4
template< class Container >
inline
// disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
@ -131,11 +143,12 @@ inline
{
return c.begin() == c.end();
}
#endif // BOOST_FILESYSTEM_VERSION < 4
template< class T >
inline bool empty(T* const& c_str)
{
BOOST_ASSERT(c_str);
BOOST_ASSERT(c_str != NULL);
return !*c_str;
}
@ -255,48 +268,57 @@ inline void convert(const wchar_t* from, std::wstring& to)
template< class U >
inline void dispatch(std::string const& c, U& to, codecvt_type const& cvt)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), to, 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)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), to, 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)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), 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)
{
if (!c.empty())
convert(&*c.begin(), &*c.begin() + c.size(), 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())
@ -305,6 +327,7 @@ inline void dispatch(std::vector< wchar_t > const& c, U& 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?)
@ -317,6 +340,7 @@ inline
convert(s.c_str(), s.c_str() + s.size(), to, cvt);
}
}
#endif // BOOST_FILESYSTEM_VERSION < 4
// c_str
template< class T, class U >
@ -339,8 +363,10 @@ void dispatch(directory_entry const& de,
#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?)
@ -353,13 +379,14 @@ inline
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);
BOOST_ASSERT(c_str != NULL);
convert(c_str, to);
}

View File

@ -16,6 +16,9 @@
#include <boost/filesystem.hpp>
#include <boost/filesystem/string_file.hpp>
#include <list>
#include <vector>
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_main.hpp>
@ -27,6 +30,11 @@ using boost::filesystem::path;
namespace {
std::string platform(BOOST_PLATFORM);
std::list< char > l; // see main() for initialization to s, t, r, i, n, g
std::list< wchar_t > wl; // see main() for initialization to w, s, t, r, i, n, g
std::vector< char > v; // see main() for initialization to f, u, z
std::vector< wchar_t > wv; // see main() for initialization to w, f, u, z
void check(const fs::path& source, const std::string& expected, int line)
{
if (source.generic_string() == expected)
@ -34,7 +42,7 @@ void check(const fs::path& source, const std::string& expected, int line)
++::boost::detail::test_errors();
std::cout << '(' << line << ") source.string(): \"" << source.string()
std::cout << __FILE__ << '(' << line << ") source.string(): \"" << source.string()
<< "\" != expected: \"" << expected
<< "\"" << std::endl;
}
@ -158,6 +166,29 @@ void misc_test()
p.directory_string();
}
// path_container_ctor_test ---------------------------------------------------------//
void path_container_ctor_test()
{
path x4v(v); // std::vector<char>
PATH_CHECK(x4v, "fuz");
BOOST_TEST_EQ(x4v.native().size(), 3U);
path x5v(wv); // std::vector<wchar_t>
PATH_CHECK(x5v, "wfuz");
BOOST_TEST_EQ(x5v.native().size(), 4U);
// non-contiguous containers
path x10(l); // std::list<char>
PATH_CHECK(x10, "string");
BOOST_TEST_EQ(x10.native().size(), 6U);
path xll(wl); // std::list<wchar_t>
PATH_CHECK(xll, "wstring");
BOOST_TEST_EQ(xll.native().size(), 7U);
}
// path_rename_test -----------------------------------------------------------------//
void path_rename_test()
@ -206,6 +237,30 @@ int cpp_main(int /*argc*/, char* /*argv*/[])
platform = (platform == "Win32" || platform == "Win64" || platform == "Cygwin") ? "Windows" : "POSIX";
std::cout << "Platform is " << platform << '\n';
l.push_back('s');
l.push_back('t');
l.push_back('r');
l.push_back('i');
l.push_back('n');
l.push_back('g');
wl.push_back(L'w');
wl.push_back(L's');
wl.push_back(L't');
wl.push_back(L'r');
wl.push_back(L'i');
wl.push_back(L'n');
wl.push_back(L'g');
v.push_back('f');
v.push_back('u');
v.push_back('z');
wv.push_back(L'w');
wv.push_back(L'f');
wv.push_back(L'u');
wv.push_back(L'z');
BOOST_TEST(fs::initial_path() == fs::current_path());
//path::default_name_check(fs::no_check);
@ -227,6 +282,7 @@ int cpp_main(int /*argc*/, char* /*argv*/[])
fs::create_directory(temp_dir);
misc_test();
path_container_ctor_test();
path_rename_test();
normalize_test();
string_file_tests(temp_dir);

View File

@ -46,6 +46,7 @@
#include <cstring>
#include <cwchar>
#include <locale>
#include <vector>
#include <list>
namespace fs = boost::filesystem;
@ -180,14 +181,6 @@ void test_constructors()
PATH_IS(x5, L"std::wstring");
BOOST_TEST_EQ(x5.native().size(), 12U);
path x4v(v); // std::vector<char>
PATH_IS(x4v, L"fuz");
BOOST_TEST_EQ(x4v.native().size(), 3U);
path x5v(wv); // std::vector<wchar_t>
PATH_IS(x5v, L"wfuz");
BOOST_TEST_EQ(x5v.native().size(), 4U);
path x6("array char"); // array char
PATH_IS(x6, L"array char");
BOOST_TEST_EQ(x6.native().size(), 10U);
@ -224,15 +217,6 @@ void test_constructors()
PATH_IS(x9nc, L"wstring");
BOOST_TEST_EQ(x9nc.native().size(), 7U);
// non-contiguous containers
path x10(l); // std::list<char>
PATH_IS(x10, L"string");
BOOST_TEST_EQ(x10.native().size(), 6U);
path xll(wl); // std::list<wchar_t>
PATH_IS(xll, L"wstring");
BOOST_TEST_EQ(xll.native().size(), 7U);
// easy-to-make coding errors
// path e1(x0, path::codecvt()); // fails to compile, and that is OK