$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r57868 - in sandbox/filesystem-v3: boost/filesystem libs/filesystem/doc libs/filesystem/example libs/filesystem/src libs/filesystem/test
From: bdawes_at_[hidden]
Date: 2009-11-23 11:48:53
Author: bemandawes
Date: 2009-11-23 11:48:52 EST (Mon, 23 Nov 2009)
New Revision: 57868
URL: http://svn.boost.org/trac/boost/changeset/57868
Log:
Refactor recursive_directory_iterator, and apply error reporting idiom.
Text files modified: 
   sandbox/filesystem-v3/boost/filesystem/convenience.hpp         |   156 ----------------------------            
   sandbox/filesystem-v3/boost/filesystem/operations.hpp          |   218 +++++++++++++++++++++++++++++++++++++-- 
   sandbox/filesystem-v3/libs/filesystem/doc/reference.html       |   172 +++++++++++++++++++++++++------         
   sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp   |    72 ++++++++++--                            
   sandbox/filesystem-v3/libs/filesystem/src/operations.cpp       |    29 +++--                                   
   sandbox/filesystem-v3/libs/filesystem/test/operations_test.cpp |    15 ++                                      
   6 files changed, 433 insertions(+), 229 deletions(-)
Modified: sandbox/filesystem-v3/boost/filesystem/convenience.hpp
==============================================================================
--- sandbox/filesystem-v3/boost/filesystem/convenience.hpp	(original)
+++ sandbox/filesystem-v3/boost/filesystem/convenience.hpp	2009-11-23 11:48:52 EST (Mon, 23 Nov 2009)
@@ -15,8 +15,6 @@
 
 #include <boost/filesystem/operations.hpp>
 #include <boost/system/error_code.hpp>
-#include <vector>
-#include <stack>
 
 #include <boost/config/abi_prefix.hpp> // must be the last #include
 
@@ -47,160 +45,6 @@
 # endif
 
 
-    //  basic_recursive_directory_iterator helpers  --------------------------//
-
-    namespace detail
-    {
-      struct recur_dir_itr_imp
-      {
-        typedef directory_iterator element_type;
-        std::stack< element_type, std::vector< element_type > > m_stack;
-        int  m_level;
-        bool m_no_push;
-        bool m_no_throw;
-
-        recur_dir_itr_imp() : m_level(0), m_no_push(false), m_no_throw(false) {}
-      };
-
-    } // namespace detail
-
-    //  recursive_directory_iterator  ----------------------------------------//
-
-    class recursive_directory_iterator
-      : public boost::iterator_facade<
-          recursive_directory_iterator,
-          directory_entry,
-          boost::single_pass_traversal_tag >
-    {
-    public:
-
-      recursive_directory_iterator(){}  // creates the "end" iterator
-
-      explicit recursive_directory_iterator( const path & dir_path )
-        : m_imp( new detail::recur_dir_itr_imp )
-      {
-        m_imp->m_stack.push( directory_iterator( dir_path ) );
-        if ( m_imp->m_stack.top () == directory_iterator() )
-          { m_imp.reset (); }
-      }
-
-      recursive_directory_iterator( const path & dir_path,
-        system::error_code & ec )
-      : m_imp( new detail::recur_dir_itr_imp )
-      {
-        m_imp->m_no_throw = true;
-        m_imp->m_stack.push( directory_iterator( dir_path, ec ) );
-        if ( m_imp->m_stack.top () == directory_iterator() )
-          { m_imp.reset (); }
-      }
-
-      int level() const { return m_imp->m_level; }
-
-      void pop();
-      void no_push()
-      {
-        BOOST_ASSERT( m_imp.get() && "no_push() on end recursive_directory_iterator" );
-        m_imp->m_no_push = true;
-      }
-
-      file_status status() const
-      {
-        BOOST_ASSERT( m_imp.get()
-          && "status() on end recursive_directory_iterator" );
-        return m_imp->m_stack.top()->status();
-      }
-
-      file_status symlink_status() const
-      {
-        BOOST_ASSERT( m_imp.get()
-          && "symlink_status() on end recursive_directory_iterator" );
-        return m_imp->m_stack.top()->symlink_status();
-      }
-
-    private:
-
-      // shared_ptr provides shallow-copy semantics required for InputIterators.
-      // m_imp.get()==0 indicates the end iterator.
-      boost::shared_ptr< detail::recur_dir_itr_imp >  m_imp;
-
-      friend class boost::iterator_core_access;
-
-      boost::iterator_facade< 
-        recursive_directory_iterator,
-        directory_entry,
-        boost::single_pass_traversal_tag >::reference
-      dereference() const 
-      {
-        BOOST_ASSERT( m_imp.get() && "dereference end recursive_directory_iterator" );
-        return *m_imp->m_stack.top();
-      }
-
-      void increment();
-
-      bool equal( const recursive_directory_iterator & rhs ) const
-        { return m_imp == rhs.m_imp; }
-
-    };
-
-# if  !defined(BOOST_FILESYSTEM_NARROW_ONLY) && !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
-    typedef recursive_directory_iterator wrecursive_directory_iterator;
-# endif
-
-    //  basic_recursive_directory_iterator implementation  -------------------//
-
-    //  increment
-    inline void recursive_directory_iterator::increment()
-    {
-      BOOST_ASSERT( m_imp.get() && "increment end recursive_directory_iterator" );
-      
-      static const directory_iterator end_itr;
-
-      if ( m_imp->m_no_push )
-        { m_imp->m_no_push = false; }
-      else if ( is_directory( m_imp->m_stack.top()->status() ) )
-      {
-        system::error_code ec;
-        m_imp->m_stack.push(
-          m_imp->m_no_throw
-            ? directory_iterator( m_imp->m_stack.top()->path(), ec )
-            : directory_iterator( m_imp->m_stack.top()->path() ) );
-        if ( m_imp->m_stack.top() != end_itr )
-        {
-          ++m_imp->m_level;
-          return;
-        }
-        m_imp->m_stack.pop();
-      }
-
-      while ( !m_imp->m_stack.empty()
-        && ++m_imp->m_stack.top() == end_itr )
-      {
-        m_imp->m_stack.pop();
-        --m_imp->m_level;
-      }
-
-      if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator
-    }
-
-    //  pop
-    inline void recursive_directory_iterator::pop()
-    {
-      BOOST_ASSERT( m_imp.get() && "pop end recursive_directory_iterator" );
-      BOOST_ASSERT( m_imp->m_level > 0 && "pop recursive_directory_iterator with level < 1" );
-
-      static const directory_iterator end_itr;
-
-      do
-      {
-        m_imp->m_stack.pop();
-        --m_imp->m_level;
-      }
-      while ( !m_imp->m_stack.empty()
-        && ++m_imp->m_stack.top() == end_itr );
-
-      if ( m_imp->m_stack.empty() ) m_imp.reset(); // done, so make end iterator
-    }
-
   } // namespace filesystem
 } // namespace boost
 
