diff --git a/include/boost/filesystem/path.hpp b/include/boost/filesystem/path.hpp index f7cb94d..8f5eaa0 100644 --- a/include/boost/filesystem/path.hpp +++ b/include/boost/filesystem/path.hpp @@ -399,42 +399,57 @@ namespace boost lhs.begin(), lhs.end(), tmp.begin(), tmp.end() ); } - // operator == uses string compare rather than !(lhs < rhs) && !(rhs < lhs) because - // the result is the same yet the direct string compare is much more efficient that - // lexicographical_compare, and lexicographical_compare used twice at that. + // operator == uses hand-written compare rather than !(lhs < rhs) && !(rhs < lhs) + // because the result is the same yet the direct compare is much more efficient + // than lexicographical_compare, which would also be called twice. template< class String, class Traits > - inline bool operator==( const basic_path & lhs, const basic_path & rhs ) + inline bool operator==( const basic_path & lhs, + const typename basic_path::string_type::value_type * rhs ) + { + typedef typename + boost::BOOST_FILESYSTEM_NAMESPACE::basic_path path_type; + const typename path_type::string_type::value_type * l (lhs.string().c_str()); + while ( (*l == *rhs +# ifdef BOOST_WINDOWS_PATH + || (*l == path_alt_separator::value && *rhs == slash::value) + || (*l == slash::value && *rhs == path_alt_separator::value) +# endif + ) && *l ) { ++l; ++rhs; } + return *l == *rhs +# ifdef BOOST_WINDOWS_PATH + || (*l == path_alt_separator::value && *rhs == slash::value) + || (*l == slash::value && *rhs == path_alt_separator::value) +# endif + ; + } + + template< class String, class Traits > + inline bool operator==( const basic_path & lhs, + const basic_path & rhs ) { - return lhs.string() == rhs.string(); + return lhs == rhs.string().c_str(); } template< class String, class Traits > inline bool operator==( const typename basic_path::string_type::value_type * lhs, const basic_path & rhs ) { - return lhs == rhs.string(); + return rhs == lhs; } template< class String, class Traits > inline bool operator==( const typename basic_path::string_type & lhs, const basic_path & rhs ) { - return lhs == rhs.string(); - } - - template< class String, class Traits > - inline bool operator==( const basic_path & lhs, - const typename basic_path::string_type::value_type * rhs ) - { - return lhs.string() == rhs; + return rhs == lhs.c_str(); } template< class String, class Traits > inline bool operator==( const basic_path & lhs, const typename basic_path::string_type & rhs ) { - return lhs.string() == rhs; + return lhs == rhs.c_str(); } template< class String, class Traits > diff --git a/src/operations.cpp b/src/operations.cpp index 383e6f3..d0655b9 100644 --- a/src/operations.cpp +++ b/src/operations.cpp @@ -1282,7 +1282,7 @@ namespace boost target = std::string( "." ); // string was static but caused trouble // when iteration called from dtor, after // static had already been destroyed - std::size_t path_size; + std::size_t path_size (0); // initialization quiets gcc warning error_code ec = path_max( path_size ); if ( ec ) return ec; dirent de; diff --git a/test/path_test.cpp b/test/path_test.cpp index bcf1caa..cff0817 100644 --- a/test/path_test.cpp +++ b/test/path_test.cpp @@ -226,6 +226,27 @@ int main( int, char*[] ) p4 = p4; // self-assignment BOOST_TEST( p4.string() == "foobar" ); + if ( platform == "Windows" ) + { + path p10 ("c:\\file"); + path p11 ("c:/file"); + // check each overload + BOOST_TEST( p10.string() == p11.string() ); + BOOST_TEST( p10 == p11 ); + BOOST_TEST( p10 == p11.string() ); + BOOST_TEST( p10 == p11.string().c_str() ); + BOOST_TEST( p10.string() == p11 ); + BOOST_TEST( p10.string().c_str() == p11 ); + BOOST_TEST( p10 == "c:\\file" ); + BOOST_TEST( p10 == "c:/file" ); + BOOST_TEST( p11 == "c:\\file" ); + BOOST_TEST( p11 == "c:/file" ); + BOOST_TEST( "c:\\file" == p10 ); + BOOST_TEST( "c:/file" == p10 ); + BOOST_TEST( "c:\\file" == p11 ); + BOOST_TEST( "c:/file" == p11 ); + } + exception_tests(); name_function_tests();