imgtools/imglib/boostlibrary/boost/filesystem/path.hpp
changeset 607 378360dbbdba
parent 600 6d08f4a05d93
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/boostlibrary/boost/filesystem/path.hpp	Wed Jun 30 11:35:58 2010 +0800
@@ -0,0 +1,1507 @@
+//  boost/filesystem/path.hpp  -----------------------------------------------//
+
+//  Copyright Beman Dawes 2002-2005
+//  Copyright Vladimir Prus 2002
+
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See library home page at http://www.boost.org/libs/filesystem
+
+//  basic_path's stem(), extension(), and replace_extension() are based on
+//  basename(), extension(), and change_extension() from the original
+//  filesystem/convenience.hpp header by Vladimir Prus.
+
+//----------------------------------------------------------------------------// 
+
+#ifndef BOOST_FILESYSTEM_PATH_HPP
+#define BOOST_FILESYSTEM_PATH_HPP
+
+#include <boost/filesystem/config.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/static_assert.hpp>
+
+#include <string>
+#include <algorithm> // for lexicographical_compare
+#include <iosfwd>    // needed by basic_path inserter and extractor
+#include <stdexcept>
+#include <cassert>
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+#   include <locale>
+# endif
+
+#include <boost/config/abi_prefix.hpp> // must be the last #include
+
+//----------------------------------------------------------------------------//
+
+namespace boost
+{
+  namespace BOOST_FILESYSTEM_NAMESPACE
+  {
+    template<class String, class Traits> class basic_path;
+
+    struct path_traits;
+    typedef basic_path< std::string, path_traits > path;
+
+    struct path_traits
+    {
+      typedef std::string internal_string_type;
+      typedef std::string external_string_type;
+      static external_string_type to_external( const path &,
+        const internal_string_type & src ) { return src; }
+      static internal_string_type to_internal(
+        const external_string_type & src ) { return src; }
+    };
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+    struct BOOST_FILESYSTEM_DECL wpath_traits;
+    
+    typedef basic_path< std::wstring, wpath_traits > wpath;
+
+    struct BOOST_FILESYSTEM_DECL wpath_traits
+    {
+      typedef std::wstring internal_string_type;
+# ifdef BOOST_WINDOWS_API
+      typedef std::wstring external_string_type;
+      static external_string_type to_external( const wpath &,
+        const internal_string_type & src ) { return src; }
+      static internal_string_type to_internal(
+        const external_string_type & src ) { return src; }
+# else
+      typedef std::string external_string_type;
+      static external_string_type to_external( const wpath & ph,
+        const internal_string_type & src );
+      static internal_string_type to_internal(
+        const external_string_type & src );
+# endif
+      static void imbue( const std::locale & loc );
+      static bool imbue( const std::locale & loc, const std::nothrow_t & );
+    };
+
+# endif // ifndef BOOST_FILESYSTEM_NARROW_ONLY
+
+    //  path traits  ---------------------------------------------------------//
+
+    template<class Path> struct is_basic_path
+      { BOOST_STATIC_CONSTANT( bool, value = false ); };
+    template<> struct is_basic_path<path>
+      { BOOST_STATIC_CONSTANT( bool, value = true ); };
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+    template<> struct is_basic_path<wpath>
+      { BOOST_STATIC_CONSTANT( bool, value = true ); };
+# endif
+
+    // These only have to be specialized if Path::string_type::value_type
+    // is not convertible from char, although specializations may eliminate
+    // compiler warnings. See ticket 2543.
+    template<class Path> struct slash
+      { BOOST_STATIC_CONSTANT( char, value = '/' ); };
+
+    template<class Path> struct dot
+      { BOOST_STATIC_CONSTANT( char, value = '.' ); };
+
+    template<class Path> struct colon
+      { BOOST_STATIC_CONSTANT( char, value = ':' ); };
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+    template<> struct slash<wpath>
+      { BOOST_STATIC_CONSTANT( wchar_t, value = L'/' ); };
+    template<> struct dot<wpath>
+      { BOOST_STATIC_CONSTANT( wchar_t, value = L'.' ); };
+    template<> struct colon<wpath>
+      { BOOST_STATIC_CONSTANT( wchar_t, value = L':' ); };
+# endif
+
+# ifdef BOOST_WINDOWS_PATH
+    template<class Path> struct path_alt_separator
+      { BOOST_STATIC_CONSTANT( char, value = '\\' ); };
+#   ifndef BOOST_FILESYSTEM_NARROW_ONLY
+    template<> struct path_alt_separator<wpath>
+      { BOOST_STATIC_CONSTANT( wchar_t, value = L'\\' ); };
+#   endif
+# endif
+
+    //  workaround for VC++ 7.0 and earlier issues with nested classes
+    namespace detail
+    {
+      template<class Path>
+      class iterator_helper
+      {
+      public:
+        typedef typename Path::iterator iterator;
+        static void do_increment( iterator & ph );
+        static void do_decrement( iterator & ph );
+      };
+    }
+
+    //  basic_path  ----------------------------------------------------------//
+  
+    template<class String, class Traits>
+    class basic_path
+    {
+    // invariant: m_path valid according to the portable generic path grammar
+
+      // validate template arguments
+// TODO: get these working
+//      BOOST_STATIC_ASSERT( ::boost::is_same<String,typename Traits::internal_string_type>::value );
+//      BOOST_STATIC_ASSERT( ::boost::is_same<typename Traits::external_string_type,std::string>::value || ::boost::is_same<typename Traits::external_string_type,std::wstring>::value );
+
+    public:
+      // compiler generates copy constructor and copy assignment
+
+      typedef basic_path<String, Traits> path_type;
+      typedef String string_type;
+      typedef typename String::value_type value_type;
+      typedef Traits traits_type;
+      typedef typename Traits::external_string_type external_string_type; 
+
+      // constructors/destructor
+      basic_path() {}
+      basic_path( const string_type & s ) { operator/=( s ); }
+      basic_path( const value_type * s )  { operator/=( s ); }
+#     ifndef BOOST_NO_MEMBER_TEMPLATES
+        template <class InputIterator>
+          basic_path( InputIterator first, InputIterator last )
+            { append( first, last ); }
+#     endif
+     ~basic_path() {}
+
+      // assignments
+      basic_path & operator=( const string_type & s )
+      {
+#     if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310)
+        m_path.clear();
+#     else
+        m_path.erase( m_path.begin(), m_path.end() );
+#     endif
+        operator/=( s ); 
+        return *this;
+      }
+      basic_path & operator=( const value_type * s )
+      { 
+#     if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310)
+        m_path.clear();
+#     else
+        m_path.erase( m_path.begin(), m_path.end() );
+#     endif
+        operator/=( s ); 
+        return *this;
+      }
+#     ifndef BOOST_NO_MEMBER_TEMPLATES
+        template <class InputIterator>
+          basic_path & assign( InputIterator first, InputIterator last )
+            { m_path.clear(); append( first, last ); return *this; }
+#     endif
+
+      // modifiers
+      basic_path & operator/=( const basic_path & rhs )  { return operator /=( rhs.string().c_str() ); }
+      basic_path & operator/=( const string_type & rhs ) { return operator /=( rhs.c_str() ); }
+      basic_path & operator/=( const value_type * s );
+#     ifndef BOOST_NO_MEMBER_TEMPLATES
+        template <class InputIterator>
+          basic_path & append( InputIterator first, InputIterator last );
+#     endif
+      
+      void swap( basic_path & rhs )
+      {
+        m_path.swap( rhs.m_path );
+#       ifdef BOOST_CYGWIN_PATH
+          std::swap( m_cygwin_root, rhs.m_cygwin_root );
+#       endif
+      }
+
+      basic_path & remove_filename();
+      basic_path & replace_extension( const string_type & new_extension = string_type() );
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+      basic_path & remove_leaf() { return remove_filename(); }
+# endif
+
+      // observers
+      const string_type & string() const         { return m_path; }
+      const string_type file_string() const;
+      const string_type directory_string() const { return file_string(); }
+
+      const external_string_type external_file_string() const { return Traits::to_external( *this, file_string() ); }
+      const external_string_type external_directory_string() const { return Traits::to_external( *this, directory_string() ); }
+
+      basic_path   root_path() const;
+      string_type  root_name() const;
+      string_type  root_directory() const;
+      basic_path   relative_path() const;
+      basic_path   parent_path() const;
+      string_type  filename() const;
+      string_type  stem() const;
+      string_type  extension() const;
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+      string_type  leaf() const            { return filename(); }
+      basic_path   branch_path() const     { return parent_path(); }
+      bool         has_leaf() const        { return !m_path.empty(); }
+      bool         has_branch_path() const { return !parent_path().empty(); }
+# endif
+
+      bool empty() const               { return m_path.empty(); } // name consistent with std containers
+      bool is_complete() const;
+      bool has_root_path() const;
+      bool has_root_name() const;
+      bool has_root_directory() const;
+      bool has_relative_path() const   { return !relative_path().empty(); }
+      bool has_filename() const        { return !m_path.empty(); }
+      bool has_parent_path() const     { return !parent_path().empty(); }
+
+      // iterators
+      class iterator : public boost::iterator_facade<
+        iterator,
+        string_type const,
+        boost::bidirectional_traversal_tag >
+      {
+      private:
+        friend class boost::iterator_core_access;
+        friend class boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits>;
+
+        const string_type & dereference() const
+          { return m_name; }
+        bool equal( const iterator & rhs ) const
+          { return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos; }
+
+        friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>;
+
+        void increment()
+        { 
+          boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>::do_increment(
+            *this );
+        }
+        void decrement()
+        { 
+          boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>::do_decrement(
+            *this );
+        }
+
+        string_type             m_name;     // current element
+        const basic_path *      m_path_ptr; // path being iterated over
+        typename string_type::size_type  m_pos;  // position of name in
+                                            // path_ptr->string(). The
+                                            // end() iterator is indicated by 
+                                            // pos == path_ptr->m_path.size()
+      }; // iterator
+
+      typedef iterator const_iterator;
+
+      iterator begin() const;
+      iterator end() const;
+
+    private:
+      // Note: This is an implementation for POSIX and Windows, where there
+      // are only minor differences between generic and native path grammars.
+      // Private members might be quite different in other implementations,
+      // particularly where there were wide differences between portable and
+      // native path formats, or between file_string() and
+      // directory_string() formats, or simply that the implementation
+      // was willing expend additional memory to achieve greater speed for
+      // some operations at the expense of other operations.
+
+      string_type  m_path; // invariant: portable path grammar
+                           // on Windows, backslashes converted to slashes
+
+#   ifdef BOOST_CYGWIN_PATH
+      bool m_cygwin_root; // if present, m_path[0] was slash. note: initialization
+                          // done by append
+#   endif  
+
+      void m_append_separator_if_needed();
+      void m_append( value_type value ); // converts Windows alt_separator
+
+      // Was qualified; como433beta8 reports:
+      //    warning #427-D: qualified name is not allowed in member declaration 
+      friend class iterator;
+      friend class boost::BOOST_FILESYSTEM_NAMESPACE::detail::iterator_helper<path_type>;
+
+      // Deprecated features ease transition for existing code. Don't use these
+      // in new code.
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+    public:
+      typedef bool (*name_check)( const std::string & name );
+      basic_path( const string_type & str, name_check ) { operator/=( str ); }
+      basic_path( const typename string_type::value_type * s, name_check )
+        { operator/=( s );}
+      string_type native_file_string() const { return file_string(); }
+      string_type native_directory_string() const { return directory_string(); }
+      static bool default_name_check_writable() { return false; } 
+      static void default_name_check( name_check ) {}
+      static name_check default_name_check() { return 0; }
+      basic_path & canonize();
+      basic_path & normalize();
+# endif
+    };
+
+  //  basic_path non-member functions  ---------------------------------------//
+
+    template< class String, class Traits >
+    inline void swap( basic_path<String, Traits> & lhs,
+               basic_path<String, Traits> & rhs ) { lhs.swap( rhs ); }
+
+    template< class String, class Traits >
+    bool operator<( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs )
+    {
+      return std::lexicographical_compare(
+        lhs.begin(), lhs.end(), rhs.begin(), rhs.end() );
+    }
+
+    template< class String, class Traits >
+    bool operator<( const typename basic_path<String, Traits>::string_type::value_type * lhs,
+                    const basic_path<String, Traits> & rhs )
+    {
+      basic_path<String, Traits> tmp( lhs );
+      return std::lexicographical_compare(
+        tmp.begin(), tmp.end(), rhs.begin(), rhs.end() );
+    }
+
+    template< class String, class Traits >
+    bool operator<( const typename basic_path<String, Traits>::string_type & lhs,
+                    const basic_path<String, Traits> & rhs )
+    {
+      basic_path<String, Traits> tmp( lhs );
+      return std::lexicographical_compare(
+        tmp.begin(), tmp.end(), rhs.begin(), rhs.end() );
+    }
+
+    template< class String, class Traits >
+    bool operator<( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type::value_type * rhs )
+    {
+      basic_path<String, Traits> tmp( rhs );
+      return std::lexicographical_compare(
+        lhs.begin(), lhs.end(), tmp.begin(), tmp.end() );
+    }
+
+    template< class String, class Traits >
+    bool operator<( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type & rhs )
+    {
+      basic_path<String, Traits> tmp( rhs );
+      return std::lexicographical_compare(
+        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.
+
+    template< class String, class Traits >
+    inline bool operator==( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs )
+    { 
+      return lhs.string() == rhs.string();
+    }
+
+    template< class String, class Traits >
+    inline bool operator==( const typename basic_path<String, Traits>::string_type::value_type * lhs,
+                    const basic_path<String, Traits> & rhs )
+    {
+      return lhs == rhs.string();
+    }
+
+    template< class String, class Traits >
+    inline bool operator==( const typename basic_path<String, Traits>::string_type & lhs,
+                    const basic_path<String, Traits> & rhs )
+    {
+      return lhs == rhs.string();
+    }
+
+    template< class String, class Traits >
+    inline bool operator==( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type::value_type * rhs )
+    {
+      return lhs.string() == rhs;
+    }
+
+    template< class String, class Traits >
+    inline bool operator==( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type & rhs )
+    {
+      return lhs.string() == rhs;
+    }
+
+    template< class String, class Traits >
+    inline bool operator!=( const basic_path<String, Traits> & lhs,
+      const basic_path<String, Traits> & rhs )
+        { return !(lhs == rhs); }
+    
+    template< class String, class Traits >
+    inline bool operator!=( const typename basic_path<String,
+      Traits>::string_type::value_type * lhs,
+        const basic_path<String, Traits> & rhs )
+        { return !(lhs == rhs); }
+
+    template< class String, class Traits >
+    inline bool operator!=( const typename basic_path<String, Traits>::string_type & lhs,
+      const basic_path<String, Traits> & rhs )
+        { return !(lhs == rhs); }
+
+    template< class String, class Traits >
+    inline bool operator!=( const basic_path<String, Traits> & lhs,
+      const typename basic_path<String, Traits>::string_type::value_type * rhs )
+        { return !(lhs == rhs); }
+
+    template< class String, class Traits >
+    inline bool operator!=( const basic_path<String, Traits> & lhs,
+      const typename basic_path<String, Traits>::string_type & rhs )
+        { return !(lhs == rhs); }
+
+    template< class String, class Traits >
+    inline bool operator>( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return rhs < lhs; }
+    
+    template< class String, class Traits >
+    inline bool operator>( const typename basic_path<String, Traits>::string_type::value_type * lhs,
+                    const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); }
+
+    template< class String, class Traits >
+    inline bool operator>( const typename basic_path<String, Traits>::string_type & lhs,
+                    const basic_path<String, Traits> & rhs ) { return rhs < basic_path<String, Traits>(lhs); }
+
+    template< class String, class Traits >
+    inline bool operator>( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type::value_type * rhs )
+                    { return basic_path<String, Traits>(rhs) < lhs; }
+
+    template< class String, class Traits >
+    inline bool operator>( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type & rhs )
+                    { return basic_path<String, Traits>(rhs) < lhs; }
+
+    template< class String, class Traits >
+    inline bool operator<=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(rhs < lhs); }
+    
+    template< class String, class Traits >
+    inline bool operator<=( const typename basic_path<String, Traits>::string_type::value_type * lhs,
+                    const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); }
+
+    template< class String, class Traits >
+    inline bool operator<=( const typename basic_path<String, Traits>::string_type & lhs,
+                    const basic_path<String, Traits> & rhs ) { return !(rhs < basic_path<String, Traits>(lhs)); }
+
+    template< class String, class Traits >
+    inline bool operator<=( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type::value_type * rhs )
+                    { return !(basic_path<String, Traits>(rhs) < lhs); }
+
+    template< class String, class Traits >
+    inline bool operator<=( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type & rhs )
+                    { return !(basic_path<String, Traits>(rhs) < lhs); }
+
+    template< class String, class Traits >
+    inline bool operator>=( const basic_path<String, Traits> & lhs, const basic_path<String, Traits> & rhs ) { return !(lhs < rhs); }
+    
+    template< class String, class Traits >
+    inline bool operator>=( const typename basic_path<String, Traits>::string_type::value_type * lhs,
+                    const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); }
+
+    template< class String, class Traits >
+    inline bool operator>=( const typename basic_path<String, Traits>::string_type & lhs,
+                    const basic_path<String, Traits> & rhs ) { return !(lhs < basic_path<String, Traits>(rhs)); }
+
+    template< class String, class Traits >
+    inline bool operator>=( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type::value_type * rhs )
+                    { return !(basic_path<String, Traits>(lhs) < rhs); }
+
+    template< class String, class Traits >
+    inline bool operator>=( const basic_path<String, Traits> & lhs,
+                    const typename basic_path<String, Traits>::string_type & rhs )
+                    { return !(basic_path<String, Traits>(lhs) < rhs); }
+
+    // operator /
+
+    template< class String, class Traits >
+    inline basic_path<String, Traits> operator/( 
+      const basic_path<String, Traits> & lhs,
+      const basic_path<String, Traits> & rhs )
+      { return basic_path<String, Traits>( lhs ) /= rhs; }
+
+    template< class String, class Traits >
+    inline basic_path<String, Traits> operator/( 
+      const basic_path<String, Traits> & lhs,
+      const typename String::value_type * rhs )
+      { return basic_path<String, Traits>( lhs ) /=
+          basic_path<String, Traits>( rhs ); }
+
+    template< class String, class Traits >
+    inline basic_path<String, Traits> operator/( 
+      const basic_path<String, Traits> & lhs, const String & rhs )
+      { return basic_path<String, Traits>( lhs ) /=
+          basic_path<String, Traits>( rhs ); }
+
+    template< class String, class Traits >
+    inline basic_path<String, Traits> operator/( 
+      const typename String::value_type * lhs,
+      const basic_path<String, Traits> & rhs )
+      { return basic_path<String, Traits>( lhs ) /= rhs; }
+
+    template< class String, class Traits >
+    inline basic_path<String, Traits> operator/(
+      const String & lhs, const basic_path<String, Traits> & rhs )
+      { return basic_path<String, Traits>( lhs ) /= rhs; }
+   
+    //  inserters and extractors  --------------------------------------------//
+
+// bypass VC++ 7.0 and earlier, and broken Borland compilers
+# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__BORLANDC__, < 0x610)
+    template< class Path >
+    std::basic_ostream< typename Path::string_type::value_type,
+      typename Path::string_type::traits_type > &
+      operator<<
+      ( std::basic_ostream< typename Path::string_type::value_type,
+      typename Path::string_type::traits_type >& os, const Path & ph )
+    {
+      os << ph.string();
+      return os;
+    }
+
+    template< class Path >
+    std::basic_istream< typename Path::string_type::value_type,
+      typename Path::string_type::traits_type > &
+      operator>>
+      ( std::basic_istream< typename Path::string_type::value_type,
+      typename Path::string_type::traits_type >& is, Path & ph )
+    {
+      typename Path::string_type str;
+      is >> str;
+      ph = str;
+      return is;
+    }
+# elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+    template< class String, class Traits >
+    std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type,
+      BOOST_DEDUCED_TYPENAME String::traits_type > &
+      operator<<
+      ( std::basic_ostream< BOOST_DEDUCED_TYPENAME String::value_type,
+          BOOST_DEDUCED_TYPENAME String::traits_type >& os, 
+        const basic_path< String, Traits > & ph )
+    {
+      os << ph.string();
+      return os;
+    }
+
+    template< class String, class Traits >
+    std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type, 
+      BOOST_DEDUCED_TYPENAME String::traits_type > &
+      operator>>
+      ( std::basic_istream< BOOST_DEDUCED_TYPENAME String::value_type,
+          BOOST_DEDUCED_TYPENAME String::traits_type> & is,
+        basic_path< String, Traits > & ph )
+    {
+      String str;
+      is >> str;
+      ph = str;
+      return is;
+    }
+# endif
+
+    //  basic_filesystem_error helpers  --------------------------------------//
+
+    //  Originally choice of implementation was done via specialization of
+    //  basic_filesystem_error::what(). Several compilers (GCC, aCC, etc.)
+    //  couldn't handle that, so the choice is now accomplished by overloading.
+
+    namespace detail
+    {
+      // BOOST_FILESYSTEM_DECL version works for VC++ but not GCC. Go figure!
+      inline
+      const char * what( const char * sys_err_what,
+        const path & path1_arg, const path & path2_arg, std::string & target )
+      {
+        try
+        {
+          if ( target.empty() )
+          {
+            target = sys_err_what;
+            if ( !path1_arg.empty() )
+            {
+              target += ": \"";
+              target += path1_arg.file_string();
+              target += "\"";
+            }
+            if ( !path2_arg.empty() )
+            {
+              target += ", \"";
+              target += path2_arg.file_string();
+              target += "\"";
+            }
+          }
+          return target.c_str();
+        }
+        catch (...)
+        {
+          return sys_err_what;
+        }
+      }
+
+      template<class Path>
+      const char * what( const char * sys_err_what,
+        const Path & /*path1_arg*/, const Path & /*path2_arg*/, std::string & /*target*/ )
+      {
+        return sys_err_what;
+      }
+    }
+
+    //  basic_filesystem_error  ----------------------------------------------//
+
+    template<class Path>
+    class basic_filesystem_error : public system::system_error
+    {
+    // see http://www.boost.org/more/error_handling.html for design rationale
+    public:
+      // compiler generates copy constructor and copy assignment
+
+      typedef Path path_type;
+
+      basic_filesystem_error( const std::string & what_arg,
+        system::error_code ec );
+
+      basic_filesystem_error( const std::string & what_arg,
+        const path_type & path1_arg, system::error_code ec );
+
+      basic_filesystem_error( const std::string & what_arg, const path_type & path1_arg,
+        const path_type & path2_arg, system::error_code ec );
+
+      ~basic_filesystem_error() throw() {}
+
+      const path_type & path1() const
+      {
+        static const path_type empty_path;
+        return m_imp_ptr.get() ? m_imp_ptr->m_path1 : empty_path ;
+      }
+      const path_type & path2() const
+      {
+        static const path_type empty_path;
+        return m_imp_ptr.get() ? m_imp_ptr->m_path2 : empty_path ;
+      }
+
+      const char * what() const throw()
+      { 
+        if ( !m_imp_ptr.get() )
+          return system::system_error::what();
+        return detail::what( system::system_error::what(), m_imp_ptr->m_path1,
+          m_imp_ptr->m_path2, m_imp_ptr->m_what );  
+      }
+
+    private:
+      struct m_imp
+      {
+        path_type                 m_path1; // may be empty()
+        path_type                 m_path2; // may be empty()
+        std::string               m_what;  // not built until needed
+      };
+      boost::shared_ptr<m_imp> m_imp_ptr;
+    };
+
+    typedef basic_filesystem_error<path> filesystem_error;
+
+# ifndef BOOST_FILESYSTEM_NARROW_ONLY
+    typedef basic_filesystem_error<wpath> wfilesystem_error;
+# endif
+
+  //  path::name_checks  -----------------------------------------------------//
+
+    BOOST_FILESYSTEM_DECL bool portable_posix_name( const std::string & name );
+    BOOST_FILESYSTEM_DECL bool windows_name( const std::string & name );
+    BOOST_FILESYSTEM_DECL bool portable_name( const std::string & name );
+    BOOST_FILESYSTEM_DECL bool portable_directory_name( const std::string & name );
+    BOOST_FILESYSTEM_DECL bool portable_file_name( const std::string & name );
+    BOOST_FILESYSTEM_DECL bool native( const std::string & name );
+    inline bool no_check( const std::string & )
+      { return true; }
+
+// implementation  -----------------------------------------------------------//
+
+    namespace detail
+    {
+
+      //  is_separator helper ------------------------------------------------//
+
+      template<class Path>
+      inline  bool is_separator( typename Path::string_type::value_type c )
+      {
+        return c == slash<Path>::value
+#     ifdef BOOST_WINDOWS_PATH
+          || c == path_alt_separator<Path>::value
+#     endif
+          ;
+      }
+
+      // filename_pos helper  ----------------------------------------------------//
+
+      template<class String, class Traits>
+      typename String::size_type filename_pos(
+        const String & str, // precondition: portable generic path grammar
+        typename String::size_type end_pos ) // end_pos is past-the-end position
+      // return 0 if str itself is filename (or empty)
+      {
+        typedef typename
+          boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type;
+
+        // case: "//"
+        if ( end_pos == 2 
+          && str[0] == slash<path_type>::value
+          && str[1] == slash<path_type>::value ) return 0;
+
+        // case: ends in "/"
+        if ( end_pos && str[end_pos-1] == slash<path_type>::value )
+          return end_pos-1;
+        
+        // set pos to start of last element
+        typename String::size_type pos(
+          str.find_last_of( slash<path_type>::value, end_pos-1 ) );
+#       ifdef BOOST_WINDOWS_PATH
+        if ( pos == String::npos )
+          pos = str.find_last_of( path_alt_separator<path_type>::value, end_pos-1 );
+        if ( pos == String::npos )
+          pos = str.find_last_of( colon<path_type>::value, end_pos-2 );
+#       endif
+
+        return ( pos == String::npos // path itself must be a filename (or empty)
+          || (pos == 1 && str[0] == slash<path_type>::value) ) // or net
+            ? 0 // so filename is entire string
+            : pos + 1; // or starts after delimiter
+      }
+
+      // first_element helper  -----------------------------------------------//
+      //   sets pos and len of first element, excluding extra separators
+      //   if src.empty(), sets pos,len, to 0,0.
+
+      template<class String, class Traits>
+        void first_element(
+          const String & src, // precondition: portable generic path grammar
+          typename String::size_type & element_pos,
+          typename String::size_type & element_size,
+#       if !BOOST_WORKAROUND( BOOST_MSVC, <= 1310 ) // VC++ 7.1
+          typename String::size_type size = String::npos
+#       else
+          typename String::size_type size = -1
+#       endif
+          )
+      {
+        if ( size == String::npos ) size = src.size();
+        element_pos = 0;
+        element_size = 0;
+        if ( src.empty() ) return;
+
+        typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type;
+
+        typename String::size_type cur(0);
+        
+        // deal with // [network]
+        if ( size >= 2 && src[0] == slash<path_type>::value
+          && src[1] == slash<path_type>::value
+          && (size == 2
+            || src[2] != slash<path_type>::value) )
+        { 
+          cur += 2;
+          element_size += 2;
+        }
+
+        // leading (not non-network) separator
+        else if ( src[0] == slash<path_type>::value )
+        {
+          ++element_size;
+          // bypass extra leading separators
+          while ( cur+1 < size
+            && src[cur+1] == slash<path_type>::value )
+          {
+            ++cur;
+            ++element_pos;
+          }
+          return;
+        }
+
+        // at this point, we have either a plain name, a network name,
+        // or (on Windows only) a device name
+
+        // find the end
+        while ( cur < size
+#         ifdef BOOST_WINDOWS_PATH
+          && src[cur] != colon<path_type>::value
+#         endif
+          && src[cur] != slash<path_type>::value )
+        {
+          ++cur;
+          ++element_size;
+        }
+
+#       ifdef BOOST_WINDOWS_PATH
+        if ( cur == size ) return;
+        // include device delimiter
+        if ( src[cur] == colon<path_type>::value )
+          { ++element_size; }
+#       endif
+
+        return;
+      }
+
+      // root_directory_start helper  ----------------------------------------//
+
+      template<class String, class Traits>
+      typename String::size_type root_directory_start(
+        const String & s, // precondition: portable generic path grammar
+        typename String::size_type size )
+      // return npos if no root_directory found
+      {
+        typedef typename boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits> path_type;
+
+#     ifdef BOOST_WINDOWS_PATH
+        // case "c:/"
+        if ( size > 2
+          && s[1] == colon<path_type>::value
+          && s[2] == slash<path_type>::value ) return 2;
+#     endif
+
+        // case "//"
+        if ( size == 2
+          && s[0] == slash<path_type>::value
+          && s[1] == slash<path_type>::value ) return String::npos;
+
+        // case "//net {/}"
+        if ( size > 3
+          && s[0] == slash<path_type>::value
+          && s[1] == slash<path_type>::value
+          && s[2] != slash<path_type>::value )
+        {
+          typename String::size_type pos(
+            s.find( slash<path_type>::value, 2 ) );
+          return pos < size ? pos : String::npos;
+        }
+        
+        // case "/"
+        if ( size > 0 && s[0] == slash<path_type>::value ) return 0;
+
+        return String::npos;
+      }
+
+      // is_non_root_slash helper  -------------------------------------------//
+
+      template<class String, class Traits>
+      bool is_non_root_slash( const String & str,
+        typename String::size_type pos ) // pos is position of the slash
+      {
+        typedef typename
+          boost::BOOST_FILESYSTEM_NAMESPACE::basic_path<String, Traits>
+            path_type;
+
+        assert( !str.empty() && str[pos] == slash<path_type>::value
+          && "precondition violation" );
+
+        // subsequent logic expects pos to be for leftmost slash of a set
+        while ( pos > 0 && str[pos-1] == slash<path_type>::value )
+          --pos;
+
+        return  pos != 0
+          && (pos <= 2 || str[1] != slash<path_type>::value
+            || str.find( slash<path_type>::value, 2 ) != pos)
+#       ifdef BOOST_WINDOWS_PATH
+          && (pos !=2 || str[1] != colon<path_type>::value)
+#       endif
+            ;
+      }
+    } // namespace detail
+
+    // decomposition functions  ----------------------------------------------//
+
+    template<class String, class Traits>
+    String basic_path<String, Traits>::filename() const
+    {
+      typename String::size_type end_pos(
+        detail::filename_pos<String, Traits>( m_path, m_path.size() ) );
+      return (m_path.size()
+                && end_pos
+                && m_path[end_pos] == slash<path_type>::value
+                && detail::is_non_root_slash< String, Traits >(m_path, end_pos))
+        ? String( 1, dot<path_type>::value )
+        : m_path.substr( end_pos );
+    }
+
+    template<class String, class Traits>
+    String basic_path<String, Traits>::stem() const
+    {
+      string_type name = filename();
+      typename string_type::size_type n = name.rfind('.');
+      return name.substr(0, n);
+    }
+
+    template<class String, class Traits>
+    String basic_path<String, Traits>::extension() const
+    {
+      string_type name = filename();
+      typename string_type::size_type n = name.rfind('.');
+      if (n != string_type::npos)
+        return name.substr(n);
+      else
+        return string_type();
+    }
+
+    template<class String, class Traits>
+    basic_path<String, Traits> basic_path<String, Traits>::parent_path() const
+    {
+      typename String::size_type end_pos(
+        detail::filename_pos<String, Traits>( m_path, m_path.size() ) );
+
+      bool filename_was_separator( m_path.size()
+        && m_path[end_pos] == slash<path_type>::value );
+
+      // skip separators unless root directory
+      typename string_type::size_type root_dir_pos( detail::root_directory_start
+        <string_type, traits_type>( m_path, end_pos ) );
+      for ( ; 
+        end_pos > 0
+        && (end_pos-1) != root_dir_pos
+        && m_path[end_pos-1] == slash<path_type>::value
+        ;
+        --end_pos ) {}
+
+     return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator)
+       ? path_type()
+       : path_type( m_path.substr( 0, end_pos ) );
+    }
+
+    template<class String, class Traits>
+    basic_path<String, Traits> basic_path<String, Traits>::relative_path() const
+    {
+      iterator itr( begin() );
+      for ( ; itr.m_pos != m_path.size()
+          && (itr.m_name[0] == slash<path_type>::value
+#     ifdef BOOST_WINDOWS_PATH
+          || itr.m_name[itr.m_name.size()-1]
+            == colon<path_type>::value
+#     endif
+             ); ++itr ) {}
+
+      return basic_path<String, Traits>( m_path.substr( itr.m_pos ) );
+    }
+
+    template<class String, class Traits>
+    String basic_path<String, Traits>::root_name() const
+    {
+      iterator itr( begin() );
+
+      return ( itr.m_pos != m_path.size()
+        && (
+            ( itr.m_name.size() > 1
+              && itr.m_name[0] == slash<path_type>::value
+              && itr.m_name[1] == slash<path_type>::value
+            )
+#     ifdef BOOST_WINDOWS_PATH
+          || itr.m_name[itr.m_name.size()-1]
+            == colon<path_type>::value
+#     endif
+           ) )
+        ? *itr
+        : String();
+    }
+
+    template<class String, class Traits>
+    String basic_path<String, Traits>::root_directory() const
+    {
+      typename string_type::size_type start(
+        detail::root_directory_start<String, Traits>( m_path, m_path.size() ) );
+
+      return start == string_type::npos
+        ? string_type()
+        : m_path.substr( start, 1 );
+    }
+
+    template<class String, class Traits>
+    basic_path<String, Traits> basic_path<String, Traits>::root_path() const
+    {
+      // even on POSIX, root_name() is non-empty() on network paths
+      return basic_path<String, Traits>( root_name() ) /= root_directory();
+    }
+
+    // path query functions  -------------------------------------------------//
+
+    template<class String, class Traits>
+    inline bool basic_path<String, Traits>::is_complete() const
+    {
+#   ifdef BOOST_WINDOWS_PATH
+      return has_root_name() && has_root_directory();
+#   else
+      return has_root_directory();
+#   endif
+    }
+
+    template<class String, class Traits>
+    inline bool basic_path<String, Traits>::has_root_path() const
+    {
+      return !root_path().empty();
+    }
+
+    template<class String, class Traits>
+    inline bool basic_path<String, Traits>::has_root_name() const
+    {
+      return !root_name().empty();
+    }
+
+    template<class String, class Traits>
+    inline bool basic_path<String, Traits>::has_root_directory() const
+    {
+      return !root_directory().empty();
+    }
+
+    // append  ---------------------------------------------------------------//
+
+    template<class String, class Traits>
+    void basic_path<String, Traits>::m_append_separator_if_needed()
+    // requires: !empty()
+    {
+      if (
+#       ifdef BOOST_WINDOWS_PATH
+        *(m_path.end()-1) != colon<path_type>::value && 
+#       endif
+        *(m_path.end()-1) != slash<path_type>::value )
+      {
+        m_path += slash<path_type>::value;
+      }
+    }
+      
+    template<class String, class Traits>
+    void basic_path<String, Traits>::m_append( value_type value )
+    {
+#   ifdef BOOST_CYGWIN_PATH
+      if ( m_path.empty() ) m_cygwin_root = (value == slash<path_type>::value);
+#   endif
+
+#   ifdef BOOST_WINDOWS_PATH
+      // for BOOST_WINDOWS_PATH, convert alt_separator ('\') to separator ('/')
+      m_path += ( value == path_alt_separator<path_type>::value
+        ? slash<path_type>::value
+        : value );
+#   else
+      m_path += value;
+#   endif
+    }
+    
+    // except that it wouldn't work for BOOST_NO_MEMBER_TEMPLATES compilers,
+    // the append() member template could replace this code.
+    template<class String, class Traits>
+    basic_path<String, Traits> & basic_path<String, Traits>::operator /=
+      ( const value_type * next_p )
+    {
+      // ignore escape sequence on POSIX or Windows
+      if ( *next_p == slash<path_type>::value
+        && *(next_p+1) == slash<path_type>::value
+        && *(next_p+2) == colon<path_type>::value ) next_p += 3;
+      
+      // append slash<path_type>::value if needed
+      if ( !empty() && *next_p != 0
+        && !detail::is_separator<path_type>( *next_p ) )
+      { m_append_separator_if_needed(); }
+
+      for ( ; *next_p != 0; ++next_p ) m_append( *next_p );
+      return *this;
+    }
+
+# ifndef BOOST_NO_MEMBER_TEMPLATES
+    template<class String, class Traits> template <class InputIterator>
+      basic_path<String, Traits> & basic_path<String, Traits>::append(
+        InputIterator first, InputIterator last )
+    {
+      // append slash<path_type>::value if needed
+      if ( !empty() && first != last
+        && !detail::is_separator<path_type>( *first ) )
+      { m_append_separator_if_needed(); }
+
+      // song-and-dance to avoid violating InputIterator requirements
+      // (which prohibit lookahead) in detecting a possible escape sequence
+      // (escape sequences are simply ignored on POSIX and Windows)
+      bool was_escape_sequence(true);
+      std::size_t append_count(0);
+      typename String::size_type initial_pos( m_path.size() );
+
+      for ( ; first != last && *first; ++first )
+      {
+        if ( append_count == 0 && *first != slash<path_type>::value )
+          was_escape_sequence = false;
+        if ( append_count == 1 && *first != slash<path_type>::value )
+          was_escape_sequence = false;
+        if ( append_count == 2 && *first != colon<path_type>::value )
+          was_escape_sequence = false;
+        m_append( *first );
+        ++append_count;
+      }
+
+      // erase escape sequence if any
+      if ( was_escape_sequence && append_count >= 3 )
+        m_path.erase( initial_pos, 3 );
+
+      return *this;
+    }
+# endif
+
+# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
+
+    // canonize  ------------------------------------------------------------//
+
+    template<class String, class Traits>
+    basic_path<String, Traits> & basic_path<String, Traits>::canonize()
+    {
+      static const typename string_type::value_type dot_str[]
+        = { dot<path_type>::value, 0 };
+
+      if ( m_path.empty() ) return *this;
+        
+      path_type temp;
+
+      for ( iterator itr( begin() ); itr != end(); ++itr )
+      {
+        temp /= *itr;
+      };
+
+      if ( temp.empty() ) temp /= dot_str;
+      m_path = temp.m_path;
+      return *this;
+    }
+
+    // normalize  ------------------------------------------------------------//
+
+    template<class String, class Traits>
+    basic_path<String, Traits> & basic_path<String, Traits>::normalize()
+    {
+      static const typename string_type::value_type dot_str[]
+        = { dot<path_type>::value, 0 };
+
+      if ( m_path.empty() ) return *this;
+        
+      path_type temp;
+      iterator start( begin() );
+      iterator last( end() );
+      iterator stop( last-- );
+      for ( iterator itr( start ); itr != stop; ++itr )
+      {
+        // ignore "." except at start and last
+        if ( itr->size() == 1
+          && (*itr)[0] == dot<path_type>::value
+          && itr != start
+          && itr != last ) continue;
+
+        // ignore a name and following ".."
+        if ( !temp.empty()
+          && itr->size() == 2
+          && (*itr)[0] == dot<path_type>::value
+          && (*itr)[1] == dot<path_type>::value ) // dot dot
+        {
+          string_type lf( temp.filename() );  
+          if ( lf.size() > 0  
+            && (lf.size() != 1
+              || (lf[0] != dot<path_type>::value
+                && lf[0] != slash<path_type>::value))
+            && (lf.size() != 2 
+              || (lf[0] != dot<path_type>::value
+                && lf[1] != dot<path_type>::value
+#             ifdef BOOST_WINDOWS_PATH
+                && lf[1] != colon<path_type>::value
+#             endif
+                 )
+               )
+            )
+          {
+            temp.remove_filename();
+            // if not root directory, must also remove "/" if any
+            if ( temp.m_path.size() > 0
+              && temp.m_path[temp.m_path.size()-1]
+                == slash<path_type>::value )
+            {
+              typename string_type::size_type rds(
+                detail::root_directory_start<String,Traits>( temp.m_path,
+                  temp.m_path.size() ) );
+              if ( rds == string_type::npos
+                || rds != temp.m_path.size()-1 ) 
+                { temp.m_path.erase( temp.m_path.size()-1 ); }
+            }
+
+            iterator next( itr );
+            if ( temp.empty() && ++next != stop
+              && next == last && *last == dot_str ) temp /= dot_str;
+            continue;
+          }
+        }
+
+        temp /= *itr;
+      };
+
+      if ( temp.empty() ) temp /= dot_str;
+      m_path = temp.m_path;
+      return *this;
+    }
+
+# endif
+
+    // modifiers  ------------------------------------------------------------//
+
+    template<class String, class Traits>
+    basic_path<String, Traits> & basic_path<String, Traits>::remove_filename()
+    {
+      m_path.erase(
+        detail::filename_pos<String, Traits>( m_path, m_path.size() ) );
+      return *this;
+    }
+
+    template<class String, class Traits>
+    basic_path<String, Traits> &
+    basic_path<String, Traits>::replace_extension( const string_type & new_ext )
+    {
+      // erase existing extension if any
+      string_type old_ext = extension();
+      if ( !old_ext.empty() )
+        m_path.erase( m_path.size() - old_ext.size() );
+
+      if ( !new_ext.empty() && new_ext[0] != dot<path_type>::value )
+        m_path += dot<path_type>::value;
+
+      m_path += new_ext;
+
+      return *this;
+    }
+
+
+    // path conversion functions  --------------------------------------------//
+
+    template<class String, class Traits>
+    const String
+    basic_path<String, Traits>::file_string() const
+    {
+#   ifdef BOOST_WINDOWS_PATH
+      // for Windows, use the alternate separator, and bypass extra 
+      // root separators
+
+      typename string_type::size_type root_dir_start(
+        detail::root_directory_start<String, Traits>( m_path, m_path.size() ) );
+      bool in_root( root_dir_start != string_type::npos );
+      String s;
+      for ( typename string_type::size_type pos( 0 );
+        pos != m_path.size(); ++pos )
+      {
+        // special case // [net]
+        if ( pos == 0 && m_path.size() > 1
+          && m_path[0] == slash<path_type>::value
+          && m_path[1] == slash<path_type>::value
+          && ( m_path.size() == 2 
+            || !detail::is_separator<path_type>( m_path[2] )
+             ) )
+        {
+          ++pos;
+          s += path_alt_separator<path_type>::value;
+          s += path_alt_separator<path_type>::value;
+          continue;
+        }   
+
+        // bypass extra root separators
+        if ( in_root )
+        { 
+          if ( s.size() > 0
+            && s[s.size()-1] == path_alt_separator<path_type>::value
+            && m_path[pos] == slash<path_type>::value
+            ) continue;
+        }
+
+        if ( m_path[pos] == slash<path_type>::value )
+          s += path_alt_separator<path_type>::value;
+        else
+          s += m_path[pos];
+
+        if ( pos > root_dir_start
+          && m_path[pos] == slash<path_type>::value )
+          { in_root = false; }
+      }
+#   ifdef BOOST_CYGWIN_PATH
+      if ( m_cygwin_root ) s[0] = slash<path_type>::value;
+#   endif
+      return s;
+#   else
+      return m_path;
+#   endif
+    }
+
+    // iterator functions  ---------------------------------------------------//
+
+    template<class String, class Traits>
+    typename basic_path<String, Traits>::iterator basic_path<String, Traits>::begin() const
+    {
+      iterator itr;
+      itr.m_path_ptr = this;
+      typename string_type::size_type element_size;
+      detail::first_element<String, Traits>( m_path, itr.m_pos, element_size );
+      itr.m_name = m_path.substr( itr.m_pos, element_size );
+      return itr;
+    }
+
+    template<class String, class Traits>
+    typename basic_path<String, Traits>::iterator basic_path<String, Traits>::end() const
+      {
+        iterator itr;
+        itr.m_path_ptr = this;
+        itr.m_pos = m_path.size();
+        return itr;
+      }
+
+    namespace detail
+    {
+      //  do_increment  ------------------------------------------------------//
+
+      template<class Path>
+      void iterator_helper<Path>::do_increment( iterator & itr )
+      {
+        typedef typename Path::string_type string_type;
+        typedef typename Path::traits_type traits_type;
+
+        assert( itr.m_pos < itr.m_path_ptr->m_path.size() && "basic_path::iterator increment past end()" );
+
+        bool was_net( itr.m_name.size() > 2
+          && itr.m_name[0] == slash<Path>::value
+          && itr.m_name[1] == slash<Path>::value
+          && itr.m_name[2] != slash<Path>::value );
+
+        // increment to position past current element
+        itr.m_pos += itr.m_name.size();
+
+        // if end reached, create end iterator
+        if ( itr.m_pos == itr.m_path_ptr->m_path.size() )
+        {
+          itr.m_name.erase( itr.m_name.begin(), itr.m_name.end() ); // VC++ 6.0 lib didn't supply clear() 
+          return;
+        }
+
+        // process separator (Windows drive spec is only case not a separator)
+        if ( itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value )
+        {
+          // detect root directory
+          if ( was_net
+  #       ifdef BOOST_WINDOWS_PATH
+            // case "c:/"
+            || itr.m_name[itr.m_name.size()-1] == colon<Path>::value
+  #       endif
+             )
+          {
+            itr.m_name = slash<Path>::value;
+            return;
+          }
+
+          // bypass separators
+          while ( itr.m_pos != itr.m_path_ptr->m_path.size()
+            && itr.m_path_ptr->m_path[itr.m_pos] == slash<Path>::value )
+            { ++itr.m_pos; }
+
+          // detect trailing separator, and treat it as ".", per POSIX spec
+          if ( itr.m_pos == itr.m_path_ptr->m_path.size()
+            && detail::is_non_root_slash< string_type, traits_type >(
+                itr.m_path_ptr->m_path, itr.m_pos-1 ) ) 
+          {
+            --itr.m_pos;
+            itr.m_name = dot<Path>::value;
+            return;
+          }
+        }
+
+        // get next element
+        typename string_type::size_type end_pos(
+          itr.m_path_ptr->m_path.find( slash<Path>::value, itr.m_pos ) );
+        itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos );
+      } 
+
+      //  do_decrement  ------------------------------------------------------//
+
+      template<class Path>
+      void iterator_helper<Path>::do_decrement( iterator & itr )
+      {                                                                                
+        assert( itr.m_pos && "basic_path::iterator decrement past begin()"  );
+
+        typedef typename Path::string_type string_type;
+        typedef typename Path::traits_type traits_type;
+
+        typename string_type::size_type end_pos( itr.m_pos );
+
+        typename string_type::size_type root_dir_pos(
+          detail::root_directory_start<string_type, traits_type>(
+            itr.m_path_ptr->m_path, end_pos ) );
+
+        // if at end and there was a trailing non-root '/', return "."
+        if ( itr.m_pos == itr.m_path_ptr->m_path.size()
+          && itr.m_path_ptr->m_path.size() > 1
+          && itr.m_path_ptr->m_path[itr.m_pos-1] == slash<Path>::value
+          && detail::is_non_root_slash< string_type, traits_type >(
+               itr.m_path_ptr->m_path, itr.m_pos-1 ) 
+           )
+        {
+          --itr.m_pos;
+            itr.m_name = dot<Path>::value;
+            return;
+        }
+
+        // skip separators unless root directory
+        for ( 
+          ; 
+          end_pos > 0
+          && (end_pos-1) != root_dir_pos
+          && itr.m_path_ptr->m_path[end_pos-1] == slash<Path>::value
+          ;
+          --end_pos ) {}
+
+        itr.m_pos = detail::filename_pos<string_type, traits_type>
+            ( itr.m_path_ptr->m_path, end_pos );
+        itr.m_name = itr.m_path_ptr->m_path.substr( itr.m_pos, end_pos - itr.m_pos );
+      }
+    } // namespace detail
+
+    //  basic_filesystem_error implementation --------------------------------//
+
+    template<class Path>
+    basic_filesystem_error<Path>::basic_filesystem_error(
+      const std::string & what_arg, system::error_code ec )
+      : system::system_error(ec, what_arg)
+    {
+      try
+      {
+        m_imp_ptr.reset( new m_imp );
+      }
+      catch (...) { m_imp_ptr.reset(); }
+    }
+
+    template<class Path>
+    basic_filesystem_error<Path>::basic_filesystem_error(
+      const std::string & what_arg, const path_type & path1_arg,
+      system::error_code ec )
+      : system::system_error(ec, what_arg)
+    {
+      try
+      {
+        m_imp_ptr.reset( new m_imp );
+        m_imp_ptr->m_path1 = path1_arg;
+      }
+      catch (...) { m_imp_ptr.reset(); }
+    }
+
+    template<class Path>
+    basic_filesystem_error<Path>::basic_filesystem_error(
+      const std::string & what_arg, const path_type & path1_arg,
+      const path_type & path2_arg, system::error_code ec )
+      : system::system_error(ec, what_arg)
+    {
+      try
+      {
+        m_imp_ptr.reset( new m_imp );
+        m_imp_ptr->m_path1 = path1_arg;
+        m_imp_ptr->m_path2 = path2_arg;
+      }
+      catch (...) { m_imp_ptr.reset(); }
+    }
+
+  } // namespace BOOST_FILESYSTEM_NAMESPACE
+} // namespace boost
+
+#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
+
+#endif // BOOST_FILESYSTEM_PATH_HPP