comparison DEPENDENCIES/generic/include/boost/filesystem/path.hpp @ 101:c530137014c0

Update Boost headers (1.58.0)
author Chris Cannam
date Mon, 07 Sep 2015 11:12:49 +0100
parents 2665513ce2d3
children
comparison
equal deleted inserted replaced
100:793467b5e61c 101:c530137014c0
119 119
120 // All source arguments except pointers to null terminated byte strings support 120 // All source arguments except pointers to null terminated byte strings support
121 // multi-byte character strings which may have embedded nulls. Embedded null 121 // multi-byte character strings which may have embedded nulls. Embedded null
122 // support is required for some Asian languages on Windows. 122 // support is required for some Asian languages on Windows.
123 123
124 // [defaults] "const codecvt_type& cvt=codecvt()" default arguments are not used 124 // "const codecvt_type& cvt=codecvt()" default arguments are not used because this
125 // because some compilers, such as Microsoft prior to VC++ 10, do not handle defaults 125 // limits the impact of locale("") initialization failures on POSIX systems to programs
126 // correctly in templates. 126 // that actually depend on locale(""). It further ensures that exceptions thrown
127 // as a result of such failues occur after main() has started, so can be caught.
127 128
128 // ----- constructors ----- 129 // ----- constructors -----
129 130
130 path(){} 131 path(){}
131 132
134 template <class Source> 135 template <class Source>
135 path(Source const& source, 136 path(Source const& source,
136 typename boost::enable_if<path_traits::is_pathable< 137 typename boost::enable_if<path_traits::is_pathable<
137 typename boost::decay<Source>::type> >::type* =0) 138 typename boost::decay<Source>::type> >::type* =0)
138 { 139 {
139 path_traits::dispatch(source, m_pathname, codecvt()); 140 path_traits::dispatch(source, m_pathname);
140 } 141 }
141 142
142 // Overloads for the operating system API's native character type. Rationale:
143 // - Avoids use of codecvt() for native value_type strings. This limits the
144 // impact of locale("") initialization failures on POSIX systems to programs
145 // that actually depend on locale(""). It further ensures that exceptions thrown
146 // as a result of such failues occur after main() has started, so can be caught.
147 // This is a partial resolution of tickets 4688, 5100, and 5289.
148 // - A slight optimization for a common use case, particularly on POSIX since
149 // value_type is char and that is the most common useage.
150 path(const value_type* s) : m_pathname(s) {} 143 path(const value_type* s) : m_pathname(s) {}
151 path(const std::basic_string<value_type>& s) : m_pathname(s) {} 144 path(value_type* s) : m_pathname(s) {}
145 path(const string_type& s) : m_pathname(s) {}
146 path(string_type& s) : m_pathname(s) {}
152 147
153 template <class Source> 148 template <class Source>
154 path(Source const& source, const codecvt_type& cvt) 149 path(Source const& source, const codecvt_type& cvt)
155 // see [defaults] note above explaining why codecvt() default arguments are not used
156 { 150 {
157 path_traits::dispatch(source, m_pathname, cvt); 151 path_traits::dispatch(source, m_pathname, cvt);
158 } 152 }
159 153
160 template <class InputIterator> 154 template <class InputIterator>
161 path(InputIterator begin, InputIterator end) 155 path(InputIterator begin, InputIterator end)
162 { 156 {
163 if (begin != end) 157 if (begin != end)
164 { 158 {
159 // convert requires contiguous string, so copy
165 std::basic_string<typename std::iterator_traits<InputIterator>::value_type> 160 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
166 s(begin, end); 161 seq(begin, end);
167 path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, codecvt()); 162 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname);
168 } 163 }
169 } 164 }
170 165
171 template <class InputIterator> 166 template <class InputIterator>
172 path(InputIterator begin, InputIterator end, const codecvt_type& cvt) 167 path(InputIterator begin, InputIterator end, const codecvt_type& cvt)
173 { 168 {
174 if (begin != end) 169 if (begin != end)
175 { 170 {
171 // convert requires contiguous string, so copy
176 std::basic_string<typename std::iterator_traits<InputIterator>::value_type> 172 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
177 s(begin, end); 173 seq(begin, end);
178 path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); 174 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt);
179 } 175 }
180 } 176 }
181 177
182 // ----- assignments ----- 178 // ----- assignments -----
183 179
184 path& operator=(const path& p) 180 path& operator=(const path& p)
185 { 181 {
186 m_pathname = p.m_pathname; 182 m_pathname = p.m_pathname;
187 return *this;
188 }
189
190 path& operator=(const value_type* ptr) // required in case ptr overlaps *this
191 {
192 m_pathname = ptr;
193 return *this; 183 return *this;
194 } 184 }
195 185
196 template <class Source> 186 template <class Source>
197 typename boost::enable_if<path_traits::is_pathable< 187 typename boost::enable_if<path_traits::is_pathable<
198 typename boost::decay<Source>::type>, path&>::type 188 typename boost::decay<Source>::type>, path&>::type
199 operator=(Source const& source) 189 operator=(Source const& source)
200 { 190 {
201 m_pathname.clear(); 191 m_pathname.clear();
202 path_traits::dispatch(source, m_pathname, codecvt()); 192 path_traits::dispatch(source, m_pathname);
203 return *this; 193 return *this;
204 } 194 }
195
196 // value_type overloads
197
198 path& operator=(const value_type* ptr) // required in case ptr overlaps *this
199 {m_pathname = ptr; return *this;}
200 path& operator=(value_type* ptr) // required in case ptr overlaps *this
201 {m_pathname = ptr; return *this;}
202 path& operator=(const string_type& s) {m_pathname = s; return *this;}
203 path& operator=(string_type& s) {m_pathname = s; return *this;}
205 204
206 path& assign(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this 205 path& assign(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this
207 { 206 {m_pathname = ptr; return *this;}
208 m_pathname = ptr;
209 return *this;
210 }
211
212 template <class Source> 207 template <class Source>
213 path& assign(Source const& source, const codecvt_type& cvt) 208 path& assign(Source const& source, const codecvt_type& cvt)
214 { 209 {
215 m_pathname.clear(); 210 m_pathname.clear();
216 path_traits::dispatch(source, m_pathname, cvt); 211 path_traits::dispatch(source, m_pathname, cvt);
218 } 213 }
219 214
220 template <class InputIterator> 215 template <class InputIterator>
221 path& assign(InputIterator begin, InputIterator end) 216 path& assign(InputIterator begin, InputIterator end)
222 { 217 {
223 return assign(begin, end, codecvt()); 218 m_pathname.clear();
219 if (begin != end)
220 {
221 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
222 seq(begin, end);
223 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname);
224 }
225 return *this;
224 } 226 }
225 227
226 template <class InputIterator> 228 template <class InputIterator>
227 path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt) 229 path& assign(InputIterator begin, InputIterator end, const codecvt_type& cvt)
228 { 230 {
229 m_pathname.clear(); 231 m_pathname.clear();
230 if (begin != end) 232 if (begin != end)
231 { 233 {
232 std::basic_string<typename std::iterator_traits<InputIterator>::value_type> 234 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
233 s(begin, end); 235 seq(begin, end);
234 path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); 236 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt);
235 } 237 }
236 return *this; 238 return *this;
237 } 239 }
238 240
239 // ----- concatenation ----- 241 // ----- concatenation -----
240
241 path& operator+=(const path& p) {m_pathname += p.m_pathname; return *this;}
242 path& operator+=(const string_type& s) {m_pathname += s; return *this;}
243 path& operator+=(const value_type* ptr) {m_pathname += ptr; return *this;}
244 path& operator+=(value_type c) {m_pathname += c; return *this;}
245 242
246 template <class Source> 243 template <class Source>
247 typename boost::enable_if<path_traits::is_pathable< 244 typename boost::enable_if<path_traits::is_pathable<
248 typename boost::decay<Source>::type>, path&>::type 245 typename boost::decay<Source>::type>, path&>::type
249 operator+=(Source const& source) 246 operator+=(Source const& source)
250 { 247 {
251 return concat(source, codecvt()); 248 return concat(source);
252 } 249 }
250
251 // value_type overloads. Same rationale as for constructors above
252 path& operator+=(const path& p) { m_pathname += p.m_pathname; return *this; }
253 path& operator+=(const value_type* ptr) { m_pathname += ptr; return *this; }
254 path& operator+=(value_type* ptr) { m_pathname += ptr; return *this; }
255 path& operator+=(const string_type& s) { m_pathname += s; return *this; }
256 path& operator+=(string_type& s) { m_pathname += s; return *this; }
257 path& operator+=(value_type c) { m_pathname += c; return *this; }
253 258
254 template <class CharT> 259 template <class CharT>
255 typename boost::enable_if<is_integral<CharT>, path&>::type 260 typename boost::enable_if<is_integral<CharT>, path&>::type
256 operator+=(CharT c) 261 operator+=(CharT c)
257 { 262 {
258 CharT tmp[2]; 263 CharT tmp[2];
259 tmp[0] = c; 264 tmp[0] = c;
260 tmp[1] = 0; 265 tmp[1] = 0;
261 return concat(tmp, codecvt()); 266 return concat(tmp);
267 }
268
269 template <class Source>
270 path& concat(Source const& source)
271 {
272 path_traits::dispatch(source, m_pathname);
273 return *this;
262 } 274 }
263 275
264 template <class Source> 276 template <class Source>
265 path& concat(Source const& source, const codecvt_type& cvt) 277 path& concat(Source const& source, const codecvt_type& cvt)
266 { 278 {
269 } 281 }
270 282
271 template <class InputIterator> 283 template <class InputIterator>
272 path& concat(InputIterator begin, InputIterator end) 284 path& concat(InputIterator begin, InputIterator end)
273 { 285 {
274 return concat(begin, end, codecvt()); 286 if (begin == end)
287 return *this;
288 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
289 seq(begin, end);
290 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname);
291 return *this;
275 } 292 }
276 293
277 template <class InputIterator> 294 template <class InputIterator>
278 path& concat(InputIterator begin, InputIterator end, const codecvt_type& cvt) 295 path& concat(InputIterator begin, InputIterator end, const codecvt_type& cvt)
279 { 296 {
280 if (begin == end) 297 if (begin == end)
281 return *this; 298 return *this;
282 std::basic_string<typename std::iterator_traits<InputIterator>::value_type> 299 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
283 s(begin, end); 300 seq(begin, end);
284 path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); 301 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt);
285 return *this; 302 return *this;
286 } 303 }
287 304
288 // ----- appends ----- 305 // ----- appends -----
289 306
290 // if a separator is added, it is the preferred separator for the platform; 307 // if a separator is added, it is the preferred separator for the platform;
291 // slash for POSIX, backslash for Windows 308 // slash for POSIX, backslash for Windows
292 309
293 path& operator/=(const path& p); 310 path& operator/=(const path& p);
294
295 path& operator/=(const value_type* ptr);
296 311
297 template <class Source> 312 template <class Source>
298 typename boost::enable_if<path_traits::is_pathable< 313 typename boost::enable_if<path_traits::is_pathable<
299 typename boost::decay<Source>::type>, path&>::type 314 typename boost::decay<Source>::type>, path&>::type
300 operator/=(Source const& source) 315 operator/=(Source const& source)
301 { 316 {
302 return append(source, codecvt()); 317 return append(source);
318 }
319
320 path& operator/=(const value_type* ptr);
321 path& operator/=(value_type* ptr)
322 {
323 return this->operator/=(const_cast<const value_type*>(ptr));
324 }
325 path& operator/=(const string_type& s) { return this->operator/=(path(s)); }
326 path& operator/=(string_type& s) { return this->operator/=(path(s)); }
327
328 path& append(const value_type* ptr) // required in case ptr overlaps *this
329 {
330 this->operator/=(ptr);
331 return *this;
303 } 332 }
304 333
305 path& append(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this 334 path& append(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this
306 { 335 {
307 this->operator/=(ptr); 336 this->operator/=(ptr);
308 return *this; 337 return *this;
309 } 338 }
310 339
311 template <class Source> 340 template <class Source>
341 path& append(Source const& source);
342
343 template <class Source>
312 path& append(Source const& source, const codecvt_type& cvt); 344 path& append(Source const& source, const codecvt_type& cvt);
313 345
314 template <class InputIterator> 346 template <class InputIterator>
315 path& append(InputIterator begin, InputIterator end) 347 path& append(InputIterator begin, InputIterator end);
316 {
317 return append(begin, end, codecvt());
318 }
319 348
320 template <class InputIterator> 349 template <class InputIterator>
321 path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt); 350 path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt);
322 351
323 // ----- modifiers ----- 352 // ----- modifiers -----
328 { return *this; } // POSIX no effect 357 { return *this; } // POSIX no effect
329 # else // BOOST_WINDOWS_API 358 # else // BOOST_WINDOWS_API
330 ; // change slashes to backslashes 359 ; // change slashes to backslashes
331 # endif 360 # endif
332 path& remove_filename(); 361 path& remove_filename();
362 path& remove_trailing_separator();
333 path& replace_extension(const path& new_extension = path()); 363 path& replace_extension(const path& new_extension = path());
334 void swap(path& rhs) { m_pathname.swap(rhs.m_pathname); } 364 void swap(path& rhs) { m_pathname.swap(rhs.m_pathname); }
335 365
336 // ----- observers ----- 366 // ----- observers -----
337 367
362 392
363 template <class String> 393 template <class String>
364 String string(const codecvt_type& cvt) const; 394 String string(const codecvt_type& cvt) const;
365 395
366 # ifdef BOOST_WINDOWS_API 396 # ifdef BOOST_WINDOWS_API
367 const std::string string() const { return string(codecvt()); } 397 const std::string string() const
398 {
399 std::string tmp;
400 if (!m_pathname.empty())
401 path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
402 tmp);
403 return tmp;
404 }
368 const std::string string(const codecvt_type& cvt) const 405 const std::string string(const codecvt_type& cvt) const
369 { 406 {
370 std::string tmp; 407 std::string tmp;
371 if (!m_pathname.empty()) 408 if (!m_pathname.empty())
372 path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), 409 path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
381 # else // BOOST_POSIX_API 418 # else // BOOST_POSIX_API
382 // string_type is std::string, so there is no conversion 419 // string_type is std::string, so there is no conversion
383 const std::string& string() const { return m_pathname; } 420 const std::string& string() const { return m_pathname; }
384 const std::string& string(const codecvt_type&) const { return m_pathname; } 421 const std::string& string(const codecvt_type&) const { return m_pathname; }
385 422
386 const std::wstring wstring() const { return wstring(codecvt()); } 423 const std::wstring wstring() const
424 {
425 std::wstring tmp;
426 if (!m_pathname.empty())
427 path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
428 tmp);
429 return tmp;
430 }
387 const std::wstring wstring(const codecvt_type& cvt) const 431 const std::wstring wstring(const codecvt_type& cvt) const
388 { 432 {
389 std::wstring tmp; 433 std::wstring tmp;
390 if (!m_pathname.empty()) 434 if (!m_pathname.empty())
391 path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(), 435 path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
402 446
403 template <class String> 447 template <class String>
404 String generic_string(const codecvt_type& cvt) const; 448 String generic_string(const codecvt_type& cvt) const;
405 449
406 # ifdef BOOST_WINDOWS_API 450 # ifdef BOOST_WINDOWS_API
407 const std::string generic_string() const { return generic_string(codecvt()); } 451 const std::string generic_string() const;
408 const std::string generic_string(const codecvt_type& cvt) const; 452 const std::string generic_string(const codecvt_type& cvt) const;
409 const std::wstring generic_wstring() const; 453 const std::wstring generic_wstring() const;
410 const std::wstring generic_wstring(const codecvt_type&) const { return generic_wstring(); }; 454 const std::wstring generic_wstring(const codecvt_type&) const { return generic_wstring(); };
411 455
412 # else // BOOST_POSIX_API 456 # else // BOOST_POSIX_API
413 // On POSIX-like systems, the generic format is the same as the native format 457 // On POSIX-like systems, the generic format is the same as the native format
414 const std::string& generic_string() const { return m_pathname; } 458 const std::string& generic_string() const { return m_pathname; }
415 const std::string& generic_string(const codecvt_type&) const { return m_pathname; } 459 const std::string& generic_string(const codecvt_type&) const { return m_pathname; }
416 const std::wstring generic_wstring() const { return wstring(codecvt()); } 460 const std::wstring generic_wstring() const { return wstring(); }
417 const std::wstring generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); } 461 const std::wstring generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); }
418 462
419 # endif 463 # endif
420 464
421 // ----- compare ----- 465 // ----- compare -----
554 namespace detail 598 namespace detail
555 { 599 {
556 BOOST_FILESYSTEM_DECL 600 BOOST_FILESYSTEM_DECL
557 int lex_compare(path::iterator first1, path::iterator last1, 601 int lex_compare(path::iterator first1, path::iterator last1,
558 path::iterator first2, path::iterator last2); 602 path::iterator first2, path::iterator last2);
603 BOOST_FILESYSTEM_DECL
604 const path& dot_path();
605 BOOST_FILESYSTEM_DECL
606 const path& dot_dot_path();
559 } 607 }
560 608
561 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED 609 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
562 typedef path wpath; 610 typedef path wpath;
563 # endif 611 # endif
684 //--------------------------------------------------------------------------------------// 732 //--------------------------------------------------------------------------------------//
685 // class path member template implementation // 733 // class path member template implementation //
686 //--------------------------------------------------------------------------------------// 734 //--------------------------------------------------------------------------------------//
687 735
688 template <class InputIterator> 736 template <class InputIterator>
689 path& path::append(InputIterator begin, InputIterator end, const codecvt_type& cvt) 737 path& path::append(InputIterator begin, InputIterator end)
690 { 738 {
691 if (begin == end) 739 if (begin == end)
692 return *this; 740 return *this;
693 string_type::size_type sep_pos(m_append_separator_if_needed()); 741 string_type::size_type sep_pos(m_append_separator_if_needed());
694 std::basic_string<typename std::iterator_traits<InputIterator>::value_type> 742 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
695 s(begin, end); 743 seq(begin, end);
696 path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt); 744 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname);
745 if (sep_pos)
746 m_erase_redundant_separator(sep_pos);
747 return *this;
748 }
749
750 template <class InputIterator>
751 path& path::append(InputIterator begin, InputIterator end, const codecvt_type& cvt)
752 {
753 if (begin == end)
754 return *this;
755 string_type::size_type sep_pos(m_append_separator_if_needed());
756 std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
757 seq(begin, end);
758 path_traits::convert(seq.c_str(), seq.c_str()+seq.size(), m_pathname, cvt);
759 if (sep_pos)
760 m_erase_redundant_separator(sep_pos);
761 return *this;
762 }
763
764 template <class Source>
765 path& path::append(Source const& source)
766 {
767 if (path_traits::empty(source))
768 return *this;
769 string_type::size_type sep_pos(m_append_separator_if_needed());
770 path_traits::dispatch(source, m_pathname);
697 if (sep_pos) 771 if (sep_pos)
698 m_erase_redundant_separator(sep_pos); 772 m_erase_redundant_separator(sep_pos);
699 return *this; 773 return *this;
700 } 774 }
701 775
745 819
746 template <> inline 820 template <> inline
747 std::wstring path::generic_string<std::wstring>(const codecvt_type& cvt) const 821 std::wstring path::generic_string<std::wstring>(const codecvt_type& cvt) const
748 { return generic_wstring(cvt); } 822 { return generic_wstring(cvt); }
749 823
750 824 //--------------------------------------------------------------------------------------//
825 // path_traits convert function implementations //
826 // requiring path::codecvt() be visable //
827 //--------------------------------------------------------------------------------------//
828
829 namespace path_traits
830 { // without codecvt
831
832 inline
833 void convert(const char* from,
834 const char* from_end, // 0 for null terminated MBCS
835 std::wstring & to)
836 {
837 convert(from, from_end, to, path::codecvt());
838 }
839
840 inline
841 void convert(const wchar_t* from,
842 const wchar_t* from_end, // 0 for null terminated MBCS
843 std::string & to)
844 {
845 convert(from, from_end, to, path::codecvt());
846 }
847
848 inline
849 void convert(const char* from,
850 std::wstring & to)
851 {
852 BOOST_ASSERT(from);
853 convert(from, 0, to, path::codecvt());
854 }
855
856 inline
857 void convert(const wchar_t* from,
858 std::string & to)
859 {
860 BOOST_ASSERT(from);
861 convert(from, 0, to, path::codecvt());
862 }
863 } // namespace path_traits
751 } // namespace filesystem 864 } // namespace filesystem
752 } // namespace boost 865 } // namespace boost
753 866
754 //----------------------------------------------------------------------------// 867 //----------------------------------------------------------------------------//
755 868