$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r50731 - in sandbox/filesystem-v3: boost/filesystem libs/filesystem/src libs/filesystem/test
From: bdawes_at_[hidden]
Date: 2009-01-22 14:19:11
Author: bemandawes
Date: 2009-01-22 14:19:10 EST (Thu, 22 Jan 2009)
New Revision: 50731
URL: http://svn.boost.org/trac/boost/changeset/50731
Log:
Filesystem.v3: work-in-progress; remove excessively aggressive path conversions, start operator== rework to use simple string comparison
Text files modified: 
   sandbox/filesystem-v3/boost/filesystem/path.hpp                     |    53 ++++++++++++++++++++++-------------     
   sandbox/filesystem-v3/libs/filesystem/src/operations.cpp            |     4 +-                                      
   sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp      |     4 ++                                      
   sandbox/filesystem-v3/libs/filesystem/test/operations_unit_test.cpp |     2                                         
   sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp       |    60 +++------------------------------------ 
   5 files changed, 44 insertions(+), 79 deletions(-)
Modified: sandbox/filesystem-v3/boost/filesystem/path.hpp
==============================================================================
--- sandbox/filesystem-v3/boost/filesystem/path.hpp	(original)
+++ sandbox/filesystem-v3/boost/filesystem/path.hpp	2009-01-22 14:19:10 EST (Thu, 22 Jan 2009)
@@ -502,21 +502,6 @@
 
     path & remove_filename();
 
-    //  -----  conversion operators  -----
-
-    //  return formatted "as input"
-
-    operator const string_type&() const  { return m_path; }
-    operator const detail::interface_string_type() const
-    { 
-      return detail::convert_to_string( m_path, boost::throws() );
-    }
-
-# ifdef BOOST_FILESYSTEM_CPP0X_CHAR_TYPES
-    operator const std::u16string() const { return detail::convert_to_u16string( m_path, boost::throws() ); }
-    operator const std::u32string() const { return detail::convert_to_u32string( m_path, boost::throws() ); }
-# endif
-
     //  -----  observers  -----
   
     //  For operating systems that format file paths differently than directory
@@ -553,7 +538,8 @@
 #   ifdef BOOST_WINDOWS_PATH
 
     //  return value is formatted as indicated by function name
-    const path  native() const;
+    const path  native() const;    // all separators converted to preferred separator;
+                                   // thus on Windows slashes are converted to backslashes
     const path  generic() const;
 
 #   else // BOOST_POSIX_PATH
@@ -564,7 +550,9 @@
 
 #   endif
 
-    const value_type *  c_str() const { return m_path.c_str(); }  // native format
+    //  native format c_str(), suitable for passing to native OS API calls;
+    //  on Windows, slashes and backslashes are exactly as input
+    const value_type *   c_str() const         { return m_path.c_str(); }
 
     //  -----  decomposition  -----
 
@@ -622,7 +610,8 @@
     //  characters; POSIX just treats paths as a sequence of bytes. Windows
     //  encoding is UCS-2 or UTF-16 depending on the version.
 
-    string_type  m_path;  // Windows: backslashes NOT converted to slashes
+    string_type  m_path;  // Windows: as input; backslashes NOT converted to slashes,
+                          // slashes NOT converted to backslashes
 
     //  These helpers factor out common code and convert iterators to pointers.
     template< class InputIterator >
@@ -735,12 +724,36 @@
       lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );
   }
 
-  inline bool operator==( const path & lhs, const path & rhs ) { return !(lhs < rhs) && !(rhs < lhs); }
-  inline bool operator!=( const path & lhs, const path & rhs ) { return !(lhs == rhs); }
   inline bool operator<=( const path & lhs, const path & rhs ) { return !(rhs < lhs); }
   inline bool operator> ( const path & lhs, const path & rhs ) { return rhs < lhs; }
   inline bool operator>=( const path & lhs, const path & rhs ) { return !(lhs < rhs);  }
 
+  // operator==() efficiency is a concern; a user reported the original version 2
+  // !(lhs < rhs) && !(rhs < lhs) implementation caused a serious performance problem
+  // for a map of 10,000 paths.
+# ifdef BOOST_WINDOWS_API
+  inline bool operator==( const path & lhs, const path::value_type * rhs )
+  {
+    const path::value_type * l(lhs.c_str());
+    while ( (*l == *rhs || (*l == L'\\' && *rhs == L'/') || (*l == L'/' && *rhs == L'\\'))
+      && *l ) { ++l; ++rhs; }
+    return *l == *rhs || (*l == L'\\' && *rhs == L'/') || (*l == L'/' && *rhs == L'\\');  
+  }
+  inline bool operator==( const path & lhs, const path & rhs ) { return lhs == rhs.c_str(); }
+  inline bool operator==( const path & lhs, const path::string_type & rhs ) { return lhs == rhs.c_str(); }
+  inline bool operator==( const path::string_type & lhs, const path & rhs ) { return rhs == lhs; }
+  inline bool operator==( const path::value_type * lhs, const path & rhs )  { return rhs == lhs; }
+# else   // BOOST_POSIX_API
+  inline bool operator==( const path & lhs, const path & rhs ) { return lhs.native_string() == rhs.native_string(); }
+  inline bool operator==( const path & lhs, const path::string_type & rhs ) { return lhs.native_string() == rhs; }
+  inline bool operator==( const path & lhs, const path::value_type * rhs )  { return lhs.native_string() == rhs; }
+  inline bool operator==( const path::string_type & lhs, const path & rhs ) { return lhs == rhs.native_string(); }
+  inline bool operator==( const path::value_type * lhs, const path & rhs )  { return lhs == rhs.native_string(); }
+# endif
+
+
+  inline bool operator!=( const path & lhs, const path & rhs ) { return !(lhs == rhs); }
+
   inline void swap( path & lhs, path & rhs )                   { lhs.swap( rhs ); }
 
   inline path operator/( const path & lhs, const path & rhs )  { return path( lhs ) /= rhs; }
