diff --git a/doc/faq.htm b/doc/faq.htm index 525b4ac..343663e 100644 --- a/doc/faq.htm +++ b/doc/faq.htm @@ -9,9 +9,8 @@ FAQ since URI's extend far beyond what most operating systems consider a file or a directory.  Thus for the primary "portable script-style file system operations" requirement of the Filesystem Library, full URI's appear to be over-specification.

-

Why base the generic-path string format on POSIX?
-
-
POSIX is the basis for the most familiar path-string formats, including the +

Why base the generic-path string format on POSIX?

+

POSIX is the basis for the most familiar path-string formats, including the URL portion of URI's and the native Windows format. It is ubiquitous and familiar.  On many systems, it is very easy to implement because it is either the native operating system format (Unix and Windows) or via a @@ -23,6 +22,14 @@ POSIX library (z/OS, OS/390, and many more.)

Several early versions did require users to identify each path as a file or directory path, and this seemed to increase errors and decrease code readability. There was no apparent upside benefit.

+

Why do some path member function names have a "system_specific_" prefix?

+

To alert users that the results are inherently non-portable. The names are +deliberately ugly to discourage use except where really necessary.

+

Why doesn't path supply operator== and other comparison operators?

+

There is no way to know if two path objects actually represent the +same path.  For example, path("/foo") and path("../foo") may +represent the same path, even though they are textually different. +path::string()'s can be used for textual comparison.

Why not support a concept of specific kinds file systems, such as posix_file_system or windows_file_system.

Portability is one of the one or two most important requirements for the @@ -153,10 +160,7 @@ conditions for error are very different between the source and the target.

detection were evaluated, including at least four complete implementations.  While the details for rejection differed, they all tended to distort the otherwise simple design of the rest of the library.

-

Why do some path member function names have a "system_specific_" prefix?

-

To alert users that the results are inherently non-portable. The names are -deliberately ugly to discourage use except where really necessary.


© Copyright Beman Dawes, 2002

Revised -20 November, 2002

\ No newline at end of file +26 November, 2002

\ No newline at end of file diff --git a/doc/path.htm b/doc/path.htm index 4da9960..0a5888d 100644 --- a/doc/path.htm +++ b/doc/path.htm @@ -179,11 +179,11 @@ ensure names in paths are as portable as desired, but they must be explicitly called by the user.

Naming Rationale: Class path member function names and operations.hpp non-member -function names are chosen to be distinct from one another. Otherwise, given a -path foo, for example, both foo.empty() and empty( foo ) -would be valid, but with completely different semantics. Avoiding this was -considered more important than consistency with some C++ Standard Library naming -conventions, which aren't followed uniformly anyhow, even in the standard.

+function names were chosen to be somewhat distinct from one another. The +objective was to avoid both foo.empty() and empty( foo ) being +valid, but with completely different semantics. At one point path::empty() +was renamed path::is_null(), but that caused many coding typos because +std::string::empty() is often used nearby.

System-specific Representation

Several path non-member functions return representations of m_name in formats specific to the operating system. These formats are implementation @@ -603,7 +603,7 @@ efficient, and less error prone.


© Copyright Beman Dawes, 2002

Revised -24 November, 2002

+26 November, 2002

