File indexing completed on 2025-07-05 08:29:16
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