diff --git a/doc/deprecated.html b/doc/deprecated.html index 6852a31..43b4cec 100644 --- a/doc/deprecated.html +++ b/doc/deprecated.html @@ -215,6 +215,16 @@ BOOST_FILESYSTEM_NO_DEPRECATED is defined.

remove_filename() + + + class path + +

Construction, assignment and appending from container types. + + ✔ + +

Use string types or iterators as the source for path construction, assignment and appending. + path.hpp diff --git a/doc/reference.html b/doc/reference.html index 84f3038..d0dc691 100644 --- a/doc/reference.html +++ b/doc/reference.html @@ -1275,7 +1275,7 @@ always be able to distinguish between native format and generic format arguments This is by design as it simplifies use for operating systems that do not require disambiguation. Should an implementation encounter an operating system where disambiguation is required, an implementation can defined -an extension to distinguish between the formats. +an extension to distinguish between the formats. —end note]

@@ -1288,7 +1288,7 @@ otherwise it shall be treated as a regular file path.

path argument encoding conversions [path.arg.encoding.cvt]

For member function arguments that take character sequences representing -paths, if the value type of the argument is not value_type and one +paths, if the value type of the argument is not value_type and one of the value types is char and the other is wchar_t, conversion to value_type shall be performed by the path::codecvt() facet. ([path.imbued.locale]).

path Conversions @@ -1297,20 +1297,20 @@ to generic format [fs.cvt.to.generic]

shall return strings formatted according to the generic pathname format using preferred-separator. See [fs.os.examples].

path Requirements [path.req]

-

Template parameters named InputIterator are required meet the -requirements for a C++ standard library RandomIterator compliant iterator. The iterator's value type is required to be char, wchar_t, char16_t, or char32_t.

+

Template parameters named InputIterator are required to meet the +requirements for a C++ standard library RandomIterator compliant iterator. The iterator's value type is required +to be one of: char, wchar_t. Collectively, these types are referred to as supported character types.

Template parameters named Source are required to be one of:

@@ -1327,7 +1327,7 @@ path(InputIterator begin, InputIterator end, const codecvt_type& cvt=codecvt

Effects: Stores the contents [begin,end) - or source in pathname, converting format and + of source in pathname, converting format and encoding if required ([path.arg.convert]).

diff --git a/doc/release_history.html b/doc/release_history.html index 8b9ac56..0edab3e 100644 --- a/doc/release_history.html +++ b/doc/release_history.html @@ -41,6 +41,7 @@

1.81.0


-

© Copyright Andrey Semashev, 2021

+

© Copyright Andrey Semashev, 2021-2022

Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt

diff --git a/include/boost/filesystem/config.hpp b/include/boost/filesystem/config.hpp index 68d0557..0eced92 100644 --- a/include/boost/filesystem/config.hpp +++ b/include/boost/filesystem/config.hpp @@ -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 diff --git a/include/boost/filesystem/path_traits.hpp b/include/boost/filesystem/path_traits.hpp index e4f9b52..1c90ed2 100644 --- a/include/boost/filesystem/path_traits.hpp +++ b/include/boost/filesystem/path_traits.hpp @@ -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 -#include -#include -#include -#include #include #include // for mbstate_t +#include #include +#include +#include +#if BOOST_FILESYSTEM_VERSION < 4 #include #include -#include -#include -#include +#include +#include +#endif #include // 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); } diff --git a/test/deprecated_test.cpp b/test/deprecated_test.cpp index afc1494..6ed3b2d 100644 --- a/test/deprecated_test.cpp +++ b/test/deprecated_test.cpp @@ -16,6 +16,9 @@ #include #include +#include +#include + #include #include @@ -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 + PATH_CHECK(x4v, "fuz"); + BOOST_TEST_EQ(x4v.native().size(), 3U); + + path x5v(wv); // std::vector + PATH_CHECK(x5v, "wfuz"); + BOOST_TEST_EQ(x5v.native().size(), 4U); + + // non-contiguous containers + path x10(l); // std::list + PATH_CHECK(x10, "string"); + BOOST_TEST_EQ(x10.native().size(), 6U); + + path xll(wl); // std::list + 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); diff --git a/test/path_unit_test.cpp b/test/path_unit_test.cpp index 09d69da..81bd7ee 100644 --- a/test/path_unit_test.cpp +++ b/test/path_unit_test.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include 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 - PATH_IS(x4v, L"fuz"); - BOOST_TEST_EQ(x4v.native().size(), 3U); - - path x5v(wv); // std::vector - 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 - PATH_IS(x10, L"string"); - BOOST_TEST_EQ(x10.native().size(), 6U); - - path xll(wl); // std::list - 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