diff --git a/include/boost/filesystem/operations.hpp b/include/boost/filesystem/operations.hpp index dc23182..d1ed66b 100644 --- a/include/boost/filesystem/operations.hpp +++ b/include/boost/filesystem/operations.hpp @@ -74,6 +74,7 @@ namespace boost namespace detail { const char * implementation_name(); // helps testing to know name + bool single_rooted_filesystem(); } // directory_iterator ------------------------------------------------------// diff --git a/include/boost/filesystem/path.hpp b/include/boost/filesystem/path.hpp index 2d4271a..31218ec 100644 --- a/include/boost/filesystem/path.hpp +++ b/include/boost/filesystem/path.hpp @@ -76,15 +76,17 @@ namespace boost path branch_path() const; // query functions: - bool is_null() const { return m_path.size() == 0; } - bool is_absolute() const; + bool empty() const { return m_path.empty(); } // name consistent with std containers -/* - bool has_root_path() const; + bool is_complete() const; // has_root_directory [&& has_system_specific_root()] + + bool has_root_path() const; // has_system_specific_root() || has_root_directory() bool has_system_specific_root() const; bool has_root_directory() const; bool has_relative_path() const; -*/ + bool has_leaf() const { return !m_path.empty(); } + bool has_branch_path() const; + const std::string & string() const { return m_path; } std::string system_specific_file_string() const; diff --git a/src/operations_posix_windows.cpp b/src/operations_posix_windows.cpp index 08472bc..db4d2b9 100644 --- a/src/operations_posix_windows.cpp +++ b/src/operations_posix_windows.cpp @@ -112,6 +112,7 @@ namespace BOOST_HANDLE & handle, BOOST_SYSTEM_DIRECTORY_TYPE & data ) // Returns: 0 if error, otherwise name { +// std::cout << "find_first_file " << dir << std::endl; std::string dirpath( std::string(dir) + "/*" ); return ( (handle = ::FindFirstFileA( dirpath.c_str(), &data )) == BOOST_INVALID_HANDLE_VALUE ) ? 0 : data.cFileName; @@ -119,6 +120,7 @@ namespace inline void find_close( BOOST_HANDLE handle ) { +// std::cout << "find_close" << std::endl; assert( handle != BOOST_INVALID_HANDLE_VALUE ); ::FindClose( handle ); } @@ -174,8 +176,10 @@ namespace boost { #ifdef BOOST_POSIX const char * implementation_name() { return "POSIX"; } + bool single_rooted_filesystem() { return true; } #else const char * implementation_name() { return "Windows"; } + bool single_rooted_filesystem() { return false; } #endif } // namespace detail @@ -204,7 +208,7 @@ namespace boost m_imp.reset( new dir_itr_imp ); BOOST_SYSTEM_DIRECTORY_TYPE scratch; const char * name; - if ( dir_path.is_null() ) + if ( dir_path.empty() ) m_imp->handle = BOOST_INVALID_HANDLE_VALUE; else name = find_first_file( dir_path.system_specific_directory_string().c_str(), @@ -423,7 +427,7 @@ namespace boost const path & initial_path() { static path init_path; - if ( init_path.is_null() ) init_path = current_path(); + if ( init_path.empty() ) init_path = current_path(); return init_path; } diff --git a/src/path_posix_windows.cpp b/src/path_posix_windows.cpp index 39aa9b8..8b24c6f 100644 --- a/src/path_posix_windows.cpp +++ b/src/path_posix_windows.cpp @@ -167,7 +167,7 @@ namespace boost && name.find_first_not_of( valid_boost_directory ) == std::string::npos; } - // path implementation -------------------------------------------------// +// path implementation -----------------------------------------------------// path::path( const std::string & src ) { @@ -269,7 +269,7 @@ namespace boost { // append '/' if needed - if ( !is_null() + if ( !empty() && *(m_path.end()-1) != ':' && *(m_path.end()-1) != '/' ) m_path += '/'; @@ -343,6 +343,8 @@ namespace boost } // while more elements } +// path decomposition functions ---------------------------------------------// + path::iterator path::begin() const { iterator itr; @@ -358,6 +360,24 @@ namespace boost m_path += new_leaf; } +/* + path & path::make_absolute( const path & root_source ) + { + assert( root_source.is_absolute() ); + if ( !is_absolute() ) + { + path tmp( root_source.root_path() ); + tmp /= relative_path(); + operator=( tmp ); + } + return *this; + } + + path & path::make_absolute() + { + return make_absolute( initial_path() ); + } +*/ std::string path::leaf() const { return m_path.substr( leaf_pos( m_path, m_path.size() ) ); @@ -397,20 +417,6 @@ namespace boost return path( m_path.substr( 0, end_pos ), system_specific ); } - bool path::is_absolute() const - { - return ( m_path.size() - && m_path[0] == '/' ) // covers both "/" and "//share" -# ifdef BOOST_WINDOWS - || ( m_path.size() > 2 - && m_path[1] == ':' - && m_path[2] == '/' ) // "c:/" - || ( m_path.size() > 3 - && m_path[m_path.size()-1] == ':' ) // "device:" -# endif - ; - } - path path::relative_path() const { std::string::size_type pos( 0 ); @@ -468,7 +474,73 @@ namespace boost # endif } - namespace detail +// path query functions -----------------------------------------------------// + + bool path::is_complete() const + { +# ifdef BOOST_WINDOWS + return m_path.size() > 2 + && ( (m_path[1] == ':' && m_path[2] == '/') // "c:/" + || (m_path[0] == '/' && m_path[1] == '/') // "//share" + || m_path[m_path.size()-1] == ':' ); +# else + return m_path.size() && m_path[0] == '/'; +# endif + + + return ( m_path.size() + && m_path[0] == '/' ) // covers both "/" and "//share" +# ifdef BOOST_WINDOWS + || ( m_path.size() > 1 && m_path[1] == ':' ) // "c:" and "c:/" + || ( m_path.size() > 3 + && m_path[m_path.size()-1] == ':' ) // "device:" +# endif + ; + } + + bool path::has_root_path() const + { + return ( m_path.size() + && m_path[0] == '/' ) // covers both "/" and "//share" +# ifdef BOOST_WINDOWS + || ( m_path.size() > 1 && m_path[1] == ':' ) // "c:" and "c:/" + || ( m_path.size() > 3 + && m_path[m_path.size()-1] == ':' ) // "device:" +# endif + ; + } + + bool path::has_system_specific_root() const + { +# ifdef BOOST_WINDOWS + return m_path.size() > 1 + && ( m_path[1] == ':' // "c:" + || m_path[m_path.size()-1] == ':' // "prn:" + || (m_path[0] == '/' && m_path[1] == '/') // "//share" + ); +# else + return false; +# endif + } + + bool path::has_root_directory() const + { + return ( m_path.size() + && m_path[0] == '/' ) // covers both "/" and "//share" +# ifdef BOOST_WINDOWS + || ( m_path.size() > 2 + && m_path[1] == ':' && m_path[2] == '/' ) // "c:/" +# endif + ; + } + + bool path::has_relative_path() const { return !relative_path().empty(); } + bool path::has_branch_path() const { return !branch_path().empty(); } + + +// path_itr_imp implementation ----------------------------------------------// + + namespace detail { void path_itr_imp::operator++() { diff --git a/test/operations_test.cpp b/test/operations_test.cpp index 412877f..6c4fec3 100644 --- a/test/operations_test.cpp +++ b/test/operations_test.cpp @@ -75,6 +75,10 @@ int test_main( int, char * [] ) << fs::initial_path().system_specific_file_string() << "\"\n"; + BOOST_TEST( fs::initial_path().is_complete() ); + BOOST_TEST( fs::current_path().is_complete() ); + BOOST_TEST( fs::initial_path().string() == fs::current_path().string() ); + fs::path dir( fs::initial_path() / "temp_fs_test_directory" ); if ( std::strcmp( fs::detail::implementation_name(), "Windows" ) == 0 ) @@ -125,14 +129,26 @@ int test_main( int, char * [] ) BOOST_TEST( dir_itr->leaf() == "d1" || dir_itr->leaf() == "d2" ); if ( dir_itr->leaf() == "d1" ) { - // Thomas Witt suggested the ++ to verify a compiler problem workaround -// BOOST_TEST( (++fs::directory_iterator(dir))->leaf() == "d2" ); - ++dir_itr; + BOOST_TEST( (++dir_itr)->leaf() == "d2" ); + } + else + { + BOOST_TEST( (++dir_itr)->leaf() == "d1" ); + } + } + + { // *i++ must work to meet the standard's InputIterator requirements + fs::directory_iterator dir_itr( dir ); + BOOST_TEST( dir_itr->leaf() == "d1" || dir_itr->leaf() == "d2" ); + if ( dir_itr->leaf() == "d1" ) + { + BOOST_TEST( (*dir_itr++).leaf() == "d1" ); BOOST_TEST( dir_itr->leaf() == "d2" ); } else { - BOOST_TEST( (++fs::directory_iterator(dir))->leaf() == "d1" ); + BOOST_TEST( (*dir_itr++).leaf() == "d2" ); + BOOST_TEST( dir_itr->leaf() == "d1" ); } } diff --git a/test/path_test.cpp b/test/path_test.cpp index 3bdb8a0..e29751e 100644 --- a/test/path_test.cpp +++ b/test/path_test.cpp @@ -64,6 +64,7 @@ int test_main( int, char*[] ) path p1( "fe/fi/fo/fum" ); path p2( p1 ); path p3; + BOOST_TEST( p1.string() != p3.string() ); p3 = p2; // p1.branch_path() = p2; // should fail @@ -83,8 +84,8 @@ int test_main( int, char*[] ) BOOST_TEST( path( "foo" ).branch_path().string() == "" ); BOOST_TEST( p1.leaf() == "fum" ); BOOST_TEST( p1.branch_path().string() == "fe/fi/fo" ); - BOOST_TEST( path( "" ).is_null() == true ); - BOOST_TEST( path( "foo" ).is_null() == false ); + BOOST_TEST( path( "" ).empty() == true ); + BOOST_TEST( path( "foo" ).empty() == false ); PATH_CHECK( "", "" ); @@ -233,40 +234,97 @@ int test_main( int, char*[] ) BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); - BOOST_TEST( path( "/" ).relative_path().string() == "" ); - BOOST_TEST( path( "/" ).branch_path().string() == "" ); - BOOST_TEST( path( "/" ).leaf() == "/" ); - BOOST_TEST( path( "/" ).system_specific_root() == "" ); - BOOST_TEST( path( "/" ).root_directory() == "/" ); - BOOST_TEST( path( "/" ).root_path().string() == "/" ); + path p; - BOOST_TEST( path( "foo" ).relative_path().string() == "foo" ); - BOOST_TEST( path( "foo" ).branch_path().string() == "" ); - BOOST_TEST( path( "foo" ).leaf() == "foo" ); - BOOST_TEST( path( "foo" ).system_specific_root() == "" ); - BOOST_TEST( path( "foo" ).root_directory() == "" ); - BOOST_TEST( path( "foo" ).root_path().string() == "" ); + p = ""; + BOOST_TEST( p.relative_path().string() == "" ); + BOOST_TEST( p.branch_path().string() == "" ); + BOOST_TEST( p.leaf() == "" ); + BOOST_TEST( p.system_specific_root() == "" ); + BOOST_TEST( p.root_directory() == "" ); + BOOST_TEST( p.root_path().string() == "" ); + BOOST_TEST( !p.has_root_path() ); + BOOST_TEST( !p.has_system_specific_root() ); + BOOST_TEST( !p.has_root_directory() ); + BOOST_TEST( !p.has_relative_path() ); + BOOST_TEST( !p.has_leaf() ); + BOOST_TEST( !p.has_branch_path() ); + BOOST_TEST( !p.is_complete() ); - BOOST_TEST( path( "/foo" ).relative_path().string() == "foo" ); - BOOST_TEST( path( "/foo" ).branch_path().string() == "/" ); - BOOST_TEST( path( "/foo" ).leaf() == "foo" ); - BOOST_TEST( path( "/foo" ).system_specific_root() == "" ); - BOOST_TEST( path( "/foo" ).root_directory() == "/" ); - BOOST_TEST( path( "/foo" ).root_path().string() == "/" ); + p = "/"; + BOOST_TEST( p.relative_path().string() == "" ); + BOOST_TEST( p.branch_path().string() == "" ); + BOOST_TEST( p.leaf() == "/" ); + BOOST_TEST( p.system_specific_root() == "" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( !p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( !p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( !p.has_branch_path() ); + BOOST_TEST( fs::detail::single_rooted_filesystem() == p.is_complete() ); - BOOST_TEST( path( "foo/bar" ).relative_path().string() == "foo/bar" ); - BOOST_TEST( path( "foo/bar" ).branch_path().string() == "foo" ); - BOOST_TEST( path( "foo/bar" ).leaf() == "bar" ); - BOOST_TEST( path( "foo/bar" ).system_specific_root() == "" ); - BOOST_TEST( path( "foo/bar" ).root_directory() == "" ); - BOOST_TEST( path( "foo/bar" ).root_path().string() == "" ); + p = "foo"; + BOOST_TEST( p.relative_path().string() == "foo" ); + BOOST_TEST( p.branch_path().string() == "" ); + BOOST_TEST( p.leaf() == "foo" ); + BOOST_TEST( p.system_specific_root() == "" ); + BOOST_TEST( p.root_directory() == "" ); + BOOST_TEST( p.root_path().string() == "" ); + BOOST_TEST( !p.has_root_path() ); + BOOST_TEST( !p.has_system_specific_root() ); + BOOST_TEST( !p.has_root_directory() ); + BOOST_TEST( p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( !p.has_branch_path() ); + BOOST_TEST( !p.is_complete() ); - BOOST_TEST( path( "/foo/bar" ).relative_path().string() == "foo/bar" ); - BOOST_TEST( path( "/foo/bar" ).branch_path().string() == "/foo" ); - BOOST_TEST( path( "/foo/bar" ).leaf() == "bar" ); - BOOST_TEST( path( "/foo/bar" ).system_specific_root() == "" ); - BOOST_TEST( path( "/foo/bar" ).root_directory() == "/" ); - BOOST_TEST( path( "/foo/bar" ).root_path().string() == "/" ); + p = "/foo"; + BOOST_TEST( p.relative_path().string() == "foo" ); + BOOST_TEST( p.branch_path().string() == "/" ); + BOOST_TEST( p.leaf() == "foo" ); + BOOST_TEST( p.system_specific_root() == "" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( !p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( fs::detail::single_rooted_filesystem() == p.is_complete() ); + + p = "foo/bar"; + BOOST_TEST( p.relative_path().string() == "foo/bar" ); + BOOST_TEST( p.branch_path().string() == "foo" ); + BOOST_TEST( p.leaf() == "bar" ); + BOOST_TEST( p.system_specific_root() == "" ); + BOOST_TEST( p.root_directory() == "" ); + BOOST_TEST( p.root_path().string() == "" ); + BOOST_TEST( !p.has_root_path() ); + BOOST_TEST( !p.has_system_specific_root() ); + BOOST_TEST( !p.has_root_directory() ); + BOOST_TEST( p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( !p.is_complete() ); + + p = "/foo/bar"; + BOOST_TEST( p.relative_path().string() == "foo/bar" ); + BOOST_TEST( p.branch_path().string() == "/foo" ); + BOOST_TEST( p.leaf() == "bar" ); + BOOST_TEST( p.system_specific_root() == "" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( !p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( fs::detail::single_rooted_filesystem() == p.is_complete() ); if ( std::strcmp( fs::detail::implementation_name(), "Windows" ) == 0 ) { @@ -288,61 +346,125 @@ int test_main( int, char*[] ) PATH_CHECK( path( "c:/foo", fs::system_specific ), "c:/foo" ); PATH_CHECK( path( "prn:", fs::system_specific ), "prn:" ); - BOOST_TEST( path( "c:", fs::system_specific ).relative_path().string() == "" ); - BOOST_TEST( path( "c:", fs::system_specific ).branch_path().string() == "" ); - BOOST_TEST( path( "c:", fs::system_specific ).leaf() == "c:" ); - BOOST_TEST( path( "c:", fs::system_specific ).system_specific_root() == "c:" ); - BOOST_TEST( path( "c:", fs::system_specific ).root_directory() == "" ); - BOOST_TEST( path( "c:", fs::system_specific ).root_path().string() == "c:" ); + p = path( "c:", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "" ); + BOOST_TEST( p.branch_path().string() == "" ); + BOOST_TEST( p.leaf() == "c:" ); + BOOST_TEST( p.system_specific_root() == "c:" ); + BOOST_TEST( p.root_directory() == "" ); + BOOST_TEST( p.root_path().string() == "c:" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( !p.has_root_directory() ); + BOOST_TEST( !p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( !p.has_branch_path() ); + BOOST_TEST( !p.is_complete() ); - BOOST_TEST( path( "c:foo", fs::system_specific ).relative_path().string() == "foo" ); - BOOST_TEST( path( "c:foo", fs::system_specific ).branch_path().string() == "c:" ); - BOOST_TEST( path( "c:foo", fs::system_specific ).leaf() == "foo" ); - BOOST_TEST( path( "c:foo", fs::system_specific ).system_specific_root() == "c:" ); - BOOST_TEST( path( "c:foo", fs::system_specific ).root_directory() == "" ); - BOOST_TEST( path( "c:foo", fs::system_specific ).root_path().string() == "c:" ); + p = path( "c:foo", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "foo" ); + BOOST_TEST( p.branch_path().string() == "c:" ); + BOOST_TEST( p.leaf() == "foo" ); + BOOST_TEST( p.system_specific_root() == "c:" ); + BOOST_TEST( p.root_directory() == "" ); + BOOST_TEST( p.root_path().string() == "c:" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( !p.has_root_directory() ); + BOOST_TEST( p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( !p.is_complete() ); + + p = path( "c:/", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "" ); + BOOST_TEST( p.branch_path().string() == "c:" ); + BOOST_TEST( p.leaf() == "/" ); + BOOST_TEST( p.system_specific_root() == "c:" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "c:/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( !p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( p.is_complete() ); - BOOST_TEST( path( "c:/", fs::system_specific ).relative_path().string() == "" ); - BOOST_TEST( path( "c:/", fs::system_specific ).branch_path().string() == "c:" ); - BOOST_TEST( path( "c:/", fs::system_specific ).leaf() == "/" ); - BOOST_TEST( path( "c:/", fs::system_specific ).system_specific_root() == "c:" ); - BOOST_TEST( path( "c:/", fs::system_specific ).root_directory() == "/" ); - BOOST_TEST( path( "c:/", fs::system_specific ).root_path().string() == "c:/" ); + p = path( "c:/foo", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "foo" ); + BOOST_TEST( p.branch_path().string() == "c:/" ); + BOOST_TEST( p.leaf() == "foo" ); + BOOST_TEST( p.system_specific_root() == "c:" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "c:/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( p.is_complete() ); - BOOST_TEST( path( "c:/foo", fs::system_specific ).relative_path().string() == "foo" ); - BOOST_TEST( path( "c:/foo", fs::system_specific ).branch_path().string() == "c:/" ); - BOOST_TEST( path( "c:/foo", fs::system_specific ).leaf() == "foo" ); - BOOST_TEST( path( "c:/foo", fs::system_specific ).system_specific_root() == "c:" ); - BOOST_TEST( path( "c:/foo", fs::system_specific ).root_directory() == "/" ); - BOOST_TEST( path( "c:/foo", fs::system_specific ).root_path().string() == "c:/" ); + p = path( "//share", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "" ); + BOOST_TEST( p.branch_path().string() == "" ); + BOOST_TEST( p.leaf() == "//share" ); + BOOST_TEST( p.system_specific_root() == "//share" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "//share/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( !p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( p.is_complete() ); - BOOST_TEST( path( "//share", fs::system_specific ).relative_path().string() == "" ); - BOOST_TEST( path( "//share", fs::system_specific ).branch_path().string() == "" ); - BOOST_TEST( path( "//share", fs::system_specific ).leaf() == "//share" ); - BOOST_TEST( path( "//share", fs::system_specific ).system_specific_root() == "//share" ); - BOOST_TEST( path( "//share", fs::system_specific ).root_directory() == "/" ); - BOOST_TEST( path( "//share", fs::system_specific ).root_path().string() == "//share/" ); + p = path( "//share/", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "" ); + BOOST_TEST( p.branch_path().string() == "//share" ); + BOOST_TEST( p.leaf() == "/" ); + BOOST_TEST( p.system_specific_root() == "//share" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "//share/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( !p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( p.is_complete() ); - BOOST_TEST( path( "//share/", fs::system_specific ).relative_path().string() == "" ); - BOOST_TEST( path( "//share/", fs::system_specific ).branch_path().string() == "//share" ); - BOOST_TEST( path( "//share/", fs::system_specific ).leaf() == "/" ); - BOOST_TEST( path( "//share/", fs::system_specific ).system_specific_root() == "//share" ); - BOOST_TEST( path( "//share/", fs::system_specific ).root_directory() == "/" ); - BOOST_TEST( path( "//share/", fs::system_specific ).root_path().string() == "//share/" ); + p = path( "//share/foo", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "foo" ); + BOOST_TEST( p.branch_path().string() == "//share/" ); + BOOST_TEST( p.leaf() == "foo" ); + BOOST_TEST( p.system_specific_root() == "//share" ); + BOOST_TEST( p.root_directory() == "/" ); + BOOST_TEST( p.root_path().string() == "//share/" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( p.has_root_directory() ); + BOOST_TEST( p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( p.has_branch_path() ); + BOOST_TEST( p.is_complete() ); - BOOST_TEST( path( "//share/foo", fs::system_specific ).relative_path().string() == "foo" ); - BOOST_TEST( path( "//share/foo", fs::system_specific ).branch_path().string() == "//share/" ); - BOOST_TEST( path( "//share/foo", fs::system_specific ).leaf() == "foo" ); - BOOST_TEST( path( "//share/foo", fs::system_specific ).system_specific_root() == "//share" ); - BOOST_TEST( path( "//share/foo", fs::system_specific ).root_directory() == "/" ); - BOOST_TEST( path( "//share/foo", fs::system_specific ).root_path().string() == "//share/" ); - - BOOST_TEST( path( "prn:", fs::system_specific ).relative_path().string() == "" ); - BOOST_TEST( path( "prn:", fs::system_specific ).branch_path().string() == "" ); - BOOST_TEST( path( "prn:", fs::system_specific ).leaf() == "prn:" ); - BOOST_TEST( path( "prn:", fs::system_specific ).system_specific_root() == "prn:" ); - BOOST_TEST( path( "prn:", fs::system_specific ).root_directory() == "" ); - BOOST_TEST( path( "prn:", fs::system_specific ).root_path().string() == "prn:" ); + p = path( "prn:", fs::system_specific ); + BOOST_TEST( p.relative_path().string() == "" ); + BOOST_TEST( p.branch_path().string() == "" ); + BOOST_TEST( p.leaf() == "prn:" ); + BOOST_TEST( p.system_specific_root() == "prn:" ); + BOOST_TEST( p.root_directory() == "" ); + BOOST_TEST( p.root_path().string() == "prn:" ); + BOOST_TEST( p.has_root_path() ); + BOOST_TEST( p.has_system_specific_root() ); + BOOST_TEST( !p.has_root_directory() ); + BOOST_TEST( !p.has_relative_path() ); + BOOST_TEST( p.has_leaf() ); + BOOST_TEST( !p.has_branch_path() ); + BOOST_TEST( p.is_complete() ); itr_ck = path( "c:", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "c:" ) );