Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make boost::iostreams::detail::path constructible from std::filesystem::path #110

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions doc/classes/file_descriptor.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ <H4><CODE>file_descriptor_source::file_descriptor_source</CODE></H4>
</P>

<P>
The second member constructs a <CODE>file_descriptor_source</CODE> to access the file with the given pathname. <CODE>Path</CODE> should be either a string or a Boost.Filesystem path. The parameter <CODE>mode</CODE> has the same interpretation as <CODE>(mode | std::ios_base::in)</CODE> in <CODE>std::basic_filebuf::open</CODE>.<A CLASS="footnote_ref" NAME="note_1_ref" HREF="#note_1"><SUP>[1]</SUP></A>
The second member constructs a <CODE>file_descriptor_source</CODE> to access the file with the given pathname. <CODE>Path</CODE> should be either a string, a Boost.Filesystem path or a std::filesystem::path. The parameter <CODE>mode</CODE> has the same interpretation as <CODE>(mode | std::ios_base::in)</CODE> in <CODE>std::basic_filebuf::open</CODE>.<A CLASS="footnote_ref" NAME="note_1_ref" HREF="#note_1"><SUP>[1]</SUP></A>
</P>

<P>
Expand Down Expand Up @@ -308,7 +308,7 @@ <H4><CODE>file_descriptor_sink::file_descriptor_sink</CODE></H4>
</P>

<P>
The second member constructs a <CODE>file_descriptor_sink</CODE> to access the file with the given pathname. <CODE>Path</CODE> should be either a string or a Boost.Filesystem path. The parameter <CODE>mode</CODE> has the same interpretation as <CODE>(mode | std::ios_base::out)</CODE> in <CODE>std::basic_filebuf::open</CODE>.<A CLASS="footnote_ref" NAME="note_1_ref2" HREF="#note_1"><SUP>[1]</SUP></A>
The second member constructs a <CODE>file_descriptor_sink</CODE> to access the file with the given pathname. <CODE>Path</CODE> should be either a string, a Boost.Filesystem path or a std::filesystem::path. The parameter <CODE>mode</CODE> has the same interpretation as <CODE>(mode | std::ios_base::out)</CODE> in <CODE>std::basic_filebuf::open</CODE>.<A CLASS="footnote_ref" NAME="note_1_ref2" HREF="#note_1"><SUP>[1]</SUP></A>
</P>

<P>
Expand Down Expand Up @@ -448,7 +448,7 @@ <H4><CODE>file_descriptor::file_descriptor</CODE></H4>
</P>

<P>
The second member constructs a <CODE>file_descriptor</CODE> to access the file with the given pathname. <CODE>Path</CODE> should be either a string or a Boost.Filesystem path. The parameter <CODE>mode</CODE> has the same interpretation as in <CODE>std::basic_filebuf::open</CODE>.<A CLASS="footnote_ref" NAME="note_1_ref3" HREF="#note_1"><SUP>[1]</SUP></A>
The second member constructs a <CODE>file_descriptor</CODE> to access the file with the given pathname. <CODE>Path</CODE> should be either a string, a Boost.Filesystem path or a std::filesystem::path. The parameter <CODE>mode</CODE> has the same interpretation as in <CODE>std::basic_filebuf::open</CODE>.<A CLASS="footnote_ref" NAME="note_1_ref3" HREF="#note_1"><SUP>[1]</SUP></A>
</P>

<P>
Expand Down Expand Up @@ -526,4 +526,4 @@ <H4><CODE>file_descriptor::handle</CODE></H4>

<!-- End Footer -->

</BODY>
</BODY>
8 changes: 4 additions & 4 deletions include/boost/iostreams/detail/path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ class path {
init(p.external_file_string());
}

// Constructor taking a boost::filesystem3::path (boost filesystem v3)
// Constructor taking a boost::filesystem3::path or a std::filesystem::path
template<typename Path>
explicit path(const Path& p, typename Path::codecvt_type* = 0)
explicit path(const Path& p, typename Path::string_type* = 0)
{
init(p.native());
}
Expand Down Expand Up @@ -113,9 +113,9 @@ class path {
}
#endif

// Assignment operator taking a boost::filesystem3::path
// Assignment operator taking a boost::filesystem3::path or a std::filesystem::path
template<typename Path>
typename sfinae<typename Path::codecvt_type, path&>::type
typename sfinae<typename Path::string_type, path&>::type
operator=(const Path& p)
{
init(p.native());
Expand Down
14 changes: 13 additions & 1 deletion test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ rule compile-fail-iostreams ( sources * : requirements * : target-name ? ) {
] ;
}

lib stdc++fs ;
lib c++fs ;

