//  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_FILESYSTEM2_PATH_HPP
#define BOOST_FILESYSTEM2_PATH_HPP

#include <boost/filesystem/v2/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_FILESYSTEM2_NARROW_ONLY
#   include <locale>
# endif

#include <boost/config/abi_prefix.hpp> // must be the last #include

namespace boost
{
  namespace BOOST_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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 clear()
      { 
#     if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, >= 310)
        m_path.clear();
#     else
        m_path.erase( m_path.begin(), m_path.end() );
#     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_FILESYSTEM2_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_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>;

        void increment()
        { 
          boost::BOOST_FILESYSTEM2_NAMESPACE::detail::iterator_helper<path_type>::do_increment(
            *this );
        }
        void decrement()
        { 
          boost::BOOST_FILESYSTEM2_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_FILESYSTEM2_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 hand-written compare rather than !(lhs < rhs) && !(rhs < lhs)
    //  because the result is the same yet the direct compare is much more efficient
    //  than lexicographical_compare, which would also be called twice.

    template< class String, class Traits >
    inline bool operator==( const basic_path<String, Traits> & lhs,
                    const typename basic_path<String, Traits>::string_type::value_type * rhs )
    {
      typedef typename
        boost::BOOST_FILESYSTEM2_NAMESPACE::basic_path<String, Traits> path_type;
      const typename path_type::string_type::value_type * l (lhs.string().c_str());
      while ( (*l == *rhs
#      ifdef BOOST_WINDOWS_PATH
        || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) 
            || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value)
#      endif
        ) && *l ) { ++l; ++rhs; }
      return *l == *rhs
#      ifdef BOOST_WINDOWS_PATH
        || (*l == path_alt_separator<path_type>::value && *rhs == slash<path_type>::value) 
          || (*l == slash<path_type>::value && *rhs == path_alt_separator<path_type>::value)
#      endif
        ;  
    }

    template< class String, class Traits >
    inline bool operator==( const basic_path<String, Traits> & lhs,
                            const basic_path<String, Traits> & rhs )
    { 
      return lhs == rhs.string().c_str();
    }

    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 == 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 == lhs.c_str();
    }

    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.c_str();
    }

    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;
      std::getline(is, str);  // See ticket 3863
      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;
      std::getline(is, str);  // See ticket 3863
      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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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_FILESYSTEM2_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(dot<path_type>::value);
      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(dot<path_type>::value);
      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_FILESYSTEM2_NAMESPACE
} // namespace boost

//----------------------------------------------------------------------------//

namespace boost
{
  namespace filesystem
  {
    using filesystem2::basic_path;
    using filesystem2::path_traits;

    using filesystem2::slash;
    using filesystem2::dot;
    using filesystem2::colon;

    using filesystem2::path;
# ifndef BOOST_FILESYSTEM2_NARROW_ONLY
    using filesystem2::wpath_traits;
    using filesystem2::wpath;
    using filesystem2::wfilesystem_error;
# endif
    using filesystem2::basic_filesystem_error;
    using filesystem2::filesystem_error;
    using filesystem2::portable_posix_name;
    using filesystem2::windows_name;
    using filesystem2::portable_name;
    using filesystem2::portable_directory_name;
    using filesystem2::portable_file_name;
    using filesystem2::native;
    using filesystem2::no_check;
    using filesystem2::swap;
    using filesystem2::operator<;
    using filesystem2::operator==;
    using filesystem2::operator!=;
    using filesystem2::operator>;
    using filesystem2::operator<=;
    using filesystem2::operator>=;
    using filesystem2::operator/;
    using filesystem2::operator<<;
    using filesystem2::operator>>;
  }
}

//----------------------------------------------------------------------------//

#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas

#endif // BOOST_FILESYSTEM2_PATH_HPP