Modified: sandbox/filesystem-v3/boost/filesystem/operations.hpp
==============================================================================
--- sandbox/filesystem-v3/boost/filesystem/operations.hpp	(original)
+++ sandbox/filesystem-v3/boost/filesystem/operations.hpp	2009-11-23 11:48:52 EST (Mon, 23 Nov 2009)
@@ -46,6 +46,8 @@
 #include <string>
 #include <utility> // for pair
 #include <ctime>
+#include <vector>
+#include <stack>
 
 #ifdef BOOST_WINDOWS_API
 #  include <fstream>
@@ -543,13 +545,13 @@
 #     endif
   ); 
 
-  struct BOOST_FILESYSTEM_DECL dir_itr_imp
+  struct dir_itr_imp
   {
     directory_entry  dir_entry;
-    void *           handle;
+    void*            handle;
 
 #   ifdef BOOST_POSIX_API
-      void *           buffer;  // see dir_itr_increment implementation
+      void*            buffer;  // see dir_itr_increment implementation
 #   endif
 
     dir_itr_imp() : handle(0)
@@ -569,9 +571,10 @@
   };
 
   // see path::iterator: comment below
-  BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator & it,
-    const path& p, system::error_code * ec);
-  BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator & it);
+  BOOST_FILESYSTEM_DECL void directory_iterator_construct(directory_iterator& it,
+    const path& p, system::error_code* ec);
+  BOOST_FILESYSTEM_DECL void directory_iterator_increment(directory_iterator& it,
+    system::error_code* ec);
 
 }  // namespace detail
 
@@ -600,13 +603,20 @@
         : m_imp(new detail::dir_itr_imp)
           { detail::directory_iterator_construct(*this, p, &ec); }
 
-    ~directory_iterator() {} // never throws
+   ~directory_iterator() {} // never throws
+
+    directory_iterator& increment(system::error_code& ec)
+    { 
+      detail::directory_iterator_increment(*this, &ec);
+      return *this;
+    }
 
   private:
     friend struct detail::dir_itr_imp;
-    friend void detail::directory_iterator_construct(directory_iterator & it,
-      const path& p, system::error_code * ec);
-    friend void detail::directory_iterator_increment(directory_iterator & it);
+    friend void detail::directory_iterator_construct(directory_iterator& it,
+      const path& p, system::error_code* ec);
+    friend void detail::directory_iterator_increment(directory_iterator& it,
+      system::error_code* ec);
 
     // shared_ptr provides shallow-copy semantics required for InputIterators.
     // m_imp.get()==0 indicates the end iterator.