exe can_use_stdcxxfs : checks/std_filesystem_libstdcxx.cpp stdc++fs ;
exe can_use_cxxfs : checks/std_filesystem_libcxx.cpp c++fs ;

explicit can_use_stdcxxfs ;
explicit can_use_cxxfs ;

local all-tests =
[ test-iostreams array_test.cpp ]
Expand Down Expand Up @@ -91,7 +99,11 @@ rule compile-fail-iostreams ( sources * : requirements * : target-name ? ) {
[ test-iostreams line_filter_test.cpp ]
[ test-iostreams mapped_file_test.cpp
../build//boost_iostreams ]
[ test-iostreams path_test.cpp ]
[ test-iostreams
path_test.cpp
: [ check-target-builds ../../config/checks//cpp_lib_filesystem
: [ check-target-builds can_use_stdcxxfs : <source>stdc++fs : [ check-target-builds can_use_cxxfs : <source>c++fs ] ]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

early gcc and clang versions requires to link specific filesystem library

<define>BOOST_IOSTREAMS_TEST_PATH_WITH_STD_FILESYSTEM ] ]
[ test-iostreams newline_test.cpp ]
[ test-iostreams null_test.cpp ]
[ test-iostreams operation_sequence_test.cpp ]
Expand Down
14 changes: 14 additions & 0 deletions test/checks/std_filesystem_libcxx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright John Doe 2020.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)

#include <filesystem>

#ifndef _LIBCPP_VERSION
#error libc++ expected
#endif

int main()
{
std::filesystem::create_directory(std::filesystem::path("/tmp/cpp_lib_filesystem_link"));
}
14 changes: 14 additions & 0 deletions test/checks/std_filesystem_libstdcxx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright John Doe 2020.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)

#include <filesystem>

#ifndef __GLIBCXX__
#error libstdc++ expected
#endif

int main()
{
std::filesystem::create_directory(std::filesystem::path("/tmp/cpp_lib_filesystem_link"));
}
65 changes: 57 additions & 8 deletions test/path_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,70 @@
// See http://www.boost.org/libs/iostreams for documentation.

#include <boost/iostreams/detail/path.hpp>
#include <boost/filesystem/path.hpp>

#include <boost/core/enable_if.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/mpl/list.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>

void path_test()
#ifdef BOOST_IOSTREAMS_TEST_PATH_WITH_STD_FILESYSTEM
#include <filesystem>
#endif

template <typename Path>
void check_path_invariant(
Path const& original_path,
boost::iostreams::detail::path const& path,
typename boost::enable_if<typename boost::is_same<typename Path::string_type::value_type, char>, void*>::type = NULL)
{
boost::filesystem::path orig("a/b");
boost::iostreams::detail::path p(orig);
p = orig;
BOOST_CHECK(!path.is_wide());
BOOST_CHECK(original_path.native() == path.c_str());
BOOST_CHECK(std::wstring() == path.c_wstr());
}

boost::unit_test::test_suite* init_unit_test_suite(int, char* [])
template <typename Path>
void check_path_invariant(
Path const& original_path,
boost::iostreams::detail::path const& path,
typename boost::enable_if<typename boost::is_same<typename Path::string_type::value_type, wchar_t>, void*>::type = NULL)
{
BOOST_CHECK(path.is_wide());
BOOST_CHECK(original_path.native() == path.c_wstr());
BOOST_CHECK(std::string() == path.c_str());
}

BOOST_TEST_CASE_TEMPLATE_FUNCTION(construct_from_std_filesystem_path_test, Path)
{
Path const original_path("abc");

boost::iostreams::detail::path const path(original_path);

check_path_invariant(original_path, path);
}

BOOST_TEST_CASE_TEMPLATE_FUNCTION(assign_std_filesystem_path_test, Path)
{
Path const original_path("abc");

boost::iostreams::detail::path path;
path = original_path;

check_path_invariant(original_path, path);
}

typedef boost::mpl::list<
boost::filesystem::path
#ifdef BOOST_IOSTREAMS_TEST_PATH_WITH_STD_FILESYSTEM
, std::filesystem::path
#endif
> path_types;

boost::unit_test::test_suite* init_unit_test_suite(int, char* [])
{
boost::unit_test::test_suite* test = BOOST_TEST_SUITE("mapped_file test");
test->add(BOOST_TEST_CASE(&path_test));
boost::unit_test::test_suite* test = BOOST_TEST_SUITE("path test");
test->add(BOOST_TEST_CASE_TEMPLATE(construct_from_std_filesystem_path_test, path_types));
test->add(BOOST_TEST_CASE_TEMPLATE(assign_std_filesystem_path_test, path_types));
return test;
}