Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/filesystem/test/path_test.cpp @ 30

Last change on this file since 30 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 44.9 KB
Line 
1//  path_test program  -------------------------------------------------------//
2
3//  Copyright Beman Dawes 2002.
4//  Use, modification, and distribution is subject to the Boost Software
5//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6//  http://www.boost.org/LICENSE_1_0.txt)
7
8//  See library home page at http://www.boost.org/libs/filesystem
9
10#include <boost/filesystem/operations.hpp>
11#include <boost/utility.hpp>
12#include <iostream>
13#include <sstream>
14#include <string>
15#include <vector>
16#include <cstring>
17#include <cassert>
18
19namespace fs = boost::filesystem;
20using boost::filesystem::path;
21using boost::next;
22using boost::prior;
23
24#include <boost/test/minimal.hpp>
25
26#define PATH_CHECK( a, b ) check( a, b, __LINE__ )
27#define DIR_CHECK( a, b ) check_dir( a, b, __LINE__ )
28#define CHECK_EQUAL( a,b ) check_equal( a, b, __LINE__ )
29
30
31namespace
32{
33  int errors;
34
35  std::string platform( BOOST_PLATFORM );
36
37  void check( const fs::path & source,
38              const std::string & expected, int line )
39  {
40    if ( source.string()== expected ) return;
41
42    ++errors;
43
44    std::cout << '(' << line << ") source.string(): \"" << source.string()
45              << "\" != expected: \"" << expected
46              << "\"" << std::endl;
47  }
48
49  void check_dir( const fs::path & source,
50              const std::string & expected, int line )
51  {
52    if ( source.directory_string()== expected ) return;
53
54    ++errors;
55
56    std::cout << '(' << line << ") source.directory_string(): \""
57              << source.directory_string()
58              << "\" != expected: \"" << expected
59              << "\"" << std::endl;
60  }
61
62  void check_equal( const std::string & value,
63              const std::string & expected, int line )
64  {
65    if ( value == expected ) return;
66
67    ++errors;
68
69    std::cout << '(' << line << ") value: \"" << value
70              << "\" != expected: \"" << expected
71              << "\"" << std::endl;
72  }
73
74  void check_normalize()
75  {
76    PATH_CHECK( path("").normalize(), "" );
77    PATH_CHECK( path("/").normalize(), "/" );
78    PATH_CHECK( path("//").normalize(), "//" );
79    PATH_CHECK( path("///").normalize(), "/" );
80    PATH_CHECK( path("f").normalize(), "f" );
81    PATH_CHECK( path("foo").normalize(), "foo" );
82    PATH_CHECK( path("foo/").normalize(), "foo/." );
83    PATH_CHECK( path("f/").normalize(), "f/." );
84    PATH_CHECK( path( "/foo" ).normalize(), "/foo" );
85    PATH_CHECK( path( "foo/bar" ).normalize(), "foo/bar" );
86    PATH_CHECK( path("..").normalize(), ".." );
87    PATH_CHECK( path("../..").normalize(), "../.." );
88    PATH_CHECK( path("/..").normalize(), "/.." );
89    PATH_CHECK( path("/../..").normalize(), "/../.." );
90    PATH_CHECK( path("../foo").normalize(), "../foo" );
91    PATH_CHECK( path("foo/..").normalize(), "." );
92    PATH_CHECK( path("foo/../").normalize(), "./." );
93    PATH_CHECK( (path("foo") / "..").normalize() , "." );
94    PATH_CHECK( path("foo/...").normalize(), "foo/..." );
95    PATH_CHECK( path("foo/.../").normalize(), "foo/.../." );
96    PATH_CHECK( path("foo/..bar").normalize(), "foo/..bar" );
97    PATH_CHECK( path("../f").normalize(), "../f" );
98    PATH_CHECK( path("/../f").normalize(), "/../f" );
99    PATH_CHECK( path("f/..").normalize(), "." );
100    PATH_CHECK( (path("f") / "..").normalize() , "." );
101    PATH_CHECK( path("foo/../..").normalize(), ".." );
102    PATH_CHECK( path("foo/../../").normalize(), "../." );
103    PATH_CHECK( path("foo/../../..").normalize(), "../.." );
104    PATH_CHECK( path("foo/../../../").normalize(), "../../." );
105    PATH_CHECK( path("foo/../bar").normalize(), "bar" );
106    PATH_CHECK( path("foo/../bar/").normalize(), "bar/." );
107    PATH_CHECK( path("foo/bar/..").normalize(), "foo" );
108    PATH_CHECK( path("foo/bar/../").normalize(), "foo/." );
109    PATH_CHECK( path("foo/bar/../..").normalize(), "." );
110    PATH_CHECK( path("foo/bar/../../").normalize(), "./." );
111    PATH_CHECK( path("foo/bar/../blah").normalize(), "foo/blah" );
112    PATH_CHECK( path("f/../b").normalize(), "b" );
113    PATH_CHECK( path("f/b/..").normalize(), "f" );
114    PATH_CHECK( path("f/b/../").normalize(), "f/." );
115    PATH_CHECK( path("f/b/../a").normalize(), "f/a" );
116    PATH_CHECK( path("foo/bar/blah/../..").normalize(), "foo" );
117    PATH_CHECK( path("foo/bar/blah/../../bletch").normalize(), "foo/bletch" );
118    PATH_CHECK( path( "//net" ).normalize(), "//net" );
119    PATH_CHECK( path( "//net/" ).normalize(), "//net/" );
120    PATH_CHECK( path( "//..net" ).normalize(), "//..net" );
121    PATH_CHECK( path( "//net/.." ).normalize(), "//net/.." );
122    PATH_CHECK( path( "//net/foo" ).normalize(), "//net/foo" );
123    PATH_CHECK( path( "//net/foo/" ).normalize(), "//net/foo/." );
124    PATH_CHECK( path( "//net/foo/.." ).normalize(), "//net/" );
125    PATH_CHECK( path( "//net/foo/../" ).normalize(), "//net/." );
126
127    PATH_CHECK( path( "/net/foo/bar" ).normalize(), "/net/foo/bar" );
128    PATH_CHECK( path( "/net/foo/bar/" ).normalize(), "/net/foo/bar/." );
129    PATH_CHECK( path( "/net/foo/.." ).normalize(), "/net" );
130    PATH_CHECK( path( "/net/foo/../" ).normalize(), "/net/." );
131
132    PATH_CHECK( path( "//net//foo//bar" ).normalize(), "//net/foo/bar" );
133    PATH_CHECK( path( "//net//foo//bar//" ).normalize(), "//net/foo/bar/." );
134    PATH_CHECK( path( "//net//foo//.." ).normalize(), "//net/" );
135    PATH_CHECK( path( "//net//foo//..//" ).normalize(), "//net/." );
136
137    PATH_CHECK( path( "///net///foo///bar" ).normalize(), "/net/foo/bar" );
138    PATH_CHECK( path( "///net///foo///bar///" ).normalize(), "/net/foo/bar/." );
139    PATH_CHECK( path( "///net///foo///.." ).normalize(), "/net" );
140    PATH_CHECK( path( "///net///foo///..///" ).normalize(), "/net/." );
141
142    if ( platform == "Windows" )
143    {
144      PATH_CHECK( path( "c:.." ).normalize(), "c:.." );
145      PATH_CHECK( path( "c:foo/.." ).normalize(), "c:" );
146
147      PATH_CHECK( path( "c:foo/../" ).normalize(), "c:." );
148
149      PATH_CHECK( path( "c:/foo/.." ).normalize(), "c:/" );
150      PATH_CHECK( path( "c:/foo/../" ).normalize(), "c:/." );
151      PATH_CHECK( path( "c:/.." ).normalize(), "c:/.." );
152      PATH_CHECK( path( "c:/../" ).normalize(), "c:/../." );
153      PATH_CHECK( path( "c:/../.." ).normalize(), "c:/../.." );
154      PATH_CHECK( path( "c:/../../" ).normalize(), "c:/../../." );
155      PATH_CHECK( path( "c:/../foo" ).normalize(), "c:/../foo" );
156      PATH_CHECK( path( "c:/../foo/" ).normalize(), "c:/../foo/." );
157      PATH_CHECK( path( "c:/../../foo" ).normalize(), "c:/../../foo" );
158      PATH_CHECK( path( "c:/../../foo/" ).normalize(), "c:/../../foo/." );
159      PATH_CHECK( path( "c:/..foo" ).normalize(), "c:/..foo" );
160    }
161    else // POSIX
162    {
163      PATH_CHECK( path( "c:.." ).normalize(), "c:.." );
164      PATH_CHECK( path( "c:foo/.." ).normalize(), "." );
165      PATH_CHECK( path( "c:foo/../" ).normalize(), "./." );
166      PATH_CHECK( path( "c:/foo/.." ).normalize(), "c:" );
167      PATH_CHECK( path( "c:/foo/../" ).normalize(), "c:/." );
168      PATH_CHECK( path( "c:/.." ).normalize(), "." );
169      PATH_CHECK( path( "c:/../" ).normalize(), "./." );
170      PATH_CHECK( path( "c:/../.." ).normalize(), ".." );
171      PATH_CHECK( path( "c:/../../" ).normalize(), "../." );
172      PATH_CHECK( path( "c:/../foo" ).normalize(), "foo" );
173      PATH_CHECK( path( "c:/../foo/" ).normalize(), "foo/." );
174      PATH_CHECK( path( "c:/../../foo" ).normalize(), "../foo" );
175      PATH_CHECK( path( "c:/../../foo/" ).normalize(), "../foo/." );
176      PATH_CHECK( path( "c:/..foo" ).normalize(), "c:/..foo" );
177    }
178  }
179
180  void exception_tests()
181  {
182    const std::string str_1("string-1");
183    try { throw fs::filesystem_error( str_1, 12345 ); }
184    catch ( const fs::filesystem_error & ex )
185    {
186      BOOST_CHECK( ex.what() == str_1 );
187      BOOST_CHECK( ex.system_error() == 12345 );
188    }
189
190    try { throw fs::filesystem_path_error( str_1, "p1", "p2", 12345 ); }
191    catch ( const fs::filesystem_path_error & ex )
192    {
193      BOOST_CHECK( ex.what() == str_1 );
194      BOOST_CHECK( ex.system_error() == 12345 );
195      BOOST_CHECK( ex.path1().string() == "p1" );
196      BOOST_CHECK( ex.path2().string() == "p2" );
197    }
198  }
199
200} // unnamed namespace
201
202int test_main( int, char*[] )
203{
204  // The choice of platform is make at runtime rather than compile-time
205  // so that compile errors for all platforms will be detected even though
206  // only the current platform is runtime tested.
207  platform = ( platform == "Win32" || platform == "Win64" || platform == "Cygwin" )
208               ? "Windows"
209               : "POSIX";
210  std::cout << "Platform is " << platform << '\n';
211
212  path p1( "fe/fi/fo/fum" );
213  path p2( p1 );
214  path p3;
215  BOOST_CHECK( p1.string() != p3.string() );
216  p3 = p2;
217  BOOST_CHECK( p1.string() == p3.string() );
218
219  path p4( "foobar" );
220  BOOST_CHECK( p4.string() == "foobar" );
221  p4 = p4; // self-assignment
222  BOOST_CHECK( p4.string() == "foobar" );
223
224  exception_tests();
225
226  // These verify various overloads don't cause compiler errors
227
228  fs::exists( p1 );
229  fs::exists( "foo" );
230  fs::exists( std::string( "foo" ) );
231
232  fs::exists( p1 / path( "foo" ) );
233  fs::exists( p1 / "foo" );
234  fs::exists( p1 / std::string( "foo" ) );
235
236  fs::exists( "foo" / p1 );
237  fs::exists( std::string( "foo" ) / p1 );
238
239  p4 /= path( "foo" );
240  p4 /= "foo";
241  p4 /= std::string( "foo" );
242
243  path p5;
244  std::string s1( "//:somestring" );
245
246# ifndef BOOST_NO_MEMBER_TEMPLATES
247
248  // check the path member templates
249  p5.assign( s1.begin(), s1.end() );
250
251  PATH_CHECK( p5, "somestring" );
252  p5 = s1;
253  PATH_CHECK( p5, "somestring" );
254
255  BOOST_CHECK( p4.string() == path( p4.string().begin(), p4.string().end() ).string() );
256
257  char c0 = 'a';
258  p5.assign( &c0, &c0 );
259  PATH_CHECK( p5, "" );
260  p5 /= "";
261  PATH_CHECK( p5, "" );
262  p5 /= "foo/bar";
263  PATH_CHECK( p5, "foo/bar" );
264  p5.append( &c0, &c0 );
265  PATH_CHECK( p5, "foo/bar" );
266  p5 /= "";
267  PATH_CHECK( p5, "foo/bar" );
268  char bf[]= "bar/foo";
269  p5.assign( bf, bf + sizeof(bf) ); 
270  PATH_CHECK( p5, bf );
271  p5.append( bf, bf + sizeof(bf) ); 
272  PATH_CHECK( p5, "bar/foo/bar/foo" );
273
274  // this code, courtesy of David Whetstone, detected a now fixed bug that
275  // derefereced the end iterator (assuming debug build with checked itors)
276  std::vector<char> v1;
277  p5.assign( v1.begin(), v1.end() );
278  std::string s2( v1.begin(), v1.end() );
279  PATH_CHECK( p5, s2 );
280  p5.assign( s1.begin(), s1.begin() + 1 );
281  PATH_CHECK( p5, "/" );
282
283# endif
284
285  BOOST_CHECK( p1 != p4 );
286  BOOST_CHECK( p1.string() == p2.string() );
287  BOOST_CHECK( p1.string() == p3.string() );
288  BOOST_CHECK( path( "foo" ).leaf() == "foo" );
289  BOOST_CHECK( path( "foo" ).branch_path().string() == "" );
290  BOOST_CHECK( p1.leaf() == "fum" );
291  BOOST_CHECK( p1.branch_path().string() == "fe/fi/fo" );
292  BOOST_CHECK( path( "" ).empty() == true );
293  BOOST_CHECK( path( "foo" ).empty() == false );
294
295  PATH_CHECK( "", "" );
296
297  PATH_CHECK( "foo", "foo" );
298  PATH_CHECK( "f", "f" );
299
300  PATH_CHECK( "foo/", "foo/" );
301  PATH_CHECK( "f/", "f/" );
302  PATH_CHECK( "foo/..", "foo/.." );
303  PATH_CHECK( "foo/../", "foo/../" );
304  PATH_CHECK( "foo/bar/../..", "foo/bar/../.." );
305  PATH_CHECK( "foo/bar/../../", "foo/bar/../../" );
306  PATH_CHECK( path("") / "foo", "foo" );
307  PATH_CHECK( path("") / "foo/", "foo/" );
308  PATH_CHECK( path("foo") / "", "foo" );
309  PATH_CHECK( path( "/" ), "/" );
310  PATH_CHECK( path( "/" ) / "", "/" );
311  PATH_CHECK( path( "/f" ), "/f" );
312
313  PATH_CHECK( "/foo", "/foo" );
314  PATH_CHECK( path("") / "/foo", "/foo" );
315  PATH_CHECK( path("/foo") / "", "/foo" );
316
317  if ( platform == "Windows" )
318  {
319    PATH_CHECK( path("c:") / "foo", "c:foo" );
320    PATH_CHECK( path("c:") / "/foo", "c:/foo" );
321  }
322
323  check_normalize();
324
325  if ( platform == "Windows" )
326  {
327    PATH_CHECK( path("c:", fs::native ) / "foo", "c:foo" );
328    PATH_CHECK( path("c:", fs::native) / "/foo", "c:/foo" );
329  }
330
331  PATH_CHECK( "foo/bar", "foo/bar" );
332  PATH_CHECK( path("foo") / path("bar"), "foo/bar" ); // path arg
333  PATH_CHECK( path("foo") / "bar", "foo/bar" );       // const char * arg
334  PATH_CHECK( path("foo") / path("woo/bar").leaf(), "foo/bar" ); // const std::string & arg
335  PATH_CHECK( "foo" / path("bar"), "foo/bar" );
336
337  PATH_CHECK( "a/b", "a/b" );  // probe for length effects
338  PATH_CHECK( path("a") / "b", "a/b" );
339
340  PATH_CHECK( "..", ".." );
341  PATH_CHECK( path("..") / "", ".." );
342  PATH_CHECK( path("") / "..", ".." );
343
344  PATH_CHECK( "../..", "../.." );
345  PATH_CHECK( path("..") / ".." , "../.." );
346
347  PATH_CHECK( "/..", "/.." );
348  PATH_CHECK( path("/") / ".." , "/.." );
349
350  PATH_CHECK( "/../..", "/../.." );
351  PATH_CHECK( path("/..") / ".." , "/../.." );
352
353  PATH_CHECK( "../foo", "../foo" );
354  PATH_CHECK( path("..") / "foo" , "../foo" );
355
356  PATH_CHECK( "foo/..", "foo/.." );
357  PATH_CHECK( path("foo") / ".." , "foo/.." );
358  PATH_CHECK( path( "foo/..bar"), "foo/..bar" );
359
360  PATH_CHECK( "../f", "../f" );
361  PATH_CHECK( path("..") / "f" , "../f" );
362
363  PATH_CHECK( "/../f", "/../f" );
364  PATH_CHECK( path("/..") / "f" , "/../f" );
365
366  PATH_CHECK( "f/..", "f/.." );
367  PATH_CHECK( path("f") / ".." , "f/.." );
368
369  PATH_CHECK( "foo/../..", "foo/../.." );
370  PATH_CHECK( path("foo") / ".." / ".." , "foo/../.." );
371
372  PATH_CHECK( "foo/../../..", "foo/../../.." );
373  PATH_CHECK( path("foo") / ".." / ".." / ".." , "foo/../../.." );
374
375  PATH_CHECK( "foo/../bar", "foo/../bar" );
376  PATH_CHECK( path("foo") / ".." / "bar" , "foo/../bar" );
377
378  PATH_CHECK( "foo/bar/..", "foo/bar/.." );
379  PATH_CHECK( path("foo") / "bar" / ".." , "foo/bar/.." );
380
381  PATH_CHECK( "foo/bar/../..", "foo/bar/../.." );
382  PATH_CHECK( path("foo") / "bar" / ".." / "..", "foo/bar/../.." );
383
384  PATH_CHECK( "foo/bar/../blah", "foo/bar/../blah" );
385  PATH_CHECK( path("foo") / "bar" / ".." / "blah", "foo/bar/../blah" );
386
387  PATH_CHECK( "f/../b", "f/../b" );
388  PATH_CHECK( path("f") / ".." / "b" , "f/../b" );
389
390  PATH_CHECK( "f/b/..", "f/b/.." );
391  PATH_CHECK( path("f") / "b" / ".." , "f/b/.." );
392
393  PATH_CHECK( "f/b/../a", "f/b/../a" );
394  PATH_CHECK( path("f") / "b" / ".." / "a", "f/b/../a" );
395
396  PATH_CHECK( "foo/bar/blah/../..", "foo/bar/blah/../.." );
397  PATH_CHECK( path("foo") / "bar" / "blah" / ".." / "..", "foo/bar/blah/../.." );
398
399  PATH_CHECK( "foo/bar/blah/../../bletch", "foo/bar/blah/../../bletch" );
400  PATH_CHECK( path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo/bar/blah/../../bletch" );
401
402  PATH_CHECK( "...", "..." );
403  PATH_CHECK( "....", "...." );
404  PATH_CHECK( "foo/...", "foo/..." );
405  PATH_CHECK( "abc.", "abc." );
406  PATH_CHECK( "abc..", "abc.." );
407  PATH_CHECK( "foo/abc.", "foo/abc." );
408  PATH_CHECK( "foo/abc..", "foo/abc.." );
409
410  PATH_CHECK( path(".abc"), ".abc" );
411  PATH_CHECK( "a.c", "a.c" );
412  PATH_CHECK( path("..abc"), "..abc" );
413  PATH_CHECK( "a..c", "a..c" );
414  PATH_CHECK( path("foo/.abc"), "foo/.abc" );
415  PATH_CHECK( "foo/a.c", "foo/a.c" );
416  PATH_CHECK( path("foo/..abc"), "foo/..abc" );
417  PATH_CHECK( "foo/a..c", "foo/a..c" );
418
419  PATH_CHECK( ".", "." );
420  PATH_CHECK( path("") / ".", "." );
421  PATH_CHECK( "./foo", "./foo" );
422  PATH_CHECK( path(".") / "foo", "./foo" );
423  PATH_CHECK( "./..", "./.." );
424  PATH_CHECK( path(".") / "..", "./.." );
425  PATH_CHECK( "./../foo", "./../foo" );
426  PATH_CHECK( "foo/.", "foo/." );
427  PATH_CHECK( path("foo") / ".", "foo/." );
428  PATH_CHECK( "../.", "../." );
429  PATH_CHECK( path("..") / ".", "../." );
430  PATH_CHECK( "./.", "./." );
431  PATH_CHECK( path(".") / ".", "./." );
432  PATH_CHECK( "././.", "././." );
433  PATH_CHECK( path(".") / "." / ".", "././." );
434  PATH_CHECK( "./foo/.", "./foo/." );
435  PATH_CHECK( path(".") / "foo" / ".", "./foo/." );
436  PATH_CHECK( "foo/./bar", "foo/./bar" );
437  PATH_CHECK( path("foo") / "." / "bar", "foo/./bar" );
438  PATH_CHECK( "foo/./.", "foo/./." );
439  PATH_CHECK( path("foo") / "." / ".", "foo/./." );
440  PATH_CHECK( "foo/./..", "foo/./.." );
441  PATH_CHECK( path("foo") / "." / "..", "foo/./.." );
442  PATH_CHECK( "foo/./../bar", "foo/./../bar" );
443  PATH_CHECK( "foo/../.", "foo/../." );
444  PATH_CHECK( path(".") / "." / "..", "././.." );
445  PATH_CHECK( "././..", "././.." );
446  PATH_CHECK( path(".") / "." / "..", "././.." );
447  PATH_CHECK( "./../.", "./../." );
448  PATH_CHECK( path(".") / ".." / ".", "./../." );
449  PATH_CHECK( ".././.", ".././." );
450  PATH_CHECK( path("..") / "." / ".", ".././." );
451
452  // iterator tests
453
454  path itr_ck = "";
455  path::const_iterator itr = itr_ck.begin();
456  BOOST_CHECK( itr == itr_ck.end() );
457
458  itr_ck = "/";
459  itr = itr_ck.begin();
460  BOOST_CHECK( *itr == std::string( "/" ) );
461  BOOST_CHECK( ++itr == itr_ck.end() );
462  BOOST_CHECK( *--itr == std::string( "/" ) );
463
464  itr_ck = "foo";
465  BOOST_CHECK( *itr_ck.begin() == std::string( "foo" ) );
466  BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
467  BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
468  BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
469
470  itr_ck = path( "/foo" );
471  BOOST_CHECK( *itr_ck.begin() == std::string( "/" ) );
472  BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "foo" ) );
473  BOOST_CHECK( next(next( itr_ck.begin() )) == itr_ck.end() );
474  BOOST_CHECK( next( itr_ck.begin() ) == prior( itr_ck.end() ) );
475  BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
476  BOOST_CHECK( *prior(prior( itr_ck.end() )) == std::string( "/" ) );
477  BOOST_CHECK( prior(prior( itr_ck.end() )) == itr_ck.begin() );
478
479  itr_ck = "/foo/bar";
480  itr = itr_ck.begin();
481  BOOST_CHECK( *itr == std::string( "/" ) );
482  BOOST_CHECK( *++itr == std::string( "foo" ) );
483  BOOST_CHECK( *++itr == std::string( "bar" ) );
484  BOOST_CHECK( ++itr == itr_ck.end() );
485  CHECK_EQUAL( *--itr, "bar" );
486  CHECK_EQUAL( *--itr, "foo" );
487  CHECK_EQUAL( *--itr, "/" );
488
489  itr_ck = "../f"; // previously failed due to short name bug
490  itr = itr_ck.begin();
491  CHECK_EQUAL( *itr, ".." );
492  CHECK_EQUAL( *++itr, "f" );
493  BOOST_CHECK( ++itr == itr_ck.end() );
494  CHECK_EQUAL( *--itr, "f" );
495  CHECK_EQUAL( *--itr, ".." );
496
497  // POSIX says treat "/foo/bar/" as "/foo/bar/."
498  itr_ck = "/foo/bar/";
499  itr = itr_ck.begin();
500  CHECK_EQUAL( *itr, "/" );
501  CHECK_EQUAL( *++itr, "foo" );
502  CHECK_EQUAL( *++itr, "bar" );
503  CHECK_EQUAL( *++itr, "." );
504  BOOST_CHECK( ++itr == itr_ck.end() );
505  CHECK_EQUAL( *--itr, "." );
506  CHECK_EQUAL( *--itr, "bar" );
507  CHECK_EQUAL( *--itr, "foo" );
508  CHECK_EQUAL( *--itr, "/" );
509
510  // POSIX says treat "/f/b/" as "/f/b/."
511  itr_ck = "/f/b/";
512  itr = itr_ck.begin();
513  CHECK_EQUAL( *itr, "/" );
514  CHECK_EQUAL( *++itr, "f" );
515  CHECK_EQUAL( *++itr, "b" );
516  CHECK_EQUAL( *++itr, "." );
517  BOOST_CHECK( ++itr == itr_ck.end() );
518  CHECK_EQUAL( *--itr, "." );
519  CHECK_EQUAL( *--itr, "b" );
520  CHECK_EQUAL( *--itr, "f" );
521  CHECK_EQUAL( *--itr, "/" );
522
523  itr_ck = "//net";
524  itr = itr_ck.begin();
525  // two leading slashes are permitted by POSIX (as implementation defined),
526  // while for Windows it is always well defined (as a network name)
527  CHECK_EQUAL( *itr, "//net" );
528  BOOST_CHECK( ++itr == itr_ck.end() );
529  CHECK_EQUAL( *--itr, "//net" );
530
531  itr_ck = "//net/";
532  itr = itr_ck.begin();
533  CHECK_EQUAL( *itr, "//net" );
534  CHECK_EQUAL( *++itr, "/" );
535  BOOST_CHECK( ++itr == itr_ck.end() );
536  CHECK_EQUAL( *--itr, "/" );
537  CHECK_EQUAL( *--itr, "//net" );
538
539  itr_ck = "//foo///bar///";
540  itr = itr_ck.begin();
541  CHECK_EQUAL( *itr, "//foo" );
542  CHECK_EQUAL( *++itr, "/" );
543  CHECK_EQUAL( *++itr, "bar" );
544  CHECK_EQUAL( *++itr, "." );
545  BOOST_CHECK( ++itr == itr_ck.end() );
546  CHECK_EQUAL( *--itr, "." );
547  CHECK_EQUAL( *--itr, "bar" );
548  CHECK_EQUAL( *--itr, "/" );
549  CHECK_EQUAL( *--itr, "//foo" );
550
551  itr_ck = "///foo///bar///";
552  itr = itr_ck.begin();
553  // three or more leading slashes are to be treated as a single slash
554  CHECK_EQUAL( *itr, "/" );
555  CHECK_EQUAL( *++itr, "foo" );
556  CHECK_EQUAL( *++itr, "bar" );
557  CHECK_EQUAL( *++itr, "." );
558  BOOST_CHECK( ++itr == itr_ck.end() );
559  CHECK_EQUAL( *--itr, "." );
560  CHECK_EQUAL( *--itr, "bar" );
561  CHECK_EQUAL( *--itr, "foo" );
562  CHECK_EQUAL( *--itr, "/" );
563
564  if ( platform == "Windows" )
565  {
566    itr_ck = "c:/";
567    itr = itr_ck.begin();
568    CHECK_EQUAL( *itr, "c:" );
569    CHECK_EQUAL( *++itr, "/" );
570    BOOST_CHECK( ++itr == itr_ck.end() );
571    CHECK_EQUAL( *--itr, "/" );
572    CHECK_EQUAL( *--itr, "c:" );
573
574    itr_ck = "c:/foo";
575    itr = itr_ck.begin();
576    BOOST_CHECK( *itr == std::string( "c:" ) );
577    BOOST_CHECK( *++itr == std::string( "/" ) );
578    BOOST_CHECK( *++itr == std::string( "foo" ) );
579    BOOST_CHECK( ++itr == itr_ck.end() );
580    BOOST_CHECK( *--itr == std::string( "foo" ) );
581    BOOST_CHECK( *--itr == std::string( "/" ) );
582    BOOST_CHECK( *--itr == std::string( "c:" ) );
583
584    itr_ck = "c:foo";
585    itr = itr_ck.begin();
586    BOOST_CHECK( *itr == std::string( "c:" ) );
587    BOOST_CHECK( *++itr == std::string( "foo" ) );
588    BOOST_CHECK( ++itr == itr_ck.end() );
589    BOOST_CHECK( *--itr == std::string( "foo" ) );
590    BOOST_CHECK( *--itr == std::string( "c:" ) );
591
592    itr_ck = "c:foo/";
593    itr = itr_ck.begin();
594    BOOST_CHECK( *itr == std::string( "c:" ) );
595    BOOST_CHECK( *++itr == std::string( "foo" ) );
596    BOOST_CHECK( *++itr == std::string( "." ) );
597    BOOST_CHECK( ++itr == itr_ck.end() );
598    BOOST_CHECK( *--itr == std::string( "." ) );
599    BOOST_CHECK( *--itr == std::string( "foo" ) );
600    BOOST_CHECK( *--itr == std::string( "c:" ) );
601  }
602  else
603  {
604    itr_ck = "///";
605    itr = itr_ck.begin();
606    CHECK_EQUAL( *itr,  "/" );
607    BOOST_CHECK( ++itr == itr_ck.end() );
608  }
609
610  path p;
611
612  p = "";
613  BOOST_CHECK( p.relative_path().string() == "" );
614  BOOST_CHECK( p.branch_path().string() == "" );
615  BOOST_CHECK( p.leaf() == "" );
616  BOOST_CHECK( p.root_name() == "" );
617  BOOST_CHECK( p.root_directory() == "" );
618  BOOST_CHECK( p.root_path().string() == "" );
619  BOOST_CHECK( !p.has_root_path() );
620  BOOST_CHECK( !p.has_root_name() );
621  BOOST_CHECK( !p.has_root_directory() );
622  BOOST_CHECK( !p.has_relative_path() );
623  BOOST_CHECK( !p.has_leaf() );
624  BOOST_CHECK( !p.has_branch_path() );
625  BOOST_CHECK( !p.is_complete() );
626
627  p = "/";
628  BOOST_CHECK( p.relative_path().string() == "" );
629  BOOST_CHECK( p.branch_path().string() == "" );
630  BOOST_CHECK( p.leaf() == "/" );
631  BOOST_CHECK( p.root_name() == "" );
632  BOOST_CHECK( p.root_directory() == "/" );
633  BOOST_CHECK( p.root_path().string() == "/" );
634  BOOST_CHECK( p.has_root_path() );
635  BOOST_CHECK( !p.has_root_name() );
636  BOOST_CHECK( p.has_root_directory() );
637  BOOST_CHECK( !p.has_relative_path() );
638  BOOST_CHECK( p.has_leaf() );
639  BOOST_CHECK( !p.has_branch_path() );
640  if ( platform == "POSIX" )
641    BOOST_CHECK( p.is_complete() );
642  else
643    BOOST_CHECK( !p.is_complete() );
644
645  p = "//";
646  CHECK_EQUAL( p.relative_path().string(), "" );
647  CHECK_EQUAL( p.branch_path().string(), "" );
648  CHECK_EQUAL( p.leaf(), "//" );
649  CHECK_EQUAL( p.root_name(), "//" );
650  CHECK_EQUAL( p.root_directory(), "" );
651  CHECK_EQUAL( p.root_path().string(), "//" );
652  BOOST_CHECK( p.has_root_path() );
653  BOOST_CHECK( p.has_root_name() );
654  BOOST_CHECK( !p.has_root_directory() );
655  BOOST_CHECK( !p.has_relative_path() );
656  BOOST_CHECK( p.has_leaf() );
657  BOOST_CHECK( !p.has_branch_path() );
658  BOOST_CHECK( !p.is_complete() );
659
660
661  p = "///";
662  CHECK_EQUAL( p.relative_path().string(), "" );
663  CHECK_EQUAL( p.branch_path().string(), "" );
664  CHECK_EQUAL( p.leaf(), "/" );
665  CHECK_EQUAL( p.root_name(), "" );
666  CHECK_EQUAL( p.root_directory(), "/" );
667  CHECK_EQUAL( p.root_path().string(), "/" );
668  BOOST_CHECK( p.has_root_path() );
669  BOOST_CHECK( !p.has_root_name() );
670  BOOST_CHECK( p.has_root_directory() );
671  BOOST_CHECK( !p.has_relative_path() );
672  BOOST_CHECK( p.has_leaf() );
673  BOOST_CHECK( !p.has_branch_path() );
674  if ( platform == "POSIX" )
675    BOOST_CHECK( p.is_complete() );
676  else
677    BOOST_CHECK( !p.is_complete() );
678
679  p = ".";
680  BOOST_CHECK( p.relative_path().string() == "." );
681  BOOST_CHECK( p.branch_path().string() == "" );
682  BOOST_CHECK( p.leaf() == "." );
683  BOOST_CHECK( p.root_name() == "" );
684  BOOST_CHECK( p.root_directory() == "" );
685  BOOST_CHECK( p.root_path().string() == "" );
686  BOOST_CHECK( !p.has_root_path() );
687  BOOST_CHECK( !p.has_root_name() );
688  BOOST_CHECK( !p.has_root_directory() );
689  BOOST_CHECK( p.has_relative_path() );
690  BOOST_CHECK( p.has_leaf() );
691  BOOST_CHECK( !p.has_branch_path() );
692  BOOST_CHECK( !p.is_complete() );
693
694  p = "..";
695  BOOST_CHECK( p.relative_path().string() == ".." );
696  BOOST_CHECK( p.branch_path().string() == "" );
697  BOOST_CHECK( p.leaf() == ".." );
698  BOOST_CHECK( p.root_name() == "" );
699  BOOST_CHECK( p.root_directory() == "" );
700  BOOST_CHECK( p.root_path().string() == "" );
701  BOOST_CHECK( !p.has_root_path() );
702  BOOST_CHECK( !p.has_root_name() );
703  BOOST_CHECK( !p.has_root_directory() );
704  BOOST_CHECK( p.has_relative_path() );
705  BOOST_CHECK( p.has_leaf() );
706  BOOST_CHECK( !p.has_branch_path() );
707  BOOST_CHECK( !p.is_complete() );
708
709  p = "foo";
710  BOOST_CHECK( p.relative_path().string() == "foo" );
711  BOOST_CHECK( p.branch_path().string() == "" );
712  BOOST_CHECK( p.leaf() == "foo" );
713  BOOST_CHECK( p.root_name() == "" );
714  BOOST_CHECK( p.root_directory() == "" );
715  BOOST_CHECK( p.root_path().string() == "" );
716  BOOST_CHECK( !p.has_root_path() );
717  BOOST_CHECK( !p.has_root_name() );
718  BOOST_CHECK( !p.has_root_directory() );
719  BOOST_CHECK( p.has_relative_path() );
720  BOOST_CHECK( p.has_leaf() );
721  BOOST_CHECK( !p.has_branch_path() );
722  BOOST_CHECK( !p.is_complete() );
723
724  p = "/foo";
725  CHECK_EQUAL( p.relative_path().string(), "foo" );
726  CHECK_EQUAL( p.branch_path().string(), "/" );
727  CHECK_EQUAL( p.leaf(), "foo" );
728  CHECK_EQUAL( p.root_name(), "" );
729  CHECK_EQUAL( p.root_directory(), "/" );
730  CHECK_EQUAL( p.root_path().string(), "/" );
731  BOOST_CHECK( p.has_root_path() );
732  BOOST_CHECK( !p.has_root_name() );
733  BOOST_CHECK( p.has_root_directory() );
734  BOOST_CHECK( p.has_relative_path() );
735  BOOST_CHECK( p.has_leaf() );
736  BOOST_CHECK( p.has_branch_path() );
737  if ( platform == "POSIX" )
738    BOOST_CHECK( p.is_complete() );
739  else
740    BOOST_CHECK( !p.is_complete() );
741
742  p = "/foo/";
743  CHECK_EQUAL( p.relative_path().string(), "foo/" );
744  CHECK_EQUAL( p.branch_path().string(), "/foo" );
745  CHECK_EQUAL( p.leaf(), "." );
746  CHECK_EQUAL( p.root_name(), "" );
747  CHECK_EQUAL( p.root_directory(), "/" );
748  CHECK_EQUAL( p.root_path().string(), "/" );
749  BOOST_CHECK( p.has_root_path() );
750  BOOST_CHECK( !p.has_root_name() );
751  BOOST_CHECK( p.has_root_directory() );
752  BOOST_CHECK( p.has_relative_path() );
753  BOOST_CHECK( p.has_leaf() );
754  BOOST_CHECK( p.has_branch_path() );
755  if ( platform == "POSIX" )
756    BOOST_CHECK( p.is_complete() );
757  else
758    BOOST_CHECK( !p.is_complete() );
759
760  p = "///foo";
761  CHECK_EQUAL( p.relative_path().string(), "foo" );
762  CHECK_EQUAL( p.branch_path().string(), "/" );
763  CHECK_EQUAL( p.leaf(), "foo" );
764  CHECK_EQUAL( p.root_name(), "" );
765  CHECK_EQUAL( p.root_directory(), "/" );
766  CHECK_EQUAL( p.root_path().string(), "/" );
767  BOOST_CHECK( p.has_root_path() );
768  BOOST_CHECK( !p.has_root_name() );
769  BOOST_CHECK( p.has_root_directory() );
770  BOOST_CHECK( p.has_relative_path() );
771  BOOST_CHECK( p.has_leaf() );
772  BOOST_CHECK( p.has_branch_path() );
773  if ( platform == "POSIX" )
774    BOOST_CHECK( p.is_complete() );
775  else
776    BOOST_CHECK( !p.is_complete() );
777
778  p = "foo/bar";
779  BOOST_CHECK( p.relative_path().string() == "foo/bar" );
780  BOOST_CHECK( p.branch_path().string() == "foo" );
781  BOOST_CHECK( p.leaf() == "bar" );
782  BOOST_CHECK( p.root_name() == "" );
783  BOOST_CHECK( p.root_directory() == "" );
784  BOOST_CHECK( p.root_path().string() == "" );
785  BOOST_CHECK( !p.has_root_path() );
786  BOOST_CHECK( !p.has_root_name() );
787  BOOST_CHECK( !p.has_root_directory() );
788  BOOST_CHECK( p.has_relative_path() );
789  BOOST_CHECK( p.has_leaf() );
790  BOOST_CHECK( p.has_branch_path() );
791  BOOST_CHECK( !p.is_complete() );
792
793  p = "../foo";
794  BOOST_CHECK( p.relative_path().string() == "../foo" );
795  BOOST_CHECK( p.branch_path().string() == ".." );
796  BOOST_CHECK( p.leaf() == "foo" );
797  BOOST_CHECK( p.root_name() == "" );
798  BOOST_CHECK( p.root_directory() == "" );
799  BOOST_CHECK( p.root_path().string() == "" );
800  BOOST_CHECK( !p.has_root_path() );
801  BOOST_CHECK( !p.has_root_name() );
802  BOOST_CHECK( !p.has_root_directory() );
803  BOOST_CHECK( p.has_relative_path() );
804  BOOST_CHECK( p.has_leaf() );
805  BOOST_CHECK( p.has_branch_path() );
806  BOOST_CHECK( !p.is_complete() );
807
808  p = "..///foo";
809  CHECK_EQUAL( p.relative_path().string(), "..///foo" );
810  CHECK_EQUAL( p.branch_path().string(), ".." );
811  CHECK_EQUAL( p.leaf(), "foo" );
812  CHECK_EQUAL( p.root_name(), "" );
813  CHECK_EQUAL( p.root_directory(), "" );
814  CHECK_EQUAL( p.root_path().string(), "" );
815  BOOST_CHECK( !p.has_root_path() );
816  BOOST_CHECK( !p.has_root_name() );
817  BOOST_CHECK( !p.has_root_directory() );
818  BOOST_CHECK( p.has_relative_path() );
819  BOOST_CHECK( p.has_leaf() );
820  BOOST_CHECK( p.has_branch_path() );
821  BOOST_CHECK( !p.is_complete() );
822
823  p = "/foo/bar";
824  BOOST_CHECK( p.relative_path().string() == "foo/bar" );
825  BOOST_CHECK( p.branch_path().string() == "/foo" );
826  BOOST_CHECK( p.leaf() == "bar" );
827  BOOST_CHECK( p.root_name() == "" );
828  BOOST_CHECK( p.root_directory() == "/" );
829  BOOST_CHECK( p.root_path().string() == "/" );
830  BOOST_CHECK( p.has_root_path() );
831  BOOST_CHECK( !p.has_root_name() );
832  BOOST_CHECK( p.has_root_directory() );
833  BOOST_CHECK( p.has_relative_path() );
834  BOOST_CHECK( p.has_leaf() );
835  BOOST_CHECK( p.has_branch_path() );
836  if ( platform == "POSIX" )
837    BOOST_CHECK( p.is_complete() );
838  else
839    BOOST_CHECK( !p.is_complete() );
840
841  // Both POSIX and Windows allow two leading slashs
842  // (POSIX meaning is implementation defined)
843  PATH_CHECK( path( "//resource" ), "//resource" );
844  PATH_CHECK( path( "//resource/" ), "//resource/" );
845  PATH_CHECK( path( "//resource/foo" ), "//resource/foo" );
846
847  p = path( "//net" );
848  CHECK_EQUAL( p.string(), "//net" );
849  CHECK_EQUAL( p.relative_path().string(), "" );
850  CHECK_EQUAL( p.branch_path().string(), "" );
851  CHECK_EQUAL( p.leaf(), "//net" );
852  CHECK_EQUAL( p.root_name(), "//net" );
853  CHECK_EQUAL( p.root_directory(), "" );
854  CHECK_EQUAL( p.root_path().string(), "//net" );
855  BOOST_CHECK( p.has_root_path() );
856  BOOST_CHECK( p.has_root_name() );
857  BOOST_CHECK( !p.has_root_directory() );
858  BOOST_CHECK( !p.has_relative_path() );
859  BOOST_CHECK( p.has_leaf() );
860  BOOST_CHECK( !p.has_branch_path() );
861  BOOST_CHECK( !p.is_complete() );
862
863  p = path( "//net/" );
864  BOOST_CHECK( p.relative_path().string() == "" );
865  BOOST_CHECK( p.branch_path().string() == "//net" );
866  BOOST_CHECK( p.leaf() == "/" );
867  BOOST_CHECK( p.root_name() == "//net" );
868  BOOST_CHECK( p.root_directory() == "/" );
869  BOOST_CHECK( p.root_path().string() == "//net/" );
870  BOOST_CHECK( p.has_root_path() );
871  BOOST_CHECK( p.has_root_name() );
872  BOOST_CHECK( p.has_root_directory() );
873  BOOST_CHECK( !p.has_relative_path() );
874  BOOST_CHECK( p.has_leaf() );
875  BOOST_CHECK( p.has_branch_path() );
876  BOOST_CHECK( p.is_complete() );
877
878  p = path( "//net/foo" );
879  BOOST_CHECK( p.relative_path().string() == "foo" );
880  BOOST_CHECK( p.branch_path().string() == "//net/" );
881  BOOST_CHECK( p.leaf() == "foo" );
882  BOOST_CHECK( p.root_name() == "//net" );
883  BOOST_CHECK( p.root_directory() == "/" );
884  BOOST_CHECK( p.root_path().string() == "//net/" );
885  BOOST_CHECK( p.has_root_path() );
886  BOOST_CHECK( p.has_root_name() );
887  BOOST_CHECK( p.has_root_directory() );
888  BOOST_CHECK( p.has_relative_path() );
889  BOOST_CHECK( p.has_leaf() );
890  BOOST_CHECK( p.has_branch_path() );
891  BOOST_CHECK( p.is_complete() );
892
893  p = path( "//net///foo" );
894  CHECK_EQUAL( p.relative_path().string(), "foo" );
895  CHECK_EQUAL( p.branch_path().string(), "//net/" );
896  CHECK_EQUAL( p.leaf(), "foo" );
897  CHECK_EQUAL( p.root_name(), "//net" );
898  CHECK_EQUAL( p.root_directory(), "/" );
899  CHECK_EQUAL( p.root_path().string(), "//net/" );
900  BOOST_CHECK( p.has_root_path() );
901  BOOST_CHECK( p.has_root_name() );
902  BOOST_CHECK( p.has_root_directory() );
903  BOOST_CHECK( p.has_relative_path() );
904  BOOST_CHECK( p.has_leaf() );
905  BOOST_CHECK( p.has_branch_path() );
906  BOOST_CHECK( p.is_complete() );
907
908  if ( platform == "Windows" )
909  {
910    DIR_CHECK( path( "/foo/bar/" ), "\\foo\\bar\\" );
911    DIR_CHECK( path( "//foo//bar//" ), "\\\\foo\\bar\\\\" );
912    DIR_CHECK( path( "///foo///bar///" ), "\\foo\\\\\\bar\\\\\\" );
913
914    DIR_CHECK( path( "\\/foo\\/bar\\/" ), "\\\\foo\\bar\\\\" );
915    DIR_CHECK( path( "\\//foo\\//bar\\//" ), "\\foo\\\\\\bar\\\\\\" );
916
917
918    DIR_CHECK( path( "\\foo\\bar\\" ), "\\foo\\bar\\" );
919    DIR_CHECK( path( "\\\\foo\\\\bar\\\\" ), "\\\\foo\\bar\\\\" );
920    DIR_CHECK( path( "\\\\\\foo\\\\\\bar\\\\\\" ), "\\foo\\\\\\bar\\\\\\" );
921
922    PATH_CHECK( path( "\\" ), "/" );
923    PATH_CHECK( path( "\\f" ), "/f" );
924    PATH_CHECK( path( "\\foo" ), "/foo" );
925    PATH_CHECK( path( "foo\\bar" ), "foo/bar" );
926    PATH_CHECK( path( "foo bar" ), "foo bar" );
927    PATH_CHECK( path( "c:" ), "c:" );
928    PATH_CHECK( path( "c:/" ), "c:/" );
929    PATH_CHECK( path( "c:." ), "c:." );
930    PATH_CHECK( path( "c:./foo" ), "c:./foo" );
931    PATH_CHECK( path( "c:.\\foo" ), "c:./foo" );
932    PATH_CHECK( path( "c:.." ), "c:.." );
933    PATH_CHECK( path( "c:/." ), "c:/." );
934    PATH_CHECK( path( "c:/.." ), "c:/.." );
935    PATH_CHECK( path( "c:/../" ), "c:/../" );
936    PATH_CHECK( path( "c:\\..\\" ), "c:/../" );
937    PATH_CHECK( path( "c:/../.." ), "c:/../.." );
938    PATH_CHECK( path( "c:/../foo" ), "c:/../foo" );
939    PATH_CHECK( path( "c:\\..\\foo" ), "c:/../foo" );
940    PATH_CHECK( path( "c:../foo" ), "c:../foo" );
941    PATH_CHECK( path( "c:..\\foo" ), "c:../foo" );
942    PATH_CHECK( path( "c:/../../foo" ), "c:/../../foo" );
943    PATH_CHECK( path( "c:\\..\\..\\foo" ), "c:/../../foo" );
944    PATH_CHECK( path( "c:foo/.." ), "c:foo/.." );
945    PATH_CHECK( path( "c:/foo/.." ), "c:/foo/.." );
946    PATH_CHECK( path( "c:/..foo" ), "c:/..foo" );
947    PATH_CHECK( path( "c:foo" ), "c:foo" );
948    PATH_CHECK( path( "c:/foo" ), "c:/foo" );
949    PATH_CHECK( path( "\\\\netname" ), "//netname" );
950    PATH_CHECK( path( "\\\\netname\\" ), "//netname/" );
951    PATH_CHECK( path( "\\\\netname\\foo" ), "//netname/foo" );
952    PATH_CHECK( path( "c:/foo" ), "c:/foo" );
953    PATH_CHECK( path( "prn:" ), "prn:" );
954
955    p = path( "c:" );
956    BOOST_CHECK( p.relative_path().string() == "" );
957    BOOST_CHECK( p.branch_path().string() == "" );
958    BOOST_CHECK( p.leaf() == "c:" );
959    BOOST_CHECK( p.root_name() == "c:" );
960    BOOST_CHECK( p.root_directory() == "" );
961    BOOST_CHECK( p.root_path().string() == "c:" );
962    BOOST_CHECK( p.has_root_path() );
963    BOOST_CHECK( p.has_root_name() );
964    BOOST_CHECK( !p.has_root_directory() );
965    BOOST_CHECK( !p.has_relative_path() );
966    BOOST_CHECK( p.has_leaf() );
967    BOOST_CHECK( !p.has_branch_path() );
968    BOOST_CHECK( !p.is_complete() );
969
970    p = path( "c:foo" );
971    BOOST_CHECK( p.relative_path().string() == "foo" );
972    BOOST_CHECK( p.branch_path().string() == "c:" );
973    BOOST_CHECK( p.leaf() == "foo" );
974    BOOST_CHECK( p.root_name() == "c:" );
975    BOOST_CHECK( p.root_directory() == "" );
976    BOOST_CHECK( p.root_path().string() == "c:" );
977    BOOST_CHECK( p.has_root_path() );
978    BOOST_CHECK( p.has_root_name() );
979    BOOST_CHECK( !p.has_root_directory() );
980    BOOST_CHECK( p.has_relative_path() );
981    BOOST_CHECK( p.has_leaf() );
982    BOOST_CHECK( p.has_branch_path() );
983    BOOST_CHECK( !p.is_complete() );
984 
985    p = path( "c:/" );
986    BOOST_CHECK( p.relative_path().string() == "" );
987    BOOST_CHECK( p.branch_path().string() == "c:" );
988    BOOST_CHECK( p.leaf() == "/" );
989    BOOST_CHECK( p.root_name() == "c:" );
990    BOOST_CHECK( p.root_directory() == "/" );
991    BOOST_CHECK( p.root_path().string() == "c:/" );
992    BOOST_CHECK( p.has_root_path() );
993    BOOST_CHECK( p.has_root_name() );
994    BOOST_CHECK( p.has_root_directory() );
995    BOOST_CHECK( !p.has_relative_path() );
996    BOOST_CHECK( p.has_leaf() );
997    BOOST_CHECK( p.has_branch_path() );
998    BOOST_CHECK( p.is_complete() );
999
1000    p = path( "c:.." );
1001    BOOST_CHECK( p.relative_path().string() == ".." );
1002    BOOST_CHECK( p.branch_path().string() == "c:" );
1003    BOOST_CHECK( p.leaf() == ".." );
1004    BOOST_CHECK( p.root_name() == "c:" );
1005    BOOST_CHECK( p.root_directory() == "" );
1006    BOOST_CHECK( p.root_path().string() == "c:" );
1007    BOOST_CHECK( p.has_root_path() );
1008    BOOST_CHECK( p.has_root_name() );
1009    BOOST_CHECK( !p.has_root_directory() );
1010    BOOST_CHECK( p.has_relative_path() );
1011    BOOST_CHECK( p.has_leaf() );
1012    BOOST_CHECK( p.has_branch_path() );
1013    BOOST_CHECK( !p.is_complete() );
1014
1015    p = path( "c:/foo" );
1016    CHECK_EQUAL( p.relative_path().string(), "foo" );
1017    CHECK_EQUAL( p.branch_path().string(), "c:/" );
1018    CHECK_EQUAL( p.leaf(), "foo" );
1019    CHECK_EQUAL( p.root_name(), "c:" );
1020    CHECK_EQUAL( p.root_directory(), "/" );
1021    CHECK_EQUAL( p.root_path().string(), "c:/" );
1022    BOOST_CHECK( p.has_root_path() );
1023    BOOST_CHECK( p.has_root_name() );
1024    BOOST_CHECK( p.has_root_directory() );
1025    BOOST_CHECK( p.has_relative_path() );
1026    BOOST_CHECK( p.has_leaf() );
1027    BOOST_CHECK( p.has_branch_path() );
1028    BOOST_CHECK( p.is_complete() );
1029
1030    p = path( "c://foo" );
1031    CHECK_EQUAL( p.relative_path().string(), "foo" );
1032    CHECK_EQUAL( p.branch_path().string(), "c:/" );
1033    CHECK_EQUAL( p.leaf(), "foo" );
1034    CHECK_EQUAL( p.root_name(), "c:" );
1035    CHECK_EQUAL( p.root_directory(), "/" );
1036    CHECK_EQUAL( p.root_path().string(), "c:/" );
1037    BOOST_CHECK( p.has_root_path() );
1038    BOOST_CHECK( p.has_root_name() );
1039    BOOST_CHECK( p.has_root_directory() );
1040    BOOST_CHECK( p.has_relative_path() );
1041    BOOST_CHECK( p.has_leaf() );
1042    BOOST_CHECK( p.has_branch_path() );
1043    BOOST_CHECK( p.is_complete() );
1044
1045    p = path( "c:\\foo\\bar" );
1046    CHECK_EQUAL( p.relative_path().string(), "foo/bar" );
1047    CHECK_EQUAL( p.branch_path().string(), "c:/foo" );
1048    CHECK_EQUAL( p.leaf(), "bar" );
1049    CHECK_EQUAL( p.root_name(), "c:" );
1050    CHECK_EQUAL( p.root_directory(), "/" );
1051    CHECK_EQUAL( p.root_path().string(), "c:/" );
1052    BOOST_CHECK( p.has_root_path() );
1053    BOOST_CHECK( p.has_root_name() );
1054    BOOST_CHECK( p.has_root_directory() );
1055    BOOST_CHECK( p.has_relative_path() );
1056    BOOST_CHECK( p.has_leaf() );
1057    BOOST_CHECK( p.has_branch_path() );
1058    BOOST_CHECK( p.is_complete() );
1059
1060    p = path( "prn:" );
1061    BOOST_CHECK( p.relative_path().string() == "" );
1062    BOOST_CHECK( p.branch_path().string() == "" );
1063    BOOST_CHECK( p.leaf() == "prn:" );
1064    BOOST_CHECK( p.root_name() == "prn:" );
1065    BOOST_CHECK( p.root_directory() == "" );
1066    BOOST_CHECK( p.root_path().string() == "prn:" );
1067    BOOST_CHECK( p.has_root_path() );
1068    BOOST_CHECK( p.has_root_name() );
1069    BOOST_CHECK( !p.has_root_directory() );
1070    BOOST_CHECK( !p.has_relative_path() );
1071    BOOST_CHECK( p.has_leaf() );
1072    BOOST_CHECK( !p.has_branch_path() );
1073    BOOST_CHECK( !p.is_complete() );
1074
1075    p = path( "\\\\net\\\\\\foo" );
1076    CHECK_EQUAL( p.relative_path().string(), "foo" );
1077    CHECK_EQUAL( p.branch_path().string(), "//net/" );
1078    CHECK_EQUAL( p.leaf(), "foo" );
1079    CHECK_EQUAL( p.root_name(), "//net" );
1080    CHECK_EQUAL( p.root_directory(), "/" );
1081    CHECK_EQUAL( p.root_path().string(), "//net/" );
1082    BOOST_CHECK( p.has_root_path() );
1083    BOOST_CHECK( p.has_root_name() );
1084    BOOST_CHECK( p.has_root_directory() );
1085    BOOST_CHECK( p.has_relative_path() );
1086    BOOST_CHECK( p.has_leaf() );
1087    BOOST_CHECK( p.has_branch_path() );
1088    BOOST_CHECK( p.is_complete() );
1089
1090    itr_ck = path( "c:" );
1091    BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
1092    BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
1093    BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
1094    BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "c:" ) );
1095
1096    itr_ck = path( "c:/" );
1097    BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
1098    BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "/" ) );
1099    BOOST_CHECK( next( next( itr_ck.begin() )) == itr_ck.end() );
1100    BOOST_CHECK( prior( prior( itr_ck.end() )) == itr_ck.begin() );
1101    BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "/" ) );
1102    BOOST_CHECK( *prior( prior( itr_ck.end() )) == std::string( "c:" ) );
1103
1104    itr_ck = path( "c:foo" );
1105    BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
1106    BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "foo" ) );
1107    BOOST_CHECK( next(next( itr_ck.begin() )) == itr_ck.end() );
1108    BOOST_CHECK( prior(prior( itr_ck.end() )) == itr_ck.begin() );
1109    BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
1110    BOOST_CHECK( *prior(prior( itr_ck.end() )) == std::string( "c:" ) );
1111
1112    itr_ck = path( "c:/foo" );
1113    BOOST_CHECK( *itr_ck.begin() == std::string( "c:" ) );
1114    BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "/" ) );
1115    BOOST_CHECK( *next( next( itr_ck.begin() )) == std::string( "foo" ) );
1116    BOOST_CHECK( next( next( next( itr_ck.begin() ))) == itr_ck.end() );
1117    BOOST_CHECK( prior( prior( prior( itr_ck.end() ))) == itr_ck.begin() );
1118    BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
1119    BOOST_CHECK( *prior( prior( itr_ck.end() )) == std::string( "/" ) );
1120    BOOST_CHECK( *prior( prior( prior( itr_ck.end() ))) == std::string( "c:" ) );
1121
1122    itr_ck = path( "//net" );
1123    BOOST_CHECK( *itr_ck.begin() == std::string( "//net" ) );
1124    BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
1125    BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
1126    BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "//net" ) );
1127
1128    itr_ck = path( "//net/" );
1129    CHECK_EQUAL( *itr_ck.begin(), "//net" );
1130    CHECK_EQUAL( *next( itr_ck.begin() ), "/" );
1131    BOOST_CHECK( next(next( itr_ck.begin() )) == itr_ck.end() );
1132    BOOST_CHECK( prior(prior( itr_ck.end() )) == itr_ck.begin() );
1133    CHECK_EQUAL( *prior( itr_ck.end() ), "/" );
1134    CHECK_EQUAL( *prior(prior( itr_ck.end() )), "//net" );
1135
1136    itr_ck = path( "//net/foo" );
1137    BOOST_CHECK( *itr_ck.begin() == std::string( "//net" ) );
1138    BOOST_CHECK( *next( itr_ck.begin() ) == std::string( "/" ) );
1139    BOOST_CHECK( *next(next( itr_ck.begin() )) == std::string( "foo" ) );
1140    BOOST_CHECK( next(next(next( itr_ck.begin() ))) == itr_ck.end() );
1141    BOOST_CHECK( prior(prior(prior( itr_ck.end() ))) == itr_ck.begin() );
1142    BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "foo" ) );
1143    BOOST_CHECK( *prior(prior( itr_ck.end() )) == std::string( "/" ) );
1144    BOOST_CHECK( *prior(prior(prior( itr_ck.end() ))) == std::string( "//net" ) );
1145
1146    itr_ck = path( "prn:" );
1147    BOOST_CHECK( *itr_ck.begin() == std::string( "prn:" ) );
1148    BOOST_CHECK( next( itr_ck.begin() ) == itr_ck.end() );
1149    BOOST_CHECK( prior( itr_ck.end() ) == itr_ck.begin() );
1150    BOOST_CHECK( *prior( itr_ck.end() ) == std::string( "prn:" ) );
1151  } // Windows
1152
1153  else
1154  { // POSIX
1155    DIR_CHECK( path( "/foo/bar/" ), "/foo/bar/" );
1156    DIR_CHECK( path( "//foo//bar//" ), "//foo//bar//" );
1157    DIR_CHECK( path( "///foo///bar///" ), "///foo///bar///" );
1158
1159    p = path( "/usr/local/bin:/usr/bin:/bin" );
1160    BOOST_CHECK( p.file_string() == "/usr/local/bin:/usr/bin:/bin" );
1161  } // POSIX
1162
1163  // test non-member functions, particularly operator overloads
1164                                                             
1165  path e, e2;
1166  std::string es, es2;
1167  char ecs[] = "";
1168  char ecs2[] = "";
1169
1170  char acs[] = "a";
1171  std::string as(acs);
1172  path a( as );
1173
1174  char acs2[] = "a";
1175  std::string as2(acs2);
1176  path a2( as2 );
1177
1178  char bcs[] = "b";
1179  std::string bs(bcs);
1180  path b( bs );
1181
1182  // swap
1183  a.swap( b );
1184  BOOST_CHECK( a.string() == "b" );
1185  BOOST_CHECK( b.string() == "a" );
1186  fs::swap( a, b );
1187  BOOST_CHECK( a.string() == "a" );
1188  BOOST_CHECK( b.string() == "b" );
1189
1190  // probe operator /
1191  BOOST_CHECK( (b / a).string() == "b/a" );
1192  BOOST_CHECK( (bs / a).string() == "b/a" );
1193  BOOST_CHECK( (bcs / a).string() == "b/a" );
1194  BOOST_CHECK( (b / as).string() == "b/a" );
1195  BOOST_CHECK( (b / acs).string() == "b/a" );
1196
1197  // probe operator <
1198  BOOST_CHECK( !(e < e2) );
1199  BOOST_CHECK( !(es < e2) );
1200  BOOST_CHECK( !(ecs < e2) );
1201  BOOST_CHECK( !(e < es2) );
1202  BOOST_CHECK( !(e < ecs2) );
1203
1204  BOOST_CHECK( e < a );
1205  BOOST_CHECK( es < a );
1206  BOOST_CHECK( ecs < a );
1207  BOOST_CHECK( e < as );
1208  BOOST_CHECK( e < acs );
1209
1210  BOOST_CHECK( a < b );
1211  BOOST_CHECK( as < b );
1212  BOOST_CHECK( acs < b );
1213  BOOST_CHECK( a < bs );
1214  BOOST_CHECK( a < bcs );
1215
1216  BOOST_CHECK( !(a < a2) );
1217  BOOST_CHECK( !(as < a2) );
1218  BOOST_CHECK( !(acs < a2) );
1219  BOOST_CHECK( !(a < as2) );
1220  BOOST_CHECK( !(a < acs2) );
1221
1222  // make sure basic_path overloads don't conflict with std::string overloads
1223
1224  BOOST_CHECK( !(as < as) );
1225  BOOST_CHECK( !(as < acs) );
1226  BOOST_CHECK( !(acs < as) );
1227
1228  // reality check character set is as expected
1229  BOOST_CHECK( std::string("a.b") < std::string("a/b") );
1230  // verify compare is actually lexicographical
1231  BOOST_CHECK( path("a/b") < path("a.b") );
1232
1233  // make sure the derivative operators also work
1234  BOOST_CHECK( a == a2 );
1235  BOOST_CHECK( as == a2 );
1236  BOOST_CHECK( acs == a2 );
1237  BOOST_CHECK( a == as2 );
1238  BOOST_CHECK( a == acs2 );
1239
1240  BOOST_CHECK( a != b );
1241  BOOST_CHECK( as != b );
1242  BOOST_CHECK( acs != b );
1243  BOOST_CHECK( a != bs );
1244  BOOST_CHECK( a != bcs );
1245
1246  BOOST_CHECK( b > a );
1247  BOOST_CHECK( b > as );
1248  BOOST_CHECK( b > acs );
1249  BOOST_CHECK( bs > a);
1250  BOOST_CHECK( bcs > a);
1251
1252  BOOST_CHECK( !(a2 > a) );
1253  BOOST_CHECK( !(a2 > as) );
1254  BOOST_CHECK( !(a2 > acs) );
1255  BOOST_CHECK( !(as2 > a) );
1256  BOOST_CHECK( !(acs2 > a) );
1257
1258  BOOST_CHECK( a <= b );
1259  BOOST_CHECK( as <= b );
1260  BOOST_CHECK( acs <= b );
1261  BOOST_CHECK( a <= bs );
1262  BOOST_CHECK( a <= bcs );
1263
1264  BOOST_CHECK( a <= a2 );
1265  BOOST_CHECK( as <= a2 );
1266  BOOST_CHECK( acs <= a2 );
1267  BOOST_CHECK( a <= as2 );
1268  BOOST_CHECK( a <= acs2 );
1269
1270  BOOST_CHECK( b >= a );
1271  BOOST_CHECK( bs >= a );
1272  BOOST_CHECK( bcs >= a );
1273  BOOST_CHECK( b >= as );
1274  BOOST_CHECK( b >= acs );
1275
1276  BOOST_CHECK( a2 >= a );
1277  BOOST_CHECK( as2 >= a );
1278  BOOST_CHECK( acs2 >= a );
1279  BOOST_CHECK( a2 >= as );
1280  BOOST_CHECK( a2 >= acs );
1281
1282  // inserter and extractor tests
1283# if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // bypass VC++ 7.0 and earlier
1284  std::cout << "\nInserter and extractor test...";
1285  std::stringstream ss;
1286  ss << fs::path( "foo/bar" ) << std::endl;
1287  fs::path round_trip;
1288  ss >> round_trip;
1289  BOOST_CHECK( round_trip.string() == "foo/bar" );
1290  std::cout << round_trip.string() << "..." << round_trip << " complete\n";
1291# endif
1292
1293
1294  std::cout << errors << " errors detected\n";
1295 
1296  return errors;
1297}
Note: See TracBrowser for help on using the repository browser.