@@ -623,14 +633,198 @@
       return m_imp->dir_entry;
     }
 
-    void increment() { detail::directory_iterator_increment(*this); }
+    void increment() { detail::directory_iterator_increment(*this, 0); }
 
-    bool equal(const directory_iterator & rhs) const
+    bool equal(const directory_iterator& rhs) const
       { return m_imp == rhs.m_imp; }
   };
 
 //--------------------------------------------------------------------------------------//
 //                                                                                      //
+//                      recursive_directory_iterator helpers                            //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+  namespace detail
+  {
+    struct recur_dir_itr_imp
+    {
+      typedef directory_iterator element_type;
+      std::stack< element_type, std::vector< element_type > > m_stack;
+      int  m_level;
+      bool m_no_push_request;
+
+      recur_dir_itr_imp() : m_level(0), m_no_push_request(false) {}
+
+      void increment(system::error_code* ec);  // ec == 0 means throw on error
+
+      void pop();
+
+    };
+
+    //  Implementation is inline to avoid dynamic linking difficulties with m_stack:
+    //  Microsoft warning C4251, m_stack needs to have dll-interface to be used by
+    //  clients of struct 'boost::filesystem::detail::recur_dir_itr_imp'
+
+    inline
+    void recur_dir_itr_imp::increment(system::error_code* ec)
+    // ec == 0 means throw on error
+    {
+      if (m_no_push_request)
+        { m_no_push_request = false; }
+      else if (is_directory(m_stack.top()->status()))
+      {
+        if (ec == 0)
+          m_stack.push(directory_iterator(m_stack.top()->path()));
+        else
+        {
+          m_stack.push(directory_iterator(m_stack.top()->path(), *ec));
+          if (*ec) return;
+        }
+        if (m_stack.top() != directory_iterator())
+        {
+          ++m_level;
+          return;
+        }
+        m_stack.pop();
+      }
+
+      while (!m_stack.empty() && ++m_stack.top() == directory_iterator())
+      {
+        m_stack.pop();
+        --m_level;
+      }
+    }
+
+    inline
+    void recur_dir_itr_imp::pop()
+    {
+      BOOST_ASSERT(m_level > 0 && "pop() on recursive_directory_iterator with level < 1");
+
+      do
+      {
+        m_stack.pop();
+        --m_level;
+      }
+      while (!m_stack.empty() && ++m_stack.top() == directory_iterator());
+    }
+  } // namespace detail
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
+//                           recursive_directory_iterator                               //
+//                                                                                      //
+//--------------------------------------------------------------------------------------//
+
+  class recursive_directory_iterator
+    : public boost::iterator_facade<
+        recursive_directory_iterator,
+        directory_entry,
+        boost::single_pass_traversal_tag >
+  {
+  public:
+
+    recursive_directory_iterator(){}  // creates the "end" iterator
+
+    explicit recursive_directory_iterator(const path& dir_path)
+      : m_imp(new detail::recur_dir_itr_imp)
+    {
+      m_imp->m_stack.push(directory_iterator(dir_path));
+      if (m_imp->m_stack.top() == directory_iterator())
+        { m_imp.reset (); }
+    }
+
+    recursive_directory_iterator(const path& dir_path,
+      system::error_code & ec)
+    : m_imp(new detail::recur_dir_itr_imp)
+    {
+      m_imp->m_stack.push(directory_iterator(dir_path, ec));
+      if (m_imp->m_stack.top() == directory_iterator())
+        { m_imp.reset (); }
+    }
+
+    recursive_directory_iterator& increment(system::error_code* ec)
+    {
+      BOOST_ASSERT(m_imp.get() && "increment() on end recursive_directory_iterator");
+      m_imp->increment(ec);
+      return *this;
+    }
+
+    int level() const
+    { 
+      BOOST_ASSERT(m_imp.get() && "level() on end recursive_directory_iterator");
+      return m_imp->m_level;
+    }
+
+    bool no_push_request() const
+    {
+      BOOST_ASSERT(m_imp.get() && "no_push_request() on end recursive_directory_iterator");
+      return m_imp->m_no_push_request;
+    }
+
+    void pop()
+    { 
+      BOOST_ASSERT(m_imp.get() && "pop() on end recursive_directory_iterator");
+      m_imp->pop();
+      if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator
+    }
+
+    void no_push()
+    {
+      BOOST_ASSERT(m_imp.get() && "no_push() on end recursive_directory_iterator");
+      m_imp->m_no_push_request = true;
+    }
+
+    file_status status() const
+    {
+      BOOST_ASSERT(m_imp.get()
+        && "status() on end recursive_directory_iterator");
+      return m_imp->m_stack.top()->status();
+    }
+
+    file_status symlink_status() const
+    {
+      BOOST_ASSERT(m_imp.get()
+        && "symlink_status() on end recursive_directory_iterator");
+      return m_imp->m_stack.top()->symlink_status();
+    }
+
+  private:
+
+    // shared_ptr provides shallow-copy semantics required for InputIterators.
+    // m_imp.get()==0 indicates the end iterator.
+    boost::shared_ptr< detail::recur_dir_itr_imp >  m_imp;
+
+    friend class boost::iterator_core_access;
+
+    boost::iterator_facade< 
+      recursive_directory_iterator,
+      directory_entry,
+      boost::single_pass_traversal_tag >::reference
+    dereference() const 
+    {
+      BOOST_ASSERT(m_imp.get() && "dereference of end recursive_directory_iterator");
+      return *m_imp->m_stack.top();
+    }
+
+    void increment()
+    { 
+      BOOST_ASSERT(m_imp.get() && "increment of end recursive_directory_iterator");
+      m_imp->increment(0);
+      if (m_imp->m_stack.empty()) m_imp.reset(); // done, so make end iterator
+    }
+
+    bool equal(const recursive_directory_iterator& rhs) const
+      { return m_imp == rhs.m_imp; }
+
+  };
+
+# if !defined(BOOST_FILESYSTEM_NO_DEPRECATED)
+    typedef recursive_directory_iterator wrecursive_directory_iterator;
+# endif
+
+//--------------------------------------------------------------------------------------//
+//                                                                                      //
 //                            class filesystem_error                                    //
 //                                                                                      //
 //--------------------------------------------------------------------------------------//
