From 79207756b3a07fec1ff18f842e21fc64a861ebf3 Mon Sep 17 00:00:00 2001 From: Beman Dawes Date: Sat, 3 Aug 2002 18:41:42 +0000 Subject: [PATCH] path begin, end return const iterator, force cr/nl [SVN r354] --- doc/path.htm | 11 ++-- include/boost/filesystem/path.hpp | 4 +- src/path_posix_windows.cpp | 2 +- test/path_test.cpp | 83 ++++++++++++++++--------------- 4 files changed, 53 insertions(+), 47 deletions(-) diff --git a/doc/path.htm b/doc/path.htm index 0f16aa0..21d252e 100644 --- a/doc/path.htm +++ b/doc/path.htm @@ -147,7 +147,10 @@ boost/filesystem/path.hpp synopsis

Rationale: The return type of several functions (operator<<, leaf, branch) is const path instead of path to disallow expressions like (p1<<p2) = p3.  See Scott Myers, Effective C++, - Item 21.

+ Item 21. Likewise, begin() and end() return const iterator + rather than iterator. This detects non-portable code such as ++pth.begin(), + which will not work if iterator is a non-class type. See next() + and prior() in boost/utility.hpp.

Member functions

For the sake of exposition, class path member functions are described as if the class contains a private member std::vector<std::string> m_name. @@ -262,8 +265,8 @@ the returned string is always unambiguous.

leaf

const std::string leaf() const;
-

Returns: is_null() ? string() : m_name.back()

-

Rationale: Return type is string rather than const +

Returns: is_null() ? std::string() : m_name.back()

+

Rationale: Return type is const string rather than const string & to give implementations freedom to avoid  maintaining the leaf as a separate string object.

@@ -309,7 +312,7 @@ likely to change.


© Copyright Beman Dawes, 2002

Revised -01 August, 2002

+02 August, 2002

