Warning, file /include/boost/filesystem/path.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 
0012 
0013 
0014 
0015 
0016 #ifndef BOOST_FILESYSTEM_PATH_HPP
0017 #define BOOST_FILESYSTEM_PATH_HPP
0018 
0019 #include <boost/filesystem/config.hpp>
0020 #include <cstddef>
0021 #include <iosfwd>
0022 #include <locale>
0023 #include <string>
0024 #include <iterator>
0025 #include <type_traits>
0026 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0027 #include <string_view>
0028 #endif
0029 #include <boost/assert.hpp>
0030 #include <boost/iterator/iterator_facade.hpp>
0031 #include <boost/iterator/iterator_categories.hpp>
0032 #include <boost/io/quoted.hpp>
0033 #include <boost/functional/hash_fwd.hpp>
0034 #include <boost/filesystem/detail/path_traits.hpp>
0035 #include <boost/filesystem/detail/type_traits/negation.hpp>
0036 #include <boost/filesystem/detail/type_traits/conjunction.hpp>
0037 #include <boost/filesystem/detail/type_traits/disjunction.hpp>
0038 
0039 #include <boost/filesystem/detail/header.hpp> // must be the last #include
0040 
0041 namespace boost {
0042 namespace filesystem {
0043 
0044 class path;
0045 
0046 namespace path_detail { 
0047 
0048 template< typename Char, Char Separator, Char PreferredSeparator, Char Dot >
0049 struct path_constants
0050 {
0051     typedef path_constants< Char, Separator, PreferredSeparator, Dot > path_constants_base;
0052     typedef Char value_type;
0053     static BOOST_CONSTEXPR_OR_CONST value_type separator = Separator;
0054     static BOOST_CONSTEXPR_OR_CONST value_type preferred_separator = PreferredSeparator;
0055     static BOOST_CONSTEXPR_OR_CONST value_type dot = Dot;
0056 };
0057 
0058 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
0059 template< typename Char, Char Separator, Char PreferredSeparator, Char Dot >
0060 BOOST_CONSTEXPR_OR_CONST typename path_constants< Char, Separator, PreferredSeparator, Dot >::value_type
0061 path_constants< Char, Separator, PreferredSeparator, Dot >::separator;
0062 template< typename Char, Char Separator, Char PreferredSeparator, Char Dot >
0063 BOOST_CONSTEXPR_OR_CONST typename path_constants< Char, Separator, PreferredSeparator, Dot >::value_type
0064 path_constants< Char, Separator, PreferredSeparator, Dot >::preferred_separator;
0065 template< typename Char, Char Separator, Char PreferredSeparator, Char Dot >
0066 BOOST_CONSTEXPR_OR_CONST typename path_constants< Char, Separator, PreferredSeparator, Dot >::value_type
0067 path_constants< Char, Separator, PreferredSeparator, Dot >::dot;
0068 #endif
0069 
0070 class path_iterator;
0071 class path_reverse_iterator;
0072 
0073 } 
0074 
0075 namespace detail {
0076 
0077 struct path_algorithms
0078 {
0079     
0080     struct substring
0081     {
0082         std::size_t pos;
0083         std::size_t size;
0084     };
0085 
0086     typedef path_traits::path_native_char_type value_type;
0087     typedef std::basic_string< value_type > string_type;
0088 
0089     static bool has_filename_v3(path const& p);
0090     static bool has_filename_v4(path const& p);
0091     BOOST_FILESYSTEM_DECL static path filename_v3(path const& p);
0092     static path filename_v4(path const& p);
0093 
0094     BOOST_FILESYSTEM_DECL static path stem_v3(path const& p);
0095     BOOST_FILESYSTEM_DECL static path stem_v4(path const& p);
0096     BOOST_FILESYSTEM_DECL static path extension_v3(path const& p);
0097     static path extension_v4(path const& p);
0098 
0099     BOOST_FILESYSTEM_DECL static void remove_filename_v3(path& p);
0100     BOOST_FILESYSTEM_DECL static void remove_filename_v4(path& p);
0101 
0102     BOOST_FILESYSTEM_DECL static void replace_extension_v3(path& p, path const& new_extension);
0103     BOOST_FILESYSTEM_DECL static void replace_extension_v4(path& p, path const& new_extension);
0104 
0105     BOOST_FILESYSTEM_DECL static path lexically_normal_v3(path const& p);
0106     BOOST_FILESYSTEM_DECL static path lexically_normal_v4(path const& p);
0107 
0108     BOOST_FILESYSTEM_DECL static path generic_path_v3(path const& p);
0109     BOOST_FILESYSTEM_DECL static path generic_path_v4(path const& p);
0110 
0111 #if defined(BOOST_WINDOWS_API)
0112     BOOST_FILESYSTEM_DECL static void make_preferred_v3(path& p);
0113     BOOST_FILESYSTEM_DECL static void make_preferred_v4(path& p);
0114 #endif
0115 
0116     BOOST_FILESYSTEM_DECL static int compare_v3(path const& left, path const& right);
0117     BOOST_FILESYSTEM_DECL static int compare_v4(path const& left, path const& right);
0118 
0119     BOOST_FILESYSTEM_DECL static void append_v3(path& p, const value_type* b, const value_type* e);
0120     BOOST_FILESYSTEM_DECL static void append_v4(path& p, const value_type* b, const value_type* e);
0121     static void append_v4(path& left, path const& right);
0122 
0123     
0124     
0125     BOOST_FILESYSTEM_DECL static string_type::size_type append_separator_if_needed(path& p);
0126     BOOST_FILESYSTEM_DECL static void erase_redundant_separator(path& p, string_type::size_type sep_pos);
0127 
0128     BOOST_FILESYSTEM_DECL static string_type::size_type find_root_name_size(path const& p);
0129     BOOST_FILESYSTEM_DECL static string_type::size_type find_root_path_size(path const& p);
0130     BOOST_FILESYSTEM_DECL static substring find_root_directory(path const& p);
0131     BOOST_FILESYSTEM_DECL static substring find_relative_path(path const& p);
0132     BOOST_FILESYSTEM_DECL static string_type::size_type find_parent_path_size(path const& p);
0133     BOOST_FILESYSTEM_DECL static string_type::size_type find_filename_v4_size(path const& p);
0134     BOOST_FILESYSTEM_DECL static string_type::size_type find_extension_v4_size(path const& p);
0135 
0136     BOOST_FILESYSTEM_DECL static int lex_compare_v3
0137     (
0138         path_detail::path_iterator first1, path_detail::path_iterator const& last1,
0139         path_detail::path_iterator first2, path_detail::path_iterator const& last2
0140     );
0141     BOOST_FILESYSTEM_DECL static int lex_compare_v4
0142     (
0143         path_detail::path_iterator first1, path_detail::path_iterator const& last1,
0144         path_detail::path_iterator first2, path_detail::path_iterator const& last2
0145     );
0146 
0147     BOOST_FILESYSTEM_DECL static void increment_v3(path_detail::path_iterator& it);
0148     BOOST_FILESYSTEM_DECL static void increment_v4(path_detail::path_iterator& it);
0149     BOOST_FILESYSTEM_DECL static void decrement_v3(path_detail::path_iterator& it);
0150     BOOST_FILESYSTEM_DECL static void decrement_v4(path_detail::path_iterator& it);
0151 };
0152 
0153 } 
0154 
0155 
0156 
0157 
0158 
0159 
0160 
0161 class path :
0162     public filesystem::path_detail::path_constants<
0163 #ifdef BOOST_WINDOWS_API
0164         detail::path_traits::path_native_char_type, L'/', L'\\', L'.'
0165 #else
0166         detail::path_traits::path_native_char_type, '/', '/', '.'
0167 #endif
0168     >
0169 {
0170     friend class path_detail::path_iterator;
0171     friend class path_detail::path_reverse_iterator;
0172     friend struct detail::path_algorithms;
0173 
0174 public:
0175     
0176     
0177 
0178     typedef detail::path_algorithms::value_type value_type;
0179     typedef detail::path_algorithms::string_type string_type;
0180     typedef detail::path_traits::codecvt_type codecvt_type;
0181 
0182     
0183 
0184     
0185     
0186     
0187     
0188     
0189     
0190     
0191     
0192     
0193     
0194     
0195     
0196     
0197     
0198     
0199     
0200     
0201     
0202     
0203     
0204     
0205     
0206     
0207 
0208     
0209     
0210     
0211     
0212     
0213     
0214     
0215     
0216     
0217     
0218     
0219     
0220     
0221     
0222     
0223     
0224 
0225     
0226     
0227 
0228     
0229     
0230     
0231 
0232     
0233     
0234     
0235     
0236 
0237 private:
0238     
0239     class assign_op
0240     {
0241     private:
0242         path& m_self;
0243 
0244     public:
0245         typedef void result_type;
0246 
0247         explicit assign_op(path& self) noexcept : m_self(self) {}
0248 
0249         result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = nullptr) const
0250         {
0251             m_self.m_pathname.assign(source, source_end);
0252         }
0253 
0254         template< typename OtherChar >
0255         result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = nullptr) const
0256         {
0257             m_self.m_pathname.clear();
0258             detail::path_traits::convert(source, source_end, m_self.m_pathname, cvt);
0259         }
0260     };
0261 
0262     
0263     class concat_op
0264     {
0265     private:
0266         path& m_self;
0267 
0268     public:
0269         typedef void result_type;
0270 
0271         explicit concat_op(path& self) noexcept : m_self(self) {}
0272 
0273         result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = nullptr) const
0274         {
0275             m_self.m_pathname.append(source, source_end);
0276         }
0277 
0278         template< typename OtherChar >
0279         result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = nullptr) const
0280         {
0281             detail::path_traits::convert(source, source_end, m_self.m_pathname, cvt);
0282         }
0283     };
0284 
0285     
0286     class append_op
0287     {
0288     private:
0289         path& m_self;
0290 
0291     public:
0292         typedef void result_type;
0293 
0294         explicit append_op(path& self) noexcept : m_self(self) {}
0295 
0296         BOOST_FORCEINLINE result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = nullptr) const
0297         {
0298             m_self.append(source, source_end);
0299         }
0300 
0301         template< typename OtherChar >
0302         BOOST_FORCEINLINE result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = nullptr) const
0303         {
0304             string_type src;
0305             detail::path_traits::convert(source, source_end, src, cvt);
0306             m_self.append(src.data(), src.data() + src.size());
0307         }
0308     };
0309 
0310     
0311     class compare_op
0312     {
0313     private:
0314         path const& m_self;
0315 
0316     public:
0317         typedef int result_type;
0318 
0319         explicit compare_op(path const& self) noexcept : m_self(self) {}
0320 
0321         result_type operator() (const value_type* source, const value_type* source_end, const codecvt_type* = nullptr) const;
0322 
0323         template< typename OtherChar >
0324         result_type operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt = nullptr) const;
0325     };
0326 
0327 public:
0328     typedef path_detail::path_iterator iterator;
0329     typedef iterator const_iterator;
0330     typedef path_detail::path_reverse_iterator reverse_iterator;
0331     typedef reverse_iterator const_reverse_iterator;
0332 
0333 public:
0334     
0335 
0336     path() noexcept {}
0337     path(path const& p) : m_pathname(p.m_pathname) {}
0338     path(path const& p, codecvt_type const&) : m_pathname(p.m_pathname) {}
0339 
0340     path(const value_type* s) : m_pathname(s) {}
0341     path(const value_type* s, codecvt_type const&) : m_pathname(s) {}
0342     path(string_type const& s) : m_pathname(s) {}
0343     path(string_type const& s, codecvt_type const&) : m_pathname(s) {}
0344 #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
0345     path(std::basic_string_view< value_type > const& s) : m_pathname(s) {}
0346     path(std::basic_string_view< value_type > const& s, codecvt_type const&) : m_pathname(s) {}
0347 #endif
0348 
0349     template<
0350         typename Source,
0351         typename = typename std::enable_if<
0352             detail::conjunction<
0353                 detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >,
0354                 detail::negation< detail::path_traits::is_native_path_source< typename std::remove_cv< Source >::type > >
0355             >::value
0356         >::type
0357     >
0358     path(Source const& source)
0359     {
0360         assign(source);
0361     }
0362 
0363     template<
0364         typename Source,
0365         typename = typename std::enable_if<
0366             detail::conjunction<
0367                 detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >,
0368                 detail::negation< detail::path_traits::is_native_path_source< typename std::remove_cv< Source >::type > >
0369             >::value
0370         >::type
0371     >
0372     explicit path(Source const& source, codecvt_type const& cvt)
0373     {
0374         assign(source, cvt);
0375     }
0376 
0377     path(path&& p) noexcept : m_pathname(static_cast< string_type&& >(p.m_pathname))
0378     {
0379     }
0380     path(path&& p, codecvt_type const&) noexcept : m_pathname(static_cast< string_type&& >(p.m_pathname))
0381     {
0382     }
0383     path& operator=(path&& p) noexcept
0384     {
0385         m_pathname = static_cast< string_type&& >(p.m_pathname);
0386         return *this;
0387     }
0388     path& assign(path&& p) noexcept
0389     {
0390         m_pathname = static_cast< string_type&& >(p.m_pathname);
0391         return *this;
0392     }
0393     path& assign(path&& p, codecvt_type const&) noexcept
0394     {
0395         m_pathname = static_cast< string_type&& >(p.m_pathname);
0396         return *this;
0397     }
0398 
0399     path(string_type&& s) noexcept : m_pathname(static_cast< string_type&& >(s))
0400     {
0401     }
0402     path(string_type&& s, codecvt_type const&) noexcept : m_pathname(static_cast< string_type&& >(s))
0403     {
0404     }
0405     path& operator=(string_type&& p) noexcept
0406     {
0407         m_pathname = static_cast< string_type&& >(p);
0408         return *this;
0409     }
0410     path& assign(string_type&& p) noexcept
0411     {
0412         m_pathname = static_cast< string_type&& >(p);
0413         return *this;
0414     }
0415     path& assign(string_type&& p, codecvt_type const&) noexcept
0416     {
0417         m_pathname = static_cast< string_type&& >(p);
0418         return *this;
0419     }
0420 
0421     path(const value_type* begin, const value_type* end) : m_pathname(begin, end) {}
0422     path(const value_type* begin, const value_type* end, codecvt_type const&) : m_pathname(begin, end) {}
0423 
0424     template<
0425         typename InputIterator,
0426         typename = typename std::enable_if<
0427             detail::conjunction<
0428                 detail::path_traits::is_path_source_iterator< InputIterator >,
0429                 detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0430             >::value
0431         >::type
0432     >
0433     path(InputIterator begin, InputIterator end)
0434     {
0435         if (begin != end)
0436         {
0437             typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t;
0438             source_t source(begin, end);
0439             assign(static_cast< source_t&& >(source));
0440         }
0441     }
0442 
0443     template<
0444         typename InputIterator,
0445         typename = typename std::enable_if<
0446             detail::conjunction<
0447                 detail::path_traits::is_path_source_iterator< InputIterator >,
0448                 detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0449             >::value
0450         >::type
0451     >
0452     path(InputIterator begin, InputIterator end, codecvt_type const& cvt)
0453     {
0454         if (begin != end)
0455         {
0456             typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t;
0457             source_t source(begin, end);
0458             assign(static_cast< source_t&& >(source), cvt);
0459         }
0460     }
0461 
0462     path(std::nullptr_t) = delete;
0463     path& operator= (std::nullptr_t) = delete;
0464 
0465 public:
0466     
0467 
0468     
0469     path& operator=(path const& p);
0470 
0471     template< typename Source >
0472     typename std::enable_if<
0473         detail::disjunction<
0474             detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >,
0475             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
0476         >::value,
0477         path&
0478     >::type operator=(Source const& source)
0479     {
0480         return assign(source);
0481     }
0482 
0483     path& assign(path const& p)
0484     {
0485         m_pathname = p.m_pathname;
0486         return *this;
0487     }
0488 
0489     template< typename Source >
0490     typename std::enable_if<
0491         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0492         path&
0493     >::type assign(Source const& source)
0494     {
0495         detail::path_traits::dispatch(source, assign_op(*this));
0496         return *this;
0497     }
0498 
0499     template< typename Source >
0500     typename std::enable_if<
0501         detail::conjunction<
0502             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0503             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0504         >::value,
0505         path&
0506     >::type assign(Source const& source)
0507     {
0508         detail::path_traits::dispatch_convertible(source, assign_op(*this));
0509         return *this;
0510     }
0511 
0512     path& assign(path const& p, codecvt_type const&)
0513     {
0514         m_pathname = p.m_pathname;
0515         return *this;
0516     }
0517 
0518     template< typename Source >
0519     typename std::enable_if<
0520         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0521         path&
0522     >::type assign(Source const& source, codecvt_type const& cvt)
0523     {
0524         detail::path_traits::dispatch(source, assign_op(*this), &cvt);
0525         return *this;
0526     }
0527 
0528     template< typename Source >
0529     typename std::enable_if<
0530         detail::conjunction<
0531             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0532             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0533         >::value,
0534         path&
0535     >::type assign(Source const& source, codecvt_type const& cvt)
0536     {
0537         detail::path_traits::dispatch_convertible(source, assign_op(*this), &cvt);
0538         return *this;
0539     }
0540 
0541     path& assign(const value_type* begin, const value_type* end)
0542     {
0543         m_pathname.assign(begin, end);
0544         return *this;
0545     }
0546 
0547     template< typename InputIterator >
0548     typename std::enable_if<
0549         detail::conjunction<
0550             detail::path_traits::is_path_source_iterator< InputIterator >,
0551             detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0552         >::value,
0553         path&
0554     >::type assign(InputIterator begin, InputIterator end)
0555     {
0556         m_pathname.clear();
0557         if (begin != end)
0558         {
0559             typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t;
0560             source_t source(begin, end);
0561             assign(static_cast< source_t&& >(source));
0562         }
0563         return *this;
0564     }
0565 
0566     path& assign(const value_type* begin, const value_type* end, codecvt_type const&)
0567     {
0568         m_pathname.assign(begin, end);
0569         return *this;
0570     }
0571 
0572     template< typename InputIterator >
0573     typename std::enable_if<
0574         detail::conjunction<
0575             detail::path_traits::is_path_source_iterator< InputIterator >,
0576             detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0577         >::value,
0578         path&
0579     >::type assign(InputIterator begin, InputIterator end, codecvt_type const& cvt)
0580     {
0581         m_pathname.clear();
0582         if (begin != end)
0583         {
0584             typedef std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source_t;
0585             source_t source(begin, end);
0586             assign(static_cast< source_t&& >(source), cvt);
0587         }
0588         return *this;
0589     }
0590 
0591     
0592 
0593     path& operator+=(path const& p);
0594 
0595     template< typename Source >
0596     typename std::enable_if<
0597         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >::value,
0598         path&
0599     >::type operator+=(Source const& source)
0600     {
0601         return concat(source);
0602     }
0603 
0604     path& operator+=(value_type c)
0605     {
0606         m_pathname.push_back(c);
0607         return *this;
0608     }
0609 
0610     template< typename CharT >
0611     typename std::enable_if<
0612         detail::path_traits::is_path_char_type< CharT >::value,
0613         path&
0614     >::type operator+=(CharT c)
0615     {
0616         CharT tmp[2];
0617         tmp[0] = c;
0618         tmp[1] = static_cast< CharT >(0);
0619         concat_op(*this)(tmp, tmp + 1);
0620         return *this;
0621     }
0622 
0623     path& concat(path const& p)
0624     {
0625         m_pathname.append(p.m_pathname);
0626         return *this;
0627     }
0628 
0629     template< typename Source >
0630     typename std::enable_if<
0631         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0632         path&
0633     >::type concat(Source const& source)
0634     {
0635         detail::path_traits::dispatch(source, concat_op(*this));
0636         return *this;
0637     }
0638 
0639     template< typename Source >
0640     typename std::enable_if<
0641         detail::conjunction<
0642             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0643             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0644         >::value,
0645         path&
0646     >::type concat(Source const& source)
0647     {
0648         detail::path_traits::dispatch_convertible(source, concat_op(*this));
0649         return *this;
0650     }
0651 
0652     path& concat(path const& p, codecvt_type const&)
0653     {
0654         m_pathname.append(p.m_pathname);
0655         return *this;
0656     }
0657 
0658     template< typename Source >
0659     typename std::enable_if<
0660         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0661         path&
0662     >::type concat(Source const& source, codecvt_type const& cvt)
0663     {
0664         detail::path_traits::dispatch(source, concat_op(*this), &cvt);
0665         return *this;
0666     }
0667 
0668     template< typename Source >
0669     typename std::enable_if<
0670         detail::conjunction<
0671             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0672             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0673         >::value,
0674         path&
0675     >::type concat(Source const& source, codecvt_type const& cvt)
0676     {
0677         detail::path_traits::dispatch_convertible(source, concat_op(*this), &cvt);
0678         return *this;
0679     }
0680 
0681     path& concat(const value_type* begin, const value_type* end)
0682     {
0683         m_pathname.append(begin, end);
0684         return *this;
0685     }
0686 
0687     template< typename InputIterator >
0688     typename std::enable_if<
0689         detail::conjunction<
0690             detail::path_traits::is_path_source_iterator< InputIterator >,
0691             detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0692         >::value,
0693         path&
0694     >::type concat(InputIterator begin, InputIterator end)
0695     {
0696         if (begin != end)
0697         {
0698             std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end);
0699             detail::path_traits::dispatch(source, concat_op(*this));
0700         }
0701         return *this;
0702     }
0703 
0704     path& concat(const value_type* begin, const value_type* end, codecvt_type const&)
0705     {
0706         m_pathname.append(begin, end);
0707         return *this;
0708     }
0709 
0710     template< typename InputIterator >
0711     typename std::enable_if<
0712         detail::conjunction<
0713             detail::path_traits::is_path_source_iterator< InputIterator >,
0714             detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0715         >::value,
0716         path&
0717     >::type concat(InputIterator begin, InputIterator end, codecvt_type const& cvt)
0718     {
0719         if (begin != end)
0720         {
0721             std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end);
0722             detail::path_traits::dispatch(source, concat_op(*this), &cvt);
0723         }
0724         return *this;
0725     }
0726 
0727     
0728 
0729     
0730     
0731 
0732     path& operator/=(path const& p);
0733 
0734     template< typename Source >
0735     BOOST_FORCEINLINE typename std::enable_if<
0736         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >::value,
0737         path&
0738     >::type operator/=(Source const& source)
0739     {
0740         return append(source);
0741     }
0742 
0743     path& append(path const& p);
0744 
0745     template< typename Source >
0746     BOOST_FORCEINLINE typename std::enable_if<
0747         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0748         path&
0749     >::type append(Source const& source)
0750     {
0751         detail::path_traits::dispatch(source, append_op(*this));
0752         return *this;
0753     }
0754 
0755     template< typename Source >
0756     BOOST_FORCEINLINE typename std::enable_if<
0757         detail::conjunction<
0758             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0759             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0760         >::value,
0761         path&
0762     >::type append(Source const& source)
0763     {
0764         detail::path_traits::dispatch_convertible(source, append_op(*this));
0765         return *this;
0766     }
0767 
0768     path& append(path const& p, codecvt_type const&);
0769 
0770     template< typename Source >
0771     BOOST_FORCEINLINE typename std::enable_if<
0772         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0773         path&
0774     >::type append(Source const& source, codecvt_type const& cvt)
0775     {
0776         detail::path_traits::dispatch(source, append_op(*this), &cvt);
0777         return *this;
0778     }
0779 
0780     template< typename Source >
0781     BOOST_FORCEINLINE typename std::enable_if<
0782         detail::conjunction<
0783             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0784             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0785         >::value,
0786         path&
0787     >::type append(Source const& source, codecvt_type const& cvt)
0788     {
0789         detail::path_traits::dispatch_convertible(source, append_op(*this), &cvt);
0790         return *this;
0791     }
0792 
0793     path& append(const value_type* begin, const value_type* end);
0794 
0795     template< typename InputIterator >
0796     BOOST_FORCEINLINE typename std::enable_if<
0797         detail::conjunction<
0798             detail::path_traits::is_path_source_iterator< InputIterator >,
0799             detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0800         >::value,
0801         path&
0802     >::type append(InputIterator begin, InputIterator end)
0803     {
0804         std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end);
0805         detail::path_traits::dispatch(source, append_op(*this));
0806         return *this;
0807     }
0808 
0809     path& append(const value_type* begin, const value_type* end, codecvt_type const&);
0810 
0811     template< typename InputIterator >
0812     BOOST_FORCEINLINE typename std::enable_if<
0813         detail::conjunction<
0814             detail::path_traits::is_path_source_iterator< InputIterator >,
0815             detail::negation< detail::path_traits::is_native_char_ptr< InputIterator > >
0816         >::value,
0817         path&
0818     >::type append(InputIterator begin, InputIterator end, const codecvt_type& cvt)
0819     {
0820         std::basic_string< typename std::iterator_traits< InputIterator >::value_type > source(begin, end);
0821         detail::path_traits::dispatch(source, append_op(*this), &cvt);
0822         return *this;
0823     }
0824 
0825     
0826 
0827     void clear() noexcept { m_pathname.clear(); }
0828     path& make_preferred();
0829     path& remove_filename();
0830     BOOST_FILESYSTEM_DECL path& remove_filename_and_trailing_separators();
0831     BOOST_FILESYSTEM_DECL path& remove_trailing_separator();
0832     BOOST_FILESYSTEM_DECL path& replace_filename(path const& replacement);
0833     path& replace_extension(path const& new_extension = path());
0834 
0835     void swap(path& rhs) noexcept { m_pathname.swap(rhs.m_pathname); }
0836 
0837     
0838 
0839     
0840     
0841     
0842     
0843 
0844     
0845 
0846     
0847     
0848     
0849     
0850     
0851     
0852     
0853     
0854     
0855 
0856     
0857 
0858     string_type const& native() const noexcept { return m_pathname; }
0859     const value_type* c_str() const noexcept { return m_pathname.c_str(); }
0860     string_type::size_type size() const noexcept { return m_pathname.size(); }
0861 
0862     template< typename String >
0863     String string() const;
0864 
0865     template< typename String >
0866     String string(codecvt_type const& cvt) const;
0867 
0868 #ifdef BOOST_WINDOWS_API
0869     std::string string() const
0870     {
0871         std::string tmp;
0872         if (!m_pathname.empty())
0873             detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp);
0874         return tmp;
0875     }
0876     std::string string(codecvt_type const& cvt) const
0877     {
0878         std::string tmp;
0879         if (!m_pathname.empty())
0880             detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp, &cvt);
0881         return tmp;
0882     }
0883 
0884     
0885     std::wstring const& wstring() const { return m_pathname; }
0886     std::wstring const& wstring(codecvt_type const&) const { return m_pathname; }
0887 #else 
0888     
0889     std::string const& string() const { return m_pathname; }
0890     std::string const& string(codecvt_type const&) const { return m_pathname; }
0891 
0892     std::wstring wstring() const
0893     {
0894         std::wstring tmp;
0895         if (!m_pathname.empty())
0896             detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp);
0897         return tmp;
0898     }
0899     std::wstring wstring(codecvt_type const& cvt) const
0900     {
0901         std::wstring tmp;
0902         if (!m_pathname.empty())
0903             detail::path_traits::convert(m_pathname.data(), m_pathname.data() + m_pathname.size(), tmp, &cvt);
0904         return tmp;
0905     }
0906 #endif
0907 
0908     
0909 
0910     
0911     
0912     
0913     path generic_path() const;
0914 
0915     template< typename String >
0916     String generic_string() const;
0917 
0918     template< typename String >
0919     String generic_string(codecvt_type const& cvt) const;
0920 
0921     std::string generic_string() const { return generic_path().string(); }
0922     std::string generic_string(codecvt_type const& cvt) const { return generic_path().string(cvt); }
0923     std::wstring generic_wstring() const { return generic_path().wstring(); }
0924     std::wstring generic_wstring(codecvt_type const& cvt) const { return generic_path().wstring(cvt); }
0925 
0926     
0927 
0928     int compare(path const& p) const; 
0929 
0930     template< typename Source >
0931     BOOST_FORCEINLINE typename std::enable_if<
0932         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0933         int
0934     >::type compare(Source const& source) const
0935     {
0936         return detail::path_traits::dispatch(source, compare_op(*this));
0937     }
0938 
0939     template< typename Source >
0940     BOOST_FORCEINLINE typename std::enable_if<
0941         detail::conjunction<
0942             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0943             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0944         >::value,
0945         int
0946     >::type compare(Source const& source) const
0947     {
0948         return detail::path_traits::dispatch_convertible(source, compare_op(*this));
0949     }
0950 
0951     template< typename Source >
0952     BOOST_FORCEINLINE typename std::enable_if<
0953         detail::path_traits::is_path_source< typename std::remove_cv< Source >::type >::value,
0954         int
0955     >::type compare(Source const& source, codecvt_type const& cvt) const
0956     {
0957         return detail::path_traits::dispatch(source, compare_op(*this), &cvt);
0958     }
0959 
0960     template< typename Source >
0961     BOOST_FORCEINLINE typename std::enable_if<
0962         detail::conjunction<
0963             detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >,
0964             detail::negation< detail::path_traits::is_path_source< typename std::remove_cv< Source >::type > >
0965         >::value,
0966         int
0967     >::type compare(Source const& source, codecvt_type const& cvt) const
0968     {
0969         return detail::path_traits::dispatch_convertible(source, compare_op(*this), &cvt);
0970     }
0971 
0972     
0973 
0974     path root_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + detail::path_algorithms::find_root_path_size(*this)); }
0975     
0976     path root_name() const { return path(m_pathname.c_str(), m_pathname.c_str() + detail::path_algorithms::find_root_name_size(*this)); }
0977 
0978     
0979     path root_directory() const
0980     {
0981         detail::path_algorithms::substring root_dir = detail::path_algorithms::find_root_directory(*this);
0982         const value_type* p = m_pathname.c_str() + root_dir.pos;
0983         return path(p, p + root_dir.size);
0984     }
0985 
0986     path relative_path() const
0987     {
0988         detail::path_algorithms::substring rel_path = detail::path_algorithms::find_relative_path(*this);
0989         const value_type* p = m_pathname.c_str() + rel_path.pos;
0990         return path(p, p + rel_path.size);
0991     }
0992 
0993     path parent_path() const { return path(m_pathname.c_str(), m_pathname.c_str() + detail::path_algorithms::find_parent_path_size(*this)); }
0994 
0995     path filename() const;  
0996     path stem() const;      
0997     path extension() const; 
0998 
0999     
1000 
1001     bool empty() const noexcept { return m_pathname.empty(); }
1002     bool filename_is_dot() const;
1003     bool filename_is_dot_dot() const;
1004     bool has_root_path() const { return detail::path_algorithms::find_root_path_size(*this) > 0; }
1005     bool has_root_name() const { return detail::path_algorithms::find_root_name_size(*this) > 0; }
1006     bool has_root_directory() const { return detail::path_algorithms::find_root_directory(*this).size > 0; }
1007     bool has_relative_path() const { return detail::path_algorithms::find_relative_path(*this).size > 0; }
1008     bool has_parent_path() const { return detail::path_algorithms::find_parent_path_size(*this) > 0; }
1009     bool has_filename() const;
1010     bool has_stem() const { return !stem().empty(); }
1011     bool has_extension() const { return !extension().empty(); }
1012     bool is_relative() const { return !is_absolute(); }
1013     bool is_absolute() const
1014     {
1015 #if defined(BOOST_WINDOWS_API)
1016         return has_root_name() && has_root_directory();
1017 #else
1018         return has_root_directory();
1019 #endif
1020     }
1021 
1022     
1023 
1024     path lexically_normal() const;
1025     BOOST_FILESYSTEM_DECL path lexically_relative(path const& base) const;
1026     path lexically_proximate(path const& base) const;
1027 
1028     
1029 
1030     BOOST_FILESYSTEM_DECL iterator begin() const;
1031     BOOST_FILESYSTEM_DECL iterator end() const;
1032     reverse_iterator rbegin() const;
1033     reverse_iterator rend() const;
1034 
1035     
1036 
1037     static BOOST_FILESYSTEM_DECL std::locale imbue(std::locale const& loc);
1038     static BOOST_FILESYSTEM_DECL codecvt_type const& codecvt();
1039 
1040     
1041     
1042     
1043 private:
1044     
1045 
1046 
1047 
1048 
1049 
1050 
1051 
1052     string_type m_pathname;     
1053                                 
1054 };
1055 
1056 namespace detail {
1057 BOOST_FILESYSTEM_DECL path const& dot_path();
1058 BOOST_FILESYSTEM_DECL path const& dot_dot_path();
1059 } 
1060 
1061 namespace path_detail {
1062 
1063 
1064 
1065 
1066 
1067 class path_iterator :
1068     public boost::iterator_facade<
1069         path_iterator,
1070         const path,
1071         boost::bidirectional_traversal_tag
1072     >
1073 {
1074 private:
1075     friend class boost::iterator_core_access;
1076     friend class boost::filesystem::path;
1077     friend class path_reverse_iterator;
1078     friend struct boost::filesystem::detail::path_algorithms;
1079 
1080     path const& dereference() const { return m_element; }
1081 
1082     bool equal(path_iterator const& rhs) const noexcept
1083     {
1084         return m_path_ptr == rhs.m_path_ptr && m_pos == rhs.m_pos;
1085     }
1086 
1087     void increment();
1088     void decrement();
1089 
1090 private:
1091     
1092     path m_element;
1093     
1094     const path* m_path_ptr;
1095     
1096     
1097     
1098     
1099     
1100     path::string_type::size_type m_pos;
1101 };
1102 
1103 
1104 
1105 
1106 
1107 class path_reverse_iterator :
1108     public boost::iterator_facade<
1109         path_reverse_iterator,
1110         const path,
1111         boost::bidirectional_traversal_tag
1112     >
1113 {
1114 public:
1115     explicit path_reverse_iterator(path_iterator itr) :
1116         m_itr(itr)
1117     {
1118         if (itr != itr.m_path_ptr->begin())
1119             m_element = *--itr;
1120     }
1121 
1122 private:
1123     friend class boost::iterator_core_access;
1124     friend class boost::filesystem::path;
1125 
1126     path const& dereference() const { return m_element; }
1127     bool equal(path_reverse_iterator const& rhs) const noexcept { return m_itr == rhs.m_itr; }
1128 
1129     void increment()
1130     {
1131         --m_itr;
1132         if (m_itr != m_itr.m_path_ptr->begin())
1133         {
1134             path_iterator tmp = m_itr;
1135             m_element = *--tmp;
1136         }
1137     }
1138 
1139     void decrement()
1140     {
1141         m_element = *m_itr;
1142         ++m_itr;
1143     }
1144 
1145 private:
1146     path_iterator m_itr;
1147     path m_element;
1148 };
1149 
1150 
1151 
1152 bool lexicographical_compare(path_iterator first1, path_iterator const& last1, path_iterator first2, path_iterator const& last2);
1153 
1154 } 
1155 
1156 using path_detail::lexicographical_compare;
1157 
1158 
1159 
1160 
1161 
1162 
1163 
1164 BOOST_FORCEINLINE bool operator==(path const& lhs, path const& rhs)
1165 {
1166     return lhs.compare(rhs) == 0;
1167 }
1168 
1169 template< typename Path, typename Source >
1170 BOOST_FORCEINLINE typename std::enable_if<
1171     detail::conjunction<
1172         std::is_same< Path, path >,
1173         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1174     >::value,
1175     bool
1176 >::type operator==(Path const& lhs, Source const& rhs)
1177 {
1178     return lhs.compare(rhs) == 0;
1179 }
1180 
1181 template< typename Source, typename Path >
1182 BOOST_FORCEINLINE typename std::enable_if<
1183     detail::conjunction<
1184         std::is_same< Path, path >,
1185         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1186     >::value,
1187     bool
1188 >::type operator==(Source const& lhs, Path const& rhs)
1189 {
1190     return rhs.compare(lhs) == 0;
1191 }
1192 
1193 BOOST_FORCEINLINE bool operator!=(path const& lhs, path const& rhs)
1194 {
1195     return lhs.compare(rhs) != 0;
1196 }
1197 
1198 template< typename Path, typename Source >
1199 BOOST_FORCEINLINE typename std::enable_if<
1200     detail::conjunction<
1201         std::is_same< Path, path >,
1202         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1203     >::value,
1204     bool
1205 >::type operator!=(Path const& lhs, Source const& rhs)
1206 {
1207     return lhs.compare(rhs) != 0;
1208 }
1209 
1210 template< typename Source, typename Path >
1211 BOOST_FORCEINLINE typename std::enable_if<
1212     detail::conjunction<
1213         std::is_same< Path, path >,
1214         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1215     >::value,
1216     bool
1217 >::type operator!=(Source const& lhs, Path const& rhs)
1218 {
1219     return rhs.compare(lhs) != 0;
1220 }
1221 
1222 BOOST_FORCEINLINE bool operator<(path const& lhs, path const& rhs)
1223 {
1224     return lhs.compare(rhs) < 0;
1225 }
1226 
1227 template< typename Path, typename Source >
1228 BOOST_FORCEINLINE typename std::enable_if<
1229     detail::conjunction<
1230         std::is_same< Path, path >,
1231         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1232     >::value,
1233     bool
1234 >::type operator<(Path const& lhs, Source const& rhs)
1235 {
1236     return lhs.compare(rhs) < 0;
1237 }
1238 
1239 template< typename Source, typename Path >
1240 BOOST_FORCEINLINE typename std::enable_if<
1241     detail::conjunction<
1242         std::is_same< Path, path >,
1243         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1244     >::value,
1245     bool
1246 >::type operator<(Source const& lhs, Path const& rhs)
1247 {
1248     return rhs.compare(lhs) > 0;
1249 }
1250 
1251 BOOST_FORCEINLINE bool operator<=(path const& lhs, path const& rhs)
1252 {
1253     return lhs.compare(rhs) <= 0;
1254 }
1255 
1256 template< typename Path, typename Source >
1257 BOOST_FORCEINLINE typename std::enable_if<
1258     detail::conjunction<
1259         std::is_same< Path, path >,
1260         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1261     >::value,
1262     bool
1263 >::type operator<=(Path const& lhs, Source const& rhs)
1264 {
1265     return lhs.compare(rhs) <= 0;
1266 }
1267 
1268 template< typename Source, typename Path >
1269 BOOST_FORCEINLINE typename std::enable_if<
1270     detail::conjunction<
1271         std::is_same< Path, path >,
1272         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1273     >::value,
1274     bool
1275 >::type operator<=(Source const& lhs, Path const& rhs)
1276 {
1277     return rhs.compare(lhs) >= 0;
1278 }
1279 
1280 BOOST_FORCEINLINE bool operator>(path const& lhs, path const& rhs)
1281 {
1282     return lhs.compare(rhs) > 0;
1283 }
1284 
1285 template< typename Path, typename Source >
1286 BOOST_FORCEINLINE typename std::enable_if<
1287     detail::conjunction<
1288         std::is_same< Path, path >,
1289         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1290     >::value,
1291     bool
1292 >::type operator>(Path const& lhs, Source const& rhs)
1293 {
1294     return lhs.compare(rhs) > 0;
1295 }
1296 
1297 template< typename Source, typename Path >
1298 BOOST_FORCEINLINE typename std::enable_if<
1299     detail::conjunction<
1300         std::is_same< Path, path >,
1301         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1302     >::value,
1303     bool
1304 >::type operator>(Source const& lhs, Path const& rhs)
1305 {
1306     return rhs.compare(lhs) < 0;
1307 }
1308 
1309 BOOST_FORCEINLINE bool operator>=(path const& lhs, path const& rhs)
1310 {
1311     return lhs.compare(rhs) >= 0;
1312 }
1313 
1314 template< typename Path, typename Source >
1315 BOOST_FORCEINLINE typename std::enable_if<
1316     detail::conjunction<
1317         std::is_same< Path, path >,
1318         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1319     >::value,
1320     bool
1321 >::type operator>=(Path const& lhs, Source const& rhs)
1322 {
1323     return lhs.compare(rhs) >= 0;
1324 }
1325 
1326 template< typename Source, typename Path >
1327 BOOST_FORCEINLINE typename std::enable_if<
1328     detail::conjunction<
1329         std::is_same< Path, path >,
1330         detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >
1331     >::value,
1332     bool
1333 >::type operator>=(Source const& lhs, Path const& rhs)
1334 {
1335     return rhs.compare(lhs) <= 0;
1336 }
1337 
1338 
1339 
1340 template< typename Path >
1341 inline typename std::enable_if<
1342     std::is_same< Path, path >::value,
1343     std::size_t
1344 >::type hash_value(Path const& p) noexcept
1345 {
1346 #ifdef BOOST_WINDOWS_API
1347     std::size_t seed = 0u;
1348     for (typename Path::value_type const* it = p.c_str(); *it; ++it)
1349         hash_combine(seed, *it == L'/' ? L'\\' : *it);
1350     return seed;
1351 #else 
1352     return hash_range(p.native().begin(), p.native().end());
1353 #endif
1354 }
1355 
1356 inline void swap(path& lhs, path& rhs) noexcept
1357 {
1358     lhs.swap(rhs);
1359 }
1360 
1361 BOOST_FORCEINLINE path operator/(path lhs, path const& rhs)
1362 {
1363     lhs.append(rhs);
1364     return lhs;
1365 }
1366 
1367 template< typename Source >
1368 BOOST_FORCEINLINE typename std::enable_if<
1369     detail::path_traits::is_convertible_to_path_source< typename std::remove_cv< Source >::type >::value,
1370     path
1371 >::type operator/(path lhs, Source const& rhs)
1372 {
1373     lhs.append(rhs);
1374     return lhs;
1375 }
1376 
1377 
1378 
1379 
1380 
1381 template< typename Char, typename Traits >
1382 inline std::basic_ostream< Char, Traits >&
1383 operator<<(std::basic_ostream< Char, Traits >& os, path const& p)
1384 {
1385     return os << boost::io::quoted(p.template string< std::basic_string< Char > >(), static_cast< Char >('&'));
1386 }
1387 
1388 template< typename Char, typename Traits >
1389 inline std::basic_istream< Char, Traits >&
1390 operator>>(std::basic_istream< Char, Traits >& is, path& p)
1391 {
1392     std::basic_string< Char > str;
1393     is >> boost::io::quoted(str, static_cast< Char >('&'));
1394     p = str;
1395     return is;
1396 }
1397 
1398 
1399 
1400 
1401 
1402 
1403 BOOST_FILESYSTEM_DECL bool portable_posix_name(std::string const& name);
1404 BOOST_FILESYSTEM_DECL bool windows_name(std::string const& name);
1405 BOOST_FILESYSTEM_DECL bool portable_name(std::string const& name);
1406 BOOST_FILESYSTEM_DECL bool portable_directory_name(std::string const& name);
1407 BOOST_FILESYSTEM_DECL bool portable_file_name(std::string const& name);
1408 BOOST_FILESYSTEM_DECL bool native(std::string const& name);
1409 
1410 namespace detail {
1411 
1412 
1413 
1414 
1415 
1416 inline bool is_directory_separator(path::value_type c) noexcept
1417 {
1418     return c == path::separator
1419 #ifdef BOOST_WINDOWS_API
1420         || c == path::preferred_separator
1421 #endif
1422         ;
1423 }
1424 
1425 inline bool is_element_separator(path::value_type c) noexcept
1426 {
1427     return c == path::separator
1428 #ifdef BOOST_WINDOWS_API
1429         || c == path::preferred_separator || c == L':'
1430 #endif
1431         ;
1432 }
1433 
1434 } 
1435 
1436 
1437 
1438 
1439 
1440 namespace detail {
1441 
1442 inline bool path_algorithms::has_filename_v3(path const& p)
1443 {
1444     return !p.m_pathname.empty();
1445 }
1446 
1447 inline bool path_algorithms::has_filename_v4(path const& p)
1448 {
1449     return path_algorithms::find_filename_v4_size(p) > 0;
1450 }
1451 
1452 inline path path_algorithms::filename_v4(path const& p)
1453 {
1454     string_type::size_type filename_size = path_algorithms::find_filename_v4_size(p);
1455     string_type::size_type pos = p.m_pathname.size() - filename_size;
1456     const value_type* ptr = p.m_pathname.c_str() + pos;
1457     return path(ptr, ptr + filename_size);
1458 }
1459 
1460 inline path path_algorithms::extension_v4(path const& p)
1461 {
1462     string_type::size_type extension_size = path_algorithms::find_extension_v4_size(p);
1463     string_type::size_type pos = p.m_pathname.size() - extension_size;
1464     const value_type* ptr = p.m_pathname.c_str() + pos;
1465     return path(ptr, ptr + extension_size);
1466 }
1467 
1468 inline void path_algorithms::append_v4(path& left, path const& right)
1469 {
1470     path_algorithms::append_v4(left, right.m_pathname.c_str(), right.m_pathname.c_str() + right.m_pathname.size());
1471 }
1472 
1473 } 
1474 
1475 
1476 
1477 
1478 
1479 
1480 
1481 
1482 BOOST_FORCEINLINE path::compare_op::result_type path::compare_op::operator() (const value_type* source, const value_type* source_end, const codecvt_type*) const
1483 {
1484     path src;
1485     src.m_pathname.assign(source, source_end);
1486     return m_self.compare(src);
1487 }
1488 
1489 template< typename OtherChar >
1490 BOOST_FORCEINLINE path::compare_op::result_type path::compare_op::operator() (const OtherChar* source, const OtherChar* source_end, const codecvt_type* cvt) const
1491 {
1492     path src;
1493     detail::path_traits::convert(source, source_end, src.m_pathname, cvt);
1494     return m_self.compare(src);
1495 }
1496 
1497 inline path& path::operator=(path const& p)
1498 {
1499     return assign(p);
1500 }
1501 
1502 inline path& path::operator+=(path const& p)
1503 {
1504     return concat(p);
1505 }
1506 
1507 BOOST_FORCEINLINE path& path::operator/=(path const& p)
1508 {
1509     return append(p);
1510 }
1511 
1512 inline path path::lexically_proximate(path const& base) const
1513 {
1514     path tmp(lexically_relative(base));
1515     return tmp.empty() ? *this : tmp;
1516 }
1517 
1518 inline path::reverse_iterator path::rbegin() const
1519 {
1520     return reverse_iterator(end());
1521 }
1522 
1523 inline path::reverse_iterator path::rend() const
1524 {
1525     return reverse_iterator(begin());
1526 }
1527 
1528 inline bool path::filename_is_dot() const
1529 {
1530     
1531     
1532     path p(filename());
1533     return p.size() == 1 && *p.c_str() == dot;
1534 }
1535 
1536 inline bool path::filename_is_dot_dot() const
1537 {
1538     return size() >= 2 && m_pathname[size() - 1] == dot && m_pathname[size() - 2] == dot && (m_pathname.size() == 2 || detail::is_element_separator(m_pathname[size() - 3]));
1539     
1540     
1541 }
1542 
1543 
1544 
1545 
1546 
1547 
1548 #if !defined(BOOST_FILESYSTEM_SOURCE)
1549 
1550 BOOST_FORCEINLINE path& path::append(path const& p)
1551 {
1552     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, p.m_pathname.data(), p.m_pathname.data() + p.m_pathname.size());
1553     return *this;
1554 }
1555 
1556 BOOST_FORCEINLINE path& path::append(path const& p, codecvt_type const&)
1557 {
1558     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, p.m_pathname.data(), p.m_pathname.data() + p.m_pathname.size());
1559     return *this;
1560 }
1561 
1562 BOOST_FORCEINLINE path& path::append(const value_type* begin, const value_type* end)
1563 {
1564     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, begin, end);
1565     return *this;
1566 }
1567 
1568 BOOST_FORCEINLINE path& path::append(const value_type* begin, const value_type* end, codecvt_type const&)
1569 {
1570     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::append)(*this, begin, end);
1571     return *this;
1572 }
1573 
1574 BOOST_FORCEINLINE path& path::remove_filename()
1575 {
1576     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::remove_filename)(*this);
1577     return *this;
1578 }
1579 
1580 BOOST_FORCEINLINE path& path::replace_extension(path const& new_extension)
1581 {
1582     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::replace_extension)(*this, new_extension);
1583     return *this;
1584 }
1585 
1586 BOOST_FORCEINLINE int path::compare(path const& p) const
1587 {
1588     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::compare)(*this, p);
1589 }
1590 
1591 BOOST_FORCEINLINE path path::filename() const
1592 {
1593     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::filename)(*this);
1594 }
1595 
1596 BOOST_FORCEINLINE path path::stem() const
1597 {
1598     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::stem)(*this);
1599 }
1600 
1601 BOOST_FORCEINLINE path path::extension() const
1602 {
1603     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::extension)(*this);
1604 }
1605 
1606 BOOST_FORCEINLINE bool path::has_filename() const
1607 {
1608     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::has_filename)(*this);
1609 }
1610 
1611 BOOST_FORCEINLINE path path::lexically_normal() const
1612 {
1613     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::lexically_normal)(*this);
1614 }
1615 
1616 BOOST_FORCEINLINE path path::generic_path() const
1617 {
1618     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::generic_path)(*this);
1619 }
1620 
1621 BOOST_FORCEINLINE path& path::make_preferred()
1622 {
1623     
1624 #if defined(BOOST_WINDOWS_API)
1625     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::make_preferred)(*this);
1626 #endif
1627     return *this;
1628 }
1629 
1630 namespace path_detail {
1631 
1632 BOOST_FORCEINLINE void path_iterator::increment()
1633 {
1634     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::increment)(*this);
1635 }
1636 
1637 BOOST_FORCEINLINE void path_iterator::decrement()
1638 {
1639     BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::decrement)(*this);
1640 }
1641 
1642 BOOST_FORCEINLINE bool lexicographical_compare(path_iterator first1, path_iterator const& last1, path_iterator first2, path_iterator const& last2)
1643 {
1644     return BOOST_FILESYSTEM_VERSIONED_SYM(detail::path_algorithms::lex_compare)(first1, last1, first2, last2) < 0;
1645 }
1646 
1647 } 
1648 
1649 #endif 
1650 
1651 
1652 
1653 
1654 
1655 template< >
1656 inline std::string path::string< std::string >() const
1657 {
1658     return string();
1659 }
1660 
1661 template< >
1662 inline std::wstring path::string< std::wstring >() const
1663 {
1664     return wstring();
1665 }
1666 
1667 template< >
1668 inline std::string path::string< std::string >(codecvt_type const& cvt) const
1669 {
1670     return string(cvt);
1671 }
1672 
1673 template< >
1674 inline std::wstring path::string< std::wstring >(codecvt_type const& cvt) const
1675 {
1676     return wstring(cvt);
1677 }
1678 
1679 template< >
1680 inline std::string path::generic_string< std::string >() const
1681 {
1682     return generic_string();
1683 }
1684 
1685 template< >
1686 inline std::wstring path::generic_string< std::wstring >() const
1687 {
1688     return generic_wstring();
1689 }
1690 
1691 template< >
1692 inline std::string path::generic_string< std::string >(codecvt_type const& cvt) const
1693 {
1694     return generic_string(cvt);
1695 }
1696 
1697 template< >
1698 inline std::wstring path::generic_string< std::wstring >(codecvt_type const& cvt) const
1699 {
1700     return generic_wstring(cvt);
1701 }
1702 
1703 } 
1704 } 
1705 
1706 
1707 
1708 #include <boost/filesystem/detail/footer.hpp>
1709 
1710 #endif