Modified: sandbox/filesystem-v3/libs/filesystem/doc/reference.html
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/doc/reference.html	(original)
+++ sandbox/filesystem-v3/libs/filesystem/doc/reference.html	2009-11-23 11:48:52 EST (Mon, 23 Nov 2009)
@@ -74,9 +74,8 @@
     directory_entry observers<br>
     directory_entry comparisons<br>
 <a href="#Class-directory_iterator">Class  directory_iterator</a><br>
-   
-<a href="#directory_iterator-constructors">directory_iterator 
-    constructors</a><br>
+    <a href="#directory_iterator-members">directory_iterator 
+    members</a><br>
 <a href="#Class-recursive_directory_iterator">Class recursive_directory_iterator</a><br>
     <a href="#file_status">Class 
     file_status</a><br>
@@ -418,7 +417,7 @@
         typedef std::basic_string<value_type> string_type;
         typedef path_traits::codecvt_type     codecvt_type;
 
-        // constructors
+        // constructors and destructor
         path();
         path(const path& p);
 
@@ -428,6 +427,8 @@
         template <class Source>
           path(Source const& source);
 
+       ~path();
+
         // assignments
         path& operator=(const path& p);
 
@@ -1291,11 +1292,17 @@
       class basic_filesystem_error : public <span style="background-color: #FFFFFF">system</span>_error
       {
       public:
-
+        filesystem_error();
+        filesystem_error(const filesystem_error&);
         <a href="#filesystem_error-2-arg">filesystem_error</a>(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, system::error_code ec);
         <a href="#filesystem_error-3-arg">filesystem_error</a>(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path& p1, system::error_code ec);
         <a href="#filesystem_error-4-arg">filesystem_error</a>(const std::string& <span style="background-color: #FFFFFF">what_arg</span>, const path& p1, const path& p2, system::error_code ec);
 
+        filesystem_error& filesystem_error(const filesystem_error&);
+       ~filesystem_error();
+
+        filesystem_error& operator=(const filesystem_error&);
+
         const path& path1() const;
         const path& path2() const;
 
@@ -1422,11 +1429,14 @@
       {
       public:
 
-        // constructors
+        // constructors and destructor
         directory_entry();
+        directory_entry(const directory_entry&);
         explicit directory_entry(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
+       ~directory_entry(); 
 
         // modifiers
+        directory_entry& operator=(const directory_entry&);
         void assign(const path_type& p, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
         void replace_filename(const string_type& s, <span style="background-color: #FFFFFF">file_status</span> st=file_status(), <span style="background-color: #FFFFFF">file_status</span> symlink_st=file_status());
 
@@ -1598,15 +1608,21 @@
       public:
         typedef Path path_type;
 
-        // constructors
+        // member functions
+
         directory_iterator();  // creates the "end" iterator
+        directory_iterator(const directory_iterator&);
         explicit directory_iterator(const path& p);
         directory_iterator(const path& p, system::error_code& ec);
-
        ~directory_iterator();
 
+        directory_iterator& operator=(const directory_iterator&);
+
+        directory_iterator& operator++();
+        directory_iterator& increment(system::error_code& ec);
+
         // other members as required by
-        //  C++ Std, 24.1.1 Input iterators [lib.input.iterators]
+        //  C++ Std, 24.1.1 Input iterators [input.iterators]
       };
 
     } // namespace filesystem
@@ -1667,7 +1683,7 @@
 <a href="http://www.opengroup.org/onlinepubs/000095399/functions/readdir_r.html">readdir_r()</a></code>. <i>
 --end note</i>]</p>
 </blockquote>
-<h4><a name="directory_iterator-constructors"><code>directory_iterator</code> constructors</a></h4>
+<h4><a name="directory_iterator-members"><code>directory_iterator</code> members</a></h4>
 
 <p><code>directory_iterator();</code></p>
 
@@ -1684,16 +1700,29 @@
 <blockquote>
 
 <p><i>Effects:</i> Constructs a iterator representing the first 
-entry in the directory <code>p</code> resolves to, if any, otherwise, the end iterator.</p>
+entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p>
 
 <p><i>Throws:</i> As specified in
   <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
   Error reporting</a>.</p>
 
-<p>[<i>Note:</i> To iterate over the current directory, write <code>
+<p>[<i>Note:</i> To iterate over the current directory, use <code>
 directory_iterator(".")</code> rather than <code>directory_iterator("")</code>.
 <i>-- end note</i>]</p>
 </blockquote>
+<pre>directory_iterator& <a name="directory_iterator-increment">operator++</a>();
+directory_iterator& increment(system::error_code& ec);</pre>
+<blockquote>
+
+<p><i>Effects:</i> As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators]</p>
+
+<p><i>Returns:</i> <code>*this</code>.</p>
+
+<p><i>Throws:</i> As specified in
+  <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
+  Error reporting</a>.</p>
+
+</blockquote>
 <h3><a name="Class-recursive_directory_iterator">Class <code>recursive_directory_iterator</code></a></h3>
 <p>Objects of type <code>directory_iterator</code> provide standard library 
 compliant iteration over the contents of a directory, including recursion into 
@@ -1707,17 +1736,23 @@
       {
       public:
 
-        // constructors
+        // constructors and destructor
         recursive_directory_iterator();
-        explicit recursive_directory_iterator(const path& dp);
-        recursive_directory_iterator(const recursive_directory_iterator& brdi);
-        recursive_directory_iterator& operator=(const recursive_directory_iterator& brdi);
+        recursive_directory_iterator(const recursive_directory_iterator&);
+        explicit recursive_directory_iterator(const path& p);
+        recursive_directory_iterator(const path& p, system::error_code& ec);
        ~recursive_directory_iterator();
 
         // observers
         int level() const;
+        bool no_push<code>_request</code>() const;
 
         // modifiers
+        recursive_directory_iterator& operator=(const recursive_directory_iterator&);
+
+        recursive_directory_iterator& operator++();
+        recursive_directory_iterator& increment(system::error_code& ec);
+
         void pop();
         void no_push();
 
@@ -1725,7 +1760,8 @@
         //  C++ Std, 24.1.2 Input iterators [input.iterators]
 
       private:
-        int m_level; // for exposition only
+        int  m_level; <b><i>          // for exposition only</i></b>
+        bool m_no_<code>push_request</code>;  <b><i>// for exposition only</i></b>
       };
 
     } // namespace filesystem