diff --git a/include/boost/filesystem/path.hpp b/include/boost/filesystem/path.hpp index 35a88a9..38aac65 100644 --- a/include/boost/filesystem/path.hpp +++ b/include/boost/filesystem/path.hpp @@ -92,8 +92,8 @@ namespace boost std::ptrdiff_t > iterator; - iterator begin() const; - iterator end() const + const iterator begin() const; + const iterator end() const { iterator itr; itr.base().path_ptr = this; diff --git a/src/path_posix_windows.cpp b/src/path_posix_windows.cpp index 0f29a58..0489430 100644 --- a/src/path_posix_windows.cpp +++ b/src/path_posix_windows.cpp @@ -314,7 +314,7 @@ namespace boost } // while more elements } - path::iterator path::begin() const + const path::iterator path::begin() const { iterator itr; itr.base().path_ptr = this; diff --git a/test/path_test.cpp b/test/path_test.cpp index dadbedc..43ab751 100644 --- a/test/path_test.cpp +++ b/test/path_test.cpp @@ -10,11 +10,14 @@ #include #include +#include #include #include namespace fs = boost::filesystem; using boost::filesystem::path; +using boost::next; +using boost::prior; #define BOOST_INCLUDE_MAIN #include @@ -197,74 +200,74 @@ int test_main( int, char*[] ) itr_ck = path( "/", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "/" ) ); - BOOST_TEST( ++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( *--itr_ck.end() == std::string( "/" ) ); - BOOST_TEST( --itr_ck.end() == itr_ck.begin() ); + BOOST_TEST( next(itr_ck.begin()) == itr_ck.end() ); + BOOST_TEST( *next(itr_ck.end()) == std::string( "/" ) ); + BOOST_TEST( next(itr_ck.end()) == itr_ck.begin() ); itr_ck = path( "/foo", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "/" ) ); - BOOST_TEST( *++itr_ck.begin() == std::string( "foo" ) ); - BOOST_TEST( ++++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( ++itr_ck.begin() == --itr_ck.end() ); - BOOST_TEST( *--itr_ck.end() == std::string( "foo" ) ); - BOOST_TEST( *----itr_ck.end() == std::string( "/" ) ); - BOOST_TEST( ----itr_ck.end() == itr_ck.begin() ); + BOOST_TEST( *next( itr_ck.begin() ) == std::string( "foo" ) ); + BOOST_TEST( next(next( itr_ck.begin() )) == itr_ck.end() ); + BOOST_TEST( next( itr_ck.begin() ) == prior( itr_ck.end() ) ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); + BOOST_TEST( *prior(prior( itr_ck.end() )) == std::string( "/" ) ); + BOOST_TEST( prior(prior( itr_ck.end() )) == itr_ck.begin() ); itr_ck = "foo"; BOOST_TEST( *itr_ck.begin() == std::string( "foo" ) ); - BOOST_TEST( ++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( *--itr_ck.end() == std::string( "foo" ) ); - BOOST_TEST( --itr_ck.end() == itr_ck.begin() ); + BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); + BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); # ifdef BOOST_WINDOWS itr_ck = path( "c:", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "c:" ) ); - BOOST_TEST( ++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( --itr_ck.end() == itr_ck.begin() ); - BOOST_TEST( *--itr_ck.end() == std::string( "c:" ) ); + BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); + BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "c:" ) ); itr_ck = path( "c:/", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "c:/" ) ); - BOOST_TEST( ++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( --itr_ck.end() == itr_ck.begin() ); - BOOST_TEST( *--itr_ck.end() == std::string( "c:/" ) ); + BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); + BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "c:/" ) ); itr_ck = path( "c:foo", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "c:" ) ); - BOOST_TEST( *++itr_ck.begin() == std::string( "foo" ) ); - BOOST_TEST( ++++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( ----itr_ck.end() == itr_ck.begin() ); - BOOST_TEST( *--itr_ck.end() == std::string( "foo" ) ); - BOOST_TEST( *----itr_ck.end() == std::string( "c:" ) ); + BOOST_TEST( *next( itr_ck.begin() ) == std::string( "foo" ) ); + BOOST_TEST( next(next( itr_ck.begin() )) == itr_ck.end() ); + BOOST_TEST( prior(prior( itr_ck.end() )) == itr_ck.begin() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); + BOOST_TEST( *prior(prior( itr_ck.end() )) == std::string( "c:" ) ); itr_ck = path( "c:/foo", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "c:/" ) ); - BOOST_TEST( *++itr_ck.begin() == std::string( "foo" ) ); - BOOST_TEST( ++++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( ----itr_ck.end() == itr_ck.begin() ); - BOOST_TEST( *--itr_ck.end() == std::string( "foo" ) ); - BOOST_TEST( *----itr_ck.end() == std::string( "c:/" ) ); + BOOST_TEST( *next( itr_ck.begin() ) == std::string( "foo" ) ); + BOOST_TEST( next(next( itr_ck.begin() )) == itr_ck.end() ); + BOOST_TEST( prior(prior( itr_ck.end() )) == itr_ck.begin() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); + BOOST_TEST( *prior(prior( itr_ck.end() )) == std::string( "c:/" ) ); itr_ck = path( "//share", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "//share" ) ); - BOOST_TEST( ++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( --itr_ck.end() == itr_ck.begin() ); - BOOST_TEST( *--itr_ck.end() == std::string( "//share" ) ); + BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); + BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "//share" ) ); itr_ck = path( "//share/foo", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "//share" ) ); - BOOST_TEST( *++itr_ck.begin() == std::string( "foo" ) ); - BOOST_TEST( ++++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( ----itr_ck.end() == itr_ck.begin() ); - BOOST_TEST( *--itr_ck.end() == std::string( "foo" ) ); - BOOST_TEST( *----itr_ck.end() == std::string( "//share" ) ); + BOOST_TEST( *next( itr_ck.begin() ) == std::string( "foo" ) ); + BOOST_TEST( next(next( itr_ck.begin() )) == itr_ck.end() ); + BOOST_TEST( prior(prior( itr_ck.end() )) == itr_ck.begin() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "foo" ) ); + BOOST_TEST( *prior(prior( itr_ck.end() )) == std::string( "//share" ) ); itr_ck = path( "prn:", fs::system_specific ); BOOST_TEST( *itr_ck.begin() == std::string( "prn:" ) ); - BOOST_TEST( ++itr_ck.begin() == itr_ck.end() ); - BOOST_TEST( --itr_ck.end() == itr_ck.begin() ); - BOOST_TEST( *--itr_ck.end() == std::string( "prn:" ) ); + BOOST_TEST( next( itr_ck.begin() ) == itr_ck.end() ); + BOOST_TEST( prior( itr_ck.end() ) == itr_ck.begin() ); + BOOST_TEST( *prior( itr_ck.end() ) == std::string( "prn:" ) ); check( path( "/", fs::system_specific ), "/" ); check( path( "/f", fs::system_specific ), "/f" ); @@ -304,6 +307,6 @@ int test_main( int, char*[] ) # endif // BOOST_WINDOWS // std::cout << errors << " errors detected\n"; - + return errors; }