00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00047 #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_PATH
00048 #define WINSTL_INCL_WINSTL_FILESYSTEM_HPP_PATH
00049
00050 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00051 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_PATH_MAJOR 6
00052 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_PATH_MINOR 6
00053 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_PATH_REVISION 18
00054 # define WINSTL_VER_WINSTL_FILESYSTEM_HPP_PATH_EDIT 258
00055 #endif
00056
00057
00058
00059
00060
00061 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00062 # include <winstl/winstl.h>
00063 #endif
00064 #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
00065 # include <winstl/filesystem/filesystem_traits.hpp>
00066 #endif
00067 #ifndef WINSTL_INCL_WINSTL_FILESYSTEM_HPP_FILE_PATH_BUFFER
00068 # include <winstl/filesystem/file_path_buffer.hpp>
00069 #endif
00070 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00071 # include <winstl/memory/processheap_allocator.hpp>
00072 #endif
00073 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00074 # ifndef WINSTL_INCL_WINSTL_ERROR_HPP_WINDOWS_EXCEPTIONS
00075 # include <winstl/error/exceptions.hpp>
00076 # endif
00077 #endif
00078 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_FEATURES
00079 # include <stlsoft/memory/allocator_features.hpp>
00080 #endif
00081 #ifndef STLSOFT_INCL_STLSOFT_HPP_MEMORY_AUTO_BUFFER
00082 # include <stlsoft/memory/auto_buffer.hpp>
00083 #endif
00084 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_COPY_FUNCTIONS
00085 # include <stlsoft/string/copy_functions.hpp>
00086 #endif
00087 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00088 # include <stlsoft/shims/access/string.hpp>
00089 #endif
00090 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_STD_SWAP
00091 # include <stlsoft/util/std_swap.hpp>
00092 #endif
00093
00094 #ifndef STLSOFT_INCL_STDEXCEPT
00095 # define STLSOFT_INCL_STDEXCEPT
00096 # include <stdexcept>
00097 #endif
00098
00099
00100
00101
00102
00103 #ifndef _WINSTL_NO_NAMESPACE
00104 # if defined(_STLSOFT_NO_NAMESPACE) || \
00105 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00106
00107 namespace winstl
00108 {
00109 # else
00110
00111
00112 namespace stlsoft
00113 {
00114
00115 namespace winstl_project
00116 {
00117
00118 # endif
00119 #endif
00120
00121
00122
00123
00124
00125
00126
00142 template< ss_typename_param_k C
00143 #ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00144 , ss_typename_param_k T = filesystem_traits<C>
00145 , ss_typename_param_k A = processheap_allocator<C>
00146 #else
00147 , ss_typename_param_k T
00148 , ss_typename_param_k A
00149 #endif
00150 >
00151 class basic_path
00152 {
00155 public:
00157 typedef C char_type;
00159 typedef T traits_type;
00161 typedef A allocator_type;
00163 typedef basic_path<C, T, A> class_type;
00165 typedef ws_size_t size_type;
00167 typedef ws_bool_t bool_type;
00168
00169
00170
00172
00175 public:
00184 basic_path();
00197 ss_explicit_k basic_path(char_type const* path);
00198 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00219 template<ss_typename_param_k S>
00220 ss_explicit_k basic_path(S const& s)
00221 {
00222 m_len = stlsoft_ns_qual(c_str_len)(s);
00223
00224 traits_type::char_copy(&m_buffer[0], stlsoft_ns_qual(c_str_data)(s), m_len);
00225 m_buffer[m_len] = '\0';
00226 }
00227 #endif
00238 basic_path(char_type const* path, size_type cch);
00239
00240 #ifndef STLSOFT_CF_NO_COPY_CTOR_AND_COPY_CTOR_TEMPLATE_OVERLOAD
00242 basic_path(class_type const& rhs);
00243 #endif
00244
00245 #ifndef STLSOFT_CF_NO_COPY_CTOR_AND_COPY_CTOR_TEMPLATE_OVERLOAD
00247 class_type& operator =(class_type const& rhs);
00248 #endif
00250 class_type& operator =(char_type const* rhs);
00251 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
00253 template<ss_typename_param_k S>
00254 class_type& operator =(S const& s)
00255 {
00256 return operator_equal_(stlsoft_ns_qual(c_str_ptr)(s));
00257 }
00258 #endif
00259
00260
00261 static class_type root(char_type const* s);
00262 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00263
00264 template<ss_typename_param_k S>
00265 static class_type root(S const& s)
00266 {
00267 return root(stlsoft_ns_qual(c_str_ptr)(s));
00268 }
00269 #endif
00271
00274 public:
00276 class_type& push(class_type const& rhs, bool_type bAddPathNameSeparator = false);
00278 class_type& push(char_type const* rhs, bool_type bAddPathNameSeparator = false);
00280 class_type& push_ext(class_type const& rhs, bool_type bAddPathNameSeparator = false);
00282 class_type& push_ext(char_type const* rhs, bool_type bAddPathNameSeparator = false);
00288 class_type& push_sep();
00295 class_type& pop(bool_type bRemoveTrailingPathNameSeparator = true);
00301 class_type& pop_sep() stlsoft_throw_0();
00305 class_type& pop_ext() stlsoft_throw_0();
00306
00308 class_type& operator /=(char_type const* rhs);
00309
00310 #if !defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT) || \
00311 defined(STLSOFT_CF_MEMBER_TEMPLATE_OVERLOAD_DISCRIMINATED)
00313 class_type& operator /=(class_type const& rhs);
00314 #endif
00315
00316 #if defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT)
00318 template <ss_typename_param_k S>
00319 class_type& operator /=(S const& rhs)
00320 {
00321 return push(stlsoft_ns_qual(c_str_ptr)(rhs));
00322 }
00323 #endif
00324
00326 void clear();
00327
00329 class_type& make_absolute(bool_type bRemoveTrailingPathNameSeparator = true);
00339 class_type& canonicalise(bool_type bRemoveTrailingPathNameSeparator = true);
00341
00344 public:
00351 char_type const* get_file() const;
00353 char_type const* get_ext() const;
00355 size_type length() const;
00359 size_type size() const;
00361 static size_type max_size();
00363 bool_type empty() const;
00365 char_type const* c_str() const;
00370 char_type const& operator [](size_type index) const;
00372 bool_type exists() const;
00374 bool_type is_rooted() const;
00376 bool_type is_absolute() const;
00378 bool_type has_sep() const;
00379
00385 size_type copy(char_type *buffer, size_type cchBuffer) const;
00387
00390 public:
00403 bool_type equivalent(char_type const* rhs) const;
00404
00411 bool_type equivalent(class_type const& rhs) const;
00412
00416 bool_type equal(char_type const* rhs) const;
00420 bool_type equal(class_type const& rhs) const;
00422
00425 public:
00426 #if 0
00427 directory_iterator dir_begin() const;
00428 directory_iterator dir_end() const;
00429 #endif
00431
00432
00433 private:
00434 class_type& operator_equal_(char_type const* path);
00435
00436 class_type& push_(char_type const* rhs, size_type cch, bool_type bAddPathNameSeparator);
00437 class_type& push_sep_(char_type sep);
00438 void swap(class_type& rhs);
00439 class_type& concat_(char_type const* rhs, size_type cch);
00440 #if 0
00441 class_type& concat_(class_type const& rhs, size_type cch);
00442 #endif
00443
00444 bool_type has_dir_end_() const;
00445
00446 static char_type const* last_slash_(char_type const* buffer, size_type len);
00447
00448 static char_type const* next_slash_or_end(char_type const* p);
00449 static char_type const* next_part_or_end(char_type const* p);
00450 static char_type path_name_separator();
00451 static char_type path_name_separator_alt();
00452
00453
00454 private:
00455 typedef basic_file_path_buffer< char_type
00456 , allocator_type
00457 > buffer_type_;
00458
00459 struct part_type
00460 {
00461 enum Type
00462 {
00463 normal
00464 , dot
00465 , dotdot
00466 };
00467
00468 size_type len;
00469 char_type const* p;
00470 Type type;
00471 };
00472
00473 #ifdef STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT
00474 typedef ss_typename_type_k A::ss_template_qual_k rebind<part_type>::other part_ator_type_;
00475 #else
00476 # ifdef WIN32
00477 typedef ss_typename_type_k processheap_allocator<part_type> part_ator_type_;
00478 # else
00479 typedef ss_typename_type_k allocator_selector<part_type>::allocator_type part_ator_type_;
00480 # endif
00481 #endif
00482
00483 typedef stlsoft_ns_qual(auto_buffer_old)< part_type
00484 , part_ator_type_
00485 # ifdef WIN32
00486 , WINSTL_CONST_MAX_PATH / 2
00487 # endif
00488 > part_buffer_type_;
00489
00490
00491 static size_type coallesce_parts_(part_buffer_type_& parts);
00492
00493
00494 private:
00495 buffer_type_ m_buffer;
00496 size_type m_len;
00497 };
00498
00499
00500
00501
00502
00507 typedef basic_path<ws_char_a_t, filesystem_traits<ws_char_a_t> > path_a;
00512 typedef basic_path<ws_char_w_t, filesystem_traits<ws_char_w_t> > path_w;
00517 typedef basic_path<TCHAR, filesystem_traits<TCHAR> > path;
00518
00519
00520
00521
00522
00523
00524 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00525
00526 template< ss_typename_param_k C
00527 # ifdef STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00528 , ss_typename_param_k T = filesystem_traits<C>
00529 , ss_typename_param_k A = processheap_allocator<C>
00530 # else
00531 , ss_typename_param_k T
00532 , ss_typename_param_k A
00533 # endif
00534 >
00535 class basic_path__
00536 : public winstl_ns_qual(basic_path)<C, T, A>
00537 {
00538 private:
00539 typedef winstl_ns_qual(basic_path)<C, T, A> parent_class_type;
00540 typedef winstl_ns_qual(basic_path__)<C, T, A> class_type;
00541 public:
00542 typedef ss_typename_type_k parent_class_type::char_type char_type;
00543 typedef ss_typename_type_k parent_class_type::traits_type traits_type;
00544 typedef ss_typename_type_k parent_class_type::allocator_type allocator_type;
00545 typedef ss_typename_type_k parent_class_type::size_type size_type;
00546
00547 public:
00548 basic_path__()
00549 : parent_class_type()
00550 {}
00551 ss_explicit_k basic_path__(char_type const* path)
00552 : parent_class_type(path)
00553 {}
00554 # ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00556 template<ss_typename_param_k S>
00557 ss_explicit_k basic_path__(S const& s)
00558 : parent_class_type(s)
00559 {}
00560 # endif
00561 basic_path__(char_type const* path, size_type cch)
00562 : parent_class_type(path, cch)
00563 {}
00564 basic_path__(class_type const& rhs)
00565 : parent_class_type(rhs)
00566 {}
00567
00568 class_type& operator =(class_type const& rhs)
00569 {
00570 parent_class_type::operator =(rhs);
00571
00572 return *this;
00573 }
00574 class_type& operator =(char_type const* rhs)
00575 {
00576 parent_class_type::operator =(rhs);
00577
00578 return *this;
00579 }
00580 # ifdef STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT
00581 template<ss_typename_param_k S>
00582 class_type& operator =(S const& s)
00583 {
00584 parent_class_type::operator =(s);
00585
00586 return *this;
00587 }
00588 # endif
00589 };
00590
00591 #endif
00592
00593
00594
00595
00596
00597 template< ss_typename_param_k C
00598 , ss_typename_param_k T
00599 , ss_typename_param_k A
00600 >
00601 inline ws_bool_t operator ==(basic_path<C, T, A> const& lhs, ss_typename_type_k basic_path<C, T, A>::char_type const* rhs)
00602 {
00603 return lhs.equal(rhs);
00604 }
00605
00606 template< ss_typename_param_k C
00607 , ss_typename_param_k T
00608 , ss_typename_param_k A
00609 >
00610 inline ws_bool_t operator !=(basic_path<C, T, A> const& lhs, ss_typename_type_k basic_path<C, T, A>::char_type const* rhs)
00611 {
00612 return !lhs.equal(rhs);
00613 }
00614
00615 template< ss_typename_param_k C
00616 , ss_typename_param_k T
00617 , ss_typename_param_k A
00618 >
00619 inline ws_bool_t operator ==(ss_typename_type_k basic_path<C, T, A>::char_type const* lhs, basic_path<C, T, A> const& rhs)
00620 {
00621 return rhs.equal(lhs);
00622 }
00623
00624 template< ss_typename_param_k C
00625 , ss_typename_param_k T
00626 , ss_typename_param_k A
00627 >
00628 inline ws_bool_t operator !=(ss_typename_type_k basic_path<C, T, A>::char_type const* lhs, basic_path<C, T, A> const& rhs)
00629 {
00630 return !rhs.equal(lhs);
00631 }
00632
00633 template< ss_typename_param_k C
00634 , ss_typename_param_k T
00635 , ss_typename_param_k A
00636 >
00637 inline ws_bool_t operator ==(basic_path<C, T, A> const& lhs, basic_path<C, T, A> const& rhs)
00638 {
00639 return lhs.equal(rhs);
00640 }
00641
00642 template< ss_typename_param_k C
00643 , ss_typename_param_k T
00644 , ss_typename_param_k A
00645 >
00646 inline ws_bool_t operator !=(basic_path<C, T, A> const& lhs, basic_path<C, T, A> const& rhs)
00647 {
00648 return !lhs.equal(rhs);
00649 }
00650
00651
00652
00657 template< ss_typename_param_k C
00658 , ss_typename_param_k T
00659 , ss_typename_param_k A
00660 >
00661 inline basic_path<C, T, A> operator /(basic_path<C, T, A> const& lhs, ss_typename_type_k basic_path<C, T, A>::char_type const* rhs)
00662 {
00663 return basic_path<C, T, A>(lhs) /= rhs;
00664 }
00665
00670 template< ss_typename_param_k C
00671 , ss_typename_param_k T
00672 , ss_typename_param_k A
00673 >
00674 inline basic_path<C, T, A> operator /(ss_typename_type_k basic_path<C, T, A>::char_type const* lhs, basic_path<C, T, A> const& rhs)
00675 {
00676 return basic_path<C, T, A>(lhs) /= rhs;
00677 }
00678
00683 template< ss_typename_param_k C
00684 , ss_typename_param_k T
00685 , ss_typename_param_k A
00686 >
00687 inline basic_path<C, T, A> operator /(basic_path<C, T, A> const& lhs, basic_path<C, T, A> const& rhs)
00688 {
00689 return basic_path<C, T, A>(lhs) /= rhs;
00690 }
00691
00692
00693
00694
00695
00696 #if !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00697 # if !defined(STLSOFT_COMPILER_IS_MSVC) || \
00698 _MSC_VER >= 1100
00699
00705 template<ss_typename_param_k C>
00706 inline basic_path<C> make_path(C const* path)
00707 {
00708 return basic_path<C>(path);
00709 }
00710
00711 # endif
00712 #endif
00713
00714
00715
00716
00717
00718 template< ss_typename_param_k C
00719 , ss_typename_param_k T
00720 , ss_typename_param_k A
00721 >
00722 inline void swap(basic_path<C, T, A>& lhs, basic_path<C, T, A>& rhs)
00723 {
00724 lhs.swap(rhs);
00725 }
00726
00727
00728
00729
00730
00735 template< ss_typename_param_k C
00736 , ss_typename_param_k T
00737 , ss_typename_param_k A
00738 >
00739 inline C const* c_str_data(winstl_ns_qual(basic_path)<C, T, A> const& b)
00740 {
00741 return b.c_str();
00742 }
00743
00744 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00745
00746 template <ss_typename_param_k T, ss_typename_param_k A>
00747 inline ws_char_a_t const* c_str_data_a(winstl_ns_qual(basic_path)<ws_char_a_t, T, A> const& b)
00748 {
00749 return b.c_str();
00750 }
00751 template <ss_typename_param_k T, ss_typename_param_k A>
00752 inline ws_char_w_t const* c_str_data_w(winstl_ns_qual(basic_path)<ws_char_w_t, T, A> const& b)
00753 {
00754 return b.c_str();
00755 }
00756
00757 #endif
00758
00763 template< ss_typename_param_k C
00764 , ss_typename_param_k T
00765 , ss_typename_param_k A
00766 >
00767 inline ws_size_t c_str_len(winstl_ns_qual(basic_path)<C, T, A> const& b)
00768 {
00769 return stlsoft_ns_qual(c_str_len)(b.c_str());
00770 }
00771
00772 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00773
00774 template <ss_typename_param_k T, ss_typename_param_k A>
00775 inline ws_size_t c_str_len_a(winstl_ns_qual(basic_path)<ws_char_a_t, T, A> const& b)
00776 {
00777 return stlsoft_ns_qual(c_str_len_a)(b.c_str());
00778 }
00779 template <ss_typename_param_k T, ss_typename_param_k A>
00780 inline ws_size_t c_str_len_w(winstl_ns_qual(basic_path)<ws_char_w_t, T, A> const& b)
00781 {
00782 return stlsoft_ns_qual(c_str_len_w)(b.c_str());
00783 }
00784
00785 #endif
00786
00787
00788
00793 template< ss_typename_param_k C
00794 , ss_typename_param_k T
00795 , ss_typename_param_k A
00796 >
00797 inline C const* c_str_ptr(winstl_ns_qual(basic_path)<C, T, A> const& b)
00798 {
00799 return b.c_str();
00800 }
00801
00802 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00803
00804 template <ss_typename_param_k T, ss_typename_param_k A>
00805 inline ws_char_a_t const* c_str_ptr_a(winstl_ns_qual(basic_path)<ws_char_a_t, T, A> const& b)
00806 {
00807 return b.c_str();
00808 }
00809 template <ss_typename_param_k T, ss_typename_param_k A>
00810 inline ws_char_w_t const* c_str_ptr_w(winstl_ns_qual(basic_path)<ws_char_w_t, T, A> const& b)
00811 {
00812 return b.c_str();
00813 }
00814
00815 #endif
00816
00817
00818
00823 template< ss_typename_param_k C
00824 , ss_typename_param_k T
00825 , ss_typename_param_k A
00826 >
00827 inline C const* c_str_ptr_null(winstl_ns_qual(basic_path)<C, T, A> const& b)
00828 {
00829 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00830 }
00831
00832 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00833
00834 template <ss_typename_param_k T, ss_typename_param_k A>
00835 inline ws_char_a_t const* c_str_ptr_null_a(winstl_ns_qual(basic_path)<ws_char_a_t, T, A> const& b)
00836 {
00837 return stlsoft_ns_qual(c_str_ptr_null_a)(b.c_str());
00838 }
00839 template <ss_typename_param_k T, ss_typename_param_k A>
00840 inline ws_char_w_t const* c_str_ptr_null_w(winstl_ns_qual(basic_path)<ws_char_w_t, T, A> const& b)
00841 {
00842 return stlsoft_ns_qual(c_str_ptr_null_w)(b.c_str());
00843 }
00844
00845 #endif
00846
00847
00848
00849
00850
00855 template< ss_typename_param_k S
00856 , ss_typename_param_k C
00857 , ss_typename_param_k T
00858 , ss_typename_param_k A
00859 >
00860 inline S& operator <<(S& s, winstl_ns_qual(basic_path)<C, T, A> const& b)
00861 {
00862 s << b.c_str();
00863
00864 return s;
00865 }
00866
00868
00869
00870 #ifdef STLSOFT_UNITTEST
00871 # include "./unittest/path_unittest_.h"
00872 #endif
00873
00875
00876
00877 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00878
00879 template< ss_typename_param_k C
00880 , ss_typename_param_k T
00881 , ss_typename_param_k A
00882 >
00883 inline ss_typename_param_k basic_path<C, T, A>::bool_type
00884 basic_path<C, T, A>::has_dir_end_() const
00885 {
00886 return empty() ? false : traits_type::has_dir_end(m_buffer.c_str() + (m_len - 1));
00887 }
00888
00889 template< ss_typename_param_k C
00890 , ss_typename_param_k T
00891 , ss_typename_param_k A
00892 >
00893 inline ss_typename_param_k basic_path<C, T, A>::char_type const*
00894 basic_path<C, T, A>::last_slash_(
00895 ss_typename_param_k basic_path<C, T, A>::char_type const* buffer
00896 , ss_typename_param_k basic_path<C, T, A>::size_type
00897 )
00898 {
00899 char_type* slash = traits_type::str_rchr(buffer, path_name_separator());
00900 char_type* slash_a = traits_type::str_rchr(buffer, path_name_separator_alt());
00901
00902 if(slash_a > slash)
00903 {
00904 slash = slash_a;
00905 }
00906
00907 return slash;
00908 }
00909
00910
00911 template< ss_typename_param_k C
00912 , ss_typename_param_k T
00913 , ss_typename_param_k A
00914 >
00915 inline ss_typename_param_k basic_path<C, T, A>::char_type const* basic_path<C, T, A>::next_slash_or_end(ss_typename_param_k basic_path<C, T, A>::char_type const* p)
00916 {
00917 for(; ; )
00918 {
00919 switch(*p)
00920 {
00921 case '/':
00922 case '\\':
00923 case '\0':
00924 return p;
00925 default:
00926 ++p;
00927 break;
00928 }
00929 }
00930 }
00931
00932 template< ss_typename_param_k C
00933 , ss_typename_param_k T
00934 , ss_typename_param_k A
00935 >
00936 inline ss_typename_param_k basic_path<C, T, A>::char_type const* basic_path<C, T, A>::next_part_or_end(ss_typename_param_k basic_path<C, T, A>::char_type const* p)
00937 {
00938 for(; ; )
00939 {
00940 switch(*p)
00941 {
00942 case '/':
00943 case '\\':
00944 ++p;
00945 case '\0':
00946 return p;
00947 default:
00948 ++p;
00949 break;
00950 }
00951 }
00952 }
00953
00954 template< ss_typename_param_k C
00955 , ss_typename_param_k T
00956 , ss_typename_param_k A
00957 >
00958 inline ss_typename_param_k basic_path<C, T, A>::char_type basic_path<C, T, A>::path_name_separator_alt()
00959 {
00960 return '/';
00961 }
00962
00963 template <ss_typename_param_k C, ss_typename_param_k T, ss_typename_param_k A>
00964 inline ss_typename_param_k basic_path<C, T, A>::char_type
00965 basic_path<C, T, A>::path_name_separator()
00966 {
00967 WINSTL_ASSERT('\\' == traits_type::path_name_separator());
00968
00969 return '\\';
00970 }
00971
00972 template< ss_typename_param_k C
00973 , ss_typename_param_k T
00974 , ss_typename_param_k A
00975 >
00976 inline void basic_path<C, T, A>::swap(basic_path<C, T, A>& rhs)
00977 {
00978 m_buffer.swap(rhs.m_buffer);
00979 std_swap(m_len, rhs.m_len);
00980 }
00981
00982 template< ss_typename_param_k C
00983 , ss_typename_param_k T
00984 , ss_typename_param_k A
00985 >
00986 inline ss_typename_param_k basic_path<C, T, A>::class_type&
00987 basic_path<C, T, A>::concat_(ss_typename_param_k basic_path<C, T, A>::char_type const* rhs, ss_typename_param_k basic_path<C, T, A>::size_type cch)
00988 {
00989 traits_type::char_copy(&m_buffer[0] + m_len, rhs, cch);
00990 m_len += cch;
00991 m_buffer[m_len] = '\0';
00992
00993 return *this;
00994 }
00995
00996 #if 0
00997 template< ss_typename_param_k C
00998 , ss_typename_param_k T
00999 , ss_typename_param_k A
01000 >
01001 inline ss_typename_param_k basic_path<C, T, A>::class_type& basic_path<C, T, A>::concat_(basic_path<C, T, A> const& rhs)
01002 {
01003 return concat_(rhs.data(), rhs.size());
01004
01005 return *this;
01006 }
01007 #endif
01008
01009 template< ss_typename_param_k C
01010 , ss_typename_param_k T
01011 , ss_typename_param_k A
01012 >
01013 inline ss_typename_param_k basic_path<C, T, A>::size_type basic_path<C, T, A>::coallesce_parts_(ss_typename_param_k basic_path<C, T, A>::part_buffer_type_& parts)
01014 {
01015 ss_typename_param_k part_buffer_type_::iterator src = parts.begin();
01016 ss_typename_param_k part_buffer_type_::iterator dest = parts.begin();
01017
01018 { for(size_type i = 0; i < parts.size(); ++i, ++src)
01019 {
01020 if(0 == parts[i].len)
01021 {
01022 ;
01023 }
01024 else
01025 {
01026 if(dest != src)
01027 {
01028 *dest = *src;
01029 }
01030
01031 ++dest;
01032 }
01033 }}
01034
01035 size_type n = static_cast<size_type>(dest - parts.begin());
01036
01037 parts.resize(n);
01038
01039 return n;
01040 }
01041
01042
01043 template< ss_typename_param_k C
01044 , ss_typename_param_k T
01045 , ss_typename_param_k A
01046 >
01047 inline basic_path<C, T, A>::basic_path()
01048 : m_len(0)
01049 {
01050 m_buffer[0] = '\0';
01051 }
01052
01053 template< ss_typename_param_k C
01054 , ss_typename_param_k T
01055 , ss_typename_param_k A
01056 >
01057 inline basic_path<C, T, A>::basic_path(ss_typename_type_k basic_path<C, T, A>::char_type const* path)
01058 : m_len(0)
01059 {
01060 if(NULL != path)
01061 {
01062 size_type cch = traits_type::str_len(path);
01063
01064 WINSTL_MESSAGE_ASSERT("path too long", cch < m_buffer.size());
01065
01066 traits_type::char_copy(&m_buffer[0], path, cch);
01067
01068 m_len = cch;
01069 }
01070
01071 m_buffer[m_len] = '\0';
01072 }
01073
01074 template< ss_typename_param_k C
01075 , ss_typename_param_k T
01076 , ss_typename_param_k A
01077 >
01078 inline basic_path<C, T, A>::basic_path(ss_typename_type_k basic_path<C, T, A>::char_type const* path, ss_typename_type_k basic_path<C, T, A>::size_type cch)
01079 : m_len(cch)
01080 {
01081 WINSTL_ASSERT((NULL != path) || (0 == cch));
01082
01083 if(0 != cch)
01084 {
01085 WINSTL_MESSAGE_ASSERT("path too long", cch < m_buffer.size());
01086
01087 traits_type::char_copy(&m_buffer[0], path, cch);
01088 }
01089 m_buffer[cch] = '\0';
01090 }
01091
01092 #ifndef STLSOFT_CF_NO_COPY_CTOR_AND_COPY_CTOR_TEMPLATE_OVERLOAD
01093 template< ss_typename_param_k C
01094 , ss_typename_param_k T
01095 , ss_typename_param_k A
01096 >
01097 inline basic_path<C, T, A>::basic_path(basic_path<C, T, A> const& rhs)
01098 : m_len(rhs.m_len)
01099 {
01100 traits_type::char_copy(&m_buffer[0], rhs.m_buffer.c_str(), rhs.m_len + 1);
01101 }
01102 #endif
01103
01104 #ifndef STLSOFT_CF_NO_COPY_CTOR_AND_COPY_CTOR_TEMPLATE_OVERLOAD
01105 template< ss_typename_param_k C
01106 , ss_typename_param_k T
01107 , ss_typename_param_k A
01108 >
01109 inline basic_path<C, T, A>& basic_path<C, T, A>::operator =(basic_path<C, T, A> const& path)
01110 {
01111 class_type newPath(path);
01112
01113 swap(newPath);
01114
01115 return *this;
01116 }
01117 #endif
01118
01119 template< ss_typename_param_k C
01120 , ss_typename_param_k T
01121 , ss_typename_param_k A
01122 >
01123 inline basic_path<C, T, A>& basic_path<C, T, A>::operator =(ss_typename_type_k basic_path<C, T, A>::char_type const* path)
01124 {
01125 return operator_equal_(path);
01126 }
01127
01128 template< ss_typename_param_k C
01129 , ss_typename_param_k T
01130 , ss_typename_param_k A
01131 >
01132 inline basic_path<C, T, A>& basic_path<C, T, A>::operator_equal_(ss_typename_type_k basic_path<C, T, A>::char_type const* path)
01133 {
01134 class_type newPath(path);
01135
01136 swap(newPath);
01137
01138 return *this;
01139 }
01140
01141 template< ss_typename_param_k C
01142 , ss_typename_param_k T
01143 , ss_typename_param_k A
01144 >
01145 inline ss_typename_type_ret_k basic_path<C, T, A>::class_type basic_path<C, T, A>::root(ss_typename_type_k basic_path<C, T, A>::char_type const* s)
01146 {
01147 return class_type(s);
01148 }
01149
01150 template< ss_typename_param_k C
01151 , ss_typename_param_k T
01152 , ss_typename_param_k A
01153 >
01154 inline basic_path<C, T, A>& basic_path<C, T, A>::push(class_type const& rhs, ws_bool_t bAddPathNameSeparator )
01155 {
01156
01157 return push_(rhs.c_str(), rhs.size(), bAddPathNameSeparator);
01158 }
01159
01160 template< ss_typename_param_k C
01161 , ss_typename_param_k T
01162 , ss_typename_param_k A
01163 >
01164 inline basic_path<C, T, A>& basic_path<C, T, A>::push(char_type const* rhs, ws_bool_t bAddPathNameSeparator )
01165 {
01166 WINSTL_ASSERT(NULL != rhs);
01167
01168 return push_(rhs, traits_type::str_len(rhs), bAddPathNameSeparator);
01169 }
01170
01171 template< ss_typename_param_k C
01172 , ss_typename_param_k T
01173 , ss_typename_param_k A
01174 >
01175 inline basic_path<C, T, A>&
01176 basic_path<C, T, A>::push_(
01177 char_type const* rhs
01178 , size_type cch
01179 , ws_bool_t bAddPathNameSeparator
01180 )
01181 {
01182 if(0 != cch)
01183 {
01184 if(traits_type::is_path_rooted(rhs))
01185 {
01186 class_type newPath(rhs, cch);
01187
01188 if( bAddPathNameSeparator &&
01189 !newPath.has_dir_end_())
01190 {
01191 newPath.push_sep();
01192 }
01193
01194 swap(newPath);
01195 }
01196 else
01197 {
01198 WINSTL_MESSAGE_ASSERT("path too long", size() + 1 + cch < m_buffer.size());
01199
01200
01201
01202
01203 class_type newPath(*this);
01204 char_type const* psep = next_slash_or_end(c_str());
01205 char_type sep = ('\0' == *psep) ? char_type(0) : psep[0];
01206
01207 newPath.push_sep_(sep);
01208 newPath.concat_(rhs, cch);
01209 if(bAddPathNameSeparator)
01210 {
01211 newPath.push_sep();
01212 }
01213
01214 swap(newPath);
01215 }
01216 }
01217
01218 return *this;
01219 }
01220
01221 #if 0
01222 template< ss_typename_param_k C
01223 , ss_typename_param_k T
01224 , ss_typename_param_k A
01225 >
01226 inline basic_path<C, T, A>& basic_path<C, T, A>::push_ext(class_type const& rhs, ws_bool_t bAddPathNameSeparator )
01227 {
01228 }
01229 #endif
01230
01231 template< ss_typename_param_k C
01232 , ss_typename_param_k T
01233 , ss_typename_param_k A
01234 >
01235 inline basic_path<C, T, A>& basic_path<C, T, A>::push_ext(char_type const* rhs, ws_bool_t bAddPathNameSeparator )
01236 {
01237 WINSTL_ASSERT(NULL != rhs);
01238
01239 class_type newPath(*this);
01240
01241 newPath.pop_sep();
01242 if('.' != *rhs)
01243 {
01244 newPath.concat_(".", 1u);
01245 }
01246 newPath.concat_(rhs, traits_type::str_len(rhs));
01247 if(bAddPathNameSeparator)
01248 {
01249 newPath.push_sep();
01250 }
01251
01252 swap(newPath);
01253
01254 return *this;
01255 }
01256
01257 template< ss_typename_param_k C
01258 , ss_typename_param_k T
01259 , ss_typename_param_k A
01260 >
01261 inline basic_path<C, T, A>& basic_path<C, T, A>::push_sep()
01262 {
01263 char_type sep = path_name_separator();
01264
01265 char_type* slash = traits_type::str_chr(m_buffer.c_str(), path_name_separator());
01266 char_type* slash_a = traits_type::str_chr(m_buffer.c_str(), path_name_separator_alt());
01267
01268 if( NULL == slash &&
01269 NULL != slash_a)
01270 {
01271 sep = path_name_separator_alt();
01272 }
01273
01274 return push_sep_(sep);
01275 }
01276
01277 template< ss_typename_param_k C
01278 , ss_typename_param_k T
01279 , ss_typename_param_k A
01280 >
01281 inline basic_path<C, T, A>& basic_path<C, T, A>::push_sep_(ss_typename_type_k basic_path<C, T, A>::char_type sep)
01282 {
01283 if(0 == sep)
01284 {
01285 sep = path_name_separator();
01286 }
01287
01288 WINSTL_MESSAGE_ASSERT("You can only push a path name separator character recognised by your operating system!", traits_type::is_path_name_separator(sep));
01289
01290 if(0 != m_len)
01291 {
01292 char_type& last = m_buffer[m_len - 1];
01293
01294 if(traits_type::is_path_name_separator(last))
01295 {
01296 if(last != sep)
01297 {
01298 last = sep;
01299 }
01300 }
01301 else
01302 {
01303 WINSTL_ASSERT(m_len + 1 < m_buffer.size());
01304
01305 m_buffer[m_len] = sep;
01306 m_buffer[m_len + 1] = '\0';
01307 ++m_len;
01308 }
01309 }
01310
01311 return *this;
01312 }
01313
01314 template< ss_typename_param_k C
01315 , ss_typename_param_k T
01316 , ss_typename_param_k A
01317 >
01318 inline basic_path<C, T, A>& basic_path<C, T, A>::pop(ws_bool_t bRemoveTrailingPathNameSeparator )
01319 {
01320 char_type* slash = const_cast<char_type*>(last_slash_(m_buffer.data(), m_len));
01321
01322 if(NULL != slash)
01323 {
01324 if(static_cast<size_type>(slash - m_buffer.data()) + 1 == m_len)
01325 {
01326 bool shouldRemoveTrailingSlash = true;
01327
01328
01329
01330
01331 if(traits_type::is_path_rooted(m_buffer.c_str()))
01332 {
01333 if(traits_type::is_path_UNC(m_buffer.c_str()))
01334 {
01335 char_type const* share = next_part_or_end(m_buffer.c_str() + 2);
01336
01337 if(NULL == share)
01338 {
01339 shouldRemoveTrailingSlash = false;
01340 }
01341 }
01342 else if(traits_type::is_path_absolute(m_buffer.c_str()))
01343 {
01344 if(3 == m_len)
01345 {
01346 shouldRemoveTrailingSlash = false;
01347 }
01348 }
01349 else
01350 {
01351 if(1 == m_len)
01352 {
01353 shouldRemoveTrailingSlash = false;
01354 }
01355 }
01356 }
01357
01358 if(shouldRemoveTrailingSlash)
01359 {
01360 m_buffer[--m_len] = '\0';
01361
01362 slash = const_cast<char_type*>(last_slash_(m_buffer.data(), m_len));
01363 }
01364 }
01365 }
01366
01367 if(NULL != slash)
01368 {
01369 if(traits_type::is_path_UNC(m_buffer.c_str()))
01370 {
01371 char_type const* shareSlash = next_slash_or_end(m_buffer.c_str() + 2);
01372
01373 if(shareSlash == slash)
01374 {
01375 slash = NULL;
01376 }
01377 }
01378 else if(traits_type::is_path_absolute(m_buffer.c_str()) &&
01379 3 == m_len)
01380 {
01381 slash = NULL;
01382 }
01383 else if(traits_type::is_path_rooted(m_buffer.c_str()) &&
01384 1 == m_len)
01385 {
01386 slash = NULL;
01387 }
01388 }
01389
01390 if(NULL != slash)
01391 {
01392 *(slash + 1) = '\0';
01393 m_len = static_cast<size_type>((slash + 1) - m_buffer.c_str());
01394
01395 if(bRemoveTrailingPathNameSeparator)
01396 {
01397 this->pop_sep();
01398 }
01399 }
01400
01401 if(NULL == slash)
01402 {
01403 clear();
01404 }
01405
01406 return *this;
01407 }
01408
01409 template< ss_typename_param_k C
01410 , ss_typename_param_k T
01411 , ss_typename_param_k A
01412 >
01413 inline basic_path<C, T, A>& basic_path<C, T, A>::pop_sep() stlsoft_throw_0()
01414 {
01415 if(0 != m_len)
01416 {
01417 if( 1 == m_len &&
01418 traits_type::is_path_name_separator(m_buffer[0]))
01419 {
01420
01421 }
01422 else if(3 == m_len &&
01423 ':' == m_buffer[1] &&
01424 traits_type::is_path_name_separator(m_buffer[2]))
01425 {
01426
01427 }
01428 else
01429 {
01430
01431 char_type* last = &m_buffer[m_len - 1];
01432
01433 if(*last == path_name_separator())
01434 {
01435 m_buffer[m_len-- - 1] = '\0';
01436 }
01437 else if(*last == path_name_separator_alt())
01438 {
01439 m_buffer[m_len-- - 1] = '\0';
01440 }
01441 }
01442 }
01443
01444 return *this;
01445 }
01446
01447 template< ss_typename_param_k C
01448 , ss_typename_param_k T
01449 , ss_typename_param_k A
01450 >
01451 inline basic_path<C, T, A>& basic_path<C, T, A>::pop_ext() stlsoft_throw_0()
01452 {
01453 { for(ws_size_t len = m_len; 0 != len; --len)
01454 {
01455 char_type* last = &m_buffer[len - 1];
01456
01457 if(traits_type::is_path_name_separator(*last))
01458 {
01459 break;
01460 }
01461 else if('.' == *last)
01462 {
01463 m_len = len - 1;
01464
01465 m_buffer[m_len] = '\0';
01466
01467 break;
01468 }
01469 }}
01470
01471 return *this;
01472 }
01473
01474
01475 #if !defined(STLSOFT_CF_MEMBER_TEMPLATE_FUNCTION_SUPPORT) || \
01476 defined(STLSOFT_CF_MEMBER_TEMPLATE_OVERLOAD_DISCRIMINATED)
01477
01478 template< ss_typename_param_k C
01479 , ss_typename_param_k T
01480 , ss_typename_param_k A
01481 >
01482 inline basic_path<C, T, A>& basic_path<C, T, A>::operator /=(basic_path<C, T, A> const& path)
01483 {
01484 return push(path);
01485 }
01486
01487 #endif
01488
01489 template< ss_typename_param_k C
01490 , ss_typename_param_k T
01491 , ss_typename_param_k A
01492 >
01493 inline basic_path<C, T, A>& basic_path<C, T, A>::operator /=(ss_typename_type_k basic_path<C, T, A>::char_type const* path)
01494 {
01495 return push(path);
01496 }
01497
01498 template< ss_typename_param_k C
01499 , ss_typename_param_k T
01500 , ss_typename_param_k A
01501 >
01502 inline void basic_path<C, T, A>::clear()
01503 {
01504 m_buffer[0] = '\0';
01505 m_len = 0;
01506 }
01507
01508 template< ss_typename_param_k C
01509 , ss_typename_param_k T
01510 , ss_typename_param_k A
01511 >
01512 inline basic_path<C, T, A>& basic_path<C, T, A>::make_absolute(ws_bool_t bRemoveTrailingPathNameSeparator )
01513 {
01514 if(0 != size())
01515 {
01516 buffer_type_ buffer;
01517 size_type cch = traits_type::get_full_path_name(c_str(), buffer.size(), &buffer[0]);
01518
01519 if(0 == cch)
01520 {
01521 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01522 STLSOFT_THROW_X(windows_exception("could not determine the absolute path", ::GetLastError()));
01523 #else
01524 return *this;
01525 #endif
01526 }
01527
01528 class_type newPath(buffer.c_str(), cch);
01529
01530 if(bRemoveTrailingPathNameSeparator)
01531 {
01532 newPath.pop_sep();
01533 }
01534
01535 swap(newPath);
01536 }
01537
01538 return *this;
01539 }
01540
01541 template< ss_typename_param_k C
01542 , ss_typename_param_k T
01543 , ss_typename_param_k A
01544 >
01545 inline basic_path<C, T, A>& basic_path<C, T, A>::canonicalise(ws_bool_t bRemoveTrailingPathNameSeparator )
01546 {
01547 if(0 == size())
01548 {
01549 return *this;
01550 }
01551
01552 class_type newPath(*this);
01553
01554 #ifdef _DEBUG
01555 memset(&newPath.m_buffer[0], '~', newPath.m_buffer.size());
01556 #endif
01557
01558
01559
01560
01561
01562 part_buffer_type_ parts(this->length() / 2);
01563 char_type* dest = &newPath.m_buffer[0];
01564 char_type const* p1 = this->c_str();
01565 char_type const* p2;
01566
01567 if(traits_type::is_path_UNC(this->c_str()))
01568 {
01569 WINSTL_ASSERT('\\' == m_buffer[0]);
01570 WINSTL_ASSERT('\\' == m_buffer[1]);
01571 WINSTL_ASSERT('\\' != m_buffer[2]);
01572
01573 char_type const* slash0 = next_slash_or_end(&m_buffer[3]);
01574 char_type const* slash1 = next_slash_or_end(slash0);
01575
01576 for(ws_size_t i = 0, n = static_cast<ws_size_t>(slash1 - &m_buffer[0]); i < n; ++i)
01577 {
01578 *dest++ = *p1++;
01579 }
01580 }
01581 else if(this->is_absolute())
01582 {
01583
01584 *dest++ = *p1++;
01585 *dest++ = *p1++;
01586 *dest++ = *p1++;
01587 }
01588 else if(this->is_rooted())
01589 {
01590 *dest++ = path_name_separator();
01591 ++p1;
01592 }
01593
01594
01595 {
01596 size_type i = 0;
01597
01598 for(; '\0' != *p1; ++i)
01599 {
01600 p2 = next_part_or_end(p1);
01601
01602 parts[i].len = static_cast<size_type>(p2 - p1);
01603 parts[i].p = p1;
01604 parts[i].type = part_type::normal;
01605 switch(parts[i].len)
01606 {
01607 case 1:
01608 if('.' == p1[0])
01609 {
01610 parts[i].type = part_type::dot;
01611 }
01612 break;
01613 case 2:
01614 if('.' == p1[0])
01615 {
01616 if('.' == p1[1])
01617 {
01618 parts[i].type = part_type::dotdot;
01619 }
01620 else if(path_name_separator() == p1[1])
01621 {
01622 parts[i].type = part_type::dot;
01623 }
01624 else if(path_name_separator_alt() == p1[1])
01625 {
01626 parts[i].type = part_type::dot;
01627 }
01628 }
01629 break;
01630 case 3:
01631 if( '.' == p1[0] &&
01632 '.' == p1[1])
01633 {
01634 if(path_name_separator() == p1[2])
01635 {
01636 parts[i].type = part_type::dotdot;
01637 }
01638 else if(path_name_separator_alt() == p1[2])
01639 {
01640 parts[i].type = part_type::dotdot;
01641 }
01642 }
01643 break;
01644 default:
01645 break;
01646 }
01647
01648 p1 = p2;
01649 }
01650
01651 parts.resize(i);
01652 }
01653
01654
01655 { for(size_type i = 0; i < parts.size(); ++i)
01656 {
01657 WINSTL_ASSERT(0 != parts[i].len);
01658
01659 part_type& part = parts[i];
01660
01661 if(part_type::dot == part.type)
01662 {
01663 part.len = 0;
01664 }
01665 }}
01666
01667 coallesce_parts_(parts);
01668
01669
01670 { for(size_type i = 1; i < parts.size(); ++i)
01671 {
01672 WINSTL_ASSERT(0 != parts[i].len);
01673
01674 part_type& part = parts[i];
01675
01676 if(part_type::dotdot == part.type)
01677 {
01678 { for(size_type prior = i; ; )
01679 {
01680 if(0 == prior)
01681 {
01682 break;
01683 }
01684 else
01685 {
01686 --prior;
01687
01688 if(0 != parts[prior].len)
01689 {
01690 if(part_type::normal == parts[prior].type)
01691 {
01692 part.len = 0;
01693 parts[prior].len = 0;
01694 break;
01695 }
01696 }
01697 }
01698 }}
01699 }
01700 }}
01701
01702 coallesce_parts_(parts);
01703
01704
01705 if( !this->is_rooted() &&
01706 parts.empty())
01707 {
01708 static const char_type s_dot[] = { '.', '/' };
01709
01710 parts.resize(1);
01711 parts[0].type = part_type::dot;
01712 parts[0].len = 1;
01713 parts[0].p = s_dot;
01714 }
01715
01716
01717 {
01718 #ifdef _DEBUG
01719 ::memset(dest, '~', newPath.m_buffer.size() - (dest - &newPath.m_buffer[0]));
01720 #endif
01721
01722 for(size_type i = 0; i < parts.size(); ++i)
01723 {
01724 traits_type::char_copy(dest, parts[i].p, parts[i].len);
01725
01726 dest += parts[i].len;
01727 }
01728
01729 *dest = '\0';
01730 newPath.m_len = static_cast<size_type>(dest - newPath.c_str());
01731 }
01732
01733
01734
01735
01736 WINSTL_ASSERT(m_len > 0);
01737
01738 char_type last = m_buffer[m_len - 1];
01739
01740 if( !bRemoveTrailingPathNameSeparator &&
01741 traits_type::is_path_name_separator(last))
01742 {
01743 newPath.push_sep_(last);
01744 }
01745 else
01746 {
01747 newPath.pop_sep();
01748 }
01749
01750 swap(newPath);
01751
01752 return *this;
01753 }
01754
01755 template< ss_typename_param_k C
01756 , ss_typename_param_k T
01757 , ss_typename_param_k A
01758 >
01759 inline ss_typename_type_ret_k basic_path<C, T, A>::char_type const* basic_path<C, T, A>::get_file() const
01760 {
01761 char_type const* slash = last_slash_(m_buffer.data(), m_len);
01762
01763 if(NULL == slash)
01764 {
01765 slash = m_buffer.c_str();
01766 }
01767 else
01768 {
01769 ++slash;
01770 }
01771
01772 return slash;
01773 }
01774
01775 template< ss_typename_param_k C
01776 , ss_typename_param_k T
01777 , ss_typename_param_k A
01778 >
01779 inline ss_typename_type_ret_k basic_path<C, T, A>::char_type const* basic_path<C, T, A>::get_ext() const
01780 {
01781 char_type const *dot = traits_type::str_rchr(this->c_str(), '.');
01782 char_type const *file = get_file();
01783 static const char_type s_empty[1] = { '\0' };
01784
01785 if(NULL == dot)
01786 {
01787 return s_empty;
01788 }
01789 else if(dot < file)
01790 {
01791 return s_empty;
01792 }
01793 else
01794 {
01795 return dot + 1;
01796 }
01797 }
01798
01799 template< ss_typename_param_k C
01800 , ss_typename_param_k T
01801 , ss_typename_param_k A
01802 >
01803 inline ss_typename_type_ret_k basic_path<C, T, A>::size_type basic_path<C, T, A>::length() const
01804 {
01805 return m_len;
01806 }
01807
01808 template< ss_typename_param_k C
01809 , ss_typename_param_k T
01810 , ss_typename_param_k A
01811 >
01812 inline ss_typename_type_ret_k basic_path<C, T, A>::size_type basic_path<C, T, A>::size() const
01813 {
01814 return length();
01815 }
01816
01817 template< ss_typename_param_k C
01818 , ss_typename_param_k T
01819 , ss_typename_param_k A
01820 >
01821 inline ss_typename_type_ret_k basic_path<C, T, A>::size_type
01822 basic_path<C, T, A>::max_size()
01823 {
01824 return buffer_type_::max_size() - 1u;
01825 }
01826
01827 template< ss_typename_param_k C
01828 , ss_typename_param_k T
01829 , ss_typename_param_k A
01830 >
01831 inline ss_typename_type_ret_k basic_path<C, T, A>::bool_type basic_path<C, T, A>::empty() const
01832 {
01833 return 0 == size();
01834 }
01835
01836 template< ss_typename_param_k C
01837 , ss_typename_param_k T
01838 , ss_typename_param_k A
01839 >
01840 inline ss_typename_type_ret_k basic_path<C, T, A>::char_type const* basic_path<C, T, A>::c_str() const
01841 {
01842 return m_buffer.c_str();
01843 }
01844
01845 template< ss_typename_param_k C
01846 , ss_typename_param_k T
01847 , ss_typename_param_k A
01848 >
01849 inline ss_typename_type_ret_k basic_path<C, T, A>::char_type const& basic_path<C, T, A>::operator [](ss_typename_type_k basic_path<C, T, A>::size_type index) const
01850 {
01851 WINSTL_MESSAGE_ASSERT("Index out of range", !(size() < index));
01852
01853 return c_str()[index];
01854 }
01855
01856 template< ss_typename_param_k C
01857 , ss_typename_param_k T
01858 , ss_typename_param_k A
01859 >
01860 inline ws_bool_t basic_path<C, T, A>::exists() const
01861 {
01862 return traits_type::file_exists(this->c_str());
01863 }
01864
01865 template< ss_typename_param_k C
01866 , ss_typename_param_k T
01867 , ss_typename_param_k A
01868 >
01869 inline ws_bool_t basic_path<C, T, A>::is_rooted() const
01870 {
01871 return traits_type::is_path_rooted(this->c_str());
01872 }
01873
01874 template< ss_typename_param_k C
01875 , ss_typename_param_k T
01876 , ss_typename_param_k A
01877 >
01878 inline ws_bool_t basic_path<C, T, A>::is_absolute() const
01879 {
01880 return traits_type::is_path_absolute(this->c_str());
01881 }
01882
01883 template< ss_typename_param_k C
01884 , ss_typename_param_k T
01885 , ss_typename_param_k A
01886 >
01887 inline ws_bool_t basic_path<C, T, A>::has_sep() const
01888 {
01889 return this->empty() ? false : traits_type::has_dir_end(this->c_str() + (this->size() - 1));
01890 }
01891
01892 template< ss_typename_param_k C
01893 , ss_typename_param_k T
01894 , ss_typename_param_k A
01895 >
01896 inline ss_typename_type_ret_k basic_path<C, T, A>::size_type basic_path<C, T, A>::copy(ss_typename_type_k basic_path<C, T, A>::char_type *buffer, ss_typename_type_k basic_path<C, T, A>::size_type cchBuffer) const
01897 {
01898 return stlsoft_ns_qual(copy_contents)(buffer, cchBuffer, m_buffer.data(), m_len);
01899 }
01900
01901 template< ss_typename_param_k C
01902 , ss_typename_param_k T
01903 , ss_typename_param_k A
01904 >
01905 inline ws_bool_t basic_path<C, T, A>::equivalent(basic_path<C, T, A> const& rhs) const
01906 {
01907 return equivalent(rhs.c_str());
01908 }
01909
01910 template< ss_typename_param_k C
01911 , ss_typename_param_k T
01912 , ss_typename_param_k A
01913 >
01914 inline ws_bool_t basic_path<C, T, A>::equivalent(ss_typename_type_k basic_path<C, T, A>::char_type const* rhs) const
01915 {
01916 class_type lhs_(*this);
01917 class_type rhs_(rhs);
01918
01919 return lhs_.make_absolute(false).canonicalise(true) == rhs_.make_absolute(false).canonicalise(true);
01920 }
01921
01922 template< ss_typename_param_k C
01923 , ss_typename_param_k T
01924 , ss_typename_param_k A
01925 >
01926 inline ws_bool_t basic_path<C, T, A>::equal(basic_path<C, T, A> const& rhs) const
01927 {
01928 return equal(rhs.c_str());
01929 }
01930
01931 template< ss_typename_param_k C
01932 , ss_typename_param_k T
01933 , ss_typename_param_k A
01934 >
01935 inline ws_bool_t basic_path<C, T, A>::equal(ss_typename_type_k basic_path<C, T, A>::char_type const* rhs) const
01936 {
01937 return 0 == traits_type::str_compare_no_case(m_buffer.c_str(), stlsoft_ns_qual(c_str_ptr)(rhs));
01938 }
01939
01940 #endif
01941
01942
01943
01944 #ifndef _WINSTL_NO_NAMESPACE
01945 # if defined(_STLSOFT_NO_NAMESPACE) || \
01946 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01947 }
01948 # else
01949 }
01950 }
01951 # endif
01952 #endif
01953
01954
01955
01956
01957 #if defined(STLSOFT_CF_std_NAMESPACE)
01958 # if ( ( defined(STLSOFT_COMPILER_IS_INTEL) && \
01959 defined(_MSC_VER))) && \
01960 _MSC_VER < 1310
01961 namespace std
01962 {
01963 template< ss_typename_param_k C
01964 , ss_typename_param_k T
01965 , ss_typename_param_k A
01966 >
01967 inline void swap(winstl_ns_qual(basic_path)<C, T, A>& lhs, winstl_ns_qual(basic_path)<C, T, A>& rhs)
01968 {
01969 lhs.swap(rhs);
01970 }
01971 }
01972 # endif
01973 #endif
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983 #ifndef _WINSTL_NO_NAMESPACE
01984 # if !defined(_STLSOFT_NO_NAMESPACE) && \
01985 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01986 namespace stlsoft
01987 {
01988 # else
01989
01990 # endif
01991
01992 using ::winstl::c_str_data;
01993 using ::winstl::c_str_data_a;
01994 using ::winstl::c_str_data_w;
01995
01996 using ::winstl::c_str_len;
01997 using ::winstl::c_str_len_a;
01998 using ::winstl::c_str_len_w;
01999
02000 using ::winstl::c_str_ptr;
02001 using ::winstl::c_str_ptr_a;
02002 using ::winstl::c_str_ptr_w;
02003
02004 using ::winstl::c_str_ptr_null;
02005 using ::winstl::c_str_ptr_null_a;
02006 using ::winstl::c_str_ptr_null_w;
02007
02008 # if !defined(_STLSOFT_NO_NAMESPACE) && \
02009 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
02010 }
02011 # else
02012
02013 # endif
02014 #endif
02015
02016
02017
02018 #endif
02019
02020