@@ -1733,23 +1769,87 @@
 <p>The behavior of a <code>recursive_directory_iterator</code> is the same 
 as a <code>directory_iterator</code> unless otherwise specified.</p>
 <ul>
-  <li>When an iterator is constructed, <code>m_level</code> is set to 0;</li>
-  <li>When an iterator <code>it</code> is incremented, if <code>it->is_directory()</code> 
-  is true and <code>no_push()</code> had not been called subsequent to 
-  the most recent increment operation (or construction, if no increment has 
-  occurred), then  <code>m_level</code> is incremented, the 
-  directory is visited, and its contents recursively iterated over.</li>
   <li>When an iterator reaches the end of the directory currently being iterated 
   over, or when <code>pop()</code> is called, <code>m_level</code> is 
   decremented, and iteration continues with the parent directory, until the 
   directory specified in the constructor argument is reached.</li>
-  <li><code>level()</code> returns <code>m_level</code>.</li>
-  <li><code>level()</code>, <code>pop()</code>, and <code>no_push()</code> all 
-  require that the iterator not be the end iterator.</li>
 </ul>
 <blockquote>
   <p>[<i>Note:</i> One of the uses of <code>no_push()</code> is to prevent 
-  unwanted recursion into symlinked directories. This may be necessary to 
+  unwanted recursion into a directory symlink. This may be necessary to 
+  prevent loops on some operating systems. <i>--end note</i>]</p>
+</blockquote>
+<pre>recursive_directory_iterator();</pre>
+<blockquote>
+
+<p><i>Effects:</i> Constructs the end iterator.</p>
+
+<p><i>Throws:</i> Nothing.</p>
+
+</blockquote>
+
+<pre><code>explicit </code>recursive_<code>directory_iterator(</code>const path& p<code>);
+</code>recursive_<code>directory_iterator(</code>const path& p, system::error_code& ec<code>);</code></pre>
+<blockquote>
+
+<p><i>Effects:</i>  Constructs a iterator representing the first 
+entry in the directory <code>p</code> resolves to, if any; otherwise, the end iterator.</p>
+
+<p><i>Postconditions: </i>Unless the end iterator was constructed,<i> </i><code>
+level() == 0</code>, <code>no_push_request() == false</code>.</p>
+
+<p><i>Throws:</i> As specified in
+  <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
+  Error reporting</a>.</p>
+
+<p>[<i>Note:</i> To iterate over the current directory, use <code>recursive_directory_iterator(".")</code> rather than
+<code>recursive_directory_iterator("")</code>.
+<i>-- end note</i>]</p>
+</blockquote>
+<pre>int level() const;</pre>
+<blockquote>
+  <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p>
+  <p><i>Returns:</i> <code>m_level</code>.</p>
+  <p><i>Throws:</i> Nothing.</p>
+</blockquote>
+<pre>bool <code>no_push_request</code>() const;</pre>
+<blockquote>
+  <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p>
+  <p><i>Returns:</i> <code>m_no_push_request</code>.</p>
+  <p><i>Throws:</i> Nothing.</p>
+</blockquote>
+<pre><code>recursive_</code>directory_iterator& <a name="directory_iterator-increment">operator++</a>();
+<code>recursive_</code>directory_iterator& increment(system::error_code& ec);</pre>
+<blockquote>
+
+<p><i>Effects:</i> As specified by the C++ Standard, 24.1.1 Input iterators [input.iterators], 
+except that if <code>(*this)->is_directory() && !no_push_requested()</code> then  <code>m_level</code> 
+is incremented and <code>(*this)->path()</code> is recursively iterated into.</p>
+
+<p><i>Postconditions:</i> <code>no_push_request() == false</code>.</p>
+
+<p><i>Returns:</i> <code>*this</code>.</p>
+
+<p><i>Throws:</i> As specified in
+  <a href="file:///C:/boost/filesystem-v3-sandbox/libs/filesystem/doc/reference.html#Error-reporting">
+  Error reporting</a>.</p>
+
+</blockquote>
+<pre>void pop();</pre>
+<blockquote>
+  <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p>
+  <p><i>Effects:</i> If <code>level() == 0</code>, set <code>*this</code> to <code>recursive_directory_iterator()</code>. 
+  Otherwise, <code>--m_level</code>, cease iteration of the directory currently being 
+  iterated over, and continue iteration over the parent directory.</p>
+  <p><i>Throws:</i> Nothing.</p>
+</blockquote>
+<pre>void no_push();</pre>
+<blockquote>
+  <p><i>Requires:</i> <code>*this != recursive_directory_iterator()</code>.</p>
+<p><i>Postconditions:</i> <code>no_push_request() == true</code>.</p>
+  <p><i>Throws:</i> Nothing.</p>
+  <p>[<i>Note:</i> One of the uses of <code>no_push()</code> is to prevent 
+  unwanted recursion into a directory symlink. This may be necessary to 
   prevent loops on some operating systems. <i>--end note</i>]</p>
 </blockquote>
 <h3><a name="file_status">Class file_status</a></h3>
