remove \r
[extl.git] / extl / win / filesystem / path.h
blob9f23d6b5ca7b9db673476bf1cc7f7d5a1c6c4fec
1 /* ///////////////////////////////////////////////////////////////////////
2 * File: path.h
4 * Created: 08.06.24
5 * Updated: 08.06.24
7 * Brief: path class
9 * [<Home>]
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
13 #ifndef EXTL_PLATFORM_WIN_PATH_H
14 #define EXTL_PLATFORM_WIN_PATH_H
16 /*!\file path.h
17 * \brief path class
20 #ifndef __cplusplus
21 # error path.h need be supported by c++.
22 #endif
24 /* ///////////////////////////////////////////////////////////////////////
25 * Includes
27 #include "filesystem_traits.h"
28 #include "path_entry_iterator.h"
29 #include "../../memory/allocator_selector.h"
30 #include "../../string/string.h"
31 #include "../../utility/operators.h"
32 /* ///////////////////////////////////////////////////////////////////////
33 * ::extl::platform::win namespace
35 EXTL_WIN_BEGIN_WHOLE_NAMESPACE
37 /*!\brief basic_path class
39 * \param C The character type
40 * \param S The string type
41 * \param T The filesystem_traits
43 * \ingroup extl_group_filesystem
45 template< typename_param_k C
46 #ifdef EXTL_TEMPLATE_CLASS_DEFAULT_ARGUMENT_SUPPORT
47 , typename_param_k S = typename_type_def_k filesystem_traits<C>::stack_path_string_type
48 , typename_param_k T = filesystem_traits<C>
50 #else
51 , typename_param_k S
52 , typename_param_k T
53 #endif
55 class basic_path
56 #ifndef EXTL_COMPILER_IS_DMC
57 // operators: != ==
58 : private operators_equal_1_2_<basic_path<C, S, T>, typename_type_k S::const_pointer
59 , operators_div_1_2_<basic_path<C, S, T>, typename_type_k S::const_pointer
60 #ifndef EXTL_TEMPLATE_CLASS_DEFAULT_ARGUMENT_SUPPORT
61 , operators_base_< basic_path<C, S, T> >
62 #endif
63 > >
64 #endif
66 /// \name Types
67 /// @{
68 public:
69 typedef C char_type;
70 typedef S string_type;
71 typedef T filesystem_traits_type;
72 typedef basic_path<C, S, T> class_type;
73 typedef char_type value_type;
74 typedef value_type* pointer;
75 typedef value_type const* const_pointer;
76 typedef value_type& reference;
77 typedef value_type const& const_reference;
78 typedef typename_type_k string_type::string_traits_type string_traits_type;
79 typedef typename_type_k filesystem_traits_type::path_traits_type path_traits_type;
80 typedef typename_type_k filesystem_traits_type::system_traits_type system_traits_type;
81 typedef typename_type_k filesystem_traits_type::size_type size_type;
82 typedef typename_type_k filesystem_traits_type::bool_type bool_type;
83 typedef const_path_entry_iterator<char_type, path_traits<char_type> > const_entry_iterator;
84 typedef const_reverse_path_entry_iterator<char_type, path_traits<char_type> > const_reverse_entry_iterator;
85 typedef typename_type_k const_entry_iterator::path_entry_type path_entry_type;
86 typedef typename_type_k const_entry_iterator::enum_flag_type enum_flag_type;
87 /// @}
89 public:
90 #if defined(EXTL_COMPILER_IS_DMC)
91 EXTL_OPERATORS_EQUAL_1_2_(class_type const&, const_pointer)
92 // EXTL_OPERATORS_DIV_1_2_(class_type const&, const_pointer)
94 friend class_type operator/(class_type const& lhs, class_type const& rhs)
95 { basic_path<C, S, T> ret(lhs); ret /= rhs; return ret; }
96 friend class_type operator/(class_type const& lhs, const_pointer rhs)
97 { basic_path<C, S, T> ret(lhs); ret /= rhs; return ret; }
98 friend class_type operator/(const_pointer lhs, class_type const& rhs)
99 { basic_path<C, S, T> ret(lhs); ret /= rhs; return ret; } // _left_2
100 #endif
102 /// \name Constructors
103 /// @{
104 public:
105 basic_path()
106 : m_path()
109 explicit_k basic_path(const_pointer path)
110 : m_path(path)
113 basic_path(const_pointer path, size_type size)
114 : m_path(path, size)
117 basic_path(class_type const& path)
118 : m_path(path.m_path)
122 #ifdef EXTL_MEMBER_TEMPLATE_CTOR_OVERLOAD_DISCRIMINATED_SUPPORT
123 template< typename_param_k S1 >
124 explicit_k basic_path(S1 const& s)
125 : m_path(c_strptr(s), c_strlen(s))
128 #endif
129 /// @}
131 /// \name Operators
132 /// @{
133 public:
134 class_type& operator =(const_pointer rhs) { m_path.assign(rhs); return *this; }
135 class_type& operator =(class_type const& rhs) { m_path.assign(rhs.m_path); return *this; }
136 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
137 template< typename_param_k S1 >
138 class_type& operator =(S1 const& rhs) { return operator =(c_strptr(rhs)); }
139 #endif
141 /// Equivalent to push()
142 class_type& operator /=(const_pointer rhs) { return push(rhs); }
143 /// Equivalent to push()
144 class_type& operator /=(class_type rhs) { return push(rhs); }
145 /// Equivalent to push()
146 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
147 template< typename_param_k S1 >
148 class_type& operator /=(S1 const& rhs) { return push(c_strptr(rhs)); }
149 #endif
151 bool_type operator ==(const_pointer rhs) const { return equal(rhs); }
152 bool_type operator ==(class_type const& rhs) const { return equal(rhs); }
153 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
154 template< typename_param_k S1 >
155 bool_type operator ==(S1 const& rhs) { return equal(c_strptr(rhs)); }
156 #endif
157 /// @}
159 /// \name Attributes
160 /// @{
161 public:
162 /// Returns the the pointer the storage of the path
163 pointer data() { return m_path.data(); }
164 /// Returns the the pointer the storage of the path
165 const_pointer data() const { return m_path.data(); }
166 /// Returns the c-style string type of the path
167 const_pointer c_str() const { return m_path.c_str(); }
168 /// Returns the length of the path
169 size_type length() const { return m_path.length(); }
170 /// Returns the length of the path
171 size_type size() const { return length(); }
172 /// Returns \c true if the path is empty
173 bool_type is_empty() const { return m_path.is_empty(); }
174 /// Returns \c true if the path is empty
175 bool_type empty() const { return is_empty(); }
177 /// The maximum length of path
178 static size_type max_length() { return path_traits_type::max_length(); }
179 /// The maximum length of path
180 static size_type max_size() { return max_length(); }
181 /// Returns a path separator
182 static char_type path_sep() { return path_traits_type::path_sep(); }
183 /// Returns a path name separator
184 static char_type path_name_sep() { return path_traits_type::path_name_sep(); }
185 /// Returns the wildcard pattern that represents all possible matches
186 static const_pointer pattern_all() { return path_traits_type::pattern_all(); }
188 /// Returns \c true if the path represents an existing file system entry
189 bool_type exists() const { return filesystem_traits_type::file_exists(c_str()); }
190 /// Returns \c true if the path is \c "." or \c ".."
191 bool_type is_dots() const { return path_traits_type::is_dots(c_str()); }
192 /// Returns \c true if the path is is \c "\\\\..."
193 bool_type is_unc_path() const { return path_traits_type::is_unc_path(c_str()); }
194 /// Returns \c true if the path is is \c "\\\\" + '\\0'
195 bool_type is_unc_root() const { return path_traits_type::is_unc_root(c_str()); }
196 /// Returns \c true if the path is rooted
197 bool_type is_rooted_drive() const { return path_traits_type::is_rooted_drive(c_str()); }
198 /// Returns \c true if the path is absolute
199 bool_type is_absolute_path() const { return path_traits_type::is_absolute_path(c_str()); }
201 /// Returns \c true if the path has trailing path name separator
202 bool_type has_sep_end() const { return path_traits_type::has_sep_end(c_str()); }
203 /// Returns \c true if the path has rooted drive
204 bool_type has_rooted_drive() const { return path_traits_type::has_rooted_drive(c_str()); }
206 /*!\brief Returns the file name of the path
208 * e.g. "C:\\dir\\file.txt" return "file.txt"
209 * e.g. "C:\\dir" return "dir"
210 * e.g. "C:\\dir\\" return ""
212 const_pointer get_file_name() const;
214 /// Returns the extensible name of the path
215 const_pointer get_ext_name() const;
217 /// Returns the title name of the path
218 const_pointer get_title_name() const;
219 /// @}
221 /// \name Mutators
222 /// @{
223 public:
224 /// Appends a path name separator if one does not exist
225 class_type& push_sep();
226 /// \brief Removes the path name separator from the end of the path, if it has it
227 /// \note Does not trim the separator character from the root designator
228 class_type& pop_sep();
231 /// Removes the last path element from the path
232 class_type& pop(bool_type is_pop_sep = e_true_v);
233 /// Appends the contents of \c rhs to the path
234 class_type& push(const_pointer rhs, bool_type is_push_sep = e_false_v);
235 /// Appends the contents of \c rhs to the path
236 class_type& push(class_type const& rhs, bool_type is_push_sep = e_false_v);
237 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
238 /// Appends the contents of \c rhs to the path
239 template< typename_param_k S1 >
240 class_type& push(S1 const& rhs, bool_type is_push_sep = e_false_v) { push(c_strptr(rhs), is_push_sep); }
241 #endif
244 /// Removes the extensible name from the path
245 class_type& pop_ext_name(bool_type is_pop_dot = e_true_v);
246 /// Appends an extensible name
247 class_type& push_ext_name(const_pointer rhs);
248 /// Appends an extensible name
249 class_type& push_ext_name(class_type const& rhs);
250 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
251 /// Appends an extensible name
252 template< typename_param_k S1 >
253 class_type& push_ext_name(S const& rhs) { push_ext_name(c_strptr(rhs)); }
254 #endif
256 /// Makes a relative path
257 class_type& make_relative_path();
258 /// Makes a absolute path
259 class_type& make_absolute_path();
260 /// Makes a current directory
261 class_type& make_current_directory();
264 /// Clears all contents
265 void clear() { m_path.clear(); }
266 /// Swaps the contents
267 class_type& swap(class_type& other) { m_path.swap(other.m_path); return *this; }
268 /// @}
270 /// \name Comparison
271 /// @{
272 public:
273 /// Return \c true if this->c_str() == rhs (case-insensitive)
274 bool_type equal(const_pointer rhs) const { return 0 == m_path.compare_nocase(rhs); }
275 /// Return \c true if this->c_str() == rhs (case-insensitive)
276 bool_type equal(string_type const& rhs) const { return 0 == m_path.compare_nocase(rhs); }
277 /// Return \c true if this->c_str() == rhs (case-insensitive)
278 bool_type equal(class_type const& rhs) const { return equal(rhs.m_path); }
279 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
280 /// Return \c true if this->c_str() == rhs (case-insensitive)
281 template< typename_param_k S1 >
282 bool_type equal(S1 const& rhs) const { return equal(c_strptr(rhs)); }
283 #endif
284 /// @}
286 /// \name Others
287 /// @{
288 public:
289 /// Makes path
290 static class_type make_path(const_pointer path) { return class_type(path); }
291 #ifdef EXTL_MEMBER_TEMPLATE_FUNC_OVERLOAD_DISCRIMINATED_SUPPORT
292 /// Makes path
293 template< typename_param_k S1 >
294 static class_type make_path(S1 const& path) { return class_type(c_strptr(path)); }
295 #endif
296 /// @}
298 /// \name Accessors
299 /// @{
300 public:
301 /// Returns reference at the given index
302 reference operator[](size_type index)
304 return const_cast<reference>(static_cast<class_type const&>(*this).operator[](index));
306 /// Returns const reference at the given index
307 const_reference operator[](size_type index) const
309 EXTL_ASSERT(index < length());
310 return m_path[index];
312 /// Returns reference at the given index and throws index_error() if index >= length()
313 reference at(size_type index)
315 return const_cast<reference>(static_cast<class_type const&>(*this).at(index));
317 /// Returns const reference at the given index and throws index_error() if index >= length()
318 const_reference at(size_type index) const
320 EXTL_ASSERT(index < length());
321 EXTL_ASSERT_THROW(index < length(), index_error("out of range"));
322 return m_path[index];
324 /// @}
326 /// \name Path entry iterator
327 /// @{
328 public:
329 const_entry_iterator entry_begin(enum_flag_type flag = path_entry_type::en_enum_all) const
331 return const_entry_iterator(c_str(), flag);
333 const_entry_iterator entry_end() const
335 return const_entry_iterator();
337 const_reverse_entry_iterator entry_rbegin(enum_flag_type flag = path_entry_type::en_enum_all_rev) const
339 return const_reverse_entry_iterator(c_str(), flag);
341 const_reverse_entry_iterator entry_rend() const
343 return const_reverse_entry_iterator();
345 /// @}
347 /// \name Members
348 /// @{
349 private:
350 string_type m_path;
351 /// @}
353 /* ///////////////////////////////////////////////////////////////////////
354 * Macro
357 /* Template declaration */
358 #ifdef EXTL_BASIC_PATH_TEMPLATE_DECL
359 # undef EXTL_BASIC_PATH_TEMPLATE_DECL
360 #endif
362 #define EXTL_BASIC_PATH_TEMPLATE_DECL template< typename_param_k C \
363 , typename_param_k S \
364 , typename_param_k T \
367 /* Class qualification */
368 #ifdef EXTL_BASIC_PATH_QUAL
369 # undef EXTL_BASIC_PATH_QUAL
370 #endif
372 #define EXTL_BASIC_PATH_QUAL basic_path<C, S, T>
374 /* Class qualification */
375 #ifdef EXTL_BASIC_PATH_RET_QUAL
376 # undef EXTL_BASIC_PATH_RET_QUAL
377 #endif
379 #define EXTL_BASIC_PATH_RET_QUAL(ret_type) \
380 typename_type_ret_k EXTL_BASIC_PATH_QUAL::ret_type \
381 EXTL_BASIC_PATH_QUAL
383 /* ///////////////////////////////////////////////////////////////////////
384 * Implemention
386 EXTL_BASIC_PATH_TEMPLATE_DECL
387 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::push_sep()
389 EXTL_ASSERT(NULL != data());
391 /* Maybe path_name_sep() is '\\' or '/',
392 * so ensure_push_back(path_name_sep()) isn't used.
394 if(!path_traits_type::is_path_name_sep(*--m_path.end()))
395 m_path.push_back(path_traits_type::path_name_sep());
397 return *this;
399 EXTL_BASIC_PATH_TEMPLATE_DECL
400 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::pop_sep()
402 EXTL_ASSERT(NULL != data());
404 if(is_rooted_drive()) return *this;
405 if(is_unc_root()) return *this;
407 /* Maybe path_name_sep() is '\\' or '/',
408 * so ensure_pop_back(path_name_sep()) isn't used.
410 if(path_traits_type::is_path_name_sep(*--m_path.end()))
411 m_path.pop_back();
413 return *this;
416 EXTL_BASIC_PATH_TEMPLATE_DECL
417 inline EXTL_BASIC_PATH_RET_QUAL(const_pointer)::get_file_name() const
419 size_type pos = path_traits_type::rfind_sep(m_path.c_str(), m_path.size());
421 if(string_type::fof() != pos)
423 EXTL_ASSERT(pos <= length());
424 return m_path.c_str() + pos + 1;
426 else return string_traits_type::empty();
428 EXTL_BASIC_PATH_TEMPLATE_DECL
429 inline EXTL_BASIC_PATH_RET_QUAL(const_pointer)::get_ext_name() const
431 size_type pos = m_path.rfind(char_type('.'));
432 if(string_type::fof() != pos)
434 EXTL_ASSERT(pos <= length());
435 return m_path.c_str() + pos + 1;
437 else return string_traits_type::empty();
440 EXTL_BASIC_PATH_TEMPLATE_DECL
441 inline EXTL_BASIC_PATH_RET_QUAL(const_pointer)::get_title_name() const
443 string_type s(get_file_name());
444 if(s.is_empty()) return string_traits_type::empty();
446 size_type pos = s.rfind(char_type('.'));
447 if(string_type::fof() != pos) s.resize(pos);
448 return s.c_str();
451 EXTL_BASIC_PATH_TEMPLATE_DECL
452 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::push(const_pointer rhs, bool_type is_push_sep)
454 EXTL_ASSERT(NULL != rhs);
455 if (NULL == rhs) return *this;
456 if (string_traits_type::is_empty(rhs)) return *this;
457 if (path_traits_type::has_rooted_drive(rhs)) m_path.assign(rhs);
458 else
460 if (!is_empty()) push_sep();
461 m_path.append(rhs);
463 if (is_push_sep) push_sep();
464 return *this;
466 // The function isn't forwarded to push(const_pointer, bool_type) for the efficiency of string operation
467 EXTL_BASIC_PATH_TEMPLATE_DECL
468 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::push(class_type const& rhs, bool_type is_push_sep)
470 EXTL_ASSERT(!rhs.is_empty());
471 if (rhs.is_empty()) return *this;
472 if (rhs.has_rooted_drive()) m_path.assign(rhs.m_path);
473 else
475 if (!is_empty()) push_sep();
476 m_path.append(rhs.m_path);
478 if (is_push_sep) push_sep();
479 return *this;
482 EXTL_BASIC_PATH_TEMPLATE_DECL
483 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::pop(bool_type is_pop_sep)
485 if (is_rooted_drive()) return *this;
486 if (is_unc_root()) return *this;
488 size_type pos = path_traits_type::rfind_sep(m_path.c_str(), m_path.size());
489 if (string_type::fof() != pos)
491 EXTL_ASSERT(pos <= length());
493 if (!is_pop_sep) m_path.resize(pos + 1);
494 else if (has_rooted_drive() && pos < 3) // Cannot remove '\\' for "C:\\dir"
495 m_path.resize(pos + 1);
496 else m_path.resize(pos);
498 return *this;
501 EXTL_BASIC_PATH_TEMPLATE_DECL
502 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::push_ext_name(const_pointer rhs)
504 EXTL_ASSERT(NULL != rhs);
505 if (NULL == rhs) return *this;
506 if (string_traits_type::is_empty(rhs)) return *this;
507 if (path_traits_type::is_path_name_sep(*--m_path.end())) return *this; // for "C:dir\\"
508 EXTL_ASSERT(!path_traits_type::has_rooted_drive(rhs));
510 m_path.ensure_push_back(char_type('.'));
511 m_path.append(rhs);
513 return *this;
515 // The function isn't forwarded to push_ext_name(const_pointer) for the efficiency of string operation
516 EXTL_BASIC_PATH_TEMPLATE_DECL
517 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::push_ext_name(class_type const& rhs)
519 EXTL_ASSERT(!rhs.is_empty());
520 if (rhs.is_empty()) return *this;
521 if (path_traits_type::is_path_name_sep(*--m_path.end())) return *this; // for "C:dir\\"
522 EXTL_ASSERT(!rhs.has_rooted_drive());
524 m_path.ensure_push_back(char_type('.'));
525 m_path.append(rhs.m_path);
527 return *this;
530 EXTL_BASIC_PATH_TEMPLATE_DECL
531 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::pop_ext_name(bool_type is_pop_dot)
533 if (is_rooted_drive()) return *this;
534 if (is_unc_root()) return *this;
536 size_type pos = m_path.rfind(char_type('.'));
537 if (string_type::fof() != pos)
539 EXTL_ASSERT(pos <= length());
541 if (!is_pop_dot) m_path.resize(pos + 1);
542 else m_path.resize(pos);
544 return *this;
548 EXTL_BASIC_PATH_TEMPLATE_DECL
549 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::make_relative_path()
551 char_type buffer[path_traits_type::en_max_size];
552 size_type n = filesystem_traits_type::get_relative_path(c_str(), size(), buffer, path_traits_type::en_max_size);
553 m_path.assign(buffer, n);
554 return *this;
556 EXTL_BASIC_PATH_TEMPLATE_DECL
557 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::make_absolute_path()
559 char_type buffer[path_traits_type::en_max_size];
560 size_type n = filesystem_traits_type::get_absolute_path(c_str(), size(), buffer, path_traits_type::en_max_size);
561 m_path.assign(buffer, n);
562 return *this;
564 EXTL_BASIC_PATH_TEMPLATE_DECL
565 inline EXTL_BASIC_PATH_RET_QUAL(class_type&)::make_current_directory()
567 char_type buffer[path_traits_type::en_max_size];
568 size_type n = filesystem_traits_type::get_current_directory(buffer, path_traits_type::en_max_size);
569 m_path.assign(buffer, n);
570 return *this;
573 /* /////////////////////////////////////////////////////////////////////////
574 * swapping
576 EXTL_BASIC_PATH_TEMPLATE_DECL
577 EXTL_INLINE void swap(EXTL_BASIC_PATH_QUAL &lhs, EXTL_BASIC_PATH_QUAL &rhs)
579 lhs.swap(rhs);
581 /* /////////////////////////////////////////////////////////////////////////
582 * shims
584 EXTL_BASIC_PATH_TEMPLATE_DECL
585 EXTL_INLINE typename_type_ret_k EXTL_BASIC_PATH_QUAL::
586 size_type c_strlen(EXTL_BASIC_PATH_QUAL const& p)
588 return EXTL_NS(c_strlen)(p.c_str());
591 EXTL_BASIC_PATH_TEMPLATE_DECL
592 EXTL_INLINE typename_type_ret_k EXTL_BASIC_PATH_QUAL::
593 const_pointer c_strptr(EXTL_BASIC_PATH_QUAL const& p)
595 return p.c_str();
598 EXTL_BASIC_PATH_TEMPLATE_DECL
599 EXTL_INLINE typename_type_ret_k EXTL_BASIC_PATH_QUAL::
600 const_pointer get_ptr(EXTL_BASIC_PATH_QUAL const& p)
602 return p.data();
605 template< typename_param_k St
606 , typename_param_k C
607 , typename_param_k S
608 , typename_param_k T
610 EXTL_INLINE St& operator<<(St& s, EXTL_BASIC_PATH_QUAL const& p)
612 return s << p.c_str();
614 /* /////////////////////////////////////////////////////////////////////////
615 * Types
617 /// path_a
618 typedef basic_path < e_char_t
619 , filesystem_traits<e_char_t>::stack_path_string_type
620 , filesystem_traits<e_char_t>
621 > path_a;
622 /// path_w
623 typedef basic_path < e_wchar_t
624 , filesystem_traits<e_wchar_t>::stack_path_string_type
625 , filesystem_traits<e_wchar_t>
626 > path_w;
627 /// path
628 typedef basic_path < e_tchar_t
629 , filesystem_traits<e_tchar_t>::stack_path_string_type
630 , filesystem_traits<e_tchar_t>
631 > path;
632 /* //////////////////////////////////////////////////////////////////// */
633 #undef EXTL_BASIC_PATH_TEMPLATE_DECL
634 #undef EXTL_BASIC_PATH_QUAL
635 #undef EXTL_BASIC_PATH_RET_QUAL
637 /* ///////////////////////////////////////////////////////////////////////
638 * Unit-testing
640 #ifdef EXTL_PATH_TEST_ENABLE
641 # include "unit_test/path_test.h"
642 #endif
644 /* ///////////////////////////////////////////////////////////////////////
645 * ::extl::platform::win namespace
647 EXTL_WIN_END_WHOLE_NAMESPACE
649 /* ///////////////////////////////////////////////////////////////////////
650 * std::swap
652 #if !defined(EXTL_NO_STL) && \
653 !defined(EXTL_NO_NAMESPACE)
654 /* ::std namespace */
655 EXTL_STD_BEGIN_NAMESPACE
657 template< typename_param_k C
658 , typename_param_k S
659 , typename_param_k T
661 EXTL_INLINE void swap(EXTL_NS(EXTL_NS_PLATFORM(EXTL_NS_WIN(basic_path)))<C, S, T> const& lhs,
662 EXTL_NS(EXTL_NS_PLATFORM(EXTL_NS_WIN(basic_path)))<C, S, T> const& rhs)
664 lhs.swap(rhs);
666 /* ::std namespace */
667 EXTL_STD_END_NAMESPACE
668 #endif
670 /* //////////////////////////////////////////////////////////////////// */
671 #endif /* EXTL_PLATFORM_WIN_PATH_H */
672 /* //////////////////////////////////////////////////////////////////// */