Modified: sandbox/filesystem-v3/libs/filesystem/src/operations.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/src/operations.cpp	(original)
+++ sandbox/filesystem-v3/libs/filesystem/src/operations.cpp	2009-01-22 14:19:10 EST (Thu, 22 Jan 2009)
@@ -1298,14 +1298,14 @@
 {
 # ifdef BOOST_WINDOWS_API
 
-  error_code dir_itr_first( void *& handle, const wstring & dir,
+  error_code dir_itr_first( void *& handle, const path & dir,
     wstring & target, fs::file_status & sf, fs::file_status & symlink_sf )
   // Note: an empty root directory has no "." or ".." entries, so this
   // causes a ERROR_FILE_NOT_FOUND error which we do not considered an
   // error. It is treated as eof instead.
   {
     // use a form of search Sebastian Martel reports will work with Win98
-    wstring dirpath( dir );
+    wstring dirpath( dir.wstring() );
     dirpath += (dirpath.empty()
       || (dirpath[dirpath.size()-1] != L'\\'
         && dirpath[dirpath.size()-1] != L'/'
Modified: sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp	(original)
+++ sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp	2009-01-22 14:19:10 EST (Thu, 22 Jan 2009)
@@ -757,7 +757,9 @@
     == fs::current_path().string() );
 
   BOOST_CHECK( fs::complete( "" ).empty() );
-  BOOST_CHECK( fs::complete( "/" ) == fs::initial_path().root_path() );
+  fs::path px1 = fs::complete( "/" );
+  fs::path px2 = fs::initial_path().root_path();
+  BOOST_CHECK( px1 == px2 );
   BOOST_CHECK( fs::complete( "foo" ) == fs::initial_path().string()+"/foo" );
   BOOST_CHECK( fs::complete( "/foo" ) == fs::initial_path().root_path().string()+"foo" );
   BOOST_CHECK( fs::complete( "foo", fs::path( "//net/bar" ) )
Modified: sandbox/filesystem-v3/libs/filesystem/test/operations_unit_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/operations_unit_test.cpp	(original)
+++ sandbox/filesystem-v3/libs/filesystem/test/operations_unit_test.cpp	2009-01-22 14:19:10 EST (Thu, 22 Jan 2009)
@@ -78,7 +78,7 @@
 
     directory_iterator it( "." );
 
-//    CHECK( !it->path().empty() );
+    CHECK( !it->path().empty() );
 
     if ( is_regular_file( it->status() ) )
     {
Modified: sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp	(original)
+++ sandbox/filesystem-v3/libs/filesystem/test/path_unit_test.cpp	2009-01-22 14:19:10 EST (Thu, 22 Jan 2009)
@@ -111,9 +111,7 @@
   path x;
   path y;
   string s("string iterators");
-# ifndef BOOST_FILESYSTEM_NARROW_ONLY
   wstring ws(L"wstring iterators");
-# endif  // narrow only
 
   //  test_constructors  ---------------------------------------------------------------//
 
@@ -156,57 +154,6 @@
     PATH_IS(x11, L"std::wstring");
   }
 
-  //  test_use_cases  ------------------------------------------------------------------//
-
-  string use( const path & p ) { return p; }
-
-  void test_use_cases()
-  {
-    std::cout << "testing use cases..." << std::endl;
-
-    CHECK( use("foo") == "foo" );
-    CHECK( use(string("foo")) == "foo" );
-    CHECK( "foo" == use("foo") );
-    CHECK( "foo" == use(string("foo")) );
-
-# ifndef BOOST_FILESYSTEM_NARROW_ONLY
-    CHECK( use(L"foo") == "foo" );
-    CHECK( use(wstring(L"foo")) == "foo" );
-    CHECK( "foo" == use(L"foo") );
-    CHECK( "foo" == use(wstring(L"foo")) );
-# endif
-  }
-
-  //  test_conversion_operators  -------------------------------------------------------//
-
-  void test_conversion_operators()
-  {
-    std::cout << "testing test_conversion_operators..." << std::endl;
-
-    path p( "foo" );
-
-    string s1( p );
-    CHECK( s1 == "foo" );
-
-    string s2 = p;
-    CHECK( s2 == "foo" );
-
-    s2.clear();
-    s2 = p;
-    CHECK( s2 == "foo" );
-
-    wstring ws1( p );
-    CHECK( ws1 == L"foo" );
-
-    wstring ws2 = p;
-    CHECK( ws2 == L"foo" );
-
-    ws2.clear();
-    ws2 = p;
-    CHECK( ws2 == L"foo" );
-
-  }
-
   //  test_assignments  ----------------------------------------------------------------//
 
   void test_assignments()
@@ -310,6 +257,11 @@
   {
     std::cout << "testing relationals..." << std::endl;
 
+# ifdef BOOST_WINDOWS_API
+    // this is a critical use case to meet user expectations
+    CHECK( path( "c:\\abc" ) == path( "c:/abc" ) );
+# endif
+
     const path p( "bar" );
     const path p2( "baz" );
 
@@ -640,8 +592,6 @@
 int main( int, char*[] )
 {
   test_constructors();
-  test_use_cases();
-  test_conversion_operators();
   test_assignments();
   test_observers();
   ////test_appends();