@@ -1760,10 +1860,13 @@
       class file_status
       {
       public:
-        explicit file_status( file_type v = status_error );
+        file_status();
+        file_status(const file_status&);
+        explicit file_status(file_type v=status_error);
+       ~file_status();
 
         <a href="#file_type">file_type</a> type() const;
-        void type( file_type v );
+        void type(file_type v);
       };
     } // namespace filesystem
   } // namespace boost</pre>
@@ -1774,15 +1877,16 @@
   additional status information. <i>--end note]</i></p>
 </blockquote>
 <h4>Members</h4>
-<pre>explicit file_status( file_type v = status_error );</pre>
+<pre>explicit file_status(file_type v=status_error);</pre>
 <blockquote>
   <p><i>Effects:</i> Stores <code>v</code>.</p>
+  <p><i>Throws:</i> Nothing.</p>
 </blockquote>
 <pre>file_type type() const;</pre>
 <blockquote>
   <p><i>Returns: </i>The stored  file_type.</p>
 </blockquote>
-<pre>void type( file_type v );</pre>
+<pre>void type(file_type v);</pre>
 <blockquote>
   <p><i>Effects:</i> Stores <code>v</code>, replacing the previously stored 
   value.</p>
@@ -3131,9 +3235,11 @@
 Witt were particularly helpful in refining the library.</p>
 <p>The create_directories, extension, basename, and replace_extension functions 
 were developed by Vladimir Prus.</p>
-<p>Howard Hinnant and John Maddock reviewed a draft of the proposal, and 
+<p>Howard Hinnant and John Maddock reviewed a draft of the version 2 proposal, and 
 identified a number of mistakes or weaknesses, resulting in a more polished 
 final document.</p>
+<p>Peter Dimov suggested a single class path, with member templates to adapt to 
+multiple string types. His idea became the basis for the version 3 path design.</p>
 <h2><a name="References">References</a></h2>
 <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
   <tr>
@@ -3159,7 +3265,7 @@
 <p>Distributed under the Boost Software License, Version 1.0. See
 <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
 <p>Revised
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->11 November 2009<!--webbot bot="Timestamp" endspan i-checksum="40583" --></p>
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->23 November 2009<!--webbot bot="Timestamp" endspan i-checksum="40588" --></p>
 
 </body>
 
Modified: sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp
==============================================================================
--- sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp	(original)
+++ sandbox/filesystem-v3/libs/filesystem/example/error_demo.cpp	2009-11-23 11:48:52 EST (Mon, 23 Nov 2009)
@@ -37,7 +37,7 @@
 
   void report_filesystem_error(const system_error& ex)
   {
-    cout << "  Threw filesystem_error exception:\n"
+    cout << "  threw filesystem_error exception:\n"
          << "    ex.code().value() is " << ex.code().value() << '\n'
          << "    ex.code().category().name() is " << ex.code().category().name() << '\n'
          << "    ex.what() is " << ex.what() << '\n'
@@ -46,7 +46,7 @@
 
   void report_status(fs::file_status s)
   {
-    cout << "file_status::type() is ";
+    cout << "  file_status::type() is ";
     switch (s.type())
     {
     case fs::status_error:
@@ -97,25 +97,26 @@
 
   error_code ec;
 
-  //  construct path - no error_code
+  ////  construct path - no error_code
 
-  try { path p1(argv[1]); }
-  catch (const system_error& ex)
-  {
-    cout << "construct path without error_code";
-    report_system_error(ex);
-  }
+  //try { path p1(argv[1]); }
+  //catch (const system_error& ex)
+  //{
+  //  cout << "construct path without error_code";
+  //  report_system_error(ex);
+  //}
 
-  //  construct path - with error_code
+  ////  construct path - with error_code
 
+  path p (argv[1]);
 
-  path p(argv[1]);
+  fs::file_status s;
+  bool            b (false);
+  fs::directory_iterator di;
 
   //  get status - no error_code
 
-  fs::file_status s;
-
-  cout << "status(argv[1]);\n";
+  cout << "\nstatus(\"" << p.native_string() << "\");\n";
   threw_exception = false;
 
   try { s = fs::status(p); }
@@ -130,14 +131,55 @@
 
   //  get status - with error_code
 
-  cout << "status(argv[1], ec);\n";
+  cout << "\nstatus(\"" << p.native_string() << "\", ec);\n";
   s = fs::status(p, ec);
   report_status(s);
   report_error_code(ec);
 
   //  query existence - no error_code
 
+  cout << "\nexists(\"" << p.native_string() << "\");\n";
+  threw_exception = false;
+
+  try { b = fs::exists(p); }
+  catch (const system_error& ex)
+  {
+    report_filesystem_error(ex);
+    threw_exception = true;
+  }
+  if (!threw_exception)
+  {
+    cout << "  Did not throw exception\n"
+         << "  Returns: " << (b ? "true" : "false") << '\n';
+  }
+
   //  query existence - with error_code
 
+  //  directory_iterator - no error_code
+
+  cout << "\ndirectory_iterator(\"" << p.native_string() << "\");\n";
+  threw_exception = false;
+
+  try { di = fs::directory_iterator(p); }
+  catch (const system_error& ex)
+  {
+    report_filesystem_error(ex);
+    threw_exception = true;
+  }
+  if (!threw_exception)
+  {
+    cout << "  Did not throw exception\n"
+      << (di == fs::directory_iterator() ? "  Equal" : "  Not equal")
+      << " to the end iterator\n";
+  }
+
+  //  directory_iterator - with error_code
+
+  cout << "\ndirectory_iterator(\"" << p.native_string() << "\", ec);\n";
+  di = fs::directory_iterator(p, ec);
+  cout << (di == fs::directory_iterator() ? "  Equal" : "  Not equal")
+       << " to the end iterator\n";
+  report_error_code(ec);
+
   return 0;
 }
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-11-23 11:48:52 EST (Mon, 23 Nov 2009)
@@ -177,6 +177,8 @@
   const char dot = '.';
 # endif
 
+  boost::filesystem::directory_iterator end_dir_itr;
+
   const std::size_t buf_size(128);
   const error_code ok;
 
@@ -270,8 +272,7 @@
 
   bool is_empty_directory(const path& p)
   {
-    static const fs::directory_iterator end_itr;
-    return fs::directory_iterator(p)== end_itr;
+    return fs::directory_iterator(p)== end_dir_itr;
   }
 
   bool remove_directory(const path& p) // true if succeeds
@@ -306,14 +307,13 @@
   boost::uintmax_t remove_all_aux(const path& p, fs::file_status sym_stat,
     error_code* ec)
   {
-    static const fs::directory_iterator end_itr;
     boost::uintmax_t count = 1;
 
     if (!fs::is_symlink(sym_stat)// don't recurse symbolic links
       && fs::is_directory(sym_stat))
     {
       for (fs::directory_iterator itr(p);
-            itr != end_itr; ++itr)
+            itr != end_dir_itr; ++itr)
       {
         fs::file_status tmp_sym_stat = fs::symlink_status(itr->path(), *ec);
         if (ec != 0 && ec)
@@ -1658,7 +1658,7 @@
 # endif
   }
 
-  void directory_iterator_construct(directory_iterator & it,
+  void directory_iterator_construct(directory_iterator& it,
     const path& p, system::error_code* ec)    
   {
     if (error(p.empty(), not_found_error, p, ec,
@@ -1693,30 +1693,36 @@
     }
   }
 
-  void directory_iterator_increment(directory_iterator & it)
+  void directory_iterator_increment(directory_iterator& it,
+    system::error_code* ec)
   {
     BOOST_ASSERT(it.m_imp.get() && "attempt to increment end iterator");
     BOOST_ASSERT(it.m_imp->handle != 0 && "internal program error");
     
     path::string_type filename;
     file_status file_stat, symlink_file_stat;
-    system::error_code ec;
+    system::error_code temp_ec;
 
     for (;;)
     {
-      ec = dir_itr_increment(it.m_imp->handle,
+      temp_ec = dir_itr_increment(it.m_imp->handle,
 #if     defined(BOOST_POSIX_API)
         it.m_imp->buffer,
 #endif
         filename, file_stat, symlink_file_stat);
 
-      if (ec)
+      if (temp_ec)
       {
         it.m_imp.reset();
-        error(true, it.m_imp->dir_entry.path().parent_path(),
-          &ec, "boost::filesystem::directory_iterator::operator++");
+        if (ec == 0)
+          throw_exception(
+            filesystem_error("boost::filesystem::directory_iterator::operator++",
+              it.m_imp->dir_entry.path().parent_path(),
+              error_code(BOOST_ERRNO, system_category)));
+        ec->assign(BOOST_ERRNO, system_category);
         return;
       }
+      else if (ec != 0) ec->clear();
 
       if (it.m_imp->handle == 0){ it.m_imp.reset(); return; } // eof, make end
       if (!(filename[0] == dot // !(dot or dot-dot)
@@ -1730,7 +1736,6 @@
       }
     }
   }
-
 }  // namespace detail
 } // namespace filesystem
 } // namespace boost
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-11-23 11:48:52 EST (Mon, 23 Nov 2009)
@@ -292,11 +292,21 @@
     catch (const fs::filesystem_error &) { dir_itr_exception = true; }
     BOOST_TEST(dir_itr_exception);
 
+    error_code ec;
+
+    BOOST_TEST(!ec);
+    fs::directory_iterator it("", ec);
+    BOOST_TEST(ec);
+
     dir_itr_exception = false;
     try { fs::directory_iterator it("nosuchdirectory"); }
     catch (const fs::filesystem_error &) { dir_itr_exception = true; }
     BOOST_TEST(dir_itr_exception);
 
+    ec.clear();
+    fs::directory_iterator it2("nosuchdirectory", ec);
+    BOOST_TEST(ec);
+
     dir_itr_exception = false;
     try
     {
@@ -353,7 +363,10 @@
       }
       BOOST_TEST(++dir_itr == fs::directory_iterator());
       BOOST_TEST(dir_itr2 != fs::directory_iterator());
-      BOOST_TEST(++dir_itr2 == fs::directory_iterator());
+      ec.clear();
+      dir_itr2.increment(ec);
+      BOOST_TEST(!ec);
+      BOOST_TEST(dir_itr2 == fs::directory_iterator());
     }
 
     { // *i++ must work to meet the standard's InputIterator requirements